@zosmaai/pi-llm-wiki 0.6.4 → 0.6.6

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.
@@ -0,0 +1,46 @@
1
+ # Auto-Bootstrap Plan
2
+
3
+ ## Changes (3 files)
4
+
5
+ ### 1. `extensions/llm-wiki/index.ts`
6
+
7
+ **session_start hook** — Show correct status based on vault existence:
8
+ ```typescript
9
+ pi.on("session_start", async (_event, ctx) => {
10
+ const paths = resolveVaultPaths(process.cwd());
11
+ if (!existsSync(join(paths.dotWiki, "config.json"))) {
12
+ ctx.ui.setStatus("llm-wiki", "šŸ“ No wiki — call wiki_bootstrap to enable");
13
+ return;
14
+ }
15
+ ctx.ui.setStatus("llm-wiki", "🧠 LLM Wiki (12 tools, auto-recall active)");
16
+ });
17
+ ```
18
+
19
+ **before_agent_start hook** — When no wiki exists on first turn, inject a system prompt hint so the LLM knows to suggest bootstrapping:
20
+ ```typescript
21
+ pi.on("before_agent_start", async (event, _ctx) => {
22
+ const paths = resolveVaultPaths(process.cwd());
23
+ if (!existsSync(join(paths.dotWiki, "config.json"))) {
24
+ return {
25
+ systemPrompt: `${event.systemPrompt}\n\nšŸ“ No LLM Wiki found in this directory. On your first response, use ask_user to offer the user creating one via wiki_bootstrap. After suggesting once, do not repeat.`
26
+ };
27
+ }
28
+ // ... existing recall logic unchanged
29
+ });
30
+ ```
31
+
32
+ ### 2. `extensions/llm-wiki/lib/recall.ts`
33
+
34
+ **wiki_recall tool** — Improve error message when no vault exists to hint at bootstrap:
35
+ ```typescript
36
+ // Current: "No wiki vault found at this location. Initialize one with wiki_bootstrap first."
37
+ // Keep as-is but add isError flag for model to react
38
+ ```
39
+
40
+ ### 3. `skills/llm-wiki/SKILL.md`
41
+
42
+ Add a section about what to do when no wiki exists — tell the model to proactively suggest bootstrapping using `ask_user`.
43
+
44
+ ## Not in scope (separate issue)
45
+
46
+ - Migration script shipping — bcdiaconu's feedback from #22, needs its own focused PR
@@ -34,6 +34,9 @@ import { resolveVaultPaths } from "./lib/utils.js";
34
34
  * - wiki_recall tool available for explicit deep searches
35
35
  */
36
36
 
