praxis-agent 0.11.0 → 0.13.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.
Files changed (31) hide show
  1. package/README.md +13 -2
  2. package/dist/application/subagent-service.d.ts +1 -1
  3. package/dist/application/subagent-service.js +33 -2
  4. package/dist/cli/interactive.d.ts +6 -1
  5. package/dist/cli/interactive.js +197 -5
  6. package/dist/cli/tui/claude-command-inventory.d.ts +35 -19
  7. package/dist/cli/tui/claude-command-inventory.js +98 -18
  8. package/dist/cli/tui/release-notes.d.ts +10 -0
  9. package/dist/cli/tui/release-notes.js +60 -0
  10. package/dist/cli/tui/sandbox-dashboard.d.ts +10 -0
  11. package/dist/cli/tui/sandbox-dashboard.js +78 -0
  12. package/dist/cli/tui/sandbox-settings.d.ts +32 -0
  13. package/dist/cli/tui/sandbox-settings.js +146 -0
  14. package/dist/cli/tui/slash-commands.js +10 -0
  15. package/dist/cli/tui/status-line.d.ts +88 -0
  16. package/dist/cli/tui/status-line.js +234 -0
  17. package/dist/cli.d.ts +2 -0
  18. package/dist/cli.js +73 -3
  19. package/dist/extensions/claude-extensions.d.ts +1 -0
  20. package/dist/extensions/claude-extensions.js +55 -3
  21. package/dist/permissions/bash-path-safety.d.ts +2 -0
  22. package/dist/permissions/bash-path-safety.js +7 -0
  23. package/dist/permissions/claude-permission-resolver.d.ts +11 -0
  24. package/dist/permissions/claude-permission-resolver.js +15 -0
  25. package/dist/sandbox/claude-sandbox-runtime.d.ts +54 -0
  26. package/dist/sandbox/claude-sandbox-runtime.js +175 -0
  27. package/dist/sandbox/claude-sandbox-settings.d.ts +23 -0
  28. package/dist/sandbox/claude-sandbox-settings.js +286 -0
  29. package/dist/tools/local-tools.d.ts +18 -0
  30. package/dist/tools/local-tools.js +47 -8
  31. package/package.json +2 -1
package/README.md CHANGED
@@ -15,6 +15,11 @@ Anthropic/OpenAI-compatible model access. Praxis deliberately excludes
15
15
  accounts, organizations, billing, managed enterprise policy, remote control,
16
16
  IDE surfaces, and telemetry control planes.
17
17
 
18
+ Claude Code 2.1.208 is the compatibility, architecture, and design baseline.
19
+ Every single-user CLI capability remains required unless it falls inside an
20
+ explicit exclusion above. A similar Praxis surface is not a substitute for the
21
+ corresponding Claude command or runtime contract.
22
+
18
23
  ## Requirements
19
24
 
20
25
  - macOS or Linux
@@ -87,8 +92,10 @@ troubleshooting. Run `praxis --help` for the authoritative command surface.
87
92
  `/rewind`, runtime `/cd`, transcript-free
88
93
  `/btw` side questions with background-Agent handoff, interactive
89
94
  `/background` terminal handoff, unified `/status`/`/config`/`/usage` settings
90
- tabs, `/mcp`, `/memory` shared
91
- instruction and auto-memory access, and live extension-reload controls,
95
+ tabs, `/sandbox` mode/dependency/override/config controls, local cached
96
+ `/release-notes`, Claude-compatible `/statusline` command execution and setup
97
+ agent, `/mcp`, `/memory` shared instruction and auto-memory access, and live
98
+ extension-reload controls,
92
99
  cursor/history composer, per-session model/effort/permission controls,
93
100
  context/status/skill/task dashboards, prompt stash and continuation shortcuts,
94
101
  filterable `@` file and agent references, composer undo, `Ctrl+G` external
@@ -121,6 +128,10 @@ troubleshooting. Run `praxis --help` for the authoritative command surface.
121
128
  constraints, internal auto-memory/session/task path handling, compound `cd` +
122
129
  Git protection, mode-ordered `acceptEdits` handling, live raw/resolved-path
123
130
  grants for external directories,
131
+ Claude-compatible opt-in Bash sandboxing with filesystem and network
132
+ isolation, explicit ask/deny precedence, sandbox-only auto-allow,
133
+ write-allowlist/deny-within-allow enforcement, per-command overrides and
134
+ exclusions, violation reporting, and bare-repository control-file cleanup,
124
135
  safe-property Skill auto-allow, interactive
125
136
  workspace-directory add/remove controls, path confinement, credential
126
137
  redaction, and sanitized child processes.
@@ -1,7 +1,7 @@
1
1
  import { type ClaudeSidechainPermissionMode } from '../compatibility/claude/sidechain.js';
2
2
  import { type ContextAssembler } from '../core/context.js';
3
3
  import { type ModelProvider, type ModelToolCall, type ModelToolDefinition, type ModelUsage, type PermissionResolver, type PermissionApproval, type PermissionDecision, type PermissionUpdate, type RuntimeEventSink, type ToolExecutionContext, type ToolExecutionResult, type ToolRegistry } from '../core/runtime.js';
4
- import type { ClaudeExtensionCatalog } from '../extensions/claude-extensions.js';
4
+ import { type ClaudeExtensionCatalog } from '../extensions/claude-extensions.js';
5
5
  import type { ClaudeHookRunner } from '../hooks/claude-hooks.js';
6
6
  import { type BackgroundAgentSnapshot } from './background-agent-manager.js';
7
7
  export interface WorkflowAgentRunOptions {
@@ -11,6 +11,7 @@ import { createClaudeHookAttachmentEntries, translateProviderEvents, } from '../
11
11
  import { injectFirstUserMessageContext, } from '../core/context.js';
12
12
  import { ContextBudget } from '../core/context-budget.js';
13
13
  import { AgentRuntime, } from '../core/runtime.js';
14
+ import { BUILTIN_STATUSLINE_AGENT_PATH, } from '../extensions/claude-extensions.js';
14
15
  import { ClaudeHookToolCoordinator } from '../hooks/claude-hook-tools.js';
15
16
  import { ClaudeSidechainStore } from '../persistence/claude-sidechain-store.js';
16
17
  import { InMemorySidechainStore } from '../persistence/in-memory-sidechain-store.js';
@@ -79,6 +80,29 @@ export class StructuredOutputRegistry {
79
80
  });
80
81
  }
81
82
  }
