Skip to content

chore(i18n): add Cursor Memsource skill and peer usage guide - #272

Open
avivtur wants to merge 4 commits into
openshift:mainfrom
avivtur:chore/i18n-memsource-skill
Open

chore(i18n): add Cursor Memsource skill and peer usage guide#272
avivtur wants to merge 4 commits into
openshift:mainfrom
avivtur:chore/i18n-memsource-skill

Conversation

@avivtur

@avivtur avivtur commented Aug 9, 2026

Copy link
Copy Markdown

Summary

  • Adds a repo-local Cursor skill at .cursor/skills/i18n-memsource/ to automate Phrase/Memsource upload, download, and status checks
  • Keeps the existing i18n-scripts/ + i18next-parser toolchain (no forced migration)
  • Includes USAGE.md with a peer-facing walkthrough
  • Clears English placeholders from PO msgstr after export-pos so Phrase sees them as needing translation

Memsource project (Sprint 1 / OCP 5.0.0)

Uploaded PO files are in Phrase:

https://cloud.memsource.com/web/project2/show/pCBhvWn17QjhlGVQuSYf81

  • Version: 5.0.0
  • Sprint: 1
  • Total keys: 295
  • Also recorded in .cursor/skills/i18n-memsource/state.json for download/status

Why

Peers need a reliable way to send missing translations to Phrase without losing existing locale work. This skill encodes the fragile steps that are easy to miss manually.

Prerequisites to activate / use the skill

The skill only automates the workflow; each developer still needs local tooling and Phrase access:

  1. Cursor with Agent skills enabled, and this repo checked out (including .cursor/skills/i18n-memsource/)
  2. Node.js + npm install in the repo root
  3. jq (brew install jq on macOS)
  4. Memsource / Phrase CLI (memsource-cli via pip), e.g.:
    DIRECTORY="${HOME}/git/memsource-cli-client/"
    mkdir -p "$DIRECTORY" && cd "$DIRECTORY"
    python3 -m venv --system-site-packages .memsource
    source .memsource/bin/activate
    pip install -U pip setuptools pbr memsource-cli
  5. Memsource credentials in ~/.memsourcerc (Red Hat Phrase account with access to the localization template/projects):
    source ${HOME}/git/memsource-cli-client/.memsource/bin/activate
    export MEMSOURCE_URL="https://cloud.memsource.com/web"
    export MEMSOURCE_USERNAME=<your-username>
    export MEMSOURCE_PASSWORD="<your-password>"
    The skill captures MEMSOURCE_TOKEN from memsource auth login so npm run memsource-* works; peers do not need to run login by hand when using the skill.
  6. Permission to create Memsource projects from template ID zBOwr4BxYwEq7xlJ37c1F3 (same template this plugin already uses)

Without (4)–(6), upload/download/status will fail at auth or project creation. Extract/export-only steps (npm run i18n, export-pos) only need (2).

Full one-time setup: .cursor/skills/i18n-memsource/USAGE.md

Critical nuances documented and automated

  1. zh-cnzh symlink before export-pos — without it, Chinese carry-forward is empty on upload
  2. PO consolidation — English keys + merge of existing locales/<lang>/ translations (never hand-build English-only POs)
  3. Clear English placeholders after exporti18n-scripts/clear-english-msgstr.js empties msgstr when it equals msgid (leaked English from i18next-parser defaults). Empty locale values already produce empty msgstr (correct). Real non-English translations are kept.
  4. Download clean check — verify root locales/ (the script checks public/locales, which is wrong here)
  5. Nmstate PO filenamespublic__….po; validation/upload use globs

How peers use it

  1. Open this repo in Cursor
  2. Attach / invoke the i18n-memsource skill
  3. Say e.g. upload translations and provide the OCP VERSION when asked
  4. Review the locale diff + PO validation (translated vs needs_translation; English leaks should be 0), then approve the Memsource upload

Follow-up suggestion: migrate to ocp-plugin-i18n-scripts

This PR deliberately keeps the local i18n-scripts/ setup. A worthwhile follow-up is migrating to ocp-plugin-i18n-scripts (as Forklift does).

That package already filters English placeholders during PO generation (translatedValue !== englishValue && translatedValue !== key). After such a migration:

  • clear-english-msgstr.js / the post-export-pos clear step becomes redundant and should be removed
  • Language aliases (zh-cnzh) and other upload quirks are handled by config instead of symlinks/workarounds

