@shadowclone/cli 0.0.1 → 0.0.3

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,122 +1,190 @@
1
1
  # shadowclone
2
2
 
3
- 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
- ## Status
43
+ ## Quickstart
27
44
 
28
- Early.
45
+ Install the global CLI:
29
46
 
30
- - **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.
31
- - **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.
47
+ ```bash
48
+ npm i -g @shadowclone/cli
49
+ ```
32
50
 
33
- `docs/design/001-agent-transcript-pivot.md` is the spec. `docs/architecture/06-roadmap.md` is the order.
51
+ Verify your environment and supported provider CLIs:
34
52
 
35
- ### Provider coverage
53
+ ```bash
54
+ shadowclone doctor
55
+ ```
36
56
 
37
- 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.
57
+ Grant consent for desired transcript sources:
38
58
 
39
- | Provider | Observe | Distill | Dispatch |
40
- | --- | --- | --- | --- |
41
- | Claude Code | built | built | built |
42
- | Codex | built | built | blocked on granular tool and budget controls |
43
- | Cursor | built | built | blocked on granular tool and budget controls |
44
- | Antigravity CLI | built | blocked on a per-run deny-all tool policy | blocked on granular tool and budget controls |
45
- | GitHub Copilot CLI, OpenCode, Aider, Amp | planned, one reviewed provider at a time | capability dependent | capability dependent |
59
+ ```bash
60
+ shadowclone init
61
+ ```
46
62
 
47
- `docs/design/003-provider-expansion.md` defines the qualification gate and the registry that keeps these claims honest.
63
+ Index your historical sessions and build your profile:
48
64
 
49
- ## Privacy
65
+ ```bash
66
+ shadowclone learn
67
+ ```
50
68
 
51
- This is the first question to ask about a program that reads your agent transcripts, so it goes here rather than at the bottom.
69
+ To preview without writing files or databases:
52
70
 
53
- **What it reads.** Every source is opt-in and off by default. The list grows only when a release note says it grew.
71
+ ```bash
72
+ shadowclone learn --dry-run
73
+ ```
54
74
 
55
- | Source | Path | Default | Built today |
56
- | --- | --- | --- | --- |
57
- | `antigravity` | `~/.gemini/antigravity-cli/brain/*/.system_generated/logs/transcript_full.jsonl` | off | read only when enabled |
58
- | `claude-code` | `~/.claude/projects/**/*.jsonl` | off | read only when enabled |
59
- | `claude-prompts` | `~/.claude/history.jsonl` | off | read only when enabled |
60
- | `codex` | `~/.codex/sessions/**/*.jsonl` | off | read only when enabled |
61
- | `cursor` | `~/.cursor/chats/**/{store.db,meta.json}` | off | read only when enabled |
62
- | `git-metadata` | observed repositories' local `remote.origin.url` | off | read only when enabled |
63
- | `shell` | `~/.zsh_history`, `~/.bash_history` | off | read only when enabled |
75
+ To enable deep distillation through your authenticated agent CLI:
64
76
 
65
- **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.
77
+ ```bash
78
+ shadowclone learn --deep
79
+ ```
66
80
 
67
- **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.
81
+ Install the compiled profile into the current repository:
68
82
 
69
- **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.
83
+ ```bash
84
+ shadowclone install
85
+ ```
70
86
 
71
- **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.
87
+ This writes `.claude/agents/shadowclone.md` and excludes it from git tracking.
72
88
 
73
- **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.
89
+ ## Replay evaluation
74
90
 
75
- **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.
91
+ Shadowclone provides a reproducible fitness function to measure profile impact:
76
92
 
77
- 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.
93
+ ```bash
94
+ shadowclone eval --sessions 5 --max-budget-usd 0.50
95
+ ```
78
96
 
79
- ## Quickstart
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.
100
+
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.
80
106
 
81
- Needs one of `claude`, `codex`, or `cursor-agent` installed and logged in for anything that calls a model. No API key.
107
+ Evaluation receipts are written to `~/.shadowclone/eval/<evalId>.json`.
108
+
109
+ ## Unattended dispatch
110
+
111
+ Execute tasks in an isolated git worktree without touching your working tree:
82
112
 
83
113
  ```bash
84
- npm i -g @shadowclone/cli
85
- shadowclone doctor
86
- shadowclone init
87
- shadowclone learn
114
+ shadowclone run "fix the flaky test in src/auth.test.ts"
88
115
  ```
89
116
 
90
- That is the whole install. The package brings its own runtime, so nothing else is required.
117
+ The default dispatch mode creates a local worktree and branch, runs verification checks, and commits locally without pushing.
91
118
 
92
- Working on shadowclone itself:
119
+ Remote actions (push, open PR) require both a repository ceiling in `~/.shadowclone/config.toml` and an explicit per-run approval flag:
93
120
 
94
121
  ```bash
95
- git clone https://github.com/theonly1me/shadowclone.git
96
- cd shadowclone
97
- bun install
98
- bun run check # typecheck, lint, and tests
99
- bun run cli doctor
122
+ shadowclone run "prepare release notes" --approve push
100
123
  ```
101
124
 
102
- Add this checkout as a local Claude Code marketplace, then install the plugin:
125
+ ## Ground-truth privacy
126
+
127
+ Agent transcripts contain private code, environment variables, internal hosts, and customer data. Shadowclone protects data through structural guarantees:
128
+
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.
103
134
 
104
- ```text
105
- /plugin marketplace add /path/to/shadowclone
106
- /plugin install shadowclone@shadowclone
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:
143
+
144
+ ```bash
145
+ shadowclone forget --all
107
146
  ```
108
147
 
109
- 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.
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
+ }
164
+ ```
110
165
 
111
- 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`.
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.
112
167
 
113
- ## Contributing
168
+ ## CLI commands
114
169
 
115
- `CONTRIBUTING.md` has the rules. Short version: small diffs, `bun run check`, PR body under 250 words.
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
+ ```
180
+
181
+ ## Contributing
116
182
 
117
- `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:
118
184
 
119
- 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
+ ```
120
188
 
121
189
  ## License
122
190
 
