poe-code 3.0.183 → 3.0.185
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/dist/cli/commands/configure-payload.d.ts +2 -1
- package/dist/cli/commands/configure-payload.js +4 -2
- package/dist/cli/commands/configure-payload.js.map +1 -1
- package/dist/cli/commands/configure.d.ts +1 -0
- package/dist/cli/commands/configure.js +50 -11
- package/dist/cli/commands/configure.js.map +1 -1
- package/dist/cli/commands/ensure-isolated-config.js +24 -2
- package/dist/cli/commands/ensure-isolated-config.js.map +1 -1
- package/dist/cli/commands/experiment.js +15 -2
- package/dist/cli/commands/experiment.js.map +1 -1
- package/dist/cli/commands/login.js +8 -4
- package/dist/cli/commands/login.js.map +1 -1
- package/dist/cli/commands/memory.js +16 -7
- package/dist/cli/commands/memory.js.map +1 -1
- package/dist/cli/commands/pipeline-init.d.ts +0 -1
- package/dist/cli/commands/pipeline-init.js +32 -46
- package/dist/cli/commands/pipeline-init.js.map +1 -1
- package/dist/cli/commands/pipeline.js +97 -41
- package/dist/cli/commands/pipeline.js.map +1 -1
- package/dist/cli/commands/provider.d.ts +6 -0
- package/dist/cli/commands/provider.js +100 -0
- package/dist/cli/commands/provider.js.map +1 -0
- package/dist/cli/commands/shared.d.ts +7 -0
- package/dist/cli/commands/shared.js +3 -0
- package/dist/cli/commands/shared.js.map +1 -1
- package/dist/cli/commands/test.js +1 -1
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/unconfigure.js +12 -3
- package/dist/cli/commands/unconfigure.js.map +1 -1
- package/dist/cli/container.d.ts +2 -0
- package/dist/cli/container.js +3 -0
- package/dist/cli/container.js.map +1 -1
- package/dist/cli/isolated-env-runner.js +2 -2
- package/dist/cli/isolated-env-runner.js.map +1 -1
- package/dist/cli/isolated-env.d.ts +3 -2
- package/dist/cli/isolated-env.js +31 -40
- package/dist/cli/isolated-env.js.map +1 -1
- package/dist/cli/poe-code-command-runner.js +9 -2
- package/dist/cli/poe-code-command-runner.js.map +1 -1
- package/dist/cli/program.js +5 -0
- package/dist/cli/program.js.map +1 -1
- package/dist/cli/service-registry.d.ts +7 -7
- package/dist/cli/service-registry.js.map +1 -1
- package/dist/index.js +2965 -1968
- package/dist/index.js.map +4 -4
- package/dist/providers/claude-code.d.ts +2 -1
- package/dist/providers/claude-code.js +5 -5
- package/dist/providers/claude-code.js.map +2 -2
- package/dist/providers/codex.d.ts +5 -1
- package/dist/providers/codex.js +39 -12
- package/dist/providers/codex.js.map +2 -2
- package/dist/providers/goose.d.ts +2 -1
- package/dist/providers/goose.js +24 -8
- package/dist/providers/goose.js.map +3 -3
- package/dist/providers/kimi.js +3 -3
- package/dist/providers/kimi.js.map +3 -3
- package/dist/providers/opencode.js +2 -2
- package/dist/providers/opencode.js.map +3 -3
- package/dist/providers/poe-agent.js +786 -653
- package/dist/providers/poe-agent.js.map +4 -4
- package/dist/sdk/container.js +3 -0
- package/dist/sdk/container.js.map +1 -1
- package/dist/sdk/pipeline.d.ts +1 -2
- package/dist/sdk/pipeline.js +58 -9
- package/dist/sdk/pipeline.js.map +1 -1
- package/dist/services/config.d.ts +1 -0
- package/dist/services/config.js +27 -2
- package/dist/services/config.js.map +1 -1
- package/dist/templates/pipeline/SKILL_plan.md +7 -20
- package/dist/templates/pipeline/steps.yaml.mustache +5 -2
- package/package.json +10 -1
- package/packages/agent-mcp-config/dist/apply.d.ts +6 -0
- package/packages/agent-mcp-config/dist/apply.js +175 -0
- package/packages/agent-mcp-config/dist/configs.d.ts +22 -0
- package/packages/agent-mcp-config/dist/configs.js +74 -0
- package/packages/agent-mcp-config/dist/index.d.ts +3 -0
- package/packages/agent-mcp-config/dist/index.js +2 -0
- package/packages/agent-mcp-config/dist/shapes.d.ts +31 -0
- package/packages/agent-mcp-config/dist/shapes.js +87 -0
- package/packages/agent-mcp-config/dist/types.d.ts +25 -0
- package/packages/agent-mcp-config/dist/types.js +1 -0
- package/packages/agent-skill-config/dist/apply.d.ts +25 -0
- package/packages/agent-skill-config/dist/apply.js +109 -0
- package/packages/agent-skill-config/dist/configs.d.ts +16 -0
- package/packages/agent-skill-config/dist/configs.js +66 -0
- package/packages/agent-skill-config/dist/exports.compile-check.d.ts +1 -0
- package/packages/agent-skill-config/dist/exports.compile-check.js +1 -0
- package/packages/agent-skill-config/dist/index.d.ts +5 -0
- package/packages/agent-skill-config/dist/index.js +2 -0
- package/packages/agent-skill-config/dist/templates/poe-generate.md +47 -0
- package/packages/agent-skill-config/dist/templates/terminal-pilot.md +45 -0
- package/packages/agent-skill-config/dist/templates.d.ts +3 -0
- package/packages/agent-skill-config/dist/templates.js +63 -0
- package/packages/agent-skill-config/dist/types.d.ts +16 -0
- package/packages/agent-skill-config/dist/types.js +1 -0
- package/packages/cmdkit/dist/cli.js +7 -2
- package/packages/cmdkit/dist/cli.js.map +2 -2
- package/packages/config-mutations/dist/execution/apply-mutation.d.ts +5 -0
- package/packages/config-mutations/dist/execution/apply-mutation.js +552 -0
- package/packages/config-mutations/dist/execution/path-utils.d.ts +17 -0
- package/packages/config-mutations/dist/execution/path-utils.js +58 -0
- package/packages/config-mutations/dist/execution/run-mutations.d.ts +7 -0
- package/packages/config-mutations/dist/execution/run-mutations.js +46 -0
- package/packages/config-mutations/dist/formats/index.d.ts +13 -0
- package/packages/config-mutations/dist/formats/index.js +49 -0
- package/packages/config-mutations/dist/formats/json.d.ts +31 -0
- package/packages/config-mutations/dist/formats/json.js +140 -0
- package/packages/config-mutations/dist/formats/toml.d.ts +2 -0
- package/packages/config-mutations/dist/formats/toml.js +72 -0
- package/packages/config-mutations/dist/formats/yaml.d.ts +2 -0
- package/packages/config-mutations/dist/formats/yaml.js +73 -0
- package/packages/config-mutations/dist/fs-utils.d.ts +18 -0
- package/packages/config-mutations/dist/fs-utils.js +45 -0
- package/packages/config-mutations/dist/index.d.ts +8 -0
- package/packages/config-mutations/dist/index.js +8 -0
- package/packages/config-mutations/dist/mutations/config-mutation.d.ts +47 -0
- package/packages/config-mutations/dist/mutations/config-mutation.js +34 -0
- package/packages/config-mutations/dist/mutations/file-mutation.d.ts +52 -0
- package/packages/config-mutations/dist/mutations/file-mutation.js +46 -0
- package/packages/config-mutations/dist/mutations/template-mutation.d.ts +40 -0
- package/packages/config-mutations/dist/mutations/template-mutation.js +32 -0
- package/packages/config-mutations/dist/template/render.d.ts +7 -0
- package/packages/config-mutations/dist/template/render.js +28 -0
- package/packages/config-mutations/dist/testing/format-utils.d.ts +7 -0
- package/packages/config-mutations/dist/testing/format-utils.js +21 -0
- package/packages/config-mutations/dist/testing/index.d.ts +3 -0
- package/packages/config-mutations/dist/testing/index.js +2 -0
- package/packages/config-mutations/dist/testing/mock-fs.d.ts +25 -0
- package/packages/config-mutations/dist/testing/mock-fs.js +170 -0
- package/packages/config-mutations/dist/types.d.ts +156 -0
- package/packages/config-mutations/dist/types.js +6 -0
- package/packages/design-system/dist/dashboard/components/stats-pane.js +2 -1
- package/packages/design-system/dist/dashboard/types.d.ts +1 -0
- package/packages/memory/dist/audit.d.ts +11 -0
- package/packages/memory/dist/audit.js +131 -0
- package/packages/memory/dist/cache.cli.d.ts +9 -0
- package/packages/memory/dist/cache.cli.js +24 -0
- package/packages/memory/dist/cache.d.ts +14 -0
- package/packages/memory/dist/cache.js +149 -0
- package/packages/memory/dist/confidence.d.ts +4 -0
- package/packages/memory/dist/confidence.js +201 -0
- package/packages/memory/dist/corpus/001-archaeoastronomy.md +479 -0
- package/packages/memory/dist/corpus/002-magnetohydrodynamics.md +475 -0
- package/packages/memory/dist/corpus/003-biosemiotics.md +483 -0
- package/packages/memory/dist/corpus/004-cryopedology.md +483 -0
- package/packages/memory/dist/corpus/005-geomicrobiology.md +479 -0
- package/packages/memory/dist/corpus/006-aeronomy.md +487 -0
- package/packages/memory/dist/corpus/007-paleoclimatology.md +479 -0
- package/packages/memory/dist/corpus/008-hydrogeophysics.md +479 -0
- package/packages/memory/dist/corpus/009-magnetostratigraphy.md +475 -0
- package/packages/memory/dist/corpus/010-isotope-hydrology.md +481 -0
- package/packages/memory/dist/corpus/011-speleothem-geochemistry.md +474 -0
- package/packages/memory/dist/corpus/012-astrobiogeochemistry.md +475 -0
- package/packages/memory/dist/corpus/013-neuroethology.md +483 -0
- package/packages/memory/dist/corpus/014-chronophysiology.md +483 -0
- package/packages/memory/dist/corpus/015-limnogeochemistry.md +475 -0
- package/packages/memory/dist/corpus/016-palynology.md +483 -0
- package/packages/memory/dist/corpus/017-volcanotectonics.md +473 -0
- package/packages/memory/dist/corpus/018-seismotectonics.md +473 -0
- package/packages/memory/dist/corpus/019-biogeomorphology.md +475 -0
- package/packages/memory/dist/corpus/020-geobiophysics.md +479 -0
- package/packages/memory/dist/corpus/021-phytolith-analysis.md +481 -0
- package/packages/memory/dist/corpus/022-archaeometallurgy.md +479 -0
- package/packages/memory/dist/corpus/023-paleomagnetism.md +479 -0
- package/packages/memory/dist/corpus/024-biocalorimetry.md +475 -0
- package/packages/memory/dist/corpus/025-atmospheric-chemiluminescence.md +473 -0
- package/packages/memory/dist/corpus/026-cryoseismology.md +479 -0
- package/packages/memory/dist/corpus/027-extremophile-radiobiology.md +475 -0
- package/packages/memory/dist/corpus/028-heliophysics.md +479 -0
- package/packages/memory/dist/corpus/029-astroparticle-geophysics.md +474 -0
- package/packages/memory/dist/corpus/030-glaciohydrology.md +479 -0
- package/packages/memory/dist/corpus/031-permafrost-microbiology.md +477 -0
- package/packages/memory/dist/corpus/032-ecoacoustics.md +479 -0
- package/packages/memory/dist/corpus/033-dendroclimatology.md +473 -0
- package/packages/memory/dist/corpus/034-ionospheric-tomography.md +477 -0
- package/packages/memory/dist/corpus/035-marine-geodesy.md +481 -0
- package/packages/memory/dist/corpus/036-sedimentary-ancient-dna.md +481 -0
- package/packages/memory/dist/corpus/037-myrmecochory-dynamics.md +474 -0
- package/packages/memory/dist/corpus/038-chemosensory-ecology.md +477 -0
- package/packages/memory/dist/corpus/039-spintronics-materials.md +479 -0
- package/packages/memory/dist/corpus/040-nanotoxicology.md +483 -0
- package/packages/memory/dist/corpus/041-cosmochemistry.md +483 -0
- package/packages/memory/dist/corpus/042-quaternary-geochronology.md +471 -0
- package/packages/memory/dist/corpus/043-biophotonics.md +479 -0
- package/packages/memory/dist/corpus/044-evolutionary-morphometrics.md +481 -0
- package/packages/memory/dist/corpus/045-cryovolcanology.md +475 -0
- package/packages/memory/dist/corpus/046-exoplanet-atmospheric-dynamics.md +479 -0
- package/packages/memory/dist/corpus/047-microbial-electrosynthesis.md +477 -0
- package/packages/memory/dist/corpus/048-paleoseismology.md +479 -0
- package/packages/memory/dist/corpus/049-actinide-geochemistry.md +477 -0
- package/packages/memory/dist/corpus/050-quantum-biology.md +489 -0
- package/packages/memory/dist/edit.d.ts +10 -0
- package/packages/memory/dist/edit.js +43 -0
- package/packages/memory/dist/explain.cli.d.ts +8 -0
- package/packages/memory/dist/explain.cli.js +9 -0
- package/packages/memory/dist/explain.d.ts +8 -0
- package/packages/memory/dist/explain.js +77 -0
- package/packages/memory/dist/frontmatter.d.ts +9 -0
- package/packages/memory/dist/frontmatter.js +217 -0
- package/packages/memory/dist/index.d.ts +21 -0
- package/packages/memory/dist/index.js +4807 -0
- package/packages/memory/dist/index.js.map +7 -0
- package/packages/memory/dist/ingest.d.ts +3 -0
- package/packages/memory/dist/ingest.js +118 -0
- package/packages/memory/dist/init.d.ts +2 -0
- package/packages/memory/dist/init.js +24 -0
- package/packages/memory/dist/install.d.ts +18 -0
- package/packages/memory/dist/install.js +50 -0
- package/packages/memory/dist/lock.d.ts +19 -0
- package/packages/memory/dist/lock.js +102 -0
- package/packages/memory/dist/mcp.d.ts +7 -0
- package/packages/memory/dist/mcp.js +58 -0
- package/packages/memory/dist/pages.d.ts +4 -0
- package/packages/memory/dist/pages.js +92 -0
- package/packages/memory/dist/paths.d.ts +12 -0
- package/packages/memory/dist/paths.js +34 -0
- package/packages/memory/dist/query.d.ts +10 -0
- package/packages/memory/dist/query.js +130 -0
- package/packages/memory/dist/reconcile.d.ts +9 -0
- package/packages/memory/dist/reconcile.js +138 -0
- package/packages/memory/dist/resolve-root.d.ts +11 -0
- package/packages/memory/dist/resolve-root.js +22 -0
- package/packages/memory/dist/search.d.ts +2 -0
- package/packages/memory/dist/search.js +29 -0
- package/packages/memory/dist/status.d.ts +7 -0
- package/packages/memory/dist/status.js +46 -0
- package/packages/memory/dist/tokens.d.ts +2 -0
- package/packages/memory/dist/tokens.js +71 -0
- package/packages/memory/dist/types.d.ts +155 -0
- package/packages/memory/dist/types.js +1 -0
- package/packages/memory/dist/write.d.ts +9 -0
- package/packages/memory/dist/write.js +76 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MemoryDiff, MemoryRoot } from "./types.js";
|
|
2
|
+
export type EditPageOptions = {
|
|
3
|
+
reason: string;
|
|
4
|
+
launchEditor: (filePath: string) => Promise<void>;
|
|
5
|
+
};
|
|
6
|
+
export type EditPageResult = {
|
|
7
|
+
changed: boolean;
|
|
8
|
+
diff?: MemoryDiff;
|
|
9
|
+
};
|
|
10
|
+
export declare function editPage(root: MemoryRoot, relPath: string, opts: EditPageOptions): Promise<EditPageResult>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parseFrontmatter } from "./frontmatter.js";
|
|
4
|
+
import { writePage } from "./write.js";
|
|
5
|
+
export async function editPage(root, relPath, opts) {
|
|
6
|
+
const pagePath = path.join(root, relPath);
|
|
7
|
+
const original = await readIfPresent(pagePath);
|
|
8
|
+
const tempRoot = path.join(root, ".tmp");
|
|
9
|
+
await fs.mkdir(tempRoot, { recursive: true });
|
|
10
|
+
const tempDir = await fs.mkdtemp(path.join(tempRoot, "poe-code-memory-edit-"));
|
|
11
|
+
const tempPath = path.join(tempDir, path.basename(relPath));
|
|
12
|
+
try {
|
|
13
|
+
await fs.writeFile(tempPath, original ?? "", "utf8");
|
|
14
|
+
await opts.launchEditor(tempPath);
|
|
15
|
+
const edited = await fs.readFile(tempPath, "utf8");
|
|
16
|
+
if (edited === (original ?? "")) {
|
|
17
|
+
return { changed: false };
|
|
18
|
+
}
|
|
19
|
+
const parsed = parseFrontmatter(edited);
|
|
20
|
+
const diff = await writePage(root, relPath, parsed.body, {
|
|
21
|
+
frontmatter: parsed.frontmatter,
|
|
22
|
+
reason: opts.reason
|
|
23
|
+
});
|
|
24
|
+
return {
|
|
25
|
+
changed: true,
|
|
26
|
+
diff
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async function readIfPresent(filePath) {
|
|
34
|
+
try {
|
|
35
|
+
return await fs.readFile(filePath, "utf8");
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ExplainResult, MemoryRoot, SpawnFn } from "./types.js";
|
|
2
|
+
export type ExplainOptions = {
|
|
3
|
+
relPath: string;
|
|
4
|
+
budget: number;
|
|
5
|
+
agent?: string;
|
|
6
|
+
spawnFn?: SpawnFn;
|
|
7
|
+
};
|
|
8
|
+
export declare function explainPage(root: MemoryRoot, options: ExplainOptions): Promise<ExplainResult>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { countTokens } from "tokenfill";
|
|
2
|
+
import { readPage } from "./pages.js";
|
|
3
|
+
import { queryMemory, selectQueryContext } from "./query.js";
|
|
4
|
+
export async function explainPage(root, options) {
|
|
5
|
+
const targetPage = await readPageIfPresent(root, options.relPath);
|
|
6
|
+
if (targetPage === undefined) {
|
|
7
|
+
return {
|
|
8
|
+
answer: "",
|
|
9
|
+
citations: [],
|
|
10
|
+
tokensUsed: 0,
|
|
11
|
+
budget: options.budget,
|
|
12
|
+
exitCode: 0,
|
|
13
|
+
inboundPages: [],
|
|
14
|
+
outboundSources: []
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const allContext = await selectQueryContext(root, options.relPath, Number.MAX_SAFE_INTEGER);
|
|
18
|
+
const relatedPages = collectRelatedPages(allContext.selectedPages, targetPage.relPath, targetPage.frontmatter.sources ?? []);
|
|
19
|
+
const prompt = buildExplainPrompt(targetPage.relPath, relatedPages);
|
|
20
|
+
const tokensUsed = countTokens(prompt);
|
|
21
|
+
if (tokensUsed > options.budget) {
|
|
22
|
+
throw new Error(`budget too small; needs at least ${tokensUsed} tokens`);
|
|
23
|
+
}
|
|
24
|
+
const spawnFn = options.spawnFn;
|
|
25
|
+
const response = await queryMemory(root, {
|
|
26
|
+
question: `explain ${options.relPath}`,
|
|
27
|
+
budget: options.budget,
|
|
28
|
+
agent: options.agent,
|
|
29
|
+
spawnFn: spawnFn === undefined ? undefined : async (...args) => {
|
|
30
|
+
const [agent] = args;
|
|
31
|
+
return spawnFn(agent, prompt);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
...response,
|
|
36
|
+
inboundPages: relatedPages
|
|
37
|
+
.filter((page) => page.relPath !== targetPage.relPath)
|
|
38
|
+
.filter((page) => (page.frontmatter.sources ?? []).some((source) => source.path === targetPage.relPath))
|
|
39
|
+
.map((page) => page.relPath),
|
|
40
|
+
outboundSources: targetPage.frontmatter.sources ?? []
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function collectRelatedPages(pages, targetRelPath, outboundSources) {
|
|
44
|
+
const memorySourcePaths = new Set(outboundSources.map((source) => source.path));
|
|
45
|
+
return pages.filter((page) => {
|
|
46
|
+
if (page.relPath === targetRelPath) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
if (memorySourcePaths.has(page.relPath)) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
return (page.frontmatter.sources ?? []).some((source) => source.path === targetRelPath);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function buildExplainPrompt(targetRelPath, pages) {
|
|
56
|
+
return [
|
|
57
|
+
"Summarize the target page using only the provided memory pages.",
|
|
58
|
+
"Return a 1-2 paragraph explanation plus the important inbound/outbound links.",
|
|
59
|
+
"Cite pages and sections with [rel_path §section]. If memory is insufficient, say so.",
|
|
60
|
+
"No tools are available.",
|
|
61
|
+
"",
|
|
62
|
+
`Target page: ${targetRelPath}`,
|
|
63
|
+
"",
|
|
64
|
+
...pages.map((page) => [`FILE: ${page.relPath}`, page.body].join("\n"))
|
|
65
|
+
].join("\n\n");
|
|
66
|
+
}
|
|
67
|
+
async function readPageIfPresent(root, relPath) {
|
|
68
|
+
try {
|
|
69
|
+
return await readPage(root, relPath);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PageFrontmatter, SourceRef } from "./types.js";
|
|
2
|
+
export interface ParsedFrontmatter {
|
|
3
|
+
frontmatter: PageFrontmatter;
|
|
4
|
+
body: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function parseFrontmatter(markdown: string): ParsedFrontmatter;
|
|
7
|
+
export declare function serializeFrontmatter(frontmatter: PageFrontmatter, body: string): string;
|
|
8
|
+
export declare function parseSourceRef(serialized: string): SourceRef;
|
|
9
|
+
export declare function serializeSourceRef(source: SourceRef): string;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { parse, stringify } from "yaml";
|
|
2
|
+
export function parseFrontmatter(markdown) {
|
|
3
|
+
const content = markdown.startsWith("\uFEFF") ? markdown.slice(1) : markdown;
|
|
4
|
+
const openingLineBreak = readOpeningLineBreak(content);
|
|
5
|
+
if (openingLineBreak === undefined) {
|
|
6
|
+
return {
|
|
7
|
+
frontmatter: {},
|
|
8
|
+
body: markdown
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
const frontmatterStart = 3 + openingLineBreak.length;
|
|
12
|
+
const closingFenceIndex = findClosingFence(content, frontmatterStart);
|
|
13
|
+
const yamlBlock = content.slice(frontmatterStart, closingFenceIndex);
|
|
14
|
+
const bodyStart = closingFenceIndex + 4;
|
|
15
|
+
return {
|
|
16
|
+
frontmatter: parsePageFrontmatter(parseYamlFrontmatter(yamlBlock)),
|
|
17
|
+
body: readBody(content, bodyStart)
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function serializeFrontmatter(frontmatter, body) {
|
|
21
|
+
const serialized = {
|
|
22
|
+
...(frontmatter.name === undefined ? {} : { name: frontmatter.name }),
|
|
23
|
+
...(frontmatter.description === undefined ? {} : { description: frontmatter.description }),
|
|
24
|
+
...(frontmatter.lastTouchedAt === undefined
|
|
25
|
+
? {}
|
|
26
|
+
: { last_touched_at: frontmatter.lastTouchedAt }),
|
|
27
|
+
...(frontmatter.sources === undefined || frontmatter.sources.length === 0
|
|
28
|
+
? {}
|
|
29
|
+
: { sources: frontmatter.sources.map((source) => serializeSourceRef(source)) })
|
|
30
|
+
};
|
|
31
|
+
if (Object.keys(serialized).length === 0) {
|
|
32
|
+
return body;
|
|
33
|
+
}
|
|
34
|
+
return `---\n${stringify(serialized).trimEnd()}\n---\n${body}`;
|
|
35
|
+
}
|
|
36
|
+
export function parseSourceRef(serialized) {
|
|
37
|
+
const [rawPath, rawAnchor] = serialized.split("#", 2);
|
|
38
|
+
const normalizedPath = rawPath?.trim();
|
|
39
|
+
if (normalizedPath === undefined || normalizedPath.length === 0) {
|
|
40
|
+
throw new Error(`Invalid source ref "${serialized}".`);
|
|
41
|
+
}
|
|
42
|
+
if (rawAnchor === undefined) {
|
|
43
|
+
return { path: normalizedPath };
|
|
44
|
+
}
|
|
45
|
+
const singleLineMatch = /^L(\d+)$/.exec(rawAnchor);
|
|
46
|
+
if (singleLineMatch !== null) {
|
|
47
|
+
const startLine = Number.parseInt(singleLineMatch[1], 10);
|
|
48
|
+
assertValidLineNumber(startLine, serialized);
|
|
49
|
+
return {
|
|
50
|
+
path: normalizedPath,
|
|
51
|
+
startLine
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const rangeMatch = /^L(\d+)-L?(\d+)$/.exec(rawAnchor);
|
|
55
|
+
if (rangeMatch !== null) {
|
|
56
|
+
const startLine = Number.parseInt(rangeMatch[1], 10);
|
|
57
|
+
const endLine = Number.parseInt(rangeMatch[2], 10);
|
|
58
|
+
assertValidLineNumber(startLine, serialized);
|
|
59
|
+
assertValidLineNumber(endLine, serialized);
|
|
60
|
+
if (endLine < startLine) {
|
|
61
|
+
throw new Error(`Invalid source ref "${serialized}": line range is reversed.`);
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
path: normalizedPath,
|
|
65
|
+
startLine,
|
|
66
|
+
endLine
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
throw new Error(`Invalid source ref "${serialized}".`);
|
|
70
|
+
}
|
|
71
|
+
export function serializeSourceRef(source) {
|
|
72
|
+
if (source.path.trim().length === 0) {
|
|
73
|
+
throw new Error("Source path cannot be empty.");
|
|
74
|
+
}
|
|
75
|
+
if (source.startLine === undefined) {
|
|
76
|
+
if (source.endLine !== undefined) {
|
|
77
|
+
throw new Error("Source endLine requires startLine.");
|
|
78
|
+
}
|
|
79
|
+
return source.path;
|
|
80
|
+
}
|
|
81
|
+
assertValidLineNumber(source.startLine, source.path);
|
|
82
|
+
if (source.endLine === undefined) {
|
|
83
|
+
return `${source.path}#L${source.startLine}`;
|
|
84
|
+
}
|
|
85
|
+
assertValidLineNumber(source.endLine, source.path);
|
|
86
|
+
if (source.endLine < source.startLine) {
|
|
87
|
+
throw new Error(`Invalid source ref "${source.path}": line range is reversed.`);
|
|
88
|
+
}
|
|
89
|
+
return `${source.path}#L${source.startLine}-L${source.endLine}`;
|
|
90
|
+
}
|
|
91
|
+
function readOpeningLineBreak(markdown) {
|
|
92
|
+
if (!markdown.startsWith("---")) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
const nextCharacter = markdown[3];
|
|
96
|
+
if (nextCharacter === "\n") {
|
|
97
|
+
return "\n";
|
|
98
|
+
}
|
|
99
|
+
if (nextCharacter === "\r" && markdown[4] === "\n") {
|
|
100
|
+
return "\r\n";
|
|
101
|
+
}
|
|
102
|
+
return nextCharacter === undefined ? "\n" : undefined;
|
|
103
|
+
}
|
|
104
|
+
function findClosingFence(markdown, searchFrom) {
|
|
105
|
+
let currentIndex = searchFrom - 1;
|
|
106
|
+
while (currentIndex < markdown.length) {
|
|
107
|
+
const candidateIndex = markdown.indexOf("\n---", currentIndex);
|
|
108
|
+
if (candidateIndex === -1) {
|
|
109
|
+
throw new Error("Missing YAML frontmatter end delimiter (---).");
|
|
110
|
+
}
|
|
111
|
+
const fenceEnd = candidateIndex + 4;
|
|
112
|
+
const nextCharacter = markdown[fenceEnd];
|
|
113
|
+
if (nextCharacter === "\n" || nextCharacter === undefined) {
|
|
114
|
+
return candidateIndex;
|
|
115
|
+
}
|
|
116
|
+
if (nextCharacter === "\r" && markdown[fenceEnd + 1] === "\n") {
|
|
117
|
+
return candidateIndex;
|
|
118
|
+
}
|
|
119
|
+
currentIndex = fenceEnd;
|
|
120
|
+
}
|
|
121
|
+
throw new Error("Missing YAML frontmatter end delimiter (---).");
|
|
122
|
+
}
|
|
123
|
+
function readBody(markdown, bodyStart) {
|
|
124
|
+
const nextCharacter = markdown[bodyStart];
|
|
125
|
+
if (nextCharacter === "\n") {
|
|
126
|
+
return markdown.slice(bodyStart + 1);
|
|
127
|
+
}
|
|
128
|
+
if (nextCharacter === "\r" && markdown[bodyStart + 1] === "\n") {
|
|
129
|
+
return markdown.slice(bodyStart + 2);
|
|
130
|
+
}
|
|
131
|
+
return markdown.slice(bodyStart);
|
|
132
|
+
}
|
|
133
|
+
function parseYamlFrontmatter(yamlBlock) {
|
|
134
|
+
const normalizedYamlBlock = yamlBlock.includes("\r")
|
|
135
|
+
? yamlBlock.replaceAll("\r\n", "\n").replaceAll("\r", "")
|
|
136
|
+
: yamlBlock;
|
|
137
|
+
let parsed;
|
|
138
|
+
try {
|
|
139
|
+
parsed = parse(normalizedYamlBlock);
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
const message = error instanceof Error ? error.message : "Unknown YAML parse error";
|
|
143
|
+
throw new Error(`Invalid YAML frontmatter: ${message}`);
|
|
144
|
+
}
|
|
145
|
+
if (parsed === null) {
|
|
146
|
+
return {};
|
|
147
|
+
}
|
|
148
|
+
if (!isRecord(parsed)) {
|
|
149
|
+
throw new Error("YAML frontmatter must parse to an object.");
|
|
150
|
+
}
|
|
151
|
+
return parsed;
|
|
152
|
+
}
|
|
153
|
+
function parsePageFrontmatter(value) {
|
|
154
|
+
const name = readOptionalString(value.name, "name");
|
|
155
|
+
const description = readOptionalString(value.description, "description");
|
|
156
|
+
const lastTouchedAt = readOptionalString(value.last_touched_at ?? value.lastTouchedAt, "last_touched_at");
|
|
157
|
+
const sources = parseSources(value.sources);
|
|
158
|
+
return {
|
|
159
|
+
...(name === undefined ? {} : { name }),
|
|
160
|
+
...(description === undefined ? {} : { description }),
|
|
161
|
+
...(lastTouchedAt === undefined ? {} : { lastTouchedAt }),
|
|
162
|
+
...(sources === undefined ? {} : { sources })
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function parseSources(value) {
|
|
166
|
+
if (value === undefined) {
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
if (!Array.isArray(value)) {
|
|
170
|
+
throw new Error('Invalid "sources" frontmatter. Expected an array.');
|
|
171
|
+
}
|
|
172
|
+
return value.map((item) => {
|
|
173
|
+
if (typeof item === "string") {
|
|
174
|
+
return parseSourceRef(item);
|
|
175
|
+
}
|
|
176
|
+
if (!isRecord(item)) {
|
|
177
|
+
throw new Error('Invalid "sources" frontmatter. Expected each source to be a string or object.');
|
|
178
|
+
}
|
|
179
|
+
const path = readRequiredString(item.path, "sources[].path");
|
|
180
|
+
const startLine = readOptionalPositiveInteger(item.startLine, "sources[].startLine");
|
|
181
|
+
const endLine = readOptionalPositiveInteger(item.endLine, "sources[].endLine");
|
|
182
|
+
return parseSourceRef(serializeSourceRef({ path, ...(startLine === undefined ? {} : { startLine }), ...(endLine === undefined ? {} : { endLine }) }));
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
function readOptionalString(value, field) {
|
|
186
|
+
if (value === undefined || value === null) {
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
189
|
+
if (typeof value !== "string") {
|
|
190
|
+
throw new Error(`Invalid "${field}" frontmatter. Expected a string.`);
|
|
191
|
+
}
|
|
192
|
+
return value;
|
|
193
|
+
}
|
|
194
|
+
function readRequiredString(value, field) {
|
|
195
|
+
const parsed = readOptionalString(value, field);
|
|
196
|
+
if (parsed === undefined) {
|
|
197
|
+
throw new Error(`Invalid "${field}" frontmatter. Expected a string.`);
|
|
198
|
+
}
|
|
199
|
+
return parsed;
|
|
200
|
+
}
|
|
201
|
+
function readOptionalPositiveInteger(value, field) {
|
|
202
|
+
if (value === undefined || value === null) {
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
206
|
+
throw new Error(`Invalid "${field}" frontmatter. Expected a positive integer.`);
|
|
207
|
+
}
|
|
208
|
+
return value;
|
|
209
|
+
}
|
|
210
|
+
function assertValidLineNumber(line, value) {
|
|
211
|
+
if (!Number.isInteger(line) || line <= 0) {
|
|
212
|
+
throw new Error(`Invalid source ref "${value}": line numbers must be positive integers.`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function isRecord(value) {
|
|
216
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
217
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type { ConfidenceTag, ConfidenceVerb, ExplainResult, IndexEntry, IngestCacheEntry, IngestCacheKey, IngestOptions, IngestResult, IngestSource, LintOptions, LintResult, LogEntry, LogVerb, McpServerOptions, MemoryDiff, MemoryInstallResult, MemoryPage, MemoryRoot, MemorySnapshot, PageFrontmatter, PageWithClaims, QueryCitation, QueryOptions, QueryResult, SearchHit, SourceRef, SpawnFn, TaggedClaim, TokenStats } from "./types.js";
|
|
2
|
+
export { resolveMemoryRoot } from "./paths.js";
|
|
3
|
+
export { MEMORY_ROOT_ENV_VAR, resolveConfiguredMemoryRoot, type ResolveConfiguredMemoryRootOptions } from "./resolve-root.js";
|
|
4
|
+
export { initMemory } from "./init.js";
|
|
5
|
+
export { listPages, readPage } from "./pages.js";
|
|
6
|
+
export { searchMemory } from "./search.js";
|
|
7
|
+
export { statusOf } from "./status.js";
|
|
8
|
+
export { editPage } from "./edit.js";
|
|
9
|
+
export { appendToPage, clearMemory, writePage } from "./write.js";
|
|
10
|
+
export { reconcile, snapshot } from "./reconcile.js";
|
|
11
|
+
export { parseClaims, serializeTag } from "./confidence.js";
|
|
12
|
+
export { auditClaims } from "./audit.js";
|
|
13
|
+
export { clearCache, computeIngestKey, readCacheEntry, writeCacheEntry } from "./cache.js";
|
|
14
|
+
export { runMemoryCacheClear, runMemoryCacheStatus } from "./cache.cli.js";
|
|
15
|
+
export { ingest, INGEST_PROMPT_VERSION } from "./ingest.js";
|
|
16
|
+
export { computeTokenStats } from "./tokens.js";
|
|
17
|
+
export { startMemoryMcpServer, printMcpConfig } from "./mcp.js";
|
|
18
|
+
export { installMemory } from "./install.js";
|
|
19
|
+
export { queryMemory, rankPagesForQuery, selectQueryContext } from "./query.js";
|
|
20
|
+
export { explainPage } from "./explain.js";
|
|
21
|
+
export { runMemoryExplain } from "./explain.cli.js";
|