pi-para 0.5.2
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 +214 -0
- package/README.md +305 -0
- package/SETUP.md +171 -0
- package/dist/capture.d.ts +34 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.js +461 -0
- package/dist/capture.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +405 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +15 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +786 -0
- package/dist/commands.js.map +1 -0
- package/dist/context.d.ts +61 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +289 -0
- package/dist/context.js.map +1 -0
- package/dist/daemon.d.ts +49 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +226 -0
- package/dist/daemon.js.map +1 -0
- package/dist/frontmatter.d.ts +59 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +170 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/gepa/dataset.d.ts +36 -0
- package/dist/gepa/dataset.d.ts.map +1 -0
- package/dist/gepa/dataset.js +148 -0
- package/dist/gepa/dataset.js.map +1 -0
- package/dist/gepa/evaluator.d.ts +51 -0
- package/dist/gepa/evaluator.d.ts.map +1 -0
- package/dist/gepa/evaluator.js +317 -0
- package/dist/gepa/evaluator.js.map +1 -0
- package/dist/gepa/index.d.ts +66 -0
- package/dist/gepa/index.d.ts.map +1 -0
- package/dist/gepa/index.js +240 -0
- package/dist/gepa/index.js.map +1 -0
- package/dist/gepa/llm.d.ts +35 -0
- package/dist/gepa/llm.d.ts.map +1 -0
- package/dist/gepa/llm.js +268 -0
- package/dist/gepa/llm.js.map +1 -0
- package/dist/gepa/optimized/capture-prompt.txt +65 -0
- package/dist/gepa/optimizer.d.ts +29 -0
- package/dist/gepa/optimizer.d.ts.map +1 -0
- package/dist/gepa/optimizer.js +249 -0
- package/dist/gepa/optimizer.js.map +1 -0
- package/dist/gepa/targets.d.ts +39 -0
- package/dist/gepa/targets.d.ts.map +1 -0
- package/dist/gepa/targets.js +326 -0
- package/dist/gepa/targets.js.map +1 -0
- package/dist/gepa/types.d.ts +168 -0
- package/dist/gepa/types.d.ts.map +1 -0
- package/dist/gepa/types.js +124 -0
- package/dist/gepa/types.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +294 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest.d.ts +88 -0
- package/dist/ingest.d.ts.map +1 -0
- package/dist/ingest.js +105 -0
- package/dist/ingest.js.map +1 -0
- package/dist/link-discovery.d.ts +40 -0
- package/dist/link-discovery.d.ts.map +1 -0
- package/dist/link-discovery.js +122 -0
- package/dist/link-discovery.js.map +1 -0
- package/dist/link-utils.d.ts +30 -0
- package/dist/link-utils.d.ts.map +1 -0
- package/dist/link-utils.js +145 -0
- package/dist/link-utils.js.map +1 -0
- package/dist/lint.d.ts +39 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +827 -0
- package/dist/lint.js.map +1 -0
- package/dist/maintainer.d.ts +24 -0
- package/dist/maintainer.d.ts.map +1 -0
- package/dist/maintainer.js +358 -0
- package/dist/maintainer.js.map +1 -0
- package/dist/processor.d.ts +14 -0
- package/dist/processor.d.ts.map +1 -0
- package/dist/processor.js +361 -0
- package/dist/processor.js.map +1 -0
- package/dist/query.d.ts +69 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +107 -0
- package/dist/query.js.map +1 -0
- package/dist/raw.d.ts +57 -0
- package/dist/raw.d.ts.map +1 -0
- package/dist/raw.js +219 -0
- package/dist/raw.js.map +1 -0
- package/dist/redact.d.ts +21 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/redact.js +143 -0
- package/dist/redact.js.map +1 -0
- package/dist/scope.d.ts +54 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +161 -0
- package/dist/scope.js.map +1 -0
- package/dist/scripts/bulk-link-fix.d.ts +9 -0
- package/dist/scripts/bulk-link-fix.d.ts.map +1 -0
- package/dist/scripts/bulk-link-fix.js +106 -0
- package/dist/scripts/bulk-link-fix.js.map +1 -0
- package/dist/session-tools.d.ts +33 -0
- package/dist/session-tools.d.ts.map +1 -0
- package/dist/session-tools.js +211 -0
- package/dist/session-tools.js.map +1 -0
- package/dist/state.d.ts +54 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +176 -0
- package/dist/state.js.map +1 -0
- package/dist/store.d.ts +56 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +227 -0
- package/dist/store.js.map +1 -0
- package/dist/summarize.d.ts +56 -0
- package/dist/summarize.d.ts.map +1 -0
- package/dist/summarize.js +231 -0
- package/dist/summarize.js.map +1 -0
- package/dist/tag-registry.d.ts +56 -0
- package/dist/tag-registry.d.ts.map +1 -0
- package/dist/tag-registry.js +146 -0
- package/dist/tag-registry.js.map +1 -0
- package/dist/templates/prompts.d.ts +63 -0
- package/dist/templates/prompts.d.ts.map +1 -0
- package/dist/templates/prompts.js +260 -0
- package/dist/templates/prompts.js.map +1 -0
- package/dist/tools.d.ts +26 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +1033 -0
- package/dist/tools.js.map +1 -0
- package/dist/watcher.d.ts +25 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +84 -0
- package/dist/watcher.js.map +1 -0
- package/dist/webui/client/dist/index.html +1885 -0
- package/dist/webui/server.d.ts +31 -0
- package/dist/webui/server.d.ts.map +1 -0
- package/dist/webui/server.js +566 -0
- package/dist/webui/server.js.map +1 -0
- package/dist/wiki.d.ts +103 -0
- package/dist/wiki.d.ts.map +1 -0
- package/dist/wiki.js +428 -0
- package/dist/wiki.js.map +1 -0
- package/package.json +142 -0
- 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/dataset.py +192 -0
- package/scripts/gepa/lm_providers.py +472 -0
- package/scripts/gepa/metric.py +279 -0
- package/scripts/gepa/optimize.py +367 -0
- package/scripts/gepa/program.py +99 -0
- package/scripts/gepa/pyproject.toml +19 -0
- package/scripts/gepa/run-all.sh +53 -0
- package/scripts/gepa/uv.lock +2241 -0
- package/scripts/gepa/wiki_reader.py +113 -0
- package/skills/para/SKILL.md +77 -0
- package/skills/setup/SKILL.md +20 -0
- package/src/capture.ts +563 -0
- package/src/cli.ts +416 -0
- package/src/commands.ts +878 -0
- package/src/context.ts +390 -0
- package/src/daemon.ts +288 -0
- package/src/frontmatter.ts +219 -0
- package/src/gepa/index.ts +287 -0
- package/src/gepa/optimized/capture-prompt.txt +65 -0
- package/src/index.ts +384 -0
- package/src/ingest.ts +177 -0
- package/src/link-discovery.ts +170 -0
- package/src/link-utils.ts +169 -0
- package/src/lint.ts +1018 -0
- package/src/maintainer.ts +404 -0
- package/src/processor.ts +415 -0
- package/src/python/__pycache__/minimax_lm.cpython-312.pyc +0 -0
- package/src/python/minimax_lm.py +198 -0
- package/src/python/rlm_capture.py +215 -0
- package/src/query.ts +148 -0
- package/src/raw.ts +276 -0
- package/src/redact.ts +159 -0
- package/src/scope.ts +214 -0
- package/src/scripts/bulk-link-fix.ts +126 -0
- package/src/session-tools.ts +260 -0
- package/src/state.ts +271 -0
- package/src/store.ts +288 -0
- package/src/summarize.ts +273 -0
- package/src/tag-registry.ts +157 -0
- package/src/templates/index.md +17 -0
- package/src/templates/prompts.ts +274 -0
- package/src/templates/schema.md +116 -0
- package/src/tools.ts +1293 -0
- package/src/watcher.ts +101 -0
- package/src/webui/client/dist/index.html +1885 -0
- package/src/webui/server.ts +765 -0
- package/src/wiki.ts +550 -0
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* qmd store lifecycle — manages the @picassio/qmd store instance.
|
|
3
|
+
*
|
|
4
|
+
* Handles store creation/opening, search with scope filtering,
|
|
5
|
+
* re-indexing after wiki changes, and embedding lifecycle.
|
|
6
|
+
*/
|
|
7
|
+
import type { QMDStore } from "@picassio/qmd";
|
|
8
|
+
import type { PageFrontmatter, PageRef, ParaCategory } from "./wiki.js";
|
|
9
|
+
import type { ProjectScope } from "./scope.js";
|
|
10
|
+
export type { QMDStore } from "@picassio/qmd";
|
|
11
|
+
export interface WikiSearchOptions {
|
|
12
|
+
scope?: ProjectScope;
|
|
13
|
+
category?: ParaCategory;
|
|
14
|
+
limit?: number;
|
|
15
|
+
includeArchives?: boolean;
|
|
16
|
+
graphBoost?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface WikiSearchResult {
|
|
19
|
+
page: PageRef;
|
|
20
|
+
score: number;
|
|
21
|
+
snippet: string;
|
|
22
|
+
frontmatter: PageFrontmatter;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Open and configure a qmd store for the wiki directory.
|
|
26
|
+
*
|
|
27
|
+
* Creates the store with two collections:
|
|
28
|
+
* - wiki: all .md files except raw/
|
|
29
|
+
* - raw: .md files under raw/, not included in default queries
|
|
30
|
+
*
|
|
31
|
+
* Adds PARA category contexts, runs update() for BM25,
|
|
32
|
+
* and schedules embed() in the background.
|
|
33
|
+
*/
|
|
34
|
+
export declare function openStore(wikiDir: string): Promise<QMDStore>;
|
|
35
|
+
/**
|
|
36
|
+
* Close the store. Awaits any pending embed operation (with timeout) first.
|
|
37
|
+
*/
|
|
38
|
+
export declare function closeStore(store: QMDStore): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Search the wiki with scope and category filtering.
|
|
41
|
+
*
|
|
42
|
+
* Uses BM25 search (searchLex) which requires no LLM. Each result's
|
|
43
|
+
* frontmatter is parsed to apply scope/category/archive filters.
|
|
44
|
+
*/
|
|
45
|
+
export declare function searchWiki(store: QMDStore, query: string, opts: WikiSearchOptions): Promise<WikiSearchResult[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Re-index the store (fast filesystem scan). Makes new/changed
|
|
48
|
+
* content BM25-searchable immediately. Call after wiki writes.
|
|
49
|
+
*/
|
|
50
|
+
export declare function reindex(store: QMDStore): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Generate vector embeddings for new/changed pages.
|
|
53
|
+
* Slow — call only at startup (via openStore) or shutdown.
|
|
54
|
+
*/
|
|
55
|
+
export declare function embedIfNeeded(store: QMDStore): Promise<void>;
|
|
56
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,eAAe,CAAC;AAGhE,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI9C,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,eAAe,CAAC;CAC9B;AAsCD;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAwDlE;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAS/D;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAoE7B;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5D;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAElE"}
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* qmd store lifecycle — manages the @picassio/qmd store instance.
|
|
3
|
+
*
|
|
4
|
+
* Handles store creation/opening, search with scope filtering,
|
|
5
|
+
* re-indexing after wiki changes, and embedding lifecycle.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { parse as parseYaml } from "yaml";
|
|
11
|
+
import { createStore, extractSnippet } from "@picassio/qmd";
|
|
12
|
+
import { parseFrontmatter } from "./frontmatter.js";
|
|
13
|
+
import { matchesScope } from "./scope.js";
|
|
14
|
+
// -- PARA context descriptions -----------------------------------------------
|
|
15
|
+
const PARA_CONTEXTS = {
|
|
16
|
+
"projects/": "Active projects with defined goals and end dates",
|
|
17
|
+
"areas/": "Ongoing responsibilities and standards",
|
|
18
|
+
"resources/": "Reference material and how-to guides",
|
|
19
|
+
"archives/": "Completed or deprecated items",
|
|
20
|
+
};
|
|
21
|
+
const RAW_CONTEXT = "Immutable source material: articles, documents, notes. Not synthesized.";
|
|
22
|
+
// -- Pending embed tracking --------------------------------------------------
|
|
23
|
+
const pendingEmbeds = new WeakMap();
|
|
24
|
+
// -- qmd config loading ------------------------------------------------------
|
|
25
|
+
/**
|
|
26
|
+
* Read providers from ~/.config/qmd/index.yml.
|
|
27
|
+
* Returns undefined if no config file or no providers configured.
|
|
28
|
+
*/
|
|
29
|
+
function loadQmdProviders() {
|
|
30
|
+
const configPath = join(homedir(), ".config", "qmd", "index.yml");
|
|
31
|
+
if (!existsSync(configPath))
|
|
32
|
+
return undefined;
|
|
33
|
+
try {
|
|
34
|
+
const content = readFileSync(configPath, "utf-8");
|
|
35
|
+
const config = parseYaml(content);
|
|
36
|
+
return config?.providers;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// -- Functions ---------------------------------------------------------------
|
|
43
|
+
/**
|
|
44
|
+
* Open and configure a qmd store for the wiki directory.
|
|
45
|
+
*
|
|
46
|
+
* Creates the store with two collections:
|
|
47
|
+
* - wiki: all .md files except raw/
|
|
48
|
+
* - raw: .md files under raw/, not included in default queries
|
|
49
|
+
*
|
|
50
|
+
* Adds PARA category contexts, runs update() for BM25,
|
|
51
|
+
* and schedules embed() in the background.
|
|
52
|
+
*/
|
|
53
|
+
export async function openStore(wikiDir) {
|
|
54
|
+
// Read providers from ~/.config/qmd/index.yml so external API providers
|
|
55
|
+
// (embed, chat, rerank) are used instead of local GGUF models.
|
|
56
|
+
const providers = loadQmdProviders();
|
|
57
|
+
const store = await createStore({
|
|
58
|
+
dbPath: join(wikiDir, ".qmd.sqlite"),
|
|
59
|
+
config: {
|
|
60
|
+
collections: {
|
|
61
|
+
wiki: {
|
|
62
|
+
path: wikiDir,
|
|
63
|
+
pattern: "**/*.md",
|
|
64
|
+
ignore: ["raw/**"],
|
|
65
|
+
},
|
|
66
|
+
raw: {
|
|
67
|
+
path: join(wikiDir, "raw"),
|
|
68
|
+
pattern: "**/*.md",
|
|
69
|
+
includeByDefault: false,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
...(providers ? { providers: providers } : {}),
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
// Add PARA category contexts to the wiki collection
|
|
76
|
+
for (const [prefix, description] of Object.entries(PARA_CONTEXTS)) {
|
|
77
|
+
await store.addContext("wiki", prefix, description);
|
|
78
|
+
}
|
|
79
|
+
// Add context for the raw collection root
|
|
80
|
+
await store.addContext("raw", "/", RAW_CONTEXT);
|
|
81
|
+
// Sync filesystem -> BM25 index (fast, search ready immediately)
|
|
82
|
+
await store.update();
|
|
83
|
+
// Schedule embedding in background (non-blocking).
|
|
84
|
+
// BM25 search works immediately; hybrid search improves once embed completes.
|
|
85
|
+
// Suppress console.error from qmd's internal embed failures.
|
|
86
|
+
const origError = console.error;
|
|
87
|
+
const embedPromise = store.embed().then(() => {
|
|
88
|
+
pendingEmbeds.delete(store);
|
|
89
|
+
}).catch(() => {
|
|
90
|
+
// Embedding failures are non-fatal — hybrid search degrades to BM25
|
|
91
|
+
pendingEmbeds.delete(store);
|
|
92
|
+
}).finally(() => {
|
|
93
|
+
console.error = origError;
|
|
94
|
+
});
|
|
95
|
+
// Temporarily suppress embed error noise during background embed
|
|
96
|
+
console.error = (...args) => {
|
|
97
|
+
const msg = String(args[0] ?? "");
|
|
98
|
+
if (msg.includes("embed error") || msg.includes("fetch failed"))
|
|
99
|
+
return;
|
|
100
|
+
origError(...args);
|
|
101
|
+
};
|
|
102
|
+
pendingEmbeds.set(store, embedPromise);
|
|
103
|
+
return store;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Close the store. Awaits any pending embed operation (with timeout) first.
|
|
107
|
+
*/
|
|
108
|
+
export async function closeStore(store) {
|
|
109
|
+
const pending = pendingEmbeds.get(store);
|
|
110
|
+
if (pending) {
|
|
111
|
+
// Wait for pending embed with a short timeout — don't hang forever
|
|
112
|
+
const timeout = new Promise((resolve) => setTimeout(resolve, 5_000));
|
|
113
|
+
await Promise.race([pending, timeout]);
|
|
114
|
+
pendingEmbeds.delete(store);
|
|
115
|
+
}
|
|
116
|
+
await store.close();
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Search the wiki with scope and category filtering.
|
|
120
|
+
*
|
|
121
|
+
* Uses BM25 search (searchLex) which requires no LLM. Each result's
|
|
122
|
+
* frontmatter is parsed to apply scope/category/archive filters.
|
|
123
|
+
*/
|
|
124
|
+
export async function searchWiki(store, query, opts) {
|
|
125
|
+
const limit = opts.limit ?? 10;
|
|
126
|
+
// Build metadata filter for SQL-level filtering (qmd v2.2.0+)
|
|
127
|
+
// Note: we can only use metadata.category here, NOT scope.
|
|
128
|
+
// Scope filtering must remain as post-filter because:
|
|
129
|
+
// - Pages with scope:["global"] must match ANY project scope
|
|
130
|
+
// - Pages in the scope.include list need OR matching
|
|
131
|
+
// - The exclude list needs post-filter negation
|
|
132
|
+
// SQL-level scope filter would miss global pages.
|
|
133
|
+
const metadata = {};
|
|
134
|
+
if (opts.category) {
|
|
135
|
+
metadata.category = opts.category;
|
|
136
|
+
}
|
|
137
|
+
const fetchLimit = opts.scope ? limit * 3 : limit;
|
|
138
|
+
const rawResults = await store.searchLex(query, {
|
|
139
|
+
limit: fetchLimit,
|
|
140
|
+
collection: "wiki",
|
|
141
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
|
|
142
|
+
graphBoost: opts.graphBoost ?? true,
|
|
143
|
+
});
|
|
144
|
+
const results = [];
|
|
145
|
+
for (const result of rawResults) {
|
|
146
|
+
// Parse category and slug from the display path (e.g. "projects/auth-refactor.md")
|
|
147
|
+
const parsed = parseDisplayPath(result.displayPath);
|
|
148
|
+
if (!parsed)
|
|
149
|
+
continue;
|
|
150
|
+
const { category, slug } = parsed;
|
|
151
|
+
// Exclude archives unless explicitly requested (post-filter fallback
|
|
152
|
+
// for pages without frontmatter metadata)
|
|
153
|
+
if (category === "archives" && !opts.includeArchives) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
// Parse frontmatter from body
|
|
157
|
+
const body = result.body ?? "";
|
|
158
|
+
const { frontmatter } = parseFrontmatter(body);
|
|
159
|
+
// Scope post-filter fallback for pages without metadata
|
|
160
|
+
if (opts.scope && !matchesScope(frontmatter.scope, opts.scope)) {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
// Extract a snippet for display
|
|
164
|
+
const snippetResult = extractSnippet(body, query);
|
|
165
|
+
const snippet = snippetResult.snippet;
|
|
166
|
+
results.push({
|
|
167
|
+
page: {
|
|
168
|
+
category,
|
|
169
|
+
slug,
|
|
170
|
+
title: frontmatter.title || result.title,
|
|
171
|
+
path: `${category}/${slug}.md`,
|
|
172
|
+
},
|
|
173
|
+
score: result.score,
|
|
174
|
+
snippet,
|
|
175
|
+
frontmatter,
|
|
176
|
+
});
|
|
177
|
+
if (results.length >= limit)
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
return results;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Re-index the store (fast filesystem scan). Makes new/changed
|
|
184
|
+
* content BM25-searchable immediately. Call after wiki writes.
|
|
185
|
+
*/
|
|
186
|
+
export async function reindex(store) {
|
|
187
|
+
await store.update();
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Generate vector embeddings for new/changed pages.
|
|
191
|
+
* Slow — call only at startup (via openStore) or shutdown.
|
|
192
|
+
*/
|
|
193
|
+
export async function embedIfNeeded(store) {
|
|
194
|
+
await store.embed();
|
|
195
|
+
}
|
|
196
|
+
// -- Helpers -----------------------------------------------------------------
|
|
197
|
+
/** Valid PARA categories for path parsing. */
|
|
198
|
+
const VALID_CATEGORIES = new Set([
|
|
199
|
+
"projects",
|
|
200
|
+
"areas",
|
|
201
|
+
"resources",
|
|
202
|
+
"archives",
|
|
203
|
+
]);
|
|
204
|
+
/**
|
|
205
|
+
* Parse a qmd display path into category + slug.
|
|
206
|
+
* Display paths from searchLex include the collection prefix:
|
|
207
|
+
* "wiki/resources/ssl-certs.md" or "wiki/schema.md"
|
|
208
|
+
* Returns null for root-level files (schema.md, index.md, etc.) — they
|
|
209
|
+
* still appear in search results but aren't PageRef-able.
|
|
210
|
+
*/
|
|
211
|
+
function parseDisplayPath(displayPath) {
|
|
212
|
+
const parts = displayPath.split("/");
|
|
213
|
+
// Display paths are: collection/category/slug.md (3+ parts)
|
|
214
|
+
// or collection/file.md (2 parts, root-level files like schema.md)
|
|
215
|
+
if (parts.length < 3)
|
|
216
|
+
return null;
|
|
217
|
+
// Skip collection prefix (parts[0] = "wiki")
|
|
218
|
+
const category = parts[1];
|
|
219
|
+
if (!VALID_CATEGORIES.has(category))
|
|
220
|
+
return null;
|
|
221
|
+
const filename = parts.slice(2).join("/");
|
|
222
|
+
if (!filename.endsWith(".md"))
|
|
223
|
+
return null;
|
|
224
|
+
const slug = filename.slice(0, -3);
|
|
225
|
+
return { category: category, slug };
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki summarization — adapts pi's compaction approach for wiki knowledge.
|
|
3
|
+
*
|
|
4
|
+
* Produces structured wiki summaries in the standard format:
|
|
5
|
+
* Topic, Key Facts, Insights, Connections, Open Questions, Sources.
|
|
6
|
+
*
|
|
7
|
+
* Supports ingest, session, page, and iterative summarization modes.
|
|
8
|
+
*
|
|
9
|
+
* Functions here generate prompt strings — they do NOT call the LLM.
|
|
10
|
+
* The caller (capture.ts, tools.ts) passes the prompt to a standalone Agent.
|
|
11
|
+
*/
|
|
12
|
+
import type { WikiPage } from "./wiki.js";
|
|
13
|
+
import type { ParaCategory } from "./wiki.js";
|
|
14
|
+
import type { ProjectScope } from "./scope.js";
|
|
15
|
+
export interface SummarizeOptions {
|
|
16
|
+
mode: "ingest" | "session" | "page" | "iterative";
|
|
17
|
+
existingContent?: string;
|
|
18
|
+
scope: ProjectScope;
|
|
19
|
+
category?: ParaCategory;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Serialize session messages for wiki capture.
|
|
23
|
+
*
|
|
24
|
+
* Converts AgentMessage[] to a text representation that prevents the LLM
|
|
25
|
+
* from treating it as a conversation to continue. Uses pi's convertToLlm +
|
|
26
|
+
* serializeConversation when the messages contain pi-specific types
|
|
27
|
+
* (bashExecution, compactionSummary, branchSummary, etc.). Falls back to
|
|
28
|
+
* a compatible reimplementation for plain user/assistant/toolResult messages.
|
|
29
|
+
*
|
|
30
|
+
* @param messages - AgentMessage[] from @mariozechner/pi-agent-core
|
|
31
|
+
* @returns Serialized text in [User]: / [Assistant]: / [Tool result]: format
|
|
32
|
+
*/
|
|
33
|
+
export declare function serializeSessionForWiki(messages: unknown[]): string;
|
|
34
|
+
/**
|
|
35
|
+
* Generate a wiki-format summary prompt from raw content.
|
|
36
|
+
*
|
|
37
|
+
* Returns the prompt string to send to the LLM. The caller passes this
|
|
38
|
+
* to a standalone Agent or includes it in a tool result for the session agent.
|
|
39
|
+
*
|
|
40
|
+
* @param content - Source text, serialized conversation, or page content
|
|
41
|
+
* @param options - Summarization mode and context
|
|
42
|
+
* @returns Prompt string for the LLM
|
|
43
|
+
*/
|
|
44
|
+
export declare function generateSummary(content: string, options: SummarizeOptions): string;
|
|
45
|
+
/**
|
|
46
|
+
* Generate an overview prompt from multiple wiki pages.
|
|
47
|
+
*
|
|
48
|
+
* Used by /wiki-summarize and wiki_summarize tool to produce high-level
|
|
49
|
+
* overviews of a category or the entire wiki.
|
|
50
|
+
*
|
|
51
|
+
* @param pages - Wiki pages to summarize
|
|
52
|
+
* @param scope - Current project scope for context
|
|
53
|
+
* @returns Prompt string for the LLM
|
|
54
|
+
*/
|
|
55
|
+
export declare function generateOverviewPrompt(pages: WikiPage[], scope: ProjectScope): string;
|
|
56
|
+
//# sourceMappingURL=summarize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../src/summarize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAc/C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAuGD;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,OAAO,EAAE,GAClB,MAAM,CAYR;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,GACxB,MAAM,CA2DR;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,QAAQ,EAAE,EACjB,KAAK,EAAE,YAAY,GAClB,MAAM,CAqBR"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiki summarization — adapts pi's compaction approach for wiki knowledge.
|
|
3
|
+
*
|
|
4
|
+
* Produces structured wiki summaries in the standard format:
|
|
5
|
+
* Topic, Key Facts, Insights, Connections, Open Questions, Sources.
|
|
6
|
+
*
|
|
7
|
+
* Supports ingest, session, page, and iterative summarization modes.
|
|
8
|
+
*
|
|
9
|
+
* Functions here generate prompt strings — they do NOT call the LLM.
|
|
10
|
+
* The caller (capture.ts, tools.ts) passes the prompt to a standalone Agent.
|
|
11
|
+
*/
|
|
12
|
+
import { convertToLlm, serializeConversation, } from "@mariozechner/pi-coding-agent";
|
|
13
|
+
import { SUMMARIZE_SYSTEM_PROMPT, ITERATIVE_UPDATE_PROMPT, OVERVIEW_PROMPT, CAPTURE_PROMPT, } from "./templates/prompts.js";
|
|
14
|
+
// -- Constants ---------------------------------------------------------------
|
|
15
|
+
/** Maximum characters for a tool result in serialized output. */
|
|
16
|
+
const TOOL_RESULT_MAX_CHARS = 2000;
|
|
17
|
+
// -- Fallback serialization --------------------------------------------------
|
|
18
|
+
/**
|
|
19
|
+
* Truncate text to a maximum character length for summarization.
|
|
20
|
+
* Keeps the beginning and appends a truncation marker.
|
|
21
|
+
*/
|
|
22
|
+
function truncateForSummary(text, maxChars) {
|
|
23
|
+
if (text.length <= maxChars)
|
|
24
|
+
return text;
|
|
25
|
+
const truncatedChars = text.length - maxChars;
|
|
26
|
+
return `${text.slice(0, maxChars)}\n\n[... ${truncatedChars} more characters truncated]`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Extract text content from a message content field.
|
|
30
|
+
* Handles both string and array-of-blocks shapes.
|
|
31
|
+
*/
|
|
32
|
+
function extractTextContent(content) {
|
|
33
|
+
if (typeof content === "string")
|
|
34
|
+
return content;
|
|
35
|
+
if (!Array.isArray(content))
|
|
36
|
+
return "";
|
|
37
|
+
return content
|
|
38
|
+
.filter((c) => typeof c === "object" &&
|
|
39
|
+
c !== null &&
|
|
40
|
+
"type" in c &&
|
|
41
|
+
c.type === "text" &&
|
|
42
|
+
"text" in c)
|
|
43
|
+
.map((c) => c.text)
|
|
44
|
+
.join("");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Fallback serialization that mirrors pi's serializeConversation format.
|
|
48
|
+
* Used when @mariozechner/pi-coding-agent is not available.
|
|
49
|
+
*
|
|
50
|
+
* Formats: [User]:, [Assistant]:, [Assistant thinking]:,
|
|
51
|
+
* [Assistant tool calls]:, [Tool result]:
|
|
52
|
+
*/
|
|
53
|
+
function serializeMessagesFallback(messages) {
|
|
54
|
+
const parts = [];
|
|
55
|
+
for (const msg of messages) {
|
|
56
|
+
if (typeof msg !== "object" || msg === null || !("role" in msg))
|
|
57
|
+
continue;
|
|
58
|
+
const m = msg;
|
|
59
|
+
if (m.role === "user") {
|
|
60
|
+
const text = extractTextContent(m.content);
|
|
61
|
+
if (text)
|
|
62
|
+
parts.push(`[User]: ${text}`);
|
|
63
|
+
}
|
|
64
|
+
else if (m.role === "assistant") {
|
|
65
|
+
const content = m.content;
|
|
66
|
+
if (!Array.isArray(content))
|
|
67
|
+
continue;
|
|
68
|
+
const textParts = [];
|
|
69
|
+
const thinkingParts = [];
|
|
70
|
+
const toolCalls = [];
|
|
71
|
+
for (const block of content) {
|
|
72
|
+
if (typeof block !== "object" || block === null || !("type" in block))
|
|
73
|
+
continue;
|
|
74
|
+
const b = block;
|
|
75
|
+
if (b.type === "text" && typeof b.text === "string") {
|
|
76
|
+
textParts.push(b.text);
|
|
77
|
+
}
|
|
78
|
+
else if (b.type === "thinking" && typeof b.thinking === "string") {
|
|
79
|
+
thinkingParts.push(b.thinking);
|
|
80
|
+
}
|
|
81
|
+
else if (b.type === "toolCall" && typeof b.name === "string") {
|
|
82
|
+
const args = (b.arguments ?? {});
|
|
83
|
+
const argsStr = Object.entries(args)
|
|
84
|
+
.map(([k, v]) => `${k}=${JSON.stringify(v)}`)
|
|
85
|
+
.join(", ");
|
|
86
|
+
toolCalls.push(`${b.name}(${argsStr})`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (thinkingParts.length > 0) {
|
|
90
|
+
parts.push(`[Assistant thinking]: ${thinkingParts.join("\n")}`);
|
|
91
|
+
}
|
|
92
|
+
if (textParts.length > 0) {
|
|
93
|
+
parts.push(`[Assistant]: ${textParts.join("\n")}`);
|
|
94
|
+
}
|
|
95
|
+
if (toolCalls.length > 0) {
|
|
96
|
+
parts.push(`[Assistant tool calls]: ${toolCalls.join("; ")}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (m.role === "toolResult") {
|
|
100
|
+
const text = extractTextContent(m.content);
|
|
101
|
+
if (text) {
|
|
102
|
+
parts.push(`[Tool result]: ${truncateForSummary(text, TOOL_RESULT_MAX_CHARS)}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return parts.join("\n\n");
|
|
107
|
+
}
|
|
108
|
+
// -- Public API --------------------------------------------------------------
|
|
109
|
+
/**
|
|
110
|
+
* Serialize session messages for wiki capture.
|
|
111
|
+
*
|
|
112
|
+
* Converts AgentMessage[] to a text representation that prevents the LLM
|
|
113
|
+
* from treating it as a conversation to continue. Uses pi's convertToLlm +
|
|
114
|
+
* serializeConversation when the messages contain pi-specific types
|
|
115
|
+
* (bashExecution, compactionSummary, branchSummary, etc.). Falls back to
|
|
116
|
+
* a compatible reimplementation for plain user/assistant/toolResult messages.
|
|
117
|
+
*
|
|
118
|
+
* @param messages - AgentMessage[] from @mariozechner/pi-agent-core
|
|
119
|
+
* @returns Serialized text in [User]: / [Assistant]: / [Tool result]: format
|
|
120
|
+
*/
|
|
121
|
+
export function serializeSessionForWiki(messages) {
|
|
122
|
+
// Use pi's convertToLlm to handle custom message types (bashExecution,
|
|
123
|
+
// compactionSummary, branchSummary, etc.), then serialize the resulting
|
|
124
|
+
// standard LLM messages.
|
|
125
|
+
try {
|
|
126
|
+
const llmMessages = convertToLlm(messages);
|
|
127
|
+
return serializeConversation(llmMessages);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// If convertToLlm fails (e.g., unexpected message shapes), fall back
|
|
131
|
+
// to our reimplementation that handles the base roles.
|
|
132
|
+
return serializeMessagesFallback(messages);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Generate a wiki-format summary prompt from raw content.
|
|
137
|
+
*
|
|
138
|
+
* Returns the prompt string to send to the LLM. The caller passes this
|
|
139
|
+
* to a standalone Agent or includes it in a tool result for the session agent.
|
|
140
|
+
*
|
|
141
|
+
* @param content - Source text, serialized conversation, or page content
|
|
142
|
+
* @param options - Summarization mode and context
|
|
143
|
+
* @returns Prompt string for the LLM
|
|
144
|
+
*/
|
|
145
|
+
export function generateSummary(content, options) {
|
|
146
|
+
const scopeInfo = `Current scope: ${options.scope.name} (tags: ${options.scope.include.join(", ")})`;
|
|
147
|
+
const categoryHint = options.category ? `\nSuggested PARA category: ${options.category}` : "";
|
|
148
|
+
switch (options.mode) {
|
|
149
|
+
case "ingest":
|
|
150
|
+
return [
|
|
151
|
+
SUMMARIZE_SYSTEM_PROMPT,
|
|
152
|
+
"",
|
|
153
|
+
scopeInfo,
|
|
154
|
+
categoryHint,
|
|
155
|
+
"",
|
|
156
|
+
"Produce a wiki page from the following source material:",
|
|
157
|
+
"",
|
|
158
|
+
"<source-content>",
|
|
159
|
+
content,
|
|
160
|
+
"</source-content>",
|
|
161
|
+
].join("\n");
|
|
162
|
+
case "session":
|
|
163
|
+
return [
|
|
164
|
+
CAPTURE_PROMPT,
|
|
165
|
+
content,
|
|
166
|
+
"</session-conversation>",
|
|
167
|
+
].join("\n");
|
|
168
|
+
case "page":
|
|
169
|
+
return [
|
|
170
|
+
SUMMARIZE_SYSTEM_PROMPT,
|
|
171
|
+
"",
|
|
172
|
+
scopeInfo,
|
|
173
|
+
"",
|
|
174
|
+
"Summarize the following wiki page into a concise overview:",
|
|
175
|
+
"",
|
|
176
|
+
"<page-content>",
|
|
177
|
+
content,
|
|
178
|
+
"</page-content>",
|
|
179
|
+
].join("\n");
|
|
180
|
+
case "iterative":
|
|
181
|
+
if (!options.existingContent) {
|
|
182
|
+
// No existing content — treat as a fresh page
|
|
183
|
+
return generateSummary(content, { ...options, mode: "ingest" });
|
|
184
|
+
}
|
|
185
|
+
return [
|
|
186
|
+
ITERATIVE_UPDATE_PROMPT,
|
|
187
|
+
"",
|
|
188
|
+
scopeInfo,
|
|
189
|
+
categoryHint,
|
|
190
|
+
"",
|
|
191
|
+
"<existing-page>",
|
|
192
|
+
options.existingContent,
|
|
193
|
+
"</existing-page>",
|
|
194
|
+
"",
|
|
195
|
+
"<new-content>",
|
|
196
|
+
content,
|
|
197
|
+
"</new-content>",
|
|
198
|
+
].join("\n");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Generate an overview prompt from multiple wiki pages.
|
|
203
|
+
*
|
|
204
|
+
* Used by /wiki-summarize and wiki_summarize tool to produce high-level
|
|
205
|
+
* overviews of a category or the entire wiki.
|
|
206
|
+
*
|
|
207
|
+
* @param pages - Wiki pages to summarize
|
|
208
|
+
* @param scope - Current project scope for context
|
|
209
|
+
* @returns Prompt string for the LLM
|
|
210
|
+
*/
|
|
211
|
+
export function generateOverviewPrompt(pages, scope) {
|
|
212
|
+
const scopeInfo = `Current scope: ${scope.name} (tags: ${scope.include.join(", ")})`;
|
|
213
|
+
const pageEntries = pages.map((page) => {
|
|
214
|
+
const fm = page.frontmatter;
|
|
215
|
+
return [
|
|
216
|
+
`### ${fm.title} (${page.category}/${page.slug})`,
|
|
217
|
+
`PARA: ${fm.para} | Scope: ${fm.scope.join(", ")} | Tags: ${fm.tags.join(", ")}`,
|
|
218
|
+
"",
|
|
219
|
+
page.body,
|
|
220
|
+
].join("\n");
|
|
221
|
+
});
|
|
222
|
+
return [
|
|
223
|
+
OVERVIEW_PROMPT,
|
|
224
|
+
"",
|
|
225
|
+
scopeInfo,
|
|
226
|
+
`Total pages: ${pages.length}`,
|
|
227
|
+
"",
|
|
228
|
+
...pageEntries,
|
|
229
|
+
].join("\n");
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=summarize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarize.js","sourceRoot":"","sources":["../src/summarize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical tag registry — normalizes and deduplicates wiki page tags.
|
|
3
|
+
*
|
|
4
|
+
* Rules:
|
|
5
|
+
* 1. Spaces → hyphens ("session files" → "session-files")
|
|
6
|
+
* 2. Lowercase everything
|
|
7
|
+
* 3. Map aliases → canonical tags
|
|
8
|
+
* 4. Remove tags that duplicate scope values on the same page
|
|
9
|
+
* 5. Deduplicate
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Normalize a scope value.
|
|
13
|
+
*
|
|
14
|
+
* Scope should be a project name (kebab-case, single token), not a topic
|
|
15
|
+
* description. The daemon LLM sometimes writes freeform multi-word
|
|
16
|
+
* descriptions like "session exploration" or "mono project" as scope.
|
|
17
|
+
*
|
|
18
|
+
* Rules:
|
|
19
|
+
* 1. Trim + lowercase
|
|
20
|
+
* 2. If the value contains a known project name as a prefix, extract it
|
|
21
|
+
* (e.g. "pi-para daemon" → "pi-para", "pi-mono project" → "pi-mono")
|
|
22
|
+
* 3. If still multi-word after extraction, drop it — it's a topic
|
|
23
|
+
* description, not a project name
|
|
24
|
+
* 4. Return the clean kebab-case scope
|
|
25
|
+
*
|
|
26
|
+
* This is project-agnostic — works for any project, not just pi-para.
|
|
27
|
+
*/
|
|
28
|
+
export declare function normalizeScope(scope: string): string | null;
|
|
29
|
+
/**
|
|
30
|
+
* Normalize a full scope list:
|
|
31
|
+
* 1. Normalize each value
|
|
32
|
+
* 2. Deduplicate
|
|
33
|
+
* 3. Ensure at least one scope remains (fallback to "global")
|
|
34
|
+
*/
|
|
35
|
+
export declare function normalizeScopes(scopes: string[]): string[];
|
|
36
|
+
/**
|
|
37
|
+
* Normalize a single tag:
|
|
38
|
+
* 1. Trim + lowercase
|
|
39
|
+
* 2. Spaces → hyphens
|
|
40
|
+
* 3. Resolve alias → canonical
|
|
41
|
+
*/
|
|
42
|
+
export declare function normalizeTag(tag: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Normalize a full tag list for a page, given its scope.
|
|
45
|
+
*
|
|
46
|
+
* 1. Normalize each tag
|
|
47
|
+
* 2. Remove tags that exactly match a scope value
|
|
48
|
+
* 3. Deduplicate
|
|
49
|
+
* 4. Sort alphabetically
|
|
50
|
+
*/
|
|
51
|
+
export declare function normalizeTags(tags: string[], scope: string[]): string[];
|
|
52
|
+
/**
|
|
53
|
+
* Get the full alias map for external inspection (e.g., lint reporting).
|
|
54
|
+
*/
|
|
55
|
+
export declare function getAliasMap(): ReadonlyMap<string, string>;
|
|
56
|
+
//# sourceMappingURL=tag-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag-registry.d.ts","sourceRoot":"","sources":["../src/tag-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmB3D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAQ1D;AAkDD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAavE;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAEzD"}
|