cueme 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,85 @@
1
+ # How to submit a PR
2
+
3
+ ## 1. Prerequisites
4
+
5
+ - Make sure you have write access to the repository (or submit a PR from a fork).
6
+ - Use Node.js locally (recommended to match `package.json` `engines`).
7
+
8
+ ## 2. Update `main` and create a branch
9
+
10
+ - Pull the latest `main`.
11
+ - Create a new branch (recommended naming):
12
+ - `feature/<short-desc>`
13
+ - `fix/<short-desc>`
14
+ - `chore/<short-desc>`
15
+
16
+ ## 3. Development and local checks
17
+
18
+ - Make your changes.
19
+ - Run minimal local checks:
20
+ - `npm ci`
21
+ - `npm run prepare`
22
+ - Optional: run a quick manual validation relevant to your change.
23
+
24
+ ## 4. Commit conventions
25
+
26
+ - Recommended commit message prefixes:
27
+ - `feat: ...`
28
+ - `fix: ...`
29
+ - `refactor: ...`
30
+ - `chore: ...`
31
+
32
+ - Keep the PR focused: ideally one PR addresses one category of change.
33
+
34
+ ## 5. Push your branch and create a PR (recommended: gh)
35
+
36
+ - Push your branch:
37
+ - `git push -u origin <your-branch>`
38
+
39
+ - Create the PR:
40
+ - `gh pr create -R nmhjklnm/cue-command`
41
+
42
+ - Suggested PR description:
43
+ - Why (motivation)
44
+ - What (changes)
45
+ - How to test
46
+ - Risks / impact
47
+
48
+ ## 6. CI and review
49
+
50
+ - Ensure all PR checks pass (CI runs on PRs).
51
+ - Address review feedback by pushing additional commits.
52
+
53
+ ## 7. Merge policy
54
+
55
+ - This repository uses a ruleset: only `squash` / `rebase` merges are allowed.
56
+ - Generally, **squash merge** is recommended to keep `main` history clean.
57
+
58
+ ## 8. Post-merge
59
+
60
+ - After merging, confirm `main` CI runs and succeeds.
61
+ - If a release is required, follow the repository release process.
62
+
63
+ ## 9. Common pitfalls
64
+
65
+ - **CI did not run**
66
+ - Confirm your PR targets `main`, and check workflow triggers (`pull_request` / `push` branch filters).
67
+ - Use `gh pr checks <PR_NUMBER> -R nmhjklnm/cue-command` to see if checks are present.
68
+
69
+ - **CI fails (works locally but fails in CI)**
70
+ - Prefer `npm ci` (depends on the lockfile) and keep `package-lock.json` in sync with `package.json`.
71
+ - Use `gh run view <RUN_ID> -R nmhjklnm/cue-command` to inspect the failing step.
72
+
73
+ - **Merge button disabled / merge method rejected**
74
+ - The ruleset allows only `squash` / `rebase`; merge commits are not allowed.
75
+ - Selecting a disallowed merge method in the UI will be blocked by the rules.
76
+
77
+ - **Conflicts / need to sync with `main`**
78
+ - Update your branch with the latest `main` (rebase or merge per team preference).
79
+ - After resolving conflicts, push again and CI will rerun.
80
+
81
+ - **Useful gh commands**
82
+ - View PR: `gh pr view <PR_NUMBER> -R nmhjklnm/cue-command`
83
+ - View diff: `gh pr diff <PR_NUMBER> -R nmhjklnm/cue-command`
84
+ - View checks: `gh pr checks <PR_NUMBER> -R nmhjklnm/cue-command`
85
+ - List main runs: `gh run list -R nmhjklnm/cue-command --branch main`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cueme",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "Cue command protocol adapter (stdin/stdout JSON)",
5
5
  "license": "Apache-2.0",