83
+ class RestrictedToolRegistry {
84
+ base;
85
+ allowed;
86
+ constructor(base, names) {
87
+ this.base = base;
88
+ this.allowed = new Set(names);
89
+ }
90
+ definitions() {
91
+ return this.base
92
+ .definitions()
93
+ .filter((definition) => this.allowed.has(definition.name));
94
+ }
95
+ prepare(call, context) {
96
+ if (!this.allowed.has(call.name))
97
+ throw new Error(`Tool ${call.name} is unavailable to this agent`);
98
+ return this.base.prepare(call, context);
99
+ }
100
+ execute(call, context) {
101
+ if (!this.allowed.has(call.name))
102
+ throw new Error(`Tool ${call.name} is unavailable to this agent`);
103
+ return this.base.execute(call, context);
104
+ }
105
+ }
82
106
  function parseAgentInput(call) {
83
107
  const allowed = new Set([
84
108
  'description',
@@ -942,9 +966,16 @@ export class ClaudeSubagentExecutor {
942
966
  permission_mode: options.input.permissionMode ?? 'default',
943
967
  };
944
968
  const nestedTools = this.registry(String(options.root.sessionId), options.spawnDepth, () => options.promptId);
945
- const agentTools = options.outputSchema
946
- ? new StructuredOutputRegistry(structuredOnlyTools, options.outputSchema, options.structuredOutput)
969
+ const builtInStatusLineAgent = this.options.extensions?.agent(options.input.subagentType)?.path ===
970
+ BUILTIN_STATUSLINE_AGENT_PATH;
971
+ const scopedTools = builtInStatusLineAgent
972
+ ? new RestrictedToolRegistry(nestedTools, ['Read', 'Edit'])
947
973
  : nestedTools;
974
+ const agentTools = options.outputSchema
975
+ ? new StructuredOutputRegistry(builtInStatusLineAgent
976
+ ? new RestrictedToolRegistry(structuredOnlyTools, ['Read', 'Edit'])
977
+ : structuredOnlyTools, options.outputSchema, options.structuredOutput)
978
+ : scopedTools;
948
979
  const runtimeTools = this.options.hooks
949
980
  ? new ClaudeHookToolCoordinator({
950
981
  tools: agentTools,
@@ -18,6 +18,7 @@ import { loadTuiKeybindings, type TuiKeybindingsFile } from './tui/keybindings.j
18
18
  import { completeTuiWorkspaceDirectory, resolveTuiWorkspaceDirectory } from './tui/workspace-directories.js';
19
19
  import { type TuiThemeSettings } from './tui/theme.js';
20
20
  import { type CustomThemeBase, type CustomThemeToken, type TuiCustomTheme } from './tui/custom-themes.js';
21
+ import { type TuiSandboxStore } from './tui/sandbox-settings.js';
21
22
  import { type ConfigSettingsTarget } from './tui/config-settings.js';
22
23
  import { type PraxisRuntimeSettings } from './tui/runtime-settings.js';
23
24
  import { type TuiNotificationWriter } from './tui/terminal-notifications.js';
@@ -152,6 +153,7 @@ interface InteractiveAppProps {
152
153
  }): Promise<void>;
153
154
  remove?(rule: TuiPermissionRule): Promise<void>;
154
155
  };
156
+ sandboxStore?: TuiSandboxStore;
155
157
  recentlyDeniedStore?: RecentlyDeniedStore;
156
158
  themeStore?: {
157
159
  load(): Promise<TuiThemeSettings>;
@@ -173,8 +175,10 @@ interface InteractiveAppProps {
173
175
  runtimeSettingsTarget?: ConfigSettingsTarget;
174
176
  notificationWriter?: TuiNotificationWriter;
175
177
  elicitationUrlOpener?: (url: string) => void | Promise<void>;
178
+ releaseNotesLoader?: (configRoot: string) => Promise<string>;
179
+ settingSources?: readonly ClaudeResourceScope[];
176
180
  }
177
- export declare function InteractiveApp({ factory, initialSessions, initialPrompt, initialHistory, signal, onCancel, onTurnChange, onCleanup, onRendererChange, onBackground, axScreenReader, allowNewSession, resume, display, terminalWidth, slashCommands, agents, allowDangerouslySkipPermissions, additionalDirectories, diffLoader, fileLoader, externalEditor, keybindingsConfigRoot, keybindingsFile, keybindingsLoader, keybindingsEditor, memoryFilesLoader, memoryEditor, memoryFolderOpener, suspendProcess, clipboardReader, clipboardWriter, sideQuestionClipboardWriter, exportWriter, permissionRuleStore, recentlyDeniedStore: suppliedRecentlyDeniedStore, terminalSetup: terminalSetupOverride, themeStore, initialThemeSettings, initialThemeLoadError, workspaceDirectoryResolver, workspaceDirectoryCompleter, runtimeSettings: suppliedRuntimeSettings, runtimeSettingsTarget, notificationWriter, elicitationUrlOpener, }: InteractiveAppProps): import("react").JSX.Element;
181
+ export declare function InteractiveApp({ factory, initialSessions, initialPrompt, initialHistory, signal, onCancel, onTurnChange, onCleanup, onRendererChange, onBackground, axScreenReader, allowNewSession, resume, display, terminalWidth, slashCommands, agents, allowDangerouslySkipPermissions, additionalDirectories, diffLoader, fileLoader, externalEditor, keybindingsConfigRoot, keybindingsFile, keybindingsLoader, keybindingsEditor, memoryFilesLoader, memoryEditor, memoryFolderOpener, suspendProcess, clipboardReader, clipboardWriter, sideQuestionClipboardWriter, exportWriter, permissionRuleStore, sandboxStore: suppliedSandboxStore, recentlyDeniedStore: suppliedRecentlyDeniedStore, terminalSetup: terminalSetupOverride, themeStore, initialThemeSettings, initialThemeLoadError, workspaceDirectoryResolver, workspaceDirectoryCompleter, runtimeSettings: suppliedRuntimeSettings, runtimeSettingsTarget, notificationWriter, elicitationUrlOpener, releaseNotesLoader, settingSources, }: InteractiveAppProps): import("react").JSX.Element;
178
182
  export declare function runInteractive(options: {
179
183
  factory: InteractiveServiceFactory;
180
184
  initialPrompt?: string;
@@ -190,6 +194,7 @@ export declare function runInteractive(options: {
190
194
  onBackground?: (request: InteractiveBackgroundRequest) => Promise<InteractiveBackgroundResult>;
191
195
  onBackgrounded?: (result: InteractiveBackgroundResult) => void;
192
196
  runtimeSettings?: PraxisRuntimeSettings;
197
+ settingSources?: readonly ClaudeResourceScope[];
193
198
  }): Promise<number>;
194
199
  export {};
195
200
  //# sourceMappingURL=interactive.d.ts.map
@@ -12,6 +12,8 @@ import { claudePermissionActionKey, claudePermissionRuleMatches, } from '../perm
12
12
  import { redactSensitiveText, sensitiveEnvironmentValues, } from '../platform/sensitive-data.js';
13
13
  import { CommandPalette, BtwPanel, Composer, DiffDashboard, DialogFrame, ExternalEditorWait, HelpMenu, HookDashboard, ListDashboard, MemoryDashboard, MentionPicker, ModelMenu, PermissionDashboard, SelectionMenu, SessionPicker, ThemePicker, CustomThemeEditor, Transcript, WelcomePanel, useTerminalWidth, } from './tui/claude-style.js';
14
14
  import { loadTuiMemoryFiles, openTuiMemoryFolder, } from './tui/memory-files.js';
15
+ import { loadClaudeReleaseNotes } from './tui/release-notes.js';
16
+ import { createClaudeStatusLineInput, StatusLine } from './tui/status-line.js';
15
17
  import { loadGitDiff, visiblePatchLines, } from './tui/git-diff.js';
16
18
  import { addTuiPermissionRule, loadTuiPermissionRules, removeTuiPermissionRule, } from './tui/permission-settings.js';
17
19
  import { createRecentlyDeniedStore, } from './tui/recently-denied.js';
@@ -33,6 +35,8 @@ import { commitElicitationText, createTuiElicitationForm, elicitationFormIsValid
33
35
  import { openTuiUrl } from './tui/open-url.js';
34
36
  import { projectTuiToolPermission, ToolPermissionDialog, } from './tui/tool-permission.js';
35
37
  import { ConfigDashboard, projectConfigRows } from './tui/config-dashboard.js';
38
+ import { SandboxDashboard, tuiSandboxTabs } from './tui/sandbox-dashboard.js';
39
+ import { createTuiSandboxStore, } from './tui/sandbox-settings.js';
36
40
  import { loadConfigSettings, saveConfigSetting, configSettingDefinition, resolveConfigSettingsLocation, } from './tui/config-settings.js';
37
41
  import { projectRuntimeSettings, loadRuntimeSettings, } from './tui/runtime-settings.js';
38
42
  import { autoUpdateTarget, copyCandidates, externalEditorInitialContent, formatTurnDuration, questionTimeoutMilliseconds, sessionRecap, spinnerTip, shouldShowCopyPicker, } from './tui/runtime-interactions.js';
@@ -232,7 +236,18 @@ function ordinal(value) {
232
236
  return `${value}th`;
233
237
  }
234
238
  }
235
- export function InteractiveApp({ factory, initialSessions, initialPrompt, initialHistory = [], signal, onCancel, onTurnChange, onCleanup, onRendererChange, onBackground, axScreenReader = false, allowNewSession = true, resume, display = { version: 'dev', cwd: process.cwd() }, terminalWidth, slashCommands = EMPTY_SLASH_COMMANDS, agents = EMPTY_AGENTS, allowDangerouslySkipPermissions = false, additionalDirectories = [], diffLoader, fileLoader, externalEditor = editTuiPrompt, keybindingsConfigRoot, keybindingsFile = ensureTuiKeybindingsFile, keybindingsLoader = loadTuiKeybindings, keybindingsEditor = openTuiEditorFile, memoryFilesLoader = (configRoot, cwd) => loadTuiMemoryFiles({ configRoot, cwd }), memoryEditor = openTuiEditorFile, memoryFolderOpener = openTuiMemoryFolder, suspendProcess = suspendTuiProcess, clipboardReader = readTuiClipboard, clipboardWriter = writeTuiClipboard, sideQuestionClipboardWriter = writeTuiOsc52Clipboard, exportWriter = writeConversationExport, permissionRuleStore, recentlyDeniedStore: suppliedRecentlyDeniedStore, terminalSetup: terminalSetupOverride, themeStore, initialThemeSettings, initialThemeLoadError, workspaceDirectoryResolver = resolveTuiWorkspaceDirectory, workspaceDirectoryCompleter = completeTuiWorkspaceDirectory, runtimeSettings: suppliedRuntimeSettings, runtimeSettingsTarget, notificationWriter, elicitationUrlOpener = openTuiUrl, }) {
239
+ const HIDDEN_TUI_SLASH_COMMANDS = new Set([
240
+ 'background',
241
+ 'new',
242
+ 'output-style',
243
+ 'reload-skills',
244
+ 'sessions',
245
+ 'skill',
246
+ 'terminal-setup',
247
+ 'update',
248
+ 'usage',
249
+ ]);
250
+ export function InteractiveApp({ factory, initialSessions, initialPrompt, initialHistory = [], signal, onCancel, onTurnChange, onCleanup, onRendererChange, onBackground, axScreenReader = false, allowNewSession = true, resume, display = { version: 'dev', cwd: process.cwd() }, terminalWidth, slashCommands = EMPTY_SLASH_COMMANDS, agents = EMPTY_AGENTS, allowDangerouslySkipPermissions = false, additionalDirectories = [], diffLoader, fileLoader, externalEditor = editTuiPrompt, keybindingsConfigRoot, keybindingsFile = ensureTuiKeybindingsFile, keybindingsLoader = loadTuiKeybindings, keybindingsEditor = openTuiEditorFile, memoryFilesLoader = (configRoot, cwd) => loadTuiMemoryFiles({ configRoot, cwd }), memoryEditor = openTuiEditorFile, memoryFolderOpener = openTuiMemoryFolder, suspendProcess = suspendTuiProcess, clipboardReader = readTuiClipboard, clipboardWriter = writeTuiClipboard, sideQuestionClipboardWriter = writeTuiOsc52Clipboard, exportWriter = writeConversationExport, permissionRuleStore, sandboxStore: suppliedSandboxStore, recentlyDeniedStore: suppliedRecentlyDeniedStore, terminalSetup: terminalSetupOverride, themeStore, initialThemeSettings, initialThemeLoadError, workspaceDirectoryResolver = resolveTuiWorkspaceDirectory, workspaceDirectoryCompleter = completeTuiWorkspaceDirectory, runtimeSettings: suppliedRuntimeSettings, runtimeSettingsTarget, notificationWriter, elicitationUrlOpener = openTuiUrl, releaseNotesLoader = (configRoot) => loadClaudeReleaseNotes({ configRoot }), settingSources, }) {
236
251
  const { exit, suspendTerminal, waitUntilRenderFlush } = useApp();
237
252
  const width = useTerminalWidth(terminalWidth);
238
253
  const keybindingsRoot = useMemo(() => resolve(keybindingsConfigRoot ??
@@ -286,6 +301,7 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
286
301
  const [selectedIndex, setSelectedIndex] = useState(0);
287
302
  const selectedIndexRef = useRef(0);
288
303
  const [sessionId, setSessionId] = useState(resume?.sessionId ?? null);
304
+ const statusLineSessionId = useRef(resume?.sessionId ?? randomUUID());
289
305
  const sessionIdRef = useRef(resume?.sessionId ?? null);
290
306
  sessionIdRef.current = sessionId;
291
307
  const [sessionName, setSessionName] = useState(null);
@@ -369,6 +385,18 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
369
385
  permissionMode: permissionMode(display.permissionMode),
370
386
  additionalDirectories: [...new Set(additionalDirectories)],
371
387
  }));
388
+ const sandboxStore = useMemo(() => suppliedSandboxStore ??
389
+ createTuiSandboxStore({
390
+ configRoot: keybindingsRoot,
391
+ cwd: runtimeCwd,
392
+ homeDirectory: homedir(),
393
+ additionalDirectories: runtimePreferences.additionalDirectories,
394
+ }), [
395
+ keybindingsRoot,
396
+ runtimeCwd,
397
+ runtimePreferences.additionalDirectories,
398
+ suppliedSandboxStore,
399
+ ]);
372
400
  const runtimePreferencesRef = useRef(runtimePreferences);
373
401
  const [permission, setPermission] = useState(null);
374
402
  const permissionRef = useRef(null);
@@ -3157,6 +3185,62 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
3157
3185
  }
3158
3186
  return;
3159
3187
  }
3188
+ if (earlyMenu?.kind === 'sandbox') {
3189
+ if (key.escape || value === '\u001B') {
3190
+ updateMenu(null);
3191
+ return;
3192
+ }
3193
+ const tabs = tuiSandboxTabs(earlyMenu.snapshot);
3194
+ if (key.leftArrow || key.rightArrow || key.tab) {
3195
+ const index = tabs.indexOf(earlyMenu.tab);
3196
+ const direction = key.leftArrow || (key.tab && key.shift) ? -1 : 1;
3197
+ const tab = tabs[Math.max(0, Math.min(tabs.length - 1, index + direction))] ??
3198
+ earlyMenu.tab;
3199
+ updateMenu({ ...earlyMenu, tab, selectedIndex: 0 });
3200
+ return;
3201
+ }
3202
+ const rowCount = earlyMenu.tab === 'mode'
3203
+ ? 3
3204
+ : earlyMenu.tab === 'overrides' && earlyMenu.snapshot.settings.enabled
3205
+ ? 2
3206
+ : 0;
3207
+ if (rowCount > 0 && (key.upArrow || key.downArrow)) {
3208
+ updateMenu({
3209
+ ...earlyMenu,
3210
+ selectedIndex: Math.max(0, Math.min(rowCount - 1, earlyMenu.selectedIndex + (key.upArrow ? -1 : 1))),
3211
+ });
3212
+ return;
3213
+ }
3214
+ if (rowCount > 0 && key.return) {
3215
+ const saving = (async () => {
3216
+ setBusy(true);
3217
+ try {
3218
+ const snapshot = earlyMenu.tab === 'mode'
3219
+ ? await sandboxStore.setMode(['auto-allow', 'regular', 'disabled'][earlyMenu.selectedIndex] ?? 'auto-allow')
3220
+ : await sandboxStore.setAllowUnsandboxedCommands(earlyMenu.selectedIndex === 0);
3221
+ await retireService();
3222
+ const tabs = tuiSandboxTabs(snapshot);
3223
+ updateMenu({
3224
+ kind: 'sandbox',
3225
+ tab: tabs.includes(earlyMenu.tab)
3226
+ ? earlyMenu.tab
3227
+ : (tabs[0] ?? 'dependencies'),
3228
+ selectedIndex: earlyMenu.selectedIndex,
3229
+ snapshot,
3230
+ });
3231
+ }
3232
+ catch (error) {
3233
+ warn(error);
3234
+ }
3235
+ finally {
3236
+ setBusy(false);
3237
+ }
3238
+ })();
3239
+ onTurnChange?.(saving);
3240
+ void saving.finally(() => onTurnChange?.(null));
3241
+ }
3242
+ return;
3243
+ }
3160
3244
  if (earlyMenu?.kind === 'config') {
3161
3245
  if (key.escape || value === '\u001B') {
3162
3246
  if (earlyMenu.searchFocused && earlyMenu.query) {
@@ -4673,9 +4757,13 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
4673
4757
  commandNameQuery === selectedCommand.name.toLocaleLowerCase();
4674
4758
  const selectedCommandMatchesName = selectedCommand !== undefined &&
4675
4759
  selectedCommand.name.toLocaleLowerCase().startsWith(commandNameQuery);
4760
+ const exactHiddenCommand = HIDDEN_TUI_SLASH_COMMANDS.has(commandNameQuery);
4676
4761
  if (selectedCommand &&
4677
4762
  (key.tab ||
4678
- (key.return && !exactSelectedCommand && selectedCommandMatchesName))) {
4763
+ (key.return &&
4764
+ !exactSelectedCommand &&
4765
+ !exactHiddenCommand &&
4766
+ selectedCommandMatchesName))) {
4679
4767
  updateComposerInput(`/${selectedCommand.name} `);
4680
4768
  setCommandPaletteOpen(false);
4681
4769
  return;
@@ -4702,6 +4790,7 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
4702
4790
  if (!prompt || prompt === '!')
4703
4791
  return;
4704
4792
  const copyCommand = /^\/copy(?:\s+(\d+))?$/u.exec(prompt);
4793
+ const sandboxCommand = /^\/sandbox(?:\s+([\s\S]+))?$/u.exec(prompt);
4705
4794
  const tuiCommand = /^\/tui(?:\s+(default|fullscreen))?$/u.exec(prompt);
4706
4795
  const renameCommand = /^\/rename(?:\s+(.+))?$/u.exec(prompt);
4707
4796
  const cdCommand = /^\/cd(?:\s+(.+))?$/u.exec(prompt);
@@ -4713,11 +4802,13 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
4713
4802
  updateMenu({ kind: 'help', tabIndex: 0, selectedIndex: 0 });
4714
4803
  }
4715
4804
  else if (prompt === '/new') {
4805
+ statusLineSessionId.current = randomUUID();
4716
4806
  setSessionId(null);
4717
4807
  setPendingFork(false);
4718
4808
  append({ kind: 'notice', text: 'Started a new session.' });
4719
4809
  }
4720
4810
  else if (prompt === '/clear') {
4811
+ statusLineSessionId.current = randomUUID();
4721
4812
  setSessionId(null);
4722
4813
  setPendingFork(false);
4723
4814
  setHistory([]);
@@ -4883,6 +4974,52 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
4883
4974
  append({ kind: 'user', text: prompt });
4884
4975
  updateMenu({ kind: 'export', selectedIndex: 0 });
4885
4976
  }
4977
+ else if (sandboxCommand) {
4978
+ const operation = (async () => {
4979
+ setBusy(true);
4980
+ try {
4981
+ const args = sandboxCommand[1]?.trim();
4982
+ if (args) {
4983
+ const exclude = /^exclude(?:\s+([\s\S]+))?$/u.exec(args);
4984
+ if (!exclude) {
4985
+ throw new Error(`Unknown subcommand "${args.split(/\s+/u)[0] ?? args}". Available subcommand: exclude`);
4986
+ }
4987
+ if (!exclude[1]?.trim()) {
4988
+ throw new Error('Please provide a command pattern to exclude (e.g. /sandbox exclude "npm run test:*")');
4989
+ }
4990
+ const result = await sandboxStore.exclude(exclude[1]);
4991
+ await retireService();
4992
+ append({
4993
+ kind: 'local-result',
4994
+ text: `Added "${result.pattern}" to excluded commands in ${result.settingsPath}`,
4995
+ });
4996
+ return;
4997
+ }
4998
+ const snapshot = await sandboxStore.load();
4999
+ if (!snapshot.supported) {
5000
+ throw new Error('Sandboxing is currently only supported on macOS, Linux, and WSL2.');
5001
+ }
5002
+ if (snapshot.unavailableReason?.includes('not in sandbox.enabledPlatforms')) {
5003
+ throw new Error(snapshot.unavailableReason);
5004
+ }
5005
+ const tabs = tuiSandboxTabs(snapshot);
5006
+ updateMenu({
5007
+ kind: 'sandbox',
5008
+ tab: tabs[0] ?? 'dependencies',
5009
+ selectedIndex: 0,
5010
+ snapshot,
5011
+ });
5012
+ }
5013
+ catch (error) {
5014
+ warn(error);
5015
+ }
5016
+ finally {
5017
+ setBusy(false);
5018
+ }
5019
+ })();
5020
+ onTurnChange?.(operation);
5021
+ void operation.finally(() => onTurnChange?.(null));
5022
+ }
4886
5023
  else if (prompt === '/permissions') {
4887
5024
  const loading = (async () => {
4888
5025
  setBusy(true);
@@ -5044,6 +5181,27 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
5044
5181
  else if (prompt === '/status') {
5045
5182
  openSettings('status');
5046
5183
  }
5184
+ else if (prompt === '/release-notes') {
5185
+ const loading = (async () => {
5186
+ setBusy(true);
5187
+ setStatus('loading release notes');
5188
+ try {
5189
+ append({
5190
+ kind: 'local-result',
5191
+ text: await releaseNotesLoader(keybindingsRoot),
5192
+ });
5193
+ }
5194
+ catch (error) {
5195
+ warn(error);
5196
+ }
5197
+ finally {
5198
+ setBusy(false);
5199
+ setStatus('ready');
5200
+ }
5201
+ })();
5202
+ onTurnChange?.(loading);
5203
+ void loading.finally(() => onTurnChange?.(null));
5204
+ }
5047
5205
  else if (prompt === '/config') {
5048
5206
  openSettings('config');
5049
5207
  }
@@ -5197,7 +5355,7 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
5197
5355
  ? `restore ${menu.point.fileChanges.join(', ')}.`
5198
5356
  : 'be unchanged.'] }), _jsx(Text, { children: " " }), rewindActions(menu.point).map((option, index) => (_jsxs(Text, { inverse: menu.selectedIndex === index, children: [menu.selectedIndex === index ? '❯ ' : ' ', index + 1, ". ", option.label] }, option.action))), _jsx(Text, { children: " " }), _jsx(Text, { color: activePalette.warning, children: "\u26A0 Rewinding does not affect files edited manually or via bash." })] })) : menu?.kind === 'rewind-context' ? (_jsxs(DialogFrame, { title: `Summarize ${menu.direction === 'from' ? 'from' : 'up to'} here`, screenReader: axScreenReader, children: [_jsx(Text, { children: menu.direction === 'from'
5199
5357
  ? 'Messages after this point will be summarized.'
5200
- : 'Messages up to this point will be summarized.' }), _jsx(Text, { children: " " }), _jsxs(Text, { children: ["add context (optional): ", input] }), _jsx(Text, { dimColor: true, children: "Enter to summarize \u00B7 Esc to go back" })] })) : menu?.kind === 'permission-rule-input' ? (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, children: ["Add ", menu.behavior, " permission rule"] }), _jsx(Text, { children: "Permission rules are a tool name, optionally followed by a specifier in parentheses." }), _jsx(Text, { children: "e.g., WebFetch or Bash(ls *)" }), _jsx(Text, { children: " " }), _jsx(Box, { borderStyle: axScreenReader ? undefined : 'round', paddingX: axScreenReader ? 0 : 1, children: _jsx(Text, { ...(input ? {} : { dimColor: true }), children: input || 'Enter permission rule…' }) }), _jsx(Text, { dimColor: true, children: "Enter to submit \u00B7 Esc to cancel" })] })) : menu?.kind === 'workspace-directory-input' ? (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Add directory to workspace" }), _jsx(Text, { children: "Praxis Code will be able to read files in this directory and make edits when auto-accept edits is on." }), _jsx(Text, { children: " " }), _jsx(Text, { children: "Enter the path to the directory:" }), _jsx(Box, { borderStyle: axScreenReader ? undefined : 'round', paddingX: axScreenReader ? 0 : 1, children: _jsx(Text, { ...(input ? {} : { dimColor: true }), children: input || 'Directory path…' }) }), _jsx(Text, { dimColor: true, children: "Tab to complete \u00B7 Enter to add \u00B7 Esc to cancel" })] })) : menu?.kind === 'permission-delete' ? (_jsxs(DialogFrame, { title: permissionDeleteTitle(menu.rule.behavior), screenReader: axScreenReader, children: [_jsx(Text, { children: menu.rule.rule }), permissionRuleDescription(menu.rule.rule) ? (_jsx(Text, { dimColor: true, children: permissionRuleDescription(menu.rule.rule) })) : null, _jsx(Text, { dimColor: true, children: permissionScopeLabel(menu.rule.scope) }), _jsx(Text, { children: " " }), _jsx(Text, { children: "Are you sure you want to delete this permission rule?" }), _jsx(Text, { children: " " }), _jsxs(Text, { inverse: !axScreenReader && menu.selectedIndex === 0, children: [selectionPrefix(menu.selectedIndex === 0, axScreenReader), "1. Yes"] }), _jsxs(Text, { inverse: !axScreenReader && menu.selectedIndex === 1, children: [selectionPrefix(menu.selectedIndex === 1, axScreenReader), "2. No"] }), _jsx(Text, { dimColor: true, children: "Esc to cancel" })] })) : menu?.kind === 'workspace-directory-delete' ? (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Remove directory from workspace?" }), _jsxs(Text, { children: [" ", menu.path] }), _jsx(Text, { children: " " }), _jsx(Text, { children: "Praxis Code will no longer have access to files in this directory." }), _jsx(Text, { children: " " }), _jsxs(Text, { inverse: !axScreenReader && menu.selectedIndex === 0, children: [selectionPrefix(menu.selectedIndex === 0, axScreenReader), "1. Yes"] }), _jsxs(Text, { inverse: !axScreenReader && menu.selectedIndex === 1, children: [selectionPrefix(menu.selectedIndex === 1, axScreenReader), "2. No"] }), _jsx(Text, { dimColor: true, children: "Enter to confirm \u00B7 Esc to cancel" })] })) : menu ? (menu.kind === 'help' ? (_jsx(HelpMenu, { tabIndex: menu.tabIndex, selectedIndex: menu.selectedIndex, builtinCommands: builtinSlashCommands, customCommands: customSlashCommands, width: width, screenReader: axScreenReader })) : menu.kind === 'diff' ? (_jsx(DiffDashboard, { snapshots: menu.snapshots, sourceIndex: menu.sourceIndex, selectedIndex: menu.selectedIndex, viewingFile: menu.viewingFile, scrollOffset: menu.scrollOffset, width: width, screenReader: axScreenReader })) : menu.kind === 'permission-dashboard' ? (_jsx(PermissionDashboard, { tabIndex: menu.tabIndex, selectedIndex: menu.selectedIndex, query: menu.query, rules: menu.rules, recentDenied: recentDenied, retryingDeniedId: retryingDeniedId, workspaceDirectories: workspaceDirectories, width: width, screenReader: axScreenReader })) : menu.kind === 'permission-scope' ? (_jsx(SelectionMenu, { title: "Where should this rule be saved?", description: `${menu.rule}${permissionRuleDescription(menu.rule)
5358
+ : 'Messages up to this point will be summarized.' }), _jsx(Text, { children: " " }), _jsxs(Text, { children: ["add context (optional): ", input] }), _jsx(Text, { dimColor: true, children: "Enter to summarize \u00B7 Esc to go back" })] })) : menu?.kind === 'permission-rule-input' ? (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, children: ["Add ", menu.behavior, " permission rule"] }), _jsx(Text, { children: "Permission rules are a tool name, optionally followed by a specifier in parentheses." }), _jsx(Text, { children: "e.g., WebFetch or Bash(ls *)" }), _jsx(Text, { children: " " }), _jsx(Box, { borderStyle: axScreenReader ? undefined : 'round', paddingX: axScreenReader ? 0 : 1, children: _jsx(Text, { ...(input ? {} : { dimColor: true }), children: input || 'Enter permission rule…' }) }), _jsx(Text, { dimColor: true, children: "Enter to submit \u00B7 Esc to cancel" })] })) : menu?.kind === 'workspace-directory-input' ? (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Add directory to workspace" }), _jsx(Text, { children: "Praxis Code will be able to read files in this directory and make edits when auto-accept edits is on." }), _jsx(Text, { children: " " }), _jsx(Text, { children: "Enter the path to the directory:" }), _jsx(Box, { borderStyle: axScreenReader ? undefined : 'round', paddingX: axScreenReader ? 0 : 1, children: _jsx(Text, { ...(input ? {} : { dimColor: true }), children: input || 'Directory path…' }) }), _jsx(Text, { dimColor: true, children: "Tab to complete \u00B7 Enter to add \u00B7 Esc to cancel" })] })) : menu?.kind === 'permission-delete' ? (_jsxs(DialogFrame, { title: permissionDeleteTitle(menu.rule.behavior), screenReader: axScreenReader, children: [_jsx(Text, { children: menu.rule.rule }), permissionRuleDescription(menu.rule.rule) ? (_jsx(Text, { dimColor: true, children: permissionRuleDescription(menu.rule.rule) })) : null, _jsx(Text, { dimColor: true, children: permissionScopeLabel(menu.rule.scope) }), _jsx(Text, { children: " " }), _jsx(Text, { children: "Are you sure you want to delete this permission rule?" }), _jsx(Text, { children: " " }), _jsxs(Text, { inverse: !axScreenReader && menu.selectedIndex === 0, children: [selectionPrefix(menu.selectedIndex === 0, axScreenReader), "1. Yes"] }), _jsxs(Text, { inverse: !axScreenReader && menu.selectedIndex === 1, children: [selectionPrefix(menu.selectedIndex === 1, axScreenReader), "2. No"] }), _jsx(Text, { dimColor: true, children: "Esc to cancel" })] })) : menu?.kind === 'workspace-directory-delete' ? (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Remove directory from workspace?" }), _jsxs(Text, { children: [" ", menu.path] }), _jsx(Text, { children: " " }), _jsx(Text, { children: "Praxis Code will no longer have access to files in this directory." }), _jsx(Text, { children: " " }), _jsxs(Text, { inverse: !axScreenReader && menu.selectedIndex === 0, children: [selectionPrefix(menu.selectedIndex === 0, axScreenReader), "1. Yes"] }), _jsxs(Text, { inverse: !axScreenReader && menu.selectedIndex === 1, children: [selectionPrefix(menu.selectedIndex === 1, axScreenReader), "2. No"] }), _jsx(Text, { dimColor: true, children: "Enter to confirm \u00B7 Esc to cancel" })] })) : menu ? (menu.kind === 'help' ? (_jsx(HelpMenu, { tabIndex: menu.tabIndex, selectedIndex: menu.selectedIndex, builtinCommands: builtinSlashCommands, customCommands: customSlashCommands, width: width, screenReader: axScreenReader })) : menu.kind === 'diff' ? (_jsx(DiffDashboard, { snapshots: menu.snapshots, sourceIndex: menu.sourceIndex, selectedIndex: menu.selectedIndex, viewingFile: menu.viewingFile, scrollOffset: menu.scrollOffset, width: width, screenReader: axScreenReader })) : menu.kind === 'permission-dashboard' ? (_jsx(PermissionDashboard, { tabIndex: menu.tabIndex, selectedIndex: menu.selectedIndex, query: menu.query, rules: menu.rules, recentDenied: recentDenied, retryingDeniedId: retryingDeniedId, workspaceDirectories: workspaceDirectories, width: width, screenReader: axScreenReader })) : menu.kind === 'sandbox' ? (_jsx(SandboxDashboard, { snapshot: menu.snapshot, tab: menu.tab, selectedIndex: menu.selectedIndex, width: width, screenReader: axScreenReader })) : menu.kind === 'permission-scope' ? (_jsx(SelectionMenu, { title: "Where should this rule be saved?", description: `${menu.rule}${permissionRuleDescription(menu.rule)
5201
5359
  ? ` · ${permissionRuleDescription(menu.rule)}`
5202
5360
  : ''}`, options: [
5203
5361
  {
@@ -5263,7 +5421,39 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
5263
5421
  ? { prStatus: `PR #${activeSessionSummary.prNumber}` }
5264
5422
  : {}), shortcutsVisible: shortcutsVisible, ...(editorFooterMessage === undefined
5265
5423
  ? {}
5266
- : { footerMessage: editorFooterMessage }) })] }))] })) }) }));
5424
+ : { footerMessage: editorFooterMessage }) }), _jsx(StatusLine, { configRoot: keybindingsRoot, cwd: runtimeCwd, input: createClaudeStatusLineInput({
5425
+ configRoot: keybindingsRoot,
5426
+ cwd: runtimeCwd,
5427
+ projectDir: display.cwd,
5428
+ sessionId: sessionId ?? statusLineSessionId.current,
5429
+ sessionName,
5430
+ ...(runtimeDisplay.model === undefined
5431
+ ? {}
5432
+ : { model: runtimeDisplay.model }),
5433
+ version: runtimeDisplay.version,
5434
+ outputStyle: runtimeSettings.outputStyle,
5435
+ permissionMode: runtimePreferences.permissionMode,
5436
+ additionalDirectories: runtimePreferences.additionalDirectories,
5437
+ ...(usage === undefined ? {} : { usage }),
5438
+ ...(costUsd === undefined ? {} : { costUsd }),
5439
+ ...(runtimeDisplay.contextWindowTokens === undefined
5440
+ ? {}
5441
+ : {
5442
+ contextWindowTokens: runtimeDisplay.contextWindowTokens,
5443
+ }),
5444
+ ...(runtimeSettings.editor === 'vim'
5445
+ ? { vimMode: vimInsertMode ? 'INSERT' : 'NORMAL' }
5446
+ : {}),
5447
+ }), refreshKey: [
5448
+ history.length,
5449
+ runtimePreferences.permissionMode,
5450
+ runtimeDisplay.model,
5451
+ runtimeSettings.outputStyle,
5452
+ vimInsertMode,
5453
+ sessionName,
5454
+ usage?.inputTokens,
5455
+ usage?.outputTokens,
5456
+ ].join(':'), ...(settingSources === undefined ? {} : { settingSources }) })] }))] })) }) }));
5267
5457
  }
