sidekick-shared 0.28.3 → 0.29.1
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/CHANGELOG.md +86 -0
- package/README.md +188 -27
- package/dist/aggregation/EventAggregator.d.ts +19 -0
- package/dist/aggregation/EventAggregator.js +174 -35
- package/dist/aggregation/snapshot.d.ts +37 -8
- package/dist/aggregation/snapshot.js +31 -9
- package/dist/aggregation/types.d.ts +13 -0
- package/dist/authStatus.d.ts +54 -0
- package/dist/authStatus.js +91 -0
- package/dist/browser.d.ts +16 -6
- package/dist/browser.js +24 -2
- package/dist/codex.d.ts +23 -0
- package/dist/codex.js +44 -0
- package/dist/codexProfiles.d.ts +1 -0
- package/dist/codexProfiles.js +8 -11
- package/dist/context/sessionContext.js +4 -0
- package/dist/esm/aggregation/EventAggregator.js +174 -35
- package/dist/esm/aggregation/snapshot.js +31 -9
- package/dist/esm/authStatus.js +87 -0
- package/dist/esm/browser.js +5 -2
- package/dist/esm/codex.js +18 -0
- package/dist/esm/codexProfiles.js +8 -11
- package/dist/esm/context/sessionContext.js +4 -0
- package/dist/esm/formatters/toolSummary.js +4 -1
- package/dist/esm/formatting.js +10 -1
- package/dist/esm/index.js +11 -6
- package/dist/esm/modelCatalog.js +7 -5
- package/dist/esm/modelContext.js +4 -3
- package/dist/esm/modelInfo.js +425 -47
- package/dist/esm/node.js +9 -3
- package/dist/esm/observedContextWindows.js +2 -1
- package/dist/esm/ownKey.js +26 -0
- package/dist/esm/parsers/codexParser.js +351 -54
- package/dist/esm/parsers/codexRolloutOrigin.js +107 -0
- package/dist/esm/parsers/openCodeParser.js +85 -22
- package/dist/esm/parsers/subagentScanner.js +33 -12
- package/dist/esm/parsers/subagentTraceParser.js +97 -37
- package/dist/esm/pricing.js +18 -0
- package/dist/esm/pricingCatalog.js +17 -9
- package/dist/esm/promptHistory.js +66 -4
- package/dist/esm/providerFailure.js +124 -3
- package/dist/esm/providers/claudeCode.js +10 -2
- package/dist/esm/providers/codex.js +84 -62
- package/dist/esm/providers/codexDatabase.js +3 -19
- package/dist/esm/providers/codexRollouts.js +24 -1
- package/dist/esm/providers/openCode.js +9 -17
- package/dist/esm/report/htmlReportGenerator.js +42 -5
- package/dist/esm/report/transcriptParser.js +13 -11
- package/dist/esm/schemas/providerFailure.js +3 -1
- package/dist/esm/schemas/sessionEvent.js +35 -14
- package/dist/esm/schemas/transcript.js +4 -0
- package/dist/esm/sessionPromptHistory.js +2 -2
- package/dist/esm/statusline/payload.js +9 -0
- package/dist/esm/subagentSpawn.js +163 -0
- package/dist/esm/testing/credentialGuard.js +87 -5
- package/dist/esm/toolCallOrigins.js +310 -0
- package/dist/esm/transcript.js +46 -3
- package/dist/esm/turns/assistantTurn.js +3 -2
- package/dist/esm/usage/claudeUsageDedupe.js +68 -0
- package/dist/esm/usage/usageEvents.js +146 -17
- package/dist/esm/usage/usageReports.js +39 -6
- package/dist/esm/watchers/eventBridge.js +15 -0
- package/dist/esm/watchers/factory.js +5 -3
- package/dist/esm/watchers/jsonlTail.js +442 -58
- package/dist/esm/watchers/jsonlWatcher.js +51 -4
- package/dist/esm/watchers/providerReaderWatcher.js +13 -0
- package/dist/esm/zaiQuota.js +2 -1
- package/dist/formatters/toolSummary.js +4 -1
- package/dist/formatting.d.ts +26 -1
- package/dist/formatting.js +11 -1
- package/dist/index.d.ts +22 -11
- package/dist/index.js +44 -12
- package/dist/modelCatalog.js +7 -5
- package/dist/modelContext.js +4 -3
- package/dist/modelInfo.d.ts +185 -16
- package/dist/modelInfo.js +434 -49
- package/dist/node.d.ts +16 -5
- package/dist/node.js +33 -2
- package/dist/observedContextWindows.js +2 -1
- package/dist/ownKey.d.ts +16 -0
- package/dist/ownKey.js +30 -0
- package/dist/parsers/codexParser.d.ts +118 -0
- package/dist/parsers/codexParser.js +352 -54
- package/dist/parsers/codexRolloutOrigin.d.ts +49 -0
- package/dist/parsers/codexRolloutOrigin.js +111 -0
- package/dist/parsers/openCodeParser.d.ts +38 -0
- package/dist/parsers/openCodeParser.js +88 -22
- package/dist/parsers/subagentScanner.d.ts +19 -6
- package/dist/parsers/subagentScanner.js +33 -12
- package/dist/parsers/subagentTraceParser.d.ts +25 -5
- package/dist/parsers/subagentTraceParser.js +97 -37
- package/dist/pricing.d.ts +22 -0
- package/dist/pricing.js +50 -0
- package/dist/pricingCatalog.d.ts +10 -0
- package/dist/pricingCatalog.js +16 -8
- package/dist/promptHistory.d.ts +65 -4
- package/dist/promptHistory.js +68 -5
- package/dist/providerFailure.d.ts +44 -0
- package/dist/providerFailure.js +126 -4
- package/dist/providers/claudeCode.js +9 -1
- package/dist/providers/codex.d.ts +3 -22
- package/dist/providers/codex.js +85 -64
- package/dist/providers/codexDatabase.d.ts +3 -2
- package/dist/providers/codexDatabase.js +4 -22
- package/dist/providers/codexRollouts.d.ts +22 -0
- package/dist/providers/codexRollouts.js +24 -0
- package/dist/providers/openCode.js +8 -16
- package/dist/providers/types.d.ts +14 -0
- package/dist/report/htmlReportGenerator.js +42 -5
- package/dist/report/transcriptParser.d.ts +10 -1
- package/dist/report/transcriptParser.js +13 -11
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/providerFailure.d.ts +39 -0
- package/dist/schemas/providerFailure.js +2 -0
- package/dist/schemas/sessionEvent.d.ts +27 -10
- package/dist/schemas/sessionEvent.js +35 -14
- package/dist/schemas/transcript.d.ts +2 -0
- package/dist/schemas/transcript.js +4 -0
- package/dist/sessionPromptHistory.d.ts +7 -1
- package/dist/sessionPromptHistory.js +1 -1
- package/dist/statusline/payload.d.ts +10 -0
- package/dist/statusline/payload.js +14 -0
- package/dist/subagentSpawn.d.ts +80 -0
- package/dist/subagentSpawn.js +174 -0
- package/dist/testing/credentialGuard.d.ts +14 -0
- package/dist/testing/credentialGuard.js +87 -5
- package/dist/toolCallOrigins.d.ts +70 -0
- package/dist/toolCallOrigins.js +346 -0
- package/dist/transcript.d.ts +12 -0
- package/dist/transcript.js +46 -3
- package/dist/turns/assistantTurn.d.ts +1 -0
- package/dist/turns/assistantTurn.js +3 -2
- package/dist/types/opencode.d.ts +2 -0
- package/dist/usage/claudeUsageDedupe.d.ts +31 -0
- package/dist/usage/claudeUsageDedupe.js +68 -0
- package/dist/usage/usageEvents.d.ts +54 -6
- package/dist/usage/usageEvents.js +146 -17
- package/dist/usage/usageReports.d.ts +35 -4
- package/dist/usage/usageReports.js +39 -6
- package/dist/watchers/eventBridge.js +15 -0
- package/dist/watchers/factory.d.ts +6 -0
- package/dist/watchers/factory.js +5 -3
- package/dist/watchers/jsonlTail.d.ts +124 -4
- package/dist/watchers/jsonlTail.js +446 -59
- package/dist/watchers/jsonlWatcher.d.ts +18 -1
- package/dist/watchers/jsonlWatcher.js +50 -3
- package/dist/watchers/providerReaderWatcher.d.ts +7 -0
- package/dist/watchers/providerReaderWatcher.js +13 -0
- package/dist/watchers/types.d.ts +12 -0
- package/dist/zaiQuota.js +2 -1
- package/package.json +41 -1
|
@@ -76,12 +76,12 @@ export declare const userSessionEventSchema: z.ZodObject<{
|
|
|
76
76
|
promptSource: z.ZodOptional<z.ZodString>;
|
|
77
77
|
cwd: z.ZodOptional<z.ZodString>;
|
|
78
78
|
gitBranch: z.ZodOptional<z.ZodString>;
|
|
79
|
-
permissionMode: z.ZodOptional<z.ZodEnum<{
|
|
79
|
+
permissionMode: z.ZodCatch<z.ZodOptional<z.ZodEnum<{
|
|
80
80
|
default: "default";
|
|
81
81
|
acceptEdits: "acceptEdits";
|
|
82
82
|
bypassPermissions: "bypassPermissions";
|
|
83
83
|
plan: "plan";
|
|
84
|
-
}
|
|
84
|
+
}>>>;
|
|
85
85
|
rateLimits: z.ZodOptional<z.ZodObject<{
|
|
86
86
|
primary: z.ZodOptional<z.ZodObject<{
|
|
87
87
|
usedPercent: z.ZodNumber;
|
|
@@ -165,12 +165,12 @@ export declare const assistantSessionEventSchema: z.ZodObject<{
|
|
|
165
165
|
promptSource: z.ZodOptional<z.ZodString>;
|
|
166
166
|
cwd: z.ZodOptional<z.ZodString>;
|
|
167
167
|
gitBranch: z.ZodOptional<z.ZodString>;
|
|
168
|
-
permissionMode: z.ZodOptional<z.ZodEnum<{
|
|
168
|
+
permissionMode: z.ZodCatch<z.ZodOptional<z.ZodEnum<{
|
|
169
169
|
default: "default";
|
|
170
170
|
acceptEdits: "acceptEdits";
|
|
171
171
|
bypassPermissions: "bypassPermissions";
|
|
172
172
|
plan: "plan";
|
|
173
|
-
}
|
|
173
|
+
}>>>;
|
|
174
174
|
rateLimits: z.ZodOptional<z.ZodObject<{
|
|
175
175
|
primary: z.ZodOptional<z.ZodObject<{
|
|
176
176
|
usedPercent: z.ZodNumber;
|
|
@@ -255,12 +255,12 @@ export declare const systemSessionEventSchema: z.ZodObject<{
|
|
|
255
255
|
promptSource: z.ZodOptional<z.ZodString>;
|
|
256
256
|
cwd: z.ZodOptional<z.ZodString>;
|
|
257
257
|
gitBranch: z.ZodOptional<z.ZodString>;
|
|
258
|
-
permissionMode: z.ZodOptional<z.ZodEnum<{
|
|
258
|
+
permissionMode: z.ZodCatch<z.ZodOptional<z.ZodEnum<{
|
|
259
259
|
default: "default";
|
|
260
260
|
acceptEdits: "acceptEdits";
|
|
261
261
|
bypassPermissions: "bypassPermissions";
|
|
262
262
|
plan: "plan";
|
|
263
|
-
}
|
|
263
|
+
}>>>;
|
|
264
264
|
rateLimits: z.ZodOptional<z.ZodObject<{
|
|
265
265
|
primary: z.ZodOptional<z.ZodObject<{
|
|
266
266
|
usedPercent: z.ZodNumber;
|
|
@@ -348,12 +348,12 @@ export declare const toolUseSessionEventSchema: z.ZodObject<{
|
|
|
348
348
|
promptSource: z.ZodOptional<z.ZodString>;
|
|
349
349
|
cwd: z.ZodOptional<z.ZodString>;
|
|
350
350
|
gitBranch: z.ZodOptional<z.ZodString>;
|
|
351
|
-
permissionMode: z.ZodOptional<z.ZodEnum<{
|
|
351
|
+
permissionMode: z.ZodCatch<z.ZodOptional<z.ZodEnum<{
|
|
352
352
|
default: "default";
|
|
353
353
|
acceptEdits: "acceptEdits";
|
|
354
354
|
bypassPermissions: "bypassPermissions";
|
|
355
355
|
plan: "plan";
|
|
356
|
-
}
|
|
356
|
+
}>>>;
|
|
357
357
|
rateLimits: z.ZodOptional<z.ZodObject<{
|
|
358
358
|
primary: z.ZodOptional<z.ZodObject<{
|
|
359
359
|
usedPercent: z.ZodNumber;
|
|
@@ -442,12 +442,12 @@ export declare const toolResultSessionEventSchema: z.ZodObject<{
|
|
|
442
442
|
promptSource: z.ZodOptional<z.ZodString>;
|
|
443
443
|
cwd: z.ZodOptional<z.ZodString>;
|
|
444
444
|
gitBranch: z.ZodOptional<z.ZodString>;
|
|
445
|
-
permissionMode: z.ZodOptional<z.ZodEnum<{
|
|
445
|
+
permissionMode: z.ZodCatch<z.ZodOptional<z.ZodEnum<{
|
|
446
446
|
default: "default";
|
|
447
447
|
acceptEdits: "acceptEdits";
|
|
448
448
|
bypassPermissions: "bypassPermissions";
|
|
449
449
|
plan: "plan";
|
|
450
|
-
}
|
|
450
|
+
}>>>;
|
|
451
451
|
rateLimits: z.ZodOptional<z.ZodObject<{
|
|
452
452
|
primary: z.ZodOptional<z.ZodObject<{
|
|
453
453
|
usedPercent: z.ZodNumber;
|
|
@@ -520,6 +520,19 @@ export declare const toolResultSessionEventSchema: z.ZodObject<{
|
|
|
520
520
|
}, z.core.$strip>>;
|
|
521
521
|
}, z.core.$strip>;
|
|
522
522
|
export declare const sessionEventSchema: z.ZodType<SessionEvent>;
|
|
523
|
+
/** Options for {@link extractSessionEvents}. */
|
|
524
|
+
export interface ExtractSessionEventsOptions {
|
|
525
|
+
/**
|
|
526
|
+
* Also turn Claude Code's mid-turn task-notification attachments
|
|
527
|
+
* (`{ type: 'attachment', attachment: { type: 'queued_command',
|
|
528
|
+
* commandMode: 'task-notification', prompt } }`) into one `system` event
|
|
529
|
+
* with `origin: { kind: 'task-notification' }`, `message: { role: 'user',
|
|
530
|
+
* sourceLabel: 'task notification', content: <prompt> }`, and the line's
|
|
531
|
+
* timestamp. They report background agents finishing. Default `false`:
|
|
532
|
+
* attachment lines yield no events.
|
|
533
|
+
*/
|
|
534
|
+
includeTaskNotifications?: boolean;
|
|
535
|
+
}
|
|
523
536
|
/**
|
|
524
537
|
* Extracts canonical SessionEvents from a raw JSONL value.
|
|
525
538
|
*
|
|
@@ -528,5 +541,9 @@ export declare const sessionEventSchema: z.ZodType<SessionEvent>;
|
|
|
528
541
|
* `sessionEventSchema` alone rejects. This helper tries a direct parse,
|
|
529
542
|
* then unwraps progress envelopes (recursively, in case of nesting).
|
|
530
543
|
* Returns zero events for unrecognized input — never throws.
|
|
544
|
+
*
|
|
545
|
+
* The second argument is either the starting progress depth (the original
|
|
546
|
+
* signature) or an options object.
|
|
531
547
|
*/
|
|
532
548
|
export declare function extractSessionEvents(raw: unknown, depth?: number): SessionEvent[];
|
|
549
|
+
export declare function extractSessionEvents(raw: unknown, options?: ExtractSessionEventsOptions): SessionEvent[];
|
|
@@ -12,6 +12,7 @@ exports.sessionEventSchema = exports.toolResultSessionEventSchema = exports.tool
|
|
|
12
12
|
exports.extractSessionEvents = extractSessionEvents;
|
|
13
13
|
const zod_1 = require("zod");
|
|
14
14
|
const usageNormalization_1 = require("./usageNormalization");
|
|
15
|
+
const subagentSpawn_1 = require("../subagentSpawn");
|
|
15
16
|
// ── MessageUsage ──
|
|
16
17
|
exports.messageUsageSchema = zod_1.z.object({
|
|
17
18
|
input_tokens: zod_1.z.number(),
|
|
@@ -56,7 +57,9 @@ const eventBaseShape = {
|
|
|
56
57
|
promptSource: zod_1.z.string().optional(),
|
|
57
58
|
cwd: zod_1.z.string().optional(),
|
|
58
59
|
gitBranch: zod_1.z.string().optional(),
|
|
59
|
-
|
|
60
|
+
// A mode this release doesn't know (Claude Code added `auto`) is dropped
|
|
61
|
+
// rather than rejecting the whole line with its prompt or tool results.
|
|
62
|
+
permissionMode: exports.permissionModeSchema.optional().catch(undefined),
|
|
60
63
|
rateLimits: zod_1.z
|
|
61
64
|
.object({
|
|
62
65
|
primary: zod_1.z
|
|
@@ -173,22 +176,21 @@ exports.sessionEventSchema = zod_1.z.union([
|
|
|
173
176
|
// ── Progress unwrapping ──
|
|
174
177
|
/** Recursion bound for nested progress envelopes; real data nests 1 level. */
|
|
175
178
|
const MAX_PROGRESS_DEPTH = 8;
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
* `sessionEventSchema` alone rejects. This helper tries a direct parse,
|
|
182
|
-
* then unwraps progress envelopes (recursively, in case of nesting).
|
|
183
|
-
* Returns zero events for unrecognized input — never throws.
|
|
184
|
-
*/
|
|
185
|
-
function extractSessionEvents(raw, depth = 0) {
|
|
186
|
-
return extractSessionEventsWithProvenance(raw, depth, {});
|
|
179
|
+
function extractSessionEvents(raw, depthOrOptions = 0) {
|
|
180
|
+
if (typeof depthOrOptions === 'number') {
|
|
181
|
+
return extractSessionEventsWithProvenance(raw, depthOrOptions, {}, {});
|
|
182
|
+
}
|
|
183
|
+
return extractSessionEventsWithProvenance(raw, 0, {}, depthOrOptions ?? {});
|
|
187
184
|
}
|
|
188
|
-
function extractSessionEventsWithProvenance(raw, depth, inherited) {
|
|
185
|
+
function extractSessionEventsWithProvenance(raw, depth, inherited, options) {
|
|
189
186
|
const direct = exports.sessionEventSchema.safeParse(raw);
|
|
190
187
|
if (direct.success)
|
|
191
188
|
return [{ ...inherited, ...direct.data }];
|
|
189
|
+
if (options.includeTaskNotifications) {
|
|
190
|
+
const notification = taskNotificationAttachmentEvent(raw);
|
|
191
|
+
if (notification)
|
|
192
|
+
return [{ ...inherited, ...notification }];
|
|
193
|
+
}
|
|
192
194
|
if (depth >= MAX_PROGRESS_DEPTH)
|
|
193
195
|
return [];
|
|
194
196
|
if (typeof raw === 'object' && raw !== null && raw.type === 'progress') {
|
|
@@ -197,12 +199,31 @@ function extractSessionEventsWithProvenance(raw, depth, inherited) {
|
|
|
197
199
|
if (typeof data === 'object' && data !== null) {
|
|
198
200
|
const message = data.message;
|
|
199
201
|
if (typeof message === 'object' && message !== null) {
|
|
200
|
-
return extractSessionEventsWithProvenance(message, depth + 1, provenance);
|
|
202
|
+
return extractSessionEventsWithProvenance(message, depth + 1, provenance, options);
|
|
201
203
|
}
|
|
202
204
|
}
|
|
203
205
|
}
|
|
204
206
|
return [];
|
|
205
207
|
}
|
|
208
|
+
/** The `system` event for a task-notification attachment line, or `null`. */
|
|
209
|
+
function taskNotificationAttachmentEvent(raw) {
|
|
210
|
+
const prompt = (0, subagentSpawn_1.taskNotificationPromptFromAttachment)(raw);
|
|
211
|
+
if (prompt === null)
|
|
212
|
+
return null;
|
|
213
|
+
const line = raw;
|
|
214
|
+
const candidate = {
|
|
215
|
+
type: 'system',
|
|
216
|
+
timestamp: line.timestamp,
|
|
217
|
+
origin: { kind: 'task-notification' },
|
|
218
|
+
message: { role: 'user', sourceLabel: 'task notification', content: prompt },
|
|
219
|
+
};
|
|
220
|
+
for (const key of ['entrypoint', 'isSidechain', 'cwd', 'gitBranch']) {
|
|
221
|
+
if (line[key] !== undefined)
|
|
222
|
+
candidate[key] = line[key];
|
|
223
|
+
}
|
|
224
|
+
const parsed = exports.systemSessionEventSchema.safeParse(candidate);
|
|
225
|
+
return parsed.success ? parsed.data : null;
|
|
226
|
+
}
|
|
206
227
|
function progressProvenance(raw) {
|
|
207
228
|
const value = raw;
|
|
208
229
|
const provenance = {};
|
|
@@ -12,6 +12,8 @@ export declare const canonicalTranscriptBlockSchema: z.ZodObject<{
|
|
|
12
12
|
}>;
|
|
13
13
|
text: z.ZodOptional<z.ZodString>;
|
|
14
14
|
toolName: z.ZodOptional<z.ZodString>;
|
|
15
|
+
rawToolName: z.ZodOptional<z.ZodString>;
|
|
16
|
+
mcpServerName: z.ZodOptional<z.ZodString>;
|
|
15
17
|
toolUseId: z.ZodOptional<z.ZodString>;
|
|
16
18
|
input: z.ZodOptional<z.ZodUnknown>;
|
|
17
19
|
output: z.ZodOptional<z.ZodUnknown>;
|
|
@@ -20,6 +20,8 @@ exports.canonicalTranscriptBlockSchema = zod_1.z.object({
|
|
|
20
20
|
type: zod_1.z.enum(['text', 'thinking', 'tool_use', 'tool_result', 'image', 'unknown']),
|
|
21
21
|
text: zod_1.z.string().optional(),
|
|
22
22
|
toolName: zod_1.z.string().optional(),
|
|
23
|
+
rawToolName: zod_1.z.string().optional(),
|
|
24
|
+
mcpServerName: zod_1.z.string().optional(),
|
|
23
25
|
toolUseId: zod_1.z.string().optional(),
|
|
24
26
|
input: zod_1.z.unknown().optional(),
|
|
25
27
|
output: zod_1.z.unknown().optional(),
|
|
@@ -31,6 +33,8 @@ exports.canonicalTranscriptBlockSchema = zod_1.z.object({
|
|
|
31
33
|
exports.canonicalToolCallSchema = zod_1.z.object({
|
|
32
34
|
id: zod_1.z.string().optional(),
|
|
33
35
|
name: zod_1.z.string(),
|
|
36
|
+
rawToolName: zod_1.z.string().optional(),
|
|
37
|
+
mcpServerName: zod_1.z.string().optional(),
|
|
34
38
|
timestamp: zod_1.z.string(),
|
|
35
39
|
input: zod_1.z.unknown().optional(),
|
|
36
40
|
output: zod_1.z.unknown().optional(),
|
|
@@ -28,7 +28,13 @@ export interface SessionPromptHistoryBounds {
|
|
|
28
28
|
maxSessionBytes?: number;
|
|
29
29
|
/** Bytes read across all sessions in one call. Default 256 MiB. */
|
|
30
30
|
maxTotalBytes?: number;
|
|
31
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Largest single log record that is parsed. Default 16 MiB
|
|
33
|
+
* (`PROMPT_HISTORY_ORDINAL_MAX_RECORD_BYTES`). A prompt inside a longer
|
|
34
|
+
* record is never seen, so later ordinals do not count it: ordinals match
|
|
35
|
+
* `collectPromptHistory()` (and usage events' `promptOrdinal`) only when
|
|
36
|
+
* both use the default.
|
|
37
|
+
*/
|
|
32
38
|
maxRecordBytes?: number;
|
|
33
39
|
/** Wall-clock budget for the call. Default 60 000 ms. */
|
|
34
40
|
deadlineMs?: number;
|
|
@@ -56,7 +56,7 @@ const DEFAULT_SESSION_BOUNDS = {
|
|
|
56
56
|
maxSessions: 1000,
|
|
57
57
|
maxSessionBytes: 256 * 1024 * 1024,
|
|
58
58
|
maxTotalBytes: 256 * 1024 * 1024,
|
|
59
|
-
maxRecordBytes: promptHistory_1.
|
|
59
|
+
maxRecordBytes: promptHistory_1.PROMPT_HISTORY_ORDINAL_MAX_RECORD_BYTES,
|
|
60
60
|
deadlineMs: 60_000,
|
|
61
61
|
};
|
|
62
62
|
const MAX_EXCLUSIONS = 1000;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sidekick-shared/statusline/payload` — the pure Claude Code status-line
|
|
3
|
+
* stdin parser on its own, for hosts with a tight bundle budget that render
|
|
4
|
+
* their own line. Loads no account, credential, quota-snapshot, or network
|
|
5
|
+
* code (the full `sidekick-shared/statusline` entry does).
|
|
6
|
+
*
|
|
7
|
+
* @module statusline/payload
|
|
8
|
+
*/
|
|
9
|
+
export { parseClaudeStatuslinePayload, quotaFromStatuslinePayload, } from './claudeStatuslinePayload';
|
|
10
|
+
export type { ClaudeStatuslinePayload, ClaudeStatuslineRateLimitWindow, QuotaFromStatuslineOptions, } from './claudeStatuslinePayload';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `sidekick-shared/statusline/payload` — the pure Claude Code status-line
|
|
4
|
+
* stdin parser on its own, for hosts with a tight bundle budget that render
|
|
5
|
+
* their own line. Loads no account, credential, quota-snapshot, or network
|
|
6
|
+
* code (the full `sidekick-shared/statusline` entry does).
|
|
7
|
+
*
|
|
8
|
+
* @module statusline/payload
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.quotaFromStatuslinePayload = exports.parseClaudeStatuslinePayload = void 0;
|
|
12
|
+
var claudeStatuslinePayload_1 = require("./claudeStatuslinePayload");
|
|
13
|
+
Object.defineProperty(exports, "parseClaudeStatuslinePayload", { enumerable: true, get: function () { return claudeStatuslinePayload_1.parseClaudeStatuslinePayload; } });
|
|
14
|
+
Object.defineProperty(exports, "quotaFromStatuslinePayload", { enumerable: true, get: function () { return claudeStatuslinePayload_1.quotaFromStatuslinePayload; } });
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recognizes Claude Code subagent spawns and background-task notifications.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code's subagent tool is `Agent`; `Task` is its earlier name (and the
|
|
5
|
+
* name OpenCode's `task` tool is normalized to). A background agent's spawning
|
|
6
|
+
* tool call gets its result right away ("Async agent launched successfully.")
|
|
7
|
+
* and its completion arrives later as a `<task-notification>` block, delivered
|
|
8
|
+
* either as a user line or as a mid-turn `queued_command` attachment.
|
|
9
|
+
*
|
|
10
|
+
* Pure: no filesystem access, so it is safe for browser bundles.
|
|
11
|
+
*
|
|
12
|
+
* @module subagentSpawn
|
|
13
|
+
*/
|
|
14
|
+
import type { SubagentOutcome } from './aggregation/types';
|
|
15
|
+
import type { SessionEvent } from './types/sessionEvent';
|
|
16
|
+
/** Tool names that spawn a subagent: `Agent` (current) and `Task` (earlier name). */
|
|
17
|
+
export declare const SUBAGENT_SPAWN_TOOL_NAMES: readonly string[];
|
|
18
|
+
/** Whether a tool name spawns a subagent (`Agent` or `Task`). */
|
|
19
|
+
export declare function isSubagentSpawnTool(name: string | null | undefined): boolean;
|
|
20
|
+
/** A spawning tool result that launched the agent in the background. */
|
|
21
|
+
export interface AsyncAgentLaunch {
|
|
22
|
+
/** The agent id Claude Code reported (`agentId: <id>`), when present. */
|
|
23
|
+
agentId?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Plain text of tool-result or message content: a string as-is, or the text
|
|
27
|
+
* blocks of a content array joined by newlines.
|
|
28
|
+
*/
|
|
29
|
+
export declare function contentText(content: unknown): string;
|
|
30
|
+
/**
|
|
31
|
+
* Recognizes the immediate result of a background spawn
|
|
32
|
+
* (`Async agent launched successfully.` … `agentId: <id> …`). Accepts the
|
|
33
|
+
* result text or the raw tool-result content. Returns `null` for anything
|
|
34
|
+
* else, including a finished foreground agent's result.
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseAsyncAgentLaunch(result: unknown): AsyncAgentLaunch | null;
|
|
37
|
+
/** Fields of a `<task-notification>` block. */
|
|
38
|
+
export interface TaskNotification {
|
|
39
|
+
/** `<task-id>`: the background agent's id (or a background shell task's id). */
|
|
40
|
+
taskId: string;
|
|
41
|
+
/** `<tool-use-id>`: the tool call that started the background work. */
|
|
42
|
+
toolUseId?: string;
|
|
43
|
+
/** `<status>` as written, e.g. `completed`, `failed`, `killed`, `stopped`. */
|
|
44
|
+
status?: string;
|
|
45
|
+
/** `<summary>`, e.g. `Agent "Explore auth" finished`. */
|
|
46
|
+
summary?: string;
|
|
47
|
+
/**
|
|
48
|
+
* The agent stopped while background work of its own is still running; it
|
|
49
|
+
* may resume, and the same task id notifies again.
|
|
50
|
+
*/
|
|
51
|
+
interim: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Parses the first `<task-notification>` block in `text`. Whitespace and
|
|
55
|
+
* newlines between tags, missing fields, and unknown extra fields are
|
|
56
|
+
* tolerated; the block needs a `<task-id>`. Fields are read before the
|
|
57
|
+
* agent's own `<result>` output, which may quote anything.
|
|
58
|
+
*/
|
|
59
|
+
export declare function parseTaskNotification(text: unknown): TaskNotification | null;
|
|
60
|
+
/**
|
|
61
|
+
* The `<task-notification>` prompt of a raw Claude Code attachment line
|
|
62
|
+
* (`{ type: 'attachment', attachment: { type: 'queued_command', commandMode:
|
|
63
|
+
* 'task-notification', prompt } }`), which is how a notification that lands
|
|
64
|
+
* mid-turn is recorded. `null` for any other value.
|
|
65
|
+
*/
|
|
66
|
+
export declare function taskNotificationPromptFromAttachment(raw: unknown): string | null;
|
|
67
|
+
/**
|
|
68
|
+
* The synthetic `system` event `extractSessionEvents(raw, {
|
|
69
|
+
* includeTaskNotifications: true })` makes from a mid-turn task-notification
|
|
70
|
+
* attachment. It is bookkeeping, not a message or a prompt.
|
|
71
|
+
*/
|
|
72
|
+
export declare function isTaskNotificationSystemEvent(event: SessionEvent): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* The task notification an event carries: a user line with
|
|
75
|
+
* `origin.kind === 'task-notification'` or whose text starts with
|
|
76
|
+
* `<task-notification>`, or the opt-in synthetic system event. `null` otherwise.
|
|
77
|
+
*/
|
|
78
|
+
export declare function taskNotificationFromEvent(event: SessionEvent): TaskNotification | null;
|
|
79
|
+
/** Maps a notification `<status>` to an outcome; unknown or missing statuses read as `completed`. */
|
|
80
|
+
export declare function taskNotificationOutcome(status: string | undefined): SubagentOutcome;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Recognizes Claude Code subagent spawns and background-task notifications.
|
|
4
|
+
*
|
|
5
|
+
* Claude Code's subagent tool is `Agent`; `Task` is its earlier name (and the
|
|
6
|
+
* name OpenCode's `task` tool is normalized to). A background agent's spawning
|
|
7
|
+
* tool call gets its result right away ("Async agent launched successfully.")
|
|
8
|
+
* and its completion arrives later as a `<task-notification>` block, delivered
|
|
9
|
+
* either as a user line or as a mid-turn `queued_command` attachment.
|
|
10
|
+
*
|
|
11
|
+
* Pure: no filesystem access, so it is safe for browser bundles.
|
|
12
|
+
*
|
|
13
|
+
* @module subagentSpawn
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.SUBAGENT_SPAWN_TOOL_NAMES = void 0;
|
|
17
|
+
exports.isSubagentSpawnTool = isSubagentSpawnTool;
|
|
18
|
+
exports.contentText = contentText;
|
|
19
|
+
exports.parseAsyncAgentLaunch = parseAsyncAgentLaunch;
|
|
20
|
+
exports.parseTaskNotification = parseTaskNotification;
|
|
21
|
+
exports.taskNotificationPromptFromAttachment = taskNotificationPromptFromAttachment;
|
|
22
|
+
exports.isTaskNotificationSystemEvent = isTaskNotificationSystemEvent;
|
|
23
|
+
exports.taskNotificationFromEvent = taskNotificationFromEvent;
|
|
24
|
+
exports.taskNotificationOutcome = taskNotificationOutcome;
|
|
25
|
+
/** Tool names that spawn a subagent: `Agent` (current) and `Task` (earlier name). */
|
|
26
|
+
exports.SUBAGENT_SPAWN_TOOL_NAMES = Object.freeze(['Agent', 'Task']);
|
|
27
|
+
const SPAWN_TOOLS = new Set(exports.SUBAGENT_SPAWN_TOOL_NAMES);
|
|
28
|
+
/** Whether a tool name spawns a subagent (`Agent` or `Task`). */
|
|
29
|
+
function isSubagentSpawnTool(name) {
|
|
30
|
+
return typeof name === 'string' && SPAWN_TOOLS.has(name);
|
|
31
|
+
}
|
|
32
|
+
const ASYNC_LAUNCH_PREFIX = /^\s*Async agent launched successfully\b/;
|
|
33
|
+
const AGENT_ID_LINE = /(?:^|\n)[ \t]*agentId:[ \t]*([A-Za-z0-9][\w.@-]*)/;
|
|
34
|
+
/**
|
|
35
|
+
* Plain text of tool-result or message content: a string as-is, or the text
|
|
36
|
+
* blocks of a content array joined by newlines.
|
|
37
|
+
*/
|
|
38
|
+
function contentText(content) {
|
|
39
|
+
if (typeof content === 'string')
|
|
40
|
+
return content;
|
|
41
|
+
if (!Array.isArray(content))
|
|
42
|
+
return '';
|
|
43
|
+
const parts = [];
|
|
44
|
+
for (const block of content) {
|
|
45
|
+
if (!block || typeof block !== 'object')
|
|
46
|
+
continue;
|
|
47
|
+
const typed = block;
|
|
48
|
+
if (typed.type === 'text' && typeof typed.text === 'string')
|
|
49
|
+
parts.push(typed.text);
|
|
50
|
+
}
|
|
51
|
+
return parts.join('\n');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Recognizes the immediate result of a background spawn
|
|
55
|
+
* (`Async agent launched successfully.` … `agentId: <id> …`). Accepts the
|
|
56
|
+
* result text or the raw tool-result content. Returns `null` for anything
|
|
57
|
+
* else, including a finished foreground agent's result.
|
|
58
|
+
*/
|
|
59
|
+
function parseAsyncAgentLaunch(result) {
|
|
60
|
+
const text = contentText(result);
|
|
61
|
+
if (!ASYNC_LAUNCH_PREFIX.test(text))
|
|
62
|
+
return null;
|
|
63
|
+
const match = AGENT_ID_LINE.exec(text);
|
|
64
|
+
return match ? { agentId: match[1] } : {};
|
|
65
|
+
}
|
|
66
|
+
const NOTIFICATION_OPEN = '<task-notification>';
|
|
67
|
+
const NOTIFICATION_CLOSE = '</task-notification>';
|
|
68
|
+
const NOTIFICATION_PREFIX = /^\s*<task-notification>/;
|
|
69
|
+
const TAG_PATTERNS = {
|
|
70
|
+
taskId: /<task-id>\s*([\s\S]*?)\s*<\/task-id>/,
|
|
71
|
+
toolUseId: /<tool-use-id>\s*([\s\S]*?)\s*<\/tool-use-id>/,
|
|
72
|
+
status: /<status>\s*([\s\S]*?)\s*<\/status>/,
|
|
73
|
+
summary: /<summary>\s*([\s\S]*?)\s*<\/summary>/,
|
|
74
|
+
note: /<note>\s*([\s\S]*?)\s*<\/note>/,
|
|
75
|
+
};
|
|
76
|
+
const INTERIM_TEXT = /waiting on its own background work|background work of its own still running/i;
|
|
77
|
+
function tagValue(body, pattern) {
|
|
78
|
+
const value = pattern.exec(body)?.[1]?.trim();
|
|
79
|
+
return value ? value : undefined;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Parses the first `<task-notification>` block in `text`. Whitespace and
|
|
83
|
+
* newlines between tags, missing fields, and unknown extra fields are
|
|
84
|
+
* tolerated; the block needs a `<task-id>`. Fields are read before the
|
|
85
|
+
* agent's own `<result>` output, which may quote anything.
|
|
86
|
+
*/
|
|
87
|
+
function parseTaskNotification(text) {
|
|
88
|
+
if (typeof text !== 'string')
|
|
89
|
+
return null;
|
|
90
|
+
const start = text.indexOf(NOTIFICATION_OPEN);
|
|
91
|
+
if (start < 0)
|
|
92
|
+
return null;
|
|
93
|
+
let body = text.slice(start + NOTIFICATION_OPEN.length);
|
|
94
|
+
const resultAt = body.indexOf('<result>');
|
|
95
|
+
let header = resultAt >= 0 ? body.slice(0, resultAt) : body;
|
|
96
|
+
if (resultAt < 0) {
|
|
97
|
+
const end = body.indexOf(NOTIFICATION_CLOSE);
|
|
98
|
+
if (end >= 0)
|
|
99
|
+
header = body = body.slice(0, end);
|
|
100
|
+
}
|
|
101
|
+
if (!TAG_PATTERNS.taskId.test(header))
|
|
102
|
+
header = body;
|
|
103
|
+
const taskId = tagValue(header, TAG_PATTERNS.taskId);
|
|
104
|
+
if (!taskId)
|
|
105
|
+
return null;
|
|
106
|
+
const toolUseId = tagValue(header, TAG_PATTERNS.toolUseId);
|
|
107
|
+
const status = tagValue(header, TAG_PATTERNS.status);
|
|
108
|
+
const summary = tagValue(header, TAG_PATTERNS.summary);
|
|
109
|
+
const note = tagValue(header, TAG_PATTERNS.note);
|
|
110
|
+
return {
|
|
111
|
+
taskId,
|
|
112
|
+
...(toolUseId ? { toolUseId } : {}),
|
|
113
|
+
...(status ? { status } : {}),
|
|
114
|
+
...(summary ? { summary } : {}),
|
|
115
|
+
interim: INTERIM_TEXT.test(summary ?? '') || INTERIM_TEXT.test(note ?? ''),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The `<task-notification>` prompt of a raw Claude Code attachment line
|
|
120
|
+
* (`{ type: 'attachment', attachment: { type: 'queued_command', commandMode:
|
|
121
|
+
* 'task-notification', prompt } }`), which is how a notification that lands
|
|
122
|
+
* mid-turn is recorded. `null` for any other value.
|
|
123
|
+
*/
|
|
124
|
+
function taskNotificationPromptFromAttachment(raw) {
|
|
125
|
+
if (!raw || typeof raw !== 'object')
|
|
126
|
+
return null;
|
|
127
|
+
const line = raw;
|
|
128
|
+
if (line.type !== 'attachment' || !line.attachment || typeof line.attachment !== 'object') {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
const attachment = line.attachment;
|
|
132
|
+
return attachment.type === 'queued_command' &&
|
|
133
|
+
attachment.commandMode === 'task-notification' &&
|
|
134
|
+
typeof attachment.prompt === 'string'
|
|
135
|
+
? attachment.prompt
|
|
136
|
+
: null;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* The synthetic `system` event `extractSessionEvents(raw, {
|
|
140
|
+
* includeTaskNotifications: true })` makes from a mid-turn task-notification
|
|
141
|
+
* attachment. It is bookkeeping, not a message or a prompt.
|
|
142
|
+
*/
|
|
143
|
+
function isTaskNotificationSystemEvent(event) {
|
|
144
|
+
return event.type === 'system' && event.origin?.kind === 'task-notification';
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The task notification an event carries: a user line with
|
|
148
|
+
* `origin.kind === 'task-notification'` or whose text starts with
|
|
149
|
+
* `<task-notification>`, or the opt-in synthetic system event. `null` otherwise.
|
|
150
|
+
*/
|
|
151
|
+
function taskNotificationFromEvent(event) {
|
|
152
|
+
if (event.type !== 'user' && event.type !== 'system')
|
|
153
|
+
return null;
|
|
154
|
+
const flagged = event.origin?.kind === 'task-notification';
|
|
155
|
+
if (event.type === 'system' && !flagged)
|
|
156
|
+
return null;
|
|
157
|
+
const text = contentText(event.message?.content);
|
|
158
|
+
if (!flagged && !NOTIFICATION_PREFIX.test(text))
|
|
159
|
+
return null;
|
|
160
|
+
return parseTaskNotification(text);
|
|
161
|
+
}
|
|
162
|
+
/** Maps a notification `<status>` to an outcome; unknown or missing statuses read as `completed`. */
|
|
163
|
+
function taskNotificationOutcome(status) {
|
|
164
|
+
switch (status?.toLowerCase()) {
|
|
165
|
+
case 'failed':
|
|
166
|
+
return 'failed';
|
|
167
|
+
case 'killed':
|
|
168
|
+
return 'killed';
|
|
169
|
+
case 'stopped':
|
|
170
|
+
return 'stopped';
|
|
171
|
+
default:
|
|
172
|
+
return 'completed';
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -15,6 +15,20 @@ export interface CredentialGuardOptions {
|
|
|
15
15
|
blockedBinaries?: string[];
|
|
16
16
|
/** Extra real paths to protect, besides the Claude, Codex, and Sidekick homes. */
|
|
17
17
|
protectedPaths?: string[];
|
|
18
|
+
/**
|
|
19
|
+
* Home overrides to keep instead of unsetting, for a suite that points one
|
|
20
|
+
* at its own fixture before the guard installs. Accepts only the variables
|
|
21
|
+
* the guard unsets: `CLAUDE_CONFIG_DIR`, `CLAUDE_SECURESTORAGE_CONFIG_DIR`,
|
|
22
|
+
* `CODEX_HOME`, and `SIDEKICK_CONFIG_DIR`.
|
|
23
|
+
*
|
|
24
|
+
* Install throws, before changing anything, for any other name, or when a
|
|
25
|
+
* preserved value is, contains, or lies inside a real protected location:
|
|
26
|
+
* the real home's `.claude`, `.claude.json`, and `.codex`, the default
|
|
27
|
+
* Sidekick config dir, or a `protectedPaths` entry. Symlinks are resolved
|
|
28
|
+
* first. The guard cannot tell a real store kept elsewhere from a fixture,
|
|
29
|
+
* so preserve only paths the suite created. Blank values are kept unchecked.
|
|
30
|
+
*/
|
|
31
|
+
preserveEnv?: readonly string[];
|
|
18
32
|
}
|
|
19
33
|
/**
|
|
20
34
|
* Installs the guard once per process and returns it; later calls return the
|