This PR’s clear step is the minimal fix while staying on the old scripts.

Test plan

  • Open .cursor/skills/i18n-memsource/USAGE.md and confirm the peer steps / prerequisites are clear
  • With Memsource credentials configured, confirm memsource auth whoami works
  • npm installln -sfn zh locales/zh-cnnpm run export-pos → confirm console reports cleared English placeholders
  • Validate POs: real translations kept, msgstr == msgid count is 0, former English placeholders are empty
  • Confirm Chinese PO still has non-empty msgstr for previously translated keys when the symlink is present
  • Optional: full upload only when intentionally sending a sprint to localization

Summary by CodeRabbit

  • New Features

    • Added a documented workflow for uploading, downloading, and checking translation status through Memsource.
    • Added guidance for locale management, authentication, PO files, validation, and translation preservation.
    • Added persisted translation workflow state and history tracking.
  • Bug Fixes

    • Automatically clears English placeholders from untranslated PO entries after locale exports.
    • Preserves translation headers and completed translations while updating only affected entries.

Add a repo-local Cursor skill that automates Phrase/Memsource upload and
download while keeping the existing i18n-scripts + i18next-parser setup.
Includes USAGE.md with the zh-cn symlink nuance and carry-forward PO flow.

Co-authored-by: Cursor <cursoragent@cursor.com>
@openshift-ci
openshift-ci Bot requested review from batyana and lkladnit August 9, 2026 05:48
@openshift-ci

openshift-ci Bot commented Aug 9, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: avivtur

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 9, 2026
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Walkthrough

Adds the i18n-memsource workflow skill. It documents setup, authentication, locale handling, upload and download procedures, validation, notifications, and persisted workflow state. It also adds English-placeholder cleanup for exported PO files.

Changes

Memsource localization workflow

Layer / File(s) Summary
Workflow configuration and operating procedures
.cursor/skills/i18n-memsource/SKILL.md, .cursor/skills/i18n-memsource/USAGE.md
Defines Memsource configuration, locale conventions, authentication, state handling, upload, download, status checks, and notification steps.
PO generation and placeholder validation
.cursor/skills/i18n-memsource/SKILL.md, .cursor/skills/i18n-memsource/USAGE.md, i18n-scripts/clear-english-msgstr.js, i18n-scripts/export-pos.sh
Documents PO generation and validation rules. Clears msgstr values that match non-empty msgid values after export.
Persisted localization state
.cursor/skills/i18n-memsource/state.json
Records the project metadata and upload history for version 5.0.0 and sprint 1.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: lkladnit, batyana

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a Cursor Memsource skill and peer usage guide for the i18n workflow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed The complete PR adds only documentation, state, and i18n scripts; searches found no Ginkgo It/Describe/Context/When test declarations or dynamic test titles.
Test Structure And Quality ✅ Passed The PR changes only documentation and i18n scripts; repository searches found no Ginkgo imports, Go tests, It/BeforeEach/AfterEach, or Eventually/Consistently calls.
Microshift Test Compatibility ✅ Passed The pull request adds no Ginkgo e2e tests or Go test files; it changes only documentation and an i18n JavaScript script, so MicroShift test compatibility is not applicable.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The PR adds only documentation and i18n scripts; the full origin/main...HEAD diff contains no Ginkgo constructs, Go files, or e2e test paths.
Topology-Aware Scheduling Compatibility ✅ Passed The patch changes only two Markdown skill documents and one PO-processing JavaScript file; no deployment manifests, controllers, operators, or scheduling constraints were added or modified.
Ote Binary Stdout Contract ✅ Passed The PR adds JavaScript, shell, Markdown, and JSON i18n files; the repository has no Go files or OTE suite/binary code, so this check is not applicable.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The PR adds only documentation, JSON, and i18n scripts; no Ginkgo e2e tests or IPv4/external-network test code were added.
No-Weak-Crypto ✅ Passed PR files and referenced scripts contain no MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB, crypto API, or secret comparison; the only equality check is msgstr === msgid.
Container-Privileges ✅ Passed The PR changes only documentation and i18n scripts; no container/K8s manifest adds privileged, host namespace, SYS_ADMIN, or allowPrivilegeEscalation settings.
No-Sensitive-Data-In-Logs ✅ Passed Added logging prints only PO paths, counts, locale names, and project identifiers; no password, token, API key, email, session ID, hostname, or customer data is logged.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.cursor/skills/i18n-memsource/SKILL.md:
- Around line 301-315: The memsource download auto-commits before the PR branch
is created; update .cursor/skills/i18n-memsource/SKILL.md lines 301-315 and
.cursor/skills/i18n-memsource/USAGE.md lines 152-165 to create or switch to
chore/i18n-update-sprint-${SPRINT} before invoking npm run memsource-download,
or otherwise enable a no-commit mode.
- Line 127: Update the four fenced blocks to include the text language tag:
.cursor/skills/i18n-memsource/SKILL.md lines 127-127, 234-234, and 261-261, plus
.cursor/skills/i18n-memsource/USAGE.md lines 199-199.
- Around line 174-182: Update i18n-scripts/memsource-upload.sh and the Step 9
workflow so uploads are resumable: persist or emit the remote project ID
immediately, install a cleanup trap for failures, and resume or delete any
in-flight project before retrying. Only remove local artifacts and update state
after the upload completes successfully, while preserving the stable project
result for callers.
- Around line 186-213: Update Step 7’s PO validation gate to parse multiline PO
entries, including continuation lines, while excluding the msgid "" header from
key counts. Make validation fail for missing files, parse errors, or any nonzero
english_leaks, and require an explicitly recorded override before allowing
exceptions. Ensure rg failures are not silently converted to zero, then present
validation results and request approval only after the gate passes.
- Around line 54-59: Replace the password-based Memsource authentication
snippets with an API token or credential flow that never passes the raw password
through command-line arguments. Update both
.cursor/skills/i18n-memsource/SKILL.md lines 54-59 and
.cursor/skills/i18n-memsource/USAGE.md lines 88-96, preserving the existing
token export behavior while removing the --password "$MEMSOURCE_PASSWORD" usage.