37
+ // Track whether we already suggested bootstrapping this session
38
+ let bootstrapSuggested = false;
39
+
37
40
  export default function (pi: ExtensionAPI) {
38
41
  registerWikiBootstrap(pi);
39
42
  registerWikiCaptureSource(pi);
@@ -51,6 +54,12 @@ export default function (pi: ExtensionAPI) {
51
54
  installGuardrails(pi);
52
55
 
53
56
  pi.on("session_start", async (_event, ctx) => {
57
+ bootstrapSuggested = false;
58
+ const paths = resolveVaultPaths(process.cwd());
59
+ if (!existsSync(join(paths.dotWiki, "config.json"))) {
60
+ ctx.ui.setStatus("llm-wiki", "šŸ“ No wiki — call wiki_bootstrap to enable");
61
+ return;
62
+ }
54
63
  ctx.ui.setStatus("llm-wiki", "🧠 LLM Wiki (12 tools, auto-recall active)");
55
64
  });
56
65
 
@@ -60,7 +69,14 @@ export default function (pi: ExtensionAPI) {
60
69
  pi.on("before_agent_start", async (event, _ctx) => {
61
70
  const paths = resolveVaultPaths(process.cwd());
62
71
  if (!existsSync(join(paths.dotWiki, "config.json"))) {
63
- return; // No wiki vault — nothing to recall
72
+ // No wiki — suggest bootstrap on first turn only
73
+ if (!bootstrapSuggested) {
74
+ bootstrapSuggested = true;
75
+ return {
76
+ systemPrompt: `${event.systemPrompt}\n\nšŸ“ No LLM Wiki found in this directory. On your first response, use ask_user to offer the user creating one via wiki_bootstrap. After suggesting once, do not repeat.`,
77
+ };
78
+ }
79
+ return;
64
80
  }
65
81
 
66
82
  const prompt = event.prompt || "";
@@ -102,6 +102,7 @@ export function registerWikiBootstrap(pi: ExtensionAPI): void {
102
102
  "- **concept** — ideas, patterns, frameworks",
103
103
  "- **synthesis** — cross-source theses and tensions",
104
104
  "- **analysis** — durable filed answers from queries",
105
+ "- **requirement** — atomic requirements with status, priority, and traceability",
105
106
  "",
106
107
  "## Linking Style",
107
108
  "",
@@ -368,7 +369,9 @@ export function registerWikiEnsurePage(pi: ExtensionAPI): void {
368
369
  "Search existing pages first with wiki_search.",
369
370
  ],
370
371
  parameters: Type.Object({
371
- type: Type.String({ description: "Page type: entity | concept | synthesis | analysis" }),
372
+ type: Type.String({
373
+ description: "Page type: entity | concept | synthesis | analysis | requirement",
374
+ }),
372
375
  title: Type.String({ description: "Page title" }),
373
376
  content: Type.Optional(
374
377
  Type.String({ description: "Optional initial content (otherwise uses template)" }),
@@ -398,6 +401,7 @@ export function registerWikiEnsurePage(pi: ExtensionAPI): void {
398
401
  concept: "concepts",
399
402
  synthesis: "syntheses",
400
403
  analysis: "analyses",
404
+ requirement: "requirements",
401
405
  };
402
406
  const folder = folderMap[type] || "concepts";
403
407
  const pagePath = join(paths.wiki, folder, `${slug}.md`);
@@ -466,6 +470,43 @@ function buildPageTemplate(
466
470
  "Durable answer from a query.\n\n## Question\n\n[Original question]",
467
471
  );
468
472
  }
473
+ if (type === "requirement") {
474
+ return [
475
+ "---",
476
+ "type: requirement",
477
+ `created: ${date}`,
478
+ `updated: ${date}`,
479
+ "status: draft",
480
+ "priority: p2",
481
+ "source_id: ",
482
+ "depends_on: []",
483
+ "---",
484
+ "",
485
+ `# ${title}`,
486
+ "",
487
+ "## Description",
488
+ "",
489
+ "[Clear description of what this requirement entails]",
490
+ "",
491
+ "## Acceptance Criteria",
492
+ "",
493
+ "- [ ] [Criterion 1]",
494
+ "- [ ] [Criterion 2]",
495
+ "",
496
+ "## Dependencies",
497
+ "",
498
+ "_Pages this requirement depends on._",
499
+ "",
500
+ "## Implementation Notes",
501
+ "",
502
+ "[Optional notes]",
503
+ "",
504
+ "## Sources",
505
+ "",
506
+ "- [[sources/SRC-...]] — original concept capture",
507
+ "",
508
+ ].join("\n");
509
+ }
469
510
  return base;
470
511
  }
471
512
 
@@ -97,6 +97,7 @@ export function ensureVaultStructure(paths: VaultPaths): void {
97
97
  join(paths.wiki, "concepts"),
98
98
  join(paths.wiki, "syntheses"),
99
99
  join(paths.wiki, "analyses"),
100
+ join(paths.wiki, "requirements"),
100
101
  paths.meta,
101
102
  paths.dotWiki,
102
103
  paths.outputs,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zosmaai/pi-llm-wiki",
3
- "version": "0.6.4",
3
+ "version": "0.6.6",
4
4
  "description": "Self-maintaining LLM Wiki for Pi — Karpathy-pattern knowledge base with immutable source capture, automated ingestion, search, linting, and Obsidian-compatible vault. auto-updating personal & company wiki.",
5
5
  "keywords": [
6
6
  "pi",
@@ -0,0 +1,55 @@
1
+ ---
2
+ description: Capture and decompose a concept into atomic, traceable wiki requirements. Clarifies ambiguous requirements, splits them into atomic pieces, and persists them as wiki/requirements/ pages with status tracking.
3
+ argument-hint: "<concept description>"
4
+ section: LLM Wiki
5
+ topLevelCli: true
6
+ ---
7
+
8
+ # /wiki-req
9
+
10
+ Capture a concept and decompose it into atomic, traceable requirements in the wiki.
11
+
12
+ Transforms natural language descriptions into structured `wiki/requirements/` pages, preserving the original clarified concept as an immutable source packet in `raw/sources/`.
13
+
14
+ ## User Arguments
15
+
16
+ $ARGUMENTS
17
+
18
+ Read the LLM Wiki skill at `.pi/skills/llm-wiki/SKILL.md` first to understand the wiki conventions, architecture, and page type rules.
19
+
20
+ ## Steps
21
+
22
+ 1. **Clarify the concept**
23
+ - Discuss with the user: unpack ambiguous terms, surfaces implicit assumptions, identify scope boundaries
24
+ - Ask targeted questions to resolve unknowns (e.g., "Which providers?", "What's the fallback behavior?", "Who are the actors?")
25
+ - Reach mutual clarity before proceeding
26
+
27
+ 2. **Capture the clarified concept**
28
+ - Call `wiki_capture_source(text=...)` with the clarified conversation as markdown
29
+ - This creates an immutable record in `raw/sources/SRC-YYYY-MM-DD-NNN/`
30
+ - The source captures the original intent verbatim — no interpretation, no decomposition
31
+
32
+ 3. **Decompose into atomic requirements**
33
+ - Break the clarified concept into the smallest meaningful units of functionality
34
+ - Each requirement should represent one independently verifiable behavior
35
+ - For each atomic requirement, call `wiki_ensure_page(type="requirement", title="...", content="...")` where content includes:
36
+ - `type: requirement` and `status: draft` in frontmatter
37
+ - A clear `## Description` section
38
+ - `## Acceptance Criteria` as a checkbox list (the threshold for "done")
39
+ - `source_id` linking back to the source capture
40
+ - `depends_on` linking to any prerequisite requirements
41
+ - `[[wikilinks]]` to relevant entities, concepts, and other wiki pages
42
+ - Set priority based on user input: `p0` (blocking), `p1` (critical), `p2` (important), `p3` (nice-to-have)
43
+
44
+ 4. **Cross-link and finalize**
45
+ - Ensure each requirement page has bidirectional wikilinks to related pages
46
+ - Update any existing entity or concept pages that these requirements reference
47
+ - Report the results: how many requirements created, their priorities, and the source capture ID
48
+
49
+ **Rules:**
50
+ - One atomic requirement per `wiki_ensure_page` call — each must be independently testable
51
+ - Always capture the clarified concept first via `wiki_capture_source` before decomposing
52
+ - Requirements live in `wiki/requirements/` — they are editable wiki pages, not immutable sources
53
+ - Use status values: `draft` → `clarified` → `active` → `implemented` → `deferred` → `rejected`
54
+ - Use priority values: `p0` (blocking), `p1` (critical), `p2` (important), `p3` (nice-to-have)
55
+ - Do not create requirements in `raw/` — that layer is for external source artifacts only
@@ -81,6 +81,14 @@ wiki_recall(query="specific terms...", max_results=10)
81
81
 
82
82
  This gives you more control over the search terms and returns content previews.
83
83
 
84
+ ### No Wiki Yet
85
+
86
+ If the extension injects a "No LLM Wiki found" hint, use `ask_user` to offer creating one:
87
+
88
+ > "No LLM Wiki found in this directory. Would you like to create one? It gives you a linked knowledge base with automatic recall."
89
+
90
+ If the user agrees, call `wiki_bootstrap(topic="...", mode="personal")`. Suggest only once per session.
91
+
84
92
  ## Available Tools
85
93
 
86
94
  Use these directly — they handle scaffolding, bookkeeping, recall, and capture: