one-code-extension 0.4.0 → 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/README.md +219 -219
- package/agents/general-purpose.md +2 -2
- package/docs/guide/README.md +2 -1
- package/docs/guide/bring-your-claude-code-setup.md +60 -9
- package/docs/guide/configuration.md +48 -14
- package/docs/guide/differences-from-claude-code.md +32 -23
- package/docs/guide/doctor.md +20 -13
- package/docs/guide/hooks.md +18 -3
- package/docs/guide/installation.md +27 -4
- package/docs/guide/permissions-modes-and-auto-mode.md +225 -49
- package/docs/guide/providers-and-models.md +137 -54
- package/docs/guide/reference.md +27 -15
- package/docs/guide/sessions-and-context.md +69 -16
- package/docs/guide/skills-plugins-and-mcp.md +57 -20
- package/docs/guide/subagents-and-workflows.md +95 -29
- package/docs/guide/tasks-and-background-work.md +101 -26
- package/docs/guide/terminal-interface.md +24 -12
- package/docs/guide/tools.md +46 -5
- package/docs/guide/troubleshooting.md +13 -9
- package/docs/guide/windows.md +66 -34
- package/extensions/artifacts/gallery.ts +227 -0
- package/extensions/artifacts/index.ts +288 -0
- package/extensions/artifacts/store.ts +570 -0
- package/extensions/artifacts/viewer.ts +199 -0
- package/extensions/ask-user/description.ts +67 -0
- package/extensions/ask-user/dialogs.ts +80 -0
- package/extensions/ask-user/index.ts +37 -33
- package/extensions/ask-user/questions.ts +32 -7
- package/extensions/ask-user/widget.ts +45 -25
- package/extensions/auto-mode/actions.ts +6 -0
- package/extensions/auto-mode/cache.ts +88 -0
- package/extensions/auto-mode/classifier-prompt.ts +5 -4
- package/extensions/auto-mode/classifier.ts +290 -65
- package/extensions/auto-mode/config.ts +72 -20
- package/extensions/auto-mode/decision-log.ts +2 -0
- package/extensions/auto-mode/defaults.ts +1 -1
- package/extensions/auto-mode/denials.ts +123 -0
- package/extensions/auto-mode/git-checkout-programs.ts +187 -0
- package/extensions/auto-mode/git-status-meta.ts +159 -0
- package/extensions/auto-mode/history.ts +189 -0
- package/extensions/auto-mode/instructions.ts +58 -52
- package/extensions/auto-mode/model-select.ts +159 -134
- package/extensions/auto-mode/paths.ts +57 -5
- package/extensions/auto-mode/pause.ts +57 -2
- package/extensions/auto-mode/prompt.ts +37 -21
- package/extensions/auto-mode/read-only-options.ts +724 -0
- package/extensions/auto-mode/resolved-paths-meta.ts +133 -0
- package/extensions/auto-mode/rules.ts +18 -1
- package/extensions/auto-mode/safety-floor.ts +361 -18
- package/extensions/auto-mode/setup-run.ts +20 -14
- package/extensions/auto-mode/shell-analysis.ts +764 -490
- package/extensions/auto-mode/shell-parse.ts +885 -0
- package/extensions/auto-mode/system-note.ts +33 -0
- package/extensions/auto-mode/transcript.ts +80 -51
- package/extensions/background/cron.ts +515 -0
- package/extensions/background/index.ts +514 -236
- package/extensions/background/loop-fire.ts +136 -0
- package/extensions/background/loop-preamble.ts +59 -0
- package/extensions/background/loop-skill.ts +163 -0
- package/extensions/background/monitor-batch.ts +53 -0
- package/extensions/background/noop-fold.ts +128 -0
- package/extensions/background/switch-guard.ts +52 -0
- package/extensions/background/wakeup.ts +159 -55
- package/extensions/bash/background.ts +53 -17
- package/extensions/bash/child.ts +7 -0
- package/extensions/bash/description.ts +188 -0
- package/extensions/bash/guards.ts +15 -67
- package/extensions/bash/index.ts +88 -35
- package/extensions/branding/compaction-keep.ts +63 -0
- package/extensions/branding/declined.ts +22 -0
- package/extensions/branding/index.ts +133 -9
- package/extensions/branding/prompt-editor.ts +53 -6
- package/extensions/branding/queued-edit.ts +31 -0
- package/extensions/branding/replaced-builtins.ts +68 -0
- package/extensions/branding/startup.ts +33 -71
- package/extensions/btw/index.ts +229 -71
- package/extensions/btw/panel.ts +228 -100
- package/extensions/btw/prompt.ts +41 -4
- package/extensions/claude-compat/index.ts +7 -11
- package/extensions/claude-context/index.ts +446 -58
- package/extensions/compaction/cut.ts +157 -0
- package/extensions/compaction/index.ts +216 -75
- package/extensions/compaction/kept-thinking.ts +62 -0
- package/extensions/compaction/prompt.ts +15 -12
- package/extensions/context-budget/index.ts +24 -5
- package/extensions/context-management/index.ts +25 -0
- package/extensions/doctor/build.ts +59 -8
- package/extensions/doctor/builtins.ts +84 -0
- package/extensions/doctor/cli.ts +7 -1
- package/extensions/doctor/compat.ts +88 -23
- package/extensions/doctor/dependencies.ts +41 -5
- package/extensions/doctor/fix-prompt.ts +9 -2
- package/extensions/doctor/index.ts +102 -58
- package/extensions/doctor/models.ts +102 -63
- package/extensions/doctor/presets.ts +42 -27
- package/extensions/doctor/report.ts +19 -2
- package/extensions/doctor/viewer.ts +49 -27
- package/extensions/effort/index.ts +72 -19
- package/extensions/effort/settings.ts +21 -0
- package/extensions/effort/slider.ts +24 -20
- package/extensions/exit/index.ts +32 -1
- package/extensions/file-tracker/index.ts +337 -26
- package/extensions/file-tracker/replay.ts +96 -10
- package/extensions/file-tracker/restore.ts +63 -0
- package/extensions/file-tracker/results.ts +66 -0
- package/extensions/file-tracker/shell-reads.ts +211 -0
- package/extensions/file-tracker/tracker.ts +32 -15
- package/extensions/footer/footer-line.ts +45 -24
- package/extensions/footer/index.ts +47 -2
- package/extensions/footer/pr.ts +34 -5
- package/extensions/hooks/compaction.ts +7 -0
- package/extensions/hooks/executor.ts +32 -30
- package/extensions/hooks/index.ts +198 -31
- package/extensions/hooks/matcher.ts +3 -0
- package/extensions/hooks/protocol.ts +41 -3
- package/extensions/hooks/settings.ts +50 -19
- package/extensions/hooks/subagent-bridge.ts +2 -0
- package/extensions/hooks/trust.ts +13 -5
- package/extensions/idle-compact/index.ts +119 -0
- package/extensions/idle-compact/policy.ts +143 -0
- package/extensions/init/index.ts +11 -10
- package/extensions/init/prompt.ts +25 -32
- package/extensions/interrupted/index.ts +13 -1
- package/extensions/kept-thinking/index.ts +27 -0
- package/extensions/lib/agent-cron.ts +130 -0
- package/extensions/lib/agent-loader.ts +15 -1
- package/extensions/lib/agent-view.ts +85 -0
- package/extensions/lib/anthropic-payload.ts +82 -1
- package/extensions/lib/anthropic-server-call.ts +230 -0
- package/extensions/lib/anthropic-server-tools.ts +485 -0
- package/extensions/lib/app-launch.mjs +94 -0
- package/extensions/lib/argument-hints.ts +190 -0
- package/extensions/lib/atomic-write.ts +6 -2
- package/extensions/lib/auto-memory.ts +75 -0
- package/extensions/lib/bash-parser.ts +84 -0
- package/extensions/lib/btw-fork.ts +93 -0
- package/extensions/lib/child-extensions.ts +42 -0
- package/extensions/lib/child-writes.ts +45 -0
- package/extensions/lib/claude-context.ts +515 -100
- package/extensions/lib/claude-external-includes.ts +68 -0
- package/extensions/lib/claude-id.ts +22 -0
- package/extensions/lib/claude-rules.ts +323 -0
- package/extensions/lib/claude-settings.ts +76 -4
- package/extensions/lib/compaction-boundary.ts +36 -0
- package/extensions/lib/compaction-keep.mjs +83 -0
- package/extensions/lib/config-mode.ts +112 -0
- package/extensions/lib/consent-dialogs.ts +63 -0
- package/extensions/lib/consent-preview.ts +5 -1
- package/extensions/lib/consent-stores.ts +48 -0
- package/extensions/lib/context-facts.ts +78 -0
- package/extensions/lib/context-stack.ts +81 -0
- package/extensions/lib/deferred.ts +219 -25
- package/extensions/lib/dock-rows.ts +60 -0
- package/extensions/lib/empty-tool-result.ts +27 -0
- package/extensions/lib/environment-block.ts +76 -0
- package/extensions/lib/fetch-timeout.ts +24 -6
- package/extensions/{system-prompt → lib}/git-status.ts +51 -13
- package/extensions/lib/git.ts +75 -13
- package/extensions/lib/grammars/LICENSE-tree-sitter-bash +21 -0
- package/extensions/lib/grammars/README.md +2 -0
- package/extensions/lib/grammars/tree-sitter-bash.wasm +0 -0
- package/extensions/lib/guide-docs.ts +45 -0
- package/extensions/lib/headless-output.ts +46 -0
- package/extensions/lib/hook-gate.ts +7 -7
- package/extensions/lib/interrupt.ts +20 -4
- package/extensions/lib/key-input.ts +455 -0
- package/extensions/lib/keys.ts +14 -1
- package/extensions/lib/local-command.ts +47 -13
- package/extensions/lib/mcp-overrides.ts +1 -1
- package/extensions/lib/mcp-share.ts +46 -0
- package/extensions/lib/memory-content.ts +146 -0
- package/extensions/lib/memory-index.ts +18 -0
- package/extensions/lib/memory.ts +134 -123
- package/extensions/lib/model-catalog/huggingface.json +174 -0
- package/extensions/lib/model-catalog/models-dev.json +18297 -0
- package/extensions/lib/model-catalog/openrouter.json +5252 -0
- package/extensions/lib/model-catalog-data.ts +513 -0
- package/extensions/lib/model-catalog.ts +462 -0
- package/extensions/lib/model-choice-warnings.ts +137 -0
- package/extensions/lib/model-pairings.ts +152 -0
- package/extensions/{auto-mode → lib}/model-picker.ts +26 -43
- package/extensions/lib/model-policy.ts +112 -15
- package/extensions/lib/model-tier.ts +283 -355
- package/extensions/lib/model-unusable.ts +1 -1
- package/extensions/lib/newer-model.ts +100 -0
- package/extensions/lib/notices.ts +87 -0
- package/extensions/lib/notifications.ts +308 -64
- package/extensions/lib/one-code-settings.ts +74 -8
- package/extensions/lib/open-browser.ts +63 -0
- package/extensions/lib/openrouter-generation.ts +94 -0
- package/extensions/lib/operation-deadline.ts +30 -0
- package/extensions/lib/original-command.ts +4 -4
- package/extensions/lib/package-version.ts +1 -1
- package/extensions/lib/panel-focus.ts +134 -0
- package/extensions/lib/paths.ts +17 -2
- package/extensions/lib/permission-gate.ts +72 -6
- package/extensions/lib/persisted-output.ts +60 -8
- package/extensions/lib/pi-ai-estimate.ts +19 -3
- package/extensions/lib/pi-version.ts +21 -2
- package/extensions/lib/plan-mode-channels.ts +20 -5
- package/extensions/lib/plugins.ts +26 -17
- package/extensions/lib/powershell-parse-script.ts +208 -0
- package/extensions/lib/powershell-parser.ts +344 -0
- package/extensions/lib/process-tree.ts +131 -8
- package/extensions/lib/prompt-options.ts +82 -0
- package/extensions/lib/queued-delivery.ts +44 -0
- package/extensions/lib/reminders.ts +364 -58
- package/extensions/lib/replaced-builtins.mjs +199 -0
- package/extensions/lib/replay-call.ts +70 -0
- package/extensions/lib/request-replay.ts +439 -0
- package/extensions/lib/scratchpad.ts +81 -14
- package/extensions/lib/send-now-channel.ts +7 -0
- package/extensions/lib/session-model-tier.ts +51 -0
- package/extensions/lib/session-work.ts +64 -0
- package/extensions/lib/settings-channels.ts +4 -4
- package/extensions/lib/shell-exit-semantics.ts +170 -0
- package/extensions/lib/shell-quote.ts +11 -0
- package/extensions/lib/shell-result.ts +70 -0
- package/extensions/lib/shell-spawn.ts +70 -6
- package/extensions/lib/shell-tool.ts +75 -25
- package/extensions/lib/side-call-cache.ts +124 -0
- package/extensions/lib/side-call-run.ts +96 -0
- package/extensions/lib/side-call-usage.ts +38 -0
- package/extensions/lib/side-call.ts +13 -1
- package/extensions/lib/single-flight.ts +18 -0
- package/extensions/lib/skill-body.ts +42 -0
- package/extensions/lib/skill-scan.ts +63 -24
- package/extensions/lib/spill-file.ts +140 -0
- package/extensions/lib/subagent-handback.ts +113 -0
- package/extensions/lib/system-role.ts +156 -0
- package/extensions/lib/terminal-text.ts +114 -0
- package/extensions/lib/text-width.ts +47 -16
- package/extensions/lib/timer-ops.ts +20 -0
- package/extensions/lib/tool-additions.ts +149 -0
- package/extensions/lib/tool-call-corruption.ts +134 -0
- package/extensions/lib/tool-path.ts +66 -0
- package/extensions/lib/tool-variants.ts +69 -0
- package/extensions/lib/tui-render.ts +255 -27
- package/extensions/lib/turn-budget-layout.ts +143 -0
- package/extensions/lib/update-check.mjs +15 -2
- package/extensions/lib/usage-bus.ts +1 -1
- package/extensions/lib/user-denial.ts +38 -0
- package/extensions/lib/workspace-channel.ts +16 -0
- package/extensions/lib/worktree-channel.ts +31 -3
- package/extensions/lib/worktree-isolation.ts +40 -10
- package/extensions/lsp/client.ts +8 -9
- package/extensions/lsp/index.ts +70 -4
- package/extensions/lsp/keep-alive.ts +1 -1
- package/extensions/lsp/trust.ts +119 -0
- package/extensions/lsp/watcher.ts +1 -1
- package/extensions/mcp/announce.ts +87 -5
- package/extensions/mcp/client.ts +161 -48
- package/extensions/mcp/config.ts +132 -8
- package/extensions/mcp/discovery.ts +19 -0
- package/extensions/mcp/index.ts +209 -71
- package/extensions/mcp/oauth/browser.ts +38 -17
- package/extensions/mcp/oauth/flow.ts +25 -17
- package/extensions/mcp/oauth/provider.ts +14 -8
- package/extensions/mcp/oauth/store.ts +34 -16
- package/extensions/mcp/panel/keys.ts +12 -11
- package/extensions/mcp/panel/render.ts +9 -6
- package/extensions/mcp/schema.ts +104 -5
- package/extensions/mcp/trust.ts +151 -67
- package/extensions/memory/entries.ts +23 -14
- package/extensions/memory/index.ts +134 -28
- package/extensions/memory/open-external.ts +33 -18
- package/extensions/memory/panel.ts +135 -26
- package/extensions/newer-model/index.ts +31 -0
- package/extensions/notebook/description.ts +18 -0
- package/extensions/notebook/index.ts +6 -5
- package/extensions/notebook/notebook.ts +1 -1
- package/extensions/permissions/index.ts +1300 -381
- package/extensions/permissions/matcher.ts +425 -74
- package/extensions/permissions/modes.ts +6 -4
- package/extensions/permissions/panel/host.ts +130 -0
- package/extensions/permissions/panel/keys.ts +48 -0
- package/extensions/permissions/panel/render.ts +450 -0
- package/extensions/permissions/panel/state.ts +550 -0
- package/extensions/permissions/powershell-cmdlets.ts +198 -0
- package/extensions/permissions/powershell-paths.ts +197 -0
- package/extensions/permissions/powershell-rules.ts +207 -280
- package/extensions/permissions/powershell-tree.ts +557 -0
- package/extensions/permissions/project-trust.ts +27 -11
- package/extensions/permissions/protected-paths.ts +14 -2
- package/extensions/permissions/session-grant.ts +6 -0
- package/extensions/permissions/settings.ts +166 -31
- package/extensions/permissions/subagent-gate.ts +25 -0
- package/extensions/permissions/workspace.ts +78 -0
- package/extensions/plan-mode/index.ts +156 -69
- package/extensions/plan-mode/reminder.ts +89 -21
- package/extensions/plan-mode/texts.ts +177 -0
- package/extensions/plan-mode/viewer.ts +92 -27
- package/extensions/plugins/counts.ts +3 -3
- package/extensions/plugins/index.ts +61 -46
- package/extensions/plugins/install/install.ts +16 -0
- package/extensions/plugins/marketplace/sync.ts +9 -3
- package/extensions/plugins/marketplace/types.ts +3 -1
- package/extensions/plugins/panel/keys.ts +21 -24
- package/extensions/plugins/panel/render.ts +12 -6
- package/extensions/plugins/shell-expand.ts +107 -0
- package/extensions/plugins/template.ts +32 -15
- package/extensions/powershell/child.ts +7 -0
- package/extensions/powershell/description.ts +38 -6
- package/extensions/powershell/guards.ts +1 -1
- package/extensions/powershell/index.ts +12 -7
- package/extensions/recap/index.ts +65 -60
- package/extensions/recap/prompt.ts +2 -2
- package/extensions/recap/scheduler.ts +3 -5
- package/extensions/search-tools/grep-merge.ts +39 -0
- package/extensions/search-tools/index.ts +0 -0
- package/extensions/send-now/chord.ts +62 -0
- package/extensions/send-now/index.ts +133 -0
- package/extensions/session-title/index.ts +3 -0
- package/extensions/session-title/title.ts +4 -1
- package/extensions/skill/code-review.ts +97 -0
- package/extensions/skill/index.ts +421 -101
- package/extensions/skill/invoke.ts +128 -18
- package/extensions/skill/listing.ts +133 -9
- package/extensions/skill/panel/keys.ts +15 -16
- package/extensions/skill/panel/render.ts +5 -2
- package/extensions/skill/panel/state.ts +12 -1
- package/extensions/subagents/agent-args.ts +39 -0
- package/extensions/subagents/agent-description.ts +132 -0
- package/extensions/subagents/agents.ts +116 -23
- package/extensions/subagents/announce.ts +69 -0
- package/extensions/subagents/default-model.ts +2 -3
- package/extensions/subagents/delegation-steer.ts +4 -4
- package/extensions/subagents/fork-cache.ts +76 -0
- package/extensions/subagents/guide-agent.ts +189 -0
- package/extensions/subagents/hand-back-review.ts +3 -0
- package/extensions/subagents/index.ts +1493 -824
- package/extensions/subagents/live-runs.ts +26 -6
- package/extensions/subagents/model-select.ts +38 -25
- package/extensions/subagents/outcome.ts +2 -2
- package/extensions/subagents/panel-keys.ts +73 -31
- package/extensions/subagents/panel-render.ts +120 -96
- package/extensions/subagents/panel-widget.ts +60 -89
- package/extensions/subagents/runner.ts +108 -80
- package/extensions/subagents/runs.ts +39 -5
- package/extensions/subagents/send-to-main-tool.ts +1 -1
- package/extensions/subagents/session-turns.ts +32 -8
- package/extensions/subagents/shell-panel.ts +36 -178
- package/extensions/subagents/tasks-dialog.ts +170 -0
- package/extensions/subagents/viewport-mirror.ts +95 -0
- package/extensions/subagents/worktree.ts +57 -13
- package/extensions/system-prompt/environment.ts +19 -19
- package/extensions/system-prompt/idle-turn.ts +65 -0
- package/extensions/system-prompt/index.ts +131 -47
- package/extensions/system-prompt/template.ts +24 -50
- package/extensions/system-prompt/tiers/common.ts +23 -64
- package/extensions/system-prompt/tiers/frontier.ts +32 -11
- package/extensions/system-prompt/tiers/low.ts +67 -45
- package/extensions/system-prompt/tiers/mid.ts +96 -38
- package/extensions/system-reminder/index.ts +175 -13
- package/extensions/tasks/descriptions.ts +190 -0
- package/extensions/tasks/index.ts +120 -41
- package/extensions/tasks/store.ts +83 -16
- package/extensions/tool-call-corruption/child.ts +7 -0
- package/extensions/tool-call-corruption/index.ts +237 -0
- package/extensions/tool-search/announce.ts +16 -0
- package/extensions/tool-search/index.ts +189 -41
- package/extensions/tool-style/index.ts +68 -10
- package/extensions/tool-style/write-description.ts +40 -0
- package/extensions/tool-style/write-render.ts +237 -0
- package/extensions/turn-duration/index.ts +7 -3
- package/extensions/turn-duration/line.ts +47 -4
- package/extensions/web/backends.ts +6 -9
- package/extensions/web/description.ts +50 -0
- package/extensions/web/index.ts +118 -53
- package/extensions/web/native-call.ts +15 -0
- package/extensions/web/native-results.ts +41 -0
- package/extensions/web-fetch/description.ts +42 -0
- package/extensions/web-fetch/extract.ts +53 -6
- package/extensions/web-fetch/index.ts +125 -76
- package/extensions/web-fetch/page-content.ts +19 -0
- package/extensions/web-fetch/response.ts +49 -0
- package/extensions/web-fetch/summarize.ts +9 -10
- package/extensions/workflow/agent-session.ts +105 -18
- package/extensions/workflow/args.ts +24 -0
- package/extensions/workflow/description.ts +67 -0
- package/extensions/workflow/globals.ts +17 -3
- package/extensions/workflow/index.ts +145 -162
- package/extensions/workflow/records.ts +1 -0
- package/extensions/workflow/run-manager.ts +29 -6
- package/extensions/workflow/saved-workflows.ts +3 -2
- package/extensions/workflow/types.ts +22 -1
- package/extensions/workflow/viewer.ts +54 -24
- package/extensions/workflow/widget.ts +20 -0
- package/extensions/worktree/descriptions.ts +91 -0
- package/extensions/worktree/guards.ts +316 -54
- package/extensions/worktree/index.ts +121 -39
- package/extensions/worktree/powershell-guards.ts +167 -0
- package/extensions/worktree/rewrite.ts +14 -16
- package/package.json +19 -7
- package/skills/artifact-design/SKILL.md +85 -0
- package/skills/code-review/SKILL.md +20 -20
- package/skills/code-review/cells/arguments-and-flags.md +19 -0
- package/skills/code-review/cells/high-3x5-recall-verify.md +137 -0
- package/skills/code-review/cells/high-8-inline.md +122 -0
- package/skills/code-review/cells/low-1-pass-max4.md +27 -0
- package/skills/code-review/cells/low-1-pass-min-files-4.md +28 -0
- package/skills/code-review/cells/max-5x5-verify-sweep.md +162 -0
- package/skills/code-review/cells/medium-3x5-verify.md +132 -0
- package/skills/code-review/cells/minimal-prompt.md +32 -0
- package/skills/code-review/cells/xhigh-10-inline-sweep.md +149 -0
- package/skills/code-review/cells/xhigh-5x5-verify-sweep.md +162 -0
- package/skills/fewer-permission-prompts/SKILL.md +1 -1
- package/skills/loop/SKILL.md +11 -0
- package/skills/security-review/SKILL.md +2 -5
- package/skills/simplify/SKILL.md +7 -5
- package/skills/workflow-authoring/SKILL.md +143 -0
- package/themes/onecode-light.json +1 -1
- package/themes/onecode.json +1 -1
- package/types/app.d.ts +58 -0
- package/types/community-packages.d.ts +26 -1
- package/extensions/auto-mode/recoverability.ts +0 -229
- package/extensions/lib/capability-index.ts +0 -466
- package/extensions/lib/model-facts.generated.json +0 -2675
- package/extensions/lib/model-facts.ts +0 -162
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/** Project the active session branch for the classifier; never keep a second transcript. */
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { inContextEntries, latestCompaction } from "../lib/compaction-boundary.ts";
|
|
4
|
+
import { isHistoricalRead, type TranscriptEntry } from "./transcript.ts";
|
|
5
|
+
|
|
6
|
+
/** Non-model-facing provenance for user messages and harness permission facts. */
|
|
7
|
+
export const CLASSIFIER_USER_INPUT = "auto-mode-user-input";
|
|
8
|
+
export const CLASSIFIER_TOOL_META = "auto-mode-tool-meta";
|
|
9
|
+
|
|
10
|
+
export function messageText(content: unknown): string {
|
|
11
|
+
if (typeof content === "string") return content;
|
|
12
|
+
if (!Array.isArray(content)) return "";
|
|
13
|
+
return content.map((block) => block?.type === "text" && typeof block.text === "string" ? block.text : "").filter(Boolean).join("\n");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function record(value: unknown): Record<string, any> {
|
|
17
|
+
return value !== null && typeof value === "object" ? value as Record<string, any> : {};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A user message's identity in the provenance entries: its timestamp and a
|
|
22
|
+
* digest of its text. Provenance only has to recognise the message, so the
|
|
23
|
+
* text itself is not stored a second time.
|
|
24
|
+
*/
|
|
25
|
+
export function userMessageDigest(text: string): string {
|
|
26
|
+
return createHash("sha256").update(text).digest("hex").slice(0, 32);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function userMessageKey(timestamp: unknown, digest: string): string {
|
|
30
|
+
return JSON.stringify([timestamp, digest]);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** What a branch's provenance entries say, and how far into the branch that was read. */
|
|
34
|
+
interface ProvenanceIndex {
|
|
35
|
+
head?: string;
|
|
36
|
+
length: number;
|
|
37
|
+
tail?: unknown;
|
|
38
|
+
/** Whether the branch has any provenance entry: none means a session from before provenance. */
|
|
39
|
+
recorded: boolean;
|
|
40
|
+
byKey: Map<string, string | null>;
|
|
41
|
+
/** Entry id → digest of that user message's text. */
|
|
42
|
+
digests: Map<string, string>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let provenanceMemo: ProvenanceIndex | undefined;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The provenance entries of a branch. pi only appends, so a gated call
|
|
49
|
+
* resumes the scan where the previous one stopped; a branch whose prefix
|
|
50
|
+
* changed (a new session, a /tree switch past the read point) is read again.
|
|
51
|
+
* Entries without ids are never memoised.
|
|
52
|
+
*/
|
|
53
|
+
function provenanceIndex(branch: readonly unknown[]): ProvenanceIndex {
|
|
54
|
+
const id = (i: number): unknown => record(branch[i]).id;
|
|
55
|
+
const head = id(0);
|
|
56
|
+
const memo = provenanceMemo;
|
|
57
|
+
const resumable = typeof head === "string" && memo !== undefined && memo.head === head && memo.length <= branch.length && (memo.length === 0 || id(memo.length - 1) === memo.tail);
|
|
58
|
+
const index: ProvenanceIndex = resumable ? memo : { head: typeof head === "string" ? head : undefined, length: 0, recorded: false, byKey: new Map(), digests: new Map() };
|
|
59
|
+
for (let i = index.length; i < branch.length; i++) {
|
|
60
|
+
const entry = record(branch[i]);
|
|
61
|
+
if (entry.type !== "custom" || entry.customType !== CLASSIFIER_USER_INPUT) continue;
|
|
62
|
+
index.recorded = true;
|
|
63
|
+
const data = record(entry.data);
|
|
64
|
+
if (typeof data.userText !== "string" && data.userText !== null) continue;
|
|
65
|
+
// Entries written before the digest carry the message text itself.
|
|
66
|
+
const digest = typeof data.messageDigest === "string" ? data.messageDigest : typeof data.messageText === "string" ? userMessageDigest(data.messageText) : undefined;
|
|
67
|
+
if (digest !== undefined) index.byKey.set(userMessageKey(data.timestamp, digest), data.userText);
|
|
68
|
+
}
|
|
69
|
+
index.length = branch.length;
|
|
70
|
+
index.tail = id(branch.length - 1);
|
|
71
|
+
provenanceMemo = typeof head === "string" && typeof index.tail === "string" ? index : undefined;
|
|
72
|
+
return index;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The words a user-role message gives the classifier as the user's own: the
|
|
77
|
+
* input event's text when recorded, null for an extension-generated turn.
|
|
78
|
+
* Every user message gets an entry once the gate is loaded, so a message
|
|
79
|
+
* without one was written before it (plain pi, or a build before provenance)
|
|
80
|
+
* and is unverified (null), even after the resumed session records new ones.
|
|
81
|
+
*/
|
|
82
|
+
function userWords(index: ProvenanceIndex, entry: Record<string, any>, message: Record<string, any>, text: string): string | null {
|
|
83
|
+
if (!index.recorded) return null;
|
|
84
|
+
let digest = typeof entry.id === "string" ? index.digests.get(entry.id) : undefined;
|
|
85
|
+
if (digest === undefined) {
|
|
86
|
+
digest = userMessageDigest(text);
|
|
87
|
+
if (typeof entry.id === "string") index.digests.set(entry.id, digest);
|
|
88
|
+
}
|
|
89
|
+
return index.byKey.get(userMessageKey(message.timestamp, digest)) ?? null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Where the projected history ends; neither field reads the whole active branch. */
|
|
93
|
+
export interface HistoryCursor {
|
|
94
|
+
beforeToolCallId?: string;
|
|
95
|
+
throughToolCallId?: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Where a subagent's view of the main session ends, for its own gated calls
|
|
100
|
+
* and its hand-back review. pi persists the main turn's whole tool-call batch
|
|
101
|
+
* before any of it runs, so a later call in that batch is not yet context.
|
|
102
|
+
* A child started by a call in the batch in flight (its Agent call, or the
|
|
103
|
+
* SendMessage call that began this turn) sees through that call; one started
|
|
104
|
+
* in an earlier turn sees every finished turn and none of the batch in
|
|
105
|
+
* flight; with nothing in flight it sees the whole branch. A child whose
|
|
106
|
+
* starting call is unknown (a workflow agent, a cron fire) keeps the last
|
|
107
|
+
* main call as its cursor.
|
|
108
|
+
*/
|
|
109
|
+
export function childHistoryCursor(startedBy: string | undefined, inFlight: readonly string[], lastMainCall: string | undefined): HistoryCursor {
|
|
110
|
+
if (startedBy === undefined) return { throughToolCallId: lastMainCall };
|
|
111
|
+
if (inFlight.includes(startedBy)) return { throughToolCallId: startedBy };
|
|
112
|
+
return inFlight.length > 0 ? { beforeToolCallId: inFlight[0] } : {};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* The summary comes before the kept tail, though its stored entry follows it.
|
|
117
|
+
* `beforeToolCallId` excludes the pending call and later calls from the same
|
|
118
|
+
* assistant message (pi persists the whole tool-call batch before executing it).
|
|
119
|
+
* A bridged child uses `throughToolCallId` to include its parent's running call.
|
|
120
|
+
*/
|
|
121
|
+
export function classifierHistory(branch: readonly unknown[], options: HistoryCursor = {}): {
|
|
122
|
+
transcript: TranscriptEntry[];
|
|
123
|
+
userMessages: string[];
|
|
124
|
+
} {
|
|
125
|
+
const transcript: TranscriptEntry[] = [];
|
|
126
|
+
const userMessages: string[] = [];
|
|
127
|
+
const boundary = latestCompaction(branch);
|
|
128
|
+
if (boundary) {
|
|
129
|
+
const summary = record(branch[boundary.index]).summary;
|
|
130
|
+
if (typeof summary === "string" && summary) transcript.push({ kind: "summary", text: summary });
|
|
131
|
+
}
|
|
132
|
+
const provenance = provenanceIndex(branch);
|
|
133
|
+
const active = inContextEntries(branch).map(record);
|
|
134
|
+
const facts = new Map<string, Record<string, any>[]>();
|
|
135
|
+
for (const entry of active) {
|
|
136
|
+
if (entry.type !== "custom" || entry.customType !== CLASSIFIER_TOOL_META) continue;
|
|
137
|
+
const data = record(entry.data);
|
|
138
|
+
if (typeof data.toolCallId !== "string") continue;
|
|
139
|
+
const list = facts.get(data.toolCallId) ?? [];
|
|
140
|
+
list.push(data);
|
|
141
|
+
facts.set(data.toolCallId, list);
|
|
142
|
+
}
|
|
143
|
+
let reachedPending = false;
|
|
144
|
+
for (const entry of active) {
|
|
145
|
+
if (reachedPending) break;
|
|
146
|
+
if (entry.type === "branch_summary" && typeof entry.summary === "string") {
|
|
147
|
+
transcript.push({ kind: "summary", text: entry.summary });
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (entry.type !== "message") continue;
|
|
151
|
+
const message = record(entry.message);
|
|
152
|
+
if (message.role === "user") {
|
|
153
|
+
// Sessions preserve the input event's source, so extension-generated
|
|
154
|
+
// turns never gain intent authority on resume and expanded skill text
|
|
155
|
+
// is not credited as typed.
|
|
156
|
+
const userText = userWords(provenance, entry, message, messageText(message.content));
|
|
157
|
+
if (userText?.trim()) {
|
|
158
|
+
transcript.push({ kind: "user", text: userText.trim() });
|
|
159
|
+
userMessages.push(userText.trim());
|
|
160
|
+
}
|
|
161
|
+
} else if (message.role === "assistant" && Array.isArray(message.content)) {
|
|
162
|
+
for (const rawBlock of message.content) {
|
|
163
|
+
const block = record(rawBlock);
|
|
164
|
+
if (block.type !== "toolCall" || typeof block.name !== "string") continue;
|
|
165
|
+
if (options.beforeToolCallId !== undefined && block.id === options.beforeToolCallId) {
|
|
166
|
+
reachedPending = true;
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
const tool: TranscriptEntry = { kind: "tool", tool: block.name, input: record(block.arguments) };
|
|
170
|
+
if (!isHistoricalRead(tool)) {
|
|
171
|
+
for (const fact of facts.get(block.id) ?? []) if (fact.gitStatus) transcript.push({ kind: "meta", gitStatus: fact.gitStatus });
|
|
172
|
+
transcript.push(tool);
|
|
173
|
+
}
|
|
174
|
+
// A standing permission-rule denial is relevant even when the local
|
|
175
|
+
// read input itself is omitted from ordinary history.
|
|
176
|
+
for (const fact of facts.get(block.id) ?? []) {
|
|
177
|
+
if (typeof fact.deniedSubject === "string" && typeof fact.rule === "string") {
|
|
178
|
+
transcript.push({ kind: "denied", tool: block.name, subject: fact.deniedSubject, rule: fact.rule });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (options.throughToolCallId !== undefined && block.id === options.throughToolCallId) {
|
|
182
|
+
reachedPending = true;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return { transcript, userMessages };
|
|
189
|
+
}
|
|
@@ -2,8 +2,16 @@
|
|
|
2
2
|
* Project instruction files for the classifier (pure fs).
|
|
3
3
|
*
|
|
4
4
|
* Claude Code's classifier reads the same CLAUDE.md the agent does, so an
|
|
5
|
-
* instruction like "never force push" steers both at once. This
|
|
6
|
-
*
|
|
5
|
+
* instruction like "never force push" steers both at once. This runs the
|
|
6
|
+
* agent's own discovery (lib/claude-context.ts, lib/claude-rules.ts): the
|
|
7
|
+
* managed and global files, every ancestor's CLAUDE.md, `.claude/CLAUDE.md`,
|
|
8
|
+
* `.claude/rules` and CLAUDE.local.md, ONECODE.md, with the same external
|
|
9
|
+
* import consent and symlink confinement, and in independent mode only the
|
|
10
|
+
* AGENTS.md and ONECODE.md files. Two widenings, since an instruction here can
|
|
11
|
+
* only tighten: AGENTS.md loads whatever `instructionFiles` picks for the
|
|
12
|
+
* agent, and every path-conditional rule loads, labelled with its paths, not
|
|
13
|
+
* only those for files the agent has read (the block opens the cached
|
|
14
|
+
* classifier prefix, so it must not change as the session touches new paths).
|
|
7
15
|
*
|
|
8
16
|
* These files are checked in, so they are untrusted input in a way the user's
|
|
9
17
|
* own messages are not — the classifier prompt tells the model they may tighten
|
|
@@ -11,65 +19,63 @@
|
|
|
11
19
|
* them safe; without it, a repository could ship its own authorisation.
|
|
12
20
|
*/
|
|
13
21
|
|
|
14
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
15
22
|
import { dirname, join } from "node:path";
|
|
16
|
-
import {
|
|
23
|
+
import { ancestorDirs, discoverContextFiles, discoverOneCodeFiles } from "../lib/claude-context.ts";
|
|
24
|
+
import { readExternalIncludesApproval } from "../lib/claude-external-includes.ts";
|
|
25
|
+
import { discoverRules, type RuleFile } from "../lib/claude-rules.ts";
|
|
26
|
+
import { claudeSourcesOn } from "../lib/config-mode.ts";
|
|
27
|
+
import { claudeManagedDir, claudeUserDir, oneCodeStateDir, tryRealpath } from "../lib/paths.ts";
|
|
17
28
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
function readCapped(path: string): string | undefined {
|
|
25
|
-
try {
|
|
26
|
-
// readFileSync loads the whole file regardless, so the cap is applied to the
|
|
27
|
-
// decoded string. (A prior statSync branch claimed to bound the read but did
|
|
28
|
-
// the same full read either way.)
|
|
29
|
-
return readFileSync(path, "utf-8").slice(0, PER_FILE_LIMIT);
|
|
30
|
-
} catch {
|
|
31
|
-
return undefined;
|
|
32
|
-
}
|
|
29
|
+
/** One file the classifier is shown. */
|
|
30
|
+
interface InstructionFile {
|
|
31
|
+
path: string;
|
|
32
|
+
content: string;
|
|
33
|
+
/** A path-conditional rule's globs, named in its heading. */
|
|
34
|
+
globs?: string[];
|
|
33
35
|
}
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Every path-conditional rule from the directories the agent reads rules
|
|
39
|
+
* from, under the same consent: managed, the user's, and each ancestor's
|
|
40
|
+
* `.claude/rules`.
|
|
41
|
+
*/
|
|
42
|
+
function conditionalRules(cwd: string, home: string, homeClaudeDir: string, includeExternal: boolean): RuleFile[] {
|
|
43
|
+
const dirs: { rulesDir: string; scope: "Managed" | "User" | "Project" }[] = [
|
|
44
|
+
{ rulesDir: join(claudeManagedDir(), ".claude", "rules"), scope: "Managed" },
|
|
45
|
+
{ rulesDir: join(homeClaudeDir, "rules"), scope: "User" },
|
|
46
|
+
...ancestorDirs(cwd).filter((dir) => dirname(dir) !== dir).map((dir) => ({ rulesDir: join(dir, ".claude", "rules"), scope: "Project" as const })),
|
|
47
|
+
];
|
|
48
|
+
return dirs.flatMap(({ rulesDir, scope }) =>
|
|
49
|
+
discoverRules({ rulesDir, scope, cwd, home, allConditional: true, ...(scope !== "User" ? { includeExternal } : {}) }),
|
|
50
|
+
);
|
|
43
51
|
}
|
|
44
52
|
|
|
45
53
|
/**
|
|
46
|
-
* Concatenated instruction files
|
|
47
|
-
*
|
|
48
|
-
* convention from
|
|
54
|
+
* Concatenated instruction files in the agent's order (managed and global,
|
|
55
|
+
* then each directory from the farthest down, ONECODE.md last), each labelled
|
|
56
|
+
* with its path so the classifier can tell project convention from
|
|
57
|
+
* user-global preference; undefined when there are none. Every file is whole,
|
|
58
|
+
* as Claude Code's classifier gets the agent's CLAUDE.md: a cut would drop the
|
|
59
|
+
* restrictions past it. A transcript too large for the classifier's window is
|
|
60
|
+
* not judged (`decisions/auto-mode.md`).
|
|
49
61
|
*/
|
|
50
62
|
export function loadProjectInstructions(cwd: string, home: string): string | undefined {
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
if (!
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
total += chunk.length;
|
|
63
|
+
const claude = claudeSourcesOn();
|
|
64
|
+
const homeClaudeDir = claudeUserDir(home);
|
|
65
|
+
const includeExternal = claude && readExternalIncludesApproval(cwd, home).approved;
|
|
66
|
+
const files: InstructionFile[] = [];
|
|
67
|
+
const seen = new Set<string>();
|
|
68
|
+
const add = (file: InstructionFile) => {
|
|
69
|
+
const key = tryRealpath(file.path) ?? file.path;
|
|
70
|
+
if (seen.has(key) || !file.content.trim()) return;
|
|
71
|
+
seen.add(key);
|
|
72
|
+
files.push(file);
|
|
62
73
|
};
|
|
74
|
+
if (claude) for (const rule of conditionalRules(cwd, home, homeClaudeDir, includeExternal)) add(rule);
|
|
75
|
+
const rule = claude ? "claude-md-and-agents-md" : "agents-md";
|
|
76
|
+
for (const file of discoverContextFiles({ cwd, homeClaudeDir, rule, home, includeExternal })) add(file);
|
|
77
|
+
for (const file of discoverOneCodeFiles({ cwd, homeOneCodeDir: oneCodeStateDir(process.env, home), home })) add(file);
|
|
63
78
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
for (const name of FILE_NAMES) add(join(dir, name));
|
|
67
|
-
if (dir === stop) break;
|
|
68
|
-
const parent = dirname(dir);
|
|
69
|
-
if (parent === dir) break;
|
|
70
|
-
dir = parent;
|
|
71
|
-
}
|
|
72
|
-
add(join(claudeUserDir(home), "CLAUDE.md"));
|
|
73
|
-
|
|
74
|
-
return parts.length > 0 ? parts.join("\n\n") : undefined;
|
|
79
|
+
if (files.length === 0) return undefined;
|
|
80
|
+
return files.map((file) => `# ${file.path}${file.globs ? ` (applies to ${file.globs.join(", ")})` : ""}\n${file.content.trim()}`).join("\n\n");
|
|
75
81
|
}
|