@nowcrew/daemon 0.5.12 → 0.5.13

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.
@@ -0,0 +1,310 @@
1
+ import { z } from "zod";
2
+ const ExecutionIdSchema = z.string().uuid();
3
+ const ProtocolVersionSchema = z.literal(1);
4
+ const TimestampSchema = z.string().datetime({ offset: true });
5
+ export const MAX_PG_INTEGER = 2_147_483_647;
6
+ const MIN_SIGNED_32_INTEGER = -2_147_483_648;
7
+ const SequenceSchema = z.number().int().min(0).max(MAX_PG_INTEGER);
8
+ const TokenCountSchema = z.number().int().min(0).max(MAX_PG_INTEGER);
9
+ const ExitCodeSchema = z.number().int().min(MIN_SIGNED_32_INTEGER).max(MAX_PG_INTEGER);
10
+ const RuntimeSchema = z.enum(["claude", "codex", "kimi"]);
11
+ const UnsafePathCharacterSchema = /[\p{Cc}<>:"/\\|?*]/u;
12
+ const WindowsReservedNameSchema = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i;
13
+ const AgentHandleSchema = z.string().min(1).max(64).refine((handle) => handle !== "."
14
+ && handle !== ".."
15
+ && !UnsafePathCharacterSchema.test(handle)
16
+ && !WindowsReservedNameSchema.test(handle)
17
+ && !handle.endsWith(".")
18
+ && !handle.endsWith(" ")
19
+ && Buffer.byteLength(handle, "utf8") <= 255, "agent handle must be a cross-platform safe filesystem component");
20
+ export const ReasoningSchema = z.enum([
21
+ "default",
22
+ "none",
23
+ "minimal",
24
+ "low",
25
+ "medium",
26
+ "high",
27
+ "xhigh",
28
+ "max",
29
+ ]);
30
+ export const PermissionSchema = z.enum([
31
+ "local_default",
32
+ "sandboxed",
33
+ "workspace_write",
34
+ "full_access",
35
+ ]);
36
+ export const EffectivePermissionSchema = z.enum([
37
+ "sandboxed",
38
+ "workspace_write",
39
+ "full_access",
40
+ ]);
41
+ export const LegacyAgentStartSchema = z.object({
42
+ type: z.literal("agent:start"),
43
+ agentHandle: z.string().min(1),
44
+ channelId: z.string().min(1),
45
+ reason: z.string().optional(),
46
+ wake: z.object({
47
+ seq: z.number().int().nonnegative().optional(),
48
+ content: z.string().optional(),
49
+ senderHandle: z.string().optional(),
50
+ threadId: z.string().optional(),
51
+ origin: z.enum(["wecom"]).optional(),
52
+ }).passthrough().optional(),
53
+ scheduledRun: z.object({
54
+ jobId: z.string().min(1),
55
+ runId: z.string().min(1),
56
+ title: z.string().optional(),
57
+ outputPolicy: z.unknown().optional(),
58
+ }).passthrough().optional(),
59
+ silent: z.boolean().optional(),
60
+ }).passthrough();
61
+ export const RejectionReasonSchema = z.enum([
62
+ "invalid_spec",
63
+ "runtime_unavailable",
64
+ "capability_missing",
65
+ "local_policy_denied",
66
+ "resource_limit",
67
+ ]);
68
+ export const ActivityKindSchema = z.enum([
69
+ "working",
70
+ "thinking",
71
+ "reading",
72
+ "sending",
73
+ "claiming",
74
+ "checking",
75
+ "done",
76
+ "error",
77
+ ]);
78
+ export const ConsoleStreamSchema = z.enum([
79
+ "system",
80
+ "thinking",
81
+ "text",
82
+ "tool",
83
+ "tool_result",
84
+ "result",
85
+ "error",
86
+ ]);
87
+ export const ExecutionStartSchema = z.object({
88
+ type: z.literal("execution:start"),
89
+ protocolVersion: ProtocolVersionSchema,
90
+ executionId: ExecutionIdSchema,
91
+ agent: z.object({
92
+ id: z.string().min(1),
93
+ handle: AgentHandleSchema,
94
+ }).strict(),
95
+ workspace: z.object({
96
+ taskKey: z.string().min(1).max(200),
97
+ resumeKey: z.string().min(1).max(200).optional(),
98
+ }).strict(),
99
+ instructions: z.object({
100
+ language: z.enum(["zh", "en"]),
101
+ systemPrompt: z.string(),
102
+ wakePrompt: z.string(),
103
+ }).strict(),
104
+ runtime: z.object({
105
+ name: RuntimeSchema,
106
+ model: z.string().optional(),
107
+ reasoning: ReasoningSchema.optional(),
108
+ timeoutMs: z.number().int().positive().optional(),
109
+ }).strict(),
110
+ permissions: z.object({
111
+ requested: PermissionSchema,
112
+ }).strict(),
113
+ context: z.object({
114
+ channelId: z.string().min(1),
115
+ threadId: z.string().min(1).optional(),
116
+ wakeMessageId: z.string().min(1).optional(),
117
+ }).strict(),
118
+ reporting: z.object({
119
+ captureFinal: z.boolean(),
120
+ streamActivity: z.boolean(),
121
+ streamConsole: z.boolean(),
122
+ }).strict(),
123
+ }).strict();
124
+ export const ExecutionCancelSchema = z.object({
125
+ type: z.literal("execution:cancel"),
126
+ protocolVersion: ProtocolVersionSchema,
127
+ executionId: ExecutionIdSchema,
128
+ }).strict();
129
+ export const ExecutionSyncSchema = z.object({
130
+ type: z.literal("execution:sync"),
131
+ protocolVersion: ProtocolVersionSchema,
132
+ reqId: z.string().min(1).max(200),
133
+ }).strict();
134
+ export const ExecutionCompletionAckSchema = z.object({
135
+ type: z.literal("execution:completion-ack"),
136
+ protocolVersion: ProtocolVersionSchema,
137
+ executionId: ExecutionIdSchema,
138
+ }).strict();
139
+ export const ExecutionAcceptedSchema = z.object({
140
+ type: z.literal("execution:accepted"),
141
+ protocolVersion: ProtocolVersionSchema,
142
+ executionId: ExecutionIdSchema,
143
+ state: z.enum(["queued", "ready"]),
144
+ effectivePermission: EffectivePermissionSchema,
145
+ at: TimestampSchema,
146
+ }).strict();
147
+ export const ExecutionRejectedSchema = z.object({
148
+ type: z.literal("execution:rejected"),
149
+ protocolVersion: ProtocolVersionSchema,
150
+ executionId: ExecutionIdSchema,
151
+ reason: RejectionReasonSchema,
152
+ message: z.string().optional(),
153
+ at: TimestampSchema,
154
+ }).strict();
155
+ export const ExecutionStartedSchema = z.object({
156
+ type: z.literal("execution:started"),
157
+ protocolVersion: ProtocolVersionSchema,
158
+ executionId: ExecutionIdSchema,
159
+ at: TimestampSchema,
160
+ }).strict();
161
+ export const ExecutionActivitySchema = z.object({
162
+ type: z.literal("execution:activity"),
163
+ protocolVersion: ProtocolVersionSchema,
164
+ executionId: ExecutionIdSchema,
165
+ activity: ActivityKindSchema,
166
+ detail: z.string(),
167
+ seq: SequenceSchema,
168
+ at: TimestampSchema,
169
+ }).strict();
170
+ export const ExecutionConsoleSchema = z.object({
171
+ type: z.literal("execution:console"),
172
+ protocolVersion: ProtocolVersionSchema,
173
+ executionId: ExecutionIdSchema,
174
+ stream: ConsoleStreamSchema,
175
+ text: z.string(),
176
+ seq: SequenceSchema,
177
+ at: TimestampSchema,
178
+ }).strict();
179
+ export const ExecutionUsageSchema = z.object({
180
+ inputTokens: TokenCountSchema,
181
+ outputTokens: TokenCountSchema,
182
+ cacheReadTokens: TokenCountSchema,
183
+ cacheCreationTokens: TokenCountSchema,
184
+ costUsd: z.number().finite().nonnegative().optional(),
185
+ }).strict();
186
+ const RawExecutionCompletedSchema = z.object({
187
+ type: z.literal("execution:completed"),
188
+ protocolVersion: ProtocolVersionSchema,
189
+ executionId: ExecutionIdSchema,
190
+ outcome: z.enum(["succeeded", "failed", "cancelled"]),
191
+ exitCode: ExitCodeSchema.optional(),
192
+ terminationSignal: z.string().min(1).optional(),
193
+ errorCode: z.string().min(1).optional(),
194
+ errorMessage: z.string().min(1).optional(),
195
+ runtime: RuntimeSchema,
196
+ model: z.string().optional(),
197
+ resumed: z.boolean(),
198
+ finalText: z.string().optional(),
199
+ usage: ExecutionUsageSchema.optional(),
200
+ startedAt: TimestampSchema,
201
+ finishedAt: TimestampSchema,
202
+ }).strict();
203
+ function validateCompletionSemantics(completion, ctx) {
204
+ const addIssue = (message, path) => {
205
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message, path });
206
+ };
207
+ if (Date.parse(completion.finishedAt) < Date.parse(completion.startedAt)) {
208
+ addIssue("finishedAt must be greater than or equal to startedAt", ["finishedAt"]);
209
+ }
210
+ if (completion.outcome === "succeeded") {
211
+ if (completion.exitCode !== 0) {
212
+ addIssue("succeeded completion requires exitCode 0", ["exitCode"]);
213
+ }
214
+ for (const field of ["terminationSignal", "errorCode", "errorMessage"]) {
215
+ if (completion[field] !== undefined) {
216
+ addIssue(`succeeded completion cannot include ${field}`, [field]);
217
+ }
218
+ }
219
+ return;
220
+ }
221
+ const hasNonExitDiagnostic = completion.terminationSignal !== undefined
222
+ || completion.errorCode !== undefined
223
+ || completion.errorMessage !== undefined;
224
+ const hasDiagnostic = completion.outcome === "failed"
225
+ ? (completion.exitCode !== undefined && completion.exitCode !== 0) || hasNonExitDiagnostic
226
+ : completion.exitCode !== undefined || hasNonExitDiagnostic;
227
+ if (!hasDiagnostic) {
228
+ addIssue(`${completion.outcome} completion requires a diagnostic fact`, ["outcome"]);
229
+ }
230
+ }
231
+ export const ExecutionCompletedSchema = RawExecutionCompletedSchema.superRefine(validateCompletionSemantics);
232
+ const SnapshotAcceptedEntrySchema = z.object({
233
+ executionId: ExecutionIdSchema,
234
+ state: z.literal("accepted"),
235
+ updatedAt: TimestampSchema,
236
+ }).strict();
237
+ const SnapshotRunningEntrySchema = z.object({
238
+ executionId: ExecutionIdSchema,
239
+ state: z.literal("running"),
240
+ updatedAt: TimestampSchema,
241
+ }).strict();
242
+ const SnapshotCompletedEntrySchema = z.object({
243
+ executionId: ExecutionIdSchema,
244
+ state: z.literal("completed"),
245
+ completion: ExecutionCompletedSchema,
246
+ updatedAt: TimestampSchema,
247
+ }).strict();
248
+ const SnapshotInterruptedEntrySchema = z.object({
249
+ executionId: ExecutionIdSchema,
250
+ state: z.literal("interrupted"),
251
+ completion: ExecutionCompletedSchema,
252
+ updatedAt: TimestampSchema,
253
+ }).strict();
254
+ const RawExecutionSnapshotEntrySchema = z.discriminatedUnion("state", [
255
+ SnapshotAcceptedEntrySchema,
256
+ SnapshotRunningEntrySchema,
257
+ SnapshotCompletedEntrySchema,
258
+ SnapshotInterruptedEntrySchema,
259
+ ]);
260
+ export const ExecutionSnapshotEntrySchema = RawExecutionSnapshotEntrySchema.superRefine((entry, ctx) => {
261
+ if ((entry.state === "completed" || entry.state === "interrupted")
262
+ && entry.executionId !== entry.completion.executionId) {
263
+ ctx.addIssue({
264
+ code: z.ZodIssueCode.custom,
265
+ message: "snapshot entry executionId must match completion executionId",
266
+ path: ["completion", "executionId"],
267
+ });
268
+ }
269
+ if (entry.state === "interrupted") {
270
+ if (entry.completion.outcome !== "failed") {
271
+ ctx.addIssue({
272
+ code: z.ZodIssueCode.custom,
273
+ message: "interrupted snapshot entry requires a failed completion",
274
+ path: ["completion", "outcome"],
275
+ });
276
+ }
277
+ if (entry.completion.errorCode !== "interrupted") {
278
+ ctx.addIssue({
279
+ code: z.ZodIssueCode.custom,
280
+ message: "interrupted snapshot entry requires errorCode interrupted",
281
+ path: ["completion", "errorCode"],
282
+ });
283
+ }
284
+ }
285
+ });
286
+ export const ExecutionSnapshotSchema = z.object({
287
+ type: z.literal("execution:snapshot"),
288
+ protocolVersion: ProtocolVersionSchema,
289
+ reqId: z.string().min(1).max(200),
290
+ entries: z.array(ExecutionSnapshotEntrySchema),
291
+ }).strict();
292
+ export const ServerToDaemonExecutionFrameSchema = z.discriminatedUnion("type", [
293
+ ExecutionStartSchema,
294
+ ExecutionCancelSchema,
295
+ ExecutionSyncSchema,
296
+ ExecutionCompletionAckSchema,
297
+ ]);
298
+ const RawDaemonToServerExecutionFrameSchema = z.discriminatedUnion("type", [
299
+ ExecutionAcceptedSchema,
300
+ ExecutionRejectedSchema,
301
+ ExecutionStartedSchema,
302
+ ExecutionActivitySchema,
303
+ ExecutionConsoleSchema,
304
+ RawExecutionCompletedSchema,
305
+ ExecutionSnapshotSchema,
306
+ ]);
307
+ export const DaemonToServerExecutionFrameSchema = RawDaemonToServerExecutionFrameSchema.superRefine((frame, ctx) => {
308
+ if (frame.type === "execution:completed")
309
+ validateCompletionSemantics(frame, ctx);
310
+ });