portable-agent-layer 0.41.1 → 0.42.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/.husky/install.mjs +8 -0
- package/README.md +2 -1
- package/assets/skills/analyze-youtube/SKILL.md +1 -1
- package/assets/skills/entities/SKILL.md +95 -0
- package/assets/templates/PAL/README.md +1 -1
- package/package.json +10 -12
- package/src/cli/index.ts +8 -0
- package/src/cli/knowledge.ts +620 -0
- package/src/cli/migrate.ts +188 -3
- package/src/hooks/lib/export.ts +1 -1
- package/src/hooks/lib/paths.ts +2 -1
- package/src/targets/lib.ts +23 -36
- package/src/tools/knowledge/graph.ts +395 -0
- package/src/tools/knowledge/ingest.ts +409 -0
- package/src/tools/knowledge/lib.ts +493 -0
- package/assets/skills/extract-entities/SKILL.md +0 -62
- package/assets/skills/extract-entities/tools/entity-save.ts +0 -110
- package/src/hooks/lib/entities.ts +0 -304
- package/src/tools/export.ts +0 -40
- package/src/tools/import.ts +0 -111
package/README.md
CHANGED
|
@@ -84,6 +84,7 @@ pal cli status # check your setup
|
|
|
84
84
|
| `pal cli doctor` | Check prerequisites and system health |
|
|
85
85
|
| `pal cli migrate` | Run pending data migrations (non-destructive) |
|
|
86
86
|
| `pal cli usage` | Summarize token usage and estimated cost |
|
|
87
|
+
| `pal cli knowledge` | Query & manage the knowledge store (search, graph, stats, hubs, find, show, add, ls, ingest) |
|
|
87
88
|
|
|
88
89
|
### Target flags
|
|
89
90
|
|
|
@@ -159,7 +160,7 @@ PAL ships with built-in skills that extend your agent's capabilities:
|
|
|
159
160
|
| `council` | Multi-perspective parallel debate on decisions |
|
|
160
161
|
| `create-pdf` | Render structured content into a PDF |
|
|
161
162
|
| `create-skill` | Scaffold a new skill from a description |
|
|
162
|
-
| `
|
|
163
|
+
| `entities` | Detect, save, and query people & companies in the personal knowledge graph |
|
|
163
164
|
| `extract-wisdom` | Extract structured insights from content |
|
|
164
165
|
| `first-principles` | Break down problems to fundamentals |
|
|
165
166
|
| `fyzz-chat-api` | Query Fyzz Chat conversations via API |
|
|
@@ -23,7 +23,7 @@ Follow the user's request. Common tasks:
|
|
|
23
23
|
|
|
24
24
|
- **Summarize** the video content
|
|
25
25
|
- **Answer a specific question** about what's shown or discussed
|
|
26
|
-
- **Extract entities** (defer to /
|
|
26
|
+
- **Extract entities** (defer to /entities if installed)
|
|
27
27
|
- **Extract wisdom** (defer to /extract-wisdom if installed)
|
|
28
28
|
- **Compare** with other content
|
|
29
29
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: entities
|
|
3
|
+
description: Maintain the personal knowledge graph of people and companies. Detect named entities in any content (article, video, paste, conversation), upsert them to ~/.pal/memory/knowledge/, and surface what's already known. Use proactively whenever named entities appear — don't wait to be asked.
|
|
4
|
+
argument-hint: <content, URL, or pasted text>
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Detect, persist, and query people and companies referenced in $ARGUMENTS.
|
|
8
|
+
|
|
9
|
+
The default workflow is **extract → save → show summary**, in that order. Saving is not optional: persistence is the point of the skill. Skip the save step only if the user explicitly said "don't save", "just look", or similar.
|
|
10
|
+
|
|
11
|
+
## 1. Extract
|
|
12
|
+
|
|
13
|
+
Read/fetch the content and extract ALL people and companies mentioned.
|
|
14
|
+
|
|
15
|
+
### People
|
|
16
|
+
|
|
17
|
+
For each person, extract:
|
|
18
|
+
- **name**: Full name
|
|
19
|
+
- **role**: author | subject | mentioned | quoted | expert | interviewer | interviewee
|
|
20
|
+
- **title**: Job title (null if unknown)
|
|
21
|
+
- **company**: Company affiliation (null if unknown)
|
|
22
|
+
- **social**: twitter (@handle), linkedin (URL), email, website — null if unknown
|
|
23
|
+
- **context**: Why this person is mentioned and their relevance
|
|
24
|
+
- **importance**: primary (central to content) | secondary (supporting) | minor (brief mention)
|
|
25
|
+
|
|
26
|
+
### Companies
|
|
27
|
+
|
|
28
|
+
For each company/organization, extract:
|
|
29
|
+
- **name**: Official name
|
|
30
|
+
- **domain**: Primary website domain (e.g. "anthropic.com", null if unknown)
|
|
31
|
+
- **industry**: Classification (AI, security, fintech, healthcare, etc.)
|
|
32
|
+
- **context**: How and why mentioned
|
|
33
|
+
- **mentioned_as**: subject | source | example | competitor | partner | acquisition | product | other
|
|
34
|
+
- **sentiment**: positive | neutral | negative | mixed
|
|
35
|
+
|
|
36
|
+
### Extraction guidelines
|
|
37
|
+
|
|
38
|
+
- Accuracy over quantity — use null for unknown fields, never guess
|
|
39
|
+
- Include authors, subjects, quoted individuals, and anyone significantly mentioned
|
|
40
|
+
- For research papers: all authors get "author" role
|
|
41
|
+
- For interviews: distinguish interviewer vs interviewee
|
|
42
|
+
- Universities and research institutions count as companies
|
|
43
|
+
- Extract social handles from bios, signatures, or text body
|
|
44
|
+
- Context fields should explain relevance, not just repeat the mention
|
|
45
|
+
|
|
46
|
+
### Output shape
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"people": [...],
|
|
51
|
+
"companies": [...]
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 2. Save (default)
|
|
56
|
+
|
|
57
|
+
Immediately persist the extracted JSON. Do not ask first — saving is the default:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
echo '<the JSON output>' | pal cli knowledge ingest --source "<URL or content origin>"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The CLI writes one markdown file per entity under `~/.pal/memory/knowledge/{People,Companies}/<slug>.md`, preserving every extracted field (role, title, social, context, importance for people; domain, industry, sentiment, mentioned_as for companies) as frontmatter. When a person record includes a `company`, a `part-of` typed edge is auto-created from the person to the company (the company is stub-created if it doesn't exist yet). Each ingestion appends a per-source log section to the entity's body so the same source can be re-ingested safely (idempotent on `--source`).
|
|
64
|
+
|
|
65
|
+
The CLI prints a JSON summary of `{created, updated, slugs}` counts per domain.
|
|
66
|
+
|
|
67
|
+
**Opt-out:** if the user explicitly said not to save (e.g. "who's mentioned in this email — don't store anything"), skip step 2 entirely and just show the extracted JSON.
|
|
68
|
+
|
|
69
|
+
## 3. Query (read-back)
|
|
70
|
+
|
|
71
|
+
Before scraping a known source, or after saving, surface what's already on file:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pal cli knowledge search "<name>" # substring across title, tags, body
|
|
75
|
+
pal cli knowledge show <slug> # full entity (frontmatter + body)
|
|
76
|
+
pal cli knowledge graph <slug> # related entities (BFS, default 2 hops)
|
|
77
|
+
pal cli knowledge ls People # list a domain
|
|
78
|
+
pal cli knowledge stats # counts, hubs, isolated nodes
|
|
79
|
+
pal cli knowledge find <tag> # entities tagged with <tag> (topic: prefix transparent)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Use `search` before extracting to detect duplicates; use `show` to confirm a save landed correctly; use `graph` to surface relationships the user may have forgotten.
|
|
83
|
+
|
|
84
|
+
## Tag conventions (important)
|
|
85
|
+
|
|
86
|
+
Tags do two different jobs in the store, and PAL keeps them separated so the graph stays meaningful:
|
|
87
|
+
|
|
88
|
+
| Tag form | Purpose | Example | Generates graph edges? |
|
|
89
|
+
|---|---|---|---|
|
|
90
|
+
| `topic:<token>` | **Facet** — for filtering / `find` | `topic:ai`, `topic:consulting` | **No** — two entities sharing `topic:ai` do NOT get linked |
|
|
91
|
+
| Unprefixed | **Structural** — for navigation | `acme-labs`, `customer` | Yes — co-occurrence creates tag edges |
|
|
92
|
+
|
|
93
|
+
**Industry inheritance.** When ingest sees a company `industry`, it splits the string on whitespace and `/` and writes `topic:<token>` tags for each piece. When a person is linked to a company, the person inherits **only** the company's `topic:*` tags — never structural ones. This keeps `find ai` useful (it surfaces every AI-industry company + their employees) without creating phantom graph edges between unrelated entities that merely share an industry word.
|
|
94
|
+
|
|
95
|
+
Users can query with or without the prefix — `find ai` and `find topic:ai` are equivalent.
|
|
@@ -82,7 +82,7 @@ Persistent storage across sessions:
|
|
|
82
82
|
- **state/** — Session registry, counts cache, debug logs
|
|
83
83
|
|
|
84
84
|
### Tools (`src/tools/`)
|
|
85
|
-
CLI utilities: `tool:opinion` (manage opinions), `tool:reflect` (relationship reflection), `tool:analyze` (learning analysis), `pal cli usage` (token usage tracking), `
|
|
85
|
+
CLI utilities: `tool:opinion` (manage opinions), `tool:reflect` (relationship reflection), `tool:analyze` (learning analysis), `pal cli usage` (token usage tracking), `pal cli export` / `pal cli import` (state portability).
|
|
86
86
|
|
|
87
87
|
### TELOS (`telos/`)
|
|
88
88
|
Personal context system — mission, goals, projects, beliefs, challenges, strategies, ideas, learnings, mental models, narratives. Managed via the telos skill.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "portable-agent-layer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.42.0",
|
|
4
4
|
"description": "PAL — Portable Agent Layer: persistent personal context for AI coding assistants",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"src/",
|
|
11
11
|
"assets/",
|
|
12
|
+
".husky/install.mjs",
|
|
12
13
|
"README.md",
|
|
13
14
|
"LICENSE"
|
|
14
15
|
],
|
|
@@ -42,8 +43,7 @@
|
|
|
42
43
|
"check-write": "biome check --write",
|
|
43
44
|
"knip": "knip-bun",
|
|
44
45
|
"klint": "klint",
|
|
45
|
-
"jscpd": "jscpd
|
|
46
|
-
"jscpd:report": "jscpd src --noTips",
|
|
46
|
+
"jscpd": "jscpd --noTips",
|
|
47
47
|
"lint-staged": "lint-staged",
|
|
48
48
|
"prepare": "bun .husky/install.mjs",
|
|
49
49
|
"install:all": "bun run src/cli/index.ts cli install",
|
|
@@ -52,9 +52,7 @@
|
|
|
52
52
|
"tool:thread": "bun run src/tools/agent/thread.ts",
|
|
53
53
|
"tool:analyze": "bun run src/tools/agent/analyze.ts",
|
|
54
54
|
"tool:wisdom-frame": "bun run src/tools/agent/wisdom-frame.ts",
|
|
55
|
-
"tool:reflect": "bun run src/tools/relationship-reflect.ts"
|
|
56
|
-
"tool:export": "bun run src/tools/export.ts",
|
|
57
|
-
"tool:import": "bun run src/tools/import.ts"
|
|
55
|
+
"tool:reflect": "bun run src/tools/relationship-reflect.ts"
|
|
58
56
|
},
|
|
59
57
|
"lint-staged": {
|
|
60
58
|
"*.ts": [
|
|
@@ -62,9 +60,9 @@
|
|
|
62
60
|
]
|
|
63
61
|
},
|
|
64
62
|
"devDependencies": {
|
|
65
|
-
"@biomejs/biome": "2.4.
|
|
66
|
-
"@commitlint/cli": "
|
|
67
|
-
"@commitlint/config-conventional": "
|
|
63
|
+
"@biomejs/biome": "2.4.15",
|
|
64
|
+
"@commitlint/cli": "21.0.1",
|
|
65
|
+
"@commitlint/config-conventional": "21.0.1",
|
|
68
66
|
"@opencode-ai/plugin": "latest",
|
|
69
67
|
"@semantic-release/changelog": "^6.0.3",
|
|
70
68
|
"@semantic-release/git": "^10.0.1",
|
|
@@ -75,15 +73,15 @@
|
|
|
75
73
|
"husky": "^9.1.7",
|
|
76
74
|
"jscpd": "^4.2.3",
|
|
77
75
|
"knip": "^6.14.1",
|
|
78
|
-
"lint-staged": "
|
|
76
|
+
"lint-staged": "17.0.5",
|
|
79
77
|
"semantic-release": "^25.0.3",
|
|
80
78
|
"typescript": "^5.9.3"
|
|
81
79
|
},
|
|
82
80
|
"dependencies": {
|
|
83
81
|
"@clack/prompts": "^1.4.0",
|
|
84
|
-
"@konvert7/klint": "
|
|
82
|
+
"@konvert7/klint": "0.4.0",
|
|
85
83
|
"adm-zip": "^0.5.17",
|
|
86
|
-
"marked": "
|
|
84
|
+
"marked": "18.0.4",
|
|
87
85
|
"playwright": "^1.60.0"
|
|
88
86
|
}
|
|
89
87
|
}
|
package/src/cli/index.ts
CHANGED
|
@@ -186,6 +186,12 @@ async function runCli(command: string | undefined, args: string[]) {
|
|
|
186
186
|
usage();
|
|
187
187
|
break;
|
|
188
188
|
}
|
|
189
|
+
case "knowledge": {
|
|
190
|
+
const { runKnowledge } = await import("./knowledge");
|
|
191
|
+
const code = await runKnowledge(args);
|
|
192
|
+
if (code !== 0) process.exit(code);
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
189
195
|
case "--help":
|
|
190
196
|
case "-h":
|
|
191
197
|
case "help":
|
|
@@ -226,6 +232,8 @@ function showHelp() {
|
|
|
226
232
|
pal cli doctor [--probe-inference] Check prerequisites and health (--probe fires real inference per route)
|
|
227
233
|
pal cli migrate [--list] [--dry-run] Run pending data migrations
|
|
228
234
|
pal cli usage Summarize token usage and cost
|
|
235
|
+
pal cli knowledge <sub> [args] Query & manage the knowledge store
|
|
236
|
+
(search · graph · stats · hubs · find · show · add · ls)
|
|
229
237
|
|
|
230
238
|
Environment:
|
|
231
239
|
PAL_HOME Override user state directory (default: ~/.pal or repo root)
|