In @.cursor/skills/i18n-memsource/USAGE.md:
- Around line 98-108: Update the manual command examples around npm run
memsource-upload and the related commands to use explicitly defined VERSION,
SPRINT, and PROJECT_ID inputs instead of hard-coded 4.20, 1, or the literal
PROJECT_ID token. Ensure the documented variables are assigned or clearly marked
as required placeholders before use, and apply this consistently through the
sections covering the referenced commands.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f97cecb8-6f1a-432e-8588-a16467430647

📥 Commits

Reviewing files that changed from the base of the PR and between 5d05b77 and 097f986.

📒 Files selected for processing (3)
  • .cursor/skills/i18n-memsource/SKILL.md
  • .cursor/skills/i18n-memsource/USAGE.md
  • .cursor/skills/i18n-memsource/state.json

Comment thread .cursor/skills/i18n-memsource/SKILL.md Outdated
Comment thread .cursor/skills/i18n-memsource/SKILL.md Outdated
Comment thread .cursor/skills/i18n-memsource/SKILL.md Outdated
Comment thread .cursor/skills/i18n-memsource/SKILL.md Outdated
Comment thread .cursor/skills/i18n-memsource/SKILL.md
Comment thread .cursor/skills/i18n-memsource/USAGE.md Outdated
avivtur and others added 2 commits August 9, 2026 09:17
Add clear-english-msgstr.js and run it at the end of export-pos so msgstr
values that still equal msgid are emptied before Phrase upload. Update the
Memsource skill/USAGE docs accordingly.

