portable-agent-layer 0.10.0 → 0.12.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/assets/skills/{analyze-pdf.md → analyze-pdf/SKILL.md} +4 -4
- package/{src → assets/skills/analyze-pdf}/tools/pdf-download.ts +3 -3
- package/assets/skills/{analyze-youtube.md → analyze-youtube/SKILL.md} +4 -4
- package/{src → assets/skills/analyze-youtube}/tools/youtube-analyze.ts +2 -2
- package/assets/skills/{council.md → council/SKILL.md} +3 -2
- package/assets/skills/{create-skill.md → create-skill/SKILL.md} +2 -1
- package/assets/skills/{extract-entities.md → extract-entities/SKILL.md} +4 -5
- package/{src → assets/skills/extract-entities}/tools/entity-save.ts +3 -3
- package/assets/skills/{extract-wisdom.md → extract-wisdom/SKILL.md} +3 -2
- package/assets/skills/{first-principles.md → first-principles/SKILL.md} +3 -2
- package/assets/skills/{fyzz-chat-api.md → fyzz-chat-api/SKILL.md} +6 -6
- package/{src → assets/skills/fyzz-chat-api}/tools/fyzz-api.ts +6 -6
- package/assets/skills/{reflect.md → reflect/SKILL.md} +2 -1
- package/assets/skills/{research.md → research/SKILL.md} +2 -1
- package/assets/skills/{review.md → review/SKILL.md} +2 -1
- package/assets/skills/{summarize.md → summarize/SKILL.md} +3 -2
- package/assets/skills/telos/SKILL.md +94 -0
- package/assets/skills/telos/tools/update-telos.ts +100 -0
- package/assets/skills/think/SKILL.md +47 -0
- package/assets/templates/AGENTS.md.template +51 -32
- package/assets/templates/PAL/ALGORITHM.md +120 -0
- package/assets/templates/PAL/CONTEXT_ROUTING.md +28 -0
- package/assets/templates/PAL/MEMORY_SYSTEM.md +26 -0
- package/assets/templates/PAL/OPINION_TRACKING.md +3 -0
- package/assets/templates/PAL/STEERING_RULES.md +43 -0
- package/assets/templates/PAL/WORK_TRACKING.md +14 -0
- package/assets/templates/pal-settings.json +32 -0
- package/assets/templates/settings.claude.json +80 -0
- package/package.json +4 -7
- package/src/cli/index.ts +7 -0
- package/src/cli/setup-identity.ts +119 -0
- package/src/hooks/lib/claude-md.ts +52 -26
- package/src/hooks/lib/context.ts +49 -25
- package/src/hooks/lib/paths.ts +2 -0
- package/src/hooks/lib/security.ts +2 -0
- package/src/hooks/lib/setup.ts +4 -16
- package/src/targets/claude/install.ts +20 -93
- package/src/targets/claude/uninstall.ts +22 -47
- package/src/targets/lib.ts +207 -48
- package/src/targets/opencode/install.ts +13 -2
- package/src/targets/opencode/uninstall.ts +4 -1
- package/assets/templates/STEERING-RULES.md +0 -23
- package/assets/templates/telos/IDENTITY.md +0 -4
- package/src/cli/install.ts +0 -86
- package/src/cli/uninstall.ts +0 -45
|
@@ -1,51 +1,70 @@
|
|
|
1
1
|
# PAL — Portable Agent Layer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Identity
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
You are {{IDENTITY_NAME}} ({{IDENTITY_DISPLAY}}). Your user is {{PRINCIPAL_NAME}}. Greet with: {{IDENTITY_CATCHPHRASE}}
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
## Modes
|
|
8
|
+
|
|
9
|
+
Every response uses exactly one mode. Classify the request BEFORE responding:
|
|
10
|
+
|
|
11
|
+
- **Greetings, ratings, acknowledgments** → MINIMAL
|
|
12
|
+
- **Single-step, quick tasks (under 2 minutes of work)** → NATIVE
|
|
13
|
+
- **Everything else** → ALGORITHM
|
|
14
|
+
|
|
15
|
+
Your first output MUST be the mode header. No freeform output. No skipping this step.
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
### MINIMAL
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
For greetings and brief acknowledgments only.
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
```
|
|
22
|
+
══════════════ PAL ══════════════
|
|
23
|
+
🗣️ {{IDENTITY_NAME}}: [response]
|
|
24
|
+
```
|
|
16
25
|
|
|
17
|
-
###
|
|
26
|
+
### NATIVE
|
|
18
27
|
|
|
19
|
-
|
|
20
|
-
- **Relationship notes**: Daily `.md` file with bullet-point observations about the interaction (tone, preferences, corrections).
|
|
21
|
-
- **Session learnings**: One `.md` file per session with a `**Title:**` line summarizing what was learned.
|
|
22
|
-
- **Failure captures**: One directory per failure, named `{YYYYMMDD-HHmmss}_{slug}/`, containing a `capture.md` with what went wrong and why.
|
|
28
|
+
FOR: Simple tasks that won't take much effort or time. More advanced tasks use ALGORITHM below.
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
```
|
|
31
|
+
══════════════ PAL | NATIVE ══════════════
|
|
32
|
+
🗒️ TASK: [brief description]
|
|
33
|
+
[work]
|
|
34
|
+
🔄 ITERATION on: [16 words of context if this is a follow-up]
|
|
35
|
+
📃 CONTENT: [Up to 128 lines of the content, if there is any]
|
|
36
|
+
🔧 CHANGE: [what changed, if applicable]
|
|
37
|
+
✅ VERIFY: [how we verified, if applicable]
|
|
38
|
+
🗣️ {{IDENTITY_NAME}}: [brief summary]
|
|
39
|
+
```
|
|
25
40
|
|
|
26
|
-
|
|
41
|
+
On follow-ups, include the ITERATION line. On first response to a new request, omit it.
|
|
27
42
|
|
|
28
|
-
###
|
|
43
|
+
### ALGORITHM
|
|
29
44
|
|
|
30
|
-
|
|
31
|
-
- **Starting sustained multi-session work** → create a project with objectives and an id (slugified, e.g. "pdf-template-engine")
|
|
32
|
-
- **Making a key decision** → add to the project's `decisions` array
|
|
33
|
-
- **Completing a milestone** → add to `completed`, remove from `nextSteps`
|
|
34
|
-
- **Session ends with open work** → update `nextSteps` and `handoff`
|
|
35
|
-
- **Work is done** → set status to "completed"
|
|
45
|
+
FOR: Multi-step, complex, or difficult work. Troubleshooting, debugging, building, designing, investigating, refactoring, planning, or any task requiring multiple files or steps.
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
**MANDATORY FIRST ACTION:** Read `~/.agents/PAL/ALGORITHM.md` and follow its instructions exactly.
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
Start your response with the following header in this mode:
|
|
50
|
+
══════════════ PAL | ALGORITHM ══════════════
|
|
40
51
|
|
|
41
|
-
|
|
42
|
-
- When you learn something about how the user prefers to work → relationship note
|
|
43
|
-
- When a session produces reusable insights → session learning
|
|
44
|
-
- When something fails significantly (rating < 6) → failure capture
|
|
45
|
-
- Do NOT write memories about trivial exchanges or things already captured in TELOS.
|
|
52
|
+
---
|
|
46
53
|
|
|
47
|
-
|
|
54
|
+
### Critical Rules (Zero Exceptions)
|
|
55
|
+
|
|
56
|
+
- **Mandatory output format** — Every response MUST use exactly one of the output formats above (ALGORITHM, NATIVE, or MINIMAL). No freeform output.
|
|
57
|
+
- **Response format before questions** — Always complete the current response format output FIRST, then invoke AskUserQuestion at the end.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
{{SETUP_PROMPT}}
|
|
62
|
+
## Context Routing
|
|
48
63
|
|
|
49
|
-
|
|
64
|
+
When you need context about any of these topics, read `~/.agents/PAL/CONTEXT_ROUTING.md` for the file path:
|
|
50
65
|
|
|
51
|
-
|
|
66
|
+
- PAL internals
|
|
67
|
+
- The user, their life and work, etc
|
|
68
|
+
- Your own personality and rules
|
|
69
|
+
- Any project referenced, any work, etc.
|
|
70
|
+
- Basically anything that's specialized
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# The Algorithm
|
|
2
|
+
|
|
3
|
+
Core: transition from CURRENT STATE to IDEAL STATE using verifiable criteria. Every criterion is atomic, binary testable, and checked off with evidence.
|
|
4
|
+
|
|
5
|
+
## The Four Phases
|
|
6
|
+
|
|
7
|
+
All work happens inside these phases. No work outside the phase structure until the Algorithm completes.
|
|
8
|
+
|
|
9
|
+
### ━━━ 👁️ OBSERVE ━━━ 1/4
|
|
10
|
+
|
|
11
|
+
Thinking-only. No tool calls except context recovery (Grep/Glob/Read).
|
|
12
|
+
|
|
13
|
+
**1. Reverse engineer the request:**
|
|
14
|
+
|
|
15
|
+
🔎 REVERSE ENGINEERING:
|
|
16
|
+
- What did they explicitly say they wanted?
|
|
17
|
+
- What is implied that they wanted but didn't say?
|
|
18
|
+
- What did they explicitly say they don't want?
|
|
19
|
+
- What is obvious they don't want that they didn't say?
|
|
20
|
+
- What are common gotchas for this type of work?
|
|
21
|
+
|
|
22
|
+
**2. Define verifiable criteria:**
|
|
23
|
+
|
|
24
|
+
Write atomic criteria — each one is a single testable end-state. Apply the splitting test:
|
|
25
|
+
- **"And"/"With" test**: Joins two verifiable things? → Split them.
|
|
26
|
+
- **Independent failure test**: Part A can pass while Part B fails? → Separate criteria.
|
|
27
|
+
- **Scope word test**: "All", "every", "complete" → Enumerate what "all" means.
|
|
28
|
+
|
|
29
|
+
Format:
|
|
30
|
+
```
|
|
31
|
+
- [ ] C-1: [8-12 word atomic criterion]
|
|
32
|
+
- [ ] C-2: [8-12 word atomic criterion]
|
|
33
|
+
- [ ] C-A1: [anti-criterion — what must NOT happen]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Include at least one anti-criterion (C-A prefix).
|
|
37
|
+
|
|
38
|
+
**3. Select capabilities:**
|
|
39
|
+
|
|
40
|
+
Scan the available skills listing. Select skills and tools you'll invoke during EXECUTE. Selecting a capability = commitment to invoke it via tool call. Don't select what you won't use.
|
|
41
|
+
|
|
42
|
+
Output:
|
|
43
|
+
```
|
|
44
|
+
🏹 CAPABILITIES: [list each selected skill/tool and why]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### ━━━ 🧠 PLAN ━━━ 2/4
|
|
48
|
+
|
|
49
|
+
**Pressure test the criteria:**
|
|
50
|
+
|
|
51
|
+
🧠 RISKS: What are the riskiest assumptions?
|
|
52
|
+
🧠 PREMORTEM: How could this approach fail?
|
|
53
|
+
🧠 PREREQUISITES: What must be true before we start?
|
|
54
|
+
|
|
55
|
+
Refine criteria if the pressure test reveals gaps. Add criteria for uncovered failure modes.
|
|
56
|
+
|
|
57
|
+
**Plan the execution:**
|
|
58
|
+
- Validate prerequisites (env vars, dependencies, files, state)
|
|
59
|
+
- Decide execution order — what's serial, what can parallelize
|
|
60
|
+
- If Advanced+ complexity, use EnterPlanMode for user alignment
|
|
61
|
+
|
|
62
|
+
### ━━━ ⚡ EXECUTE ━━━ 3/4
|
|
63
|
+
|
|
64
|
+
Do the work. Invoke selected capabilities via tool calls.
|
|
65
|
+
|
|
66
|
+
- Check off criteria as they're satisfied: `- [x] C-1: ...`
|
|
67
|
+
- If a criterion can't be met, flag it immediately — don't defer to VERIFY
|
|
68
|
+
- Make decisions explicit — state why you chose approach A over B
|
|
69
|
+
|
|
70
|
+
### ━━━ ✅ VERIFY ━━━ 4/4
|
|
71
|
+
|
|
72
|
+
No rubber-stamping. Each criterion needs specific evidence.
|
|
73
|
+
|
|
74
|
+
For EACH criterion:
|
|
75
|
+
- Test that it's actually complete
|
|
76
|
+
- Cite the evidence (test output, file content, diff, tool result)
|
|
77
|
+
- Mark pass or fail
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
✅ VERIFICATION:
|
|
81
|
+
- [x] C-1: [criterion] — PASS: [evidence]
|
|
82
|
+
- [x] C-2: [criterion] — PASS: [evidence]
|
|
83
|
+
- [ ] C-3: [criterion] — FAIL: [what went wrong]
|
|
84
|
+
- [x] C-A1: [anti-criterion] — PASS: [confirmed not present]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Capability check:** Confirm every selected capability was actually invoked via tool call. Text output alone does not count.
|
|
88
|
+
|
|
89
|
+
If any criteria failed, fix and re-verify before completing.
|
|
90
|
+
|
|
91
|
+
## Output Format
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
♻️ ALGORITHM ═══════════════════════════
|
|
95
|
+
🗒️ TASK: [brief description]
|
|
96
|
+
|
|
97
|
+
━━━ 👁️ OBSERVE ━━━ 1/4
|
|
98
|
+
🔎 REVERSE ENGINEERING:
|
|
99
|
+
[reverse engineering output]
|
|
100
|
+
|
|
101
|
+
📋 CRITERIA:
|
|
102
|
+
[criteria checklist]
|
|
103
|
+
|
|
104
|
+
🏹 CAPABILITIES: [selected capabilities]
|
|
105
|
+
|
|
106
|
+
━━━ 🧠 PLAN ━━━ 2/4
|
|
107
|
+
🧠 RISKS: [risks]
|
|
108
|
+
🧠 PREMORTEM: [failure modes]
|
|
109
|
+
📐 APPROACH: [execution plan]
|
|
110
|
+
|
|
111
|
+
━━━ ⚡ EXECUTE ━━━ 3/4
|
|
112
|
+
[work happens here]
|
|
113
|
+
|
|
114
|
+
━━━ ✅ VERIFY ━━━ 4/4
|
|
115
|
+
✅ VERIFICATION:
|
|
116
|
+
[criterion-by-criterion evidence]
|
|
117
|
+
|
|
118
|
+
🔧 CHANGE: [what changed]
|
|
119
|
+
🗣️ {{IDENTITY_NAME}}: [summary]
|
|
120
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Context Routing
|
|
2
|
+
|
|
3
|
+
Load context on-demand by reading the file at the path listed. Only load what the current task requires.
|
|
4
|
+
|
|
5
|
+
## PAL System
|
|
6
|
+
|
|
7
|
+
| Topic | Path |
|
|
8
|
+
|-------|------|
|
|
9
|
+
| Memory format & guidelines | `~/.agents/PAL/MEMORY_SYSTEM.md` |
|
|
10
|
+
| Work tracking (projects, sessions) | `~/.agents/PAL/WORK_TRACKING.md` |
|
|
11
|
+
| Opinion tracking | `~/.agents/PAL/OPINION_TRACKING.md` |
|
|
12
|
+
| Steering rules | `~/.agents/PAL/STEERING_RULES.md` |
|
|
13
|
+
| Algorithm (complex work phases) | `~/.agents/PAL/ALGORITHM.md` |
|
|
14
|
+
|
|
15
|
+
## User Context (TELOS)
|
|
16
|
+
|
|
17
|
+
| Topic | Path |
|
|
18
|
+
|-------|------|
|
|
19
|
+
| Projects & priorities | `~/.agents/PAL/telos/PROJECTS.md` |
|
|
20
|
+
| Goals (short/medium/long-term) | `~/.agents/PAL/telos/GOALS.md` |
|
|
21
|
+
| Beliefs & principles | `~/.agents/PAL/telos/BELIEFS.md` |
|
|
22
|
+
| Current challenges | `~/.agents/PAL/telos/CHALLENGES.md` |
|
|
23
|
+
| Mission & direction | `~/.agents/PAL/telos/MISSION.md` |
|
|
24
|
+
| Strategies & approaches | `~/.agents/PAL/telos/STRATEGIES.md` |
|
|
25
|
+
| Ideas to explore | `~/.agents/PAL/telos/IDEAS.md` |
|
|
26
|
+
| Key lessons learned | `~/.agents/PAL/telos/LEARNED.md` |
|
|
27
|
+
| Mental models | `~/.agents/PAL/telos/MODELS.md` |
|
|
28
|
+
| Narrative context | `~/.agents/PAL/telos/NARRATIVES.md` |
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Memory System
|
|
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.
|
|
4
|
+
|
|
5
|
+
## Where to write
|
|
6
|
+
|
|
7
|
+
- **Wisdom frames**: `~/.agents/PAL/memory/wisdom/frames/` — crystallized principles per domain (loaded every session)
|
|
8
|
+
- **Relationship notes**: `~/.agents/PAL/memory/relationship/YYYY-MM/YYYY-MM-DD.md` — daily interaction observations (loaded every session)
|
|
9
|
+
- **Session learnings**: `~/.agents/PAL/memory/learning/session/YYYY-MM/*.md` — reusable insights from sessions (loaded every session)
|
|
10
|
+
- **Failure captures**: `~/.agents/PAL/memory/learning/failures/YYYY-MM/{timestamp}_{slug}/capture.md` — what went wrong and why
|
|
11
|
+
- **Signals**: `~/.agents/PAL/memory/signals/ratings.jsonl` — append-only rating signal log (do not edit directly)
|
|
12
|
+
|
|
13
|
+
## Format
|
|
14
|
+
|
|
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.
|
|
19
|
+
|
|
20
|
+
## When to write
|
|
21
|
+
|
|
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 insights → session learning
|
|
25
|
+
- When something fails significantly (rating < 6) → failure capture
|
|
26
|
+
- Do NOT write memories about trivial exchanges or things already captured in TELOS.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Opinion Tracking
|
|
2
|
+
|
|
3
|
+
PAL tracks confidence-scored opinions about the user. When you notice the user confirming or contradicting a behavioral pattern, update it via `bun run tool:opinion`. Run `bun run tool:opinion -- --help` for full usage and examples. Opinions at ≥85% confidence are automatically injected into every session context.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Steering Rules
|
|
2
|
+
|
|
3
|
+
Behavioral directives — act on these, don't just know them.
|
|
4
|
+
|
|
5
|
+
**Surgical fixes only.** When debugging, make precise corrections to the broken behavior. Never delete or rearchitect components as a fix. If you believe a component is the root cause, explain your reasoning and ask before removing it.
|
|
6
|
+
Bad: Hook throws error → remove the entire hook. Build fails → delete and rewrite the config.
|
|
7
|
+
Correct: Hook throws error → read it, trace the error, fix the specific line.
|
|
8
|
+
|
|
9
|
+
**Never assert without verification.** Don't say something "is" a certain way unless you've verified it with your tools. After making changes, verify the result before claiming success. Evidence required — tests, diffs, tool output. Never "Done!" without proof.
|
|
10
|
+
Bad: "The file is correct" without reading it. "Tests pass" without running them. "The deploy succeeded" without checking.
|
|
11
|
+
Correct: Read the file → confirm contents. Run tests → report actual output. Check deploy status → report what you see.
|
|
12
|
+
|
|
13
|
+
**First principles over bolt-ons.** Most problems are symptoms. Understand → Simplify → Reduce → Add (last resort). Don't accrue technical debt through band-aid solutions.
|
|
14
|
+
Bad: Page slow → add caching layer. Actual issue: bad SQL query.
|
|
15
|
+
Correct: Profile → find the slow query → fix it. No new components.
|
|
16
|
+
|
|
17
|
+
**Read before modifying.** Understand existing code, imports, and patterns before suggesting changes.
|
|
18
|
+
Bad: Add rate limiting without reading existing middleware → break session management.
|
|
19
|
+
Correct: Read the handler, imports, and patterns first → integrate with what's already there.
|
|
20
|
+
|
|
21
|
+
**One change when debugging.** Isolate, verify, proceed. Don't change multiple things at once.
|
|
22
|
+
Bad: Page broken → change CSS, API, config, and routes at once. Still broken, now you don't know which change helped or hurt.
|
|
23
|
+
Correct: Dev tools → 404 on API → fix the route → verify → move to next issue.
|
|
24
|
+
|
|
25
|
+
**Minimal scope.** Only change what was asked. No bonus refactoring, no extra cleanup, no unsolicited improvements.
|
|
26
|
+
Bad: Fix bug on line 42, also refactor the whole file → 200-line diff for a one-line fix.
|
|
27
|
+
Correct: Fix the bug → 1-line diff.
|
|
28
|
+
|
|
29
|
+
**Ask before destructive actions.** Deletes, force pushes, production deploys — always ask first.
|
|
30
|
+
Bad: "Clean up cruft" → delete 15 files including backups without asking.
|
|
31
|
+
Correct: List candidates → explain consequences → ask approval first.
|
|
32
|
+
|
|
33
|
+
**Plan means stop.** "Create a plan" = present and STOP. No execution without approval.
|
|
34
|
+
Bad: User says "plan the migration" → you plan it AND start executing it.
|
|
35
|
+
Correct: Present the plan → wait for explicit "go ahead" before writing any code.
|
|
36
|
+
|
|
37
|
+
**Error recovery.** When told you did something wrong — review the session, identify the violation, fix it, then explain what happened and capture the learning. Don't ask "What did I do wrong?"
|
|
38
|
+
Bad: User says "you broke it" → "What did I do wrong?" or "Can you clarify?"
|
|
39
|
+
Correct: Review your recent actions → find the mistake → fix it → explain what happened.
|
|
40
|
+
|
|
41
|
+
**Act on what you know.** When tracked opinions or relationship notes reveal user preferences, apply them to your behavior. If you know the user prefers concise responses, be concise. If they prefer manual commits, never offer to commit.
|
|
42
|
+
Bad: Memory says user dislikes verbose summaries → you write a 3-paragraph recap after every change.
|
|
43
|
+
Correct: Memory says user dislikes verbose summaries → you keep the summary to one line.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Work Tracking
|
|
2
|
+
|
|
3
|
+
PAL tracks your work across sessions in `memory/state/sessions.json` (auto-captured) and `memory/state/projects.json` (AI-managed).
|
|
4
|
+
|
|
5
|
+
## Projects
|
|
6
|
+
|
|
7
|
+
Update `projects.json` via the work-tracking library when:
|
|
8
|
+
- **Starting sustained multi-session work** → create a project with objectives and an id (slugified, e.g. "pdf-template-engine")
|
|
9
|
+
- **Making a key decision** → add to the project's `decisions` array
|
|
10
|
+
- **Completing a milestone** → add to `completed`, remove from `nextSteps`
|
|
11
|
+
- **Session ends with open work** → update `nextSteps` and `handoff`
|
|
12
|
+
- **Work is done** → set status to "completed"
|
|
13
|
+
|
|
14
|
+
Do not create projects for one-off questions or quick fixes.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"identity": {
|
|
3
|
+
"ai": {
|
|
4
|
+
"name": "",
|
|
5
|
+
"fullName": "",
|
|
6
|
+
"displayName": "",
|
|
7
|
+
"catchphrase": ""
|
|
8
|
+
},
|
|
9
|
+
"principal": {
|
|
10
|
+
"name": "",
|
|
11
|
+
"timezone": ""
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"loadAtStartup": {
|
|
15
|
+
"_docs": "Files force-loaded into session context at startup. Injected as <system-reminder> blocks.",
|
|
16
|
+
"files": [
|
|
17
|
+
"~/.agents/PAL/STEERING_RULES.md",
|
|
18
|
+
"~/.agents/PAL/telos/PROJECTS.md"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"dynamicContext": {
|
|
22
|
+
"_docs": "Dynamic context sections injected at session start. Set to false to disable.",
|
|
23
|
+
"wisdom": true,
|
|
24
|
+
"opinions": true,
|
|
25
|
+
"relationship": true,
|
|
26
|
+
"learningDigest": true,
|
|
27
|
+
"synthesis": true,
|
|
28
|
+
"signalTrends": true,
|
|
29
|
+
"failurePatterns": true,
|
|
30
|
+
"activeWork": true
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Read(//*)",
|
|
5
|
+
"Grep(//*)",
|
|
6
|
+
"Glob(//*)",
|
|
7
|
+
"WebFetch",
|
|
8
|
+
"WebSearch",
|
|
9
|
+
"Bash(cat //*)",
|
|
10
|
+
"Bash(head //*)",
|
|
11
|
+
"Bash(tail //*)",
|
|
12
|
+
"Bash(ls //*)",
|
|
13
|
+
"Bash(find //*)",
|
|
14
|
+
"Bash(grep *)",
|
|
15
|
+
"Bash(rg //*)",
|
|
16
|
+
"Bash(wc *)",
|
|
17
|
+
"Bash(diff //*)",
|
|
18
|
+
"Bash(which //*)",
|
|
19
|
+
"Bash(file //*)",
|
|
20
|
+
"Bash(stat //*)",
|
|
21
|
+
"Bash(readlink //*)",
|
|
22
|
+
"Bash(bun ~/.agents/skills/*/tools/*.ts *)"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"hooks": {
|
|
26
|
+
"SessionStart": [
|
|
27
|
+
{
|
|
28
|
+
"matcher": "",
|
|
29
|
+
"hooks": [
|
|
30
|
+
{
|
|
31
|
+
"type": "command",
|
|
32
|
+
"command": "bun run {{PKG_ROOT}}/src/hooks/LoadContext.ts"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"UserPromptSubmit": [
|
|
38
|
+
{
|
|
39
|
+
"matcher": "",
|
|
40
|
+
"hooks": [
|
|
41
|
+
{
|
|
42
|
+
"type": "command",
|
|
43
|
+
"command": "bun run {{PKG_ROOT}}/src/hooks/UserPromptOrchestrator.ts"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"PreToolUse": [
|
|
49
|
+
{
|
|
50
|
+
"matcher": "Bash|Write|Edit",
|
|
51
|
+
"hooks": [
|
|
52
|
+
{
|
|
53
|
+
"type": "command",
|
|
54
|
+
"command": "bun run {{PKG_ROOT}}/src/hooks/SecurityValidator.ts"
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"matcher": "Skill",
|
|
60
|
+
"hooks": [
|
|
61
|
+
{
|
|
62
|
+
"type": "command",
|
|
63
|
+
"command": "bun run {{PKG_ROOT}}/src/hooks/SkillGuard.ts"
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"Stop": [
|
|
69
|
+
{
|
|
70
|
+
"matcher": "",
|
|
71
|
+
"hooks": [
|
|
72
|
+
{
|
|
73
|
+
"type": "command",
|
|
74
|
+
"command": "bun run {{PKG_ROOT}}/src/hooks/StopOrchestrator.ts"
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "portable-agent-layer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "PAL — Portable Agent Layer: persistent personal context for AI coding assistants",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -42,12 +42,8 @@
|
|
|
42
42
|
"check-write": "biome check --write",
|
|
43
43
|
"lint-staged": "lint-staged",
|
|
44
44
|
"prepare": "husky",
|
|
45
|
-
"install:all": "bun run src/cli/
|
|
46
|
-
"uninstall": "bun run src/cli/
|
|
47
|
-
"ai:entity-save": "bun run src/tools/entity-save.ts",
|
|
48
|
-
"ai:fyzz-api": "bun run src/tools/fyzz-api.ts",
|
|
49
|
-
"ai:pdf-download": "bun run src/tools/pdf-download.ts",
|
|
50
|
-
"ai:youtube-analyze": "bun run src/tools/youtube-analyze.ts",
|
|
45
|
+
"install:all": "bun run src/cli/index.ts cli install",
|
|
46
|
+
"uninstall": "bun run src/cli/index.ts cli uninstall",
|
|
51
47
|
"tool:analyze": "bun run src/tools/analyze.ts",
|
|
52
48
|
"tool:opinion": "bun run src/tools/opinion.ts",
|
|
53
49
|
"tool:reflect": "bun run src/tools/relationship-reflect.ts",
|
|
@@ -77,6 +73,7 @@
|
|
|
77
73
|
"typescript": "^5.9.0"
|
|
78
74
|
},
|
|
79
75
|
"dependencies": {
|
|
76
|
+
"@clack/prompts": "^1.1.0",
|
|
80
77
|
"adm-zip": "^0.5.16"
|
|
81
78
|
}
|
|
82
79
|
}
|
package/src/cli/index.ts
CHANGED
|
@@ -425,6 +425,13 @@ async function init(args: string[]) {
|
|
|
425
425
|
}
|
|
426
426
|
|
|
427
427
|
async function install(targets: { claude: boolean; opencode: boolean }) {
|
|
428
|
+
// Scaffold TELOS + PAL settings, then prompt for missing identity
|
|
429
|
+
const { scaffoldTelos, scaffoldPalSettings } = await import("../targets/lib");
|
|
430
|
+
const { promptIdentity } = await import("./setup-identity");
|
|
431
|
+
scaffoldTelos();
|
|
432
|
+
scaffoldPalSettings();
|
|
433
|
+
await promptIdentity();
|
|
434
|
+
|
|
428
435
|
if (targets.claude) {
|
|
429
436
|
console.log("━━━ Claude Code ━━━");
|
|
430
437
|
await import("../targets/claude/install");
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive identity setup — prompts for missing fields in pal-settings.json.
|
|
3
|
+
* Called during `pal install`. Skips fields that already have values.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
import * as clack from "@clack/prompts";
|
|
9
|
+
import { palHome } from "../hooks/lib/paths";
|
|
10
|
+
|
|
11
|
+
interface PalSettings {
|
|
12
|
+
identity?: {
|
|
13
|
+
ai?: { name?: string; fullName?: string; displayName?: string; catchphrase?: string };
|
|
14
|
+
principal?: { name?: string; timezone?: string };
|
|
15
|
+
};
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function settingsPath(): string {
|
|
20
|
+
return resolve(palHome(), "memory", "pal-settings.json");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function readSettings(): PalSettings {
|
|
24
|
+
const p = settingsPath();
|
|
25
|
+
if (!existsSync(p)) return {};
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(readFileSync(p, "utf-8"));
|
|
28
|
+
} catch {
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function writeSettings(settings: PalSettings): void {
|
|
34
|
+
writeFileSync(settingsPath(), `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Prompt for missing identity fields. Skips any field that already has a value. */
|
|
38
|
+
export async function promptIdentity(): Promise<void> {
|
|
39
|
+
// Skip interactive prompts in non-TTY environments (tests, CI)
|
|
40
|
+
if (!process.stdin.isTTY) return;
|
|
41
|
+
|
|
42
|
+
const settings = readSettings();
|
|
43
|
+
if (!settings.identity) settings.identity = {};
|
|
44
|
+
if (!settings.identity.ai) settings.identity.ai = {};
|
|
45
|
+
if (!settings.identity.principal) settings.identity.principal = {};
|
|
46
|
+
|
|
47
|
+
const ai = settings.identity.ai;
|
|
48
|
+
const principal = settings.identity.principal;
|
|
49
|
+
|
|
50
|
+
// Check if anything is missing
|
|
51
|
+
const needsPrincipal = !principal.name;
|
|
52
|
+
const needsAi = !ai.name;
|
|
53
|
+
const needsCatchphrase = !ai.catchphrase;
|
|
54
|
+
const needsTimezone = !principal.timezone;
|
|
55
|
+
|
|
56
|
+
if (!needsPrincipal && !needsAi && !needsCatchphrase && !needsTimezone) {
|
|
57
|
+
clack.log.info("Identity already configured");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
clack.intro("Identity Setup");
|
|
62
|
+
|
|
63
|
+
if (needsPrincipal) {
|
|
64
|
+
const name = await clack.text({
|
|
65
|
+
message: "What's your name?",
|
|
66
|
+
placeholder: "e.g. John",
|
|
67
|
+
validate: (v) => (!v || v.length === 0 ? "Name is required" : undefined),
|
|
68
|
+
});
|
|
69
|
+
if (clack.isCancel(name)) {
|
|
70
|
+
clack.cancel("Setup cancelled");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
principal.name = name;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (needsAi) {
|
|
77
|
+
const name = await clack.text({
|
|
78
|
+
message: "Name your AI",
|
|
79
|
+
defaultValue: "Assistant",
|
|
80
|
+
placeholder: "e.g. Jarvis, Friday, Atlas",
|
|
81
|
+
});
|
|
82
|
+
if (clack.isCancel(name)) {
|
|
83
|
+
clack.cancel("Setup cancelled");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
ai.name = name;
|
|
87
|
+
ai.fullName = `${name} — Personal AI`;
|
|
88
|
+
ai.displayName = name.toUpperCase();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (needsCatchphrase) {
|
|
92
|
+
const catchphrase = await clack.text({
|
|
93
|
+
message: "Startup catchphrase ({name} gets replaced with AI name)",
|
|
94
|
+
defaultValue: "{name} here, ready when you are.",
|
|
95
|
+
placeholder: "{name} online. What's the mission?",
|
|
96
|
+
});
|
|
97
|
+
if (clack.isCancel(catchphrase)) {
|
|
98
|
+
clack.cancel("Setup cancelled");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
ai.catchphrase = catchphrase;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (needsTimezone) {
|
|
105
|
+
const guess = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
106
|
+
const tz = await clack.text({
|
|
107
|
+
message: "Your timezone",
|
|
108
|
+
defaultValue: guess,
|
|
109
|
+
});
|
|
110
|
+
if (clack.isCancel(tz)) {
|
|
111
|
+
clack.cancel("Setup cancelled");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
principal.timezone = tz;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
writeSettings(settings);
|
|
118
|
+
clack.outro("Identity saved ✓");
|
|
119
|
+
}
|