@rasensio/aidlc 1.10.6 → 1.10.8

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.
Files changed (43) hide show
  1. package/dist/commands/cost.d.ts.map +1 -1
  2. package/dist/commands/cost.js +29 -7
  3. package/dist/commands/cost.js.map +1 -1
  4. package/dist/commands/status.d.ts.map +1 -1
  5. package/dist/commands/status.js +22 -1
  6. package/dist/commands/status.js.map +1 -1
  7. package/dist/concurrency/gitattributes.d.ts.map +1 -1
  8. package/dist/concurrency/gitattributes.js +10 -0
  9. package/dist/concurrency/gitattributes.js.map +1 -1
  10. package/dist/cost/hooks/claude-code.d.ts +38 -5
  11. package/dist/cost/hooks/claude-code.d.ts.map +1 -1
  12. package/dist/cost/hooks/claude-code.js +38 -13
  13. package/dist/cost/hooks/claude-code.js.map +1 -1
  14. package/dist/cost/hooks/entry.d.ts +14 -0
  15. package/dist/cost/hooks/entry.d.ts.map +1 -0
  16. package/dist/cost/hooks/entry.js +18 -0
  17. package/dist/cost/hooks/entry.js.map +1 -0
  18. package/dist/cost/hooks/kiro.d.ts +16 -4
  19. package/dist/cost/hooks/kiro.d.ts.map +1 -1
  20. package/dist/cost/hooks/kiro.js +21 -9
  21. package/dist/cost/hooks/kiro.js.map +1 -1
  22. package/dist/cost/hooks/shim.d.ts +54 -0
  23. package/dist/cost/hooks/shim.d.ts.map +1 -0
  24. package/dist/cost/hooks/shim.js +170 -0
  25. package/dist/cost/hooks/shim.js.map +1 -0
  26. package/dist/cost/recorder.d.ts +22 -0
  27. package/dist/cost/recorder.d.ts.map +1 -1
  28. package/dist/cost/recorder.js +44 -0
  29. package/dist/cost/recorder.js.map +1 -1
  30. package/dist/doctor/migrations/cost-gitignore.d.ts.map +1 -1
  31. package/dist/doctor/migrations/cost-gitignore.js +15 -1
  32. package/dist/doctor/migrations/cost-gitignore.js.map +1 -1
  33. package/dist/doctor/migrations/index.js +2 -2
  34. package/dist/doctor/migrations/index.js.map +1 -1
  35. package/dist/doctor/migrations/legacy-cost-hooks.d.ts +40 -0
  36. package/dist/doctor/migrations/legacy-cost-hooks.d.ts.map +1 -0
  37. package/dist/doctor/migrations/legacy-cost-hooks.js +92 -0
  38. package/dist/doctor/migrations/legacy-cost-hooks.js.map +1 -0
  39. package/package.json +2 -2
  40. package/dist/doctor/migrations/stale-cost-hooks.d.ts +0 -37
  41. package/dist/doctor/migrations/stale-cost-hooks.d.ts.map +0 -1
  42. package/dist/doctor/migrations/stale-cost-hooks.js +0 -85
  43. package/dist/doctor/migrations/stale-cost-hooks.js.map +0 -1
