pi-crew 0.9.56 → 0.9.57
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/AGENTS.md +1 -1
- package/CHANGELOG.md +29 -0
- package/README.md +53 -5
- package/dist/index.mjs +5350 -4350
- package/docs/README.md +54 -0
- package/package.json +12 -12
- package/skills/real-test-pi-crew/SKILL.md +93 -3
- package/src/agents/discover-agents.ts +68 -10
- package/src/benchmark/feedback-loop.ts +1 -1
- package/src/config/config.ts +2 -1
- package/src/config/types.ts +12 -0
- package/src/extension/action-suggestions.ts +16 -63
- package/src/extension/async-notifier.ts +3 -3
- package/src/extension/command-completions.ts +2 -2
- package/src/extension/crew-cleanup.ts +3 -3
- package/src/extension/crew-vibes/footer.ts +4 -2
- package/src/extension/cross-extension-rpc.ts +10 -5
- package/src/extension/knowledge-injection.ts +57 -10
- package/src/extension/register.ts +2 -2
- package/src/extension/registration/artifact-cleanup.ts +41 -3
- package/src/extension/registration/commands.ts +4 -4
- package/src/extension/registration/context-builder.ts +10 -10
- package/src/extension/registration/crash-recovery-cache.ts +3 -3
- package/src/extension/registration/foreground-run-controller.ts +1 -1
- package/src/extension/registration/lazy-configurers.ts +2 -2
- package/src/extension/registration/lifecycle-handlers.ts +12 -12
- package/src/extension/registration/lifecycle.ts +2 -2
- package/src/extension/registration/observability.ts +2 -2
- package/src/extension/registration/registration-types.ts +3 -3
- package/src/extension/registration/runtime-cleanup.ts +1 -1
- package/src/extension/registration/subagent-helpers.ts +2 -2
- package/src/extension/registration/subagent-manager-setup.ts +2 -2
- package/src/extension/registration/subagent-tools.ts +21 -16
- package/src/extension/registration/team-tool.ts +108 -17
- package/src/extension/registration/viewers.ts +3 -4
- package/src/extension/registration/wire-cross-extension.ts +7 -7
- package/src/extension/rpc-hmac.ts +3 -2
- package/src/extension/run-bundle-schema.ts +13 -4
- package/src/extension/run-export.ts +2 -2
- package/src/extension/run-index.ts +2 -3
- package/src/extension/run-maintenance.ts +57 -1
- package/src/extension/team-manager-command.ts +3 -1
- package/src/extension/team-tool/anchor.ts +8 -2
- package/src/extension/team-tool/api.ts +117 -39
- package/src/extension/team-tool/cancel.ts +23 -8
- package/src/extension/team-tool/chain-executor.ts +1 -1
- package/src/extension/team-tool/dispatch/automate.ts +17 -2
- package/src/extension/team-tool/dispatch/control.ts +17 -2
- package/src/extension/team-tool/dispatch/manage.ts +34 -2
- package/src/extension/team-tool/dispatch/run.ts +17 -2
- package/src/extension/team-tool/dispatch/status.ts +37 -5
- package/src/extension/team-tool/doctor.ts +2 -2
- package/src/extension/team-tool/explain.ts +1 -1
- package/src/extension/team-tool/goal-wrap.ts +5 -5
- package/src/extension/team-tool/goal.ts +30 -9
- package/src/extension/team-tool/handle-schedule.ts +37 -19
- package/src/extension/team-tool/inspect.ts +21 -5
- package/src/extension/team-tool/lifecycle-actions.ts +53 -10
- package/src/extension/team-tool/parallel-dispatch.ts +14 -5
- package/src/extension/team-tool/param-error.ts +24 -0
- package/src/extension/team-tool/respond.ts +20 -6
- package/src/extension/team-tool/run.ts +27 -17
- package/src/extension/team-tool/status.ts +11 -5
- package/src/extension/team-tool.ts +26 -19
- package/src/hooks/registry.ts +1 -1
- package/src/i18n.ts +22 -0
- package/src/observability/event-bus.ts +1 -1
- package/src/prompt/prompt-runtime.ts +2 -2
- package/src/runtime/README.md +35 -0
- package/src/runtime/agent-control.ts +1 -1
- package/src/runtime/anchor-manager.ts +0 -2
- package/src/runtime/async-runner.ts +1 -1
- package/src/runtime/attention-events.ts +1 -1
- package/src/runtime/auto-summarize.ts +0 -2
- package/src/runtime/background-runner.ts +103 -30
- package/src/runtime/{crew-broker-child.ts → broker/crew-broker-child.ts} +2 -2
- package/src/runtime/{crew-broker-client.ts → broker/crew-broker-client.ts} +4 -7
- package/src/runtime/{crew-broker.ts → broker/crew-broker.ts} +13 -21
- package/src/runtime/chain-runner.ts +50 -5
- package/src/runtime/{child-pi-constants.ts → child-pi/child-pi-constants.ts} +1 -1
- package/src/runtime/{child-pi-kill.ts → child-pi/child-pi-kill.ts} +3 -3
- package/src/runtime/{child-pi-spawn.ts → child-pi/child-pi-spawn.ts} +28 -12
- package/src/runtime/{child-pi-steering.ts → child-pi/child-pi-steering.ts} +1 -1
- package/src/runtime/{child-pi-streams.ts → child-pi/child-pi-streams.ts} +11 -4
- package/src/runtime/{child-pi-transcript.ts → child-pi/child-pi-transcript.ts} +6 -6
- package/src/runtime/{child-pi.ts → child-pi/child-pi.ts} +28 -72
- package/src/runtime/{compact-stages → compaction/compact-stages}/bounded-tail.ts +1 -1
- package/src/runtime/{compact-stages → compaction/compact-stages}/index.ts +2 -2
- package/src/runtime/{compaction-summary.ts → compaction/compaction-summary.ts} +3 -3
- package/src/runtime/{tool-output-pruner.ts → compaction/tool-output-pruner.ts} +1 -1
- package/src/runtime/custom-tools/irc-tool.ts +2 -2
- package/src/runtime/delivery-coordinator.ts +0 -3
- package/src/runtime/diagnostic-export.ts +3 -3
- package/src/runtime/foreground-control.ts +1 -1
- package/src/runtime/foreground-watchdog.ts +1 -1
- package/src/runtime/{adaptive-plan.ts → goal-workflow/adaptive-plan.ts} +8 -8
- package/src/runtime/{dynamic-workflow-context.ts → goal-workflow/dynamic-workflow-context.ts} +16 -16
- package/src/runtime/{dynamic-workflow-runner.ts → goal-workflow/dynamic-workflow-runner.ts} +10 -10
- package/src/runtime/{goal-achievement.ts → goal-workflow/goal-achievement.ts} +3 -3
- package/src/runtime/{goal-evaluator.ts → goal-workflow/goal-evaluator.ts} +8 -8
- package/src/runtime/{goal-loop-runner.ts → goal-workflow/goal-loop-runner.ts} +27 -25
- package/src/runtime/{goal-state-store.ts → goal-workflow/goal-state-store.ts} +8 -8
- package/src/runtime/{plan-templates.ts → goal-workflow/plan-templates.ts} +1 -1
- package/src/runtime/group-join.ts +3 -3
- package/src/runtime/handoff-manager.ts +0 -2
- package/src/runtime/{heartbeat-watcher.ts → heartbeat/heartbeat-watcher.ts} +7 -7
- package/src/runtime/iteration-hooks.ts +1 -1
- package/src/runtime/{live-agent-control.ts → live-session/live-agent-control.ts} +2 -2
- package/src/runtime/{live-agent-manager.ts → live-session/live-agent-manager.ts} +4 -4
- package/src/runtime/{live-session-runtime.ts → live-session/live-session-runtime.ts} +39 -41
- package/src/runtime/manifest-cache.ts +1 -1
- package/src/runtime/{model-fallback.ts → model/model-fallback.ts} +1 -1
- package/src/runtime/{pi-args.ts → model/pi-args.ts} +20 -5
- package/src/runtime/model/provider-extensions.ts +116 -0
- package/src/runtime/{runtime-policy.ts → model/runtime-policy.ts} +2 -2
- package/src/runtime/{runtime-resolver.ts → model/runtime-resolver.ts} +3 -3
- package/src/runtime/{runtime-warmup.ts → model/runtime-warmup.ts} +8 -8
- package/src/runtime/orphan-worker-registry.ts +1 -1
- package/src/runtime/{progress-tracker.ts → output/progress-tracker.ts} +1 -1
- package/src/runtime/{result-extractor.ts → output/result-extractor.ts} +4 -4
- package/src/runtime/{sidechain-output.ts → output/sidechain-output.ts} +2 -2
- package/src/runtime/{stream-preview.ts → output/stream-preview.ts} +1 -1
- package/src/runtime/{streaming-output.ts → output/streaming-output.ts} +2 -2
- package/src/runtime/{tool-progress.ts → output/tool-progress.ts} +1 -1
- package/src/runtime/parent-guard.ts +30 -10
- package/src/runtime/pipeline-runner.ts +2 -2
- package/src/runtime/policy-engine.ts +2 -2
- package/src/runtime/{cancellation.ts → process/cancellation.ts} +1 -1
- package/src/runtime/{post-exit-stdio-guard.ts → process/post-exit-stdio-guard.ts} +1 -1
- package/src/runtime/{process-lifecycle.ts → process/process-lifecycle.ts} +3 -3
- package/src/runtime/{checkpoint.ts → recovery/checkpoint.ts} +4 -4
- package/src/runtime/{crash-recovery.ts → recovery/crash-recovery.ts} +93 -21
- package/src/runtime/{overflow-recovery.ts → recovery/overflow-recovery.ts} +1 -1
- package/src/runtime/{recovery-recipes.ts → recovery/recovery-recipes.ts} +1 -1
- package/src/runtime/{retry-executor.ts → recovery/retry-executor.ts} +2 -2
- package/src/runtime/{retry-runner.ts → recovery/retry-runner.ts} +2 -8
- package/src/runtime/run-tracker.ts +1 -1
- package/src/runtime/run-worker.ts +3 -3
- package/src/runtime/{coalesce-tasks.ts → scheduling/coalesce-tasks.ts} +3 -3
- package/src/runtime/{concurrency.ts → scheduling/concurrency.ts} +1 -1
- package/src/runtime/{parallel-research.ts → scheduling/parallel-research.ts} +4 -2
- package/src/runtime/{run-coalesced-task-group.ts → scheduling/run-coalesced-task-group.ts} +95 -36
- package/src/runtime/{task-graph-scheduler.ts → scheduling/task-graph-scheduler.ts} +1 -1
- package/src/runtime/session-resources.ts +1 -1
- package/src/runtime/settings-store.ts +1 -1
- package/src/runtime/single-agent-compose.ts +1 -0
- package/src/runtime/stale-reconciler.ts +1 -1
- package/src/runtime/subagent-manager.ts +1 -1
- package/src/runtime/supervisor-contact.ts +1 -1
- package/src/runtime/task-output-context.ts +7 -5
- package/src/runtime/task-runner/child-executor.ts +62 -22
- package/src/runtime/task-runner/live-executor.ts +8 -8
- package/src/runtime/task-runner/post-execution.ts +12 -12
- package/src/runtime/task-runner/pre-execution.ts +6 -6
- package/src/runtime/task-runner/progress.ts +1 -1
- package/src/runtime/task-runner/run-projection.ts +1 -1
- package/src/runtime/task-runner/scaffold-executor.ts +1 -1
- package/src/runtime/task-runner/state-helpers.ts +2 -2
- package/src/runtime/task-runner.ts +4 -4
- package/src/runtime/team-runner.ts +380 -139
- package/src/runtime/{completion-guard.ts → verification/completion-guard.ts} +1 -1
- package/src/runtime/{green-contract.ts → verification/green-contract.ts} +1 -1
- package/src/runtime/{post-checks.ts → verification/post-checks.ts} +4 -4
- package/src/runtime/{verification-gates.ts → verification/verification-gates.ts} +5 -5
- package/src/runtime/{verification-integrity.ts → verification/verification-integrity.ts} +1 -1
- package/src/schema/config-schema.ts +1 -0
- package/src/schema/team-tool-schema.ts +133 -177
- package/src/state/README.md +44 -0
- package/src/state/atomic-write.ts +24 -3
- package/src/state/{locks.ts → coordination/locks.ts} +118 -38
- package/src/state/{mailbox.ts → coordination/mailbox.ts} +14 -8
- package/src/state/{schedule.ts → coordination/schedule.ts} +3 -3
- package/src/state/{task-claims.ts → coordination/task-claims.ts} +1 -1
- package/src/state/decision-ledger.ts +1 -1
- package/src/state/{event-log-rotation.ts → event-log/event-log-rotation.ts} +161 -31
- package/src/state/{event-log.ts → event-log/event-log.ts} +38 -26
- package/src/state/{jsonl-writer.ts → event-log/jsonl-writer.ts} +14 -6
- package/src/state/hook-instinct-bridge.ts +2 -2
- package/src/state/{active-run-registry.ts → stores/active-run-registry.ts} +7 -7
- package/src/state/{artifact-store.ts → stores/artifact-store.ts} +62 -4
- package/src/state/{blob-store.ts → stores/blob-store.ts} +3 -3
- package/src/state/{health-store.ts → stores/health-store.ts} +3 -3
- package/src/state/{instinct-store.ts → stores/instinct-store.ts} +3 -3
- package/src/state/{observation-store.ts → stores/observation-store.ts} +2 -2
- package/src/state/{run-cache.ts → stores/run-cache.ts} +4 -4
- package/src/state/{run-graph.ts → stores/run-graph.ts} +4 -4
- package/src/state/{run-metrics.ts → stores/run-metrics.ts} +3 -3
- package/src/state/{state-store.ts → stores/state-store.ts} +236 -17
- package/src/state/types.ts +27 -3
- package/src/ui/component.ts +55 -0
- package/src/ui/crew-select-list.ts +3 -1
- package/src/ui/dashboard-panes/agents-pane.ts +1 -1
- package/src/ui/dwf-phase-display.ts +1 -1
- package/src/ui/heartbeat-aggregator.ts +1 -1
- package/src/ui/keybinding-map.ts +179 -6
- package/src/ui/layout-primitives.ts +9 -5
- package/src/ui/live-conversation-overlay.ts +1 -1
- package/src/ui/live-run-sidebar.ts +1 -1
- package/src/ui/overlay-stack.ts +148 -0
- package/src/ui/overlays/agent-picker-overlay.ts +1 -1
- package/src/ui/overlays/mailbox-compose-overlay.ts +1 -1
- package/src/ui/overlays/mailbox-detail-overlay.ts +2 -2
- package/src/ui/powerbar-publisher.ts +1 -1
- package/src/ui/render-scheduler.ts +1 -1
- package/src/ui/run-action-dispatcher.ts +3 -3
- package/src/ui/run-dashboard.ts +5 -33
- package/src/ui/run-event-bus.ts +3 -3
- package/src/ui/run-snapshot-cache.ts +37 -18
- package/src/ui/settings-overlay.ts +13 -21
- package/src/ui/snapshot-types.ts +1 -1
- package/src/ui/status-colors.ts +0 -2
- package/src/ui/terminal-status.ts +1 -1
- package/src/ui/theme-adapter.ts +33 -13
- package/src/ui/tool-renderers/index.ts +8 -0
- package/src/ui/transcript-viewer.ts +37 -13
- package/src/ui/widget/index.ts +32 -9
- package/src/ui/widget/widget-formatters.ts +62 -4
- package/src/ui/widget/widget-model.ts +2 -2
- package/src/ui/widget/widget-renderer.ts +1 -1
- package/src/utils/conflict-detect.ts +58 -5
- package/src/utils/ndjson.ts +2 -2
- package/src/utils/socket-path.ts +1 -1
- package/src/workflows/workflow-config.ts +1 -1
- package/src/worktree/cleanup.ts +1 -1
- package/src/worktree/worktree-manager.ts +88 -39
- package/workflows/chain.workflow.md +2 -2
- package/index.bundle.ts +0 -25
- package/scripts/bench-check.mjs +0 -96
- package/scripts/bench-cold-start.mjs +0 -216
- package/scripts/build-bundle.mjs +0 -92
- package/scripts/check-all-skills.ts +0 -294
- package/scripts/check-bundle-size.mjs +0 -38
- package/scripts/check-bundle-staleness.mjs +0 -97
- package/scripts/check-conflict-markers.mjs +0 -91
- package/scripts/check-lazy-imports.mjs +0 -28
- package/scripts/dev-runner.mjs +0 -106
- package/scripts/profile-startup.mjs +0 -125
- package/scripts/release-smoke.mjs +0 -74
- package/scripts/run-bench.mjs +0 -47
- package/scripts/run-real-chain.ts +0 -41
- package/scripts/smoke-team-perf.ts +0 -43
- package/scripts/test-issue-29-crash.ts +0 -111
- package/scripts/test-issue-29-e2e.ts +0 -183
- package/scripts/test-issue-29-real-runtime.ts +0 -330
- package/scripts/test-issue-29-real-tasks.ts +0 -387
- package/scripts/test-issue-29-team-tool.ts +0 -105
- package/scripts/test-runner.mjs +0 -84
- package/scripts/verify-flicker-fix.ts +0 -109
- package/scripts/verify-skill.ts +0 -550
- package/scripts/watch-bundle.mjs +0 -259
- package/scripts/watchdog-harness.ts +0 -119
- package/src/adapters/claude-adapter.ts +0 -23
- package/src/adapters/codex-adapter.ts +0 -21
- package/src/adapters/cursor-adapter.ts +0 -17
- package/src/adapters/export-util.ts +0 -143
- package/src/adapters/index.ts +0 -15
- package/src/adapters/registry.ts +0 -18
- package/src/adapters/types.ts +0 -23
- package/src/runtime/code-summary.ts +0 -292
- package/src/runtime/cross-extension-rpc.ts +0 -143
- package/src/runtime/hidden-handoff.ts +0 -407
- package/src/runtime/prose-compressor.ts +0 -162
- package/src/subagents/async-entry.ts +0 -1
- package/src/subagents/index.ts +0 -3
- package/src/subagents/live/control.ts +0 -1
- package/src/subagents/live/manager.ts +0 -1
- package/src/subagents/live/realtime.ts +0 -1
- package/src/subagents/live/session-runtime.ts +0 -1
- package/src/subagents/manager.ts +0 -1
- package/src/subagents/spawn.ts +0 -1
- package/test-integration-check.ts +0 -118
- /package/src/runtime/{broker-issuer.ts → broker/broker-issuer.ts} +0 -0
- /package/src/runtime/{crew-broker-tokens.ts → broker/crew-broker-tokens.ts} +0 -0
- /package/src/runtime/{child-pi-pool.ts → child-pi/child-pi-pool.ts} +0 -0
- /package/src/runtime/{compact-pipeline.ts → compaction/compact-pipeline.ts} +0 -0
- /package/src/runtime/{compact-stages → compaction/compact-stages}/ansi-strip-stage.ts +0 -0
- /package/src/runtime/{compact-stages → compaction/compact-stages}/blank-collapse-stage.ts +0 -0
- /package/src/runtime/{compact-stages → compaction/compact-stages}/deduplicate-stage.ts +0 -0
- /package/src/runtime/{compact-stages → compaction/compact-stages}/head-snap-stage.ts +0 -0
- /package/src/runtime/{compact-stages → compaction/compact-stages}/tail-capture-stage.ts +0 -0
- /package/src/runtime/{compact-stages → compaction/compact-stages}/truncation-stage.ts +0 -0
- /package/src/runtime/{important-line-classifier.ts → compaction/important-line-classifier.ts} +0 -0
- /package/src/runtime/{heartbeat-gradient.ts → heartbeat/heartbeat-gradient.ts} +0 -0
- /package/src/runtime/{worker-heartbeat.ts → heartbeat/worker-heartbeat.ts} +0 -0
- /package/src/runtime/{worker-startup.ts → heartbeat/worker-startup.ts} +0 -0
- /package/src/runtime/{intercom-bridge.ts → live-session/intercom-bridge.ts} +0 -0
- /package/src/runtime/{live-control-realtime.ts → live-session/live-control-realtime.ts} +0 -0
- /package/src/runtime/{live-extension-bridge.ts → live-session/live-extension-bridge.ts} +0 -0
- /package/src/runtime/{live-irc.ts → live-session/live-irc.ts} +0 -0
- /package/src/runtime/{live-session-health.ts → live-session/live-session-health.ts} +0 -0
- /package/src/runtime/{model-resolver.ts → model/model-resolver.ts} +0 -0
- /package/src/runtime/{model-scope.ts → model/model-scope.ts} +0 -0
- /package/src/runtime/{output-validator.ts → output/output-validator.ts} +0 -0
- /package/src/runtime/{pi-json-output.ts → output/pi-json-output.ts} +0 -0
- /package/src/runtime/{progress-event-coalescer.ts → output/progress-event-coalescer.ts} +0 -0
- /package/src/runtime/{cancellation-token.ts → process/cancellation-token.ts} +0 -0
- /package/src/runtime/{zombie-scanner.ts → process/zombie-scanner.ts} +0 -0
- /package/src/runtime/{crash-classification.ts → recovery/crash-classification.ts} +0 -0
- /package/src/runtime/{batch-barrier.ts → scheduling/batch-barrier.ts} +0 -0
- /package/src/runtime/{global-worker-cap.ts → scheduling/global-worker-cap.ts} +0 -0
- /package/src/runtime/{parallel-utils.ts → scheduling/parallel-utils.ts} +0 -0
- /package/src/runtime/{scheduler.ts → scheduling/scheduler.ts} +0 -0
- /package/src/runtime/{semaphore.ts → scheduling/semaphore.ts} +0 -0
- /package/src/runtime/{task-graph.ts → scheduling/task-graph.ts} +0 -0
- /package/src/runtime/{verification-worktree.ts → verification/verification-worktree.ts} +0 -0
- /package/src/state/{event-reconstructor.ts → event-log/event-reconstructor.ts} +0 -0
- /package/src/state/{worker-atomic-writer.ts → event-log/worker-atomic-writer.ts} +0 -0
|
@@ -23,8 +23,6 @@
|
|
|
23
23
|
|
|
24
24
|
import * as fsp from "node:fs/promises";
|
|
25
25
|
import * as net from "node:net";
|
|
26
|
-
|
|
27
|
-
import { readEventsCursor } from "../state/event-log.ts";
|
|
28
26
|
import {
|
|
29
27
|
appendMailboxMessageAsync,
|
|
30
28
|
type MailboxMessage,
|
|
@@ -32,14 +30,15 @@ import {
|
|
|
32
30
|
type MailboxMessagePriority,
|
|
33
31
|
readMailbox,
|
|
34
32
|
registerMailboxAppendObserver,
|
|
35
|
-
} from "
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
33
|
+
} from "../../state/coordination/mailbox.ts";
|
|
34
|
+
import { readEventsCursor } from "../../state/event-log/event-log.ts";
|
|
35
|
+
import { loadRunManifestById } from "../../state/stores/state-store.ts";
|
|
36
|
+
import { runEventBus } from "../../ui/run-event-bus.ts";
|
|
37
|
+
import { logInternalError } from "../../utils/internal-error.ts";
|
|
38
|
+
import { BrokerError, encodeBrokerFrame, MAX_BROKER_FRAME_BYTES, NdjsonDecoder } from "../../utils/ndjson.ts";
|
|
39
|
+
import { redactSecretString } from "../../utils/redaction.ts";
|
|
40
|
+
import { resolveRealContainedPath } from "../../utils/safe-paths.ts";
|
|
41
|
+
import { getBrokerSocketPath, prepareBrokerSocketDir, removeStaleBrokerSocket } from "../../utils/socket-path.ts";
|
|
43
42
|
import { BrokerTokenRegistry } from "./crew-broker-tokens.ts";
|
|
44
43
|
|
|
45
44
|
/** Protocol version negotiated at `hello` time. Bump on breaking change. */
|
|
@@ -103,7 +102,6 @@ export class CrewBroker {
|
|
|
103
102
|
private server: net.Server | null = null;
|
|
104
103
|
private resolvedSocketPath: string | null = null;
|
|
105
104
|
private stopped = false;
|
|
106
|
-
private starting = false;
|
|
107
105
|
private startingPromise: Promise<void> | null = null;
|
|
108
106
|
private readonly connections = new Set<ServerConnection>();
|
|
109
107
|
/** Connections indexed by runId for live message fanout (Phase 1.3). */
|
|
@@ -186,16 +184,10 @@ export class CrewBroker {
|
|
|
186
184
|
}
|
|
187
185
|
if (this.server) return Promise.resolve();
|
|
188
186
|
if (this.startingPromise) return this.startingPromise;
|
|
189
|
-
this.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
})
|
|
194
|
-
.catch((err) => {
|
|
195
|
-
this.starting = false;
|
|
196
|
-
this.startingPromise = null;
|
|
197
|
-
throw err;
|
|
198
|
-
});
|
|
187
|
+
this.startingPromise = this.doStart().catch((err) => {
|
|
188
|
+
this.startingPromise = null;
|
|
189
|
+
throw err;
|
|
190
|
+
});
|
|
199
191
|
return this.startingPromise;
|
|
200
192
|
}
|
|
201
193
|
|
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
* - Supports per-step overrides for model, skill, thinking
|
|
7
7
|
* - Accumulates handoffs between steps
|
|
8
8
|
* - Executes steps sequentially with context passing
|
|
9
|
-
*
|
|
10
|
-
* @see docs/pi-boomerang-integration-plan.md
|
|
11
9
|
*/
|
|
12
10
|
|
|
13
11
|
import { errorMessage } from "../utils/guards.ts";
|
|
@@ -148,7 +146,7 @@ export class ChainRunner {
|
|
|
148
146
|
}
|
|
149
147
|
}
|
|
150
148
|
|
|
151
|
-
const stepStrings =
|
|
149
|
+
const stepStrings = this.splitChainSteps(chainString).map((s) => s.trim());
|
|
152
150
|
|
|
153
151
|
const steps: ChainStep[] = stepStrings.map((step, index) => {
|
|
154
152
|
return this.parseStep(step, index);
|
|
@@ -236,8 +234,8 @@ export class ChainRunner {
|
|
|
236
234
|
|
|
237
235
|
// Emit progress event if eventsPath provided
|
|
238
236
|
if (eventsPath) {
|
|
239
|
-
// LAZY: defer dynamic import of ../state/event-log.ts to its call site.
|
|
240
|
-
const { appendEventAsync } = await import("../state/event-log.ts");
|
|
237
|
+
// LAZY: defer dynamic import of ../state/event-log/event-log.ts to its call site.
|
|
238
|
+
const { appendEventAsync } = await import("../state/event-log/event-log.ts");
|
|
241
239
|
await appendEventAsync(eventsPath, {
|
|
242
240
|
type: "chain.step_completed",
|
|
243
241
|
runId: "chain",
|
|
@@ -277,6 +275,53 @@ export class ChainRunner {
|
|
|
277
275
|
};
|
|
278
276
|
}
|
|
279
277
|
|
|
278
|
+
/**
|
|
279
|
+
* Split a chain string on top-level `->` arrows, ignoring arrows inside
|
|
280
|
+
* quotes. Prevents inline goals containing `->` (e.g. "Change A -> B")
|
|
281
|
+
* from being incorrectly split into separate steps.
|
|
282
|
+
*/
|
|
283
|
+
private splitChainSteps(chainString: string): string[] {
|
|
284
|
+
const parts: string[] = [];
|
|
285
|
+
let current = "";
|
|
286
|
+
let inQuote = false;
|
|
287
|
+
let quoteChar = "";
|
|
288
|
+
|
|
289
|
+
for (let i = 0; i < chainString.length; i++) {
|
|
290
|
+
const ch = chainString[i]!;
|
|
291
|
+
|
|
292
|
+
// Handle escape sequences inside quotes (e.g. \" or \')
|
|
293
|
+
if (inQuote && ch === "\\" && i + 1 < chainString.length) {
|
|
294
|
+
current += ch + (chainString[i + 1] ?? "");
|
|
295
|
+
i++;
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Toggle quote state on unescaped quote characters
|
|
300
|
+
if (ch === '"' || ch === "'") {
|
|
301
|
+
if (!inQuote) {
|
|
302
|
+
inQuote = true;
|
|
303
|
+
quoteChar = ch;
|
|
304
|
+
} else if (ch === quoteChar) {
|
|
305
|
+
inQuote = false;
|
|
306
|
+
}
|
|
307
|
+
current += ch;
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Split on -> only when not inside quotes
|
|
312
|
+
if (!inQuote && ch === "-" && chainString[i + 1] === ">") {
|
|
313
|
+
parts.push(current);
|
|
314
|
+
current = "";
|
|
315
|
+
i++; // skip the '>'
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
current += ch;
|
|
320
|
+
}
|
|
321
|
+
parts.push(current);
|
|
322
|
+
return parts;
|
|
323
|
+
}
|
|
324
|
+
|
|
280
325
|
/**
|
|
281
326
|
* Parse a single step from the chain string.
|
|
282
327
|
* Includes type safety checks for ChainStep parsing (H3).
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* and makes the timing budget configurable from one place.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { DEFAULT_CHILD_PI } from "
|
|
11
|
+
import { DEFAULT_CHILD_PI } from "../../config/defaults.ts";
|
|
12
12
|
|
|
13
13
|
/** Post-exit window during which stdio is guarded against late writes. */
|
|
14
14
|
export const POST_EXIT_STDIO_GUARD_MS = DEFAULT_CHILD_PI.postExitStdioGuardMs;
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
|
|
18
18
|
import type { ChildProcess } from "node:child_process";
|
|
19
19
|
import { spawn } from "node:child_process";
|
|
20
|
-
import { DEFAULT_CHILD_PI } from "
|
|
21
|
-
import { logInternalError } from "
|
|
20
|
+
import { DEFAULT_CHILD_PI } from "../../config/defaults.ts";
|
|
21
|
+
import { logInternalError } from "../../utils/internal-error.ts";
|
|
22
|
+
import { TailCaptureStage } from "../compaction/compact-stages/tail-capture-stage.ts";
|
|
22
23
|
import { HARD_KILL_MS } from "./child-pi-constants.ts";
|
|
23
|
-
import { TailCaptureStage } from "./compact-stages/tail-capture-stage.ts";
|
|
24
24
|
|
|
25
25
|
const MAX_CAPTURE_BYTES = DEFAULT_CHILD_PI.maxCaptureBytes;
|
|
26
26
|
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
import type { SpawnOptions } from "node:child_process";
|
|
20
20
|
import * as fs from "node:fs";
|
|
21
21
|
import * as path from "node:path";
|
|
22
|
-
import { WINDOWS_ESSENTIAL_ENV_VARS } from "
|
|
23
|
-
import { buildScopedAllowList, sanitizeEnvSecrets } from "
|
|
24
|
-
import { logInternalError } from "
|
|
22
|
+
import { WINDOWS_ESSENTIAL_ENV_VARS } from "../../utils/env-allowlist.ts";
|
|
23
|
+
import { buildScopedAllowList, sanitizeEnvSecrets } from "../../utils/env-filter.ts";
|
|
24
|
+
import { logInternalError } from "../../utils/internal-error.ts";
|
|
25
|
+
import { buildPiWorkerArgs } from "../model/pi-args.ts";
|
|
26
|
+
import { getPiSpawnCommand } from "../pi-spawn.ts";
|
|
25
27
|
import type { ChildPiRunInput, ChildPiRunResult } from "./child-pi.ts";
|
|
26
|
-
import { buildPiWorkerArgs } from "./pi-args.ts";
|
|
27
|
-
import { getPiSpawnCommand } from "./pi-spawn.ts";
|
|
28
28
|
|
|
29
29
|
// ── Env allowlist (base set always passed to children) ──────────────────
|
|
30
30
|
// Provider API keys are injected dynamically via buildScopedAllowList() only
|
|
@@ -68,7 +68,8 @@ export const BASE_ALLOWLIST: string[] = [
|
|
|
68
68
|
* 1. Validate cwd (realpath + isDirectory) — fall back to lexical path on ENOENT.
|
|
69
69
|
* 2. Filter env vars to the allowlist (model-aware provider key scoping).
|
|
70
70
|
* 3. Validate NODE_PATH against safe prefixes (/opt, /lib, /usr, /home).
|
|
71
|
-
* 4. Add PI_CREW_PARENT_PID for the child-side parent-guard
|
|
71
|
+
* 4. Add PI_CREW_PARENT_PID for the child-side parent-guard (currently UNUSED —
|
|
72
|
+
* see note at the PI_CREW_PARENT_PID assignment below).
|
|
72
73
|
*/
|
|
73
74
|
export function buildChildPiSpawnOptions(cwd: string, env: NodeJS.ProcessEnv, model?: string): SpawnOptions {
|
|
74
75
|
// SECURITY FIX (Issue #1): Validate cwd before passing to spawn.
|
|
@@ -131,17 +132,32 @@ export function buildChildPiSpawnOptions(cwd: string, env: NodeJS.ProcessEnv, mo
|
|
|
131
132
|
|
|
132
133
|
return {
|
|
133
134
|
cwd: validatedCwd,
|
|
134
|
-
env: {
|
|
135
|
+
env: {
|
|
136
|
+
...filteredEnv,
|
|
137
|
+
// PI_CREW_PARENT_PID is set so that child pi workers could theoretically
|
|
138
|
+
// run a parent-guard (parent-guard.ts). However, as of RT-19/RT-2, this
|
|
139
|
+
// env var has ZERO consumers: child workers are the external `pi` binary
|
|
140
|
+
// (@earendil-works/pi-coding-agent) which does NOT read
|
|
141
|
+
// PI_CREW_PARENT_PID or call startParentGuard (grep of Pi dist = 0 matches).
|
|
142
|
+
// The deeper fix (wiring startParentGuard into the pi worker entry point)
|
|
143
|
+
// is DEFERRED because workers are an external binary pi-crew doesn't control.
|
|
144
|
+
//
|
|
145
|
+
// Orphan-mitigation for this gap relies on:
|
|
146
|
+
// 1. The RT-2 SIGINT fix in background-runner.ts (abort + exitCode pattern
|
|
147
|
+
// lets the finally/runCleanup block terminate child-pi processes).
|
|
148
|
+
// 2. The reactive zombie-scanner.ts sweep (finds workers whose
|
|
149
|
+
// PI_CREW_PARENT_PID points at a dead PID).
|
|
150
|
+
PI_CREW_PARENT_PID: String(process.pid),
|
|
151
|
+
},
|
|
135
152
|
stdio: ["ignore", "pipe", "pipe"], // stdin=ignore: child doesn't wait for input; task comes via CLI args
|
|
136
153
|
detached: process.platform !== "win32",
|
|
137
154
|
setsid: true,
|
|
138
155
|
// NOTE: setsid creates a new session; the child process becomes the session leader
|
|
139
156
|
// and its parent becomes that session leader (still the team-runner in the same
|
|
140
|
-
// process group). PI_CREW_PARENT_PID is set before spawn using process.pid (team-runner)
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
// sees its direct parent (team-runner) as alive. This is correct for the parent-guard model.
|
|
157
|
+
// process group). PI_CREW_PARENT_PID is set before spawn using process.pid (team-runner),
|
|
158
|
+
// but see the comment above — child pi workers do NOT actually consume it. The
|
|
159
|
+
// parent-guard model would check direct parent liveness via process.kill(pid, 0),
|
|
160
|
+
// but this is only implemented in background-runner.ts, not in the worker binary.
|
|
145
161
|
windowsHide: true,
|
|
146
162
|
} as SpawnOptions;
|
|
147
163
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import * as fs from "node:fs";
|
|
16
|
-
import { logInternalError } from "
|
|
16
|
+
import { logInternalError } from "../../utils/internal-error.ts";
|
|
17
17
|
import { killProcessTree } from "./child-pi-kill.ts";
|
|
18
18
|
|
|
19
19
|
/** Action emitted by the controller when a `turn_end` event is processed. */
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
* child-pi-constants.ts (MAX_*_CHARS, MAX_LINE_BUFFER_BYTES).
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { logInternalError } from "
|
|
11
|
+
import { logInternalError } from "../../utils/internal-error.ts";
|
|
12
|
+
import { extractText } from "../output/pi-json-output.ts";
|
|
12
13
|
import type { ChildPiRunInput } from "./child-pi.ts";
|
|
13
14
|
import { MAX_ASSISTANT_TEXT_CHARS, MAX_LINE_BUFFER_BYTES, MAX_TOOL_INPUT_CHARS, MAX_TOOL_RESULT_CHARS } from "./child-pi-constants.ts";
|
|
14
15
|
import { appendTranscript, compactString, compactValue, flushPendingTranscriptWrites } from "./child-pi-transcript.ts";
|
|
15
|
-
import { extractText } from "./pi-json-output.ts";
|
|
16
16
|
|
|
17
17
|
function asRecord(value: unknown): Record<string, unknown> | undefined {
|
|
18
18
|
if (!value || typeof value !== "object" || Array.isArray(value)) return undefined;
|
|
@@ -199,9 +199,16 @@ export class ChildPiLineObserver {
|
|
|
199
199
|
new Error(`Line buffer exceeded ${MAX_LINE_BUFFER_BYTES} bytes; force-flushing`),
|
|
200
200
|
`bufferLen=${this.buffer.length}`,
|
|
201
201
|
);
|
|
202
|
-
|
|
202
|
+
// RT-9: split on newlines first so each complete \n-delimited JSON event
|
|
203
|
+
// is emitted as its own line. Previously the ENTIRE buffer was flushed
|
|
204
|
+
// as one "line", merging all events → JSON.parse failure → usage/turn/
|
|
205
|
+
// transcript events lost. Now only the trailing partial (no terminating
|
|
206
|
+
// newline) is force-flushed; complete lines keep per-line identity. When
|
|
207
|
+
// there are no newlines at all (the original RT-F8 single-huge-line case)
|
|
208
|
+
// split yields a single element and behavior is unchanged.
|
|
209
|
+
const overflowLines = this.buffer.split(/\r?\n/);
|
|
203
210
|
this.buffer = "";
|
|
204
|
-
this.emitLine(line);
|
|
211
|
+
for (const line of overflowLines) this.emitLine(line);
|
|
205
212
|
return;
|
|
206
213
|
}
|
|
207
214
|
const lines = this.buffer.split(/\r?\n/);
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import * as fs from "node:fs";
|
|
22
|
-
import { DEFAULT_CHILD_PI } from "
|
|
23
|
-
import { logInternalError } from "
|
|
24
|
-
import { redactJsonLine } from "
|
|
25
|
-
import { resolveRealContainedPath } from "
|
|
22
|
+
import { DEFAULT_CHILD_PI } from "../../config/defaults.ts";
|
|
23
|
+
import { logInternalError } from "../../utils/internal-error.ts";
|
|
24
|
+
import { redactJsonLine } from "../../utils/redaction.ts";
|
|
25
|
+
import { resolveRealContainedPath } from "../../utils/safe-paths.ts";
|
|
26
|
+
import { applyCompactPipeline } from "../compaction/compact-pipeline.ts";
|
|
27
|
+
import { TruncationStage } from "../compaction/compact-stages/truncation-stage.ts";
|
|
26
28
|
import type { ChildPiRunInput } from "./child-pi.ts";
|
|
27
|
-
import { applyCompactPipeline } from "./compact-pipeline.ts";
|
|
28
|
-
import { TruncationStage } from "./compact-stages/truncation-stage.ts";
|
|
29
29
|
|
|
30
30
|
// ── Transcript batch buffer (OPT-PHASE3) ────────────────────────────────
|
|
31
31
|
// Instead of open/write/close per line (3 syscalls × N), accumulate lines
|
|
@@ -2,21 +2,21 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as os from "node:os";
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
-
import type { AgentConfig } from "
|
|
6
|
-
import { DEFAULT_CHILD_PI } from "
|
|
7
|
-
import { registerChildProcess, unregisterChildProcess } from "
|
|
8
|
-
import { atomicWriteFile } from "
|
|
9
|
-
import type { WorkerExitStatus } from "
|
|
10
|
-
import { logInternalError } from "
|
|
11
|
-
import { redactSecretString } from "
|
|
12
|
-
import { getActiveBrokerIssuer } from "
|
|
5
|
+
import type { AgentConfig } from "../../agents/agent-config.ts";
|
|
6
|
+
import { DEFAULT_CHILD_PI } from "../../config/defaults.ts";
|
|
7
|
+
import { registerChildProcess, unregisterChildProcess } from "../../extension/crew-cleanup.ts";
|
|
8
|
+
import { atomicWriteFile } from "../../state/atomic-write.ts";
|
|
9
|
+
import type { WorkerExitStatus } from "../../state/types.ts";
|
|
10
|
+
import { logInternalError } from "../../utils/internal-error.ts";
|
|
11
|
+
import { redactSecretString } from "../../utils/redaction.ts";
|
|
12
|
+
import { getActiveBrokerIssuer } from "../broker/broker-issuer.ts";
|
|
13
|
+
import { BoundedTail } from "../compaction/compact-stages/bounded-tail.ts";
|
|
13
14
|
import { FINAL_DRAIN_MS, HARD_KILL_MS, POST_EXIT_STDIO_GUARD_MS, RESPONSE_TIMEOUT_MS } from "./child-pi-constants.ts";
|
|
14
15
|
import { clearHardKillTimer, killProcessTree, registerActiveChild, unregisterActiveChild } from "./child-pi-kill.ts";
|
|
15
16
|
import { buildFinalChildPiSpawnOptions, prepareSpawnContext } from "./child-pi-spawn.ts";
|
|
16
17
|
import { ChildPiSteeringController } from "./child-pi-steering.ts";
|
|
17
18
|
// Internal helpers for active-child bookkeeping (extracted to child-pi-kill.ts).
|
|
18
19
|
import { ChildPiLineObserver } from "./child-pi-streams.ts";
|
|
19
|
-
import { BoundedTail } from "./compact-stages/bounded-tail.ts";
|
|
20
20
|
|
|
21
21
|
// ── Re-exports from child-pi-kill.ts (H-7 decomposition step 2) ──
|
|
22
22
|
// killProcessTree is internal (not previously exported) — keep that invariant.
|
|
@@ -33,10 +33,9 @@ export { buildChildPiSpawnOptions, buildFinalChildPiSpawnOptions } from "./child
|
|
|
33
33
|
// ── Re-export from child-pi-streams.ts (H-7 decomposition step 4) ──
|
|
34
34
|
export { ChildPiLineObserver } from "./child-pi-streams.ts";
|
|
35
35
|
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
|
|
39
|
-
import { attachPostExitStdioGuard, trySignalChild } from "./post-exit-stdio-guard.ts";
|
|
36
|
+
import { checkCrewDepth, cleanupTempDir } from "../model/pi-args.ts";
|
|
37
|
+
import { attachPostExitStdioGuard, trySignalChild } from "../process/post-exit-stdio-guard.ts";
|
|
38
|
+
import { classifyProcessCrash } from "../recovery/crash-classification.ts";
|
|
40
39
|
|
|
41
40
|
/** Maximum size (bytes) for the ChildPiLineObserver's line accumulation buffer.
|
|
42
41
|
* When exceeded, the buffer is force-flushed to prevent unbounded memory growth
|
|
@@ -421,10 +420,15 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
|
|
|
421
420
|
pid: child.pid,
|
|
422
421
|
ts: new Date().toISOString(),
|
|
423
422
|
});
|
|
424
|
-
// Register with cleanup handler for graceful shutdown
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
423
|
+
// Register with cleanup handler for graceful shutdown (RT-11):
|
|
424
|
+
// ALWAYS register — every spawned child must be visible to host-SIGTERM
|
|
425
|
+
// cleanup. Use synthetic IDs when the caller omitted runId/agentId so the
|
|
426
|
+
// PID is still tracked for killProcessPid on session shutdown.
|
|
427
|
+
registerChildProcess(
|
|
428
|
+
child.pid,
|
|
429
|
+
input.runId ?? `untracked-run-${child.pid}`,
|
|
430
|
+
input.agentId ?? `untracked-agent-${child.pid}`,
|
|
431
|
+
);
|
|
428
432
|
} else {
|
|
429
433
|
input.onLifecycleEvent?.({
|
|
430
434
|
type: "spawn_error",
|
|
@@ -476,37 +480,6 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
|
|
|
476
480
|
let hardKilled = false;
|
|
477
481
|
const cleanupErrors: string[] = [];
|
|
478
482
|
const steeringController = new ChildPiSteeringController(input.maxTurns, input.graceTurns);
|
|
479
|
-
// Track in-flight operations for proper rejection on unexpected exit
|
|
480
|
-
interface PendingOperation {
|
|
481
|
-
id: string;
|
|
482
|
-
type: "prompt" | "steer" | "json_event";
|
|
483
|
-
startedAt: number;
|
|
484
|
-
}
|
|
485
|
-
const pendingOperations = new Map<string, PendingOperation>();
|
|
486
|
-
let operationIdCounter = 0;
|
|
487
|
-
|
|
488
|
-
const startOperation = (type: PendingOperation["type"]): string => {
|
|
489
|
-
const id = `op-${++operationIdCounter}`;
|
|
490
|
-
pendingOperations.set(id, { id, type, startedAt: Date.now() });
|
|
491
|
-
return id;
|
|
492
|
-
};
|
|
493
|
-
|
|
494
|
-
const completeOperation = (id: string): void => {
|
|
495
|
-
pendingOperations.delete(id);
|
|
496
|
-
};
|
|
497
|
-
|
|
498
|
-
const rejectPendingOperations = (error: Error): void => {
|
|
499
|
-
pendingOperations.forEach((op, id) => {
|
|
500
|
-
logInternalError(
|
|
501
|
-
"child-pi.pending-operation-rejected",
|
|
502
|
-
error,
|
|
503
|
-
`opId=${id} type=${op.type} elapsed=${Date.now() - op.startedAt}ms`,
|
|
504
|
-
);
|
|
505
|
-
});
|
|
506
|
-
pendingOperations.clear();
|
|
507
|
-
};
|
|
508
|
-
|
|
509
|
-
const steerInjectionFailed = false;
|
|
510
483
|
let abortDueToParentSignal = false;
|
|
511
484
|
// CP-1: track whether the turn-limit hard-abort has been initiated. Once
|
|
512
485
|
// true, we must NOT restart the no-response timer — the child is already
|
|
@@ -610,21 +583,14 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
|
|
|
610
583
|
},
|
|
611
584
|
onJsonEvent: (event) => {
|
|
612
585
|
if (!steeringController.isHardAbortInitiated()) restartNoResponseTimer();
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
if (
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
const action = steeringController.onTurnEnd(child.pid, child, input.steeringFile);
|
|
621
|
-
if (action.kind === "hardAbort") killProcessTree(action.pid, action.child);
|
|
622
|
-
}
|
|
586
|
+
// Turn-count-based steering: soft limit steer + hard abort after graceTurns
|
|
587
|
+
if (event && typeof event === "object" && !Array.isArray(event)) {
|
|
588
|
+
const obj = event as Record<string, unknown>;
|
|
589
|
+
if (obj.type === "turn_end") {
|
|
590
|
+
// H-7 step 5: steering state machine extracted to ChildPiSteeringController.
|
|
591
|
+
const action = steeringController.onTurnEnd(child.pid, child, input.steeringFile);
|
|
592
|
+
if (action.kind === "hardAbort") killProcessTree(action.pid, action.child);
|
|
623
593
|
}
|
|
624
|
-
completeOperation(eventOpId);
|
|
625
|
-
} catch (err) {
|
|
626
|
-
completeOperation(eventOpId);
|
|
627
|
-
throw err;
|
|
628
594
|
}
|
|
629
595
|
// F12: capture monotonic timestamp BEFORE dispatching — any stdout
|
|
630
596
|
// JSON event counts as activity. This lets the quiet-window
|
|
@@ -924,12 +890,10 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
|
|
|
924
890
|
// P0-1: snapshot the bounded accumulators once for this handler.
|
|
925
891
|
const stdout = stdoutTail.value();
|
|
926
892
|
const stderr = stderrTail.value();
|
|
927
|
-
// Reject pending operations with process error context
|
|
928
893
|
// SEC-1: redact stderr secrets embedded in the error message + excerpt.
|
|
929
894
|
const processError = new Error(
|
|
930
895
|
`Child Pi process error: ${error.message}. Stderr: ${redactStderrExcerpt(stderr, 500) || "(none)"}`,
|
|
931
896
|
);
|
|
932
|
-
rejectPendingOperations(processError);
|
|
933
897
|
try {
|
|
934
898
|
input.onLifecycleEvent?.({
|
|
935
899
|
type: "spawn_error",
|
|
@@ -985,9 +949,6 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
|
|
|
985
949
|
`Stderr: ${redactStderrExcerpt(stderr, 1000) || "(none)"}`,
|
|
986
950
|
)
|
|
987
951
|
: null;
|
|
988
|
-
if (exitError) {
|
|
989
|
-
rejectPendingOperations(exitError);
|
|
990
|
-
}
|
|
991
952
|
try {
|
|
992
953
|
// Phase-0 diagnostic (HB-003a): capture signal + drain timing in the
|
|
993
954
|
// exit lifecycle event so the exit-null race is diagnosable instead of
|
|
@@ -1072,10 +1033,6 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
|
|
|
1072
1033
|
steeringController.getTurnCount() >=
|
|
1073
1034
|
(steeringController.getMaxTurns() ?? 0) + (steeringController.getGraceTurns() ?? 5);
|
|
1074
1035
|
const wasParentAborted = abortDueToParentSignal && !wasGraceAborted;
|
|
1075
|
-
// steerInjectionFailed is now always false (Phase-1 fix: steer backpressure
|
|
1076
|
-
// is logged, not fatal). The steerError branch is retained for safety in
|
|
1077
|
-
// case a future change reintroduces a fatal steer path.
|
|
1078
|
-
const steerError = steerInjectionFailed ? "Steer injection failed due to stdin backpressure; process killed" : undefined;
|
|
1079
1036
|
// P0 crash taxonomy: classify the exit so callers/dashboards can bucket
|
|
1080
1037
|
// failure modes (timeout vs cancel vs native panic vs signal …).
|
|
1081
1038
|
// The classifier is a pure function; this is the single integration point.
|
|
@@ -1093,7 +1050,6 @@ export async function runChildPi(input: ChildPiRunInput): Promise<ChildPiRunResu
|
|
|
1093
1050
|
stdout,
|
|
1094
1051
|
stderr,
|
|
1095
1052
|
...(timeoutError ? { error: timeoutError.error } : {}),
|
|
1096
|
-
...(steerError ? { error: steerError } : {}),
|
|
1097
1053
|
aborted: wasGraceAborted || wasParentAborted,
|
|
1098
1054
|
steered: steeringController.isSoftLimitReached() && !wasGraceAborted,
|
|
1099
1055
|
exitStatus: {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* verbatim; over cap → `[pi-crew captured output truncated to last X KiB]\n` + the last
|
|
19
19
|
* ≤maxBytes bytes snapped to a UTF-8 char boundary.
|
|
20
20
|
*/
|
|
21
|
-
import { DEFAULT_CHILD_PI } from "
|
|
21
|
+
import { DEFAULT_CHILD_PI } from "../../../config/defaults.ts";
|
|
22
22
|
|
|
23
23
|
const DEFAULT_MAX_BYTES = DEFAULT_CHILD_PI.maxCaptureBytes;
|
|
24
24
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Barrel re-exports for the compact-stages module.
|
|
3
3
|
*
|
|
4
|
-
* Callers import from `../../runtime/compact-stages/index.ts` (or just
|
|
5
|
-
* `../../runtime/compact-stages/`) rather than reaching into individual
|
|
4
|
+
* Callers import from `../../runtime/compaction/compact-stages/index.ts` (or just
|
|
5
|
+
* `../../runtime/compaction/compact-stages/`) rather than reaching into individual
|
|
6
6
|
* stage files, so internal refactors do not break the public surface.
|
|
7
7
|
*/
|
|
8
8
|
export { ANSI_STRIP_STAGE, AnsiStripStage } from "./ansi-strip-stage.ts";
|
|
@@ -14,9 +14,9 @@ class GiantLineFallbackError extends Error {
|
|
|
14
14
|
|
|
15
15
|
import * as fs from "node:fs";
|
|
16
16
|
import * as path from "node:path";
|
|
17
|
-
import { readJsonFile } from "
|
|
18
|
-
import type { TeamEvent } from "
|
|
19
|
-
import type { TeamRunManifest, TeamTaskState } from "
|
|
17
|
+
import { readJsonFile } from "../../state/atomic-write.ts";
|
|
18
|
+
import type { TeamEvent } from "../../state/event-log/event-log.ts";
|
|
19
|
+
import type { TeamRunManifest, TeamTaskState } from "../../state/types.ts";
|
|
20
20
|
|
|
21
21
|
/** Maximum number of events to read from the tail of events.jsonl. */
|
|
22
22
|
const MAX_TAIL_EVENTS = 100;
|
|
@@ -90,7 +90,7 @@ export interface PruneResult {
|
|
|
90
90
|
// Token estimation (rough char/4 heuristic, matching gajae-code)
|
|
91
91
|
// ---------------------------------------------------------------------------
|
|
92
92
|
|
|
93
|
-
import { countTokens } from "
|
|
93
|
+
import { countTokens } from "../../utils/token-counter.ts";
|
|
94
94
|
|
|
95
95
|
function estimateTokens(text: string): number {
|
|
96
96
|
return countTokens(text);
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
import { defineTool, type ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
16
16
|
import { type Static, Type } from "@sinclair/typebox";
|
|
17
|
-
import { broadcastIrcMessage, listLiveAgents, respondAsBackground, sendIrcMessage } from "../live-agent-manager.ts";
|
|
18
|
-
import type { IrcMessage } from "../live-irc.ts";
|
|
17
|
+
import { broadcastIrcMessage, listLiveAgents, respondAsBackground, sendIrcMessage } from "../live-session/live-agent-manager.ts";
|
|
18
|
+
import type { IrcMessage } from "../live-session/live-irc.ts";
|
|
19
19
|
|
|
20
20
|
const IrcParams = Type.Object({
|
|
21
21
|
op: Type.Union(
|
|
@@ -28,21 +28,18 @@ export class DeliveryCoordinator {
|
|
|
28
28
|
private readonly deps: DeliveryCoordinatorDeps;
|
|
29
29
|
private ttlTimer: ReturnType<typeof setInterval> | undefined;
|
|
30
30
|
private timerStarted = false;
|
|
31
|
-
private ownerSessionId: string | undefined = undefined;
|
|
32
31
|
|
|
33
32
|
constructor(deps: DeliveryCoordinatorDeps) {
|
|
34
33
|
this.deps = deps;
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
activate(sessionId: string): void {
|
|
38
|
-
this.ownerSessionId = sessionId;
|
|
39
37
|
this.active = true;
|
|
40
38
|
this.flushQueuedResults();
|
|
41
39
|
}
|
|
42
40
|
|
|
43
41
|
deactivate(): void {
|
|
44
42
|
this.active = false;
|
|
45
|
-
this.ownerSessionId = undefined;
|
|
46
43
|
this.generation += 1;
|
|
47
44
|
}
|
|
48
45
|
|
|
@@ -4,15 +4,15 @@ import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
|
4
4
|
import type { MetricRegistry } from "../observability/metric-registry.ts";
|
|
5
5
|
import type { MetricSnapshot } from "../observability/metrics-primitives.ts";
|
|
6
6
|
import { atomicWriteFile } from "../state/atomic-write.ts";
|
|
7
|
-
import type { TeamEvent } from "../state/event-log.ts";
|
|
8
|
-
import { loadRunManifestById } from "../state/state-store.ts";
|
|
7
|
+
import type { TeamEvent } from "../state/event-log/event-log.ts";
|
|
8
|
+
import { loadRunManifestById } from "../state/stores/state-store.ts";
|
|
9
9
|
import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
|
|
10
10
|
import { type HeartbeatSummary, summarizeHeartbeats } from "../ui/heartbeat-aggregator.ts";
|
|
11
11
|
import type { RunUiSnapshot } from "../ui/snapshot-types.ts";
|
|
12
12
|
import { readJsonlTail } from "../utils/incremental-reader.ts";
|
|
13
13
|
import { isSecretKey, redactSecrets } from "../utils/redaction.ts";
|
|
14
14
|
import { readCrewAgents } from "./crew-agent-records.ts";
|
|
15
|
-
import { buildRecoveryLedger, type RecoveryLedgerEntry } from "./recovery-recipes.ts";
|
|
15
|
+
import { buildRecoveryLedger, type RecoveryLedgerEntry } from "./recovery/recovery-recipes.ts";
|
|
16
16
|
|
|
17
17
|
export { isSecretKey, redactSecrets } from "../utils/redaction.ts";
|
|
18
18
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { atomicWriteFile } from "../state/atomic-write.ts";
|
|
4
|
-
import { appendEvent } from "../state/event-log.ts";
|
|
4
|
+
import { appendEvent } from "../state/event-log/event-log.ts";
|
|
5
5
|
import type { TeamRunManifest, TeamTaskState } from "../state/types.ts";
|
|
6
6
|
import { logInternalError } from "../utils/internal-error.ts";
|
|
7
7
|
import { sleepSync } from "../utils/sleep.ts";
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* 3. Cleans up after itself when the run completes or the session ends.
|
|
13
13
|
*/
|
|
14
14
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
15
|
-
import { loadRunManifestById } from "../state/state-store.ts";
|
|
15
|
+
import { loadRunManifestById } from "../state/stores/state-store.ts";
|
|
16
16
|
import { readCrewAgents } from "./crew-agent-records.ts";
|
|
17
17
|
import { isActiveRunStatus, isLikelyOrphanedActiveRun } from "./process-status.ts";
|
|
18
18
|
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
// `__test__parseAdaptivePlan` and `__test__repairAdaptivePlan` are re-exported
|
|
16
16
|
// from team-runner.ts so existing test imports keep working.
|
|
17
17
|
import * as fs from "node:fs";
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { saveRunManifestAsync } from "
|
|
21
|
-
import type { TeamRunManifest, TeamTaskState } from "
|
|
22
|
-
import type { TeamConfig } from "
|
|
23
|
-
import type { WorkflowConfig, WorkflowStep } from "
|
|
18
|
+
import { appendEventAsync, appendEventFireAndForget } from "../../state/event-log/event-log.ts";
|
|
19
|
+
import { writeArtifact } from "../../state/stores/artifact-store.ts";
|
|
20
|
+
import { saveRunManifestAsync } from "../../state/stores/state-store.ts";
|
|
21
|
+
import type { TeamRunManifest, TeamTaskState } from "../../state/types.ts";
|
|
22
|
+
import type { TeamConfig } from "../../teams/team-config.ts";
|
|
23
|
+
import type { WorkflowConfig, WorkflowStep } from "../../workflows/workflow-config.ts";
|
|
24
|
+
import { refreshTaskGraphQueues } from "../scheduling/task-graph-scheduler.ts";
|
|
24
25
|
import { getPlanTemplate, renderPlanTemplate } from "./plan-templates.ts";
|
|
25
|
-
import { refreshTaskGraphQueues } from "./task-graph-scheduler.ts";
|
|
26
26
|
|
|
27
27
|
export interface AdaptivePlanTask {
|
|
28
28
|
role: string;
|
|
@@ -557,7 +557,7 @@ export async function injectAdaptivePlanIfReady(input: InjectAdaptivePlanInput):
|
|
|
557
557
|
|
|
558
558
|
// Test compatibility: original team-runner.ts exposed these names. Keep
|
|
559
559
|
// matching exports here; team-runner.ts re-exports them so existing test
|
|
560
|
-
// imports (`import { __test__parseAdaptivePlan } from "
|
|
560
|
+
// imports (`import { __test__parseAdaptivePlan } from "../../../src/runtime/team-runner.ts"`)
|
|
561
561
|
// keep working without churn.
|
|
562
562
|
export const __test__parseAdaptivePlan = parseAdaptivePlan;
|
|
563
563
|
export const __test__repairAdaptivePlan = repairAdaptivePlan;
|