specweave 3.0.2 → 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.
Files changed (92) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/bin/specweave.js +7 -2
  3. package/dist/src/cli/commands/auto-handoff.d.ts +21 -5
  4. package/dist/src/cli/commands/auto-handoff.d.ts.map +1 -1
  5. package/dist/src/cli/commands/auto-handoff.js +132 -28
  6. package/dist/src/cli/commands/auto-handoff.js.map +1 -1
  7. package/dist/src/cli/commands/handoff.d.ts +10 -0
  8. package/dist/src/cli/commands/handoff.d.ts.map +1 -1
  9. package/dist/src/cli/commands/handoff.js +50 -0
  10. package/dist/src/cli/commands/handoff.js.map +1 -1
  11. package/dist/src/cli/commands/jev-helpers.d.ts +1 -1
  12. package/dist/src/cli/commands/jev-helpers.d.ts.map +1 -1
  13. package/dist/src/cli/commands/jev-helpers.js +8 -4
  14. package/dist/src/cli/commands/jev-helpers.js.map +1 -1
  15. package/dist/src/cli/commands/jev.js +4 -4
  16. package/dist/src/cli/commands/jev.js.map +1 -1
  17. package/dist/src/cli/commands/pickup.d.ts +11 -0
  18. package/dist/src/cli/commands/pickup.d.ts.map +1 -1
  19. package/dist/src/cli/commands/pickup.js +28 -8
  20. package/dist/src/cli/commands/pickup.js.map +1 -1
  21. package/dist/src/cli/commands/refresh-plugins.d.ts.map +1 -1
  22. package/dist/src/cli/commands/refresh-plugins.js +3 -9
  23. package/dist/src/cli/commands/refresh-plugins.js.map +1 -1
  24. package/dist/src/cli/commands/task.js +6 -2
  25. package/dist/src/cli/commands/task.js.map +1 -1
  26. package/dist/src/cli/helpers/init/gitignore-generator.d.ts.map +1 -1
  27. package/dist/src/cli/helpers/init/gitignore-generator.js +35 -11
  28. package/dist/src/cli/helpers/init/gitignore-generator.js.map +1 -1
  29. package/dist/src/core/config/types.d.ts +2 -2
  30. package/dist/src/core/config/types.d.ts.map +1 -1
  31. package/dist/src/core/doctor/checkers/installation-health-checker.d.ts +3 -1
  32. package/dist/src/core/doctor/checkers/installation-health-checker.d.ts.map +1 -1
  33. package/dist/src/core/doctor/checkers/installation-health-checker.js +36 -62
  34. package/dist/src/core/doctor/checkers/installation-health-checker.js.map +1 -1
  35. package/dist/src/core/jev/client.d.ts +4 -1
  36. package/dist/src/core/jev/client.d.ts.map +1 -1
  37. package/dist/src/core/jev/client.js +118 -23
  38. package/dist/src/core/jev/client.js.map +1 -1
  39. package/dist/src/core/jev/config.d.ts +1 -1
  40. package/dist/src/core/jev/config.d.ts.map +1 -1
  41. package/dist/src/core/jev/config.js +8 -3
  42. package/dist/src/core/jev/config.js.map +1 -1
  43. package/dist/src/core/jev/openai.d.ts +21 -0
  44. package/dist/src/core/jev/openai.d.ts.map +1 -0
  45. package/dist/src/core/jev/openai.js +116 -0
  46. package/dist/src/core/jev/openai.js.map +1 -0
  47. package/dist/src/core/jev/usage.d.ts +4 -0
  48. package/dist/src/core/jev/usage.d.ts.map +1 -1
  49. package/dist/src/core/jev/usage.js +3 -0
  50. package/dist/src/core/jev/usage.js.map +1 -1
  51. package/dist/src/core/session/handoff-all.d.ts +124 -0
  52. package/dist/src/core/session/handoff-all.d.ts.map +1 -0
  53. package/dist/src/core/session/handoff-all.js +429 -0
  54. package/dist/src/core/session/handoff-all.js.map +1 -0
  55. package/dist/src/core/session/handoff-doc-format.d.ts +7 -0
  56. package/dist/src/core/session/handoff-doc-format.d.ts.map +1 -1
  57. package/dist/src/core/session/handoff-doc-format.js +12 -0
  58. package/dist/src/core/session/handoff-doc-format.js.map +1 -1
  59. package/dist/src/core/session/handoff-report.js +1 -0
  60. package/dist/src/core/session/handoff-report.js.map +1 -1
  61. package/dist/src/core/session/nested-repos.d.ts +90 -0
  62. package/dist/src/core/session/nested-repos.d.ts.map +1 -0
  63. package/dist/src/core/session/nested-repos.js +239 -0
  64. package/dist/src/core/session/nested-repos.js.map +1 -0
  65. package/dist/src/core/session/pickup.d.ts +1 -0
  66. package/dist/src/core/session/pickup.d.ts.map +1 -1
  67. package/dist/src/core/session/pickup.js +4 -4
  68. package/dist/src/core/session/pickup.js.map +1 -1
  69. package/dist/src/core/session/usage-guard.d.ts +84 -13
  70. package/dist/src/core/session/usage-guard.d.ts.map +1 -1
  71. package/dist/src/core/session/usage-guard.js +206 -15
  72. package/dist/src/core/session/usage-guard.js.map +1 -1
  73. package/dist/src/core/session/work-handoff.d.ts +2 -0
  74. package/dist/src/core/session/work-handoff.d.ts.map +1 -1
  75. package/dist/src/core/session/work-handoff.js +24 -3
  76. package/dist/src/core/session/work-handoff.js.map +1 -1
  77. package/dist/src/core/tasks/ledger.d.ts +5 -1
  78. package/dist/src/core/tasks/ledger.d.ts.map +1 -1
  79. package/dist/src/core/tasks/ledger.js +6 -2
  80. package/dist/src/core/tasks/ledger.js.map +1 -1
  81. package/dist/src/utils/cleanup-stale-plugins.d.ts +0 -8
  82. package/dist/src/utils/cleanup-stale-plugins.d.ts.map +1 -1
  83. package/dist/src/utils/cleanup-stale-plugins.js +0 -100
  84. package/dist/src/utils/cleanup-stale-plugins.js.map +1 -1
  85. package/dist/src/utils/plugin-copier.d.ts +10 -8
  86. package/dist/src/utils/plugin-copier.d.ts.map +1 -1
  87. package/dist/src/utils/plugin-copier.js +17 -55
  88. package/dist/src/utils/plugin-copier.js.map +1 -1
  89. package/package.json +1 -1
  90. package/plugins/specweave/.claude-plugin/plugin.json +1 -1
  91. package/plugins/specweave/skills/handoff/SKILL.md +42 -5
  92. 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 the agent runs
