@rasensio/aidlc 1.15.0 → 1.15.2
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.
- package/dist/commands/add-action.d.ts +0 -3
- package/dist/commands/add-action.d.ts.map +1 -1
- package/dist/commands/add-action.js +31 -14
- package/dist/commands/add-action.js.map +1 -1
- package/dist/commands/add-skill.js +7 -3
- package/dist/commands/add-skill.js.map +1 -1
- package/dist/commands/cost.d.ts.map +1 -1
- package/dist/commands/cost.js +37 -1
- package/dist/commands/cost.js.map +1 -1
- package/dist/commands/init.d.ts +16 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +40 -26
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/knowledge.js +8 -3
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +10 -8
- package/dist/commands/start.js.map +1 -1
- package/dist/compile/loaders.d.ts.map +1 -1
- package/dist/compile/loaders.js +12 -2
- package/dist/compile/loaders.js.map +1 -1
- package/dist/core/prompt.d.ts +140 -0
- package/dist/core/prompt.d.ts.map +1 -0
- package/dist/core/prompt.js +115 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/cost/agent.d.ts.map +1 -1
- package/dist/cost/agent.js +2 -11
- package/dist/cost/agent.js.map +1 -1
- package/dist/cost/hooks/claude-code.d.ts +17 -1
- package/dist/cost/hooks/claude-code.d.ts.map +1 -1
- package/dist/cost/hooks/claude-code.js +30 -5
- package/dist/cost/hooks/claude-code.js.map +1 -1
- package/dist/cost/hooks/kiro.d.ts.map +1 -1
- package/dist/cost/hooks/kiro.js +42 -26
- package/dist/cost/hooks/kiro.js.map +1 -1
- package/dist/cost/sessions.d.ts +85 -2
- package/dist/cost/sessions.d.ts.map +1 -1
- package/dist/cost/sessions.js +132 -9
- package/dist/cost/sessions.js.map +1 -1
- package/dist/cost/types.d.ts +10 -0
- package/dist/cost/types.d.ts.map +1 -1
- package/dist/cost/types.js.map +1 -1
- package/dist/doctor/migrations/index.d.ts.map +1 -1
- package/dist/doctor/migrations/index.js +8 -0
- package/dist/doctor/migrations/index.js.map +1 -1
- package/dist/doctor/migrations/outdated-cost-hooks.d.ts +35 -0
- package/dist/doctor/migrations/outdated-cost-hooks.d.ts.map +1 -0
- package/dist/doctor/migrations/outdated-cost-hooks.js +81 -0
- package/dist/doctor/migrations/outdated-cost-hooks.js.map +1 -0
- package/dist/doctor/migrations/trust-run-actions.d.ts +14 -0
- package/dist/doctor/migrations/trust-run-actions.d.ts.map +1 -0
- package/dist/doctor/migrations/trust-run-actions.js +68 -0
- package/dist/doctor/migrations/trust-run-actions.js.map +1 -0
- package/dist/doctor/runner.d.ts.map +1 -1
- package/dist/doctor/runner.js +5 -3
- package/dist/doctor/runner.js.map +1 -1
- package/dist/events/event-bus.d.ts +3 -1
- package/dist/events/event-bus.d.ts.map +1 -1
- package/dist/events/event-bus.js +40 -10
- package/dist/events/event-bus.js.map +1 -1
- package/dist/menu/index.d.ts +5 -2
- package/dist/menu/index.d.ts.map +1 -1
- package/dist/menu/index.js +13 -7
- package/dist/menu/index.js.map +1 -1
- package/dist/security/action-trust.d.ts +34 -0
- package/dist/security/action-trust.d.ts.map +1 -0
- package/dist/security/action-trust.js +82 -0
- package/dist/security/action-trust.js.map +1 -0
- package/dist/traceability/gate-criterion.d.ts.map +1 -1
- package/dist/traceability/gate-criterion.js +7 -0
- package/dist/traceability/gate-criterion.js.map +1 -1
- package/package.json +2 -2
- package/dist/menu/prompt.d.ts +0 -74
- package/dist/menu/prompt.d.ts.map +0 -1
- package/dist/menu/prompt.js +0 -69
- package/dist/menu/prompt.js.map +0 -1
package/dist/cost/sessions.d.ts
CHANGED
|
@@ -11,6 +11,20 @@
|
|
|
11
11
|
* Design: design.md §2.2, §2.3, §4.3
|
|
12
12
|
*/
|
|
13
13
|
import type { SessionEvent, ClaimInterval, ActiveSession } from './types.js';
|
|
14
|
+
/**
|
|
15
|
+
* How recently a stash entry must show activity to count as a *candidate* for
|
|
16
|
+
* "which session am I?".
|
|
17
|
+
*
|
|
18
|
+
* Deletion (TTL) and candidacy (liveness) are different questions and the bug
|
|
19
|
+
* came from answering only the first. `resolveCurrentSession` used to treat every
|
|
20
|
+
* unexpired entry as a candidate, so each finished session poisoned resolution
|
|
21
|
+
* for up to 48 hours; this repo carried 18 entries of which 3 were running.
|
|
22
|
+
*
|
|
23
|
+
* 30 minutes is chosen against the caller: `resolveCurrentSession` runs from
|
|
24
|
+
* inside a live session (`aidlc claim`), whose transcript was appended to seconds
|
|
25
|
+
* ago. Anything that has been silent for half an hour is not the session asking.
|
|
26
|
+
*/
|
|
27
|
+
export declare const STASH_LIVENESS_MS: number;
|
|
14
28
|
export declare function sessionsPath(projectRoot: string, instance: string): string;
|
|
15
29
|
export declare function stashDir(projectRoot: string): string;
|
|
16
30
|
/** Append a session event (O_APPEND whole-line write). */
|
|
@@ -32,9 +46,49 @@ export declare function readSessionEvents(path: string): SessionEvent[];
|
|
|
32
46
|
export declare function resolveIntervals(events: SessionEvent[], claimTimeoutMinutes: number, now?: Date): ClaimInterval[];
|
|
33
47
|
/** Write a stash entry for a just-started platform session. */
|
|
34
48
|
export declare function stashSession(projectRoot: string, session: ActiveSession): void;
|
|
49
|
+
/**
|
|
50
|
+
* Remove one session's stash entry — the step that never existed.
|
|
51
|
+
*
|
|
52
|
+
* Entries were written on SessionStart and removed only by a 48-hour timer, so a
|
|
53
|
+
* finished session went on being a candidate for two days and
|
|
54
|
+
* `resolveCurrentSession` refused to guess between it and the live one. The
|
|
55
|
+
* SessionEnd hook already receives the ending session's id; this is what it does
|
|
56
|
+
* with it.
|
|
57
|
+
*
|
|
58
|
+
* Returns whether an entry was removed. Idempotent by contract: an end hook can
|
|
59
|
+
* fire twice, and a second call is a `false`, not an error.
|
|
60
|
+
*
|
|
61
|
+
* SECURITY: the id is regex-validated before it reaches `join`, so a hook payload
|
|
62
|
+
* cannot steer the unlink outside the stash directory — the same rule
|
|
63
|
+
* `stashSession` applies on the way in.
|
|
64
|
+
*/
|
|
65
|
+
export declare function unstashSession(projectRoot: string, sessionId: string): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Whether an entry looks like a session that is still running.
|
|
68
|
+
*
|
|
69
|
+
* Three cases, ordered by how much the entry lets us know:
|
|
70
|
+
*
|
|
71
|
+
* - declares a readable `transcript_path` → live iff it was appended to within
|
|
72
|
+
* STASH_LIVENESS_MS. This is the real signal: a running session writes its
|
|
73
|
+
* transcript every turn.
|
|
74
|
+
* - declares a `transcript_path` that is not there → fall back to `started_at`.
|
|
75
|
+
* A session can be seconds old with no transcript on disk yet (SessionStart
|
|
76
|
+
* fires before the first message is written), so absence alone must not read
|
|
77
|
+
* as death — but an entry claiming a transcript that never appeared and
|
|
78
|
+
* starting hours ago is not running.
|
|
79
|
+
* - declares no `transcript_path` → liveness is unmeasurable, so it stays a
|
|
80
|
+
* candidate and only the TTL applies. Kiro supplies no transcript, and
|
|
81
|
+
* excluding those entries would strip resolution from long kiro sessions that
|
|
82
|
+
* work today.
|
|
83
|
+
*/
|
|
84
|
+
export declare function isLiveEntry(entry: ActiveSession, now?: Date): boolean;
|
|
35
85
|
/**
|
|
36
86
|
* Stash entries past the TTL (or unparseable — pruneStash removes those
|
|
37
87
|
* too). Read-only half of pruneStash, shared with `aidlc doctor` (AC-18).
|
|
88
|
+
*
|
|
89
|
+
* Deliberately TTL-only: liveness decides candidacy, never deletion, so an idle
|
|
90
|
+
* session's entry stays on disk and `aidlc doctor` keeps reporting exactly what it
|
|
91
|
+
* removes.
|
|
38
92
|
*/
|
|
39
93
|
export declare function expiredStashEntries(projectRoot: string, now?: Date): string[];
|
|
40
94
|
/**
|
|
@@ -42,12 +96,41 @@ export declare function expiredStashEntries(projectRoot: string, now?: Date): st
|
|
|
42
96
|
* Returns the removed filenames.
|
|
43
97
|
*/
|
|
44
98
|
export declare function pruneStash(projectRoot: string, now?: Date): string[];
|
|
45
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* Resolve a directory to its repo identity (git common dir), or null.
|
|
101
|
+
*
|
|
102
|
+
* The anchor is canonicalized because two spellings of one directory otherwise
|
|
103
|
+
* read as two repositories: a hook payload saying `/tmp/x` and a project root
|
|
104
|
+
* resolved to `/private/tmp/x` produced *zero* candidates, which looks exactly
|
|
105
|
+
* like "no session here". `cost/agent.ts:canonical` already does this, in its
|
|
106
|
+
* non-git branch only.
|
|
107
|
+
*
|
|
108
|
+
* What is NOT changed: `join(cwd, out)`. `git rev-parse --git-common-dir` answers
|
|
109
|
+
* relatively from a primary checkout and absolutely from a linked worktree, so
|
|
110
|
+
* `join` concatenates rather than replaces and a worktree gets its own identity —
|
|
111
|
+
* load-bearing for `resolveCurrentSession`, whose single-candidate rule wants a
|
|
112
|
+
* worktree session and a primary-checkout session to look like different
|
|
113
|
+
* workspaces. See the note at `sync.ts:repoCommonDir`, which needs the opposite
|
|
114
|
+
* and therefore has its own function.
|
|
115
|
+
*/
|
|
46
116
|
export declare function repoIdentity(cwd: string): string | null;
|
|
117
|
+
/**
|
|
118
|
+
* Resolve symlinks for comparison; unresolvable paths compare as written.
|
|
119
|
+
*
|
|
120
|
+
* Shared with `cost/agent.ts`, which needs the same rule for the same reason —
|
|
121
|
+
* two spellings of one directory must not compare as two directories.
|
|
122
|
+
*/
|
|
123
|
+
export declare function canonical(p: string): string;
|
|
47
124
|
/**
|
|
48
125
|
* Find the current platform session with the strict single-candidate rule:
|
|
49
|
-
* exactly one live stash entry whose repo identity matches → that session;
|
|
126
|
+
* exactly one **live** stash entry whose repo identity matches → that session;
|
|
50
127
|
* zero or multiple → null (caller degrades to id_source: agent).
|
|
128
|
+
*
|
|
129
|
+
* The rule itself is unchanged and correct — two genuinely live sessions are
|
|
130
|
+
* ambiguous, and guessing between them would attribute one session's cost to the
|
|
131
|
+
* other's instance. What changed is the candidate set: `isLiveEntry` drops
|
|
132
|
+
* sessions that have finished or died, which is what the rule always assumed and
|
|
133
|
+
* nothing enforced.
|
|
51
134
|
*/
|
|
52
135
|
export declare function resolveCurrentSession(projectRoot: string, now?: Date): ActiveSession | null;
|
|
53
136
|
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/cost/sessions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/cost/sessions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAkBH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAe7E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAEhD,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEpD;AAgBD,0DAA0D;AAC1D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAS1E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,EAAE,CA0B9D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,YAAY,EAAE,EACtB,mBAAmB,EAAE,MAAM,EAC3B,GAAG,GAAE,IAAiB,GACrB,aAAa,EAAE,CA6BjB;AAiBD,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAK9E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAS9E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,GAAE,IAAiB,GAAG,OAAO,CAWjF;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,GAAE,IAAiB,GAAG,MAAM,EAAE,CAgBzF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,GAAE,IAAiB,GAAG,MAAM,EAAE,CAWhF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWvD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAM3C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,GAAG,GAAE,IAAiB,GACrB,aAAa,GAAG,IAAI,CAsBtB"}
|
package/dist/cost/sessions.js
CHANGED
|
@@ -10,12 +10,34 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Design: design.md §2.2, §2.3, §4.3
|
|
12
12
|
*/
|
|
13
|
-
import { readFileSync, writeFileSync, readdirSync, unlinkSync, openSync, writeSync, closeSync, constants, mkdirSync, existsSync, } from 'node:fs';
|
|
13
|
+
import { readFileSync, writeFileSync, readdirSync, realpathSync, statSync, unlinkSync, openSync, writeSync, closeSync, constants, mkdirSync, existsSync, } from 'node:fs';
|
|
14
14
|
import { dirname, join } from 'node:path';
|
|
15
15
|
import { execFileSync } from 'node:child_process';
|
|
16
16
|
import { SESSION_ID_RE } from './types.js';
|
|
17
17
|
const EVENTS = new Set(['claim', 'renew', 'release']);
|
|
18
|
+
/**
|
|
19
|
+
* How long a stash entry survives on disk. Since unstash-on-session-end exists
|
|
20
|
+
* (`unstashSession`, wired to the SessionEnd hook) this is only a crash-recovery
|
|
21
|
+
* backstop, and it is deliberately left long: pruning is *deletion*, and a
|
|
22
|
+
* session can legitimately stay open for days, so a short TTL would delete a
|
|
23
|
+
* live session's entry. Candidacy is a separate, much tighter question — see
|
|
24
|
+
* STASH_LIVENESS_MS.
|
|
25
|
+
*/
|
|
18
26
|
const STASH_TTL_MS = 48 * 60 * 60 * 1000;
|
|
27
|
+
/**
|
|
28
|
+
* How recently a stash entry must show activity to count as a *candidate* for
|
|
29
|
+
* "which session am I?".
|
|
30
|
+
*
|
|
31
|
+
* Deletion (TTL) and candidacy (liveness) are different questions and the bug
|
|
32
|
+
* came from answering only the first. `resolveCurrentSession` used to treat every
|
|
33
|
+
* unexpired entry as a candidate, so each finished session poisoned resolution
|
|
34
|
+
* for up to 48 hours; this repo carried 18 entries of which 3 were running.
|
|
35
|
+
*
|
|
36
|
+
* 30 minutes is chosen against the caller: `resolveCurrentSession` runs from
|
|
37
|
+
* inside a live session (`aidlc claim`), whose transcript was appended to seconds
|
|
38
|
+
* ago. Anything that has been silent for half an hour is not the session asking.
|
|
39
|
+
*/
|
|
40
|
+
export const STASH_LIVENESS_MS = 30 * 60 * 1000;
|
|
19
41
|
export function sessionsPath(projectRoot, instance) {
|
|
20
42
|
return join(projectRoot, '.aidlc', 'state', instance, 'sessions.ndjson');
|
|
21
43
|
}
|
|
@@ -142,9 +164,74 @@ export function stashSession(projectRoot, session) {
|
|
|
142
164
|
mkdirSync(dir, { recursive: true });
|
|
143
165
|
writeFileSync(join(dir, `${session.session_id}.json`), JSON.stringify(session) + '\n');
|
|
144
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Remove one session's stash entry — the step that never existed.
|
|
169
|
+
*
|
|
170
|
+
* Entries were written on SessionStart and removed only by a 48-hour timer, so a
|
|
171
|
+
* finished session went on being a candidate for two days and
|
|
172
|
+
* `resolveCurrentSession` refused to guess between it and the live one. The
|
|
173
|
+
* SessionEnd hook already receives the ending session's id; this is what it does
|
|
174
|
+
* with it.
|
|
175
|
+
*
|
|
176
|
+
* Returns whether an entry was removed. Idempotent by contract: an end hook can
|
|
177
|
+
* fire twice, and a second call is a `false`, not an error.
|
|
178
|
+
*
|
|
179
|
+
* SECURITY: the id is regex-validated before it reaches `join`, so a hook payload
|
|
180
|
+
* cannot steer the unlink outside the stash directory — the same rule
|
|
181
|
+
* `stashSession` applies on the way in.
|
|
182
|
+
*/
|
|
183
|
+
export function unstashSession(projectRoot, sessionId) {
|
|
184
|
+
if (!SESSION_ID_RE.test(sessionId))
|
|
185
|
+
return false;
|
|
186
|
+
try {
|
|
187
|
+
unlinkSync(join(stashDir(projectRoot), `${sessionId}.json`));
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
// Already gone (double-fired hook, concurrent prune) — the desired state.
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Whether an entry looks like a session that is still running.
|
|
197
|
+
*
|
|
198
|
+
* Three cases, ordered by how much the entry lets us know:
|
|
199
|
+
*
|
|
200
|
+
* - declares a readable `transcript_path` → live iff it was appended to within
|
|
201
|
+
* STASH_LIVENESS_MS. This is the real signal: a running session writes its
|
|
202
|
+
* transcript every turn.
|
|
203
|
+
* - declares a `transcript_path` that is not there → fall back to `started_at`.
|
|
204
|
+
* A session can be seconds old with no transcript on disk yet (SessionStart
|
|
205
|
+
* fires before the first message is written), so absence alone must not read
|
|
206
|
+
* as death — but an entry claiming a transcript that never appeared and
|
|
207
|
+
* starting hours ago is not running.
|
|
208
|
+
* - declares no `transcript_path` → liveness is unmeasurable, so it stays a
|
|
209
|
+
* candidate and only the TTL applies. Kiro supplies no transcript, and
|
|
210
|
+
* excluding those entries would strip resolution from long kiro sessions that
|
|
211
|
+
* work today.
|
|
212
|
+
*/
|
|
213
|
+
export function isLiveEntry(entry, now = new Date()) {
|
|
214
|
+
if (entry.transcript_path === undefined || entry.transcript_path === '')
|
|
215
|
+
return true;
|
|
216
|
+
try {
|
|
217
|
+
const st = statSync(entry.transcript_path);
|
|
218
|
+
return now.getTime() - st.mtimeMs <= STASH_LIVENESS_MS;
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
const started = Date.parse(entry.started_at);
|
|
222
|
+
// An unparseable timestamp measures nothing; unmeasurable is not dead.
|
|
223
|
+
if (Number.isNaN(started))
|
|
224
|
+
return true;
|
|
225
|
+
return now.getTime() - started <= STASH_LIVENESS_MS;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
145
228
|
/**
|
|
146
229
|
* Stash entries past the TTL (or unparseable — pruneStash removes those
|
|
147
230
|
* too). Read-only half of pruneStash, shared with `aidlc doctor` (AC-18).
|
|
231
|
+
*
|
|
232
|
+
* Deliberately TTL-only: liveness decides candidacy, never deletion, so an idle
|
|
233
|
+
* session's entry stays on disk and `aidlc doctor` keeps reporting exactly what it
|
|
234
|
+
* removes.
|
|
148
235
|
*/
|
|
149
236
|
export function expiredStashEntries(projectRoot, now = new Date()) {
|
|
150
237
|
const dir = stashDir(projectRoot);
|
|
@@ -183,7 +270,23 @@ export function pruneStash(projectRoot, now = new Date()) {
|
|
|
183
270
|
}
|
|
184
271
|
return expired;
|
|
185
272
|
}
|
|
186
|
-
/**
|
|
273
|
+
/**
|
|
274
|
+
* Resolve a directory to its repo identity (git common dir), or null.
|
|
275
|
+
*
|
|
276
|
+
* The anchor is canonicalized because two spellings of one directory otherwise
|
|
277
|
+
* read as two repositories: a hook payload saying `/tmp/x` and a project root
|
|
278
|
+
* resolved to `/private/tmp/x` produced *zero* candidates, which looks exactly
|
|
279
|
+
* like "no session here". `cost/agent.ts:canonical` already does this, in its
|
|
280
|
+
* non-git branch only.
|
|
281
|
+
*
|
|
282
|
+
* What is NOT changed: `join(cwd, out)`. `git rev-parse --git-common-dir` answers
|
|
283
|
+
* relatively from a primary checkout and absolutely from a linked worktree, so
|
|
284
|
+
* `join` concatenates rather than replaces and a worktree gets its own identity —
|
|
285
|
+
* load-bearing for `resolveCurrentSession`, whose single-candidate rule wants a
|
|
286
|
+
* worktree session and a primary-checkout session to look like different
|
|
287
|
+
* workspaces. See the note at `sync.ts:repoCommonDir`, which needs the opposite
|
|
288
|
+
* and therefore has its own function.
|
|
289
|
+
*/
|
|
187
290
|
export function repoIdentity(cwd) {
|
|
188
291
|
try {
|
|
189
292
|
const out = execFileSync('git', ['rev-parse', '--git-common-dir'], {
|
|
@@ -191,16 +294,36 @@ export function repoIdentity(cwd) {
|
|
|
191
294
|
encoding: 'utf8',
|
|
192
295
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
193
296
|
}).trim();
|
|
194
|
-
return join(cwd, out);
|
|
297
|
+
return join(canonical(cwd), out);
|
|
195
298
|
}
|
|
196
299
|
catch {
|
|
197
300
|
return null;
|
|
198
301
|
}
|
|
199
302
|
}
|
|
303
|
+
/**
|
|
304
|
+
* Resolve symlinks for comparison; unresolvable paths compare as written.
|
|
305
|
+
*
|
|
306
|
+
* Shared with `cost/agent.ts`, which needs the same rule for the same reason —
|
|
307
|
+
* two spellings of one directory must not compare as two directories.
|
|
308
|
+
*/
|
|
309
|
+
export function canonical(p) {
|
|
310
|
+
try {
|
|
311
|
+
return realpathSync(p);
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
return p;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
200
317
|
/**
|
|
201
318
|
* Find the current platform session with the strict single-candidate rule:
|
|
202
|
-
* exactly one live stash entry whose repo identity matches → that session;
|
|
319
|
+
* exactly one **live** stash entry whose repo identity matches → that session;
|
|
203
320
|
* zero or multiple → null (caller degrades to id_source: agent).
|
|
321
|
+
*
|
|
322
|
+
* The rule itself is unchanged and correct — two genuinely live sessions are
|
|
323
|
+
* ambiguous, and guessing between them would attribute one session's cost to the
|
|
324
|
+
* other's instance. What changed is the candidate set: `isLiveEntry` drops
|
|
325
|
+
* sessions that have finished or died, which is what the rule always assumed and
|
|
326
|
+
* nothing enforced.
|
|
204
327
|
*/
|
|
205
328
|
export function resolveCurrentSession(projectRoot, now = new Date()) {
|
|
206
329
|
pruneStash(projectRoot, now);
|
|
@@ -208,6 +331,7 @@ export function resolveCurrentSession(projectRoot, now = new Date()) {
|
|
|
208
331
|
if (!existsSync(dir))
|
|
209
332
|
return null;
|
|
210
333
|
const here = repoIdentity(projectRoot);
|
|
334
|
+
const hereReal = canonical(projectRoot);
|
|
211
335
|
const candidates = [];
|
|
212
336
|
for (const f of readdirSync(dir)) {
|
|
213
337
|
if (!f.endsWith('.json'))
|
|
@@ -215,12 +339,11 @@ export function resolveCurrentSession(projectRoot, now = new Date()) {
|
|
|
215
339
|
try {
|
|
216
340
|
const entry = JSON.parse(readFileSync(join(dir, f), 'utf8'));
|
|
217
341
|
const theirs = repoIdentity(entry.cwd);
|
|
218
|
-
|
|
342
|
+
const sameRepo = here !== null && theirs !== null
|
|
343
|
+
? here === theirs
|
|
344
|
+
: here === null && canonical(entry.cwd) === hereReal;
|
|
345
|
+
if (sameRepo && isLiveEntry(entry, now))
|
|
219
346
|
candidates.push(entry);
|
|
220
|
-
}
|
|
221
|
-
else if (here === null && entry.cwd === projectRoot) {
|
|
222
|
-
candidates.push(entry);
|
|
223
|
-
}
|
|
224
347
|
}
|
|
225
348
|
catch {
|
|
226
349
|
// Unreadable stash entries are ignored here; pruneStash removes them.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/cost/sessions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,YAAY,EACZ,aAAa,EACb,WAAW,EACX,UAAU,EACV,QAAQ,EACR,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/cost/sessions.ts"],"names":[],"mappings":"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"}
|
package/dist/cost/types.d.ts
CHANGED
|
@@ -152,6 +152,16 @@ export interface RecordInput {
|
|
|
152
152
|
session_id: string;
|
|
153
153
|
transcript_path?: string;
|
|
154
154
|
cwd?: string;
|
|
155
|
+
/**
|
|
156
|
+
* The platform event that fired this hook, when the payload names it
|
|
157
|
+
* (claude-code always does; kiro's `Stop` does not).
|
|
158
|
+
*
|
|
159
|
+
* Read for one purpose: recognizing a session *end*, which is when the stash
|
|
160
|
+
* entry must be removed. Carrying it in the payload rather than only in the
|
|
161
|
+
* installed command text is what makes the fix reach installs that have not
|
|
162
|
+
* re-run `aidlc cost hooks install`.
|
|
163
|
+
*/
|
|
164
|
+
hook_event_name?: string;
|
|
155
165
|
}
|
|
156
166
|
/** Per-model (or per-unit) pricing entry. */
|
|
157
167
|
export interface RateEntry {
|
package/dist/cost/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cost/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+DAA+D;AAC/D,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;AAEjD,8CAA8C;AAC9C,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC;AAE9E,sDAAsD;AACtD,MAAM,WAAW,SAAS;IACxB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qEAAqE;IACrE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;IACvB,sCAAsC;IACtC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,6EAA6E;IAC7E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,+DAA+D;IAC/D,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,mCAAmC;AACnC,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,IAAI,EAAE,OAAO,CAAC;CACf;AAED,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,gEAAgE;AAChE,MAAM,WAAW,YAAY;IAC3B,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,SAAS,CAAC;IACjB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC5C;AAED,uDAAuD;AACvD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG,gBAAgB,CAAC;AAElE,+CAA+C;AAC/C,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAC/B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAIjD,CAAC;AAEF,qEAAqE;AACrE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cost/types.ts"],"names":[],"mappings":"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"}
|
package/dist/cost/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cost/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAqIH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAsB;IACrD,IAAI;IACJ,gBAAgB;IAChB,uBAAuB;CACxB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cost/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAqIH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAsB;IACrD,IAAI;IACJ,gBAAgB;IAChB,uBAAuB;CACxB,CAAC;AA0CF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,aAAa,GAAG,uBAAuB,CAAC;AAErD,iDAAiD;AACjD,MAAM,CAAC,MAAM,WAAW,GAAG,4BAA4B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/doctor/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/doctor/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAqB7C,eAAO,MAAM,UAAU,EAAE,SAAS,EAsCjC,CAAC"}
|
|
@@ -16,8 +16,10 @@ import { pruneCaptureLogMigration } from './prune-capture-log.js';
|
|
|
16
16
|
import { pruneRegistry } from './prune-registry.js';
|
|
17
17
|
import { unknownAgentClaims } from './unknown-agent-claims.js';
|
|
18
18
|
import { legacyCostHooks } from './legacy-cost-hooks.js';
|
|
19
|
+
import { outdatedCostHooks } from './outdated-cost-hooks.js';
|
|
19
20
|
import { missingCostShim } from './missing-cost-shim.js';
|
|
20
21
|
import { installGuidance } from './install-guidance.js';
|
|
22
|
+
import { trustRunActions } from './trust-run-actions.js';
|
|
21
23
|
import { staleIdeaSkill } from './stale-idea-skill.js';
|
|
22
24
|
import { roadmapLayout } from './roadmap-layout.js';
|
|
23
25
|
import { roadmapItemTitles } from './roadmap-item-titles.js';
|
|
@@ -54,5 +56,11 @@ export const MIGRATIONS = [
|
|
|
54
56
|
// Running this first keeps each migration's report about its own condition.
|
|
55
57
|
missingCostShim,
|
|
56
58
|
legacyCostHooks,
|
|
59
|
+
// Ordered after legacy-cost-hooks: that migration re-installs, which leaves the
|
|
60
|
+
// command current, so one run never reports a legacy hook twice.
|
|
61
|
+
outdatedCostHooks,
|
|
62
|
+
// Confirm tier: shows the exact `run:` commands from actions.yaml before
|
|
63
|
+
// recording machine-local trust — the event bus declines them until then.
|
|
64
|
+
trustRunActions,
|
|
57
65
|
];
|
|
58
66
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/doctor/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,CAAC,MAAM,UAAU,GAAgB;IACrC,aAAa;IACb,kBAAkB;IAClB,aAAa;IACb,cAAc;IACd,eAAe;IACf,4EAA4E;IAC5E,2EAA2E;IAC3E,8EAA8E;IAC9E,cAAc;IACd,aAAa;IACb,0EAA0E;IAC1E,qEAAqE;IACrE,+EAA+E;IAC/E,0EAA0E;IAC1E,mDAAmD;IACnD,iBAAiB;IACjB,8EAA8E;IAC9E,0EAA0E;IAC1E,yEAAyE;IACzE,kBAAkB;IAClB,mBAAmB;IACnB,iBAAiB;IACjB,cAAc;IACd,wBAAwB;IACxB,aAAa;IACb,kBAAkB;IAClB,6EAA6E;IAC7E,6EAA6E;IAC7E,4EAA4E;IAC5E,eAAe;IACf,eAAe;CAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/doctor/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,CAAC,MAAM,UAAU,GAAgB;IACrC,aAAa;IACb,kBAAkB;IAClB,aAAa;IACb,cAAc;IACd,eAAe;IACf,4EAA4E;IAC5E,2EAA2E;IAC3E,8EAA8E;IAC9E,cAAc;IACd,aAAa;IACb,0EAA0E;IAC1E,qEAAqE;IACrE,+EAA+E;IAC/E,0EAA0E;IAC1E,mDAAmD;IACnD,iBAAiB;IACjB,8EAA8E;IAC9E,0EAA0E;IAC1E,yEAAyE;IACzE,kBAAkB;IAClB,mBAAmB;IACnB,iBAAiB;IACjB,cAAc;IACd,wBAAwB;IACxB,aAAa;IACb,kBAAkB;IAClB,6EAA6E;IAC7E,6EAA6E;IAC7E,4EAA4E;IAC5E,eAAe;IACf,eAAe;IACf,gFAAgF;IAChF,iEAAiE;IACjE,iBAAiB;IACjB,yEAAyE;IACzE,0EAA0E;IAC1E,eAAe;CAChB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* outdated-cost-hooks migration: re-install cost hooks whose command text is not
|
|
3
|
+
* what this version writes.
|
|
4
|
+
*
|
|
5
|
+
* `legacy-cost-hooks` answers one historical question — does this hook predate the
|
|
6
|
+
* shim? — and had to be written when that change shipped. This one answers the
|
|
7
|
+
* question that recurs: is the installed command current? Every future
|
|
8
|
+
* command-shape change is then repaired by machinery that already exists, instead
|
|
9
|
+
* of by another bespoke detector nobody remembers to add.
|
|
10
|
+
*
|
|
11
|
+
* The change that prompted it: the claude-code SessionEnd hook now passes
|
|
12
|
+
* `--session-end`, so the recorder drops the ending session's active-session stash
|
|
13
|
+
* entry. An install without the flag is not broken — `cost record` also accepts the
|
|
14
|
+
* `hook_event_name: "SessionEnd"` signal in the payload, which is deliberately what
|
|
15
|
+
* makes the fix land without a re-install — but it should not stay behind.
|
|
16
|
+
*
|
|
17
|
+
* Same narrow warrant as `legacy-cost-hooks`: it only ever replaces hook entries
|
|
18
|
+
* carrying our own `#aidlc-cost-hook` marker, through the merge-not-clobber
|
|
19
|
+
* installer, so nothing the user wrote is touched. Self-clearing — after the
|
|
20
|
+
* re-install the status reads current.
|
|
21
|
+
*
|
|
22
|
+
* Ordered after `legacy-cost-hooks`, which re-installs and therefore leaves those
|
|
23
|
+
* platforms current: each migration then reports only its own condition.
|
|
24
|
+
*/
|
|
25
|
+
import type { Migration } from '../types.js';
|
|
26
|
+
/**
|
|
27
|
+
* Platforms whose installed hook command differs from the current one. Read-only
|
|
28
|
+
* half, exported for reuse and direct testing.
|
|
29
|
+
*
|
|
30
|
+
* Only installed hooks count: an absent hook was never armed, which is a different
|
|
31
|
+
* condition that `aidlc cost hooks status` already reports.
|
|
32
|
+
*/
|
|
33
|
+
export declare function outdatedCostHookPlatforms(projectRoot: string): string[];
|
|
34
|
+
export declare const outdatedCostHooks: Migration;
|
|
35
|
+
//# sourceMappingURL=outdated-cost-hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outdated-cost-hooks.d.ts","sourceRoot":"","sources":["../../../src/doctor/migrations/outdated-cost-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAgB7C;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAOvE;AAWD,eAAO,MAAM,iBAAiB,EAAE,SAqB/B,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* outdated-cost-hooks migration: re-install cost hooks whose command text is not
|
|
3
|
+
* what this version writes.
|
|
4
|
+
*
|
|
5
|
+
* `legacy-cost-hooks` answers one historical question — does this hook predate the
|
|
6
|
+
* shim? — and had to be written when that change shipped. This one answers the
|
|
7
|
+
* question that recurs: is the installed command current? Every future
|
|
8
|
+
* command-shape change is then repaired by machinery that already exists, instead
|
|
9
|
+
* of by another bespoke detector nobody remembers to add.
|
|
10
|
+
*
|
|
11
|
+
* The change that prompted it: the claude-code SessionEnd hook now passes
|
|
12
|
+
* `--session-end`, so the recorder drops the ending session's active-session stash
|
|
13
|
+
* entry. An install without the flag is not broken — `cost record` also accepts the
|
|
14
|
+
* `hook_event_name: "SessionEnd"` signal in the payload, which is deliberately what
|
|
15
|
+
* makes the fix land without a re-install — but it should not stay behind.
|
|
16
|
+
*
|
|
17
|
+
* Same narrow warrant as `legacy-cost-hooks`: it only ever replaces hook entries
|
|
18
|
+
* carrying our own `#aidlc-cost-hook` marker, through the merge-not-clobber
|
|
19
|
+
* installer, so nothing the user wrote is touched. Self-clearing — after the
|
|
20
|
+
* re-install the status reads current.
|
|
21
|
+
*
|
|
22
|
+
* Ordered after `legacy-cost-hooks`, which re-installs and therefore leaves those
|
|
23
|
+
* platforms current: each migration then reports only its own condition.
|
|
24
|
+
*/
|
|
25
|
+
import { claudeCodeHookStatus, installClaudeCodeHooks } from '../../cost/hooks/claude-code.js';
|
|
26
|
+
import { kiroHookStatus, installKiroHooks } from '../../cost/hooks/kiro.js';
|
|
27
|
+
import { cliEntryPath } from '../../cost/hooks/entry.js';
|
|
28
|
+
// Static for the same reason as legacy-cost-hooks: allProviders() is empty unless
|
|
29
|
+
// someone has called registerBuiltinProviders(), and a diagnostic that silently
|
|
30
|
+
// finds nothing is worse than no diagnostic.
|
|
31
|
+
const HOOK_PLATFORMS = [
|
|
32
|
+
{ name: 'claude-code', status: claudeCodeHookStatus, install: installClaudeCodeHooks },
|
|
33
|
+
{ name: 'kiro', status: kiroHookStatus, install: installKiroHooks },
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* Platforms whose installed hook command differs from the current one. Read-only
|
|
37
|
+
* half, exported for reuse and direct testing.
|
|
38
|
+
*
|
|
39
|
+
* Only installed hooks count: an absent hook was never armed, which is a different
|
|
40
|
+
* condition that `aidlc cost hooks status` already reports.
|
|
41
|
+
*/
|
|
42
|
+
export function outdatedCostHookPlatforms(projectRoot) {
|
|
43
|
+
const outdated = [];
|
|
44
|
+
for (const p of HOOK_PLATFORMS) {
|
|
45
|
+
const status = p.status(projectRoot);
|
|
46
|
+
if (status.installed && status.outdated)
|
|
47
|
+
outdated.push(p.name);
|
|
48
|
+
}
|
|
49
|
+
return outdated;
|
|
50
|
+
}
|
|
51
|
+
function summarize(outdated) {
|
|
52
|
+
const one = outdated.length === 1;
|
|
53
|
+
return (`${outdated.length} cost hook${one ? '' : 's'} ` +
|
|
54
|
+
`still ${one ? 'uses' : 'use'} an older command form (${outdated.join(', ')}) — ` +
|
|
55
|
+
`re-installed so session end is reported and the stash stays accurate`);
|
|
56
|
+
}
|
|
57
|
+
export const outdatedCostHooks = {
|
|
58
|
+
id: 'outdated-cost-hooks',
|
|
59
|
+
tier: 'safe',
|
|
60
|
+
check(ctx) {
|
|
61
|
+
const outdated = outdatedCostHookPlatforms(ctx.projectRoot);
|
|
62
|
+
if (outdated.length === 0)
|
|
63
|
+
return { applicable: true, pending: false };
|
|
64
|
+
return { applicable: true, pending: true, description: summarize(outdated) };
|
|
65
|
+
},
|
|
66
|
+
apply(ctx) {
|
|
67
|
+
const outdated = outdatedCostHookPlatforms(ctx.projectRoot);
|
|
68
|
+
if (outdated.length === 0)
|
|
69
|
+
return { changed: false, summary: 'cost hook commands are current' };
|
|
70
|
+
// Hints only: the shim validates both at run time and neither reaches the
|
|
71
|
+
// command text (cost-capture-goes-dark/AC-1).
|
|
72
|
+
const nodePath = process.execPath;
|
|
73
|
+
const cliPath = cliEntryPath();
|
|
74
|
+
for (const p of HOOK_PLATFORMS) {
|
|
75
|
+
if (outdated.includes(p.name))
|
|
76
|
+
p.install(ctx.projectRoot, nodePath, cliPath);
|
|
77
|
+
}
|
|
78
|
+
return { changed: true, summary: summarize(outdated) };
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=outdated-cost-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outdated-cost-hooks.js","sourceRoot":"","sources":["../../../src/doctor/migrations/outdated-cost-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;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,kFAAkF;AAClF,gFAAgF;AAChF,6CAA6C;AAC7C,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,yBAAyB,CAAC,WAAmB;IAC3D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,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,QAAQ;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,SAAS,CAAC,QAAkB;IACnC,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;IAClC,OAAO,CACL,GAAG,QAAQ,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QAChD,SAAS,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,2BAA2B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;QACjF,sEAAsE,CACvE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAc;IAC1C,EAAE,EAAE,qBAAqB;IACzB,IAAI,EAAE,MAAM;IACZ,KAAK,CAAC,GAAG;QACP,MAAM,QAAQ,GAAG,yBAAyB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC5D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACvE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC/E,CAAC;IACD,KAAK,CAAC,GAAG;QACP,MAAM,QAAQ,GAAG,yBAAyB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC5D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,gCAAgC,EAAE,CAAC;QAEhG,0EAA0E;QAC1E,8CAA8C;QAC9C,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,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;gBAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC/E,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;IACzD,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* trust-run-actions migration: approve custom `run:` commands from
|
|
3
|
+
* `.aidlc/actions.yaml` that have no machine-local trust record.
|
|
4
|
+
*
|
|
5
|
+
* The event bus declines untrusted `run:` commands (see
|
|
6
|
+
* security/action-trust.ts for the threat model: `actions.yaml` is tracked, so
|
|
7
|
+
* a cloned repo's commands are the repo author's code). This migration is the
|
|
8
|
+
* approval path for commands that arrived by clone, pull, or hand edit —
|
|
9
|
+
* confirm tier, because the whole point is that a human reads the exact
|
|
10
|
+
* command before it ever runs.
|
|
11
|
+
*/
|
|
12
|
+
import type { Migration } from '../types.js';
|
|
13
|
+
export declare const trustRunActions: Migration;
|
|
14
|
+
//# sourceMappingURL=trust-run-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-run-actions.d.ts","sourceRoot":"","sources":["../../../src/doctor/migrations/trust-run-actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AA2B7C,eAAO,MAAM,eAAe,EAAE,SAuB7B,CAAC"}
|