From a0aa460191e0accef782dffa22a5442f31b34709 Mon Sep 17 00:00:00 2001 From: XiangqianHuang <2332671@stu.zyufl.edu.cn> Date: Sat, 17 Jan 2026 15:41:06 +0800 Subject: [PATCH 1/4] feat: add Kiro AI programming tool support - Add detectKiroCandidates() function for auto-detecting Kiro config paths - Add Kiro configuration paths for macOS, Linux, and Windows - Update detectAndFillTemplatePaths() to include Kiro detection - Update protoInit() to display Kiro detection status - Add Kiro to default config template with empty prefix Kiro config file paths: - macOS: ~/.kiro/cueme_proto.md - Linux: ~/.config/kiro/cueme_proto.md - Windows: %USERPROFILE%\.kiro\cueme_proto.md --- src/proto.js | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/proto.js b/src/proto.js index c0556a9..4553f0a 100644 --- a/src/proto.js +++ b/src/proto.js @@ -91,6 +91,25 @@ function detectWindsurfCandidates({ platform }) { return candidates; } +function detectKiroCandidates({ platform }) { + const candidates = []; + const cwd = process.cwd(); + + // Workspace-level (repo-local) + candidates.push(path.join(cwd, '.kiro', 'cueme_proto.md')); + + // User-level (standard) + const home = os.homedir(); + const userProfile = process.env.USERPROFILE || home; + if (platform === 'macos') candidates.push(path.join(home, '.kiro', 'cueme_proto.md')); + if (platform === 'linux') candidates.push(path.join(home, '.config', 'kiro', 'cueme_proto.md')); + if (platform === 'windows') { + candidates.push(path.join(userProfile, '.kiro', 'cueme_proto.md')); + } + + return candidates; +} + function firstExistingPath(candidates) { for (const p of candidates) { if (typeof p === 'string' && p.trim().length > 0 && pathExists(p)) return p; @@ -125,6 +144,11 @@ function defaultPathMapTemplate() { out['windows.windsurf'] = path.join(userProfile, '.codeium', 'windsurf', 'memories', 'global_rules.md'); out['linux.windsurf'] = path.join(home, '.codeium', 'windsurf', 'memories', 'global_rules.md'); + // Kiro + out['macos.kiro'] = path.join(home, '.kiro', 'cueme_proto.md'); + out['windows.kiro'] = path.join(userProfile, '.kiro', 'cueme_proto.md'); + out['linux.kiro'] = path.join(home, '.config', 'kiro', 'cueme_proto.md'); + return out; } @@ -135,6 +159,7 @@ function defaultConfigTemplate() { 'cueme.proto.prefix': { windsurf: [], vscode: ['---', 'applyTo: "**"', '---'], + kiro: [], }, 'cueme.proto.protocol_path': protocolPath, }; @@ -144,9 +169,10 @@ function detectAndFillTemplatePaths(tpl) { const platform = getPlatformKey(); const keyVscode = `${platform}.vscode`; const keyWindsurf = `${platform}.windsurf`; + const keyKiro = `${platform}.kiro`; const pathMap = tpl['cueme.proto.path'] || {}; - const detected = { platform, vscode: '', windsurf: '' }; + const detected = { platform, vscode: '', windsurf: '', kiro: '' }; if (typeof pathMap !== 'object' || Array.isArray(pathMap)) { return { tpl, detected }; @@ -169,6 +195,14 @@ function detectAndFillTemplatePaths(tpl) { } } + if (typeof pathMap[keyKiro] !== 'string' || pathMap[keyKiro].trim().length === 0) { + const p = firstExistingPath(detectKiroCandidates({ platform })); + if (p) { + pathMap[keyKiro] = p; + detected.kiro = p; + } + } + tpl['cueme.proto.path'] = pathMap; return { tpl, detected }; } @@ -374,9 +408,11 @@ function protoInit() { const platform = detected && detected.platform ? detected.platform : getPlatformKey(); const keyVscode = `${platform}.vscode`; const keyWindsurf = `${platform}.windsurf`; + const keyKiro = `${platform}.kiro`; const vs = detected && detected.vscode ? 'detected' : 'empty'; const ws = detected && detected.windsurf ? 'detected' : 'empty'; - return `ok: initialized ${p} (auto-detect: ${keyVscode}=${vs}, ${keyWindsurf}=${ws})`; + const ks = detected && detected.kiro ? 'detected' : 'empty'; + return `ok: initialized ${p} (auto-detect: ${keyVscode}=${vs}, ${keyWindsurf}=${ws}, ${keyKiro}=${ks})`; } module.exports = { From a4754034bb0d244f99e7b30dc1717d7f629bb10d Mon Sep 17 00:00:00 2001 From: XiangqianHuang <2332671@stu.zyufl.edu.cn> Date: Sat, 17 Jan 2026 16:16:23 +0800 Subject: [PATCH 2/4] refactor: improve repo-local detection and add CI workflow Address code review feedback: 1. Improve repo-local detection logic: - Add findGitRoot() helper to locate Git repository root - Update detectKiroCandidates() to use Git root instead of cwd - Prevents false positives when running cueme outside repo root 2. Add GitHub Actions CI workflow: - Run on push to main and all pull requests - Test on Node.js 20.x and 22.x - Perform syntax checks on all JS files - Verify proto.js exports are correct This ensures code quality and provides automated checks for PRs. --- .github/workflows/ci.yml | 45 ++++++++++++++++++++++++++++++++++++++++ src/proto.js | 25 ++++++++++++++++++---- 2 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b40026c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,45 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + lint-and-test: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20.x, 22.x] + + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Run syntax check + run: npm run prepare + + - name: Check for syntax errors in all JS files + run: | + for file in $(find src bin -name "*.js"); do + echo "Checking $file..." + node -c "$file" + done + + - name: Verify proto.js exports + run: | + node -e "const proto = require('./src/proto.js'); \ + console.log('Exported functions:', Object.keys(proto)); \ + if (!proto.protoApply || !proto.protoInit) { \ + throw new Error('Missing required exports'); \ + }" diff --git a/src/proto.js b/src/proto.js index 4553f0a..9d910ef 100644 --- a/src/proto.js +++ b/src/proto.js @@ -46,6 +46,21 @@ function pathExists(p) { } } +function findGitRoot(startDir) { + let current = startDir || process.cwd(); + const root = path.parse(current).root; + + while (current !== root) { + const gitPath = path.join(current, '.git'); + if (pathExists(gitPath)) { + return current; + } + current = path.dirname(current); + } + + return null; +} + function detectVscodeCandidates({ platform }) { const candidates = []; const cwd = process.cwd(); @@ -93,10 +108,12 @@ function detectWindsurfCandidates({ platform }) { function detectKiroCandidates({ platform }) { const candidates = []; - const cwd = process.cwd(); - - // Workspace-level (repo-local) - candidates.push(path.join(cwd, '.kiro', 'cueme_proto.md')); + + // Workspace-level (repo-local): only check if we're in a git repo + const gitRoot = findGitRoot(); + if (gitRoot) { + candidates.push(path.join(gitRoot, '.kiro', 'cueme_proto.md')); + } // User-level (standard) const home = os.homedir(); From 154e3ca38d8d20863acd124aa167bce3e30e4bfa Mon Sep 17 00:00:00 2001 From: XiangqianHuang <2332671@stu.zyufl.edu.cn> Date: Sat, 17 Jan 2026 16:34:58 +0800 Subject: [PATCH 3/4] refactor: simplify Kiro config to user-level only Address code review feedback: - Remove findGitRoot() helper function - Remove repo-local detection from detectKiroCandidates() - Keep only user-level configuration paths: * macOS: ~/.kiro/cueme_proto.md * Linux: ~/.config/kiro/cueme_proto.md * Windows: %USERPROFILE%\.kiro\cueme_proto.md Rationale: cueme's role is to update user/tool config. Per-repo Kiro config would introduce unnecessary complexity and semantic confusion. Keeping configuration strictly at user-level simplifies the design. --- src/proto.js | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/src/proto.js b/src/proto.js index 9d910ef..44af90d 100644 --- a/src/proto.js +++ b/src/proto.js @@ -46,21 +46,6 @@ function pathExists(p) { } } -function findGitRoot(startDir) { - let current = startDir || process.cwd(); - const root = path.parse(current).root; - - while (current !== root) { - const gitPath = path.join(current, '.git'); - if (pathExists(gitPath)) { - return current; - } - current = path.dirname(current); - } - - return null; -} - function detectVscodeCandidates({ platform }) { const candidates = []; const cwd = process.cwd(); @@ -108,16 +93,10 @@ function detectWindsurfCandidates({ platform }) { function detectKiroCandidates({ platform }) { const candidates = []; - - // Workspace-level (repo-local): only check if we're in a git repo - const gitRoot = findGitRoot(); - if (gitRoot) { - candidates.push(path.join(gitRoot, '.kiro', 'cueme_proto.md')); - } - - // User-level (standard) const home = os.homedir(); const userProfile = process.env.USERPROFILE || home; + + // User-level only (no repo-local detection for Kiro) if (platform === 'macos') candidates.push(path.join(home, '.kiro', 'cueme_proto.md')); if (platform === 'linux') candidates.push(path.join(home, '.config', 'kiro', 'cueme_proto.md')); if (platform === 'windows') { From 804068b14ef19bcc835c1d489e7b451c62e19745 Mon Sep 17 00:00:00 2001 From: XiangqianHuang <2332671@stu.zyufl.edu.cn> Date: Sat, 17 Jan 2026 16:45:15 +0800 Subject: [PATCH 4/4] fix: correct Kiro config path to use steering directory Fix incorrect Kiro configuration file paths based on official documentation. Changes: - Update all Kiro paths to use ~/.kiro/steering/ directory - macOS: ~/.kiro/steering/cueme_proto.md - Linux: ~/.kiro/steering/cueme_proto.md - Windows: %USERPROFILE%\.kiro\steering\cueme_proto.md Rationale: Kiro uses the steering directory structure for global steering files, not a flat config directory. The steering directory is where Kiro automatically loads markdown files for project context. References: - https://kiro.dev/docs/cli/steering/ - Global steering location: ~/.kiro/steering/ --- src/proto.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/proto.js b/src/proto.js index 44af90d..aaeefd2 100644 --- a/src/proto.js +++ b/src/proto.js @@ -97,10 +97,11 @@ function detectKiroCandidates({ platform }) { const userProfile = process.env.USERPROFILE || home; // User-level only (no repo-local detection for Kiro) - if (platform === 'macos') candidates.push(path.join(home, '.kiro', 'cueme_proto.md')); - if (platform === 'linux') candidates.push(path.join(home, '.config', 'kiro', 'cueme_proto.md')); + // Kiro uses ~/.kiro/steering/ directory for global steering files + if (platform === 'macos') candidates.push(path.join(home, '.kiro', 'steering', 'cueme_proto.md')); + if (platform === 'linux') candidates.push(path.join(home, '.kiro', 'steering', 'cueme_proto.md')); if (platform === 'windows') { - candidates.push(path.join(userProfile, '.kiro', 'cueme_proto.md')); + candidates.push(path.join(userProfile, '.kiro', 'steering', 'cueme_proto.md')); } return candidates; @@ -141,9 +142,9 @@ function defaultPathMapTemplate() { out['linux.windsurf'] = path.join(home, '.codeium', 'windsurf', 'memories', 'global_rules.md'); // Kiro - out['macos.kiro'] = path.join(home, '.kiro', 'cueme_proto.md'); - out['windows.kiro'] = path.join(userProfile, '.kiro', 'cueme_proto.md'); - out['linux.kiro'] = path.join(home, '.config', 'kiro', 'cueme_proto.md'); + out['macos.kiro'] = path.join(home, '.kiro', 'steering', 'cueme_proto.md'); + out['windows.kiro'] = path.join(userProfile, '.kiro', 'steering', 'cueme_proto.md'); + out['linux.kiro'] = path.join(home, '.kiro', 'steering', 'cueme_proto.md'); return out; }