@namzu/cli 12.0.4 → 13.0.0
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/README.md +28 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +119 -60
- package/dist/cli.js.map +1 -1
- package/dist/commands/acp.d.ts +24 -8
- package/dist/commands/acp.d.ts.map +1 -1
- package/dist/commands/acp.js +221 -80
- package/dist/commands/acp.js.map +1 -1
- package/dist/commands/drain.d.ts.map +1 -1
- package/dist/commands/drain.js +45 -9
- package/dist/commands/drain.js.map +1 -1
- package/dist/commands/prior-messages.d.ts +11 -0
- package/dist/commands/prior-messages.d.ts.map +1 -0
- package/dist/commands/prior-messages.js +280 -0
- package/dist/commands/prior-messages.js.map +1 -0
- package/dist/commands/resume.d.ts.map +1 -1
- package/dist/commands/resume.js +21 -19
- package/dist/commands/resume.js.map +1 -1
- package/dist/commands/run-stream.d.ts +5 -3
- package/dist/commands/run-stream.d.ts.map +1 -1
- package/dist/commands/run-stream.js +66 -62
- package/dist/commands/run-stream.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +50 -37
- package/dist/commands/run.js.map +1 -1
- package/dist/config/debug.d.ts +55 -0
- package/dist/config/debug.d.ts.map +1 -0
- package/dist/config/debug.js +126 -0
- package/dist/config/debug.js.map +1 -0
- package/dist/config/load.d.ts +88 -4
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +386 -56
- package/dist/config/load.js.map +1 -1
- package/dist/config/schema.d.ts +87 -5
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +5 -5
- package/dist/config/schema.js.map +1 -1
- package/dist/config/trusted-project-context.d.ts +11 -0
- package/dist/config/trusted-project-context.d.ts.map +1 -0
- package/dist/config/trusted-project-context.js +28 -0
- package/dist/config/trusted-project-context.js.map +1 -0
- package/dist/context/project-path.d.ts +3 -0
- package/dist/context/project-path.d.ts.map +1 -0
- package/dist/context/project-path.js +16 -0
- package/dist/context/project-path.js.map +1 -0
- package/dist/context/project-tracker.d.ts +30 -0
- package/dist/context/project-tracker.d.ts.map +1 -0
- package/dist/context/project-tracker.js +217 -0
- package/dist/context/project-tracker.js.map +1 -0
- package/dist/context/sandbox.d.ts +29 -9
- package/dist/context/sandbox.d.ts.map +1 -1
- package/dist/context/sandbox.js +8 -0
- package/dist/context/sandbox.js.map +1 -1
- package/dist/exit-codes.d.ts +5 -4
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +5 -4
- package/dist/exit-codes.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/clipboard/text.d.ts +43 -0
- package/dist/integrations/clipboard/text.d.ts.map +1 -0
- package/dist/integrations/clipboard/text.js +43 -0
- package/dist/integrations/clipboard/text.js.map +1 -0
- package/dist/integrations/mcp/servers.d.ts +9 -0
- package/dist/integrations/mcp/servers.d.ts.map +1 -1
- package/dist/integrations/mcp/servers.js +11 -4
- package/dist/integrations/mcp/servers.js.map +1 -1
- package/dist/integrations/notifications/terminal.d.ts +32 -0
- package/dist/integrations/notifications/terminal.d.ts.map +1 -0
- package/dist/integrations/notifications/terminal.js +46 -0
- package/dist/integrations/notifications/terminal.js.map +1 -0
- package/dist/integrations/plugins/runtime.d.ts +17 -0
- package/dist/integrations/plugins/runtime.d.ts.map +1 -0
- package/dist/integrations/plugins/runtime.js +100 -0
- package/dist/integrations/plugins/runtime.js.map +1 -0
- package/dist/integrations/providers/credential-store.d.ts +17 -0
- package/dist/integrations/providers/credential-store.d.ts.map +1 -1
- package/dist/integrations/providers/credential-store.js +114 -2
- package/dist/integrations/providers/credential-store.js.map +1 -1
- package/dist/integrations/providers/index.d.ts +2 -2
- package/dist/integrations/providers/index.d.ts.map +1 -1
- package/dist/integrations/providers/index.js +2 -2
- package/dist/integrations/providers/index.js.map +1 -1
- package/dist/integrations/providers/keychain.d.ts +0 -13
- package/dist/integrations/providers/keychain.d.ts.map +1 -1
- package/dist/integrations/providers/keychain.js +0 -76
- package/dist/integrations/providers/keychain.js.map +1 -1
- package/dist/integrations/providers/oauth.d.ts +45 -16
- package/dist/integrations/providers/oauth.d.ts.map +1 -1
- package/dist/integrations/providers/oauth.js +170 -43
- package/dist/integrations/providers/oauth.js.map +1 -1
- package/dist/integrations/providers/register.d.ts.map +1 -1
- package/dist/integrations/providers/register.js +5 -0
- package/dist/integrations/providers/register.js.map +1 -1
- package/dist/integrations/providers/registry.d.ts +18 -1
- package/dist/integrations/providers/registry.d.ts.map +1 -1
- package/dist/integrations/providers/registry.js +30 -9
- package/dist/integrations/providers/registry.js.map +1 -1
- package/dist/integrations/providers/subscription-login.d.ts +2 -0
- package/dist/integrations/providers/subscription-login.d.ts.map +1 -1
- package/dist/integrations/providers/subscription-login.js +117 -14
- package/dist/integrations/providers/subscription-login.js.map +1 -1
- package/dist/integrations/sessions/store.d.ts +111 -1
- package/dist/integrations/sessions/store.d.ts.map +1 -1
- package/dist/integrations/sessions/store.js +400 -7
- package/dist/integrations/sessions/store.js.map +1 -1
- package/dist/integrations/sessions/transcript-export.d.ts +25 -0
- package/dist/integrations/sessions/transcript-export.d.ts.map +1 -0
- package/dist/integrations/sessions/transcript-export.js +441 -0
- package/dist/integrations/sessions/transcript-export.js.map +1 -0
- package/dist/integrations/sessions/turn-evidence.d.ts +138 -0
- package/dist/integrations/sessions/turn-evidence.d.ts.map +1 -0
- package/dist/integrations/sessions/turn-evidence.js +506 -0
- package/dist/integrations/sessions/turn-evidence.js.map +1 -0
- package/dist/integrations/subagents/runtime.d.ts +7 -12
- package/dist/integrations/subagents/runtime.d.ts.map +1 -1
- package/dist/integrations/subagents/runtime.js +19 -10
- package/dist/integrations/subagents/runtime.js.map +1 -1
- package/dist/integrations/trust/store.d.ts.map +1 -1
- package/dist/integrations/trust/store.js +27 -13
- package/dist/integrations/trust/store.js.map +1 -1
- package/dist/permissions/canonical-project.d.ts +9 -0
- package/dist/permissions/canonical-project.d.ts.map +1 -0
- package/dist/permissions/canonical-project.js +13 -0
- package/dist/permissions/canonical-project.js.map +1 -0
- package/dist/permissions/checks.d.ts +65 -0
- package/dist/permissions/checks.d.ts.map +1 -0
- package/dist/permissions/checks.js +122 -0
- package/dist/permissions/checks.js.map +1 -0
- package/dist/permissions/headless-trust.d.ts +9 -5
- package/dist/permissions/headless-trust.d.ts.map +1 -1
- package/dist/permissions/headless-trust.js +18 -4
- package/dist/permissions/headless-trust.js.map +1 -1
- package/dist/permissions/rules.d.ts +16 -7
- package/dist/permissions/rules.d.ts.map +1 -1
- package/dist/permissions/rules.js +78 -13
- package/dist/permissions/rules.js.map +1 -1
- package/dist/tui/App.d.ts +5 -2
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +1555 -143
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/Composer.d.ts +14 -3
- package/dist/tui/Composer.d.ts.map +1 -1
- package/dist/tui/Composer.js +53 -15
- package/dist/tui/Composer.js.map +1 -1
- package/dist/tui/EditPromptPicker.d.ts +8 -0
- package/dist/tui/EditPromptPicker.d.ts.map +1 -0
- package/dist/tui/EditPromptPicker.js +18 -0
- package/dist/tui/EditPromptPicker.js.map +1 -0
- package/dist/tui/LiveActivity.d.ts.map +1 -1
- package/dist/tui/LiveActivity.js +2 -1
- package/dist/tui/LiveActivity.js.map +1 -1
- package/dist/tui/Markdown.d.ts.map +1 -1
- package/dist/tui/Markdown.js +2 -1
- package/dist/tui/Markdown.js.map +1 -1
- package/dist/tui/PermissionOverlay.d.ts.map +1 -1
- package/dist/tui/PermissionOverlay.js +7 -1
- package/dist/tui/PermissionOverlay.js.map +1 -1
- package/dist/tui/Picker.d.ts +4 -4
- package/dist/tui/Picker.d.ts.map +1 -1
- package/dist/tui/Picker.js +86 -7
- package/dist/tui/Picker.js.map +1 -1
- package/dist/tui/ResumePicker.d.ts.map +1 -1
- package/dist/tui/ResumePicker.js +1 -1
- package/dist/tui/ResumePicker.js.map +1 -1
- package/dist/tui/Transcript.d.ts +4 -2
- package/dist/tui/Transcript.d.ts.map +1 -1
- package/dist/tui/Transcript.js +31 -5
- package/dist/tui/Transcript.js.map +1 -1
- package/dist/tui/agent.d.ts +124 -19
- package/dist/tui/agent.d.ts.map +1 -1
- package/dist/tui/agent.js +675 -144
- package/dist/tui/agent.js.map +1 -1
- package/dist/tui/compact-transcript.d.ts +24 -0
- package/dist/tui/compact-transcript.d.ts.map +1 -0
- package/dist/tui/compact-transcript.js +46 -0
- package/dist/tui/compact-transcript.js.map +1 -0
- package/dist/tui/conversation-history.d.ts +33 -0
- package/dist/tui/conversation-history.d.ts.map +1 -0
- package/dist/tui/conversation-history.js +42 -0
- package/dist/tui/conversation-history.js.map +1 -0
- package/dist/tui/edit-prompts.d.ts +23 -0
- package/dist/tui/edit-prompts.d.ts.map +1 -0
- package/dist/tui/edit-prompts.js +35 -0
- package/dist/tui/edit-prompts.js.map +1 -0
- package/dist/tui/live-window.d.ts +3 -1
- package/dist/tui/live-window.d.ts.map +1 -1
- package/dist/tui/live-window.js +20 -8
- package/dist/tui/live-window.js.map +1 -1
- package/dist/tui/slashCommands.d.ts +178 -9
- package/dist/tui/slashCommands.d.ts.map +1 -1
- package/dist/tui/slashCommands.js +339 -15
- package/dist/tui/slashCommands.js.map +1 -1
- package/dist/tui/terminal-display.d.ts +12 -0
- package/dist/tui/terminal-display.d.ts.map +1 -0
- package/dist/tui/terminal-display.js +65 -0
- package/dist/tui/terminal-display.js.map +1 -0
- package/dist/tui/types.d.ts +14 -2
- package/dist/tui/types.d.ts.map +1 -1
- package/dist/tui/workspace-diff.d.ts +40 -0
- package/dist/tui/workspace-diff.d.ts.map +1 -0
- package/dist/tui/workspace-diff.js +101 -0
- package/dist/tui/workspace-diff.js.map +1 -0
- package/package.json +7 -6
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { isCompactionMessage, isProjectInstructionMessageSource, isWorkingMemoryMessage, } from '@namzu/sdk';
|
|
2
|
+
const isObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3
|
+
const isFiniteNumber = (value) => typeof value === 'number' && Number.isFinite(value);
|
|
4
|
+
function optional(value, key, path, accepts, expected) {
|
|
5
|
+
const candidate = value[key];
|
|
6
|
+
return candidate === undefined || accepts(candidate) ? null : `${path}.${key} must be ${expected}`;
|
|
7
|
+
}
|
|
8
|
+
function stringField(value, key, path) {
|
|
9
|
+
return typeof value[key] === 'string' ? null : `${path}.${key} must be a string`;
|
|
10
|
+
}
|
|
11
|
+
function validateCommon(value, path) {
|
|
12
|
+
return (optional(value, 'timestamp', path, isFiniteNumber, 'a finite number') ??
|
|
13
|
+
optional(value, 'cacheHint', path, (candidate) => candidate === 'cache' || candidate === 'ephemeral' || candidate === 'none', '"cache", "ephemeral", or "none"') ??
|
|
14
|
+
optional(value, 'retain', path, (candidate) => typeof candidate === 'boolean', 'a boolean'));
|
|
15
|
+
}
|
|
16
|
+
function validateAttachment(value, path) {
|
|
17
|
+
if (!isObject(value))
|
|
18
|
+
return `${path} must be an attachment object`;
|
|
19
|
+
const type = value.type;
|
|
20
|
+
if (type === 'stored') {
|
|
21
|
+
return `${path} is a stored attachment reference, but stateless run-stream has no attachment store; send inline data instead`;
|
|
22
|
+
}
|
|
23
|
+
if (type === 'document') {
|
|
24
|
+
return (stringField(value, 'data', path) ??
|
|
25
|
+
stringField(value, 'mediaType', path) ??
|
|
26
|
+
optional(value, 'name', path, (candidate) => typeof candidate === 'string', 'a string') ??
|
|
27
|
+
optional(value, 'citations', path, (candidate) => typeof candidate === 'boolean', 'a boolean'));
|
|
28
|
+
}
|
|
29
|
+
if (type !== undefined && type !== 'image') {
|
|
30
|
+
return `${path}.type must be "image", "document", "stored", or absent`;
|
|
31
|
+
}
|
|
32
|
+
return stringField(value, 'data', path) ?? stringField(value, 'mediaType', path);
|
|
33
|
+
}
|
|
34
|
+
function validateAttachments(value, path) {
|
|
35
|
+
if (!Array.isArray(value))
|
|
36
|
+
return `${path} must be an array`;
|
|
37
|
+
for (let index = 0; index < value.length; index++) {
|
|
38
|
+
const error = validateAttachment(value[index], `${path}[${index}]`);
|
|
39
|
+
if (error)
|
|
40
|
+
return error;
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
function validateUserSource(value, path) {
|
|
45
|
+
if (!isObject(value))
|
|
46
|
+
return `${path} must be a source object`;
|
|
47
|
+
if (value.type === 'project-instructions') {
|
|
48
|
+
return isProjectInstructionMessageSource(value)
|
|
49
|
+
? null
|
|
50
|
+
: `${path} must contain unique canonical project-relative AGENTS.md paths`;
|
|
51
|
+
}
|
|
52
|
+
if (value.type !== 'goal-round') {
|
|
53
|
+
return `${path}.type must be "goal-round" or "project-instructions"`;
|
|
54
|
+
}
|
|
55
|
+
return (stringField(value, 'goalId', path) ??
|
|
56
|
+
stringField(value, 'objective', path) ??
|
|
57
|
+
(isFiniteNumber(value.goalRevision) ? null : `${path}.goalRevision must be a finite number`) ??
|
|
58
|
+
(isFiniteNumber(value.round) ? null : `${path}.round must be a finite number`) ??
|
|
59
|
+
(isFiniteNumber(value.maxGoalRounds) ? null : `${path}.maxGoalRounds must be a finite number`));
|
|
60
|
+
}
|
|
61
|
+
function validateAssistantSource(value, path) {
|
|
62
|
+
if (!isObject(value))
|
|
63
|
+
return `${path} must be a source object`;
|
|
64
|
+
if (value.type !== 'model')
|
|
65
|
+
return `${path}.type must be "model"`;
|
|
66
|
+
return (stringField(value, 'providerId', path) ??
|
|
67
|
+
stringField(value, 'model', path) ??
|
|
68
|
+
(Number.isSafeInteger(value.chainIndex) && value.chainIndex >= 0
|
|
69
|
+
? null
|
|
70
|
+
: `${path}.chainIndex must be a non-negative safe integer`));
|
|
71
|
+
}
|
|
72
|
+
function validateToolCall(value, path) {
|
|
73
|
+
if (!isObject(value))
|
|
74
|
+
return `${path} must be a tool-call object`;
|
|
75
|
+
const fn = value.function;
|
|
76
|
+
if (!isObject(fn))
|
|
77
|
+
return `${path}.function must be an object`;
|
|
78
|
+
const metadata = value.metadata;
|
|
79
|
+
return (stringField(value, 'id', path) ??
|
|
80
|
+
(value.type === 'function' ? null : `${path}.type must be "function"`) ??
|
|
81
|
+
stringField(fn, 'name', `${path}.function`) ??
|
|
82
|
+
stringField(fn, 'arguments', `${path}.function`) ??
|
|
83
|
+
(metadata === undefined
|
|
84
|
+
? null
|
|
85
|
+
: !isObject(metadata)
|
|
86
|
+
? `${path}.metadata must be an object`
|
|
87
|
+
: (optional(metadata, 'inputTruncated', `${path}.metadata`, (candidate) => typeof candidate === 'boolean', 'a boolean') ??
|
|
88
|
+
optional(metadata, 'partialArguments', `${path}.metadata`, (candidate) => typeof candidate === 'string', 'a string'))));
|
|
89
|
+
}
|
|
90
|
+
function validateReasoning(value, path) {
|
|
91
|
+
if (!isObject(value))
|
|
92
|
+
return `${path} must be a reasoning object`;
|
|
93
|
+
return ((value.type === 'thinking' || value.type === 'redacted_thinking'
|
|
94
|
+
? null
|
|
95
|
+
: `${path}.type must be "thinking" or "redacted_thinking"`) ??
|
|
96
|
+
optional(value, 'text', path, (candidate) => typeof candidate === 'string', 'a string') ??
|
|
97
|
+
optional(value, 'signature', path, (candidate) => typeof candidate === 'string', 'a string') ??
|
|
98
|
+
optional(value, 'encrypted', path, (candidate) => typeof candidate === 'string', 'a string'));
|
|
99
|
+
}
|
|
100
|
+
function validateCitation(value, path) {
|
|
101
|
+
if (!isObject(value))
|
|
102
|
+
return `${path} must be a citation object`;
|
|
103
|
+
const location = value.location;
|
|
104
|
+
if (!isObject(location))
|
|
105
|
+
return `${path}.location must be an object`;
|
|
106
|
+
return (stringField(value, 'citedText', path) ??
|
|
107
|
+
(isFiniteNumber(value.documentIndex)
|
|
108
|
+
? null
|
|
109
|
+
: `${path}.documentIndex must be a finite number`) ??
|
|
110
|
+
optional(value, 'documentTitle', path, (candidate) => typeof candidate === 'string', 'a string') ??
|
|
111
|
+
(location.kind === 'page' || location.kind === 'char' || location.kind === 'block'
|
|
112
|
+
? null
|
|
113
|
+
: `${path}.location.kind must be "page", "char", or "block"`) ??
|
|
114
|
+
(isFiniteNumber(location.start) ? null : `${path}.location.start must be a finite number`) ??
|
|
115
|
+
(isFiniteNumber(location.end) ? null : `${path}.location.end must be a finite number`));
|
|
116
|
+
}
|
|
117
|
+
function validateToolResultBlock(value, path) {
|
|
118
|
+
if (!isObject(value))
|
|
119
|
+
return `${path} must be a tool-result block object`;
|
|
120
|
+
if (value.type === 'text')
|
|
121
|
+
return stringField(value, 'text', path);
|
|
122
|
+
if (value.type === 'image') {
|
|
123
|
+
return stringField(value, 'data', path) ?? stringField(value, 'mediaType', path);
|
|
124
|
+
}
|
|
125
|
+
if (value.type === 'document')
|
|
126
|
+
return validateAttachment(value, path);
|
|
127
|
+
return `${path}.type must be "text", "image", or "document"`;
|
|
128
|
+
}
|
|
129
|
+
function validateMessage(value, index) {
|
|
130
|
+
const path = `messages[${index}]`;
|
|
131
|
+
if (!isObject(value))
|
|
132
|
+
return `${path} must be an object`;
|
|
133
|
+
const common = validateCommon(value, path);
|
|
134
|
+
if (common)
|
|
135
|
+
return common;
|
|
136
|
+
if (value.role === 'system') {
|
|
137
|
+
if (typeof value.content !== 'string')
|
|
138
|
+
return `${path}.content must be a string`;
|
|
139
|
+
return isCompactionMessage(value.content) || isWorkingMemoryMessage(value.content)
|
|
140
|
+
? null
|
|
141
|
+
: `${path} is an arbitrary system prompt; stateless history accepts only compacted or working-memory conversation state`;
|
|
142
|
+
}
|
|
143
|
+
if (value.role === 'user') {
|
|
144
|
+
if (typeof value.content !== 'string')
|
|
145
|
+
return `${path}.content must be a string`;
|
|
146
|
+
return ((value.attachments === undefined
|
|
147
|
+
? null
|
|
148
|
+
: validateAttachments(value.attachments, `${path}.attachments`)) ??
|
|
149
|
+
(value.source === undefined ? null : validateUserSource(value.source, `${path}.source`)));
|
|
150
|
+
}
|
|
151
|
+
if (value.role === 'assistant') {
|
|
152
|
+
if (typeof value.content !== 'string' && value.content !== null) {
|
|
153
|
+
return `${path}.content must be a string or null`;
|
|
154
|
+
}
|
|
155
|
+
if (value.toolCalls !== undefined) {
|
|
156
|
+
if (!Array.isArray(value.toolCalls))
|
|
157
|
+
return `${path}.toolCalls must be an array`;
|
|
158
|
+
for (let callIndex = 0; callIndex < value.toolCalls.length; callIndex++) {
|
|
159
|
+
const error = validateToolCall(value.toolCalls[callIndex], `${path}.toolCalls[${callIndex}]`);
|
|
160
|
+
if (error)
|
|
161
|
+
return error;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (value.reasoning !== undefined) {
|
|
165
|
+
if (!Array.isArray(value.reasoning))
|
|
166
|
+
return `${path}.reasoning must be an array`;
|
|
167
|
+
for (let reasoningIndex = 0; reasoningIndex < value.reasoning.length; reasoningIndex++) {
|
|
168
|
+
const error = validateReasoning(value.reasoning[reasoningIndex], `${path}.reasoning[${reasoningIndex}]`);
|
|
169
|
+
if (error)
|
|
170
|
+
return error;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (value.citations !== undefined) {
|
|
174
|
+
if (!Array.isArray(value.citations))
|
|
175
|
+
return `${path}.citations must be an array`;
|
|
176
|
+
for (let citationIndex = 0; citationIndex < value.citations.length; citationIndex++) {
|
|
177
|
+
const error = validateCitation(value.citations[citationIndex], `${path}.citations[${citationIndex}]`);
|
|
178
|
+
if (error)
|
|
179
|
+
return error;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return value.source === undefined
|
|
183
|
+
? null
|
|
184
|
+
: validateAssistantSource(value.source, `${path}.source`);
|
|
185
|
+
}
|
|
186
|
+
if (value.role === 'tool') {
|
|
187
|
+
if (typeof value.content !== 'string') {
|
|
188
|
+
if (!Array.isArray(value.content)) {
|
|
189
|
+
return `${path}.content must be a string or tool-result block array`;
|
|
190
|
+
}
|
|
191
|
+
for (let blockIndex = 0; blockIndex < value.content.length; blockIndex++) {
|
|
192
|
+
const error = validateToolResultBlock(value.content[blockIndex], `${path}.content[${blockIndex}]`);
|
|
193
|
+
if (error)
|
|
194
|
+
return error;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return (stringField(value, 'toolCallId', path) ??
|
|
198
|
+
optional(value, 'isError', path, (candidate) => typeof candidate === 'boolean', 'a boolean'));
|
|
199
|
+
}
|
|
200
|
+
return `${path}.role must be "system", "user", "assistant", or "tool"`;
|
|
201
|
+
}
|
|
202
|
+
function validateSequence(messages) {
|
|
203
|
+
const seenCallIds = new Set();
|
|
204
|
+
let pending = null;
|
|
205
|
+
let sawConversation = false;
|
|
206
|
+
for (let index = 0; index < messages.length; index++) {
|
|
207
|
+
const message = messages[index];
|
|
208
|
+
if (!message)
|
|
209
|
+
continue;
|
|
210
|
+
if (pending) {
|
|
211
|
+
if (message.role !== 'tool') {
|
|
212
|
+
return `messages[${index}] cannot appear before every tool call from messages[${pending.openedAt}] has a result`;
|
|
213
|
+
}
|
|
214
|
+
if (!pending.ids.has(message.toolCallId)) {
|
|
215
|
+
return `messages[${index}].toolCallId does not match an unanswered call from messages[${pending.openedAt}]`;
|
|
216
|
+
}
|
|
217
|
+
pending.ids.delete(message.toolCallId);
|
|
218
|
+
if (pending.ids.size === 0)
|
|
219
|
+
pending = null;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
if (message.role === 'system') {
|
|
223
|
+
if (sawConversation)
|
|
224
|
+
return `messages[${index}] is a system message after conversation began`;
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
if (!sawConversation) {
|
|
228
|
+
sawConversation = true;
|
|
229
|
+
if (message.role !== 'user') {
|
|
230
|
+
return `messages[${index}] must be a user message at the start of conversation history`;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (message.role === 'tool')
|
|
234
|
+
return `messages[${index}] is a tool result with no pending call`;
|
|
235
|
+
if (message.role !== 'assistant' || !message.toolCalls || message.toolCalls.length === 0) {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
const ids = new Set();
|
|
239
|
+
for (let callIndex = 0; callIndex < message.toolCalls.length; callIndex++) {
|
|
240
|
+
const id = message.toolCalls[callIndex]?.id;
|
|
241
|
+
if (!id)
|
|
242
|
+
continue;
|
|
243
|
+
if (seenCallIds.has(id) || ids.has(id)) {
|
|
244
|
+
return `messages[${index}].toolCalls[${callIndex}].id duplicates tool call id "${id}"`;
|
|
245
|
+
}
|
|
246
|
+
ids.add(id);
|
|
247
|
+
seenCallIds.add(id);
|
|
248
|
+
}
|
|
249
|
+
pending = { openedAt: index, ids };
|
|
250
|
+
}
|
|
251
|
+
if (pending) {
|
|
252
|
+
return `messages[${pending.openedAt}] has tool calls without immediate results for: ${[...pending.ids].join(', ')}`;
|
|
253
|
+
}
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
/** Parse the stateless stdin contract without dropping or inventing message fields. */
|
|
257
|
+
export function parsePriorMessages(raw) {
|
|
258
|
+
const trimmed = raw.trim();
|
|
259
|
+
if (!trimmed)
|
|
260
|
+
return { ok: true, messages: [] };
|
|
261
|
+
let parsed;
|
|
262
|
+
try {
|
|
263
|
+
parsed = JSON.parse(trimmed);
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
return { ok: false, error: 'stdin history is not valid JSON' };
|
|
267
|
+
}
|
|
268
|
+
if (!Array.isArray(parsed)) {
|
|
269
|
+
return { ok: false, error: 'stdin history must be a JSON Message[] array' };
|
|
270
|
+
}
|
|
271
|
+
for (let index = 0; index < parsed.length; index++) {
|
|
272
|
+
const error = validateMessage(parsed[index], index);
|
|
273
|
+
if (error)
|
|
274
|
+
return { ok: false, error };
|
|
275
|
+
}
|
|
276
|
+
const messages = parsed;
|
|
277
|
+
const sequenceError = validateSequence(messages);
|
|
278
|
+
return sequenceError ? { ok: false, error: sequenceError } : { ok: true, messages };
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=prior-messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prior-messages.js","sourceRoot":"","sources":["../../src/commands/prior-messages.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../src/commands/resume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,EACN,KAAK,WAAW,EAIhB,MAAM,mCAAmC,CAAA;AAE1C,MAAM,WAAW,aAAa;IAC7B,oEAAoE;IACpE,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,wDAAwD;IACxD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAED,MAAM,MAAM,aAAa,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,GAC/F;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAClC,QAAQ,EAAE,WAAW,GAAG,IAAI,EAC5B,OAAO,EAAE,aAAa,EACtB,GAAG,EAAE,MAAM,GACT,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../src/commands/resume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,EACN,KAAK,WAAW,EAIhB,MAAM,mCAAmC,CAAA;AAE1C,MAAM,WAAW,aAAa;IAC7B,oEAAoE;IACpE,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,wDAAwD;IACxD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAED,MAAM,MAAM,aAAa,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,GAC/F;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAClC,QAAQ,EAAE,WAAW,GAAG,IAAI,EAC5B,OAAO,EAAE,aAAa,EACtB,GAAG,EAAE,MAAM,GACT,OAAO,CAAC,aAAa,CAAC,CA4CxB"}
|
package/dist/commands/resume.js
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* If that is what you want, run the command with no flag. The absence of a
|
|
32
32
|
* thing must not be spellable as a silent widening of it.
|
|
33
33
|
*/
|
|
34
|
-
import { listRecent,
|
|
34
|
+
import { listRecent, loadResumableConversation, } from '../integrations/sessions/store.js';
|
|
35
35
|
/**
|
|
36
36
|
* Resolve what a `--continue` / `--resume` asked for.
|
|
37
37
|
*
|
|
@@ -54,8 +54,17 @@ export async function resolveResume(sessions, request, cwd) {
|
|
|
54
54
|
message: `no conversation store in ${cwd} — it could not be opened, so there is nothing to resume`,
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
const recent = await listRecent(sessions, 50);
|
|
58
57
|
if (request.continueLast) {
|
|
58
|
+
let recent;
|
|
59
|
+
try {
|
|
60
|
+
recent = await listRecent(sessions, 50);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
return {
|
|
64
|
+
kind: 'error',
|
|
65
|
+
message: `conversations in ${cwd} cannot be resumed: ${err instanceof Error ? err.message : String(err)}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
59
68
|
const latest = recent[0];
|
|
60
69
|
if (!latest) {
|
|
61
70
|
// Its own sentence, because the cause is different from a bad id and
|
|
@@ -66,25 +75,18 @@ export async function resolveResume(sessions, request, cwd) {
|
|
|
66
75
|
message: `no previous conversation in ${cwd} — run without --continue to start one, or pass --cwd if you meant a different directory`,
|
|
67
76
|
};
|
|
68
77
|
}
|
|
69
|
-
return await load(sessions, latest);
|
|
78
|
+
return await load(sessions, latest.id, cwd);
|
|
70
79
|
}
|
|
71
80
|
const wanted = request.sessionId;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
kind: 'error',
|
|
77
|
-
message: known === 0
|
|
78
|
-
? `no conversation "${wanted}" in ${cwd}, and no others either — pass --cwd if you meant a different directory`
|
|
79
|
-
: `no conversation "${wanted}" in ${cwd}. ${known} other${known === 1 ? '' : 's'} here; \`namzu history\` lists them`,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
return await load(sessions, match);
|
|
81
|
+
// An exact id is not a request for a row in the recent picker. The previous
|
|
82
|
+
// implementation searched a 50-row list, so the 51st valid conversation was
|
|
83
|
+
// reported missing even though its durable record was intact.
|
|
84
|
+
return await load(sessions, wanted, cwd);
|
|
83
85
|
}
|
|
84
|
-
async function load(sessions,
|
|
86
|
+
async function load(sessions, sessionId, cwd) {
|
|
85
87
|
let messages;
|
|
86
88
|
try {
|
|
87
|
-
messages = await
|
|
89
|
+
messages = await loadResumableConversation(sessions, sessionId);
|
|
88
90
|
}
|
|
89
91
|
catch (err) {
|
|
90
92
|
// Reading the transcript failed after the conversation was found. NOT
|
|
@@ -93,15 +95,15 @@ async function load(sessions, conversation) {
|
|
|
93
95
|
// session that had been resumed.
|
|
94
96
|
return {
|
|
95
97
|
kind: 'error',
|
|
96
|
-
message: `conversation "${
|
|
98
|
+
message: `conversation "${sessionId}" could not be resumed in ${cwd}: ${err instanceof Error ? err.message : String(err)}`,
|
|
97
99
|
};
|
|
98
100
|
}
|
|
99
101
|
if (messages.length === 0) {
|
|
100
102
|
return {
|
|
101
103
|
kind: 'error',
|
|
102
|
-
message: `conversation "${
|
|
104
|
+
message: `conversation "${sessionId}" has no messages to resume — its transcript is empty`,
|
|
103
105
|
};
|
|
104
106
|
}
|
|
105
|
-
return { kind: 'resumed', sessionId
|
|
107
|
+
return { kind: 'resumed', sessionId, messages };
|
|
106
108
|
}
|
|
107
109
|
//# sourceMappingURL=resume.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../src/commands/resume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,OAAO,EAGN,UAAU,EACV,
|
|
1
|
+
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../src/commands/resume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,OAAO,EAGN,UAAU,EACV,yBAAyB,GACzB,MAAM,mCAAmC,CAAA;AAc1C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,QAA4B,EAC5B,OAAsB,EACtB,GAAW;IAEX,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IACzE,IAAI,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QAC/C,OAAO;YACN,IAAI,EAAE,OAAO;YACb,OAAO,EACN,wIAAwI;SACzI,CAAA;IACF,CAAC;IACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,OAAO;YACN,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,4BAA4B,GAAG,0DAA0D;SAClG,CAAA;IACF,CAAC;IAED,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QAC1B,IAAI,MAA4B,CAAA;QAChC,IAAI,CAAC;YACJ,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO;gBACN,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,oBAAoB,GAAG,uBAAuB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;aACzG,CAAA;QACF,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;QACxB,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,qEAAqE;YACrE,qEAAqE;YACrE,6DAA6D;YAC7D,OAAO;gBACN,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,+BAA+B,GAAG,0FAA0F;aACrI,CAAA;QACF,CAAC;QACD,OAAO,MAAM,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IAC5C,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,SAAmB,CAAA;IAC1C,4EAA4E;IAC5E,4EAA4E;IAC5E,8DAA8D;IAC9D,OAAO,MAAM,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;AACzC,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,QAAqB,EAAE,SAAiB,EAAE,GAAW;IACxE,IAAI,QAA4B,CAAA;IAChC,IAAI,CAAC;QACJ,QAAQ,GAAG,MAAM,yBAAyB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;IAChE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,sEAAsE;QACtE,gEAAgE;QAChE,kEAAkE;QAClE,iCAAiC;QACjC,OAAO;YACN,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,iBAAiB,SAAS,6BAA6B,GAAG,KAClE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAChD,EAAE;SACF,CAAA;IACF,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO;YACN,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,iBAAiB,SAAS,uDAAuD;SAC1F,CAAA;IACF,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAA;AAChD,CAAC"}
|
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
* History: with `--session <key>` the turn is bound to a persisted
|
|
11
11
|
* conversation in the cwd's `.namzu` store (keyed by the embedder's own
|
|
12
|
-
* session id), so prior turns are loaded as context and the
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* session id), so prior turns are loaded as context and the kernel's exact
|
|
13
|
+
* settled conversation projection is published — including opaque reasoning
|
|
14
|
+
* and complete tool turns, excluding its fresh per-run system floor. That's
|
|
15
|
+
* what lets a reopened session show and replay its past messages (`namzu
|
|
16
|
+
* history --session <key>`). Without `--session`,
|
|
15
17
|
* prior history may be supplied on stdin as a JSON `Message[]` and nothing is
|
|
16
18
|
* persisted (stateless one-shot).
|
|
17
19
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-stream.d.ts","sourceRoot":"","sources":["../../src/commands/run-stream.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"run-stream.d.ts","sourceRoot":"","sources":["../../src/commands/run-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AA8BH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAoB5C,eAAO,MAAM,gBAAgB,EAAE,UAiV9B,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,UAkD5B,CAAA;AAMD,eAAO,MAAM,iBAAiB,EAAE,UAqC/B,CAAA;AAOD,eAAO,MAAM,oBAAoB,EAAE,UA8ClC,CAAA"}
|
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
* History: with `--session <key>` the turn is bound to a persisted
|
|
11
11
|
* conversation in the cwd's `.namzu` store (keyed by the embedder's own
|
|
12
|
-
* session id), so prior turns are loaded as context and the
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* session id), so prior turns are loaded as context and the kernel's exact
|
|
13
|
+
* settled conversation projection is published — including opaque reasoning
|
|
14
|
+
* and complete tool turns, excluding its fresh per-run system floor. That's
|
|
15
|
+
* what lets a reopened session show and replay its past messages (`namzu
|
|
16
|
+
* history --session <key>`). Without `--session`,
|
|
15
17
|
* prior history may be supplied on stdin as a JSON `Message[]` and nothing is
|
|
16
18
|
* persisted (stateless one-shot).
|
|
17
19
|
*
|
|
@@ -55,14 +57,17 @@
|
|
|
55
57
|
* asked for rather than achieving it.
|
|
56
58
|
*/
|
|
57
59
|
import { jsonLinesSink } from '@namzu/sdk';
|
|
60
|
+
import { resolveTrustedProjectContext } from '../config/trusted-project-context.js';
|
|
58
61
|
import { EXIT_FAIL, EXIT_OK, EXIT_UNTRUSTED } from '../exit-codes.js';
|
|
59
|
-
import { appendMessages, loadConversation, openSessions, resolveConversation, } from '../integrations/sessions/store.js';
|
|
62
|
+
import { appendMessages, loadConversation, openSessions, replaceConversation, resolveConversation, } from '../integrations/sessions/store.js';
|
|
60
63
|
import { contextLogging, installCliLogging } from '../logging.js';
|
|
61
64
|
import { decideHeadlessTrust } from '../permissions/headless-trust.js';
|
|
62
65
|
import { resolvePermissionMode } from '../permissions/mode.js';
|
|
63
66
|
import { compilePermissions } from '../permissions/rules.js';
|
|
67
|
+
import { planTurnPublication } from '../tui/conversation-history.js';
|
|
64
68
|
import { hostCommandNames } from '../tui/slashCommands.js';
|
|
65
69
|
import { expandHeadlessCommand } from '../user-commands/store.js';
|
|
70
|
+
import { parsePriorMessages } from './prior-messages.js';
|
|
66
71
|
import { applyProviderFlags, buildGate, loadSkillsContext, parseRunFlags, resolveWorkingDirectory, unknownOptionMessage, } from './run-flags.js';
|
|
67
72
|
async function readStdin() {
|
|
68
73
|
if (process.stdin.isTTY)
|
|
@@ -75,34 +80,12 @@ async function readStdin() {
|
|
|
75
80
|
function defaultPrefs(detected) {
|
|
76
81
|
const first = detected[0];
|
|
77
82
|
return first
|
|
78
|
-
? {
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function parsePriorMessages(raw) {
|
|
83
|
-
const trimmed = raw.trim();
|
|
84
|
-
if (!trimmed)
|
|
85
|
-
return [];
|
|
86
|
-
try {
|
|
87
|
-
const parsed = JSON.parse(trimmed);
|
|
88
|
-
if (!Array.isArray(parsed))
|
|
89
|
-
return [];
|
|
90
|
-
const out = [];
|
|
91
|
-
for (const m of parsed) {
|
|
92
|
-
if (!m || typeof m !== 'object')
|
|
93
|
-
continue;
|
|
94
|
-
const role = m.role;
|
|
95
|
-
const content = m.content;
|
|
96
|
-
if ((role === 'user' || role === 'assistant') && typeof content === 'string') {
|
|
97
|
-
const ts = m.timestamp;
|
|
98
|
-
out.push({ role, content, timestamp: typeof ts === 'number' ? ts : Date.now() });
|
|
99
|
-
}
|
|
83
|
+
? {
|
|
84
|
+
version: 3,
|
|
85
|
+
providers: [{ id: first.entry.id }],
|
|
86
|
+
subagents: { active: [] },
|
|
100
87
|
}
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
return [];
|
|
105
|
-
}
|
|
88
|
+
: null;
|
|
106
89
|
}
|
|
107
90
|
export const runStreamCommand = {
|
|
108
91
|
name: 'run-stream',
|
|
@@ -121,6 +104,8 @@ export const runStreamCommand = {
|
|
|
121
104
|
'',
|
|
122
105
|
'History is bound with --session <id>. --continue and --resume are `run`',
|
|
123
106
|
'options and are refused here rather than ignored.',
|
|
107
|
+
'Without --session, optional stdin must be one complete JSON Message[];',
|
|
108
|
+
'invalid or provider-incomplete tool history is refused before a run.',
|
|
124
109
|
'',
|
|
125
110
|
'The folder has to be trusted: run `namzu` here once and accept the',
|
|
126
111
|
'prompt, or pass --trust for one run. An untrusted folder emits an error',
|
|
@@ -136,7 +121,8 @@ export const runStreamCommand = {
|
|
|
136
121
|
'there, a conversation that cannot be opened); 77 when the folder has not',
|
|
137
122
|
'been trusted, which only a person can change.',
|
|
138
123
|
].join('\n'),
|
|
139
|
-
handler: async ({ ctx, rawArgs }) => {
|
|
124
|
+
handler: async ({ ctx: bootstrapCtx, rawArgs }) => {
|
|
125
|
+
let ctx = bootstrapCtx;
|
|
140
126
|
const write = (o) => {
|
|
141
127
|
process.stdout.write(`${JSON.stringify(o)}\n`);
|
|
142
128
|
};
|
|
@@ -179,26 +165,7 @@ export const runStreamCommand = {
|
|
|
179
165
|
const resolved = resolveWorkingDirectory(flags.cwd);
|
|
180
166
|
if ('error' in resolved)
|
|
181
167
|
return fail(resolved.error);
|
|
182
|
-
const
|
|
183
|
-
// The same expansion `run` does. A host UI sending `/ozet x` on behalf of
|
|
184
|
-
// someone who defined that command should get the command, not the model
|
|
185
|
-
// improvising on the literal text.
|
|
186
|
-
const expansion = expandHeadlessCommand(prompt, {
|
|
187
|
-
cwd,
|
|
188
|
-
// Through the merge, so a kernel-registered command is refused or
|
|
189
|
-
// expanded here with the same vocabulary the interactive path
|
|
190
|
-
// uses. Mapping the local array left it unknown, and an unknown
|
|
191
|
-
// name goes to the model as prose.
|
|
192
|
-
builtins: hostCommandNames(),
|
|
193
|
-
});
|
|
194
|
-
// Two different refusals wear this one word. An interactive builtin named
|
|
195
|
-
// headlessly, or arguments handed to a template that takes none, are fixed
|
|
196
|
-
// by sending a different prompt. A command FILE that will not parse is not
|
|
197
|
-
// — and no prompt fixes a file.
|
|
198
|
-
if (expansion.kind === 'refused') {
|
|
199
|
-
return expansion.fixable ? fail(expansion.reason) : refuse(expansion.reason);
|
|
200
|
-
}
|
|
201
|
-
const finalPrompt = expansion.kind === 'expanded' ? expansion.prompt : prompt;
|
|
168
|
+
const requestedCwd = resolved.cwd;
|
|
202
169
|
// Before the session store is opened, before anything is read or run in
|
|
203
170
|
// that directory.
|
|
204
171
|
//
|
|
@@ -209,12 +176,27 @@ export const runStreamCommand = {
|
|
|
209
176
|
// a host that cannot tell the two apart will retry the one that must not
|
|
210
177
|
// be retried — so the event carries the explanation and the exit code
|
|
211
178
|
// carries the fact that nothing ran.
|
|
212
|
-
const trust = decideHeadlessTrust({
|
|
179
|
+
const trust = decideHeadlessTrust({
|
|
180
|
+
cwd: requestedCwd,
|
|
181
|
+
trustFlag: flags.trust,
|
|
182
|
+
});
|
|
213
183
|
if (!trust.allowed) {
|
|
214
184
|
write({ kind: 'error', message: trust.message ?? 'folder not trusted' });
|
|
215
185
|
write({ kind: 'done' });
|
|
216
186
|
return EXIT_UNTRUSTED;
|
|
217
187
|
}
|
|
188
|
+
const cwd = trust.cwd;
|
|
189
|
+
ctx = resolveTrustedProjectContext(bootstrapCtx, cwd);
|
|
190
|
+
// Project command discovery belongs behind the target folder's trust
|
|
191
|
+
// gate, alongside project config and instructions.
|
|
192
|
+
const expansion = expandHeadlessCommand(prompt, {
|
|
193
|
+
cwd,
|
|
194
|
+
builtins: hostCommandNames(),
|
|
195
|
+
});
|
|
196
|
+
if (expansion.kind === 'refused') {
|
|
197
|
+
return expansion.fixable ? fail(expansion.reason) : refuse(expansion.reason);
|
|
198
|
+
}
|
|
199
|
+
const finalPrompt = expansion.kind === 'expanded' ? expansion.prompt : prompt;
|
|
218
200
|
// Resolve the persisted conversation (if a session key was given) so we
|
|
219
201
|
// load prior turns as context and can append this turn afterward. Falls
|
|
220
202
|
// back to stdin-supplied history when running stateless.
|
|
@@ -259,7 +241,10 @@ export const runStreamCommand = {
|
|
|
259
241
|
}
|
|
260
242
|
}
|
|
261
243
|
if (!cli) {
|
|
262
|
-
|
|
244
|
+
const parsed = parsePriorMessages(await readStdin());
|
|
245
|
+
if (!parsed.ok)
|
|
246
|
+
return fail(`invalid stdin history: ${parsed.error}`);
|
|
247
|
+
prior = [...parsed.messages];
|
|
263
248
|
}
|
|
264
249
|
// Always NDJSON on stderr, regardless of --log-format/NAMZU_LOG_FORMAT
|
|
265
250
|
// — this is the machine-read channel §6.6 of the logging design
|
|
@@ -291,7 +276,7 @@ export const runStreamCommand = {
|
|
|
291
276
|
});
|
|
292
277
|
if ('error' in modeResult)
|
|
293
278
|
return fail(modeResult.error);
|
|
294
|
-
const permissions = compilePermissions(ctx.config.permissions);
|
|
279
|
+
const permissions = compilePermissions(ctx.config.permissions, ctx.config.permissionChecks);
|
|
295
280
|
for (const d of permissions.diagnostics) {
|
|
296
281
|
const where = d.pattern ? `permissions.${d.tool}."${d.pattern}"` : `permissions.${d.tool}`;
|
|
297
282
|
// In band, because a host line-scanning stdout has no other channel —
|
|
@@ -312,6 +297,8 @@ export const runStreamCommand = {
|
|
|
312
297
|
...(gate ?? {}),
|
|
313
298
|
permissionMode: modeResult.mode,
|
|
314
299
|
...(ctx.config.mcpServers ? { mcpServers: ctx.config.mcpServers } : {}),
|
|
300
|
+
...(ctx.config.plugins ? { plugins: ctx.config.plugins } : {}),
|
|
301
|
+
...(ctx.config.sandbox ? { sandbox: ctx.config.sandbox } : {}),
|
|
315
302
|
});
|
|
316
303
|
if (!session.hasProvider) {
|
|
317
304
|
await session.close();
|
|
@@ -359,8 +346,14 @@ export const runStreamCommand = {
|
|
|
359
346
|
};
|
|
360
347
|
const messages = [...prior, userMessage];
|
|
361
348
|
let assistantText = '';
|
|
349
|
+
let conversationMessages;
|
|
362
350
|
try {
|
|
363
|
-
for await (const event of session.send(messages,
|
|
351
|
+
for await (const event of session.send(messages, {
|
|
352
|
+
...(extraSystem ? { extraSystem } : {}),
|
|
353
|
+
onConversationMessages: (settled) => {
|
|
354
|
+
conversationMessages = settled;
|
|
355
|
+
},
|
|
356
|
+
})) {
|
|
364
357
|
if (event.kind === 'delta')
|
|
365
358
|
assistantText += event.text;
|
|
366
359
|
write(event);
|
|
@@ -394,12 +387,23 @@ export const runStreamCommand = {
|
|
|
394
387
|
// later reads are now incomplete.
|
|
395
388
|
if (cli && conversationId) {
|
|
396
389
|
try {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
390
|
+
if (conversationMessages) {
|
|
391
|
+
const publication = planTurnPublication(prior, userMessage, conversationMessages);
|
|
392
|
+
if (publication.kind === 'replace') {
|
|
393
|
+
await replaceConversation(cli, conversationId, publication.messages);
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
await appendMessages(cli, conversationId, publication.messages);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
const assistant = {
|
|
401
|
+
role: 'assistant',
|
|
402
|
+
content: assistantText,
|
|
403
|
+
timestamp: Date.now(),
|
|
404
|
+
};
|
|
405
|
+
await appendMessages(cli, conversationId, [userMessage, assistant]);
|
|
406
|
+
}
|
|
403
407
|
}
|
|
404
408
|
catch (err) {
|
|
405
409
|
write({
|