@the-open-engine/zeroshot 6.38.1 → 6.39.1
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 +6 -0
- package/cli/event-copy.js +8 -7
- package/cli/event-copy.ts +12 -0
- package/cli/index.js +67 -48
- package/cli/json-export.js +61 -64
- package/cli/json-export.ts +112 -0
- package/cli/message-formatter-utils.js +68 -56
- package/cli/message-formatter-utils.ts +121 -0
- package/cli/message-formatters-normal.js +124 -259
- package/cli/message-formatters-normal.ts +250 -0
- package/cli/message-formatters-watch.js +81 -84
- package/cli/message-formatters-watch.ts +189 -0
- package/lib/cluster/generated/protocol-schema.cjs +1 -1
- package/lib/cluster/generated/protocol-schema.mjs +1 -1
- package/lib/cluster/generated/protocol.d.cts +8 -0
- package/lib/cluster/generated/protocol.d.mts +8 -0
- package/lib/cluster/generated/protocol.d.ts +8 -0
- package/lib/clusters-registry.d.ts +23 -0
- package/lib/clusters-registry.js +17 -29
- package/lib/completion.d.ts +12 -0
- package/lib/completion.js +84 -94
- package/lib/compose-utils.d.ts +32 -0
- package/lib/compose-utils.js +57 -72
- package/lib/detached-startup.d.ts +84 -0
- package/lib/detached-startup.js +232 -302
- package/lib/docker-config.d.ts +43 -0
- package/lib/docker-config.js +150 -325
- package/lib/docker-env-auth.d.ts +17 -0
- package/lib/docker-env-auth.js +75 -0
- package/lib/git-remote-utils.d.ts +48 -0
- package/lib/git-remote-utils.js +147 -213
- package/lib/id-detector.d.ts +15 -0
- package/lib/id-detector.js +37 -41
- package/lib/path-check.d.ts +30 -0
- package/lib/path-check.js +42 -45
- package/lib/process-liveness.d.ts +16 -0
- package/lib/process-liveness.js +19 -12
- package/lib/provider-credential-path.d.ts +16 -0
- package/lib/provider-credential-path.js +31 -29
- package/lib/provider-defaults.d.ts +30 -0
- package/lib/provider-defaults.js +47 -42
- package/lib/provider-detection.d.ts +11 -0
- package/lib/provider-detection.js +91 -54
- package/lib/provider-names.d.ts +38 -0
- package/lib/provider-names.js +56 -64
- package/lib/repo-settings.d.ts +28 -0
- package/lib/repo-settings.js +83 -59
- package/lib/run-mode.d.ts +21 -0
- package/lib/run-mode.js +21 -20
- package/lib/run-plan.d.ts +28 -0
- package/lib/run-plan.js +17 -16
- package/lib/settings/claude-auth.d.ts +35 -0
- package/lib/settings/claude-auth.js +30 -47
- package/lib/settings-defaults.d.ts +20 -0
- package/lib/settings-defaults.js +149 -0
- package/lib/settings-error.d.ts +7 -0
- package/lib/settings-error.js +8 -0
- package/lib/settings-issue-providers.d.ts +10 -0
- package/lib/settings-issue-providers.js +12 -0
- package/lib/settings-models.d.ts +22 -0
- package/lib/settings-models.js +93 -0
- package/lib/settings-storage.d.ts +23 -0
- package/lib/settings-storage.js +205 -0
- package/lib/settings-validation.d.ts +7 -0
- package/lib/settings-validation.js +182 -0
- package/lib/settings.d.ts +29 -0
- package/lib/settings.js +41 -736
- package/lib/setup-apply-types.d.ts +66 -0
- package/lib/setup-apply-types.js +2 -0
- package/lib/setup-apply.d.ts +39 -0
- package/lib/setup-apply.js +267 -264
- package/lib/setup-journal.d.ts +41 -0
- package/lib/setup-journal.js +119 -76
- package/lib/setup-plan-types.d.ts +102 -0
- package/lib/setup-plan-types.js +2 -0
- package/lib/setup-plan.d.ts +30 -0
- package/lib/setup-plan.js +300 -324
- package/lib/setup-undo.d.ts +44 -0
- package/lib/setup-undo.js +61 -74
- package/lib/start-cluster-config.d.ts +26 -0
- package/lib/start-cluster-config.js +56 -0
- package/lib/start-cluster-environment.d.ts +41 -0
- package/lib/start-cluster-environment.js +134 -0
- package/lib/start-cluster-run-options.d.ts +54 -0
- package/lib/start-cluster-run-options.js +148 -0
- package/lib/start-cluster.d.ts +64 -0
- package/lib/start-cluster.js +98 -454
- package/lib/stream-json-parser.d.ts +17 -0
- package/lib/stream-json-parser.js +51 -52
- package/npm-shrinkwrap.json +6 -8
- package/package.json +14 -8
- package/scripts/postinstall.js +27 -0
- package/scripts/rust-distribution.js +36 -45
- package/src/agent/agent-command-proofs-context.js +35 -45
- package/src/agent/agent-command-proofs-context.ts +87 -0
- package/src/agent/agent-config-settings.js +19 -0
- package/src/agent/agent-config-settings.ts +41 -0
- package/src/agent/agent-config.js +122 -231
- package/src/agent/agent-config.ts +285 -0
- package/src/agent/agent-context-builder.js +38 -273
- package/src/agent/agent-context-builder.ts +51 -0
- package/src/agent/agent-context-environment-sections.js +105 -0
- package/src/agent/agent-context-environment-sections.ts +134 -0
- package/src/agent/agent-context-packs.js +165 -0
- package/src/agent/agent-context-packs.ts +296 -0
- package/src/agent/agent-context-prompt-sections.js +100 -0
- package/src/agent/agent-context-prompt-sections.ts +148 -0
- package/src/agent/agent-context-sections.js +25 -334
- package/src/agent/agent-context-sections.ts +36 -0
- package/src/agent/agent-context-sources.js +96 -149
- package/src/agent/agent-context-sources.ts +253 -0
- package/src/agent/agent-context-types.js +2 -0
- package/src/agent/agent-context-types.ts +132 -0
- package/src/agent/agent-context-validation-sections.js +73 -0
- package/src/agent/agent-context-validation-sections.ts +129 -0
- package/src/agent/agent-input-injector.js +99 -118
- package/src/agent/agent-input-injector.ts +195 -0
- package/src/agent/agent-liveness-poll.js +74 -78
- package/src/agent/agent-liveness-poll.ts +163 -0
- package/src/agent/agent-quality-gate-schema.js +77 -86
- package/src/agent/agent-quality-gate-schema.ts +135 -0
- package/src/agent/agent-quality-gates-context.js +44 -50
- package/src/agent/agent-quality-gates-context.ts +91 -0
- package/src/agent/agent-stuck-detector.js +171 -239
- package/src/agent/agent-stuck-detector.ts +288 -0
- package/src/agent/agent-trigger-evaluator.js +29 -46
- package/src/agent/agent-trigger-evaluator.ts +98 -0
- package/src/agent/context-metrics.js +110 -141
- package/src/agent/context-metrics.ts +261 -0
- package/src/agent/context-pack-builder.js +72 -358
- package/src/agent/context-pack-builder.ts +105 -0
- package/src/agent/context-pack-core.js +70 -0
- package/src/agent/context-pack-core.ts +96 -0
- package/src/agent/context-pack-selection.js +119 -0
- package/src/agent/context-pack-selection.ts +187 -0
- package/src/agent/context-pack-truncation.js +139 -0
- package/src/agent/context-pack-truncation.ts +208 -0
- package/src/agent/context-pack-types.js +2 -0
- package/src/agent/context-pack-types.ts +98 -0
- package/src/agent/context-replay-policy.js +30 -39
- package/src/agent/context-replay-policy.ts +71 -0
- package/src/agent/critical-agent-policy.js +6 -10
- package/src/agent/critical-agent-policy.ts +20 -0
- package/src/agent/guidance-queue.js +74 -87
- package/src/agent/guidance-queue.ts +166 -0
- package/src/agent/output-extraction-error-detail.js +45 -0
- package/src/agent/output-extraction-error-detail.ts +49 -0
- package/src/agent/output-extraction-failures.js +125 -0
- package/src/agent/output-extraction-failures.ts +149 -0
- package/src/agent/output-extraction-json.js +234 -0
- package/src/agent/output-extraction-json.ts +235 -0
- package/src/agent/output-extraction-pi.js +124 -0
- package/src/agent/output-extraction-pi.ts +137 -0
- package/src/agent/output-extraction-types.js +2 -0
- package/src/agent/output-extraction-types.ts +49 -0
- package/src/agent/output-extraction.js +17 -617
- package/src/agent/output-extraction.ts +30 -0
- package/src/agent/output-reformatter-errors.js +83 -0
- package/src/agent/output-reformatter-errors.ts +106 -0
- package/src/agent/output-reformatter-types.js +2 -0
- package/src/agent/output-reformatter-types.ts +86 -0
- package/src/agent/output-reformatter.js +140 -185
- package/src/agent/output-reformatter.ts +238 -0
- package/src/agent/pi-terminal-lifecycle-types.js +2 -0
- package/src/agent/pi-terminal-lifecycle-types.ts +41 -0
- package/src/agent/pi-terminal-lifecycle.js +186 -206
- package/src/agent/pi-terminal-lifecycle.ts +297 -0
- package/src/agent/provider-control-plane.js +22 -21
- package/src/agent/provider-control-plane.ts +52 -0
- package/src/agent/provider-terminal-failure-types.js +2 -0
- package/src/agent/provider-terminal-failure-types.ts +60 -0
- package/src/agent/provider-terminal-failure.js +194 -191
- package/src/agent/provider-terminal-failure.ts +262 -0
- package/src/agent/rate-limit-backoff.js +31 -74
- package/src/agent/rate-limit-backoff.ts +71 -0
- package/src/agent/schema-utils.js +85 -125
- package/src/agent/schema-utils.ts +148 -0
- package/src/agent/structured-output-error.js +34 -33
- package/src/agent/structured-output-error.ts +105 -0
- package/src/agent/validation-platform.js +27 -27
- package/src/agent/validation-platform.ts +49 -0
- package/src/agents/git-pusher-template.js +17 -34
- package/src/attach/attach-client.js +232 -405
- package/src/attach/attach-client.ts +300 -0
- package/src/attach/attach-server-cleanup.js +43 -0
- package/src/attach/attach-server-cleanup.ts +39 -0
- package/src/attach/attach-server-clients.js +117 -0
- package/src/attach/attach-server-clients.ts +122 -0
- package/src/attach/attach-server-events.js +38 -0
- package/src/attach/attach-server-events.ts +36 -0
- package/src/attach/attach-server-pty.js +45 -0
- package/src/attach/attach-server-pty.ts +64 -0
- package/src/attach/attach-server-runtime.js +73 -0
- package/src/attach/attach-server-runtime.ts +62 -0
- package/src/attach/attach-server-socket.js +28 -0
- package/src/attach/attach-server-socket.ts +23 -0
- package/src/attach/attach-server-types.js +2 -0
- package/src/attach/attach-server-types.ts +82 -0
- package/src/attach/attach-server.js +106 -523
- package/src/attach/attach-server.ts +158 -0
- package/src/attach/index.js +18 -35
- package/src/attach/index.ts +18 -0
- package/src/attach/protocol.js +95 -184
- package/src/attach/protocol.ts +181 -0
- package/src/attach/ring-buffer.js +76 -102
- package/src/attach/ring-buffer.ts +109 -0
- package/src/attach/send-input.js +64 -75
- package/src/attach/send-input.ts +94 -0
- package/src/attach/socket-discovery.js +164 -218
- package/src/attach/socket-discovery.ts +230 -0
- package/src/attach/socket-paths.js +42 -61
- package/src/attach/socket-paths.ts +81 -0
- package/src/claude-credentials.js +51 -54
- package/src/claude-credentials.ts +89 -0
- package/src/cluster/generated/protocol-schema.ts +1 -1
- package/src/cluster/generated/protocol.ts +2 -1
- package/src/command-proofs.js +110 -141
- package/src/command-proofs.ts +216 -0
- package/src/config-router.js +81 -73
- package/src/config-router.ts +131 -0
- package/src/copy-containment.js +191 -0
- package/src/copy-containment.ts +259 -0
- package/src/copy-worker.js +53 -30
- package/src/copy-worker.ts +88 -0
- package/src/darwin-keychain-boundary.js +80 -111
- package/src/darwin-keychain-boundary.ts +148 -0
- package/src/guidance-topics.js +4 -5
- package/src/guidance-topics.ts +10 -0
- package/src/input-helpers.js +33 -54
- package/src/input-helpers.ts +58 -0
- package/src/isolation-manager.js +59 -20
- package/src/ledger-sequence.js +45 -48
- package/src/ledger-sequence.ts +63 -0
- package/src/legacy-lib/clusters-registry.ts +40 -0
- package/src/legacy-lib/completion.ts +148 -0
- package/src/legacy-lib/compose-utils.ts +102 -0
- package/src/legacy-lib/detached-startup.ts +451 -0
- package/src/legacy-lib/docker-config.ts +282 -0
- package/src/legacy-lib/docker-env-auth.ts +116 -0
- package/src/legacy-lib/git-remote-utils.ts +244 -0
- package/src/legacy-lib/id-detector.ts +57 -0
- package/src/legacy-lib/js-yaml.d.ts +3 -0
- package/src/legacy-lib/omelette.d.ts +15 -0
- package/src/legacy-lib/path-check.ts +89 -0
- package/src/legacy-lib/process-liveness.ts +36 -0
- package/src/legacy-lib/provider-credential-path.ts +57 -0
- package/src/legacy-lib/provider-defaults.ts +114 -0
- package/src/legacy-lib/provider-detection.ts +67 -0
- package/src/legacy-lib/provider-names.ts +126 -0
- package/src/legacy-lib/repo-settings.ts +88 -0
- package/src/legacy-lib/run-mode.ts +58 -0
- package/src/legacy-lib/run-plan.ts +49 -0
- package/src/legacy-lib/settings/claude-auth.ts +80 -0
- package/src/legacy-lib/settings-defaults.ts +212 -0
- package/src/legacy-lib/settings-error.ts +8 -0
- package/src/legacy-lib/settings-issue-providers.ts +18 -0
- package/src/legacy-lib/settings-models.ts +124 -0
- package/src/legacy-lib/settings-storage.ts +277 -0
- package/src/legacy-lib/settings-validation.ts +220 -0
- package/src/legacy-lib/settings.ts +87 -0
- package/src/legacy-lib/setup-apply-types.ts +70 -0
- package/src/legacy-lib/setup-apply.ts +456 -0
- package/src/legacy-lib/setup-journal.ts +185 -0
- package/src/legacy-lib/setup-plan-types.ts +96 -0
- package/src/legacy-lib/setup-plan.ts +500 -0
- package/src/legacy-lib/setup-undo.ts +142 -0
- package/src/legacy-lib/start-cluster-config.ts +124 -0
- package/src/legacy-lib/start-cluster-environment.ts +166 -0
- package/src/legacy-lib/start-cluster-run-options.ts +281 -0
- package/src/legacy-lib/start-cluster.ts +237 -0
- package/src/legacy-lib/stream-json-parser.ts +88 -0
- package/src/message-buffer.js +55 -71
- package/src/message-buffer.ts +107 -0
- package/src/message-bus-bridge.js +92 -133
- package/src/message-bus-bridge.ts +149 -0
- package/src/name-generator-shared.js +220 -0
- package/src/name-generator-shared.ts +231 -0
- package/src/name-generator.js +8 -217
- package/src/name-generator.ts +27 -0
- package/src/omp-blob-root.js +83 -64
- package/src/omp-blob-root.ts +116 -0
- package/src/omp-config-overlay.js +65 -38
- package/src/omp-config-overlay.ts +110 -0
- package/src/omp-execution-fingerprint.js +38 -43
- package/src/omp-execution-fingerprint.ts +92 -0
- package/src/omp-session-limits.js +10 -15
- package/src/omp-session-limits.ts +53 -0
- package/src/omp-session-partition.js +2 -2
- package/src/omp-session-verifier.js +1 -1
- package/src/orchestrator.js +32 -7
- package/src/pr-body-template.js +71 -0
- package/src/providers/anthropic/index.js +3 -1
- package/src/providers/anthropic/index.ts +13 -0
- package/src/providers/capabilities.js +19 -27
- package/src/providers/capabilities.ts +44 -0
- package/src/providers/google/index.js +3 -1
- package/src/providers/google/index.ts +13 -0
- package/src/providers/openai/index.js +3 -1
- package/src/providers/openai/index.ts +13 -0
- package/src/providers/opencode/index.js +3 -1
- package/src/providers/opencode/index.ts +13 -0
- package/src/quality-gates.js +67 -127
- package/src/quality-gates.ts +149 -0
- package/src/repo-settings-access.js +40 -0
- package/src/repo-settings-access.ts +64 -0
- package/src/schemas/sub-cluster.js +127 -183
- package/src/schemas/sub-cluster.ts +238 -0
- package/src/state-snapshot-normalization.js +224 -0
- package/src/state-snapshot-normalization.ts +222 -0
- package/src/state-snapshot.js +192 -359
- package/src/state-snapshot.ts +291 -0
- package/src/state-snapshotter.js +118 -130
- package/src/state-snapshotter.ts +167 -0
- package/src/sub-cluster-wrapper.js +4 -13
- package/src/task-run-model-args.js +87 -124
- package/src/task-run-model-args.ts +204 -0
- package/src/task-runner.js +5 -25
- package/src/task-runner.ts +28 -0
- package/src/task-startup-error.js +73 -58
- package/src/task-startup-error.ts +126 -0
- package/src/template-validation/consensus-gate-contracts.js +2 -0
- package/src/template-validation/consensus-gate-contracts.ts +70 -0
- package/src/template-validation/consensus-gate-scenarios.js +76 -0
- package/src/template-validation/consensus-gate-scenarios.ts +130 -0
- package/src/template-validation/consensus-gate-stage.js +34 -0
- package/src/template-validation/consensus-gate-stage.ts +56 -0
- package/src/template-validation/random-topology-contracts.js +2 -0
- package/src/template-validation/random-topology-contracts.ts +54 -0
- package/src/template-validation/random-topology-dispatch.js +25 -0
- package/src/template-validation/random-topology-dispatch.ts +33 -0
- package/src/template-validation/random-topology-message-loop.js +53 -0
- package/src/template-validation/random-topology-message-loop.ts +73 -0
- package/src/template-validation/random-topology-operations.js +79 -0
- package/src/template-validation/random-topology-operations.ts +101 -0
- package/src/template-validation/random-topology-runtime.js +25 -0
- package/src/template-validation/random-topology-runtime.ts +43 -0
- package/src/template-validation/random-topology-scenario.js +52 -0
- package/src/template-validation/random-topology-scenario.ts +57 -0
- package/src/template-validation/random-topology-schema.js +159 -0
- package/src/template-validation/random-topology-schema.ts +190 -0
- package/src/template-validation/random-topology-state.js +28 -0
- package/src/template-validation/random-topology-state.ts +30 -0
- package/src/template-validation/random-topology-trigger-evaluation.js +45 -0
- package/src/template-validation/random-topology-trigger-evaluation.ts +65 -0
- package/src/template-validation/random-topology-trigger.js +75 -0
- package/src/template-validation/random-topology-trigger.ts +88 -0
- package/src/template-validation/report-formatter.js +40 -46
- package/src/template-validation/report-formatter.ts +101 -0
- package/src/template-validation/simulate-consensus-gates.js +111 -302
- package/src/template-validation/simulate-consensus-gates.ts +196 -0
- package/src/template-validation/simulate-random-topology.js +26 -519
- package/src/template-validation/simulate-random-topology.ts +57 -0
- package/src/template-validation/simulate-two-stage-validation.js +41 -265
- package/src/template-validation/simulate-two-stage-validation.ts +55 -0
- package/src/template-validation/simulation-agent-runtime.js +25 -0
- package/src/template-validation/simulation-agent-runtime.ts +40 -0
- package/src/template-validation/simulation-agent.js +29 -0
- package/src/template-validation/simulation-agent.ts +73 -0
- package/src/template-validation/simulation-runtime.js +34 -0
- package/src/template-validation/simulation-runtime.ts +72 -0
- package/src/template-validation/two-stage-contracts.js +2 -0
- package/src/template-validation/two-stage-contracts.ts +41 -0
- package/src/template-validation/two-stage-inputs.js +21 -0
- package/src/template-validation/two-stage-inputs.ts +29 -0
- package/src/template-validation/two-stage-results.js +30 -0
- package/src/template-validation/two-stage-results.ts +40 -0
- package/src/template-validation/two-stage-scenario.js +86 -0
- package/src/template-validation/two-stage-scenario.ts +120 -0
- package/src/worktree-claude-config.js +182 -220
- package/src/worktree-claude-config.ts +272 -0
- package/src/worktree-tooling-env.js +103 -125
- package/src/worktree-tooling-env.ts +142 -0
- package/task-lib/completion.js +2 -3
- package/task-lib/completion.ts +9 -0
- package/task-lib/config.js +1 -4
- package/task-lib/config.ts +11 -0
- package/task-lib/name-generator.js +4 -226
- package/task-lib/name-generator.ts +11 -0
- package/task-lib/omp-session-cleanup.js +1 -1
- package/task-lib/omp-storage-root.js +8 -12
- package/task-lib/omp-storage-root.ts +62 -0
- package/task-lib/process-termination.js +143 -166
- package/task-lib/process-termination.ts +268 -0
package/README.md
CHANGED
|
@@ -106,6 +106,7 @@ zeroshot run <input> # issue, URL, markdown file, or inline text
|
|
|
106
106
|
zeroshot run 123 --docker # container isolation
|
|
107
107
|
zeroshot run 123 --pr # worktree + pull request
|
|
108
108
|
zeroshot run 123 --ship # worktree + PR + merge after approval
|
|
109
|
+
zeroshot run 123 --pr --pr-body $'## Summary\n\nCustom text\n\n{{issue_reference}}'
|
|
109
110
|
zeroshot run 123 -d # background run
|
|
110
111
|
|
|
111
112
|
zeroshot list # tasks and clusters (--json)
|
|
@@ -120,6 +121,11 @@ zeroshot settings # effective settings
|
|
|
120
121
|
zeroshot agents list # available agents
|
|
121
122
|
```
|
|
122
123
|
|
|
124
|
+
`--pr-body` supplies a deterministic pull-request body for `--pr` and `--ship` runs. The
|
|
125
|
+
template supports `{{issue_number}}`, `{{issue_title}}`, and `{{issue_reference}}`; all three
|
|
126
|
+
expand to empty text for tasks without an issue, so manual runs never emit `Closes #unknown`.
|
|
127
|
+
The unrendered template is retained for detached and resumed runs.
|
|
128
|
+
|
|
123
129
|
</details>
|
|
124
130
|
|
|
125
131
|
<details>
|
package/cli/event-copy.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
const EVENT_COPY = {
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
IMPLEMENTATION_READY: 'Implementation ready',
|
|
4
|
+
PR_CREATED: 'Pull request created',
|
|
4
5
|
};
|
|
5
|
-
|
|
6
6
|
function formatMergeStatus(merged) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
if (merged === true || merged === 'true')
|
|
8
|
+
return 'merged';
|
|
9
|
+
if (merged === false || merged === 'false')
|
|
10
|
+
return 'auto-merge pending approval';
|
|
11
|
+
return null;
|
|
10
12
|
}
|
|
11
|
-
|
|
12
13
|
module.exports = { EVENT_COPY, formatMergeStatus };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const EVENT_COPY = {
|
|
2
|
+
IMPLEMENTATION_READY: 'Implementation ready',
|
|
3
|
+
PR_CREATED: 'Pull request created',
|
|
4
|
+
} as const;
|
|
5
|
+
|
|
6
|
+
function formatMergeStatus(merged: unknown): string | null {
|
|
7
|
+
if (merged === true || merged === 'true') return 'merged';
|
|
8
|
+
if (merged === false || merged === 'false') return 'auto-merge pending approval';
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export = { EVENT_COPY, formatMergeStatus };
|
package/cli/index.js
CHANGED
|
@@ -35,7 +35,12 @@ const {
|
|
|
35
35
|
formatClusterFailed,
|
|
36
36
|
formatGenericMessage,
|
|
37
37
|
} = require('./message-formatters-normal');
|
|
38
|
-
const {
|
|
38
|
+
const {
|
|
39
|
+
getColorForSender,
|
|
40
|
+
buildMessagePrefix,
|
|
41
|
+
formatLifecycleEvent,
|
|
42
|
+
partitionValidationCriteria,
|
|
43
|
+
} = require('./message-formatter-utils');
|
|
39
44
|
const {
|
|
40
45
|
loadSettings,
|
|
41
46
|
mutateSettings,
|
|
@@ -102,6 +107,8 @@ const {
|
|
|
102
107
|
runLegacyUpdateIfRequested,
|
|
103
108
|
} = require('./lib/update-checker');
|
|
104
109
|
const { checkBinDirOnPath, printPathWarning } = require('../lib/path-check');
|
|
110
|
+
const { quoteShellArgument } = require('../lib/git-remote-utils');
|
|
111
|
+
const { renderPullRequestBody, resolveIssueContext } = require('../src/pr-body-template');
|
|
105
112
|
const { StatusFooter, AGENT_STATE, ACTIVE_STATES } = require('../src/status-footer');
|
|
106
113
|
const { EVENT_COPY, formatMergeStatus } = require('./event-copy');
|
|
107
114
|
|
|
@@ -2007,9 +2014,25 @@ function buildContextSummary({
|
|
|
2007
2014
|
return contextSummary;
|
|
2008
2015
|
}
|
|
2009
2016
|
|
|
2010
|
-
function
|
|
2011
|
-
const
|
|
2012
|
-
|
|
2017
|
+
function buildDefaultFinishPrBody({ taskText, issueNumber, issueTitle }) {
|
|
2018
|
+
const issueReference = renderPullRequestBody(undefined, { issueNumber, issueTitle });
|
|
2019
|
+
return [
|
|
2020
|
+
issueReference,
|
|
2021
|
+
issueReference ? '' : null,
|
|
2022
|
+
'## Summary',
|
|
2023
|
+
`${String(taskText || 'Unknown task').slice(0, 200)}...`,
|
|
2024
|
+
'',
|
|
2025
|
+
'## Changes',
|
|
2026
|
+
'- Implementation complete',
|
|
2027
|
+
'- All validations addressed',
|
|
2028
|
+
'',
|
|
2029
|
+
'🤖 Generated with zeroshot finish',
|
|
2030
|
+
]
|
|
2031
|
+
.filter((line) => line !== null)
|
|
2032
|
+
.join('\n');
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
const FINISH_MERGE_STEP = `
|
|
2013
2036
|
8. MERGE THE PR - THIS IS MANDATORY:
|
|
2014
2037
|
\`\`\`bash
|
|
2015
2038
|
gh pr merge --merge --auto
|
|
@@ -2024,7 +2047,29 @@ function buildCompletionPrompt({ contextSummary, taskText, issueNumber, issueTit
|
|
|
2024
2047
|
|
|
2025
2048
|
REPEAT UNTIL MERGED. DO NOT GIVE UP.`;
|
|
2026
2049
|
|
|
2027
|
-
|
|
2050
|
+
function buildFinishCommandArguments({ taskText, issueNumber, issueTitle, prBody }) {
|
|
2051
|
+
const issueContext = resolveIssueContext({ issueNumber, issueTitle });
|
|
2052
|
+
const resolvedTitle = issueContext.issueTitle;
|
|
2053
|
+
const resolvedBody =
|
|
2054
|
+
typeof prBody === 'string'
|
|
2055
|
+
? renderPullRequestBody(prBody, { issueNumber, issueTitle: resolvedTitle })
|
|
2056
|
+
: buildDefaultFinishPrBody({ taskText, issueNumber, issueTitle: resolvedTitle });
|
|
2057
|
+
return {
|
|
2058
|
+
commitMessage: quoteShellArgument(resolvedTitle || 'feat: implement task'),
|
|
2059
|
+
branch: quoteShellArgument(
|
|
2060
|
+
issueContext.issueNumber !== 'unknown'
|
|
2061
|
+
? `issue-${issueContext.issueNumber}`
|
|
2062
|
+
: 'feature/implementation'
|
|
2063
|
+
),
|
|
2064
|
+
prTitle: quoteShellArgument(resolvedTitle),
|
|
2065
|
+
prBody: quoteShellArgument(resolvedBody),
|
|
2066
|
+
};
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
|
+
function buildCompletionPrompt({ contextSummary, taskText, issueNumber, issueTitle, prBody }) {
|
|
2070
|
+
const args = buildFinishCommandArguments({ taskText, issueNumber, issueTitle, prBody });
|
|
2071
|
+
|
|
2072
|
+
return `# YOUR MISSION: CREATE PR AND MERGE IT
|
|
2028
2073
|
|
|
2029
2074
|
${contextSummary}
|
|
2030
2075
|
|
|
@@ -2045,12 +2090,12 @@ You are the FINISHER. Your ONLY job is to take this cluster's work and push it a
|
|
|
2045
2090
|
2. COMMIT ALL CHANGES - Stage and commit everything:
|
|
2046
2091
|
\`\`\`bash
|
|
2047
2092
|
git add .
|
|
2048
|
-
git commit -m
|
|
2093
|
+
git commit -m ${args.commitMessage}
|
|
2049
2094
|
\`\`\`
|
|
2050
2095
|
|
|
2051
2096
|
3. CREATE BRANCH - Use issue number if available:
|
|
2052
2097
|
\`\`\`bash
|
|
2053
|
-
|
|
2098
|
+
git checkout -b ${args.branch}
|
|
2054
2099
|
\`\`\`
|
|
2055
2100
|
|
|
2056
2101
|
4. PUSH TO REMOTE:
|
|
@@ -2060,16 +2105,7 @@ You are the FINISHER. Your ONLY job is to take this cluster's work and push it a
|
|
|
2060
2105
|
|
|
2061
2106
|
5. CREATE PULL REQUEST:
|
|
2062
2107
|
\`\`\`bash
|
|
2063
|
-
gh pr create --title
|
|
2064
|
-
|
|
2065
|
-
## Summary
|
|
2066
|
-
${taskText.slice(0, 200)}...
|
|
2067
|
-
|
|
2068
|
-
## Changes
|
|
2069
|
-
- Implementation complete
|
|
2070
|
-
- All validations addressed
|
|
2071
|
-
|
|
2072
|
-
🤖 Generated with zeroshot finish"
|
|
2108
|
+
gh pr create --title ${args.prTitle} --body ${args.prBody}
|
|
2073
2109
|
\`\`\`
|
|
2074
2110
|
|
|
2075
2111
|
6. GET PR URL:
|
|
@@ -2078,7 +2114,7 @@ ${taskText.slice(0, 200)}...
|
|
|
2078
2114
|
\`\`\`
|
|
2079
2115
|
|
|
2080
2116
|
7. OUTPUT THE PR URL - Print it clearly so user can see it
|
|
2081
|
-
${
|
|
2117
|
+
${FINISH_MERGE_STEP}
|
|
2082
2118
|
|
|
2083
2119
|
## RULES
|
|
2084
2120
|
|
|
@@ -2702,6 +2738,10 @@ program
|
|
|
2702
2738
|
'Full automation: worktree isolation + PR + auto-merge (use --docker for Docker)'
|
|
2703
2739
|
)
|
|
2704
2740
|
.option('--pr-base <branch>', 'Target branch for PRs (default: repo default branch)')
|
|
2741
|
+
.option(
|
|
2742
|
+
'--pr-body <template>',
|
|
2743
|
+
'PR body template; supports {{issue_number}}, {{issue_title}}, and {{issue_reference}}'
|
|
2744
|
+
)
|
|
2705
2745
|
.option('--merge-queue', 'Use GitHub merge queue instead of direct merge')
|
|
2706
2746
|
.option(
|
|
2707
2747
|
'--close-issue <mode>',
|
|
@@ -3709,6 +3749,10 @@ program
|
|
|
3709
3749
|
.helpGroup('Control:')
|
|
3710
3750
|
.description('Take existing cluster and create completion-focused task (creates PR and merges)')
|
|
3711
3751
|
.option('-y, --yes', 'Skip confirmation if cluster is running')
|
|
3752
|
+
.option(
|
|
3753
|
+
'--pr-body <template>',
|
|
3754
|
+
'PR body template; supports {{issue_number}}, {{issue_title}}, and {{issue_reference}}'
|
|
3755
|
+
)
|
|
3712
3756
|
.action(async (id, options) => {
|
|
3713
3757
|
try {
|
|
3714
3758
|
const orchestrator = await getOrchestrator();
|
|
@@ -3727,6 +3771,7 @@ program
|
|
|
3727
3771
|
taskText: context.taskText,
|
|
3728
3772
|
issueNumber: context.issueNumber,
|
|
3729
3773
|
issueTitle: context.issueTitle,
|
|
3774
|
+
prBody: options.prBody ?? cluster.prOptions?.prBody,
|
|
3730
3775
|
});
|
|
3731
3776
|
printCompletionPromptPreview(completionPrompt);
|
|
3732
3777
|
|
|
@@ -5325,34 +5370,6 @@ function flushAllRenderBuffers(lines, buffers) {
|
|
|
5325
5370
|
}
|
|
5326
5371
|
}
|
|
5327
5372
|
|
|
5328
|
-
function formatLifecycleEvent(data) {
|
|
5329
|
-
const event = data?.event;
|
|
5330
|
-
let icon;
|
|
5331
|
-
let eventText;
|
|
5332
|
-
|
|
5333
|
-
switch (event) {
|
|
5334
|
-
case 'STARTED': {
|
|
5335
|
-
icon = chalk.green('▶');
|
|
5336
|
-
const triggers = data?.triggers?.join(', ') || 'none';
|
|
5337
|
-
eventText = `started (listening for: ${chalk.dim(triggers)})`;
|
|
5338
|
-
break;
|
|
5339
|
-
}
|
|
5340
|
-
case 'TASK_STARTED':
|
|
5341
|
-
icon = chalk.yellow('⚡');
|
|
5342
|
-
eventText = `${chalk.cyan(data.triggeredBy)} → task #${data.iteration} (${chalk.dim(data.model)})`;
|
|
5343
|
-
break;
|
|
5344
|
-
case 'TASK_COMPLETED':
|
|
5345
|
-
icon = chalk.green('✓');
|
|
5346
|
-
eventText = `task #${data.iteration} completed`;
|
|
5347
|
-
break;
|
|
5348
|
-
default:
|
|
5349
|
-
icon = chalk.dim('•');
|
|
5350
|
-
eventText = event || 'unknown event';
|
|
5351
|
-
}
|
|
5352
|
-
|
|
5353
|
-
return { icon, eventText };
|
|
5354
|
-
}
|
|
5355
|
-
|
|
5356
5373
|
function handleLifecycleRender({ msg, prefix, lines }) {
|
|
5357
5374
|
const data = msg.content?.data;
|
|
5358
5375
|
const { icon, eventText } = formatLifecycleEvent(data);
|
|
@@ -5427,7 +5444,7 @@ function appendCriteriaGroup({ lines, prefix, label, items, color, reasonLabel }
|
|
|
5427
5444
|
function appendCriteriaResults(lines, prefix, criteriaResults) {
|
|
5428
5445
|
if (!Array.isArray(criteriaResults)) return;
|
|
5429
5446
|
|
|
5430
|
-
const cannotValidateYet = criteriaResults
|
|
5447
|
+
const { cannotValidateYet, cannotValidate } = partitionValidationCriteria(criteriaResults);
|
|
5431
5448
|
appendCriteriaGroup({
|
|
5432
5449
|
lines,
|
|
5433
5450
|
prefix,
|
|
@@ -5437,7 +5454,6 @@ function appendCriteriaResults(lines, prefix, criteriaResults) {
|
|
|
5437
5454
|
reasonLabel: 'work incomplete',
|
|
5438
5455
|
});
|
|
5439
5456
|
|
|
5440
|
-
const cannotValidate = criteriaResults.filter((c) => c.status === 'CANNOT_VALIDATE');
|
|
5441
5457
|
appendCriteriaGroup({
|
|
5442
5458
|
lines,
|
|
5443
5459
|
prefix,
|
|
@@ -6214,6 +6230,9 @@ module.exports = {
|
|
|
6214
6230
|
isStartupUpdateEligible,
|
|
6215
6231
|
handleNoArgumentInvocation,
|
|
6216
6232
|
shouldRunInitialSetup,
|
|
6233
|
+
extractFinishContext,
|
|
6234
|
+
buildDefaultFinishPrBody,
|
|
6235
|
+
buildCompletionPrompt,
|
|
6217
6236
|
resolveRunMode,
|
|
6218
6237
|
killRunningClusters,
|
|
6219
6238
|
};
|
package/cli/json-export.js
CHANGED
|
@@ -1,77 +1,74 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
function isInteger(value) {
|
|
4
|
+
return Number.isInteger(value);
|
|
5
|
+
}
|
|
3
6
|
function indentJson(value, spaces) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const prefix = ' '.repeat(spaces);
|
|
8
|
+
return JSON.stringify(value, null, 2)
|
|
9
|
+
.split('\n')
|
|
10
|
+
.map((line) => `${prefix}${line}`)
|
|
11
|
+
.join('\n');
|
|
9
12
|
}
|
|
10
|
-
|
|
11
13
|
function writeAll(fd, value) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const bytes = Buffer.from(value);
|
|
15
|
+
let offset = 0;
|
|
16
|
+
while (offset < bytes.length) {
|
|
17
|
+
const written = fs.writeSync(fd, bytes, offset, bytes.length - offset);
|
|
18
|
+
if (!Number.isInteger(written) || written <= 0) {
|
|
19
|
+
throw new Error('JSON export destination stopped accepting bytes');
|
|
20
|
+
}
|
|
21
|
+
offset += written;
|
|
18
22
|
}
|
|
19
|
-
offset += written;
|
|
20
|
-
}
|
|
21
23
|
}
|
|
22
|
-
|
|
23
24
|
function createDestination(outputPath, stdout) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
if (outputPath) {
|
|
26
|
+
const fd = fs.openSync(outputPath, 'w');
|
|
27
|
+
return {
|
|
28
|
+
close: () => fs.closeSync(fd),
|
|
29
|
+
write: (value) => writeAll(fd, value),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (isInteger(stdout.fd)) {
|
|
33
|
+
const fd = stdout.fd;
|
|
34
|
+
return {
|
|
35
|
+
close() { },
|
|
36
|
+
write: (value) => writeAll(fd, value),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
33
39
|
return {
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
close() { },
|
|
41
|
+
write: (value) => {
|
|
42
|
+
stdout.write(value);
|
|
43
|
+
},
|
|
36
44
|
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return {
|
|
40
|
-
close() {},
|
|
41
|
-
write: (value) => stdout.write(value),
|
|
42
|
-
};
|
|
43
45
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
clusterId,
|
|
48
|
-
outputPath = null,
|
|
49
|
-
stdout = process.stdout,
|
|
50
|
-
}) {
|
|
51
|
-
const destination = createDestination(outputPath, stdout);
|
|
52
|
-
const iterator = ledger.iterateAll(clusterId);
|
|
53
|
-
try {
|
|
54
|
-
destination.write(`{\n "cluster_id": ${JSON.stringify(clusterId)},\n "messages": `);
|
|
55
|
-
let current = iterator.next();
|
|
56
|
-
if (current.done) {
|
|
57
|
-
destination.write('[]\n}\n');
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
destination.write('[\n');
|
|
62
|
-
while (!current.done) {
|
|
63
|
-
destination.write(indentJson(current.value, 4));
|
|
64
|
-
current = iterator.next();
|
|
65
|
-
destination.write(current.done ? '\n' : ',\n');
|
|
66
|
-
}
|
|
67
|
-
destination.write(' ]\n}\n');
|
|
68
|
-
} finally {
|
|
46
|
+
function streamClusterJsonExport({ ledger, clusterId, outputPath = null, stdout = process.stdout, }) {
|
|
47
|
+
const destination = createDestination(outputPath, stdout);
|
|
48
|
+
const iterator = ledger.iterateAll(clusterId);
|
|
69
49
|
try {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
50
|
+
destination.write(`{\n "cluster_id": ${JSON.stringify(clusterId)},\n "messages": `);
|
|
51
|
+
let current = iterator.next();
|
|
52
|
+
if (current.done) {
|
|
53
|
+
destination.write('[]\n}\n');
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
destination.write('[\n');
|
|
57
|
+
while (!current.done) {
|
|
58
|
+
destination.write(indentJson(current.value, 4));
|
|
59
|
+
current = iterator.next();
|
|
60
|
+
destination.write(current.done ? '\n' : ',\n');
|
|
61
|
+
}
|
|
62
|
+
destination.write(' ]\n}\n');
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
try {
|
|
66
|
+
if (typeof iterator.return === 'function')
|
|
67
|
+
iterator.return();
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
destination.close();
|
|
71
|
+
}
|
|
73
72
|
}
|
|
74
|
-
}
|
|
75
73
|
}
|
|
76
|
-
|
|
77
74
|
module.exports = { streamClusterJsonExport };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import fs = require('fs');
|
|
2
|
+
|
|
3
|
+
interface LedgerMessageIterator extends Iterator<unknown> {
|
|
4
|
+
return?: () => IteratorResult<unknown>;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface ClusterLedger {
|
|
8
|
+
iterateAll(clusterId: string): LedgerMessageIterator;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface ExportStream {
|
|
12
|
+
readonly fd?: number;
|
|
13
|
+
write(value: string): unknown;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface JsonExportOptions {
|
|
17
|
+
ledger: ClusterLedger;
|
|
18
|
+
clusterId: string;
|
|
19
|
+
outputPath?: string | null;
|
|
20
|
+
stdout?: ExportStream;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface Destination {
|
|
24
|
+
close(): void;
|
|
25
|
+
write(value: string): void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isInteger(value: unknown): value is number {
|
|
29
|
+
return Number.isInteger(value);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function indentJson(value: unknown, spaces: number): string {
|
|
33
|
+
const prefix = ' '.repeat(spaces);
|
|
34
|
+
return JSON.stringify(value, null, 2)
|
|
35
|
+
.split('\n')
|
|
36
|
+
.map((line) => `${prefix}${line}`)
|
|
37
|
+
.join('\n');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function writeAll(fd: number, value: string): void {
|
|
41
|
+
const bytes = Buffer.from(value);
|
|
42
|
+
let offset = 0;
|
|
43
|
+
while (offset < bytes.length) {
|
|
44
|
+
const written = fs.writeSync(fd, bytes, offset, bytes.length - offset);
|
|
45
|
+
if (!Number.isInteger(written) || written <= 0) {
|
|
46
|
+
throw new Error('JSON export destination stopped accepting bytes');
|
|
47
|
+
}
|
|
48
|
+
offset += written;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function createDestination(
|
|
53
|
+
outputPath: string | null | undefined,
|
|
54
|
+
stdout: ExportStream
|
|
55
|
+
): Destination {
|
|
56
|
+
if (outputPath) {
|
|
57
|
+
const fd = fs.openSync(outputPath, 'w');
|
|
58
|
+
return {
|
|
59
|
+
close: () => fs.closeSync(fd),
|
|
60
|
+
write: (value) => writeAll(fd, value),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (isInteger(stdout.fd)) {
|
|
65
|
+
const fd = stdout.fd;
|
|
66
|
+
return {
|
|
67
|
+
close(): void {},
|
|
68
|
+
write: (value) => writeAll(fd, value),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
close(): void {},
|
|
74
|
+
write: (value): void => {
|
|
75
|
+
stdout.write(value);
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function streamClusterJsonExport({
|
|
81
|
+
ledger,
|
|
82
|
+
clusterId,
|
|
83
|
+
outputPath = null,
|
|
84
|
+
stdout = process.stdout,
|
|
85
|
+
}: JsonExportOptions): void {
|
|
86
|
+
const destination = createDestination(outputPath, stdout);
|
|
87
|
+
const iterator = ledger.iterateAll(clusterId);
|
|
88
|
+
try {
|
|
89
|
+
destination.write(`{\n "cluster_id": ${JSON.stringify(clusterId)},\n "messages": `);
|
|
90
|
+
let current = iterator.next();
|
|
91
|
+
if (current.done) {
|
|
92
|
+
destination.write('[]\n}\n');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
destination.write('[\n');
|
|
97
|
+
while (!current.done) {
|
|
98
|
+
destination.write(indentJson(current.value, 4));
|
|
99
|
+
current = iterator.next();
|
|
100
|
+
destination.write(current.done ? '\n' : ',\n');
|
|
101
|
+
}
|
|
102
|
+
destination.write(' ]\n}\n');
|
|
103
|
+
} finally {
|
|
104
|
+
try {
|
|
105
|
+
if (typeof iterator.return === 'function') iterator.return();
|
|
106
|
+
} finally {
|
|
107
|
+
destination.close();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export = { streamClusterJsonExport };
|
|
@@ -1,75 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const chalk = require("chalk");
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Extracted from index.js to reduce complexity
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const chalk = require('chalk');
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Get color for sender based on consistent hashing
|
|
10
|
-
* @param {string} sender - Sender name
|
|
11
|
-
* @returns {Function} Chalk color function
|
|
4
|
+
* Get color for sender based on consistent hashing.
|
|
12
5
|
*/
|
|
13
6
|
function getColorForSender(sender) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
7
|
+
const colors = [chalk.cyan, chalk.magenta, chalk.yellow, chalk.green, chalk.blue];
|
|
8
|
+
let hash = 0;
|
|
9
|
+
for (let i = 0; i < sender.length; i++) {
|
|
10
|
+
hash = (hash << 5) - hash + sender.charCodeAt(i);
|
|
11
|
+
hash = hash & hash;
|
|
12
|
+
}
|
|
13
|
+
return colors[Math.abs(hash) % colors.length] ?? chalk.cyan;
|
|
21
14
|
}
|
|
22
|
-
|
|
23
15
|
/**
|
|
24
|
-
* Build message prefix with timestamp, sender, and optional cluster ID
|
|
25
|
-
* @param {Object} msg - Message object
|
|
26
|
-
* @param {boolean} showClusterId - Whether to show cluster ID
|
|
27
|
-
* @param {boolean} isActive - Whether cluster is active
|
|
28
|
-
* @returns {string} Formatted prefix
|
|
16
|
+
* Build message prefix with timestamp, sender, and optional cluster ID.
|
|
29
17
|
*/
|
|
30
18
|
function buildMessagePrefix(msg, showClusterId, isActive) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const modelSuffix = msg.sender_model ? chalk.dim(` [${msg.sender_model}]`) : '';
|
|
39
|
-
return color(`${senderLabel.padEnd(showClusterId ? 25 : 15)} |`) + modelSuffix;
|
|
19
|
+
const color = isActive ? getColorForSender(msg.sender) : chalk.dim;
|
|
20
|
+
let senderLabel = msg.sender;
|
|
21
|
+
if (showClusterId && msg.cluster_id) {
|
|
22
|
+
senderLabel = `${msg.cluster_id}/${msg.sender}`;
|
|
23
|
+
}
|
|
24
|
+
const modelSuffix = msg.sender_model ? chalk.dim(` [${msg.sender_model}]`) : '';
|
|
25
|
+
return color(`${senderLabel.padEnd(showClusterId ? 25 : 15)} |`) + modelSuffix;
|
|
40
26
|
}
|
|
41
|
-
|
|
42
27
|
/**
|
|
43
|
-
* Build cluster prefix for watch mode
|
|
44
|
-
* @param {string} clusterId - Cluster ID
|
|
45
|
-
* @param {boolean} isActive - Whether cluster is active
|
|
46
|
-
* @returns {string} Formatted prefix
|
|
28
|
+
* Build cluster prefix for watch mode.
|
|
47
29
|
*/
|
|
48
30
|
function buildClusterPrefix(clusterId, isActive) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
: chalk.dim(`${clusterId.padEnd(20)} |`);
|
|
31
|
+
const color = isActive ? chalk.white : chalk.dim;
|
|
32
|
+
return color(`${clusterId.padEnd(20)} |`);
|
|
52
33
|
}
|
|
53
|
-
|
|
54
34
|
/**
|
|
55
|
-
* Parse and normalize data fields (handles string JSON)
|
|
56
|
-
* @param {string|Array} data - Data to parse
|
|
57
|
-
* @returns {Array} Parsed array
|
|
35
|
+
* Parse and normalize data fields (handles string JSON).
|
|
58
36
|
*/
|
|
59
37
|
function parseDataField(data) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
38
|
+
if (typeof data === 'string') {
|
|
39
|
+
try {
|
|
40
|
+
const parsed = JSON.parse(data);
|
|
41
|
+
return parsed;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
65
46
|
}
|
|
66
|
-
|
|
67
|
-
|
|
47
|
+
return Array.isArray(data) ? data : [];
|
|
48
|
+
}
|
|
49
|
+
function formatLifecycleEvent(data) {
|
|
50
|
+
const event = data?.event;
|
|
51
|
+
let icon;
|
|
52
|
+
let eventText;
|
|
53
|
+
switch (event) {
|
|
54
|
+
case 'STARTED': {
|
|
55
|
+
icon = chalk.green('▶');
|
|
56
|
+
const triggers = data?.triggers?.join(', ') || 'none';
|
|
57
|
+
eventText = `started (listening for: ${chalk.dim(triggers)})`;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
case 'TASK_STARTED':
|
|
61
|
+
icon = chalk.yellow('⚡');
|
|
62
|
+
eventText = `${chalk.cyan(data?.triggeredBy)} → task #${data?.iteration} (${chalk.dim(data?.model)})`;
|
|
63
|
+
break;
|
|
64
|
+
case 'TASK_COMPLETED':
|
|
65
|
+
icon = chalk.green('✓');
|
|
66
|
+
eventText = `task #${data?.iteration} completed`;
|
|
67
|
+
break;
|
|
68
|
+
default:
|
|
69
|
+
icon = chalk.dim('•');
|
|
70
|
+
eventText = event || 'unknown event';
|
|
71
|
+
}
|
|
72
|
+
return { icon, eventText };
|
|
73
|
+
}
|
|
74
|
+
function partitionValidationCriteria(criteria) {
|
|
75
|
+
return {
|
|
76
|
+
cannotValidateYet: criteria.filter((criterion) => criterion.status === 'CANNOT_VALIDATE_YET'),
|
|
77
|
+
cannotValidate: criteria.filter((criterion) => criterion.status === 'CANNOT_VALIDATE'),
|
|
78
|
+
};
|
|
68
79
|
}
|
|
69
|
-
|
|
70
80
|
module.exports = {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
81
|
+
getColorForSender,
|
|
82
|
+
buildMessagePrefix,
|
|
83
|
+
buildClusterPrefix,
|
|
84
|
+
parseDataField,
|
|
85
|
+
formatLifecycleEvent,
|
|
86
|
+
partitionValidationCriteria,
|
|
75
87
|
};
|