@gajae-code/coding-agent 0.16.3 → 0.16.6
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/CHANGELOG.md +113 -0
- package/dist/types/capability/types.d.ts +4 -0
- package/dist/types/cli/args.d.ts +2 -2
- package/dist/types/cli/customize-doctor.d.ts +22 -0
- package/dist/types/cli/root-flags.d.ts +4 -2
- package/dist/types/cli.d.ts +1 -1
- package/dist/types/commands/launch.d.ts +1 -1
- package/dist/types/config/autorouting-tier-map.d.ts +3 -0
- package/dist/types/config/file-lock.d.ts +31 -3
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/model-resolver.d.ts +9 -0
- package/dist/types/config/settings-schema.d.ts +29 -1
- package/dist/types/coordinator-mcp/question-state.d.ts +7 -0
- package/dist/types/coordinator-mcp/server.d.ts +7 -0
- package/dist/types/discovery/claude-plugins.d.ts +3 -1
- package/dist/types/discovery/helpers.d.ts +35 -0
- package/dist/types/exec/bash-executor.d.ts +17 -1
- package/dist/types/exec/bash-shell-guardian.d.ts +15 -0
- package/dist/types/exec/bash-shell-runtime-entry.d.ts +2 -0
- package/dist/types/exec/bash-shell-signals.d.ts +2 -0
- package/dist/types/exec/bash-shell-supervisor-entry.d.ts +1 -0
- package/dist/types/exec/bash-shell-supervisor.d.ts +10 -0
- package/dist/types/exec/bash-shell-worker-entry.d.ts +2 -0
- package/dist/types/exec/bash-shell-worker-protocol.d.ts +63 -0
- package/dist/types/exec/bash-shell-worker.d.ts +1 -0
- package/dist/types/exec/isolated-shell.d.ts +19 -0
- package/dist/types/extensibility/extensions/function-hooks-internal.d.ts +9 -0
- package/dist/types/extensibility/extensions/function-hooks.d.ts +169 -0
- package/dist/types/extensibility/extensions/index.d.ts +1 -0
- package/dist/types/extensibility/extensions/runner.d.ts +46 -6
- package/dist/types/extensibility/extensions/types.d.ts +16 -0
- package/dist/types/extensibility/extensions/wrapper.d.ts +3 -1
- package/dist/types/extensibility/gjc-plugins/constrained-hooks.d.ts +35 -2
- package/dist/types/extensibility/gjc-plugins/mcp-policy.d.ts +16 -0
- package/dist/types/extensibility/gjc-plugins/paths.d.ts +2 -0
- package/dist/types/extensibility/gjc-plugins/types.d.ts +25 -0
- package/dist/types/extensibility/hooks/types.d.ts +4 -0
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +5 -2
- package/dist/types/extensibility/shared-events.d.ts +1 -1
- package/dist/types/extensibility/skill-management.d.ts +9 -4
- package/dist/types/extensibility/skills.d.ts +2 -0
- package/dist/types/gjc-runtime/empty-delete-gc.d.ts +4 -1
- package/dist/types/gjc-runtime/linux-proc.d.ts +2 -0
- package/dist/types/gjc-runtime/session-state-lock.d.ts +14 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +41 -3
- package/dist/types/gjc-runtime/ultragoal-succession.d.ts +251 -0
- package/dist/types/modes/components/assistant-message.d.ts +1 -2
- package/dist/types/modes/components/bash-execution.d.ts +1 -0
- package/dist/types/modes/components/execution-shared.d.ts +1 -0
- package/dist/types/modes/components/settings-selector.d.ts +6 -1
- package/dist/types/modes/components/status-line/command.d.ts +35 -0
- package/dist/types/modes/components/status-line/index.d.ts +1 -0
- package/dist/types/modes/components/status-line/types.d.ts +5 -0
- package/dist/types/modes/components/tool-status-header.d.ts +14 -0
- package/dist/types/modes/controllers/event-controller.d.ts +6 -0
- package/dist/types/modes/interactive-mode.d.ts +3 -0
- package/dist/types/modes/types.d.ts +7 -0
- package/dist/types/runtime-mcp/client.d.ts +9 -1
- package/dist/types/runtime-mcp/manager.d.ts +7 -1
- package/dist/types/runtime-mcp/pool.d.ts +22 -3
- package/dist/types/runtime-mcp/transports/stdio.d.ts +0 -4
- package/dist/types/runtime-mcp/types.d.ts +22 -0
- package/dist/types/sdk/broker/ensure.d.ts +32 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +0 -1
- package/dist/types/sdk/broker/lifecycle.d.ts +6 -0
- package/dist/types/sdk/broker/startup-failure.d.ts +4 -1
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +2 -0
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +12 -0
- package/dist/types/sdk/bus/chat-effect-journal.d.ts +17 -2
- package/dist/types/sdk/bus/conversation-store.d.ts +11 -0
- package/dist/types/sdk/bus/lifecycle-commands.d.ts +8 -8
- package/dist/types/sdk/bus/slack-daemon.d.ts +1 -1
- package/dist/types/sdk/bus/slack-live-provider.d.ts +6 -0
- package/dist/types/sdk/bus/slack-provider.d.ts +12 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +8 -0
- package/dist/types/sdk/client/client.d.ts +6 -0
- package/dist/types/sdk/host/host.d.ts +3 -1
- package/dist/types/sdk/host/session-runtime.d.ts +26 -1
- package/dist/types/sdk/lifecycle/service.d.ts +1 -0
- package/dist/types/sdk/router/session-router.d.ts +10 -2
- package/dist/types/sdk/session-api-key.d.ts +26 -0
- package/dist/types/sdk/session.d.ts +5 -1
- package/dist/types/sdk/transport/serve-cli.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +11 -0
- package/dist/types/session/fallback-chain-controller.d.ts +15 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +7 -0
- package/dist/types/session/messages.d.ts +1 -0
- package/dist/types/session/session-manager.d.ts +3 -1
- package/dist/types/setup/paseo/announce.d.ts +112 -0
- package/dist/types/setup/paseo/setup-deps.d.ts +2 -1
- package/dist/types/skill-state/canonical-skills.d.ts +4 -0
- package/dist/types/system-prompt.d.ts +10 -0
- package/dist/types/task/executor.d.ts +5 -1
- package/dist/types/tools/bash.d.ts +1 -0
- package/dist/types/tools/fetch.d.ts +7 -0
- package/dist/types/tools/github-cache.d.ts +2 -1
- package/dist/types/tools/index.d.ts +10 -0
- package/dist/types/tools/path-utils.d.ts +2 -0
- package/dist/types/tools/search.d.ts +6 -0
- package/package.json +9 -7
- package/scripts/capture-status-line-custom-editor-showcase.ts +151 -0
- package/scripts/generate-sdk-operation-inventory.ts +11 -0
- package/scripts/verify-status-line-custom-editor-showcase.ts +309 -0
- package/src/capability/index.ts +14 -2
- package/src/capability/types.ts +4 -0
- package/src/cli/args.ts +20 -9
- package/src/cli/customize-doctor.ts +155 -12
- package/src/cli/root-flags.ts +5 -3
- package/src/cli.ts +22 -0
- package/src/commands/sdk.ts +74 -31
- package/src/config/autorouting-tier-map.ts +1 -0
- package/src/config/file-lock-gc.ts +40 -2
- package/src/config/file-lock.ts +379 -31
- package/src/config/model-preset-registry.ts +120 -19
- package/src/config/model-profiles.ts +40 -0
- package/src/config/model-registry.ts +73 -23
- package/src/config/model-resolver.ts +48 -0
- package/src/config/settings-schema.ts +33 -1
- package/src/config/settings.ts +1 -0
- package/src/coordinator-mcp/question-state.ts +33 -2
- package/src/coordinator-mcp/server.ts +477 -101
- package/src/crash/sanitize.ts +1 -1
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.ts +11 -11
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/register.ts +13 -2
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +22 -0
- package/src/discovery/builtin.ts +52 -55
- package/src/discovery/claude-plugins.ts +12 -4
- package/src/discovery/helpers.ts +307 -34
- package/src/exec/bash-executor.ts +330 -50
- package/src/exec/bash-shell-guardian.ts +388 -0
- package/src/exec/bash-shell-runtime-entry.ts +5 -0
- package/src/exec/bash-shell-signals.ts +29 -0
- package/src/exec/bash-shell-supervisor-entry.ts +3 -0
- package/src/exec/bash-shell-supervisor.ts +359 -0
- package/src/exec/bash-shell-worker-entry.ts +5 -0
- package/src/exec/bash-shell-worker-protocol.ts +36 -0
- package/src/exec/bash-shell-worker.ts +116 -0
- package/src/exec/isolated-shell.ts +393 -0
- package/src/extensibility/extensions/function-hooks-internal.ts +73 -0
- package/src/extensibility/extensions/function-hooks.ts +959 -0
- package/src/extensibility/extensions/index.ts +22 -0
- package/src/extensibility/extensions/loader.ts +53 -2
- package/src/extensibility/extensions/runner.ts +895 -264
- package/src/extensibility/extensions/types.ts +42 -0
- package/src/extensibility/extensions/wrapper.ts +56 -15
- package/src/extensibility/gjc-plugins/compiler.ts +228 -60
- package/src/extensibility/gjc-plugins/constrained-hooks.ts +321 -23
- package/src/extensibility/gjc-plugins/installer.ts +13 -12
- package/src/extensibility/gjc-plugins/mcp-policy.ts +81 -52
- package/src/extensibility/gjc-plugins/paths.ts +13 -0
- package/src/extensibility/gjc-plugins/registry.ts +113 -1
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +758 -16
- package/src/extensibility/gjc-plugins/runtime-quarantine.ts +20 -2
- package/src/extensibility/gjc-plugins/schema.ts +121 -4
- package/src/extensibility/gjc-plugins/types.ts +25 -0
- package/src/extensibility/hooks/loader.ts +133 -16
- package/src/extensibility/hooks/types.ts +28 -0
- package/src/extensibility/runtime-skill-discovery.ts +149 -190
- package/src/extensibility/shared-events.ts +1 -1
- package/src/extensibility/skill-management.ts +200 -52
- package/src/extensibility/skills.ts +73 -25
- package/src/gjc-runtime/empty-delete-gc.ts +94 -4
- package/src/gjc-runtime/gc-runtime.ts +29 -0
- package/src/gjc-runtime/linux-proc.ts +14 -0
- package/src/gjc-runtime/repository-binding.ts +1 -1
- package/src/gjc-runtime/session-state-lock.ts +143 -10
- package/src/gjc-runtime/session-state-sidecar.ts +27 -11
- package/src/gjc-runtime/state-writer.ts +30 -29
- package/src/gjc-runtime/ultragoal-runtime.ts +189 -47
- package/src/gjc-runtime/ultragoal-succession.ts +1667 -0
- package/src/gjc-runtime/workflow-manifest.generated.json +52 -1
- package/src/gjc-runtime/workflow-manifest.ts +16 -0
- package/src/harness-control-plane/session-lease.ts +2 -2
- package/src/internal-urls/docs-index.generated.ts +12 -12
- package/src/lsp/config.ts +10 -3
- package/src/lsp/index.ts +1 -1
- package/src/lsp/path-trust.ts +69 -14
- package/src/main.ts +78 -35
- package/src/modes/DESIGN.md +54 -0
- package/src/modes/acp/acp-agent.ts +16 -3
- package/src/modes/components/assistant-message.ts +22 -9
- package/src/modes/components/bash-execution.ts +4 -1
- package/src/modes/components/execution-shared.ts +4 -1
- package/src/modes/components/model-selector.ts +166 -33
- package/src/modes/components/session-observer-overlay.ts +1 -1
- package/src/modes/components/settings-selector.ts +1075 -235
- package/src/modes/components/status-line/command.ts +190 -0
- package/src/modes/components/status-line/index.ts +1 -0
- package/src/modes/components/status-line/segments.ts +32 -5
- package/src/modes/components/status-line/types.ts +5 -0
- package/src/modes/components/tool-status-header.ts +396 -22
- package/src/modes/controllers/command-controller.ts +3 -0
- package/src/modes/controllers/event-controller.ts +151 -7
- package/src/modes/controllers/extension-ui-controller.ts +1 -0
- package/src/modes/controllers/input-controller.ts +6 -3
- package/src/modes/controllers/selector-controller.ts +21 -0
- package/src/modes/interactive-mode.ts +53 -6
- package/src/modes/print-mode.ts +5 -1
- package/src/modes/prompt-action-autocomplete.ts +54 -27
- package/src/modes/runtime-init.ts +2 -0
- package/src/modes/types.ts +17 -3
- package/src/modes/utils/ui-helpers.ts +2 -0
- package/src/prompts/system/system-prompt.md +8 -0
- package/src/prompts/tools/search.md +2 -0
- package/src/prompts/tools/subagent.md +1 -0
- package/src/runtime-mcp/client.ts +60 -17
- package/src/runtime-mcp/manager.ts +189 -14
- package/src/runtime-mcp/pool.test.ts +218 -0
- package/src/runtime-mcp/pool.ts +224 -23
- package/src/runtime-mcp/transports/stdio.ts +158 -24
- package/src/runtime-mcp/types.ts +24 -0
- package/src/sdk/broker/broker.ts +124 -32
- package/src/sdk/broker/ensure.ts +248 -41
- package/src/sdk/broker/lifecycle-ledger.ts +7 -17
- package/src/sdk/broker/lifecycle.ts +56 -6
- package/src/sdk/broker/startup-failure.ts +15 -6
- package/src/sdk/bus/chat-daemon-control.ts +3 -1
- package/src/sdk/bus/chat-daemon-runtime.ts +72 -6
- package/src/sdk/bus/chat-effect-journal.ts +132 -7
- package/src/sdk/bus/conversation-store.ts +29 -0
- package/src/sdk/bus/lifecycle-commands.ts +17 -11
- package/src/sdk/bus/slack-conversation.ts +1 -0
- package/src/sdk/bus/slack-daemon.ts +478 -49
- package/src/sdk/bus/slack-live-provider.ts +12 -0
- package/src/sdk/bus/slack-provider.ts +5 -0
- package/src/sdk/bus/telegram-daemon.ts +16 -2
- package/src/sdk/bus/topic-registry.ts +19 -0
- package/src/sdk/cli/master-cli.ts +1 -1
- package/src/sdk/cli/session-cli.ts +11 -8
- package/src/sdk/client/client.ts +66 -17
- package/src/sdk/host/host.ts +29 -9
- package/src/sdk/host/query/revision-store.ts +19 -13
- package/src/sdk/host/reverse-leases.ts +7 -4
- package/src/sdk/host/session-runtime.test.ts +52 -10
- package/src/sdk/host/session-runtime.ts +383 -44
- package/src/sdk/lifecycle/service.ts +4 -0
- package/src/sdk/protocol/operation-inventory.generated.json +77 -0
- package/src/sdk/router/session-router.ts +89 -38
- package/src/sdk/session-api-key.ts +94 -0
- package/src/sdk/session.ts +228 -55
- package/src/sdk/transport/relay.ts +35 -13
- package/src/sdk/transport/serve-cli.ts +3 -3
- package/src/session/agent-session.ts +240 -90
- package/src/session/contribution-prep.ts +214 -21
- package/src/session/fallback-chain-controller.ts +38 -0
- package/src/session/internal/managed-session-storage.ts +19 -5
- package/src/session/messages.ts +5 -0
- package/src/session/session-manager.ts +29 -5
- package/src/session-import/redact.ts +5 -1
- package/src/setup/paseo/announce.ts +456 -0
- package/src/setup/paseo/setup-deps.ts +15 -3
- package/src/skill-state/canonical-skills.ts +12 -0
- package/src/skills/skills.test.ts +41 -21
- package/src/slash-commands/builtin-registry.ts +1 -0
- package/src/system-prompt.ts +29 -3
- package/src/task/executor.ts +7 -1
- package/src/task/index.ts +21 -4
- package/src/tools/bash.ts +63 -19
- package/src/tools/cron.ts +1 -1
- package/src/tools/fetch.ts +29 -1
- package/src/tools/gh.ts +26 -3
- package/src/tools/github-cache.ts +68 -16
- package/src/tools/index.ts +10 -0
- package/src/tools/job.ts +21 -4
- package/src/tools/monitor.ts +8 -2
- package/src/tools/path-utils.ts +7 -0
- package/src/tools/read.ts +14 -2
- package/src/tools/render-utils.ts +1 -3
- package/src/tools/resource-gc.ts +28 -8
- package/src/tools/search.ts +116 -58
- package/src/tools/skill-discovery.ts +5 -0
- package/src/tools/skill.ts +37 -2
- package/src/tools/subagent.ts +6 -3
- package/src/tools/tool-catalog.generated.ts +10 -3
- package/src/tools/ultragoal-ask-guard.ts +2 -2
- package/src/web/insane/bridge.ts +113 -23
- package/src/web/search/providers/perplexity.ts +102 -41
|
@@ -11,6 +11,8 @@ const inventoryPath = process.env.GJC_SDK_OPERATION_INVENTORY
|
|
|
11
11
|
|
|
12
12
|
/** Reviewed seams deliberately excluded from the public SDK operation surface. */
|
|
13
13
|
const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
14
|
+
"agent_session:reloadSkills":
|
|
15
|
+
"internal marketplace lifecycle refresh for the session skill catalog; not an independent SDK ingress operation",
|
|
14
16
|
"agent_session:getTerminalTurnEpoch":
|
|
15
17
|
"internal terminal-abort bus seam (epoch only), threaded via terminalAbortSeams; not a user-facing SDK control seam",
|
|
16
18
|
"agent_session:cancelPendingPreflightForTerminalAbort":
|
|
@@ -113,12 +115,21 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
113
115
|
"agent_session:getPendingNextTurnMessagesForTests": "read-only test seam, not a user-facing SDK control seam",
|
|
114
116
|
"agent_session:queueCoordinatorRuntimeStatePersistForTests":
|
|
115
117
|
"test-only coordinator persistence ordering seam, not a user-facing SDK control seam",
|
|
118
|
+
"agent_session:awaitCoordinatorRuntimeStatePersistenceForTests":
|
|
119
|
+
"test-only coordinator persistence drain barrier, not a user-facing SDK control seam",
|
|
116
120
|
"agent_session:parkAgentEndForCoordinatorPersistForTests":
|
|
117
121
|
"test-only parked terminal persistence seam, not a user-facing SDK control seam",
|
|
118
122
|
"agent_session:flushParkedAgentEndForCoordinatorPersistForTests":
|
|
119
123
|
"test-only parked terminal flush seam, not a user-facing SDK control seam",
|
|
120
124
|
"agent_session:setCancelAndSubmitAbortOutcomeProviderForTests":
|
|
121
125
|
"test-only cancellation seam, not a user-facing SDK control seam",
|
|
126
|
+
"agent_session:awaitDisposeCompletion": "test-only disposal completion seam, not a user-facing SDK control seam",
|
|
127
|
+
"agent_session:setDisposeTimeoutForTests": "test-only disposal timeout seam, not a user-facing SDK control seam",
|
|
128
|
+
"agent_session:trackPostPromptTaskForTests": "test-only post-prompt task seam, not a user-facing SDK control seam",
|
|
129
|
+
"agent_session:requestWorkerIntegrationForTests":
|
|
130
|
+
"test-only worker integration seam, not a user-facing SDK control seam",
|
|
131
|
+
"agent_session:runWithPromptAdmissionForTests":
|
|
132
|
+
"test-only prompt admission seam, not a user-facing SDK control seam",
|
|
122
133
|
"agent_session:getAgentId": "internal accessor/plumbing, not a user-facing control seam",
|
|
123
134
|
"agent_session:emitNotice": "internal accessor/plumbing, not a user-facing control seam",
|
|
124
135
|
"agent_session:subscribe": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { ansiToHtml } from "./capture-sticky-viewport-showcase";
|
|
4
|
+
|
|
5
|
+
const CAPTURE_TOOL_VERSION = "status-line-custom-editor-showcase-v1";
|
|
6
|
+
const CANONICAL_COMMAND =
|
|
7
|
+
"bun packages/coding-agent/scripts/capture-status-line-custom-editor-showcase.ts --out .gjc/qa/status-line-custom-editor-<run>";
|
|
8
|
+
const FIXED_CLOCK = "2026-01-01T00:00:00.000Z";
|
|
9
|
+
|
|
10
|
+
const UNICODE_STATES = [
|
|
11
|
+
"root-statusbar",
|
|
12
|
+
"picked-origin-slot",
|
|
13
|
+
"palette-exact-insert",
|
|
14
|
+
"separator-control",
|
|
15
|
+
"separator-choice-focused",
|
|
16
|
+
"separator-choice-applied",
|
|
17
|
+
"option-boolean-choice-focused",
|
|
18
|
+
"option-enum-choice-focused",
|
|
19
|
+
"option-numeric-choice-focused",
|
|
20
|
+
"option-choice-applied",
|
|
21
|
+
"exit-restored",
|
|
22
|
+
"confirm-persisted",
|
|
23
|
+
"overflow-two-row-warning",
|
|
24
|
+
] as const;
|
|
25
|
+
const ASCII_STATES = [
|
|
26
|
+
"root-statusbar",
|
|
27
|
+
"picked-origin-slot",
|
|
28
|
+
"separator-choice-focused",
|
|
29
|
+
"option-boolean-choice-focused",
|
|
30
|
+
"option-enum-choice-focused",
|
|
31
|
+
"option-numeric-choice-focused",
|
|
32
|
+
] as const;
|
|
33
|
+
const EXPECTED_KEYS = new Set([
|
|
34
|
+
...UNICODE_STATES.map(state => `${state}/80x32/unicode-color`),
|
|
35
|
+
"overflow-two-row-warning/48x40/unicode-color",
|
|
36
|
+
"narrow-cjk/48x40/unicode-color",
|
|
37
|
+
...ASCII_STATES.map(state => `${state}/80x32/ascii-no-color`),
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
function expectedWrappingPolicy(statusbarRows: number): string {
|
|
41
|
+
return statusbarRows > 2 ? "two-row" : "single-row";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface ManifestFile {
|
|
45
|
+
tool: string;
|
|
46
|
+
sourceHead: string;
|
|
47
|
+
sourceHash: string;
|
|
48
|
+
captureActor: string;
|
|
49
|
+
entries: Array<{
|
|
50
|
+
key: string;
|
|
51
|
+
stateId: string;
|
|
52
|
+
viewport: { columns: number; rows: number };
|
|
53
|
+
renderMode: string;
|
|
54
|
+
simulatedStatusbarRows: number;
|
|
55
|
+
files: Array<{ path: string; sha256: string; byte_length: number }>;
|
|
56
|
+
}>;
|
|
57
|
+
independentReview?: {
|
|
58
|
+
reviewer: string;
|
|
59
|
+
reviewerAssociation: "OWNER" | "MEMBER" | "COLLABORATOR";
|
|
60
|
+
verdict: "approved" | "rejected";
|
|
61
|
+
evidence: string;
|
|
62
|
+
manifestSha256?: string;
|
|
63
|
+
sourceHash?: string;
|
|
64
|
+
headSha?: string;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function sha256(value: string): string {
|
|
69
|
+
return new Bun.CryptoHasher("sha256").update(value).digest("hex");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function measuredStatusbarRows(plain: string): number {
|
|
73
|
+
const lines = plain.split("\n");
|
|
74
|
+
const heading = lines.findIndex(line => line.includes("Simulated statusbar"));
|
|
75
|
+
if (heading < 0) return 0;
|
|
76
|
+
let end = heading + 1;
|
|
77
|
+
while (end < lines.length && lines[end]?.trim() && !lines[end]?.includes("Warning:")) end++;
|
|
78
|
+
return Math.max(0, end - heading - 1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function parseArgs(args: string[]): { root: string; requireIndependentReview: boolean } {
|
|
82
|
+
let root = "";
|
|
83
|
+
let requireIndependentReview = false;
|
|
84
|
+
for (let i = 0; i < args.length; i++) {
|
|
85
|
+
const arg = args[i];
|
|
86
|
+
if (arg === "--root") root = args[++i] ?? "";
|
|
87
|
+
else if (arg === "--require-independent-review") requireIndependentReview = true;
|
|
88
|
+
else throw new Error(`Unknown argument: ${arg}`);
|
|
89
|
+
}
|
|
90
|
+
if (!root) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
"Usage: bun packages/coding-agent/scripts/verify-status-line-custom-editor-showcase.ts --root <dir> [--require-independent-review]",
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return { root, requireIndependentReview };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function readText(root: string, relativePath: string): Promise<string> {
|
|
99
|
+
const fullPath = path.resolve(root, relativePath);
|
|
100
|
+
const resolvedRoot = path.resolve(root);
|
|
101
|
+
if (!fullPath.startsWith(`${resolvedRoot}${path.sep}`)) throw new Error(`Artifact escapes root: ${relativePath}`);
|
|
102
|
+
return await Bun.file(fullPath).text();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function tryReadReview(root: string): Promise<ManifestFile["independentReview"] | undefined> {
|
|
106
|
+
const reviewPath = path.join(root, "independent-review.json");
|
|
107
|
+
if (!(await Bun.file(reviewPath).exists())) return undefined;
|
|
108
|
+
return JSON.parse(await Bun.file(reviewPath).text()) as ManifestFile["independentReview"];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function collectRelativeFiles(root: string, dir = ""): Promise<string[]> {
|
|
112
|
+
const fullDir = path.join(root, dir);
|
|
113
|
+
const entries = await fs.readdir(fullDir, { withFileTypes: true });
|
|
114
|
+
const files: string[] = [];
|
|
115
|
+
for (const entry of entries) {
|
|
116
|
+
const relative = dir ? `${dir}/${entry.name}` : entry.name;
|
|
117
|
+
if (entry.isDirectory()) {
|
|
118
|
+
files.push(...(await collectRelativeFiles(root, relative)));
|
|
119
|
+
} else if (entry.isFile()) {
|
|
120
|
+
files.push(relative);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return files;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function requireWitness(entry: ManifestFile["entries"][number], plain: string): void {
|
|
127
|
+
if (entry.stateId === "exit-restored" || entry.stateId === "confirm-persisted") {
|
|
128
|
+
if (!plain.includes("Status Line")) throw new Error(`${entry.key}: missing returned settings witness`);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const baseWitnesses = [
|
|
132
|
+
"Status Line Custom Editor",
|
|
133
|
+
"Simulated statusbar",
|
|
134
|
+
"Hidden segment palette",
|
|
135
|
+
"Visible choices",
|
|
136
|
+
];
|
|
137
|
+
for (const witness of baseWitnesses) {
|
|
138
|
+
if (!plain.includes(witness)) throw new Error(`${entry.key}: missing witness ${witness}`);
|
|
139
|
+
}
|
|
140
|
+
if (entry.stateId.includes("choice-focused") && !plain.includes("Choices:")) {
|
|
141
|
+
throw new Error(`${entry.key}: missing choice panel witness`);
|
|
142
|
+
}
|
|
143
|
+
if (
|
|
144
|
+
entry.stateId === "picked-origin-slot" &&
|
|
145
|
+
(!plain.includes("Selected:") || plain.includes("Floating ghost") || plain.includes("Origin "))
|
|
146
|
+
) {
|
|
147
|
+
throw new Error(`${entry.key}: missing selected witness or stale ghost/origin text present`);
|
|
148
|
+
}
|
|
149
|
+
if (entry.stateId.includes("overflow") && !plain.includes("Warning: statusbar wrapped to 2 rows")) {
|
|
150
|
+
throw new Error(`${entry.key}: missing overflow warning`);
|
|
151
|
+
}
|
|
152
|
+
if (entry.stateId === "narrow-cjk" && !/[\u3131-\uD7A3\u3040-\u30FF\u3400-\u9FFF]/.test(plain)) {
|
|
153
|
+
throw new Error(`${entry.key}: missing CJK width witness`);
|
|
154
|
+
}
|
|
155
|
+
if (plain.includes("Move left:") || plain.includes("Move right:") || plain.includes("Segment: gajae")) {
|
|
156
|
+
throw new Error(`${entry.key}: legacy row witness present`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async function main(): Promise<void> {
|
|
161
|
+
const { root, requireIndependentReview } = parseArgs(process.argv.slice(2));
|
|
162
|
+
const manifestText = await Bun.file(path.join(root, "manifest.json")).text();
|
|
163
|
+
const manifest = JSON.parse(manifestText) as ManifestFile;
|
|
164
|
+
const manifestSha256 = sha256(manifestText);
|
|
165
|
+
if (manifest.tool !== CAPTURE_TOOL_VERSION) throw new Error(`Unexpected tool version: ${manifest.tool}`);
|
|
166
|
+
if (!/^[0-9a-f]{40}$/.test(manifest.sourceHead)) throw new Error("Manifest source HEAD is not a full commit SHA");
|
|
167
|
+
if (!/^sha256:[0-9a-f]{64}$/.test(manifest.sourceHash)) throw new Error("Manifest source hash is invalid");
|
|
168
|
+
const actualKeys = new Set(manifest.entries.map(entry => entry.key));
|
|
169
|
+
if (manifest.entries.length !== actualKeys.size) throw new Error("Duplicate showcase entries found");
|
|
170
|
+
if (manifest.entries.length !== EXPECTED_KEYS.size) throw new Error("Unexpected showcase entry count");
|
|
171
|
+
for (const key of EXPECTED_KEYS) if (!actualKeys.has(key)) throw new Error(`Missing showcase key: ${key}`);
|
|
172
|
+
for (const key of actualKeys) if (!EXPECTED_KEYS.has(key)) throw new Error(`Unexpected showcase key: ${key}`);
|
|
173
|
+
if (requireIndependentReview) {
|
|
174
|
+
const review = manifest.independentReview ?? (await tryReadReview(root));
|
|
175
|
+
if (
|
|
176
|
+
review?.verdict !== "approved" ||
|
|
177
|
+
!review.reviewer?.trim() ||
|
|
178
|
+
review.reviewer === manifest.captureActor ||
|
|
179
|
+
!(["OWNER", "MEMBER", "COLLABORATOR"] as const).includes(review.reviewerAssociation) ||
|
|
180
|
+
!/^https:\/\/github\.com\//.test(review.evidence) ||
|
|
181
|
+
review.manifestSha256 !== manifestSha256 ||
|
|
182
|
+
review.sourceHash !== manifest.sourceHash ||
|
|
183
|
+
review.headSha !== manifest.sourceHead
|
|
184
|
+
) {
|
|
185
|
+
throw new Error("Missing approved independent review in manifest");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const artifactPaths = new Set<string>();
|
|
189
|
+
const expectedRootFiles = new Set(["manifest.json"]);
|
|
190
|
+
if (await Bun.file(path.join(root, "independent-review.json")).exists())
|
|
191
|
+
expectedRootFiles.add("independent-review.json");
|
|
192
|
+
for (const entry of manifest.entries) {
|
|
193
|
+
if (entry.key !== `${entry.stateId}/${entry.viewport.columns}x${entry.viewport.rows}/${entry.renderMode}`) {
|
|
194
|
+
throw new Error(`${entry.key}: key does not match manifest fields`);
|
|
195
|
+
}
|
|
196
|
+
const expectedDirectory = entry.key.replace(/[^a-zA-Z0-9._/-]/g, "_");
|
|
197
|
+
const names = new Set(entry.files.map(file => path.basename(file.path)));
|
|
198
|
+
if (names.size !== 4 || entry.files.length !== 4)
|
|
199
|
+
throw new Error(`${entry.key}: artifact membership is not exact`);
|
|
200
|
+
for (const required of ["terminal.txt", "terminal-ansi.txt", "terminal.html", "metadata.json"]) {
|
|
201
|
+
if (!names.has(required)) throw new Error(`${entry.key}: missing ${required}`);
|
|
202
|
+
}
|
|
203
|
+
for (const file of entry.files) {
|
|
204
|
+
if (!file.path.startsWith(`${expectedDirectory}/`)) {
|
|
205
|
+
throw new Error(`${entry.key}: artifact path is not bound to canonical entry directory`);
|
|
206
|
+
}
|
|
207
|
+
if (artifactPaths.has(file.path)) throw new Error(`${entry.key}: duplicate artifact path ${file.path}`);
|
|
208
|
+
artifactPaths.add(file.path);
|
|
209
|
+
const content = await readText(root, file.path);
|
|
210
|
+
if (sha256(content) !== file.sha256) throw new Error(`${entry.key}: sha mismatch for ${file.path}`);
|
|
211
|
+
if (Buffer.byteLength(content) !== file.byte_length) {
|
|
212
|
+
throw new Error(`${entry.key}: byte length mismatch for ${file.path}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const plainPath = entry.files.find(file => path.basename(file.path) === "terminal.txt")?.path;
|
|
216
|
+
const ansiPath = entry.files.find(file => path.basename(file.path) === "terminal-ansi.txt")?.path;
|
|
217
|
+
const htmlPath = entry.files.find(file => path.basename(file.path) === "terminal.html")?.path;
|
|
218
|
+
const metadataPath = entry.files.find(file => path.basename(file.path) === "metadata.json")?.path;
|
|
219
|
+
if (!plainPath || !ansiPath || !htmlPath || !metadataPath) throw new Error(`${entry.key}: incomplete file list`);
|
|
220
|
+
const plain = await readText(root, plainPath);
|
|
221
|
+
const ansi = await readText(root, ansiPath);
|
|
222
|
+
const html = await readText(root, htmlPath);
|
|
223
|
+
if (Bun.stripANSI(ansi) !== plain) throw new Error(`${entry.key}: stripped ANSI differs from plain text`);
|
|
224
|
+
if (html !== ansiToHtml(ansi)) throw new Error(`${entry.key}: HTML artifact is not canonical ANSI conversion`);
|
|
225
|
+
if (plain.split("\n").length > entry.viewport.rows) {
|
|
226
|
+
throw new Error(`${entry.key}: terminal row count exceeds declared viewport`);
|
|
227
|
+
}
|
|
228
|
+
for (const line of plain.split("\n")) {
|
|
229
|
+
if (Bun.stringWidth(line) > entry.viewport.columns) {
|
|
230
|
+
throw new Error(`${entry.key}: terminal line exceeds declared viewport width`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (entry.renderMode === "ascii-no-color") {
|
|
234
|
+
if (/\x1b\[[0-9;]*m/.test(ansi)) throw new Error(`${entry.key}: ascii-no-color artifact contains ANSI`);
|
|
235
|
+
if (/[^\x09\x0a\x0d\x20-\x7e]/.test(plain)) {
|
|
236
|
+
throw new Error(`${entry.key}: ascii-no-color artifact contains non-ASCII glyphs`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
const metadata = JSON.parse(await readText(root, metadataPath)) as {
|
|
240
|
+
tool?: string;
|
|
241
|
+
command?: string;
|
|
242
|
+
stateId?: string;
|
|
243
|
+
viewport?: { columns?: number; rows?: number };
|
|
244
|
+
renderMode?: string;
|
|
245
|
+
fixedClock?: string;
|
|
246
|
+
simulatedStatusbarRows?: number;
|
|
247
|
+
wrappingPolicy?: string;
|
|
248
|
+
};
|
|
249
|
+
const actualStatusbarRows = measuredStatusbarRows(plain);
|
|
250
|
+
if (
|
|
251
|
+
metadata.tool !== CAPTURE_TOOL_VERSION ||
|
|
252
|
+
metadata.command !== CANONICAL_COMMAND ||
|
|
253
|
+
metadata.stateId !== entry.stateId ||
|
|
254
|
+
metadata.viewport?.columns !== entry.viewport.columns ||
|
|
255
|
+
metadata.viewport?.rows !== entry.viewport.rows ||
|
|
256
|
+
metadata.renderMode !== entry.renderMode ||
|
|
257
|
+
metadata.fixedClock !== FIXED_CLOCK ||
|
|
258
|
+
entry.simulatedStatusbarRows !== actualStatusbarRows ||
|
|
259
|
+
metadata.simulatedStatusbarRows !== actualStatusbarRows ||
|
|
260
|
+
metadata.wrappingPolicy !== expectedWrappingPolicy(actualStatusbarRows)
|
|
261
|
+
) {
|
|
262
|
+
throw new Error(`${entry.key}: metadata does not match manifest`);
|
|
263
|
+
}
|
|
264
|
+
requireWitness(entry, plain);
|
|
265
|
+
if (entry.stateId === "palette-exact-insert" && (plain.includes("Selected:") || plain.includes("{gajae}"))) {
|
|
266
|
+
throw new Error(`${entry.key}: exact insertion state still has floating/hidden segment evidence`);
|
|
267
|
+
}
|
|
268
|
+
if (entry.stateId === "palette-exact-insert" && !plain.includes("left model / path /")) {
|
|
269
|
+
throw new Error(`${entry.key}: exact insertion state missing ordered layout witness`);
|
|
270
|
+
}
|
|
271
|
+
if (
|
|
272
|
+
entry.stateId === "exit-restored" &&
|
|
273
|
+
!plain.includes("left=model,path,git right=session_name,jobs separator=slash")
|
|
274
|
+
) {
|
|
275
|
+
throw new Error(`${entry.key}: exit-restored state missing exact restored preview witness`);
|
|
276
|
+
}
|
|
277
|
+
if (
|
|
278
|
+
entry.stateId === "confirm-persisted" &&
|
|
279
|
+
!plain.includes("left=path,git right=session_name,jobs separator=slash")
|
|
280
|
+
) {
|
|
281
|
+
throw new Error(`${entry.key}: confirm-persisted state missing exact persisted preview witness`);
|
|
282
|
+
}
|
|
283
|
+
if (entry.stateId === "separator-choice-applied" && !plain.includes("[Pipe]")) {
|
|
284
|
+
throw new Error(`${entry.key}: separator applied state missing Pipe witness`);
|
|
285
|
+
}
|
|
286
|
+
if (entry.stateId === "option-choice-applied" && !plain.includes("[40]")) {
|
|
287
|
+
throw new Error(`${entry.key}: option applied state missing numeric option witness`);
|
|
288
|
+
}
|
|
289
|
+
if (entry.stateId.includes("narrow") && !plain.includes("Focused target:")) {
|
|
290
|
+
throw new Error(`${entry.key}: narrow state missing focused target witness`);
|
|
291
|
+
}
|
|
292
|
+
if (entry.stateId === "overflow-two-row-warning" && actualStatusbarRows !== 4) {
|
|
293
|
+
throw new Error(`${entry.key}: expected two actual and two slot statusbar rows`);
|
|
294
|
+
}
|
|
295
|
+
if (entry.stateId === "narrow-cjk" && !plain.includes("상태줄 경계 · 意味の境界 · 语义边界")) {
|
|
296
|
+
throw new Error(`${entry.key}: missing exact mixed-width semantic witness`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
for (const filePath of await collectRelativeFiles(root)) {
|
|
300
|
+
if (expectedRootFiles.has(filePath)) continue;
|
|
301
|
+
if (!artifactPaths.has(filePath)) throw new Error(`Unmanifested artifact file: ${filePath}`);
|
|
302
|
+
}
|
|
303
|
+
process.stdout.write(`Verified ${manifest.entries.length} status-line custom editor showcase entries at ${root}\n`);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
void main().catch(error => {
|
|
307
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
308
|
+
process.exit(1);
|
|
309
|
+
});
|
package/src/capability/index.ts
CHANGED
|
@@ -7,7 +7,14 @@
|
|
|
7
7
|
* - Loading items for a capability across all providers
|
|
8
8
|
*/
|
|
9
9
|
import * as path from "node:path";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
getAgentDir,
|
|
12
|
+
getAgentProfileAuthority,
|
|
13
|
+
getProjectDir,
|
|
14
|
+
getTrustedHomeDir,
|
|
15
|
+
logger,
|
|
16
|
+
normalizePathForComparison,
|
|
17
|
+
} from "@gajae-code/utils";
|
|
11
18
|
|
|
12
19
|
import type { Settings } from "../config/settings";
|
|
13
20
|
import { clearCache as clearFsCache, findRepoRoot, cacheStats as fsCacheStats, invalidate as invalidateFs } from "./fs";
|
|
@@ -243,8 +250,13 @@ export async function loadCapability<T>(capabilityId: string, options: LoadOptio
|
|
|
243
250
|
const cwd = options.cwd ?? getProjectDir();
|
|
244
251
|
const home = getTrustedHomeDir();
|
|
245
252
|
const userAgentDir = options.agentDir ? path.resolve(options.agentDir) : getAgentDir();
|
|
253
|
+
const profileAuthority =
|
|
254
|
+
options.profileAuthority ??
|
|
255
|
+
(options.agentDir && normalizePathForComparison(userAgentDir) !== normalizePathForComparison(getAgentDir())
|
|
256
|
+
? "custom"
|
|
257
|
+
: getAgentProfileAuthority());
|
|
246
258
|
const repoRoot = await findRepoRoot(cwd);
|
|
247
|
-
const ctx: LoadContext = { cwd, home, userAgentDir, repoRoot, settings: options.settings };
|
|
259
|
+
const ctx: LoadContext = { cwd, home, userAgentDir, profileAuthority, repoRoot, settings: options.settings };
|
|
248
260
|
const providers = filterProviders(capability, options);
|
|
249
261
|
|
|
250
262
|
return await loadImpl(capability, providers, ctx, options);
|
package/src/capability/types.ts
CHANGED
|
@@ -29,6 +29,8 @@ export interface LoadContext {
|
|
|
29
29
|
* produced. This includes MCP registrations and user-installed skills.
|
|
30
30
|
*/
|
|
31
31
|
userAgentDir?: string;
|
|
32
|
+
/** Resolver-owned classification for the selected user agent directory. */
|
|
33
|
+
profileAuthority?: "default" | "custom";
|
|
32
34
|
/** Git repository root (directory containing .git), or null if not in a repo */
|
|
33
35
|
repoRoot: string | null;
|
|
34
36
|
/** Owning session settings for provider policy decisions. */
|
|
@@ -89,6 +91,8 @@ export interface LoadOptions {
|
|
|
89
91
|
* process-wide one (`createAgentSession({ agentDir })`).
|
|
90
92
|
*/
|
|
91
93
|
agentDir?: string;
|
|
94
|
+
/** Resolver-owned classification for `agentDir`; preserve it across HOME/config refreshes. */
|
|
95
|
+
profileAuthority?: "default" | "custom";
|
|
92
96
|
/** Include items even if they fail validation. Default: false */
|
|
93
97
|
includeInvalid?: boolean;
|
|
94
98
|
/** Include items disabled via settings. Default: false */
|
package/src/cli/args.ts
CHANGED
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
* CLI argument parsing
|
|
3
3
|
*/
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
-
import {
|
|
5
|
+
import { ThinkingLevel } from "@gajae-code/agent-core";
|
|
6
6
|
import { logger } from "@gajae-code/utils";
|
|
7
7
|
import { CliParseError } from "@gajae-code/utils/cli";
|
|
8
|
-
import {
|
|
8
|
+
import { parseThinkingLevel } from "../thinking";
|
|
9
9
|
import { BUILTIN_TOOLS } from "../tools";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
type ConsumerLaunchFlagName,
|
|
12
|
+
LAUNCH_PARSE_FLAGS,
|
|
13
|
+
launchFlagIsOwnedBy,
|
|
14
|
+
ROOT_THINKING_LEVELS,
|
|
15
|
+
type RootThinkingLevel,
|
|
16
|
+
} from "./root-flags";
|
|
11
17
|
|
|
12
18
|
const ROOT_FLAG_TOKENS = new Set<string>();
|
|
13
19
|
for (const [name, descriptor] of Object.entries(LAUNCH_PARSE_FLAGS)) {
|
|
@@ -55,7 +61,7 @@ export interface Args {
|
|
|
55
61
|
mcpConfig?: string;
|
|
56
62
|
/** Opt a standalone session out of conventional MCP autoload (mutually exclusive with --mcp-config). */
|
|
57
63
|
noMcp?: boolean;
|
|
58
|
-
thinking?:
|
|
64
|
+
thinking?: RootThinkingLevel;
|
|
59
65
|
continue?: boolean;
|
|
60
66
|
resume?: string | true;
|
|
61
67
|
help?: boolean;
|
|
@@ -138,6 +144,7 @@ export function parseArgs(args: string[], authority: ParseArgsAuthority = "local
|
|
|
138
144
|
unknownFlags: new Map(),
|
|
139
145
|
};
|
|
140
146
|
const consumerFlags = new Map<ConsumerLaunchFlagName, string>();
|
|
147
|
+
let hasThinkingFlag = false;
|
|
141
148
|
|
|
142
149
|
for (let i = 0; i < args.length; i++) {
|
|
143
150
|
let arg = args[i];
|
|
@@ -344,19 +351,23 @@ export function parseArgs(args: string[], authority: ParseArgsAuthority = "local
|
|
|
344
351
|
}
|
|
345
352
|
result.tools = validTools;
|
|
346
353
|
} else if (arg === "--thinking") {
|
|
354
|
+
if (hasThinkingFlag) {
|
|
355
|
+
throw new CliParseError("--thinking can only be specified once");
|
|
356
|
+
}
|
|
357
|
+
hasThinkingFlag = true;
|
|
347
358
|
// Match --credential / --mcp-config: a missing value or a following flag is
|
|
348
359
|
// a usage error, not a silent no-op / accidental consumption of `-p`.
|
|
349
360
|
const next = args[i + 1];
|
|
350
361
|
if (!next || next.startsWith("-")) {
|
|
351
|
-
throw new CliParseError(`--thinking requires <level> (${
|
|
362
|
+
throw new CliParseError(`--thinking requires <level> (${ROOT_THINKING_LEVELS.join(", ")})`);
|
|
352
363
|
}
|
|
353
364
|
const rawThinking = args[++i];
|
|
354
|
-
const thinking =
|
|
355
|
-
if (thinking === undefined) {
|
|
365
|
+
const thinking = parseThinkingLevel(rawThinking);
|
|
366
|
+
if (thinking === undefined || thinking === ThinkingLevel.Inherit) {
|
|
356
367
|
// Fail closed: a silent ignore left users believing `ultra` (or any typo)
|
|
357
|
-
// was applied. Help / Flags.options advertise the
|
|
368
|
+
// was applied. Help / Flags.options advertise the root thinking levels.
|
|
358
369
|
throw new CliParseError(
|
|
359
|
-
`Invalid --thinking level "${rawThinking}". Expected one of: ${
|
|
370
|
+
`Invalid --thinking level "${rawThinking}". Expected one of: ${ROOT_THINKING_LEVELS.join(", ")}`,
|
|
360
371
|
);
|
|
361
372
|
}
|
|
362
373
|
result.thinking = thinking;
|