specweave 3.0.3 → 3.0.5
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/.claude-plugin/marketplace.json +2 -2
- package/bin/specweave.js +7 -2
- package/dist/src/cli/commands/auto-handoff.d.ts +21 -5
- package/dist/src/cli/commands/auto-handoff.d.ts.map +1 -1
- package/dist/src/cli/commands/auto-handoff.js +132 -28
- package/dist/src/cli/commands/auto-handoff.js.map +1 -1
- package/dist/src/cli/commands/handoff.d.ts +10 -0
- package/dist/src/cli/commands/handoff.d.ts.map +1 -1
- package/dist/src/cli/commands/handoff.js +50 -0
- package/dist/src/cli/commands/handoff.js.map +1 -1
- package/dist/src/cli/commands/jev-helpers.d.ts +1 -1
- package/dist/src/cli/commands/jev-helpers.d.ts.map +1 -1
- package/dist/src/cli/commands/jev-helpers.js +8 -4
- package/dist/src/cli/commands/jev-helpers.js.map +1 -1
- package/dist/src/cli/commands/jev.js +4 -4
- package/dist/src/cli/commands/jev.js.map +1 -1
- package/dist/src/cli/commands/pickup.d.ts +11 -0
- package/dist/src/cli/commands/pickup.d.ts.map +1 -1
- package/dist/src/cli/commands/pickup.js +28 -8
- package/dist/src/cli/commands/pickup.js.map +1 -1
- package/dist/src/cli/helpers/init/gitignore-generator.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/gitignore-generator.js +26 -5
- package/dist/src/cli/helpers/init/gitignore-generator.js.map +1 -1
- package/dist/src/core/config/types.d.ts +2 -2
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/jev/client.d.ts +4 -1
- package/dist/src/core/jev/client.d.ts.map +1 -1
- package/dist/src/core/jev/client.js +118 -23
- package/dist/src/core/jev/client.js.map +1 -1
- package/dist/src/core/jev/config.d.ts +1 -1
- package/dist/src/core/jev/config.d.ts.map +1 -1
- package/dist/src/core/jev/config.js +8 -3
- package/dist/src/core/jev/config.js.map +1 -1
- package/dist/src/core/jev/openai.d.ts +21 -0
- package/dist/src/core/jev/openai.d.ts.map +1 -0
- package/dist/src/core/jev/openai.js +116 -0
- package/dist/src/core/jev/openai.js.map +1 -0
- package/dist/src/core/jev/usage.d.ts +4 -0
- package/dist/src/core/jev/usage.d.ts.map +1 -1
- package/dist/src/core/jev/usage.js +3 -0
- package/dist/src/core/jev/usage.js.map +1 -1
- package/dist/src/core/session/handoff-all.d.ts +124 -0
- package/dist/src/core/session/handoff-all.d.ts.map +1 -0
- package/dist/src/core/session/handoff-all.js +429 -0
- package/dist/src/core/session/handoff-all.js.map +1 -0
- package/dist/src/core/session/handoff-doc-format.d.ts +7 -0
- package/dist/src/core/session/handoff-doc-format.d.ts.map +1 -1
- package/dist/src/core/session/handoff-doc-format.js +12 -0
- package/dist/src/core/session/handoff-doc-format.js.map +1 -1
- package/dist/src/core/session/handoff-report.js +1 -0
- package/dist/src/core/session/handoff-report.js.map +1 -1
- package/dist/src/core/session/nested-repos.d.ts +90 -0
- package/dist/src/core/session/nested-repos.d.ts.map +1 -0
- package/dist/src/core/session/nested-repos.js +239 -0
- package/dist/src/core/session/nested-repos.js.map +1 -0
- package/dist/src/core/session/pickup.d.ts +1 -0
- package/dist/src/core/session/pickup.d.ts.map +1 -1
- package/dist/src/core/session/pickup.js +4 -4
- package/dist/src/core/session/pickup.js.map +1 -1
- package/dist/src/core/session/usage-guard.d.ts +84 -13
- package/dist/src/core/session/usage-guard.d.ts.map +1 -1
- package/dist/src/core/session/usage-guard.js +206 -15
- package/dist/src/core/session/usage-guard.js.map +1 -1
- package/dist/src/core/session/work-handoff.d.ts +2 -0
- package/dist/src/core/session/work-handoff.d.ts.map +1 -1
- package/dist/src/core/session/work-handoff.js +24 -3
- package/dist/src/core/session/work-handoff.js.map +1 -1
- package/dist/src/core/tasks/ledger.d.ts +5 -1
- package/dist/src/core/tasks/ledger.d.ts.map +1 -1
- package/dist/src/core/tasks/ledger.js +6 -2
- package/dist/src/core/tasks/ledger.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave/skills/handoff/SKILL.md +42 -5
- package/plugins/specweave/skills/jev/SKILL.md +81 -83
|
@@ -13,12 +13,15 @@
|
|
|
13
13
|
* rollout file the hook's `transcript_path` points at.
|
|
14
14
|
*
|
|
15
15
|
* The Stop hook (`specweave usage-guard`) then blocks the stop once per
|
|
16
|
-
* session when any window is at or past the threshold, and
|
|
17
|
-
* `specweave handoff`. Under the threshold it prints `{}`: no
|
|
16
|
+
* session and usage window when any window is at or past the threshold, and
|
|
17
|
+
* the agent runs `specweave handoff`. Under the threshold it prints `{}`: no
|
|
18
|
+
* tokens, no files.
|
|
18
19
|
*
|
|
19
20
|
* @module core/session/usage-guard
|
|
20
21
|
*/
|
|
21
22
|
export declare const DEFAULT_THRESHOLD = 90;
|
|
23
|
+
/** The shortest usage window; a session that hit the limit may hit it again after this. */
|
|
24
|
+
export declare const LIMIT_HIT_REARM_MS: number;
|
|
22
25
|
export interface UsageWindow {
|
|
23
26
|
/** "5-hour", "weekly", "spend" or "<n>-minute". */
|
|
24
27
|
name: string;
|
|
@@ -40,8 +43,58 @@ export declare function writeSettings(settings: AutoHandoffSettings | undefined,
|
|
|
40
43
|
export declare function claudeWindows(input: unknown): UsageWindow[];
|
|
41
44
|
/** Save what the status line saw, for the Stop hook of the same session. */
|
|
42
45
|
export declare function recordClaudeUsage(input: unknown, home?: string, now?: number): UsageWindow[];
|
|
46
|
+
/** Claude Code drops its own usage cache after an hour; so does the guard. */
|
|
47
|
+
export declare const CLAUDE_CACHE_MAX_AGE_MS: number;
|
|
48
|
+
/**
|
|
49
|
+
* Claude Code's own record of the plan usage: `cachedUsageUtilization` in
|
|
50
|
+
* ~/.claude.json (or $CLAUDE_CONFIG_DIR/.claude.json), written whenever Claude
|
|
51
|
+
* Code fetches the usage, in every kind of session: terminal, desktop, Remote
|
|
52
|
+
* Control and `claude -p`. It is the reading for sessions that never run a
|
|
53
|
+
* status line. Ignored when older than an hour or saved for another account.
|
|
54
|
+
*/
|
|
55
|
+
export declare function claudeCachedReading(opts?: {
|
|
56
|
+
env?: NodeJS.ProcessEnv;
|
|
57
|
+
home?: string;
|
|
58
|
+
now?: number;
|
|
59
|
+
}): UsageReading | undefined;
|
|
60
|
+
/** Desktop samples arrive about every 15 minutes; an older one may miss a jump to the limit. */
|
|
61
|
+
export declare const DESKTOP_SAMPLE_MAX_AGE_MS: number;
|
|
62
|
+
/** Where the Claude desktop app keeps its own files. */
|
|
63
|
+
export declare function desktopAppDir(home?: string, platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): string;
|
|
64
|
+
/**
|
|
65
|
+
* The Claude desktop app's plan-usage samples, `plan-usage-history.json`:
|
|
66
|
+
* `{ version: 2, samples: [{ t, org, u: { fh, sd } }] }`, 5-hour (`fh`) and
|
|
67
|
+
* 7-day (`sd`) percentages per organization, written about every 15 minutes
|
|
68
|
+
* while the app runs. It is the only reading desktop and Remote Control
|
|
69
|
+
* sessions leave on disk. Undocumented, so best effort: only the newest sample
|
|
70
|
+
* of this session's organization (CLAUDE_CODE_ORGANIZATION_UUID), and only
|
|
71
|
+
* when it is under 20 minutes old.
|
|
72
|
+
*/
|
|
73
|
+
export declare function desktopUsageReading(opts?: {
|
|
74
|
+
env?: NodeJS.ProcessEnv;
|
|
75
|
+
home?: string;
|
|
76
|
+
now?: number;
|
|
77
|
+
platform?: NodeJS.Platform;
|
|
78
|
+
}): UsageReading | undefined;
|
|
79
|
+
/** The freshest reading for a Claude Code session that runs no status line. */
|
|
80
|
+
export declare function claudeFallbackReading(opts?: {
|
|
81
|
+
env?: NodeJS.ProcessEnv;
|
|
82
|
+
home?: string;
|
|
83
|
+
now?: number;
|
|
84
|
+
platform?: NodeJS.Platform;
|
|
85
|
+
}): UsageReading | undefined;
|
|
43
86
|
/** Windows from the newest `token_count` event in a Codex rollout file. */
|
|
44
87
|
export declare function codexWindows(transcriptPath: string): UsageWindow[];
|
|
88
|
+
export interface UsageReading {
|
|
89
|
+
tool: 'Claude Code' | 'Codex';
|
|
90
|
+
/** Epoch milliseconds of the reading. */
|
|
91
|
+
at: number;
|
|
92
|
+
windows: UsageWindow[];
|
|
93
|
+
}
|
|
94
|
+
/** The newest usage any Claude Code session's status line recorded. */
|
|
95
|
+
export declare function latestClaudeReading(home?: string): UsageReading | undefined;
|
|
96
|
+
/** The rate limits in the newest Codex session log (~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl). */
|
|
97
|
+
export declare function latestCodexReading(home?: string): UsageReading | undefined;
|
|
45
98
|
/** The fullest window that has not reset yet. */
|
|
46
99
|
export declare function fullest(windows: UsageWindow[], now?: number): UsageWindow | undefined;
|
|
47
100
|
export declare function handoffInstruction(w: UsageWindow): string;
|
|
@@ -50,23 +103,39 @@ export interface GuardInput {
|
|
|
50
103
|
transcript_path?: string;
|
|
51
104
|
stop_hook_active?: boolean;
|
|
52
105
|
}
|
|
106
|
+
export interface GuardOutput {
|
|
107
|
+
/** Codex: block the stop; `reason` goes to the model. */
|
|
108
|
+
decision?: 'block';
|
|
109
|
+
reason?: string;
|
|
110
|
+
/**
|
|
111
|
+
* Claude Code: non-error context for the model; the turn continues so it can
|
|
112
|
+
* act on it. A `decision: "block"` would show the user "Stop hook error".
|
|
113
|
+
*/
|
|
114
|
+
hookSpecificOutput?: {
|
|
115
|
+
hookEventName: 'Stop';
|
|
116
|
+
additionalContext: string;
|
|
117
|
+
};
|
|
118
|
+
/** Claude Code: a line shown to the user. */
|
|
119
|
+
systemMessage?: string;
|
|
120
|
+
}
|
|
53
121
|
/**
|
|
54
|
-
* Stop-hook
|
|
55
|
-
*
|
|
122
|
+
* Stop-hook output. The first time a session is at or past the threshold in a
|
|
123
|
+
* usage window, it keeps the agent going so it hands off; otherwise `{}`.
|
|
56
124
|
*/
|
|
57
125
|
export declare function usageGuard(input: GuardInput, opts?: {
|
|
58
126
|
home?: string;
|
|
59
127
|
now?: number;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
};
|
|
128
|
+
env?: NodeJS.ProcessEnv;
|
|
129
|
+
platform?: NodeJS.Platform;
|
|
130
|
+
}): GuardOutput;
|
|
64
131
|
/** One short status line: the fullest windows, e.g. "5-hour 42% · weekly 12%". */
|
|
65
132
|
export declare function usageSummary(windows: UsageWindow[]): string;
|
|
66
133
|
/**
|
|
67
|
-
*
|
|
68
|
-
* with `error: "rate_limit"
|
|
69
|
-
*
|
|
134
|
+
* When a turn fails on the rate limit, Claude Code and Grok Build fire
|
|
135
|
+
* `StopFailure` with `error: "rate_limit"`. It is the backstop for a session
|
|
136
|
+
* that ran out before the Stop hook could ask for a handoff, and the only
|
|
137
|
+
* signal Grok Build gives (it shows no usage percentage). Grok's hook input is
|
|
138
|
+
* camelCase (`sessionId`, `workspaceRoot`), Claude Code's snake_case.
|
|
70
139
|
*/
|
|
71
140
|
export interface LimitHitInput {
|
|
72
141
|
sessionId?: string;
|
|
@@ -78,8 +147,10 @@ export interface LimitHitInput {
|
|
|
78
147
|
/**
|
|
79
148
|
* Where a rate-limited turn should hand off, or undefined when it should not:
|
|
80
149
|
* auto-handoff is off, the failure is not a rate limit, the session already
|
|
81
|
-
*
|
|
82
|
-
*
|
|
150
|
+
* already wrote one in the last five hours, or the directory is not a
|
|
151
|
+
* SpecWeave project. Writes its marker before returning, so a retry storm
|
|
152
|
+
* hands off once. The marker is separate from the Stop hook's: a session that
|
|
153
|
+
* was asked to hand off at 90% and still ran out writes a fresh handoff.
|
|
83
154
|
*/
|
|
84
155
|
export declare function limitHitTarget(input: LimitHitInput, opts?: {
|
|
85
156
|
home?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-guard.d.ts","sourceRoot":"","sources":["../../../../src/core/session/usage-guard.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"usage-guard.d.ts","sourceRoot":"","sources":["../../../../src/core/session/usage-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
* rollout file the hook's `transcript_path` points at.
|
|
14
14
|
*
|
|
15
15
|
* The Stop hook (`specweave usage-guard`) then blocks the stop once per
|
|
16
|
-
* session when any window is at or past the threshold, and
|
|
17
|
-
* `specweave handoff`. Under the threshold it prints `{}`: no
|
|
16
|
+
* session and usage window when any window is at or past the threshold, and
|
|
17
|
+
* the agent runs `specweave handoff`. Under the threshold it prints `{}`: no
|
|
18
|
+
* tokens, no files.
|
|
18
19
|
*
|
|
19
20
|
* @module core/session/usage-guard
|
|
20
21
|
*/
|
|
@@ -23,6 +24,8 @@ import * as os from 'os';
|
|
|
23
24
|
import * as path from 'path';
|
|
24
25
|
import { findProjectRoot } from '../../utils/find-project-root.js';
|
|
25
26
|
export const DEFAULT_THRESHOLD = 90;
|
|
27
|
+
/** The shortest usage window; a session that hit the limit may hit it again after this. */
|
|
28
|
+
export const LIMIT_HIT_REARM_MS = 5 * 60 * 60 * 1000;
|
|
26
29
|
export function specweaveHome(home = os.homedir()) {
|
|
27
30
|
return path.join(home, '.specweave');
|
|
28
31
|
}
|
|
@@ -89,6 +92,104 @@ function readClaudeUsage(sessionId, home) {
|
|
|
89
92
|
return [];
|
|
90
93
|
}
|
|
91
94
|
}
|
|
95
|
+
/** Claude Code drops its own usage cache after an hour; so does the guard. */
|
|
96
|
+
export const CLAUDE_CACHE_MAX_AGE_MS = 60 * 60 * 1000;
|
|
97
|
+
function claudeConfigFile(env, home = os.homedir()) {
|
|
98
|
+
const dir = env.CLAUDE_CONFIG_DIR?.trim();
|
|
99
|
+
return dir ? path.join(dir, '.claude.json') : path.join(home, '.claude.json');
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Claude Code's own record of the plan usage: `cachedUsageUtilization` in
|
|
103
|
+
* ~/.claude.json (or $CLAUDE_CONFIG_DIR/.claude.json), written whenever Claude
|
|
104
|
+
* Code fetches the usage, in every kind of session: terminal, desktop, Remote
|
|
105
|
+
* Control and `claude -p`. It is the reading for sessions that never run a
|
|
106
|
+
* status line. Ignored when older than an hour or saved for another account.
|
|
107
|
+
*/
|
|
108
|
+
export function claudeCachedReading(opts = {}) {
|
|
109
|
+
const now = opts.now ?? Date.now();
|
|
110
|
+
let cfg;
|
|
111
|
+
try {
|
|
112
|
+
cfg = JSON.parse(fs.readFileSync(claudeConfigFile(opts.env ?? process.env, opts.home), 'utf8'));
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
const cache = cfg?.cachedUsageUtilization;
|
|
118
|
+
const at = cache?.fetchedAtMs;
|
|
119
|
+
if (!cache || typeof at !== 'number' || now - at < 0 || now - at > CLAUDE_CACHE_MAX_AGE_MS)
|
|
120
|
+
return undefined;
|
|
121
|
+
const account = cfg.oauthAccount?.accountUuid;
|
|
122
|
+
if (account && cache.accountUuid && account !== cache.accountUuid)
|
|
123
|
+
return undefined;
|
|
124
|
+
const u = cache.utilization ?? {};
|
|
125
|
+
const windows = [];
|
|
126
|
+
const names = { five_hour: '5-hour', seven_day: 'weekly' };
|
|
127
|
+
for (const [key, name] of Object.entries(names)) {
|
|
128
|
+
const w = u[key];
|
|
129
|
+
if (!w || typeof w.utilization !== 'number')
|
|
130
|
+
continue;
|
|
131
|
+
const reset = w.resets_at ? Date.parse(w.resets_at) : NaN;
|
|
132
|
+
windows.push({ name, percent: w.utilization, ...(Number.isFinite(reset) ? { resetsAt: Math.floor(reset / 1000) } : {}) });
|
|
133
|
+
}
|
|
134
|
+
return windows.length ? { tool: 'Claude Code', at, windows } : undefined;
|
|
135
|
+
}
|
|
136
|
+
/** Desktop samples arrive about every 15 minutes; an older one may miss a jump to the limit. */
|
|
137
|
+
export const DESKTOP_SAMPLE_MAX_AGE_MS = 20 * 60 * 1000;
|
|
138
|
+
/** Where the Claude desktop app keeps its own files. */
|
|
139
|
+
export function desktopAppDir(home = os.homedir(), platform = process.platform, env = process.env) {
|
|
140
|
+
if (platform === 'darwin')
|
|
141
|
+
return path.join(home, 'Library', 'Application Support', 'Claude');
|
|
142
|
+
if (platform === 'win32')
|
|
143
|
+
return path.join(env.APPDATA ?? path.join(home, 'AppData', 'Roaming'), 'Claude');
|
|
144
|
+
return path.join(env.XDG_CONFIG_HOME ?? path.join(home, '.config'), 'Claude');
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The Claude desktop app's plan-usage samples, `plan-usage-history.json`:
|
|
148
|
+
* `{ version: 2, samples: [{ t, org, u: { fh, sd } }] }`, 5-hour (`fh`) and
|
|
149
|
+
* 7-day (`sd`) percentages per organization, written about every 15 minutes
|
|
150
|
+
* while the app runs. It is the only reading desktop and Remote Control
|
|
151
|
+
* sessions leave on disk. Undocumented, so best effort: only the newest sample
|
|
152
|
+
* of this session's organization (CLAUDE_CODE_ORGANIZATION_UUID), and only
|
|
153
|
+
* when it is under 20 minutes old.
|
|
154
|
+
*/
|
|
155
|
+
export function desktopUsageReading(opts = {}) {
|
|
156
|
+
const env = opts.env ?? process.env;
|
|
157
|
+
const now = opts.now ?? Date.now();
|
|
158
|
+
let samples;
|
|
159
|
+
try {
|
|
160
|
+
const raw = JSON.parse(fs.readFileSync(path.join(desktopAppDir(opts.home, opts.platform, env), 'plan-usage-history.json'), 'utf8'));
|
|
161
|
+
samples = Array.isArray(raw?.samples) ? raw.samples : [];
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
let org = env.CLAUDE_CODE_ORGANIZATION_UUID?.trim();
|
|
167
|
+
if (!org) {
|
|
168
|
+
const orgs = new Set(samples.map((x) => x?.org).filter((o) => typeof o === 'string'));
|
|
169
|
+
if (orgs.size !== 1)
|
|
170
|
+
return undefined; // several accounts and no way to tell which is this one
|
|
171
|
+
org = [...orgs][0];
|
|
172
|
+
}
|
|
173
|
+
let newest;
|
|
174
|
+
for (const x of samples) {
|
|
175
|
+
if (x?.org === org && typeof x.t === 'number' && (!newest || x.t > newest.t))
|
|
176
|
+
newest = x;
|
|
177
|
+
}
|
|
178
|
+
const at = newest?.t;
|
|
179
|
+
if (!newest || at === undefined || now - at < 0 || now - at > DESKTOP_SAMPLE_MAX_AGE_MS)
|
|
180
|
+
return undefined;
|
|
181
|
+
const windows = [];
|
|
182
|
+
if (typeof newest.u?.fh === 'number')
|
|
183
|
+
windows.push({ name: '5-hour', percent: newest.u.fh });
|
|
184
|
+
if (typeof newest.u?.sd === 'number')
|
|
185
|
+
windows.push({ name: 'weekly', percent: newest.u.sd });
|
|
186
|
+
return windows.length ? { tool: 'Claude Code', at, windows } : undefined;
|
|
187
|
+
}
|
|
188
|
+
/** The freshest reading for a Claude Code session that runs no status line. */
|
|
189
|
+
export function claudeFallbackReading(opts = {}) {
|
|
190
|
+
const readings = [desktopUsageReading(opts), claudeCachedReading(opts)].filter((r) => !!r);
|
|
191
|
+
return readings.sort((a, b) => b.at - a.at)[0];
|
|
192
|
+
}
|
|
92
193
|
/** Windows from the newest `token_count` event in a Codex rollout file. */
|
|
93
194
|
export function codexWindows(transcriptPath) {
|
|
94
195
|
let text;
|
|
@@ -132,20 +233,92 @@ export function codexWindows(transcriptPath) {
|
|
|
132
233
|
}
|
|
133
234
|
return [];
|
|
134
235
|
}
|
|
236
|
+
/** The newest usage any Claude Code session's status line recorded. */
|
|
237
|
+
export function latestClaudeReading(home) {
|
|
238
|
+
let best;
|
|
239
|
+
let names = [];
|
|
240
|
+
try {
|
|
241
|
+
names = fs.readdirSync(usageDir(home)).filter((n) => n.endsWith('.json'));
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
246
|
+
for (const name of names) {
|
|
247
|
+
try {
|
|
248
|
+
const saved = JSON.parse(fs.readFileSync(path.join(usageDir(home), name), 'utf8'));
|
|
249
|
+
const at = Date.parse(saved.at ?? '');
|
|
250
|
+
if (saved.windows?.length && at && (!best || at > best.at))
|
|
251
|
+
best = { tool: 'Claude Code', at, windows: saved.windows };
|
|
252
|
+
}
|
|
253
|
+
catch { /* skip a half-written file */ }
|
|
254
|
+
}
|
|
255
|
+
return best;
|
|
256
|
+
}
|
|
257
|
+
/** The newest file under `dir` whose name matches, walking date folders newest first. */
|
|
258
|
+
function newestFile(dir, match, depth) {
|
|
259
|
+
let entries;
|
|
260
|
+
try {
|
|
261
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
const files = entries.filter((e) => e.isFile() && match(e.name)).map((e) => path.join(dir, e.name));
|
|
267
|
+
if (files.length)
|
|
268
|
+
return files.sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs)[0];
|
|
269
|
+
if (depth <= 0)
|
|
270
|
+
return undefined;
|
|
271
|
+
for (const sub of entries.filter((e) => e.isDirectory()).map((e) => e.name).sort().reverse()) {
|
|
272
|
+
const found = newestFile(path.join(dir, sub), match, depth - 1);
|
|
273
|
+
if (found)
|
|
274
|
+
return found;
|
|
275
|
+
}
|
|
276
|
+
return undefined;
|
|
277
|
+
}
|
|
278
|
+
/** The rate limits in the newest Codex session log (~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl). */
|
|
279
|
+
export function latestCodexReading(home = os.homedir()) {
|
|
280
|
+
const file = newestFile(path.join(home, '.codex', 'sessions'), (n) => n.startsWith('rollout-') && n.endsWith('.jsonl'), 3);
|
|
281
|
+
if (!file)
|
|
282
|
+
return undefined;
|
|
283
|
+
const windows = codexWindows(file);
|
|
284
|
+
return windows.length ? { tool: 'Codex', at: fs.statSync(file).mtimeMs, windows } : undefined;
|
|
285
|
+
}
|
|
135
286
|
/** The fullest window that has not reset yet. */
|
|
136
287
|
export function fullest(windows, now = Date.now()) {
|
|
137
288
|
return windows
|
|
138
289
|
.filter((w) => !w.resetsAt || w.resetsAt * 1000 > now)
|
|
139
290
|
.sort((a, b) => b.percent - a.percent)[0];
|
|
140
291
|
}
|
|
292
|
+
/**
|
|
293
|
+
* Whether a session may be asked to hand off (again). A session is asked once
|
|
294
|
+
* per usage window: when the window that triggered the handoff has reset, a
|
|
295
|
+
* session that kept going is guarded again. A marker without a reset time
|
|
296
|
+
* stays spent.
|
|
297
|
+
*/
|
|
298
|
+
function rearmed(marker, now) {
|
|
299
|
+
let text;
|
|
300
|
+
try {
|
|
301
|
+
text = fs.readFileSync(marker, 'utf8');
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
try {
|
|
307
|
+
const resetsAt = JSON.parse(text).resetsAt;
|
|
308
|
+
return typeof resetsAt === 'number' && resetsAt * 1000 <= now;
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
141
314
|
export function handoffInstruction(w) {
|
|
142
315
|
const pct = Math.round(w.percent);
|
|
143
316
|
return `Usage is at ${pct}% of the ${w.name} limit. Hand off now so no work is lost: run \`specweave handoff --reason "usage at ${pct}% of the ${w.name} limit"\`, ` +
|
|
144
317
|
`then tell the user in one line that they can say "pick up" in another tool or account to continue, and stop.`;
|
|
145
318
|
}
|
|
146
319
|
/**
|
|
147
|
-
* Stop-hook
|
|
148
|
-
*
|
|
320
|
+
* Stop-hook output. The first time a session is at or past the threshold in a
|
|
321
|
+
* usage window, it keeps the agent going so it hands off; otherwise `{}`.
|
|
149
322
|
*/
|
|
150
323
|
export function usageGuard(input, opts = {}) {
|
|
151
324
|
const settings = readSettings(opts.home);
|
|
@@ -154,22 +327,33 @@ export function usageGuard(input, opts = {}) {
|
|
|
154
327
|
const id = safeId(String(input.session_id ?? ''));
|
|
155
328
|
if (!id)
|
|
156
329
|
return {};
|
|
330
|
+
const now = opts.now ?? Date.now();
|
|
157
331
|
const marker = path.join(usageDir(opts.home), `${id}.handed-off`);
|
|
158
|
-
if (
|
|
332
|
+
if (!rearmed(marker, now))
|
|
159
333
|
return {};
|
|
160
334
|
const rollout = input.transcript_path && path.basename(input.transcript_path).startsWith('rollout-') ? input.transcript_path : undefined;
|
|
161
|
-
|
|
162
|
-
|
|
335
|
+
// Codex: its session log. Claude Code: what the status line saw in this
|
|
336
|
+
// session (terminal only), else the desktop app's samples or Claude Code's
|
|
337
|
+
// own usage cache, whichever is fresher.
|
|
338
|
+
let windows = rollout ? codexWindows(rollout) : readClaudeUsage(id, opts.home);
|
|
339
|
+
if (!rollout && !windows.length)
|
|
340
|
+
windows = claudeFallbackReading({ env: opts.env, home: opts.home, now, platform: opts.platform })?.windows ?? [];
|
|
341
|
+
const top = fullest(windows, now);
|
|
163
342
|
if (!top || top.percent < settings.at)
|
|
164
343
|
return {};
|
|
165
344
|
try {
|
|
166
345
|
fs.mkdirSync(path.dirname(marker), { recursive: true });
|
|
167
|
-
fs.writeFileSync(marker,
|
|
346
|
+
fs.writeFileSync(marker, JSON.stringify({ at: new Date(now).toISOString(), window: top.name, percent: top.percent, ...(top.resetsAt ? { resetsAt: top.resetsAt } : {}) }) + '\n');
|
|
168
347
|
}
|
|
169
348
|
catch {
|
|
170
349
|
return {}; // without the marker it would fire every turn; stay quiet instead
|
|
171
350
|
}
|
|
172
|
-
|
|
351
|
+
if (rollout)
|
|
352
|
+
return { decision: 'block', reason: handoffInstruction(top) };
|
|
353
|
+
return {
|
|
354
|
+
hookSpecificOutput: { hookEventName: 'Stop', additionalContext: handoffInstruction(top) },
|
|
355
|
+
systemMessage: `Auto-handoff: usage is at ${Math.round(top.percent)}% of the ${top.name} limit, so this session is handing off. Say "pick up" in another tool or account to continue.`,
|
|
356
|
+
};
|
|
173
357
|
}
|
|
174
358
|
/** One short status line: the fullest windows, e.g. "5-hour 42% · weekly 12%". */
|
|
175
359
|
export function usageSummary(windows) {
|
|
@@ -178,8 +362,10 @@ export function usageSummary(windows) {
|
|
|
178
362
|
/**
|
|
179
363
|
* Where a rate-limited turn should hand off, or undefined when it should not:
|
|
180
364
|
* auto-handoff is off, the failure is not a rate limit, the session already
|
|
181
|
-
*
|
|
182
|
-
*
|
|
365
|
+
* already wrote one in the last five hours, or the directory is not a
|
|
366
|
+
* SpecWeave project. Writes its marker before returning, so a retry storm
|
|
367
|
+
* hands off once. The marker is separate from the Stop hook's: a session that
|
|
368
|
+
* was asked to hand off at 90% and still ran out writes a fresh handoff.
|
|
183
369
|
*/
|
|
184
370
|
export function limitHitTarget(input, opts = {}) {
|
|
185
371
|
if (!readSettings(opts.home))
|
|
@@ -193,12 +379,17 @@ export function limitHitTarget(input, opts = {}) {
|
|
|
193
379
|
const root = start ? findProjectRoot(start) ?? undefined : undefined;
|
|
194
380
|
if (!root)
|
|
195
381
|
return undefined;
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
382
|
+
const now = opts.now ?? Date.now();
|
|
383
|
+
const marker = path.join(usageDir(opts.home), `${id}.limit-hit`);
|
|
384
|
+
try {
|
|
385
|
+
if (now - fs.statSync(marker).mtimeMs < LIMIT_HIT_REARM_MS)
|
|
386
|
+
return undefined;
|
|
387
|
+
}
|
|
388
|
+
catch { /* no marker yet */ }
|
|
199
389
|
try {
|
|
200
390
|
fs.mkdirSync(path.dirname(marker), { recursive: true });
|
|
201
|
-
fs.writeFileSync(marker, `${new Date(
|
|
391
|
+
fs.writeFileSync(marker, `${new Date(now).toISOString()} rate_limit\n`);
|
|
392
|
+
fs.utimesSync(marker, now / 1000, now / 1000);
|
|
202
393
|
}
|
|
203
394
|
catch {
|
|
204
395
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-guard.js","sourceRoot":"","sources":["../../../../src/core/session/usage-guard.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usage-guard.js","sourceRoot":"","sources":["../../../../src/core/session/usage-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -57,6 +57,8 @@ export declare class AmbiguousActiveIncrementError extends Error {
|
|
|
57
57
|
constructor(candidates: string[]);
|
|
58
58
|
}
|
|
59
59
|
export declare const HANDOFF_POINTER_FILE = "handoff-latest.txt";
|
|
60
|
+
/** Where the generated doc goes when the increment's `handoff.md` was written by hand. */
|
|
61
|
+
export declare const AUTO_HANDOFF_FILE = "handoff.auto.md";
|
|
60
62
|
export declare function buildWorkHandoff(repoRoot: string, opts?: WorkHandoffOptions): Promise<WorkHandoffResult>;
|
|
61
63
|
/** Read-only export for callers that want the active ids (e.g. session-start context). */
|
|
62
64
|
export declare function activeIncrementIds(projectRoot: string): string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"work-handoff.d.ts","sourceRoot":"","sources":["../../../../src/core/session/work-handoff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAeH,OAAO,
|
|
1
|
+
{"version":3,"file":"work-handoff.d.ts","sourceRoot":"","sources":["../../../../src/core/session/work-handoff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAeH,OAAO,EASL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,6EAA6E;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AAED,qBAAa,6BAA8B,SAAQ,KAAK;aAC1B,UAAU,EAAE,MAAM,EAAE;gBAApB,UAAU,EAAE,MAAM,EAAE;CAIjD;AAED,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AACzD,0FAA0F;AAC1F,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAEnD,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA8GlH;AAMD,0FAA0F;AAC1F,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAEhE;AA8CD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BxD;AAkDD,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAIjE"}
|
|
@@ -27,7 +27,7 @@ import { resolveIncrement, listActiveIncrementIds, readLeaseHours, IncrementReso
|
|
|
27
27
|
import { parseSpecAcs } from '../tasks/verify-runner.js';
|
|
28
28
|
import { INTENT_BOARD_PATH, readIntentContext } from '../intent/portable-context.js';
|
|
29
29
|
import { serializeHandoffPointer } from './handoff-pointer.js';
|
|
30
|
-
import { renderHandoffDoc, renderPastePrompt, DOC_FORMAT_MARKER, LEGACY_DOC_FORMAT_MARKER, } from './handoff-doc-format.js';
|
|
30
|
+
import { renderHandoffDoc, renderPastePrompt, DOC_FORMAT_MARKER, LEGACY_DOC_FORMAT_MARKER, extractKeepBlocks, } from './handoff-doc-format.js';
|
|
31
31
|
export class AmbiguousActiveIncrementError extends Error {
|
|
32
32
|
constructor(candidates) {
|
|
33
33
|
super(`Multiple active increments — pass an explicit id. Candidates: ${candidates.join(', ')}`);
|
|
@@ -36,6 +36,8 @@ export class AmbiguousActiveIncrementError extends Error {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
export const HANDOFF_POINTER_FILE = 'handoff-latest.txt';
|
|
39
|
+
/** Where the generated doc goes when the increment's `handoff.md` was written by hand. */
|
|
40
|
+
export const AUTO_HANDOFF_FILE = 'handoff.auto.md';
|
|
39
41
|
export async function buildWorkHandoff(repoRoot, opts = {}) {
|
|
40
42
|
const passedRoot = path.resolve(repoRoot);
|
|
41
43
|
const resolved = resolveEffectiveRoot(passedRoot);
|
|
@@ -123,6 +125,13 @@ export async function buildWorkHandoff(repoRoot, opts = {}) {
|
|
|
123
125
|
redactionCounts: scrubbed.counts,
|
|
124
126
|
};
|
|
125
127
|
docInput.released = released;
|
|
128
|
+
// Hand-kept blocks of the previous version survive regeneration (scrubbed like the rest).
|
|
129
|
+
docInput.keep = readKeepBlocks(docPath).map((b) => {
|
|
130
|
+
const r = scrubSecrets(b);
|
|
131
|
+
for (const [k, v] of Object.entries(r.counts))
|
|
132
|
+
scrubbed.counts[k] = (scrubbed.counts[k] ?? 0) + v;
|
|
133
|
+
return r.scrubbed;
|
|
134
|
+
});
|
|
126
135
|
// The HTML timeline travels with the handoff as evidence of who did what.
|
|
127
136
|
if (!opts.checkpoint && incrementId && incDir) {
|
|
128
137
|
try {
|
|
@@ -238,7 +247,9 @@ export function readDecisions(filePath) {
|
|
|
238
247
|
* Decide doc + diff paths.
|
|
239
248
|
*
|
|
240
249
|
* - explicit `out`: use it (diff is a sibling `.diff`).
|
|
241
|
-
* - SpecWeave + active increment: the increment's own `handoff.md
|
|
250
|
+
* - SpecWeave + active increment: the increment's own `handoff.md`, unless a
|
|
251
|
+
* hand-written one (no generator marker) is there: then `handoff.auto.md`,
|
|
252
|
+
* so a person's handoff is never overwritten.
|
|
242
253
|
* - SpecWeave, no active increment: `state/handoff-latest.md`.
|
|
243
254
|
* - non-SpecWeave: `.handoff/HANDOFF.md`, unless a foreign root `./HANDOFF.md`
|
|
244
255
|
* without the marker exists (ownership sentinel still routes to `.handoff/`).
|
|
@@ -249,7 +260,9 @@ function resolveWritePaths(effectiveRoot, isSpecWeave, incDir, out) {
|
|
|
249
260
|
return { docPath: abs, diffPath: siblingDiff(abs) };
|
|
250
261
|
}
|
|
251
262
|
if (isSpecWeave && incDir) {
|
|
252
|
-
|
|
263
|
+
const own = path.join(incDir, 'handoff.md');
|
|
264
|
+
const docPath = isForeignHandoffFile(own) ? path.join(incDir, AUTO_HANDOFF_FILE) : own;
|
|
265
|
+
return { docPath, diffPath: path.join(incDir, 'handoff.diff') };
|
|
253
266
|
}
|
|
254
267
|
// No increment (SpecWeave without an active one, or plain repo): root
|
|
255
268
|
// ./HANDOFF.md if it is ours, else .handoff/ (gitignored).
|
|
@@ -278,6 +291,14 @@ export function isForeignHandoffFile(handoffPath) {
|
|
|
278
291
|
const content = fs.readFileSync(handoffPath, 'utf-8');
|
|
279
292
|
return !content.includes(DOC_FORMAT_MARKER) && !content.includes(LEGACY_DOC_FORMAT_MARKER);
|
|
280
293
|
}
|
|
294
|
+
function readKeepBlocks(docPath) {
|
|
295
|
+
try {
|
|
296
|
+
return extractKeepBlocks(fs.readFileSync(docPath, 'utf-8'));
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
return [];
|
|
300
|
+
}
|
|
301
|
+
}
|
|
281
302
|
function writeDoc(docPath, markdown) {
|
|
282
303
|
fs.mkdirSync(path.dirname(docPath), { recursive: true });
|
|
283
304
|
fs.writeFileSync(docPath, markdown, 'utf-8');
|