portable-agent-layer 0.39.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A cross-platform, cross-agent layer for portable AI workflows, memory, and accumulated knowledge.
4
4
 
5
- PAL lets you carry your agent context across **Windows**, **macOS**, and **Linux**, and work across different agent runtimes and interfaces such as **Claude Code**, **opencode**, **Cursor**, and **Codex**. Its core idea is simple: your knowledge and workflows should belong to **you**, not to a single machine, tool, or vendor.
5
+ PAL lets you carry your agent context across **Windows**, **macOS**, and **Linux**, and work across different agent runtimes and interfaces such as **Claude Code**, **opencode**, **Cursor**, **GitHub Copilot**, and **Codex**. Its core idea is simple: your knowledge and workflows should belong to **you**, not to a single machine, tool, or vendor.
6
6
 
7
7
  > Inspired in part by [Daniel Miessler](https://danielmiessler.com)'s work on [Personal AI Infrastructure](https://github.com/danielmiessler/Personal_AI_Infrastructure). PAL is an independent open-source implementation focused on portability across platforms and agents. It is not affiliated with or endorsed by Daniel Miessler.
8
8
 
@@ -33,7 +33,7 @@ With PAL, you can:
33
33
  > **Bun is required.** PAL is built on [Bun](https://bun.sh) and will not work with Node.js or other runtimes. Install it with `curl -fsSL https://bun.sh/install | bash`.
34
34
 
35
35
  - [Bun](https://bun.sh) >= 1.3.0
36
- - At least one of: [Claude Code](https://claude.ai/code), [opencode](https://opencode.ai), [Cursor](https://cursor.com), or [Codex](https://openai.com/index/introducing-codex/)
36
+ - At least one of: [Claude Code](https://claude.ai/code), [opencode](https://opencode.ai), [Cursor](https://cursor.com), [GitHub Copilot CLI](https://docs.github.com/en/copilot/github-copilot-in-the-cli), or [Codex](https://openai.com/index/introducing-codex/)
37
37
 
38
38
  ### Package mode (recommended)
39
39
 
@@ -98,31 +98,36 @@ pal cli install # all available (default)
98
98
 
99
99
  ### Supported agents
100
100
 
101
- | Agent | Support | Skills | Hooks | AGENTS.md | Subagents |
102
- |-------|---------|--------|-------|-----------|-----------|
103
- | Claude Code | Full | Yes | Yes | Yes | Yes |
104
- | opencode | Full | Yes | Yes (plugin) | Yes | Yes |
105
- | Cursor | Full | Yes | Yes | Yes (injected via hook) | Yes |
106
- | GitHub Copilot | Full | Yes | Yes | Yes (via `~/.copilot/instructions/*.instructions.md`) | Yes |
107
- | Codex | Partial | Yes | No | Yes | No |
101
+ | Agent | Support | Skills | Hooks | AGENTS.md | Subagents | Inference routing |
102
+ |-------|---------|--------|-------|-----------|-----------|-------------------|
103
+ | Claude Code | Full | Yes | Yes | Yes | Yes | `claude --print` |
104
+ | opencode | Full | Yes | Yes (plugin) | Yes | Yes | `opencode run` |
105
+ | Cursor | Full | Yes | Yes | Yes (injected via hook) | Yes | `cursor-agent` |
106
+ | GitHub Copilot | Full | Yes | Yes | Yes (via `~/.copilot/instructions/*.instructions.md`) | Yes | `copilot` |
107
+ | Codex | Full | Yes | Yes | Yes | No | `codex exec` |
108
+
109
+ PAL's background inference (session naming, summaries, failure capture, etc.) runs through whichever subscription CLI is active — no API key required by default.
108
110
 
109
111
  ---
110
112
 
111
113
  ## Environment variables
112
114
 
113
- ### Required
115
+ ### API keys (all optional)
116
+
117
+ PAL routes inference through the host agent's subscription CLI by default. API keys are only needed as fallbacks when no CLI binary is available, or for skills that call non-Anthropic providers.
114
118
 
115
119
  | Variable | Description |
116
120
  |----------|-------------|
117
- | `PAL_ANTHROPIC_API_KEY` | Required for PAL's hook inference (sentiment analysis, session naming). Uses Haiku for low-cost background calls. |
121
+ | `PAL_ANTHROPIC_API_KEY` | Fallback for hook inference when no native CLI is available. Uses Haiku. |
122
+ | `PAL_OPENAI_API_KEY` | Fallback for hook inference when Codex is active without the `codex` binary, or when no Anthropic key is set. |
123
+ | `PAL_GEMINI_API_KEY` | For YouTube video analysis and web search skill |
124
+ | `PAL_XAI_API_KEY` | For Grok real-time research skill (X/web search) |
125
+ | `PAL_PERPLEXITY_API_KEY` | For Perplexity deep research skill |
118
126
 
119
- ### Optional
127
+ ### Path overrides
120
128
 
121
129
  | Variable | Description |
122
130
  |----------|-------------|
123
- | `PAL_GEMINI_API_KEY` | For YouTube video analysis and web search skill |
124
- | `PAL_XAI_API_KEY` | For Grok real-time research skill (X/web search) |
125
- | `PAL_PERPLEXITY_API_KEY` | For Perplexity deep research skill |
126
131
  | `PAL_HOME` | Override user state directory (default: `~/.pal` or repo root) |
127
132
  | `PAL_PKG` | Override package root |
128
133
  | `PAL_CLAUDE_DIR` | Override Claude config dir (default: `~/.claude`) |
@@ -132,6 +137,14 @@ pal cli install # all available (default)
132
137
  | `PAL_CODEX_DIR` | Override Codex config dir (default: `~/.codex`) |
133
138
  | `PAL_AGENTS_DIR` | Override agents dir (default: `~/.agents`) |
134
139
 
140
+ ### Debug / test
141
+
142
+ | Variable | Description |
143
+ |----------|-------------|
144
+ | `PAL_DEBUG` | Set to `1` to emit verbose hook logs to `memory/state/debug.log` |
145
+ | `PAL_INFERENCE_DISABLED` | Set to `1` to disable all inference (used by the test suite to prevent real CLI spawns) |
146
+ | `PAL_NOTIFICATIONS_DISABLED` | Set to `1` to suppress desktop notifications (used by the test suite) |
147
+
135
148
  ---
136
149
 
137
150
  ## Skills
@@ -142,16 +155,23 @@ PAL ships with built-in skills that extend your agent's capabilities:
142
155
  |-------|-------------|
143
156
  | `analyze-pdf` | Download and analyze PDF files |
144
157
  | `analyze-youtube` | Analyze YouTube videos using Gemini |
158
+ | `consulting-report` | Generate consulting-style reports as PDFs |
145
159
  | `council` | Multi-perspective parallel debate on decisions |
160
+ | `create-pdf` | Render structured content into a PDF |
146
161
  | `create-skill` | Scaffold a new skill from a description |
147
162
  | `extract-entities` | Extract people and companies from content |
148
163
  | `extract-wisdom` | Extract structured insights from content |
149
164
  | `first-principles` | Break down problems to fundamentals |
150
165
  | `fyzz-chat-api` | Query Fyzz Chat conversations via API |
166
+ | `opinion` | Confirm or contradict tracked opinions (confidence-weighted) |
167
+ | `presentation` | Build branded slide decks from outlines |
168
+ | `projects` | Look up, resume, register, or manage tracked projects |
151
169
  | `reflect` | Diagnose why a PAL behavior didn't trigger |
152
170
  | `research` | Multi-agent parallel research |
153
171
  | `review` | Security-focused code review |
154
172
  | `summarize` | Structured summarization |
173
+ | `telos` | Inspect or update goals, beliefs, strategies, narratives |
174
+ | `think` | Structured first-pass reasoning on a problem |
155
175
 
156
176
  ---
157
177
 
@@ -178,7 +198,8 @@ Your setup should be able to travel with you.
178
198
  ## Features
179
199
 
180
200
  - **Cross-platform**: works on Windows, macOS, and Linux
181
- - **Cross-agent**: full support for Claude Code, opencode, and Cursor; partial support for Codex
201
+ - **Cross-agent**: full support for Claude Code, opencode, Cursor, GitHub Copilot, and Codex (Codex still lacks subagents)
202
+ - **Subscription-first inference**: background inference routes through whichever subscription CLI is active — no API key needed by default
182
203
  - **Portable knowledge**: export and import accumulated knowledge
183
204
  - **TypeScript-first**: built in TypeScript from day one
184
205
  - **Open source**: hackable, inspectable, extensible
@@ -1,26 +1,72 @@
1
1
  # Memory System
2
2
 
3
- PAL has its own memory system that persists across sessions AND across tools (Claude Code, opencode). Always prefer PAL memory over any tool-native memory system.
3
+ PAL has its own memory system that persists across sessions AND across tools (Claude Code, opencode, Cursor, Copilot, Codex). Always prefer PAL memory over any tool-native memory system.
4
+
5
+ ## Layout
6
+
7
+ All memory lives under `~/.pal/memory/`:
8
+
9
+ ```
10
+ memory/
11
+ ├── state/ # Runtime state (managed by hooks)
12
+ │ ├── sessions.json # Session registry
13
+ │ ├── counts.json # Cached counts for greeting
14
+ │ ├── last-responses.json # Cached responses for rating correlation
15
+ │ ├── pending-failure.json # Deferred failure capture
16
+ │ ├── captured-learnings.json # Session-intelligence dedup map
17
+ │ ├── session-names.json # Generated session titles
18
+ │ ├── debug.log[.1-.5] # Rotated hook execution logs
19
+ │ └── token-usage.jsonl # Per-call inference token usage
20
+
21
+ ├── signals/
22
+ │ └── ratings.jsonl # Append-only rating signals (explicit + implicit)
23
+
24
+ ├── relationship/
25
+ │ ├── YYYY-MM/YYYY-MM-DD.md # Daily interaction notes (W / O / B)
26
+ │ ├── opinions.json # Confidence-tracked opinions
27
+ │ └── reflections/ # Periodic reflection reports
28
+
29
+ ├── self-model/
30
+ │ └── current.md # Synthesized self-model (auto-imported into CLAUDE.md)
31
+
32
+ ├── learning/
33
+ │ ├── session/YYYY-MM/*.md # Per-session learnings with frontmatter
34
+ │ ├── failures/YYYY-MM/*.md # Low-rating context captures
35
+ │ ├── synthesis/YYYY-MM/*.md # Weekly/monthly synthesis reports
36
+ │ └── .retrieval-index.json # Embedding index for retrieval
37
+
38
+ ├── wisdom/
39
+ │ ├── frames/<domain>.md # Crystallized principles per domain
40
+ │ └── state/ # Wisdom graduation bookkeeping
41
+
42
+ └── projects/
43
+ └── <slug>/ # Per-project history, threads, progress
44
+ ```
4
45
 
5
46
  ## Where to write
6
47
 
7
- - **Wisdom frames**: `~/.pal/memory/wisdom/frames/` — crystallized principles per domain (loaded every session)
8
- - **Relationship notes**: `~/.pal/memory/relationship/YYYY-MM/YYYY-MM-DD.md` — daily interaction observations (loaded every session)
9
- - **Session learnings**: `~/.pal/memory/learning/session/YYYY-MM/*.md` reusable insights from sessions (loaded every session)
10
- - **Failure captures**: `~/.pal/memory/learning/failures/YYYY-MM/{timestamp}_{slug}/capture.md` — what went wrong and why
11
- - **Signals**: `~/.pal/memory/signals/ratings.jsonl` append-only rating signal log (do not edit directly)
48
+ Almost everything in `state/`, `signals/`, `relationship/opinions.json`, `learning/`, `wisdom/`, and `self-model/` is hook-managed **never edit these directly**. Use the relevant skill or tool instead.
49
+
50
+ | You want to capture | Go through | Lands at |
51
+ |---------------------|------------|----------|
52
+ | A new validated principle | `skill: opinion` (confirm) or wisdom frame edit | `wisdom/frames/<domain>.md` |
53
+ | A daily observation about the user | Relationship note in algorithm LEARN phase | `relationship/YYYY-MM/YYYY-MM-DD.md` |
54
+ | A reusable session insight | Session-intelligence handler (automatic) | `learning/session/YYYY-MM/*.md` |
55
+ | A failure worth learning from | Failure-principle handler (automatic, low ratings) | `learning/failures/YYYY-MM/*.md` |
56
+ | A rating signal | UserPromptOrchestrator rating capture | `signals/ratings.jsonl` |
57
+ | A project handoff | Project skill / detached handlers | `projects/<slug>/` |
12
58
 
13
- ## Format
59
+ ## Format conventions
14
60
 
15
- - **Wisdom frames**: One `.md` file per domain/topic. Each file contains bullet-point principles the user has validated or you've learned. Append new principles to existing files or create new domain files.
16
- - **Relationship notes**: Daily `.md` file with bullet-point observations about the interaction (tone, preferences, corrections).
17
- - **Session learnings**: One `.md` file per session with a `**Title:**` line summarizing what was learned.
18
- - **Failure captures**: One directory per failure, named `{YYYYMMDD-HHmmss}_{slug}/`, containing a `capture.md` with what went wrong and why.
61
+ - **Wisdom frames**: One `.md` file per domain. Bullet-point principles, each tagged with a confidence value (e.g. `(85%)`). Append to existing files when possible; create a new domain only when none fits.
62
+ - **Relationship notes**: Daily `.md` file. Each bullet is typed: `W` (world fact), `O(c=0.85)` (opinion), or `B(c=0.75)` (behavior pattern), with a confidence in `c=...`.
63
+ - **Session learnings**: Frontmatter (`title`, `category`, `date`, `cwd`, optional `session`) + a body split into `## What Was Done` and `## Insights`.
64
+ - **Failure captures**: One `.md` per failure, named `{YYYYMMDD-HHmmss}_{slug}.md`, describing what went wrong, why, and what to do differently.
65
+ - **Synthesis reports**: One `.md` per period (`YYYY-MM-DD_weekly.md` etc.) aggregating recurring patterns from session learnings + failures.
19
66
 
20
- ## When to write
67
+ ## When NOT to write
21
68
 
22
- - When the user corrects you or gives feedback wisdom frame
23
- - When you learn something about how the user prefers to work relationship note
24
- - When a session produces reusable insightssession learning
25
- - When something fails significantly (rating < 6) failure capture
26
- - Do NOT write memories about trivial exchanges or things already captured in TELOS.
69
+ - Trivial exchanges (greetings, brief acknowledgments)skip
70
+ - Anything already captured in TELOSskip
71
+ - Anything that duplicates an existing wisdom frame or opinion use the opinion skill to reinforce instead
72
+ - Anything the user has not validated yet record it as a relationship note first, let it graduate naturally
@@ -227,12 +227,20 @@ Brief description.
227
227
  └─────────────────────┘
228
228
 
229
229
  ┌─────────────────────┐
230
- │ Stop │──► StopOrchestrator.ts
230
+ │ Stop │──► StopOrchestrator.ts → runStopHandlers()
231
+ │ │ Detached (inference-bearing, fire-and-forget):
232
+ │ │ - Session intelligence (title, summary, insights, handoff)
233
+ │ │ - Failure principle extraction (low ratings)
234
+ │ │ - Auto-graduate wisdom (24h TTL, idempotent)
235
+ │ │ Concurrent (Promise.allSettled):
231
236
  │ │ - Work session capture
232
- │ │ - Relationship extraction (Haiku inference)
233
- │ │ - Work learning capture
234
- │ │ - Failure logging
237
+ │ │ - Project touch / history
238
+ │ │ - Persist last exchange (handoff seed)
239
+ │ │ - Cache last response (rating correlation)
235
240
  │ │ - Reflect trigger check
241
+ │ │ - Self-model trigger check
242
+ │ │ - Synthesis pipeline
243
+ │ │ - Desktop notify
236
244
  │ │ - Write context digests (semi-static sources)
237
245
  │ │ - Auto-backup
238
246
  │ │ - Count updates
@@ -243,9 +251,11 @@ Brief description.
243
251
  ### Design Principles
244
252
 
245
253
  - **Fail-open**: Hook errors never block the user's session
246
- - **Parallel execution**: Stop handlers run via `Promise.allSettled`one failure doesn't block others
247
- - **Idempotent**: Handlers check for existing state before writing (e.g., session dedup)
248
- - **Timeout-aware**: Inference calls have hard timeouts (8s default)
254
+ - **Detached inference**: Long inference calls (session intelligence, failure principle, auto-graduate) spawn detached child processes that survive the hook returning. The parent hook exits in milliseconds cold-start latency for the subscription CLI no longer blocks the next prompt.
255
+ - **Parallel execution**: Non-inference handlers run via `Promise.allSettled` one failure doesn't block others
256
+ - **Idempotent**: Handlers check for existing state before writing (auto-graduate uses 24h TTL + content dedup; session intelligence dedups by message count)
257
+ - **Timeout-aware**: Inference calls have hard timeouts (60s default; longer because they run detached and don't block the user)
258
+ - **Race-safe**: Detached claim files use atomic `rename()` with ENOENT treated as a benign "already claimed" signal (opencode fires `session.idle` + `session.diff` concurrently)
249
259
  - **Subagent-aware**: `LoadContext.ts` skips heavy context loading for subagent sessions
250
260
 
251
261
  ### Configuration
@@ -404,6 +414,66 @@ Everything else loads via the routing table in CLAUDE.md. The AI reads files onl
404
414
 
405
415
  ---
406
416
 
417
+ ## Inference Routing Architecture
418
+
419
+ ### Subscription-First Model
420
+
421
+ PAL's background inference (session naming, summaries, failure capture, wisdom graduation, etc.) routes through whichever subscription CLI is currently hosting the session. No API key is required by default — the user already pays for the subscription that comes with their agent.
422
+
423
+ ### Routing Table
424
+
425
+ The active agent is detected via `getActiveAgent()` in `src/hooks/lib/agent.ts` (driven by the `PAL_AGENT` env var set per-target). The dispatcher in `src/hooks/lib/inference.ts` then routes to the matching CLI:
426
+
427
+ | Active agent | CLI invoked | Notes |
428
+ |--------------|-------------|-------|
429
+ | `claude` | `claude --print` | Inherits the user's Claude Code subscription |
430
+ | `opencode` | `opencode run` | Output parsed via `extractOpencodeText()` |
431
+ | `cursor` | `cursor-agent` | argv-only, no stdin |
432
+ | `copilot` | `copilot` | GitHub Copilot CLI |
433
+ | `codex` | `codex exec` | Falls back to `PAL_OPENAI_API_KEY` if the `codex` binary is missing |
434
+
435
+ If no CLI binary is available, the dispatcher falls back to `PAL_ANTHROPIC_API_KEY` (Haiku via the Anthropic API) or `PAL_OPENAI_API_KEY` (OpenAI API). `canInfer()` returns `false` only when both routes are unavailable — handlers then skip silently.
436
+
437
+ ### Recursion Defense (Three Layers)
438
+
439
+ Spawning a CLI from inside a hook risks the child re-triggering the same hooks, leading to an infinite spawn loop. Three defenses, all active at once:
440
+
441
+ 1. **CLI flags** — Mirrors PAI's pattern: `--setting-sources ''` and `--tools ''` strip the child of its hook config and tool access entirely (claude, opencode equivalents).
442
+ 2. **Sentinel env var** — `PAL_SPAWNED_INFERENCE=1` is set on every spawn. Hook entry points call `exitIfSpawnedInference()` and bail before doing any work.
443
+ 3. **Depth counter** — `PAL_SPAWN_DEPTH` increments per hop; the circuit breaks at `MAX_DEPTH=1`. Belt-and-suspenders for the above.
444
+
445
+ The `CLAUDECODE` env var is unset *scoped to the child process only* (not deleted from the parent's environment) so the spawned `claude` CLI doesn't think it's nested inside another Claude session.
446
+
447
+ ### Detached Inference Pattern
448
+
449
+ Long inference calls (session intelligence, failure principle extraction, auto-graduate) run via `spawnDetachedInference()`. The parent hook writes the transcript to a tmp file, spawns a detached child with `--run <args>`, and returns immediately. The child reads the tmp file, runs inference, writes results to disk, and unlinks the tmp file.
450
+
451
+ ```
452
+ StopOrchestrator
453
+
454
+ ├─► detachSessionIntelligence(transcript, sessionId)
455
+ │ └─► [child] inference → session-learning/YYYY-MM/...
456
+
457
+ ├─► detachFailurePrinciple(transcript)
458
+ │ ├─► Atomic claim: rename pending-failure.json → tmp/pending.json
459
+ │ │ (ENOENT means another concurrent Stop hook claimed it — benign)
460
+ │ └─► [child] inference → failures/YYYY-MM/...
461
+
462
+ └─► detachAutoGraduate()
463
+ └─► [child] 24h TTL + content dedup → wisdom/frames/...
464
+ ```
465
+
466
+ The orchestrator returns in milliseconds; subscription-CLI cold-start latency no longer blocks the user's next prompt.
467
+
468
+ ### Resilience
469
+
470
+ - **Empty-abort retry** — If a CLI returns an empty stdout (burst-concurrency race), retry once with 500–1500ms jitter
471
+ - **Test kill-switch** — `PAL_INFERENCE_DISABLED=1` (preloaded by `test/setup.ts`) short-circuits all inference so tests never spawn real CLIs
472
+ - **Per-call attribution** — Every inference call logs `caller=X sessionId=Y` so debug.log makes routing trivially auditable
473
+ - **Doctor probes** — `pal cli doctor` actually invokes each route and reports which agents are correctly wired
474
+
475
+ ---
476
+
407
477
  ## Security Architecture
408
478
 
409
479
  ### Fail-Open Design
@@ -450,10 +520,13 @@ src/targets/
450
520
  ├── copilot/ # GitHub Copilot specific
451
521
  │ ├── install.ts # Write instruction files + update VS Code settings
452
522
  │ └── uninstall.ts
523
+ ├── codex/ # Codex specific
524
+ │ ├── install.ts # Merge hooks into ~/.codex/hooks.json + skills + AGENTS.md
525
+ │ └── uninstall.ts
453
526
  └── lib.ts # Shared: JSON read/write, settings merge, TELOS scaffold
454
527
  ```
455
528
 
456
- Codex support is partial AGENTS.md is symlinked to `~/.codex/AGENTS.md` automatically (no dedicated target installer needed).
529
+ All five targets install hooks, skills, and AGENTS.md. Codex does not yet support subagents.
457
530
 
458
531
  ### Path Resolution
459
532
 
@@ -10,23 +10,23 @@
10
10
  "userPromptSubmitted": [
11
11
  {
12
12
  "type": "command",
13
- "bash": "bun run {{PKG_ROOT}}/src/hooks/UserPromptOrchestrator.ts"
13
+ "bash": "PAL_AGENT=copilot bun run {{PKG_ROOT}}/src/hooks/UserPromptOrchestrator.ts"
14
14
  }
15
15
  ],
16
16
  "preToolUse": [
17
17
  {
18
18
  "type": "command",
19
- "bash": "bun run {{PKG_ROOT}}/src/hooks/SecurityValidator.ts"
19
+ "bash": "PAL_AGENT=copilot bun run {{PKG_ROOT}}/src/hooks/SecurityValidator.ts"
20
20
  },
21
21
  {
22
22
  "type": "command",
23
- "bash": "bun run {{PKG_ROOT}}/src/hooks/SkillGuard.ts"
23
+ "bash": "PAL_AGENT=copilot bun run {{PKG_ROOT}}/src/hooks/SkillGuard.ts"
24
24
  }
25
25
  ],
26
26
  "agentStop": [
27
27
  {
28
28
  "type": "command",
29
- "bash": "bun run {{PKG_ROOT}}/src/hooks/StopOrchestrator.ts"
29
+ "bash": "PAL_AGENT=copilot bun run {{PKG_ROOT}}/src/hooks/StopOrchestrator.ts"
30
30
  }
31
31
  ]
32
32
  }
@@ -30,7 +30,7 @@
30
30
  "hooks": [
31
31
  {
32
32
  "type": "command",
33
- "command": "bun run {{PKG_ROOT}}/src/hooks/LoadContext.ts"
33
+ "command": "PAL_AGENT=claude bun run {{PKG_ROOT}}/src/hooks/LoadContext.ts"
34
34
  }
35
35
  ]
36
36
  },
@@ -39,7 +39,7 @@
39
39
  "hooks": [
40
40
  {
41
41
  "type": "command",
42
- "command": "bun run {{PKG_ROOT}}/src/hooks/CompactRecover.ts"
42
+ "command": "PAL_AGENT=claude bun run {{PKG_ROOT}}/src/hooks/CompactRecover.ts"
43
43
  }
44
44
  ]
45
45
  }
@@ -50,7 +50,7 @@
50
50
  "hooks": [
51
51
  {
52
52
  "type": "command",
53
- "command": "bun run {{PKG_ROOT}}/src/hooks/PreCompactPersist.ts"
53
+ "command": "PAL_AGENT=claude bun run {{PKG_ROOT}}/src/hooks/PreCompactPersist.ts"
54
54
  }
55
55
  ]
56
56
  }
@@ -61,7 +61,7 @@
61
61
  "hooks": [
62
62
  {
63
63
  "type": "command",
64
- "command": "bun run {{PKG_ROOT}}/src/hooks/UserPromptOrchestrator.ts"
64
+ "command": "PAL_AGENT=claude bun run {{PKG_ROOT}}/src/hooks/UserPromptOrchestrator.ts"
65
65
  }
66
66
  ]
67
67
  }
@@ -72,7 +72,7 @@
72
72
  "hooks": [
73
73
  {
74
74
  "type": "command",
75
- "command": "bun run {{PKG_ROOT}}/src/hooks/SecurityValidator.ts"
75
+ "command": "PAL_AGENT=claude bun run {{PKG_ROOT}}/src/hooks/SecurityValidator.ts"
76
76
  }
77
77
  ]
78
78
  },
@@ -81,7 +81,7 @@
81
81
  "hooks": [
82
82
  {
83
83
  "type": "command",
84
- "command": "bun run {{PKG_ROOT}}/src/hooks/SkillGuard.ts"
84
+ "command": "PAL_AGENT=claude bun run {{PKG_ROOT}}/src/hooks/SkillGuard.ts"
85
85
  }
86
86
  ]
87
87
  }
@@ -92,7 +92,7 @@
92
92
  "hooks": [
93
93
  {
94
94
  "type": "command",
95
- "command": "bun run {{PKG_ROOT}}/src/hooks/StopOrchestrator.ts"
95
+ "command": "PAL_AGENT=claude bun run {{PKG_ROOT}}/src/hooks/StopOrchestrator.ts"
96
96
  }
97
97
  ]
98
98
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "portable-agent-layer",
3
- "version": "0.39.0",
3
+ "version": "0.41.0",
4
4
  "description": "PAL — Portable Agent Layer: persistent personal context for AI coding assistants",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,6 +42,8 @@
42
42
  "check-write": "biome check --write",
43
43
  "knip": "knip-bun",
44
44
  "klint": "klint",
45
+ "jscpd": "jscpd src --noTips --silent",
46
+ "jscpd:report": "jscpd src --noTips",
45
47
  "lint-staged": "lint-staged",
46
48
  "prepare": "bun .husky/install.mjs",
47
49
  "install:all": "bun run src/cli/index.ts cli install",
@@ -66,21 +68,22 @@
66
68
  "@opencode-ai/plugin": "latest",
67
69
  "@semantic-release/changelog": "^6.0.3",
68
70
  "@semantic-release/git": "^10.0.1",
69
- "@semantic-release/github": "^12.0.6",
71
+ "@semantic-release/github": "^12.0.8",
70
72
  "@types/adm-zip": "^0.5.8",
71
73
  "@types/bun": "latest",
72
74
  "@types/node": "latest",
73
75
  "husky": "^9.1.7",
74
- "knip": "^6.9.0",
76
+ "jscpd": "^4.2.3",
77
+ "knip": "^6.14.1",
75
78
  "lint-staged": "^15.5.2",
76
79
  "semantic-release": "^25.0.3",
77
80
  "typescript": "^5.9.3"
78
81
  },
79
82
  "dependencies": {
80
- "@clack/prompts": "^1.3.0",
83
+ "@clack/prompts": "^1.4.0",
81
84
  "@konvert7/klint": "^0.2.0",
82
85
  "adm-zip": "^0.5.17",
83
86
  "marked": "^15.0.12",
84
- "playwright": "^1.59.1"
87
+ "playwright": "^1.60.0"
85
88
  }
86
89
  }