Co-authored-by: Cursor <cursoragent@cursor.com>
Store lastProjectId and URL from the OCP 5.0.0 / Sprint 1 Phrase upload
so download/status can reuse it.

Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@i18n-scripts/clear-english-msgstr.js`:
- Line 18: Update processPoFile to process only regular files and canonicalize
each candidate path before writing, rejecting symlinks or paths whose resolved
location is outside PO_ROOT. Preserve processing for regular .po files contained
within the canonicalized PO_ROOT.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3727ebe9-34b4-477a-8b77-9f53cb89adcf

📥 Commits

Reviewing files that changed from the base of the PR and between 097f986 and 99c0f3b.

📒 Files selected for processing (5)
  • .cursor/skills/i18n-memsource/SKILL.md
  • .cursor/skills/i18n-memsource/USAGE.md
  • .cursor/skills/i18n-memsource/state.json
  • i18n-scripts/clear-english-msgstr.js
  • i18n-scripts/export-pos.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • .cursor/skills/i18n-memsource/USAGE.md

Comment thread i18n-scripts/clear-english-msgstr.js
Keep Memsource credentials user-owned, harden clear-english path
handling, and align download/manual upload docs with networking skill.

Resolves: None
Signed-off-by: Aviv Turgeman <aturgema@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
i18n-scripts/clear-english-msgstr.js (1)

30-48: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Use the same complete-entry PO parser for both script and docs.

clear-english-msgstr.js and the USAGE.md validation regex only match single-line msgid/msgstr pairs. Use one complete-entry PO parser in both code paths so escaped strings, continued string fragments, and msgstr[n] plurals are handled consistently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@i18n-scripts/clear-english-msgstr.js` around lines 30 - 48, The single-line
regex in clearEnglishPlaceholders only handles simple msgid/msgstr pairs, while
the documented validation uses a separate parser. Replace both
i18n-scripts/clear-english-msgstr.js:30-48 and
.cursor/skills/i18n-memsource/USAGE.md:123-132 with the same complete-entry PO
parsing logic, covering escaped strings, continued fragments, and msgstr[n]
plural entries while preserving header exclusion and English-placeholder
clearing behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.cursor/skills/i18n-memsource/SKILL.md:
- Line 32: Align the PO filename guidance in the i18n-memsource instructions:
replace the hard-coded plugin__nmstate-console-plugin.po pattern with
po-files/<lang>/*.po, and update the related guidance around the basename rule
so both locations consistently avoid hard-coded PO basenames unless the verified
generated basename is documented in both places.
- Around line 332-337: Update the download workflow around the branch creation
and memsource-download commands to load SPRINT from state or prompt the user
before constructing the branch name. Check whether
chore/i18n-update-sprint-${SPRINT} already exists, switching to it when present
and creating it only when absent, then run the existing download command.
- Around line 83-89: The upload workflow around the Step 5 symlink and EXIT trap
must keep cleanup active through the Step 8 export-pos and memsource-upload
operations. Consolidate symlink creation, validation, export-pos, and upload
into one wrapper shell, or add explicit cleanup that runs after upload success
or failure; ensure locales/zh-cn remains available until export-pos has
completed.

In @.cursor/skills/i18n-memsource/USAGE.md:
- Around line 75-76: Update the credential guidance near the MEMSOURCE_TOKEN
instructions to prohibit exporting the token into any agent-controlled shell,
including short-lived tokens. State that authenticated Memsource commands must
be run only in the user's terminal, and remove wording that permits temporary
shell export.
- Line 234: Update the locale verification command near the documented push
workflow to use git diff HEAD~1 -- locales/ instead of the --stat variant, so
the full locale content is reviewed before the push step on the following line.

---

Nitpick comments:
In `@i18n-scripts/clear-english-msgstr.js`:
- Around line 30-48: The single-line regex in clearEnglishPlaceholders only
handles simple msgid/msgstr pairs, while the documented validation uses a
separate parser. Replace both i18n-scripts/clear-english-msgstr.js:30-48 and
.cursor/skills/i18n-memsource/USAGE.md:123-132 with the same complete-entry PO
parsing logic, covering escaped strings, continued fragments, and msgstr[n]
plural entries while preserving header exclusion and English-placeholder
clearing behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 28ac8e18-53b6-4fd3-b3bf-c61c3dddfad7

📥 Commits

Reviewing files that changed from the base of the PR and between 99c0f3b and fc15194.

📒 Files selected for processing (3)
  • .cursor/skills/i18n-memsource/SKILL.md
  • .cursor/skills/i18n-memsource/USAGE.md
  • i18n-scripts/clear-english-msgstr.js

| Project title | `[OCP $VERSION] UI Localization nmstate-console-plugin - Sprint $SPRINT/Branch $BRANCH` |
| Languages | `ja`, `zh-cn`, `ko`, `fr`, `es` |
| Locale dirs on disk | `en`, `es`, `fr`, `ja`, `ko`, **`zh`** (not `zh-cn`) |
| PO filename pattern | `po-files/<lang>/plugin__nmstate-console-plugin.po` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use one PO filename contract.

Line [32] documents plugin__nmstate-console-plugin.po. Line [382] says that PO basenames must not be hard-coded because this repository uses a public__ prefix. These instructions conflict.

Use po-files/<lang>/*.po in the configuration, or document the verified generated basename in both locations.

Proposed documentation fix
-| PO filename pattern | `po-files/<lang>/plugin__nmstate-console-plugin.po` |
+| PO filename pattern | `po-files/<lang>/*.po` |

Also applies to: 382-382

🧰 Tools
🪛 SkillSpector (2.5.1)

[warning] 149: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.cursor/skills/i18n-memsource/SKILL.md at line 32, Align the PO filename
guidance in the i18n-memsource instructions: replace the hard-coded
plugin__nmstate-console-plugin.po pattern with po-files/<lang>/*.po, and update
the related guidance around the basename rule so both locations consistently
avoid hard-coded PO basenames unless the verified generated basename is
documented in both places.

Comment on lines +83 to +89
**Before any `export-pos` during upload**, create the symlink and register
unconditional cleanup (also on failure / cancel):

```bash
ln -sfn zh locales/zh-cn
trap 'rm -f locales/zh-cn; rm -rf po-files locales/tmp' EXIT
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

tmp=$(mktemp -d)
mkdir -p "$tmp/locales"
(
  ln -s zh "$tmp/locales/zh-cn"
  trap 'rm -f "$tmp/locales/zh-cn"' EXIT
)
test ! -e "$tmp/locales/zh-cn"
echo "A separate shell removes the symlink before the next workflow step."

Repository: openshift/nmstate-console-plugin

Length of output: 238


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Tracked skill file exists:\n'
ls -l .cursor/skills/i18n-memsource/SKILL.md

printf '\nRelevant upload section (lines 60-115):\n'
sed -n '60,115p' .cursor/skills/i18n-memsource/SKILL.md | cat -n -v

printf '\nCleanup/export-pos references around lines 180-215:\n'
sed -n '180,215p' .cursor/skills/i18n-memsource/SKILL.md | cat -n -v

printf '\nAll export-pos / cleanup mentions in file:\n'
rg -n 'export-pos|rm -f|trap|locales/zh-cn|cleanup|po-files|locales/tmp' .cursor/skills/i18n-memsource/SKILL.md

Repository: openshift/nmstate-console-plugin

Length of output: 4996


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Upload workflow section (lines 170-330):\n'
sed -n '170,330p' .cursor/skills/i18n-memsource/SKILL.md | nl -ba

printf '\nCommand block formatting around upload steps:\n'
rg -n '^<{3}bash|^```(bash)?|### Step 5|### Step 6|### Step 7|### Step 8|export-pos|cleanup|rm -f|rm -rf' .cursor/skills/i18n-memsource/SKILL.md

Repository: openshift/nmstate-console-plugin

Length of output: 251


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Upload workflow section (lines 170-330):\n'
sed -n '170,330p' .cursor/skills/i18n-memsource/SKILL.md | awk '{printf "%6d\t%s\n", NR+169, $0}'

printf '\nCommand block references in upload workflow:\n'
rg -n '^<\|bash|<\|bash|^```(bash)?|### Step 5|### Step 6|### Step 7|### Step 8|export-pos|cleanup|rm -f|rm -rf' .cursor/skills/i18n-memsource/SKILL.md

Repository: openshift/nmstate-console-plugin

Length of output: 7319


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path('.cursor/skills/i18n-memsource/SKILL.md')
s = p.read_text()
steps = [i for i, line in enumerate(s.splitlines(), 1) if "### Step " in line]
print("Step headings:", steps)
for start in steps:
    line = s.splitlines()[start-1]
    raw = line.replace('###', '').replace(':', '').strip()
    print(f"{start}: {raw}")

print("\nFenced bash block starts:")
for i, line in enumerate(s.splitlines(), 1):
    if line.startswith("```bash"):
        print(i)

print("\nTrap command starts:")
for i, line in enumerate(s.splitlines(), 1):
    if line.startswith("trap "):
        print(f"{i}: {line}")
PY

Repository: openshift/nmstate-console-plugin

Length of output: 1000


Ensure the upload cleanup trap survives until Step 8.

The EXIT trap is installed in Step 5, but export-pos runs in a separate fenced command block before memsource-upload. If each block is a separate shell, the trap exits and deletes locales/zh-cn before the upload re-runs export-pos, so Chinese translations can be dropped from the generated POs. Keep the install and cleanup in one wrapper script that also runs validation and upload, or use an explicit cleanup step after the upload succeeds or fails.

🧰 Tools
🪛 SkillSpector (2.5.1)

[warning] 149: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.cursor/skills/i18n-memsource/SKILL.md around lines 83 - 89, The upload
workflow around the Step 5 symlink and EXIT trap must keep cleanup active
through the Step 8 export-pos and memsource-upload operations. Consolidate
symlink creation, validation, export-pos, and upload into one wrapper shell, or
add explicit cleanup that runs after upload success or failure; ensure
locales/zh-cn remains available until export-pos has completed.

Comment on lines +332 to +337
Create/switch to the PR branch **before** download (the script auto-commits):

```bash
git checkout -b "chore/i18n-update-sprint-${SPRINT}"
npm run memsource-download -- -p "$PROJECT_ID"
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Define SPRINT before creating the download branch.

The download workflow confirms PROJECT_ID, but it never loads or asks for SPRINT. Line [335] therefore creates chore/i18n-update-sprint-, or fails when the shell uses set -u. git checkout -b also fails when the branch already exists.

Load SPRINT from state or request it from the user. Then switch to the existing branch or create it when absent.

Proposed workflow fix
+SPRINT=$(jq -er '.sprint' .cursor/skills/i18n-memsource/state.json)
+BRANCH="chore/i18n-update-sprint-${SPRINT}"
+
+if git show-ref --verify --quiet "refs/heads/${BRANCH}"; then
+  git switch "$BRANCH"
+else
+  git switch -c "$BRANCH"
+fi
+
-git checkout -b "chore/i18n-update-sprint-${SPRINT}"
 npm run memsource-download -- -p "$PROJECT_ID"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Create/switch to the PR branch **before** download (the script auto-commits):
```bash
git checkout -b "chore/i18n-update-sprint-${SPRINT}"
npm run memsource-download -- -p "$PROJECT_ID"
```
Create/switch to the PR branch **before** download (the script auto-commits):
🧰 Tools
🪛 SkillSpector (2.5.1)

[warning] 149: [RA2] Session Persistence: Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Remediation: Remove any persistence mechanisms (cron jobs, startup scripts, state files). Skills should not maintain state across sessions without explicit user consent.

(Rogue Agent (RA2))

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.cursor/skills/i18n-memsource/SKILL.md around lines 332 - 337, Update the
download workflow around the branch creation and memsource-download commands to
load SPRINT from state or prompt the user before constructing the branch name.
Check whether chore/i18n-update-sprint-${SPRINT} already exists, switching to it
when present and creating it only when absent, then run the existing download
command.

Comment on lines +75 to +76
If you temporarily export `MEMSOURCE_TOKEN` into a shell the agent uses, prefer
a short-lived token and do not commit it or paste it into chat.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Keep MEMSOURCE_TOKEN out of the agent shell.

A short-lived token is still a credential. An agent-controlled shell can read the environment and expose the token through a command or diagnostic. Run authenticated Memsource commands only in the user's terminal.

Suggested change
-If you temporarily export `MEMSOURCE_TOKEN` into a shell the agent uses, prefer
-a short-lived token and do not commit it or paste it into chat.
+Do not export `MEMSOURCE_TOKEN` into a shell used by the agent.
+Run authenticated Memsource commands in your own terminal.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
If you temporarily export `MEMSOURCE_TOKEN` into a shell the agent uses, prefer
a short-lived token and do not commit it or paste it into chat.
Do not export `MEMSOURCE_TOKEN` into a shell used by the agent.
Run authenticated Memsource commands in your own terminal.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.cursor/skills/i18n-memsource/USAGE.md around lines 75 - 76, Update the
credential guidance near the MEMSOURCE_TOKEN instructions to prohibit exporting
the token into any agent-controlled shell, including short-lived tokens. State
that authenticated Memsource commands must be run only in the user's terminal,
and remove wording that permits temporary shell export.

git checkout -b "chore/i18n-update-sprint-${SPRINT}"

npm run memsource-download -- -p "$PROJECT_ID"
git diff HEAD~1 --stat -- locales/

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Show the full locale diff before pushing.

Line 234 reports only file and line counts. It cannot reveal incorrect locale mapping, English leakage, or unintended translations. Replace it with git diff HEAD~1 -- locales/ and review the content before Line 235 pushes the branch.

Suggested change
-git diff HEAD~1 --stat -- locales/
+git diff HEAD~1 -- locales/
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
git diff HEAD~1 --stat -- locales/
git diff HEAD~1 -- locales/
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.cursor/skills/i18n-memsource/USAGE.md at line 234, Update the locale
verification command near the documented push workflow to use git diff HEAD~1 --
locales/ instead of the --stat variant, so the full locale content is reviewed
before the push step on the following line.

@openshift-ci

openshift-ci Bot commented Aug 10, 2026

Copy link
Copy Markdown

@avivtur: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant