agent-lyceum 0.4.14 → 0.6.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 +21 -21
- package/README.zh-TW.md +21 -21
- package/dist/adapters/claude.js +2 -0
- package/dist/ask-answer.d.ts +10 -0
- package/dist/ask-answer.js +21 -0
- package/dist/ask-reply.d.ts +65 -0
- package/dist/ask-reply.js +165 -0
- package/dist/assert.d.ts +2 -0
- package/dist/assert.js +6 -0
- package/dist/cli.js +202 -16
- package/dist/config.d.ts +21 -16
- package/dist/config.js +19 -7
- package/dist/dispatcher.d.ts +3 -34
- package/dist/dispatcher.js +4 -464
- package/dist/doctor.js +3 -0
- package/dist/format.js +7 -5
- package/dist/fs-util.d.ts +2 -0
- package/dist/fs-util.js +15 -0
- package/dist/guard.d.ts +8 -0
- package/dist/guard.js +24 -3
- package/dist/mailbox.d.ts +11 -1
- package/dist/mailbox.js +21 -8
- package/dist/memory-tidy.d.ts +115 -0
- package/dist/memory-tidy.js +351 -0
- package/dist/policy.js +3 -3
- package/dist/process-runner.js +1 -2
- package/dist/project-lock.d.ts +10 -1
- package/dist/project-lock.js +39 -4
- package/dist/prompt.d.ts +20 -0
- package/dist/prompt.js +76 -3
- package/dist/run-cleanup.js +4 -3
- package/dist/run-log.d.ts +5 -0
- package/dist/run-log.js +18 -0
- package/dist/run-outcome.d.ts +22 -0
- package/dist/run-outcome.js +28 -0
- package/dist/run-session.d.ts +92 -0
- package/dist/run-session.js +602 -0
- package/dist/run-store.d.ts +3 -1
- package/dist/run-store.js +7 -6
- package/dist/scaffold.js +1 -0
- package/dist/schema.d.ts +72 -239
- package/dist/schema.js +8 -3
- package/dist/status.d.ts +9 -1
- package/dist/status.js +51 -15
- package/dist/validate.js +12 -8
- package/dist/worktree.js +7 -6
- package/package.json +14 -8
package/dist/schema.d.ts
CHANGED
|
@@ -9,51 +9,30 @@ export declare const RUNTIME_EFFORTS: Record<Runtime, readonly Effort[]>;
|
|
|
9
9
|
/** Guess the runtime from a model name: Claude aliases/IDs -> claude-code, GPT/o-series/codex names -> codex. */
|
|
10
10
|
export declare function inferRuntime(model: string | undefined): Runtime | undefined;
|
|
11
11
|
export declare const AgentPartial: z.ZodObject<{
|
|
12
|
-
runtime: z.ZodOptional<z.ZodEnum<
|
|
12
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
13
|
+
"claude-code": "claude-code";
|
|
14
|
+
codex: "codex";
|
|
15
|
+
}>>;
|
|
13
16
|
model: z.ZodOptional<z.ZodString>;
|
|
14
|
-
effort: z.ZodOptional<z.ZodEnum<
|
|
17
|
+
effort: z.ZodOptional<z.ZodEnum<{
|
|
18
|
+
high: "high";
|
|
19
|
+
low: "low";
|
|
20
|
+
max: "max";
|
|
21
|
+
medium: "medium";
|
|
22
|
+
minimal: "minimal";
|
|
23
|
+
xhigh: "xhigh";
|
|
24
|
+
}>>;
|
|
15
25
|
agent_md: z.ZodOptional<z.ZodString>;
|
|
16
26
|
memory: z.ZodOptional<z.ZodObject<{
|
|
17
27
|
global: z.ZodOptional<z.ZodString>;
|
|
18
28
|
project: z.ZodOptional<z.ZodString>;
|
|
19
|
-
},
|
|
20
|
-
global?: string | undefined;
|
|
21
|
-
project?: string | undefined;
|
|
22
|
-
}, {
|
|
23
|
-
global?: string | undefined;
|
|
24
|
-
project?: string | undefined;
|
|
25
|
-
}>>;
|
|
29
|
+
}, z.core.$strict>>;
|
|
26
30
|
resume: z.ZodOptional<z.ZodBoolean>;
|
|
27
|
-
can_message: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"all">, z.ZodArray<z.ZodString
|
|
31
|
+
can_message: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"all">, z.ZodArray<z.ZodString>]>>;
|
|
28
32
|
can_edit_agent_md: z.ZodOptional<z.ZodBoolean>;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
model?: string | undefined;
|
|
33
|
-
effort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
|
|
34
|
-
agent_md?: string | undefined;
|
|
35
|
-
memory?: {
|
|
36
|
-
global?: string | undefined;
|
|
37
|
-
project?: string | undefined;
|
|
38
|
-
} | undefined;
|
|
39
|
-
resume?: boolean | undefined;
|
|
40
|
-
can_message?: string[] | "all" | undefined;
|
|
41
|
-
can_edit_agent_md?: boolean | undefined;
|
|
42
|
-
owns?: string[] | undefined;
|
|
43
|
-
}, {
|
|
44
|
-
runtime?: "claude-code" | "codex" | undefined;
|
|
45
|
-
model?: string | undefined;
|
|
46
|
-
effort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
|
|
47
|
-
agent_md?: string | undefined;
|
|
48
|
-
memory?: {
|
|
49
|
-
global?: string | undefined;
|
|
50
|
-
project?: string | undefined;
|
|
51
|
-
} | undefined;
|
|
52
|
-
resume?: boolean | undefined;
|
|
53
|
-
can_message?: string[] | "all" | undefined;
|
|
54
|
-
can_edit_agent_md?: boolean | undefined;
|
|
55
|
-
owns?: string[] | undefined;
|
|
56
|
-
}>;
|
|
33
|
+
can_ask_user: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
owns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
35
|
+
}, z.core.$strict>;
|
|
57
36
|
export type AgentPartialT = z.infer<typeof AgentPartial>;
|
|
58
37
|
export declare const DispatcherPartial: z.ZodObject<{
|
|
59
38
|
max_rounds: z.ZodOptional<z.ZodNumber>;
|
|
@@ -61,232 +40,84 @@ export declare const DispatcherPartial: z.ZodObject<{
|
|
|
61
40
|
wake_timeout_sec: z.ZodOptional<z.ZodNumber>;
|
|
62
41
|
retry: z.ZodOptional<z.ZodNumber>;
|
|
63
42
|
strict: z.ZodOptional<z.ZodBoolean>;
|
|
64
|
-
workspace_mode: z.ZodOptional<z.ZodEnum<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
workspace_mode?: "shared" | "auto" | "worktree" | undefined;
|
|
72
|
-
}, {
|
|
73
|
-
strict?: boolean | undefined;
|
|
74
|
-
max_rounds?: number | undefined;
|
|
75
|
-
max_parallel?: number | undefined;
|
|
76
|
-
wake_timeout_sec?: number | undefined;
|
|
77
|
-
retry?: number | undefined;
|
|
78
|
-
workspace_mode?: "shared" | "auto" | "worktree" | undefined;
|
|
79
|
-
}>;
|
|
43
|
+
workspace_mode: z.ZodOptional<z.ZodEnum<{
|
|
44
|
+
auto: "auto";
|
|
45
|
+
shared: "shared";
|
|
46
|
+
worktree: "worktree";
|
|
47
|
+
}>>;
|
|
48
|
+
log_max_bytes: z.ZodOptional<z.ZodNumber>;
|
|
49
|
+
}, z.core.$strict>;
|
|
80
50
|
export declare const GlobalConfig: z.ZodObject<{
|
|
81
51
|
agents: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
82
|
-
runtime: z.ZodOptional<z.ZodEnum<
|
|
52
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
53
|
+
"claude-code": "claude-code";
|
|
54
|
+
codex: "codex";
|
|
55
|
+
}>>;
|
|
83
56
|
model: z.ZodOptional<z.ZodString>;
|
|
84
|
-
effort: z.ZodOptional<z.ZodEnum<
|
|
57
|
+
effort: z.ZodOptional<z.ZodEnum<{
|
|
58
|
+
high: "high";
|
|
59
|
+
low: "low";
|
|
60
|
+
max: "max";
|
|
61
|
+
medium: "medium";
|
|
62
|
+
minimal: "minimal";
|
|
63
|
+
xhigh: "xhigh";
|
|
64
|
+
}>>;
|
|
85
65
|
agent_md: z.ZodOptional<z.ZodString>;
|
|
86
66
|
memory: z.ZodOptional<z.ZodObject<{
|
|
87
67
|
global: z.ZodOptional<z.ZodString>;
|
|
88
68
|
project: z.ZodOptional<z.ZodString>;
|
|
89
|
-
},
|
|
90
|
-
global?: string | undefined;
|
|
91
|
-
project?: string | undefined;
|
|
92
|
-
}, {
|
|
93
|
-
global?: string | undefined;
|
|
94
|
-
project?: string | undefined;
|
|
95
|
-
}>>;
|
|
69
|
+
}, z.core.$strict>>;
|
|
96
70
|
resume: z.ZodOptional<z.ZodBoolean>;
|
|
97
|
-
can_message: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"all">, z.ZodArray<z.ZodString
|
|
71
|
+
can_message: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"all">, z.ZodArray<z.ZodString>]>>;
|
|
98
72
|
can_edit_agent_md: z.ZodOptional<z.ZodBoolean>;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
effort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
|
|
104
|
-
agent_md?: string | undefined;
|
|
105
|
-
memory?: {
|
|
106
|
-
global?: string | undefined;
|
|
107
|
-
project?: string | undefined;
|
|
108
|
-
} | undefined;
|
|
109
|
-
resume?: boolean | undefined;
|
|
110
|
-
can_message?: string[] | "all" | undefined;
|
|
111
|
-
can_edit_agent_md?: boolean | undefined;
|
|
112
|
-
owns?: string[] | undefined;
|
|
113
|
-
}, {
|
|
114
|
-
runtime?: "claude-code" | "codex" | undefined;
|
|
115
|
-
model?: string | undefined;
|
|
116
|
-
effort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
|
|
117
|
-
agent_md?: string | undefined;
|
|
118
|
-
memory?: {
|
|
119
|
-
global?: string | undefined;
|
|
120
|
-
project?: string | undefined;
|
|
121
|
-
} | undefined;
|
|
122
|
-
resume?: boolean | undefined;
|
|
123
|
-
can_message?: string[] | "all" | undefined;
|
|
124
|
-
can_edit_agent_md?: boolean | undefined;
|
|
125
|
-
owns?: string[] | undefined;
|
|
126
|
-
}>>>;
|
|
127
|
-
}, "strict", z.ZodTypeAny, {
|
|
128
|
-
agents: Record<string, {
|
|
129
|
-
runtime?: "claude-code" | "codex" | undefined;
|
|
130
|
-
model?: string | undefined;
|
|
131
|
-
effort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
|
|
132
|
-
agent_md?: string | undefined;
|
|
133
|
-
memory?: {
|
|
134
|
-
global?: string | undefined;
|
|
135
|
-
project?: string | undefined;
|
|
136
|
-
} | undefined;
|
|
137
|
-
resume?: boolean | undefined;
|
|
138
|
-
can_message?: string[] | "all" | undefined;
|
|
139
|
-
can_edit_agent_md?: boolean | undefined;
|
|
140
|
-
owns?: string[] | undefined;
|
|
141
|
-
}>;
|
|
142
|
-
}, {
|
|
143
|
-
agents?: Record<string, {
|
|
144
|
-
runtime?: "claude-code" | "codex" | undefined;
|
|
145
|
-
model?: string | undefined;
|
|
146
|
-
effort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
|
|
147
|
-
agent_md?: string | undefined;
|
|
148
|
-
memory?: {
|
|
149
|
-
global?: string | undefined;
|
|
150
|
-
project?: string | undefined;
|
|
151
|
-
} | undefined;
|
|
152
|
-
resume?: boolean | undefined;
|
|
153
|
-
can_message?: string[] | "all" | undefined;
|
|
154
|
-
can_edit_agent_md?: boolean | undefined;
|
|
155
|
-
owns?: string[] | undefined;
|
|
156
|
-
}> | undefined;
|
|
157
|
-
}>;
|
|
73
|
+
can_ask_user: z.ZodOptional<z.ZodBoolean>;
|
|
74
|
+
owns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
75
|
+
}, z.core.$strict>>>;
|
|
76
|
+
}, z.core.$strict>;
|
|
158
77
|
export declare const ProjectConfig: z.ZodObject<{
|
|
159
78
|
dir: z.ZodString;
|
|
160
79
|
team: z.ZodObject<{
|
|
161
80
|
lead: z.ZodString;
|
|
162
|
-
},
|
|
163
|
-
lead: string;
|
|
164
|
-
}, {
|
|
165
|
-
lead: string;
|
|
166
|
-
}>;
|
|
81
|
+
}, z.core.$strict>;
|
|
167
82
|
dispatcher: z.ZodDefault<z.ZodObject<{
|
|
168
83
|
max_rounds: z.ZodOptional<z.ZodNumber>;
|
|
169
84
|
max_parallel: z.ZodOptional<z.ZodNumber>;
|
|
170
85
|
wake_timeout_sec: z.ZodOptional<z.ZodNumber>;
|
|
171
86
|
retry: z.ZodOptional<z.ZodNumber>;
|
|
172
87
|
strict: z.ZodOptional<z.ZodBoolean>;
|
|
173
|
-
workspace_mode: z.ZodOptional<z.ZodEnum<
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
workspace_mode?: "shared" | "auto" | "worktree" | undefined;
|
|
181
|
-
}, {
|
|
182
|
-
strict?: boolean | undefined;
|
|
183
|
-
max_rounds?: number | undefined;
|
|
184
|
-
max_parallel?: number | undefined;
|
|
185
|
-
wake_timeout_sec?: number | undefined;
|
|
186
|
-
retry?: number | undefined;
|
|
187
|
-
workspace_mode?: "shared" | "auto" | "worktree" | undefined;
|
|
188
|
-
}>>;
|
|
88
|
+
workspace_mode: z.ZodOptional<z.ZodEnum<{
|
|
89
|
+
auto: "auto";
|
|
90
|
+
shared: "shared";
|
|
91
|
+
worktree: "worktree";
|
|
92
|
+
}>>;
|
|
93
|
+
log_max_bytes: z.ZodOptional<z.ZodNumber>;
|
|
94
|
+
}, z.core.$strict>>;
|
|
189
95
|
agents: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
190
|
-
runtime: z.ZodOptional<z.ZodEnum<
|
|
96
|
+
runtime: z.ZodOptional<z.ZodEnum<{
|
|
97
|
+
"claude-code": "claude-code";
|
|
98
|
+
codex: "codex";
|
|
99
|
+
}>>;
|
|
191
100
|
model: z.ZodOptional<z.ZodString>;
|
|
192
|
-
effort: z.ZodOptional<z.ZodEnum<
|
|
101
|
+
effort: z.ZodOptional<z.ZodEnum<{
|
|
102
|
+
high: "high";
|
|
103
|
+
low: "low";
|
|
104
|
+
max: "max";
|
|
105
|
+
medium: "medium";
|
|
106
|
+
minimal: "minimal";
|
|
107
|
+
xhigh: "xhigh";
|
|
108
|
+
}>>;
|
|
193
109
|
agent_md: z.ZodOptional<z.ZodString>;
|
|
194
110
|
memory: z.ZodOptional<z.ZodObject<{
|
|
195
111
|
global: z.ZodOptional<z.ZodString>;
|
|
196
112
|
project: z.ZodOptional<z.ZodString>;
|
|
197
|
-
},
|
|
198
|
-
global?: string | undefined;
|
|
199
|
-
project?: string | undefined;
|
|
200
|
-
}, {
|
|
201
|
-
global?: string | undefined;
|
|
202
|
-
project?: string | undefined;
|
|
203
|
-
}>>;
|
|
113
|
+
}, z.core.$strict>>;
|
|
204
114
|
resume: z.ZodOptional<z.ZodBoolean>;
|
|
205
|
-
can_message: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"all">, z.ZodArray<z.ZodString
|
|
115
|
+
can_message: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"all">, z.ZodArray<z.ZodString>]>>;
|
|
206
116
|
can_edit_agent_md: z.ZodOptional<z.ZodBoolean>;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
effort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
|
|
212
|
-
agent_md?: string | undefined;
|
|
213
|
-
memory?: {
|
|
214
|
-
global?: string | undefined;
|
|
215
|
-
project?: string | undefined;
|
|
216
|
-
} | undefined;
|
|
217
|
-
resume?: boolean | undefined;
|
|
218
|
-
can_message?: string[] | "all" | undefined;
|
|
219
|
-
can_edit_agent_md?: boolean | undefined;
|
|
220
|
-
owns?: string[] | undefined;
|
|
221
|
-
}, {
|
|
222
|
-
runtime?: "claude-code" | "codex" | undefined;
|
|
223
|
-
model?: string | undefined;
|
|
224
|
-
effort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
|
|
225
|
-
agent_md?: string | undefined;
|
|
226
|
-
memory?: {
|
|
227
|
-
global?: string | undefined;
|
|
228
|
-
project?: string | undefined;
|
|
229
|
-
} | undefined;
|
|
230
|
-
resume?: boolean | undefined;
|
|
231
|
-
can_message?: string[] | "all" | undefined;
|
|
232
|
-
can_edit_agent_md?: boolean | undefined;
|
|
233
|
-
owns?: string[] | undefined;
|
|
234
|
-
}>>>;
|
|
235
|
-
}, "strict", z.ZodTypeAny, {
|
|
236
|
-
agents: Record<string, {
|
|
237
|
-
runtime?: "claude-code" | "codex" | undefined;
|
|
238
|
-
model?: string | undefined;
|
|
239
|
-
effort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
|
|
240
|
-
agent_md?: string | undefined;
|
|
241
|
-
memory?: {
|
|
242
|
-
global?: string | undefined;
|
|
243
|
-
project?: string | undefined;
|
|
244
|
-
} | undefined;
|
|
245
|
-
resume?: boolean | undefined;
|
|
246
|
-
can_message?: string[] | "all" | undefined;
|
|
247
|
-
can_edit_agent_md?: boolean | undefined;
|
|
248
|
-
owns?: string[] | undefined;
|
|
249
|
-
}>;
|
|
250
|
-
dir: string;
|
|
251
|
-
team: {
|
|
252
|
-
lead: string;
|
|
253
|
-
};
|
|
254
|
-
dispatcher: {
|
|
255
|
-
strict?: boolean | undefined;
|
|
256
|
-
max_rounds?: number | undefined;
|
|
257
|
-
max_parallel?: number | undefined;
|
|
258
|
-
wake_timeout_sec?: number | undefined;
|
|
259
|
-
retry?: number | undefined;
|
|
260
|
-
workspace_mode?: "shared" | "auto" | "worktree" | undefined;
|
|
261
|
-
};
|
|
262
|
-
}, {
|
|
263
|
-
dir: string;
|
|
264
|
-
team: {
|
|
265
|
-
lead: string;
|
|
266
|
-
};
|
|
267
|
-
agents?: Record<string, {
|
|
268
|
-
runtime?: "claude-code" | "codex" | undefined;
|
|
269
|
-
model?: string | undefined;
|
|
270
|
-
effort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | undefined;
|
|
271
|
-
agent_md?: string | undefined;
|
|
272
|
-
memory?: {
|
|
273
|
-
global?: string | undefined;
|
|
274
|
-
project?: string | undefined;
|
|
275
|
-
} | undefined;
|
|
276
|
-
resume?: boolean | undefined;
|
|
277
|
-
can_message?: string[] | "all" | undefined;
|
|
278
|
-
can_edit_agent_md?: boolean | undefined;
|
|
279
|
-
owns?: string[] | undefined;
|
|
280
|
-
}> | undefined;
|
|
281
|
-
dispatcher?: {
|
|
282
|
-
strict?: boolean | undefined;
|
|
283
|
-
max_rounds?: number | undefined;
|
|
284
|
-
max_parallel?: number | undefined;
|
|
285
|
-
wake_timeout_sec?: number | undefined;
|
|
286
|
-
retry?: number | undefined;
|
|
287
|
-
workspace_mode?: "shared" | "auto" | "worktree" | undefined;
|
|
288
|
-
} | undefined;
|
|
289
|
-
}>;
|
|
117
|
+
can_ask_user: z.ZodOptional<z.ZodBoolean>;
|
|
118
|
+
owns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
119
|
+
}, z.core.$strict>>>;
|
|
120
|
+
}, z.core.$strict>;
|
|
290
121
|
export interface DispatcherSettings {
|
|
291
122
|
max_rounds: number;
|
|
292
123
|
max_parallel: number;
|
|
@@ -295,9 +126,11 @@ export interface DispatcherSettings {
|
|
|
295
126
|
strict: boolean;
|
|
296
127
|
/** "auto": a git worktree per non-lead agent when agents can run in parallel, otherwise one shared checkout. */
|
|
297
128
|
workspace_mode: "auto" | "shared" | "worktree";
|
|
129
|
+
/** log.jsonl is rotated to log.1.jsonl past this size; 0 = never. */
|
|
130
|
+
log_max_bytes: number;
|
|
298
131
|
}
|
|
299
132
|
export declare const DISPATCHER_DEFAULTS: DispatcherSettings;
|
|
300
133
|
/** How a run turned out, independent of why it stopped (`EndReason`). Only "completed" means success. */
|
|
301
|
-
export declare const RUN_OUTCOMES: readonly ["completed", "partial", "blocked", "failed", "cancelled"];
|
|
134
|
+
export declare const RUN_OUTCOMES: readonly ["completed", "partial", "blocked", "failed", "waiting", "cancelled"];
|
|
302
135
|
export type RunOutcome = (typeof RUN_OUTCOMES)[number];
|
|
303
|
-
export declare function exitCodeForOutcome(outcome: RunOutcome): 0 | 1 | 2 | 130;
|
|
136
|
+
export declare function exitCodeForOutcome(outcome: RunOutcome): 0 | 1 | 2 | 3 | 130;
|
package/dist/schema.js
CHANGED
|
@@ -34,6 +34,7 @@ export const AgentPartial = z
|
|
|
34
34
|
resume: z.boolean().optional(),
|
|
35
35
|
can_message: z.union([z.literal("all"), z.array(z.string())]).optional(),
|
|
36
36
|
can_edit_agent_md: z.boolean().optional(),
|
|
37
|
+
can_ask_user: z.boolean().optional(),
|
|
37
38
|
owns: z.array(z.string()).optional(),
|
|
38
39
|
})
|
|
39
40
|
.strict();
|
|
@@ -45,11 +46,12 @@ export const DispatcherPartial = z
|
|
|
45
46
|
retry: z.number().int().min(0).optional(),
|
|
46
47
|
strict: z.boolean().optional(),
|
|
47
48
|
workspace_mode: z.enum(["auto", "shared", "worktree"]).optional(),
|
|
49
|
+
log_max_bytes: z.number().int().min(0).optional(),
|
|
48
50
|
})
|
|
49
51
|
.strict();
|
|
50
52
|
export const GlobalConfig = z
|
|
51
53
|
.object({
|
|
52
|
-
agents: z.record(AgentPartial).default({}),
|
|
54
|
+
agents: z.record(z.string(), AgentPartial).default({}),
|
|
53
55
|
})
|
|
54
56
|
.strict();
|
|
55
57
|
export const ProjectConfig = z
|
|
@@ -57,7 +59,7 @@ export const ProjectConfig = z
|
|
|
57
59
|
dir: z.string(),
|
|
58
60
|
team: z.object({ lead: z.string() }).strict(),
|
|
59
61
|
dispatcher: DispatcherPartial.default({}),
|
|
60
|
-
agents: z.record(AgentPartial).default({}),
|
|
62
|
+
agents: z.record(z.string(), AgentPartial).default({}),
|
|
61
63
|
})
|
|
62
64
|
.strict();
|
|
63
65
|
export const DISPATCHER_DEFAULTS = {
|
|
@@ -67,15 +69,18 @@ export const DISPATCHER_DEFAULTS = {
|
|
|
67
69
|
retry: 1,
|
|
68
70
|
strict: false,
|
|
69
71
|
workspace_mode: "auto",
|
|
72
|
+
log_max_bytes: 8 * 1024 * 1024,
|
|
70
73
|
};
|
|
71
74
|
/** How a run turned out, independent of why it stopped (`EndReason`). Only "completed" means success. */
|
|
72
|
-
export const RUN_OUTCOMES = ["completed", "partial", "blocked", "failed", "cancelled"];
|
|
75
|
+
export const RUN_OUTCOMES = ["completed", "partial", "blocked", "failed", "waiting", "cancelled"];
|
|
73
76
|
export function exitCodeForOutcome(outcome) {
|
|
74
77
|
switch (outcome) {
|
|
75
78
|
case "completed":
|
|
76
79
|
return 0;
|
|
77
80
|
case "failed":
|
|
78
81
|
return 1;
|
|
82
|
+
case "waiting":
|
|
83
|
+
return 3;
|
|
79
84
|
case "cancelled":
|
|
80
85
|
return 130;
|
|
81
86
|
default:
|
package/dist/status.d.ts
CHANGED
|
@@ -44,7 +44,7 @@ export interface RunReport {
|
|
|
44
44
|
run_id: string;
|
|
45
45
|
dir: string;
|
|
46
46
|
/** running: its dispatcher is alive; interrupted: it died mid-run; ended: it stopped (see end_reason). */
|
|
47
|
-
state: "running" | "interrupted" | "ended";
|
|
47
|
+
state: "running" | "interrupted" | "ended" | "waiting";
|
|
48
48
|
live: boolean;
|
|
49
49
|
end_reason?: EndReason;
|
|
50
50
|
outcome?: RunOutcome;
|
|
@@ -83,6 +83,12 @@ export interface RunReport {
|
|
|
83
83
|
ok: boolean;
|
|
84
84
|
error?: string;
|
|
85
85
|
}>;
|
|
86
|
+
/** Present while the run waits for the user: the file to fill in and how many questions are still open. */
|
|
87
|
+
ask?: {
|
|
88
|
+
path: string;
|
|
89
|
+
total: number;
|
|
90
|
+
unanswered: number;
|
|
91
|
+
};
|
|
86
92
|
}
|
|
87
93
|
export interface AgentReport {
|
|
88
94
|
name: string;
|
|
@@ -104,6 +110,8 @@ export interface StatusReport {
|
|
|
104
110
|
};
|
|
105
111
|
agents: AgentReport[];
|
|
106
112
|
run?: RunReport;
|
|
113
|
+
/** Hints that a `memory tidy` might help. Only a suggestion; nothing runs it. */
|
|
114
|
+
memory_advice?: string[];
|
|
107
115
|
}
|
|
108
116
|
export interface TaskListReport {
|
|
109
117
|
schema_version: 1;
|
package/dist/status.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { askReplyPath, readAskReply } from "./ask-reply.js";
|
|
3
4
|
import { RESULT_FILE } from "./dispatcher.js";
|
|
4
5
|
import { bindRunProject, loadRunState, outcomeOf } from "./run-store.js";
|
|
5
6
|
import { listUnread } from "./mailbox.js";
|
|
7
|
+
import { tidyAdvice } from "./memory-tidy.js";
|
|
6
8
|
import { inspectProjectLock, lockHolderAlive } from "./project-lock.js";
|
|
7
9
|
export function latestRun(project) {
|
|
8
10
|
const root = project.paths.runs;
|
|
@@ -76,8 +78,10 @@ function alive(pid) {
|
|
|
76
78
|
return e.code === "EPERM";
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
|
-
const OUTCOME_ZH = { completed: "完成", partial: "部分完成", blocked: "受阻", failed: "失敗", cancelled: "已取消" };
|
|
81
|
+
const OUTCOME_ZH = { completed: "完成", partial: "部分完成", blocked: "受阻", failed: "失敗", waiting: "等待回答", cancelled: "已取消" };
|
|
80
82
|
export function runStateLabel(s, live = alive(s.pid)) {
|
|
83
|
+
if (s.end_reason === "waiting")
|
|
84
|
+
return "等待回答";
|
|
81
85
|
if (s.end_reason) {
|
|
82
86
|
const o = outcomeOf(s);
|
|
83
87
|
// Runs from before outcomes existed: keep what they recorded, but never present it as a checked success.
|
|
@@ -137,7 +141,7 @@ function stepsLine(steps, c, finished = false) {
|
|
|
137
141
|
function queueOf(project) {
|
|
138
142
|
const rows = Object.values(project.agents)
|
|
139
143
|
.map((a) => ({ agent: a.name, msg: listUnread(project, a.name)[0] }))
|
|
140
|
-
.
|
|
144
|
+
.flatMap((r) => (r.msg ? [{ agent: r.agent, msg: r.msg }] : []));
|
|
141
145
|
rows.sort((x, y) => {
|
|
142
146
|
if ((x.agent === project.lead) !== (y.agent === project.lead))
|
|
143
147
|
return x.agent === project.lead ? -1 : 1;
|
|
@@ -155,10 +159,23 @@ export function buildRunReport(run, project, opts = {}) {
|
|
|
155
159
|
const result = path.join(run.dir, RESULT_FILE);
|
|
156
160
|
const hasResult = detail && s.end_reason === "done" && fs.existsSync(result);
|
|
157
161
|
const cur = s.steps?.find((x) => !x.done);
|
|
162
|
+
let ask;
|
|
163
|
+
if (s.end_reason === "waiting") {
|
|
164
|
+
try {
|
|
165
|
+
const r = readAskReply(run.dir);
|
|
166
|
+
if (r) {
|
|
167
|
+
const open = r.questions.filter((q) => !q.delivered);
|
|
168
|
+
ask = { path: askReplyPath(run.dir), total: open.length, unanswered: open.filter((q) => !q.answer?.value.trim()).length };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
ask = { path: askReplyPath(run.dir), total: 0, unanswered: 0 };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
158
175
|
return {
|
|
159
176
|
run_id: s.run_id,
|
|
160
177
|
dir: run.dir,
|
|
161
|
-
state: s.end_reason ? "ended" : live ? "running" : "interrupted",
|
|
178
|
+
state: s.end_reason === "waiting" ? "waiting" : s.end_reason ? "ended" : live ? "running" : "interrupted",
|
|
162
179
|
live,
|
|
163
180
|
end_reason: s.end_reason,
|
|
164
181
|
outcome: o?.outcome,
|
|
@@ -186,6 +203,7 @@ export function buildRunReport(run, project, opts = {}) {
|
|
|
186
203
|
mail_layout: s.mail_layout,
|
|
187
204
|
workspace_mode: s.workspace_mode,
|
|
188
205
|
last_wake: s.last_wake,
|
|
206
|
+
...(ask ? { ask } : {}),
|
|
189
207
|
};
|
|
190
208
|
}
|
|
191
209
|
const projectInfo = (p) => ({ name: p.name, dir: p.dir, lead: p.lead });
|
|
@@ -203,6 +221,13 @@ export function buildStatusReport(base, runId) {
|
|
|
203
221
|
// Mail is per run: count the unread mail of the run being shown.
|
|
204
222
|
const project = run ? bindRunProject(base, run.dir, run.state.mail_layout) : base;
|
|
205
223
|
const report = run ? buildRunReport(run, base) : undefined;
|
|
224
|
+
let advice = [];
|
|
225
|
+
try {
|
|
226
|
+
advice = tidyAdvice(base).map((a) => `${a.agent}: ${a.reason}`);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
/* a hint only: never let it break status */
|
|
230
|
+
}
|
|
206
231
|
return {
|
|
207
232
|
schema_version: 1,
|
|
208
233
|
project: projectInfo(base),
|
|
@@ -214,6 +239,7 @@ export function buildStatusReport(base, runId) {
|
|
|
214
239
|
last_wake: run?.state.last_wake[a.name],
|
|
215
240
|
})),
|
|
216
241
|
run: report,
|
|
242
|
+
...(advice.length ? { memory_advice: advice } : {}),
|
|
217
243
|
};
|
|
218
244
|
}
|
|
219
245
|
/** Every run of the project, newest first. */
|
|
@@ -251,13 +277,16 @@ function summaryBlock(run, now, c) {
|
|
|
251
277
|
lines.push(`${L("進度:")}${steps ?? `無清單;已用 ${s.rounds}/${s.max_rounds} 輪(lead 可在信中加入 "## Steps" 清單)`}`);
|
|
252
278
|
const active = Object.entries(s.active ?? {});
|
|
253
279
|
if (active.length) {
|
|
254
|
-
|
|
280
|
+
for (const [i, [agent, a]] of active.entries()) {
|
|
281
|
+
lines.push(`${i === 0 ? L("現在:") : " "}${c.cyan(agent)} ${live ? c.green(`工作中 ${since(a.since, now)}`) : c.yellow("曾在工作(已中斷)")},處理 ${handlingText(a.handling)}`);
|
|
282
|
+
}
|
|
255
283
|
}
|
|
256
284
|
else
|
|
257
285
|
lines.push(`${L("現在:")}${c.dim(`閒置${s.end_reason ? `(執行已結束:${s.end_reason})` : live ? "" : "(執行未在運作)"}`)}`);
|
|
258
286
|
const queue = s.queue;
|
|
259
287
|
if (queue.length) {
|
|
260
|
-
|
|
288
|
+
for (const [i, q] of queue.slice(0, 3).entries())
|
|
289
|
+
lines.push(`${i === 0 ? L("下一個:") : " "}${c.cyan(q.agent)} ← ${mailText(q)}`);
|
|
261
290
|
if (queue.length > 3)
|
|
262
291
|
lines.push(c.dim(` … 還有 ${queue.length - 3} 筆`));
|
|
263
292
|
}
|
|
@@ -271,6 +300,8 @@ function summaryBlock(run, now, c) {
|
|
|
271
300
|
const lastWake = (s.wakes ?? []).at(-1);
|
|
272
301
|
if (lastWake)
|
|
273
302
|
lines.push(`${L("上一次:")}#${lastWake.round} ${c.cyan(lastWake.agent)} ${okText(c, lastWake.ok)} → ${sentText(lastWake.sent)}`);
|
|
303
|
+
if (s.ask)
|
|
304
|
+
lines.push(`${L("等你回答:")}${s.ask.unanswered}/${s.ask.total} 題未答 → ${s.ask.path}`, c.dim(` 填完後執行 agent-lyceum answer ${s.run_id}(或 resume)`));
|
|
274
305
|
lines.push(`${L("流程:")}${flowLine(s, c)}`);
|
|
275
306
|
return lines;
|
|
276
307
|
}
|
|
@@ -343,7 +374,8 @@ export function formatTaskListReport(report, color = false) {
|
|
|
343
374
|
const head = `${c.bold("專案:")}${report.project.name} ${c.dim(`(共 ${runs.length} 個任務)`)}`;
|
|
344
375
|
if (!runs.length)
|
|
345
376
|
return `${head}\n\n無執行紀錄。`;
|
|
346
|
-
const
|
|
377
|
+
const header = ["ID", "狀態", "輪次", "目前步驟", "任務"];
|
|
378
|
+
const rows = [header];
|
|
347
379
|
for (const s of runs) {
|
|
348
380
|
rows.push([
|
|
349
381
|
s.run_id,
|
|
@@ -353,11 +385,11 @@ export function formatTaskListReport(report, color = false) {
|
|
|
353
385
|
clip(taskText(s), 60),
|
|
354
386
|
]);
|
|
355
387
|
}
|
|
356
|
-
const w =
|
|
388
|
+
const w = header.map((_, i) => Math.max(...rows.map((r) => cols(r[i] ?? ""))));
|
|
357
389
|
const line = (r, ri) => r
|
|
358
390
|
.map((t, i) => {
|
|
359
|
-
const p = i === r.length - 1 ? t : padCols(t, w[i]);
|
|
360
|
-
return ri === 0 ? c.bold(p) : i === 1 ? stateColor(c, t) + " ".repeat(Math.max(0, w[i] - cols(t))) : p;
|
|
391
|
+
const p = i === r.length - 1 ? t : padCols(t, w[i] ?? 0);
|
|
392
|
+
return ri === 0 ? c.bold(p) : i === 1 ? stateColor(c, t) + " ".repeat(Math.max(0, (w[i] ?? 0) - cols(t))) : p;
|
|
361
393
|
})
|
|
362
394
|
.join(" ")
|
|
363
395
|
.trimEnd();
|
|
@@ -371,23 +403,25 @@ export function formatStatus(base, now = Date.now(), color = false) {
|
|
|
371
403
|
export function formatStatusReport(report, now = Date.now(), color = false) {
|
|
372
404
|
const c = paint(color);
|
|
373
405
|
const run = report.run;
|
|
374
|
-
const
|
|
406
|
+
const header = ["成員", "執行環境", "未讀", "上次喚醒"];
|
|
407
|
+
const rows = [header];
|
|
375
408
|
for (const a of report.agents) {
|
|
376
409
|
const lw = a.last_wake;
|
|
377
410
|
rows.push([a.name + (a.lead ? " (lead)" : ""), a.runtime ?? "?", String(a.unread), lw ? `${lw.ok ? "成功" : "失敗"} ${lw.at}` : "-"]);
|
|
378
411
|
}
|
|
379
|
-
const w =
|
|
412
|
+
const w = header.map((_, i) => Math.max(...rows.map((r) => cols(r[i] ?? ""))));
|
|
380
413
|
// Pad on the plain text first so ANSI codes never skew the column widths.
|
|
381
414
|
const cell = (r, ri, i) => {
|
|
382
|
-
const
|
|
415
|
+
const text = r[i] ?? "";
|
|
416
|
+
const t = i === r.length - 1 ? text : padCols(text, w[i] ?? 0); // no trailing padding, as in plain output
|
|
383
417
|
if (ri === 0)
|
|
384
418
|
return c.bold(t);
|
|
385
419
|
if (i === 0)
|
|
386
|
-
return
|
|
420
|
+
return text.endsWith("(lead)") ? c.cyan(t) : t;
|
|
387
421
|
if (i === 2)
|
|
388
|
-
return
|
|
422
|
+
return text === "0" ? c.dim(t) : c.yellow(t);
|
|
389
423
|
if (i === 3)
|
|
390
|
-
return
|
|
424
|
+
return text.startsWith("失敗") ? c.red(t) : text.startsWith("成功") ? c.green(t) : c.dim(t);
|
|
391
425
|
return t;
|
|
392
426
|
};
|
|
393
427
|
const table = rows.map((r, ri) => r.map((_, i) => cell(r, ri, i)).join(" ").trimEnd());
|
|
@@ -395,5 +429,7 @@ export function formatStatusReport(report, now = Date.now(), color = false) {
|
|
|
395
429
|
const lines = [`${c.bold("專案:")}${report.project.name} ${c.dim(`(repo:${report.project.dir})`)}`, "", ...summaryBlock(run, now, c), "", ...table];
|
|
396
430
|
if (run)
|
|
397
431
|
lines.push("", `輸出 tokens:${tokens(run.output_tokens)}`);
|
|
432
|
+
if (report.memory_advice?.length)
|
|
433
|
+
lines.push("", `記憶:${report.memory_advice.join(";")}(建議執行 agent-lyceum memory tidy -p ${report.project.name};status 只提示,不會自動整理)`);
|
|
398
434
|
return lines.join("\n");
|
|
399
435
|
}
|