@@ -1,34 +1,42 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- var sr={name:"@shadowclone/cli",version:"0.0.1",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 X(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function R(e,r){let t=e[r];return typeof t==="string"?t:null}function he(e,r){let t=e[r];return typeof t==="number"?t:null}function zt(e){let r=e.message;if(!X(r)||!Array.isArray(r.content))return"";return r.content.flatMap((t)=>X(t)&&R(t,"type")==="text"&&R(t,"text")!==null?[R(t,"text")??""]:[]).join("")}function Gt(e){if(!Array.isArray(e))return[];return e.flatMap((r)=>{if(!X(r))return[];let t=R(r,"tool_name")??R(r,"toolName");return t?[{toolName:t,toolUseId:R(r,"tool_use_id")??R(r,"toolUseId")}]:[]})}function be(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(!X(s))continue;if(R(s,"type")==="assistant")r.push(zt(s));if(R(s,"type")==="result")t=s}catch{continue}}let n=t?R(t,"result"):null,o=r.join("");return{engine:"claude-code",sessionId:(t?R(t,"session_id"):null)??e.fallbackSessionId,transcriptPath:null,text:o.length>0?o:n??"",structured:t?.structured_output??null,costUsd:t?he(t,"total_cost_usd"):null,durationMs:t?he(t,"duration_ms")??0:0,turns:t?he(t,"num_turns")??0:0,isError:t?.is_error===!0||t===null,permissionDenials:Gt(t?.permission_denials)}}function ar(e){if(e.values===void 0)return;e.arguments_.push(e.flag),e.arguments_.push(...e.values.length===0?[""]:e.values)}function lr(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 ar({arguments_:r,flag:"--allowedTools",values:e.run.allowedTools}),ar({arguments_:r,flag:"--disallowedTools",values:e.run.disallowedTools}),r}async function we(e){let r=e.sessionId??crypto.randomUUID(),t=Bun.spawn({cmd:[...lr({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=be({stream:o,fallbackSessionId:r});return n===0?i:{...i,isError:!0}}import{mkdtemp as Jt,rm as Wt}from"fs/promises";import Kt from"os";import cr from"path";function dr(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 Ht(e){try{return JSON.parse(e)}catch{return null}}function xe(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(!dr(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=dr(s.item)?s.item:null,y=d?N(d,"item_type")??N(d,"type"):null;if(a==="item.completed"&&d!==null&&(y==="assistant_message"||y==="agent_message"))t=N(d,"text")??t}return{engine:"codex",sessionId:r,transcriptPath:null,text:t,structured:Ht(t),costUsd:null,durationMs:e.durationMs,turns:n,isError:o,permissionDenials:[]}}async function Z(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 ge={name:"@shadowclone/cli",version:"0.0.3",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 Po from"path";import{mkdir as Vn}from"fs/promises";import Yn from"path";import Nn from"os";import P from"path";function Ln(e){if(e==="darwin")return"/Library/Application Support/shadowclone/managed.json";if(e==="linux")return"/etc/shadowclone/managed.json";return null}function Un(e){let t=P.join(e.homeDirectory,".shadowclone"),r=P.join(t,"profile");return{shadowcloneDirectory:t,configFile:P.join(t,"config.toml"),indexDatabase:P.join(t,"index.db"),profileDirectory:r,rejectedProfileFile:P.join(r,".rejected"),profileManifestFile:P.join(r,".generated"),compiledProfileFile:P.join(r,".compiled.md"),distillDirectory:P.join(t,"distill"),worktreesDirectory:P.join(t,"worktrees"),runsDirectory:P.join(t,"runs"),antigravityBrainDirectory:P.join(e.homeDirectory,".gemini","antigravity-cli","brain"),claudeProjectsDirectory:P.join(e.homeDirectory,".claude","projects"),claudePromptHistoryFile:P.join(e.homeDirectory,".claude","history.jsonl"),codexSessionsDirectory:P.join(e.homeDirectory,".codex","sessions"),cursorChatsDirectory:P.join(e.homeDirectory,".cursor","chats"),shellHistoryFiles:[P.join(e.homeDirectory,".zsh_history"),P.join(e.homeDirectory,".bash_history")],managedConfigFile:Ln(e.platform),runDirectory:(n)=>P.join(t,"runs",n),worktreeDirectory:(n)=>P.join(t,"worktrees",n)}}var w=Un({homeDirectory:Nn.homedir(),platform:process.platform});import{stat as Wn}from"fs/promises";var B=["push","pr-draft","pr-reply"];function Lt(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function qn(e){if(!Array.isArray(e))return null;let t=e.flatMap((r)=>{let n=B.find((o)=>o===r);return n?[n]:[]});return t.length===e.length?t:null}function Ut(e){if(e===void 0)return{};if(!Lt(e))throw Error("Config repo settings must be tables");let t={};for(let[r,n]of Object.entries(e)){if(!Lt(n))throw Error("Every repo policy must be a table");let o=qn(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 qt(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 A=["antigravity","claude-code","claude-prompts","codex","cursor","git-metadata","shell"],zn=A.filter((e)=>e!=="antigravity"),Gn=A.filter((e)=>e!=="antigravity"&&e!=="git-metadata"),_={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 qe(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function G(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 Hn(e){if(!qe(e)||!G({record:e,keys:A})&&!G({record:e,keys:zn})&&!G({record:e,keys:Gn}))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 Jn(e){if(!qe(e)||!G({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 zt(e){let t=["schema-version","sources","distillation"],r=[...t,"repo"];if(!qe(e)||!G({record:e,keys:t})&&!G({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:Hn(e.sources),distillation:Jn(e.distillation),repo:Ut(e.repo)}}var Gt=["claude-code","codex","cursor-agent","antigravity","anthropic-api","openai-compatible"],ze={enabled:!0,allowedSources:A,allowedEngines:Gt,distillation:"allowed",originScope:"strict",blockedOrigins:[],maxActionTier:"act"};function Kn(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Ge(e){return Array.isArray(e)&&e.every((t)=>typeof t==="string")?e:null}function Xn(e){let t=Ge(e);if(t===null)return null;let r=t.flatMap((n)=>{let o=A.find((s)=>s===n);return o?[o]:[]});return r.length===t.length?r:null}function Zn(e){let t=Ge(e);if(t===null)return null;let r=t.flatMap((n)=>{let o=Gt.find((s)=>s===n);return o?[o]:[]});return r.length===t.length?r:null}function Ht(e){if(!Kn(e))throw Error("Managed policy must be a JSON object");let t=Xn(e.allowedSources),r=Zn(e.allowedEngines),n=Ge(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 He(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 Q(e){if(e===null)return ze;let t=Bun.file(e);if(!await t.exists())return ze;if((await Wn(e)).uid!==0)throw Error("Managed policy must be owned by root");let n=await t.json();return Ht(n)}async function Qn(e={}){let t=e.configPath??w.configFile,r=Bun.file(t);if(!await r.exists())return _;let n=Bun.TOML.parse(await r.text());return zt(n)}async function k(e={}){let t=await Q(e.managedConfigPath===void 0?w.managedConfigFile:e.managedConfigPath),r=t.enabled?await Qn({configPath:e.configPath}):_;return{config:He({config:r,policy:t}),policy:t}}function eo(e){let t=A.map((r)=>`${r} = ${e.sources[r]}`);return[`schema-version = ${e.schemaVersion}`,"","[sources]",...t,"","[distillation]",`deep = ${e.distillation.deep}`,...qt(e.repo),""].join(`
4
+ `)}async function Je(e){let t=e.configPath??w.configFile;await Vn(Yn.dirname(t),{recursive:!0}),await Bun.write(t,eo(e.config))}function We(e){return{...e.config,sources:{...e.config.sources,[e.source]:e.enabled}}}function Jt(e){return{...e.config,distillation:{deep:e.enabled}}}import{mkdir as Wt}from"fs/promises";import H from"path";async function to(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=H.isAbsolute(r)?r:H.resolve(e.cwd,r),o=Bun.file(n),s=await o.exists()?await o.text():"";if(s.includes(e.relativePath))return;await Wt(H.dirname(n),{recursive:!0});let i=s.length>0&&!s.endsWith(`
5
+ `)?`${s}
6
+ `:s;await Bun.write(n,`${i}${e.relativePath}
7
+ `)}function Kt(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 Ke(e){let t=e.name??"shadowclone",r=H.join(e.targetDirectory,".claude","agents"),n=H.join(r,`${t}.md`);await Wt(r,{recursive:!0}),await Bun.write(n,Kt(e));let o=H.join(".claude","agents",`${t}.md`);return await to({cwd:e.targetDirectory,relativePath:o}),n}import{mkdir as no}from"fs/promises";import he from"path";function ye(e){return new Bun.CryptoHasher("sha256").update(e).digest("hex").slice(0,16)}function M(e){return new Bun.CryptoHasher("sha256").update(`semantic:${e.toLowerCase()}`).digest("hex").slice(0,16)}function Xe(e){return e.scope==="global"?`global/${e.section}.md`:`org/${e.originDirectory??"isolated"}/${e.section}.md`}function ee(e){let t=`## ${e.title}
6
9
 
7
- `)}function pr(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 fr(e){pr(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 ur(e){let r=await Z({run:e.run,outputSchemaInPrompt:!1}),t=crypto.randomUUID(),n=Date.now(),o=Bun.spawn({cmd:[...fr(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=xe({stream:s,fallbackSessionId:t,durationMs:Date.now()-n});return i===0?a:{...a,isError:!0}}async function Pe(e){if(pr(e),e.outputSchema===void 0)return ur({run:e});let r=await Jt(cr.join(Kt.tmpdir(),"shadowclone-codex-")),t=cr.join(r,"schema.json");await Bun.write(t,JSON.stringify(e.outputSchema));try{return await ur({run:e,outputSchemaPath:t})}finally{await Wt(r,{recursive:!0,force:!0})}}import{mkdir as Yt,mkdtemp as Qt,rm as en}from"fs/promises";import rn from"os";import ve from"path";function Xt(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function V(e,r){let t=e[r];return typeof t==="string"?t:null}function Zt(e,r){let t=e[r];return typeof t==="number"?t:null}function Vt(e){try{return JSON.parse(e)}catch{return null}}function Re(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(!Xt(s))continue;if(r=V(s,"session_id")??r,V(s,"type")==="assistant")n+=1;if(V(s,"type")==="result")t=s}let o=t?V(t,"result")??"":"";return{engine:"cursor-agent",sessionId:r,transcriptPath:null,text:o,structured:Vt(o),costUsd:null,durationMs:t?Zt(t,"duration_ms")??0:0,turns:n,isError:t===null||t.is_error===!0,permissionDenials:[]}}function mr(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 gr(e){mr(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 yr(e){let r=await Z({run:e.run,outputSchemaInPrompt:!0}),t=crypto.randomUUID(),n=Bun.spawn({cmd:[...gr({...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=Re({stream:i,fallbackSessionId:t});return o===0?s:{...s,isError:!0}}async function Ee(e){if(mr(e),e.allowedTools?.length!==0)return yr({run:e,workspace:e.cwd});let r=await Qt(ve.join(rn.tmpdir(),"shadowclone-cursor-")),t=ve.join(r,".cursor");await Yt(t,{recursive:!0}),await Bun.write(ve.join(t,"cli.json"),JSON.stringify({version:1,permissions:{allow:[],deny:["Shell(*)","Read(*)","Write(*)","WebFetch(*)","Mcp(*:*)"]}}));try{return await yr({run:e,workspace:r})}finally{await en(r,{recursive:!0,force:!0})}}var Y=[{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 Ce(e){return Y.find((r)=>r.engine?.id===e)??null}function tn(e){return e?.implemented===!0&&e.capabilities.structuredOutput!=="none"&&e.capabilities.isolatedNoTools}function Q(e){let r=tn(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 ke(e){let r=Q(e.definition);return e.purpose==="distill"?r.distill:r.dispatch}async function ee(e){try{return await Bun.spawn({cmd:[...e],stdout:"ignore",stderr:"ignore"}).exited===0}catch{return!1}}async function hr(e={}){let r=e.probe??ee,t=await r(["claude","--version"]),n=t&&await r(["claude","auth","status"]);return{engine:"claude-code",installed:t,authenticated:n}}async function br(e={}){let r=e.probe??ee,t=await r(["codex","--version"]),n=t&&await r(["codex","login","status"]);return{engine:"codex",installed:t,authenticated:n}}async function wr(e={}){let r=e.probe??ee,t=await r(["cursor-agent","--version"]),n=t&&await r(["cursor-agent","status"]);return{engine:"cursor-agent",installed:t,authenticated:n}}function nn(e){if(e==="claude-code")return we;if(e==="codex")return Pe;if(e==="cursor-agent")return Ee;return null}function on(e){let r=Ce(e.engineId);return r!==null&&ke({definition:r,purpose:e.purpose})}async function T(e){let r=await hr(e),t=await br(e),n=await wr(e),o=e.allowedEngines??["claude-code","codex","cursor-agent"],i=[r,t,n],s=i.find((d)=>d.authenticated&&o.includes(d.engine)&&on({engineId:d.engine,purpose:e.purpose})),a=s?nn(s.engine):null;return{availability:i,runner:a,selectedEngine:a?s?.engine??null:null}}import{mkdir as bn}from"fs/promises";import wn from"path";import sn from"os";import g from"path";function an(e){if(e==="darwin")return"/Library/Application Support/shadowclone/managed.json";if(e==="linux")return"/etc/shadowclone/managed.json";return null}function ln(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:an(e.platform),runDirectory:(n)=>g.join(r,"runs",n),worktreeDirectory:(n)=>g.join(r,"worktrees",n)}}var h=ln({homeDirectory:sn.homedir(),platform:process.platform});import{stat as yn}from"fs/promises";var S=["push","pr-draft","pr-reply"];function xr(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function dn(e){if(!Array.isArray(e))return null;let r=e.flatMap((t)=>{let n=S.find((o)=>o===t);return n?[n]:[]});return r.length===e.length?r:null}function Pr(e){if(e===void 0)return{};if(!xr(e))throw Error("Config repo settings must be tables");let r={};for(let[t,n]of Object.entries(e)){if(!xr(n))throw Error("Every repo policy must be a table");let o=dn(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 Rr(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 C=["antigravity","claude-code","claude-prompts","codex","cursor","git-metadata","shell"],cn=C.filter((e)=>e!=="antigravity"),un=C.filter((e)=>e!=="antigravity"&&e!=="git-metadata"),O={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 Se(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function j(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 pn(e){if(!Se(e)||!j({record:e,keys:C})&&!j({record:e,keys:cn})&&!j({record:e,keys:un}))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 fn(e){if(!Se(e)||!j({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 vr(e){let r=["schema-version","sources","distillation"],t=[...r,"repo"];if(!Se(e)||!j({record:e,keys:r})&&!j({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:pn(e.sources),distillation:fn(e.distillation),repo:Pr(e.repo)}}var Er=["claude-code","codex","cursor-agent","antigravity","anthropic-api","openai-compatible"],Ie={enabled:!0,allowedSources:C,allowedEngines:Er,distillation:"allowed",originScope:"strict",blockedOrigins:[],maxActionTier:"act"};function mn(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Ae(e){return Array.isArray(e)&&e.every((r)=>typeof r==="string")?e:null}function gn(e){let r=Ae(e);if(r===null)return null;let t=r.flatMap((n)=>{let o=C.find((i)=>i===n);return o?[o]:[]});return t.length===r.length?t:null}function hn(e){let r=Ae(e);if(r===null)return null;let t=r.flatMap((n)=>{let o=Er.find((i)=>i===n);return o?[o]:[]});return t.length===r.length?t:null}function Cr(e){if(!mn(e))throw Error("Managed policy must be a JSON object");let r=gn(e.allowedSources),t=hn(e.allowedEngines),n=Ae(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 Te(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 Ie;let r=Bun.file(e);if(!await r.exists())return Ie;if((await yn(e)).uid!==0)throw Error("Managed policy must be owned by root");let n=await r.json();return Cr(n)}async function xn(e={}){let r=e.configPath??h.configFile,t=Bun.file(r);if(!await t.exists())return O;let n=Bun.TOML.parse(await t.text());return vr(n)}async function v(e={}){let r=await L(e.managedConfigPath===void 0?h.managedConfigFile:e.managedConfigPath),t=r.enabled?await xn({configPath:e.configPath}):O;return{config:Te({config:t,policy:r}),policy:r}}function Pn(e){let r=C.map((t)=>`${t} = ${e.sources[t]}`);return[`schema-version = ${e.schemaVersion}`,"","[sources]",...r,"","[distillation]",`deep = ${e.distillation.deep}`,...Rr(e.repo),""].join(`
9
- `)}async function Oe(e){let r=e.configPath??h.configFile;await bn(wn.dirname(r),{recursive:!0}),await Bun.write(r,Pn(e.config))}function De(e){return{...e.config,sources:{...e.config.sources,[e.source]:e.enabled}}}function kr(e){return{...e.config,distillation:{deep:e.enabled}}}function Rn(){return Y.map((e)=>{let r=Q(e);return`${e.id}: observe=${r.observe?"yes":"no"}, distill=${r.distill?"yes":"no"}, dispatch=${r.dispatch?"yes":"no"}`})}function vn(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 Sr(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 T({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(vn({distillation:t.distillation,selectedEngine:o.selectedEngine})),console.log("Provider support:");for(let i of Rn())console.log(i)}import{rm as En}from"fs/promises";async function Ir(e=h.shadowcloneDirectory){await En(e,{recursive:!0,force:!0}),console.log("Removed all shadowclone data.")}import Un from"path";import{mkdir as Cn}from"fs/promises";import Ar from"path";function Tr(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 Be(e){let r=e.name??"shadowclone",t=Ar.join(e.targetDirectory,".claude","agents"),n=Ar.join(t,`${r}.md`);return await Cn(t,{recursive:!0}),await Bun.write(n,Tr(e)),n}import{mkdir as Sn}from"fs/promises";import ne from"path";function re(e){return new Bun.CryptoHasher("sha256").update(e).digest("hex").slice(0,16)}function _e(e){return e.scope==="global"?`global/${e.section}.md`:`org/${e.originDirectory??"isolated"}/${e.section}.md`}function te(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=${ye(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=${re(r)}`].join(" ");return`${r}
13
-
14
- <!-- shadowclone: ${t} -->`}function Or(e){let r=e.metadata.split(/\s+/),t=`${e.name}=`;return r.find((o)=>o.startsWith(t))?.slice(t.length)??null}function kn(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=Or({metadata:t,name:"key"}),o=Or({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();return{key:n,fingerprint:o,content:e.trim(),edited:re(i)!==o}}function U(e){return e.trim().split(/\n(?=## )/).filter((r)=>r.trim().length>0).map(kn)}function Dr(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 In(e){let r=!e.includes("<!-- shadowclone:");return{content:e.replace(/\n\n<!-- shadowclone: [^\n]+ -->\s*$/,"").trim(),observations:Dr({content:e,name:"observations",fallback:r?Number.MAX_SAFE_INTEGER:0}),confidence:Dr({content:e,name:"confidence",fallback:r?1:0})}}async function An(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 Tn(e){let r=e.filePath.split(ne.sep).join("/");if(!r.includes("/projects/"))return!0;return e.targetRepo!==null&&r.endsWith(`/projects/${e.targetRepo}.md`)}async function oe(e){let r=[ne.join(e.profileDirectory,"global"),ne.join(e.profileDirectory,"org",e.origin.directoryName)],t=(await Promise.all(r.map(An))).flat(),n=[];for(let s of t){if(!Tn({filePath:s,targetRepo:e.targetRepo??null}))continue;let a=await Bun.file(s).text();n.push(...U(a).map((d)=>In(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 Xt(e){let t=e.metadata.split(/\s+/),r=`${e.name}=`;return t.find((o)=>o.startsWith(r))?.slice(r.length)??null}function ro(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=Xt({metadata:r,name:"key"}),o=Xt({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:ye(s)!==o}}function te(e){return e.trim().split(/\n(?=## )/).filter((t)=>t.trim().length>0).map(ro)}function Zt(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 oo(e){let t=!e.includes("<!-- shadowclone:");return{content:e.replace(/\n\n<!-- shadowclone: [^\n]+ -->\s*$/,"").trim(),observations:Zt({content:e,name:"observations",fallback:t?Number.MAX_SAFE_INTEGER:0}),confidence:Zt({content:e,name:"confidence",fallback:t?1:0})}}async function io(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 so(e){let t=e.filePath.split(he.sep).join("/");if(!t.includes("/projects/"))return!0;return e.targetRepo!==null&&t.endsWith(`/projects/${e.targetRepo}.md`)}async function J(e){let t=[he.join(e.profileDirectory,"global"),he.join(e.profileDirectory,"org",e.origin.directoryName)],r=(await Promise.all(t.map(io))).flat(),n=[];for(let i of r){if(!so({filePath:i,targetRepo:e.targetRepo??null}))continue;let a=await Bun.file(i).text();n.push(...te(a).map((l)=>oo(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
15
14
  `:`# Shadowclone profile
16
15
 
17
- ${i.map((s)=>s.content).join(`
16
+ ${s.map((i)=>i.content).join(`
18
17
 
19
18
  `)}
20
- `}async function q(e){let r=await oe(e);return await Sn(ne.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 Br(e){return D(e.label,`${e.count} of ${e.total}`)}function Fe(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",Br({label:"agent questions",count:r.answeredQuestions,total:r.askedQuestions}),Br({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(`
21
- `)}import On 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 _r(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 Ne(e){let r=_r(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 Fr(e){let r=_r(e),t=Ne(e);if(r===null||t===null)return null;return{id:`${t.id}/${r.repository.toLowerCase()}`,origin:t}}function Dn(e,r){let t=r.split("*").map((n)=>n.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${t}$`).test(e)}function k(e){let r=e.cwd?On.basename(e.cwd):null,t=[e.origin.id,...r?[`${e.origin.id}/${r}`]:[]];return e.patterns.some((n)=>t.some((o)=>Dn(o,n)))}async function ie(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 Me(e){return e.cwd.length>0?e.cwd:`${e.source}:${e.sessionId}`}async function $e(e){let r=new Map,t=e.readRemote??ie;for(let n of e.events){let o=Me(n);if(r.has(o))continue;r.set(o,await B({cwd:n.cwd,fallbackKey:o,enabled:e.enabled,readRemote:t}))}return r}async function B(e){let r=e.cwd||e.fallbackKey||"unknown",t=e.readRemote??ie,n=e.enabled&&e.cwd.length>0?await t(e.cwd):null;return n===null?je(r):Ne(n)??je(r)}async function Le(e){let r=e.readRemote??ie,t=e.enabled&&e.cwd.length>0?await r(e.cwd):null,n=t?Fr(t):null;if(n!==null)return n;let o=await B({cwd:e.cwd,enabled:!1});return{id:o.id,origin:o}}function I(e){return e.origins.get(Me(e.event))??je(Me(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 Bn(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 se(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 _n(e){let r=[],t=[],n=null,o=null;for(let i of e.events){let s=I({event:i,origins:e.origins});if(i.kind==="interruption"){let a=jr(t),d=Bn(a);r.push(se({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(se({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(se({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(se({kind:"plan-resolved",category:"presented-plan",label:"a presented plan",event:i,origin:s,relatedEvent:o})),o=null}t.push(i)}return r}function Mr(e){return[...Map.groupBy(e.events,(t)=>`${t.source}:${t.sessionId}`).values()].flatMap((t)=>_n({events:t,origins:e.origins}))}function Nr(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 Ue(e){return Nr(e)}function $r(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:Nr(e.flatMap((o)=>o.tool?[{category:o.tool.name,label:o.tool.name}]:[])),planSessions:t.size,totalSessions:r.size}}function Lr(e,r){return e.filter((t)=>t.kind===r).length}async function ae(e){let r=await $e({events:e.events,enabled:e.gitMetadataEnabled,readRemote:e.readRemote}),t=e.events.filter((s)=>!k({origin:I({event:s,origins:r}),cwd:s.cwd,patterns:e.blockedOrigins??[]})),n=Mr({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:Ue(o),denials:Ue(i),answeredQuestions:n.filter((s)=>s.kind==="question-answered").length,askedQuestions:Lr(t,"question-asked"),resolvedPlans:n.filter((s)=>s.kind==="plan-resolved").length,presentedPlans:Lr(t,"plan-presented"),structural:$r(t)}}}function qr(e){return new Bun.CryptoHasher("sha256").update(e).digest("hex").slice(0,16)}function Fn(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 jn(e){let r=Map.groupBy(e,(t)=>`${t.origin.id}:${t.kind}`);return e.map((t)=>{let n=Fn(t);return{key:qr(`${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 Mn(e){let r=e.events.filter((n)=>n.tool!==null),t=Map.groupBy(r,(n)=>I({event:n,origins:e.origins}).id);return r.map((n)=>{let o=I({event:n,origins:e.origins}),i=n.tool?.name??"unknown";return{key:qr(`tool-use:${i}`),title:`Uses ${i} in agent sessions`,body:`The \`${i}\` tool is part of the regular workflow.`,section:"engineering",origin:o,timestamp:n.timestamp,sessionId:n.sessionId,opportunities:t.get(o.id)?.length??1}})}function Ur(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 z(e){let r=[...jn(e.signals),...Mn(e)],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(Ur({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(Ur({observations:s,scope:"org"}))}return t.sort((n,o)=>o.observations-n.observations||n.title.localeCompare(o.title))}import{mkdir as zr}from"fs/promises";import Gr from"path";async function qe(e){let r=Bun.file(e);if(!await r.exists())return[];return(await r.text()).split(`
22
- `).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 F(e){let t=await J(e);return await no(he.dirname(e.outputPath),{recursive:!0}),await Bun.write(e.outputPath,t),t}function N(e,t){let r=Math.max(3,48-e.length);return` ${e} ${".".repeat(r)} ${t}`}function Vt(e){return N(e.label,`${e.count} of ${e.total}`)}function we(e){let t=e.report,r=(t.corpus.bytes/1048576).toFixed(1),n=t.interruptions.length>0?t.interruptions.slice(0,5).map((i)=>N(i.label,i.count)):[N("no interruptions indexed",0)],o=t.denials.length>0?t.denials.slice(0,5).map((i)=>N(i.label,i.count)):[N("no tool refusals indexed",0)],s=t.structural.toolUses.length>0?t.structural.toolUses.slice(0,5).map((i)=>N(i.label,i.count)):[N("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",Vt({label:"agent questions",count:t.answeredQuestions,total:t.askedQuestions}),Vt({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 ao(e){return new Bun.CryptoHasher("sha256").update(e).digest("hex").slice(0,16)}function lo(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 co(e){let t=Map.groupBy(e,(r)=>`${r.origin.id}:${r.kind}`);return e.map((r)=>{let n=lo(r);return{key:ao(`${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 Yt(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 re(e){let t=co(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(Yt({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(Yt({observations:i,scope:"org"}))}return r.sort((n,o)=>o.observations-n.observations||n.title.localeCompare(o.title))}import{mkdir as Qt,rm as uo}from"fs/promises";import er from"path";async function Ze(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 Ve(e){return`${e.slice().sort((t,r)=>t.relativePath.localeCompare(r.relativePath)||t.key.localeCompare(r.key)).map((t)=>`${t.relativePath} ${t.key}`).join(`
23
22
  `)}
24
- `}function Nn(e){return Map.groupBy(e,_e)}async function $n(e){let r=Bun.file(e);return await r.exists()?U(await r.text()):[]}function Ge(e){return`${e.relativePath} ${e.key}`}async function G(e){await zr(e.paths.profileDirectory,{recursive:!0});let r=await qe(e.paths.profileManifestFile),t=await qe(e.paths.rejectedProfileFile),n=new Map(t.map((u)=>[Ge(u),u])),o=Nn(e.rules),i=r.map((u)=>u.relativePath),s=new Set([...o.keys(),...i]),a=[],d=0,y=0;for(let u of s){let b=Gr.join(e.paths.profileDirectory,u),m=await $n(b),E=new Map(m.flatMap((c)=>c.key===null?[]:[[c.key,c]])),P=o.get(u)??[],p=[];for(let c of r.filter((x)=>x.relativePath===u))if(P.some((x)=>x.key===c.key)&&!E.has(c.key))n.set(Ge(c),c);for(let c of m){if(c.key===null){p.push(c.content);continue}let x=P.find((Ut)=>Ut.key===c.key);p.push(x&&!c.edited?te(x):c.content),a.push({relativePath:u,key:c.key})}for(let c of P){let x={relativePath:u,key:c.key};if(!E.has(c.key)&&!n.has(Ge(x)))p.push(te(c)),a.push(x)}if(p.length>0)await zr(Gr.dirname(b),{recursive:!0}),await Bun.write(b,`${p.join(`
23
+ `}function po(e){return M(e.title)===e.key}function fo(e){if(e.isUpdated||e.existingRule.edited)return!1;let t=po(e.existingRule);if(e.generator==="all")return!0;if(e.generator==="structural")return!t;return t}function mo(e){if(e.generator)return e.generator;let t=e.rules.some((n)=>M(n.title)===n.key),r=e.rules.some((n)=>M(n.title)!==n.key);if(t&&r)return"all";return t?"distilled":"structural"}var go=(e)=>Map.groupBy(e,Xe);async function yo(e){let t=Bun.file(e);return await t.exists()?te(await t.text()):[]}var Ye=(e)=>`${e.relativePath} ${e.key}`;async function ne(e){await Qt(e.paths.profileDirectory,{recursive:!0});let t=mo({generator:e.generator,rules:e.rules}),r=await Ze(e.paths.profileManifestFile),n=await Ze(e.paths.rejectedProfileFile),o=new Map(n.map((f)=>[Ye(f),f])),s=go(e.rules),i=r.map((f)=>f.relativePath),a=new Set([...s.keys(),...i]),l=[],u=0,p=0;for(let f of a){let m=er.join(e.paths.profileDirectory,f),y=await yo(m),x=new Map(y.flatMap((d)=>d.key===null?[]:[[d.key,d]])),S=s.get(f)??[],g=[];for(let d of r.filter((h)=>h.relativePath===f))if(S.some((h)=>h.key===d.key)&&!x.has(d.key))o.set(Ye(d),d);for(let d of y){if(d.key===null){g.push(d.content);continue}let h=S.find((C)=>C.key===d.key);if(fo({existingRule:d,isUpdated:h!==void 0,generator:t}))continue;g.push(h&&!d.edited?ee(h):d.content),l.push({relativePath:f,key:d.key})}for(let d of S){let h={relativePath:f,key:d.key};if(!x.has(d.key)&&!o.has(Ye(h)))x.set(d.key,{key:d.key,title:d.title,fingerprint:"",content:ee(d),edited:!1}),g.push(ee(d)),l.push(h)}if(g.length>0){await Qt(er.dirname(m),{recursive:!0}),await Bun.write(m,`${g.join(`
25
24
 
26
25
  `)}
27
- `),d+=1,y+=p.length}return await Bun.write(e.paths.profileManifestFile,ze(a)),await Bun.write(e.paths.rejectedProfileFile,ze([...n.values()])),{files:d,rules:y,rejected:n.size}}function Ln(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function le(e){let r=JSON.parse(e);if(!Ln(r))throw Error("Hook input must be a JSON object");return r}function de(e,r){let t=e[r];return typeof t==="string"?t:null}async function qn(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=le(e.input),i=de(o,"cwd")??process.cwd(),s=await B({cwd:i,enabled:t.sources["git-metadata"],readRemote:e.readRemote});if(k({origin:s,cwd:i,patterns:n.blockedOrigins}))return null;return{profile:await oe({profileDirectory:r.profileDirectory,origin:s,targetRepo:Un.basename(i)})}}async function Hr(e){let r=await qn(e);return r===null?null:{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:r.profile}}}async function He(e){let r=await Hr(e);if(r!==null)await Bun.stdout.write(`${JSON.stringify(r)}
28
- `)}import{realpath as Rt}from"fs/promises";import Ke from"path";import{Database as Eo}from"bun:sqlite";import{mkdir as Co}from"fs/promises";import ko from"path";import{stat as Jn}from"fs/promises";import ce from"path";import{stat as zn}from"fs/promises";function Gn(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Hn(e){return Gn(e)&&e.code==="ENOENT"}async function Jr(e){let r=await zn(e.sourcePath).catch((m)=>{if(Hn(m))return null;throw m});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()),y=[],u=0,b=0;for(let m=0;m<d.length;m+=1){if(d[m]!==10)continue;let P=m>u&&d[m-1]===13?m-1:m,p=P-u;if(p>0)y.push({ref:{type:"file",sourcePath:e.sourcePath,byteOffset:s+u,byteLength:p},bytes:d.slice(u,P)});u=m+1,b=u}return{values:y,cursor:{sourcePath:e.sourcePath,byteSize:r.size,modifiedAt:t,byteOffset:s+b},rescanned:i,bytesRead:d.length}}async function A(e){let r=await Jr(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 Wr(e){let r=await Jr(e);if(r===null)return null;return{...r,values:r.values.map((t)=>t.ref)}}function f(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 _(e,r){return e[r]===!0}function F(e,r){let t=e[r];return f(t)?t:null}function w(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 Wn=new Set(["CODE_ACTION","GREP_SEARCH","LIST_DIRECTORY","MCP_TOOL","REPLACE_FILE_CONTENT","RUN_COMMAND","VIEW_FILE","WRITE_TO_FILE"]);function Kr(e){let r=e.tool_calls;if(!Array.isArray(r))return null;let t=r.find(f);if(!t)return null;return{toolUseId:l(t,"id")??l(t,"tool_call_id"),name:l(t,"name")??"unknown"}}function Kn(e,r){return{toolUseId:l(e,"tool_call_id")??l(e,"call_id"),name:l(e,"tool_name")??r.toLowerCase()}}function Xn(e){let r=l(e,"type");if(r==="USER_INPUT")return l(e,"content")===null?null:"user-prompt";if(r==="PLANNER_RESPONSE"){if(Kr(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&&Wn.has(r)?"tool-result":null}function Zn(e){return ce.basename(ce.dirname(ce.dirname(ce.dirname(e))))}function Vn(e){if(!f(e.value))return null;let r=Xn(e.value),t=l(e.value,"type");if(r===null||t===null)return null;let n=e.value.step_index,o=r==="tool-call"?Kr(e.value):r==="tool-result"?Kn(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:w(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 Xr(e){let r=await A(e);if(r===null)return null;let t=Zn(e.sourcePath),n=null,o=r.values.flatMap((i)=>{let s=Vn({...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 Zr(e){try{if(!(await Jn(e)).isDirectory())return[]}catch(n){if(f(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 Qr from"path";import Vr from"path";function ue(e){let r=`${Vr.basename(e.ref.sourcePath)}:${w(e.record.timestamp)}`;return{source:"claude-code",sessionId:l(e.record,"sessionId")??Vr.basename(e.ref.sourcePath,".jsonl"),eventId:l(e.message,"id")??l(e.record,"uuid")??r,parentEventId:l(e.record,"parentUuid"),timestamp:w(e.record.timestamp),cwd:l(e.record,"cwd")??"",gitBranch:l(e.record,"gitBranch")}}function pe(e,r){if(typeof e==="string")return e.includes(r);if(!Array.isArray(e))return!1;return e.some((t)=>f(t)&&typeof t.content==="string"&&t.content.includes(r))}function Yn(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 Yr(e){if(_(e.record,"isMeta"))return[];let r=ue(e),t=e.message.content,n=pe(t,"[Request interrupted by user"),o=pe(t,"user doesn't want to proceed with this tool use"),i=pe(t,"User has answered your questions"),s=pe(t,"The user has approved your plan"),a=typeof t==="string",d=Yn({interrupted:n,denied:o,questionAnswered:i,planResolved:s,plainPrompt:a});return[{...r,kind:d,tool:null,isError:_(e.record,"is_error"),textRef:a&&!n&&!o?e.ref:null}]}function Qn(e){if(e==="ExitPlanMode")return"plan-presented";if(e==="AskUserQuestion")return"question-asked";return"tool-call"}function eo(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 ro(e){let r=e.content;return Array.isArray(r)?r:[r]}function to(e){return e.blocks.length===1&&(l(e.block,"type")==="text"||e.kind==="question-asked"||e.kind==="plan-presented")?e.ref:null}function no(e){let r=ue(e),t=ro(e.message),n=[];for(let o of t){if(!f(o))continue;let i=l(o,"type"),s=eo(o),a=s===null?i==="thinking"?"thinking":"assistant-text":Qn(s.name);n.push({...r,kind:a,tool:s,isError:!1,textRef:to({blocks:t,block:o,ref:e.ref,kind:a})})}return n}function oo(e){if(!f(e.value))return[];let r=l(e.value,"type");if(r==="result"){let n=w(e.value.timestamp);return[{source:"claude-code",sessionId:l(e.value,"session_id")??l(e.value,"sessionId")??Qr.basename(e.ref.sourcePath,".jsonl"),eventId:l(e.value,"uuid")??`result:${Qr.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:_(e.value,"is_error"),textRef:null}]}let t=F(e.value,"message");if(t===null)return[];if(r==="assistant")return no({record:e.value,message:t,ref:e.ref});if(r==="user")return Yr({record:e.value,message:t,ref:e.ref});return[]}async function fe(e){let r=await A(e);if(r===null)return null;return{source:"claude-code",sourcePath:e.sourcePath,events:r.values.flatMap(oo),cursor:r.cursor,rescanned:r.rescanned,bytesRead:r.bytesRead}}async function et(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 io from"path";function so(e){if(!f(e.value))return null;if((l(e.value,"display")??l(e.value,"prompt"))===null)return null;let t=w(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 rt(e){let r=await A(e);if(r===null)return null;let t=r.values.map(so).filter((n)=>n!==null);return{source:"claude-prompts",sourcePath:io.resolve(e.sourcePath),events:t,cursor:r.cursor,rescanned:r.rescanned,bytesRead:r.bytesRead}}import ao from"path";function nt(e){return{sessionId:ao.basename(e,".jsonl"),cwd:"",gitBranch:null}}function tt(e){if(!f(e.value)||l(e.value,"type")!=="session_meta")return null;let r=F(e.value,"payload");if(r===null)return null;let t=F(r,"git");return{sessionId:l(r,"id")??nt(e.sourcePath).sessionId,cwd:l(r,"cwd")??"",gitBranch:t?l(t,"branch"):null}}async function lo(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 ot(e){for(let t of e.values){let n=tt({sourcePath:e.sourcePath,value:t.value});if(n!==null)return n}return tt({sourcePath:e.sourcePath,value:await lo(e.sourcePath)})??nt(e.sourcePath)}function st(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 co(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 st(e)?"tool-call":null}function it(e){return{source:"codex",sessionId:e.context.sessionId,eventId:`codex:${e.ref.byteOffset}`,parentEventId:null,timestamp:w(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 uo(e){if(!f(e.value))return null;let r=l(e.value,"type"),t=F(e.value,"payload");if(t===null)return null;if(r==="response_item"){let i=co(t);return i===null?null:it({context:e.context,envelope:e.value,ref:e.ref,kind:i,tool:st(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{...it({context:e.context,envelope:e.value,ref:e.ref,kind:o,tool:null}),isError:_(t,"is_error")}}async function at(e){let r=await A(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 ot({sourcePath:e.sourcePath,values:r.values}),n=null,o=r.values.flatMap((i)=>{let s=uo({...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 lt(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 po(e){return{type:"sqlite-blob",sourcePath:e.context.sourcePath,blobId:e.blobId,jsonPath:e.jsonPath,unwrap:e.unwrap}}function fo(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 ye(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 dt(e){let r=e.role==="user"&&e.text.includes("<user_query>"),t=e.role==="assistant";if(!r&&!t)return null;return ye({context:e.context,blobId:e.blobId,index:e.index,kind:r?"user-prompt":"assistant-text",tool:null,ref:po({context:e.context,blobId:e.blobId,jsonPath:e.jsonPath,unwrap:r?"user-query":null})})}function ct(e){if(!f(e.blob.value))return[];let r=l(e.blob.value,"role");if(r==="tool")return[ye({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=dt({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(!f(n))return[];let i=l(n,"type");if(r==="assistant"&&i==="reasoning")return[ye({context:e.context,blobId:e.blob.id,index:o,kind:"thinking",tool:null,ref:null})];let s=fo(n);if(s!==null)return[ye({context:e.context,blobId:e.blob.id,index:o,kind:"tool-call",tool:s,ref:null})];let a=l(n,"text"),d=a?dt({context:e.context,blobId:e.blob.id,index:o,role:r??"",text:a,jsonPath:["content",o,"text"]}):null;return d?[d]:[]})}import{Database as yo}from"bun:sqlite";import{stat as mo}from"fs/promises";import M from"path";async function Je(e){try{let r=await mo(e);return{size:r.size,modifiedAt:r.mtimeMs}}catch{return null}}function go(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 ho(e){try{return JSON.parse(new TextDecoder().decode(e))}catch{return null}}async function bo(e){let r=Bun.file(M.join(M.dirname(e),"meta.json"));if(!await r.exists())return null;try{return JSON.parse(await r.text())}catch{return null}}async function ut(e){let r=await Je(e);if(r===null)return null;let[t,n]=await Promise.all([Je(`${e}-wal`),Je(M.join(M.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 pt(e){let r=null;try{r=new yo(e.sourcePath,{readonly:!0,strict:!0});let t=r.query("SELECT id, data FROM blobs ORDER BY rowid").all().flatMap((a)=>{let d=ho(a.data);return d===null?[]:[{id:a.id,value:d}]}),n=go(r.query("SELECT value FROM meta WHERE key = '0'").get()?.value??""),o=await bo(e.sourcePath),i=f(n)?n:{},s=f(o)?o:{};return{blobs:t,sessionId:l(i,"agentId")??M.basename(M.dirname(e.sourcePath)),cwd:l(s,"cwd")??"",timestamp:w(s.createdAtMs)||w(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{throw Error("Cursor chat store could not be read")}finally{r?.close()}}async function ft(e){let r=await ut(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 pt({sourcePath:e.sourcePath,signature:r}),n=[],o=null;for(let i of t.blobs)for(let s of ct({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 yt(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 wo from"path";async function mt(e){let r=await Wr(e);if(r===null)return null;return{source:"shell",sourcePath:wo.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 xo(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function We(e){if(!xo(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 H(e){return JSON.stringify(e)}async function*gt(e){if(e.config.sources.antigravity){let r=await Zr(e.paths.antigravityBrainDirectory);for(let t of r){let n=await Xr({sourcePath:t,cursor:await e.getCursor(t)});if(n!==null)yield n}}if(e.config.sources["claude-code"]){let r=await et(e.paths.claudeProjectsDirectory);for(let t of r){let n=await fe({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 rt({sourcePath:r,cursor:await e.getCursor(r)});if(t!==null)yield t}if(e.config.sources.codex){let r=await lt(e.paths.codexSessionsDirectory);for(let t of r){let n=await at({sourcePath:t,cursor:await e.getCursor(t)});if(n!==null)yield n}}if(e.config.sources.cursor){let r=await yt(e.paths.cursorChatsDirectory);for(let t of r){let n=await ft({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 mt({sourcePath:r,cursor:await e.getCursor(r)});if(t!==null)yield t}}function Po(e){if(e.query("PRAGMA user_version").get()?.user_version===2)return;e.exec(`
26
+ `),u+=1,p+=g.length;continue}if(y.length>0)await uo(m,{force:!0})}return await Bun.write(e.paths.profileManifestFile,Ve(l)),await Bun.write(e.paths.rejectedProfileFile,Ve([...o.values()])),{files:u,rules:p,rejected:o.size}}import ho from"path";function Qe(e){let t=new Bun.CryptoHasher("sha256").update(e).digest("hex").slice(0,16);return{id:`isolated:${t}`,directoryName:`isolated--${t}`,promotable:!1}}function tr(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 tt(e){let t=tr(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 rr(e){let t=tr(e),r=tt(e);if(t===null||r===null)return null;return{id:`${r.id}/${t.repository.toLowerCase()}`,origin:r}}function wo(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?ho.basename(e.cwd):null,r=[e.origin.id,...t?[`${e.origin.id}/${t}`]:[]];return e.patterns.some((n)=>r.some((o)=>wo(o,n)))}async function be(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 et(e){return e.cwd.length>0?e.cwd:`${e.source}:${e.sessionId}`}async function rt(e){let t=new Map,r=e.readRemote??be;for(let n of e.events){let o=et(n);if(t.has(o))continue;t.set(o,await T({cwd:n.cwd,fallbackKey:o,enabled:e.enabled,readRemote:r}))}return t}async function T(e){let t=e.cwd||e.fallbackKey||"unknown",r=e.readRemote??be,n=e.enabled&&e.cwd.length>0?await r(e.cwd):null;return n===null?Qe(t):tt(n)??Qe(t)}async function nt(e){let t=e.readRemote??be,r=e.enabled&&e.cwd.length>0?await t(e.cwd):null,n=r?rr(r):null;if(n!==null)return n;let o=await T({cwd:e.cwd,enabled:!1});return{id:o.id,origin:o}}function oe(e){return e.origins.get(et(e.event))??Qe(et(e.event))}function nr(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 bo(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 xe(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 xo(e){let t=[],r=[],n=null,o=null;for(let s of e.events){let i=oe({event:s,origins:e.origins});if(s.kind==="interruption"){let a=nr(r),l=bo(a);t.push(xe({kind:"interruption",...l,event:s,origin:i,relatedEvent:a}))}if(s.kind==="permission-denied"){let a=nr(r),l=a?.tool?.name??"an unspecified tool";t.push(xe({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(xe({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(xe({kind:"plan-resolved",category:"presented-plan",label:"a presented plan",event:s,origin:i,relatedEvent:o})),o=null}r.push(s)}return t}function or(e){return[...Map.groupBy(e.events,(r)=>`${r.source}:${r.sessionId}`).values()].flatMap((r)=>xo({events:r,origins:e.origins}))}function ir(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 ot(e){return ir(e)}function sr(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:ir(e.flatMap((o)=>o.tool?[{category:o.tool.name,label:o.tool.name}]:[])),planSessions:r.size,totalSessions:t.size}}function Pe(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 it(e){let t=Pe(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 ar(e,t){return e.filter((r)=>r.kind===t).length}async function ve(e){let t=await rt({events:e.events,enabled:e.gitMetadataEnabled,readRemote:e.readRemote}),r=e.events.filter((i)=>!I({origin:oe({event:i,origins:t}),cwd:i.cwd,patterns:e.blockedOrigins??[]})),n=or({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:ot(o),denials:ot(s),answeredQuestions:n.filter((i)=>i.kind==="question-answered").length,askedQuestions:ar(r,"question-asked"),resolvedPlans:n.filter((i)=>i.kind==="plan-resolved").length,presentedPlans:ar(r,"plan-presented"),structural:sr(r)}}}function at(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function vo(e){if(!at(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 lr(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:ge.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((at(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 Ro(e){let{config:t,policy:r}=await k({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?e.paths.managedConfigFile:e.managedConfigPath});if(!r.enabled)return`# Shadowclone profile
27
+ `;let n=await T({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 J({profileDirectory:e.paths.profileDirectory,origin:n,targetRepo:Po.basename(e.cwd)})}async function st(e){await Bun.stdout.write(`${JSON.stringify(e)}
29
+ `)}async function lt(e={}){let t=e.cwd??process.cwd(),r=e.paths??w,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=vo(JSON.parse(a));if(l===null)await st({jsonrpc:"2.0",id:null,error:{code:-32600,message:"Invalid request"}});else{let u=l.method==="tools/call"&&at(l.params)&&l.params.name==="shadowclone_profile"?await Ro({cwd:t,configPath:e.configPath,paths:r,readRemote:e.readRemote,managedConfigPath:e.managedConfigPath}):"",p=lr({request:l,profile:u});if(p!==null)await st(p)}}catch{await st({jsonrpc:"2.0",id:null,error:{code:-32700,message:"Parse error"}})}i=n.indexOf(`
31
+ `)}}}function L(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function v(e,t){let r=e[t];return typeof r==="string"?r:null}function ct(e,t){let r=e[t];return typeof r==="number"?r:null}function ko(e){let t=e.message;if(!L(t)||!Array.isArray(t.content))return"";return t.content.flatMap((r)=>L(r)&&v(r,"type")==="text"&&v(r,"text")!==null?[v(r,"text")??""]:[]).join("")}function Eo(e){let t=e.message;if(!L(t)||!Array.isArray(t.content))return[];return t.content.flatMap((r)=>{if(!L(r)||v(r,"type")!=="tool_use")return[];let n=v(r,"name")??"",o=L(r.input)?r.input:null,s=o?v(o,"file_path")??v(o,"path")??v(o,"notebook_path"):null,i=o?v(o,"command"):null;return[{tool:n,path:s,command:i}]})}function So(e){if(!Array.isArray(e))return[];return e.flatMap((t)=>{if(!L(t))return[];let r=v(t,"tool_name")??v(t,"toolName");return r?[{toolName:r,toolUseId:v(t,"tool_use_id")??v(t,"toolUseId")}]:[]})}function dt(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(!L(a))continue;if(v(a,"type")==="assistant")t.push(ko(a)),r.push(...Eo(a));if(v(a,"type")==="result")n=a}catch{}}let o=n?v(n,"result"):null,s=t.join("");return{engine:"claude-code",sessionId:(n?v(n,"session_id"):null)??e.fallbackSessionId,transcriptPath:null,text:s.length>0?s:o??"",structured:n?.structured_output??null,costUsd:n?ct(n,"total_cost_usd"):null,durationMs:n?ct(n,"duration_ms")??0:0,turns:n?ct(n,"num_turns")??0:0,isError:n?.is_error===!0||n===null,permissionDenials:So(n?.permission_denials),actions:r}}function cr(e){if(e.values===void 0||e.values.length===0)return;e.arguments_.push(e.flag),e.arguments_.push(...e.values)}function dr(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 cr({arguments_:t,flag:"--allowedTools",values:e.run.allowedTools}),cr({arguments_:t,flag:"--disallowedTools",values:e.run.disallowedTools}),t}async function ut(e){let t=e.sessionId??crypto.randomUUID(),r=Bun.spawn({cmd:[...dr({run:e,sessionId:t})],cwd:e.cwd,stdin:"pipe",stdout:"pipe",stderr:"ignore",signal:e.signal});r.stdin.write(e.prompt),r.stdin.end();let[n,o]=await Promise.all([r.exited,new Response(r.stdout).text()]),s=dt({stream:o,fallbackSessionId:t});return n===0?s:{...s,isError:!0}}import{mkdtemp as Io,rm as Ao}from"fs/promises";import To from"os";import pr from"path";function ur(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function ie(e,t){let r=e[t];return typeof r==="string"?r:null}function Co(e){try{return JSON.parse(e)}catch{return null}}function pt(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(!ur(i))continue;let a=ie(i,"type");if(a==="thread.started")t=ie(i,"thread_id")??t;if(a==="turn.completed")n+=1;if(a==="turn.failed"||a==="error")o=!0;let l=ur(i.item)?i.item:null,u=l?ie(l,"item_type")??ie(l,"type"):null;if(a==="item.completed"&&l!==null&&(u==="assistant_message"||u==="agent_message"))r=ie(l,"text")??r}return{engine:"codex",sessionId:t,transcriptPath:null,text:r,structured:Co(r),costUsd:null,durationMs:e.durationMs,turns:n,isError:o,permissionDenials:[]}}async function Re(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 mr(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 gr(e){mr(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 fr(e){let t=await Re({run:e.run,outputSchemaInPrompt:!1}),r=crypto.randomUUID(),n=Date.now(),o=Bun.spawn({cmd:[...gr(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=pt({stream:i,fallbackSessionId:r,durationMs:Date.now()-n});return s===0?a:{...a,isError:!0}}async function ft(e){if(mr(e),e.outputSchema===void 0)return fr({run:e});let t=await Io(pr.join(To.tmpdir(),"shadowclone-codex-")),r=pr.join(t,"schema.json");await Bun.write(r,JSON.stringify(e.outputSchema));try{return await fr({run:e,outputSchemaPath:r})}finally{await Ao(t,{recursive:!0,force:!0})}}import{mkdir as jo,mkdtemp as _o,rm as Mo}from"fs/promises";import Fo from"os";import gt from"path";function Do(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function ke(e,t){let r=e[t];return typeof r==="string"?r:null}function Bo(e,t){let r=e[t];return typeof r==="number"?r:null}function Oo(e){try{return JSON.parse(e)}catch{return null}}function mt(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(!Do(i))continue;if(t=ke(i,"session_id")??t,ke(i,"type")==="assistant")n+=1;if(ke(i,"type")==="result")r=i}let o=r?ke(r,"result")??"":"";return{engine:"cursor-agent",sessionId:t,transcriptPath:null,text:o,structured:Oo(o),costUsd:null,durationMs:r?Bo(r,"duration_ms")??0:0,turns:n,isError:r===null||r.is_error===!0,permissionDenials:[]}}function hr(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 wr(e){hr(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 yr(e){let t=await Re({run:e.run,outputSchemaInPrompt:!0}),r=crypto.randomUUID(),n=Bun.spawn({cmd:[...wr({...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=mt({stream:s,fallbackSessionId:r});return o===0?i:{...i,isError:!0}}async function yt(e){if(hr(e),e.allowedTools?.length!==0)return yr({run:e,workspace:e.cwd});let t=await _o(gt.join(Fo.tmpdir(),"shadowclone-cursor-")),r=gt.join(t,".cursor");await jo(r,{recursive:!0}),await Bun.write(gt.join(r,"cli.json"),JSON.stringify({version:1,permissions:{allow:[],deny:["Shell(*)","Read(*)","Write(*)","WebFetch(*)","Mcp(*:*)"]}}));try{return await yr({run:e,workspace:t})}finally{await Mo(t,{recursive:!0,force:!0})}}var Ee=[{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 ht(e){return Ee.find((t)=>t.engine?.id===e)??null}function $o(e){return e?.implemented===!0&&e.capabilities.structuredOutput!=="none"&&e.capabilities.isolatedNoTools}function Se(e){let t=$o(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 wt(e){let t=Se(e.definition);return e.purpose==="distill"?t.distill:t.dispatch}async function Ce(e){try{return await Bun.spawn({cmd:[...e],stdout:"ignore",stderr:"ignore"}).exited===0}catch{return!1}}async function br(e={}){let t=e.probe??Ce,r=await t(["claude","--version"]),n=r&&await t(["claude","auth","status"]);return{engine:"claude-code",installed:r,authenticated:n}}async function xr(e={}){let t=e.probe??Ce,r=await t(["codex","--version"]),n=r&&await t(["codex","login","status"]);return{engine:"codex",installed:r,authenticated:n}}async function Pr(e={}){let t=e.probe??Ce,r=await t(["cursor-agent","--version"]),n=r&&await t(["cursor-agent","status"]);return{engine:"cursor-agent",installed:r,authenticated:n}}function No(e){if(e==="claude-code")return ut;if(e==="codex")return ft;if(e==="cursor-agent")return yt;return null}function Lo(e){let t=ht(e.engineId);return t!==null&&wt({definition:t,purpose:e.purpose})}async function D(e){let t=await br(e),r=await xr(e),n=await Pr(e),o=e.allowedEngines??["claude-code","codex","cursor-agent"],s=[t,r,n],i=s.find((l)=>l.authenticated&&o.includes(l.engine)&&Lo({engineId:l.engine,purpose:e.purpose})),a=i?No(i.engine):null;return{availability:s,runner:a,selectedEngine:a?i?.engine??null:null}}import{Database as Pi}from"bun:sqlite";import{mkdir as vi}from"fs/promises";import Ri from"path";import{stat as Go}from"fs/promises";import Ie from"path";import{stat as Uo}from"fs/promises";function qo(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function zo(e){return qo(e)&&e.code==="ENOENT"}async function vr(e){let t=await Uo(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()),u=[],p=0,f=0;for(let m=0;m<l.length;m+=1){if(l[m]!==10)continue;let x=m>p&&l[m-1]===13?m-1:m,S=x-p;if(S>0)u.push({ref:{type:"file",sourcePath:e.sourcePath,byteOffset:i+p,byteLength:S},bytes:l.slice(p,x)});p=m+1,f=p}return{values:u,cursor:{sourcePath:e.sourcePath,byteSize:t.size,modifiedAt:r,byteOffset:i+f},rescanned:s,bytesRead:l.length}}async function O(e){let t=await vr(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 Rr(e){let t=await vr(e);if(t===null)return null;return{...t,values:t.values.map((r)=>r.ref)}}function b(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 U(e,t){return e[t]===!0}function q(e,t){let r=e[t];return b(r)?r:null}function E(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 Ho=new Set(["CODE_ACTION","GREP_SEARCH","LIST_DIRECTORY","MCP_TOOL","REPLACE_FILE_CONTENT","RUN_COMMAND","VIEW_FILE","WRITE_TO_FILE"]);function kr(e){let t=e.tool_calls;if(!Array.isArray(t))return null;let r=t.find(b);if(!r)return null;return{toolUseId:c(r,"id")??c(r,"tool_call_id"),name:c(r,"name")??"unknown"}}function Jo(e,t){return{toolUseId:c(e,"tool_call_id")??c(e,"call_id"),name:c(e,"tool_name")??t.toLowerCase()}}function Wo(e){let t=c(e,"type");if(t==="USER_INPUT")return c(e,"content")===null?null:"user-prompt";if(t==="PLANNER_RESPONSE"){if(kr(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&&Ho.has(t)?"tool-result":null}function Ko(e){return Ie.basename(Ie.dirname(Ie.dirname(Ie.dirname(e))))}function Xo(e){if(!b(e.value))return null;let t=Wo(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"?kr(e.value):t==="tool-result"?Jo(e.value,r):null;return{source:"antigravity",sessionId:e.sessionId,eventId:`antigravity:${typeof s==="number"?s:e.ref.byteOffset}`,parentEventId:null,timestamp:E(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 Er(e){let t=await O(e);if(t===null)return null;let r=Ko(e.sourcePath),n=null,o=t.values.flatMap((s)=>{let i=Xo({...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 Sr(e){try{if(!(await Go(e)).isDirectory())return[]}catch(n){if(b(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 Ar from"path";import Cr from"path";function Ae(e){let t=`${Cr.basename(e.ref.sourcePath)}:${E(e.record.timestamp)}`;return{source:"claude-code",sessionId:c(e.record,"sessionId")??Cr.basename(e.ref.sourcePath,".jsonl"),eventId:c(e.message,"id")??c(e.record,"uuid")??t,parentEventId:c(e.record,"parentUuid"),timestamp:E(e.record.timestamp),cwd:c(e.record,"cwd")??"",gitBranch:c(e.record,"gitBranch")}}function Te(e,t){if(typeof e==="string")return e.includes(t);if(!Array.isArray(e))return!1;return e.some((r)=>b(r)&&typeof r.content==="string"&&r.content.includes(t))}function Zo(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 Ir(e){if(U(e.record,"isMeta"))return[];let t=Ae(e),r=e.message.content,n=Te(r,"[Request interrupted by user"),o=Te(r,"user doesn't want to proceed with this tool use"),s=Te(r,"User has answered your questions"),i=Te(r,"The user has approved your plan"),a=typeof r==="string",l=Zo({interrupted:n,denied:o,questionAnswered:s,planResolved:i,plainPrompt:a});return[{...t,kind:l,tool:null,isError:U(e.record,"is_error"),textRef:a&&!n&&!o?e.ref:null}]}function Vo(e){if(e==="ExitPlanMode")return"plan-presented";if(e==="AskUserQuestion")return"question-asked";return"tool-call"}function Yo(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 Qo(e){let t=e.content;return Array.isArray(t)?t:[t]}function ei(e){return e.blocks.length===1&&(c(e.block,"type")==="text"||e.kind==="question-asked"||e.kind==="plan-presented")?e.ref:null}function ti(e){let t=Ae(e),r=Qo(e.message),n=[];for(let o of r){if(!b(o))continue;let s=c(o,"type"),i=Yo(o),a=i===null?s==="thinking"?"thinking":"assistant-text":Vo(i.name);n.push({...t,kind:a,tool:i,isError:!1,textRef:ei({blocks:r,block:o,ref:e.ref,kind:a})})}return n}function ri(e){if(!b(e.value))return[];let t=c(e.value,"type");if(t==="result"){let n=E(e.value.timestamp);return[{source:"claude-code",sessionId:c(e.value,"session_id")??c(e.value,"sessionId")??Ar.basename(e.ref.sourcePath,".jsonl"),eventId:c(e.value,"uuid")??`result:${Ar.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:U(e.value,"is_error"),textRef:null}]}let r=q(e.value,"message");if(r===null)return[];if(t==="assistant")return ti({record:e.value,message:r,ref:e.ref});if(t==="user")return Ir({record:e.value,message:r,ref:e.ref});return[]}async function De(e){let t=await O(e);if(t===null)return null;return{source:"claude-code",sourcePath:e.sourcePath,events:t.values.flatMap(ri),cursor:t.cursor,rescanned:t.rescanned,bytesRead:t.bytesRead}}async function Tr(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 ni from"path";function oi(e){if(!b(e.value))return null;if((c(e.value,"display")??c(e.value,"prompt"))===null)return null;let r=E(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 Dr(e){let t=await O(e);if(t===null)return null;let r=t.values.map(oi).filter((n)=>n!==null);return{source:"claude-prompts",sourcePath:ni.resolve(e.sourcePath),events:r,cursor:t.cursor,rescanned:t.rescanned,bytesRead:t.bytesRead}}import ii from"path";function Or(e){return{sessionId:ii.basename(e,".jsonl"),cwd:"",gitBranch:null}}function Br(e){if(!b(e.value)||c(e.value,"type")!=="session_meta")return null;let t=q(e.value,"payload");if(t===null)return null;let r=q(t,"git");return{sessionId:c(t,"id")??Or(e.sourcePath).sessionId,cwd:c(t,"cwd")??"",gitBranch:r?c(r,"branch"):null}}async function si(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 jr(e){for(let r of e.values){let n=Br({sourcePath:e.sourcePath,value:r.value});if(n!==null)return n}return Br({sourcePath:e.sourcePath,value:await si(e.sourcePath)})??Or(e.sourcePath)}function Mr(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 ai(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 Mr(e)?"tool-call":null}function _r(e){return{source:"codex",sessionId:e.context.sessionId,eventId:`codex:${e.ref.byteOffset}`,parentEventId:null,timestamp:E(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 li(e){if(!b(e.value))return null;let t=c(e.value,"type"),r=q(e.value,"payload");if(r===null)return null;if(t==="response_item"){let s=ai(r);return s===null?null:_r({context:e.context,envelope:e.value,ref:e.ref,kind:s,tool:Mr(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{..._r({context:e.context,envelope:e.value,ref:e.ref,kind:o,tool:null}),isError:U(r,"is_error")}}async function Fr(e){let t=await O(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 jr({sourcePath:e.sourcePath,values:t.values}),n=null,o=t.values.flatMap((s)=>{let i=li({...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 $r(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 ci(e){return{type:"sqlite-blob",sourcePath:e.context.sourcePath,blobId:e.blobId,jsonPath:e.jsonPath,unwrap:e.unwrap}}function di(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 Be(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 Nr(e){let t=e.role==="user"&&e.text.includes("<user_query>"),r=e.role==="assistant";if(!t&&!r)return null;return Be({context:e.context,blobId:e.blobId,index:e.index,kind:t?"user-prompt":"assistant-text",tool:null,ref:ci({context:e.context,blobId:e.blobId,jsonPath:e.jsonPath,unwrap:t?"user-query":null})})}function Lr(e){if(!b(e.blob.value))return[];let t=c(e.blob.value,"role");if(t==="tool")return[Be({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=Nr({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(!b(n))return[];let s=c(n,"type");if(t==="assistant"&&s==="reasoning")return[Be({context:e.context,blobId:e.blob.id,index:o,kind:"thinking",tool:null,ref:null})];let i=di(n);if(i!==null)return[Be({context:e.context,blobId:e.blob.id,index:o,kind:"tool-call",tool:i,ref:null})];let a=c(n,"text"),l=a?Nr({context:e.context,blobId:e.blob.id,index:o,role:t??"",text:a,jsonPath:["content",o,"text"]}):null;return l?[l]:[]})}import{Database as ui}from"bun:sqlite";import{stat as pi}from"fs/promises";import W from"path";async function bt(e){try{let t=await pi(e);return{size:t.size,modifiedAt:t.mtimeMs}}catch{return null}}function fi(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 mi(e){try{return JSON.parse(new TextDecoder().decode(e))}catch{return null}}async function gi(e){let t=Bun.file(W.join(W.dirname(e),"meta.json"));if(!await t.exists())return null;try{return JSON.parse(await t.text())}catch{return null}}async function Ur(e){let t=await bt(e);if(t===null)return null;let[r,n]=await Promise.all([bt(`${e}-wal`),bt(W.join(W.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))}}async function qr(e){let t=null;try{t=new ui(e.sourcePath,{readonly:!0,strict:!0});let r=t.query("SELECT id, data FROM blobs ORDER BY rowid").all().flatMap((a)=>{let l=mi(a.data);return l===null?[]:[{id:a.id,value:l}]}),n=fi(t.query("SELECT value FROM meta WHERE key = '0'").get()?.value??""),o=await gi(e.sourcePath),s=b(n)?n:{},i=b(o)?o:{};return{blobs:r,sessionId:c(s,"agentId")??W.basename(W.dirname(e.sourcePath)),cwd:c(i,"cwd")??"",timestamp:E(i.createdAtMs)||E(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 zr(e){let t=await Ur(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 qr({sourcePath:e.sourcePath,signature:t});if(r===null)return null;let n=[],o=null;for(let s of r.blobs)for(let i of Lr({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 Gr(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 yi from"path";async function Hr(e){let t=await Rr(e);if(t===null)return null;return{source:"shell",sourcePath:yi.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 hi(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function xt(e){if(!hi(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 se(e){return JSON.stringify(e)}async function*Jr(e){if(e.config.sources.antigravity){let t=await Sr(e.paths.antigravityBrainDirectory);for(let r of t){let n=await Er({sourcePath:r,cursor:await e.getCursor(r)});if(n!==null)yield n}}if(e.config.sources["claude-code"]){let t=await Tr(e.paths.claudeProjectsDirectory);for(let r of t){let n=await De({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 Dr({sourcePath:t,cursor:await e.getCursor(t)});if(r!==null)yield r}if(e.config.sources.codex){let t=await $r(e.paths.codexSessionsDirectory);for(let r of t){let n=await Fr({sourcePath:r,cursor:await e.getCursor(r)});if(n!==null)yield n}}if(e.config.sources.cursor){let t=await Gr(e.paths.cursorChatsDirectory);for(let r of t){let n=await zr({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 Hr({sourcePath:t,cursor:await e.getCursor(t)});if(r!==null)yield r}}function wi(e){if(e.query("PRAGMA user_version").get()?.user_version===2)return;e.exec(`
29
37
  DROP TABLE IF EXISTS events;
30
38
  DROP TABLE IF EXISTS cursors;
31
- `)}function ht(e){Po(e),e.exec(`
39
+ `)}function Wr(e){wi(e),e.exec(`
32
40
  PRAGMA journal_mode = WAL;
33
41
  PRAGMA foreign_keys = ON;
34
42
 
@@ -65,22 +73,22 @@ ${i.map((s)=>s.content).join(`
65
73
  ON events(kind);
66
74
 
67
75
  PRAGMA user_version = 2;
68
- `)}function bt(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 Kr(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 (
69
77
  source_path, source, session_id, event_id, parent_event_id,
70
78
  timestamp, cwd, git_branch, kind, tool_use_id, tool_name,
71
79
  is_error, text_ref
72
- ) 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 (
73
81
  source_path, source, byte_size, modified_at, byte_offset
74
82
  ) VALUES (?, ?, ?, ?, ?)
75
83
  ON CONFLICT(source_path) DO UPDATE SET
76
84
  source = excluded.source,
77
85
  byte_size = excluded.byte_size,
78
86
  modified_at = excluded.modified_at,
79
- byte_offset = excluded.byte_offset`).run(t.sourcePath,t.source,t.cursor.byteSize,t.cursor.modifiedAt,t.cursor.byteOffset)})(e.batch)}function Ro(e){if(e===null)return null;try{return We(JSON.parse(e))}catch{return null}}function vo(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:Ro(e.text_ref)}}class me{#e;constructor(e){this.#e=e}getCursor(e){let r=this.#e.query(`SELECT source_path, byte_size, modified_at, byte_offset
80
- 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){bt({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 bi(e){if(e===null)return null;try{return xt(JSON.parse(e))}catch{return null}}function xi(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:bi(e.text_ref)}}class Oe{#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){Kr({database:this.#e,batch:e})}listEvents(){return this.#e.query(`SELECT id, source_path, source, session_id, event_id,
81
89
  parent_event_id, timestamp, cwd, git_branch, kind, tool_use_id,
82
90
  tool_name, is_error, text_ref
83
- FROM events ORDER BY source, session_id, id`).all().map(vo)}getCorpusSummary(){return this.#e.query(`SELECT
91
+ FROM events ORDER BY source, session_id, id`).all().map(xi)}getCorpusSummary(){return this.#e.query(`SELECT
84
92
  (SELECT COUNT(*) FROM (
85
93
  SELECT DISTINCT source, session_id FROM events
86
94
  )) AS sessions,
@@ -88,16 +96,27 @@ ${i.map((s)=>s.content).join(`
88
96
  (SELECT COUNT(*) FROM (
89
97
  SELECT DISTINCT date(timestamp / 1000, 'unixepoch')
90
98
  FROM events WHERE timestamp > 0
91
- )) 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 ge(e){await Co(ko.dirname(e),{recursive:!0});let r=new Eo(e,{create:!0});return ht(r),new me(r)}async function wt(e){let r=0,t=0,n=0,o=0;for await(let i of gt({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 xt(e){let r=await fe({sourcePath:e.sourcePath,cursor:e.index.getCursor(e.sourcePath)});if(r===null)return 0;return e.index.saveBatch(r),r.events.length}async function Pt(e){let r=e.index.listEvents(),t=await ae({events:r,corpus:e.index.getCorpusSummary(),gitMetadataEnabled:e.config.sources["git-metadata"],readRemote:e.readRemote,blockedOrigins:e.blockedOrigins}),n=z({events:t.events,signals:t.corrections,origins:t.origins});await G({paths:e.paths,rules:n})}async function So(e){let r,t;try{[r,t]=await Promise.all([Rt(e.filePath),Rt(e.directory)])}catch{return!1}let n=Ke.relative(t,r);return n.length>0&&!n.startsWith(`..${Ke.sep}`)&&n!==".."&&!Ke.isAbsolute(n)}async function Xe(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=de(le(e.input),"transcript_path");if(o===null||!await So({filePath:o,directory:r.claudeProjectsDirectory}))throw Error("Session hook received an invalid transcript path");let i=await ge(r.indexDatabase);try{await xt({index:i,sourcePath:o}),await Pt({index:i,config:t,paths:r,readRemote:e.readRemote,blockedOrigins:n.blockedOrigins})}finally{i.close()}}var Io=[{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 Ao(e){return prompt(`${e} [y/N]`)?.trim().toLowerCase()==="y"}async function vt(e={}){await Oe({config:O,configPath:e.configPath});let r=e.ask??Ao,t=O,n=!1;for(let d of Io){let y=await r(d.question);t=De({config:t,source:d.id,enabled:y}),n=n||y}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=De({config:t,source:"git-metadata",enabled:o}),a=kr({config:s,enabled:i});await Oe({config:a,configPath:e.configPath}),console.log(n||o||i?"Selected sources and capabilities enabled.":"All capture sources remain disabled.")}import To from"path";async function Et(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 B({cwd:r,enabled:n.sources["git-metadata"],readRemote:e.readRemote});if(k({origin:i,cwd:r,patterns:o.blockedOrigins}))throw Error("Managed policy blocks this repository");let s=await q({profileDirectory:t.profileDirectory,outputPath:t.compiledProfileFile,origin:i,targetRepo:To.basename(r)});await Be({targetDirectory:r,profile:s}),console.log("Installed .claude/agents/shadowclone.md for this repository.")}import Oo from"os";import{Database as Do}from"bun:sqlite";var Ze=[{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 Ct(e){let r=e.homeDirectory??Oo.homedir(),t=r?e.text.replaceAll(r,"~"):e.text;for(let n of Ze)t=t.replace(n.pattern,n.replacement);return t}var Jl=Ze.map((e)=>e.label);function Bo(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function _o(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(!Bo(r))return null;r=r[t]}return r}function Fo(e){if(e.unwrap===null)return e.text;return e.text.match(/<user_query>\s*([\s\S]*?)\s*<\/user_query>/)?.[1]??""}async function jo(e){if(!await Bun.file(e.sourcePath).exists())return"";let r=null;try{r=new Do(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=_o({value:n,path:e.jsonPath});return typeof o==="string"?Fo({text:o,unwrap:e.unwrap}):""}catch{return""}finally{r?.close()}}async function Ve(e){if(e.ref.type==="sqlite-blob"){let n=await jo(e.ref);return Ct({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 Ct({text:t})}function J(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 Ye(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 Ve({ref:s});if(a.length>0)i.push(a.slice(0,t))}n.push([`Kind: ${o.kind}`,`Pattern: ${o.label}`,...i.map((s)=>`Excerpt:
92
- ${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 j(e){await vi(Ri.dirname(e),{recursive:!0});let t=new Pi(e,{create:!0});return Wr(t),new Oe(t)}async function Xr(e){let t=0,r=0,n=0,o=0;for await(let s of Jr({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 Zr(e){let t=await De({sourcePath:e.sourcePath,cursor:e.index.getCursor(e.sourcePath)});if(t===null)return 0;return e.index.saveBatch(t),t.events.length}function ki(){return Ee.map((e)=>{let t=Se(e);return`${e.id}: observe=${t.observe?"yes":"no"}, distill=${t.distill?"yes":"no"}, dispatch=${t.dispatch?"yes":"no"}`})}function Ei(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 Si(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 Vr(e={}){let t=e.managedConfigPath===void 0?w.managedConfigFile:e.managedConfigPath,r=await Q(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 D({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(Ei({distillation:r.distillation,selectedEngine:o.selectedEngine})),console.log("Provider support:");for(let i of ki())console.log(i);if(await Bun.file(e.databasePath??w.indexDatabase).exists()){let i=await j(e.databasePath??w.indexDatabase);try{let a=i.listEvents(),l=Pe(a);console.log("Marker health:");for(let u of Si({health:l}))console.log(` ${u}`)}finally{i.close()}}}import Pt from"path";var Yr=new Set(["Edit","Write","NotebookEdit"]),Qr=new Set(["ExitPlanMode","TodoWrite","Plan","EnterPlanMode"]);function en(e){let t=Pt.posix.normalize(e.rawPath.replaceAll("\\","/"));if(e.cwd){let r=Pt.posix.normalize(e.cwd.replaceAll("\\","/"));if(t.startsWith(r))return Pt.posix.relative(r,t)}return t}function tn(e){return e.trim().split(/\s+/).filter(Boolean).slice(0,2).join(" ")}function je(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(Qr.has(a.tool))i=!0;if(Yr.has(a.tool)){if(!s)o=i,s=!0;if(a.path)r.push(en({rawPath:a.path,cwd:e.cwd}))}if(a.tool==="Bash"&&a.command){let l=tn(a.command);if(l.length>0)n.push(l)}}return{tools:t,verificationSteps:[...new Set(n)],filesTouched:[...new Set(r)],plannedBeforeEditing:o}}function vt(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&&Qr.has(i))o=!0;if(i&&Yr.has(i)){if(!n)r=o,n=!0}}return{tools:t,verificationSteps:[],filesTouched:null,plannedBeforeEditing:r}}import{mkdir as Mi,mkdtemp as sn,rm as an}from"fs/promises";import ln from"os";import de from"path";import Ci from"os";import{Database as Ii}from"bun:sqlite";function R(e,t){return(r)=>{if(t<=0)return`[redacted:${e}]`;return`${r.slice(0,t)}...[redacted:${e}]`}}function ae(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 rn(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 u=r.slice(a).slice(0,t);return`${s}${i}${u}...[redacted:${e}]`}}var Rt=[{label:"pem-block",pattern:/-----BEGIN [^-]+-----[\s\S]*?-----END [^-]+-----/g,replace:R("pem-block",0)},{label:"authorization-header",pattern:/(Authorization\s*:\s*)(?:Bearer|Basic|Token)\s+[A-Za-z0-9._~+/=-]+/gi,replace:ae("authorization",0)},{label:"stripe-key",pattern:/\b[sr]k_(?:live|test)_[A-Za-z0-9]{20,}\b/g,replace:R("stripe-key",8)},{label:"google-api-key",pattern:/\bAIza[0-9A-Za-z_-]{35}\b/g,replace:R("google-api-key",4)},{label:"llm-api-key",pattern:/\bsk-[A-Za-z0-9_-]{12,}\b/g,replace:R("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:R("github-token",7)},{label:"slack-token",pattern:/\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g,replace:R("slack-token",7)},{label:"aws-access-key-id",pattern:/\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,replace:R("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:R("jwt",0)},{label:"hex-secret",pattern:/\b[0-9a-f]{32,}\b/gi,replace:R("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:rn("secret-assignment",0)},{label:"database-url",pattern:/\b((?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis):\/\/)[^\s"'`]+/gi,replace:ae("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:R("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:R("ip-address",0)},{label:"internal-hostname",pattern:/\b(?:[a-z0-9-]+\.)+(?:internal|corp|local)\b/gi,replace:R("internal-hostname",0)},{label:"cloud-resource",pattern:/\b(arn:aws:|(?:s3|gs):\/\/)[^\s"'`]+/gi,replace:ae("cloud-resource",0)},{label:"windows-path",pattern:/\b[A-Za-z]:(?:\/|\\{1,2})Users(?:\/|\\{1,2})[^\s"'`<>|]+/g,replace:R("windows-path",0)},{label:"absolute-path",pattern:/(^|[\s("'=])\/(?:Users|home|private|var|opt|etc|srv|Volumes|mnt|root|data|workspace)\/[^\s"'`),]+/gm,replace:ae("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:R("high-entropy-string",7)}];function Ai(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ti(e){if(e.homeDirectory.length===0)return e.text;let t=Ai(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 nn(e){let t=e.homeDirectory??Ci.homedir(),r=t?Ti({text:e.text,homeDirectory:t}):e.text;for(let n of Rt)r=r.replace(n.pattern,n.replace);return r}var Lc=Rt.map((e)=>e.label);function Di(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Bi(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(!Di(t))return null;t=t[r]}return t}function Oi(e){if(e.unwrap===null)return e.text;return e.text.match(/<user_query>\s*([\s\S]*?)\s*<\/user_query>/)?.[1]??""}async function ji(e){if(!await Bun.file(e.sourcePath).exists())return"";let t=null;try{t=new Ii(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=Bi({value:n,path:e.jsonPath});return typeof o==="string"?Oi({text:o,unwrap:e.unwrap}):""}catch{return""}finally{t?.close()}}async function le(e){if(e.ref.type==="sqlite-blob"){let n=await ji(e.ref);return nn({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 nn({text:r})}import _i from"path";function on(e){return _i.posix.normalize(e.replaceAll("\\","/"))}function kt(e,t){if(e===null||t===null)return null;let r=new Set(e.map(on)),n=new Set(t.map(on)),o=new Set([...r,...n]);if(o.size===0)return null;return[...r].filter((i)=>n.has(i)).length/o.size}function ce(e){let t=kt(e.actual.tools,e.clone.tools)??0,r=kt(e.actual.verificationSteps,e.clone.verificationSteps),n=kt(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,u)=>l+u,0),a=s.length>0?i/s.length:0;return{tools:t,verification:r,files:n,planning:o,total:a}}function Et(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}}var Fi={id:"global",directoryName:"global",promotable:!0};function ue(e){let t=e.filter((r)=>r!==null);return t.length>0?t.reduce((r,n)=>r+n,0)/t.length:null}var St=(e)=>({tools:ue(e.map((t)=>t.tools))??0,verification:ue(e.map((t)=>t.verification)),files:ue(e.map((t)=>t.files)),planning:ue(e.map((t)=>t.planning))??0,total:ue(e.map((t)=>t.total))??0});async function Ct(e={}){let t=e.paths??w,{policy:r}=await k({configPath:e.configPath,managedConfigPath:t.managedConfigFile});if(!r.enabled)throw Error("Shadowclone is disabled by managed policy");let n=e.runner?null:await D({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 j(t.indexDatabase),i=s.listEvents();s.close();let a=new Map;for(let g of i){let d=a.get(g.sessionId)??[];d.push(g),a.set(g.sessionId,d)}let l=e.since?Date.parse(e.since):0,u=[...a.entries()].filter(([g,d])=>Boolean(d[0]&&d[0].timestamp>=l&&d.some((h)=>h.kind==="user-prompt"&&h.textRef!==null))).slice(0,e.sessions??10),p=crypto.randomUUID(),f=de.join(t.shadowcloneDirectory,"eval",p);await Mi(f,{recursive:!0});let m=de.join(f,"profile.md");await F({profileDirectory:t.profileDirectory,outputPath:m,origin:Fi});let y=[];for(let[g,d]of u){let h=d.find((me)=>me.kind==="user-prompt"&&me.textRef!==null);if(!h?.textRef)continue;let C=await le({ref:h.textRef}),V=vt({events:d}),Y=await sn(de.join(ln.tmpdir(),"shadowclone-eval-base-")),Nt=await sn(de.join(ln.tmpdir(),"shadowclone-eval-clone-")),Le,Ue;try{let me=await o({prompt:C,cwd:Y,sessionId:`eval-base-${g}`,permissionMode:"dontAsk",maxBudgetUsd:e.maxBudgetUsd??0.5}),_n=je({actions:me.actions??[]});Le=ce({actual:V,clone:_n});let Mn=await o({prompt:C,cwd:Nt,systemPromptFile:m,sessionId:`eval-clone-${g}`,permissionMode:"dontAsk",maxBudgetUsd:e.maxBudgetUsd??0.5}),Fn=je({actions:Mn.actions??[]});Ue=ce({actual:V,clone:Fn})}finally{await an(Y,{recursive:!0,force:!0}),await an(Nt,{recursive:!0,force:!0})}let jn=Et({baseline:Le,clone:Ue});y.push({sessionId:g,prompt:C,baseline:Le,clone:Ue,delta:jn})}let x={evalId:p,timestamp:new Date().toISOString(),sessionsEvaluated:y.length,averageBaseline:St(y.map((g)=>g.baseline)),averageClone:St(y.map((g)=>g.clone)),averageDelta:St(y.map((g)=>g.delta)),sessions:y},S=de.join(t.shadowcloneDirectory,"eval",`${p}.json`);if(await Bun.write(S,JSON.stringify(x,null,2)),e.json)console.log(JSON.stringify(x,null,2));else console.log(`Evaluated ${x.sessionsEvaluated} sessions.`),console.log(`Total delta: ${(x.averageDelta.total*100).toFixed(1)}% (${(x.averageBaseline.total*100).toFixed(1)}% -> ${(x.averageClone.total*100).toFixed(1)}%)`),console.log(`Receipt: ${S}`);return x}function $i(e){return prompt(`${e} [y/N]`)?.trim().toLowerCase()==="y"}async function cn(e,t={}){let r,n,o=!1,s,i=!1;for(let f=0;f<e.length;f++){let m=e[f];if(m==="--json")o=!0;else if(m==="--yes"||m==="-y")i=!0;else if(m==="--sessions"&&f+1<e.length){f++;let y=Number.parseInt(e[f]??"",10);if(!Number.isNaN(y))r=y}else if(m==="--since"&&f+1<e.length)f++,n=e[f];else if(m==="--max-budget-usd"&&f+1<e.length){f++;let y=Number.parseFloat(e[f]??"");if(!Number.isNaN(y))s=y}}let a=r??10,l=s??0.5,u=a*2*l,p=t.ask??$i;if(!i&&!o&&process.stdin.isTTY){let f=`Running eval on up to ${a} sessions (2 runs each, max $${u.toFixed(2)} budget). Proceed?`;if(!await p(f)){console.log("Evaluation cancelled.");return}}await Ct({sessions:r,since:n,json:o,maxBudgetUsd:s,runner:t.runner,paths:t.paths})}import{rm as Ni}from"fs/promises";async function dn(e=w.shadowcloneDirectory){await Ni(e,{recursive:!0,force:!0}),console.log("Removed all shadowclone data.")}import Ui from"path";function Li(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function _e(e){let t=JSON.parse(e);if(!Li(t))throw Error("Hook input must be a JSON object");return t}function Me(e,t){let r=e[t];return typeof r==="string"?r:null}async function qi(e){let t=e.paths??w,{config:r,policy:n}=await k({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?t.managedConfigFile:e.managedConfigPath});if(!n.enabled)return null;let o=_e(e.input),s=Me(o,"cwd")??process.cwd(),i=await T({cwd:s,enabled:r.sources["git-metadata"],readRemote:e.readRemote});if(I({origin:i,cwd:s,patterns:n.blockedOrigins}))return null;return{profile:await J({profileDirectory:t.profileDirectory,origin:i,targetRepo:Ui.basename(s)})}}async function un(e){let t=await qi(e);return t===null?null:{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:t.profile}}}async function It(e){let t=await un(e);if(t!==null)await Bun.stdout.write(`${JSON.stringify(t)}
100
+ `)}import{realpath as fn}from"fs/promises";import At from"path";async function pn(e){let t=e.index.listEvents(),r=await ve({events:t,corpus:e.index.getCorpusSummary(),gitMetadataEnabled:e.config.sources["git-metadata"],readRemote:e.readRemote,blockedOrigins:e.blockedOrigins}),n=re({events:r.events,signals:r.corrections,origins:r.origins});await ne({paths:e.paths,rules:n})}async function zi(e){let t,r;try{[t,r]=await Promise.all([fn(e.filePath),fn(e.directory)])}catch{return!1}let n=At.relative(r,t);return n.length>0&&!n.startsWith(`..${At.sep}`)&&n!==".."&&!At.isAbsolute(n)}async function Tt(e){let t=e.paths??w,{config:r,policy:n}=await k({configPath:e.configPath,managedConfigPath:e.managedConfigPath===void 0?t.managedConfigFile:e.managedConfigPath});if(!n.enabled||!r.sources["claude-code"])return;let o=Me(_e(e.input),"transcript_path");if(o===null||!await zi({filePath:o,directory:t.claudeProjectsDirectory}))throw Error("Session hook received an invalid transcript path");let s=await j(t.indexDatabase);try{await Zr({index:s,sourcePath:o}),await pn({index:s,config:r,paths:t,readRemote:e.readRemote,blockedOrigins:n.blockedOrigins})}finally{s.close()}}var Gi=[{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 Hi(e){return prompt(`${e} [y/N]`)?.trim().toLowerCase()==="y"}async function Fe(e={}){await Je({config:_,configPath:e.configPath});let t=e.ask??Hi,r=_,n=!1;for(let l of Gi){let u=await t(l.question);r=We({config:r,source:l.id,enabled:u}),n=n||u}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=We({config:r,source:"git-metadata",enabled:o}),a=Jt({config:i,enabled:s});await Je({config:a,configPath:e.configPath}),console.log(n||o||s?"Selected sources and capabilities enabled.":"All capture sources remain disabled.")}import{mkdir as mn}from"fs/promises";import K from"path";async function Ji(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=K.isAbsolute(r)?r:K.resolve(e,r),o=Bun.file(n),s=await o.exists()?await o.text():"",a=[".claude/agents/shadowclone.md",".claude/skills/shadowclone/"].filter((u)=>!s.includes(u));if(a.length===0)return;await mn(K.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 $e(e={}){let t=e.cwd??process.cwd(),r=e.paths??w,{config:n,policy:o}=await k({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 T({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 F({profileDirectory:r.profileDirectory,outputPath:r.compiledProfileFile,origin:s,targetRepo:K.basename(t)});await Ke({targetDirectory:t,profile:i});let a=K.join(t,".claude","skills","shadowclone");await mn(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(K.join(a,"SKILL.md"),l),await Ji(t),console.log("Installed .claude/agents/shadowclone.md for this repository.")}function pe(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 Dt(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 le({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(`
93
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(`
94
108
 
95
109
  `)].join(`
96
- `)}import{mkdir as Mo}from"fs/promises";import kt from"path";function St(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 It(e){let r=Bun.file(kt.join(e.checkpointDirectory,`${St(e.batch)}.json`));if(!await r.exists())return null;let t=await r.json();return Array.isArray(t)?t.filter(No):null}function No(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 At(e){await Mo(e.checkpointDirectory,{recursive:!0}),await Bun.write(kt.join(e.checkpointDirectory,`${St(e.batch)}.json`),`${JSON.stringify(e.rules,null,2)}
97
- `)}var 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"]}}}}}};function Tt(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Ot(e,r){return e.replaceAll("<!--","").replaceAll("-->","").replace(/\s+/g," ").trim().slice(0,r)}function $o(e){return e==="engineering"||e==="workflow"||e==="boundaries"?e:null}function er(e){if(!Tt(e)||!Array.isArray(e.rules))throw Error("The engine returned an invalid distillation result");return e.rules.flatMap((r)=>{if(!Tt(r))return[];let t=$o(r.section);if(typeof r.title!=="string"||typeof r.body!=="string"||t===null)return[];let n=Ot(r.title,120),o=Ot(r.body,600);return n&&o?[{title:n,body:o,section:t}]:[]})}var Lo=new Set(["user-prompt","plan-presented","plan-resolved","question-asked","question-answered","permission-denied","interruption"]);function Dt(e){return Lo.has(e.kind)&&e.textRef!==null}function W(e){let r=new Set(e.events.flatMap((n)=>Dt(n)&&n.textRef?[H(n.textRef)]:[])),t=new Set(e.events.flatMap((n)=>n.kind==="assistant-text"&&n.textRef?[H(n.textRef)]:[]));return e.signals.map((n)=>({...n,textRefs:n.textRefs.filter((o)=>{let i=H(o);return r.has(i)||t.has(i)})}))}function qo(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 er(e.value).map((i)=>{let s=new Bun.CryptoHasher("sha256").update(`semantic:${i.title.toLowerCase()}`).digest("hex").slice(0,16);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 zo(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 Bt(e){let r=[],t=0,n=W({signals:e.signals,events:e.events}).filter((o)=>o.textRefs.length>0);for(let o of J({signals:n})){let i=await It({checkpointDirectory:e.checkpointDirectory,batch:o});if(i!==null){r.push(...i);continue}let s=await Ye({signals:o.signals}),a=await e.runner({prompt:s,cwd:e.workingDirectory,allowedTools:[],permissionMode:"dontAsk",maxBudgetUsd:e.maxBudgetUsd,outputSchema:Qe});if(t+=1,a.isError)throw Error("The agent engine failed during distillation");let d=qo({value:zo(a),signals:o.signals});await At({checkpointDirectory:e.checkpointDirectory,batch:o,rules:d}),r.push(...d)}return{rules:r,engineRuns:t}}async function _t(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)throw Error("Shadowclone is disabled by managed policy");let o=await ge(e.databasePath??r.indexDatabase);try{let i=await wt({index:o,config:t,paths:r}),s=o.listEvents(),a=await ae({events:s,corpus:o.getCorpusSummary(),gitMetadataEnabled:t.sources["git-metadata"],readRemote:e.readRemote,blockedOrigins:n.blockedOrigins}),d=z({events:a.events,signals:a.corrections,origins:a.origins}),y=[],u=!1;if(e.deep){if(!t.distillation.deep)throw Error("Deep distillation is disabled in config");let b=W({signals:a.corrections,events:a.events}).filter((E)=>E.textRefs.length>0),m=J({signals:b});if(console.log(`Deep distillation will run up to ${m.length} agent batches.`),m.length>0){if(n.distillation!=="allowed")throw Error("Managed policy does not allow remote distillation");let E=e.runner?null:await T({purpose:"distill",allowedEngines:n.allowedEngines}),P=e.runner??E?.runner;if(!P)throw Error("No authenticated agent engine is available");let p=await Bt({signals:b,runner:P,workingDirectory:r.shadowcloneDirectory,checkpointDirectory:r.distillDirectory,events:a.events});y=p.rules,u=p.engineRuns>0}}if(await G({paths:r,rules:[...d,...y]}),console.log(Fe({report:a.report,networkCallsMade:u})),i.rescannedFiles>0)console.log(`
98
- Rescanned ${i.rescannedFiles} rewritten files.`)}finally{o.close()}}import Mt from"path";var Go=["Read","Grep","Glob","Edit","Write","Bash(git status)","Bash(git diff)","Bash(bun test)","Bash(bun run typecheck)"],Ft={push:"Bash(git push:*)","pr-draft":"Bash(gh pr create --draft:*)","pr-reply":"Bash(gh pr comment:*)"},Ho=["Bash(git add:*)","Bash(git commit:*)","Bash(git push --force:*)","Bash(git push -f:*)","Bash(gh pr merge:*)"];function rr(e){let r=e.configuredPolicy??{allow:[],maxBudgetUsd:2,requireCleanExit:!0},t=e.managedActionTier==="act"?r.allow:[],n=S.filter((a)=>t.includes(a)&&e.approvedActions.includes(a)),o=[...S.filter((a)=>!n.includes(a)),"force-push","merge"],i=[...Go,...n.map((a)=>Ft[a])],s=[...S.filter((a)=>!n.includes(a)).map((a)=>Ft[a]),...Ho];return{allowedTools:i,disallowedTools:s,permissionMode:"acceptEdits",maxBudgetUsd:r.maxBudgetUsd,requireCleanExit:r.requireCleanExit,grantedActions:n,blockedActions:o}}import{mkdir as Jo}from"fs/promises";import Wo from"path";async function tr(e){await Jo(e.runDirectory,{recursive:!0});let r=Wo.join(e.runDirectory,"receipt.json");return await Bun.write(r,`${JSON.stringify(e.receipt,null,2)}
99
- `),r}import{mkdir as Ko}from"fs/promises";import Xo from"path";async function K(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 jt(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 nr(e){let r=e.runner??K,t=await jt({runner:r,command:["git","rev-parse","--show-toplevel"],cwd:e.targetDirectory,failure:"Target directory is not a git repository"}),n=await jt({runner:r,command:["git","rev-parse","HEAD"],cwd:t,failure:"Target repository has no current commit"});if(await Ko(Xo.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 or(e){let r=e.runner??K,[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(`
100
- `).filter(Boolean).map((a)=>a.slice(3)):[],s=n.exitCode===0?n.stdout.split(`
101
- `).filter(Boolean):[];return{filesChanged:[...new Set([...s,...i])],commits:o.exitCode===0?o.stdout.split(`
102
- `).filter(Boolean):[],isClean:t.exitCode===0&&i.length===0}}async function ir(e){let r=e.runner??K,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 Zo(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,40)||"task"}function Vo(e){return e.match(/^## /gm)?.length??0}async function Nt(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 Le({cwd:r,enabled:n.sources["git-metadata"],readRemote:e.readRemote});if(k({origin:i.origin,cwd:r,patterns:o.blockedOrigins}))throw Error("Managed policy blocks this repository");let s=rr({configuredPolicy:n.repo[i.id]??null,approvedActions:e.approvedActions??[],managedActionTier:o.maxActionTier}),a=e.runner?null:await T({purpose:"dispatch",allowedEngines:o.allowedEngines}),d=e.runner??a?.runner;if(!d)throw Error("No authenticated agent engine is available");let y=e.runId??crypto.randomUUID(),u=`shadowclone/${Zo(e.task)}-${y.slice(0,8)}`,b=await nr({targetDirectory:r,worktreeDirectory:t.worktreeDirectory(y),branch:u,runner:e.commandRunner}),m=Mt.join(t.runDirectory(y),"profile.md"),E=await q({profileDirectory:t.profileDirectory,outputPath:m,origin:i.origin,targetRepo:Mt.basename(b.repoDirectory)}),P=e.startedAt??new Date().toISOString(),p=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(`
103
- `),cwd:b.worktreeDirectory,systemPromptFile:m,sessionId:y,allowedTools:s.allowedTools,disallowedTools:s.disallowedTools,permissionMode:s.permissionMode,maxBudgetUsd:s.maxBudgetUsd});if(!p.isError)await ir({worktree:b,runner:e.commandRunner});let c=await or({worktree:b,runner:e.commandRunner}),x={runId:y,task:e.task,repo:i.id,branch:u,engine:p.engine,model:null,sessionId:p.sessionId,transcriptPath:p.transcriptPath,startedAt:P,durationMs:p.durationMs,costUsd:p.costUsd,turns:p.turns,filesChanged:c.filesChanged,commits:c.commits,actionsTaken:c.commits.length>0?["commit"]:[],actionsBlockedByPolicy:s.blockedActions,permissionDenials:p.permissionDenials,profileRulesApplied:Vo(E)};if(await tr({runDirectory:t.runDirectory(y),receipt:x}),p.isError||s.requireCleanExit&&!c.isClean)throw Error("Clone run did not finish cleanly; review its receipt");return x}function Yo(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=S.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 $t(e){let r=Yo(e),t=await Nt(r);console.log(`Clone run ${t.runId} finished. Review ~/.shadowclone/runs/${t.runId}/receipt.json.`)}var Qo="Usage: shadowclone <init|learn [--deep]|doctor|install|run <task>|forget --all>";function Lt(){console.log(Qo)}function ei(){console.log(sr.version)}async function ri(e){let[r,...t]=e;if(r==="--help"||r==="-h"||r==="help"){Lt();return}if(r==="--version"||r==="-v"){ei();return}if(r==="init"){await vt();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 Sr();return}if(r==="install"&&t.length===0){await Et();return}if(r==="run"){await $t(t);return}if(r==="hook"&&t[0]==="session-end"){await Xe({input:await Bun.stdin.text()});return}if(r==="hook"&&t[0]==="session-start"){await He({input:await Bun.stdin.text()});return}if(r==="forget"&&t[0]==="--all"){await Ir();return}if(Lt(),r!==void 0)process.exitCode=1}await ri(Bun.argv.slice(2));
110
+ `)}import{mkdir as Wi}from"fs/promises";import gn from"path";function yn(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 hn(e){let t=Bun.file(gn.join(e.checkpointDirectory,`${yn(e.batch)}.json`));if(!await t.exists())return null;let r=await t.json();return Array.isArray(r)?r.filter(Ki):null}function Ki(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 wn(e){await Wi(e.checkpointDirectory,{recursive:!0}),await Bun.write(gn.join(e.checkpointDirectory,`${yn(e.batch)}.json`),`${JSON.stringify(e.rules,null,2)}
111
+ `)}var Bt={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"]}}}}}},Ne={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 bn(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function xn(e,t){return e.replaceAll("<!--","").replaceAll("-->","").replace(/\s+/g," ").trim().slice(0,t)}function Xi(e){return e==="engineering"||e==="workflow"||e==="boundaries"?e:null}function X(e){if(!bn(e)||!Array.isArray(e.rules))throw Error("The engine returned an invalid distillation result");return e.rules.flatMap((t)=>{if(!bn(t))return[];let r=Xi(t.section);if(typeof t.title!=="string"||typeof t.body!=="string"||r===null)return[];let n=xn(t.title,120),o=xn(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 Zi}from"fs/promises";import Pn from"path";function Vi(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 vn(e){if(e.rules.length<=1)return e.rules;let t=e.checkpointDirectory?Pn.join(e.checkpointDirectory,`merge-${Vi(e.rules)}.json`):null;if(t&&await Bun.file(t).exists())try{let i=await Bun.file(t).json();return X(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}
112
+ Body: ${i.body}
113
+ Section: ${i.section}
114
+ `)].join(`
115
+ `),n={...Ne,properties:{rules:{...Ne.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=X(s);if(t)await Zi(Pn.dirname(t),{recursive:!0}),await Bun.write(t,`${JSON.stringify({rules:i},null,2)}
116
+ `);return i}catch{return e.rules}}var Yi=new Set(["user-prompt","plan-presented","plan-resolved","question-asked","question-answered","permission-denied","interruption"]);function Rn(e){return Yi.has(e.kind)&&e.textRef!==null}function fe(e){let t=new Set(e.events.flatMap((n)=>Rn(n)&&n.textRef?[se(n.textRef)]:[])),r=new Set(e.events.flatMap((n)=>n.kind==="assistant-text"&&n.textRef?[se(n.textRef)]:[]));return e.signals.map((n)=>({...n,textRefs:n.textRefs.filter((o)=>{let s=se(o);return t.has(s)||r.has(s)})}))}function kn(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 X(e.value).map((i)=>{let a=M(i.title),l=(i.sources??[]).flatMap((y)=>e.originRules?.[y]?[e.originRules[y]]:[]),u=l.length>0?l.reduce((y,x)=>y+x.observations,0):r,p=l.length>0?Math.max(...l.map((y)=>y.sessions)):n,f=l.length>0?l.map((y)=>y.lastSeen).sort().at(-1)??s:s,m=l.length>0?[...new Set(l.flatMap((y)=>y.origins))].sort():[t.origin.id];return{title:i.title,body:i.body,section:i.section,key:a,scope:"org",originDirectory:t.origin.directoryName,observations:u,confidence:Number(Math.min(1,p/3).toFixed(2)),lastSeen:f,sessions:p,origins:m}})}function Qi(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 En(e){let t=[],r=0,n=fe({signals:e.signals,events:e.events}).filter((i)=>i.textRefs.length>0);for(let i of pe({signals:n})){let a=await hn({checkpointDirectory:e.checkpointDirectory,batch:i});if(a!==null){t.push(...a);continue}let l=await Dt({signals:i.signals}),u=await e.runner({prompt:l,cwd:e.workingDirectory,allowedTools:[],permissionMode:"dontAsk",maxBudgetUsd:e.maxBudgetUsd,outputSchema:Bt});if(r+=1,u.isError)throw Error("The agent engine failed during distillation");let p=kn({value:Qi(u),signals:i.signals});await wn({checkpointDirectory:e.checkpointDirectory,batch:i,rules:p}),t.push(...p)}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,u=await vn({rules:a.map((f)=>({title:f.title,body:f.body,section:f.section})),runner:async(f)=>(l=!0,e.runner(f)),cwd:e.workingDirectory,maxBudgetUsd:e.maxBudgetUsd,checkpointDirectory:e.checkpointDirectory});if(l)r+=1;let p=n.filter((f)=>f.origin.directoryName===i);s.push(...kn({value:{rules:u},signals:p,originRules:a}))}return{rules:s,engineRuns:r}}async function es(e){return await Bun.spawn({cmd:["git","-C",e,"rev-parse","--is-inside-work-tree"],stdout:"ignore",stderr:"ignore"}).exited===0}async function Sn(e={}){let t=e.paths??w,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 Fe({configPath:e.configPath})}let{config:o,policy:s}=await k({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 j(i);try{let l=await Xr({index:a,config:o,paths:t}),u=a.listEvents(),p=await ve({events:u,corpus:a.getCorpusSummary(),gitMetadataEnabled:o.sources["git-metadata"],readRemote:e.readRemote,blockedOrigins:s.blockedOrigins}),f=it(u);for(let d of f)console.warn(`Warning: ${d}`);if(e.dryRun){console.log(we({report:p.report,networkCallsMade:!1}));return}let m=re({events:p.events,signals:p.corrections,origins:p.origins}),y=[],x=!1;if(e.deep){if(!o.distillation.deep)throw Error("Deep distillation is disabled in config");let d=fe({signals:p.corrections,events:p.events}).filter((C)=>C.textRefs.length>0),h=pe({signals:d});if(console.log(`Deep distillation will run up to ${h.length} agent batches.`),h.length>0){if(s.distillation!=="allowed")throw Error("Managed policy does not allow remote distillation");let C=e.runner?null:await D({purpose:"distill",allowedEngines:s.allowedEngines}),V=e.runner??C?.runner;if(!V)throw Error("No authenticated agent engine is available");let Y=await En({signals:d,runner:V,workingDirectory:t.shadowcloneDirectory,checkpointDirectory:t.distillDirectory,events:p.events});y=Y.rules,x=Y.engineRuns>0}}let S=[...m,...y].sort((d,h)=>h.observations-d.observations||d.title.localeCompare(h.title));if(await ne({paths:t,rules:S,generator:e.deep?"all":"structural"}),console.log(we({report:p.report,networkCallsMade:x})),l.rescannedFiles>0)console.log(`
117
+ Rescanned ${l.rescannedFiles} rewritten files.`);let g=e.targetDirectory??process.cwd();if(await es(g))try{await $e({cwd:g,paths:t,readRemote:e.readRemote,configPath:e.configPath,managedConfigPath:e.managedConfigPath})}catch(d){let h=d instanceof Error?d.message:String(d);console.warn(`Warning: failed to install clone hook: ${h}`)}}finally{a.close()}}import Tn from"path";var ts=["Read","Grep","Glob","Edit","Write","Bash(git status:*)","Bash(git diff:*)"];function Cn(e){if(e==="pr-draft")return"Bash(gh pr create --draft:*)";if(e==="pr-reply")return"Bash(gh pr comment:*)";return null}var rs=["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 Ot(e){let t=e.configuredPolicy??{allow:[],maxBudgetUsd:2,requireCleanExit:!0},r=e.managedActionTier==="act"?t.allow:[],n=B.filter((u)=>r.includes(u)&&e.approvedActions.includes(u)),o=[...B.filter((u)=>!n.includes(u)),"force-push","merge"],s=e.verificationTools??["Bash(bun test:*)","Bash(bun run typecheck:*)"],a=[...[...ts,...s],...n.flatMap((u)=>{let p=Cn(u);return p?[p]:[]})],l=[...B.filter((u)=>!n.includes(u)).flatMap((u)=>{let p=Cn(u);return p?[p]:[]}),...rs];return{allowedTools:a,disallowedTools:l,permissionMode:"dontAsk",maxBudgetUsd:t.maxBudgetUsd,requireCleanExit:t.requireCleanExit,grantedActions:n,blockedActions:o}}import{mkdir as ns}from"fs/promises";import os from"path";async function jt(e){await ns(e.runDirectory,{recursive:!0});let t=os.join(e.runDirectory,"receipt.json");return await Bun.write(t,`${JSON.stringify(e.receipt,null,2)}
118
+ `),t}import z from"path";async function In(e){if(e.overrides&&e.overrides.length>0)return e.overrides.map((u)=>`Bash(${u}:*)`);if(!e.cwd)return["Bash(bun test:*)","Bash(bun run typecheck:*)","Bash(npm test:*)"];let t=[],r=Bun.file(z.join(e.cwd,"bun.lock")),n=Bun.file(z.join(e.cwd,"bun.lockb")),o=Bun.file(z.join(e.cwd,"package.json")),s=Bun.file(z.join(e.cwd,"Cargo.toml")),i=Bun.file(z.join(e.cwd,"go.mod")),a=Bun.file(z.join(e.cwd,"pyproject.toml")),l=Bun.file(z.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 is}from"fs/promises";import ss from"path";async function Z(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 An(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??Z,r=await An({runner:t,command:["git","rev-parse","--show-toplevel"],cwd:e.targetDirectory,failure:"Target directory is not a git repository"}),n=await An({runner:t,command:["git","rev-parse","HEAD"],cwd:r,failure:"Target repository has no current commit"});if(await is(ss.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 Mt(e){let t=e.runner??Z,[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 Ft(e){let t=e.runner??Z,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 $t(e){if((await(e.runner??Z)({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 as(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,40)||"task"}function ls(e){return e.match(/^## /gm)?.length??0}async function Dn(e){let t=e.targetDirectory??process.cwd(),r=e.paths??w,{config:n,policy:o}=await k({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 nt({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 In({cwd:t}),a=Ot({configuredPolicy:n.repo[s.id]??null,approvedActions:e.approvedActions??[],managedActionTier:o.maxActionTier,verificationTools:i}),l=e.runner?null:await D({purpose:"dispatch",allowedEngines:o.allowedEngines}),u=e.runner??l?.runner;if(!u)throw Error("No authenticated agent engine is available");let p=e.runId??crypto.randomUUID(),f=`shadowclone/${as(e.task)}-${p.slice(0,8)}`,m=await _t({targetDirectory:t,worktreeDirectory:r.worktreeDirectory(p),branch:f,runner:e.commandRunner}),y=Tn.join(r.runDirectory(p),"profile.md"),x=await F({profileDirectory:r.profileDirectory,outputPath:y,origin:s.origin,targetRepo:Tn.basename(m.repoDirectory)}),S=e.startedAt??new Date().toISOString(),g=await u({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:y,sessionId:p,allowedTools:a.allowedTools,disallowedTools:a.disallowedTools,permissionMode:a.permissionMode,maxBudgetUsd:a.maxBudgetUsd});if(!g.isError)await Ft({worktree:m,runner:e.commandRunner});let d=await Mt({worktree:m,runner:e.commandRunner}),h=d.commits.length>0?["commit"]:[];if(!g.isError&&a.grantedActions.includes("push")&&d.commits.length>0)await $t({worktree:m,runner:e.commandRunner}),h.push("push");let C={runId:p,task:e.task,repo:s.id,branch:f,engine:g.engine,model:null,sessionId:g.sessionId,transcriptPath:g.transcriptPath,startedAt:S,durationMs:g.durationMs,costUsd:g.costUsd,turns:g.turns,filesChanged:d.filesChanged,commits:d.commits,actionsTaken:h,actionsBlockedByPolicy:a.blockedActions,permissionDenials:g.permissionDenials,profileRulesApplied:ls(x)};if(await jt({runDirectory:r.runDirectory(p),receipt:C}),g.isError||a.requireCleanExit&&!d.isClean)throw Error("Clone run did not finish cleanly; review its receipt");return C}function cs(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=B.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 Bn(e){let t=cs(e),r=await Dn(t);console.log(`Clone run ${r.runId} finished. Review ~/.shadowclone/runs/${r.runId}/receipt.json.`)}var ds="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 On(){console.log(ds)}function us(){console.log(ge.version)}async function ps(e){let[t,...r]=e;if(t==="--help"||t==="-h"||t==="help"){On();return}if(t==="--version"||t==="-v"){us();return}if(t==="init"){await Fe();return}if(t==="learn"){let n=r.includes("--deep"),o=r.includes("--dry-run");if(r.every((i)=>i==="--deep"||i==="--dry-run")){await Sn({deep:n,dryRun:o});return}}if(t==="doctor"&&r.length===0){await Vr();return}if(t==="install"&&r.length===0){await $e();return}if(t==="run"){await Bn(r);return}if(t==="eval"){await cn(r);return}if(t==="mcp"){await lt();return}if(t==="hook"&&r[0]==="session-end"){await Tt({input:await Bun.stdin.text()});return}if(t==="hook"&&r[0]==="session-start"){await It({input:await Bun.stdin.text()});return}if(t==="forget"&&r[0]==="--all"){await dn();return}if(On(),t!==void 0)process.exitCode=1}await ps(Bun.argv.slice(2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shadowclone/cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
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
  ],