pi-para 0.5.5 → 0.6.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/CHANGELOG.md +22 -0
- package/package.json +8 -5
- package/scripts/build-assets.mjs +29 -0
- package/scripts/install.ps1 +27 -16
- package/scripts/install.sh +3 -2
- package/scripts/smoke-install.mjs +5 -3
- package/src/doctor.ts +5 -0
- package/dist/atomic-write.d.ts +0 -2
- package/dist/atomic-write.d.ts.map +0 -1
- package/dist/atomic-write.js +0 -18
- package/dist/atomic-write.js.map +0 -1
- package/dist/capture.d.ts +0 -34
- package/dist/capture.d.ts.map +0 -1
- package/dist/capture.js +0 -461
- package/dist/capture.js.map +0 -1
- package/dist/cli-legacy.d.ts +0 -4
- package/dist/cli-legacy.d.ts.map +0 -1
- package/dist/cli-legacy.js +0 -41
- package/dist/cli-legacy.js.map +0 -1
- package/dist/cli.d.ts +0 -8
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -511
- package/dist/cli.js.map +0 -1
- package/dist/commands.d.ts +0 -15
- package/dist/commands.d.ts.map +0 -1
- package/dist/commands.js +0 -719
- package/dist/commands.js.map +0 -1
- package/dist/config.d.ts +0 -104
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -242
- package/dist/config.js.map +0 -1
- package/dist/context.d.ts +0 -63
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -311
- package/dist/context.js.map +0 -1
- package/dist/credentials.d.ts +0 -27
- package/dist/credentials.d.ts.map +0 -1
- package/dist/credentials.js +0 -85
- package/dist/credentials.js.map +0 -1
- package/dist/daemon.d.ts +0 -49
- package/dist/daemon.d.ts.map +0 -1
- package/dist/daemon.js +0 -226
- package/dist/daemon.js.map +0 -1
- package/dist/doctor.d.ts +0 -20
- package/dist/doctor.d.ts.map +0 -1
- package/dist/doctor.js +0 -171
- package/dist/doctor.js.map +0 -1
- package/dist/frontmatter.d.ts +0 -59
- package/dist/frontmatter.d.ts.map +0 -1
- package/dist/frontmatter.js +0 -170
- package/dist/frontmatter.js.map +0 -1
- package/dist/gepa/dataset.d.ts +0 -36
- package/dist/gepa/dataset.d.ts.map +0 -1
- package/dist/gepa/dataset.js +0 -148
- package/dist/gepa/dataset.js.map +0 -1
- package/dist/gepa/evaluator.d.ts +0 -51
- package/dist/gepa/evaluator.d.ts.map +0 -1
- package/dist/gepa/evaluator.js +0 -317
- package/dist/gepa/evaluator.js.map +0 -1
- package/dist/gepa/index.d.ts +0 -66
- package/dist/gepa/index.d.ts.map +0 -1
- package/dist/gepa/index.js +0 -240
- package/dist/gepa/index.js.map +0 -1
- package/dist/gepa/llm.d.ts +0 -35
- package/dist/gepa/llm.d.ts.map +0 -1
- package/dist/gepa/llm.js +0 -268
- package/dist/gepa/llm.js.map +0 -1
- package/dist/gepa/optimized/capture-prompt.txt +0 -65
- package/dist/gepa/optimizer.d.ts +0 -29
- package/dist/gepa/optimizer.d.ts.map +0 -1
- package/dist/gepa/optimizer.js +0 -249
- package/dist/gepa/optimizer.js.map +0 -1
- package/dist/gepa/targets.d.ts +0 -39
- package/dist/gepa/targets.d.ts.map +0 -1
- package/dist/gepa/targets.js +0 -326
- package/dist/gepa/targets.js.map +0 -1
- package/dist/gepa/types.d.ts +0 -168
- package/dist/gepa/types.d.ts.map +0 -1
- package/dist/gepa/types.js +0 -124
- package/dist/gepa/types.js.map +0 -1
- package/dist/index.d.ts +0 -21
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -359
- package/dist/index.js.map +0 -1
- package/dist/ingest.d.ts +0 -88
- package/dist/ingest.d.ts.map +0 -1
- package/dist/ingest.js +0 -105
- package/dist/ingest.js.map +0 -1
- package/dist/link-discovery.d.ts +0 -40
- package/dist/link-discovery.d.ts.map +0 -1
- package/dist/link-discovery.js +0 -122
- package/dist/link-discovery.js.map +0 -1
- package/dist/link-utils.d.ts +0 -30
- package/dist/link-utils.d.ts.map +0 -1
- package/dist/link-utils.js +0 -145
- package/dist/link-utils.js.map +0 -1
- package/dist/lint.d.ts +0 -39
- package/dist/lint.d.ts.map +0 -1
- package/dist/lint.js +0 -827
- package/dist/lint.js.map +0 -1
- package/dist/maintainer.d.ts +0 -24
- package/dist/maintainer.d.ts.map +0 -1
- package/dist/maintainer.js +0 -358
- package/dist/maintainer.js.map +0 -1
- package/dist/model-resolver.d.ts +0 -30
- package/dist/model-resolver.d.ts.map +0 -1
- package/dist/model-resolver.js +0 -71
- package/dist/model-resolver.js.map +0 -1
- package/dist/paths.d.ts +0 -20
- package/dist/paths.d.ts.map +0 -1
- package/dist/paths.js +0 -33
- package/dist/paths.js.map +0 -1
- package/dist/processor.d.ts +0 -14
- package/dist/processor.d.ts.map +0 -1
- package/dist/processor.js +0 -361
- package/dist/processor.js.map +0 -1
- package/dist/qmd-providers.d.ts +0 -12
- package/dist/qmd-providers.d.ts.map +0 -1
- package/dist/qmd-providers.js +0 -45
- package/dist/qmd-providers.js.map +0 -1
- package/dist/query.d.ts +0 -69
- package/dist/query.d.ts.map +0 -1
- package/dist/query.js +0 -120
- package/dist/query.js.map +0 -1
- package/dist/raw.d.ts +0 -57
- package/dist/raw.d.ts.map +0 -1
- package/dist/raw.js +0 -219
- package/dist/raw.js.map +0 -1
- package/dist/redact.d.ts +0 -21
- package/dist/redact.d.ts.map +0 -1
- package/dist/redact.js +0 -143
- package/dist/redact.js.map +0 -1
- package/dist/repair.d.ts +0 -11
- package/dist/repair.d.ts.map +0 -1
- package/dist/repair.js +0 -41
- package/dist/repair.js.map +0 -1
- package/dist/scheduler/controls.d.ts +0 -35
- package/dist/scheduler/controls.d.ts.map +0 -1
- package/dist/scheduler/controls.js +0 -98
- package/dist/scheduler/controls.js.map +0 -1
- package/dist/scheduler/index.d.ts +0 -48
- package/dist/scheduler/index.d.ts.map +0 -1
- package/dist/scheduler/index.js +0 -193
- package/dist/scheduler/index.js.map +0 -1
- package/dist/scheduler/leases.d.ts +0 -22
- package/dist/scheduler/leases.d.ts.map +0 -1
- package/dist/scheduler/leases.js +0 -74
- package/dist/scheduler/leases.js.map +0 -1
- package/dist/scheduler/session-capture.d.ts +0 -33
- package/dist/scheduler/session-capture.d.ts.map +0 -1
- package/dist/scheduler/session-capture.js +0 -108
- package/dist/scheduler/session-capture.js.map +0 -1
- package/dist/scheduler/state.d.ts +0 -56
- package/dist/scheduler/state.d.ts.map +0 -1
- package/dist/scheduler/state.js +0 -210
- package/dist/scheduler/state.js.map +0 -1
- package/dist/scope.d.ts +0 -54
- package/dist/scope.d.ts.map +0 -1
- package/dist/scope.js +0 -161
- package/dist/scope.js.map +0 -1
- package/dist/scripts/bulk-link-fix.d.ts +0 -9
- package/dist/scripts/bulk-link-fix.d.ts.map +0 -1
- package/dist/scripts/bulk-link-fix.js +0 -106
- package/dist/scripts/bulk-link-fix.js.map +0 -1
- package/dist/session-tools.d.ts +0 -33
- package/dist/session-tools.d.ts.map +0 -1
- package/dist/session-tools.js +0 -211
- package/dist/session-tools.js.map +0 -1
- package/dist/settings.d.ts +0 -19
- package/dist/settings.d.ts.map +0 -1
- package/dist/settings.js +0 -106
- package/dist/settings.js.map +0 -1
- package/dist/setup.d.ts +0 -29
- package/dist/setup.d.ts.map +0 -1
- package/dist/setup.js +0 -90
- package/dist/setup.js.map +0 -1
- package/dist/state.d.ts +0 -54
- package/dist/state.d.ts.map +0 -1
- package/dist/state.js +0 -176
- package/dist/state.js.map +0 -1
- package/dist/status.d.ts +0 -22
- package/dist/status.d.ts.map +0 -1
- package/dist/status.js +0 -93
- package/dist/status.js.map +0 -1
- package/dist/store.d.ts +0 -71
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -282
- package/dist/store.js.map +0 -1
- package/dist/summarize.d.ts +0 -60
- package/dist/summarize.d.ts.map +0 -1
- package/dist/summarize.js +0 -266
- package/dist/summarize.js.map +0 -1
- package/dist/tag-registry.d.ts +0 -56
- package/dist/tag-registry.d.ts.map +0 -1
- package/dist/tag-registry.js +0 -146
- package/dist/tag-registry.js.map +0 -1
- package/dist/templates/prompts.d.ts +0 -63
- package/dist/templates/prompts.d.ts.map +0 -1
- package/dist/templates/prompts.js +0 -260
- package/dist/templates/prompts.js.map +0 -1
- package/dist/tools.d.ts +0 -26
- package/dist/tools.d.ts.map +0 -1
- package/dist/tools.js +0 -1198
- package/dist/tools.js.map +0 -1
- package/dist/watcher.d.ts +0 -25
- package/dist/watcher.d.ts.map +0 -1
- package/dist/watcher.js +0 -84
- package/dist/watcher.js.map +0 -1
- package/dist/webui/client/dist/index.html +0 -1885
- package/dist/webui/server.d.ts +0 -31
- package/dist/webui/server.d.ts.map +0 -1
- package/dist/webui/server.js +0 -566
- package/dist/webui/server.js.map +0 -1
- package/dist/wiki-tool-guidance.d.ts +0 -6
- package/dist/wiki-tool-guidance.d.ts.map +0 -1
- package/dist/wiki-tool-guidance.js +0 -70
- package/dist/wiki-tool-guidance.js.map +0 -1
- package/dist/wiki.d.ts +0 -108
- package/dist/wiki.d.ts.map +0 -1
- package/dist/wiki.js +0 -497
- package/dist/wiki.js.map +0 -1
- package/scripts/gepa/__pycache__/dataset.cpython-313.pyc +0 -0
- package/scripts/gepa/__pycache__/lm_providers.cpython-313.pyc +0 -0
- package/scripts/gepa/__pycache__/metric.cpython-313.pyc +0 -0
- package/scripts/gepa/__pycache__/program.cpython-313.pyc +0 -0
- package/scripts/gepa/__pycache__/wiki_reader.cpython-313.pyc +0 -0
- package/scripts/gepa/uv.lock +0 -2241
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
export const WIKI_TOOL_DESCRIPTIONS = {
|
|
2
|
-
wiki_ingest: "Ingest a URL, file path, or raw text into the PARA wiki and save a raw source copy.",
|
|
3
|
-
wiki_query: "Search the PARA wiki with scope/category filters and freshness metadata.",
|
|
4
|
-
wiki_edit: "Atomically edit an existing wiki page with exact oldText→newText replacements.",
|
|
5
|
-
wiki_write: "Create new pages, append sections, or intentionally replace complete wiki pages.",
|
|
6
|
-
wiki_read: "Read index.md or a wiki page by path/title, including frontmatter and freshness metadata.",
|
|
7
|
-
wiki_move: "Move a wiki page between PARA categories and update frontmatter.",
|
|
8
|
-
wiki_lint: "Run wiki health checks and optionally auto-fix safe issues.",
|
|
9
|
-
wiki_migrate: "Batch-migrate all wiki pages to the current schema version.",
|
|
10
|
-
wiki_summarize: "Collect page/category/wiki content for an LLM-written summary.",
|
|
11
|
-
};
|
|
12
|
-
export const WIKI_TOOL_SNIPPETS = {
|
|
13
|
-
wiki_ingest: "Ingest a source into the PARA wiki.",
|
|
14
|
-
wiki_query: "Search the PARA wiki for relevant knowledge.",
|
|
15
|
-
wiki_edit: "Surgically edit an existing wiki page; every oldText must match exactly once.",
|
|
16
|
-
wiki_write: "Create/append/replace PARA wiki pages; prefer wiki_edit for surgical updates.",
|
|
17
|
-
wiki_read: "Read index.md or a wiki page and check freshness for page results.",
|
|
18
|
-
wiki_move: "Move a wiki page between PARA categories.",
|
|
19
|
-
wiki_lint: "Run wiki health checks and safe autofixes.",
|
|
20
|
-
wiki_migrate: "Batch-migrate wiki pages to the current schema.",
|
|
21
|
-
wiki_summarize: "Summarize wiki pages, categories, or the entire wiki.",
|
|
22
|
-
};
|
|
23
|
-
const TOOL_SPECIFIC_GUIDELINES = {
|
|
24
|
-
wiki_ingest: [
|
|
25
|
-
"Use wiki_ingest when the user provides a URL, file path, or text to add to the knowledge base.",
|
|
26
|
-
"After ingesting, synthesize durable knowledge with wiki_write/wiki_edit when the source contains reusable facts.",
|
|
27
|
-
],
|
|
28
|
-
wiki_query: [
|
|
29
|
-
"Use wiki_query before answering questions that may depend on past architecture decisions, debugging history, conventions, or domain knowledge.",
|
|
30
|
-
"Use global=true only when the answer should search across project scopes.",
|
|
31
|
-
],
|
|
32
|
-
wiki_edit: [
|
|
33
|
-
"Use wiki_edit after wiki_read when fixing stale, incorrect, or incomplete content.",
|
|
34
|
-
"Keep oldText as small as possible while still unique in the page body.",
|
|
35
|
-
],
|
|
36
|
-
wiki_write: [
|
|
37
|
-
"Use wiki_write for new pages, appending new sections, or intentional whole-page replacement.",
|
|
38
|
-
"mode=create is safe: if a page exists it is skipped, not overwritten.",
|
|
39
|
-
"Use mode=replace only when deliberately rewriting the entire page.",
|
|
40
|
-
],
|
|
41
|
-
wiki_read: [
|
|
42
|
-
"When wiki_read returns AGING/STALE/VERY STALE, verify code/config/API claims against source before trusting them.",
|
|
43
|
-
],
|
|
44
|
-
wiki_move: [
|
|
45
|
-
"Use wiki_move when a page's PARA lifecycle changes, such as archiving a completed project.",
|
|
46
|
-
],
|
|
47
|
-
wiki_lint: [
|
|
48
|
-
"Use wiki_lint to check orphan pages, broken links, stale pages, scope drift, frontmatter, index drift, and duplicate slugs.",
|
|
49
|
-
],
|
|
50
|
-
wiki_migrate: [
|
|
51
|
-
"Use wiki_migrate when schemaVersion changes or doctor/lint reports stale page schema.",
|
|
52
|
-
],
|
|
53
|
-
wiki_summarize: [
|
|
54
|
-
"Use wiki_summarize to gather source material for a synthesized summary; write a durable page only if the summary is worth preserving.",
|
|
55
|
-
],
|
|
56
|
-
};
|
|
57
|
-
export function getWikiToolGuidelines(name) {
|
|
58
|
-
return [...TOOL_SPECIFIC_GUIDELINES[name]];
|
|
59
|
-
}
|
|
60
|
-
export function buildWikiToolGuidanceSection() {
|
|
61
|
-
return [
|
|
62
|
-
"## pi-para Wiki Tool Guidance",
|
|
63
|
-
"",
|
|
64
|
-
"- Search with wiki_query when past architecture, debugging, conventions, domain facts, or prior discussion may matter.",
|
|
65
|
-
"- Treat AGING/STALE/VERY STALE code/config/API claims as untrusted until verified against source; fix wrong pages with wiki_edit.",
|
|
66
|
-
"- Persist major decisions/debugging/conventions without being asked. Use wiki_edit for surgical fixes; wiki_write create/append for new/additive knowledge; replace only for deliberate full rewrites.",
|
|
67
|
-
"- Prefer resources/, kebab-case scope/tags, [[wikilinks]], and no secrets.",
|
|
68
|
-
].join("\n");
|
|
69
|
-
}
|
|
70
|
-
//# sourceMappingURL=wiki-tool-guidance.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wiki-tool-guidance.js","sourceRoot":"","sources":["../src/wiki-tool-guidance.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,sBAAsB,GAAiC;IAClE,WAAW,EAAE,qFAAqF;IAClG,UAAU,EAAE,0EAA0E;IACtF,SAAS,EAAE,gFAAgF;IAC3F,UAAU,EAAE,kFAAkF;IAC9F,SAAS,EAAE,2FAA2F;IACtG,SAAS,EAAE,kEAAkE;IAC7E,SAAS,EAAE,6DAA6D;IACxE,YAAY,EAAE,6DAA6D;IAC3E,cAAc,EAAE,gEAAgE;CACjF,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAiC;IAC9D,WAAW,EAAE,qCAAqC;IAClD,UAAU,EAAE,8CAA8C;IAC1D,SAAS,EAAE,+EAA+E;IAC1F,UAAU,EAAE,+EAA+E;IAC3F,SAAS,EAAE,oEAAoE;IAC/E,SAAS,EAAE,2CAA2C;IACtD,SAAS,EAAE,4CAA4C;IACvD,YAAY,EAAE,iDAAiD;IAC/D,cAAc,EAAE,uDAAuD;CACxE,CAAC;AAEF,MAAM,wBAAwB,GAA4C;IACxE,WAAW,EAAE;QACX,gGAAgG;QAChG,kHAAkH;KACnH;IACD,UAAU,EAAE;QACV,gJAAgJ;QAChJ,2EAA2E;KAC5E;IACD,SAAS,EAAE;QACT,oFAAoF;QACpF,wEAAwE;KACzE;IACD,UAAU,EAAE;QACV,8FAA8F;QAC9F,uEAAuE;QACvE,oEAAoE;KACrE;IACD,SAAS,EAAE;QACT,mHAAmH;KACpH;IACD,SAAS,EAAE;QACT,4FAA4F;KAC7F;IACD,SAAS,EAAE;QACT,6HAA6H;KAC9H;IACD,YAAY,EAAE;QACZ,uFAAuF;KACxF;IACD,cAAc,EAAE;QACd,uIAAuI;KACxI;CACF,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,IAAkB;IACtD,OAAO,CAAC,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,OAAO;QACL,+BAA+B;QAC/B,EAAE;QACF,wHAAwH;QACxH,mIAAmI;QACnI,wMAAwM;QACxM,4EAA4E;KAC7E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
package/dist/wiki.d.ts
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wiki filesystem operations — manages ~/.pi/wiki/ directory structure.
|
|
3
|
-
*
|
|
4
|
-
* Handles CRUD for wiki pages (markdown + YAML frontmatter), index/log
|
|
5
|
-
* maintenance, page moves between PARA categories, and wiki initialization.
|
|
6
|
-
*/
|
|
7
|
-
import type { StateDB } from "./state.js";
|
|
8
|
-
export type ParaCategory = "projects" | "areas" | "resources" | "archives";
|
|
9
|
-
export interface PageFrontmatter {
|
|
10
|
-
title: string;
|
|
11
|
-
para: ParaCategory;
|
|
12
|
-
scope: string[];
|
|
13
|
-
tags: string[];
|
|
14
|
-
sources: string[];
|
|
15
|
-
created: string;
|
|
16
|
-
updated: string;
|
|
17
|
-
links: string[];
|
|
18
|
-
schemaVersion: number;
|
|
19
|
-
}
|
|
20
|
-
export interface WikiPage {
|
|
21
|
-
category: ParaCategory;
|
|
22
|
-
slug: string;
|
|
23
|
-
frontmatter: PageFrontmatter;
|
|
24
|
-
body: string;
|
|
25
|
-
}
|
|
26
|
-
export interface PageRef {
|
|
27
|
-
category: ParaCategory;
|
|
28
|
-
slug: string;
|
|
29
|
-
title: string;
|
|
30
|
-
path: string;
|
|
31
|
-
}
|
|
32
|
-
export interface LogEntry {
|
|
33
|
-
date: string;
|
|
34
|
-
operation: "ingest" | "query" | "lint" | "capture" | "move" | "archive" | "edit";
|
|
35
|
-
summary: string;
|
|
36
|
-
pages: string[];
|
|
37
|
-
}
|
|
38
|
-
export declare const PARA_CATEGORIES: readonly ParaCategory[];
|
|
39
|
-
/**
|
|
40
|
-
* Initialize a wiki directory. Creates the PARA category directories,
|
|
41
|
-
* raw source directories, and seeds schema.md, index.md, log.md, and
|
|
42
|
-
* sessions.md if they do not already exist. Idempotent.
|
|
43
|
-
*/
|
|
44
|
-
export declare function initWiki(wikiDir: string): Promise<void>;
|
|
45
|
-
/**
|
|
46
|
-
* Read a wiki page by category and slug. Returns null if the page does
|
|
47
|
-
* not exist. Parses YAML frontmatter via frontmatter.ts.
|
|
48
|
-
*/
|
|
49
|
-
export declare function readPage(wikiDir: string, category: ParaCategory, slug: string): Promise<WikiPage | null>;
|
|
50
|
-
/**
|
|
51
|
-
* Write a wiki page. Creates the category directory if needed. Serializes
|
|
52
|
-
* frontmatter and body via frontmatter.ts.
|
|
53
|
-
*
|
|
54
|
-
* If stateDb is provided, also updates the page summary cache.
|
|
55
|
-
*/
|
|
56
|
-
export declare function writePage(wikiDir: string, page: WikiPage, stateDb?: StateDB): Promise<void>;
|
|
57
|
-
/**
|
|
58
|
-
* Delete a wiki page. No-op if the page does not exist.
|
|
59
|
-
*/
|
|
60
|
-
export declare function deletePage(wikiDir: string, category: ParaCategory, slug: string): Promise<void>;
|
|
61
|
-
/**
|
|
62
|
-
* Move a page between PARA categories. Updates the page's `para` and
|
|
63
|
-
* `updated` frontmatter fields. The slug is preserved.
|
|
64
|
-
*/
|
|
65
|
-
export declare function movePage(wikiDir: string, from: PageRef, toCategory: ParaCategory): Promise<void>;
|
|
66
|
-
/**
|
|
67
|
-
* List pages across one or all PARA categories. Returns PageRef objects
|
|
68
|
-
* sorted by category then slug.
|
|
69
|
-
*/
|
|
70
|
-
export declare function listPages(wikiDir: string, category?: ParaCategory): Promise<PageRef[]>;
|
|
71
|
-
/**
|
|
72
|
-
* List page slugs across all PARA categories without reading file contents.
|
|
73
|
-
* Much cheaper than listPages() when only slugs are needed (e.g. auto-linking).
|
|
74
|
-
*/
|
|
75
|
-
export declare function listPageSlugs(wikiDir: string): Promise<Set<string>>;
|
|
76
|
-
/**
|
|
77
|
-
* Read the wiki index (index.md).
|
|
78
|
-
*/
|
|
79
|
-
export declare function readIndex(wikiDir: string): Promise<string>;
|
|
80
|
-
/**
|
|
81
|
-
* Write the wiki index (index.md).
|
|
82
|
-
*/
|
|
83
|
-
export declare function writeIndex(wikiDir: string, content: string): Promise<void>;
|
|
84
|
-
/**
|
|
85
|
-
* Append an entry to the activity log (log.md).
|
|
86
|
-
*/
|
|
87
|
-
export declare function appendLog(wikiDir: string, entry: LogEntry): Promise<void>;
|
|
88
|
-
/**
|
|
89
|
-
* Read the wiki schema (schema.md).
|
|
90
|
-
*/
|
|
91
|
-
export declare function readSchema(wikiDir: string): Promise<string>;
|
|
92
|
-
/**
|
|
93
|
-
* Rebuild index.md deterministically from all pages on disk.
|
|
94
|
-
*
|
|
95
|
-
* Reads all pages, groups by PARA category, sorts alphabetically within
|
|
96
|
-
* each category, and writes a standardized index.md with one-line summaries.
|
|
97
|
-
*/
|
|
98
|
-
export declare function rebuildIndex(wikiDir: string): Promise<void>;
|
|
99
|
-
/**
|
|
100
|
-
* Auto-commit all wiki changes with a descriptive message.
|
|
101
|
-
*
|
|
102
|
-
* Silently no-ops if:
|
|
103
|
-
* - git is not installed
|
|
104
|
-
* - wiki dir is not a git repo
|
|
105
|
-
* - there are no changes to commit
|
|
106
|
-
*/
|
|
107
|
-
export declare function gitCommit(wikiDir: string, message: string): Promise<boolean>;
|
|
108
|
-
//# sourceMappingURL=wiki.d.ts.map
|
package/dist/wiki.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wiki.d.ts","sourceRoot":"","sources":["../src/wiki.ts"],"names":[],"mappings":"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"}
|
package/dist/wiki.js
DELETED
|
@@ -1,497 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wiki filesystem operations — manages ~/.pi/wiki/ directory structure.
|
|
3
|
-
*
|
|
4
|
-
* Handles CRUD for wiki pages (markdown + YAML frontmatter), index/log
|
|
5
|
-
* maintenance, page moves between PARA categories, and wiki initialization.
|
|
6
|
-
*/
|
|
7
|
-
import { readFile, writeFile, mkdir, unlink, readdir, access, } from "node:fs/promises";
|
|
8
|
-
import { join } from "node:path";
|
|
9
|
-
import { execFile } from "node:child_process";
|
|
10
|
-
import { parseFrontmatter, serializeFrontmatter, } from "./frontmatter.js";
|
|
11
|
-
// -- Constants ---------------------------------------------------------------
|
|
12
|
-
export const PARA_CATEGORIES = [
|
|
13
|
-
"projects",
|
|
14
|
-
"areas",
|
|
15
|
-
"resources",
|
|
16
|
-
"archives",
|
|
17
|
-
];
|
|
18
|
-
const DEFAULT_SCHEMA = `# Wiki Schema
|
|
19
|
-
|
|
20
|
-
## Page Format
|
|
21
|
-
|
|
22
|
-
Every wiki page is a markdown file with YAML frontmatter:
|
|
23
|
-
|
|
24
|
-
\`\`\`yaml
|
|
25
|
-
---
|
|
26
|
-
title: Page Title
|
|
27
|
-
para: projects | areas | resources | archives
|
|
28
|
-
scope:
|
|
29
|
-
- project-name
|
|
30
|
-
- global
|
|
31
|
-
tags:
|
|
32
|
-
- topic-tag
|
|
33
|
-
sources:
|
|
34
|
-
- https://example.com
|
|
35
|
-
- session:~/.pi/agent/sessions/.../file.jsonl
|
|
36
|
-
created: "2026-01-01"
|
|
37
|
-
updated: "2026-01-01"
|
|
38
|
-
links:
|
|
39
|
-
- other-page-slug
|
|
40
|
-
---
|
|
41
|
-
\`\`\`
|
|
42
|
-
|
|
43
|
-
## PARA Categories
|
|
44
|
-
|
|
45
|
-
- **projects/**: Active, goal-defined work with an end date. Default scope: current project name.
|
|
46
|
-
- **areas/**: Ongoing responsibilities with no end date. Default scope: \`["global"]\`.
|
|
47
|
-
- **resources/**: Reference material, how-tos, patterns. Scope assigned by content analysis.
|
|
48
|
-
- **archives/**: Completed, deprecated, or inactive items. Moved from other categories.
|
|
49
|
-
|
|
50
|
-
## Naming Conventions
|
|
51
|
-
|
|
52
|
-
- Slugs: lowercase, hyphens, no special characters (e.g., \`ssl-cert-gotchas\`)
|
|
53
|
-
- One concept per page
|
|
54
|
-
- Use [[wikilinks]] for cross-references: \`[[slug]]\`
|
|
55
|
-
|
|
56
|
-
## Wiki Summary Format
|
|
57
|
-
|
|
58
|
-
\`\`\`markdown
|
|
59
|
-
## Topic
|
|
60
|
-
[What this page covers]
|
|
61
|
-
|
|
62
|
-
## Key Facts
|
|
63
|
-
- [Established knowledge points]
|
|
64
|
-
|
|
65
|
-
## Insights
|
|
66
|
-
- [Non-obvious findings, patterns, implications]
|
|
67
|
-
|
|
68
|
-
## Connections
|
|
69
|
-
- [[related-page]] — how this relates
|
|
70
|
-
|
|
71
|
-
## Open Questions
|
|
72
|
-
- [Gaps in knowledge, unresolved contradictions]
|
|
73
|
-
|
|
74
|
-
## Sources
|
|
75
|
-
- [Source URLs, file paths, session references]
|
|
76
|
-
\`\`\`
|
|
77
|
-
|
|
78
|
-
## Index Format
|
|
79
|
-
|
|
80
|
-
\`index.md\` is organized by PARA category with one-line summaries per page.
|
|
81
|
-
|
|
82
|
-
## Log Format
|
|
83
|
-
|
|
84
|
-
\`log.md\` uses the heading format: \`## [YYYY-MM-DD] operation | summary\`
|
|
85
|
-
|
|
86
|
-
## Tone
|
|
87
|
-
|
|
88
|
-
Technical, concise, factual. No fluff.
|
|
89
|
-
|
|
90
|
-
## Updates vs. New Pages
|
|
91
|
-
|
|
92
|
-
- Update an existing page when new information relates to the same concept
|
|
93
|
-
- Create a new page when the concept is distinct enough to stand alone
|
|
94
|
-
- When in doubt, create a new page and add [[wikilinks]]
|
|
95
|
-
|
|
96
|
-
## Archiving
|
|
97
|
-
|
|
98
|
-
Move projects to archives when:
|
|
99
|
-
- The project goal is completed
|
|
100
|
-
- No log entries in 90+ days
|
|
101
|
-
- Explicitly requested by user
|
|
102
|
-
`;
|
|
103
|
-
const DEFAULT_INDEX = `# Wiki Index
|
|
104
|
-
|
|
105
|
-
## Projects
|
|
106
|
-
|
|
107
|
-
_No active projects yet._
|
|
108
|
-
|
|
109
|
-
## Areas
|
|
110
|
-
|
|
111
|
-
_No areas defined yet._
|
|
112
|
-
|
|
113
|
-
## Resources
|
|
114
|
-
|
|
115
|
-
_No resources yet._
|
|
116
|
-
|
|
117
|
-
## Archives
|
|
118
|
-
|
|
119
|
-
_No archived items._
|
|
120
|
-
`;
|
|
121
|
-
const DEFAULT_LOG = "# Activity Log\n";
|
|
122
|
-
const DEFAULT_SESSIONS = "# Session Digests\n";
|
|
123
|
-
const DEFAULT_GITIGNORE = `# pi-para generated state (do not version)
|
|
124
|
-
.qmd.sqlite*
|
|
125
|
-
.daemon.sqlite*
|
|
126
|
-
.pi-para.sqlite*
|
|
127
|
-
gepa/input/
|
|
128
|
-
gepa/output/
|
|
129
|
-
|
|
130
|
-
# local caches/logs
|
|
131
|
-
*.tmp
|
|
132
|
-
`;
|
|
133
|
-
// -- Helpers -----------------------------------------------------------------
|
|
134
|
-
async function fileExists(path) {
|
|
135
|
-
try {
|
|
136
|
-
await access(path);
|
|
137
|
-
return true;
|
|
138
|
-
}
|
|
139
|
-
catch {
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
async function seedFile(path, content) {
|
|
144
|
-
if (!(await fileExists(path))) {
|
|
145
|
-
await writeFile(path, content, "utf-8");
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
// -- Functions ---------------------------------------------------------------
|
|
149
|
-
/**
|
|
150
|
-
* Initialize a wiki directory. Creates the PARA category directories,
|
|
151
|
-
* raw source directories, and seeds schema.md, index.md, log.md, and
|
|
152
|
-
* sessions.md if they do not already exist. Idempotent.
|
|
153
|
-
*/
|
|
154
|
-
export async function initWiki(wikiDir) {
|
|
155
|
-
// Create PARA category directories
|
|
156
|
-
for (const cat of PARA_CATEGORIES) {
|
|
157
|
-
await mkdir(join(wikiDir, cat), { recursive: true });
|
|
158
|
-
}
|
|
159
|
-
// Create raw source directories
|
|
160
|
-
for (const sub of ["articles", "docs", "notes"]) {
|
|
161
|
-
await mkdir(join(wikiDir, "raw", sub), { recursive: true });
|
|
162
|
-
}
|
|
163
|
-
// Seed default files (only if missing)
|
|
164
|
-
await seedFile(join(wikiDir, "schema.md"), DEFAULT_SCHEMA);
|
|
165
|
-
await seedFile(join(wikiDir, "index.md"), DEFAULT_INDEX);
|
|
166
|
-
await seedFile(join(wikiDir, "log.md"), DEFAULT_LOG);
|
|
167
|
-
await seedFile(join(wikiDir, "sessions.md"), DEFAULT_SESSIONS);
|
|
168
|
-
await seedFile(join(wikiDir, ".gitignore"), DEFAULT_GITIGNORE);
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Read a wiki page by category and slug. Returns null if the page does
|
|
172
|
-
* not exist. Parses YAML frontmatter via frontmatter.ts.
|
|
173
|
-
*/
|
|
174
|
-
export async function readPage(wikiDir, category, slug) {
|
|
175
|
-
const filePath = join(wikiDir, category, `${slug}.md`);
|
|
176
|
-
let content;
|
|
177
|
-
try {
|
|
178
|
-
content = await readFile(filePath, "utf-8");
|
|
179
|
-
}
|
|
180
|
-
catch (err) {
|
|
181
|
-
if (err.code === "ENOENT") {
|
|
182
|
-
return null;
|
|
183
|
-
}
|
|
184
|
-
throw err;
|
|
185
|
-
}
|
|
186
|
-
const { frontmatter, body } = parseFrontmatter(content);
|
|
187
|
-
return { category, slug, frontmatter, body };
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Write a wiki page. Creates the category directory if needed. Serializes
|
|
191
|
-
* frontmatter and body via frontmatter.ts.
|
|
192
|
-
*
|
|
193
|
-
* If stateDb is provided, also updates the page summary cache.
|
|
194
|
-
*/
|
|
195
|
-
export async function writePage(wikiDir, page, stateDb) {
|
|
196
|
-
const dirPath = join(wikiDir, page.category);
|
|
197
|
-
await mkdir(dirPath, { recursive: true });
|
|
198
|
-
const filePath = join(dirPath, `${page.slug}.md`);
|
|
199
|
-
const content = serializeFrontmatter(page.frontmatter, page.body);
|
|
200
|
-
await writeFile(filePath, content, "utf-8");
|
|
201
|
-
// Update page summary cache if state DB is available
|
|
202
|
-
if (stateDb) {
|
|
203
|
-
const firstPara = extractFirstParagraphFromBody(page.body);
|
|
204
|
-
stateDb.upsertPageSummary(page.slug, page.category, page.frontmatter.scope, page.frontmatter.tags, firstPara, page.frontmatter.updated);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Delete a wiki page. No-op if the page does not exist.
|
|
209
|
-
*/
|
|
210
|
-
export async function deletePage(wikiDir, category, slug) {
|
|
211
|
-
const filePath = join(wikiDir, category, `${slug}.md`);
|
|
212
|
-
try {
|
|
213
|
-
await unlink(filePath);
|
|
214
|
-
}
|
|
215
|
-
catch (err) {
|
|
216
|
-
if (err.code === "ENOENT") {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
throw err;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Move a page between PARA categories. Updates the page's `para` and
|
|
224
|
-
* `updated` frontmatter fields. The slug is preserved.
|
|
225
|
-
*/
|
|
226
|
-
export async function movePage(wikiDir, from, toCategory) {
|
|
227
|
-
const srcPath = join(wikiDir, from.category, `${from.slug}.md`);
|
|
228
|
-
const destDir = join(wikiDir, toCategory);
|
|
229
|
-
const destPath = join(destDir, `${from.slug}.md`);
|
|
230
|
-
// Read source
|
|
231
|
-
const content = await readFile(srcPath, "utf-8");
|
|
232
|
-
const { frontmatter, body } = parseFrontmatter(content);
|
|
233
|
-
// Update frontmatter
|
|
234
|
-
frontmatter.para = toCategory;
|
|
235
|
-
frontmatter.updated = new Date().toISOString();
|
|
236
|
-
// Write to new location, then remove old file
|
|
237
|
-
await mkdir(destDir, { recursive: true });
|
|
238
|
-
await writeFile(destPath, serializeFrontmatter(frontmatter, body), "utf-8");
|
|
239
|
-
await unlink(srcPath);
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* List pages across one or all PARA categories. Returns PageRef objects
|
|
243
|
-
* sorted by category then slug.
|
|
244
|
-
*/
|
|
245
|
-
export async function listPages(wikiDir, category) {
|
|
246
|
-
const categories = category ? [category] : PARA_CATEGORIES;
|
|
247
|
-
const refs = [];
|
|
248
|
-
for (const cat of categories) {
|
|
249
|
-
const dirPath = join(wikiDir, cat);
|
|
250
|
-
let entries;
|
|
251
|
-
try {
|
|
252
|
-
entries = await readdir(dirPath);
|
|
253
|
-
}
|
|
254
|
-
catch {
|
|
255
|
-
continue; // directory doesn't exist yet
|
|
256
|
-
}
|
|
257
|
-
const catRefs = await Promise.all(entries
|
|
258
|
-
.filter((entry) => entry.endsWith(".md"))
|
|
259
|
-
.map(async (entry) => {
|
|
260
|
-
const slug = entry.slice(0, -3);
|
|
261
|
-
const content = await readFile(join(dirPath, entry), "utf-8");
|
|
262
|
-
const { frontmatter } = parseFrontmatter(content);
|
|
263
|
-
return {
|
|
264
|
-
category: cat,
|
|
265
|
-
slug,
|
|
266
|
-
title: frontmatter.title,
|
|
267
|
-
path: `${cat}/${entry}`,
|
|
268
|
-
};
|
|
269
|
-
}));
|
|
270
|
-
refs.push(...catRefs);
|
|
271
|
-
}
|
|
272
|
-
// Sort by category order, then slug alphabetically
|
|
273
|
-
refs.sort((a, b) => {
|
|
274
|
-
const catCmp = PARA_CATEGORIES.indexOf(a.category) -
|
|
275
|
-
PARA_CATEGORIES.indexOf(b.category);
|
|
276
|
-
if (catCmp !== 0)
|
|
277
|
-
return catCmp;
|
|
278
|
-
return a.slug.localeCompare(b.slug);
|
|
279
|
-
});
|
|
280
|
-
return refs;
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* List page slugs across all PARA categories without reading file contents.
|
|
284
|
-
* Much cheaper than listPages() when only slugs are needed (e.g. auto-linking).
|
|
285
|
-
*/
|
|
286
|
-
export async function listPageSlugs(wikiDir) {
|
|
287
|
-
const slugs = new Set();
|
|
288
|
-
for (const cat of PARA_CATEGORIES) {
|
|
289
|
-
let entries;
|
|
290
|
-
try {
|
|
291
|
-
entries = await readdir(join(wikiDir, cat));
|
|
292
|
-
}
|
|
293
|
-
catch {
|
|
294
|
-
continue;
|
|
295
|
-
}
|
|
296
|
-
for (const entry of entries) {
|
|
297
|
-
if (entry.endsWith(".md"))
|
|
298
|
-
slugs.add(entry.slice(0, -3));
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
return slugs;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Read the wiki index (index.md).
|
|
305
|
-
*/
|
|
306
|
-
export async function readIndex(wikiDir) {
|
|
307
|
-
return readFile(join(wikiDir, "index.md"), "utf-8");
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Write the wiki index (index.md).
|
|
311
|
-
*/
|
|
312
|
-
export async function writeIndex(wikiDir, content) {
|
|
313
|
-
await writeFile(join(wikiDir, "index.md"), content, "utf-8");
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* Append an entry to the activity log (log.md).
|
|
317
|
-
*/
|
|
318
|
-
export async function appendLog(wikiDir, entry) {
|
|
319
|
-
const logPath = join(wikiDir, "log.md");
|
|
320
|
-
const existing = await readFile(logPath, "utf-8");
|
|
321
|
-
const pages = entry.pages.length > 0 ? entry.pages.join(", ") : "none";
|
|
322
|
-
const line = `\n## [${entry.date}] ${entry.operation} | ${entry.summary}\nPages: ${pages}\n`;
|
|
323
|
-
await writeFile(logPath, existing + line, "utf-8");
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* Read the wiki schema (schema.md).
|
|
327
|
-
*/
|
|
328
|
-
export async function readSchema(wikiDir) {
|
|
329
|
-
return readFile(join(wikiDir, "schema.md"), "utf-8");
|
|
330
|
-
}
|
|
331
|
-
// -- Git auto-commit ---------------------------------------------------------
|
|
332
|
-
/**
|
|
333
|
-
* Run a git command in the wiki directory. Returns stdout or null on failure.
|
|
334
|
-
*/
|
|
335
|
-
function git(wikiDir, args) {
|
|
336
|
-
return new Promise((resolve) => {
|
|
337
|
-
execFile("git", args, { cwd: wikiDir, timeout: 10_000 }, (err, stdout) => {
|
|
338
|
-
if (err)
|
|
339
|
-
resolve(null);
|
|
340
|
-
else
|
|
341
|
-
resolve(stdout.trim());
|
|
342
|
-
});
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
// -- Index rebuild -----------------------------------------------------------
|
|
346
|
-
/**
|
|
347
|
-
* Rebuild index.md deterministically from all pages on disk.
|
|
348
|
-
*
|
|
349
|
-
* Reads all pages, groups by PARA category, sorts alphabetically within
|
|
350
|
-
* each category, and writes a standardized index.md with one-line summaries.
|
|
351
|
-
*/
|
|
352
|
-
export async function rebuildIndex(wikiDir) {
|
|
353
|
-
const sections = {
|
|
354
|
-
projects: [],
|
|
355
|
-
areas: [],
|
|
356
|
-
resources: [],
|
|
357
|
-
archives: [],
|
|
358
|
-
};
|
|
359
|
-
// Single pass: read each page file exactly once, in parallel per category.
|
|
360
|
-
// (Previously this called listPages() and then readPage() per page, reading
|
|
361
|
-
// every file twice sequentially — the dominant cost of wiki_write at scale.)
|
|
362
|
-
for (const cat of PARA_CATEGORIES) {
|
|
363
|
-
const dirPath = join(wikiDir, cat);
|
|
364
|
-
let entries;
|
|
365
|
-
try {
|
|
366
|
-
entries = await readdir(dirPath);
|
|
367
|
-
}
|
|
368
|
-
catch {
|
|
369
|
-
continue; // directory doesn't exist yet
|
|
370
|
-
}
|
|
371
|
-
const lines = await Promise.all(entries
|
|
372
|
-
.filter((entry) => entry.endsWith(".md"))
|
|
373
|
-
.map((entry) => entry.slice(0, -3))
|
|
374
|
-
.sort((a, b) => a.localeCompare(b))
|
|
375
|
-
.map(async (slug) => {
|
|
376
|
-
const entry = `${slug}.md`;
|
|
377
|
-
const content = await readFile(join(dirPath, entry), "utf-8");
|
|
378
|
-
const { frontmatter, body } = parseFrontmatter(content);
|
|
379
|
-
const title = frontmatter.title;
|
|
380
|
-
const summary = extractFirstParagraphFromBody(body);
|
|
381
|
-
const desc = summary && summary !== "(no summary)"
|
|
382
|
-
? ": " + (summary.length > 120 ? summary.slice(0, 117) + "..." : summary)
|
|
383
|
-
: "";
|
|
384
|
-
return `- [[${slug}]] \u2014 ${title}${desc}`;
|
|
385
|
-
}));
|
|
386
|
-
sections[cat].push(...lines);
|
|
387
|
-
}
|
|
388
|
-
const categoryLabels = {
|
|
389
|
-
projects: "Projects",
|
|
390
|
-
areas: "Areas",
|
|
391
|
-
resources: "Resources",
|
|
392
|
-
archives: "Archives",
|
|
393
|
-
};
|
|
394
|
-
const lines = ["# Wiki Index", ""];
|
|
395
|
-
for (const cat of PARA_CATEGORIES) {
|
|
396
|
-
lines.push(`## ${categoryLabels[cat]}`, "");
|
|
397
|
-
if (sections[cat].length > 0) {
|
|
398
|
-
lines.push(...sections[cat]);
|
|
399
|
-
}
|
|
400
|
-
else {
|
|
401
|
-
const emptyMsg = {
|
|
402
|
-
projects: "_No active projects yet._",
|
|
403
|
-
areas: "_No areas defined yet._",
|
|
404
|
-
resources: "_No resources yet._",
|
|
405
|
-
archives: "_No archived items._",
|
|
406
|
-
};
|
|
407
|
-
lines.push(emptyMsg[cat]);
|
|
408
|
-
}
|
|
409
|
-
lines.push("");
|
|
410
|
-
}
|
|
411
|
-
// Remove trailing empty line to avoid double newlines
|
|
412
|
-
while (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
413
|
-
lines.pop();
|
|
414
|
-
}
|
|
415
|
-
lines.push(""); // single trailing newline
|
|
416
|
-
await writeIndex(wikiDir, lines.join("\n"));
|
|
417
|
-
}
|
|
418
|
-
/**
|
|
419
|
-
* Extract the first non-empty paragraph from a markdown body.
|
|
420
|
-
* Skips headings and blank lines. Returns a single line.
|
|
421
|
-
*/
|
|
422
|
-
function extractFirstParagraphFromBody(body) {
|
|
423
|
-
const lines = body.split("\n");
|
|
424
|
-
const paragraphLines = [];
|
|
425
|
-
let inParagraph = false;
|
|
426
|
-
for (const line of lines) {
|
|
427
|
-
const trimmed = line.trim();
|
|
428
|
-
// Skip headings and empty lines before paragraph starts
|
|
429
|
-
if (!inParagraph) {
|
|
430
|
-
if (trimmed === "" || trimmed.startsWith("#"))
|
|
431
|
-
continue;
|
|
432
|
-
inParagraph = true;
|
|
433
|
-
}
|
|
434
|
-
// End paragraph on blank line or heading
|
|
435
|
-
if (inParagraph && (trimmed === "" || trimmed.startsWith("#"))) {
|
|
436
|
-
break;
|
|
437
|
-
}
|
|
438
|
-
paragraphLines.push(trimmed);
|
|
439
|
-
}
|
|
440
|
-
const result = paragraphLines.join(" ");
|
|
441
|
-
// Truncate long paragraphs
|
|
442
|
-
if (result.length > 200) {
|
|
443
|
-
return result.slice(0, 197) + "...";
|
|
444
|
-
}
|
|
445
|
-
return result || "(no summary)";
|
|
446
|
-
}
|
|
447
|
-
/**
|
|
448
|
-
* Auto-commit all wiki changes with a descriptive message.
|
|
449
|
-
*
|
|
450
|
-
* Silently no-ops if:
|
|
451
|
-
* - git is not installed
|
|
452
|
-
* - wiki dir is not a git repo
|
|
453
|
-
* - there are no changes to commit
|
|
454
|
-
*/
|
|
455
|
-
export async function gitCommit(wikiDir, message) {
|
|
456
|
-
try {
|
|
457
|
-
// Check if it's a git repo
|
|
458
|
-
const isRepo = await git(wikiDir, ["rev-parse", "--git-dir"]);
|
|
459
|
-
if (!isRepo) {
|
|
460
|
-
// Auto-init if not a repo yet
|
|
461
|
-
const initResult = await git(wikiDir, ["init"]);
|
|
462
|
-
if (!initResult)
|
|
463
|
-
return false;
|
|
464
|
-
}
|
|
465
|
-
// Stage durable wiki content only. Generated SQLite/search state can be large
|
|
466
|
-
// and made wiki edits slow when `git add -A` tried to version it.
|
|
467
|
-
const stageCandidates = [
|
|
468
|
-
".gitignore",
|
|
469
|
-
"schema.md",
|
|
470
|
-
"index.md",
|
|
471
|
-
"log.md",
|
|
472
|
-
"sessions.md",
|
|
473
|
-
"config.json",
|
|
474
|
-
".completed-sessions",
|
|
475
|
-
...PARA_CATEGORIES,
|
|
476
|
-
];
|
|
477
|
-
const stagePaths = [];
|
|
478
|
-
for (const p of stageCandidates) {
|
|
479
|
-
if (await fileExists(join(wikiDir, p)))
|
|
480
|
-
stagePaths.push(p);
|
|
481
|
-
}
|
|
482
|
-
if (stagePaths.length > 0) {
|
|
483
|
-
await git(wikiDir, ["add", "--", ...stagePaths]);
|
|
484
|
-
}
|
|
485
|
-
// Check if there's anything to commit
|
|
486
|
-
const status = await git(wikiDir, ["status", "--porcelain"]);
|
|
487
|
-
if (!status)
|
|
488
|
-
return false; // nothing to commit
|
|
489
|
-
// Commit
|
|
490
|
-
const result = await git(wikiDir, ["commit", "-m", message, "--no-gpg-sign"]);
|
|
491
|
-
return result !== null;
|
|
492
|
-
}
|
|
493
|
-
catch {
|
|
494
|
-
return false;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
//# sourceMappingURL=wiki.js.map
|