@tekmidian/pai 0.11.0 → 0.12.1

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.
Files changed (128) hide show
  1. package/README.md +84 -10
  2. package/dist/{auto-route-D54Kv7yI.mjs → auto-route-CLYcToZ5.mjs} +4 -4
  3. package/dist/{auto-route-D54Kv7yI.mjs.map → auto-route-CLYcToZ5.mjs.map} +1 -1
  4. package/dist/cli/index.mjs +20 -10275
  5. package/dist/cli/index.mjs.map +1 -1
  6. package/dist/cli/program.d.mts +11 -0
  7. package/dist/cli/program.d.mts.map +1 -0
  8. package/dist/cli/program.mjs +249 -0
  9. package/dist/cli/program.mjs.map +1 -0
  10. package/dist/{clusters-BwmdKB-V.mjs → clusters-BYPw7vfW.mjs} +2 -2
  11. package/dist/{clusters-BwmdKB-V.mjs.map → clusters-BYPw7vfW.mjs.map} +1 -1
  12. package/dist/{config-DqBY3aT0.mjs → config-BuhHWyOK.mjs} +1 -1
  13. package/dist/{config-DqBY3aT0.mjs.map → config-BuhHWyOK.mjs.map} +1 -1
  14. package/dist/daemon/index.mjs +16 -18
  15. package/dist/daemon/index.mjs.map +1 -1
  16. package/dist/{daemon-CSKj8Xm9.mjs → daemon-BldK8-57.mjs} +197 -43
  17. package/dist/daemon-BldK8-57.mjs.map +1 -0
  18. package/dist/daemon-mcp/index.mjs +2 -2
  19. package/dist/{db-CYmBWcjh.mjs → db-CmYbAVCD.mjs} +1 -1
  20. package/dist/{db-CYmBWcjh.mjs.map → db-CmYbAVCD.mjs.map} +1 -1
  21. package/dist/{detect-CdaA48EI.mjs → detect-KjycLtXM.mjs} +1 -1
  22. package/dist/{detect-CdaA48EI.mjs.map → detect-KjycLtXM.mjs.map} +1 -1
  23. package/dist/{detector-Q_lVXtj-.mjs → detector-ZiOhHszd.mjs} +2 -2
  24. package/dist/{detector-Q_lVXtj-.mjs.map → detector-ZiOhHszd.mjs.map} +1 -1
  25. package/dist/{embeddings-DGRAPAYb.mjs → embeddings-BJPOcbik.mjs} +1 -1
  26. package/dist/{embeddings-DGRAPAYb.mjs.map → embeddings-BJPOcbik.mjs.map} +1 -1
  27. package/dist/factory-Q88X1bAN.mjs +69 -0
  28. package/dist/factory-Q88X1bAN.mjs.map +1 -0
  29. package/dist/{helpers-crDEr6S2.mjs → helpers-IjZkXBhj.mjs} +1 -1
  30. package/dist/{helpers-crDEr6S2.mjs.map → helpers-IjZkXBhj.mjs.map} +1 -1
  31. package/dist/hooks/observe.mjs +21 -0
  32. package/dist/hooks/observe.mjs.map +2 -2
  33. package/dist/index.mjs +9 -10
  34. package/dist/{indexer-backend-DcYThufd.mjs → indexer-backend-Cm5RS7y0.mjs} +3 -3
  35. package/dist/{indexer-backend-DcYThufd.mjs.map → indexer-backend-Cm5RS7y0.mjs.map} +1 -1
  36. package/dist/{ipc-client-C3pjwy2m.mjs → ipc-client-CoyUHPod.mjs} +1 -1
  37. package/dist/{ipc-client-C3pjwy2m.mjs.map → ipc-client-CoyUHPod.mjs.map} +1 -1
  38. package/dist/{kg-entity-DVzTsy6G.mjs → kg-entity-LXblD7LZ.mjs} +1 -1
  39. package/dist/{kg-entity-DVzTsy6G.mjs.map → kg-entity-LXblD7LZ.mjs.map} +1 -1
  40. package/dist/{kg-extraction-iR1BKKWK.mjs → kg-extraction-C8DEUHTS.mjs} +17 -6
  41. package/dist/kg-extraction-C8DEUHTS.mjs.map +1 -0
  42. package/dist/{latent-ideas-dWVuI_dg.mjs → latent-ideas-RyC6eyqI.mjs} +4 -4
  43. package/dist/{latent-ideas-dWVuI_dg.mjs.map → latent-ideas-RyC6eyqI.mjs.map} +1 -1
  44. package/dist/main-resolver-uFxNiDy7.mjs +1339 -0
  45. package/dist/main-resolver-uFxNiDy7.mjs.map +1 -0
  46. package/dist/{migrate-fLD6rAdO.mjs → migrate-B02wDDgS.mjs} +2 -2
  47. package/dist/{migrate-fLD6rAdO.mjs.map → migrate-B02wDDgS.mjs.map} +1 -1
  48. package/dist/{neighborhood-DixmpfPT.mjs → neighborhood-CklGIB8r.mjs} +2 -2
  49. package/dist/{neighborhood-DixmpfPT.mjs.map → neighborhood-CklGIB8r.mjs.map} +1 -1
  50. package/dist/{note-context-BY7rfGdl.mjs → note-context-qvZlVXVO.mjs} +1 -1
  51. package/dist/{note-context-BY7rfGdl.mjs.map → note-context-qvZlVXVO.mjs.map} +1 -1
  52. package/dist/{pai-marker-CXQPX2P6.mjs → pai-marker-HVBwwBW-.mjs} +1 -1
  53. package/dist/{pai-marker-CXQPX2P6.mjs.map → pai-marker-HVBwwBW-.mjs.map} +1 -1
  54. package/dist/pick-7Kg9DX7S.mjs +8250 -0
  55. package/dist/pick-7Kg9DX7S.mjs.map +1 -0
  56. package/dist/{postgres-Cp25xZes.mjs → postgres-B451Hnkm.mjs} +2 -2
  57. package/dist/{postgres-Cp25xZes.mjs.map → postgres-B451Hnkm.mjs.map} +1 -1
  58. package/dist/{query-feedback-C0hKUHVz.mjs → query-feedback-fapbqRgh.mjs} +1 -1
  59. package/dist/{query-feedback-C0hKUHVz.mjs.map → query-feedback-fapbqRgh.mjs.map} +1 -1
  60. package/dist/{reranker-CMNZcfVx.mjs → reranker-C08R99zn.mjs} +1 -1
  61. package/dist/{reranker-CMNZcfVx.mjs.map → reranker-C08R99zn.mjs.map} +1 -1
  62. package/dist/{search-i2nlQ-JM.mjs → search-HcdKtMla.mjs} +3 -3
  63. package/dist/{search-i2nlQ-JM.mjs.map → search-HcdKtMla.mjs.map} +1 -1
  64. package/dist/{sqlite-B3JHfJc2.mjs → sqlite-DQpY1Esi.mjs} +3 -3
  65. package/dist/{sqlite-B3JHfJc2.mjs.map → sqlite-DQpY1Esi.mjs.map} +1 -1
  66. package/dist/{state-BHZAhLou.mjs → state-BIlxNRUn.mjs} +1 -1
  67. package/dist/{state-BHZAhLou.mjs.map → state-BIlxNRUn.mjs.map} +1 -1
  68. package/dist/{stop-words-BaMEGVeY.mjs → stop-words-BwplsQ3z.mjs} +1 -1
  69. package/dist/{stop-words-BaMEGVeY.mjs.map → stop-words-BwplsQ3z.mjs.map} +1 -1
  70. package/dist/{sync-CmBKOL3K.mjs → sync-uPR4g438.mjs} +205 -6
  71. package/dist/sync-uPR4g438.mjs.map +1 -0
  72. package/dist/{themes-DO8mUVwD.mjs → themes-Cg8oG9Ra.mjs} +3 -3
  73. package/dist/{themes-DO8mUVwD.mjs.map → themes-Cg8oG9Ra.mjs.map} +1 -1
  74. package/dist/{tools-C1JNgya7.mjs → tools-Op3C2Nm6.mjs} +26 -26
  75. package/dist/{tools-C1JNgya7.mjs.map → tools-Op3C2Nm6.mjs.map} +1 -1
  76. package/dist/{trace-TYCLMCkY.mjs → trace-CLK-NPkb.mjs} +1 -1
  77. package/dist/{trace-TYCLMCkY.mjs.map → trace-CLK-NPkb.mjs.map} +1 -1
  78. package/dist/{utils-BAxjW3j8.mjs → utils-CqqgB0dH.mjs} +1 -1
  79. package/dist/{utils-BAxjW3j8.mjs.map → utils-CqqgB0dH.mjs.map} +1 -1
  80. package/dist/{vault-indexer-vNnL3Azb.mjs → vault-indexer-Dn_BccVK.mjs} +2 -2
  81. package/dist/{vault-indexer-vNnL3Azb.mjs.map → vault-indexer-Dn_BccVK.mjs.map} +1 -1
  82. package/dist/{work-queue-worker-BxsBtz6j.mjs → work-queue-worker-DHOIVVQ7.mjs} +5 -5
  83. package/dist/{work-queue-worker-BxsBtz6j.mjs.map → work-queue-worker-DHOIVVQ7.mjs.map} +1 -1
  84. package/dist/{zettelkasten-B-94vghH.mjs → zettelkasten-NwBD1NsT.mjs} +4 -4
  85. package/dist/{zettelkasten-B-94vghH.mjs.map → zettelkasten-NwBD1NsT.mjs.map} +1 -1
  86. package/docs/commands/README.md +151 -0
  87. package/docs/commands/_examples/kg.md +13 -0
  88. package/docs/commands/_examples/memory.md +13 -0
  89. package/docs/commands/_examples/observation.md +13 -0
  90. package/docs/commands/_examples/projects.md +16 -0
  91. package/docs/commands/_examples/skill.md +13 -0
  92. package/docs/commands/_examples/zettel.md +13 -0
  93. package/docs/commands/backup.md +24 -0
  94. package/docs/commands/clear-names.md +27 -0
  95. package/docs/commands/daemon.md +78 -0
  96. package/docs/commands/db.md +74 -0
  97. package/docs/commands/end.md +24 -0
  98. package/docs/commands/help.md +30 -0
  99. package/docs/commands/kg.md +89 -0
  100. package/docs/commands/mcp.md +35 -0
  101. package/docs/commands/memory.md +125 -0
  102. package/docs/commands/notify.md +83 -0
  103. package/docs/commands/observation.md +80 -0
  104. package/docs/commands/obsidian.md +60 -0
  105. package/docs/commands/pause.md +35 -0
  106. package/docs/commands/project.md +345 -0
  107. package/docs/commands/projects.md +364 -0
  108. package/docs/commands/registry.md +68 -0
  109. package/docs/commands/restore.md +31 -0
  110. package/docs/commands/sessions.md +25 -0
  111. package/docs/commands/setup.md +20 -0
  112. package/docs/commands/shell-init.md +18 -0
  113. package/docs/commands/skill.md +54 -0
  114. package/docs/commands/topic.md +46 -0
  115. package/docs/commands/update.md +18 -0
  116. package/docs/commands/zettel.md +151 -0
  117. package/docs/mcp-skill-guide.md +292 -0
  118. package/package.json +4 -2
  119. package/scripts/build-docs.mjs +371 -0
  120. package/src/hooks/ts/post-tool-use/observe.ts +43 -0
  121. package/dist/daemon-CSKj8Xm9.mjs.map +0 -1
  122. package/dist/db-BtuN768f.mjs +0 -206
  123. package/dist/db-BtuN768f.mjs.map +0 -1
  124. package/dist/factory-BufouUQ1.mjs +0 -44
  125. package/dist/factory-BufouUQ1.mjs.map +0 -1
  126. package/dist/indexer-D7MvSQPY.mjs +0 -1
  127. package/dist/kg-extraction-iR1BKKWK.mjs.map +0 -1
  128. package/dist/sync-CmBKOL3K.mjs.map +0 -1
