@stigmer/runner 3.2.1 → 3.2.3
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/dist/.build-fingerprint +1 -1
- package/dist/activities/call-transform.js +12 -2
- package/dist/activities/call-transform.js.map +1 -1
- package/dist/activities/call-validate.js +20 -2
- package/dist/activities/call-validate.js.map +1 -1
- package/dist/activities/discover-mcp-server.js +6 -20
- package/dist/activities/discover-mcp-server.js.map +1 -1
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.d.ts +5 -0
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js +1 -1
- package/dist/activities/execute-cursor/__test-utils__/cursor-hook-harness.js.map +1 -1
- package/dist/activities/execute-cursor/approval-state.d.ts +27 -2
- package/dist/activities/execute-cursor/approval-state.js +13 -1
- package/dist/activities/execute-cursor/approval-state.js.map +1 -1
- package/dist/activities/execute-cursor/hook-script.js +38 -0
- package/dist/activities/execute-cursor/hook-script.js.map +1 -1
- package/dist/activities/execute-cursor/index.d.ts +12 -0
- package/dist/activities/execute-cursor/index.js +72 -15
- package/dist/activities/execute-cursor/index.js.map +1 -1
- package/dist/activities/execute-cursor/message-translator.d.ts +26 -0
- package/dist/activities/execute-cursor/message-translator.js +78 -2
- package/dist/activities/execute-cursor/message-translator.js.map +1 -1
- package/dist/activities/execute-cursor/prompt-builder.d.ts +19 -0
- package/dist/activities/execute-cursor/prompt-builder.js +21 -0
- package/dist/activities/execute-cursor/prompt-builder.js.map +1 -1
- package/dist/activities/execute-cursor/session-lifecycle.d.ts +45 -0
- package/dist/activities/execute-cursor/session-lifecycle.js +41 -0
- package/dist/activities/execute-cursor/session-lifecycle.js.map +1 -1
- package/dist/activities/execute-cursor/turn-boundary.js +15 -2
- package/dist/activities/execute-cursor/turn-boundary.js.map +1 -1
- package/dist/activities/execute-deep-agent/hitl.d.ts +25 -0
- package/dist/activities/execute-deep-agent/hitl.js +48 -1
- package/dist/activities/execute-deep-agent/hitl.js.map +1 -1
- package/dist/activities/execute-deep-agent/index.js +10 -1
- package/dist/activities/execute-deep-agent/index.js.map +1 -1
- package/dist/activities/execute-deep-agent/prompt-builder.d.ts +19 -0
- package/dist/activities/execute-deep-agent/prompt-builder.js +12 -0
- package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/setup.d.ts +14 -0
- package/dist/activities/execute-deep-agent/setup.js +16 -1
- package/dist/activities/execute-deep-agent/setup.js.map +1 -1
- package/dist/activities/execute-deep-agent/status-builder-shared.d.ts +8 -0
- package/dist/activities/execute-deep-agent/status-builder-shared.js.map +1 -1
- package/dist/activities/execute-deep-agent/status-builder.js +6 -0
- package/dist/activities/execute-deep-agent/status-builder.js.map +1 -1
- package/dist/activities/execute-deep-agent/v3-status-builder.js +6 -0
- package/dist/activities/execute-deep-agent/v3-status-builder.js.map +1 -1
- package/dist/activities/workflow-event-activities.js +11 -0
- package/dist/activities/workflow-event-activities.js.map +1 -1
- package/dist/config.d.ts +17 -0
- package/dist/config.js +14 -0
- package/dist/config.js.map +1 -1
- package/dist/middleware/approval-gate.d.ts +20 -0
- package/dist/middleware/approval-gate.js +16 -1
- package/dist/middleware/approval-gate.js.map +1 -1
- package/dist/runner-manager.d.ts +2 -0
- package/dist/runner-manager.js +2 -1
- package/dist/runner-manager.js.map +1 -1
- package/dist/runner.d.ts +2 -0
- package/dist/runner.js +2 -1
- package/dist/runner.js.map +1 -1
- package/dist/shared/approval-policy.d.ts +24 -1
- package/dist/shared/approval-policy.js +35 -1
- package/dist/shared/approval-policy.js.map +1 -1
- package/dist/shared/context-bridge.d.ts +30 -0
- package/dist/shared/context-bridge.js +45 -0
- package/dist/shared/context-bridge.js.map +1 -0
- package/dist/shared/sender-identity.d.ts +50 -0
- package/dist/shared/sender-identity.js +69 -0
- package/dist/shared/sender-identity.js.map +1 -0
- package/dist/shared/with-timeout.d.ts +27 -0
- package/dist/shared/with-timeout.js +47 -0
- package/dist/shared/with-timeout.js.map +1 -0
- package/dist/workflow-engine/do-executor.d.ts +7 -0
- package/dist/workflow-engine/do-executor.js +59 -1
- package/dist/workflow-engine/do-executor.js.map +1 -1
- package/dist/workflow-engine/tasks/call-function.js +68 -1
- package/dist/workflow-engine/tasks/call-function.js.map +1 -1
- package/dist/workflow-engine/tasks/human-input.js +1 -0
- package/dist/workflow-engine/tasks/human-input.js.map +1 -1
- package/dist/workflow-engine/types.d.ts +48 -0
- package/dist/workflow-engine/types.js.map +1 -1
- package/dist/workflows/engine-core.js +5 -1
- package/dist/workflows/engine-core.js.map +1 -1
- package/dist/workflows/human-input-orchestrator.d.ts +2 -1
- package/dist/workflows/human-input-orchestrator.js +2 -1
- package/dist/workflows/human-input-orchestrator.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/config.test.ts +8 -0
- package/src/activities/__tests__/call-validate.test.ts +137 -0
- package/src/activities/__tests__/classify-tool-approvals.test.ts +1 -0
- package/src/activities/__tests__/discover-mcp-server.test.ts +1 -0
- package/src/activities/__tests__/workflow-event-activities.test.ts +89 -0
- package/src/activities/call-transform.ts +20 -2
- package/src/activities/call-validate.ts +27 -2
- package/src/activities/discover-mcp-server.ts +7 -28
- package/src/activities/execute-cursor/__test-utils__/cursor-hook-harness.ts +6 -0
- package/src/activities/execute-cursor/__tests__/build-prompt.test.ts +65 -0
- package/src/activities/execute-cursor/__tests__/hitl-ledger.test.ts +105 -0
- package/src/activities/execute-cursor/__tests__/hook-script.test.ts +54 -0
- package/src/activities/execute-cursor/__tests__/session-lifecycle.test.ts +122 -1
- package/src/activities/execute-cursor/approval-state.ts +32 -1
- package/src/activities/execute-cursor/hook-script.ts +40 -0
- package/src/activities/execute-cursor/index.ts +86 -17
- package/src/activities/execute-cursor/message-translator.ts +82 -1
- package/src/activities/execute-cursor/prompt-builder.ts +44 -0
- package/src/activities/execute-cursor/session-lifecycle.ts +76 -0
- package/src/activities/execute-cursor/turn-boundary.ts +23 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-reject.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-approve-all.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/hitl-resume-history.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/hitl.test.ts +103 -2
- package/src/activities/execute-deep-agent/__tests__/index.test.ts +1 -0
- package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +58 -0
- package/src/activities/execute-deep-agent/__tests__/sequential-gate-resume.test.ts +1 -0
- package/src/activities/execute-deep-agent/hitl.ts +51 -0
- package/src/activities/execute-deep-agent/index.ts +11 -1
- package/src/activities/execute-deep-agent/prompt-builder.ts +35 -0
- package/src/activities/execute-deep-agent/setup.ts +31 -0
- package/src/activities/execute-deep-agent/status-builder-shared.ts +8 -0
- package/src/activities/execute-deep-agent/status-builder.ts +7 -0
- package/src/activities/execute-deep-agent/v3-status-builder.ts +7 -0
- package/src/activities/workflow-event-activities.ts +11 -0
- package/src/config.ts +23 -0
- package/src/middleware/__tests__/approval-gate.test.ts +95 -0
- package/src/middleware/approval-gate.ts +37 -0
- package/src/runner-manager.ts +6 -1
- package/src/runner.ts +6 -1
- package/src/shared/__tests__/artifact-storage.test.ts +1 -0
- package/src/shared/__tests__/context-bridge.test.ts +51 -0
- package/src/shared/__tests__/sender-identity.test.ts +92 -0
- package/src/shared/__tests__/with-timeout.test.ts +60 -0
- package/src/shared/approval-policy.ts +41 -2
- package/src/shared/context-bridge.ts +51 -0
- package/src/shared/sender-identity.ts +85 -0
- package/src/shared/with-timeout.ts +53 -0
- package/src/workflow-engine/__tests__/do-executor.test.ts +155 -0
- package/src/workflow-engine/__tests__/tasks/call-function.test.ts +94 -0
- package/src/workflow-engine/__tests__/tasks/human-input.test.ts +40 -0
- package/src/workflow-engine/do-executor.ts +65 -1
- package/src/workflow-engine/tasks/call-function.ts +84 -3
- package/src/workflow-engine/tasks/human-input.ts +1 -0
- package/src/workflow-engine/types.ts +50 -0
- package/src/workflows/__tests__/execute-serverless-workflow.test.ts +1 -0
- package/src/workflows/engine-core.ts +5 -1
- package/src/workflows/human-input-orchestrator.ts +2 -1
|
@@ -328,6 +328,17 @@ export interface TaskExecutionContext {
|
|
|
328
328
|
* this opaque callback at well-defined yield points.
|
|
329
329
|
*/
|
|
330
330
|
readonly checkPause?: () => Promise<void>;
|
|
331
|
+
/**
|
|
332
|
+
* Deterministic version gate for engine behavior changes that alter
|
|
333
|
+
* the workflow's command sequence — Temporal `patched()` semantics:
|
|
334
|
+
* `true` for new executions (recording a marker) and for replays whose
|
|
335
|
+
* history carries the marker; `false` when replaying pre-change
|
|
336
|
+
* histories, which must re-execute the old command order. Wired to
|
|
337
|
+
* Temporal's `patched()` in the workflow function; the kernel stays
|
|
338
|
+
* Temporal-agnostic and treats an absent gate as "change active"
|
|
339
|
+
* (tests and the minimal context never replay old histories).
|
|
340
|
+
*/
|
|
341
|
+
readonly isPatched?: (changeId: string) => boolean;
|
|
331
342
|
/**
|
|
332
343
|
* Accumulates per-task status entries throughout the workflow run.
|
|
333
344
|
* Passed to the emit activity on every event batch so the server
|
|
@@ -417,12 +428,31 @@ export interface HumanInputExecutionConfig {
|
|
|
417
428
|
}
|
|
418
429
|
export interface HumanInputResult {
|
|
419
430
|
readonly outcome: string;
|
|
431
|
+
/** Canonical reviewer identity (identity-account ID). Empty/absent when unattributed. */
|
|
420
432
|
readonly reviewer?: string;
|
|
433
|
+
/**
|
|
434
|
+
* Display snapshot of the reviewer, stamped server-side by the control
|
|
435
|
+
* plane at decision time. Rides the signal opaquely into the task output
|
|
436
|
+
* (for downstream tasks, e.g. notifications) and the approval_resolved
|
|
437
|
+
* event (for UIs). Absent when no attribution exists — never synthesized.
|
|
438
|
+
*/
|
|
439
|
+
readonly reviewer_actor?: HumanInputReviewerActor;
|
|
421
440
|
readonly responded_at?: string;
|
|
422
441
|
readonly form_data?: Record<string, unknown>;
|
|
423
442
|
readonly auto_resolved?: boolean;
|
|
424
443
|
readonly reason?: string;
|
|
425
444
|
}
|
|
445
|
+
/** Write-time snapshot of the reviewer's display identity. */
|
|
446
|
+
export interface HumanInputReviewerActor {
|
|
447
|
+
/** Canonical identity (matches HumanInputResult.reviewer). */
|
|
448
|
+
readonly id: string;
|
|
449
|
+
/** Human-readable name; empty when unknown. */
|
|
450
|
+
readonly display_name?: string;
|
|
451
|
+
/** Email address; empty when unknown. */
|
|
452
|
+
readonly email?: string;
|
|
453
|
+
/** Avatar URL; empty when unknown. */
|
|
454
|
+
readonly avatar?: string;
|
|
455
|
+
}
|
|
426
456
|
export interface HumanInputConfig {
|
|
427
457
|
readonly prompt: string;
|
|
428
458
|
readonly outcomes?: HumanInputOutcome[];
|
|
@@ -563,6 +593,14 @@ export interface TaskStartedEvent extends EventBase {
|
|
|
563
593
|
readonly type: "task_started";
|
|
564
594
|
readonly taskKind: string;
|
|
565
595
|
readonly attemptNumber: number;
|
|
596
|
+
/**
|
|
597
|
+
* Truncated resolved task input (proto `TaskStartedPayload.input_summary`).
|
|
598
|
+
* The live-stream preview source for task cards — the FULL input lives on
|
|
599
|
+
* the status snapshot. Only present when the input is a plain object
|
|
600
|
+
* (proto Struct constraint, mirroring `status.tasks[].input`) and when
|
|
601
|
+
* emission happens after input resolution (the patched()-gated path).
|
|
602
|
+
*/
|
|
603
|
+
readonly inputSummary?: Record<string, unknown>;
|
|
566
604
|
}
|
|
567
605
|
export interface TaskCompletedEvent extends EventBase {
|
|
568
606
|
readonly type: "task_completed";
|
|
@@ -570,6 +608,13 @@ export interface TaskCompletedEvent extends EventBase {
|
|
|
570
608
|
readonly durationMs: number;
|
|
571
609
|
readonly costMicros: number;
|
|
572
610
|
readonly tokensUsed: number;
|
|
611
|
+
/**
|
|
612
|
+
* Truncated task output (proto `TaskCompletedPayload.output_summary`).
|
|
613
|
+
* The live-stream preview source for task cards — the FULL output lives
|
|
614
|
+
* on the status snapshot. Only present when the output is a plain object
|
|
615
|
+
* (proto Struct constraint, mirroring `status.tasks[].output`).
|
|
616
|
+
*/
|
|
617
|
+
readonly outputSummary?: Record<string, unknown>;
|
|
573
618
|
}
|
|
574
619
|
export interface TaskFailedEvent extends EventBase {
|
|
575
620
|
readonly type: "task_failed";
|
|
@@ -612,7 +657,10 @@ export interface ApprovalRequestedEvent extends EventBase {
|
|
|
612
657
|
export interface ApprovalResolvedEvent extends EventBase {
|
|
613
658
|
readonly type: "approval_resolved";
|
|
614
659
|
readonly outcome: string;
|
|
660
|
+
/** Canonical reviewer identity. Empty when unattributed. */
|
|
615
661
|
readonly resolvedBy: string;
|
|
662
|
+
/** Display snapshot of the reviewer from the signal payload, if stamped. */
|
|
663
|
+
readonly resolvedByActor?: HumanInputReviewerActor;
|
|
616
664
|
readonly comment: string;
|
|
617
665
|
readonly waitDurationMs: number;
|
|
618
666
|
readonly autoResolved: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/workflow-engine/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA6LH,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;AACxC,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC;AAC9B,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC;AAEhC,MAAM,UAAU,aAAa,CAAC,SAAwB;IACpD,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,SAAS,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAwB;IACvD,OAAO,CACL,SAAS,KAAK,aAAa;QAC3B,SAAS,KAAK,QAAQ;QACtB,SAAS,KAAK,SAAS,CACxB,CAAC;AACJ,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/workflow-engine/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA6LH,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;AACxC,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC;AAC9B,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC;AAEhC,MAAM,UAAU,aAAa,CAAC,SAAwB;IACpD,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,SAAS,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAwB;IACvD,OAAO,CACL,SAAS,KAAK,aAAa;QAC3B,SAAS,KAAK,QAAQ;QACtB,SAAS,KAAK,SAAS,CACxB,CAAC;AACJ,CAAC;AAwrBD,wEAAwE;AACxE,cAAc;AACd,wEAAwE;AAExE;;;;;;;;;;GAUG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,gBAAgB,CAAS;IAElC,YAAY,OAAe,EAAE,gBAAwB;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;CACF"}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* operations, no side-effecting imports. Only @temporalio/workflow APIs,
|
|
13
13
|
* type-only imports, and pure JS/TS logic.
|
|
14
14
|
*/
|
|
15
|
-
import { proxyLocalActivities, proxyActivities, log, workflowInfo, sleep } from "@temporalio/workflow";
|
|
15
|
+
import { proxyLocalActivities, proxyActivities, log, patched, workflowInfo, sleep } from "@temporalio/workflow";
|
|
16
16
|
import { ApplicationFailure, CancelledFailure, ActivityFailure } from "@temporalio/workflow";
|
|
17
17
|
import { recordExecutionStartMetric, recordExecutionEndMetric } from "./metrics-sink.js";
|
|
18
18
|
import { orchestrateAgentCall } from "./call-agent-orchestrator.js";
|
|
@@ -135,6 +135,10 @@ export async function runWorkflowEngine(input, options) {
|
|
|
135
135
|
checkPause: options?.checkPause,
|
|
136
136
|
emitEvents,
|
|
137
137
|
taskStatusAccumulator,
|
|
138
|
+
// Deterministic version gate for engine command-order changes (the
|
|
139
|
+
// kernel never imports Temporal APIs — it receives patched() as an
|
|
140
|
+
// opaque callback, like every other capability on this context).
|
|
141
|
+
isPatched: (changeId) => patched(changeId),
|
|
138
142
|
sleep: async (durationMs) => {
|
|
139
143
|
try {
|
|
140
144
|
await sleep(durationMs);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine-core.js","sourceRoot":"","sources":["../../src/workflows/engine-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"engine-core.js","sourceRoot":"","sources":["../../src/workflows/engine-core.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* - "approve": returns auto-approved output
|
|
9
9
|
* - "deny": returns auto-denied output
|
|
10
10
|
*
|
|
11
|
-
* Signal payload shape:
|
|
11
|
+
* Signal payload shape:
|
|
12
|
+
* { outcome, form_data?, reviewer, reviewer_actor?, responded_at }
|
|
12
13
|
*
|
|
13
14
|
* TEMPORAL SANDBOX: This file runs inside the deterministic workflow isolate.
|
|
14
15
|
*/
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* - "approve": returns auto-approved output
|
|
9
9
|
* - "deny": returns auto-denied output
|
|
10
10
|
*
|
|
11
|
-
* Signal payload shape:
|
|
11
|
+
* Signal payload shape:
|
|
12
|
+
* { outcome, form_data?, reviewer, reviewer_actor?, responded_at }
|
|
12
13
|
*
|
|
13
14
|
* TEMPORAL SANDBOX: This file runs inside the deterministic workflow isolate.
|
|
14
15
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"human-input-orchestrator.js","sourceRoot":"","sources":["../../src/workflows/human-input-orchestrator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"human-input-orchestrator.js","sourceRoot":"","sources":["../../src/workflows/human-input-orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAI3E;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAiC;IAEjC,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAEzD,IAAI,OAAqC,CAAC;IAC1C,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,MAAM,MAAM,GAAG,YAAY,CAAqB,UAAU,CAAC,CAAC;IAC5D,UAAU,CAAC,MAAM,EAAE,CAAC,IAAsB,EAAE,EAAE;QAC5C,OAAO,GAAG,IAAI,CAAC;QACf,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,cAAc,GAAG,IAAI,CAAC;QACxC,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAE7D,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,OAAQ,CAAC;AAClB,CAAC;AAED,SAAS,aAAa,CACpB,UAAkB,EAClB,MAAmC;IAEnC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO;gBACL,OAAO,EAAE,SAAS;gBAClB,aAAa,EAAE,IAAI;gBACnB,MAAM,EAAE,SAAS;aAClB,CAAC;QAEJ,KAAK,MAAM;YACT,OAAO;gBACL,OAAO,EAAE,MAAM;gBACf,aAAa,EAAE,IAAI;gBACnB,MAAM,EAAE,SAAS;aAClB,CAAC;QAEJ,KAAK,MAAM,CAAC;QACZ;YACE,MAAM,IAAI,KAAK,CACb,kDAAkD,UAAU,GAAG,CAChE,CAAC;IACN,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigmer/runner",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.3",
|
|
4
4
|
"description": "Embeddable Temporal worker for the Stigmer AI agent platform — handles agent execution, workflow orchestration, and MCP server management",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"@opentelemetry/sdk-metrics": "^2.0.0",
|
|
86
86
|
"@opentelemetry/sdk-trace-base": "^2.0.0",
|
|
87
87
|
"@opentelemetry/sdk-trace-node": "^2.0.0",
|
|
88
|
-
"@stigmer/protos": "3.2.
|
|
88
|
+
"@stigmer/protos": "3.2.3",
|
|
89
89
|
"@temporalio/activity": "^1.11.0",
|
|
90
90
|
"@temporalio/client": "^1.11.0",
|
|
91
91
|
"@temporalio/common": "^1.11.0",
|
|
@@ -33,9 +33,17 @@ describe("loadConfig", () => {
|
|
|
33
33
|
expect(config.proxyEndpoint).toBeNull();
|
|
34
34
|
expect(config.maxConcurrentActivities).toBe(5);
|
|
35
35
|
expect(config.cursorStreamStallTimeoutMs).toBe(180000);
|
|
36
|
+
expect(config.agentResolveTimeoutMs).toBe(120000);
|
|
36
37
|
expect(config.workspaceLockTimeoutMs).toBe(900000);
|
|
37
38
|
});
|
|
38
39
|
|
|
40
|
+
it("respects CURSOR_AGENT_RESOLVE_TIMEOUT_MS", () => {
|
|
41
|
+
process.env.CURSOR_API_KEY = "test-key";
|
|
42
|
+
process.env.CURSOR_AGENT_RESOLVE_TIMEOUT_MS = "45000";
|
|
43
|
+
const config = loadConfig();
|
|
44
|
+
expect(config.agentResolveTimeoutMs).toBe(45000);
|
|
45
|
+
});
|
|
46
|
+
|
|
39
47
|
it("respects CURSOR_STREAM_STALL_TIMEOUT_MS", () => {
|
|
40
48
|
process.env.CURSOR_API_KEY = "test-key";
|
|
41
49
|
process.env.CURSOR_STREAM_STALL_TIMEOUT_MS = "90000";
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { validateAction } from "../call-validate.js";
|
|
3
|
+
import { transformAction } from "../call-transform.js";
|
|
4
|
+
|
|
5
|
+
// Regression coverage for the `expr.includes is not a function` crash
|
|
6
|
+
// (workflow-execution-ux-parity upstream #7): rule expressions are
|
|
7
|
+
// deferred code that must reach this activity as jq strings — in either
|
|
8
|
+
// the strict `${ ... }` wrapper or the bare form — and be evaluated here
|
|
9
|
+
// against the validated data, never pre-resolved by the config resolver.
|
|
10
|
+
|
|
11
|
+
describe("validateAction — rule expressions", () => {
|
|
12
|
+
// The exact shape of WF1 ux-linear-basics' check_order task after the
|
|
13
|
+
// call-function builder resolves `input` and defers the rule.
|
|
14
|
+
const checkOrderConfig = {
|
|
15
|
+
input: {
|
|
16
|
+
order_id: "ORD-2026-0716",
|
|
17
|
+
customer: "Ada Lovelace",
|
|
18
|
+
currency: "USD",
|
|
19
|
+
line_count: 2,
|
|
20
|
+
total: 150,
|
|
21
|
+
},
|
|
22
|
+
schema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
required: ["order_id", "total", "line_count"],
|
|
25
|
+
properties: {
|
|
26
|
+
order_id: { type: "string" },
|
|
27
|
+
total: { type: "number" },
|
|
28
|
+
line_count: { type: "integer" },
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
rules: [
|
|
32
|
+
{
|
|
33
|
+
name: "total_is_positive",
|
|
34
|
+
expression: "${ .total > 0 }",
|
|
35
|
+
message: "Order total must be positive",
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
on_fail: "VALIDATION_FAIL_RAISE",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
it("evaluates a ${ }-wrapped rule against the validate input (WF1 check_order)", async () => {
|
|
42
|
+
const result = await validateAction(checkOrderConfig);
|
|
43
|
+
expect(result.valid).toBe(true);
|
|
44
|
+
expect(result.errors).toEqual([]);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("evaluates a bare jq rule expression", async () => {
|
|
48
|
+
const result = await validateAction({
|
|
49
|
+
input: { total: 150 },
|
|
50
|
+
rules: [{ name: "positive", expression: ".total > 0" }],
|
|
51
|
+
on_fail: "VALIDATION_FAIL_WARN",
|
|
52
|
+
});
|
|
53
|
+
expect(result.valid).toBe(true);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("reports the rule message when the predicate fails", async () => {
|
|
57
|
+
const result = await validateAction({
|
|
58
|
+
input: { total: -5 },
|
|
59
|
+
rules: [
|
|
60
|
+
{
|
|
61
|
+
name: "total_is_positive",
|
|
62
|
+
expression: "${ .total > 0 }",
|
|
63
|
+
message: "Order total must be positive",
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
on_fail: "VALIDATION_FAIL_WARN",
|
|
67
|
+
});
|
|
68
|
+
expect(result.valid).toBe(false);
|
|
69
|
+
expect(result.errors).toEqual([
|
|
70
|
+
{ rule: "total_is_positive", message: "Order total must be positive" },
|
|
71
|
+
]);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("turns a non-string expression into a named config error, not a TypeError", async () => {
|
|
75
|
+
// The pre-fix failure mode: the resolver substituted the evaluated
|
|
76
|
+
// boolean back into the rule. The guard must name the rule and the
|
|
77
|
+
// expected shape instead of crashing in the jq engine.
|
|
78
|
+
const result = await validateAction({
|
|
79
|
+
input: { total: 150 },
|
|
80
|
+
rules: [
|
|
81
|
+
{ name: "broken_rule", expression: true as unknown as string },
|
|
82
|
+
],
|
|
83
|
+
on_fail: "VALIDATION_FAIL_WARN",
|
|
84
|
+
});
|
|
85
|
+
expect(result.valid).toBe(false);
|
|
86
|
+
expect(result.errors).toHaveLength(1);
|
|
87
|
+
expect(result.errors[0].rule).toBe("broken_rule");
|
|
88
|
+
expect(result.errors[0].message).toContain("expected a jq predicate string");
|
|
89
|
+
expect(result.errors[0].message).toContain("boolean");
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("raises on failed rules when on_fail is RAISE", async () => {
|
|
93
|
+
await expect(
|
|
94
|
+
validateAction({
|
|
95
|
+
input: { total: -5 },
|
|
96
|
+
rules: [
|
|
97
|
+
{
|
|
98
|
+
name: "total_is_positive",
|
|
99
|
+
expression: "${ .total > 0 }",
|
|
100
|
+
message: "Order total must be positive",
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
on_fail: "VALIDATION_FAIL_RAISE",
|
|
104
|
+
}),
|
|
105
|
+
).rejects.toThrow("Order total must be positive");
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe("transformAction — deferred expression forms", () => {
|
|
110
|
+
it("accepts a ${ }-wrapped expression", async () => {
|
|
111
|
+
const result = await transformAction({
|
|
112
|
+
engine: "TRANSFORM_ENGINE_JQ",
|
|
113
|
+
expression: "${ { doubled: (.qty * 2) } }",
|
|
114
|
+
input: { qty: 21 },
|
|
115
|
+
});
|
|
116
|
+
expect(result).toEqual({ doubled: 42 });
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("accepts the bare jq form the converter emits", async () => {
|
|
120
|
+
const result = await transformAction({
|
|
121
|
+
engine: "TRANSFORM_ENGINE_JQ",
|
|
122
|
+
expression: "{ total: ([.items[] | .qty * .unit_price] | add) }",
|
|
123
|
+
input: { items: [{ qty: 2, unit_price: 25.5 }, { qty: 1, unit_price: 99 }] },
|
|
124
|
+
});
|
|
125
|
+
expect(result).toEqual({ total: 150 });
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("rejects a non-string expression with a clear config error", async () => {
|
|
129
|
+
await expect(
|
|
130
|
+
transformAction({
|
|
131
|
+
engine: "JQ",
|
|
132
|
+
expression: { not: "a string" } as unknown as string,
|
|
133
|
+
input: {},
|
|
134
|
+
}),
|
|
135
|
+
).rejects.toThrow("must be a jq string");
|
|
136
|
+
});
|
|
137
|
+
});
|
|
@@ -240,6 +240,35 @@ describe("toProtoEvent", () => {
|
|
|
240
240
|
expect(evt.payload.value.taskKind).toBe(0);
|
|
241
241
|
});
|
|
242
242
|
|
|
243
|
+
it("maps inputSummary onto the payload Struct", () => {
|
|
244
|
+
const evt = toProtoEvent({
|
|
245
|
+
type: "task_started",
|
|
246
|
+
taskName: "seed_order",
|
|
247
|
+
occurredAt: NOW,
|
|
248
|
+
taskKind: "set",
|
|
249
|
+
attemptNumber: 1,
|
|
250
|
+
inputSummary: { variables: { order_id: "ORD-1" } },
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
if (evt.payload.case !== "taskStarted") throw new Error("unexpected");
|
|
254
|
+
expect(evt.payload.value.inputSummary).toEqual({
|
|
255
|
+
variables: { order_id: "ORD-1" },
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it("leaves inputSummary unset when the descriptor omits it", () => {
|
|
260
|
+
const evt = toProtoEvent({
|
|
261
|
+
type: "task_started",
|
|
262
|
+
taskName: "t",
|
|
263
|
+
occurredAt: NOW,
|
|
264
|
+
taskKind: "set",
|
|
265
|
+
attemptNumber: 1,
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
if (evt.payload.case !== "taskStarted") throw new Error("unexpected");
|
|
269
|
+
expect(evt.payload.value.inputSummary).toBeUndefined();
|
|
270
|
+
});
|
|
271
|
+
|
|
243
272
|
it("maps call:agent to proto agent_call (13), not http_call (2)", () => {
|
|
244
273
|
const evt = toProtoEvent({
|
|
245
274
|
type: "task_started",
|
|
@@ -352,6 +381,37 @@ describe("toProtoEvent", () => {
|
|
|
352
381
|
expect(evt.payload.value.costMicros).toBe(BigInt(100000));
|
|
353
382
|
expect(evt.payload.value.tokensUsed).toBe(BigInt(800));
|
|
354
383
|
});
|
|
384
|
+
|
|
385
|
+
it("maps outputSummary onto the payload Struct", () => {
|
|
386
|
+
const evt = toProtoEvent({
|
|
387
|
+
type: "task_completed",
|
|
388
|
+
taskName: "total_order",
|
|
389
|
+
occurredAt: NOW,
|
|
390
|
+
taskKind: "call:function:transform",
|
|
391
|
+
durationMs: 160,
|
|
392
|
+
costMicros: 0,
|
|
393
|
+
tokensUsed: 0,
|
|
394
|
+
outputSummary: { total: 150, line_count: 2 },
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
if (evt.payload.case !== "taskCompleted") throw new Error("unexpected");
|
|
398
|
+
expect(evt.payload.value.outputSummary).toEqual({ total: 150, line_count: 2 });
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
it("leaves outputSummary unset when the descriptor omits it", () => {
|
|
402
|
+
const evt = toProtoEvent({
|
|
403
|
+
type: "task_completed",
|
|
404
|
+
taskName: "t",
|
|
405
|
+
occurredAt: NOW,
|
|
406
|
+
taskKind: "set",
|
|
407
|
+
durationMs: 1,
|
|
408
|
+
costMicros: 0,
|
|
409
|
+
tokensUsed: 0,
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
if (evt.payload.case !== "taskCompleted") throw new Error("unexpected");
|
|
413
|
+
expect(evt.payload.value.outputSummary).toBeUndefined();
|
|
414
|
+
});
|
|
355
415
|
});
|
|
356
416
|
|
|
357
417
|
describe("task_failed", () => {
|
|
@@ -499,6 +559,35 @@ describe("toProtoEvent", () => {
|
|
|
499
559
|
expect(p.resolvedBy).toBe("alice");
|
|
500
560
|
expect(p.comment).toBe("LGTM");
|
|
501
561
|
expect(p.waitDurationMs).toBe(BigInt(45000));
|
|
562
|
+
// No actor on the descriptor — the proto field stays unset (no synthesis).
|
|
563
|
+
expect(p.resolvedByActor).toBeUndefined();
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
it("maps resolvedByActor display snapshot when stamped", () => {
|
|
567
|
+
const evt = toProtoEvent({
|
|
568
|
+
type: "approval_resolved",
|
|
569
|
+
taskName: "reviewGate",
|
|
570
|
+
occurredAt: NOW,
|
|
571
|
+
outcome: "approve",
|
|
572
|
+
resolvedBy: "ida_01abc",
|
|
573
|
+
resolvedByActor: {
|
|
574
|
+
id: "ida_01abc",
|
|
575
|
+
display_name: "Ada Lovelace",
|
|
576
|
+
email: "ada@example.com",
|
|
577
|
+
avatar: "https://example.com/ada.png",
|
|
578
|
+
},
|
|
579
|
+
comment: "",
|
|
580
|
+
waitDurationMs: 100,
|
|
581
|
+
autoResolved: false,
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
if (evt.payload.case !== "approvalResolved") throw new Error("unexpected");
|
|
585
|
+
const actor = evt.payload.value.resolvedByActor;
|
|
586
|
+
expect(actor).toBeDefined();
|
|
587
|
+
expect(actor!.id).toBe("ida_01abc");
|
|
588
|
+
expect(actor!.displayName).toBe("Ada Lovelace");
|
|
589
|
+
expect(actor!.email).toBe("ada@example.com");
|
|
590
|
+
expect(actor!.avatar).toBe("https://example.com/ada.png");
|
|
502
591
|
});
|
|
503
592
|
|
|
504
593
|
it("does not map outcome or autoResolved (proto limitation)", () => {
|
|
@@ -14,7 +14,11 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { ApplicationFailure } from "@temporalio/activity";
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
evaluateExpression,
|
|
19
|
+
isStrictExpr,
|
|
20
|
+
sanitizeExpr,
|
|
21
|
+
} from "../workflow-engine/expression.js";
|
|
18
22
|
|
|
19
23
|
export interface TransformConfig {
|
|
20
24
|
readonly engine: string;
|
|
@@ -38,6 +42,13 @@ export async function transformAction(
|
|
|
38
42
|
"TRANSFORM_MISSING_EXPRESSION",
|
|
39
43
|
);
|
|
40
44
|
}
|
|
45
|
+
if (typeof config.expression !== "string") {
|
|
46
|
+
throw ApplicationFailure.nonRetryable(
|
|
47
|
+
`transform: 'expression' must be a jq string, got ${typeof config.expression}. ` +
|
|
48
|
+
"Fix the expression in the workflow's transform task_config.",
|
|
49
|
+
"TRANSFORM_INVALID_EXPRESSION",
|
|
50
|
+
);
|
|
51
|
+
}
|
|
41
52
|
|
|
42
53
|
const engine = normalizeEngine(config.engine || "JQ");
|
|
43
54
|
|
|
@@ -50,5 +61,12 @@ export async function transformAction(
|
|
|
50
61
|
|
|
51
62
|
const data = config.input !== undefined ? config.input : taskInput;
|
|
52
63
|
|
|
53
|
-
|
|
64
|
+
// The expression arrives unresolved (deferred code — see the
|
|
65
|
+
// call-function builder). Accept both the strict `${ ... }` wrapper
|
|
66
|
+
// and the bare jq form the converter emits.
|
|
67
|
+
const expression = isStrictExpr(config.expression)
|
|
68
|
+
? sanitizeExpr(config.expression)
|
|
69
|
+
: config.expression;
|
|
70
|
+
|
|
71
|
+
return evaluateExpression(expression, data, {});
|
|
54
72
|
}
|
|
@@ -18,7 +18,11 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import { ApplicationFailure } from "@temporalio/activity";
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
evaluateExpression,
|
|
23
|
+
isStrictExpr,
|
|
24
|
+
sanitizeExpr,
|
|
25
|
+
} from "../workflow-engine/expression.js";
|
|
22
26
|
|
|
23
27
|
export interface ValidateConfig {
|
|
24
28
|
readonly input: unknown;
|
|
@@ -160,7 +164,28 @@ async function validateRules(
|
|
|
160
164
|
const errors: ValidationError[] = [];
|
|
161
165
|
|
|
162
166
|
for (const rule of rules) {
|
|
163
|
-
|
|
167
|
+
// Config guard: the expression must be a jq string. Anything else is
|
|
168
|
+
// a workflow-definition defect (or an upstream resolution bug) — name
|
|
169
|
+
// the rule and what to fix instead of crashing in the jq engine.
|
|
170
|
+
if (typeof rule.expression !== "string" || rule.expression.length === 0) {
|
|
171
|
+
errors.push({
|
|
172
|
+
rule: rule.name,
|
|
173
|
+
message:
|
|
174
|
+
`Rule '${rule.name}' has an invalid 'expression': expected a jq ` +
|
|
175
|
+
`predicate string, got ${typeof rule.expression}. Fix the rule in ` +
|
|
176
|
+
`the workflow's validate task_config.`,
|
|
177
|
+
});
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Rule expressions arrive unresolved (deferred code — see the
|
|
182
|
+
// call-function builder). Accept both the strict `${ ... }` wrapper
|
|
183
|
+
// and a bare jq predicate.
|
|
184
|
+
const expr = isStrictExpr(rule.expression)
|
|
185
|
+
? sanitizeExpr(rule.expression)
|
|
186
|
+
: rule.expression;
|
|
187
|
+
|
|
188
|
+
const result = await evaluateExpression(expr, data, {});
|
|
164
189
|
if (!result) {
|
|
165
190
|
errors.push({
|
|
166
191
|
rule: rule.name,
|
|
@@ -25,6 +25,7 @@ import { StigmerClient } from "../client/stigmer-client.js";
|
|
|
25
25
|
import { mcpServerToResolved } from "../shared/mcp-resolver.js";
|
|
26
26
|
import { toMcpClientConfig } from "../shared/mcp-manager.js";
|
|
27
27
|
import { detectOAuthChallenge } from "../shared/mcp-oauth-detect.js";
|
|
28
|
+
import { withTimeout } from "../shared/with-timeout.js";
|
|
28
29
|
import type { McpServer } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
|
|
29
30
|
import type { Config } from "../config.js";
|
|
30
31
|
|
|
@@ -326,7 +327,12 @@ async function connectAndDiscover(
|
|
|
326
327
|
const resourceTemplates: DiscoveredResourceTemplateResult[] = [];
|
|
327
328
|
|
|
328
329
|
try {
|
|
329
|
-
|
|
330
|
+
const timeoutMessage =
|
|
331
|
+
`MCP server '${slug}' did not respond within ` +
|
|
332
|
+
`${Math.round(SESSION_INIT_TIMEOUT_MS / 1000)}s. If this server requires compilation or ` +
|
|
333
|
+
`package installation on first run (e.g. go run, npx), the cold ` +
|
|
334
|
+
`start may have exceeded the discovery timeout.`;
|
|
335
|
+
await withTimeout(SESSION_INIT_TIMEOUT_MS, timeoutMessage, async () => {
|
|
330
336
|
await client.initializeConnections();
|
|
331
337
|
|
|
332
338
|
const mcpClient = await client.getClient(slug);
|
|
@@ -411,33 +417,6 @@ async function classifyHttpOAuthFailure(
|
|
|
411
417
|
return detectOAuthChallenge(connection.url, connection.headers, slug);
|
|
412
418
|
}
|
|
413
419
|
|
|
414
|
-
async function withTimeout<T>(
|
|
415
|
-
ms: number,
|
|
416
|
-
serverSlug: string,
|
|
417
|
-
fn: () => Promise<T>,
|
|
418
|
-
): Promise<T> {
|
|
419
|
-
return new Promise<T>((resolve, reject) => {
|
|
420
|
-
const timer = setTimeout(() => {
|
|
421
|
-
reject(new Error(
|
|
422
|
-
`MCP server '${serverSlug}' did not respond within ` +
|
|
423
|
-
`${Math.round(ms / 1000)}s. If this server requires compilation or ` +
|
|
424
|
-
`package installation on first run (e.g. go run, npx), the cold ` +
|
|
425
|
-
`start may have exceeded the discovery timeout.`,
|
|
426
|
-
));
|
|
427
|
-
}, ms);
|
|
428
|
-
|
|
429
|
-
fn()
|
|
430
|
-
.then((result) => {
|
|
431
|
-
clearTimeout(timer);
|
|
432
|
-
resolve(result);
|
|
433
|
-
})
|
|
434
|
-
.catch((err) => {
|
|
435
|
-
clearTimeout(timer);
|
|
436
|
-
reject(err);
|
|
437
|
-
});
|
|
438
|
-
});
|
|
439
|
-
}
|
|
440
|
-
|
|
441
420
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
442
421
|
// Temporal Activity Factory
|
|
443
422
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -103,6 +103,11 @@ export interface CursorHookHarnessOptions {
|
|
|
103
103
|
* skips the git-tracked flow arm.
|
|
104
104
|
*/
|
|
105
105
|
gitWorkspace?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Unattended approval mode (DD-014): approval denies are recorded with the
|
|
108
|
+
* non-pausing "unattended" kind and the adapt-and-explain agent message.
|
|
109
|
+
*/
|
|
110
|
+
unattendedSkip?: boolean;
|
|
106
111
|
}
|
|
107
112
|
|
|
108
113
|
/**
|
|
@@ -164,6 +169,7 @@ export function setupCursorHookHarness(opts: CursorHookHarnessOptions = {}): Cur
|
|
|
164
169
|
opts.captureMode ?? false,
|
|
165
170
|
opts.captureIgnored ?? false,
|
|
166
171
|
opts.gitWorkspace ?? true,
|
|
172
|
+
opts.unattendedSkip ?? false,
|
|
167
173
|
);
|
|
168
174
|
writeFileSync(statePath, JSON.stringify(state), "utf-8");
|
|
169
175
|
}
|