@@ -0,0 +1,92 @@
1
+ /**
2
+ * legacy-cost-hooks migration: re-install cost hooks that predate the shim.
3
+ *
4
+ * Replaces `stale-cost-hooks` (cost-capture-goes-dark/AC-14, AC-18). That
5
+ * migration asked "does the absolute CLI path recorded in the hook still exist?"
6
+ * — the right question only while the command *contained* an absolute path. Hook
7
+ * commands now invoke `.aidlc/cost/capture.sh`, which resolves node and the CLI
8
+ * at run time, so there is no longer a path that can go stale and nothing left
9
+ * to detect. What remains is a one-time migration: hooks installed by an older
10
+ * version still carry the frozen paths and are still silently broken.
11
+ *
12
+ * WHY THIS ONE REPAIRS, WHERE ITS PREDECESSOR ONLY REPORTED. `stale-cost-hooks`
13
+ * was deliberately report-only, reasoning that "a diagnostic must not silently
14
+ * rewrite a user's .claude/settings.json". That reasoning was sound and is
15
+ * narrowed here rather than discarded: this migration only ever replaces hook
16
+ * entries carrying our own `#aidlc-cost-hook` marker, via the same
17
+ * merge-not-clobber installer that leaves every other key and every unmarked
18
+ * hook untouched. Nothing the user wrote is rewritten.
19
+ *
20
+ * The reason to change the stance at all is what report-only cost us: the
21
+ * detection was correct, the report printed on every `aidlc update`, and the
22
+ * data was lost anyway, because the last link in the chain was a human reading a
23
+ * line. A repair that needs to be noticed is a repair that does not happen. The
24
+ * failure it prevents is silent and unrecoverable — usage that was never
25
+ * captured cannot be reconstructed later.
26
+ *
27
+ * Self-clearing: re-installing produces the shim form, so `legacy` goes false
28
+ * and this stops reporting without anyone editing state.
29
+ */
30
+ import { claudeCodeHookStatus, installClaudeCodeHooks } from '../../cost/hooks/claude-code.js';
31
+ import { kiroHookStatus, installKiroHooks } from '../../cost/hooks/kiro.js';
32
+ import { cliEntryPath } from '../../cost/hooks/entry.js';
33
+ /*
34
+ * Deliberately NOT driven by allProviders(): that registry is populated by an
35
+ * explicit registerBuiltinProviders() call, so any caller that has not made it
36
+ * sees an EMPTY list — the predecessor migration reproduced exactly that bug on
37
+ * its first run and found nothing in every case. A diagnostic that silently
38
+ * finds nothing is worse than no diagnostic. Hook installation exists only for
39
+ * these two platforms, so the pairing is static.
40
+ */
41
+ const HOOK_PLATFORMS = [
42
+ { name: 'claude-code', status: claudeCodeHookStatus, install: installClaudeCodeHooks },
43
+ { name: 'kiro', status: kiroHookStatus, install: installKiroHooks },
44
+ ];
45
+ /**
46
+ * Platforms whose installed hook still uses the pre-shim absolute-path form.
47
+ * Read-only half, exported for reuse and direct testing.
48
+ *
49
+ * Only installed hooks are considered: an absent hook is a different condition
50
+ * (never armed, not broken), and `aidlc cost hooks status` already says so.
51
+ */
52
+ export function legacyCostHookPlatforms(projectRoot) {
53
+ const legacy = [];
54
+ for (const p of HOOK_PLATFORMS) {
55
+ const status = p.status(projectRoot);
56
+ if (status.installed && status.legacy)
57
+ legacy.push(p.name);
58
+ }
59
+ return legacy;
60
+ }
61
+ function summarize(legacy) {
62
+ const one = legacy.length === 1;
63
+ return (`${legacy.length} cost hook${one ? '' : 's'} ` +
64
+ `still ${one ? 'names' : 'name'} an absolute node/CLI path frozen at install time ` +
65
+ `(${legacy.join(', ')}) — re-installed so capture survives a node or machine change`);
66
+ }
67
+ export const legacyCostHooks = {
68
+ id: 'legacy-cost-hooks',
69
+ tier: 'safe',
70
+ check(ctx) {
71
+ const legacy = legacyCostHookPlatforms(ctx.projectRoot);
72
+ if (legacy.length === 0)
73
+ return { applicable: true, pending: false };
74
+ return { applicable: true, pending: true, description: summarize(legacy) };
75
+ },
76
+ apply(ctx) {
77
+ const legacy = legacyCostHookPlatforms(ctx.projectRoot);
78
+ if (legacy.length === 0)
79
+ return { changed: false, summary: 'no legacy cost hooks' };
80
+ // process.execPath and the resolved CLI are only *hints* for the shim; they
81
+ // are validated at run time and never written into the command text, so a
82
+ // hint captured here going stale later is no longer a failure mode.
83
+ const nodePath = process.execPath;
84
+ const cliPath = cliEntryPath();
85
+ for (const p of HOOK_PLATFORMS) {
86
+ if (legacy.includes(p.name))
87
+ p.install(ctx.projectRoot, nodePath, cliPath);
88
+ }
89
+ return { changed: true, summary: summarize(legacy) };
90
+ },
91
+ };
92
+ //# sourceMappingURL=legacy-cost-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy-cost-hooks.js","sourceRoot":"","sources":["../../../src/doctor/migrations/legacy-cost-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC/F,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AASzD;;;;;;;GAOG;AACH,MAAM,cAAc,GAAmB;IACrC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,sBAAsB,EAAE;IACtF,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,EAAE;CACpE,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAAmB;IACzD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACrC,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,SAAS,CAAC,MAAgB;IACjC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;IAChC,OAAO,CACL,GAAG,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QAC9C,SAAS,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,oDAAoD;QACnF,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,+DAA+D,CACrF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,EAAE,EAAE,mBAAmB;IACvB,IAAI,EAAE,MAAM;IACZ,KAAK,CAAC,GAAG;QACP,MAAM,MAAM,GAAG,uBAAuB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACxD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACrE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;IAC7E,CAAC;IACD,KAAK,CAAC,GAAG;QACP,MAAM,MAAM,GAAG,uBAAuB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACxD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC;QAEpF,4EAA4E;QAC5E,0EAA0E;QAC1E,oEAAoE;QACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAClC,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;QAC/B,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;YAC/B,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;gBAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;IACvD,CAAC;CACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rasensio/aidlc",
3
- "version": "1.10.6",
3
+ "version": "1.10.8",
4
4
  "description": "AI Development Lifecycle Framework — structured lifecycle guidance for AI coding agents across platforms",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",
