salmon-loop 0.2.13 → 0.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/argv/headless-detection.js +27 -0
- package/dist/cli/chat-flow.js +11 -0
- package/dist/cli/chat.js +160 -24
- package/dist/cli/commands/chat.js +14 -7
- package/dist/cli/commands/flow-mode.js +63 -0
- package/dist/cli/commands/registry.js +2 -0
- package/dist/cli/commands/run/benchmark-artifacts.js +41 -0
- package/dist/cli/commands/run/early-errors.js +23 -0
- package/dist/cli/commands/run/handler.js +115 -27
- package/dist/cli/commands/run/headless-error-writer.js +8 -0
- package/dist/cli/commands/run/loop-params.js +2 -0
- package/dist/cli/commands/run/mode.js +2 -5
- package/dist/cli/commands/run/parse-options.js +16 -0
- package/dist/cli/commands/run/persist-session.js +10 -1
- package/dist/cli/commands/run/preflight.js +10 -0
- package/dist/cli/commands/run/reporter-factory.js +4 -0
- package/dist/cli/commands/run/runtime-llm.js +38 -11
- package/dist/cli/commands/run/runtime-options.js +2 -2
- package/dist/cli/commands/serve.js +91 -71
- package/dist/cli/commands/tool-names.js +78 -78
- package/dist/cli/headless/anthropic-stream-normalized-encoder.js +6 -1
- package/dist/cli/headless/json-protocol.js +37 -0
- package/dist/cli/headless/native-stream-normalized-encoder.js +6 -1
- package/dist/cli/headless/protocol-metadata.js +22 -0
- package/dist/cli/headless/stream-json-protocol.js +34 -1
- package/dist/cli/index.js +6 -4
- package/dist/cli/locales/en.js +30 -6
- package/dist/cli/program-bootstrap.js +8 -3
- package/dist/cli/program-commands.js +5 -1
- package/dist/cli/reporters/anthropic-stream.js +7 -1
- package/dist/cli/reporters/json.js +4 -0
- package/dist/cli/reporters/stream-json.js +17 -2
- package/dist/cli/run-cli.js +5 -3
- package/dist/cli/slash/runtime.js +27 -12
- package/dist/cli/ui/components/CommandInput.js +7 -3
- package/dist/cli/ui/components/CommandSuggestionList.js +1 -1
- package/dist/cli/utils/command-option-source.js +13 -0
- package/dist/cli/utils/verify-resolver.js +8 -4
- package/dist/cli/utils/worktree-prepare-resolver.js +7 -3
- package/dist/core/adapters/fs/file-adapter.js +6 -0
- package/dist/core/adapters/fs/filesystem.js +2 -1
- package/dist/core/adapters/git/git-adapter.js +78 -1
- package/dist/core/benchmark/patch-artifact.js +124 -0
- package/dist/core/benchmark/swe-bench.js +25 -0
- package/dist/core/config/load.js +18 -11
- package/dist/core/config/resolve-llm.js +12 -0
- package/dist/core/config/resolvers/server.js +0 -6
- package/dist/core/config/validate.js +73 -21
- package/dist/core/context/gatherers/metadata-gatherer.js +1 -0
- package/dist/core/context/gatherers/ripgrep-gatherer.js +84 -2
- package/dist/core/context/keywords.js +18 -4
- package/dist/core/context/service-deps.js +2 -2
- package/dist/core/context/service.js +8 -0
- package/dist/core/context/steps/context-gather.js +38 -0
- package/dist/core/context/summarization/summarizer.js +55 -12
- package/dist/core/context/targeting/target-resolver.js +4 -4
- package/dist/core/extensions/index.js +23 -5
- package/dist/core/extensions/paths.js +31 -0
- package/dist/core/extensions/schemas.js +8 -5
- package/dist/core/facades/cli-chat.js +6 -2
- package/dist/core/facades/cli-command-chat.js +1 -0
- package/dist/core/facades/cli-command-tool-names.js +2 -0
- package/dist/core/facades/cli-observability.js +1 -1
- package/dist/core/facades/cli-run-handler.js +4 -2
- package/dist/core/facades/cli-run-persist-session.js +1 -0
- package/dist/core/facades/cli-serve.js +2 -4
- package/dist/core/facades/cli-utils-worktree.js +1 -1
- package/dist/core/failure/diagnostics.js +53 -1
- package/dist/core/grizzco/dsl/llm-strategy.js +4 -1
- package/dist/core/grizzco/engine/outcome/loop-result-mapper.js +67 -9
- package/dist/core/grizzco/engine/pipeline/pipeline.js +6 -2
- package/dist/core/grizzco/engine/transaction/attempt-failure.js +90 -15
- package/dist/core/grizzco/engine/transaction/report-mapper.js +17 -3
- package/dist/core/grizzco/engine/transaction/transaction-runner.js +165 -7
- package/dist/core/grizzco/flows/AutopilotFlow.js +18 -0
- package/dist/core/grizzco/flows/flow-dispatch.js +11 -0
- package/dist/core/grizzco/steps/answer.js +13 -14
- package/dist/core/grizzco/steps/autopilot.js +396 -0
- package/dist/core/grizzco/steps/cache-sharing.js +29 -0
- package/dist/core/grizzco/steps/explore.js +37 -21
- package/dist/core/grizzco/steps/generateReview.js +2 -5
- package/dist/core/grizzco/steps/patch/apply-check.js +10 -0
- package/dist/core/grizzco/steps/patch/diff-normalization.js +70 -0
- package/dist/core/grizzco/steps/patch/diff-salvage.js +46 -0
- package/dist/core/grizzco/steps/patch/prompt-input.js +42 -0
- package/dist/core/grizzco/steps/patch.js +105 -146
- package/dist/core/grizzco/steps/plan.js +101 -25
- package/dist/core/grizzco/steps/preflight.js +5 -6
- package/dist/core/grizzco/steps/request-assembly.js +78 -0
- package/dist/core/grizzco/steps/research.js +39 -36
- package/dist/core/grizzco/steps/tool-runtime.js +47 -0
- package/dist/core/grizzco/steps/verify-shared.js +23 -0
- package/dist/core/grizzco/steps/verify.js +13 -21
- package/dist/core/llm/ai-sdk/chat-executor.js +2 -0
- package/dist/core/llm/ai-sdk/high-level-phase-specs.js +63 -0
- package/dist/core/llm/ai-sdk/message-mapper.js +40 -10
- package/dist/core/llm/ai-sdk/provider-factory.js +14 -0
- package/dist/core/llm/ai-sdk/request-params.js +73 -0
- package/dist/core/llm/ai-sdk/result-mapper.js +16 -0
- package/dist/core/llm/ai-sdk.js +112 -27
- package/dist/core/llm/capabilities.js +12 -0
- package/dist/core/llm/contracts/repair.js +36 -30
- package/dist/core/llm/errors.js +83 -2
- package/dist/core/llm/message-composition.js +7 -22
- package/dist/core/llm/phase-router.js +29 -10
- package/dist/core/llm/redact.js +28 -3
- package/dist/core/llm/registry.js +2 -0
- package/dist/core/llm/request-augmentation.js +55 -0
- package/dist/core/llm/request-envelope.js +334 -0
- package/dist/core/llm/shared-request-assembly.js +35 -0
- package/dist/core/llm/stream-utils.js +13 -4
- package/dist/core/llm/utils.js +18 -29
- package/dist/core/memory/relevant-retrieval.js +144 -0
- package/dist/core/observability/logger.js +11 -2
- package/dist/core/patch/diff.js +1 -0
- package/dist/core/prompts/registry.js +39 -2
- package/dist/core/prompts/runtime.js +50 -12
- package/dist/core/prompts/templates/phases/patch_user.hbs +2 -5
- package/dist/core/prompts/templates/phases/research_user.hbs +11 -0
- package/dist/core/prompts/templates/phases/review_user.hbs +3 -0
- package/dist/core/prompts/templates/system/answer_system.hbs +5 -0
- package/dist/core/prompts/templates/system/autopilot_system.hbs +11 -0
- package/dist/core/prompts/templates/system/explore_system.hbs +14 -23
- package/dist/core/prompts/templates/system/main_system.hbs +4 -16
- package/dist/core/prompts/templates/system/patch_system.hbs +39 -8
- package/dist/core/prompts/templates/system/plan_system.hbs +86 -1
- package/dist/core/prompts/templates/system/research_system.hbs +2 -0
- package/dist/core/protocols/a2a/agent-card.js +3 -2
- package/dist/core/protocols/a2a/sdk/executor.js +2 -1
- package/dist/core/protocols/a2a/sdk/server.js +0 -1
- package/dist/core/protocols/acp/formal-agent.js +74 -51
- package/dist/core/protocols/acp/handlers.js +5 -1
- package/dist/core/protocols/acp/permission-provider.js +1 -1
- package/dist/core/protocols/shared/flow-mode-mapping.js +23 -0
- package/dist/core/public-capabilities/flow-mode-metadata.js +39 -0
- package/dist/core/public-capabilities/projections.js +29 -0
- package/dist/core/public-capabilities/registry.js +26 -0
- package/dist/core/public-capabilities/types.js +2 -0
- package/dist/core/runtime/agent-server-runtime.js +47 -43
- package/dist/core/runtime/execution-profile.js +67 -0
- package/dist/core/session/artifact-state.js +160 -0
- package/dist/core/session/compaction/index.js +183 -0
- package/dist/core/session/compaction/microcompact.js +78 -0
- package/dist/core/session/compaction/tracking.js +48 -0
- package/dist/core/session/compaction/types.js +11 -0
- package/dist/core/session/compression.js +8 -0
- package/dist/core/session/manager.js +244 -8
- package/dist/core/session/pruning-strategy.js +55 -9
- package/dist/core/session/replacement-preview-provider.js +24 -0
- package/dist/core/session/replacement-state.js +131 -0
- package/dist/core/session/resume-repair/pipeline.js +79 -0
- package/dist/core/session/resume-repair/stages/load-raw-archive-state.js +40 -0
- package/dist/core/session/resume-repair/stages/reattach-runtime-state.js +8 -0
- package/dist/core/session/resume-repair/stages/recover-orphaned-branches.js +10 -0
- package/dist/core/session/resume-repair/stages/relink-boundary-and-tail.js +36 -0
- package/dist/core/session/resume-repair/stages/replay-startup-hooks.js +23 -0
- package/dist/core/session/resume-repair/stages/rescue-stale-metadata.js +17 -0
- package/dist/core/session/resume-repair/types.js +2 -0
- package/dist/core/session/summary-sync.js +164 -13
- package/dist/core/session/token-tracker.js +6 -0
- package/dist/core/skills/audit.js +34 -0
- package/dist/core/skills/bridge.js +84 -7
- package/dist/core/skills/discovery.js +94 -0
- package/dist/core/skills/feature-flags.js +52 -0
- package/dist/core/skills/index.js +1 -1
- package/dist/core/skills/loader.js +195 -20
- package/dist/core/skills/parser.js +296 -24
- package/dist/core/skills/permissions.js +117 -0
- package/dist/core/skills/runtime/MicroTaskRunner.js +10 -4
- package/dist/core/skills/runtime/SkillRunner.js +240 -61
- package/dist/core/strata/layers/shadow-driver/shadow-driver.js +37 -7
- package/dist/core/strata/layers/worktree.js +67 -10
- package/dist/core/strata/runtime/synchronizer.js +29 -2
- package/dist/core/streaming/stream-assembler.js +75 -31
- package/dist/core/sub-agent/context-snapshot.js +156 -0
- package/dist/core/sub-agent/core/loop.js +1 -1
- package/dist/core/sub-agent/core/manager.js +119 -20
- package/dist/core/sub-agent/dispatch-policy.js +29 -0
- package/dist/core/sub-agent/prefix-consistency.js +48 -0
- package/dist/core/sub-agent/registry-defaults.js +4 -0
- package/dist/core/sub-agent/tools/task-spawn.js +79 -2
- package/dist/core/sub-agent/types.js +134 -5
- package/dist/core/tools/audit.js +13 -4
- package/dist/core/tools/builtin/ast-grep.js +1 -1
- package/dist/core/tools/builtin/ast.js +1 -1
- package/dist/core/tools/builtin/benchmark.js +360 -0
- package/dist/core/tools/builtin/code-search/backends/rg.js +2 -1
- package/dist/core/tools/builtin/code-search/executor.js +6 -1
- package/dist/core/tools/builtin/code-search/spec.js +26 -2
- package/dist/core/tools/builtin/fs.js +256 -23
- package/dist/core/tools/builtin/git.js +2 -2
- package/dist/core/tools/builtin/index.js +51 -2
- package/dist/core/tools/builtin/interaction.js +8 -1
- package/dist/core/tools/builtin/plan.js +37 -15
- package/dist/core/tools/builtin/shell.js +1 -1
- package/dist/core/tools/loader.js +39 -16
- package/dist/core/tools/mapper.js +17 -3
- package/dist/core/tools/parallel/scheduler.js +35 -4
- package/dist/core/tools/permissions/permission-rules.js +5 -10
- package/dist/core/tools/policy.js +6 -1
- package/dist/core/tools/recoverable-tool-errors.js +10 -0
- package/dist/core/tools/router.js +24 -6
- package/dist/core/tools/session.js +458 -48
- package/dist/core/tools/tool-visibility.js +62 -0
- package/dist/core/tools/types.js +9 -1
- package/dist/core/types/execution.js +4 -0
- package/dist/core/types/flow-mode.js +8 -0
- package/dist/core/utils/path.js +52 -0
- package/dist/core/verification/runner.js +4 -1
- package/dist/languages/typescript/index.js +4 -1
- package/dist/locales/en.js +35 -2
- package/dist/utils/eol.js +1 -1
- package/package.json +13 -6
- package/scripts/fix-es-abstract-compat.js +77 -0
- package/dist/core/runtime/fastify-server-bundle.js +0 -26
- package/dist/core/runtime/sidecar-fastify-plugin.js +0 -35
- package/dist/core/runtime/sidecar-paths.js +0 -47
- package/dist/core/runtime/sidecar-route-catalog.js +0 -103
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getExitCode } from '../../core/facades/cli-headless.js';
|
|
2
|
+
import { HEADLESS_NATIVE_STREAM_PROTOCOL_VERSION, normalizeHeadlessWarnings, } from './protocol-metadata.js';
|
|
2
3
|
function toIso(date) {
|
|
3
4
|
return date.toISOString();
|
|
4
5
|
}
|
|
@@ -27,6 +28,8 @@ function encodeEnvelope(params) {
|
|
|
27
28
|
return dropUndefined({
|
|
28
29
|
uuid: params.uuid,
|
|
29
30
|
session_id: params.sessionId,
|
|
31
|
+
protocol_version: HEADLESS_NATIVE_STREAM_PROTOCOL_VERSION,
|
|
32
|
+
event_seq: params.eventSeq,
|
|
30
33
|
event: params.event,
|
|
31
34
|
parent_tool_use_id: params.parentToolUseId,
|
|
32
35
|
});
|
|
@@ -42,6 +45,7 @@ export function encodeStreamStart(params) {
|
|
|
42
45
|
repo_path: params.repoPath,
|
|
43
46
|
instruction: params.instruction,
|
|
44
47
|
}),
|
|
48
|
+
eventSeq: params.eventSeq,
|
|
45
49
|
});
|
|
46
50
|
}
|
|
47
51
|
export function encodeStreamEvent(params) {
|
|
@@ -53,6 +57,7 @@ export function encodeStreamEvent(params) {
|
|
|
53
57
|
...params.event,
|
|
54
58
|
timestamp: toIso(params.at),
|
|
55
59
|
}),
|
|
60
|
+
eventSeq: params.eventSeq,
|
|
56
61
|
});
|
|
57
62
|
}
|
|
58
63
|
export function encodeStreamLoopEvent(params) {
|
|
@@ -65,10 +70,30 @@ export function encodeStreamLoopEvent(params) {
|
|
|
65
70
|
...mapLoopEventToJson(params.event),
|
|
66
71
|
timestamp: toIso(params.event.timestamp),
|
|
67
72
|
}),
|
|
73
|
+
eventSeq: params.eventSeq,
|
|
68
74
|
});
|
|
69
75
|
}
|
|
70
76
|
export function encodeStreamResult(params) {
|
|
71
77
|
const exitCode = getStreamExitCode(params.loopResult);
|
|
78
|
+
const warnings = normalizeHeadlessWarnings(params.warnings);
|
|
79
|
+
const patchArtifact = params.loopResult.benchmarkPatchArtifact
|
|
80
|
+
? {
|
|
81
|
+
kind: params.loopResult.benchmarkPatchArtifact.kind,
|
|
82
|
+
path: params.loopResult.benchmarkPatchArtifact.path,
|
|
83
|
+
sha256: params.loopResult.benchmarkPatchArtifact.sha256,
|
|
84
|
+
bytes: params.loopResult.benchmarkPatchArtifact.bytes,
|
|
85
|
+
changed_files: params.loopResult.benchmarkPatchArtifact.changedFiles,
|
|
86
|
+
is_empty: params.loopResult.benchmarkPatchArtifact.isEmpty,
|
|
87
|
+
}
|
|
88
|
+
: undefined;
|
|
89
|
+
const benchmarkArtifact = params.loopResult.benchmarkArtifact
|
|
90
|
+
? {
|
|
91
|
+
provider: params.loopResult.benchmarkArtifact.provider,
|
|
92
|
+
instance_id: params.loopResult.benchmarkArtifact.instanceId,
|
|
93
|
+
model_name_or_path: params.loopResult.benchmarkArtifact.modelNameOrPath,
|
|
94
|
+
predictions_path: params.loopResult.benchmarkArtifact.predictionsPath,
|
|
95
|
+
}
|
|
96
|
+
: undefined;
|
|
72
97
|
return encodeEnvelope({
|
|
73
98
|
uuid: params.uuid,
|
|
74
99
|
sessionId: params.sessionId,
|
|
@@ -83,17 +108,21 @@ export function encodeStreamResult(params) {
|
|
|
83
108
|
safe_hint: params.loopResult.safeHint ?? params.loopResult.reason,
|
|
84
109
|
remediation_steps: params.loopResult.remediationSteps ?? [],
|
|
85
110
|
attempts: params.loopResult.attempts,
|
|
86
|
-
changed_files: params.loopResult.changedFiles,
|
|
111
|
+
changed_files: params.loopResult.changedFiles ?? [],
|
|
112
|
+
patch_artifact: patchArtifact,
|
|
113
|
+
benchmark_artifact: benchmarkArtifact,
|
|
87
114
|
audit_path: params.loopResult.auditPath,
|
|
88
115
|
error_code: params.loopResult.errorCode,
|
|
89
116
|
authorization_summary: params.loopResult.authorizationSummary,
|
|
90
117
|
result: params.resultText,
|
|
118
|
+
warnings,
|
|
91
119
|
run_end: {
|
|
92
120
|
success: Boolean(params.loopResult.success),
|
|
93
121
|
exit_code: exitCode,
|
|
94
122
|
timestamp: toIso(params.at),
|
|
95
123
|
},
|
|
96
124
|
}),
|
|
125
|
+
eventSeq: params.eventSeq,
|
|
97
126
|
});
|
|
98
127
|
}
|
|
99
128
|
export function encodeStreamFailure(params) {
|
|
@@ -103,12 +132,14 @@ export function encodeStreamFailure(params) {
|
|
|
103
132
|
event: {
|
|
104
133
|
type: 'error',
|
|
105
134
|
timestamp: toIso(params.at),
|
|
135
|
+
audit_path: params.auditPath,
|
|
106
136
|
error: dropUndefined({
|
|
107
137
|
name: params.name,
|
|
108
138
|
message: params.message,
|
|
109
139
|
stack: params.stack,
|
|
110
140
|
}),
|
|
111
141
|
},
|
|
142
|
+
eventSeq: params.eventSeq,
|
|
112
143
|
});
|
|
113
144
|
}
|
|
114
145
|
export function encodeStreamCrash(params) {
|
|
@@ -119,6 +150,7 @@ export function encodeStreamCrash(params) {
|
|
|
119
150
|
message: params.error.message,
|
|
120
151
|
name: params.error.name,
|
|
121
152
|
stack: params.error.stack,
|
|
153
|
+
eventSeq: params.eventSeq,
|
|
122
154
|
});
|
|
123
155
|
}
|
|
124
156
|
export function encodeStreamEnd(params) {
|
|
@@ -131,6 +163,7 @@ export function encodeStreamEnd(params) {
|
|
|
131
163
|
success: params.success,
|
|
132
164
|
exit_code: params.exitCode,
|
|
133
165
|
},
|
|
166
|
+
eventSeq: params.eventSeq,
|
|
134
167
|
});
|
|
135
168
|
}
|
|
136
169
|
//# sourceMappingURL=stream-json-protocol.js.map
|
package/dist/cli/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
process.
|
|
2
|
+
import { detectHeadlessOutputFromArgv, shouldForceColorForArgv, } from './argv/headless-detection.js';
|
|
3
|
+
const headlessOutput = Boolean(detectHeadlessOutputFromArgv(process.argv).outputFormat);
|
|
4
|
+
if (!headlessOutput && shouldForceColorForArgv(process.argv)) {
|
|
5
|
+
process.env.FORCE_COLOR = '3';
|
|
6
|
+
}
|
|
5
7
|
import 'dotenv/config';
|
|
6
|
-
|
|
8
|
+
const { runCli } = await import('./run-cli.js');
|
|
7
9
|
await runCli(process.argv);
|
|
8
10
|
//# sourceMappingURL=index.js.map
|
package/dist/cli/locales/en.js
CHANGED
|
@@ -3,7 +3,7 @@ export const en = {
|
|
|
3
3
|
programDescription: 'A minimal viable loop for automated code patching',
|
|
4
4
|
runDescription: 'Run the salmon-loop',
|
|
5
5
|
contextDescription: 'Build and print the context prompt (no LLM call)',
|
|
6
|
-
serveDescription: 'Start the A2A
|
|
6
|
+
serveDescription: 'Start the A2A server and ACP stdio bridge',
|
|
7
7
|
serveAcpDescription: 'Start the agent-client-protocol (ACP) stdio server only',
|
|
8
8
|
noColorOption: 'Disable colored output in logs',
|
|
9
9
|
// Chat mode
|
|
@@ -74,6 +74,7 @@ export const en = {
|
|
|
74
74
|
commandLlmOutput: 'Set which LLM sections are shown in the UI (advanced)',
|
|
75
75
|
commandMode: 'Set permission mode (interactive|yolo) and save to config',
|
|
76
76
|
commandLogMode: 'Set UI verbosity (quiet|normal|debug) and save to config',
|
|
77
|
+
commandFlowMode: 'Set the current chat flow mode for this session',
|
|
77
78
|
commandConfig: 'Settings hub (mode, log-mode, view, output, allowlist)',
|
|
78
79
|
commandAuth: 'Manage tool allowlist',
|
|
79
80
|
commandParallel: 'Manage parallel plans',
|
|
@@ -120,6 +121,25 @@ export const en = {
|
|
|
120
121
|
modeUpdated: (mode) => `Permission mode updated: ${mode}`,
|
|
121
122
|
modePersisted: (path) => `Permission mode saved to ${path}`,
|
|
122
123
|
modePersistFailed: (error) => `Failed to save permission mode: ${error}`,
|
|
124
|
+
flowModeUsage: 'Usage: /flow-mode <patch|review|debug|research|answer|autopilot>',
|
|
125
|
+
flowModeSuggestion: (mode) => {
|
|
126
|
+
if (mode === 'patch')
|
|
127
|
+
return 'Patch code and run verification';
|
|
128
|
+
if (mode === 'review')
|
|
129
|
+
return 'Analyze code without modifying files';
|
|
130
|
+
if (mode === 'debug')
|
|
131
|
+
return 'Investigate issues, then patch and verify';
|
|
132
|
+
if (mode === 'research')
|
|
133
|
+
return 'Research the codebase and summarize findings';
|
|
134
|
+
if (mode === 'answer')
|
|
135
|
+
return 'Answer directly without modifying files';
|
|
136
|
+
if (mode === 'autopilot')
|
|
137
|
+
return 'Let SalmonLoop choose the appropriate flow';
|
|
138
|
+
return `Set flow mode to ${mode}`;
|
|
139
|
+
},
|
|
140
|
+
flowModeCurrent: (mode) => `Current chat flow mode: ${mode}`,
|
|
141
|
+
flowModeInvalid: (mode) => `Invalid flow mode: ${mode}. Expected one of: patch, review, debug, research, answer, autopilot.`,
|
|
142
|
+
flowModeUpdated: (mode) => `Chat flow mode updated: ${mode}`,
|
|
123
143
|
logModeUsage: 'Usage: /log-mode <quiet|normal|debug>',
|
|
124
144
|
logModeSuggestion: (mode) => {
|
|
125
145
|
if (mode === 'quiet')
|
|
@@ -159,11 +179,9 @@ export const en = {
|
|
|
159
179
|
a2aPortOption: 'A2A listen port (default: 7431)',
|
|
160
180
|
a2aTokenOption: 'Bearer token for A2A auth (repeatable)',
|
|
161
181
|
acpStdioDisableOption: 'Disable agent-client-protocol (ACP) stdio server',
|
|
162
|
-
sidecarSocketOption: 'UDS path for the sidecar UI server',
|
|
163
|
-
sidecarAllowConditionalOption: 'Expose conditional sidecar routes (use with care)',
|
|
164
182
|
acpStdioStarted: (port) => `ACP (agent-client-protocol) stdio enabled; port ${port}`,
|
|
165
183
|
invalidA2APort: (value) => `Invalid A2A port: ${value}`,
|
|
166
|
-
serveStarted: (host, port
|
|
184
|
+
serveStarted: (host, port) => `A2A listening on ${host}:${port}`,
|
|
167
185
|
configAllowlistUsage: 'Usage: /config allowlist <list|add|remove|clear|hash|reload> [scope] [tool] [phase] [args=<hash>] [effects=a,b] [deny]',
|
|
168
186
|
authUsage: 'Usage: /allowlist <list|add|remove|clear|hash|reload> [scope] [tool] [phase] [args=<hash>] [effects=a,b] [deny]',
|
|
169
187
|
authSubcommandHint: (sub) => `Allowlist ${sub} command`,
|
|
@@ -243,6 +261,10 @@ export const en = {
|
|
|
243
261
|
includePartialMessagesOption: 'Include partial message streaming events in stream-json output (alias for --stream-output).',
|
|
244
262
|
outputFormatOption: 'Output format (text, json, stream-json)',
|
|
245
263
|
outputProfileOption: 'Output profile for stream-json (native, anthropic, openai). Only valid with --output-format stream-json.',
|
|
264
|
+
exportPatchOption: 'Write the final workspace git unified diff to a patch file after the run completes.',
|
|
265
|
+
sweBenchInstanceIdOption: 'SWE-bench instance_id to include when writing a predictions JSONL record.',
|
|
266
|
+
sweBenchModelNameOption: 'SWE-bench model_name_or_path to include when writing a predictions JSONL record.',
|
|
267
|
+
sweBenchPredictionsOption: 'Append a SWE-bench predictions JSONL record containing instance_id, model_name_or_path, and model_patch.',
|
|
246
268
|
headlessIncludeToolInputOption: 'Headless only: include (redacted) tool input in stream-json output. Only valid with --output-format stream-json.',
|
|
247
269
|
headlessIncludeToolOutputOption: 'Headless only: include tool output summary in stream-json output. Only valid with --output-format stream-json.',
|
|
248
270
|
headlessIncludeAuthorizationDecisionsOption: 'Headless only: include tool authorization decisions in headless output. Only valid with --output-format json or stream-json.',
|
|
@@ -252,7 +274,7 @@ export const en = {
|
|
|
252
274
|
auditScopeOption: 'Audit log scope (repo, user)',
|
|
253
275
|
contextDiffScopeOption: 'Diff scope for context (primary, ast_related)',
|
|
254
276
|
contextBudgetCharsOption: 'Context budget in characters (e.g., 30000)',
|
|
255
|
-
actModeOption: 'Flow mode to run (patch, review, debug, research)',
|
|
277
|
+
actModeOption: 'Flow mode to run (patch, review, debug, research, answer, autopilot)',
|
|
256
278
|
// Error messages
|
|
257
279
|
fileSelectionConflict: '--file and --selection are mutually exclusive',
|
|
258
280
|
instructionRequired: '--instruction is required',
|
|
@@ -262,10 +284,12 @@ export const en = {
|
|
|
262
284
|
jsonSchemaRequiresJsonOutput: '--json-schema is only valid when --output-format is set to "json".',
|
|
263
285
|
jsonSchemaLoadFailed: (msg) => `Failed to load JSON schema: ${msg}.`,
|
|
264
286
|
structuredOutputSchemaFailed: 'Structured output failed schema validation.',
|
|
265
|
-
invalidActMode: (mode) => `Invalid --act-mode "${mode}". Expected "patch", "review", "debug", or "
|
|
287
|
+
invalidActMode: (mode) => `Invalid --act-mode "${mode}". Expected "patch", "review", "debug", "research", "answer", or "autopilot".`,
|
|
266
288
|
invalidEnvironmentMode: (mode) => `Invalid --environment-mode "${mode}". Expected "strict" or "parity".`,
|
|
267
289
|
invalidOutputFormat: (format) => `Invalid --output-format "${format}". Expected "text", "stream-json", or "json".`,
|
|
268
290
|
invalidOutputProfile: (profile) => `Invalid --output-profile "${profile}". Expected "native", "anthropic", or "openai".`,
|
|
291
|
+
sweBenchInstanceRequired: '--swe-bench-predictions requires --swe-bench-instance-id.',
|
|
292
|
+
sweBenchModelRequired: '--swe-bench-predictions requires --swe-bench-model-name.',
|
|
269
293
|
invalidAuditScope: (scope) => `Invalid --audit-scope "${scope}". Expected "repo" or "user".`,
|
|
270
294
|
headlessToolPayloadRequiresStreamJson: '--headless-include-tool-input/--headless-include-tool-output are only valid when --output-format is set to "stream-json".',
|
|
271
295
|
headlessToolPayloadNotSupportedWithOpenAiProfile: '--headless-include-tool-input/--headless-include-tool-output are not supported with --output-profile "openai".',
|
|
@@ -2,10 +2,15 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { initializeRuntime } from '../core/facades/cli-program-bootstrap.js';
|
|
4
4
|
import { text } from './locales/index.js';
|
|
5
|
-
export function bootstrapProgram() {
|
|
5
|
+
export function bootstrapProgram(options = {}) {
|
|
6
6
|
initializeRuntime();
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
if (!options.headlessDetection?.outputFormat && process.env.NO_COLOR === undefined) {
|
|
8
|
+
// Force global chalk level for interactive output paths.
|
|
9
|
+
chalk.level = 3;
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
chalk.level = 0;
|
|
13
|
+
}
|
|
9
14
|
const program = new Command();
|
|
10
15
|
program.exitOverride();
|
|
11
16
|
program
|
|
@@ -22,7 +22,7 @@ export function registerProgramCommands(program) {
|
|
|
22
22
|
.option('--force-reset', text.cli.forceResetOption)
|
|
23
23
|
.option('--validate', text.cli.validateOption)
|
|
24
24
|
.option('--preflight-policy <policy>', text.cli.preflightPolicyOption, 'lenient')
|
|
25
|
-
.option('--act-mode <mode>', text.cli.actModeOption, '
|
|
25
|
+
.option('--act-mode <mode>', text.cli.actModeOption, 'autopilot')
|
|
26
26
|
.option('--apply-back-on-dirty <mode>', text.cli.applyBackOnDirtyOption, '3way')
|
|
27
27
|
.option('--environment-mode <mode>', text.cli.environmentModeOption, 'strict')
|
|
28
28
|
.option('--worktree-prepare <command>', text.cli.worktreePrepareOption)
|
|
@@ -30,6 +30,10 @@ export function registerProgramCommands(program) {
|
|
|
30
30
|
.option('--include-partial-messages', text.cli.includePartialMessagesOption)
|
|
31
31
|
.option('--output-format <format>', text.cli.outputFormatOption, 'text')
|
|
32
32
|
.option('--output-profile <profile>', text.cli.outputProfileOption)
|
|
33
|
+
.option('--export-patch <path>', text.cli.exportPatchOption)
|
|
34
|
+
.option('--swe-bench-instance-id <id>', text.cli.sweBenchInstanceIdOption)
|
|
35
|
+
.option('--swe-bench-model-name <name>', text.cli.sweBenchModelNameOption)
|
|
36
|
+
.option('--swe-bench-predictions <path>', text.cli.sweBenchPredictionsOption)
|
|
33
37
|
.option('--headless-include-tool-input', text.cli.headlessIncludeToolInputOption)
|
|
34
38
|
.option('--headless-include-tool-output', text.cli.headlessIncludeToolOutputOption)
|
|
35
39
|
.option('--allow-outside-cache-root', text.cli.allowOutsideCacheRootOption)
|
|
@@ -8,13 +8,18 @@ export class AnthropicStreamReporter {
|
|
|
8
8
|
repoPath;
|
|
9
9
|
sessionId;
|
|
10
10
|
writer;
|
|
11
|
+
includeToolInput;
|
|
11
12
|
lastTextResult;
|
|
12
|
-
assembler
|
|
13
|
+
assembler;
|
|
13
14
|
constructor(options = {}) {
|
|
14
15
|
this.mode = options.mode ?? 'run';
|
|
15
16
|
this.repoPath = options.repoPath;
|
|
16
17
|
this.sessionId = options.sessionId ?? randomUUID();
|
|
17
18
|
this.writer = options.writer ?? createStdoutWriter();
|
|
19
|
+
this.includeToolInput = options.includeToolInput ?? false;
|
|
20
|
+
this.assembler = new StreamAssembler({
|
|
21
|
+
deferToolRequestsUntilExecutionInput: this.includeToolInput,
|
|
22
|
+
});
|
|
18
23
|
}
|
|
19
24
|
onStart(instruction) {
|
|
20
25
|
this.emit(encodeAnthropicStart({
|
|
@@ -40,6 +45,7 @@ export class AnthropicStreamReporter {
|
|
|
40
45
|
const lines = encodeNormalizedToAnthropicStreamLines({
|
|
41
46
|
sessionId: this.sessionId,
|
|
42
47
|
event: normalizedEvent,
|
|
48
|
+
includeToolInput: this.includeToolInput,
|
|
43
49
|
});
|
|
44
50
|
for (const line of lines)
|
|
45
51
|
this.emit(line);
|
|
@@ -7,6 +7,7 @@ export class JsonReporter {
|
|
|
7
7
|
sessionId;
|
|
8
8
|
getStructuredOutput;
|
|
9
9
|
getPayloadOverrides;
|
|
10
|
+
getWarnings;
|
|
10
11
|
now;
|
|
11
12
|
writer;
|
|
12
13
|
startedAt = null;
|
|
@@ -18,6 +19,7 @@ export class JsonReporter {
|
|
|
18
19
|
this.sessionId = options.sessionId ?? randomUUID();
|
|
19
20
|
this.getStructuredOutput = options.getStructuredOutput;
|
|
20
21
|
this.getPayloadOverrides = options.getPayloadOverrides;
|
|
22
|
+
this.getWarnings = options.getWarnings;
|
|
21
23
|
this.now = options.now ?? (() => new Date());
|
|
22
24
|
this.writer = options.writer ?? createStdoutWriter();
|
|
23
25
|
}
|
|
@@ -48,6 +50,7 @@ export class JsonReporter {
|
|
|
48
50
|
structuredOutput,
|
|
49
51
|
loopResult: result,
|
|
50
52
|
overrides,
|
|
53
|
+
warnings: this.getWarnings?.(),
|
|
51
54
|
});
|
|
52
55
|
this.writer.writeJsonLine(payload);
|
|
53
56
|
}
|
|
@@ -62,6 +65,7 @@ export class JsonReporter {
|
|
|
62
65
|
startedAt,
|
|
63
66
|
endedAt,
|
|
64
67
|
error,
|
|
68
|
+
warnings: this.getWarnings?.(),
|
|
65
69
|
});
|
|
66
70
|
this.writer.writeJsonLine(payload);
|
|
67
71
|
}
|
|
@@ -10,8 +10,11 @@ export class StreamJsonReporter {
|
|
|
10
10
|
now;
|
|
11
11
|
uuid;
|
|
12
12
|
writer;
|
|
13
|
+
getWarnings;
|
|
13
14
|
lastTextResult;
|
|
14
|
-
|
|
15
|
+
nextEventSeq = 0;
|
|
16
|
+
assembler;
|
|
17
|
+
includeToolInput;
|
|
15
18
|
constructor(options = {}) {
|
|
16
19
|
this.mode = options.mode ?? 'run';
|
|
17
20
|
this.repoPath = options.repoPath;
|
|
@@ -19,6 +22,11 @@ export class StreamJsonReporter {
|
|
|
19
22
|
this.now = options.now ?? (() => new Date());
|
|
20
23
|
this.uuid = options.uuid ?? randomUUID;
|
|
21
24
|
this.writer = options.writer ?? createStdoutWriter();
|
|
25
|
+
this.getWarnings = options.getWarnings;
|
|
26
|
+
this.includeToolInput = options.includeToolInput ?? false;
|
|
27
|
+
this.assembler = new StreamAssembler({
|
|
28
|
+
deferToolRequestsUntilExecutionInput: this.includeToolInput,
|
|
29
|
+
});
|
|
22
30
|
}
|
|
23
31
|
onStart(instruction) {
|
|
24
32
|
this.emit(encodeStreamStart({
|
|
@@ -47,6 +55,7 @@ export class StreamJsonReporter {
|
|
|
47
55
|
sessionId: this.sessionId,
|
|
48
56
|
uuid: this.uuid,
|
|
49
57
|
event: normalizedEvent,
|
|
58
|
+
includeToolInput: this.includeToolInput,
|
|
50
59
|
});
|
|
51
60
|
for (const line of lines)
|
|
52
61
|
this.emit(line);
|
|
@@ -76,6 +85,7 @@ export class StreamJsonReporter {
|
|
|
76
85
|
loopResult: result,
|
|
77
86
|
at,
|
|
78
87
|
resultText: this.lastTextResult,
|
|
88
|
+
warnings: this.getWarnings?.(),
|
|
79
89
|
});
|
|
80
90
|
this.emit(resultLine);
|
|
81
91
|
const exitCode = getStreamExitCode(result);
|
|
@@ -88,6 +98,7 @@ export class StreamJsonReporter {
|
|
|
88
98
|
}));
|
|
89
99
|
}
|
|
90
100
|
onError(error) {
|
|
101
|
+
const auditPath = typeof error.auditPath === 'string' ? error.auditPath : undefined;
|
|
91
102
|
this.emit(encodeStreamFailure({
|
|
92
103
|
uuid: this.uuid(),
|
|
93
104
|
sessionId: this.sessionId,
|
|
@@ -95,6 +106,7 @@ export class StreamJsonReporter {
|
|
|
95
106
|
message: error.message,
|
|
96
107
|
name: error.name,
|
|
97
108
|
stack: error.stack,
|
|
109
|
+
auditPath,
|
|
98
110
|
}));
|
|
99
111
|
this.emit(encodeStreamEnd({
|
|
100
112
|
uuid: this.uuid(),
|
|
@@ -105,7 +117,10 @@ export class StreamJsonReporter {
|
|
|
105
117
|
}));
|
|
106
118
|
}
|
|
107
119
|
emit(line) {
|
|
108
|
-
this.writer.writeJsonLine(
|
|
120
|
+
this.writer.writeJsonLine({
|
|
121
|
+
...line,
|
|
122
|
+
event_seq: line.event_seq ?? this.nextEventSeq++,
|
|
123
|
+
});
|
|
109
124
|
}
|
|
110
125
|
}
|
|
111
126
|
//# sourceMappingURL=stream-json.js.map
|
package/dist/cli/run-cli.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
+
import { detectHeadlessOutputFromArgv } from './argv/headless-detection.js';
|
|
1
2
|
import { createCliRuntimeContext } from './cli-runtime-context.js';
|
|
2
3
|
import { bootstrapProgram } from './program-bootstrap.js';
|
|
3
4
|
import { registerProgramCommands } from './program-commands.js';
|
|
4
5
|
import { configureGlobalProgramOptions } from './program-options.js';
|
|
5
6
|
import { configureProgramOutputForHeadless } from './program-output-mode.js';
|
|
6
7
|
import { parseProgramOrExit } from './program-parse.js';
|
|
7
|
-
export function buildCliProgram() {
|
|
8
|
-
const
|
|
8
|
+
export function buildCliProgram(argv = process.argv) {
|
|
9
|
+
const headlessDetection = detectHeadlessOutputFromArgv(argv);
|
|
10
|
+
const program = bootstrapProgram({ headlessDetection });
|
|
9
11
|
configureGlobalProgramOptions(program);
|
|
10
12
|
registerProgramCommands(program);
|
|
11
13
|
return program;
|
|
12
14
|
}
|
|
13
15
|
export function createCliContextFromArgv(argv) {
|
|
14
|
-
const program = buildCliProgram();
|
|
16
|
+
const program = buildCliProgram(argv);
|
|
15
17
|
return createCliRuntimeContext(program, argv);
|
|
16
18
|
}
|
|
17
19
|
export async function executeCliContext(context) {
|
|
@@ -5,14 +5,22 @@ import { text } from '../locales/index.js';
|
|
|
5
5
|
function isSafeSkillId(id) {
|
|
6
6
|
return /^[a-z0-9][a-z0-9-_]*$/i.test(id);
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Build a SlashCommandSpec from a Tier 1 catalog entry (lightweight metadata).
|
|
10
|
+
*
|
|
11
|
+
* This supports the AgentSkills progressive disclosure pattern: only name and
|
|
12
|
+
* description are needed at startup to populate the slash command registry.
|
|
13
|
+
* Full skill content is loaded on demand via SkillLoader.activateSkill().
|
|
14
|
+
*
|
|
15
|
+
* @see https://agentskills.io/specification — Progressive disclosure
|
|
16
|
+
*/
|
|
17
|
+
function catalogEntryToSlashSpec(entry) {
|
|
18
|
+
const id = String(entry.id || '').trim();
|
|
10
19
|
if (!id || !isSafeSkillId(id))
|
|
11
20
|
return null;
|
|
12
21
|
return {
|
|
13
22
|
name: `/${id}`,
|
|
14
|
-
description:
|
|
15
|
-
hidden: skill.metadata?.userInvocable === false,
|
|
23
|
+
description: entry.description || `Skill: ${id}`,
|
|
16
24
|
order: 220,
|
|
17
25
|
};
|
|
18
26
|
}
|
|
@@ -28,11 +36,15 @@ function commandToSlashSpec(cmd) {
|
|
|
28
36
|
export async function createCliSlashRuntime(options) {
|
|
29
37
|
const skillLoader = new SkillLoader({
|
|
30
38
|
repoRoot: options.repoRoot,
|
|
31
|
-
useDefaults: options.skillDiscovery?.useDefaults,
|
|
32
39
|
extraPaths: options.skillDiscovery?.paths,
|
|
33
40
|
});
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
// Tier 1: Load lightweight catalog (name + description only, ~50-100 tokens per skill).
|
|
42
|
+
// Full skill content is loaded on demand via activateSkill() (Tier 2).
|
|
43
|
+
// @see https://agentskills.io/specification — Progressive disclosure
|
|
44
|
+
const catalog = await skillLoader.loadCatalog();
|
|
45
|
+
const skillSpecs = catalog
|
|
46
|
+
.map(catalogEntryToSlashSpec)
|
|
47
|
+
.filter((s) => Boolean(s));
|
|
36
48
|
const commandSpecs = options.baseCommands.map(commandToSlashSpec);
|
|
37
49
|
// /help is best-effort and must reflect the effective registry (including skills).
|
|
38
50
|
const helpSpec = {
|
|
@@ -51,11 +63,11 @@ export async function createCliSlashRuntime(options) {
|
|
|
51
63
|
}
|
|
52
64
|
}
|
|
53
65
|
const skillBySlash = new Map();
|
|
54
|
-
for (const
|
|
55
|
-
const spec =
|
|
66
|
+
for (const entry of catalog) {
|
|
67
|
+
const spec = catalogEntryToSlashSpec(entry);
|
|
56
68
|
if (!spec)
|
|
57
69
|
continue;
|
|
58
|
-
skillBySlash.set(spec.name.toLowerCase(),
|
|
70
|
+
skillBySlash.set(spec.name.toLowerCase(), entry);
|
|
59
71
|
}
|
|
60
72
|
const handlers = {
|
|
61
73
|
getHandler(commandName) {
|
|
@@ -115,10 +127,13 @@ export async function createCliSlashRuntime(options) {
|
|
|
115
127
|
: undefined,
|
|
116
128
|
};
|
|
117
129
|
}
|
|
118
|
-
const
|
|
119
|
-
if (
|
|
130
|
+
const catalogEntry = skillBySlash.get(normalized);
|
|
131
|
+
if (catalogEntry) {
|
|
120
132
|
return {
|
|
121
133
|
execute: async (req) => {
|
|
134
|
+
// Tier 2: Activate skill on demand — load full SKILL.md content.
|
|
135
|
+
// @see https://agentskills.io/specification — Progressive disclosure
|
|
136
|
+
const skill = await skillLoader.activateSkill(catalogEntry.id);
|
|
122
137
|
const meta = (req.meta ?? {});
|
|
123
138
|
const signal = meta?.signal;
|
|
124
139
|
// Prepare an isolated worktree environment for governed shell execution.
|
|
@@ -9,6 +9,7 @@ import { useCommandSuggestions } from '../hooks/useCommandSuggestions.js';
|
|
|
9
9
|
import { useInputHistory } from '../hooks/useInputHistory.js';
|
|
10
10
|
import { rejectSelection, resolveSelection } from '../selection/bus.js';
|
|
11
11
|
import { useUIStore } from '../store/context.js';
|
|
12
|
+
import { COLORS } from '../styles/theme.js';
|
|
12
13
|
import { CommandSuggestionList } from './CommandSuggestionList.js';
|
|
13
14
|
export const CommandInput = ({ value, onChange, onSubmit, placeholder, getSuggestions, findCommand, }) => {
|
|
14
15
|
const { state, dispatch } = useUIStore();
|
|
@@ -185,16 +186,19 @@ export const CommandInput = ({ value, onChange, onSubmit, placeholder, getSugges
|
|
|
185
186
|
: en.gui.selectionPlaceholder
|
|
186
187
|
: isIntercepting && activeChallenge
|
|
187
188
|
? en.gui.confirmationChallenge(activeChallenge)
|
|
188
|
-
: placeholder }, inputKey), ghostText && (_jsx(Text, { color:
|
|
189
|
+
: placeholder }, inputKey), ghostText && (_jsx(Text, { color: COLORS.text.muted, dimColor: true, children: ghostText }))] }), isIntercepting && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: COLORS.semantic.yellow, paddingX: 1, children: [_jsx(Text, { color: COLORS.semantic.yellow, bold: true, children: isSelecting
|
|
189
190
|
? pendingSelection?.title
|
|
190
191
|
: isAuthorizing
|
|
191
192
|
? en.gui.authorizationTitle
|
|
192
|
-
: en.gui.confirmationTitle }), !isSelecting && (_jsx(Text, { color:
|
|
193
|
+
: en.gui.confirmationTitle }), !isSelecting && (_jsx(Text, { color: COLORS.text.primary, children: isAuthorizing ? pendingAuthorization?.message : pendingConfirmation?.message })), _jsx(Text, { color: COLORS.text.muted, dimColor: true, children: isSelecting
|
|
193
194
|
? isMultiSelecting
|
|
194
195
|
? en.gui.selectionHintMulti
|
|
195
196
|
: en.gui.selectionHint
|
|
196
197
|
: isAuthorizing
|
|
197
198
|
? en.gui.authorizationWarning
|
|
198
|
-
: en.gui.highRiskWarning }), isAuthorizing && (_jsx(Text, { color:
|
|
199
|
+
: en.gui.highRiskWarning }), isAuthorizing && (_jsx(Text, { color: COLORS.text.muted, dimColor: true, children: en.gui.authorizationHint })), isSelecting && pendingSelection && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: pendingSelection.items.map((item, idx) => {
|
|
200
|
+
const isSelected = idx === selectionIndex;
|
|
201
|
+
return (_jsxs(Text, { color: isSelected ? COLORS.semantic.cyan : COLORS.text.muted, children: [isSelected ? '❯ ' : ' ', isMultiSelecting && (_jsx(Text, { color: selectedItems.includes(item.id) ? COLORS.semantic.cyan : COLORS.text.muted, children: selectedItems.includes(item.id) ? '[x] ' : '[ ] ' })), item.label, item.description ? ` - ${item.description}` : ''] }, item.id));
|
|
202
|
+
}) }))] })), !isIntercepting && suggestions.length > 0 && !isListClosed && (_jsx(CommandSuggestionList, { suggestions: visibleSuggestions, selectedIndex: selectedIndex - startIndex, parentCommand: activeCommand }))] }));
|
|
199
203
|
};
|
|
200
204
|
//# sourceMappingURL=CommandInput.js.map
|
|
@@ -14,7 +14,7 @@ export const CommandSuggestionList = ({ suggestions, selectedIndex, parentComman
|
|
|
14
14
|
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: COLORS.border.subtle, marginTop: 0, marginBottom: 0, paddingX: 0, width: "100%", children: [_jsx(Box, { flexDirection: "column", paddingY: 0, children: suggestions.map((item, index) => {
|
|
15
15
|
const isSelected = index === selectedIndex;
|
|
16
16
|
const hasSubcommands = !!item.command?.subcommands?.length;
|
|
17
|
-
return (_jsxs(Box, { flexDirection: "row", paddingX: 1, children: [_jsx(Box, { width: 2, children: _jsx(Text, { color: COLORS.semantic.salmon, children: isSelected ? '│ ' : ' ' }) }), _jsx(Box, { width: maxNameLength + 4, children: _jsx(Text, { color: isSelected ? COLORS.semantic.cyan : COLORS.semantic.blue, bold: isSelected, children: item.name }) }), _jsx(Box, { width: 2, marginRight: 1, children: hasSubcommands ? _jsx(Text, { color: COLORS.text.muted, children: "
|
|
17
|
+
return (_jsxs(Box, { flexDirection: "row", paddingX: 1, children: [_jsx(Box, { width: 2, children: _jsx(Text, { color: COLORS.semantic.salmon, children: isSelected ? '│ ' : ' ' }) }), _jsx(Box, { width: maxNameLength + 4, children: _jsx(Text, { color: isSelected ? COLORS.semantic.cyan : COLORS.semantic.blue, bold: isSelected, children: item.name }) }), _jsx(Box, { width: 2, marginRight: 1, children: hasSubcommands ? _jsx(Text, { color: COLORS.text.muted, children: "\u203A" }) : _jsx(Text, { children: " " }) }), _jsx(Box, { flexGrow: 1, children: _jsx(Text, { color: isSelected ? COLORS.text.primary : COLORS.text.muted, wrap: "truncate", children: item.description }) })] }, `${item.name}-${index}`));
|
|
18
18
|
}) }), suggestions[selectedIndex]?.command?.usage && (_jsxs(Box, { flexDirection: "row", borderStyle: "single", borderTop: true, borderLeft: false, borderRight: false, borderBottom: false, borderColor: COLORS.border.subtle, paddingX: 1, paddingY: 0, children: [_jsx(Text, { color: COLORS.semantic.blue, children: "TIP: " }), _jsx(Text, { color: COLORS.text.muted, children: "Usage: " }), _jsx(Text, { color: COLORS.text.primary, children: suggestions[selectedIndex].command?.usage })] })), _jsxs(Box, { flexDirection: "row", borderStyle: "single", borderTop: true, borderLeft: false, borderRight: false, borderBottom: false, borderColor: COLORS.border.subtle, paddingX: 1, paddingY: 0, justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { color: COLORS.semantic.salmon, children: "\u2502 " }), _jsx(Text, { color: COLORS.semantic.blue, bold: true, children: title })] }), _jsx(Box, { children: _jsx(Text, { color: COLORS.text.muted, dimColor: true, children: "\u2191\u2193 nav \u00B7 \u23CE select \u00B7 esc close" }) })] })] }));
|
|
19
19
|
};
|
|
20
20
|
//# sourceMappingURL=CommandSuggestionList.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function getOptionValueSourceWithGlobalFallback(command, optionName) {
|
|
2
|
+
if (typeof command.getOptionValueSource === 'function') {
|
|
3
|
+
const direct = command.getOptionValueSource(optionName);
|
|
4
|
+
if (direct)
|
|
5
|
+
return direct;
|
|
6
|
+
}
|
|
7
|
+
const parent = command.parent;
|
|
8
|
+
if (parent && typeof parent.getOptionValueSource === 'function') {
|
|
9
|
+
return parent.getOptionValueSource(optionName);
|
|
10
|
+
}
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=command-option-source.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { tryGetLogger } from '../../core/facades/cli-observability.js';
|
|
2
2
|
import { text } from '../../locales/index.js';
|
|
3
3
|
import { autoDetectVerifyCommand } from './detectors/index.js';
|
|
4
4
|
/**
|
|
@@ -8,11 +8,11 @@ import { autoDetectVerifyCommand } from './detectors/index.js';
|
|
|
8
8
|
* 3. Config file command -> "cmd"
|
|
9
9
|
* 4. Auto-detection -> "detected-cmd"
|
|
10
10
|
*/
|
|
11
|
-
export async function resolveVerifyOption(repoPath, cliVerify, configVerify) {
|
|
11
|
+
export async function resolveVerifyOption(repoPath, cliVerify, configVerify, options = {}) {
|
|
12
12
|
// 1. Explicitly disabled via --no-verify
|
|
13
13
|
// Commander sets options.verify to false when --no-verify is used
|
|
14
14
|
if (cliVerify === false) {
|
|
15
|
-
|
|
15
|
+
tryGetLogger()?.debug(text.verify.explicitlyDisabled);
|
|
16
16
|
return undefined;
|
|
17
17
|
}
|
|
18
18
|
// 2. Explicitly provided via CLI --verify "cmd"
|
|
@@ -26,7 +26,11 @@ export async function resolveVerifyOption(repoPath, cliVerify, configVerify) {
|
|
|
26
26
|
// 4. Auto-detect
|
|
27
27
|
const detected = await autoDetectVerifyCommand(repoPath);
|
|
28
28
|
if (detected) {
|
|
29
|
-
|
|
29
|
+
const logger = tryGetLogger();
|
|
30
|
+
if (options.quiet)
|
|
31
|
+
logger?.debug(text.verify.autoDetected(detected));
|
|
32
|
+
else
|
|
33
|
+
logger?.info(text.verify.autoDetected(detected));
|
|
30
34
|
return detected;
|
|
31
35
|
}
|
|
32
36
|
return undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { tryGetLogger } from '../../core/facades/cli-utils-worktree.js';
|
|
2
2
|
import { text } from '../../locales/index.js';
|
|
3
3
|
import { autoDetectWorktreePrepareCommand } from './detectors/index.js';
|
|
4
|
-
export async function resolveWorktreePrepareOption(repoPath, strategy, cliWorktreePrepare) {
|
|
4
|
+
export async function resolveWorktreePrepareOption(repoPath, strategy, cliWorktreePrepare, options = {}) {
|
|
5
5
|
if (typeof cliWorktreePrepare === 'string' && cliWorktreePrepare.trim()) {
|
|
6
6
|
return cliWorktreePrepare;
|
|
7
7
|
}
|
|
@@ -10,7 +10,11 @@ export async function resolveWorktreePrepareOption(repoPath, strategy, cliWorktr
|
|
|
10
10
|
}
|
|
11
11
|
const detected = await autoDetectWorktreePrepareCommand(repoPath);
|
|
12
12
|
if (detected) {
|
|
13
|
-
|
|
13
|
+
const logger = tryGetLogger();
|
|
14
|
+
if (options.quiet)
|
|
15
|
+
logger?.debug(text.verify.autoDetectedWorktreePrepare(detected));
|
|
16
|
+
else
|
|
17
|
+
logger?.info(text.verify.autoDetectedWorktreePrepare(detected));
|
|
14
18
|
return detected;
|
|
15
19
|
}
|
|
16
20
|
return undefined;
|
|
@@ -73,6 +73,12 @@ export class FileAdapter {
|
|
|
73
73
|
async stat(filePath) {
|
|
74
74
|
return fs.stat(filePath);
|
|
75
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Get file stats without following symlinks.
|
|
78
|
+
*/
|
|
79
|
+
async lstat(filePath) {
|
|
80
|
+
return fs.lstat(filePath);
|
|
81
|
+
}
|
|
76
82
|
/**
|
|
77
83
|
* Create directory recursively
|
|
78
84
|
*/
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveExecutionProfile } from '../../runtime/execution-profile.js';
|
|
1
2
|
import { FileAdapter } from './file-adapter.js';
|
|
2
3
|
import { ReadOnlyFileSystem } from './readonly-filesystem.js';
|
|
3
4
|
class FileAdapterFileSystem {
|
|
@@ -23,7 +24,7 @@ class FileAdapterFileSystem {
|
|
|
23
24
|
* Review mode returns a ReadOnlyFileSystem to block writes.
|
|
24
25
|
*/
|
|
25
26
|
export function createFileSystemAdapter(mode, realFs = new FileAdapterFileSystem()) {
|
|
26
|
-
if (mode
|
|
27
|
+
if (resolveExecutionProfile(mode).readOnly) {
|
|
27
28
|
return new ReadOnlyFileSystem(realFs);
|
|
28
29
|
}
|
|
29
30
|
return realFs;
|