@@ -0,0 +1,151 @@
1
+ <!-- GENERATED by scripts/build-docs.mjs from the live Commander tree (src/cli/program.ts). Do not edit by hand. -->
2
+
3
+ # pai zettel
4
+
5
+ > Zettelkasten intelligence: explore, surprise, converse, themes, health, suggest
6
+
7
+ ## Synopsis
8
+
9
+ ```
10
+ pai zettel <subcommand> [options]
11
+ ```
12
+
13
+ ## Subcommands
14
+
15
+ | Command | Description |
16
+ |---------|-------------|
17
+ | [`pai zettel explore <note>`](#pai-zettel-explore-note) | Follow link chains from a starting note |
18
+ | [`pai zettel health`](#pai-zettel-health) | Vault structural health audit: dead links, orphans, connectivity |
19
+ | [`pai zettel surprise <note>`](#pai-zettel-surprise-note) | Find semantically similar but graph-distant notes (surprising connections) |
20
+ | [`pai zettel suggest <note>`](#pai-zettel-suggest-note) | Suggest new wikilink connections for a note |
21
+ | [`pai zettel converse <question>`](#pai-zettel-converse-question) | Ask the vault a question and get a synthesis prompt with relevant notes |
22
+ | [`pai zettel themes`](#pai-zettel-themes) | Detect emerging theme clusters in recently edited notes |
23
+
24
+ ### pai zettel explore <note>
25
+
26
+ Follow link chains from a starting note
27
+
28
+ **Arguments**
29
+
30
+ | Argument | Kind |
31
+ |----------|------|
32
+ | `<note>` | required |
33
+
34
+ **Options**
35
+
36
+ | Option | Description | Default |
37
+ |--------|-------------|---------|
38
+ | `--depth <n>` | Maximum traversal depth (1-10) | `3` |
39
+ | `--direction <d>` | Link direction: forward \| backward \| both | `both` |
40
+ | `--mode <m>` | Edge mode: sequential \| associative \| all | `all` |
41
+
42
+
43
+ ### pai zettel health
44
+
45
+ Vault structural health audit: dead links, orphans, connectivity
46
+
47
+ **Options**
48
+
49
+ | Option | Description | Default |
50
+ |--------|-------------|---------|
51
+ | `--scope <s>` | Scope: full \| recent \| project | `full` |
52
+ | `--project <path>` | Project path prefix (requires --scope project) | |
53
+ | `--days <n>` | Look-back window in days (requires --scope recent) | `30` |
54
+ | `--include <types>` | Comma-separated subset: dead_links,orphans,disconnected,low_connectivity | |
55
+
56
+
57
+ ### pai zettel surprise <note>
58
+
59
+ Find semantically similar but graph-distant notes (surprising connections)
60
+
61
+ **Arguments**
62
+
63
+ | Argument | Kind |
64
+ |----------|------|
65
+ | `<note>` | required |
66
+
67
+ **Options**
68
+
69
+ | Option | Description | Default |
70
+ |--------|-------------|---------|
71
+ | `--vault-project-id <n>` | Project ID for the vault in the federation DB | |
72
+ | `--limit <n>` | Maximum results | `10` |
73
+ | `--min-similarity <f>` | Minimum cosine similarity (0–1) | `0.3` |
74
+ | `--min-distance <n>` | Minimum graph distance | `3` |
75
+
76
+
77
+ ### pai zettel suggest <note>
78
+
79
+ Suggest new wikilink connections for a note
80
+
81
+ **Arguments**
82
+
83
+ | Argument | Kind |
84
+ |----------|------|
85
+ | `<note>` | required |
86
+
87
+ **Options**
88
+
89
+ | Option | Description | Default |
90
+ |--------|-------------|---------|
91
+ | `--vault-project-id <n>` | Project ID for the vault in the federation DB | |
92
+ | `--limit <n>` | Maximum suggestions | `5` |
93
+ | `--no-exclude-linked` | Include notes already linked from this one | |
94
+
95
+
96
+ ### pai zettel converse <question>
97
+
98
+ Ask the vault a question and get a synthesis prompt with relevant notes
99
+
100
+ **Arguments**
101
+
102
+ | Argument | Kind |
103
+ |----------|------|
104
+ | `<question>` | required |
105
+
106
+ **Options**
107
+
108
+ | Option | Description | Default |
109
+ |--------|-------------|---------|
110
+ | `--vault-project-id <n>` | Project ID for the vault in the federation DB | |
111
+ | `--depth <n>` | Graph expansion depth around matched notes | `2` |
112
+ | `--limit <n>` | Maximum relevant notes to include | `15` |
113
+
114
+
115
+ ### pai zettel themes
116
+
117
+ Detect emerging theme clusters in recently edited notes
118
+
119
+ **Options**
120
+
121
+ | Option | Description | Default |
122
+ |--------|-------------|---------|
123
+ | `--vault-project-id <n>` | Project ID for the vault in the federation DB | |
124
+ | `--days <n>` | Look-back window in days | `30` |
125
+ | `--min-size <n>` | Minimum notes per cluster | `3` |
126
+ | `--max-themes <n>` | Maximum themes to return | `10` |
127
+ | `--threshold <f>` | Similarity threshold for clustering (0–1) | `0.65` |
128
+
129
+
130
+ ## Examples
131
+
132
+ ```bash
133
+ # Explore the neighbourhood of a note
134
+ pai zettel explore "token factory"
135
+
136
+ # Surface an unexpected connection
137
+ pai zettel surprise
138
+
139
+ # Emergent themes across the vault
140
+ pai zettel themes
141
+
142
+ # Vault connectivity health (orphans, dead links)
143
+ pai zettel health
144
+ ```
145
+
146
+ ## See also
147
+
148
+ [`pai backup`](backup.md) · [`pai clear-names`](clear-names.md) · [`pai daemon`](daemon.md) · [`pai db`](db.md) · [`pai end`](end.md) · [`pai help`](help.md) · [`pai kg`](kg.md) · [`pai mcp`](mcp.md) · [`pai memory`](memory.md) · [`pai notify`](notify.md) · [`pai observation`](observation.md) · [`pai obsidian`](obsidian.md) · [`pai pause`](pause.md) · [`pai project`](project.md) · [`pai projects`](projects.md) · [`pai registry`](registry.md) · [`pai restore`](restore.md) · [`pai sessions`](sessions.md) · [`pai setup`](setup.md) · [`pai shell-init`](shell-init.md) · [`pai skill`](skill.md) · [`pai topic`](topic.md) · [`pai update`](update.md)
149
+
150
+ Run `pai help <area>` to read any of these in the terminal.
151
+
@@ -0,0 +1,292 @@
1
+ # MCP Skill Delivery Guide
2
+
3
+ How to structure MCP server instructions, prompts, and resources for optimal context efficiency.
4
+
5
+ ## The Three-Tier Architecture
6
+
7
+ MCP provides three mechanisms for delivering content to Claude. Each tier has a specific purpose. Mixing them up is the most common source of context bloat and skill drift.
8
+
9
+ ### Tier 1: instructions (Always Loaded)
10
+
11
+ The `instructions` field is loaded into EVERY message's context for the lifetime of the MCP connection. Keep it thin.
12
+
13
+ **What belongs here:**
14
+ - Brief description of the MCP server (1-2 sentences)
15
+ - Routing table: "When user says X, fetch prompt Y"
16
+ - Core behavioral rules that apply to every interaction
17
+ - Resource directory: "Fetch pai://name for full guide on X"
18
+
19
+ **What does NOT belong here:**
20
+ - Full skill descriptions and workflow steps
21
+ - Reference documentation (aesthetic guides, API docs)
22
+ - Examples and tutorials
23
+ - Anything that changes rarely and is only needed sometimes
24
+
25
+ **Target size:** Under 2KB. If it exceeds this, you are stuffing the wrong tier.
26
+
27
+ ### Tier 2: prompts (On-Demand Workflows)
28
+
29
+ Prompts are fetched by Claude when a specific skill is triggered via `prompts/get`. The user does not see these directly — they are instructions for Claude.
30
+
31
+ **What belongs here:**
32
+ - Complete skill workflow instructions
33
+ - USE WHEN trigger conditions
34
+ - Step-by-step workflow routing tables
35
+ - Platform-specific rules (LinkedIn vs X vs Bluesky)
36
+ - Command tables and data source lists
37
+
38
+ **Registration:**
39
+
40
+ ```typescript
41
+ server.prompt(
42
+ "review",
43
+ "Weekly/daily/monthly review of work accomplished",
44
+ () => ({
45
+ messages: [{
46
+ role: "user" as const,
47
+ content: {
48
+ type: "text" as const,
49
+ text: reviewSkillContent,
50
+ },
51
+ }],
52
+ })
53
+ );
54
+ ```
55
+
56
+ **Naming convention:** lowercase-kebab. Examples: `review`, `share`, `vault-context`.
57
+
58
+ ### Tier 3: resources (Reference Documentation)
59
+
60
+ Resources are reference documents that Claude reads when it needs detailed information. Unlike prompts, they are not workflow instructions — they are reference material fetched via `resources/read`.
61
+
62
+ **What belongs here:**
63
+ - Style guides (aesthetic, voice, prosody)
64
+ - Constitutional documents (philosophy, architecture)
65
+ - API reference documentation
66
+ - Configuration schemas
67
+ - Technical specifications
68
+
69
+ **Registration:**
70
+
71
+ ```typescript
72
+ server.resource(
73
+ "aesthetic",
74
+ "pai://aesthetic",
75
+ { mimeType: "text/markdown" },
76
+ async () => ({
77
+ contents: [{
78
+ uri: "pai://aesthetic",
79
+ mimeType: "text/markdown",
80
+ text: aestheticGuideContent,
81
+ }],
82
+ })
83
+ );
84
+ ```
85
+
86
+ **URI convention:** Use a consistent scheme like `pai://name` or `mcp://server-name/resource`.
87
+
88
+ ---
89
+
90
+ ## Decision Matrix
91
+
92
+ | Content Type | Tier | Reasoning |
93
+ |--------------|------|-----------|
94
+ | "When user says X, fetch prompt Y" | instructions | Routes to the right skill |
95
+ | Full skill workflow (20+ lines) | prompt | Only needed when skill triggers |
96
+ | Aesthetic style guide | resource | Reference, not workflow |
97
+ | Core operating rules (git, security, format) | instructions | Applies to every interaction |
98
+ | Platform-specific post formatting | prompt | Part of share skill workflow |
99
+ | Voice prosody guide | resource | Reference, rarely needed |
100
+ | Session lifecycle commands | instructions | Always applicable |
101
+ | API endpoint documentation | resource | Reference, read on demand |
102
+
103
+ ---
104
+
105
+ ## Anti-Patterns
106
+
107
+ ### Anti-Pattern 1: Stuffing everything into instructions
108
+
109
+ ```typescript
110
+ // WRONG — 20 full skill descriptions in instructions
111
+ const PAI_INSTRUCTIONS = `
112
+ ## Review Skill
113
+ USE WHEN user says 'review'...
114
+ [200 lines of workflow details]
115
+
116
+ ## Journal Skill
117
+ USE WHEN user says 'journal'...
118
+ [150 lines of workflow details]
119
+
120
+ [18 more skills...]
121
+ `;
122
+ ```
123
+
124
+ **Problem:** Consumes 8-15KB of context on every message. Most content is irrelevant 95% of the time.
125
+
126
+ **Fix:** One-line routing table in instructions. Full content in prompts.
127
+
128
+ ### Anti-Pattern 2: File path references in instructions
129
+
130
+ ```
131
+ // WRONG — hardcoded personal paths
132
+ "Read ~/.claude/Skills/Share/SKILL.md for social media instructions"
133
+ ```
134
+
135
+ **Problem:** Paths are personal, not portable. The file may not exist. Reading a file wastes a tool call.
136
+
137
+ **Fix:** Embed content directly in prompts/resources. No file path reads needed.
138
+
139
+ ### Anti-Pattern 3: Personal data in instructions
140
+
141
+ ```
142
+ // WRONG — personal identifiers in shipped code
143
+ "You are assisting John Smith at Acme Corp. His timezone is PST..."
144
+ ```
145
+
146
+ **Problem:** Instructions ship with the MCP server. If the server is open-source, personal data leaks.
147
+
148
+ **Fix:** Use placeholders (`${USER_NAME}`) or omit personal data from instructions entirely.
149
+
150
+ ### Anti-Pattern 4: Duplicating content across tiers
151
+
152
+ ```
153
+ // WRONG — routing table AND full skill in instructions
154
+ instructions: `
155
+ When user says 'share', use Share skill.
156
+
157
+ Share skill rules:
158
+ - LinkedIn: 1000-2000 chars, first-person builder voice...
159
+ [100 more lines]
160
+ `
161
+ ```
162
+
163
+ **Fix:** Routing table in instructions, full skill in prompt. Never both.
164
+
165
+ ---
166
+
167
+ ## How to Add a New Skill
168
+
169
+ 1. Write the full skill content (workflow steps, trigger conditions, examples)
170
+ 2. Add a one-line entry to the routing table in instructions
171
+ 3. Register as a prompt with `server.prompt()`
172
+ 4. Test that the routing table correctly identifies trigger phrases
173
+
174
+ ```typescript
175
+ // Step 2: Add to routing table in instructions
176
+ `| When user says 'deploy' or 'push to production' | Fetch prompt: deploy |`
177
+
178
+ // Step 3: Register the prompt
179
+ server.prompt(
180
+ "deploy",
181
+ "Deploy to staging or production environments",
182
+ () => ({
183
+ messages: [{
184
+ role: "user" as const,
185
+ content: {
186
+ type: "text" as const,
187
+ text: deploySkillContent, // Full workflow here
188
+ },
189
+ }],
190
+ })
191
+ );
192
+ ```
193
+
194
+ ---
195
+
196
+ ## How to Add a New Resource
197
+
198
+ 1. Write the reference content (guide, spec, configuration schema)
199
+ 2. Add an entry to the resource directory in instructions
200
+ 3. Register with `server.resource()`
201
+
202
+ ```typescript
203
+ // Step 2: Add to resource directory in instructions
204
+ `| API reference | pai://api-reference |`
205
+
206
+ // Step 3: Register the resource
207
+ server.resource(
208
+ "api-reference",
209
+ "pai://api-reference",
210
+ { mimeType: "text/markdown" },
211
+ async () => ({
212
+ contents: [{
213
+ uri: "pai://api-reference",
214
+ mimeType: "text/markdown",
215
+ text: apiReferenceContent,
216
+ }],
217
+ })
218
+ );
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Testing Checklist
224
+
225
+ Before shipping a refactored MCP server:
226
+
227
+ - [ ] `instructions` field is under 2KB
228
+ - [ ] `instructions` contains ONLY routing table + core rules
229
+ - [ ] Each skill has a registered prompt (`server.prompt`)
230
+ - [ ] Each reference doc has a registered resource (`server.resource`)
231
+ - [ ] No full skill descriptions in `instructions`
232
+ - [ ] No hardcoded personal paths in `instructions`
233
+ - [ ] No personal data (names, emails, timezones) in `instructions`
234
+ - [ ] Prompts are fetchable: `prompts/list` returns all expected prompts
235
+ - [ ] Resources are readable: `resources/list` returns all expected resources
236
+ - [ ] All tools are unchanged (only instructions/prompts/resources changed)
237
+ - [ ] Build succeeds
238
+
239
+ ---
240
+
241
+ ## Context Size Impact Example
242
+
243
+ PAI MCP before and after applying this guide:
244
+
245
+ | Metric | Before | After |
246
+ |--------|--------|-------|
247
+ | `instructions` size | ~8KB (20 skills) | ~1.5KB (routing table) |
248
+ | Context loaded per message | ~8KB | ~1.5KB |
249
+ | Full skill content when triggered | ~8KB (all skills) | ~0.5KB (one skill) |
250
+ | Context savings (typical session) | — | ~6.5KB per message |
251
+
252
+ At 200 messages per session, that is 1.3MB of context saved — equivalent to several extra tool calls worth of working memory.
253
+
254
+ ---
255
+
256
+ ## Using `@modelcontextprotocol/sdk`
257
+
258
+ The high-level `McpServer` class handles protocol details. Use it unless you need low-level control.
259
+
260
+ ```typescript
261
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
262
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
263
+
264
+ const server = new McpServer(
265
+ { name: "my-server", version: "1.0.0" },
266
+ { instructions: thinRoutingTable }
267
+ );
268
+
269
+ // Register a prompt
270
+ server.prompt("skill-name", "One-line description", () => ({
271
+ messages: [{ role: "user", content: { type: "text", text: fullContent } }],
272
+ }));
273
+
274
+ // Register a resource
275
+ server.resource("doc-name", "scheme://uri", { mimeType: "text/markdown" }, async () => ({
276
+ contents: [{ uri: "scheme://uri", mimeType: "text/markdown", text: docContent }],
277
+ }));
278
+
279
+ // Register a tool (unchanged by refactor)
280
+ server.tool("tool-name", "Tool description", { param: z.string() }, async (args) => ({
281
+ content: [{ type: "text", text: "result" }],
282
+ }));
283
+
284
+ const transport = new StdioServerTransport();
285
+ await server.connect(transport);
286
+ ```
287
+
288
+ ---
289
+
290
+ ## Summary
291
+
292
+ The three-tier rule in one sentence: put routing metadata in instructions, put workflow execution steps in prompts, and put reference documentation in resources. Everything else is implementation detail.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekmidian/pai",
3
- "version": "0.11.0",
3
+ "version": "0.12.1",
4
4
  "description": "PAI Knowledge OS — Personal AI Infrastructure with federated memory and project management",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
@@ -23,7 +23,9 @@
23
23
  "tab-color-command.sh",
24
24
  "scripts/build-hooks.mjs",
25
25
  "scripts/build-skill-stubs.mjs",
26
+ "scripts/build-docs.mjs",
26
27
  "src/hooks",
28
+ "docs",
27
29
  "README.md",
28
30
  "LICENSE",
29
31
  "ARCHITECTURE.md",
@@ -54,7 +56,7 @@
54
56
  "pai-daemon-mcp": "dist/daemon-mcp/index.mjs"
55
57
  },
56
58
  "scripts": {
57
- "build": "tsdown && node scripts/build-hooks.mjs --sync && node scripts/build-skill-stubs.mjs --sync",
59
+ "build": "tsdown && node scripts/build-hooks.mjs --sync && node scripts/build-skill-stubs.mjs --sync && node scripts/build-docs.mjs",
58
60
  "dev": "tsdown --watch",
59
61
  "test": "vitest",
60
62
  "lint": "tsc --noEmit",