5268
5458
  export async function runInteractive(options) {
5269
5459
  const controller = new AbortController();
@@ -5352,7 +5542,9 @@ export async function runInteractive(options) {
5352
5542
  let cleanup = null;
5353
5543
  let backgrounded;
5354
5544
  rendererChange = null;
5355
- const instance = render(_jsx(InteractiveApp, { factory: options.factory, initialSessions: initialSessions, slashCommands: initialSlashCommands, agents: initialAgents, initialHistory: history, runtimeSettings: currentRuntimeSettings, initialThemeSettings: initialThemeSettings, ...(initialThemeLoadError === undefined
5545
+ const instance = render(_jsx(InteractiveApp, { factory: options.factory, initialSessions: initialSessions, slashCommands: initialSlashCommands, agents: initialAgents, initialHistory: history, runtimeSettings: currentRuntimeSettings, ...(options.settingSources === undefined
5546
+ ? {}
5547
+ : { settingSources: options.settingSources }), initialThemeSettings: initialThemeSettings, ...(initialThemeLoadError === undefined
5356
5548
  ? {}
5357
5549
  : { initialThemeLoadError }), ...(currentInitialPrompt === undefined
5358
5550
  ? {}
@@ -1,4 +1,4 @@
1
- export type ClaudeCommandDisposition = 'included' | 'excluded';
1
+ export type ClaudeCommandDisposition = 'included' | 'deferred' | 'excluded';
2
2
  export type ClaudeCommandVisibility = 'visible' | 'hidden' | 'conditional';
3
3
  export interface ClaudeCommandInventoryEntry {
4
4
  name: string;
@@ -12,8 +12,9 @@ export declare const CLAUDE_2_1_208_COMMAND_INVENTORY: readonly [{
12
12
  readonly visibility: "visible";
13
13
  }, {
14
14
  readonly name: "advisor";
15
- readonly disposition: "included";
15
+ readonly disposition: "deferred";
16
16
  readonly visibility: "conditional";
17
+ readonly reason: "Conditional advice mode is required parity work and is not implemented yet.";
17
18
  }, {
18
19
  readonly name: "agents";
19
20
  readonly disposition: "included";
@@ -28,17 +29,18 @@ export declare const CLAUDE_2_1_208_COMMAND_INVENTORY: readonly [{
28
29
  readonly visibility: "visible";
29
30
  }, {
30
31
  readonly name: "chrome";
31
- readonly disposition: "excluded";
32
+ readonly disposition: "deferred";
32
33
  readonly visibility: "conditional";
33
- readonly reason: "Chrome integration is outside the CLI-only product boundary.";
34
+ readonly reason: "The CLI-driven Chrome integration is required parity work and is not implemented yet.";
34
35
  }, {
35
36
  readonly name: "clear";
36
37
  readonly disposition: "included";
37
38
  readonly visibility: "visible";
38
39
  }, {
39
40
  readonly name: "color";
40
- readonly disposition: "included";
41
+ readonly disposition: "deferred";
41
42
  readonly visibility: "visible";
43
+ readonly reason: "The dedicated /color contract is required; /theme is not a substitute.";
42
44
  }, {
43
45
  readonly name: "compact";
44
46
  readonly disposition: "included";
@@ -62,16 +64,18 @@ export declare const CLAUDE_2_1_208_COMMAND_INVENTORY: readonly [{
62
64
  readonly visibility: "conditional";
63
65
  }, {
64
66
  readonly name: "cost";
65
- readonly disposition: "included";
67
+ readonly disposition: "deferred";
66
68
  readonly visibility: "conditional";
69
+ readonly reason: "The dedicated /cost contract is required; /status is not a substitute.";
67
70
  }, {
68
71
  readonly name: "diff";
69
72
  readonly disposition: "included";
70
73
  readonly visibility: "visible";
71
74
  }, {
72
75
  readonly name: "doctor";
73
- readonly disposition: "included";
76
+ readonly disposition: "deferred";
74
77
  readonly visibility: "conditional";
78
+ readonly reason: "Interactive /doctor is required; the top-level command is not a substitute.";
75
79
  }, {
76
80
  readonly name: "effort";
77
81
  readonly disposition: "included";
@@ -82,8 +86,9 @@ export declare const CLAUDE_2_1_208_COMMAND_INVENTORY: readonly [{
82
86
  readonly visibility: "visible";
83
87
  }, {
84
88
  readonly name: "fast";
85
- readonly disposition: "included";
89
+ readonly disposition: "deferred";
86
90
  readonly visibility: "conditional";
91
+ readonly reason: "The /fast state flow is required; model and effort controls are not a substitute.";
87
92
  }, {
88
93
  readonly name: "files";
89
94
  readonly disposition: "excluded";
@@ -91,8 +96,9 @@ export declare const CLAUDE_2_1_208_COMMAND_INVENTORY: readonly [{
91
96
  readonly reason: "The source command is restricted to the internal Ant user type.";
92
97
  }, {
93
98
  readonly name: "heapdump";
94
- readonly disposition: "included";
99
+ readonly disposition: "deferred";
95
100
  readonly visibility: "hidden";
101
+ readonly reason: "The hidden heap-diagnostic contract is required parity work and is not implemented yet.";
96
102
  }, {
97
103
  readonly name: "help";
98
104
  readonly disposition: "included";
@@ -181,8 +187,9 @@ export declare const CLAUDE_2_1_208_COMMAND_INVENTORY: readonly [{
181
187
  readonly visibility: "visible";
182
188
  }, {
183
189
  readonly name: "stats";
184
- readonly disposition: "included";
190
+ readonly disposition: "deferred";
185
191
  readonly visibility: "visible";
192
+ readonly reason: "Historical usage statistics are required parity work and are not implemented yet.";
186
193
  }, {
187
194
  readonly name: "status";
188
195
  readonly disposition: "included";
@@ -253,8 +260,9 @@ export declare const CLAUDE_2_1_208_COMMAND_INVENTORY: readonly [{
253
260
  readonly reason: "The source command is the Claude subscription plan-usage panel.";
254
261
  }, {
255
262
  readonly name: "insights";
256
- readonly disposition: "included";
263
+ readonly disposition: "deferred";
257
264
  readonly visibility: "visible";
265
+ readonly reason: "Retrospective insights are required parity work and are not implemented yet.";
258
266
  }, {
259
267
  readonly name: "vim";
260
268
  readonly disposition: "included";
@@ -270,20 +278,24 @@ export declare const CLAUDE_2_1_208_COMMAND_INVENTORY: readonly [{
270
278
  readonly visibility: "conditional";
271
279
  }, {
272
280
  readonly name: "buddy";
273
- readonly disposition: "included";
281
+ readonly disposition: "deferred";
274
282
  readonly visibility: "conditional";
283
+ readonly reason: "This conditional source mode is required parity work and is not implemented yet.";
275
284
  }, {
276
285
  readonly name: "proactive";
277
- readonly disposition: "included";
286
+ readonly disposition: "deferred";
278
287
  readonly visibility: "conditional";
288
+ readonly reason: "This conditional source mode is required parity work and is not implemented yet.";
279
289
  }, {
280
290
  readonly name: "brief";
281
- readonly disposition: "included";
291
+ readonly disposition: "deferred";
282
292
  readonly visibility: "conditional";
293
+ readonly reason: "This conditional source mode is required parity work and is not implemented yet.";
283
294
  }, {
284
295
  readonly name: "assistant";
285
- readonly disposition: "included";
296
+ readonly disposition: "deferred";
286
297
  readonly visibility: "conditional";
298
+ readonly reason: "This conditional source mode is required parity work and is not implemented yet.";
287
299
  }, {
288
300
  readonly name: "remote-control";
289
301
  readonly disposition: "excluded";
@@ -296,16 +308,19 @@ export declare const CLAUDE_2_1_208_COMMAND_INVENTORY: readonly [{
296
308
  readonly reason: "Remote Control is outside the local-only boundary.";
297
309
  }, {
298
310
  readonly name: "voice";
299
- readonly disposition: "included";
311
+ readonly disposition: "deferred";
300
312
  readonly visibility: "conditional";
313
+ readonly reason: "Conditional voice input is required parity work and is not implemented yet.";
301
314
  }, {
302
315
  readonly name: "think-back";
303
- readonly disposition: "included";
316
+ readonly disposition: "deferred";
304
317
  readonly visibility: "conditional";
318
+ readonly reason: "The conditional retrospective flow is required parity work and is not implemented yet.";
305
319
  }, {
306
320
  readonly name: "thinkback-play";
307
- readonly disposition: "included";
321
+ readonly disposition: "deferred";
308
322
  readonly visibility: "hidden";
323
+ readonly reason: "The hidden retrospective playback flow is required parity work and is not implemented yet.";
309
324
  }, {
310
325
  readonly name: "permissions";
311
326
  readonly disposition: "included";
@@ -361,8 +376,9 @@ export declare const CLAUDE_2_1_208_COMMAND_INVENTORY: readonly [{
361
376
  readonly visibility: "conditional";
362
377
  }, {
363
378
  readonly name: "torch";
364
- readonly disposition: "included";
379
+ readonly disposition: "deferred";
365
380
  readonly visibility: "conditional";
381
+ readonly reason: "This source-gated behavior is required conditional parity work and is not implemented yet.";
366
382
  }];
367
383
  export declare const CLAUDE_2_1_208_COMMAND_BY_NAME: ReadonlyMap<string, ClaudeCommandInventoryEntry>;
368
384
  //# sourceMappingURL=claude-command-inventory.d.ts.map