6
6
  "files": [
package/src/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const { readAllStdin } = require('./io');
2
2
  const { handleCommand } = require('./handler');
3
3
  const { parseTagBlocksEnvelope } = require('./envelope');
4
- const { protoApply, protoInit, protoLs, protoPath, protoRender } = require('./proto');
4
+ const { protoApply, protoRemove, protoInit, protoLs, protoPath, protoRender } = require('./proto');
5
5
  const pkg = require('../package.json');
6
6
  const fs = require('fs');
7
7
  const path = require('path');
@@ -99,6 +99,7 @@ async function main() {
99
99
  ' cueme -p|--protocol',
100
100
  ' cueme proto <agent>',
101
101
  ' cueme proto apply <agent>',
102
+ ' cueme proto rm|remove <agent>',
102
103
  ' cueme proto init',
103
104
  ' cueme proto ls',
104
105
  ' cueme proto path <agent>',
@@ -258,6 +259,17 @@ async function main() {
258
259
  return;
259
260
  }
260
261
 
262
+ if (action === 'rm' || action === 'remove') {
263
+ const agent = pos[1];
264
+ if (!agent) {
265
+ process.stderr.write('error: missing <agent>\n');
266
+ process.exitCode = 2;
267
+ return;
268
+ }
269
+ process.stdout.write(protoRemove(String(agent)) + '\n');
270
+ return;
271
+ }
272
+
261
273
  if (action === 'path') {
262
274
  const agent = pos[1];
263
275
  if (!agent) {
package/src/proto.js CHANGED
@@ -91,6 +91,22 @@ function detectWindsurfCandidates({ platform }) {
91
91
  return candidates;
92
92
  }
93
93
 
94
+ function detectKiroCandidates({ platform }) {
95
+ const candidates = [];
96
+ const home = os.homedir();
97
+ const userProfile = process.env.USERPROFILE || home;
98
+
99
+ // User-level only (no repo-local detection for Kiro)
100
+ // Kiro uses ~/.kiro/steering/ directory for global steering files
101
+ if (platform === 'macos') candidates.push(path.join(home, '.kiro', 'steering', 'cueme_proto.md'));
102
+ if (platform === 'linux') candidates.push(path.join(home, '.kiro', 'steering', 'cueme_proto.md'));
103
+ if (platform === 'windows') {
104
+ candidates.push(path.join(userProfile, '.kiro', 'steering', 'cueme_proto.md'));
105
+ }
106
+
107
+ return candidates;
108
+ }
109
+
94
110
  function firstExistingPath(candidates) {
95
111
  for (const p of candidates) {
96
112
  if (typeof p === 'string' && p.trim().length > 0 && pathExists(p)) return p;
@@ -125,6 +141,11 @@ function defaultPathMapTemplate() {
125
141
  out['windows.windsurf'] = path.join(userProfile, '.codeium', 'windsurf', 'memories', 'global_rules.md');
126
142
  out['linux.windsurf'] = path.join(home, '.codeium', 'windsurf', 'memories', 'global_rules.md');
127
143
 
144
+ // Kiro
145
+ out['macos.kiro'] = path.join(home, '.kiro', 'steering', 'cueme_proto.md');
146
+ out['windows.kiro'] = path.join(userProfile, '.kiro', 'steering', 'cueme_proto.md');
147
+ out['linux.kiro'] = path.join(home, '.kiro', 'steering', 'cueme_proto.md');
148
+
128
149
  return out;
129
150
  }
130
151
 
@@ -135,6 +156,7 @@ function defaultConfigTemplate() {
135
156
  'cueme.proto.prefix': {
136
157
  windsurf: [],
137
158
  vscode: ['---', 'applyTo: "**"', '---'],
159
+ kiro: [],
138
160
  },
139
161
  'cueme.proto.protocol_path': protocolPath,
140
162
  };
@@ -144,9 +166,10 @@ function detectAndFillTemplatePaths(tpl) {
144
166
  const platform = getPlatformKey();
145
167
  const keyVscode = `${platform}.vscode`;
146
168
  const keyWindsurf = `${platform}.windsurf`;
169
+ const keyKiro = `${platform}.kiro`;
147
170
 
148
171
  const pathMap = tpl['cueme.proto.path'] || {};
149
- const detected = { platform, vscode: '', windsurf: '' };
172
+ const detected = { platform, vscode: '', windsurf: '', kiro: '' };
150
173
 
151
174
  if (typeof pathMap !== 'object' || Array.isArray(pathMap)) {
152
175
  return { tpl, detected };
@@ -169,6 +192,14 @@ function detectAndFillTemplatePaths(tpl) {
169
192
  }
170
193
  }
171
194
 
195
+ if (typeof pathMap[keyKiro] !== 'string' || pathMap[keyKiro].trim().length === 0) {
196
+ const p = firstExistingPath(detectKiroCandidates({ platform }));
197
+ if (p) {
198
+ pathMap[keyKiro] = p;
199
+ detected.kiro = p;
200
+ }
201
+ }
202
+
172
203
  tpl['cueme.proto.path'] = pathMap;
173
204
  return { tpl, detected };
174
205
  }
@@ -368,15 +399,59 @@ function protoApply(agent) {
368
399
  return `ok: applied to ${targetPath}`;
369
400
  }
370
401
 
402
+ function protoRemove(agent) {
403
+ const cfg = readConfigOrThrow({ auto_init: true });
404
+ const targetPath = resolveTargetPath({ cfg, agent });
405
+
406
+ let existing = '';
407
+ try {
408
+ existing = fs.readFileSync(targetPath, 'utf8');
409
+ } catch {
410
+ return `ok: file does not exist: ${targetPath}`;
411
+ }
412
+
413
+ const beginMatch = existing.match(BEGIN_MARKER_RE);
414
+ const endMatch = existing.match(END_MARKER_RE);
415
+
416
+ if (!beginMatch || !endMatch || endMatch.index <= beginMatch.index) {
417
+ return `ok: no managed block found in: ${targetPath}`;
418
+ }
419
+
420
+ const beginIdx = beginMatch.index;
421
+ const endIdx = endMatch.index;
422
+ const endLen = endMatch[0].length;
423
+
424
+ const before = existing.slice(0, beginIdx);
425
+ const after = existing.slice(endIdx + endLen);
426
+
427
+ const eol = detectEol(existing);
428
+ const afterTrim = after.startsWith(eol) ? after.slice(eol.length) : after;
429
+ const out = before + afterTrim;
430
+
431
+ if (out.trim().length === 0) {
432
+ try {
433
+ fs.unlinkSync(targetPath);
434
+ return `ok: removed managed block and deleted empty file: ${targetPath}`;
435
+ } catch (err) {
436
+ throw new Error(`error: failed to delete file after removing managed block: ${targetPath}: ${err.message}`);
437
+ }
438
+ }
439
+
440
+ fs.writeFileSync(targetPath, out, 'utf8');
441
+ return `ok: removed managed block from: ${targetPath}`;
442
+ }
443
+
371
444
  function protoInit() {
372
445
  const { created, path: p, detected } = initConfigIfMissing();
373
446
  if (!created) return `ok: exists ${p}`;
374
447
  const platform = detected && detected.platform ? detected.platform : getPlatformKey();
375
448
  const keyVscode = `${platform}.vscode`;
376
449
  const keyWindsurf = `${platform}.windsurf`;
450
+ const keyKiro = `${platform}.kiro`;
377
451
  const vs = detected && detected.vscode ? 'detected' : 'empty';
378
452
  const ws = detected && detected.windsurf ? 'detected' : 'empty';
379
- return `ok: initialized ${p} (auto-detect: ${keyVscode}=${vs}, ${keyWindsurf}=${ws})`;
453
+ const ks = detected && detected.kiro ? 'detected' : 'empty';
454
+ return `ok: initialized ${p} (auto-detect: ${keyVscode}=${vs}, ${keyWindsurf}=${ws}, ${keyKiro}=${ks})`;
380
455
  }
381
456
 
382
457
  module.exports = {
@@ -384,6 +459,7 @@ module.exports = {
384
459
  END_MARKER,
385
460
  getPlatformKey,
386
461
  protoApply,
462
+ protoRemove,
387
463
  protoInit,
388
464
  protoLs,
389
465
  protoPath,