@akagilnc/pi-workflow-roles 0.1.3789 → 0.1.3795
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 +3 -1
- package/README.zh-CN.md +3 -1
- package/dist/acp-host/production-host.js +203 -42
- package/dist/collector-evidence.js +4 -1
- package/dist/collector-github.js +1 -0
- package/dist/collector-identity.js +11 -0
- package/dist/collector-ledger.js +73 -19
- package/dist/collector-role.js +82 -7
- package/dist/collector-tool-schemas.js +15 -2
- package/dist/headless-host/production-host.js +203 -42
- package/dist/pi/role-turn-host.js +1 -0
- package/dist/public-cli/invocation.js +15 -0
- package/dist/public-cli/main.js +43 -5
- package/dist/public-cli/option-definitions.js +14 -0
- package/dist/public-cli/run-lifecycle.js +8 -0
- package/package.json +1 -1
- package/src/acp-host/role-envelope.ts +1 -0
- package/src/collector-evidence.ts +6 -1
- package/src/collector-github.ts +3 -0
- package/src/collector-identity.ts +14 -0
- package/src/collector-ledger.ts +95 -23
- package/src/collector-role.ts +81 -3
- package/src/collector-tool-schemas.ts +17 -2
- package/src/host-contracts.ts +2 -0
- package/src/pi/role-turn-host.ts +1 -0
- package/src/public-cli/collector-run.ts +2 -0
- package/src/public-cli/invocation.ts +21 -0
- package/src/public-cli/option-definitions.ts +14 -0
- package/src/public-cli/run-lifecycle.ts +10 -0
package/src/collector-role.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
type CollectorRepository,
|
|
18
18
|
} from "./collector-config.ts";
|
|
19
19
|
import {
|
|
20
|
+
COLLECTOR_DEFAULT_WAIT_WINDOW_MS,
|
|
20
21
|
createSystemCollectorClock,
|
|
21
22
|
type CollectorClock,
|
|
22
23
|
} from "./collector-evidence.ts";
|
|
@@ -34,6 +35,7 @@ import {
|
|
|
34
35
|
COLLECTOR_BIND_TARGET_TOOL,
|
|
35
36
|
COLLECTOR_HANDBOOK_WRITE_TOOL,
|
|
36
37
|
COLLECTOR_OBSERVE_TOOL,
|
|
38
|
+
COLLECTOR_OPEN_WAIT_WINDOW_TOOL,
|
|
37
39
|
COLLECTOR_OUTPUT_TOOL,
|
|
38
40
|
COLLECTOR_READ_TOOL,
|
|
39
41
|
COLLECTOR_REQUEST_TOOL,
|
|
@@ -50,6 +52,7 @@ import {
|
|
|
50
52
|
collectorBindTargetArgsSchema,
|
|
51
53
|
collectorHandbookWriteArgsSchema,
|
|
52
54
|
collectorObserveArgsSchema,
|
|
55
|
+
collectorOpenWaitWindowArgsSchema,
|
|
53
56
|
collectorOutputArgsSchema,
|
|
54
57
|
collectorReadArgsSchema,
|
|
55
58
|
collectorRequestArgsSchema,
|
|
@@ -85,6 +88,7 @@ export {
|
|
|
85
88
|
COLLECTOR_BIND_TARGET_TOOL,
|
|
86
89
|
COLLECTOR_HANDBOOK_WRITE_TOOL,
|
|
87
90
|
COLLECTOR_OBSERVE_TOOL,
|
|
91
|
+
COLLECTOR_OPEN_WAIT_WINDOW_TOOL,
|
|
88
92
|
COLLECTOR_OUTPUT_TOOL,
|
|
89
93
|
COLLECTOR_READ_TOOL,
|
|
90
94
|
COLLECTOR_REQUEST_TOOL,
|
|
@@ -96,6 +100,7 @@ export const COLLECTOR_REQUIRED_TOOLS = [
|
|
|
96
100
|
COLLECTOR_OBSERVE_TOOL,
|
|
97
101
|
COLLECTOR_READ_TOOL,
|
|
98
102
|
COLLECTOR_REQUEST_TOOL,
|
|
103
|
+
COLLECTOR_OPEN_WAIT_WINDOW_TOOL,
|
|
99
104
|
COLLECTOR_WAIT_TOOL,
|
|
100
105
|
COLLECTOR_HANDBOOK_WRITE_TOOL,
|
|
101
106
|
COLLECTOR_OUTPUT_TOOL,
|
|
@@ -127,11 +132,20 @@ export const COLLECTOR_TRANSPORT_FLAGS = Object.freeze([
|
|
|
127
132
|
type: "string" as const,
|
|
128
133
|
}),
|
|
129
134
|
}),
|
|
135
|
+
Object.freeze({
|
|
136
|
+
name: "ak-collector-wait-ms",
|
|
137
|
+
definition: Object.freeze({
|
|
138
|
+
description:
|
|
139
|
+
`Collector wait-window duration in milliseconds (default ${COLLECTOR_DEFAULT_WAIT_WINDOW_MS}). Caller-configurable; opens at a work step, not session start (#678 D4).`,
|
|
140
|
+
type: "string" as const,
|
|
141
|
+
}),
|
|
142
|
+
}),
|
|
130
143
|
] as const);
|
|
131
144
|
|
|
132
145
|
const observeSchema = collectorObserveArgsSchema;
|
|
133
146
|
const readSchema = collectorReadArgsSchema;
|
|
134
147
|
const requestSchema = collectorRequestArgsSchema;
|
|
148
|
+
const openWaitWindowSchema = collectorOpenWaitWindowArgsSchema;
|
|
135
149
|
const waitSchema = collectorWaitArgsSchema;
|
|
136
150
|
const bindSchema = collectorBindTargetArgsSchema;
|
|
137
151
|
const handbookWriteSchema = collectorHandbookWriteArgsSchema;
|
|
@@ -139,11 +153,22 @@ const outputSchema = collectorOutputArgsSchema;
|
|
|
139
153
|
|
|
140
154
|
type RequestParams = Static<typeof requestSchema>;
|
|
141
155
|
type ReadParams = Static<typeof readSchema>;
|
|
156
|
+
type OpenWaitWindowParams = Static<typeof openWaitWindowSchema>;
|
|
142
157
|
type WaitParams = Static<typeof waitSchema>;
|
|
143
158
|
type BindParams = Static<typeof bindSchema>;
|
|
144
159
|
type HandbookWriteParams = Static<typeof handbookWriteSchema>;
|
|
145
160
|
type OutputParams = Static<typeof outputSchema>;
|
|
146
161
|
|
|
162
|
+
function parseWaitWindowMsFlag(raw: unknown): number {
|
|
163
|
+
if (raw === undefined || raw === null || raw === "") return COLLECTOR_DEFAULT_WAIT_WINDOW_MS;
|
|
164
|
+
if (typeof raw === "number" && Number.isSafeInteger(raw) && raw >= 1) return raw;
|
|
165
|
+
if (typeof raw === "string" && /^[1-9]\d*$/.test(raw.trim())) {
|
|
166
|
+
const value = Number(raw.trim());
|
|
167
|
+
if (Number.isSafeInteger(value) && value >= 1) return value;
|
|
168
|
+
}
|
|
169
|
+
throw new Error("Collector --ak-collector-wait-ms must be a positive safe-integer millisecond string");
|
|
170
|
+
}
|
|
171
|
+
|
|
147
172
|
export type CollectorRoleDependencies = {
|
|
148
173
|
loadSoul(): Promise<string>;
|
|
149
174
|
createTransport(): CollectorGitHubTransport;
|
|
@@ -184,6 +209,7 @@ function buildMethodContext(activation: CollectorActivation): string {
|
|
|
184
209
|
`host: github.com`,
|
|
185
210
|
`repository: ${activation.repository.canonical}`,
|
|
186
211
|
`prNumber: ${pr === undefined ? "未绑定" : String(pr)}`,
|
|
212
|
+
`waitWindowMs: ${String(activation.ledger.config.waitWindowMs)}`,
|
|
187
213
|
`requests: ${JSON.stringify(activation.manifest.requests.map((request) => ({ id: request.id })))}`,
|
|
188
214
|
`handbookGeneralSource: ${handbook.generalSource}`,
|
|
189
215
|
`handbookRepoSource: ${handbook.repoSource}`,
|
|
@@ -244,6 +270,7 @@ export function createCollectorRoleRuntime(
|
|
|
244
270
|
const repoFlag = pi.getFlag("ak-collector-repo");
|
|
245
271
|
const prFlag = pi.getFlag("ak-collector-pr");
|
|
246
272
|
const requestManifestFlag = pi.getFlag("ak-collector-request-manifest");
|
|
273
|
+
const waitMsFlag = pi.getFlag("ak-collector-wait-ms");
|
|
247
274
|
if (typeof repoFlag !== "string" || repoFlag.trim().length === 0) {
|
|
248
275
|
throw new Error("Collector requires --ak-collector-repo");
|
|
249
276
|
}
|
|
@@ -258,11 +285,12 @@ export function createCollectorRoleRuntime(
|
|
|
258
285
|
const manifest = typeof requestManifestFlag === "string" && requestManifestFlag.trim().length > 0
|
|
259
286
|
? await loadCollectorManifest(requestManifestFlag)
|
|
260
287
|
: emptyCollectorManifest();
|
|
288
|
+
const waitWindowMs = parseWaitWindowMsFlag(waitMsFlag);
|
|
261
289
|
|
|
262
290
|
const clock = dependencies.createClock?.() ?? createSystemCollectorClock();
|
|
263
291
|
const transport = dependencies.createTransport();
|
|
264
292
|
const ledger = dependencies.createLedger(
|
|
265
|
-
{ repository, prNumber, manifest },
|
|
293
|
+
{ repository, prNumber, manifest, waitWindowMs },
|
|
266
294
|
clock,
|
|
267
295
|
ctx,
|
|
268
296
|
);
|
|
@@ -557,11 +585,60 @@ export function createCollectorRoleRuntime(
|
|
|
557
585
|
},
|
|
558
586
|
});
|
|
559
587
|
|
|
588
|
+
pi.registerTool({
|
|
589
|
+
name: COLLECTOR_OPEN_WAIT_WINDOW_TOOL,
|
|
590
|
+
label: "通进司开启等待窗",
|
|
591
|
+
description:
|
|
592
|
+
"在工作步骤上开启等待窗:新建并自动触发的 PR 传创建成功时刻;已有 PR 在触发阶段结束后省略 startedAt(=现在)。窗长由使用方配置,默认十分钟;开启后不因 PR 更新重置。",
|
|
593
|
+
promptSnippet: "按工作步骤开启等待窗",
|
|
594
|
+
parameters: openWaitWindowSchema,
|
|
595
|
+
async execute(toolCallId: string, params: OpenWaitWindowParams, _signal: AbortSignal | undefined, _onUpdate: unknown, ctx: HostContext) {
|
|
596
|
+
const activation = getActivation();
|
|
597
|
+
if (activation === undefined) throw new Error("通进司未激活");
|
|
598
|
+
try {
|
|
599
|
+
activation.ledger.beginOperational(COLLECTOR_OPEN_WAIT_WINDOW_TOOL, toolCallId);
|
|
600
|
+
let startedAt: Date | undefined;
|
|
601
|
+
if (typeof params.startedAt === "string" && params.startedAt.trim().length > 0) {
|
|
602
|
+
const parsed = new Date(params.startedAt);
|
|
603
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
604
|
+
throw new Error("通进司等待窗 startedAt 须为有效 ISO 时间");
|
|
605
|
+
}
|
|
606
|
+
startedAt = parsed;
|
|
607
|
+
}
|
|
608
|
+
activation.ledger.openWaitWindow(
|
|
609
|
+
activation.clock,
|
|
610
|
+
startedAt === undefined ? undefined : { startedAt },
|
|
611
|
+
);
|
|
612
|
+
activation.ledger.completeOperational(toolCallId);
|
|
613
|
+
return {
|
|
614
|
+
content: [{
|
|
615
|
+
type: "text" as const,
|
|
616
|
+
text: "等待窗已开启",
|
|
617
|
+
}],
|
|
618
|
+
details: {
|
|
619
|
+
activationTime: activation.ledger.activationTime?.toISOString(),
|
|
620
|
+
deadlineTime: activation.ledger.deadlineTime?.toISOString(),
|
|
621
|
+
waitWindowMs: activation.ledger.config.waitWindowMs,
|
|
622
|
+
},
|
|
623
|
+
};
|
|
624
|
+
} catch (error) {
|
|
625
|
+
if (isCorrectableExecuteError(error)) throw error;
|
|
626
|
+
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
627
|
+
} finally {
|
|
628
|
+
try {
|
|
629
|
+
activation.ledger.completeOperational(toolCallId);
|
|
630
|
+
} catch {
|
|
631
|
+
// already completed or not begun
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
});
|
|
636
|
+
|
|
560
637
|
pi.registerTool({
|
|
561
638
|
name: COLLECTOR_WAIT_TOOL,
|
|
562
639
|
label: "通进司等待",
|
|
563
|
-
description: "
|
|
564
|
-
promptSnippet: "
|
|
640
|
+
description: "再观察前等待;实际睡眠不超过剩余等待窗。",
|
|
641
|
+
promptSnippet: "等待窗内等待",
|
|
565
642
|
parameters: waitSchema,
|
|
566
643
|
async execute(toolCallId: string, params: WaitParams, signal: AbortSignal | undefined, _onUpdate: unknown, ctx: HostContext) {
|
|
567
644
|
const activation = getActivation();
|
|
@@ -582,6 +659,7 @@ export function createCollectorRoleRuntime(
|
|
|
582
659
|
details,
|
|
583
660
|
};
|
|
584
661
|
} catch (error) {
|
|
662
|
+
if (isCorrectableExecuteError(error)) throw error;
|
|
585
663
|
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
586
664
|
}
|
|
587
665
|
},
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Type, type Static } from "typebox";
|
|
2
|
-
import { COLLECTOR_ELIGIBILITY_MS } from "./collector-evidence.ts";
|
|
3
2
|
import { openToolObject } from "./open-tool-schema.ts";
|
|
4
3
|
import { withInfrastructureFailureDeclaration } from "./package-contracts/terminating-infrastructure.ts";
|
|
5
4
|
|
|
@@ -36,7 +35,22 @@ export const collectorReadArgsSchema = Type.Object({
|
|
|
36
35
|
evidenceId: Type.String({ minLength: 1, description: "observe 返回的材料证据 id(evidenceId)" }),
|
|
37
36
|
}, { additionalProperties: false });
|
|
38
37
|
export const collectorWaitArgsSchema = Type.Object({
|
|
39
|
-
durationMs: Type.Integer({
|
|
38
|
+
durationMs: Type.Integer({
|
|
39
|
+
minimum: 1,
|
|
40
|
+
description: "等待毫秒;实际睡眠不超过剩余等待窗(#678;无包内单次任意上限)",
|
|
41
|
+
}),
|
|
42
|
+
}, { additionalProperties: false });
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* #678 D4: open the wait window at a work step.
|
|
46
|
+
* Omit startedAt for existing-PR trigger-phase end (= now).
|
|
47
|
+
* Pass PR creation success time for new-PR auto-trigger rounds.
|
|
48
|
+
*/
|
|
49
|
+
export const collectorOpenWaitWindowArgsSchema = Type.Object({
|
|
50
|
+
startedAt: Type.Optional(Type.String({
|
|
51
|
+
minLength: 1,
|
|
52
|
+
description: "等待窗起点 ISO 时间;新建 PR 用创建成功时刻;省略=现在(触发阶段结束)",
|
|
53
|
+
})),
|
|
40
54
|
}, { additionalProperties: false });
|
|
41
55
|
|
|
42
56
|
/**
|
|
@@ -112,5 +126,6 @@ export type CollectorObserveArgs = Static<typeof collectorObserveArgsSchema>;
|
|
|
112
126
|
export type CollectorRequestArgs = Static<typeof collectorRequestArgsSchema>;
|
|
113
127
|
export type CollectorReadArgs = Static<typeof collectorReadArgsSchema>;
|
|
114
128
|
export type CollectorWaitArgs = Static<typeof collectorWaitArgsSchema>;
|
|
129
|
+
export type CollectorOpenWaitWindowArgs = Static<typeof collectorOpenWaitWindowArgsSchema>;
|
|
115
130
|
export type CollectorBindTargetArgs = Static<typeof collectorBindTargetArgsSchema>;
|
|
116
131
|
export type CollectorOutputArgs = Static<typeof collectorOutputArgsSchema>;
|
package/src/host-contracts.ts
CHANGED
|
@@ -106,6 +106,8 @@ export type RoleTurnActivation =
|
|
|
106
106
|
/** Bound PR when known at admission; omit when role will bind from materials. */
|
|
107
107
|
readonly pr?: string;
|
|
108
108
|
readonly requestManifestPath?: string;
|
|
109
|
+
/** Wait-window ms as decimal string (#678 D4); omit → package default 10 minutes. */
|
|
110
|
+
readonly waitMs?: string;
|
|
109
111
|
}
|
|
110
112
|
| { readonly role: "doctor"; readonly casePath: string }
|
|
111
113
|
| {
|
package/src/pi/role-turn-host.ts
CHANGED
|
@@ -116,6 +116,7 @@ function buildActivationFlagArgs(activation: RoleTurnActivation): string[] {
|
|
|
116
116
|
...(activation.requestManifestPath === undefined
|
|
117
117
|
? []
|
|
118
118
|
: ["--ak-collector-request-manifest", activation.requestManifestPath]),
|
|
119
|
+
...(activation.waitMs === undefined ? [] : ["--ak-collector-wait-ms", activation.waitMs]),
|
|
119
120
|
];
|
|
120
121
|
case "doctor":
|
|
121
122
|
return ["--ak-role", "doctor", "--ak-doctor-case", activation.casePath];
|
|
@@ -54,6 +54,7 @@ export function buildCollectorTurnRequest(
|
|
|
54
54
|
// #676 A: omit pr when unbound — role binds via ak_collector_bind_target.
|
|
55
55
|
...(admitted.prNumber === undefined ? {} : { pr: String(admitted.prNumber) }),
|
|
56
56
|
...(admitted.requestManifestPath === undefined ? {} : { requestManifestPath: admitted.requestManifestPath }),
|
|
57
|
+
...(admitted.waitWindowMs === undefined ? {} : { waitMs: String(admitted.waitWindowMs) }),
|
|
57
58
|
},
|
|
58
59
|
},
|
|
59
60
|
options,
|
|
@@ -83,6 +84,7 @@ export async function runPublicCollector(
|
|
|
83
84
|
...(parsed.project === undefined ? {} : { project: parsed.project }),
|
|
84
85
|
...(parsed.repo === undefined ? {} : { repo: parsed.repo }),
|
|
85
86
|
...(parsed.requestManifestPath === undefined ? {} : { requestManifestPath: parsed.requestManifestPath }),
|
|
87
|
+
...(parsed.waitWindowMs === undefined ? {} : { waitWindowMs: parsed.waitWindowMs }),
|
|
86
88
|
...(env.createRunId === undefined ? {} : { createRunId: env.createRunId }),
|
|
87
89
|
...(env.model === undefined ? {} : { model: env.model }),
|
|
88
90
|
});
|
|
@@ -178,6 +178,8 @@ export type AdmittedCollectorInvocation = AdmittedRoleInvocationBase & {
|
|
|
178
178
|
readonly repository: CollectorRepository;
|
|
179
179
|
readonly requestManifestPath?: string;
|
|
180
180
|
readonly manifestDigest: string;
|
|
181
|
+
/** Wait-window ms (#678 D4); default applied at role activate when omitted. */
|
|
182
|
+
readonly waitWindowMs?: number;
|
|
181
183
|
};
|
|
182
184
|
|
|
183
185
|
export type AdmittedDoctorInvocation = AdmittedRoleInvocationBase & {
|
|
@@ -727,6 +729,8 @@ export type ParseCollectorArgvResult = {
|
|
|
727
729
|
project?: string;
|
|
728
730
|
repo?: string;
|
|
729
731
|
requestManifestPath?: string;
|
|
732
|
+
/** Optional wait-window ms (#678 D4). */
|
|
733
|
+
waitWindowMs?: number;
|
|
730
734
|
};
|
|
731
735
|
|
|
732
736
|
export type ParseDoctorArgvResult = {
|
|
@@ -1722,6 +1726,7 @@ export function parseCollectorArgv(args: readonly string[]): ParseCollectorArgvR
|
|
|
1722
1726
|
let repo: string | undefined;
|
|
1723
1727
|
let prNumber: number | undefined;
|
|
1724
1728
|
let requestManifestPath: string | undefined;
|
|
1729
|
+
let waitWindowMs: number | undefined;
|
|
1725
1730
|
const positional: string[] = [];
|
|
1726
1731
|
const tokens = [...args];
|
|
1727
1732
|
const definitions = roleOptions("collector");
|
|
@@ -1754,6 +1759,17 @@ export function parseCollectorArgv(args: readonly string[]): ParseCollectorArgvR
|
|
|
1754
1759
|
requestManifestPath = requireOptionPath(taken.def.canonical, taken.value);
|
|
1755
1760
|
continue;
|
|
1756
1761
|
}
|
|
1762
|
+
if (taken.def.id === "wait-ms") {
|
|
1763
|
+
if (taken.value === undefined || !/^[1-9]\d*$/.test(taken.value.trim())) {
|
|
1764
|
+
throw new CliUsageError("--wait-ms requires a positive safe-integer millisecond value");
|
|
1765
|
+
}
|
|
1766
|
+
const parsed = Number(taken.value.trim());
|
|
1767
|
+
if (!Number.isSafeInteger(parsed) || parsed < 1) {
|
|
1768
|
+
throw new CliUsageError("--wait-ms requires a positive safe-integer millisecond value");
|
|
1769
|
+
}
|
|
1770
|
+
waitWindowMs = parsed;
|
|
1771
|
+
continue;
|
|
1772
|
+
}
|
|
1757
1773
|
throw new CliUsageError(`unknown collector option: ${taken.def.canonical}`);
|
|
1758
1774
|
}
|
|
1759
1775
|
const token = tokens.shift()!;
|
|
@@ -1772,6 +1788,7 @@ export function parseCollectorArgv(args: readonly string[]): ParseCollectorArgvR
|
|
|
1772
1788
|
...(project === undefined ? {} : { project }),
|
|
1773
1789
|
...(repo === undefined ? {} : { repo }),
|
|
1774
1790
|
...(requestManifestPath === undefined ? {} : { requestManifestPath }),
|
|
1791
|
+
...(waitWindowMs === undefined ? {} : { waitWindowMs }),
|
|
1775
1792
|
};
|
|
1776
1793
|
}
|
|
1777
1794
|
|
|
@@ -1845,6 +1862,8 @@ export type AdmitCollectorInvocationOptions = {
|
|
|
1845
1862
|
repo?: string;
|
|
1846
1863
|
/** Optional public request configuration; copied into the admitted run. */
|
|
1847
1864
|
requestManifestPath?: string;
|
|
1865
|
+
/** Optional wait-window ms (#678 D4). */
|
|
1866
|
+
waitWindowMs?: number;
|
|
1848
1867
|
createRunId?: () => string;
|
|
1849
1868
|
/** Effective model for this invocation — written onto invocation.json. */
|
|
1850
1869
|
model?: InvocationEffectiveModel;
|
|
@@ -1947,6 +1966,7 @@ export async function admitCollectorInvocation(
|
|
|
1947
1966
|
repository: repository.canonical,
|
|
1948
1967
|
repositoryDisplay: repository.display,
|
|
1949
1968
|
...(requestManifestPath === undefined ? {} : { requestManifestPath }),
|
|
1969
|
+
...(options.waitWindowMs === undefined ? {} : { waitWindowMs: options.waitWindowMs }),
|
|
1950
1970
|
manifestDigest,
|
|
1951
1971
|
attachments: attachments.map((a) => ({
|
|
1952
1972
|
provenancePath: a.provenancePath,
|
|
@@ -1977,6 +1997,7 @@ export async function admitCollectorInvocation(
|
|
|
1977
1997
|
...(prNumber === undefined ? {} : { prNumber }),
|
|
1978
1998
|
repository,
|
|
1979
1999
|
...(requestManifestPath === undefined ? {} : { requestManifestPath }),
|
|
2000
|
+
...(options.waitWindowMs === undefined ? {} : { waitWindowMs: options.waitWindowMs }),
|
|
1980
2001
|
manifestDigest,
|
|
1981
2002
|
};
|
|
1982
2003
|
}
|
|
@@ -602,6 +602,20 @@ const COLLECTOR_OPTIONS = [
|
|
|
602
602
|
zh: "可选 request manifest JSON 路径({requests:[{id,body}]})。角色亦可依手册/现场自行判定请求正文,不必依赖本文件。",
|
|
603
603
|
},
|
|
604
604
|
},
|
|
605
|
+
{
|
|
606
|
+
id: "wait-ms",
|
|
607
|
+
owner: "collector",
|
|
608
|
+
canonical: "--wait-ms",
|
|
609
|
+
aliases: [],
|
|
610
|
+
valueMetavar: "ms",
|
|
611
|
+
required: false,
|
|
612
|
+
repeatable: false,
|
|
613
|
+
form: "option",
|
|
614
|
+
description: {
|
|
615
|
+
en: "Wait-window duration in milliseconds after the work step opens (default 600000 = 10 minutes). Does not require a code change to adjust.",
|
|
616
|
+
zh: "工作步骤开启后的等待窗时长(毫秒;默认 600000=十分钟)。改配置即可,无需改代码。",
|
|
617
|
+
},
|
|
618
|
+
},
|
|
605
619
|
] as const satisfies readonly PublicOptionDefinition[];
|
|
606
620
|
|
|
607
621
|
const DOCTOR_OPTIONS = [
|
|
@@ -1149,6 +1149,8 @@ type LoadedAdmittedRequestFields = {
|
|
|
1149
1149
|
readonly repositoryDisplay?: string;
|
|
1150
1150
|
readonly requestManifestPath?: string;
|
|
1151
1151
|
readonly manifestDigest?: string;
|
|
1152
|
+
/** Collector wait-window ms restored on resume (#678). */
|
|
1153
|
+
readonly waitWindowMs?: number;
|
|
1152
1154
|
/** Doctor — admitted single-case identity restored on resume (#633). */
|
|
1153
1155
|
readonly issueNumber?: number;
|
|
1154
1156
|
readonly caseRunsPath?: string;
|
|
@@ -1244,6 +1246,7 @@ async function loadResumableRunRecord(
|
|
|
1244
1246
|
let repositoryDisplay: string | undefined;
|
|
1245
1247
|
let requestManifestPath: string | undefined;
|
|
1246
1248
|
let manifestDigest: string | undefined;
|
|
1249
|
+
let waitWindowMs: number | undefined;
|
|
1247
1250
|
let issueNumber: number | undefined;
|
|
1248
1251
|
let caseRunsPath: string | undefined;
|
|
1249
1252
|
let caseIdentity: DoctorCaseIdentity | undefined;
|
|
@@ -1304,6 +1307,9 @@ async function loadResumableRunRecord(
|
|
|
1304
1307
|
if (typeof record.manifestDigest === "string" && record.manifestDigest.trim() !== "") {
|
|
1305
1308
|
manifestDigest = record.manifestDigest;
|
|
1306
1309
|
}
|
|
1310
|
+
if (typeof record.waitWindowMs === "number" && Number.isSafeInteger(record.waitWindowMs) && record.waitWindowMs >= 1) {
|
|
1311
|
+
waitWindowMs = record.waitWindowMs;
|
|
1312
|
+
}
|
|
1307
1313
|
// Doctor — admitted single-case identity (#633 resume).
|
|
1308
1314
|
if (typeof record.issueNumber === "number" && Number.isSafeInteger(record.issueNumber) && record.issueNumber >= 1) {
|
|
1309
1315
|
issueNumber = record.issueNumber;
|
|
@@ -1471,6 +1477,7 @@ async function loadResumableRunRecord(
|
|
|
1471
1477
|
...(repositoryDisplay === undefined ? {} : { repositoryDisplay }),
|
|
1472
1478
|
...(requestManifestPath === undefined ? {} : { requestManifestPath }),
|
|
1473
1479
|
...(manifestDigest === undefined ? {} : { manifestDigest }),
|
|
1480
|
+
...(waitWindowMs === undefined ? {} : { waitWindowMs }),
|
|
1474
1481
|
...(issueNumber === undefined ? {} : { issueNumber }),
|
|
1475
1482
|
...(caseRunsPath === undefined ? {} : { caseRunsPath }),
|
|
1476
1483
|
...(caseIdentity === undefined ? {} : { caseIdentity }),
|
|
@@ -1913,6 +1920,9 @@ export async function loadResumableCollectorRun(
|
|
|
1913
1920
|
...(loaded.admittedFields.requestManifestPath === undefined
|
|
1914
1921
|
? {}
|
|
1915
1922
|
: { requestManifestPath: loaded.admittedFields.requestManifestPath }),
|
|
1923
|
+
...(loaded.admittedFields.waitWindowMs === undefined
|
|
1924
|
+
? {}
|
|
1925
|
+
: { waitWindowMs: loaded.admittedFields.waitWindowMs }),
|
|
1916
1926
|
manifestDigest,
|
|
1917
1927
|
};
|
|
1918
1928
|
return seatLoadedResult(loaded, admitted);
|