portable-agent-layer 0.12.0 → 0.13.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/opinion/SKILL.md +84 -0
- package/{src → assets/skills/opinion}/tools/opinion.ts +11 -27
- package/assets/templates/PAL/CONTEXT_ROUTING.md +2 -0
- package/assets/templates/PAL/OPINION_TRACKING.md +1 -1
- package/assets/templates/PAL/README.md +127 -0
- package/assets/templates/PAL/STEERING_RULES.md +7 -3
- package/assets/templates/PAL/SYSTEM_ARCHITECTURE.md +471 -0
- package/package.json +1 -2
- package/src/hooks/handlers/relationship.ts +6 -6
- package/src/hooks/handlers/session-name.ts +19 -20
- package/src/hooks/lib/relationship.ts +2 -2
- package/src/tools/relationship-reflect.ts +5 -5
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: opinion
|
|
3
|
+
description: "Opinion tracker for relationship notes. PROACTIVE: When the user confirms a preference ('yes exactly', 'keep doing that'), contradicts one ('no, don't do that', 'stop'), or you observe a recurring behavioral pattern — invoke this to update opinion confidence."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Opinion Tracker
|
|
7
|
+
|
|
8
|
+
Tool: `tools/opinion.ts`
|
|
9
|
+
|
|
10
|
+
Manage confidence-scored opinions about the user. Opinions are promoted from recurring relationship notes (the W/O/B observations captured at session end). This tool is the fast path to grow opinion confidence — relationship notes feed the slow path (+2% per reflect cycle), while explicit confirmations here jump +10%.
|
|
11
|
+
|
|
12
|
+
Opinions at ≥85% confidence are automatically injected into every session context.
|
|
13
|
+
|
|
14
|
+
## When to Use
|
|
15
|
+
|
|
16
|
+
**Proactively call this tool during conversations when:**
|
|
17
|
+
|
|
18
|
+
- The user **explicitly confirms** a preference → `--confirmation`
|
|
19
|
+
- "yes, keep it short" → confirms concise preference
|
|
20
|
+
- "exactly, that's how I want it" → confirms the approach you used
|
|
21
|
+
- User accepts an unusual choice without pushback → implicit confirmation
|
|
22
|
+
|
|
23
|
+
- The user **explicitly contradicts** a preference → `--contradiction`
|
|
24
|
+
- "no, I actually want more detail here" → contradicts concise preference
|
|
25
|
+
- "stop doing X" → contradicts a tracked pattern
|
|
26
|
+
|
|
27
|
+
- You observe a **recurring behavioral pattern** → `--supporting`
|
|
28
|
+
- User does the same thing for the 2nd+ time in a session
|
|
29
|
+
- Pattern matches an existing tracked opinion
|
|
30
|
+
|
|
31
|
+
**Do NOT call when:**
|
|
32
|
+
- The observation is ephemeral or task-specific (not a general preference)
|
|
33
|
+
- You're unsure whether it's a real preference or a one-off request
|
|
34
|
+
- The opinion would be trivially obvious ("user wants correct code")
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# List all tracked opinions
|
|
40
|
+
bun opinion.ts list
|
|
41
|
+
|
|
42
|
+
# Show details for a specific opinion (fuzzy-matched)
|
|
43
|
+
bun opinion.ts show "keywords"
|
|
44
|
+
|
|
45
|
+
# Add a new opinion (starts at 50%)
|
|
46
|
+
bun opinion.ts add "statement" [--category workflow]
|
|
47
|
+
|
|
48
|
+
# Add evidence to an existing opinion
|
|
49
|
+
bun opinion.ts evidence "keywords" --supporting "why" # +2%
|
|
50
|
+
bun opinion.ts evidence "keywords" --counter "why" # -5%
|
|
51
|
+
bun opinion.ts evidence "keywords" --confirmation "why" # +10%
|
|
52
|
+
bun opinion.ts evidence "keywords" --contradiction "why" # -20%
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Categories
|
|
56
|
+
|
|
57
|
+
`communication` | `technical` | `workflow` | `general`
|
|
58
|
+
|
|
59
|
+
## Confidence Lifecycle
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
New opinion (add) → 50%
|
|
63
|
+
├── supporting evidence → +2% each
|
|
64
|
+
├── counter evidence → -5% each
|
|
65
|
+
├── explicit confirmation → +10% each
|
|
66
|
+
├── explicit contradiction → -20% each
|
|
67
|
+
└── at ≥85% → auto-injected into session context
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Examples
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# User says "yes keep it concise, I don't need long explanations"
|
|
74
|
+
bun opinion.ts evidence "concise responses" --confirmation "User explicitly said keep it concise"
|
|
75
|
+
|
|
76
|
+
# User asks for detailed explanation (contradicts concise preference)
|
|
77
|
+
bun opinion.ts evidence "concise responses" --contradiction "User requested detailed explanation for this topic"
|
|
78
|
+
|
|
79
|
+
# You notice user prefers iterative development for the 3rd time
|
|
80
|
+
bun opinion.ts evidence "iterative development" --supporting "User again chose incremental approach over big-bang change"
|
|
81
|
+
|
|
82
|
+
# New pattern: user always checks git status before committing
|
|
83
|
+
bun opinion.ts add "User checks git status before every commit" --category workflow
|
|
84
|
+
```
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
* contradictions, or new behavioral patterns.
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
9
|
-
* bun
|
|
10
|
-
* bun
|
|
11
|
-
* bun
|
|
12
|
-
* bun
|
|
13
|
-
* bun
|
|
14
|
-
* bun
|
|
15
|
-
* bun
|
|
9
|
+
* bun opinion.ts list List all opinions
|
|
10
|
+
* bun opinion.ts show "statement" Show opinion details
|
|
11
|
+
* bun opinion.ts add "statement" [--category workflow] Add new opinion
|
|
12
|
+
* bun opinion.ts evidence "statement" --supporting "why" Add supporting evidence
|
|
13
|
+
* bun opinion.ts evidence "statement" --counter "why" Add counter evidence
|
|
14
|
+
* bun opinion.ts evidence "statement" --confirmation "why" Explicit user confirmation
|
|
15
|
+
* bun opinion.ts evidence "statement" --contradiction "why" Explicit user contradiction
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import {
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
type OpinionCategory,
|
|
24
24
|
readOpinions,
|
|
25
25
|
saveOpinion,
|
|
26
|
-
} from "
|
|
26
|
+
} from "../../../../src/hooks/lib/opinions";
|
|
27
27
|
|
|
28
28
|
const args = process.argv.slice(2);
|
|
29
29
|
const command = args[0];
|
|
@@ -82,7 +82,7 @@ switch (command) {
|
|
|
82
82
|
case "show": {
|
|
83
83
|
const statement = args[1];
|
|
84
84
|
if (!statement) {
|
|
85
|
-
console.error('Usage: bun
|
|
85
|
+
console.error('Usage: bun opinion.ts show "statement"');
|
|
86
86
|
process.exit(1);
|
|
87
87
|
}
|
|
88
88
|
|
|
@@ -128,9 +128,7 @@ switch (command) {
|
|
|
128
128
|
case "add": {
|
|
129
129
|
const statement = args[1];
|
|
130
130
|
if (!statement) {
|
|
131
|
-
console.error(
|
|
132
|
-
'Usage: bun run tool:opinion -- add "statement" [--category workflow]'
|
|
133
|
-
);
|
|
131
|
+
console.error('Usage: bun opinion.ts add "statement" [--category workflow]');
|
|
134
132
|
process.exit(1);
|
|
135
133
|
}
|
|
136
134
|
|
|
@@ -156,7 +154,7 @@ switch (command) {
|
|
|
156
154
|
const statement = args[1];
|
|
157
155
|
if (!statement) {
|
|
158
156
|
console.error(
|
|
159
|
-
'Usage: bun
|
|
157
|
+
'Usage: bun opinion.ts evidence "statement" --supporting "description"'
|
|
160
158
|
);
|
|
161
159
|
process.exit(1);
|
|
162
160
|
}
|
|
@@ -226,20 +224,6 @@ switch (command) {
|
|
|
226
224
|
evidence "keywords" --contradiction "why" User explicitly contradicted (-20%)
|
|
227
225
|
|
|
228
226
|
Categories: communication, technical, workflow, general
|
|
229
|
-
|
|
230
|
-
Examples:
|
|
231
|
-
bun run tool:opinion -- list
|
|
232
|
-
bun run tool:opinion -- evidence "concise direct responses" --confirmation "User said: keep it short"
|
|
233
|
-
bun run tool:opinion -- evidence "concise direct responses" --contradiction "User asked for detailed explanation"
|
|
234
|
-
bun run tool:opinion -- add "User prefers iterative development" --category workflow
|
|
235
|
-
bun run tool:opinion -- show "iterative development"
|
|
236
|
-
|
|
237
|
-
Confidence lifecycle:
|
|
238
|
-
New opinions start at 50%. Supporting notes from reflect add +2% each.
|
|
239
|
-
Explicit confirmations jump +10%, contradictions drop -20%.
|
|
240
|
-
At >=85%, opinions are auto-injected into every session context.
|
|
241
|
-
|
|
242
|
-
Usage: bun run tool:opinion -- <command> [args]
|
|
243
227
|
`);
|
|
244
228
|
break;
|
|
245
229
|
}
|
|
@@ -6,6 +6,8 @@ Load context on-demand by reading the file at the path listed. Only load what th
|
|
|
6
6
|
|
|
7
7
|
| Topic | Path |
|
|
8
8
|
|-------|------|
|
|
9
|
+
| PAL system overview | `~/.agents/PAL/README.md` |
|
|
10
|
+
| System architecture | `~/.agents/PAL/SYSTEM_ARCHITECTURE.md` |
|
|
9
11
|
| Memory format & guidelines | `~/.agents/PAL/MEMORY_SYSTEM.md` |
|
|
10
12
|
| Work tracking (projects, sessions) | `~/.agents/PAL/WORK_TRACKING.md` |
|
|
11
13
|
| Opinion tracking | `~/.agents/PAL/OPINION_TRACKING.md` |
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# Opinion Tracking
|
|
2
2
|
|
|
3
|
-
PAL tracks confidence-scored opinions about the user. When you notice the user confirming or contradicting a behavioral pattern,
|
|
3
|
+
PAL tracks confidence-scored opinions about the user. When you notice the user confirming or contradicting a behavioral pattern, use the `opinion` skill to update confidence. Opinions at ≥85% confidence are automatically injected into every session context.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# PAL — Portable Agent Layer
|
|
2
|
+
|
|
3
|
+
PAL is a persistent, cross-platform, cross-agent layer for portable AI workflows, memory, and accumulated knowledge. It runs inside any compatible AI coding agent (Claude Code, opencode) as an interconnected set of skills, hooks, tools, memory, and configuration — all orchestrated by The Algorithm.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
**CLAUDE.md** (or the agent equivalent) is the entry point — generated from a template by the CLI installer. It defines execution modes, The Algorithm routing, and the context routing table. The agent loads it natively every session. A SessionStart hook keeps it fresh automatically.
|
|
8
|
+
|
|
9
|
+
**The PAL home directory (`~/.agents/PAL/`)** contains all system documentation, user context (TELOS), and routing files. The rest of the system lives in the PAL package (`src/`) and the agent's config directory (`~/.claude/` or `~/.config/opencode/`).
|
|
10
|
+
|
|
11
|
+
## Directory Structure
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
~/.agents/PAL/ # PAL home — user context + routing
|
|
15
|
+
ALGORITHM.md # The execution engine (4-phase)
|
|
16
|
+
CONTEXT_ROUTING.md # On-demand context routing table
|
|
17
|
+
MEMORY_SYSTEM.md # Memory guidelines
|
|
18
|
+
OPINION_TRACKING.md # Opinion system reference
|
|
19
|
+
STEERING_RULES.md # Behavioral rules
|
|
20
|
+
WORK_TRACKING.md # Work tracking reference
|
|
21
|
+
telos/ # User life context (TELOS)
|
|
22
|
+
MISSION.md, GOALS.md, PROJECTS.md, BELIEFS.md,
|
|
23
|
+
CHALLENGES.md, STRATEGIES.md, IDEAS.md, LEARNED.md,
|
|
24
|
+
MODELS.md, NARRATIVES.md
|
|
25
|
+
|
|
26
|
+
<PAL package>/ # The PAL codebase
|
|
27
|
+
src/
|
|
28
|
+
cli/ # CLI entry point (pal command)
|
|
29
|
+
hooks/ # Session lifecycle hooks
|
|
30
|
+
handlers/ # Individual stop/prompt handlers
|
|
31
|
+
lib/ # Shared utilities
|
|
32
|
+
targets/ # Agent-specific installers (Claude, opencode)
|
|
33
|
+
tools/ # Standalone CLI tools
|
|
34
|
+
assets/
|
|
35
|
+
skills/ # Bundled skills (16+)
|
|
36
|
+
templates/PAL/ # Templates for PAL home files
|
|
37
|
+
|
|
38
|
+
<PAL package>/memory/ # Persistent memory (gitignored)
|
|
39
|
+
state/ # Runtime state (sessions, counts, caches)
|
|
40
|
+
signals/ # Rating signals (ratings.jsonl)
|
|
41
|
+
relationship/ # Daily interaction notes + opinions
|
|
42
|
+
YYYY-MM/YYYY-MM-DD.md # Daily relationship notes
|
|
43
|
+
opinions.json # Confidence-tracked opinions
|
|
44
|
+
reflections/ # Periodic reflection reports
|
|
45
|
+
session-learning/ # Per-session learnings
|
|
46
|
+
failures/ # Low-rating context dumps
|
|
47
|
+
wisdom/ # Crystallized principles (frames)
|
|
48
|
+
synthesis/ # Pattern synthesis reports
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Core Subsystems
|
|
52
|
+
|
|
53
|
+
### The Algorithm (`ALGORITHM.md`)
|
|
54
|
+
The 4-phase execution engine: Observe, Plan, Execute, Verify. Transitions from CURRENT STATE to IDEAL STATE via verifiable criteria. Used for all complex work.
|
|
55
|
+
|
|
56
|
+
### Three Execution Modes
|
|
57
|
+
Every response uses exactly one mode:
|
|
58
|
+
- **MINIMAL** — Greetings, acknowledgments
|
|
59
|
+
- **NATIVE** — Simple, quick tasks
|
|
60
|
+
- **ALGORITHM** — Multi-step, complex work (invokes the full 4-phase engine)
|
|
61
|
+
|
|
62
|
+
### Skills (`assets/skills/`)
|
|
63
|
+
Bundled skills installed into the agent's skill directory. Each has a `SKILL.md` defining triggers, workflows, and capabilities. Skills are the primary capability unit — they tell the AI what it can do and when to do it.
|
|
64
|
+
|
|
65
|
+
### Hooks (`src/hooks/`)
|
|
66
|
+
Event hooks across the session lifecycle:
|
|
67
|
+
- **SessionStart** → `LoadContext.ts` — inject dynamic context, regenerate CLAUDE.md if stale
|
|
68
|
+
- **UserPromptSubmit** → `UserPromptOrchestrator.ts` — rating capture, session naming
|
|
69
|
+
- **PreToolUse** → `SecurityValidator.ts` — block dangerous commands; `SkillGuard.ts` — block false-positive skill matches
|
|
70
|
+
- **Stop** → `StopOrchestrator.ts` — work tracking, relationship capture, learnings, backups, reflect trigger
|
|
71
|
+
|
|
72
|
+
### Memory (`memory/`)
|
|
73
|
+
Persistent storage across sessions:
|
|
74
|
+
- **signals/** — User satisfaction ratings (explicit + implicit)
|
|
75
|
+
- **relationship/** — Daily interaction notes, confidence-tracked opinions, reflection reports
|
|
76
|
+
- **session-learning/** — Per-session context and learnings
|
|
77
|
+
- **failures/** — Low-rating session context dumps for pattern avoidance
|
|
78
|
+
- **wisdom/** — Crystallized principles that compound over time
|
|
79
|
+
- **synthesis/** — Weekly pattern synthesis reports
|
|
80
|
+
- **state/** — Session registry, counts cache, debug logs
|
|
81
|
+
|
|
82
|
+
### Tools (`src/tools/`)
|
|
83
|
+
CLI utilities: `tool:opinion` (manage opinions), `tool:reflect` (relationship reflection), `tool:analyze` (learning analysis), `tool:tokens` (usage tracking), `tool:export` / `tool:import` (state portability).
|
|
84
|
+
|
|
85
|
+
### TELOS (`telos/`)
|
|
86
|
+
Personal context system — mission, goals, projects, beliefs, challenges, strategies, ideas, learnings, mental models, narratives. Managed via the telos skill.
|
|
87
|
+
|
|
88
|
+
### Security (`SecurityValidator.ts`)
|
|
89
|
+
Hook-based security: validates Bash commands and file operations against dangerous patterns. Fail-open design — blocks known-dangerous operations without breaking legitimate work.
|
|
90
|
+
|
|
91
|
+
## Startup & Context Loading
|
|
92
|
+
|
|
93
|
+
At session start, three things happen:
|
|
94
|
+
1. **CLAUDE.md** loads natively (identity, modes, routing table)
|
|
95
|
+
2. **`loadAtStartup` files** from `pal-settings.json` are loaded by `LoadContext.ts`
|
|
96
|
+
3. **Dynamic context** injected by `LoadContext.ts`: crystallized principles, tracked opinions (≥85%), recent interaction notes, learning digest, signal trends, failure patterns, active work summary — each toggleable in `pal-settings.json → dynamicContext`
|
|
97
|
+
|
|
98
|
+
All other documentation loads on-demand via the routing table in CLAUDE.md.
|
|
99
|
+
|
|
100
|
+
## CLI
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
pal # Start agent session with auto-summary on exit
|
|
104
|
+
pal cli init # Scaffold PAL home + install hooks
|
|
105
|
+
pal cli install [--claude] # Register hooks/skills for Claude Code
|
|
106
|
+
pal cli install [--opencode] # Register hooks/skills for opencode
|
|
107
|
+
pal cli uninstall # Remove hooks/skills
|
|
108
|
+
pal cli status # Show configuration
|
|
109
|
+
pal cli doctor # Check prerequisites and health
|
|
110
|
+
pal cli export [path] # Export user state to zip
|
|
111
|
+
pal cli import [path] # Import state from zip
|
|
112
|
+
pal cli update # Update PAL
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Cross-Platform & Cross-Agent
|
|
116
|
+
|
|
117
|
+
PAL is designed to work identically across:
|
|
118
|
+
- **Platforms:** macOS, Linux, Windows
|
|
119
|
+
- **Agents:** Claude Code, opencode (and future tools)
|
|
120
|
+
- **Environment overrides:** `PAL_HOME`, `PAL_PKG`, `PAL_CLAUDE_DIR`, `PAL_OPENCODE_DIR`, `PAL_AGENTS_DIR`
|
|
121
|
+
|
|
122
|
+
## Extending PAL
|
|
123
|
+
|
|
124
|
+
- **Add a skill:** Use the `create-skill` skill or manually create `assets/skills/<name>/SKILL.md`
|
|
125
|
+
- **Add startup files:** Append to `pal-settings.json → loadAtStartup.files`
|
|
126
|
+
- **Add user context:** Create files in `~/.agents/PAL/telos/`
|
|
127
|
+
- **Toggle dynamic context:** Set keys in `pal-settings.json → dynamicContext` to `false`
|
|
@@ -22,9 +22,13 @@ Correct: Read the handler, imports, and patterns first → integrate with what's
|
|
|
22
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
23
|
Correct: Dev tools → 404 on API → fix the route → verify → move to next issue.
|
|
24
24
|
|
|
25
|
-
**Minimal scope.** Only change what was asked. No bonus
|
|
26
|
-
Bad: Fix bug on line 42, also
|
|
27
|
-
Correct: Fix the bug →
|
|
25
|
+
**Minimal scope.** Only change what was asked. No bonus features, no unsolicited additions.
|
|
26
|
+
Bad: Fix bug on line 42, also add a new logging framework → 200-line diff for a one-line fix.
|
|
27
|
+
Correct: Fix the bug → focused diff.
|
|
28
|
+
|
|
29
|
+
**Cleanup on touch.** When modifying a file, assess it for dead code, unnecessary complexity, or poor organization. Offer to clean it up — don't silently refactor, flag what you found and ask. This applies to the file being edited, not neighboring files.
|
|
30
|
+
Bad: Editing a handler → silently rewrite the whole file and three others.
|
|
31
|
+
Correct: Editing a handler → notice dead imports and a 200-line function → "This file has dead imports and a function that could be split — want me to clean it up?"
|
|
28
32
|
|
|
29
33
|
**Ask before destructive actions.** Deletes, force pushes, production deploys — always ask first.
|
|
30
34
|
Bad: "Clean up cruft" → delete 15 files including backups without asking.
|
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
# PAL System Architecture
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
SYSTEM ARCHITECTURE TEMPLATE
|
|
5
|
+
=============================
|
|
6
|
+
This file defines the GENERIC architecture patterns for any PAL installation.
|
|
7
|
+
These are the foundational patterns that apply to ALL PAL implementations.
|
|
8
|
+
|
|
9
|
+
WHAT GOES HERE:
|
|
10
|
+
- The Founding Principles (universal)
|
|
11
|
+
- Generic system patterns (skill structure, hook lifecycle, memory layout)
|
|
12
|
+
- Architecture diagrams showing how components interact
|
|
13
|
+
- Design philosophy and constraints
|
|
14
|
+
|
|
15
|
+
WHAT DOES NOT GO HERE:
|
|
16
|
+
- User-specific skill counts, configurations, or API keys
|
|
17
|
+
- Personal projects or deployment details
|
|
18
|
+
- Ephemeral state or session-specific information
|
|
19
|
+
-->
|
|
20
|
+
|
|
21
|
+
**The Founding Principles and Universal Architecture Patterns for the Portable Agent Layer**
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Core Philosophy
|
|
26
|
+
|
|
27
|
+
**PAL is scaffolding for AI, not a replacement for human intelligence.**
|
|
28
|
+
|
|
29
|
+
AI systems need structure to be reliable. Like physical scaffolding supports construction work, PAL provides the architectural framework that makes AI assistance dependable, maintainable, and effective — regardless of which AI agent runs underneath.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## The Founding Principles
|
|
34
|
+
|
|
35
|
+
### 1. Portability First
|
|
36
|
+
|
|
37
|
+
**PAL exists so your AI context, memory, and workflows survive any single tool.**
|
|
38
|
+
|
|
39
|
+
AI agents come and go. Your accumulated knowledge, preferences, and workflows should not be locked into one vendor's tool. PAL abstracts the agent-specific layer so the same skills, hooks, memory, and configuration work across Claude Code, opencode, and future agents.
|
|
40
|
+
|
|
41
|
+
**What portability means in practice:**
|
|
42
|
+
- No agent-specific assumptions in core logic
|
|
43
|
+
- Agent-specific code isolated in `src/targets/`
|
|
44
|
+
- Skills, memory, and TELOS are agent-agnostic
|
|
45
|
+
- A single `pal cli install --<agent>` registers everything
|
|
46
|
+
|
|
47
|
+
### 2. Cross-Platform by Default
|
|
48
|
+
|
|
49
|
+
**Every feature must work identically on macOS, Linux, and Windows.**
|
|
50
|
+
|
|
51
|
+
No platform-specific code without a portable fallback. Path resolution, shell commands, and file operations use cross-platform abstractions. Environment overrides (`PAL_HOME`, `PAL_PKG`, etc.) let users customize paths without touching code.
|
|
52
|
+
|
|
53
|
+
### 3. The Continuously Upgrading Algorithm
|
|
54
|
+
|
|
55
|
+
**The Algorithm is the gravitational center — everything else exists to serve it.**
|
|
56
|
+
|
|
57
|
+
PAL is built around a universal pattern for accomplishing any task: **Current State → Ideal State** via verifiable criteria. This pattern applies at every scale.
|
|
58
|
+
|
|
59
|
+
Everything feeds back into improving The Algorithm:
|
|
60
|
+
- The **Memory System** captures signals from every interaction
|
|
61
|
+
- The **Hook System** detects sentiment, ratings, and behavioral patterns
|
|
62
|
+
- The **Learning System** organizes evidence by session
|
|
63
|
+
- The **Wisdom System** crystallizes recurring patterns into principles
|
|
64
|
+
- The **Relationship System** tracks how the user works and what they prefer
|
|
65
|
+
|
|
66
|
+
### 4. Scaffolding > Model
|
|
67
|
+
|
|
68
|
+
**The system architecture matters more than the underlying AI model.**
|
|
69
|
+
|
|
70
|
+
A well-structured system with good scaffolding will outperform a more powerful model with poor structure. PAL's value comes from:
|
|
71
|
+
- Organized workflows that guide AI execution
|
|
72
|
+
- Routing systems that activate the right context
|
|
73
|
+
- Quality gates that verify outputs
|
|
74
|
+
- Memory systems that enable learning
|
|
75
|
+
- Feedback systems that provide awareness
|
|
76
|
+
|
|
77
|
+
### 5. As Deterministic as Possible
|
|
78
|
+
|
|
79
|
+
**Favor predictable, repeatable outcomes over flexibility.**
|
|
80
|
+
|
|
81
|
+
- Same input → Same output
|
|
82
|
+
- Behavior defined by code and hooks, not prompt variations
|
|
83
|
+
- Version control tracks explicit changes
|
|
84
|
+
- Hooks run deterministic TypeScript, not prompt-driven logic
|
|
85
|
+
|
|
86
|
+
### 6. Code Before Prompts
|
|
87
|
+
|
|
88
|
+
**Write code to solve problems, use prompts to orchestrate code.**
|
|
89
|
+
|
|
90
|
+
Prompts should never replicate functionality that code can provide:
|
|
91
|
+
- Hooks are TypeScript, not prompt instructions
|
|
92
|
+
- Tools are CLI programs, not natural language procedures
|
|
93
|
+
- Memory is structured JSON/JSONL, not freeform text
|
|
94
|
+
- Configuration is `pal-settings.json`, not prose in CLAUDE.md
|
|
95
|
+
|
|
96
|
+
### 7. Clear Thinking + Prompting is King
|
|
97
|
+
|
|
98
|
+
**The quality of outcomes depends on the quality of thinking and prompts.**
|
|
99
|
+
|
|
100
|
+
Before any code, before any architecture — there must be clear thinking:
|
|
101
|
+
- Understand the problem deeply before solving it
|
|
102
|
+
- Define success criteria before building
|
|
103
|
+
- Challenge assumptions before accepting them
|
|
104
|
+
- Simplify before optimizing
|
|
105
|
+
|
|
106
|
+
### 8. UNIX Philosophy
|
|
107
|
+
|
|
108
|
+
**Do one thing well. Compose tools through standard interfaces.**
|
|
109
|
+
|
|
110
|
+
- Each hook handler does one thing
|
|
111
|
+
- Each tool is a standalone CLI program
|
|
112
|
+
- Each skill is a self-contained capability
|
|
113
|
+
- Hooks compose via `Promise.allSettled` — independent, parallel, isolated failures
|
|
114
|
+
- Tools compose via `bun run tool:<name>` — standard I/O, exit codes
|
|
115
|
+
|
|
116
|
+
### 9. CLI as Interface
|
|
117
|
+
|
|
118
|
+
**Every operation should be accessible via command line.**
|
|
119
|
+
|
|
120
|
+
- `pal cli <command>` for system management
|
|
121
|
+
- `bun run tool:<name>` for utilities
|
|
122
|
+
- Skills triggered via agent slash commands
|
|
123
|
+
- No hidden operations — everything is scriptable and testable
|
|
124
|
+
|
|
125
|
+
### 10. Spec / Test First
|
|
126
|
+
|
|
127
|
+
**Define expected behavior before writing implementation.**
|
|
128
|
+
|
|
129
|
+
- Write tests before implementation
|
|
130
|
+
- Tests should fail initially
|
|
131
|
+
- Implement until tests pass
|
|
132
|
+
- Run `check-write`, `type-check`, and `test` after every edit
|
|
133
|
+
|
|
134
|
+
### 11. Custom Skill Management
|
|
135
|
+
|
|
136
|
+
**Skills are the organizational unit for all domain expertise.**
|
|
137
|
+
|
|
138
|
+
Skills are active orchestrators, not passive documentation:
|
|
139
|
+
- **Self-activating:** Trigger automatically based on user request
|
|
140
|
+
- **Self-contained:** Package all context, workflows, and tools
|
|
141
|
+
- **Composable:** Can invoke other skills and agents
|
|
142
|
+
- **Evolvable:** Easy to add, modify, or deprecate
|
|
143
|
+
|
|
144
|
+
### 12. Custom Memory System
|
|
145
|
+
|
|
146
|
+
**Automatic capture and preservation of valuable work.**
|
|
147
|
+
|
|
148
|
+
Every session, every insight, every decision — captured automatically:
|
|
149
|
+
- Relationship notes extracted via inference
|
|
150
|
+
- Learnings captured per session
|
|
151
|
+
- Ratings tracked (explicit and implicit)
|
|
152
|
+
- Wisdom crystallized from recurring patterns
|
|
153
|
+
- Failures logged for pattern avoidance
|
|
154
|
+
|
|
155
|
+
### 13. Permission to Fail
|
|
156
|
+
|
|
157
|
+
**Explicit permission to say "I don't know" prevents hallucinations.**
|
|
158
|
+
|
|
159
|
+
The AI has explicit permission to say "I don't know" when:
|
|
160
|
+
- Information isn't available in context
|
|
161
|
+
- Multiple conflicting answers seem equally valid
|
|
162
|
+
- Verification isn't possible
|
|
163
|
+
|
|
164
|
+
Fabricating an answer is far worse than admitting uncertainty.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Skill System Architecture
|
|
169
|
+
|
|
170
|
+
### Canonical Skill Structure
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
assets/skills/<name>/
|
|
174
|
+
├── SKILL.md # Main skill file (REQUIRED)
|
|
175
|
+
└── tools/ # CLI tools for automation (optional)
|
|
176
|
+
└── tool-name.ts # TypeScript CLI tool
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### SKILL.md Format
|
|
180
|
+
|
|
181
|
+
```markdown
|
|
182
|
+
---
|
|
183
|
+
name: skill-name
|
|
184
|
+
description: What it does. Use when [triggers]. Capabilities.
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
# Skill Name
|
|
188
|
+
|
|
189
|
+
Brief description.
|
|
190
|
+
|
|
191
|
+
## Workflow
|
|
192
|
+
[Steps, decision trees, or procedures]
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Key Rules
|
|
196
|
+
|
|
197
|
+
- **Description**: Used by the agent for skill matching — be specific about triggers
|
|
198
|
+
- **One SKILL.md per skill**: The single entry point
|
|
199
|
+
- **Tools are optional**: Only add when the skill needs CLI automation
|
|
200
|
+
- **Skills are agent-agnostic**: No agent-specific assumptions in SKILL.md
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Hook System Architecture
|
|
205
|
+
|
|
206
|
+
### Lifecycle
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
┌─────────────────────┐
|
|
210
|
+
│ Session Start │──► LoadContext.ts
|
|
211
|
+
│ │ - Regenerate CLAUDE.md if stale
|
|
212
|
+
│ │ - Inject dynamic context (system-reminder)
|
|
213
|
+
└─────────────────────┘
|
|
214
|
+
|
|
215
|
+
┌─────────────────────┐
|
|
216
|
+
│ User Prompt Submit │──► UserPromptOrchestrator.ts
|
|
217
|
+
│ │ - Rating capture (explicit/implicit)
|
|
218
|
+
│ │ - Session naming (first prompt)
|
|
219
|
+
└─────────────────────┘
|
|
220
|
+
|
|
221
|
+
┌─────────────────────┐
|
|
222
|
+
│ Pre Tool Use │──► SecurityValidator.ts
|
|
223
|
+
│ │ - Bash command validation
|
|
224
|
+
│ │ - File path validation
|
|
225
|
+
│ │──► SkillGuard.ts
|
|
226
|
+
│ │ - Block false-positive skill matches
|
|
227
|
+
└─────────────────────┘
|
|
228
|
+
|
|
229
|
+
┌─────────────────────┐
|
|
230
|
+
│ Stop │──► StopOrchestrator.ts
|
|
231
|
+
│ │ - Work session capture
|
|
232
|
+
│ │ - Relationship extraction (Haiku inference)
|
|
233
|
+
│ │ - Work learning capture
|
|
234
|
+
│ │ - Failure logging
|
|
235
|
+
│ │ - Reflect trigger check
|
|
236
|
+
│ │ - Auto-backup
|
|
237
|
+
│ │ - Count updates
|
|
238
|
+
│ │ - Tab reset
|
|
239
|
+
└─────────────────────┘
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Design Principles
|
|
243
|
+
|
|
244
|
+
- **Fail-open**: Hook errors never block the user's session
|
|
245
|
+
- **Parallel execution**: Stop handlers run via `Promise.allSettled` — one failure doesn't block others
|
|
246
|
+
- **Idempotent**: Handlers check for existing state before writing (e.g., session dedup)
|
|
247
|
+
- **Timeout-aware**: Inference calls have hard timeouts (8s default)
|
|
248
|
+
- **Subagent-aware**: `LoadContext.ts` skips heavy context loading for subagent sessions
|
|
249
|
+
|
|
250
|
+
### Configuration
|
|
251
|
+
|
|
252
|
+
Hooks are registered in the agent's settings file during `pal cli install`:
|
|
253
|
+
|
|
254
|
+
```json
|
|
255
|
+
{
|
|
256
|
+
"hooks": {
|
|
257
|
+
"SessionStart": [{ "type": "command", "command": "bun run <path>/LoadContext.ts" }],
|
|
258
|
+
"UserPromptSubmit": [{ "type": "command", "command": "bun run <path>/UserPromptOrchestrator.ts" }],
|
|
259
|
+
"PreToolUse": [
|
|
260
|
+
{ "type": "command", "command": "bun run <path>/SecurityValidator.ts", "matcher": "Bash" },
|
|
261
|
+
{ "type": "command", "command": "bun run <path>/SkillGuard.ts", "matcher": "Skill" }
|
|
262
|
+
],
|
|
263
|
+
"Stop": [{ "type": "command", "command": "bun run <path>/StopOrchestrator.ts" }]
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Memory System Architecture
|
|
271
|
+
|
|
272
|
+
### Directory Structure
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
memory/
|
|
276
|
+
├── state/ # Runtime state
|
|
277
|
+
│ ├── sessions.json # Session registry (name, cwd, status, summary)
|
|
278
|
+
│ ├── projects.json # Multi-session project tracking
|
|
279
|
+
│ ├── counts.json # Cached counts for greeting
|
|
280
|
+
│ ├── last-responses.json # Cached responses for rating correlation
|
|
281
|
+
│ ├── pending-failure.json # Deferred failure capture
|
|
282
|
+
│ └── debug.log # Hook execution logs
|
|
283
|
+
│
|
|
284
|
+
├── signals/ # User feedback
|
|
285
|
+
│ └── ratings.jsonl # Explicit + implicit ratings
|
|
286
|
+
│
|
|
287
|
+
├── relationship/ # Interaction tracking
|
|
288
|
+
│ ├── YYYY-MM/
|
|
289
|
+
│ │ └── YYYY-MM-DD.md # Daily notes (W/O/B format)
|
|
290
|
+
│ ├── opinions.json # Confidence-tracked opinions
|
|
291
|
+
│ └── reflections/ # Periodic reflection reports
|
|
292
|
+
│
|
|
293
|
+
├── session-learning/ # Per-session learnings
|
|
294
|
+
│ └── YYYY-MM/
|
|
295
|
+
│ └── YYYY-MM-DD_title.md # Session learning with frontmatter
|
|
296
|
+
│
|
|
297
|
+
├── failures/ # Low-rating context dumps
|
|
298
|
+
│ └── YYYY-MM/
|
|
299
|
+
│ └── YYYY-MM-DD_context.md # Failed session context for avoidance
|
|
300
|
+
│
|
|
301
|
+
├── wisdom/ # Crystallized principles
|
|
302
|
+
│ └── frames/
|
|
303
|
+
│ └── domain.md # Domain-specific principles with confidence
|
|
304
|
+
│
|
|
305
|
+
└── synthesis/ # Pattern aggregation
|
|
306
|
+
└── YYYY-MM/
|
|
307
|
+
└── YYYY-MM-DD_period.md # Weekly/monthly synthesis reports
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Data Flow
|
|
311
|
+
|
|
312
|
+
```
|
|
313
|
+
Session interaction
|
|
314
|
+
│
|
|
315
|
+
├─► [Stop] Rating capture ──► signals/ratings.jsonl
|
|
316
|
+
│
|
|
317
|
+
├─► [Stop] Relationship extraction (Haiku) ──► relationship/YYYY-MM/YYYY-MM-DD.md
|
|
318
|
+
│
|
|
319
|
+
├─► [Stop] Work learning capture ──► session-learning/YYYY-MM/...
|
|
320
|
+
│
|
|
321
|
+
├─► [Stop] Failure capture (low ratings) ──► failures/YYYY-MM/...
|
|
322
|
+
│
|
|
323
|
+
├─► [Periodic] Reflect trigger ──► relationship/opinions.json
|
|
324
|
+
│ relationship/reflections/...
|
|
325
|
+
│
|
|
326
|
+
├─► [Periodic] Synthesis ──► synthesis/YYYY-MM/...
|
|
327
|
+
│
|
|
328
|
+
└─► [Periodic] Wisdom graduation ──► wisdom/frames/...
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Relationship Note Format
|
|
332
|
+
|
|
333
|
+
Three note types, captured via Haiku inference at session end:
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
W — World facts (user's situation, projects, tools)
|
|
337
|
+
O(c=0.85) — Opinions/preferences with confidence
|
|
338
|
+
B(c=0.75) — Beliefs/behavioral patterns with confidence
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Opinion Lifecycle
|
|
342
|
+
|
|
343
|
+
```
|
|
344
|
+
Relationship notes (O/B types)
|
|
345
|
+
│
|
|
346
|
+
├─► Reflect tool groups similar notes
|
|
347
|
+
│ ├─► 2+ occurrences → new opinion at 50% confidence
|
|
348
|
+
│ └─► Matches existing → +2% supporting evidence
|
|
349
|
+
│
|
|
350
|
+
├─► AI confirmation → +10% (via tool:opinion)
|
|
351
|
+
├─► AI contradiction → -20% (via tool:opinion)
|
|
352
|
+
│
|
|
353
|
+
└─► At ≥85% confidence → auto-injected into session context
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Context Loading Architecture
|
|
359
|
+
|
|
360
|
+
### Two-Layer Design
|
|
361
|
+
|
|
362
|
+
**Static context** (loaded natively by the agent):
|
|
363
|
+
- CLAUDE.md — identity, modes, context routing table
|
|
364
|
+
- Loaded once at session start, always available
|
|
365
|
+
|
|
366
|
+
**Dynamic context** (injected by LoadContext hook):
|
|
367
|
+
- Changes per-session, can't live in a static file
|
|
368
|
+
- Injected as `<system-reminder>` block to stdout
|
|
369
|
+
- Each section independently toggleable in `pal-settings.json → dynamicContext`
|
|
370
|
+
|
|
371
|
+
### Injection Order
|
|
372
|
+
|
|
373
|
+
```
|
|
374
|
+
LoadContext.ts
|
|
375
|
+
│
|
|
376
|
+
├─► Regenerate CLAUDE.md if template/telos changed
|
|
377
|
+
│
|
|
378
|
+
└─► Build system-reminder:
|
|
379
|
+
1. loadAtStartup files (user-configured)
|
|
380
|
+
2. Crystallized principles (wisdom frames)
|
|
381
|
+
3. Tracked opinions (≥85% confidence)
|
|
382
|
+
4. Recent interaction notes (last 2 days)
|
|
383
|
+
5. Learning digest (this project + other recent)
|
|
384
|
+
6. Pattern synthesis recommendations
|
|
385
|
+
7. Signal trends (today/week/trend)
|
|
386
|
+
8. Failure patterns (last 5 low-rating contexts)
|
|
387
|
+
9. Active work summary (sessions + projects)
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### On-Demand Context
|
|
391
|
+
|
|
392
|
+
Everything else loads via the routing table in CLAUDE.md. The AI reads files only when the current task requires that context — no upfront loading of the full system.
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Security Architecture
|
|
397
|
+
|
|
398
|
+
### Fail-Open Design
|
|
399
|
+
|
|
400
|
+
`SecurityValidator.ts` runs on PreToolUse for Bash commands. It blocks known-dangerous patterns but never prevents legitimate work:
|
|
401
|
+
|
|
402
|
+
- **Blocked**: `rm -rf /`, `chmod 777`, known secret file paths, command injection patterns
|
|
403
|
+
- **Allowed**: Everything else passes through
|
|
404
|
+
- **On error**: The hook exits silently — a broken security hook never blocks the user
|
|
405
|
+
|
|
406
|
+
### What's Protected
|
|
407
|
+
|
|
408
|
+
- Dangerous shell commands (recursive deletes, permission changes)
|
|
409
|
+
- Known secret file paths (.env, credentials, key files)
|
|
410
|
+
- Command injection patterns in arguments
|
|
411
|
+
|
|
412
|
+
### What's NOT Protected
|
|
413
|
+
|
|
414
|
+
PAL does not implement:
|
|
415
|
+
- Network-level security (no firewall, no proxy)
|
|
416
|
+
- File encryption (memory is plaintext on disk)
|
|
417
|
+
- Access control (anyone with filesystem access can read memory)
|
|
418
|
+
|
|
419
|
+
Users are responsible for securing their own machine and API keys.
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## Cross-Platform Architecture
|
|
424
|
+
|
|
425
|
+
### Agent Abstraction
|
|
426
|
+
|
|
427
|
+
```
|
|
428
|
+
src/targets/
|
|
429
|
+
├── claude/ # Claude Code specific
|
|
430
|
+
│ ├── install.ts # Register hooks + skills in ~/.claude/settings.json
|
|
431
|
+
│ └── uninstall.ts
|
|
432
|
+
├── opencode/ # opencode specific
|
|
433
|
+
│ ├── install.ts # Register hooks + skills in opencode config
|
|
434
|
+
│ ├── uninstall.ts
|
|
435
|
+
│ └── plugin.ts # opencode plugin interface
|
|
436
|
+
└── lib.ts # Shared: JSON read/write, settings merge, TELOS scaffold
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Path Resolution
|
|
440
|
+
|
|
441
|
+
All paths resolve through `src/hooks/lib/paths.ts`:
|
|
442
|
+
|
|
443
|
+
| Path | Default | Override |
|
|
444
|
+
|------|---------|----------|
|
|
445
|
+
| PAL home | `~/.agents/PAL` | `PAL_HOME` |
|
|
446
|
+
| PAL package | Auto-detected from source | `PAL_PKG` |
|
|
447
|
+
| Claude config | `~/.claude` | `PAL_CLAUDE_DIR` |
|
|
448
|
+
| opencode config | `~/.config/opencode` | `PAL_OPENCODE_DIR` |
|
|
449
|
+
| Agents dir | `~/.agents` | `PAL_AGENTS_DIR` |
|
|
450
|
+
|
|
451
|
+
### Portability Contract
|
|
452
|
+
|
|
453
|
+
- Core logic (`src/hooks/lib/`, `src/tools/`) has zero agent-specific imports
|
|
454
|
+
- Agent-specific code lives only in `src/targets/`
|
|
455
|
+
- Skills reference no agent-specific APIs
|
|
456
|
+
- Memory format is plain JSON/JSONL/Markdown — readable by any tool
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## File Naming Conventions
|
|
461
|
+
|
|
462
|
+
| Type | Convention | Example |
|
|
463
|
+
|------|------------|---------|
|
|
464
|
+
| Skill directory | kebab-case | `extract-wisdom/`, `first-principles/` |
|
|
465
|
+
| SKILL.md | Uppercase | `SKILL.md` |
|
|
466
|
+
| Hook files | PascalCase | `LoadContext.ts`, `StopOrchestrator.ts` |
|
|
467
|
+
| Handler files | kebab-case | `session-name.ts`, `work-learning.ts` |
|
|
468
|
+
| Library files | kebab-case | `text-similarity.ts`, `signal-trends.ts` |
|
|
469
|
+
| Tool files | kebab-case | `relationship-reflect.ts`, `token-cost.ts` |
|
|
470
|
+
| Memory files | date-prefixed | `2026-03-24.md`, `2026-03-24_weekly.md` |
|
|
471
|
+
| Template files | UPPER_SNAKE | `ALGORITHM.md`, `CONTEXT_ROUTING.md` |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "portable-agent-layer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "PAL — Portable Agent Layer: persistent personal context for AI coding assistants",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -45,7 +45,6 @@
|
|
|
45
45
|
"install:all": "bun run src/cli/index.ts cli install",
|
|
46
46
|
"uninstall": "bun run src/cli/index.ts cli uninstall",
|
|
47
47
|
"tool:analyze": "bun run src/tools/analyze.ts",
|
|
48
|
-
"tool:opinion": "bun run src/tools/opinion.ts",
|
|
49
48
|
"tool:reflect": "bun run src/tools/relationship-reflect.ts",
|
|
50
49
|
"tool:export": "bun run src/tools/export.ts",
|
|
51
50
|
"tool:import": "bun run src/tools/import.ts",
|
|
@@ -22,7 +22,7 @@ const OBSERVATION_SCHEMA = {
|
|
|
22
22
|
type: "string",
|
|
23
23
|
enum: ["O", "W", "B"],
|
|
24
24
|
description:
|
|
25
|
-
"O=opinion/preference, W=factual observation, B=
|
|
25
|
+
"O=opinion/preference, W=factual observation, B=biographical (what the AI did this session)",
|
|
26
26
|
},
|
|
27
27
|
text: { type: "string" },
|
|
28
28
|
confidence: { type: "number" },
|
|
@@ -74,11 +74,11 @@ export async function captureRelationship(
|
|
|
74
74
|
logDebug("relationship", "Calling inference...");
|
|
75
75
|
const result = await inference({
|
|
76
76
|
system:
|
|
77
|
-
"You analyze
|
|
78
|
-
"Types: O=opinions/preferences (how
|
|
79
|
-
"B=
|
|
80
|
-
"W=world facts (
|
|
81
|
-
"Focus on: preferences, corrections, frustrations, positive reactions, communication style,
|
|
77
|
+
"You analyze messages from an AI coding session to extract relationship observations. " +
|
|
78
|
+
"Types: O=opinions/preferences (how the user likes to work, what they want), " +
|
|
79
|
+
"B=biographical (what the AI accomplished this session, written in first-person), " +
|
|
80
|
+
"W=world facts (user's situation, projects, tools they use). " +
|
|
81
|
+
"Focus on: preferences, corrections, frustrations, positive reactions, communication style, and session accomplishments. " +
|
|
82
82
|
"Return 0-3 observations. If nothing notable, return empty observations array. Be concise.",
|
|
83
83
|
user: `User messages from this session:\n${userMessages.map((m, i) => `${i + 1}. ${m}`).join("\n")}`,
|
|
84
84
|
maxTokens: 300,
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* This avoids the 1-5s inference latency that previously blocked every first prompt.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
import { spawn } from "node:child_process";
|
|
13
13
|
import { inference } from "../lib/inference";
|
|
14
14
|
import { logDebug, logError } from "../lib/log";
|
|
15
15
|
import {
|
|
@@ -41,25 +41,24 @@ export async function captureSessionName(
|
|
|
41
41
|
writeSessionName(sessionId, name);
|
|
42
42
|
logDebug("session-name", `Named from prompt: "${name}"`);
|
|
43
43
|
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// }
|
|
44
|
+
// Spawn detached background process to upgrade with Haiku inference
|
|
45
|
+
if (!process.env.ANTHROPIC_API_KEY) return;
|
|
46
|
+
try {
|
|
47
|
+
const promptB64 = Buffer.from(message.slice(0, 800)).toString("base64");
|
|
48
|
+
const child = spawn(
|
|
49
|
+
"bun",
|
|
50
|
+
[import.meta.filename, "--upgrade", sessionId, promptB64, name],
|
|
51
|
+
{
|
|
52
|
+
detached: true,
|
|
53
|
+
stdio: "ignore",
|
|
54
|
+
env: { ...process.env, CLAUDECODE: undefined },
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
child.unref();
|
|
58
|
+
logDebug("session-name", "Spawned background Haiku upgrade");
|
|
59
|
+
} catch {
|
|
60
|
+
// Non-critical — deterministic name is already stored
|
|
61
|
+
}
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
/**
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Notes live at memory/relationship/YYYY-MM/YYYY-MM-DD.md
|
|
6
6
|
* W = world (facts about user's situation)
|
|
7
7
|
* O = opinion (preference with confidence)
|
|
8
|
-
* B =
|
|
8
|
+
* B = biographical (what the AI did this session, first-person)
|
|
9
9
|
*
|
|
10
10
|
* Extraction is handled by the relationship handler via Haiku inference.
|
|
11
11
|
* This lib provides storage and reading utilities only.
|
|
@@ -80,7 +80,7 @@ export function appendNotes(notes: RelationshipNote[], sessionId?: string): void
|
|
|
80
80
|
if (sessionId) lines.push(`<!-- session:${sessionId} -->`);
|
|
81
81
|
|
|
82
82
|
for (const note of fresh) {
|
|
83
|
-
if (
|
|
83
|
+
if (note.type === "O" && note.confidence !== undefined) {
|
|
84
84
|
lines.push(`- ${note.type}(c=${note.confidence}): ${note.text}`);
|
|
85
85
|
} else {
|
|
86
86
|
lines.push(`- ${note.type}: ${note.text}`);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* RelationshipReflect — Periodic reflection on relationship patterns.
|
|
4
4
|
*
|
|
5
5
|
* Reads recent relationship notes and ratings to:
|
|
6
|
-
* - Promote recurring O
|
|
6
|
+
* - Promote recurring O notes into tracked opinions with confidence
|
|
7
7
|
* - Update confidence on existing opinions via supporting evidence
|
|
8
8
|
* - Generate a summary report
|
|
9
9
|
*
|
|
@@ -159,9 +159,9 @@ function promoteToOpinions(notes: ParsedNote[], dryRun: boolean): OpinionChange[
|
|
|
159
159
|
const opinions = readOpinions();
|
|
160
160
|
const lastReflect = getLastReflectDate();
|
|
161
161
|
|
|
162
|
-
// Only O
|
|
162
|
+
// Only O notes become opinions (B=biographical, about the AI, not user preferences)
|
|
163
163
|
const opinionNotes = notes.filter(
|
|
164
|
-
(n) =>
|
|
164
|
+
(n) => n.type === "O" && (!lastReflect || n.date > lastReflect)
|
|
165
165
|
);
|
|
166
166
|
|
|
167
167
|
// Group similar notes together
|
|
@@ -225,7 +225,7 @@ interface OpinionSummary {
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
function groupNoteOccurrences(notes: ParsedNote[]): OpinionSummary[] {
|
|
228
|
-
const opNotes = notes.filter((n) => n.type === "O"
|
|
228
|
+
const opNotes = notes.filter((n) => n.type === "O");
|
|
229
229
|
const groups = new Map<
|
|
230
230
|
string,
|
|
231
231
|
{ confidences: number[]; dates: string[]; text: string }
|
|
@@ -397,7 +397,7 @@ if (values.help) {
|
|
|
397
397
|
RelationshipReflect — Periodic reflection + opinion promotion
|
|
398
398
|
|
|
399
399
|
Reads recent relationship notes and ratings. Promotes recurring
|
|
400
|
-
observations (O
|
|
400
|
+
observations (O type) into tracked opinions with confidence scoring.
|
|
401
401
|
|
|
402
402
|
Usage:
|
|
403
403
|
bun run tool:reflect Reflect on last 7 days (default)
|