salmon-loop 0.3.2 → 0.5.0
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/authorization/non-interactive.js +9 -13
- package/dist/cli/authorization/provider.js +2 -10
- package/dist/cli/chat.js +12 -6
- package/dist/cli/commands/allowlist.js +1 -1
- package/dist/cli/commands/chat.js +13 -13
- package/dist/cli/commands/config.js +2 -2
- package/dist/cli/commands/mode.js +2 -2
- package/dist/cli/commands/parallel.js +1 -1
- package/dist/cli/commands/run/handler.js +9 -4
- package/dist/cli/commands/run/loop-params.js +2 -0
- package/dist/cli/commands/run/parse-options.js +14 -26
- package/dist/cli/commands/run/runtime-llm.js +15 -12
- package/dist/cli/commands/run/runtime-options.js +3 -1
- package/dist/cli/config.js +0 -8
- package/dist/cli/headless/openai-responses-canonical-applier.js +1 -7
- package/dist/cli/locales/en.js +2 -2
- package/dist/cli/reporters/standard.js +12 -3
- package/dist/cli/reporters/stream-json.js +2 -1
- package/dist/cli/slash/runtime.js +2 -2
- package/dist/cli/ui/hooks/useLoopEvents.js +1 -1
- package/dist/cli/ui/hooks/useLoopState.js +1 -1
- package/dist/core/adapters/fs/file-adapter.js +3 -1
- package/dist/core/adapters/git/git-adapter.js +6 -3
- package/dist/core/adapters/git/git-runner.js +5 -2
- package/dist/core/adapters/git/lock-manager.js +7 -4
- package/dist/core/ast/parser.js +18 -9
- package/dist/core/checkpoint-domain/manifest-store.js +21 -13
- package/dist/core/checkpoint-domain/service.js +3 -1
- package/dist/core/config/limits.js +1 -1
- package/dist/core/config/model-pricing.js +61 -0
- package/dist/core/config/schema.js +738 -0
- package/dist/core/config/validate.js +11 -922
- package/dist/core/context/ast/skeleton-extractor.js +225 -0
- package/dist/core/context/ast/source-outline.js +24 -1
- package/dist/core/context/budget/dynamic-adjuster.js +20 -5
- package/dist/core/context/builder.js +7 -3
- package/dist/core/context/cache/store-factory.js +3 -1
- package/dist/core/context/dependencies.js +2 -1
- package/dist/core/context/effectiveness/persistence.js +50 -0
- package/dist/core/context/effectiveness/tracker.js +24 -0
- package/dist/core/context/gatherers/architecture-gatherer.js +2 -1
- package/dist/core/context/gatherers/artifact-gatherer.js +7 -4
- package/dist/core/context/gatherers/ast-gatherer.js +34 -40
- package/dist/core/context/gatherers/ghost-dependency-gatherer.js +0 -1
- package/dist/core/context/gatherers/git-history-gatherer.js +3 -1
- package/dist/core/context/gatherers/knowledge-gatherer.js +21 -2
- package/dist/core/context/gatherers/metadata-gatherer.js +12 -7
- package/dist/core/context/gatherers/ripgrep-gatherer.js +6 -3
- package/dist/core/context/service.js +12 -2
- package/dist/core/context/steps/context-gather.js +14 -3
- package/dist/core/context/steps/context-targets.js +1 -0
- package/dist/core/context/targeting/target-resolver.js +29 -11
- package/dist/core/context/token/cache.js +5 -2
- package/dist/core/context/token/encoding-registry.js +7 -6
- package/dist/core/context/truncation/strategies/json.js +5 -2
- package/dist/core/context/truncation/type-detector.js +3 -1
- package/dist/core/extensions/index.js +48 -3
- package/dist/core/extensions/load.js +3 -2
- package/dist/core/extensions/merge.js +5 -1
- package/dist/core/extensions/paths.js +8 -2
- package/dist/core/extensions/schemas.js +21 -0
- package/dist/core/facades/cli-authorization-provider.js +1 -0
- package/dist/core/facades/cli-command-chat.js +2 -0
- package/dist/core/facades/cli-run-handler.js +1 -0
- package/dist/core/facades/cli-utils-serialize.js +2 -0
- package/dist/core/feedback/parsers.js +290 -1
- package/dist/core/grizzco/dsl/llm-strategy.js +4 -3
- package/dist/core/grizzco/engine/observability/loop-telemetry.js +5 -2
- package/dist/core/grizzco/engine/outcome/loop-result-mapper.js +30 -13
- package/dist/core/grizzco/engine/pipeline/pipeline.js +149 -240
- package/dist/core/grizzco/engine/transaction/attempt-failure.js +49 -24
- package/dist/core/grizzco/engine/transaction/authorization-summary.js +2 -1
- package/dist/core/grizzco/engine/transaction/transaction-runner.js +40 -34
- package/dist/core/grizzco/execution/RejectionManager.js +7 -5
- package/dist/core/grizzco/runtime/apply-back-runtime.js +5 -2
- package/dist/core/grizzco/services/implementations/default/GitConfigService.js +2 -1
- package/dist/core/grizzco/services/registry.js +18 -0
- package/dist/core/grizzco/steps/audit.js +20 -10
- package/dist/core/grizzco/steps/autopilot.js +21 -32
- package/dist/core/grizzco/steps/display-report.js +4 -11
- package/dist/core/grizzco/steps/explore.js +14 -4
- package/dist/core/grizzco/steps/generateReview.js +3 -1
- package/dist/core/grizzco/steps/patch/prompt-input.js +4 -1
- package/dist/core/grizzco/steps/patch.js +1 -0
- package/dist/core/grizzco/steps/plan.js +58 -49
- package/dist/core/grizzco/steps/research.js +3 -1
- package/dist/core/grizzco/steps/tool-runtime.js +3 -0
- package/dist/core/grizzco/steps/verify.js +7 -1
- package/dist/core/grizzco/validation/AstValidationService.js +3 -1
- package/dist/core/grizzco/workers/strata-sync-worker.js +2 -1
- package/dist/core/history/input-history.js +3 -1
- package/dist/core/intent/chat-intent.js +3 -1
- package/dist/core/llm/ai-sdk/message-mapper.js +37 -26
- package/dist/core/llm/ai-sdk/request-params.js +2 -6
- package/dist/core/llm/ai-sdk/result-mapper.js +14 -8
- package/dist/core/llm/ai-sdk/retry-classifier.js +17 -7
- package/dist/core/llm/ai-sdk/retry-executor.js +1 -1
- package/dist/core/llm/contracts/repair.js +16 -8
- package/dist/core/llm/errors.js +18 -14
- package/dist/core/llm/output-policy.js +8 -0
- package/dist/core/llm/redact.js +1 -3
- package/dist/core/llm/retry-utils.js +8 -2
- package/dist/core/llm/stream-utils.js +5 -3
- package/dist/core/llm/sub-agent-factory.js +51 -0
- package/dist/core/llm/tool-calling-stub.js +48 -0
- package/dist/core/llm/utils.js +17 -6
- package/dist/core/mcp/bridge/prompt-command-provider.js +4 -3
- package/dist/core/mcp/bridge/resource-context-provider.js +3 -1
- package/dist/core/mcp/bridge/tool-bridge.js +5 -14
- package/dist/core/mcp/catalog/discovery.js +3 -1
- package/dist/core/mcp/client/connection-manager.js +7 -4
- package/dist/core/mcp/client/transport-factory.js +7 -3
- package/dist/core/mcp/host/sampling-provider.js +1 -1
- package/dist/core/mcp/schema/json-schema-to-zod.js +2 -1
- package/dist/core/memory/relevant-retrieval.js +6 -4
- package/dist/core/observability/audit-file.js +2 -1
- package/dist/core/observability/audit-trail.js +3 -1
- package/dist/core/observability/authorization-decisions.js +13 -12
- package/dist/core/observability/error-mapping.js +2 -1
- package/dist/core/observability/logger.js +2 -1
- package/dist/core/observability/monitor.js +24 -0
- package/dist/core/observability/run-outcome-reporter.js +1 -0
- package/dist/core/observability/token-usage.js +5 -4
- package/dist/core/permission-gate/default-gate.js +5 -8
- package/dist/core/plan/storage.js +7 -4
- package/dist/core/plugin/loader.js +8 -5
- package/dist/core/prompts/registry.js +12 -30
- package/dist/core/prompts/runtime.js +3 -1
- package/dist/core/prompts/templates/system/autopilot_system.hbs +28 -4
- package/dist/core/protocols/a2a/sdk/executor.js +3 -1
- package/dist/core/protocols/a2a/sdk/server.js +5 -4
- package/dist/core/protocols/acp/acp-command-runner.js +7 -6
- package/dist/core/protocols/acp/acp-session-persistence.js +13 -10
- package/dist/core/protocols/acp/formal-agent.js +13 -6
- package/dist/core/protocols/acp/permission-provider.js +3 -2
- package/dist/core/protocols/acp/stdio-server.js +6 -6
- package/dist/core/reflection/engine.js +114 -14
- package/dist/core/runtime/agent-server-runtime.js +3 -2
- package/dist/core/runtime/batch-runner.js +81 -0
- package/dist/core/runtime/initialize.js +71 -6
- package/dist/core/runtime/loop-finalize.js +3 -0
- package/dist/core/runtime/loop-session-runner.js +5 -0
- package/dist/core/runtime/loop.js +4 -0
- package/dist/core/runtime/paths.js +9 -6
- package/dist/core/runtime/spawn-interactive.js +5 -4
- package/dist/core/security/redaction.js +3 -2
- package/dist/core/session/compaction/index.js +4 -3
- package/dist/core/session/compression.js +3 -1
- package/dist/core/session/manager.js +26 -38
- package/dist/core/session/pruning-strategy.js +2 -1
- package/dist/core/session/token-tracker.js +27 -9
- package/dist/core/skills/parser.js +3 -2
- package/dist/core/skills/permissions.js +2 -2
- package/dist/core/skills/runtime/MicroTaskRunner.js +1 -1
- package/dist/core/skills/runtime/SkillRunner.js +5 -2
- package/dist/core/slash/steps/slash-execute.js +7 -5
- package/dist/core/slash/strategy.js +1 -1
- package/dist/core/strata/checkpoint/manager.js +16 -10
- package/dist/core/strata/checkpoint/snapshot-create.js +5 -4
- package/dist/core/strata/checkpoint/snapshot-write-tree.js +7 -3
- package/dist/core/strata/engine/shadow-merge-engine.js +4 -2
- package/dist/core/strata/interaction/file-system-provider.js +2 -1
- package/dist/core/strata/layers/file-state-resolver.js +9 -7
- package/dist/core/strata/layers/immutable-git-layer.js +3 -1
- package/dist/core/strata/layers/shadow-driver/readonly-lock.js +8 -6
- package/dist/core/strata/layers/shadow-driver/shadow-driver.js +2 -1
- package/dist/core/strata/layers/worktree.js +9 -10
- package/dist/core/strata/runtime/environment.js +2 -1
- package/dist/core/strata/runtime/synchronizer.js +28 -26
- package/dist/core/streaming/canonical/parts-from-llm-stream-chunk.js +1 -11
- package/dist/core/structured-output/json-extract.js +3 -1
- package/dist/core/structured-output/json-schema-validator.js +1 -13
- package/dist/core/sub-agent/artifacts/store.js +2 -1
- package/dist/core/sub-agent/context-snapshot.js +12 -6
- package/dist/core/sub-agent/controller.js +70 -1
- package/dist/core/sub-agent/core/loop.js +25 -3
- package/dist/core/sub-agent/core/manager.js +343 -117
- package/dist/core/sub-agent/registry-defaults.js +12 -0
- package/dist/core/sub-agent/registry.js +8 -0
- package/dist/core/sub-agent/summary.js +96 -0
- package/dist/core/sub-agent/team.js +98 -0
- package/dist/core/sub-agent/tools/task-await.js +109 -0
- package/dist/core/sub-agent/tools/task-spawn.js +52 -7
- package/dist/core/sub-agent/tools/team.js +92 -0
- package/dist/core/sub-agent/types.js +11 -2
- package/dist/core/target-runtime/profile.js +3 -1
- package/dist/core/tools/audit.js +3 -2
- package/dist/core/tools/budget.js +7 -12
- package/dist/core/tools/builtin/ast.js +144 -0
- package/dist/core/tools/builtin/code-search/backends/powershell.js +3 -1
- package/dist/core/tools/builtin/code-search/backends/rg.js +3 -1
- package/dist/core/tools/builtin/code-search/executor.js +46 -43
- package/dist/core/tools/builtin/code-search/parse/plain-grep.js +3 -1
- package/dist/core/tools/builtin/code-search/parse/rg-json.js +3 -1
- package/dist/core/tools/builtin/fs.js +90 -7
- package/dist/core/tools/builtin/git.js +242 -0
- package/dist/core/tools/builtin/glob.js +79 -0
- package/dist/core/tools/builtin/index.js +53 -111
- package/dist/core/tools/builtin/interaction.js +13 -15
- package/dist/core/tools/builtin/knowledge.js +146 -4
- package/dist/core/tools/builtin/proposal.js +14 -3
- package/dist/core/tools/builtin/verify.js +35 -3
- package/dist/core/tools/capability/executor.js +5 -5
- package/dist/core/tools/headless-payload.js +1 -3
- package/dist/core/tools/mapper.js +8 -42
- package/dist/core/tools/parallel/persistence.js +17 -5
- package/dist/core/tools/parallel/scheduler.js +23 -21
- package/dist/core/tools/permissions/permission-rules.js +69 -115
- package/dist/core/tools/plugins/loader.js +4 -3
- package/dist/core/tools/router.js +112 -58
- package/dist/core/tools/session.js +64 -102
- package/dist/core/tools/streaming/ToolCallAccumulator.js +1 -3
- package/dist/core/tools/tool-visibility.js +2 -1
- package/dist/core/tools/types.js +10 -0
- package/dist/core/types/batch.js +2 -0
- package/dist/core/utils/error.js +79 -0
- package/dist/core/utils/sanitizer.js +5 -2
- package/dist/core/utils/serialize.js +66 -0
- package/dist/core/utils/zod.js +29 -0
- package/dist/core/verification/detect-runner.js +86 -0
- package/dist/core/verification/runner.js +76 -0
- package/dist/core/version.js +3 -1
- package/dist/core/workspace/capabilities.js +3 -2
- package/dist/integrations/langfuse/litellm-langfuse-outcome-reporter.js +9 -8
- package/dist/languages/python/index.js +154 -0
- package/dist/locales/en.js +8 -1
- package/package.json +2 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { execa } from 'execa';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { getLogger, McpConnectionManager, } from '../../core/facades/cli-authorization-non-interactive.js';
|
|
4
|
+
import { isRecord } from '../../core/facades/cli-utils-serialize.js';
|
|
4
5
|
import { text } from '../locales/index.js';
|
|
5
6
|
const DecisionSchema = z
|
|
6
7
|
.object({
|
|
@@ -22,24 +23,19 @@ function findMcpServer(extensions, name) {
|
|
|
22
23
|
return extensions.mcpServers.find((s) => s.enabled && s.name === name);
|
|
23
24
|
}
|
|
24
25
|
function extractDecisionPayloadFromMcpResult(result) {
|
|
25
|
-
if (!result
|
|
26
|
+
if (!isRecord(result))
|
|
26
27
|
return result;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const content = obj.content;
|
|
28
|
+
if (isRecord(result.decision))
|
|
29
|
+
return result.decision;
|
|
30
|
+
if (typeof result.outcome === 'string')
|
|
31
|
+
return result;
|
|
32
|
+
const content = result.content;
|
|
33
33
|
if (!Array.isArray(content))
|
|
34
34
|
return result;
|
|
35
35
|
for (const item of content) {
|
|
36
|
-
if (!item
|
|
36
|
+
if (!isRecord(item))
|
|
37
37
|
continue;
|
|
38
|
-
const candidate = item.json ??
|
|
39
|
-
item.text ??
|
|
40
|
-
item.value ??
|
|
41
|
-
item.data ??
|
|
42
|
-
undefined;
|
|
38
|
+
const candidate = item.json ?? item.text ?? item.value ?? item.data ?? undefined;
|
|
43
39
|
if (typeof candidate === 'string' && candidate.trim()) {
|
|
44
40
|
try {
|
|
45
41
|
return JSON.parse(candidate);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { createInterface } from 'readline/promises';
|
|
2
|
-
import { getLogger } from '../../core/facades/cli-authorization-provider.js';
|
|
3
|
-
import { TOOL_AUTH_CONFIG } from '../config.js';
|
|
2
|
+
import { DEFAULT_TOOL_AUTH, getLogger } from '../../core/facades/cli-authorization-provider.js';
|
|
4
3
|
import { text } from '../locales/index.js';
|
|
5
4
|
import { getPendingAuthorization, requestAuthorization } from '../ui/authorization/bus.js';
|
|
6
5
|
import { loadAllowlistDecision, persistAllowlistDecision } from './allowlist.js';
|
|
@@ -27,14 +26,7 @@ const shouldAutoAllow = (request, config) => {
|
|
|
27
26
|
const resolveConfig = (config) => {
|
|
28
27
|
if (config)
|
|
29
28
|
return config;
|
|
30
|
-
return
|
|
31
|
-
sessionTtlMs: TOOL_AUTH_CONFIG.SESSION_TTL_MS,
|
|
32
|
-
autoAllowRisk: TOOL_AUTH_CONFIG.AUTO_ALLOW_RISK,
|
|
33
|
-
allowlist: {
|
|
34
|
-
repoFile: '.salmonloop/config/authorization.json',
|
|
35
|
-
userFile: '~/.salmonloop/config/authorization-user.json',
|
|
36
|
-
},
|
|
37
|
-
};
|
|
29
|
+
return DEFAULT_TOOL_AUTH;
|
|
38
30
|
};
|
|
39
31
|
export function createUiAuthorizationProvider(options) {
|
|
40
32
|
const pending = new Map();
|
package/dist/cli/chat.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { buildSessionArtifactStateFromLoopResult, buildEffectiveConversationContext, ChatSessionManager, DEFAULT_LLM_OUTPUT_POLICY, emitLlmOutput, getDefaultSessionContextBudgetTokens, InputHistoryManager, logIgnoredError, getLogger, refreshSessionSummary, runSalmonLoop, TokenTracker, createInitialTracking, onNormalTurnComplete, runCompactionPipeline, reactiveCompact, } from '../core/facades/cli-chat.js';
|
|
2
2
|
import { createSubAgentController } from '../core/facades/cli-subagent.js';
|
|
3
|
+
import { isRecord } from '../core/facades/cli-utils-serialize.js';
|
|
3
4
|
import { createUiAuthorizationProvider } from './authorization/provider.js';
|
|
4
5
|
import { resolveActiveChatFlowMode, resolveChatCheckpointStrategy } from './chat-flow.js';
|
|
5
6
|
import { commands } from './commands/registry.js';
|
|
@@ -66,8 +67,9 @@ export async function startChatMode(options) {
|
|
|
66
67
|
const answers = {};
|
|
67
68
|
for (const question of input.questions) {
|
|
68
69
|
if (requestOptions?.signal?.aborted) {
|
|
69
|
-
const err = new Error(text.cli.askUserCancelled)
|
|
70
|
-
|
|
70
|
+
const err = Object.assign(new Error(text.cli.askUserCancelled), {
|
|
71
|
+
code: 'ASK_USER_CANCELLED',
|
|
72
|
+
});
|
|
71
73
|
throw err;
|
|
72
74
|
}
|
|
73
75
|
const items = question.options.map((opt) => ({
|
|
@@ -84,8 +86,9 @@ export async function startChatMode(options) {
|
|
|
84
86
|
multiSelect: question.multiSelect,
|
|
85
87
|
});
|
|
86
88
|
if (!selected || selected.length === 0) {
|
|
87
|
-
const err = new Error(text.cli.askUserCancelled)
|
|
88
|
-
|
|
89
|
+
const err = Object.assign(new Error(text.cli.askUserCancelled), {
|
|
90
|
+
code: 'ASK_USER_CANCELLED',
|
|
91
|
+
});
|
|
89
92
|
throw err;
|
|
90
93
|
}
|
|
91
94
|
const answer = question.multiSelect ? selected.join(', ') : (selected[0] ?? '');
|
|
@@ -299,6 +302,7 @@ export async function startChatMode(options) {
|
|
|
299
302
|
authorizationMode: 'deferred',
|
|
300
303
|
userInputProvider,
|
|
301
304
|
subAgentController,
|
|
305
|
+
llmFactory: options.llmFactory,
|
|
302
306
|
permissionMode: options.permissionMode,
|
|
303
307
|
}).catch(async (error) => {
|
|
304
308
|
// Level 2: Reactive Compact
|
|
@@ -307,13 +311,14 @@ export async function startChatMode(options) {
|
|
|
307
311
|
const isContextOverflow = (() => {
|
|
308
312
|
if (!error || typeof error !== 'object')
|
|
309
313
|
return false;
|
|
310
|
-
if (
|
|
314
|
+
if (isRecord(error) &&
|
|
315
|
+
'llmCode' in error &&
|
|
311
316
|
error.llmCode === 'LLM_CONTEXT_LENGTH_EXCEEDED') {
|
|
312
317
|
return true;
|
|
313
318
|
}
|
|
314
319
|
const message = error instanceof Error
|
|
315
320
|
? error.message
|
|
316
|
-
: typeof error.message === 'string'
|
|
321
|
+
: isRecord(error) && typeof error.message === 'string'
|
|
317
322
|
? String(error.message)
|
|
318
323
|
: '';
|
|
319
324
|
const lower = message.toLowerCase();
|
|
@@ -382,6 +387,7 @@ export async function startChatMode(options) {
|
|
|
382
387
|
authorizationMode: 'deferred',
|
|
383
388
|
userInputProvider,
|
|
384
389
|
subAgentController,
|
|
390
|
+
llmFactory: options.llmFactory,
|
|
385
391
|
permissionMode: options.permissionMode,
|
|
386
392
|
});
|
|
387
393
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EXECUTION_PHASES, getLogger } from '../../core/facades/cli-command-allowlist.js';
|
|
1
|
+
import { EXECUTION_PHASES, getLogger, } from '../../core/facades/cli-command-allowlist.js';
|
|
2
2
|
import { clearAllowlist, clearAllowlistCache, listAllowlist, persistAllowlistDecision, removeAllowlistRule, } from '../authorization/allowlist.js';
|
|
3
3
|
import { text } from '../locales/index.js';
|
|
4
4
|
import { clearKnownToolNames, getKnownToolNames, getKnownToolNamesSync, validateSideEffects, } from './tool-names.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createPluginRegistry, createPromptRegistry, createRuntimeLlm, setPluginRegistry, setPromptRegistry, ExtensionConfigError, getLogger, normalizePermissionMode, PluginLoader, resolveExecutionProfile, resolveExtensions, } from '../../core/facades/cli-command-chat.js';
|
|
1
|
+
import { createPluginRegistry, createPromptRegistry, createRuntimeLlm, createSubAgentLlmFactory, getString, setPluginRegistry, setPromptRegistry, ExtensionConfigError, getLogger, normalizePermissionMode, PluginLoader, resolveExecutionProfile, resolveExtensions, } from '../../core/facades/cli-command-chat.js';
|
|
2
2
|
import { text } from '../locales/index.js';
|
|
3
3
|
import { getOptionValueSourceWithGlobalFallback } from '../utils/command-option-source.js';
|
|
4
4
|
import { resolveLlmOutputPolicyFromCli } from '../utils/llm-output.js';
|
|
@@ -8,26 +8,22 @@ import { resolveVerifyOption } from '../utils/verify-resolver.js';
|
|
|
8
8
|
export async function handleChatCommand(options, command) {
|
|
9
9
|
const allOptions = command.optsWithGlobals();
|
|
10
10
|
const configResult = await resolveCliConfig({
|
|
11
|
-
repo: allOptions
|
|
11
|
+
repo: getString(allOptions, 'repo') ?? undefined,
|
|
12
12
|
cwd: process.cwd(),
|
|
13
|
-
configPath: allOptions
|
|
13
|
+
configPath: getString(allOptions, 'config') ?? undefined,
|
|
14
14
|
enableConfigFile: allOptions.configFile !== false,
|
|
15
|
-
auditScope: allOptions
|
|
15
|
+
auditScope: getString(allOptions, 'auditScope') ?? undefined,
|
|
16
16
|
verbose: allOptions.verbose,
|
|
17
|
-
logMode: allOptions
|
|
17
|
+
logMode: getString(allOptions, 'logMode') ?? undefined,
|
|
18
18
|
});
|
|
19
19
|
if (!configResult.ok) {
|
|
20
20
|
getLogger().error(configResult.message, true);
|
|
21
21
|
process.exit(1);
|
|
22
22
|
}
|
|
23
23
|
const { resolvedConfig, auditScope, repoPath: runPath, verboseLevel } = configResult;
|
|
24
|
-
const printInstruction =
|
|
25
|
-
? allOptions.print
|
|
26
|
-
: undefined;
|
|
24
|
+
const printInstruction = getString(allOptions, 'print') ?? undefined;
|
|
27
25
|
const continueSession = Boolean(allOptions.continue);
|
|
28
|
-
const resumeSessionId =
|
|
29
|
-
? allOptions.resume
|
|
30
|
-
: undefined;
|
|
26
|
+
const resumeSessionId = getString(allOptions, 'resume') ?? undefined;
|
|
31
27
|
if (printInstruction) {
|
|
32
28
|
getLogger().error(text.cli.printCommandConflict('chat'), true);
|
|
33
29
|
process.exit(1);
|
|
@@ -54,7 +50,7 @@ export async function handleChatCommand(options, command) {
|
|
|
54
50
|
getLogger().error(`Invalid --mode "${String(rawPermissionMode)}". Expected "interactive" or "yolo".`);
|
|
55
51
|
process.exit(1);
|
|
56
52
|
}
|
|
57
|
-
const llmOutputResolution = resolveLlmOutputPolicyFromCli(resolvedConfig.llmOutput, allOptions
|
|
53
|
+
const llmOutputResolution = resolveLlmOutputPolicyFromCli(resolvedConfig.llmOutput, getString(allOptions, 'llmOutput') ?? undefined);
|
|
58
54
|
if (!llmOutputResolution.ok) {
|
|
59
55
|
getLogger().error(text.cli.invalidLlmOutputKind(llmOutputResolution.invalid), true);
|
|
60
56
|
process.exitCode = 1;
|
|
@@ -64,6 +60,7 @@ export async function handleChatCommand(options, command) {
|
|
|
64
60
|
const { llm } = createRuntimeLlm(resolvedConfig.llm, {
|
|
65
61
|
langfuseEnabled: resolvedConfig.observability.langfuse.enabled,
|
|
66
62
|
});
|
|
63
|
+
const llmFactory = createSubAgentLlmFactory(resolvedConfig.llm);
|
|
67
64
|
const outcomeReporter = createOutcomeReporter({
|
|
68
65
|
enabled: resolvedConfig.observability.langfuse.outcome,
|
|
69
66
|
endpoint: resolvedConfig.observability.langfuse.endpoint,
|
|
@@ -71,7 +68,9 @@ export async function handleChatCommand(options, command) {
|
|
|
71
68
|
langfuseApiKey: resolvedConfig.observability.langfuse.apiKey,
|
|
72
69
|
});
|
|
73
70
|
// Smart verification resolution with auto-detection
|
|
74
|
-
const
|
|
71
|
+
const verifyRaw = allOptions.verify;
|
|
72
|
+
const verifyCliOption = typeof verifyRaw === 'string' || typeof verifyRaw === 'boolean' ? verifyRaw : undefined;
|
|
73
|
+
const verifyCommand = await resolveVerifyOption(runPath, verifyCliOption, resolvedConfig.verify.command);
|
|
75
74
|
// Verification is now optional - the loop will skip if undefined
|
|
76
75
|
if (!verifyCommand) {
|
|
77
76
|
getLogger().warn(text.verify.noCommandFound);
|
|
@@ -115,6 +114,7 @@ export async function handleChatCommand(options, command) {
|
|
|
115
114
|
langfuseSessionId: resolvedConfig.observability.langfuse.sessionId,
|
|
116
115
|
langfuseUserId: resolvedConfig.observability.langfuse.userId,
|
|
117
116
|
languagePlugins,
|
|
117
|
+
llmFactory,
|
|
118
118
|
});
|
|
119
119
|
}
|
|
120
120
|
catch (err) {
|
|
@@ -169,9 +169,9 @@ const permissionModeSubcommand = {
|
|
|
169
169
|
usage: text.cli.configPermissionModeUsage,
|
|
170
170
|
getSuggestions: (ctx) => modeCommand.getSuggestions?.({
|
|
171
171
|
...ctx,
|
|
172
|
-
input: delegateInputToCommand(ctx.input, '/mode'),
|
|
172
|
+
input: delegateInputToCommand(ctx.input, '/permission-mode'),
|
|
173
173
|
}) ?? [],
|
|
174
|
-
execute: async (ctx) => modeCommand.execute({ ...ctx, input: delegateInputToCommand(ctx.input, '/mode') }),
|
|
174
|
+
execute: async (ctx) => modeCommand.execute({ ...ctx, input: delegateInputToCommand(ctx.input, '/permission-mode') }),
|
|
175
175
|
};
|
|
176
176
|
const outputSubcommand = {
|
|
177
177
|
name: 'output',
|
|
@@ -41,8 +41,8 @@ async function persistPermissionMode(repoRoot, mode) {
|
|
|
41
41
|
return configPath;
|
|
42
42
|
}
|
|
43
43
|
export const modeCommand = {
|
|
44
|
-
name: '/mode',
|
|
45
|
-
aliases: ['/
|
|
44
|
+
name: '/permission-mode',
|
|
45
|
+
aliases: ['/mode', '/perm-mode'],
|
|
46
46
|
description: text.cli.commandMode,
|
|
47
47
|
order: 53,
|
|
48
48
|
getSuggestions: ({ input }) => {
|
|
@@ -198,7 +198,7 @@ export const parallelCommand = {
|
|
|
198
198
|
});
|
|
199
199
|
try {
|
|
200
200
|
const scheduler = new ParallelScheduler(toolstack.router, new InMemoryLockManager());
|
|
201
|
-
const phase = state.runtime?.phase
|
|
201
|
+
const phase = state.runtime?.phase ?? 'PATCH';
|
|
202
202
|
const runtime = {
|
|
203
203
|
repoRoot: workspace.workPath,
|
|
204
204
|
worktreeRoot: workspace.workPath,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
|
-
import { buildEffectiveConversationContext, createPluginRegistry, createPromptRegistry, getExitCode, getDefaultSessionContextBudgetTokens, getLogger, normalizePermissionMode, resolveExecutionProfile, SilentReporter, setPluginRegistry, setPromptRegistry, } from '../../../core/facades/cli-run-handler.js';
|
|
2
|
+
import { buildEffectiveConversationContext, createPluginRegistry, createPromptRegistry, createSubAgentLlmFactory, getExitCode, getDefaultSessionContextBudgetTokens, getLogger, normalizePermissionMode, resolveExecutionProfile, SilentReporter, setPluginRegistry, setPromptRegistry, } from '../../../core/facades/cli-run-handler.js';
|
|
3
3
|
import { createStdoutWriter } from '../../headless/stdout-writer.js';
|
|
4
4
|
import { text } from '../../locales/index.js';
|
|
5
5
|
import { getOptionValueSourceWithGlobalFallback } from '../../utils/command-option-source.js';
|
|
@@ -201,6 +201,7 @@ export async function handleRunCommand(options, command) {
|
|
|
201
201
|
const llmOutput = runtimeOptions.llmOutput;
|
|
202
202
|
const effectiveVerify = runtimeOptions.effectiveVerify;
|
|
203
203
|
const effectiveWorktreePrepare = runtimeOptions.effectiveWorktreePrepare;
|
|
204
|
+
const verifyPolicyOverride = runtimeOptions.verifyPolicyOverride;
|
|
204
205
|
const instructionGuard = ensureInstructionOrExit({
|
|
205
206
|
command,
|
|
206
207
|
instruction,
|
|
@@ -303,7 +304,7 @@ export async function handleRunCommand(options, command) {
|
|
|
303
304
|
}
|
|
304
305
|
const extensionResolution = extensionsResult.extensionResolution;
|
|
305
306
|
const operationalHeadlessWarnings = [];
|
|
306
|
-
if (!effectiveVerify) {
|
|
307
|
+
if (!effectiveVerify && !verifyPolicyOverride) {
|
|
307
308
|
if (!headlessOutput) {
|
|
308
309
|
getLogger().warn(text.verify.noCommandFound);
|
|
309
310
|
}
|
|
@@ -338,6 +339,7 @@ export async function handleRunCommand(options, command) {
|
|
|
338
339
|
langfuseEnabled: resolvedConfig.observability.langfuse.enabled,
|
|
339
340
|
headlessOutput,
|
|
340
341
|
});
|
|
342
|
+
const llmFactory = createSubAgentLlmFactory(resolvedConfig.llm);
|
|
341
343
|
let structuredOutputState = { ok: true, candidate: null };
|
|
342
344
|
const reporter = createRunReporter({
|
|
343
345
|
useGui,
|
|
@@ -398,6 +400,7 @@ export async function handleRunCommand(options, command) {
|
|
|
398
400
|
const loopParams = buildRunLoopParams({
|
|
399
401
|
instruction: instructionText,
|
|
400
402
|
verify: effectiveVerify,
|
|
403
|
+
verifyPolicy: verifyPolicyOverride,
|
|
401
404
|
repoPath: runPath,
|
|
402
405
|
llm,
|
|
403
406
|
languagePlugins,
|
|
@@ -435,6 +438,7 @@ export async function handleRunCommand(options, command) {
|
|
|
435
438
|
? { allow: allowedToolRules, deny: disallowedToolRules }
|
|
436
439
|
: undefined,
|
|
437
440
|
permissionMode,
|
|
441
|
+
llmFactory,
|
|
438
442
|
});
|
|
439
443
|
const buildAssistantMessage = (result) => buildRunAssistantMessage({ mode, result });
|
|
440
444
|
const result = await executeRunLoop({
|
|
@@ -504,8 +508,9 @@ export async function handleRunCommand(options, command) {
|
|
|
504
508
|
rawOutputProfile !== 'openai' &&
|
|
505
509
|
activeReporterStarted &&
|
|
506
510
|
activeReporter) {
|
|
507
|
-
const error = new Error(text.cli.unexpectedError(msg))
|
|
508
|
-
|
|
511
|
+
const error = Object.assign(new Error(text.cli.unexpectedError(msg)), {
|
|
512
|
+
auditPath: lastKnownAuditPath,
|
|
513
|
+
});
|
|
509
514
|
activeReporter.onError(error);
|
|
510
515
|
}
|
|
511
516
|
else if (outputFormat === 'stream-json') {
|
|
@@ -3,6 +3,7 @@ export function buildRunLoopParams(params) {
|
|
|
3
3
|
return {
|
|
4
4
|
instruction: params.instruction,
|
|
5
5
|
verify: params.verify,
|
|
6
|
+
verifyPolicy: params.verifyPolicy,
|
|
6
7
|
repoPath: params.repoPath,
|
|
7
8
|
llm: params.llm,
|
|
8
9
|
conversationContext: params.conversationContext,
|
|
@@ -35,6 +36,7 @@ export function buildRunLoopParams(params) {
|
|
|
35
36
|
permissionMode: params.permissionMode,
|
|
36
37
|
extensions: params.extensions,
|
|
37
38
|
permissionRules: params.permissionRules,
|
|
39
|
+
llmFactory: params.llmFactory,
|
|
38
40
|
eventPayload: params.headlessIncludeToolInput ||
|
|
39
41
|
params.headlessIncludeToolOutput ||
|
|
40
42
|
params.headlessIncludeAuthorizationDecisions
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getString } from '../../../core/utils/serialize.js';
|
|
1
2
|
import { resolveRepoPath } from '../../utils/resolve-cli-config.js';
|
|
2
3
|
function splitToolRules(raw) {
|
|
3
4
|
const parts = [];
|
|
@@ -20,39 +21,26 @@ function splitToolRules(raw) {
|
|
|
20
21
|
}
|
|
21
22
|
export function parseRunCommandOptions(command) {
|
|
22
23
|
const allOptions = command.optsWithGlobals();
|
|
23
|
-
const repoPath = resolveRepoPath({
|
|
24
|
+
const repoPath = resolveRepoPath({
|
|
25
|
+
repo: getString(allOptions, 'repo') ?? undefined,
|
|
26
|
+
cwd: process.cwd(),
|
|
27
|
+
});
|
|
24
28
|
const continueSession = Boolean(allOptions.continue);
|
|
25
|
-
const resumeSessionId =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
? allOptions.print
|
|
30
|
-
: undefined;
|
|
31
|
-
const explicitInstruction = typeof allOptions.instruction === 'string' ? allOptions.instruction : undefined;
|
|
32
|
-
const jsonSchemaSpec = typeof allOptions.jsonSchema === 'string'
|
|
33
|
-
? allOptions.jsonSchema
|
|
34
|
-
: undefined;
|
|
29
|
+
const resumeSessionId = getString(allOptions, 'resume') ?? undefined;
|
|
30
|
+
const printInstruction = getString(allOptions, 'print') ?? undefined;
|
|
31
|
+
const explicitInstruction = getString(allOptions, 'instruction') ?? undefined;
|
|
32
|
+
const jsonSchemaSpec = getString(allOptions, 'jsonSchema') ?? undefined;
|
|
35
33
|
const rawOutputFormat = String(allOptions.outputFormat || 'text');
|
|
36
|
-
const rawOutputProfile =
|
|
37
|
-
? String(allOptions.outputProfile)
|
|
38
|
-
: undefined;
|
|
34
|
+
const rawOutputProfile = getString(allOptions, 'outputProfile') ?? undefined;
|
|
39
35
|
const outputProfileForStreamJson = rawOutputProfile ?? 'native';
|
|
40
36
|
const headlessIncludeToolInput = Boolean(allOptions.headlessIncludeToolInput);
|
|
41
37
|
const headlessIncludeToolOutput = Boolean(allOptions.headlessIncludeToolOutput);
|
|
42
38
|
const headlessIncludeAuthorizationDecisions = Boolean(allOptions.headlessIncludeAuthorizationDecisions);
|
|
43
39
|
const allowOutsideCacheRoot = Boolean(allOptions.allowOutsideCacheRoot);
|
|
44
|
-
const exportPatchPath =
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
? allOptions.sweBenchInstanceId
|
|
49
|
-
: undefined;
|
|
50
|
-
const sweBenchModelName = typeof allOptions.sweBenchModelName === 'string'
|
|
51
|
-
? allOptions.sweBenchModelName
|
|
52
|
-
: undefined;
|
|
53
|
-
const sweBenchPredictionsPath = typeof allOptions.sweBenchPredictions === 'string'
|
|
54
|
-
? allOptions.sweBenchPredictions
|
|
55
|
-
: undefined;
|
|
40
|
+
const exportPatchPath = getString(allOptions, 'exportPatch') ?? undefined;
|
|
41
|
+
const sweBenchInstanceId = getString(allOptions, 'sweBenchInstanceId') ?? undefined;
|
|
42
|
+
const sweBenchModelName = getString(allOptions, 'sweBenchModelName') ?? undefined;
|
|
43
|
+
const sweBenchPredictionsPath = getString(allOptions, 'sweBenchPredictions') ?? undefined;
|
|
56
44
|
const instruction = explicitInstruction ?? printInstruction;
|
|
57
45
|
const allowedToolRules = splitToolRules(allOptions.allowedTools);
|
|
58
46
|
const disallowedToolRules = splitToolRules(allOptions.disallowedTools);
|
|
@@ -41,24 +41,27 @@ export function createRuntimeLlmAndWarn(params) {
|
|
|
41
41
|
continue;
|
|
42
42
|
if (!target || typeof target !== 'object')
|
|
43
43
|
continue;
|
|
44
|
+
const phaseTarget = target;
|
|
44
45
|
const perPhaseConfig = {
|
|
45
|
-
id:
|
|
46
|
-
type:
|
|
47
|
-
clientPackage:
|
|
46
|
+
id: phaseTarget.id,
|
|
47
|
+
type: phaseTarget.type,
|
|
48
|
+
clientPackage: phaseTarget.clientPackage,
|
|
48
49
|
api: {
|
|
49
|
-
baseUrl:
|
|
50
|
-
timeoutMs:
|
|
51
|
-
headers:
|
|
52
|
-
apiKey:
|
|
53
|
-
apiKeySource:
|
|
50
|
+
baseUrl: phaseTarget.api?.baseUrl,
|
|
51
|
+
timeoutMs: phaseTarget.api?.timeoutMs,
|
|
52
|
+
headers: phaseTarget.api?.headers,
|
|
53
|
+
apiKey: phaseTarget.api?.apiKey,
|
|
54
|
+
apiKeySource: phaseTarget.api?.apiKeySource,
|
|
54
55
|
},
|
|
55
56
|
models: {
|
|
56
|
-
selectedModelId:
|
|
57
|
-
selectedModelSlot:
|
|
57
|
+
selectedModelId: phaseTarget.model?.id,
|
|
58
|
+
selectedModelSlot: phaseTarget.model?.slot || 'default',
|
|
58
59
|
},
|
|
59
|
-
capabilities:
|
|
60
|
+
capabilities: phaseTarget.capabilities,
|
|
60
61
|
};
|
|
61
|
-
const created = createRuntimeLlm(perPhaseConfig, {
|
|
62
|
+
const created = createRuntimeLlm(perPhaseConfig, {
|
|
63
|
+
langfuseEnabled: params.langfuseEnabled,
|
|
64
|
+
});
|
|
62
65
|
warnings.push(...created.warnings);
|
|
63
66
|
phaseLlms[phase] = created.llm;
|
|
64
67
|
}
|
|
@@ -25,6 +25,8 @@ export async function resolveRunRuntimeOptions(params) {
|
|
|
25
25
|
}
|
|
26
26
|
const effectiveVerify = await resolveVerifyOption(params.repoPath, params.cliOptions.verify, params.resolvedConfig.verify.command, { quiet: params.headlessOutput });
|
|
27
27
|
const effectiveWorktreePrepare = await resolveWorktreePrepareOption(params.repoPath, params.cliOptions.checkpointStrategy, params.cliOptions.worktreePrepare, { quiet: params.headlessOutput });
|
|
28
|
-
|
|
28
|
+
// When --no-verify is explicit, override verifyPolicy to 'never'
|
|
29
|
+
const verifyPolicyOverride = params.cliOptions.verify === false && effectiveVerify === undefined ? 'never' : undefined;
|
|
30
|
+
return { ok: true, llmOutput, effectiveVerify, effectiveWorktreePrepare, verifyPolicyOverride };
|
|
29
31
|
}
|
|
30
32
|
//# sourceMappingURL=runtime-options.js.map
|
package/dist/cli/config.js
CHANGED
|
@@ -5,12 +5,4 @@ export const CHAT_QUEUE_CONFIG = {
|
|
|
5
5
|
THINKING_MIN_VISIBLE_MS: 150, // Reduced from 300ms to minimize perceived lag
|
|
6
6
|
TASK_TIMEOUT_MS: 10 * 60 * 1000,
|
|
7
7
|
};
|
|
8
|
-
export const TOOL_AUTH_CONFIG = {
|
|
9
|
-
SESSION_TTL_MS: 30 * 60 * 1000,
|
|
10
|
-
AUTO_ALLOW_RISK: {
|
|
11
|
-
low: true,
|
|
12
|
-
medium: false,
|
|
13
|
-
high: false,
|
|
14
|
-
},
|
|
15
|
-
};
|
|
16
8
|
//# sourceMappingURL=config.js.map
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { parseCanonicalFunctionCallItemId, } from '../../core/facades/cli-headless.js';
|
|
2
|
-
|
|
3
|
-
return Boolean(value) && typeof value === 'object';
|
|
4
|
-
}
|
|
5
|
-
function getString(record, key) {
|
|
6
|
-
const value = record[key];
|
|
7
|
-
return typeof value === 'string' ? value : null;
|
|
8
|
-
}
|
|
2
|
+
import { isRecord, getString } from '../../core/utils/serialize.js';
|
|
9
3
|
export class OpenAiResponsesCanonicalApplier {
|
|
10
4
|
state;
|
|
11
5
|
constructor(state) {
|
package/dist/cli/locales/en.js
CHANGED
|
@@ -19,7 +19,7 @@ export const en = {
|
|
|
19
19
|
chatCommandHistory: ' /history - Show iteration history',
|
|
20
20
|
chatCommandQueue: ' /queue - Manage the chat queue',
|
|
21
21
|
chatCommandAuth: ' /config allowlist - Manage tool allowlist',
|
|
22
|
-
chatCommandMode: ' /mode
|
|
22
|
+
chatCommandMode: ' /permission-mode - Set permission mode (interactive/yolo)',
|
|
23
23
|
chatCommandConfig: ' /config - Settings (log-mode/view/output/allowlist/permission-mode)',
|
|
24
24
|
chatSessionSaved: 'Session saved. Goodbye!',
|
|
25
25
|
chatThinking: 'Thinking...',
|
|
@@ -108,7 +108,7 @@ export const en = {
|
|
|
108
108
|
llmOutputUnavailable: 'LLM output configuration is unavailable in this mode.',
|
|
109
109
|
llmOutputPersisted: (path) => `LLM output settings saved to ${path}`,
|
|
110
110
|
llmOutputPersistFailed: (reason) => `Failed to save LLM output settings: ${reason}`,
|
|
111
|
-
modeUsage: 'Usage: /mode <interactive|yolo>',
|
|
111
|
+
modeUsage: 'Usage: /permission-mode <interactive|yolo>',
|
|
112
112
|
modeSuggestion: (mode) => {
|
|
113
113
|
if (mode === 'interactive')
|
|
114
114
|
return 'Interactive permission checks and allowlist rules';
|
|
@@ -110,6 +110,16 @@ export class StandardReporter {
|
|
|
110
110
|
getLogger().info(text.cli.budgetSummaryTitle);
|
|
111
111
|
getLogger().info(text.cli.budgetSummaryLine(s.attemptCount, s.adjustmentCount, s.alertCount, s.criticalDropCount, Math.round(s.avgUtilization * 100), Math.round(s.truncationRate * 100), Math.round(s.successRate * 100)));
|
|
112
112
|
}
|
|
113
|
+
if (result.usage) {
|
|
114
|
+
const u = result.usage;
|
|
115
|
+
const tokenLine = `Tokens: ${u.inputTokens.toLocaleString()} in / ${u.outputTokens.toLocaleString()} out (${u.totalTokens.toLocaleString()} total)`;
|
|
116
|
+
if (u.estimatedCost !== undefined && u.estimatedCost > 0) {
|
|
117
|
+
getLogger().info(`${tokenLine} | Est. cost: $${u.estimatedCost.toFixed(2)}`);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
getLogger().info(tokenLine);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
113
123
|
if (this.verbose && result.logs) {
|
|
114
124
|
getLogger().log('\n' + chalk.bold(text.cli.stepLogs));
|
|
115
125
|
result.logs.forEach((log) => {
|
|
@@ -124,9 +134,8 @@ export class StandardReporter {
|
|
|
124
134
|
getLogger().error(text.cli.unexpectedError(error.message), true);
|
|
125
135
|
}
|
|
126
136
|
initProgressBar() {
|
|
127
|
-
//
|
|
128
|
-
|
|
129
|
-
if (typeof stream.clearLine !== 'function' || typeof stream.cursorTo !== 'function') {
|
|
137
|
+
// DCAP Defense: Check if stderr supports TTY operations to prevent clearLine crashes and unexpected termination
|
|
138
|
+
if (!('clearLine' in process.stderr) || !('cursorTo' in process.stderr)) {
|
|
130
139
|
this.bar = {
|
|
131
140
|
render: () => { },
|
|
132
141
|
tick: () => { },
|
|
@@ -98,7 +98,8 @@ export class StreamJsonReporter {
|
|
|
98
98
|
}));
|
|
99
99
|
}
|
|
100
100
|
onError(error) {
|
|
101
|
-
const
|
|
101
|
+
const errorRecord = error;
|
|
102
|
+
const auditPath = typeof errorRecord.auditPath === 'string' ? errorRecord.auditPath : undefined;
|
|
102
103
|
this.emit(encodeStreamFailure({
|
|
103
104
|
uuid: this.uuid(),
|
|
104
105
|
sessionId: this.sessionId,
|
|
@@ -135,10 +135,10 @@ export async function createCliSlashRuntime(options) {
|
|
|
135
135
|
// @see https://agentskills.io/specification — Progressive disclosure
|
|
136
136
|
const skill = await skillLoader.activateSkill(catalogEntry.id);
|
|
137
137
|
const meta = (req.meta ?? {});
|
|
138
|
-
const signal = meta
|
|
138
|
+
const signal = meta.signal;
|
|
139
139
|
// Prepare an isolated worktree environment for governed shell execution.
|
|
140
140
|
const silentEmit = (event) => {
|
|
141
|
-
if (event
|
|
141
|
+
if (event.type === 'log' && event.level === 'error') {
|
|
142
142
|
options.emit(event);
|
|
143
143
|
return;
|
|
144
144
|
}
|
|
@@ -9,7 +9,7 @@ import { prepareMessagePayload, sanitizeMessage } from '../utils/sanitizer.js';
|
|
|
9
9
|
*/
|
|
10
10
|
export function useLoopEvents(mode, onStart, signal, options) {
|
|
11
11
|
const store = useUIStore();
|
|
12
|
-
const dispatch = store
|
|
12
|
+
const { dispatch } = store;
|
|
13
13
|
const runStartedRef = useRef(false);
|
|
14
14
|
const activeStreamIdRef = useRef(null);
|
|
15
15
|
const logModeRef = useRef('normal');
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { promises as fs, constants } from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
+
import { getLogger } from '../../observability/logger.js';
|
|
3
4
|
import { AtomicFileWriter } from './atomic-file-writer.js';
|
|
4
5
|
/**
|
|
5
6
|
* Unified file system adapter for all file operations.
|
|
@@ -45,7 +46,8 @@ export class FileAdapter {
|
|
|
45
46
|
await fs.access(filePath);
|
|
46
47
|
return true;
|
|
47
48
|
}
|
|
48
|
-
catch {
|
|
49
|
+
catch (error) {
|
|
50
|
+
getLogger().debug(`[FileAdapter] exists check failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
49
51
|
return false;
|
|
50
52
|
}
|
|
51
53
|
}
|
|
@@ -662,8 +662,9 @@ export class GitAdapter {
|
|
|
662
662
|
// Example: /tmp -> /private/tmp on macOS
|
|
663
663
|
tmpReal = realpathSync(tmpResolved);
|
|
664
664
|
}
|
|
665
|
-
catch {
|
|
665
|
+
catch (error) {
|
|
666
666
|
// Fall back to resolved path. If tmp is not realpath-resolvable, prefer denying shadow checks elsewhere.
|
|
667
|
+
getLogger().debug(`[GitAdapter] realpath resolve failed for tmpdir: ${error instanceof Error ? error.message : String(error)}`);
|
|
667
668
|
tmpReal = tmpResolved;
|
|
668
669
|
}
|
|
669
670
|
return path.join(tmpReal, 's8p-wt');
|
|
@@ -674,7 +675,8 @@ export class GitAdapter {
|
|
|
674
675
|
try {
|
|
675
676
|
repoReal = realpathSync(repoResolved);
|
|
676
677
|
}
|
|
677
|
-
catch {
|
|
678
|
+
catch (error) {
|
|
679
|
+
getLogger().debug(`[GitAdapter] realpath resolve failed for repo: ${error instanceof Error ? error.message : String(error)}`);
|
|
678
680
|
repoReal = repoResolved;
|
|
679
681
|
}
|
|
680
682
|
const parent = path.dirname(repoReal);
|
|
@@ -721,7 +723,8 @@ export class GitAdapter {
|
|
|
721
723
|
// Prevents attacker from creating a symlink to main repo inside shadow root
|
|
722
724
|
repo = realpathSync(repoResolved);
|
|
723
725
|
}
|
|
724
|
-
catch {
|
|
726
|
+
catch (error) {
|
|
727
|
+
getLogger().debug(`[GitAdapter] realpath resolve failed for shadow check: ${error instanceof Error ? error.message : String(error)}`);
|
|
725
728
|
repo = repoResolved;
|
|
726
729
|
}
|
|
727
730
|
if (isPathWithinDirectory(expectedRoot, repo, { allowEqual: false }))
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { realpathSync } from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { LIMITS } from '../../config/limits.js';
|
|
4
|
+
import { getLogger } from '../../observability/logger.js';
|
|
4
5
|
import { spawnCommand } from '../../runtime/process-runner.js';
|
|
5
6
|
function assertCwdSandboxed(repoRoot, cwd) {
|
|
6
7
|
const resolvedRoot = path.resolve(repoRoot);
|
|
@@ -10,13 +11,15 @@ function assertCwdSandboxed(repoRoot, cwd) {
|
|
|
10
11
|
try {
|
|
11
12
|
realRoot = realpathSync(resolvedRoot);
|
|
12
13
|
}
|
|
13
|
-
catch {
|
|
14
|
+
catch (error) {
|
|
15
|
+
getLogger().debug(`[GitRunner] realpath resolve failed for root: ${error instanceof Error ? error.message : String(error)}`);
|
|
14
16
|
realRoot = resolvedRoot;
|
|
15
17
|
}
|
|
16
18
|
try {
|
|
17
19
|
realCwd = realpathSync(resolvedCwd);
|
|
18
20
|
}
|
|
19
|
-
catch {
|
|
21
|
+
catch (error) {
|
|
22
|
+
getLogger().debug(`[GitRunner] realpath resolve failed for cwd: ${error instanceof Error ? error.message : String(error)}`);
|
|
20
23
|
realCwd = resolvedCwd;
|
|
21
24
|
}
|
|
22
25
|
const rel = path.relative(realRoot, realCwd);
|