@shadowclone/cli 0.0.2 → 0.0.4

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.
@@ -0,0 +1,25 @@
1
+ {
2
+ "description": "Keep the shadowclone profile current and load learned guidance",
3
+ "hooks": {
4
+ "SessionStart": [
5
+ {
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "bun run \"${CLAUDE_PLUGIN_ROOT}/dist/shadowclone.js\" hook session-start"
10
+ }
11
+ ]
12
+ }
13
+ ],
14
+ "SessionEnd": [
15
+ {
16
+ "hooks": [
17
+ {
18
+ "type": "command",
19
+ "command": "bun run \"${CLAUDE_PLUGIN_ROOT}/dist/shadowclone.js\" hook session-end"
20
+ }
21
+ ]
22
+ }
23
+ ]
24
+ }
25
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "shadowclone",
3
+ "owner": {
4
+ "name": "Shadowclone"
5
+ },
6
+ "plugins": [
7
+ {
8
+ "name": "shadowclone",
9
+ "source": ".",
10
+ "description": "Load and apply the user's learned engineering profile"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "shadowclone",
3
+ "version": "0.0.2",
4
+ "description": "Loads the user's shadowclone profile and learns when sessions end"
5
+ }
package/README.md CHANGED
@@ -1,145 +1,190 @@
1
1
  # shadowclone
2
2
 
3
- Every time you start a new AI agent, it has amnesia. shadowclone reads the AI coding sessions already on your disk, builds a profile of how you work, and runs copies of you inside the agent you already use.
3
+ Memory and alignment compiler for AI coding agents.
4
4
 
5
- Claude Code, Codex, and Cursor write every session to a file. Those files hold every time you stopped the agent, refused a tool, or picked one option over another. shadowclone turns those moments into a profile, loads it into your live sessions, and compiles it into a subagent. The subagent is you. Spawn ten of them on ten tasks, or let one run in a worktree while you're away.
5
+ Shadowclone reads historical coding sessions already on your disk (Claude Code, Codex, Cursor), mines your steering habits without sending raw transcripts to any server, and compiles an editable profile into the agents you already use.
6
6
 
7
- The name is the Naruto reference. A shadow clone does your work while you do something else, and what it learned comes back when it dissolves.
7
+ Developers who install the profile see a measurable action delta against unprofiled runs on their held-out corpus: the agent stops asking for confirmations you never gave, runs the tests you run, and avoids the tools you refuse.
8
8
 
9
- ## How it works
9
+ Verify the delta directly on your own machine:
10
+
11
+ ```bash
12
+ shadowclone eval --sessions 10
13
+ ```
14
+
15
+ ## Architectural scope: what shadowclone is and is not
16
+
17
+ **Not an agent runtime.**
18
+ Shadowclone does not provide an LLM chat loop, an autonomous worker daemon, or an IDE extension. It compiles behavioral profiles and subagents for the agent CLIs you already install, authenticate, and pay for.
19
+
20
+ **A memory and alignment compiler.**
21
+ Every turn where you interrupted an agent, refused a tool, corrected a proposal, or chose one implementation over another is an alignment signal. Shadowclone indexes those moments locally and distills them into plain markdown rules scoped by repository origin.
22
+
23
+ ## The pipeline
10
24
 
11
25
  ```
12
- observe -> index -> signal -> distill -> profile -> dispatch
26
+ observe -> index -> signal -> distill -> profile -> dispatch / eval
27
+ | |
28
+ zero tokens user's subscription
13
29
  ```
14
30
 
15
- | Stage | Module | Does |
31
+ | Stage | Module | Function |
16
32
  | --- | --- | --- |
17
- | observe | `src/observe/` | reads transcripts into one event stream, incrementally |
18
- | index | `src/index/` | SQLite cache of pointers into those files, never the text |
19
- | signal | `src/signal/` | finds where you overrode the agent, no model involved |
20
- | distill | `src/distill/` | turns those moments into rules, through your own agent CLI |
21
- | profile | `src/profile/` | markdown you can read, plus a subagent that is you |
22
- | dispatch | `src/dispatch/` | runs a clone in a worktree and leaves a receipt |
33
+ | observe | `src/observe/` | Normalizes agent transcripts into one incremental event stream |
34
+ | index | `src/index/` | Rebuildable SQLite cache of byte offsets and event kinds, never text |
35
+ | signal | `src/signal/` | Detects interruptions, plan changes, and tool refusals in pure code |
36
+ | distill | `src/distill/` | Distills high-signal moments into rules via your installed agent CLI |
37
+ | profile | `src/profile/` | Plain markdown rules and subagents scoped to git origins |
38
+ | dispatch | `src/dispatch/` | Executes unattended tasks on isolated worktrees with receipts |
39
+ | eval | `src/eval/` | Replays historical prompts through baseline vs clone to score behavioral deltas |
23
40
 
24
- There is no API key and no server. Model calls go through `claude`, `codex`, or `cursor-agent`, already installed and logged in, on your own plan. `docs/architecture/` has the reasoning behind each piece.
41
+ Model calls run through `claude`, `codex`, or `cursor-agent`. There is no shadowclone API key, no telemetry, and no hosted server.
25
42
 
26
- ## The Architecture Advantage
43
+ ## Quickstart
27
44
 
28
- Most "self-improving" AI agents or memory tools suffer from three massive flaws that shadowclone is explicitly designed to solve:
45
+ Install the global CLI:
29
46
 
30
- 1. **Zero Cold-Start (No Amnesia):** Other tools require months of daily use to learn your habits because they start at zero. Shadowclone mines the hundreds of past sessions *already sitting on your hard drive* to build your profile instantly.
31
- 2. **Behavioral Distillation:** Instead of feeding expensive LLMs your entire 50-turn conversation (which is 90% noise), shadowclone isolates *only* the "deltas", the exact moments you interrupted the agent or refused a tool. This gives the model an incredibly high signal-to-noise ratio, extracting your true behavioral preferences at a fraction of the cost.
32
- 3. **Enterprise Cross-Contamination:** If a memory tool learns a proprietary code convention at your day job, it will blindly leak it into your open-source side projects. Shadowclone solves this by scoping learned behaviors strictly to the `git` remote URL they were learned in, ensuring safe boundaries.
47
+ ```bash
48
+ npm i -g @shadowclone/cli
49
+ ```
33
50
 
34
- ## Status
51
+ Verify your environment and supported provider CLIs:
35
52
 
36
- Early.
53
+ ```bash
54
+ shadowclone doctor
55
+ ```
37
56
 
38
- - **Built.** Phases 0 through 6. `shadowclone learn` reads enabled Claude Code, Codex, Cursor, and Antigravity sessions into one offline mirror, `learn --deep` selects an authenticated CLI by enforceable capabilities, the plugin provides a live `shadowclone` subagent, and `shadowclone run` leaves unattended work on a local branch with a receipt.
39
- - **Manual checks.** Real authenticated provider runs, plugin installation, and provider-specific corpus tuning still need to be exercised outside recorded fixtures. API and local endpoint engines remain later work.
57
+ Grant consent for desired transcript sources:
40
58
 
41
- `docs/design/001-agent-transcript-pivot.md` is the spec. `docs/architecture/06-roadmap.md` is the order.
59
+ ```bash
60
+ shadowclone init
61
+ ```
42
62
 
43
- ### Provider coverage
63
+ Index your historical sessions and build your profile:
44
64
 
45
- Observe, distill, and dispatch are separate claims. An installed CLI is never capture consent, and an engine is not called for a purpose whose policy it cannot enforce.
65
+ ```bash
66
+ shadowclone learn
67
+ ```
46
68
 
47
- | Provider | Observe | Distill | Dispatch |
48
- | --- | --- | --- | --- |
49
- | Claude Code | built | built | built |
50
- | Codex | built | built | blocked on granular tool and budget controls |
51
- | Cursor | built | built | blocked on granular tool and budget controls |
52
- | Antigravity CLI | built | blocked on a per-run deny-all tool policy | blocked on granular tool and budget controls |
53
- | GitHub Copilot CLI, OpenCode, Aider, Amp | planned, one reviewed provider at a time | capability dependent | capability dependent |
69
+ To preview without writing files or databases:
54
70
 
55
- `docs/design/003-provider-expansion.md` defines the qualification gate and the registry that keeps these claims honest.
71
+ ```bash
72
+ shadowclone learn --dry-run
73
+ ```
56
74
 
57
- ## Privacy
75
+ To enable deep distillation through your authenticated agent CLI:
58
76
 
59
- This is the first question to ask about a program that reads your agent transcripts, so it goes here rather than at the bottom.
77
+ ```bash
78
+ shadowclone learn --deep
79
+ ```
60
80
 
61
- **What it reads.** Every source is opt-in and off by default. The list grows only when a release note says it grew.
81
+ Install the compiled profile into the current repository:
62
82
 
63
- | Source | Path | Default | Built today |
64
- | --- | --- | --- | --- |
65
- | `antigravity` | `~/.gemini/antigravity-cli/brain/*/.system_generated/logs/transcript_full.jsonl` | off | read only when enabled |
66
- | `claude-code` | `~/.claude/projects/**/*.jsonl` | off | read only when enabled |
67
- | `claude-prompts` | `~/.claude/history.jsonl` | off | read only when enabled |
68
- | `codex` | `~/.codex/sessions/**/*.jsonl` | off | read only when enabled |
69
- | `cursor` | `~/.cursor/chats/**/{store.db,meta.json}` | off | read only when enabled |
70
- | `git-metadata` | observed repositories' local `remote.origin.url` | off | read only when enabled |
71
- | `shell` | `~/.zsh_history`, `~/.bash_history` | off | read only when enabled |
83
+ ```bash
84
+ shadowclone install
85
+ ```
72
86
 
73
- **What leaves your machine.** Only what your own agent CLI sends, under your own account. `shadowclone learn` makes no network call. `shadowclone learn --deep` sends only redacted, allowlisted correction excerpts after separate consent. shadowclone has no server, account, key, telemetry, analytics, or crash reporting.
87
+ This writes `.claude/agents/shadowclone.md` and excludes it from git tracking.
74
88
 
75
- **What gets scrubbed.** Secrets, private paths, internal hosts, emails, cloud resources, and database URLs. `src/redact/index.test.ts` is the list. It is over-eager on purpose.
89
+ ## Replay evaluation
76
90
 
77
- **What is never read.** Tool results, file contents, thinking blocks, and anything from a data-access tool. Those hold other people's data, so they are excluded outright rather than redacted. `docs/architecture/07-enterprise.md` has the list.
91
+ Shadowclone provides a reproducible fitness function to measure profile impact:
78
92
 
79
- **What is stored.** Everything lives under `~/.shadowclone/`. The SQLite index contains pointers, event kinds, and tool metadata, never transcript text. The profile is plain markdown plus a generated-rule manifest containing only rule ids and relative profile paths. shadowclone never makes a second copy of your transcripts. Nothing is synced or uploaded. `shadowclone forget --all` removes all of it in one step.
93
+ ```bash
94
+ shadowclone eval --sessions 5 --max-budget-usd 0.50
95
+ ```
80
96
 
81
- **What stays in your org.** Every rule is scoped to the git remote it came from when `git-metadata` is enabled. Without that consent, each working directory is an isolated origin that never promotes a rule to global. An admin can disable shadowclone fleet-wide with a root-owned file.
97
+ The evaluator replays historical user prompts through two isolated runs:
98
+ 1. **Baseline run:** unprofiled agent invocation without system prompt customization.
99
+ 2. **Clone run:** agent invocation with the compiled project profile injected.
82
100
 
83
- **What it does on your behalf.** The live subagent runs inside your current Claude Code session and its permission mode. `shadowclone run "<task>"` explicitly approves one local worktree, branch, and commit for that task. A repo allowlist is only a ceiling for remote actions, and each run must also name an action with `--approve`. Learned denials stay advisory until observation can identify the denied action without storing raw tool input. Merge, force push, `bypassPermissions`, and `--dangerously-skip-permissions` are never allowed.
101
+ Replays are compared against historical developer actions across four dimensions:
102
+ - **Tools:** Jaccard similarity of invoked tools.
103
+ - **Verification:** Jaccard similarity of two-token bash verification commands (e.g. `bun test`, `cargo check`).
104
+ - **Files:** Jaccard similarity of posix repository-relative edited paths.
105
+ - **Planning:** Match on whether planning tools were invoked before the first file edit.
84
106
 
85
- If a secret gets past the redaction, that is the highest-value bug report this project can get. Open an issue with the shape of the string, not the string itself.
107
+ Evaluation receipts are written to `~/.shadowclone/eval/<evalId>.json`.
86
108
 
87
- ## Quickstart
109
+ ## Unattended dispatch
88
110
 
89
- Needs one of `claude`, `codex`, or `cursor-agent` installed and logged in for anything that calls a model. No API key.
111
+ Execute tasks in an isolated git worktree without touching your working tree:
90
112
 
91
113
  ```bash
92
- npm i -g @shadowclone/cli
93
- shadowclone doctor
94
- shadowclone init
95
- shadowclone learn
114
+ shadowclone run "fix the flaky test in src/auth.test.ts"
96
115
  ```
97
116
 
98
- That is the whole install. The package brings its own runtime, so nothing else is required.
99
-
100
- ### Using your clone
117
+ The default dispatch mode creates a local worktree and branch, runs verification checks, and commits locally without pushing.
101
118
 
102
- To inject your profile into a project, navigate to the repository and run:
119
+ Remote actions (push, open PR) require both a repository ceiling in `~/.shadowclone/config.toml` and an explicit per-run approval flag:
103
120
 
104
121
  ```bash
105
- shadowclone install
122
+ shadowclone run "prepare release notes" --approve push
106
123
  ```
107
124
 
108
- This writes your profile as a subagent (`.claude/agents/shadowclone.md`). Here is how to use it across different editors:
125
+ ## Ground-truth privacy
109
126
 
110
- - **Claude Code:** Ask Claude to delegate tasks to your clone. For example: *"Use the Agent tool to spawn a shadowclone subagent to write a unit test."*
111
- - **Cursor:** Since Cursor's agent dispatch is still in development, you can manually point Cursor to your profile by adding `Include .claude/agents/shadowclone.md in your context` to your `.cursorrules`.
112
- - **Codex:** Similar to Cursor, reference the generated markdown profile directly in your Codex system prompt instructions until native dispatch is unblocked.
113
- - **Headless Dispatch:** Run `shadowclone run "<task>"` in your terminal to dispatch a clone in a background worktree (currently defaults to Claude).
127
+ Agent transcripts contain private code, environment variables, internal hosts, and customer data. Shadowclone protects data through structural guarantees:
114
128
 
115
- Working on shadowclone itself:
129
+ **Pointers instead of text copies.**
130
+ The SQLite index stores file offsets, timestamps, and event kinds. Raw transcripts are never duplicated to a secondary store.
131
+
132
+ **Sliced secret redaction.**
133
+ Distillation excerpts pass through a deterministic sliced replacer before reaching any model. Secrets keep identifying prefixes (such as `AKIA` or `sk_live_`) while stripping high-entropy characters, keeping code context intact without leaking credentials.
134
+
135
+ **Shannon entropy layer.**
136
+ Unstructured tokens exceeding 4.5 bits of entropy per character are scrubbed even if they do not match known vendor regex patterns.
137
+
138
+ **Third-party tool results are excluded.**
139
+ Distillation inputs allowlist user prompts and developer steering corrections. Tool outputs from database queries, log dumps, and file reads are excluded by category rather than relying on regex filtering.
140
+
141
+ **Single-command wipe.**
142
+ Wipe the entire local index, profile, checkpoints, and receipts:
116
143
 
117
144
  ```bash
118
- git clone https://github.com/theonly1me/shadowclone.git
119
- cd shadowclone
120
- bun install
121
- bun run check # typecheck, lint, and tests
122
- bun run cli doctor
145
+ shadowclone forget --all
123
146
  ```
124
147
 
125
- Add this checkout as a local Claude Code marketplace, then install the plugin:
126
-
127
- ```text
128
- /plugin marketplace add /path/to/shadowclone
129
- /plugin install shadowclone@shadowclone
148
+ ## Enterprise governance
149
+
150
+ Security teams can enforce policy ceilings fleet-wide via root-owned managed configuration:
151
+ - **macOS:** `/Library/Application Support/shadowclone/managed.json`
152
+ - **Linux:** `/etc/shadowclone/managed.json`
153
+
154
+ ```json
155
+ {
156
+ "enabled": true,
157
+ "allowedSources": ["claude-code"],
158
+ "allowedEngines": ["claude-code"],
159
+ "distillation": "local-only",
160
+ "originScope": "strict",
161
+ "blockedOrigins": ["github.com/acme/security-*"],
162
+ "maxActionTier": "draft"
163
+ }
130
164
  ```
131
165
 
132
- Run `shadowclone install` inside a repository before its next Claude Code session. It writes the scoped `.claude/agents/shadowclone.md`. The plugin injects the same profile at session start, refreshes the offline profile at session end, and exposes it through MCP.
166
+ Managed policies act as an absolute ceiling. Users cannot enable unapproved sources or engines, and `enabled: false` enforces an immediate stop across the machine.
133
167
 
134
- The default run creates a worktree and local commit, writes a receipt under `~/.shadowclone/runs/`, and pushes nothing. Remote actions need both a matching `[repo."<host>/<owner>/<repo>"]` allowlist and an explicit per-run `--approve`.
168
+ ## CLI commands
135
169
 
136
- ## Contributing
170
+ ```bash
171
+ shadowclone init # Configure source consent and capabilities
172
+ shadowclone learn [--deep] [--dry-run] # Index sessions and synthesize rules
173
+ shadowclone doctor # Inspect active paths, engines, and policies
174
+ shadowclone install # Install profile as .claude/agents/shadowclone.md
175
+ shadowclone run <task> [--approve <action>] # Dispatch headless clone in a worktree
176
+ shadowclone eval [--sessions N] [--json] # Measure behavioral deltas against baseline
177
+ shadowclone mcp # Start stdio Model Context Protocol server
178
+ shadowclone forget --all # Remove ~/.shadowclone/ completely
179
+ ```
137
180
 
138
- `CONTRIBUTING.md` has the rules. Short version: small diffs, `bun run check`, PR body under 250 words.
181
+ ## Contributing
139
182
 
140
- `SECURITY.md` says what to report privately and how to verify a release download.
183
+ Review `CONTRIBUTING.md` and `SECURITY.md`. All contributions must pass:
141
184
 
142
- Anything touching capture, storage, or egress gets a closer read. `.claude/skills/data-handling/SKILL.md` says what a reviewer checks.
185
+ ```bash
186
+ bun run check
187
+ ```
143
188
 
144
189
  ## License
145
190
 
@@ -1,35 +1,42 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- var pr={name:"@shadowclone/cli",version:"0.0.2",module:"src/cli/index.ts",type:"module",packageManager:"bun@1.3.3",bin:{shadowclone:"bin/shadowclone.mjs"},scripts:{start:"bun run src/cli/index.ts",cli:"bun run src/cli/index.ts",check:"bun run typecheck && bun run lint && bun test",test:"bun test",typecheck:"tsc --noEmit",lint:"biome lint --error-on-warnings --diagnostic-level=warn . && bun run scripts/conventions.ts","lint:fix":"biome lint --write .",build:"bun run scripts/build.ts",prepack:"bun run build"},devDependencies:{"@biomejs/biome":"2.5.12","@types/bun":"latest",typescript:"~5.9"},description:"Learns how you work from the AI coding sessions already on your disk, then runs copies of you inside the agent you already use.",license:"MIT",repository:{type:"git",url:"git+https://github.com/theonly1me/shadowclone.git"},homepage:"https://shadowclone.co",bugs:{url:"https://github.com/theonly1me/shadowclone/issues"},keywords:["claude-code","codex","cursor","agent","subagent","local-first"],files:["bin","dist","README.md","LICENSE"],dependencies:{bun:"^1.4.2"}};function Q(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function P(e,r){let t=e[r];return typeof t==="string"?t:null}function ve(e,r){let t=e[r];return typeof t==="number"?t:null}function Kt(e){let r=e.message;if(!Q(r)||!Array.isArray(r.content))return"";return r.content.flatMap((t)=>Q(t)&&P(t,"type")==="text"&&P(t,"text")!==null?[P(t,"text")??""]:[]).join("")}function Wt(e){if(!Array.isArray(e))return[];return e.flatMap((r)=>{if(!Q(r))return[];let t=P(r,"tool_name")??P(r,"toolName");return t?[{toolName:t,toolUseId:P(r,"tool_use_id")??P(r,"toolUseId")}]:[]})}function Ee(e){let r=[],t=null;for(let i of e.stream.split(`
4
- `)){if(i.trim().length===0)continue;try{let s=JSON.parse(i);if(!Q(s))continue;if(P(s,"type")==="assistant")r.push(Kt(s));if(P(s,"type")==="result")t=s}catch{}}let n=t?P(t,"result"):null,o=r.join("");return{engine:"claude-code",sessionId:(t?P(t,"session_id"):null)??e.fallbackSessionId,transcriptPath:null,text:o.length>0?o:n??"",structured:t?.structured_output??null,costUsd:t?ve(t,"total_cost_usd"):null,durationMs:t?ve(t,"duration_ms")??0:0,turns:t?ve(t,"num_turns")??0:0,isError:t?.is_error===!0||t===null,permissionDenials:Wt(t?.permission_denials)}}function fr(e){if(e.values===void 0)return;e.arguments_.push(e.flag),e.arguments_.push(...e.values.length===0?[""]:e.values)}function mr(e){let r=["claude","-p","--output-format","stream-json","--verbose","--session-id",e.sessionId];if(e.run.systemPromptFile)r.push("--append-system-prompt-file",e.run.systemPromptFile);if(e.run.model)r.push("--model",e.run.model);if(e.run.permissionMode)r.push("--permission-mode",e.run.permissionMode);if(e.run.maxBudgetUsd!==void 0)r.push("--max-budget-usd",e.run.maxBudgetUsd.toString());if(e.run.outputSchema!==void 0)r.push("--json-schema",JSON.stringify(e.run.outputSchema));return fr({arguments_:r,flag:"--allowedTools",values:e.run.allowedTools}),fr({arguments_:r,flag:"--disallowedTools",values:e.run.disallowedTools}),r}async function Ce(e){let r=e.sessionId??crypto.randomUUID(),t=Bun.spawn({cmd:[...mr({run:e,sessionId:r})],cwd:e.cwd,stdin:"pipe",stdout:"pipe",stderr:"ignore",signal:e.signal});t.stdin.write(e.prompt),t.stdin.end();let[n,o]=await Promise.all([t.exited,new Response(t.stdout).text()]),i=Ee({stream:o,fallbackSessionId:r});return n===0?i:{...i,isError:!0}}import{mkdtemp as Zt,rm as Vt}from"fs/promises";import Yt from"os";import gr from"path";function yr(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function N(e,r){let t=e[r];return typeof t==="string"?t:null}function Xt(e){try{return JSON.parse(e)}catch{return null}}function ke(e){let r=e.fallbackSessionId,t="",n=0,o=!1;for(let i of e.stream.split(`
5
- `)){if(i.trim().length===0)continue;let s;try{s=JSON.parse(i)}catch{o=!0;continue}if(!yr(s))continue;let a=N(s,"type");if(a==="thread.started")r=N(s,"thread_id")??r;if(a==="turn.completed")n+=1;if(a==="turn.failed"||a==="error")o=!0;let d=yr(s.item)?s.item:null,u=d?N(d,"item_type")??N(d,"type"):null;if(a==="item.completed"&&d!==null&&(u==="assistant_message"||u==="agent_message"))t=N(d,"text")??t}return{engine:"codex",sessionId:r,transcriptPath:null,text:t,structured:Xt(t),costUsd:null,durationMs:e.durationMs,turns:n,isError:o,permissionDenials:[]}}async function ee(e){let r=[];if(e.run.systemPromptFile)r.push("Follow this shadowclone profile:",await Bun.file(e.run.systemPromptFile).text());if(r.push("Complete this task:",e.run.prompt),e.outputSchemaInPrompt&&e.run.outputSchema!==void 0)r.push("Return only JSON matching this schema:",JSON.stringify(e.run.outputSchema));return r.join(`
3
+ var he={name:"@shadowclone/cli",version:"0.0.4",module:"src/cli/index.ts",type:"module",packageManager:"bun@1.3.3",bin:{shadowclone:"bin/shadowclone.mjs"},scripts:{start:"bun run src/cli/index.ts",cli:"bun run src/cli/index.ts",check:"bun run typecheck && bun run lint && bun test",test:"bun test",typecheck:"tsc --noEmit",lint:"biome lint --error-on-warnings --diagnostic-level=warn . && bun run scripts/conventions.ts","lint:fix":"biome lint --write .",build:"bun run scripts/build.ts",prepack:"bun run build"},devDependencies:{"@biomejs/biome":"2.5.12","@types/bun":"latest",typescript:"~5.9"},description:"Learns how you work from the AI coding sessions already on your disk, then runs copies of you inside the agent you already use.",license:"MIT",repository:{type:"git",url:"git+https://github.com/theonly1me/shadowclone.git"},homepage:"https://shadowclone.co",bugs:{url:"https://github.com/theonly1me/shadowclone/issues"},keywords:["claude-code","codex","cursor","agent","subagent","local-first"],files:["bin","dist",".claude-plugin","README.md","LICENSE"],dependencies:{bun:"^1.4.2"}};import Io from"path";import{mkdir as oo}from"fs/promises";import io from"path";import Hn from"os";import v from"path";function Wn(e){if(e==="darwin")return"/Library/Application Support/shadowclone/managed.json";if(e==="linux")return"/etc/shadowclone/managed.json";return null}function Kn(e){let t=v.join(e.homeDirectory,".shadowclone"),r=v.join(t,"profile");return{shadowcloneDirectory:t,configFile:v.join(t,"config.toml"),indexDatabase:v.join(t,"index.db"),profileDirectory:r,rejectedProfileFile:v.join(r,".rejected"),profileManifestFile:v.join(r,".generated"),compiledProfileFile:v.join(r,".compiled.md"),distillDirectory:v.join(t,"distill"),worktreesDirectory:v.join(t,"worktrees"),runsDirectory:v.join(t,"runs"),antigravityBrainDirectory:v.join(e.homeDirectory,".gemini","antigravity-cli","brain"),claudeProjectsDirectory:v.join(e.homeDirectory,".claude","projects"),claudePromptHistoryFile:v.join(e.homeDirectory,".claude","history.jsonl"),codexSessionsDirectory:v.join(e.homeDirectory,".codex","sessions"),cursorChatsDirectory:v.join(e.homeDirectory,".cursor","chats"),shellHistoryFiles:[v.join(e.homeDirectory,".zsh_history"),v.join(e.homeDirectory,".bash_history")],managedConfigFile:Wn(e.platform),runDirectory:(n)=>v.join(t,"runs",n),worktreeDirectory:(n)=>v.join(t,"worktrees",n)}}var h=Kn({homeDirectory:Hn.homedir(),platform:process.platform});import{stat as eo}from"fs/promises";var _=["push","pr-draft","pr-reply"];function Jt(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Xn(e){if(!Array.isArray(e))return null;let t=e.flatMap((r)=>{let n=_.find((o)=>o===r);return n?[n]:[]});return t.length===e.length?t:null}function Ht(e){if(e===void 0)return{};if(!Jt(e))throw Error("Config repo settings must be tables");let t={};for(let[r,n]of Object.entries(e)){if(!Jt(n))throw Error("Every repo policy must be a table");let o=Xn(n.allow);if(o===null||typeof n.maxBudgetUsd!=="number"||n.maxBudgetUsd<=0||typeof n.requireCleanExit!=="boolean"||Object.keys(n).some((s)=>s!=="allow"&&s!=="maxBudgetUsd"&&s!=="requireCleanExit"))throw Error("Every repo policy must contain valid action settings");t[r]={allow:o,maxBudgetUsd:n.maxBudgetUsd,requireCleanExit:n.requireCleanExit}}return t}function Wt(e){return Object.entries(e).sort(([t],[r])=>t.localeCompare(r)).flatMap(([t,r])=>["",`[repo.${JSON.stringify(t)}]`,`allow = [${r.allow.map((n)=>JSON.stringify(n)).join(", ")}]`,`maxBudgetUsd = ${r.maxBudgetUsd}`,`requireCleanExit = ${r.requireCleanExit}`])}var T=["antigravity","claude-code","claude-prompts","codex","cursor","git-metadata","shell"],Zn=T.filter((e)=>e!=="antigravity"),Vn=T.filter((e)=>e!=="antigravity"&&e!=="git-metadata"),F={schemaVersion:1,sources:{antigravity:!1,"claude-code":!1,"claude-prompts":!1,codex:!1,cursor:!1,"git-metadata":!1,shell:!1},distillation:{deep:!1},repo:{}};function He(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function W(e){let t=Object.keys(e.record),r=new Set(e.keys);return t.length===e.keys.length&&t.every((n)=>r.has(n))}function Yn(e){if(!He(e)||!W({record:e,keys:T})&&!W({record:e,keys:Zn})&&!W({record:e,keys:Vn}))throw Error("Config sources must contain every supported source and no unknown sources");let t=e.antigravity??!1,r=e["claude-code"],n=e["claude-prompts"],{codex:o,cursor:s}=e,i=e["git-metadata"]??!1,a=e.shell;if(typeof t!=="boolean"||typeof r!=="boolean"||typeof n!=="boolean"||typeof o!=="boolean"||typeof s!=="boolean"||typeof i!=="boolean"||typeof a!=="boolean")throw Error("Every config source setting must be a boolean");return{antigravity:t,"claude-code":r,"claude-prompts":n,codex:o,cursor:s,"git-metadata":i,shell:a}}function Qn(e){if(!He(e)||!W({record:e,keys:["deep"]}))throw Error("Config distillation must contain only the deep setting");if(typeof e.deep!=="boolean")throw Error("Config distillation.deep must be a boolean");return{deep:e.deep}}function Kt(e){let t=["schema-version","sources","distillation"],r=[...t,"repo"];if(!He(e)||!W({record:e,keys:t})&&!W({record:e,keys:r}))throw Error("Config must contain only supported top-level settings");if(e["schema-version"]!==1)throw Error("Config schema-version must be 1");return{schemaVersion:1,sources:Yn(e.sources),distillation:Qn(e.distillation),repo:Ht(e.repo)}}var Xt=["claude-code","codex","cursor-agent","antigravity","anthropic-api","openai-compatible"],We={enabled:!0,allowedSources:T,allowedEngines:Xt,distillation:"allowed",originScope:"strict",blockedOrigins:[],maxActionTier:"act"};function to(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Ke(e){return Array.isArray(e)&&e.every((t)=>typeof t==="string")?e:null}function ro(e){let t=Ke(e);if(t===null)return null;let r=t.flatMap((n)=>{let o=T.find((s)=>s===n);return o?[o]:[]});return r.length===t.length?r:null}function no(e){let t=Ke(e);if(t===null)return null;let r=t.flatMap((n)=>{let o=Xt.find((s)=>s===n);return o?[o]:[]});return r.length===t.length?r:null}function Zt(e){if(!to(e))throw Error("Managed policy must be a JSON object");let t=ro(e.allowedSources),r=no(e.allowedEngines),n=Ke(e.blockedOrigins),{distillation:o,maxActionTier:s}=e;if(typeof e.enabled!=="boolean"||t===null||r===null||n===null||o!=="allowed"&&o!=="local-only"&&o!=="disabled"||e.originScope!=="strict"||s!=="observe"&&s!=="draft"&&s!=="act")throw Error("Managed policy has invalid or missing fields");return{enabled:e.enabled,allowedSources:t,allowedEngines:r,distillation:o,originScope:"strict",blockedOrigins:n,maxActionTier:s}}function Xe(e){let t=(r)=>e.policy.enabled&&e.policy.allowedSources.includes(r);return{...e.config,sources:{antigravity:e.config.sources.antigravity&&t("antigravity"),"claude-code":e.config.sources["claude-code"]&&t("claude-code"),"claude-prompts":e.config.sources["claude-prompts"]&&t("claude-prompts"),codex:e.config.sources.codex&&t("codex"),cursor:e.config.sources.cursor&&t("cursor"),"git-metadata":e.config.sources["git-metadata"]&&t("git-metadata"),shell:e.config.sources.shell&&t("shell")},distillation:{deep:e.config.distillation.deep&&e.policy.enabled&&e.policy.distillation!=="disabled"}}}async function re(e){if(e===null)return We;let t=Bun.file(e);if(!await t.exists())return We;if((await eo(e)).uid!==0)throw Error("Managed policy must be owned by root");let n=await t.json();return Zt(n)}async function so(e={}){let t=e.configPath??h.configFile,r=Bun.file(t);if(!await r.exists())return F;let n=Bun.TOML.parse(await r.text());return Kt(n)}async function S(e={}){let t=await re(e.managedConfigPath===void 0?h.managedConfigFile:e.managedConfigPath),r=t.enabled?await so({configPath:e.configPath}):F;return{config:Xe({config:r,policy:t}),policy:t}}function ao(e){let t=T.map((r)=>`${r} = ${e.sources[r]}`);return[`schema-version = ${e.schemaVersion}`,"","[sources]",...t,"","[distillation]",`deep = ${e.distillation.deep}`,...Wt(e.repo),""].join(`
4
+ `)}async function Ze(e){let t=e.configPath??h.configFile;await oo(io.dirname(t),{recursive:!0}),await Bun.write(t,ao(e.config))}function Ve(e){return{...e.config,sources:{...e.config.sources,[e.source]:e.enabled}}}function Vt(e){return{...e.config,distillation:{deep:e.enabled}}}import{mkdir as Yt}from"fs/promises";import K from"path";async function lo(e){let t=Bun.spawn({cmd:["git","-C",e.cwd,"rev-parse","--git-path","info/exclude"],stdout:"pipe",stderr:"ignore"});if(await t.exited!==0)return;let r=(await new Response(t.stdout).text()).trim();if(r.length===0)return;let n=K.isAbsolute(r)?r:K.resolve(e.cwd,r),o=Bun.file(n),s=await o.exists()?await o.text():"";if(s.includes(e.relativePath))return;await Yt(K.dirname(n),{recursive:!0});let i=s.length>0&&!s.endsWith(`
5
+ `)?`${s}
6
+ `:s;await Bun.write(n,`${i}${e.relativePath}
7
+ `)}function Qt(e){let t=e.name??"shadowclone";if(!/^[a-z0-9-]+$/.test(t))throw Error("Agent name must use lowercase letters, numbers, and hyphens");return["---",`name: ${t}`,"description: A copy of the user that follows their learned engineering profile","model: inherit","tools: Read, Grep, Glob, Bash, Edit, Write","---","",e.profile.trim(),""].join(`
8
+ `)}async function Ye(e){let t=e.name??"shadowclone",r=K.join(e.targetDirectory,".claude","agents"),n=K.join(r,`${t}.md`);await Yt(r,{recursive:!0}),await Bun.write(n,Qt(e));let o=K.join(".claude","agents",`${t}.md`);return await lo({cwd:e.targetDirectory,relativePath:o}),n}import{mkdir as uo}from"fs/promises";import be from"path";function we(e){return new Bun.CryptoHasher("sha256").update(e).digest("hex").slice(0,16)}function N(e){return new Bun.CryptoHasher("sha256").update(`semantic:${e.toLowerCase()}`).digest("hex").slice(0,16)}function Qe(e){return e.scope==="global"?`global/${e.section}.md`:`org/${e.originDirectory??"isolated"}/${e.section}.md`}function ne(e){let t=`## ${e.title}
6
9
 
7
- `)}function wr(e){if(e.sessionId!==void 0)throw Error("Codex cannot set a caller-provided session id");if(e.maxBudgetUsd!==void 0)throw Error("Codex cannot enforce a per-run dollar budget");if(e.disallowedTools&&e.disallowedTools.length>0)throw Error("Codex cannot enforce a granular tool denylist");if(e.allowedTools&&e.allowedTools.length>0)throw Error("Codex cannot enforce a granular tool allowlist");if(![void 0,"dontAsk","plan"].includes(e.permissionMode))throw Error("Codex cannot honor this permission mode")}function br(e){wr(e.run);let r=["codex","exec","-","--json","--sandbox","read-only","-C",e.run.cwd,"--skip-git-repo-check","-c",'approval_policy="never"',"-c","mcp_servers={}"];if(e.run.allowedTools?.length===0)r.push("--disable","shell_tool");if(e.run.model)r.push("--model",e.run.model);if(e.outputSchemaPath)r.push("--output-schema",e.outputSchemaPath);return r}async function hr(e){let r=await ee({run:e.run,outputSchemaInPrompt:!1}),t=crypto.randomUUID(),n=Date.now(),o=Bun.spawn({cmd:[...br(e)],cwd:e.run.cwd,stdin:"pipe",stdout:"pipe",stderr:"ignore",signal:e.run.signal});o.stdin.write(r),o.stdin.end();let[i,s]=await Promise.all([o.exited,new Response(o.stdout).text()]),a=ke({stream:s,fallbackSessionId:t,durationMs:Date.now()-n});return i===0?a:{...a,isError:!0}}async function Se(e){if(wr(e),e.outputSchema===void 0)return hr({run:e});let r=await Zt(gr.join(Yt.tmpdir(),"shadowclone-codex-")),t=gr.join(r,"schema.json");await Bun.write(t,JSON.stringify(e.outputSchema));try{return await hr({run:e,outputSchemaPath:t})}finally{await Vt(r,{recursive:!0,force:!0})}}import{mkdir as tn,mkdtemp as nn,rm as on}from"fs/promises";import sn from"os";import Ae from"path";function Qt(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function re(e,r){let t=e[r];return typeof t==="string"?t:null}function en(e,r){let t=e[r];return typeof t==="number"?t:null}function rn(e){try{return JSON.parse(e)}catch{return null}}function Ie(e){let r=e.fallbackSessionId,t=null,n=0;for(let i of e.stream.split(`
8
- `)){if(i.trim().length===0)continue;let s;try{s=JSON.parse(i)}catch{continue}if(!Qt(s))continue;if(r=re(s,"session_id")??r,re(s,"type")==="assistant")n+=1;if(re(s,"type")==="result")t=s}let o=t?re(t,"result")??"":"";return{engine:"cursor-agent",sessionId:r,transcriptPath:null,text:o,structured:rn(o),costUsd:null,durationMs:t?en(t,"duration_ms")??0:0,turns:n,isError:t===null||t.is_error===!0,permissionDenials:[]}}function Rr(e){if(e.sessionId!==void 0)throw Error("Cursor cannot set a caller-provided session id");if(e.maxBudgetUsd!==void 0)throw Error("Cursor cannot enforce a per-run dollar budget");if(e.disallowedTools&&e.disallowedTools.length>0)throw Error("Cursor cannot enforce a granular tool denylist");if(e.allowedTools&&e.allowedTools.length>0)throw Error("Cursor cannot enforce a granular tool allowlist");if(![void 0,"dontAsk","plan"].includes(e.permissionMode))throw Error("Cursor cannot honor this permission mode")}function Pr(e){Rr(e);let r=["cursor-agent","--print","--output-format","stream-json","--sandbox","enabled","--mode",e.permissionMode==="plan"?"plan":"ask","--workspace",e.cwd];if(e.model)r.push("--model",e.model);return r}async function xr(e){let r=await ee({run:e.run,outputSchemaInPrompt:!0}),t=crypto.randomUUID(),n=Bun.spawn({cmd:[...Pr({...e.run,cwd:e.workspace}),"--trust"],cwd:e.workspace,stdin:"pipe",stdout:"pipe",stderr:"ignore",signal:e.run.signal});n.stdin.write(r),n.stdin.end();let[o,i]=await Promise.all([n.exited,new Response(n.stdout).text()]),s=Ie({stream:i,fallbackSessionId:t});return o===0?s:{...s,isError:!0}}async function Te(e){if(Rr(e),e.allowedTools?.length!==0)return xr({run:e,workspace:e.cwd});let r=await nn(Ae.join(sn.tmpdir(),"shadowclone-cursor-")),t=Ae.join(r,".cursor");await tn(t,{recursive:!0}),await Bun.write(Ae.join(t,"cli.json"),JSON.stringify({version:1,permissions:{allow:[],deny:["Shell(*)","Read(*)","Write(*)","WebFetch(*)","Mcp(*:*)"]}}));try{return await xr({run:e,workspace:r})}finally{await on(r,{recursive:!0,force:!0})}}var te=[{id:"claude-code",captureSource:"claude-code",transcriptFormat:"jsonl",engine:{id:"claude-code",implemented:!0,capabilities:{structuredOutput:"native",callerSessionId:!0,maxBudgetUsd:!0,granularToolPolicy:!0,isolatedNoTools:!0}}},{id:"codex",captureSource:"codex",transcriptFormat:"jsonl",engine:{id:"codex",implemented:!0,capabilities:{structuredOutput:"native",callerSessionId:!1,maxBudgetUsd:!1,granularToolPolicy:!1,isolatedNoTools:!0}}},{id:"cursor",captureSource:"cursor",transcriptFormat:"sqlite",engine:{id:"cursor-agent",implemented:!0,capabilities:{structuredOutput:"prompted",callerSessionId:!1,maxBudgetUsd:!1,granularToolPolicy:!1,isolatedNoTools:!0}}},{id:"antigravity",captureSource:"antigravity",transcriptFormat:"jsonl",engine:{id:"antigravity",implemented:!1,capabilities:{structuredOutput:"native",callerSessionId:!1,maxBudgetUsd:!1,granularToolPolicy:!1,isolatedNoTools:!1}}}];function De(e){return te.find((r)=>r.engine?.id===e)??null}function an(e){return e?.implemented===!0&&e.capabilities.structuredOutput!=="none"&&e.capabilities.isolatedNoTools}function ne(e){let r=an(e.engine),t=e.engine?.implemented===!0,n=e.engine?.capabilities;return{observe:e.captureSource!==null,distill:r,dispatch:t&&n?.callerSessionId===!0&&n.maxBudgetUsd&&n.granularToolPolicy}}function Oe(e){let r=ne(e.definition);return e.purpose==="distill"?r.distill:r.dispatch}async function oe(e){try{return await Bun.spawn({cmd:[...e],stdout:"ignore",stderr:"ignore"}).exited===0}catch{return!1}}async function vr(e={}){let r=e.probe??oe,t=await r(["claude","--version"]),n=t&&await r(["claude","auth","status"]);return{engine:"claude-code",installed:t,authenticated:n}}async function Er(e={}){let r=e.probe??oe,t=await r(["codex","--version"]),n=t&&await r(["codex","login","status"]);return{engine:"codex",installed:t,authenticated:n}}async function Cr(e={}){let r=e.probe??oe,t=await r(["cursor-agent","--version"]),n=t&&await r(["cursor-agent","status"]);return{engine:"cursor-agent",installed:t,authenticated:n}}function ln(e){if(e==="claude-code")return Ce;if(e==="codex")return Se;if(e==="cursor-agent")return Te;return null}function dn(e){let r=De(e.engineId);return r!==null&&Oe({definition:r,purpose:e.purpose})}async function A(e){let r=await vr(e),t=await Er(e),n=await Cr(e),o=e.allowedEngines??["claude-code","codex","cursor-agent"],i=[r,t,n],s=i.find((d)=>d.authenticated&&o.includes(d.engine)&&dn({engineId:d.engine,purpose:e.purpose})),a=s?ln(s.engine):null;return{availability:i,runner:a,selectedEngine:a?s?.engine??null:null}}import{mkdir as Pn}from"fs/promises";import vn from"path";import cn from"os";import g from"path";function un(e){if(e==="darwin")return"/Library/Application Support/shadowclone/managed.json";if(e==="linux")return"/etc/shadowclone/managed.json";return null}function pn(e){let r=g.join(e.homeDirectory,".shadowclone"),t=g.join(r,"profile");return{shadowcloneDirectory:r,configFile:g.join(r,"config.toml"),indexDatabase:g.join(r,"index.db"),profileDirectory:t,rejectedProfileFile:g.join(t,".rejected"),profileManifestFile:g.join(t,".generated"),compiledProfileFile:g.join(t,".compiled.md"),distillDirectory:g.join(r,"distill"),worktreesDirectory:g.join(r,"worktrees"),runsDirectory:g.join(r,"runs"),antigravityBrainDirectory:g.join(e.homeDirectory,".gemini","antigravity-cli","brain"),claudeProjectsDirectory:g.join(e.homeDirectory,".claude","projects"),claudePromptHistoryFile:g.join(e.homeDirectory,".claude","history.jsonl"),codexSessionsDirectory:g.join(e.homeDirectory,".codex","sessions"),cursorChatsDirectory:g.join(e.homeDirectory,".cursor","chats"),shellHistoryFiles:[g.join(e.homeDirectory,".zsh_history"),g.join(e.homeDirectory,".bash_history")],managedConfigFile:un(e.platform),runDirectory:(n)=>g.join(r,"runs",n),worktreeDirectory:(n)=>g.join(r,"worktrees",n)}}var h=pn({homeDirectory:cn.homedir(),platform:process.platform});import{stat as wn}from"fs/promises";var k=["push","pr-draft","pr-reply"];function kr(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function fn(e){if(!Array.isArray(e))return null;let r=e.flatMap((t)=>{let n=k.find((o)=>o===t);return n?[n]:[]});return r.length===e.length?r:null}function Sr(e){if(e===void 0)return{};if(!kr(e))throw Error("Config repo settings must be tables");let r={};for(let[t,n]of Object.entries(e)){if(!kr(n))throw Error("Every repo policy must be a table");let o=fn(n.allow);if(o===null||typeof n.maxBudgetUsd!=="number"||n.maxBudgetUsd<=0||typeof n.requireCleanExit!=="boolean"||Object.keys(n).some((i)=>i!=="allow"&&i!=="maxBudgetUsd"&&i!=="requireCleanExit"))throw Error("Every repo policy must contain valid action settings");r[t]={allow:o,maxBudgetUsd:n.maxBudgetUsd,requireCleanExit:n.requireCleanExit}}return r}function Ir(e){return Object.entries(e).sort(([r],[t])=>r.localeCompare(t)).flatMap(([r,t])=>["",`[repo.${JSON.stringify(r)}]`,`allow = [${t.allow.map((n)=>JSON.stringify(n)).join(", ")}]`,`maxBudgetUsd = ${t.maxBudgetUsd}`,`requireCleanExit = ${t.requireCleanExit}`])}var E=["antigravity","claude-code","claude-prompts","codex","cursor","git-metadata","shell"],mn=E.filter((e)=>e!=="antigravity"),yn=E.filter((e)=>e!=="antigravity"&&e!=="git-metadata"),T={schemaVersion:1,sources:{antigravity:!1,"claude-code":!1,"claude-prompts":!1,codex:!1,cursor:!1,"git-metadata":!1,shell:!1},distillation:{deep:!1},repo:{}};function Be(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function F(e){let r=Object.keys(e.record),t=new Set(e.keys);return r.length===e.keys.length&&r.every((n)=>t.has(n))}function gn(e){if(!Be(e)||!F({record:e,keys:E})&&!F({record:e,keys:mn})&&!F({record:e,keys:yn}))throw Error("Config sources must contain every supported source and no unknown sources");let r=e.antigravity??!1,t=e["claude-code"],n=e["claude-prompts"],{codex:o,cursor:i}=e,s=e["git-metadata"]??!1,a=e.shell;if(typeof r!=="boolean"||typeof t!=="boolean"||typeof n!=="boolean"||typeof o!=="boolean"||typeof i!=="boolean"||typeof s!=="boolean"||typeof a!=="boolean")throw Error("Every config source setting must be a boolean");return{antigravity:r,"claude-code":t,"claude-prompts":n,codex:o,cursor:i,"git-metadata":s,shell:a}}function hn(e){if(!Be(e)||!F({record:e,keys:["deep"]}))throw Error("Config distillation must contain only the deep setting");if(typeof e.deep!=="boolean")throw Error("Config distillation.deep must be a boolean");return{deep:e.deep}}function Ar(e){let r=["schema-version","sources","distillation"],t=[...r,"repo"];if(!Be(e)||!F({record:e,keys:r})&&!F({record:e,keys:t}))throw Error("Config must contain only supported top-level settings");if(e["schema-version"]!==1)throw Error("Config schema-version must be 1");return{schemaVersion:1,sources:gn(e.sources),distillation:hn(e.distillation),repo:Sr(e.repo)}}var Tr=["claude-code","codex","cursor-agent","antigravity","anthropic-api","openai-compatible"],_e={enabled:!0,allowedSources:E,allowedEngines:Tr,distillation:"allowed",originScope:"strict",blockedOrigins:[],maxActionTier:"act"};function bn(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Fe(e){return Array.isArray(e)&&e.every((r)=>typeof r==="string")?e:null}function xn(e){let r=Fe(e);if(r===null)return null;let t=r.flatMap((n)=>{let o=E.find((i)=>i===n);return o?[o]:[]});return t.length===r.length?t:null}function Rn(e){let r=Fe(e);if(r===null)return null;let t=r.flatMap((n)=>{let o=Tr.find((i)=>i===n);return o?[o]:[]});return t.length===r.length?t:null}function Dr(e){if(!bn(e))throw Error("Managed policy must be a JSON object");let r=xn(e.allowedSources),t=Rn(e.allowedEngines),n=Fe(e.blockedOrigins),{distillation:o,maxActionTier:i}=e;if(typeof e.enabled!=="boolean"||r===null||t===null||n===null||o!=="allowed"&&o!=="local-only"&&o!=="disabled"||e.originScope!=="strict"||i!=="observe"&&i!=="draft"&&i!=="act")throw Error("Managed policy has invalid or missing fields");return{enabled:e.enabled,allowedSources:r,allowedEngines:t,distillation:o,originScope:"strict",blockedOrigins:n,maxActionTier:i}}function je(e){let r=(t)=>e.policy.enabled&&e.policy.allowedSources.includes(t);return{...e.config,sources:{antigravity:e.config.sources.antigravity&&r("antigravity"),"claude-code":e.config.sources["claude-code"]&&r("claude-code"),"claude-prompts":e.config.sources["claude-prompts"]&&r("claude-prompts"),codex:e.config.sources.codex&&r("codex"),cursor:e.config.sources.cursor&&r("cursor"),"git-metadata":e.config.sources["git-metadata"]&&r("git-metadata"),shell:e.config.sources.shell&&r("shell")},distillation:{deep:e.config.distillation.deep&&e.policy.enabled&&e.policy.distillation!=="disabled"}}}async function L(e){if(e===null)return _e;let r=Bun.file(e);if(!await r.exists())return _e;if((await wn(e)).uid!==0)throw Error("Managed policy must be owned by root");let n=await r.json();return Dr(n)}async function En(e={}){let r=e.configPath??h.configFile,t=Bun.file(r);if(!await t.exists())return T;let n=Bun.TOML.parse(await t.text());return Ar(n)}async function v(e={}){let r=await L(e.managedConfigPath===void 0?h.managedConfigFile:e.managedConfigPath),t=r.enabled?await En({configPath:e.configPath}):T;return{config:je({config:t,policy:r}),policy:r}}function Cn(e){let r=E.map((t)=>`${t} = ${e.sources[t]}`);return[`schema-version = ${e.schemaVersion}`,"","[sources]",...r,"","[distillation]",`deep = ${e.distillation.deep}`,...Ir(e.repo),""].join(`
9
- `)}async function Me(e){let r=e.configPath??h.configFile;await Pn(vn.dirname(r),{recursive:!0}),await Bun.write(r,Cn(e.config))}function Ne(e){return{...e.config,sources:{...e.config.sources,[e.source]:e.enabled}}}function Or(e){return{...e.config,distillation:{deep:e.enabled}}}function kn(){return te.map((e)=>{let r=ne(e);return`${e.id}: observe=${r.observe?"yes":"no"}, distill=${r.distill?"yes":"no"}, dispatch=${r.dispatch?"yes":"no"}`})}function Sn(e){if(e.distillation==="disabled")return"Deep distillation is disabled by managed policy.";if(e.distillation==="local-only")return"Deep distillation is restricted to local engines, which are not implemented.";return e.selectedEngine?`Selected engine: ${e.selectedEngine}`:"No authenticated distillation engine is available."}async function Br(e={}){let r=e.managedConfigPath===void 0?h.managedConfigFile:e.managedConfigPath,t=await L(r);if(r!==null&&await Bun.file(r).exists())console.log(`Managed policy: ${r}`);if(!t.enabled){console.log("Managed policy: shadowclone is disabled.");return}let n=t.distillation==="allowed"?t.allowedEngines:[],o=await A({purpose:"distill",probe:e.probe,allowedEngines:n});for(let i of o.availability){let s=i.authenticated?"authenticated":i.installed?"installed, authentication not found":"not installed";console.log(`${i.engine}: ${s}`)}console.log(Sn({distillation:t.distillation,selectedEngine:o.selectedEngine})),console.log("Provider support:");for(let i of kn())console.log(i)}import{rm as In}from"fs/promises";async function _r(e=h.shadowcloneDirectory){await In(e,{recursive:!0,force:!0}),console.log("Removed all shadowclone data.")}import Kn from"path";import{mkdir as An}from"fs/promises";import Fr from"path";function jr(e){let r=e.name??"shadowclone";if(!/^[a-z0-9-]+$/.test(r))throw Error("Agent name must use lowercase letters, numbers, and hyphens");return["---",`name: ${r}`,"description: A copy of the user that follows their learned engineering profile","model: inherit","tools: Read, Grep, Glob, Bash, Edit, Write","---","",e.profile.trim(),""].join(`
10
- `)}async function $e(e){let r=e.name??"shadowclone",t=Fr.join(e.targetDirectory,".claude","agents"),n=Fr.join(t,`${r}.md`);return await An(t,{recursive:!0}),await Bun.write(n,jr(e)),n}import{mkdir as Dn}from"fs/promises";import ae from"path";function ie(e){return new Bun.CryptoHasher("sha256").update(e).digest("hex").slice(0,16)}function U(e){return new Bun.CryptoHasher("sha256").update(`semantic:${e.toLowerCase()}`).digest("hex").slice(0,16)}function Le(e){return e.scope==="global"?`global/${e.section}.md`:`org/${e.originDirectory??"isolated"}/${e.section}.md`}function se(e){let r=`## ${e.title}
10
+ ${e.body}`,r=[`key=${e.key}`,`observations=${e.observations}`,`confidence=${e.confidence.toFixed(2)}`,`last-seen=${e.lastSeen}`,`sessions=${e.sessions}`,`origins=${e.origins.join(",")}`,`scope=${e.scope}`,`fingerprint=${we(t)}`].join(" ");return`${t}
11
11
 
12
- ${e.body}`,t=[`key=${e.key}`,`observations=${e.observations}`,`confidence=${e.confidence.toFixed(2)}`,`last-seen=${e.lastSeen}`,`sessions=${e.sessions}`,`origins=${e.origins.join(",")}`,`scope=${e.scope}`,`fingerprint=${ie(r)}`].join(" ");return`${r}
13
-
14
- <!-- shadowclone: ${t} -->`}function Mr(e){let r=e.metadata.split(/\s+/),t=`${e.name}=`;return r.find((o)=>o.startsWith(t))?.slice(t.length)??null}function Tn(e){let r=e.match(/\n\n<!-- shadowclone: ([^\n]+) -->\s*$/),t=r?.[1];if(!t||r.index===void 0)return{key:null,content:e.trim(),edited:!0};let n=Mr({metadata:t,name:"key"}),o=Mr({metadata:t,name:"fingerprint"});if(n===null||o===null)return{key:null,content:e.trim(),edited:!0};let i=e.slice(0,r.index).trim(),[s]=i.split(`
15
- `);return{key:n,title:s?.replace(/^#+\s*/,"").trim()??"",fingerprint:o,content:e.trim(),edited:ie(i)!==o}}function q(e){return e.trim().split(/\n(?=## )/).filter((r)=>r.trim().length>0).map(Tn)}function Nr(e){let r=e.content.match(new RegExp(`\\b${e.name}=([\\d.]+)`)),t=r?.[1]?Number(r[1]):Number.NaN;return Number.isFinite(t)?t:e.fallback}function On(e){let r=!e.includes("<!-- shadowclone:");return{content:e.replace(/\n\n<!-- shadowclone: [^\n]+ -->\s*$/,"").trim(),observations:Nr({content:e,name:"observations",fallback:r?Number.MAX_SAFE_INTEGER:0}),confidence:Nr({content:e,name:"confidence",fallback:r?1:0})}}async function Bn(e){let r=[],t=new Bun.Glob("**/*.md");try{for await(let n of t.scan({cwd:e,absolute:!0,onlyFiles:!0}))r.push(n)}catch{return[]}return r.sort()}function _n(e){let r=e.filePath.split(ae.sep).join("/");if(!r.includes("/projects/"))return!0;return e.targetRepo!==null&&r.endsWith(`/projects/${e.targetRepo}.md`)}async function le(e){let r=[ae.join(e.profileDirectory,"global"),ae.join(e.profileDirectory,"org",e.origin.directoryName)],t=(await Promise.all(r.map(Bn))).flat(),n=[];for(let s of t){if(!_n({filePath:s,targetRepo:e.targetRepo??null}))continue;let a=await Bun.file(s).text();n.push(...q(a).map((d)=>On(d.content)))}let o=e.confidenceThreshold??0,i=n.filter((s)=>s.confidence>=o).sort((s,a)=>a.observations-s.observations||s.content.localeCompare(a.content));return i.length===0?`# Shadowclone profile
12
+ <!-- shadowclone: ${r} -->`}function er(e){let t=e.metadata.split(/\s+/),r=`${e.name}=`;return t.find((o)=>o.startsWith(r))?.slice(r.length)??null}function co(e){let t=e.match(/\n\n<!-- shadowclone: ([^\n]+) -->\s*$/),r=t?.[1];if(!r||t.index===void 0)return{key:null,content:e.trim(),edited:!0};let n=er({metadata:r,name:"key"}),o=er({metadata:r,name:"fingerprint"});if(n===null||o===null)return{key:null,content:e.trim(),edited:!0};let s=e.slice(0,t.index).trim(),[i]=s.split(`
13
+ `);return{key:n,title:i?.replace(/^#+\s*/,"").trim()??"",fingerprint:o,content:e.trim(),edited:we(s)!==o}}function oe(e){return e.trim().split(/\n(?=## )/).filter((t)=>t.trim().length>0).map(co)}function tr(e){let t=e.content.match(new RegExp(`\\b${e.name}=([\\d.]+)`)),r=t?.[1]?Number(t[1]):Number.NaN;return Number.isFinite(r)?r:e.fallback}function po(e){let t=!e.includes("<!-- shadowclone:");return{content:e.replace(/\n\n<!-- shadowclone: [^\n]+ -->\s*$/,"").trim(),observations:tr({content:e,name:"observations",fallback:t?Number.MAX_SAFE_INTEGER:0}),confidence:tr({content:e,name:"confidence",fallback:t?1:0})}}async function fo(e){let t=[],r=new Bun.Glob("**/*.md");try{for await(let n of r.scan({cwd:e,absolute:!0,onlyFiles:!0}))t.push(n)}catch{return[]}return t.sort()}function mo(e){let t=e.filePath.split(be.sep).join("/");if(!t.includes("/projects/"))return!0;return e.targetRepo!==null&&t.endsWith(`/projects/${e.targetRepo}.md`)}async function X(e){let t=[be.join(e.profileDirectory,"global"),be.join(e.profileDirectory,"org",e.origin.directoryName)],r=(await Promise.all(t.map(fo))).flat(),n=[];for(let i of r){if(!mo({filePath:i,targetRepo:e.targetRepo??null}))continue;let a=await Bun.file(i).text();n.push(...oe(a).map((l)=>po(l.content)))}let o=e.confidenceThreshold??0,s=n.filter((i)=>i.confidence>=o).sort((i,a)=>a.observations-i.observations||i.content.localeCompare(a.content));return s.length===0?`# Shadowclone profile
16
14
  `:`# Shadowclone profile
17
15
 
18
- ${i.map((s)=>s.content).join(`
16
+ ${s.map((i)=>i.content).join(`
19
17
 
20
18
  `)}
21
- `}async function z(e){let r=await le(e);return await Dn(ae.dirname(e.outputPath),{recursive:!0}),await Bun.write(e.outputPath,r),r}function D(e,r){let t=Math.max(3,48-e.length);return` ${e} ${".".repeat(t)} ${r}`}function $r(e){return D(e.label,`${e.count} of ${e.total}`)}function Ue(e){let r=e.report,t=(r.corpus.bytes/1048576).toFixed(1),n=r.interruptions.length>0?r.interruptions.slice(0,5).map((s)=>D(s.label,s.count)):[D("no interruptions indexed",0)],o=r.denials.length>0?r.denials.slice(0,5).map((s)=>D(s.label,s.count)):[D("no tool refusals indexed",0)],i=r.structural.toolUses.length>0?r.structural.toolUses.slice(0,5).map((s)=>D(s.label,s.count)):[D("no tool calls indexed",0)];return[` Read ${r.corpus.sessions} sessions, ${t} MB, ${r.corpus.activeDays} active days.${e.networkCallsMade?"":" No network calls were made."}`,""," You stop the agent most often",...n,"",` You have refused tools ${r.denials.reduce((s,a)=>s+a.count,0)} times`,...o,""," When the agent asked, you answered",$r({label:"agent questions",count:r.answeredQuestions,total:r.askedQuestions}),$r({label:"presented plans",count:r.resolvedPlans,total:r.presentedPlans}),""," Your most used agent tools",...i,""," Profile written to ~/.shadowclone/profile/. Open it. Argue with it."].join(`
22
- `)}function Fn(e){return new Bun.CryptoHasher("sha256").update(e).digest("hex").slice(0,16)}function jn(e){if(e.kind==="interruption")return{title:`Stops the agent ${e.label}`,body:`Pause and reassess when work reaches this pattern: ${e.label}.`,section:"workflow"};if(e.kind==="permission-denied")return{title:`Requests confirmation after refusing ${e.label}`,body:`A \`${e.label}\` request was refused. Ask before repeating a similar action, but do not treat the whole tool family as blocked.`,section:"boundaries"};if(e.kind==="question-answered")return{title:"Answers agent questions before work continues",body:"Ask a focused question when a consequential choice is unresolved.",section:"workflow"};return{title:"Reviews presented plans",body:"Present the plan and wait for its resolution before implementation.",section:"workflow"}}function Mn(e){let r=Map.groupBy(e,(t)=>`${t.origin.id}:${t.kind}`);return e.map((t)=>{let n=jn(t);return{key:Fn(`${t.kind}:${t.category}`),...n,origin:t.origin,timestamp:t.timestamp,sessionId:t.sessionId,opportunities:r.get(`${t.origin.id}:${t.kind}`)?.length??1}})}function Lr(e){let[r]=e.observations;if(!r)throw Error("Cannot aggregate an empty rule");let t=new Set(e.observations.map((s)=>s.sessionId)),n=[...new Set(e.observations.map((s)=>s.origin.id))].sort(),o=Math.max(...e.observations.map((s)=>s.timestamp)),i=Math.max(...e.observations.map((s)=>s.opportunities));return{key:r.key,title:r.title,body:r.body,section:r.section,scope:e.scope,originDirectory:e.scope==="org"?r.origin.directoryName:null,observations:e.observations.length,confidence:Math.min(1,e.observations.length/i),lastSeen:o>0?new Date(o).toISOString().slice(0,10):"unknown",sessions:t.size,origins:n}}function G(e){let r=Mn(e.signals),t=[];for(let n of Map.groupBy(r,(o)=>o.key).values()){let o=new Set(n.filter((s)=>s.origin.promotable).map((s)=>s.origin.id));if(o.size>=2)t.push(Lr({observations:n.filter((s)=>s.origin.promotable),scope:"global"}));let i=Map.groupBy(n.filter((s)=>!s.origin.promotable||o.size<2),(s)=>s.origin.id);for(let s of i.values())t.push(Lr({observations:s,scope:"org"}))}return t.sort((n,o)=>o.observations-n.observations||n.title.localeCompare(o.title))}import{mkdir as Ur,rm as Nn}from"fs/promises";import qr from"path";async function qe(e){let r=Bun.file(e);if(!await r.exists())return[];return(await r.text()).split(`
23
- `).flatMap((t)=>{let[n,o]=t.split("\t");return n&&o?[{relativePath:n,key:o}]:[]})}function ze(e){return`${e.slice().sort((r,t)=>r.relativePath.localeCompare(t.relativePath)||r.key.localeCompare(t.key)).map((r)=>`${r.relativePath} ${r.key}`).join(`
19
+ `}async function L(e){let t=await X(e);return await uo(be.dirname(e.outputPath),{recursive:!0}),await Bun.write(e.outputPath,t),t}function U(e,t){let r=Math.max(3,48-e.length);return` ${e} ${".".repeat(r)} ${t}`}function rr(e){return U(e.label,`${e.count} of ${e.total}`)}function xe(e){let t=e.report,r=(t.corpus.bytes/1048576).toFixed(1),n=t.interruptions.length>0?t.interruptions.slice(0,5).map((i)=>U(i.label,i.count)):[U("no interruptions indexed",0)],o=t.denials.length>0?t.denials.slice(0,5).map((i)=>U(i.label,i.count)):[U("no tool refusals indexed",0)],s=t.structural.toolUses.length>0?t.structural.toolUses.slice(0,5).map((i)=>U(i.label,i.count)):[U("no tool calls indexed",0)];return[` Read ${t.corpus.sessions} sessions, ${r} MB, ${t.corpus.activeDays} active days.${e.networkCallsMade?"":" No network calls were made."}`,""," You stop the agent most often",...n,"",` You have refused tools ${t.denials.reduce((i,a)=>i+a.count,0)} times`,...o,""," When the agent asked, you answered",rr({label:"agent questions",count:t.answeredQuestions,total:t.askedQuestions}),rr({label:"presented plans",count:t.resolvedPlans,total:t.presentedPlans}),""," Your most used agent tools",...s,""," Profile written to ~/.shadowclone/profile/. Open it. Argue with it."].join(`
20
+ `)}function go(e){return new Bun.CryptoHasher("sha256").update(e).digest("hex").slice(0,16)}function yo(e){if(e.kind==="interruption")return{title:`Stops the agent ${e.label}`,body:`Pause and reassess when work reaches this pattern: ${e.label}.`,section:"workflow"};if(e.kind==="permission-denied")return{title:`Requests confirmation after refusing ${e.label}`,body:`A \`${e.label}\` request was refused. Ask before repeating a similar action, but do not treat the whole tool family as blocked.`,section:"boundaries"};if(e.kind==="question-answered")return{title:"Answers agent questions before work continues",body:"Ask a focused question when a consequential choice is unresolved.",section:"workflow"};return{title:"Reviews presented plans",body:"Present the plan and wait for its resolution before implementation.",section:"workflow"}}function ho(e){let t=Map.groupBy(e,(r)=>`${r.origin.id}:${r.kind}`);return e.map((r)=>{let n=yo(r);return{key:go(`${r.kind}:${r.category}`),...n,origin:r.origin,timestamp:r.timestamp,sessionId:r.sessionId,opportunities:t.get(`${r.origin.id}:${r.kind}`)?.length??1}})}function nr(e){let[t]=e.observations;if(!t)throw Error("Cannot aggregate an empty rule");let r=new Set(e.observations.map((i)=>i.sessionId)),n=[...new Set(e.observations.map((i)=>i.origin.id))].sort(),o=Math.max(...e.observations.map((i)=>i.timestamp)),s=Math.max(...e.observations.map((i)=>i.opportunities));return{key:t.key,title:t.title,body:t.body,section:t.section,scope:e.scope,originDirectory:e.scope==="org"?t.origin.directoryName:null,observations:e.observations.length,confidence:Math.min(1,e.observations.length/s),lastSeen:o>0?new Date(o).toISOString().slice(0,10):"unknown",sessions:r.size,origins:n}}function ie(e){let t=ho(e.signals),r=[];for(let n of Map.groupBy(t,(o)=>o.key).values()){let o=new Set(n.filter((i)=>i.origin.promotable).map((i)=>i.origin.id));if(o.size>=2)r.push(nr({observations:n.filter((i)=>i.origin.promotable),scope:"global"}));let s=Map.groupBy(n.filter((i)=>!i.origin.promotable||o.size<2),(i)=>i.origin.id);for(let i of s.values())r.push(nr({observations:i,scope:"org"}))}return r.sort((n,o)=>o.observations-n.observations||n.title.localeCompare(o.title))}import{mkdir as or,rm as wo}from"fs/promises";import ir from"path";async function et(e){let t=Bun.file(e);if(!await t.exists())return[];return(await t.text()).split(`
21
+ `).flatMap((r)=>{let[n,o]=r.split("\t");return n&&o?[{relativePath:n,key:o}]:[]})}function tt(e){return`${e.slice().sort((t,r)=>t.relativePath.localeCompare(r.relativePath)||t.key.localeCompare(r.key)).map((t)=>`${t.relativePath} ${t.key}`).join(`
24
22
  `)}
25
- `}function $n(e){return U(e.title)===e.key}function Ln(e){return Map.groupBy(e,Le)}async function Un(e){let r=Bun.file(e);return await r.exists()?q(await r.text()):[]}function Ge(e){return`${e.relativePath} ${e.key}`}async function J(e){await Ur(e.paths.profileDirectory,{recursive:!0});let r=await qe(e.paths.profileManifestFile),t=await qe(e.paths.rejectedProfileFile),n=new Map(t.map((p)=>[Ge(p),p])),o=Ln(e.rules),i=r.map((p)=>p.relativePath),s=new Set([...o.keys(),...i]),a=[],d=0,u=0;for(let p of s){let b=qr.join(e.paths.profileDirectory,p),y=await Un(b),I=new Map(y.flatMap((c)=>c.key===null?[]:[[c.key,c]])),R=o.get(p)??[],f=[];for(let c of r.filter((w)=>w.relativePath===p))if(R.some((w)=>w.key===c.key)&&!I.has(c.key))n.set(Ge(c),c);for(let c of y){if(c.key===null){f.push(c.content);continue}let w=R.find((Y)=>Y.key===c.key);if(!w&&!c.edited&&!$n(c))continue;f.push(w&&!c.edited?se(w):c.content),a.push({relativePath:p,key:c.key})}for(let c of R){let w={relativePath:p,key:c.key};if(!I.has(c.key)&&!n.has(Ge(w)))f.push(se(c)),a.push(w)}if(f.length>0){await Ur(qr.dirname(b),{recursive:!0}),await Bun.write(b,`${f.join(`
23
+ `}function bo(e){return N(e.title)===e.key}function xo(e){if(e.isUpdated||e.existingRule.edited)return!1;let t=bo(e.existingRule);if(e.generator==="all")return!0;if(e.generator==="structural")return!t;return t}function Ro(e){if(e.generator)return e.generator;let t=e.rules.some((n)=>N(n.title)===n.key),r=e.rules.some((n)=>N(n.title)!==n.key);if(t&&r)return"all";return t?"distilled":"structural"}var Po=(e)=>Map.groupBy(e,Qe);async function vo(e){let t=Bun.file(e);return await t.exists()?oe(await t.text()):[]}var rt=(e)=>`${e.relativePath} ${e.key}`;async function se(e){await or(e.paths.profileDirectory,{recursive:!0});let t=Ro({generator:e.generator,rules:e.rules}),r=await et(e.paths.profileManifestFile),n=await et(e.paths.rejectedProfileFile),o=new Map(n.map((p)=>[rt(p),p])),s=Po(e.rules),i=r.map((p)=>p.relativePath),a=new Set([...s.keys(),...i]),l=[],d=0,u=0;for(let p of a){let m=ir.join(e.paths.profileDirectory,p),g=await vo(m),R=new Map(g.flatMap((f)=>f.key===null?[]:[[f.key,f]])),P=s.get(p)??[],x=[];for(let f of r.filter((w)=>w.relativePath===p))if(P.some((w)=>w.key===f.key)&&!R.has(f.key))o.set(rt(f),f);for(let f of g){if(f.key===null){x.push(f.content);continue}let w=P.find((b)=>b.key===f.key);if(xo({existingRule:f,isUpdated:w!==void 0,generator:t}))continue;x.push(w&&!f.edited?ne(w):f.content),l.push({relativePath:p,key:f.key})}for(let f of P){let w={relativePath:p,key:f.key};if(!R.has(f.key)&&!o.has(rt(w)))R.set(f.key,{key:f.key,title:f.title,fingerprint:"",content:ne(f),edited:!1}),x.push(ne(f)),l.push(w)}if(x.length>0){await or(ir.dirname(m),{recursive:!0}),await Bun.write(m,`${x.join(`
26
24
 
27
25
  `)}
28
- `),d+=1,u+=f.length;continue}if(y.length>0)await Nn(b,{force:!0})}return await Bun.write(e.paths.profileManifestFile,ze(a)),await Bun.write(e.paths.rejectedProfileFile,ze([...n.values()])),{files:d,rules:u,rejected:n.size}}import qn from"path";function Je(e){let r=new Bun.CryptoHasher("sha256").update(e).digest("hex").slice(0,16);return{id:`isolated:${r}`,directoryName:`isolated--${r}`,promotable:!1}}function zr(e){let r=e.trim(),t=r.match(/^(?:[^@]+@)?([^/:]+):([^/]+)\/(.+)$/);if(t){let[,n,o,i]=t;return n&&o&&i?{host:n,owner:o,repository:i.replace(/\.git$/,"")}:null}try{let n=new URL(r),[o,i]=n.pathname.split("/").filter(Boolean);return o&&i?{host:n.hostname,owner:decodeURIComponent(o),repository:decodeURIComponent(i).replace(/\.git$/,"")}:null}catch{return null}}function Ke(e){let r=zr(e);if(r===null)return null;let t=r.host.toLowerCase(),n=r.owner.toLowerCase(),o=`${t}/${n}`,i=o.replace(/[^a-z0-9._-]+/g,"--");return{id:o,directoryName:i,promotable:!0}}function Gr(e){let r=zr(e),t=Ke(e);if(r===null||t===null)return null;return{id:`${t.id}/${r.repository.toLowerCase()}`,origin:t}}function zn(e,r){let t=r.split("*").map((n)=>n.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${t}$`).test(e)}function C(e){let r=e.cwd?qn.basename(e.cwd):null,t=[e.origin.id,...r?[`${e.origin.id}/${r}`]:[]];return e.patterns.some((n)=>t.some((o)=>zn(o,n)))}async function de(e){let r=Bun.spawn({cmd:["git","-C",e,"config","--local","--get","remote.origin.url"],stdout:"pipe",stderr:"ignore"}),[t,n]=await Promise.all([r.exited,new Response(r.stdout).text()]),o=n.trim();return t===0&&o.length>0?o:null}function He(e){return e.cwd.length>0?e.cwd:`${e.source}:${e.sessionId}`}async function We(e){let r=new Map,t=e.readRemote??de;for(let n of e.events){let o=He(n);if(r.has(o))continue;r.set(o,await O({cwd:n.cwd,fallbackKey:o,enabled:e.enabled,readRemote:t}))}return r}async function O(e){let r=e.cwd||e.fallbackKey||"unknown",t=e.readRemote??de,n=e.enabled&&e.cwd.length>0?await t(e.cwd):null;return n===null?Je(r):Ke(n)??Je(r)}async function Xe(e){let r=e.readRemote??de,t=e.enabled&&e.cwd.length>0?await r(e.cwd):null,n=t?Gr(t):null;if(n!==null)return n;let o=await O({cwd:e.cwd,enabled:!1});return{id:o.id,origin:o}}function H(e){return e.origins.get(He(e.event))??Je(He(e.event))}function Jr(e){for(let r=e.length-1;r>=0;r-=1){let t=e[r];if(t&&(t.kind==="tool-call"||t.kind==="plan-presented"||t.kind==="question-asked"||t.kind==="assistant-text"))return t}return null}function Gn(e){if(e?.tool)return{category:`tool:${e.tool.name}`,label:`while using ${e.tool.name}`};if(e?.kind==="plan-presented")return{category:"after-plan",label:"after presenting a plan"};if(e?.kind==="assistant-text")return{category:"assistant-text",label:"during an explanation"};return{category:"other",label:"before finishing a response"}}function ce(e){let r=[e.relatedEvent?.textRef,e.event.textRef].filter((t)=>t!==null&&t!==void 0);return{kind:e.kind,category:e.category,label:e.label,sessionId:e.event.sessionId,timestamp:e.event.timestamp,origin:e.origin,textRefs:r}}function Jn(e){let r=[],t=[],n=null,o=null;for(let i of e.events){let s=H({event:i,origins:e.origins});if(i.kind==="interruption"){let a=Jr(t),d=Gn(a);r.push(ce({kind:"interruption",...d,event:i,origin:s,relatedEvent:a}))}if(i.kind==="permission-denied"){let a=Jr(t),d=a?.tool?.name??"an unspecified tool";r.push(ce({kind:"permission-denied",category:`tool:${d}`,label:d,event:i,origin:s,relatedEvent:a}))}if(i.kind==="question-asked")n=i;if(i.kind==="plan-presented")o=i;if(i.kind==="user-prompt"||i.kind==="question-answered"){if(n!==null||i.kind==="question-answered")r.push(ce({kind:"question-answered",category:"agent-question",label:"an agent question",event:i,origin:s,relatedEvent:n})),n=null}if(i.kind==="user-prompt"||i.kind==="plan-resolved"){if(o!==null||i.kind==="plan-resolved")r.push(ce({kind:"plan-resolved",category:"presented-plan",label:"a presented plan",event:i,origin:s,relatedEvent:o})),o=null}t.push(i)}return r}function Hr(e){return[...Map.groupBy(e.events,(t)=>`${t.source}:${t.sessionId}`).values()].flatMap((t)=>Jn({events:t,origins:e.origins}))}function Kr(e){let r=new Map;for(let t of e){let n=r.get(t.category);r.set(t.category,{...t,count:(n?.count??0)+1})}return[...r.values()].sort((t,n)=>n.count-t.count||t.label.localeCompare(n.label))}function Ze(e){return Kr(e)}function Wr(e){let r=new Set(e.map((o)=>`${o.source}:${o.sessionId}`)),t=new Set(e.filter((o)=>o.kind==="plan-presented").map((o)=>`${o.source}:${o.sessionId}`));return{toolUses:Kr(e.flatMap((o)=>o.tool?[{category:o.tool.name,label:o.tool.name}]:[])),planSessions:t.size,totalSessions:r.size}}function Xr(e,r){return e.filter((t)=>t.kind===r).length}async function ue(e){let r=await We({events:e.events,enabled:e.gitMetadataEnabled,readRemote:e.readRemote}),t=e.events.filter((s)=>!C({origin:H({event:s,origins:r}),cwd:s.cwd,patterns:e.blockedOrigins??[]})),n=Hr({events:t,origins:r}),o=n.filter((s)=>s.kind==="interruption"),i=n.filter((s)=>s.kind==="permission-denied");return{corrections:n,events:t,origins:r,report:{corpus:e.corpus,interruptions:Ze(o),denials:Ze(i),answeredQuestions:n.filter((s)=>s.kind==="question-answered").length,askedQuestions:Xr(t,"question-asked"),resolvedPlans:n.filter((s)=>s.kind==="plan-resolved").length,presentedPlans:Xr(t,"plan-presented"),structural:Wr(t)}}}function Hn(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function pe(e){let r=JSON.parse(e);if(!Hn(r))throw Error("Hook input must be a JSON object");return r}function fe(e,r){let t=e[r];return typeof t==="string"?t:null}async function Wn(e){let r=e.paths??h,{config:t,policy:n}=await v({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?r.managedConfigFile:e.managedConfigPath});if(!n.enabled)return null;let o=pe(e.input),i=fe(o,"cwd")??process.cwd(),s=await O({cwd:i,enabled:t.sources["git-metadata"],readRemote:e.readRemote});if(C({origin:s,cwd:i,patterns:n.blockedOrigins}))return null;return{profile:await le({profileDirectory:r.profileDirectory,origin:s,targetRepo:Kn.basename(i)})}}async function Zr(e){let r=await Wn(e);return r===null?null:{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:r.profile}}}async function Ve(e){let r=await Zr(e);if(r!==null)await Bun.stdout.write(`${JSON.stringify(r)}
29
- `)}import{realpath as St}from"fs/promises";import er from"path";import{Database as To}from"bun:sqlite";import{mkdir as Do}from"fs/promises";import Oo from"path";import{stat as Yn}from"fs/promises";import me from"path";import{stat as Xn}from"fs/promises";function Zn(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Vn(e){return Zn(e)&&e.code==="ENOENT"}async function Vr(e){let r=await Xn(e.sourcePath).catch((y)=>{if(Vn(y))return null;throw y});if(r===null)return null;let t=r.mtimeMs,n=e.cursor;if(n!==null&&n.byteSize===r.size&&n.modifiedAt===t)return{values:[],cursor:n,rescanned:!1,bytesRead:0};let i=n!==null&&(r.size<n.byteOffset||r.size===n.byteSize&&t!==n.modifiedAt),s=n===null||i?0:n.byteOffset,a=Bun.file(e.sourcePath),d=new Uint8Array(await a.slice(s,r.size).arrayBuffer()),u=[],p=0,b=0;for(let y=0;y<d.length;y+=1){if(d[y]!==10)continue;let R=y>p&&d[y-1]===13?y-1:y,f=R-p;if(f>0)u.push({ref:{type:"file",sourcePath:e.sourcePath,byteOffset:s+p,byteLength:f},bytes:d.slice(p,R)});p=y+1,b=p}return{values:u,cursor:{sourcePath:e.sourcePath,byteSize:r.size,modifiedAt:t,byteOffset:s+b},rescanned:i,bytesRead:d.length}}async function S(e){let r=await Vr(e);if(r===null)return null;let t=new TextDecoder,n=r.values.map((o)=>{let i;try{i=JSON.parse(t.decode(o.bytes))}catch{throw Error(`Transcript record is invalid at byte offset ${o.ref.byteOffset}`)}return{value:i,ref:o.ref}});return{...r,values:n}}async function Yr(e){let r=await Vr(e);if(r===null)return null;return{...r,values:r.values.map((t)=>t.ref)}}function m(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function l(e,r){let t=e[r];return typeof t==="string"?t:null}function B(e,r){return e[r]===!0}function _(e,r){let t=e[r];return m(t)?t:null}function x(e){if(typeof e==="number"&&Number.isFinite(e))return e<10000000000?e*1000:e;if(typeof e==="string"){let r=Date.parse(e);return Number.isNaN(r)?0:r}return 0}var Qn=new Set(["CODE_ACTION","GREP_SEARCH","LIST_DIRECTORY","MCP_TOOL","REPLACE_FILE_CONTENT","RUN_COMMAND","VIEW_FILE","WRITE_TO_FILE"]);function Qr(e){let r=e.tool_calls;if(!Array.isArray(r))return null;let t=r.find(m);if(!t)return null;return{toolUseId:l(t,"id")??l(t,"tool_call_id"),name:l(t,"name")??"unknown"}}function eo(e,r){return{toolUseId:l(e,"tool_call_id")??l(e,"call_id"),name:l(e,"tool_name")??r.toLowerCase()}}function ro(e){let r=l(e,"type");if(r==="USER_INPUT")return l(e,"content")===null?null:"user-prompt";if(r==="PLANNER_RESPONSE"){if(Qr(e))return"tool-call";if(e.thinking!==void 0)return"thinking";return l(e,"content")===null?"thinking":"assistant-text"}if(r==="CHECKPOINT")return"session-end";return r!==null&&Qn.has(r)?"tool-result":null}function to(e){return me.basename(me.dirname(me.dirname(me.dirname(e))))}function no(e){if(!m(e.value))return null;let r=ro(e.value),t=l(e.value,"type");if(r===null||t===null)return null;let n=e.value.step_index,o=r==="tool-call"?Qr(e.value):r==="tool-result"?eo(e.value,t):null,i=l(e.value,"status");return{source:"antigravity",sessionId:e.sessionId,eventId:`antigravity:${typeof n==="number"?n:e.ref.byteOffset}`,parentEventId:null,timestamp:x(e.value.created_at),cwd:l(e.value,"workspace")??"",gitBranch:l(e.value,"git_branch"),kind:r,tool:o,isError:i==="ERROR"||i==="CANCELED",textRef:r==="user-prompt"||r==="assistant-text"?e.ref:null}}async function et(e){let r=await S(e);if(r===null)return null;let t=to(e.sourcePath),n=null,o=r.values.flatMap((i)=>{let s=no({...i,sessionId:t});if(s===null)return[];let a={...s,parentEventId:n};return n=s.eventId,[a]});return{source:"antigravity",sourcePath:e.sourcePath,events:o,cursor:r.cursor,rescanned:r.rescanned,bytesRead:r.bytesRead}}async function rt(e){try{if(!(await Yn(e)).isDirectory())return[]}catch(n){if(m(n)&&n.code==="ENOENT")return[];throw n}let r=[],t="*/.system_generated/logs/transcript_full.jsonl";for await(let n of new Bun.Glob(t).scan({cwd:e,absolute:!0,dot:!0,onlyFiles:!0}))r.push(n);return r.sort()}import ot from"path";import tt from"path";function ye(e){let r=`${tt.basename(e.ref.sourcePath)}:${x(e.record.timestamp)}`;return{source:"claude-code",sessionId:l(e.record,"sessionId")??tt.basename(e.ref.sourcePath,".jsonl"),eventId:l(e.message,"id")??l(e.record,"uuid")??r,parentEventId:l(e.record,"parentUuid"),timestamp:x(e.record.timestamp),cwd:l(e.record,"cwd")??"",gitBranch:l(e.record,"gitBranch")}}function ge(e,r){if(typeof e==="string")return e.includes(r);if(!Array.isArray(e))return!1;return e.some((t)=>m(t)&&typeof t.content==="string"&&t.content.includes(r))}function oo(e){if(e.interrupted)return"interruption";if(e.denied)return"permission-denied";if(e.questionAnswered)return"question-answered";if(e.planResolved)return"plan-resolved";return e.plainPrompt?"user-prompt":"tool-result"}function nt(e){if(B(e.record,"isMeta"))return[];let r=ye(e),t=e.message.content,n=ge(t,"[Request interrupted by user"),o=ge(t,"user doesn't want to proceed with this tool use"),i=ge(t,"User has answered your questions"),s=ge(t,"The user has approved your plan"),a=typeof t==="string",d=oo({interrupted:n,denied:o,questionAnswered:i,planResolved:s,plainPrompt:a});return[{...r,kind:d,tool:null,isError:B(e.record,"is_error"),textRef:a&&!n&&!o?e.ref:null}]}function io(e){if(e==="ExitPlanMode")return"plan-presented";if(e==="AskUserQuestion")return"question-asked";return"tool-call"}function so(e){if(l(e,"type")!=="tool_use")return null;let r=l(e,"name");if(r===null)return null;return{toolUseId:l(e,"id"),name:r}}function ao(e){let r=e.content;return Array.isArray(r)?r:[r]}function lo(e){return e.blocks.length===1&&(l(e.block,"type")==="text"||e.kind==="question-asked"||e.kind==="plan-presented")?e.ref:null}function co(e){let r=ye(e),t=ao(e.message),n=[];for(let o of t){if(!m(o))continue;let i=l(o,"type"),s=so(o),a=s===null?i==="thinking"?"thinking":"assistant-text":io(s.name);n.push({...r,kind:a,tool:s,isError:!1,textRef:lo({blocks:t,block:o,ref:e.ref,kind:a})})}return n}function uo(e){if(!m(e.value))return[];let r=l(e.value,"type");if(r==="result"){let n=x(e.value.timestamp);return[{source:"claude-code",sessionId:l(e.value,"session_id")??l(e.value,"sessionId")??ot.basename(e.ref.sourcePath,".jsonl"),eventId:l(e.value,"uuid")??`result:${ot.basename(e.ref.sourcePath)}:${n}`,parentEventId:l(e.value,"parentUuid"),timestamp:n,cwd:l(e.value,"cwd")??"",gitBranch:l(e.value,"gitBranch"),kind:"session-end",tool:null,isError:B(e.value,"is_error"),textRef:null}]}let t=_(e.value,"message");if(t===null)return[];if(r==="assistant")return co({record:e.value,message:t,ref:e.ref});if(r==="user")return nt({record:e.value,message:t,ref:e.ref});return[]}async function he(e){let r=await S(e);if(r===null)return null;return{source:"claude-code",sourcePath:e.sourcePath,events:r.values.flatMap(uo),cursor:r.cursor,rescanned:r.rescanned,bytesRead:r.bytesRead}}async function it(e){let r=new Bun.Glob("**/*.jsonl"),t=[];for await(let n of r.scan({cwd:e,absolute:!0,onlyFiles:!0}))t.push(n);return t.sort()}import po from"path";function fo(e){if(!m(e.value))return null;if((l(e.value,"display")??l(e.value,"prompt"))===null)return null;let t=x(e.value.timestamp);return{source:"claude-prompts",sessionId:l(e.value,"sessionId")??"claude-prompts",eventId:l(e.value,"id")??`prompt:${t}:${e.ref.byteOffset}`,parentEventId:null,timestamp:t,cwd:l(e.value,"project")??"",gitBranch:null,kind:"user-prompt",tool:null,isError:!1,textRef:e.ref}}async function st(e){let r=await S(e);if(r===null)return null;let t=r.values.map(fo).filter((n)=>n!==null);return{source:"claude-prompts",sourcePath:po.resolve(e.sourcePath),events:t,cursor:r.cursor,rescanned:r.rescanned,bytesRead:r.bytesRead}}import mo from"path";function lt(e){return{sessionId:mo.basename(e,".jsonl"),cwd:"",gitBranch:null}}function at(e){if(!m(e.value)||l(e.value,"type")!=="session_meta")return null;let r=_(e.value,"payload");if(r===null)return null;let t=_(r,"git");return{sessionId:l(r,"id")??lt(e.sourcePath).sessionId,cwd:l(r,"cwd")??"",gitBranch:t?l(t,"branch"):null}}async function yo(e){let r=Bun.file(e).stream().getReader(),t=[],n=0;while(!0){let s=await r.read();if(s.done)break;let a=s.value.indexOf(10),d=a<0?s.value:s.value.slice(0,a);if(t.push(d),n+=d.byteLength,a>=0){await r.cancel();break}}let o=new Uint8Array(n),i=0;for(let s of t)o.set(s,i),i+=s.byteLength;try{return JSON.parse(new TextDecoder().decode(o))}catch{throw Error("Codex transcript has an invalid session header")}}async function dt(e){for(let t of e.values){let n=at({sourcePath:e.sourcePath,value:t.value});if(n!==null)return n}return at({sourcePath:e.sourcePath,value:await yo(e.sourcePath)})??lt(e.sourcePath)}function ut(e){let r=l(e,"type");if(r!=="function_call"&&r!=="custom_tool_call"&&r!=="local_shell_call")return null;return{toolUseId:l(e,"call_id")??l(e,"id"),name:l(e,"name")??(r==="local_shell_call"?"shell":"unknown")}}function go(e){let r=l(e,"type"),t=l(e,"role");if(r==="message"&&t==="user")return"user-prompt";if(r==="message"&&t==="assistant")return"assistant-text";if(r==="reasoning")return"thinking";if(r==="function_call_output"||r==="custom_tool_call_output"||r==="local_shell_call_output")return"tool-result";return ut(e)?"tool-call":null}function ct(e){return{source:"codex",sessionId:e.context.sessionId,eventId:`codex:${e.ref.byteOffset}`,parentEventId:null,timestamp:x(e.envelope.timestamp),cwd:e.context.cwd,gitBranch:e.context.gitBranch,kind:e.kind,tool:e.tool,isError:!1,textRef:e.kind==="user-prompt"||e.kind==="assistant-text"?e.ref:null}}function ho(e){if(!m(e.value))return null;let r=l(e.value,"type"),t=_(e.value,"payload");if(t===null)return null;if(r==="response_item"){let i=go(t);return i===null?null:ct({context:e.context,envelope:e.value,ref:e.ref,kind:i,tool:ut(t)})}let n=l(t,"type");if(r!=="event_msg"||n!=="task_complete"&&n!=="task_completed"&&n!=="turn_aborted")return null;let o=n==="turn_aborted"?"interruption":"session-end";return{...ct({context:e.context,envelope:e.value,ref:e.ref,kind:o,tool:null}),isError:B(t,"is_error")}}async function pt(e){let r=await S(e);if(r===null)return null;if(r.values.length===0)return{source:"codex",sourcePath:e.sourcePath,events:[],cursor:r.cursor,rescanned:r.rescanned,bytesRead:r.bytesRead};let t=await dt({sourcePath:e.sourcePath,values:r.values}),n=null,o=r.values.flatMap((i)=>{let s=ho({...i,context:t});if(s===null)return[];let a={...s,parentEventId:n};return n=s.eventId,[a]});return{source:"codex",sourcePath:e.sourcePath,events:o,cursor:r.cursor,rescanned:r.rescanned,bytesRead:r.bytesRead}}async function ft(e){let r=[];for await(let t of new Bun.Glob("**/rollout-*.jsonl").scan({cwd:e,absolute:!0,onlyFiles:!0}))r.push(t);return r.sort()}function wo(e){return{type:"sqlite-blob",sourcePath:e.context.sourcePath,blobId:e.blobId,jsonPath:e.jsonPath,unwrap:e.unwrap}}function bo(e){let r=l(e,"type");if(r!=="tool-call"&&r!=="tool_use"&&r!=="tool_call")return null;return{toolUseId:l(e,"toolCallId")??l(e,"tool_call_id")??l(e,"id"),name:l(e,"toolName")??l(e,"name")??"unknown"}}function we(e){return{source:"cursor",sessionId:e.context.sessionId,eventId:`cursor:${e.blobId}:${e.index}`,parentEventId:null,timestamp:e.context.timestamp+e.index,cwd:e.context.cwd,gitBranch:null,kind:e.kind,tool:e.tool,isError:!1,textRef:e.ref}}function mt(e){let r=e.role==="user"&&e.text.includes("<user_query>"),t=e.role==="assistant";if(!r&&!t)return null;return we({context:e.context,blobId:e.blobId,index:e.index,kind:r?"user-prompt":"assistant-text",tool:null,ref:wo({context:e.context,blobId:e.blobId,jsonPath:e.jsonPath,unwrap:r?"user-query":null})})}function yt(e){if(!m(e.blob.value))return[];let r=l(e.blob.value,"role");if(r==="tool")return[we({context:e.context,blobId:e.blob.id,index:0,kind:"tool-result",tool:null,ref:null})];let t=e.blob.value.content;if(typeof t==="string"){let n=mt({context:e.context,blobId:e.blob.id,index:0,role:r??"",text:t,jsonPath:["content"]});return n?[n]:[]}if(!Array.isArray(t))return[];return t.flatMap((n,o)=>{if(!m(n))return[];let i=l(n,"type");if(r==="assistant"&&i==="reasoning")return[we({context:e.context,blobId:e.blob.id,index:o,kind:"thinking",tool:null,ref:null})];let s=bo(n);if(s!==null)return[we({context:e.context,blobId:e.blob.id,index:o,kind:"tool-call",tool:s,ref:null})];let a=l(n,"text"),d=a?mt({context:e.context,blobId:e.blob.id,index:o,role:r??"",text:a,jsonPath:["content",o,"text"]}):null;return d?[d]:[]})}import{Database as xo}from"bun:sqlite";import{stat as Ro}from"fs/promises";import j from"path";async function Ye(e){try{let r=await Ro(e);return{size:r.size,modifiedAt:r.mtimeMs}}catch{return null}}function Po(e){let r=/^(?:[0-9a-fA-F]{2})+$/.test(e)?new TextDecoder().decode(Uint8Array.from(e.match(/.{2}/g)?.map((t)=>Number.parseInt(t,16))??[])):e;try{return JSON.parse(r)}catch{return null}}function vo(e){try{return JSON.parse(new TextDecoder().decode(e))}catch{return null}}async function Eo(e){let r=Bun.file(j.join(j.dirname(e),"meta.json"));if(!await r.exists())return null;try{return JSON.parse(await r.text())}catch{return null}}async function gt(e){let r=await Ye(e);if(r===null)return null;let[t,n]=await Promise.all([Ye(`${e}-wal`),Ye(j.join(j.dirname(e),"meta.json"))]),o=[r,t,n].filter((i)=>i!==null);return{size:o.reduce((i,s)=>i+s.size,0),modifiedAt:Math.max(...o.map((i)=>i.modifiedAt))}}async function ht(e){let r=null;try{r=new xo(e.sourcePath,{readonly:!0,strict:!0});let t=r.query("SELECT id, data FROM blobs ORDER BY rowid").all().flatMap((a)=>{let d=vo(a.data);return d===null?[]:[{id:a.id,value:d}]}),n=Po(r.query("SELECT value FROM meta WHERE key = '0'").get()?.value??""),o=await Eo(e.sourcePath),i=m(n)?n:{},s=m(o)?o:{};return{blobs:t,sessionId:l(i,"agentId")??j.basename(j.dirname(e.sourcePath)),cwd:l(s,"cwd")??"",timestamp:x(s.createdAtMs)||x(i.createdAt)||e.signature.modifiedAt,cursor:{sourcePath:e.sourcePath,byteSize:e.signature.size,modifiedAt:e.signature.modifiedAt,byteOffset:e.signature.size},bytesRead:e.signature.size}}catch{return console.warn(`cursor: skipped an unreadable store (${e.signature.size} bytes)`),null}finally{r?.close()}}async function wt(e){let r=await gt(e.sourcePath);if(r===null)return null;if(e.cursor!==null&&e.cursor.byteSize===r.size&&e.cursor.modifiedAt===r.modifiedAt)return{source:"cursor",sourcePath:e.sourcePath,events:[],cursor:e.cursor,rescanned:!1,bytesRead:0};let t=await ht({sourcePath:e.sourcePath,signature:r});if(t===null)return null;let n=[],o=null;for(let i of t.blobs)for(let s of yt({blob:i,context:{sourcePath:e.sourcePath,sessionId:t.sessionId,cwd:t.cwd,timestamp:t.timestamp+n.length}})){let a={...s,parentEventId:o};n.push(a),o=a.eventId}return{source:"cursor",sourcePath:e.sourcePath,events:n,cursor:t.cursor,rescanned:e.cursor!==null,bytesRead:t.bytesRead}}async function bt(e){let r=[];for await(let t of new Bun.Glob("**/store.db").scan({cwd:e,absolute:!0,onlyFiles:!0}))r.push(t);return r.sort()}import Co from"path";async function xt(e){let r=await Yr(e);if(r===null)return null;return{source:"shell",sourcePath:Co.resolve(e.sourcePath),events:r.values.map((t)=>({source:"shell",sessionId:"shell-history",eventId:`shell:${t.byteOffset}`,parentEventId:null,timestamp:r.cursor.modifiedAt,cwd:"",gitBranch:null,kind:"user-prompt",tool:null,isError:!1,textRef:t})),cursor:r.cursor,rescanned:r.rescanned,bytesRead:r.bytesRead}}function ko(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Qe(e){if(!ko(e)||typeof e.sourcePath!=="string")return null;if(e.type==="file"&&typeof e.byteOffset==="number"&&typeof e.byteLength==="number")return{type:"file",sourcePath:e.sourcePath,byteOffset:e.byteOffset,byteLength:e.byteLength};if(e.type!=="sqlite-blob"||typeof e.blobId!=="string"||!Array.isArray(e.jsonPath)||!e.jsonPath.every((r)=>typeof r==="string"||typeof r==="number")||e.unwrap!==null&&e.unwrap!=="user-query")return null;return{type:"sqlite-blob",sourcePath:e.sourcePath,blobId:e.blobId,jsonPath:e.jsonPath,unwrap:e.unwrap}}function K(e){return JSON.stringify(e)}async function*Rt(e){if(e.config.sources.antigravity){let r=await rt(e.paths.antigravityBrainDirectory);for(let t of r){let n=await et({sourcePath:t,cursor:await e.getCursor(t)});if(n!==null)yield n}}if(e.config.sources["claude-code"]){let r=await it(e.paths.claudeProjectsDirectory);for(let t of r){let n=await he({sourcePath:t,cursor:await e.getCursor(t)});if(n!==null)yield n}}if(e.config.sources["claude-prompts"]){let r=e.paths.claudePromptHistoryFile,t=await st({sourcePath:r,cursor:await e.getCursor(r)});if(t!==null)yield t}if(e.config.sources.codex){let r=await ft(e.paths.codexSessionsDirectory);for(let t of r){let n=await pt({sourcePath:t,cursor:await e.getCursor(t)});if(n!==null)yield n}}if(e.config.sources.cursor){let r=await bt(e.paths.cursorChatsDirectory);for(let t of r){let n=await wt({sourcePath:t,cursor:await e.getCursor(t)});if(n!==null)yield n}}if(e.config.sources.shell)for(let r of e.paths.shellHistoryFiles){let t=await xt({sourcePath:r,cursor:await e.getCursor(r)});if(t!==null)yield t}}function So(e){if(e.query("PRAGMA user_version").get()?.user_version===2)return;e.exec(`
26
+ `),d+=1,u+=x.length;continue}if(g.length>0)await wo(m,{force:!0})}return await Bun.write(e.paths.profileManifestFile,tt(l)),await Bun.write(e.paths.rejectedProfileFile,tt([...o.values()])),{files:d,rules:u,rejected:o.size}}import ko from"path";function nt(e){let t=new Bun.CryptoHasher("sha256").update(e).digest("hex").slice(0,16);return{id:`isolated:${t}`,directoryName:`isolated--${t}`,promotable:!1}}function sr(e){let t=e.trim(),r=t.match(/^(?:[^@]+@)?([^/:]+):([^/]+)\/(.+)$/);if(r){let[,n,o,s]=r;return n&&o&&s?{host:n,owner:o,repository:s.replace(/\.git$/,"")}:null}try{let n=new URL(t),[o,s]=n.pathname.split("/").filter(Boolean);return o&&s?{host:n.hostname,owner:decodeURIComponent(o),repository:decodeURIComponent(s).replace(/\.git$/,"")}:null}catch{return null}}function it(e){let t=sr(e);if(t===null)return null;let r=t.host.toLowerCase(),n=t.owner.toLowerCase(),o=`${r}/${n}`,s=o.replace(/[^a-z0-9._-]+/g,"--");return{id:o,directoryName:s,promotable:!0}}function ar(e){let t=sr(e),r=it(e);if(t===null||r===null)return null;return{id:`${r.id}/${t.repository.toLowerCase()}`,origin:r}}function Eo(e,t){let r=t.split("*").map((n)=>n.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${r}$`).test(e)}function I(e){let t=e.cwd?ko.basename(e.cwd):null,r=[e.origin.id,...t?[`${e.origin.id}/${t}`]:[]];return e.patterns.some((n)=>r.some((o)=>Eo(o,n)))}async function Re(e){let t=Bun.spawn({cmd:["git","-C",e,"config","--local","--get","remote.origin.url"],stdout:"pipe",stderr:"ignore"}),[r,n]=await Promise.all([t.exited,new Response(t.stdout).text()]),o=n.trim();return r===0&&o.length>0?o:null}function ot(e){return e.cwd.length>0?e.cwd:`${e.source}:${e.sessionId}`}async function st(e){let t=new Map,r=e.readRemote??Re;for(let n of e.events){let o=ot(n);if(t.has(o))continue;t.set(o,await D({cwd:n.cwd,fallbackKey:o,enabled:e.enabled,readRemote:r}))}return t}async function D(e){let t=e.cwd||e.fallbackKey||"unknown",r=e.readRemote??Re,n=e.enabled&&e.cwd.length>0?await r(e.cwd):null;return n===null?nt(t):it(n)??nt(t)}async function at(e){let t=e.readRemote??Re,r=e.enabled&&e.cwd.length>0?await t(e.cwd):null,n=r?ar(r):null;if(n!==null)return n;let o=await D({cwd:e.cwd,enabled:!1});return{id:o.id,origin:o}}function ae(e){return e.origins.get(ot(e.event))??nt(ot(e.event))}function lr(e){for(let t=e.length-1;t>=0;t-=1){let r=e[t];if(r&&(r.kind==="tool-call"||r.kind==="plan-presented"||r.kind==="question-asked"||r.kind==="assistant-text"))return r}return null}function So(e){if(e?.tool)return{category:`tool:${e.tool.name}`,label:`while using ${e.tool.name}`};if(e?.kind==="plan-presented")return{category:"after-plan",label:"after presenting a plan"};if(e?.kind==="assistant-text")return{category:"assistant-text",label:"during an explanation"};return{category:"other",label:"before finishing a response"}}function Pe(e){let t=[e.relatedEvent?.textRef,e.event.textRef].filter((r)=>r!==null&&r!==void 0);return{kind:e.kind,category:e.category,label:e.label,sessionId:e.event.sessionId,timestamp:e.event.timestamp,origin:e.origin,textRefs:t}}function Co(e){let t=[],r=[],n=null,o=null;for(let s of e.events){let i=ae({event:s,origins:e.origins});if(s.kind==="interruption"){let a=lr(r),l=So(a);t.push(Pe({kind:"interruption",...l,event:s,origin:i,relatedEvent:a}))}if(s.kind==="permission-denied"){let a=lr(r),l=a?.tool?.name??"an unspecified tool";t.push(Pe({kind:"permission-denied",category:`tool:${l}`,label:l,event:s,origin:i,relatedEvent:a}))}if(s.kind==="question-asked")n=s;if(s.kind==="plan-presented")o=s;if(s.kind==="user-prompt"||s.kind==="question-answered"){if(n!==null||s.kind==="question-answered")t.push(Pe({kind:"question-answered",category:"agent-question",label:"an agent question",event:s,origin:i,relatedEvent:n})),n=null}if(s.kind==="user-prompt"||s.kind==="plan-resolved"){if(o!==null||s.kind==="plan-resolved")t.push(Pe({kind:"plan-resolved",category:"presented-plan",label:"a presented plan",event:s,origin:i,relatedEvent:o})),o=null}r.push(s)}return t}function cr(e){return[...Map.groupBy(e.events,(r)=>`${r.source}:${r.sessionId}`).values()].flatMap((r)=>Co({events:r,origins:e.origins}))}function dr(e){let t=new Map;for(let r of e){let n=t.get(r.category);t.set(r.category,{...r,count:(n?.count??0)+1})}return[...t.values()].sort((r,n)=>n.count-r.count||r.label.localeCompare(n.label))}function lt(e){return dr(e)}function ur(e){let t=new Set(e.map((o)=>`${o.source}:${o.sessionId}`)),r=new Set(e.filter((o)=>o.kind==="plan-presented").map((o)=>`${o.source}:${o.sessionId}`));return{toolUses:dr(e.flatMap((o)=>o.tool?[{category:o.tool.name,label:o.tool.name}]:[])),planSessions:r.size,totalSessions:t.size}}function ve(e){let t=new Map;for(let n of e){let o=t.get(n.source);if(!o)o={sessions:new Set,interruptions:0,denials:0},t.set(n.source,o);if(o.sessions.add(n.sessionId),n.kind==="interruption")o.interruptions+=1;else if(n.kind==="permission-denied")o.denials+=1}let r=[];for(let[n,o]of t.entries()){let s=o.sessions.size,a=(n==="claude-code"||n==="codex")&&s>=25&&o.interruptions===0&&o.denials===0;r.push({source:n,sessions:s,interruptions:o.interruptions,denials:o.denials,isStale:a})}return r.sort((n,o)=>n.source.localeCompare(o.source))}function ct(e){let t=ve(e),r=[];for(let n of t)if(n.isStale)r.push(`Source "${n.source}" has ${n.sessions} sessions with 0 interruptions and 0 tool denials. Marker patterns may be stale.`);return r}function pr(e,t){return e.filter((r)=>r.kind===t).length}async function ke(e){let t=await st({events:e.events,enabled:e.gitMetadataEnabled,readRemote:e.readRemote}),r=e.events.filter((i)=>!I({origin:ae({event:i,origins:t}),cwd:i.cwd,patterns:e.blockedOrigins??[]})),n=cr({events:r,origins:t}),o=n.filter((i)=>i.kind==="interruption"),s=n.filter((i)=>i.kind==="permission-denied");return{corrections:n,events:r,origins:t,report:{corpus:e.corpus,interruptions:lt(o),denials:lt(s),answeredQuestions:n.filter((i)=>i.kind==="question-answered").length,askedQuestions:pr(r,"question-asked"),resolvedPlans:n.filter((i)=>i.kind==="plan-resolved").length,presentedPlans:pr(r,"plan-presented"),structural:ur(r)}}}function ut(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Ao(e){if(!ut(e)||typeof e.method!=="string")return null;return{id:typeof e.id==="string"||typeof e.id==="number"?e.id:null,method:e.method,params:e.params}}function fr(e){let t={jsonrpc:"2.0",id:e.request.id};if(e.request.method==="initialize")return{...t,result:{protocolVersion:"2024-11-05",capabilities:{tools:{}},serverInfo:{name:"shadowclone",version:he.version}}};if(e.request.method==="tools/list")return{...t,result:{tools:[{name:"shadowclone_profile",description:"Load the active user's engineering profile for this repository",inputSchema:{type:"object",properties:{}}}]}};if(e.request.method==="tools/call"){if((ut(e.request.params)?e.request.params:{}).name!=="shadowclone_profile")return{...t,error:{code:-32602,message:"Unknown tool"}};return{...t,result:{content:[{type:"text",text:e.profile}],isError:!1}}}if(e.request.method.startsWith("notifications/"))return null;return{...t,error:{code:-32601,message:"Method not found"}}}async function To(e){let{config:t,policy:r}=await S({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?e.paths.managedConfigFile:e.managedConfigPath});if(!r.enabled)return`# Shadowclone profile
27
+ `;let n=await D({cwd:e.cwd,enabled:t.sources["git-metadata"],readRemote:e.readRemote});if(I({origin:n,cwd:e.cwd,patterns:r.blockedOrigins}))return`# Shadowclone profile
28
+ `;return X({profileDirectory:e.paths.profileDirectory,origin:n,targetRepo:Io.basename(e.cwd)})}async function dt(e){await Bun.stdout.write(`${JSON.stringify(e)}
29
+ `)}async function pt(e={}){let t=e.cwd??process.cwd(),r=e.paths??h,n="",o=new TextDecoder;for await(let s of Bun.stdin.stream()){n+=o.decode(s,{stream:!0});let i=n.indexOf(`
30
+ `);while(i>=0){let a=n.slice(0,i).trim();if(n=n.slice(i+1),a.length>0)try{let l=Ao(JSON.parse(a));if(l===null)await dt({jsonrpc:"2.0",id:null,error:{code:-32600,message:"Invalid request"}});else{let d=l.method==="tools/call"&&ut(l.params)&&l.params.name==="shadowclone_profile"?await To({cwd:t,configPath:e.configPath,paths:r,readRemote:e.readRemote,managedConfigPath:e.managedConfigPath}):"",u=fr({request:l,profile:d});if(u!==null)await dt(u)}}catch{await dt({jsonrpc:"2.0",id:null,error:{code:-32700,message:"Parse error"}})}i=n.indexOf(`
31
+ `)}}}function q(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function k(e,t){let r=e[t];return typeof r==="string"?r:null}function ft(e,t){let r=e[t];return typeof r==="number"?r:null}function Do(e){let t=e.message;if(!q(t)||!Array.isArray(t.content))return"";return t.content.flatMap((r)=>q(r)&&k(r,"type")==="text"&&k(r,"text")!==null?[k(r,"text")??""]:[]).join("")}function Bo(e){let t=e.message;if(!q(t)||!Array.isArray(t.content))return[];return t.content.flatMap((r)=>{if(!q(r)||k(r,"type")!=="tool_use")return[];let n=k(r,"name")??"",o=q(r.input)?r.input:null,s=o?k(o,"file_path")??k(o,"path")??k(o,"notebook_path"):null,i=o?k(o,"command"):null;return[{tool:n,path:s,command:i}]})}function Oo(e){if(!Array.isArray(e))return[];return e.flatMap((t)=>{if(!q(t))return[];let r=k(t,"tool_name")??k(t,"toolName");return r?[{toolName:r,toolUseId:k(t,"tool_use_id")??k(t,"toolUseId")}]:[]})}function mt(e){let t=[],r=[],n=null;for(let i of e.stream.split(`
32
+ `)){if(i.trim().length===0)continue;try{let a=JSON.parse(i);if(!q(a))continue;if(k(a,"type")==="assistant")t.push(Do(a)),r.push(...Bo(a));if(k(a,"type")==="result")n=a}catch{}}let o=n?k(n,"result"):null,s=t.join("");return{engine:"claude-code",sessionId:(n?k(n,"session_id"):null)??e.fallbackSessionId,transcriptPath:null,text:s.length>0?s:o??"",structured:n?.structured_output??null,costUsd:n?ft(n,"total_cost_usd"):null,durationMs:n?ft(n,"duration_ms")??0:0,turns:n?ft(n,"num_turns")??0:0,isError:n?.is_error===!0||n===null,permissionDenials:Oo(n?.permission_denials),actions:r}}function mr(e){if(e.values===void 0||e.values.length===0)return;e.arguments_.push(e.flag),e.arguments_.push(...e.values)}function gr(e){let t=["claude","-p","--output-format","stream-json","--verbose","--session-id",e.sessionId,"--setting-sources","user,project"];if(e.run.systemPromptFile)t.push("--append-system-prompt-file",e.run.systemPromptFile);if(e.run.model)t.push("--model",e.run.model);if(e.run.permissionMode)t.push("--permission-mode",e.run.permissionMode);if(e.run.maxBudgetUsd!==void 0)t.push("--max-budget-usd",e.run.maxBudgetUsd.toString());if(e.run.outputSchema!==void 0)t.push("--json-schema",JSON.stringify(e.run.outputSchema));return mr({arguments_:t,flag:"--allowedTools",values:e.run.allowedTools}),mr({arguments_:t,flag:"--disallowedTools",values:e.run.disallowedTools}),t}async function gt(e){let t=e.sessionId??crypto.randomUUID(),r=Bun.spawn({cmd:[...gr({run:e,sessionId:t})],cwd:e.cwd,stdin:"pipe",stdout:"pipe",stderr:"pipe",signal:e.signal});r.stdin.write(e.prompt),r.stdin.end();let[n,o]=await Promise.all([r.exited,new Response(r.stdout).text(),new Response(r.stderr).text()]),s=mt({stream:o,fallbackSessionId:t});return n===0?s:{...s,isError:!0}}import{mkdtemp as jo,rm as Mo}from"fs/promises";import Fo from"os";import hr from"path";function yr(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function le(e,t){let r=e[t];return typeof r==="string"?r:null}function _o(e){try{return JSON.parse(e)}catch{return null}}function yt(e){let t=e.fallbackSessionId,r="",n=0,o=!1;for(let s of e.stream.split(`
33
+ `)){if(s.trim().length===0)continue;let i;try{i=JSON.parse(s)}catch{o=!0;continue}if(!yr(i))continue;let a=le(i,"type");if(a==="thread.started")t=le(i,"thread_id")??t;if(a==="turn.completed")n+=1;if(a==="turn.failed"||a==="error")o=!0;let l=yr(i.item)?i.item:null,d=l?le(l,"item_type")??le(l,"type"):null;if(a==="item.completed"&&l!==null&&(d==="assistant_message"||d==="agent_message"))r=le(l,"text")??r}return{engine:"codex",sessionId:t,transcriptPath:null,text:r,structured:_o(r),costUsd:null,durationMs:e.durationMs,turns:n,isError:o,permissionDenials:[]}}async function Ee(e){let t=[];if(e.run.systemPromptFile)t.push("Follow this shadowclone profile:",await Bun.file(e.run.systemPromptFile).text());if(t.push("Complete this task:",e.run.prompt),e.outputSchemaInPrompt&&e.run.outputSchema!==void 0)t.push("Return only JSON matching this schema:",JSON.stringify(e.run.outputSchema));return t.join(`
34
+
35
+ `)}function br(e){if(e.sessionId!==void 0)throw Error("Codex cannot set a caller-provided session id");if(e.maxBudgetUsd!==void 0)throw Error("Codex cannot enforce a per-run dollar budget");if(e.disallowedTools&&e.disallowedTools.length>0)throw Error("Codex cannot enforce a granular tool denylist");if(e.allowedTools&&e.allowedTools.length>0)throw Error("Codex cannot enforce a granular tool allowlist");if(![void 0,"dontAsk","plan"].includes(e.permissionMode))throw Error("Codex cannot honor this permission mode")}function xr(e){br(e.run);let t=["codex","exec","-","--json","--sandbox","read-only","-C",e.run.cwd,"--skip-git-repo-check","-c",'approval_policy="never"',"-c","mcp_servers={}"];if(e.run.allowedTools?.length===0)t.push("--disable","shell_tool");if(e.run.model)t.push("--model",e.run.model);if(e.outputSchemaPath)t.push("--output-schema",e.outputSchemaPath);return t}async function wr(e){let t=await Ee({run:e.run,outputSchemaInPrompt:!1}),r=crypto.randomUUID(),n=Date.now(),o=Bun.spawn({cmd:[...xr(e)],cwd:e.run.cwd,stdin:"pipe",stdout:"pipe",stderr:"ignore",signal:e.run.signal});o.stdin.write(t),o.stdin.end();let[s,i]=await Promise.all([o.exited,new Response(o.stdout).text()]),a=yt({stream:i,fallbackSessionId:r,durationMs:Date.now()-n});return s===0?a:{...a,isError:!0}}async function ht(e){if(br(e),e.outputSchema===void 0)return wr({run:e});let t=await jo(hr.join(Fo.tmpdir(),"shadowclone-codex-")),r=hr.join(t,"schema.json");await Bun.write(r,JSON.stringify(e.outputSchema));try{return await wr({run:e,outputSchemaPath:r})}finally{await Mo(t,{recursive:!0,force:!0})}}import{mkdir as Uo,mkdtemp as qo,rm as zo}from"fs/promises";import Go from"os";import bt from"path";function $o(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Se(e,t){let r=e[t];return typeof r==="string"?r:null}function No(e,t){let r=e[t];return typeof r==="number"?r:null}function Lo(e){try{return JSON.parse(e)}catch{return null}}function wt(e){let t=e.fallbackSessionId,r=null,n=0;for(let s of e.stream.split(`
36
+ `)){if(s.trim().length===0)continue;let i;try{i=JSON.parse(s)}catch{continue}if(!$o(i))continue;if(t=Se(i,"session_id")??t,Se(i,"type")==="assistant")n+=1;if(Se(i,"type")==="result")r=i}let o=r?Se(r,"result")??"":"";return{engine:"cursor-agent",sessionId:t,transcriptPath:null,text:o,structured:Lo(o),costUsd:null,durationMs:r?No(r,"duration_ms")??0:0,turns:n,isError:r===null||r.is_error===!0,permissionDenials:[]}}function Pr(e){if(e.sessionId!==void 0)throw Error("Cursor cannot set a caller-provided session id");if(e.maxBudgetUsd!==void 0)throw Error("Cursor cannot enforce a per-run dollar budget");if(e.disallowedTools&&e.disallowedTools.length>0)throw Error("Cursor cannot enforce a granular tool denylist");if(e.allowedTools&&e.allowedTools.length>0)throw Error("Cursor cannot enforce a granular tool allowlist");if(![void 0,"dontAsk","plan"].includes(e.permissionMode))throw Error("Cursor cannot honor this permission mode")}function vr(e){Pr(e);let t=["cursor-agent","--print","--output-format","stream-json","--sandbox","enabled","--mode",e.permissionMode==="plan"?"plan":"ask","--workspace",e.cwd];if(e.model)t.push("--model",e.model);return t}async function Rr(e){let t=await Ee({run:e.run,outputSchemaInPrompt:!0}),r=crypto.randomUUID(),n=Bun.spawn({cmd:[...vr({...e.run,cwd:e.workspace}),"--trust"],cwd:e.workspace,stdin:"pipe",stdout:"pipe",stderr:"ignore",signal:e.run.signal});n.stdin.write(t),n.stdin.end();let[o,s]=await Promise.all([n.exited,new Response(n.stdout).text()]),i=wt({stream:s,fallbackSessionId:r});return o===0?i:{...i,isError:!0}}async function xt(e){if(Pr(e),e.allowedTools?.length!==0)return Rr({run:e,workspace:e.cwd});let t=await qo(bt.join(Go.tmpdir(),"shadowclone-cursor-")),r=bt.join(t,".cursor");await Uo(r,{recursive:!0}),await Bun.write(bt.join(r,"cli.json"),JSON.stringify({version:1,permissions:{allow:[],deny:["Shell(*)","Read(*)","Write(*)","WebFetch(*)","Mcp(*:*)"]}}));try{return await Rr({run:e,workspace:t})}finally{await zo(t,{recursive:!0,force:!0})}}var Ce=[{id:"claude-code",captureSource:"claude-code",transcriptFormat:"jsonl",engine:{id:"claude-code",implemented:!0,capabilities:{structuredOutput:"native",callerSessionId:!0,maxBudgetUsd:!0,granularToolPolicy:!0,isolatedNoTools:!0}}},{id:"codex",captureSource:"codex",transcriptFormat:"jsonl",engine:{id:"codex",implemented:!0,capabilities:{structuredOutput:"native",callerSessionId:!1,maxBudgetUsd:!1,granularToolPolicy:!1,isolatedNoTools:!0}}},{id:"cursor",captureSource:"cursor",transcriptFormat:"sqlite",engine:{id:"cursor-agent",implemented:!0,capabilities:{structuredOutput:"prompted",callerSessionId:!1,maxBudgetUsd:!1,granularToolPolicy:!1,isolatedNoTools:!0}}},{id:"antigravity",captureSource:"antigravity",transcriptFormat:"jsonl",engine:{id:"antigravity",implemented:!1,capabilities:{structuredOutput:"native",callerSessionId:!1,maxBudgetUsd:!1,granularToolPolicy:!1,isolatedNoTools:!1}}}];function Rt(e){return Ce.find((t)=>t.engine?.id===e)??null}function Jo(e){return e?.implemented===!0&&e.capabilities.structuredOutput!=="none"&&e.capabilities.isolatedNoTools}function Ie(e){let t=Jo(e.engine),r=e.engine?.implemented===!0,n=e.engine?.capabilities;return{observe:e.captureSource!==null,distill:t,dispatch:r&&n?.callerSessionId===!0&&n.maxBudgetUsd&&n.granularToolPolicy}}function Pt(e){let t=Ie(e.definition);return e.purpose==="distill"?t.distill:t.dispatch}async function Ae(e){try{return await Bun.spawn({cmd:[...e],stdout:"ignore",stderr:"ignore"}).exited===0}catch{return!1}}async function kr(e={}){let t=e.probe??Ae,r=await t(["claude","--version"]),n=r&&await t(["claude","auth","status"]);return{engine:"claude-code",installed:r,authenticated:n}}async function Er(e={}){let t=e.probe??Ae,r=await t(["codex","--version"]),n=r&&await t(["codex","login","status"]);return{engine:"codex",installed:r,authenticated:n}}async function Sr(e={}){let t=e.probe??Ae,r=await t(["cursor-agent","--version"]),n=r&&await t(["cursor-agent","status"]);return{engine:"cursor-agent",installed:r,authenticated:n}}function Ho(e){if(e==="claude-code")return gt;if(e==="codex")return ht;if(e==="cursor-agent")return xt;return null}function Wo(e){let t=Rt(e.engineId);return t!==null&&Pt({definition:t,purpose:e.purpose})}async function B(e){let t=await kr(e),r=await Er(e),n=await Sr(e),o=e.allowedEngines??["claude-code","codex","cursor-agent"],s=[t,r,n],i=s.find((l)=>l.authenticated&&o.includes(l.engine)&&Wo({engineId:l.engine,purpose:e.purpose})),a=i?Ho(i.engine):null;return{availability:s,runner:a,selectedEngine:a?i?.engine??null:null}}import{Database as Ii}from"bun:sqlite";import{mkdir as Ai}from"fs/promises";import Ti from"path";import{stat as Vo}from"fs/promises";import Te from"path";import{stat as Ko}from"fs/promises";function Xo(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Zo(e){return Xo(e)&&e.code==="ENOENT"}async function Cr(e){let t=await Ko(e.sourcePath).catch((m)=>{if(Zo(m))return null;throw m});if(t===null)return null;let r=t.mtimeMs,n=e.cursor;if(n!==null&&n.byteSize===t.size&&n.modifiedAt===r)return{values:[],cursor:n,rescanned:!1,bytesRead:0};let s=n!==null&&(t.size<n.byteOffset||t.size===n.byteSize&&r!==n.modifiedAt),i=n===null||s?0:n.byteOffset,a=Bun.file(e.sourcePath),l=new Uint8Array(await a.slice(i,t.size).arrayBuffer()),d=[],u=0,p=0;for(let m=0;m<l.length;m+=1){if(l[m]!==10)continue;let R=m>u&&l[m-1]===13?m-1:m,P=R-u;if(P>0)d.push({ref:{type:"file",sourcePath:e.sourcePath,byteOffset:i+u,byteLength:P},bytes:l.slice(u,R)});u=m+1,p=u}return{values:d,cursor:{sourcePath:e.sourcePath,byteSize:t.size,modifiedAt:r,byteOffset:i+p},rescanned:s,bytesRead:l.length}}async function j(e){let t=await Cr(e);if(t===null)return null;let r=new TextDecoder,n=t.values.map((o)=>{let s;try{s=JSON.parse(r.decode(o.bytes))}catch{throw Error(`Transcript record is invalid at byte offset ${o.ref.byteOffset}`)}return{value:s,ref:o.ref}});return{...t,values:n}}async function Ir(e){let t=await Cr(e);if(t===null)return null;return{...t,values:t.values.map((r)=>r.ref)}}function y(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function c(e,t){let r=e[t];return typeof r==="string"?r:null}function z(e,t){return e[t]===!0}function G(e,t){let r=e[t];return y(r)?r:null}function C(e){if(typeof e==="number"&&Number.isFinite(e))return e<10000000000?e*1000:e;if(typeof e==="string"){let t=Date.parse(e);return Number.isNaN(t)?0:t}return 0}var Yo=new Set(["CODE_ACTION","GREP_SEARCH","LIST_DIRECTORY","MCP_TOOL","REPLACE_FILE_CONTENT","RUN_COMMAND","VIEW_FILE","WRITE_TO_FILE"]);function Ar(e){let t=e.tool_calls;if(!Array.isArray(t))return null;let r=t.find(y);if(!r)return null;return{toolUseId:c(r,"id")??c(r,"tool_call_id"),name:c(r,"name")??"unknown"}}function Qo(e,t){return{toolUseId:c(e,"tool_call_id")??c(e,"call_id"),name:c(e,"tool_name")??t.toLowerCase()}}function ei(e){let t=c(e,"type");if(t==="USER_INPUT")return c(e,"content")===null?null:"user-prompt";if(t==="PLANNER_RESPONSE"){if(Ar(e))return"tool-call";if(e.thinking!==void 0)return"thinking";return c(e,"content")===null?"thinking":"assistant-text"}if(t==="CHECKPOINT")return"session-end";return t!==null&&Yo.has(t)?"tool-result":null}function ti(e){return Te.basename(Te.dirname(Te.dirname(Te.dirname(e))))}function ri(e){if(!y(e.value))return null;let t=ei(e.value),r=c(e.value,"type");if(t===null||r===null)return null;let n=c(e.value,"status"),o=n==="CANCELED"?"interruption":t,s=e.value.step_index,i=t==="tool-call"?Ar(e.value):t==="tool-result"?Qo(e.value,r):null;return{source:"antigravity",sessionId:e.sessionId,eventId:`antigravity:${typeof s==="number"?s:e.ref.byteOffset}`,parentEventId:null,timestamp:C(e.value.created_at),cwd:c(e.value,"workspace")??"",gitBranch:c(e.value,"git_branch"),kind:o,tool:i,isError:n==="ERROR",textRef:o==="user-prompt"||o==="assistant-text"?e.ref:null}}async function Tr(e){let t=await j(e);if(t===null)return null;let r=ti(e.sourcePath),n=null,o=t.values.flatMap((s)=>{let i=ri({...s,sessionId:r});if(i===null)return[];let a={...i,parentEventId:n};return n=i.eventId,[a]});return{source:"antigravity",sourcePath:e.sourcePath,events:o,cursor:t.cursor,rescanned:t.rescanned,bytesRead:t.bytesRead}}async function Dr(e){try{if(!(await Vo(e)).isDirectory())return[]}catch(n){if(y(n)&&n.code==="ENOENT")return[];throw n}let t=[],r="*/.system_generated/logs/transcript_full.jsonl";for await(let n of new Bun.Glob(r).scan({cwd:e,absolute:!0,dot:!0,onlyFiles:!0}))t.push(n);return t.sort()}import _r from"path";import Br from"path";function De(e){let t=`${Br.basename(e.ref.sourcePath)}:${C(e.record.timestamp)}`;return{source:"claude-code",sessionId:c(e.record,"sessionId")??Br.basename(e.ref.sourcePath,".jsonl"),eventId:c(e.message,"id")??c(e.record,"uuid")??t,parentEventId:c(e.record,"parentUuid"),timestamp:C(e.record.timestamp),cwd:c(e.record,"cwd")??"",gitBranch:c(e.record,"gitBranch")}}function Be(e,t){if(typeof e==="string")return e.includes(t);if(!Array.isArray(e))return!1;return e.some((r)=>y(r)&&typeof r.content==="string"&&r.content.includes(t))}function ni(e){if(e.interrupted)return"interruption";if(e.denied)return"permission-denied";if(e.questionAnswered)return"question-answered";if(e.planResolved)return"plan-resolved";return e.plainPrompt?"user-prompt":"tool-result"}function Or(e){if(z(e.record,"isMeta"))return[];let t=De(e),r=e.message.content,n=Be(r,"[Request interrupted by user"),o=Be(r,"user doesn't want to proceed with this tool use"),s=Be(r,"User has answered your questions"),i=Be(r,"The user has approved your plan"),a=typeof r==="string",l=ni({interrupted:n,denied:o,questionAnswered:s,planResolved:i,plainPrompt:a});return[{...t,kind:l,tool:null,isError:z(e.record,"is_error"),textRef:a&&!n&&!o?e.ref:null}]}function oi(e){if(e==="ExitPlanMode")return"plan-presented";if(e==="AskUserQuestion")return"question-asked";return"tool-call"}function ii(e){if(c(e,"type")!=="tool_use")return null;let t=c(e,"name");if(t===null)return null;return{toolUseId:c(e,"id"),name:t}}function si(e){let t=e.content;return Array.isArray(t)?t:[t]}function ai(e){return e.blocks.length===1&&(c(e.block,"type")==="text"||e.kind==="question-asked"||e.kind==="plan-presented")?e.ref:null}function li(e){let t=De(e),r=si(e.message),n=[];for(let o of r){if(!y(o))continue;let s=c(o,"type"),i=ii(o),a=i===null?s==="thinking"?"thinking":"assistant-text":oi(i.name);n.push({...t,kind:a,tool:i,isError:!1,textRef:ai({blocks:r,block:o,ref:e.ref,kind:a})})}return n}function ci(e){if(!y(e.value))return[];let t=c(e.value,"type");if(t==="result"){let n=C(e.value.timestamp);return[{source:"claude-code",sessionId:c(e.value,"session_id")??c(e.value,"sessionId")??_r.basename(e.ref.sourcePath,".jsonl"),eventId:c(e.value,"uuid")??`result:${_r.basename(e.ref.sourcePath)}:${n}`,parentEventId:c(e.value,"parentUuid"),timestamp:n,cwd:c(e.value,"cwd")??"",gitBranch:c(e.value,"gitBranch"),kind:"session-end",tool:null,isError:z(e.value,"is_error"),textRef:null}]}let r=G(e.value,"message");if(r===null)return[];if(t==="assistant")return li({record:e.value,message:r,ref:e.ref});if(t==="user")return Or({record:e.value,message:r,ref:e.ref});return[]}async function Oe(e){let t=await j(e);if(t===null)return null;return{source:"claude-code",sourcePath:e.sourcePath,events:t.values.flatMap(ci),cursor:t.cursor,rescanned:t.rescanned,bytesRead:t.bytesRead}}async function jr(e){let t=new Bun.Glob("**/*.jsonl"),r=[];for await(let n of t.scan({cwd:e,absolute:!0,onlyFiles:!0}))r.push(n);return r.sort()}import di from"path";function ui(e){if(!y(e.value))return null;if((c(e.value,"display")??c(e.value,"prompt"))===null)return null;let r=C(e.value.timestamp);return{source:"claude-prompts",sessionId:c(e.value,"sessionId")??"claude-prompts",eventId:c(e.value,"id")??`prompt:${r}:${e.ref.byteOffset}`,parentEventId:null,timestamp:r,cwd:c(e.value,"project")??"",gitBranch:null,kind:"user-prompt",tool:null,isError:!1,textRef:e.ref}}async function Mr(e){let t=await j(e);if(t===null)return null;let r=t.values.map(ui).filter((n)=>n!==null);return{source:"claude-prompts",sourcePath:di.resolve(e.sourcePath),events:r,cursor:t.cursor,rescanned:t.rescanned,bytesRead:t.bytesRead}}import pi from"path";function $r(e){return{sessionId:pi.basename(e,".jsonl"),cwd:"",gitBranch:null}}function Fr(e){if(!y(e.value)||c(e.value,"type")!=="session_meta")return null;let t=G(e.value,"payload");if(t===null)return null;let r=G(t,"git");return{sessionId:c(t,"id")??$r(e.sourcePath).sessionId,cwd:c(t,"cwd")??"",gitBranch:r?c(r,"branch"):null}}async function fi(e){let t=Bun.file(e).stream().getReader(),r=[],n=0;while(!0){let i=await t.read();if(i.done)break;let a=i.value.indexOf(10),l=a<0?i.value:i.value.slice(0,a);if(r.push(l),n+=l.byteLength,a>=0){await t.cancel();break}}let o=new Uint8Array(n),s=0;for(let i of r)o.set(i,s),s+=i.byteLength;try{return JSON.parse(new TextDecoder().decode(o))}catch{throw Error("Codex transcript has an invalid session header")}}async function Nr(e){for(let r of e.values){let n=Fr({sourcePath:e.sourcePath,value:r.value});if(n!==null)return n}return Fr({sourcePath:e.sourcePath,value:await fi(e.sourcePath)})??$r(e.sourcePath)}function Ur(e){let t=c(e,"type");if(t!=="function_call"&&t!=="custom_tool_call"&&t!=="local_shell_call")return null;return{toolUseId:c(e,"call_id")??c(e,"id"),name:c(e,"name")??(t==="local_shell_call"?"shell":"unknown")}}function mi(e){let t=c(e,"type"),r=c(e,"role");if(t==="message"&&r==="user")return"user-prompt";if(t==="message"&&r==="assistant")return"assistant-text";if(t==="reasoning")return"thinking";if(t==="function_call_output"||t==="custom_tool_call_output"||t==="local_shell_call_output")return"tool-result";return Ur(e)?"tool-call":null}function Lr(e){return{source:"codex",sessionId:e.context.sessionId,eventId:`codex:${e.ref.byteOffset}`,parentEventId:null,timestamp:C(e.envelope.timestamp),cwd:e.context.cwd,gitBranch:e.context.gitBranch,kind:e.kind,tool:e.tool,isError:!1,textRef:e.kind==="user-prompt"||e.kind==="assistant-text"?e.ref:null}}function gi(e){if(!y(e.value))return null;let t=c(e.value,"type"),r=G(e.value,"payload");if(r===null)return null;if(t==="response_item"){let s=mi(r);return s===null?null:Lr({context:e.context,envelope:e.value,ref:e.ref,kind:s,tool:Ur(r)})}let n=c(r,"type");if(t!=="event_msg"||n!=="task_complete"&&n!=="task_completed"&&n!=="turn_aborted")return null;let o=n==="turn_aborted"?"interruption":"session-end";return{...Lr({context:e.context,envelope:e.value,ref:e.ref,kind:o,tool:null}),isError:z(r,"is_error")}}async function qr(e){let t=await j(e);if(t===null)return null;if(t.values.length===0)return{source:"codex",sourcePath:e.sourcePath,events:[],cursor:t.cursor,rescanned:t.rescanned,bytesRead:t.bytesRead};let r=await Nr({sourcePath:e.sourcePath,values:t.values}),n=null,o=t.values.flatMap((s)=>{let i=gi({...s,context:r});if(i===null)return[];let a={...i,parentEventId:n};return n=i.eventId,[a]});return{source:"codex",sourcePath:e.sourcePath,events:o,cursor:t.cursor,rescanned:t.rescanned,bytesRead:t.bytesRead}}async function zr(e){let t=[];for await(let r of new Bun.Glob("**/rollout-*.jsonl").scan({cwd:e,absolute:!0,onlyFiles:!0}))t.push(r);return t.sort()}function yi(e){return{type:"sqlite-blob",sourcePath:e.context.sourcePath,blobId:e.blobId,jsonPath:e.jsonPath,unwrap:e.unwrap}}function hi(e){let t=c(e,"type");if(t!=="tool-call"&&t!=="tool_use"&&t!=="tool_call")return null;return{toolUseId:c(e,"toolCallId")??c(e,"tool_call_id")??c(e,"id"),name:c(e,"toolName")??c(e,"name")??"unknown"}}function _e(e){return{source:"cursor",sessionId:e.context.sessionId,eventId:`cursor:${e.blobId}:${e.index}`,parentEventId:null,timestamp:e.context.timestamp+e.index,cwd:e.context.cwd,gitBranch:null,kind:e.kind,tool:e.tool,isError:!1,textRef:e.ref}}function Gr(e){let t=e.role==="user"&&e.text.includes("<user_query>"),r=e.role==="assistant";if(!t&&!r)return null;return _e({context:e.context,blobId:e.blobId,index:e.index,kind:t?"user-prompt":"assistant-text",tool:null,ref:yi({context:e.context,blobId:e.blobId,jsonPath:e.jsonPath,unwrap:t?"user-query":null})})}function Jr(e){if(!y(e.blob.value))return[];let t=c(e.blob.value,"role");if(t==="tool")return[_e({context:e.context,blobId:e.blob.id,index:0,kind:"tool-result",tool:null,ref:null})];let r=e.blob.value.content;if(typeof r==="string"){let n=Gr({context:e.context,blobId:e.blob.id,index:0,role:t??"",text:r,jsonPath:["content"]});return n?[n]:[]}if(!Array.isArray(r))return[];return r.flatMap((n,o)=>{if(!y(n))return[];let s=c(n,"type");if(t==="assistant"&&s==="reasoning")return[_e({context:e.context,blobId:e.blob.id,index:o,kind:"thinking",tool:null,ref:null})];let i=hi(n);if(i!==null)return[_e({context:e.context,blobId:e.blob.id,index:o,kind:"tool-call",tool:i,ref:null})];let a=c(n,"text"),l=a?Gr({context:e.context,blobId:e.blob.id,index:o,role:t??"",text:a,jsonPath:["content",o,"text"]}):null;return l?[l]:[]})}import{Database as Hr}from"bun:sqlite";import{stat as wi}from"fs/promises";import Z from"path";async function vt(e){try{let t=await wi(e);return{size:t.size,modifiedAt:t.mtimeMs}}catch{return null}}function bi(e){let t=/^(?:[0-9a-fA-F]{2})+$/.test(e)?new TextDecoder().decode(Uint8Array.from(e.match(/.{2}/g)?.map((r)=>Number.parseInt(r,16))??[])):e;try{return JSON.parse(t)}catch{return null}}function xi(e){try{return JSON.parse(new TextDecoder().decode(e))}catch{return null}}async function Ri(e){let t=Bun.file(Z.join(Z.dirname(e),"meta.json"));if(!await t.exists())return null;try{return JSON.parse(await t.text())}catch{return null}}async function Wr(e){let t=await vt(e);if(t===null)return null;let[r,n]=await Promise.all([vt(`${e}-wal`),vt(Z.join(Z.dirname(e),"meta.json"))]),o=[t,r,n].filter((s)=>s!==null);return{size:o.reduce((s,i)=>s+i.size,0),modifiedAt:Math.max(...o.map((s)=>s.modifiedAt))}}function Pi(e){let t=null;try{return t=new Hr(e,{readonly:!0,strict:!0}),t.query("SELECT 1").get(),t}catch{t?.close();let r=null;try{return r=new Hr(`file:${e}?mode=ro&immutable=1`,{strict:!0}),r.query("SELECT 1").get(),r}catch(n){throw r?.close(),n}}}async function Kr(e){let t=null;try{t=Pi(e.sourcePath);let r=t.query("SELECT id, data FROM blobs ORDER BY rowid").all().flatMap((a)=>{let l=xi(a.data);return l===null?[]:[{id:a.id,value:l}]}),n=bi(t.query("SELECT value FROM meta WHERE key = '0'").get()?.value??""),o=await Ri(e.sourcePath),s=y(n)?n:{},i=y(o)?o:{};return{blobs:r,sessionId:c(s,"agentId")??Z.basename(Z.dirname(e.sourcePath)),cwd:c(i,"cwd")??"",timestamp:C(i.createdAtMs)||C(s.createdAt)||e.signature.modifiedAt,cursor:{sourcePath:e.sourcePath,byteSize:e.signature.size,modifiedAt:e.signature.modifiedAt,byteOffset:e.signature.size},bytesRead:e.signature.size}}catch{return console.warn(`cursor: skipped an unreadable store (${e.signature.size} bytes)`),null}finally{t?.close()}}async function Xr(e){let t=await Wr(e.sourcePath);if(t===null)return null;if(e.cursor!==null&&e.cursor.byteSize===t.size&&e.cursor.modifiedAt===t.modifiedAt)return{source:"cursor",sourcePath:e.sourcePath,events:[],cursor:e.cursor,rescanned:!1,bytesRead:0};let r=await Kr({sourcePath:e.sourcePath,signature:t});if(r===null)return null;let n=[],o=null;for(let s of r.blobs)for(let i of Jr({blob:s,context:{sourcePath:e.sourcePath,sessionId:r.sessionId,cwd:r.cwd,timestamp:r.timestamp+n.length}})){let a={...i,parentEventId:o};n.push(a),o=a.eventId}return{source:"cursor",sourcePath:e.sourcePath,events:n,cursor:r.cursor,rescanned:e.cursor!==null,bytesRead:r.bytesRead}}async function Zr(e){let t=[];for await(let r of new Bun.Glob("**/store.db").scan({cwd:e,absolute:!0,onlyFiles:!0}))t.push(r);return t.sort()}import vi from"path";async function Vr(e){let t=await Ir(e);if(t===null)return null;return{source:"shell",sourcePath:vi.resolve(e.sourcePath),events:t.values.map((r)=>({source:"shell",sessionId:"shell-history",eventId:`shell:${r.byteOffset}`,parentEventId:null,timestamp:t.cursor.modifiedAt,cwd:"",gitBranch:null,kind:"user-prompt",tool:null,isError:!1,textRef:r})),cursor:t.cursor,rescanned:t.rescanned,bytesRead:t.bytesRead}}function ki(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function kt(e){if(!ki(e)||typeof e.sourcePath!=="string")return null;if(e.type==="file"&&typeof e.byteOffset==="number"&&typeof e.byteLength==="number")return{type:"file",sourcePath:e.sourcePath,byteOffset:e.byteOffset,byteLength:e.byteLength};if(e.type!=="sqlite-blob"||typeof e.blobId!=="string"||!Array.isArray(e.jsonPath)||!e.jsonPath.every((t)=>typeof t==="string"||typeof t==="number")||e.unwrap!==null&&e.unwrap!=="user-query")return null;return{type:"sqlite-blob",sourcePath:e.sourcePath,blobId:e.blobId,jsonPath:e.jsonPath,unwrap:e.unwrap}}function ce(e){return JSON.stringify(e)}async function*Yr(e){if(e.config.sources.antigravity){let t=await Dr(e.paths.antigravityBrainDirectory);for(let r of t){let n=await Tr({sourcePath:r,cursor:await e.getCursor(r)});if(n!==null)yield n}}if(e.config.sources["claude-code"]){let t=await jr(e.paths.claudeProjectsDirectory);for(let r of t){let n=await Oe({sourcePath:r,cursor:await e.getCursor(r)});if(n!==null)yield n}}if(e.config.sources["claude-prompts"]){let t=e.paths.claudePromptHistoryFile,r=await Mr({sourcePath:t,cursor:await e.getCursor(t)});if(r!==null)yield r}if(e.config.sources.codex){let t=await zr(e.paths.codexSessionsDirectory);for(let r of t){let n=await qr({sourcePath:r,cursor:await e.getCursor(r)});if(n!==null)yield n}}if(e.config.sources.cursor){let t=await Zr(e.paths.cursorChatsDirectory);for(let r of t){let n=await Xr({sourcePath:r,cursor:await e.getCursor(r)});if(n!==null)yield n}}if(e.config.sources.shell)for(let t of e.paths.shellHistoryFiles){let r=await Vr({sourcePath:t,cursor:await e.getCursor(t)});if(r!==null)yield r}}function Ei(e){if(e.query("PRAGMA user_version").get()?.user_version===2)return;e.exec(`
30
37
  DROP TABLE IF EXISTS events;
31
38
  DROP TABLE IF EXISTS cursors;
32
- `)}function Pt(e){So(e),e.exec(`
39
+ `)}function Qr(e){Ei(e),e.exec(`
33
40
  PRAGMA journal_mode = WAL;
34
41
  PRAGMA foreign_keys = ON;
35
42
 
@@ -66,22 +73,22 @@ ${i.map((s)=>s.content).join(`
66
73
  ON events(kind);
67
74
 
68
75
  PRAGMA user_version = 2;
69
- `)}function vt(e){e.database.transaction((t)=>{if(t.rescanned)e.database.query("DELETE FROM events WHERE source_path = ?").run(t.sourcePath);let n=e.database.query(`INSERT INTO events (
76
+ `)}function en(e){e.database.transaction((r)=>{if(r.rescanned)e.database.query("DELETE FROM events WHERE source_path = ?").run(r.sourcePath);let n=e.database.query(`INSERT INTO events (
70
77
  source_path, source, session_id, event_id, parent_event_id,
71
78
  timestamp, cwd, git_branch, kind, tool_use_id, tool_name,
72
79
  is_error, text_ref
73
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);for(let o of t.events)n.run(t.sourcePath,o.source,o.sessionId,o.eventId,o.parentEventId,o.timestamp,o.cwd,o.gitBranch,o.kind,o.tool?.toolUseId??null,o.tool?.name??null,o.isError?1:0,o.textRef===null?null:JSON.stringify(o.textRef));e.database.query(`INSERT INTO cursors (
80
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);for(let o of r.events)n.run(r.sourcePath,o.source,o.sessionId,o.eventId,o.parentEventId,o.timestamp,o.cwd,o.gitBranch,o.kind,o.tool?.toolUseId??null,o.tool?.name??null,o.isError?1:0,o.textRef===null?null:JSON.stringify(o.textRef));e.database.query(`INSERT INTO cursors (
74
81
  source_path, source, byte_size, modified_at, byte_offset
75
82
  ) VALUES (?, ?, ?, ?, ?)
76
83
  ON CONFLICT(source_path) DO UPDATE SET
77
84
  source = excluded.source,
78
85
  byte_size = excluded.byte_size,
79
86
  modified_at = excluded.modified_at,
80
- byte_offset = excluded.byte_offset`).run(t.sourcePath,t.source,t.cursor.byteSize,t.cursor.modifiedAt,t.cursor.byteOffset)})(e.batch)}function Io(e){if(e===null)return null;try{return Qe(JSON.parse(e))}catch{return null}}function Ao(e){return{id:e.id,sourcePath:e.source_path,source:e.source,sessionId:e.session_id,eventId:e.event_id,parentEventId:e.parent_event_id,timestamp:e.timestamp,cwd:e.cwd,gitBranch:e.git_branch,kind:e.kind,tool:e.tool_name===null?null:{toolUseId:e.tool_use_id,name:e.tool_name},isError:e.is_error===1,textRef:Io(e.text_ref)}}class be{#e;constructor(e){this.#e=e}getCursor(e){let r=this.#e.query(`SELECT source_path, byte_size, modified_at, byte_offset
81
- FROM cursors WHERE source_path = ?`).get(e);return r===null?null:{sourcePath:r.source_path,byteSize:r.byte_size,modifiedAt:r.modified_at,byteOffset:r.byte_offset}}saveBatch(e){vt({database:this.#e,batch:e})}listEvents(){return this.#e.query(`SELECT id, source_path, source, session_id, event_id,
87
+ byte_offset = excluded.byte_offset`).run(r.sourcePath,r.source,r.cursor.byteSize,r.cursor.modifiedAt,r.cursor.byteOffset)})(e.batch)}function Si(e){if(e===null)return null;try{return kt(JSON.parse(e))}catch{return null}}function Ci(e){return{id:e.id,sourcePath:e.source_path,source:e.source,sessionId:e.session_id,eventId:e.event_id,parentEventId:e.parent_event_id,timestamp:e.timestamp,cwd:e.cwd,gitBranch:e.git_branch,kind:e.kind,tool:e.tool_name===null?null:{toolUseId:e.tool_use_id,name:e.tool_name},isError:e.is_error===1,textRef:Si(e.text_ref)}}class je{#e;constructor(e){this.#e=e}getCursor(e){let t=this.#e.query(`SELECT source_path, byte_size, modified_at, byte_offset
88
+ FROM cursors WHERE source_path = ?`).get(e);return t===null?null:{sourcePath:t.source_path,byteSize:t.byte_size,modifiedAt:t.modified_at,byteOffset:t.byte_offset}}saveBatch(e){en({database:this.#e,batch:e})}listEvents(){return this.#e.query(`SELECT id, source_path, source, session_id, event_id,
82
89
  parent_event_id, timestamp, cwd, git_branch, kind, tool_use_id,
83
90
  tool_name, is_error, text_ref
84
- FROM events ORDER BY source, session_id, id`).all().map(Ao)}getCorpusSummary(){return this.#e.query(`SELECT
91
+ FROM events ORDER BY source, session_id, id`).all().map(Ci)}getCorpusSummary(){return this.#e.query(`SELECT
85
92
  (SELECT COUNT(*) FROM (
86
93
  SELECT DISTINCT source, session_id FROM events
87
94
  )) AS sessions,
@@ -89,21 +96,27 @@ ${i.map((s)=>s.content).join(`
89
96
  (SELECT COUNT(*) FROM (
90
97
  SELECT DISTINCT date(timestamp / 1000, 'unixepoch')
91
98
  FROM events WHERE timestamp > 0
92
- )) AS activeDays`).get()??{sessions:0,bytes:0,activeDays:0}}countEvents(){return this.#e.query("SELECT COUNT(*) AS count FROM events").get()?.count??0}countSessions(){return this.getCorpusSummary().sessions}close(){this.#e.close()}}async function xe(e){await Do(Oo.dirname(e),{recursive:!0});let r=new To(e,{create:!0});return Pt(r),new be(r)}async function Et(e){let r=0,t=0,n=0,o=0;for await(let i of Rt({config:e.config,paths:e.paths,getCursor:(s)=>e.index.getCursor(s)}))e.index.saveBatch(i),r+=1,t+=i.events.length,n+=i.bytesRead,o+=i.rescanned?1:0;return{files:r,events:t,sessions:e.index.countSessions(),bytesRead:n,rescannedFiles:o}}async function Ct(e){let r=await he({sourcePath:e.sourcePath,cursor:e.index.getCursor(e.sourcePath)});if(r===null)return 0;return e.index.saveBatch(r),r.events.length}async function kt(e){let r=e.index.listEvents(),t=await ue({events:r,corpus:e.index.getCorpusSummary(),gitMetadataEnabled:e.config.sources["git-metadata"],readRemote:e.readRemote,blockedOrigins:e.blockedOrigins}),n=G({events:t.events,signals:t.corrections,origins:t.origins});await J({paths:e.paths,rules:n})}async function Bo(e){let r,t;try{[r,t]=await Promise.all([St(e.filePath),St(e.directory)])}catch{return!1}let n=er.relative(t,r);return n.length>0&&!n.startsWith(`..${er.sep}`)&&n!==".."&&!er.isAbsolute(n)}async function rr(e){let r=e.paths??h,{config:t,policy:n}=await v({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?r.managedConfigFile:e.managedConfigPath});if(!n.enabled||!t.sources["claude-code"])return;let o=fe(pe(e.input),"transcript_path");if(o===null||!await Bo({filePath:o,directory:r.claudeProjectsDirectory}))throw Error("Session hook received an invalid transcript path");let i=await xe(r.indexDatabase);try{await Ct({index:i,sourcePath:o}),await kt({index:i,config:t,paths:r,readRemote:e.readRemote,blockedOrigins:n.blockedOrigins})}finally{i.close()}}var _o=[{id:"antigravity",question:"Enable Antigravity CLI transcripts?"},{id:"claude-code",question:"Enable Claude Code transcripts?"},{id:"claude-prompts",question:"Enable Claude prompt history?"},{id:"codex",question:"Enable Codex transcripts?"},{id:"cursor",question:"Enable Cursor CLI chat stores?"},{id:"shell",question:"Enable shell history?"}];function Fo(e){return prompt(`${e} [y/N]`)?.trim().toLowerCase()==="y"}async function Re(e={}){await Me({config:T,configPath:e.configPath});let r=e.ask??Fo,t=T,n=!1;for(let d of _o){let u=await r(d.question);t=Ne({config:t,source:d.id,enabled:u}),n=n||u}let o=await r("Enable reading git remote origins for organization-scoped profiles?"),i=await r("Enable semantic distillation through your authenticated agent CLI?"),s=Ne({config:t,source:"git-metadata",enabled:o}),a=Or({config:s,enabled:i});await Me({config:a,configPath:e.configPath}),console.log(n||o||i?"Selected sources and capabilities enabled.":"All capture sources remain disabled.")}import{mkdir as jo}from"fs/promises";import tr from"path";async function Pe(e={}){let r=e.cwd??process.cwd(),t=e.paths??h,{config:n,policy:o}=await v({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?t.managedConfigFile:e.managedConfigPath});if(!o.enabled)throw Error("Shadowclone is disabled by managed policy");let i=await O({cwd:r,enabled:n.sources["git-metadata"],readRemote:e.readRemote});if(C({origin:i,cwd:r,patterns:o.blockedOrigins}))throw Error("Managed policy blocks this repository");let s=await z({profileDirectory:t.profileDirectory,outputPath:t.compiledProfileFile,origin:i,targetRepo:tr.basename(r)});await $e({targetDirectory:r,profile:s});let a=tr.join(r,".claude","skills","shadowclone");await jo(a,{recursive:!0});let d=["---","name: shadowclone","description: How to delegate tasks to the shadowclone subagent","---","",'When the user asks you to perform a task using shadowclone, or if you believe the task is complex enough to delegate, use the `Agent` tool with `subagent_type: "shadowclone"` to spawn a clone.',"Pass the user's request verbatim in the tool prompt."].join(`
93
- `);await Bun.write(tr.join(a,"SKILL.md"),d),console.log("Installed .claude/agents/shadowclone.md for this repository.")}import Mo from"os";import{Database as No}from"bun:sqlite";var nr=[{label:"pem-block",pattern:/-----BEGIN [^-]+-----[\s\S]*?-----END [^-]+-----/g,replacement:"[redacted:pem-block]"},{label:"authorization-header",pattern:/(Authorization\s*:\s*)(?:Bearer|Basic|Token)\s+[A-Za-z0-9._~+/=-]+/gi,replacement:"$1[redacted:authorization]"},{label:"llm-api-key",pattern:/\bsk-[A-Za-z0-9_-]{12,}/g,replacement:"[redacted:llm-api-key]"},{label:"github-token",pattern:/\b(?:gh[porsu]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,})/g,replacement:"[redacted:github-token]"},{label:"slack-token",pattern:/\bxox[abprs]-[A-Za-z0-9-]{10,}/g,replacement:"[redacted:slack-token]"},{label:"aws-access-key-id",pattern:/\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,replacement:"[redacted:aws-access-key-id]"},{label:"jwt",pattern:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]+/g,replacement:"[redacted:jwt]"},{label:"secret-assignment",pattern:/\b([A-Za-z_][A-Za-z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|CREDENTIALS)[A-Za-z0-9_]*)(\s*=\s*)(?:"[^"\n]+"|'[^'\n]+'|[^\s"'[\n]+)/gi,replacement:"$1$2[redacted:secret-assignment]"},{label:"database-url",pattern:/\b(?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis):\/\/[^\s"'`]+/gi,replacement:"[redacted:database-url]"},{label:"email-address",pattern:/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi,replacement:"[redacted:email-address]"},{label:"private-ip",pattern:/\b(?:10(?:\.\d{1,3}){3}|192\.168(?:\.\d{1,3}){2}|172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2})\b/g,replacement:"[redacted:private-ip]"},{label:"internal-hostname",pattern:/\b(?:[a-z0-9-]+\.)+(?:internal|corp|local)\b/gi,replacement:"[redacted:internal-hostname]"},{label:"cloud-resource",pattern:/\b(?:arn:aws:[^\s"'`]+|(?:s3|gs):\/\/[a-z0-9][a-z0-9._-]{2,}[^\s"'`]*)/gi,replacement:"[redacted:cloud-resource]"},{label:"absolute-path",pattern:/(^|[\s("'=])\/(?:Users|home|private|var|opt|etc|srv|Volumes)\/[^\s"'`),]+/gm,replacement:"$1[redacted:absolute-path]"},{label:"high-entropy-string",pattern:/\b(?=[A-Za-z0-9+/_=-]{40,}\b)(?=[A-Za-z0-9+/_=-]*[A-Z])(?=[A-Za-z0-9+/_=-]*[a-z])(?=[A-Za-z0-9+/_=-]*\d)[A-Za-z0-9+/_=-]+\b/g,replacement:"[redacted:high-entropy-string]"}];function It(e){let r=e.homeDirectory??Mo.homedir(),t=r?e.text.replaceAll(r,"~"):e.text;for(let n of nr)t=t.replace(n.pattern,n.replacement);return t}var Yl=nr.map((e)=>e.label);function $o(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Lo(e){let r=e.value;for(let t of e.path){if(typeof t==="number"){if(!Array.isArray(r))return null;r=r[t];continue}if(!$o(r))return null;r=r[t]}return r}function Uo(e){if(e.unwrap===null)return e.text;return e.text.match(/<user_query>\s*([\s\S]*?)\s*<\/user_query>/)?.[1]??""}async function qo(e){if(!await Bun.file(e.sourcePath).exists())return"";let r=null;try{r=new No(e.sourcePath,{readonly:!0,strict:!0});let t=r.query("SELECT data FROM blobs WHERE id = ?").get(e.blobId);if(t===null)return"";let n=JSON.parse(new TextDecoder().decode(t.data)),o=Lo({value:n,path:e.jsonPath});return typeof o==="string"?Uo({text:o,unwrap:e.unwrap}):""}catch{return""}finally{r?.close()}}async function or(e){if(e.ref.type==="sqlite-blob"){let n=await qo(e.ref);return It({text:n})}let r=Bun.file(e.ref.sourcePath);if(!await r.exists()||r.size<e.ref.byteOffset+e.ref.byteLength)return"";let t=await r.slice(e.ref.byteOffset,e.ref.byteOffset+e.ref.byteLength).text();return It({text:t})}function W(e){let r=e.batchSize??20;if(!Number.isInteger(r)||r<1)throw Error("Distillation batch size must be a positive integer");let t=[],n=Map.groupBy(e.signals,(o)=>o.origin.id);for(let o of n.values()){let[i]=o;if(!i)continue;for(let s=0;s<o.length;s+=r)t.push({origin:i.origin,signals:o.slice(s,s+r)})}return t}async function ir(e){if(new Set(e.signals.map((o)=>o.origin.id)).size>1)throw Error("A distillation request must contain one origin");let t=e.maxExcerptCharacters??4000,n=[];for(let o of e.signals){let i=[];for(let s of o.textRefs){let a=await or({ref:s});if(a.length>0)i.push(a.slice(0,t))}n.push([`Kind: ${o.kind}`,`Pattern: ${o.label}`,...i.map((s)=>`Excerpt:
94
- ${s}`)].join(`
99
+ )) AS activeDays`).get()??{sessions:0,bytes:0,activeDays:0}}countEvents(){return this.#e.query("SELECT COUNT(*) AS count FROM events").get()?.count??0}countSessions(){return this.getCorpusSummary().sessions}close(){this.#e.close()}}async function M(e){await Ai(Ti.dirname(e),{recursive:!0});let t=new Ii(e,{create:!0});return Qr(t),new je(t)}async function tn(e){let t=0,r=0,n=0,o=0;for await(let s of Yr({config:e.config,paths:e.paths,getCursor:(i)=>e.index.getCursor(i)}))e.index.saveBatch(s),t+=1,r+=s.events.length,n+=s.bytesRead,o+=s.rescanned?1:0;return{files:t,events:r,sessions:e.index.countSessions(),bytesRead:n,rescannedFiles:o}}async function rn(e){let t=await Oe({sourcePath:e.sourcePath,cursor:e.index.getCursor(e.sourcePath)});if(t===null)return 0;return e.index.saveBatch(t),t.events.length}function Di(){return Ce.map((e)=>{let t=Ie(e);return`${e.id}: observe=${t.observe?"yes":"no"}, distill=${t.distill?"yes":"no"}, dispatch=${t.dispatch?"yes":"no"}`})}function Bi(e){if(e.distillation==="disabled")return"Deep distillation is disabled by managed policy.";if(e.distillation==="local-only")return"Deep distillation is restricted to local engines, which are not implemented.";return e.selectedEngine?`Selected engine: ${e.selectedEngine}`:"No authenticated distillation engine is available."}function Oi(e){if(e.health.length===0)return["No indexed sessions yet."];return e.health.map((t)=>{let r=t.isStale?" (POSSIBLY STALE: 0 signals across 25+ sessions)":"";return`${t.source}: ${t.sessions} sessions, ${t.interruptions} interruptions, ${t.denials} denials${r}`})}async function nn(e={}){let t=e.managedConfigPath===void 0?h.managedConfigFile:e.managedConfigPath,r=await re(t);if(t!==null&&await Bun.file(t).exists())console.log(`Managed policy: ${t}`);if(!r.enabled){console.log("Managed policy: shadowclone is disabled.");return}let n=r.distillation==="allowed"?r.allowedEngines:[],o=await B({purpose:"distill",probe:e.probe,allowedEngines:n});for(let i of o.availability){let a=i.authenticated?"authenticated":i.installed?"installed, authentication not found":"not installed";console.log(`${i.engine}: ${a}`)}console.log(Bi({distillation:r.distillation,selectedEngine:o.selectedEngine})),console.log("Provider support:");for(let i of Di())console.log(i);if(await Bun.file(e.databasePath??h.indexDatabase).exists()){let i=await M(e.databasePath??h.indexDatabase);try{let a=i.listEvents(),l=ve(a);console.log("Marker health:");for(let d of Oi({health:l}))console.log(` ${d}`)}finally{i.close()}}}import Et from"path";var on=new Set(["Edit","Write","NotebookEdit"]),sn=new Set(["ExitPlanMode","TodoWrite","Plan","EnterPlanMode"]);function an(e){let t=Et.posix.normalize(e.rawPath.replaceAll("\\","/"));if(e.cwd){let r=Et.posix.normalize(e.cwd.replaceAll("\\","/"));if(t.startsWith(r))return Et.posix.relative(r,t)}return t}function ln(e){return e.trim().split(/\s+/).filter(Boolean).slice(0,2).join(" ")}function Me(e){let t=[...new Set(e.actions.map((a)=>a.tool))],r=[],n=[],o=!1,s=!1,i=!1;for(let a of e.actions){if(sn.has(a.tool))i=!0;if(on.has(a.tool)){if(!s)o=i,s=!0;if(a.path)r.push(an({rawPath:a.path,cwd:e.cwd}))}if(a.tool==="Bash"&&a.command){let l=ln(a.command);if(l.length>0)n.push(l)}}return{tools:t,verificationSteps:[...new Set(n)],filesTouched:[...new Set(r)],plannedBeforeEditing:o}}function St(e){let t=[...new Set(e.events.flatMap((s)=>s.kind==="tool-call"&&s.tool?.name?[s.tool.name]:[]))],r=!1,n=!1,o=!1;for(let s of e.events){let i=s.tool?.name;if(s.kind==="plan-presented"||s.kind==="plan-resolved"||i&&sn.has(i))o=!0;if(i&&on.has(i)){if(!n)r=o,n=!0}}return{tools:t,verificationSteps:[],filesTouched:null,plannedBeforeEditing:r}}import{mkdir as Gi,mkdtemp as mn,rm as gn}from"fs/promises";import yn from"os";import me from"path";import _i from"os";import{Database as ji}from"bun:sqlite";function E(e,t){return(r)=>{if(t<=0)return`[redacted:${e}]`;return`${r.slice(0,t)}...[redacted:${e}]`}}function de(e,t){return(r,n)=>{let o=n??"";if(t<=0)return`${o}[redacted:${e}]`;let i=r.slice(o.length).slice(0,t);return`${o}${i}...[redacted:${e}]`}}function cn(e,t){return(r,n,o)=>{let s=n??"",i=o??"",a=s.length+i.length;if(t<=0)return`${s}${i}[redacted:${e}]`;let d=r.slice(a).slice(0,t);return`${s}${i}${d}...[redacted:${e}]`}}var Ct=[{label:"pem-block",pattern:/-----BEGIN [^-]+-----[\s\S]*?-----END [^-]+-----/g,replace:E("pem-block",0)},{label:"authorization-header",pattern:/(Authorization\s*:\s*)(?:Bearer|Basic|Token)\s+[A-Za-z0-9._~+/=-]+/gi,replace:de("authorization",0)},{label:"stripe-key",pattern:/\b[sr]k_(?:live|test)_[A-Za-z0-9]{20,}\b/g,replace:E("stripe-key",8)},{label:"google-api-key",pattern:/\bAIza[0-9A-Za-z_-]{35}\b/g,replace:E("google-api-key",4)},{label:"llm-api-key",pattern:/\bsk-[A-Za-z0-9_-]{12,}\b/g,replace:E("llm-api-key",7)},{label:"github-token",pattern:/\b(?:gh[porsu]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,})\b/g,replace:E("github-token",7)},{label:"slack-token",pattern:/\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g,replace:E("slack-token",7)},{label:"aws-access-key-id",pattern:/\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,replace:E("aws-access-key-id",4)},{label:"jwt",pattern:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]+/g,replace:E("jwt",0)},{label:"hex-secret",pattern:/\b[0-9a-f]{32,}\b/gi,replace:E("hex-secret",7)},{label:"secret-assignment",pattern:/\b([A-Za-z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|CREDENTIALS|AUTH)(?:_[A-Za-z0-9]+)?)(\s*[:=]\s*)(?:\\"[^"\\\n]+\\"|\\'[^'\\\n]+\\'|"(?:\\.|[^"\\\n])+"|'(?:\\.|[^'\\\n])+'|[^\s"'[\n]+)/gi,replace:cn("secret-assignment",0)},{label:"database-url",pattern:/\b((?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis):\/\/)[^\s"'`]+/gi,replace:de("database-url",0)},{label:"git-remote",pattern:/\b(?:ssh:\/\/)?git@([A-Za-z0-9.-]+):[A-Za-z0-9._\/-]+(?:\.git)?\b/g,replace:(e,t)=>`git@${t??""}:[redacted:git-remote]`},{label:"email-address",pattern:/\b(?!git@)[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi,replace:E("email-address",0)},{label:"ip-address",pattern:/\b(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}(?::\d{1,5})?\b/g,replace:E("ip-address",0)},{label:"internal-hostname",pattern:/\b(?:[a-z0-9-]+\.)+(?:internal|corp|local)\b/gi,replace:E("internal-hostname",0)},{label:"cloud-resource",pattern:/\b(arn:aws:|(?:s3|gs):\/\/)[^\s"'`]+/gi,replace:de("cloud-resource",0)},{label:"windows-path",pattern:/\b[A-Za-z]:(?:\/|\\{1,2})Users(?:\/|\\{1,2})[^\s"'`<>|]+/g,replace:E("windows-path",0)},{label:"absolute-path",pattern:/(^|[\s("'=])\/(?:Users|home|private|var|opt|etc|srv|Volumes|mnt|root|data|workspace)\/[^\s"'`),]+/gm,replace:de("absolute-path",0)},{label:"high-entropy-string",pattern:/\b(?=[A-Za-z0-9+/_=-]{40,}\b)(?=[A-Za-z0-9+/_=-]*(?:\d|[A-Z].*[a-z]|[a-z].*[A-Z]))[A-Za-z0-9+/_=-]+\b/g,replace:E("high-entropy-string",7)}];function Mi(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Fi(e){if(e.homeDirectory.length===0)return e.text;let t=Mi(e.homeDirectory),r=["file:","",""].join("/"),n=t.startsWith("/")?t.slice(1):t,o=new RegExp(`(${r}/?)${n}(?=[/\\\\\\s"'\\),]|$)`,"gm"),s=new RegExp(`(^|[\\s"'\\(=:,])${t}(?=[/\\\\\\s"'\\),]|$)`,"gm");return e.text.replace(o,"$1~").replace(s,"$1~")}function dn(e){let t=e.homeDirectory??_i.homedir(),r=t?Fi({text:e.text,homeDirectory:t}):e.text;for(let n of Ct)r=r.replace(n.pattern,n.replace);return r}var Kc=Ct.map((e)=>e.label);function $i(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Ni(e){let t=e.value;for(let r of e.path){if(typeof r==="number"){if(!Array.isArray(t))return null;t=t[r];continue}if(!$i(t))return null;t=t[r]}return t}function Li(e){if(e.unwrap===null)return e.text;return e.text.match(/<user_query>\s*([\s\S]*?)\s*<\/user_query>/)?.[1]??""}async function Ui(e){if(!await Bun.file(e.sourcePath).exists())return"";let t=null;try{t=new ji(e.sourcePath,{readonly:!0,strict:!0});let r=t.query("SELECT data FROM blobs WHERE id = ?").get(e.blobId);if(r===null)return"";let n=JSON.parse(new TextDecoder().decode(r.data)),o=Ni({value:n,path:e.jsonPath});return typeof o==="string"?Li({text:o,unwrap:e.unwrap}):""}catch{return""}finally{t?.close()}}async function ue(e){if(e.ref.type==="sqlite-blob"){let n=await Ui(e.ref);return dn({text:n})}let t=Bun.file(e.ref.sourcePath);if(!await t.exists()||t.size<e.ref.byteOffset+e.ref.byteLength)return"";let r=await t.slice(e.ref.byteOffset,e.ref.byteOffset+e.ref.byteLength).text();return dn({text:r})}function qi(e){return y(e)&&e.type==="text"&&typeof e.text==="string"}function un(e){if(typeof e==="string"){let o=(e.match(/<USER_REQUEST>([\s\S]*?)<\/USER_REQUEST>/)?.[1]??e).trim();return o.length>0?o:null}if(!Array.isArray(e))return null;let t=e.find(qi),r=t?t.text.trim():"";return r.length>0?r:null}function pn(e){try{let r=JSON.parse(e);if(typeof r==="string"){let n=r.trim();return n.length>0?n:null}if(y(r)){let n=un(r.content);if(n!==null)return n;if(y(r.message)){let o=un(r.message.content);if(o!==null)return o}return null}}catch{let r=e.trim();return r.length>0?r:null}let t=e.trim();return t.length>0?t:null}import zi from"path";function fn(e){return zi.posix.normalize(e.replaceAll("\\","/"))}function It(e,t){if(e===null||t===null)return null;let r=new Set(e.map(fn)),n=new Set(t.map(fn)),o=new Set([...r,...n]);if(o.size===0)return null;return[...r].filter((i)=>n.has(i)).length/o.size}function fe(e){let t=It(e.actual.tools,e.clone.tools)??0,r=It(e.actual.verificationSteps,e.clone.verificationSteps),n=It(e.actual.filesTouched,e.clone.filesTouched),o=e.actual.plannedBeforeEditing===e.clone.plannedBeforeEditing?1:0,s=[t,o];if(r!==null)s.push(r);if(n!==null)s.push(n);let i=s.reduce((l,d)=>l+d,0),a=s.length>0?i/s.length:0;return{tools:t,verification:r,files:n,planning:o,total:a}}function At(e){let t=(r,n)=>{if(r===null||n===null)return null;return r-n};return{tools:e.clone.tools-e.baseline.tools,verification:t(e.clone.verification,e.baseline.verification),files:t(e.clone.files,e.baseline.files),planning:e.clone.planning-e.baseline.planning,total:e.clone.total-e.baseline.total}}function pe(e){let t=e.filter((r)=>r!==null);return t.length>0?t.reduce((r,n)=>r+n,0)/t.length:null}function Fe(e){return{tools:pe(e.map((t)=>t.tools))??0,verification:pe(e.map((t)=>t.verification)),files:pe(e.map((t)=>t.files)),planning:pe(e.map((t)=>t.planning))??0,total:pe(e.map((t)=>t.total))??0}}var Ji={id:"global",directoryName:"global",promotable:!0};async function Tt(e={}){let t=e.paths??h,{policy:r}=await S({configPath:e.configPath,managedConfigPath:t.managedConfigFile});if(!r.enabled)throw Error("Shadowclone is disabled by managed policy");let n=e.runner?null:await B({purpose:"dispatch",allowedEngines:r.allowedEngines}),o=e.runner??n?.runner;if(!o)throw Error("No authenticated agent engine is available for eval");let s=await M(t.indexDatabase),i=s.listEvents();s.close();let a=Map.groupBy(i,(f)=>f.sessionId),l=e.since?Date.parse(e.since):0,d=[...a.entries()].filter(([f,w])=>Boolean(w?.[0]&&w[0].timestamp>=l&&w.some((b)=>b.kind==="user-prompt"&&b.textRef!==null))).slice(0,e.sessions??10),u=crypto.randomUUID(),p=me.join(t.shadowcloneDirectory,"eval",u);await Gi(p,{recursive:!0});let m=me.join(p,"profile.md");await L({profileDirectory:t.profileDirectory,outputPath:m,origin:Ji});let g=0,R=[];for(let[f,w]of d){let b=w.find((H)=>H.kind==="user-prompt"&&H.textRef!==null);if(!b?.textRef)continue;let A=await ue({ref:b.textRef}),O=pn(A);if(!O)continue;let ee=St({events:w}),te=await mn(me.join(yn.tmpdir(),"shadowclone-eval-base-")),qt=await mn(me.join(yn.tmpdir(),"shadowclone-eval-clone-")),ze,Ge,zt="",Gt="";try{let H=await o({prompt:O,cwd:te,sessionId:crypto.randomUUID(),permissionMode:"dontAsk",maxBudgetUsd:e.maxBudgetUsd??0.5});if(H.isError){g+=1,console.warn(`Skipping session ${f}: baseline replay failed`);continue}zt=H.sessionId;let zn=Me({actions:H.actions??[]});ze=fe({actual:ee,clone:zn});let Je=await o({prompt:O,cwd:qt,systemPromptFile:m,sessionId:crypto.randomUUID(),permissionMode:"dontAsk",maxBudgetUsd:e.maxBudgetUsd??0.5});if(Je.isError){g+=1,console.warn(`Skipping session ${f}: clone replay failed`);continue}Gt=Je.sessionId;let Gn=Me({actions:Je.actions??[]});Ge=fe({actual:ee,clone:Gn})}finally{await gn(te,{recursive:!0,force:!0}),await gn(qt,{recursive:!0,force:!0})}let qn=At({baseline:ze,clone:Ge});R.push({sessionId:f,baselineSessionId:zt,cloneSessionId:Gt,prompt:O,baseline:ze,clone:Ge,delta:qn})}let P={evalId:u,timestamp:new Date().toISOString(),sessionsEvaluated:R.length,sessionsSkipped:g,averageBaseline:Fe(R.map((f)=>f.baseline)),averageClone:Fe(R.map((f)=>f.clone)),averageDelta:Fe(R.map((f)=>f.delta)),sessions:R},x=me.join(t.shadowcloneDirectory,"eval",`${u}.json`);if(await Bun.write(x,JSON.stringify(P,null,2)),e.json)console.log(JSON.stringify(P,null,2));else console.log(`Evaluated ${P.sessionsEvaluated} sessions.`),console.log(`Total delta: ${(P.averageDelta.total*100).toFixed(1)}% (${(P.averageBaseline.total*100).toFixed(1)}% -> ${(P.averageClone.total*100).toFixed(1)}%)`),console.log(`Receipt: ${x}`);return P}function Hi(e){return prompt(`${e} [y/N]`)?.trim().toLowerCase()==="y"}async function hn(e,t={}){let r,n,o=!1,s,i=!1;for(let p=0;p<e.length;p++){let m=e[p];if(m==="--json")o=!0;else if(m==="--yes"||m==="-y")i=!0;else if(m==="--sessions"&&p+1<e.length){p++;let g=Number.parseInt(e[p]??"",10);if(!Number.isNaN(g))r=g}else if(m==="--since"&&p+1<e.length)p++,n=e[p];else if(m==="--max-budget-usd"&&p+1<e.length){p++;let g=Number.parseFloat(e[p]??"");if(!Number.isNaN(g))s=g}}let a=r??10,l=s??0.5,d=a*2*l,u=t.ask??Hi;if(!i&&!o&&process.stdin.isTTY){let p=`Running eval on up to ${a} sessions (2 runs each, max $${d.toFixed(2)} budget). Proceed?`;if(!await u(p)){console.log("Evaluation cancelled.");return}}await Tt({sessions:r,since:n,json:o,maxBudgetUsd:s,runner:t.runner,paths:t.paths})}import{rm as Wi}from"fs/promises";async function wn(e=h.shadowcloneDirectory){await Wi(e,{recursive:!0,force:!0}),console.log("Removed all shadowclone data.")}import Xi from"path";function Ki(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function $e(e){let t=JSON.parse(e);if(!Ki(t))throw Error("Hook input must be a JSON object");return t}function Ne(e,t){let r=e[t];return typeof r==="string"?r:null}async function Zi(e){let t=e.paths??h,{config:r,policy:n}=await S({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?t.managedConfigFile:e.managedConfigPath});if(!n.enabled)return null;let o=$e(e.input),s=Ne(o,"cwd")??process.cwd(),i=await D({cwd:s,enabled:r.sources["git-metadata"],readRemote:e.readRemote});if(I({origin:i,cwd:s,patterns:n.blockedOrigins}))return null;return{profile:await X({profileDirectory:t.profileDirectory,origin:i,targetRepo:Xi.basename(s)})}}async function bn(e){let t=await Zi(e);return t===null?null:{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:t.profile}}}async function Dt(e){let t=await bn(e);if(t!==null)await Bun.stdout.write(`${JSON.stringify(t)}
100
+ `)}import{realpath as Rn}from"fs/promises";import Bt from"path";async function xn(e){let t=e.index.listEvents(),r=await ke({events:t,corpus:e.index.getCorpusSummary(),gitMetadataEnabled:e.config.sources["git-metadata"],readRemote:e.readRemote,blockedOrigins:e.blockedOrigins}),n=ie({events:r.events,signals:r.corrections,origins:r.origins});await se({paths:e.paths,rules:n})}async function Vi(e){let t,r;try{[t,r]=await Promise.all([Rn(e.filePath),Rn(e.directory)])}catch{return!1}let n=Bt.relative(r,t);return n.length>0&&!n.startsWith(`..${Bt.sep}`)&&n!==".."&&!Bt.isAbsolute(n)}async function Ot(e){let t=e.paths??h,{config:r,policy:n}=await S({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?t.managedConfigFile:e.managedConfigPath});if(!n.enabled||!r.sources["claude-code"])return;let o=Ne($e(e.input),"transcript_path");if(o===null||!await Vi({filePath:o,directory:t.claudeProjectsDirectory}))throw Error("Session hook received an invalid transcript path");let s=await M(t.indexDatabase);try{await rn({index:s,sourcePath:o}),await xn({index:s,config:r,paths:t,readRemote:e.readRemote,blockedOrigins:n.blockedOrigins})}finally{s.close()}}var Yi=[{id:"antigravity",question:"Enable Antigravity CLI transcripts?"},{id:"claude-code",question:"Enable Claude Code transcripts?"},{id:"claude-prompts",question:"Enable Claude prompt history?"},{id:"codex",question:"Enable Codex transcripts?"},{id:"cursor",question:"Enable Cursor CLI chat stores?"},{id:"shell",question:"Enable shell history?"}];function Qi(e){return prompt(`${e} [y/N]`)?.trim().toLowerCase()==="y"}async function Le(e={}){await Ze({config:F,configPath:e.configPath});let t=e.ask??Qi,r=F,n=!1;for(let l of Yi){let d=await t(l.question);r=Ve({config:r,source:l.id,enabled:d}),n=n||d}let o=await t("Enable reading git remote origins for organization-scoped profiles?"),s=await t("Enable semantic distillation through your authenticated agent CLI?"),i=Ve({config:r,source:"git-metadata",enabled:o}),a=Vt({config:i,enabled:s});await Ze({config:a,configPath:e.configPath}),console.log(n||o||s?"Selected sources and capabilities enabled.":"All capture sources remain disabled.")}import{mkdir as Pn}from"fs/promises";import V from"path";async function es(e){let t=Bun.spawn({cmd:["git","-C",e,"rev-parse","--git-path","info/exclude"],stdout:"pipe",stderr:"ignore"});if(await t.exited!==0)return;let r=(await new Response(t.stdout).text()).trim();if(r.length===0)return;let n=V.isAbsolute(r)?r:V.resolve(e,r),o=Bun.file(n),s=await o.exists()?await o.text():"",a=[".claude/agents/shadowclone.md",".claude/skills/shadowclone/"].filter((d)=>!s.includes(d));if(a.length===0)return;await Pn(V.dirname(n),{recursive:!0});let l=s.length>0&&!s.endsWith(`
101
+ `)?`${s}
102
+ `:s;await Bun.write(n,`${l}${a.join(`
103
+ `)}
104
+ `)}async function Ue(e={}){let t=e.cwd??process.cwd(),r=e.paths??h,{config:n,policy:o}=await S({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?r.managedConfigFile:e.managedConfigPath});if(!o.enabled)throw Error("Shadowclone is disabled by managed policy");let s=await D({cwd:t,enabled:n.sources["git-metadata"],readRemote:e.readRemote});if(I({origin:s,cwd:t,patterns:o.blockedOrigins}))throw Error("Managed policy blocks this repository");let i=await L({profileDirectory:r.profileDirectory,outputPath:r.compiledProfileFile,origin:s,targetRepo:V.basename(t)});await Ye({targetDirectory:t,profile:i});let a=V.join(t,".claude","skills","shadowclone");await Pn(a,{recursive:!0});let l=["---","name: shadowclone","description: How to delegate tasks to the shadowclone subagent","---","",'When the user asks you to perform a task using shadowclone, or if you believe the task is complex enough to delegate, use the `Agent` tool with `subagent_type: "shadowclone"` to spawn a clone.',"Pass the user's request verbatim in the tool prompt."].join(`
105
+ `);await Bun.write(V.join(a,"SKILL.md"),l),await es(t),console.log("Installed .claude/agents/shadowclone.md for this repository.")}function ge(e){let t=e.batchSize??20;if(!Number.isInteger(t)||t<1)throw Error("Distillation batch size must be a positive integer");let r=[],n=Map.groupBy(e.signals,(o)=>o.origin.id);for(let o of n.values()){let[s]=o;if(!s)continue;for(let i=0;i<o.length;i+=t)r.push({origin:s.origin,signals:o.slice(i,i+t)})}return r}async function _t(e){if(new Set(e.signals.map((o)=>o.origin.id)).size>1)throw Error("A distillation request must contain one origin");let r=e.maxExcerptCharacters??4000,n=[];for(let o of e.signals){let s=[];for(let i of o.textRefs){let a=await ue({ref:i});if(a.length>0)s.push(a.slice(0,r))}n.push([`Kind: ${o.kind}`,`Pattern: ${o.label}`,...s.map((i)=>`Excerpt:
106
+ ${i}`)].join(`
95
107
  `))}return["Turn these correction moments into short, reusable engineering rules.","Use only the evidence shown. Do not repeat secrets or private identifiers.","Return JSON matching the supplied schema.","",n.join(`
96
108
 
97
109
  `)].join(`
98
- `)}import{mkdir as zo}from"fs/promises";import At from"path";function Tt(e){let r=e.signals.map((t)=>({kind:t.kind,sessionId:t.sessionId,timestamp:t.timestamp,refs:t.textRefs}));return new Bun.CryptoHasher("sha256").update(`${e.origin.id}:${JSON.stringify(r)}`).digest("hex").slice(0,24)}async function Dt(e){let r=Bun.file(At.join(e.checkpointDirectory,`${Tt(e.batch)}.json`));if(!await r.exists())return null;let t=await r.json();return Array.isArray(t)?t.filter(Go):null}function Go(e){if(typeof e!=="object"||e===null||Array.isArray(e))return!1;let r="origins"in e&&Array.isArray(e.origins)?e.origins:null;return"key"in e&&typeof e.key==="string"&&"title"in e&&typeof e.title==="string"&&"body"in e&&typeof e.body==="string"&&"section"in e&&(e.section==="engineering"||e.section==="workflow"||e.section==="boundaries")&&"scope"in e&&(e.scope==="global"||e.scope==="org")&&"originDirectory"in e&&(typeof e.originDirectory==="string"||e.originDirectory===null)&&"observations"in e&&typeof e.observations==="number"&&"confidence"in e&&typeof e.confidence==="number"&&"lastSeen"in e&&typeof e.lastSeen==="string"&&"sessions"in e&&typeof e.sessions==="number"&&r?.every((t)=>typeof t==="string")===!0}async function Ot(e){await zo(e.checkpointDirectory,{recursive:!0}),await Bun.write(At.join(e.checkpointDirectory,`${Tt(e.batch)}.json`),`${JSON.stringify(e.rules,null,2)}
99
- `)}var M={type:"object",additionalProperties:!1,required:["rules"],properties:{rules:{type:"array",maxItems:8,items:{type:"object",additionalProperties:!1,required:["title","body","section"],properties:{title:{type:"string",maxLength:120},body:{type:"string",maxLength:600},section:{type:"string",enum:["engineering","workflow","boundaries"]}}}}}};function Bt(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function _t(e,r){return e.replaceAll("<!--","").replaceAll("-->","").replace(/\s+/g," ").trim().slice(0,r)}function Jo(e){return e==="engineering"||e==="workflow"||e==="boundaries"?e:null}function X(e){if(!Bt(e)||!Array.isArray(e.rules))throw Error("The engine returned an invalid distillation result");return e.rules.flatMap((r)=>{if(!Bt(r))return[];let t=Jo(r.section);if(typeof r.title!=="string"||typeof r.body!=="string"||t===null)return[];let n=_t(r.title,120),o=_t(r.body,600);return n&&o?[{title:n,body:o,section:t}]:[]})}async function Ft(e){if(e.rules.length<=1)return e.rules;let r=["You are an expert engineer. Below is a list of behavioral rules extracted from agent transcripts.","Many of these rules are duplicates, restatements, or overlap significantly.","Merge the duplicates into single, strong rules. Drop any rules that are content-free telemetry.","Output the consolidated set of rules as JSON matching the supplied schema.","",...e.rules.map((i)=>`Title: ${i.title}
110
+ `)}import{mkdir as ts}from"fs/promises";import vn from"path";function kn(e){let t=e.signals.map((r)=>({kind:r.kind,sessionId:r.sessionId,timestamp:r.timestamp,refs:r.textRefs}));return new Bun.CryptoHasher("sha256").update(`${e.origin.id}:${JSON.stringify(t)}`).digest("hex").slice(0,24)}async function En(e){let t=Bun.file(vn.join(e.checkpointDirectory,`${kn(e.batch)}.json`));if(!await t.exists())return null;let r=await t.json();return Array.isArray(r)?r.filter(rs):null}function rs(e){if(typeof e!=="object"||e===null||Array.isArray(e))return!1;let t="origins"in e&&Array.isArray(e.origins)?e.origins:null;return"key"in e&&typeof e.key==="string"&&"title"in e&&typeof e.title==="string"&&"body"in e&&typeof e.body==="string"&&"section"in e&&(e.section==="engineering"||e.section==="workflow"||e.section==="boundaries")&&"scope"in e&&(e.scope==="global"||e.scope==="org")&&"originDirectory"in e&&(typeof e.originDirectory==="string"||e.originDirectory===null)&&"observations"in e&&typeof e.observations==="number"&&"confidence"in e&&typeof e.confidence==="number"&&"lastSeen"in e&&typeof e.lastSeen==="string"&&"sessions"in e&&typeof e.sessions==="number"&&t?.every((r)=>typeof r==="string")===!0}async function Sn(e){await ts(e.checkpointDirectory,{recursive:!0}),await Bun.write(vn.join(e.checkpointDirectory,`${kn(e.batch)}.json`),`${JSON.stringify(e.rules,null,2)}
111
+ `)}var jt={type:"object",additionalProperties:!1,required:["rules"],properties:{rules:{type:"array",maxItems:8,items:{type:"object",additionalProperties:!1,required:["title","body","section"],properties:{title:{type:"string",maxLength:120},body:{type:"string",maxLength:600},section:{type:"string",enum:["engineering","workflow","boundaries"]}}}}}},qe={type:"object",additionalProperties:!1,required:["rules"],properties:{rules:{type:"array",maxItems:8,items:{type:"object",additionalProperties:!1,required:["title","body","section"],properties:{title:{type:"string",maxLength:120},body:{type:"string",maxLength:600},section:{type:"string",enum:["engineering","workflow","boundaries"]},sources:{type:"array",items:{type:"integer"}}}}}}};function Cn(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function In(e,t){return e.replaceAll("<!--","").replaceAll("-->","").replace(/\s+/g," ").trim().slice(0,t)}function ns(e){return e==="engineering"||e==="workflow"||e==="boundaries"?e:null}function Y(e){if(!Cn(e)||!Array.isArray(e.rules))throw Error("The engine returned an invalid distillation result");return e.rules.flatMap((t)=>{if(!Cn(t))return[];let r=ns(t.section);if(typeof t.title!=="string"||typeof t.body!=="string"||r===null)return[];let n=In(t.title,120),o=In(t.body,600),s=Array.isArray(t.sources)?t.sources.filter((i)=>typeof i==="number"&&Number.isInteger(i)&&i>=0):void 0;return n&&o?[{title:n,body:o,section:r,...s?{sources:s}:{}}]:[]})}import{mkdir as os}from"fs/promises";import An from"path";function is(e){let t=e.map((r)=>({title:r.title,body:r.body,section:r.section}));return new Bun.CryptoHasher("sha256").update(JSON.stringify(t)).digest("hex").slice(0,24)}async function Tn(e){if(e.rules.length<=1)return e.rules;let t=e.checkpointDirectory?An.join(e.checkpointDirectory,`merge-${is(e.rules)}.json`):null;if(t&&await Bun.file(t).exists())try{let i=await Bun.file(t).json();return Y(i)}catch{}let r=["You are an expert engineer. Below is a list of behavioral rules extracted from agent transcripts.","Many of these rules are duplicates, restatements, or overlap significantly.","Merge the duplicates into single, strong rules. Drop any rules that are content-free telemetry.","For each consolidated rule, include a `sources` array with the 0-based integer indices of the input rules it consolidated.","Output the consolidated set of rules as JSON matching the supplied schema.","",...e.rules.map((i,a)=>`[${a}] Title: ${i.title}
100
112
  Body: ${i.body}
101
113
  Section: ${i.section}
102
114
  `)].join(`
103
- `),t={...M,properties:{rules:{...M.properties.rules,maxItems:e.rules.length}}},n=await e.runner({prompt:r,cwd:e.cwd,allowedTools:[],permissionMode:"dontAsk",outputSchema:t,maxBudgetUsd:e.maxBudgetUsd});if(n.isError)return e.rules;let o=n.structured;if(!o)try{o=JSON.parse(n.text)}catch{return e.rules}try{return X(o)}catch{return e.rules}}var Ho=new Set(["user-prompt","plan-presented","plan-resolved","question-asked","question-answered","permission-denied","interruption"]);function jt(e){return Ho.has(e.kind)&&e.textRef!==null}function Z(e){let r=new Set(e.events.flatMap((n)=>jt(n)&&n.textRef?[K(n.textRef)]:[])),t=new Set(e.events.flatMap((n)=>n.kind==="assistant-text"&&n.textRef?[K(n.textRef)]:[]));return e.signals.map((n)=>({...n,textRefs:n.textRefs.filter((o)=>{let i=K(o);return r.has(i)||t.has(i)})}))}function Mt(e){let[r]=e.signals;if(!r)return[];let t=e.signals.length,n=new Set(e.signals.map((i)=>i.sessionId)).size,o=Math.max(...e.signals.map((i)=>i.timestamp));return X(e.value).map((i)=>{let s=U(i.title);return{...i,key:s,scope:"org",originDirectory:r.origin.directoryName,observations:t,confidence:1,lastSeen:o>0?new Date(o).toISOString().slice(0,10):"unknown",sessions:n,origins:[r.origin.id]}})}function Wo(e){if(e.structured!==null&&e.structured!==void 0)return e.structured;try{return JSON.parse(e.text)}catch{throw Error("The engine returned no structured distillation result")}}async function Nt(e){let r=[],t=0,n=Z({signals:e.signals,events:e.events}).filter((s)=>s.textRefs.length>0);for(let s of W({signals:n})){let a=await Dt({checkpointDirectory:e.checkpointDirectory,batch:s});if(a!==null){r.push(...a);continue}let d=await ir({signals:s.signals}),u=await e.runner({prompt:d,cwd:e.workingDirectory,allowedTools:[],permissionMode:"dontAsk",maxBudgetUsd:e.maxBudgetUsd,outputSchema:M});if(t+=1,u.isError)throw Error("The agent engine failed during distillation");let p=Mt({value:Wo(u),signals:s.signals});await Ot({checkpointDirectory:e.checkpointDirectory,batch:s,rules:p}),r.push(...p)}let o=Map.groupBy(r,(s)=>s.originDirectory),i=[];for(let[s,a]of o.entries()){if(a.length<=1){i.push(...a);continue}let d=await Ft({rules:a.map((p)=>({title:p.title,body:p.body,section:p.section})),runner:e.runner,cwd:e.workingDirectory,maxBudgetUsd:e.maxBudgetUsd});t+=1;let u=n.filter((p)=>p.origin.directoryName===s);i.push(...Mt({value:{rules:d},signals:u}))}return{rules:i,engineRuns:t}}async function Xo(e){return await Bun.spawn({cmd:["git","-C",e,"rev-parse","--is-inside-work-tree"],stdout:"ignore",stderr:"ignore"}).exited===0}async function $t(e={}){let r=e.paths??h,t=e.configPath??r.configFile;if(!await Bun.file(t).exists()){if(!process.stdin.isTTY)throw Error("No configuration found. Run shadowclone init interactively first.");console.log("No configuration found. Running shadowclone init..."),await Re({configPath:e.configPath})}let{config:o,policy:i}=await v({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?r.managedConfigFile:e.managedConfigPath});if(!i.enabled)throw Error("Shadowclone is disabled by managed policy");let s=await xe(e.databasePath??r.indexDatabase);try{let a=await Et({index:s,config:o,paths:r}),d=s.listEvents(),u=await ue({events:d,corpus:s.getCorpusSummary(),gitMetadataEnabled:o.sources["git-metadata"],readRemote:e.readRemote,blockedOrigins:i.blockedOrigins}),p=G({events:u.events,signals:u.corrections,origins:u.origins}),b=[],y=!1;if(e.deep){if(!o.distillation.deep)throw Error("Deep distillation is disabled in config");let f=Z({signals:u.corrections,events:u.events}).filter((w)=>w.textRefs.length>0),c=W({signals:f});if(console.log(`Deep distillation will run up to ${c.length} agent batches.`),c.length>0){if(i.distillation!=="allowed")throw Error("Managed policy does not allow remote distillation");let w=e.runner?null:await A({purpose:"distill",allowedEngines:i.allowedEngines}),Y=e.runner??w?.runner;if(!Y)throw Error("No authenticated agent engine is available");let ur=await Nt({signals:f,runner:Y,workingDirectory:r.shadowcloneDirectory,checkpointDirectory:r.distillDirectory,events:u.events});b=ur.rules,y=ur.engineRuns>0}}let I=[...p,...b].sort((f,c)=>c.observations-f.observations||f.title.localeCompare(c.title));if(await J({paths:r,rules:I}),console.log(Ue({report:u.report,networkCallsMade:y})),a.rescannedFiles>0)console.log(`
104
- Rescanned ${a.rescannedFiles} rewritten files.`);let R=e.targetDirectory??process.cwd();if(await Xo(R))try{await Pe({cwd:R,paths:r,configPath:e.configPath,managedConfigPath:e.managedConfigPath,readRemote:e.readRemote})}catch(f){console.log(`Skipped installing the live clone: ${f instanceof Error?f.message:"unknown error"}`)}}finally{s.close()}}import qt from"path";var Zo=["Read","Grep","Glob","Edit","Write","Bash(git status)","Bash(git diff)","Bash(bun test)","Bash(bun run typecheck)"],Lt={push:"Bash(git push:*)","pr-draft":"Bash(gh pr create --draft:*)","pr-reply":"Bash(gh pr comment:*)"},Vo=["Bash(git add:*)","Bash(git commit:*)","Bash(git push --force:*)","Bash(git push -f:*)","Bash(gh pr merge:*)"];function sr(e){let r=e.configuredPolicy??{allow:[],maxBudgetUsd:2,requireCleanExit:!0},t=e.managedActionTier==="act"?r.allow:[],n=k.filter((a)=>t.includes(a)&&e.approvedActions.includes(a)),o=[...k.filter((a)=>!n.includes(a)),"force-push","merge"],i=[...Zo,...n.map((a)=>Lt[a])],s=[...k.filter((a)=>!n.includes(a)).map((a)=>Lt[a]),...Vo];return{allowedTools:i,disallowedTools:s,permissionMode:"acceptEdits",maxBudgetUsd:r.maxBudgetUsd,requireCleanExit:r.requireCleanExit,grantedActions:n,blockedActions:o}}import{mkdir as Yo}from"fs/promises";import Qo from"path";async function ar(e){await Yo(e.runDirectory,{recursive:!0});let r=Qo.join(e.runDirectory,"receipt.json");return await Bun.write(r,`${JSON.stringify(e.receipt,null,2)}
105
- `),r}import{mkdir as ei}from"fs/promises";import ri from"path";async function V(e){let r=Bun.spawn({cmd:[...e.command],cwd:e.cwd,stdout:"pipe",stderr:"ignore"}),[t,n]=await Promise.all([r.exited,new Response(r.stdout).text()]);return{exitCode:t,stdout:n}}async function Ut(e){let r=await e.runner({command:e.command,cwd:e.cwd}),t=r.stdout.trim();if(r.exitCode!==0||t.length===0)throw Error(e.failure);return t}async function lr(e){let r=e.runner??V,t=await Ut({runner:r,command:["git","rev-parse","--show-toplevel"],cwd:e.targetDirectory,failure:"Target directory is not a git repository"}),n=await Ut({runner:r,command:["git","rev-parse","HEAD"],cwd:t,failure:"Target repository has no current commit"});if(await ei(ri.dirname(e.worktreeDirectory),{recursive:!0}),(await r({command:["git","worktree","add",e.worktreeDirectory,"-b",e.branch,n],cwd:t})).exitCode!==0)throw Error("Could not create the clone worktree");return{repoDirectory:t,worktreeDirectory:e.worktreeDirectory,baseCommit:n,branch:e.branch}}async function dr(e){let r=e.runner??V,[t,n,o]=await Promise.all([r({command:["git","status","--porcelain"],cwd:e.worktree.worktreeDirectory}),r({command:["git","diff","--name-only",`${e.worktree.baseCommit}..HEAD`],cwd:e.worktree.worktreeDirectory}),r({command:["git","log","--format=%H",`${e.worktree.baseCommit}..HEAD`],cwd:e.worktree.worktreeDirectory})]),i=t.exitCode===0?t.stdout.split(`
106
- `).filter(Boolean).map((a)=>a.slice(3)):[],s=n.exitCode===0?n.stdout.split(`
107
- `).filter(Boolean):[];return{filesChanged:[...new Set([...s,...i])],commits:o.exitCode===0?o.stdout.split(`
108
- `).filter(Boolean):[],isClean:t.exitCode===0&&i.length===0}}async function cr(e){let r=e.runner??V,t=await r({command:["git","status","--porcelain"],cwd:e.worktree.worktreeDirectory});if(t.exitCode!==0)throw Error("Could not inspect the clone worktree");if(t.stdout.trim().length===0)return!1;let o=(await r({command:["git","add","--all"],cwd:e.worktree.worktreeDirectory})).exitCode===0?await r({command:["git","commit","-m","chore: apply shadowclone task"],cwd:e.worktree.worktreeDirectory}):null;if(o===null||o.exitCode!==0)throw Error("Could not commit the clone result");return!0}function ti(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,40)||"task"}function ni(e){return e.match(/^## /gm)?.length??0}async function zt(e){let r=e.targetDirectory??process.cwd(),t=e.paths??h,{config:n,policy:o}=await v({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?t.managedConfigFile:e.managedConfigPath});if(!o.enabled||o.maxActionTier==="observe")throw Error("Managed policy does not allow headless clone runs");let i=await Xe({cwd:r,enabled:n.sources["git-metadata"],readRemote:e.readRemote});if(C({origin:i.origin,cwd:r,patterns:o.blockedOrigins}))throw Error("Managed policy blocks this repository");let s=sr({configuredPolicy:n.repo[i.id]??null,approvedActions:e.approvedActions??[],managedActionTier:o.maxActionTier}),a=e.runner?null:await A({purpose:"dispatch",allowedEngines:o.allowedEngines}),d=e.runner??a?.runner;if(!d)throw Error("No authenticated agent engine is available");let u=e.runId??crypto.randomUUID(),p=`shadowclone/${ti(e.task)}-${u.slice(0,8)}`,b=await lr({targetDirectory:r,worktreeDirectory:t.worktreeDirectory(u),branch:p,runner:e.commandRunner}),y=qt.join(t.runDirectory(u),"profile.md"),I=await z({profileDirectory:t.profileDirectory,outputPath:y,origin:i.origin,targetRepo:qt.basename(b.repoDirectory)}),R=e.startedAt??new Date().toISOString(),f=await d({prompt:[e.task,"","Work only in this worktree. Leave the finished change uncommitted.","Do not merge or force push under any circumstance."].join(`
109
- `),cwd:b.worktreeDirectory,systemPromptFile:y,sessionId:u,allowedTools:s.allowedTools,disallowedTools:s.disallowedTools,permissionMode:s.permissionMode,maxBudgetUsd:s.maxBudgetUsd});if(!f.isError)await cr({worktree:b,runner:e.commandRunner});let c=await dr({worktree:b,runner:e.commandRunner}),w={runId:u,task:e.task,repo:i.id,branch:p,engine:f.engine,model:null,sessionId:f.sessionId,transcriptPath:f.transcriptPath,startedAt:R,durationMs:f.durationMs,costUsd:f.costUsd,turns:f.turns,filesChanged:c.filesChanged,commits:c.commits,actionsTaken:c.commits.length>0?["commit"]:[],actionsBlockedByPolicy:s.blockedActions,permissionDenials:f.permissionDenials,profileRulesApplied:ni(I)};if(await ar({runDirectory:t.runDirectory(u),receipt:w}),f.isError||s.requireCleanExit&&!c.isClean)throw Error("Clone run did not finish cleanly; review its receipt");return w}function oi(e){let r=[],t=[];for(let o=0;o<e.length;o+=1){let i=e[o];if(i!=="--approve"){if(i)r.push(i);continue}let s=e[o+1],a=k.find((d)=>d===s);if(!a)throw Error("Run approval must name a supported action");t.push(a),o+=1}let n=r.join(" ").trim();if(n.length===0)throw Error("Run requires a task");return{task:n,approvedActions:[...new Set(t)]}}async function Gt(e){let r=oi(e),t=await zt(r);console.log(`Clone run ${t.runId} finished. Review ~/.shadowclone/runs/${t.runId}/receipt.json.`)}var ii="Usage: shadowclone <init|learn [--deep]|doctor|install|run <task>|forget --all>";function Jt(){console.log(ii)}function si(){console.log(pr.version)}async function ai(e){let[r,...t]=e;if(r==="--help"||r==="-h"||r==="help"){Jt();return}if(r==="--version"||r==="-v"){si();return}if(r==="init"){await Re();return}if(r==="learn"&&(t.length===0||t.length===1&&t[0]==="--deep")){await $t({deep:t[0]==="--deep"});return}if(r==="doctor"&&t.length===0){await Br();return}if(r==="install"&&t.length===0){await Pe();return}if(r==="run"){await Gt(t);return}if(r==="hook"&&t[0]==="session-end"){await rr({input:await Bun.stdin.text()});return}if(r==="hook"&&t[0]==="session-start"){await Ve({input:await Bun.stdin.text()});return}if(r==="forget"&&t[0]==="--all"){await _r();return}if(Jt(),r!==void 0)process.exitCode=1}await ai(Bun.argv.slice(2));
115
+ `),n={...qe,properties:{rules:{...qe.properties.rules,maxItems:e.rules.length}}},o=await e.runner({prompt:r,cwd:e.cwd,allowedTools:[],permissionMode:"dontAsk",outputSchema:n,maxBudgetUsd:e.maxBudgetUsd});if(o.isError)return e.rules;let s=o.structured;if(!s)try{s=JSON.parse(o.text)}catch{return e.rules}try{let i=Y(s);if(t)await os(An.dirname(t),{recursive:!0}),await Bun.write(t,`${JSON.stringify({rules:i},null,2)}
116
+ `);return i}catch{return e.rules}}var ss=new Set(["user-prompt","plan-presented","plan-resolved","question-asked","question-answered","permission-denied","interruption"]);function Dn(e){return ss.has(e.kind)&&e.textRef!==null}function ye(e){let t=new Set(e.events.flatMap((n)=>Dn(n)&&n.textRef?[ce(n.textRef)]:[])),r=new Set(e.events.flatMap((n)=>n.kind==="assistant-text"&&n.textRef?[ce(n.textRef)]:[]));return e.signals.map((n)=>({...n,textRefs:n.textRefs.filter((o)=>{let s=ce(o);return t.has(s)||r.has(s)})}))}function Bn(e){let[t]=e.signals;if(!t)return[];let r=e.signals.length,n=new Set(e.signals.map((i)=>i.sessionId)).size,o=Math.max(...e.signals.map((i)=>i.timestamp)),s=o>0?new Date(o).toISOString().slice(0,10):"unknown";return Y(e.value).map((i)=>{let a=N(i.title),l=(i.sources??[]).flatMap((g)=>e.originRules?.[g]?[e.originRules[g]]:[]),d=l.length>0?l.reduce((g,R)=>g+R.observations,0):r,u=l.length>0?Math.max(...l.map((g)=>g.sessions)):n,p=l.length>0?l.map((g)=>g.lastSeen).sort().at(-1)??s:s,m=l.length>0?[...new Set(l.flatMap((g)=>g.origins))].sort():[t.origin.id];return{title:i.title,body:i.body,section:i.section,key:a,scope:"org",originDirectory:t.origin.directoryName,observations:d,confidence:Number(Math.min(1,u/3).toFixed(2)),lastSeen:p,sessions:u,origins:m}})}function as(e){if(e.structured!==null&&e.structured!==void 0)return e.structured;try{return JSON.parse(e.text)}catch{throw Error("The engine returned no structured distillation result")}}async function On(e){let t=[],r=0,n=ye({signals:e.signals,events:e.events}).filter((i)=>i.textRefs.length>0);for(let i of ge({signals:n})){let a=await En({checkpointDirectory:e.checkpointDirectory,batch:i});if(a!==null){t.push(...a);continue}let l=await _t({signals:i.signals}),d=await e.runner({prompt:l,cwd:e.workingDirectory,allowedTools:[],permissionMode:"dontAsk",maxBudgetUsd:e.maxBudgetUsd,outputSchema:jt});if(r+=1,d.isError)throw Error("The agent engine failed during distillation");let u=Bn({value:as(d),signals:i.signals});await Sn({checkpointDirectory:e.checkpointDirectory,batch:i,rules:u}),t.push(...u)}let o=Map.groupBy(t,(i)=>i.originDirectory),s=[];for(let[i,a]of o.entries()){if(a.length<=1){s.push(...a);continue}let l=!1,d=await Tn({rules:a.map((p)=>({title:p.title,body:p.body,section:p.section})),runner:async(p)=>(l=!0,e.runner(p)),cwd:e.workingDirectory,maxBudgetUsd:e.maxBudgetUsd,checkpointDirectory:e.checkpointDirectory});if(l)r+=1;let u=n.filter((p)=>p.origin.directoryName===i);s.push(...Bn({value:{rules:d},signals:u,originRules:a}))}return{rules:s,engineRuns:r}}async function ls(e){return await Bun.spawn({cmd:["git","-C",e,"rev-parse","--is-inside-work-tree"],stdout:"ignore",stderr:"ignore"}).exited===0}async function _n(e={}){let t=e.paths??h,r=e.configPath??t.configFile;if(!await Bun.file(r).exists()){if(!process.stdin.isTTY)throw Error("No configuration found. Run shadowclone init interactively first.");console.log("No configuration found. Running shadowclone init..."),await Le({configPath:e.configPath})}let{config:o,policy:s}=await S({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?t.managedConfigFile:e.managedConfigPath});if(!s.enabled)throw Error("Shadowclone is disabled by managed policy");let i=e.databasePath??(e.dryRun?":memory:":t.indexDatabase),a=await M(i);try{let l=await tn({index:a,config:o,paths:t}),d=a.listEvents(),u=await ke({events:d,corpus:a.getCorpusSummary(),gitMetadataEnabled:o.sources["git-metadata"],readRemote:e.readRemote,blockedOrigins:s.blockedOrigins}),p=ct(d);for(let b of p)console.warn(`Warning: ${b}`);if(e.dryRun){console.log(xe({report:u.report,networkCallsMade:!1}));return}let m=ie({events:u.events,signals:u.corrections,origins:u.origins}),g=[],R=!1;if(e.deep){if(!o.distillation.deep)throw Error("Deep distillation is disabled in config");let b=ye({signals:u.corrections,events:u.events}).filter((O)=>O.textRefs.length>0),A=ge({signals:b});if(console.log(`Deep distillation will run up to ${A.length} agent batches.`),A.length>0){if(s.distillation!=="allowed")throw Error("Managed policy does not allow remote distillation");let O=e.runner?null:await B({purpose:"distill",allowedEngines:s.allowedEngines}),ee=e.runner??O?.runner;if(!ee)throw Error("No authenticated agent engine is available");let te=await On({signals:b,runner:ee,workingDirectory:t.shadowcloneDirectory,checkpointDirectory:t.distillDirectory,events:u.events});g=te.rules,R=te.engineRuns>0}}let P=e.deep&&g.length>0,f=[...P?g:m].sort((b,A)=>A.observations-b.observations||b.title.localeCompare(A.title));if(await se({paths:t,rules:f,generator:P?"all":"structural"}),console.log(xe({report:u.report,networkCallsMade:R})),l.rescannedFiles>0)console.log(`
117
+ Rescanned ${l.rescannedFiles} rewritten files.`);let w=e.targetDirectory??process.cwd();if(await ls(w))try{await Ue({cwd:w,paths:t,readRemote:e.readRemote,configPath:e.configPath,managedConfigPath:e.managedConfigPath})}catch(b){let A=b instanceof Error?b.message:String(b);console.warn(`Warning: failed to install clone hook: ${A}`)}}finally{a.close()}}import $n from"path";var cs=["Read","Grep","Glob","Edit","Write","Bash(git status:*)","Bash(git diff:*)"];function jn(e){if(e==="pr-draft")return"Bash(gh pr create --draft:*)";if(e==="pr-reply")return"Bash(gh pr comment:*)";return null}var ds=["Bash(git add:*)","Bash(git commit:*)","Bash(git push:*)","Bash(git push --force:*)","Bash(git push -f:*)","Bash(git push --force-with-lease:*)","Bash(gh pr merge:*)"];function Mt(e){let t=e.configuredPolicy??{allow:[],maxBudgetUsd:2,requireCleanExit:!0},r=e.managedActionTier==="act"?t.allow:[],n=_.filter((d)=>r.includes(d)&&e.approvedActions.includes(d)),o=[..._.filter((d)=>!n.includes(d)),"force-push","merge"],s=e.verificationTools??["Bash(bun test:*)","Bash(bun run typecheck:*)"],a=[...[...cs,...s],...n.flatMap((d)=>{let u=jn(d);return u?[u]:[]})],l=[..._.filter((d)=>!n.includes(d)).flatMap((d)=>{let u=jn(d);return u?[u]:[]}),...ds];return{allowedTools:a,disallowedTools:l,permissionMode:"dontAsk",maxBudgetUsd:t.maxBudgetUsd,requireCleanExit:t.requireCleanExit,grantedActions:n,blockedActions:o}}import{mkdir as us}from"fs/promises";import ps from"path";async function Ft(e){await us(e.runDirectory,{recursive:!0});let t=ps.join(e.runDirectory,"receipt.json");return await Bun.write(t,`${JSON.stringify(e.receipt,null,2)}
118
+ `),t}import J from"path";async function Mn(e){if(e.overrides&&e.overrides.length>0)return e.overrides.map((d)=>`Bash(${d}:*)`);if(!e.cwd)return["Bash(bun test:*)","Bash(bun run typecheck:*)","Bash(npm test:*)"];let t=[],r=Bun.file(J.join(e.cwd,"bun.lock")),n=Bun.file(J.join(e.cwd,"bun.lockb")),o=Bun.file(J.join(e.cwd,"package.json")),s=Bun.file(J.join(e.cwd,"Cargo.toml")),i=Bun.file(J.join(e.cwd,"go.mod")),a=Bun.file(J.join(e.cwd,"pyproject.toml")),l=Bun.file(J.join(e.cwd,"Makefile"));if(await r.exists()||await n.exists())t.push("Bash(bun test:*)","Bash(bun run typecheck:*)");else if(await o.exists())t.push("Bash(npm test:*)","Bash(npm run typecheck:*)");if(await s.exists())t.push("Bash(cargo test:*)","Bash(cargo check:*)");if(await i.exists())t.push("Bash(go test:*)");if(await a.exists())t.push("Bash(pytest:*)","Bash(python -m unittest:*)");if(await l.exists())t.push("Bash(make test:*)","Bash(make check:*)");if(t.length===0)t.push("Bash(bun test:*)","Bash(bun run typecheck:*)","Bash(npm test:*)");return t}import{mkdir as fs}from"fs/promises";import ms from"path";async function Q(e){let t=Bun.spawn({cmd:[...e.command],cwd:e.cwd,stdout:"pipe",stderr:"ignore"}),[r,n]=await Promise.all([t.exited,new Response(t.stdout).text()]);return{exitCode:r,stdout:n}}async function Fn(e){let t=await e.runner({command:e.command,cwd:e.cwd}),r=t.stdout.trim();if(t.exitCode!==0||r.length===0)throw Error(e.failure);return r}async function $t(e){let t=e.runner??Q,r=await Fn({runner:t,command:["git","rev-parse","--show-toplevel"],cwd:e.targetDirectory,failure:"Target directory is not a git repository"}),n=await Fn({runner:t,command:["git","rev-parse","HEAD"],cwd:r,failure:"Target repository has no current commit"});if(await fs(ms.dirname(e.worktreeDirectory),{recursive:!0}),(await t({command:["git","worktree","add",e.worktreeDirectory,"-b",e.branch,n],cwd:r})).exitCode!==0)throw Error("Could not create the clone worktree");return{repoDirectory:r,worktreeDirectory:e.worktreeDirectory,baseCommit:n,branch:e.branch}}async function Nt(e){let t=e.runner??Q,[r,n,o]=await Promise.all([t({command:["git","status","--porcelain"],cwd:e.worktree.worktreeDirectory}),t({command:["git","diff","--name-only",`${e.worktree.baseCommit}..HEAD`],cwd:e.worktree.worktreeDirectory}),t({command:["git","log","--format=%H",`${e.worktree.baseCommit}..HEAD`],cwd:e.worktree.worktreeDirectory})]),s=r.exitCode===0?r.stdout.split(`
119
+ `).filter(Boolean).map((a)=>a.slice(3)):[],i=n.exitCode===0?n.stdout.split(`
120
+ `).filter(Boolean):[];return{filesChanged:[...new Set([...i,...s])],commits:o.exitCode===0?o.stdout.split(`
121
+ `).filter(Boolean):[],isClean:r.exitCode===0&&s.length===0}}async function Lt(e){let t=e.runner??Q,r=await t({command:["git","status","--porcelain"],cwd:e.worktree.worktreeDirectory});if(r.exitCode!==0)throw Error("Could not inspect the clone worktree");if(r.stdout.trim().length===0)return!1;let o=(await t({command:["git","add","--all"],cwd:e.worktree.worktreeDirectory})).exitCode===0?await t({command:["git","commit","-m","chore: apply shadowclone task"],cwd:e.worktree.worktreeDirectory}):null;if(o===null||o.exitCode!==0)throw Error("Could not commit the clone result");return!0}async function Ut(e){if((await(e.runner??Q)({command:["git","push","--set-upstream","origin",e.worktree.branch],cwd:e.worktree.worktreeDirectory})).exitCode!==0)throw Error("Could not push the clone branch to origin");return!0}function gs(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,40)||"task"}function ys(e){return e.match(/^## /gm)?.length??0}async function Nn(e){let t=e.targetDirectory??process.cwd(),r=e.paths??h,{config:n,policy:o}=await S({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?r.managedConfigFile:e.managedConfigPath});if(!o.enabled||o.maxActionTier==="observe")throw Error("Managed policy does not allow headless clone runs");let s=await at({cwd:t,enabled:n.sources["git-metadata"],readRemote:e.readRemote});if(I({origin:s.origin,cwd:t,patterns:o.blockedOrigins}))throw Error("Managed policy blocks this repository");let i=await Mn({cwd:t}),a=Mt({configuredPolicy:n.repo[s.id]??null,approvedActions:e.approvedActions??[],managedActionTier:o.maxActionTier,verificationTools:i}),l=e.runner?null:await B({purpose:"dispatch",allowedEngines:o.allowedEngines}),d=e.runner??l?.runner;if(!d)throw Error("No authenticated agent engine is available");let u=e.runId??crypto.randomUUID(),p=`shadowclone/${gs(e.task)}-${u.slice(0,8)}`,m=await $t({targetDirectory:t,worktreeDirectory:r.worktreeDirectory(u),branch:p,runner:e.commandRunner}),g=$n.join(r.runDirectory(u),"profile.md"),R=await L({profileDirectory:r.profileDirectory,outputPath:g,origin:s.origin,targetRepo:$n.basename(m.repoDirectory)}),P=e.startedAt??new Date().toISOString(),x=await d({prompt:[e.task,"","Work only in this worktree. Leave the finished change uncommitted.","Do not merge or force push under any circumstance."].join(`
122
+ `),cwd:m.worktreeDirectory,systemPromptFile:g,sessionId:u,allowedTools:a.allowedTools,disallowedTools:a.disallowedTools,permissionMode:a.permissionMode,maxBudgetUsd:a.maxBudgetUsd});if(!x.isError)await Lt({worktree:m,runner:e.commandRunner});let f=await Nt({worktree:m,runner:e.commandRunner}),w=f.commits.length>0?["commit"]:[];if(!x.isError&&a.grantedActions.includes("push")&&f.commits.length>0)await Ut({worktree:m,runner:e.commandRunner}),w.push("push");let b={runId:u,task:e.task,repo:s.id,branch:p,engine:x.engine,model:null,sessionId:x.sessionId,transcriptPath:x.transcriptPath,startedAt:P,durationMs:x.durationMs,costUsd:x.costUsd,turns:x.turns,filesChanged:f.filesChanged,commits:f.commits,actionsTaken:w,actionsBlockedByPolicy:a.blockedActions,permissionDenials:x.permissionDenials,profileRulesApplied:ys(R)};if(await Ft({runDirectory:r.runDirectory(u),receipt:b}),x.isError||a.requireCleanExit&&!f.isClean)throw Error("Clone run did not finish cleanly; review its receipt");return b}function hs(e){let t=[],r=[];for(let o=0;o<e.length;o+=1){let s=e[o];if(s!=="--approve"){if(s)t.push(s);continue}let i=e[o+1],a=_.find((l)=>l===i);if(!a)throw Error("Run approval must name a supported action");r.push(a),o+=1}let n=t.join(" ").trim();if(n.length===0)throw Error("Run requires a task");return{task:n,approvedActions:[...new Set(r)]}}async function Ln(e){let t=hs(e),r=await Nn(t);console.log(`Clone run ${r.runId} finished. Review ~/.shadowclone/runs/${r.runId}/receipt.json.`)}var ws="Usage: shadowclone <init|learn [--deep] [--dry-run]|doctor|install|run <task>|eval [--sessions N] [--since <date>] [--json] [--max-budget-usd <n>]|mcp|forget --all>";function Un(){console.log(ws)}function bs(){console.log(he.version)}async function xs(e){let[t,...r]=e;if(t==="--help"||t==="-h"||t==="help"){Un();return}if(t==="--version"||t==="-v"){bs();return}if(t==="init"){await Le();return}if(t==="learn"){let n=r.includes("--deep"),o=r.includes("--dry-run");if(r.every((i)=>i==="--deep"||i==="--dry-run")){await _n({deep:n,dryRun:o});return}}if(t==="doctor"&&r.length===0){await nn();return}if(t==="install"&&r.length===0){await Ue();return}if(t==="run"){await Ln(r);return}if(t==="eval"){await hn(r);return}if(t==="mcp"){await pt();return}if(t==="hook"&&r[0]==="session-end"){await Ot({input:await Bun.stdin.text()});return}if(t==="hook"&&r[0]==="session-start"){await Dt({input:await Bun.stdin.text()});return}if(t==="forget"&&r[0]==="--all"){await wn();return}if(Un(),t!==void 0)process.exitCode=1}await xs(Bun.argv.slice(2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shadowclone/cli",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "module": "src/cli/index.ts",
5
5
  "type": "module",
6
6
  "packageManager": "bun@1.3.3",
@@ -44,6 +44,7 @@
44
44
  "files": [
45
45
  "bin",
46
46
  "dist",
47
+ ".claude-plugin",
47
48
  "README.md",
48
49
  "LICENSE"
49
50
  ],