@@ -24,7 +24,7 @@
24
24
  "commander": "15.0.0",
25
25
  "picomatch": "4.0.5",
26
26
  "yaml": "2.9.0",
27
- "@rasensio/aidlc-content": "1.10.6"
27
+ "@rasensio/aidlc-content": "1.10.8"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/node": "22.15.32",
@@ -1,37 +0,0 @@
1
- /**
2
- * stale-cost-hooks migration: report installed cost hooks whose recorded CLI
3
- * path no longer resolves on disk.
4
- *
5
- * Report-only, `safe` tier. The repair rewrites project files, so it belongs to
6
- * `aidlc cost hooks install` — a diagnostic must not silently rewrite a user's
7
- * .claude/settings.json or .kiro/hooks/. Same reasoning as unknown-agent-claims.
8
- *
9
- * Why this exists: hook commands are written with ABSOLUTE paths to both the
10
- * node binary and the globally installed CLI. A username change, a new machine,
11
- * or an `nvm` upgrade invalidates them, and the hook then fails silently —
12
- * nothing executes, nothing reaches capture.log, and `aidlc cost` reports no
13
- * data forever with no indication why. Observed in a real project whose hooks
14
- * still named `/Users/rodrigo` and node v24.9.0 long after the account and
15
- * runtime had moved on: capture had been dead for four days, every phase read
16
- * $0.00, and no command said anything was wrong.
17
- *
18
- * The detection already existed — `commandResolvable` on both hook-status
19
- * functions — and had no caller outside `aidlc cost hooks status`, which a
20
- * human has to remember to run. A guard nobody invokes is the same shape as the
21
- * cost feature whose arming was manual and therefore never armed.
22
- *
23
- * Self-clearing (the cost-capture-noise lesson: a suppression guard needs its
24
- * counterpart verified to exist). Reinstalling the hooks makes the path resolve
25
- * and silences this without anyone editing state.
26
- */
27
- import type { Migration } from '../types.js';
28
- /**
29
- * Platforms whose cost hooks are installed but point at a path that is gone.
30
- * Read-only half, exported for reuse and for direct testing.
31
- *
32
- * Only installed hooks are reported: an absent hook is a different condition
33
- * (never armed, not broken) and `aidlc cost hooks status` already says so.
34
- */
35
- export declare function staleCostHookPlatforms(projectRoot: string): string[];
36
- export declare const staleCostHooks: Migration;
37
- //# sourceMappingURL=stale-cost-hooks.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stale-cost-hooks.d.ts","sourceRoot":"","sources":["../../../src/doctor/migrations/stale-cost-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAwB7C;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAOpE;AAWD,eAAO,MAAM,cAAc,EAAE,SAgB5B,CAAC"}
@@ -1,85 +0,0 @@
1
- /**
2
- * stale-cost-hooks migration: report installed cost hooks whose recorded CLI
3
- * path no longer resolves on disk.
4
- *
5
- * Report-only, `safe` tier. The repair rewrites project files, so it belongs to
6
- * `aidlc cost hooks install` — a diagnostic must not silently rewrite a user's
7
- * .claude/settings.json or .kiro/hooks/. Same reasoning as unknown-agent-claims.
8
- *
9
- * Why this exists: hook commands are written with ABSOLUTE paths to both the
10
- * node binary and the globally installed CLI. A username change, a new machine,
11
- * or an `nvm` upgrade invalidates them, and the hook then fails silently —
12
- * nothing executes, nothing reaches capture.log, and `aidlc cost` reports no
13
- * data forever with no indication why. Observed in a real project whose hooks
14
- * still named `/Users/rodrigo` and node v24.9.0 long after the account and
15
- * runtime had moved on: capture had been dead for four days, every phase read
16
- * $0.00, and no command said anything was wrong.
17
- *
18
- * The detection already existed — `commandResolvable` on both hook-status
19
- * functions — and had no caller outside `aidlc cost hooks status`, which a
20
- * human has to remember to run. A guard nobody invokes is the same shape as the
21
- * cost feature whose arming was manual and therefore never armed.
22
- *
23
- * Self-clearing (the cost-capture-noise lesson: a suppression guard needs its
24
- * counterpart verified to exist). Reinstalling the hooks makes the path resolve
25
- * and silences this without anyone editing state.
26
- */
27
- import { claudeCodeHookStatus } from '../../cost/hooks/claude-code.js';
28
- import { kiroHookStatus } from '../../cost/hooks/kiro.js';
29
- /*
30
- * Deliberately NOT driven by allProviders(). That registry is populated by an
31
- * explicit registerBuiltinProviders() call, so any caller that has not made it
32
- * sees an EMPTY list — providers/index.ts documents that exact bug ("any code
33
- * path that did not import that module saw an empty registry"), and this
34
- * migration reproduced it on the first run: every case returned no findings
35
- * because the loop had nothing to iterate. A diagnostic that silently finds
36
- * nothing is worse than no diagnostic at all.
37
- *
38
- * Hook installation exists only for these two platforms, so the pairing is
39
- * static and carries no hidden initialisation order.
40
- */
41
- const HOOK_PLATFORMS = [
42
- { name: 'claude-code', status: claudeCodeHookStatus },
43
- { name: 'kiro', status: kiroHookStatus },
44
- ];
45
- /**
46
- * Platforms whose cost hooks are installed but point at a path that is gone.
47
- * Read-only half, exported for reuse and for direct testing.
48
- *
49
- * Only installed hooks are reported: an absent hook is a different condition
50
- * (never armed, not broken) and `aidlc cost hooks status` already says so.
51
- */
52
- export function staleCostHookPlatforms(projectRoot) {
53
- const stale = [];
54
- for (const p of HOOK_PLATFORMS) {
55
- const status = p.status(projectRoot);
56
- if (status.installed && !status.commandResolvable)
57
- stale.push(p.name);
58
- }
59
- return stale;
60
- }
61
- function summarize(stale) {
62
- return (`${stale.length} cost hook${stale.length === 1 ? '' : 's'} ` +
63
- `point at a path that no longer exists (${stale.join(', ')}) — ` +
64
- 'no usage is being captured; run `aidlc cost hooks install` to re-point ' +
65
- 'them at the current node and CLI');
66
- }
67
- export const staleCostHooks = {
68
- id: 'stale-cost-hooks',
69
- tier: 'safe',
70
- check(ctx) {
71
- const stale = staleCostHookPlatforms(ctx.projectRoot);
72
- if (stale.length === 0)
73
- return { applicable: true, pending: false };
74
- return { applicable: true, pending: true, description: summarize(stale) };
75
- },
76
- apply(ctx) {
77
- // Report-only. `changed: true` is what makes the finding visible: the runner
78
- // maps changed:false to status 'clean', and commands/doctor.ts filters clean
79
- // outcomes out of its report entirely, so a diagnostic returning false would
80
- // be silently swallowed. The rendered line reads `stale-cost-hooks: <summary>`.
81
- const stale = staleCostHookPlatforms(ctx.projectRoot);
82
- return { changed: stale.length > 0, summary: summarize(stale) };
83
- },
84
- };
85
- //# sourceMappingURL=stale-cost-hooks.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stale-cost-hooks.js","sourceRoot":"","sources":["../../../src/doctor/migrations/stale-cost-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAQ1D;;;;;;;;;;;GAWG;AACH,MAAM,cAAc,GAAuB;IACzC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,oBAAoB,EAAE;IACrD,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE;CACzC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,WAAmB;IACxD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACrC,IAAI,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,iBAAiB;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,KAAe;IAChC,OAAO,CACL,GAAG,KAAK,CAAC,MAAM,aAAa,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QAC5D,0CAA0C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;QAChE,yEAAyE;QACzE,kCAAkC,CACnC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAc;IACvC,EAAE,EAAE,kBAAkB;IACtB,IAAI,EAAE,MAAM;IACZ,KAAK,CAAC,GAAG;QACP,MAAM,KAAK,GAAG,sBAAsB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACtD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACpE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;IAC5E,CAAC;IACD,KAAK,CAAC,GAAG;QACP,6EAA6E;QAC7E,6EAA6E;QAC7E,6EAA6E;QAC7E,gFAAgF;QAChF,MAAM,KAAK,GAAG,sBAAsB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACtD,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;IAClE,CAAC;CACF,CAAC"}