17
- * `specweave handoff`. Under the threshold it prints `{}`: no tokens, no files.
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 decision. Returns a block (the agent keeps going and hands off)
55
- * the first time a session is at or past the threshold, otherwise `{}`.
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
- decision?: 'block';
62
- reason?: string;
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
- * Grok Build shows no usage percentage to scripts, but it fires `StopFailure`
68
- * with `error: "rate_limit"` when a turn hits the limit. Its hook input is
69
- * camelCase (`sessionId`, `cwd`, `workspaceRoot`).
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
- * handed off, or the directory is not a SpecWeave project. Writes the
82
- * once-per-session marker before returning, so a retry storm hands off once.
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;;;;;;;;;;;;;;;;;;;GAmBG;AAOH,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,aAAa;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sFAAsF;IACtF,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,aAAa,CAAC,IAAI,SAAe,GAAG,MAAM,CAEzD;AAUD,wBAAgB,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAQ3E;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,mBAAmB,GAAG,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAK5F;AAED,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,EAAE,CAU3D;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,WAAW,EAAE,CAShG;AAYD,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW,EAAE,CAkClE;AAED,iDAAiD;AACjD,wBAAgB,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,GAAG,SAAa,GAAG,WAAW,GAAG,SAAS,CAIzF;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAIzD;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAoBjI;AAED,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAE3D;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,GAAG,SAAS,CAiBnH"}
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 the agent runs
17
- * `specweave handoff`. Under the threshold it prints `{}`: no tokens, no files.
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 decision. Returns a block (the agent keeps going and hands off)
148
- * the first time a session is at or past the threshold, otherwise `{}`.
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 (fs.existsSync(marker))
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
- const windows = [...readClaudeUsage(id, opts.home), ...(rollout ? codexWindows(rollout) : [])];
162
- const top = fullest(windows, opts.now);
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, `${new Date(opts.now ?? Date.now()).toISOString()} ${top.name} ${top.percent}\n`);
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
- return { decision: 'block', reason: handoffInstruction(top) };
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
- * handed off, or the directory is not a SpecWeave project. Writes the
182
- * once-per-session marker before returning, so a retry storm hands off once.
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 marker = path.join(usageDir(opts.home), `${id}.handed-off`);
197
- if (fs.existsSync(marker))
198
- return undefined;
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(opts.now ?? Date.now()).toISOString()} rate_limit\n`);
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":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnE,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,2FAA2F;AAC3F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAkBrD,MAAM,UAAU,aAAa,CAAC,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE;IAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,QAAQ,CAAC,IAAa;IAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,MAAM,CAAC,SAAiB;IAC/B,OAAO,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAa;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC,EAAE,MAAM,CAAC,CAAwB,CAAC;QAC5H,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1B,OAAO,EAAE,GAAG,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAyC,EAAE,IAAa;IACpF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC,CAAC;IACjE,IAAI,CAAC,QAAQ,EAAE,CAAC;QAAC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IAC5D,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,MAAM,MAAM,GAAI,KAA4F,EAAE,WAAW,CAAC;IAC1H,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACrD,MAAM,KAAK,GAA2B,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;IACzG,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9C,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,eAAe,KAAK,QAAQ;YAAE,SAAS;QAC1D,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,eAAe,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3I,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,iBAAiB,CAAC,KAAc,EAAE,IAAa,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAC/E,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAE,KAAkC,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;IACjF,IAAI,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,OAAO,CAAC;IAC3C,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IAC1H,CAAC;IAAC,MAAM,CAAC,CAAC,qCAAqC,CAAC,CAAC;IACjD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,eAAe,CAAC,SAAiB,EAAE,IAAa;IACvD,MAAM,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7B,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IACnB,IAAI,CAAC;QACH,OAAQ,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAiC,CAAC,OAAO,IAAI,EAAE,CAAC;IACrI,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEtD,SAAS,gBAAgB,CAAC,GAAsB,EAAE,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE;IACnE,MAAM,GAAG,GAAG,GAAG,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC;IAC1C,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;AAChF,CAAC;AAID;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAiE,EAAE;IACrG,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACnC,IAAI,GAAgK,CAAC;IACrK,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAClG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,EAAE,sBAAsB,CAAC;IAC1C,MAAM,EAAE,GAAG,KAAK,EAAE,WAAW,CAAC;IAC9B,IAAI,CAAC,KAAK,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,GAAG,GAAG,EAAE,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,GAAG,uBAAuB;QAAE,OAAO,SAAS,CAAC;IAC7G,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC;IAC9C,IAAI,OAAO,IAAI,KAAK,CAAC,WAAW,IAAI,OAAO,KAAK,KAAK,CAAC,WAAW;QAAE,OAAO,SAAS,CAAC;IACpF,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC;IAClC,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,MAAM,KAAK,GAA2B,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;IACnF,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChD,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAoC,CAAC;QACpD,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ;YAAE,SAAS;QACtD,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5H,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3E,CAAC;AAED,gGAAgG;AAChG,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAExD,wDAAwD;AACxD,MAAM,UAAU,aAAa,CAAC,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,WAA4B,OAAO,CAAC,QAAQ,EAAE,MAAyB,OAAO,CAAC,GAAG;IACnI,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAC;IAC9F,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC3G,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA6F,EAAE;IACjI,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACnC,IAAI,OAAkF,CAAC;IACvF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,yBAAyB,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACpI,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,GAAG,GAAG,GAAG,CAAC,6BAA6B,EAAE,IAAI,EAAE,CAAC;IACpD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC;QACtF,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC,CAAC,wDAAwD;QAC/F,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAW,CAAC;IAC/B,CAAC;IACD,IAAI,MAA4C,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,EAAE,GAAG,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,GAAI,MAAM,CAAC,CAAY,CAAC;YAAE,MAAM,GAAG,CAAC,CAAC;IACvG,CAAC;IACD,MAAM,EAAE,GAAG,MAAM,EAAE,CAAuB,CAAC;IAC3C,IAAI,CAAC,MAAM,IAAI,EAAE,KAAK,SAAS,IAAI,GAAG,GAAG,EAAE,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE,GAAG,yBAAyB;QAAE,OAAO,SAAS,CAAC;IAC1G,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,IAAI,OAAO,MAAM,CAAC,CAAC,EAAE,EAAE,KAAK,QAAQ;QAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7F,IAAI,OAAO,MAAM,CAAC,CAAC,EAAE,EAAE,KAAK,QAAQ;QAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7F,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3E,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,qBAAqB,CAAC,OAA6F,EAAE;IACnI,MAAM,QAAQ,GAAG,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9G,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,YAAY,CAAC,cAAsB;IACjD,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC;YACvC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC9B,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,CAAC,CAAC;YACzC,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC;YAAE,SAAS;QAClD,IAAI,CAAC;YACH,MAAM,MAAM,GAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAmI,CAAC,OAAO,EAAE,WAAW,CAAC;YAC5L,IAAI,CAAC,MAAM;gBAAE,SAAS;YACtB,MAAM,GAAG,GAAkB,EAAE,CAAC;YAC9B,KAAK,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;gBAC3C,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;gBACtB,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ;oBAAE,SAAS;gBACvD,MAAM,IAAI,GAAG,CAAC,CAAC,cAAc,CAAC;gBAC9B,MAAM,IAAI,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;gBACjG,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,YAAY,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACrH,CAAC;YACD,IAAI,GAAG,CAAC,MAAM;gBAAE,OAAO,GAAG,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC,CAAC,oDAAoD,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AASD,uEAAuE;AACvE,MAAM,UAAU,mBAAmB,CAAC,IAAa;IAC/C,IAAI,IAA8B,CAAC;IACnC,IAAI,KAAK,GAAa,EAAE,CAAC;IACzB,IAAI,CAAC;QAAC,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,SAAS,CAAC;IAAC,CAAC;IAC9G,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAA6C,CAAC;YAC/H,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YACtC,IAAI,KAAK,CAAC,OAAO,EAAE,MAAM,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;gBAAE,IAAI,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QACzH,CAAC;QAAC,MAAM,CAAC,CAAC,8BAA8B,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yFAAyF;AACzF,SAAS,UAAU,CAAC,GAAW,EAAE,KAAgC,EAAE,KAAa;IAC9E,IAAI,OAAoB,CAAC;IACzB,IAAI,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,SAAS,CAAC;IAAC,CAAC;IAC3F,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACpG,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAClG,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACjC,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QAC7F,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QAChE,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,kBAAkB,CAAC,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE;IACpD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3H,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAChG,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,OAAO,CAAC,OAAsB,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAC9D,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,GAAG,IAAI,GAAG,GAAG,CAAC;SACrD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,SAAS,OAAO,CAAC,MAAc,EAAE,GAAW;IAC1C,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QAAC,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IACtE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC,QAAQ,CAAC;QACvE,OAAO,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,GAAG,IAAI,IAAI,GAAG,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,CAAc;IAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,eAAe,GAAG,YAAY,CAAC,CAAC,IAAI,uFAAuF,GAAG,YAAY,CAAC,CAAC,IAAI,aAAa;QAClK,8GAA8G,CAAC;AACnH,CAAC;AAqBD;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,KAAiB,EAAE,OAA6F,EAAE;IAC3I,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IACzB,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;IAClD,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IACnB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC;IAClE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAErC,MAAM,OAAO,GAAG,KAAK,CAAC,eAAe,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;IACzI,wEAAwE;IACxE,2EAA2E;IAC3E,yCAAyC;IACzC,IAAI,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/E,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,GAAG,qBAAqB,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC;IAClJ,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,GAAG,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IAEjD,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACpL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC,CAAC,kEAAkE;IAC/E,CAAC;IACD,IAAI,OAAO;QAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;IAC3E,OAAO;QACL,kBAAkB,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,kBAAkB,CAAC,GAAG,CAAC,EAAE;QACzF,aAAa,EAAE,6BAA6B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,GAAG,CAAC,IAAI,+FAA+F;KACvL,CAAC;AACJ,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,YAAY,CAAC,OAAsB;IACjD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/E,CAAC;AAiBD;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,KAAoB,EAAE,OAAwC,EAAE;IAC7F,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/C,IAAI,KAAK,CAAC,KAAK,KAAK,YAAY;QAAE,OAAO,SAAS,CAAC;IACnD,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;IACrE,IAAI,CAAC,EAAE;QAAE,OAAO,SAAS,CAAC;IAC1B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,aAAa,CAAC;IAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;IACjE,IAAI,CAAC;QACH,IAAI,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,GAAG,kBAAkB;YAAE,OAAO,SAAS,CAAC;IAC/E,CAAC;IAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAC/B,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QACxE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -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,EAQL,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;AAEzD,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAwGlH;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;AA8CD,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAIjE"}
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
- return { docPath: path.join(incDir, 'handoff.md'), diffPath: path.join(incDir, 'handoff.diff') };
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');