ricord 1.0.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/LICENSE +21 -0
- package/README.md +213 -0
- package/commands/ricord-flush.md +29 -0
- package/commands/ricord-init.md +129 -0
- package/commands/ricord-lint.md +64 -0
- package/commands/ricord-query.md +71 -0
- package/dist/cli/auth.d.ts +16 -0
- package/dist/cli/auth.js +42 -0
- package/dist/cli/auth.js.map +1 -0
- package/dist/cli/bundle.d.ts +25 -0
- package/dist/cli/bundle.js +179 -0
- package/dist/cli/bundle.js.map +1 -0
- package/dist/cli/cache.d.ts +18 -0
- package/dist/cli/cache.js +39 -0
- package/dist/cli/cache.js.map +1 -0
- package/dist/cli/cli.d.ts +21 -0
- package/dist/cli/cli.js +355 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/client.d.ts +12 -0
- package/dist/cli/client.js +35 -0
- package/dist/cli/client.js.map +1 -0
- package/dist/cli/commands/build.d.ts +44 -0
- package/dist/cli/commands/build.js +437 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/curate.d.ts +32 -0
- package/dist/cli/commands/curate.js +154 -0
- package/dist/cli/commands/curate.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +16 -0
- package/dist/cli/commands/doctor.js +92 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/ingest.d.ts +25 -0
- package/dist/cli/commands/ingest.js +121 -0
- package/dist/cli/commands/ingest.js.map +1 -0
- package/dist/cli/commands/install.d.ts +16 -0
- package/dist/cli/commands/install.js +82 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/pull.d.ts +24 -0
- package/dist/cli/commands/pull.js +104 -0
- package/dist/cli/commands/pull.js.map +1 -0
- package/dist/cli/commands/push.d.ts +28 -0
- package/dist/cli/commands/push.js +164 -0
- package/dist/cli/commands/push.js.map +1 -0
- package/dist/cli/commands/rollup.d.ts +21 -0
- package/dist/cli/commands/rollup.js +118 -0
- package/dist/cli/commands/rollup.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +7 -0
- package/dist/cli/commands/setup.js +43 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/sync.d.ts +15 -0
- package/dist/cli/commands/sync.js +63 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/commands/watch.d.ts +17 -0
- package/dist/cli/commands/watch.js +87 -0
- package/dist/cli/commands/watch.js.map +1 -0
- package/dist/cli/config.d.ts +29 -0
- package/dist/cli/config.js +52 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/extract.d.ts +101 -0
- package/dist/cli/extract.js +216 -0
- package/dist/cli/extract.js.map +1 -0
- package/dist/cli/ingest.d.ts +48 -0
- package/dist/cli/ingest.js +74 -0
- package/dist/cli/ingest.js.map +1 -0
- package/dist/cli/ledger.d.ts +44 -0
- package/dist/cli/ledger.js +67 -0
- package/dist/cli/ledger.js.map +1 -0
- package/dist/cli/llm.d.ts +21 -0
- package/dist/cli/llm.js +138 -0
- package/dist/cli/llm.js.map +1 -0
- package/dist/cli/parse.d.ts +13 -0
- package/dist/cli/parse.js +188 -0
- package/dist/cli/parse.js.map +1 -0
- package/dist/cli/run-explore.d.ts +56 -0
- package/dist/cli/run-explore.js +229 -0
- package/dist/cli/run-explore.js.map +1 -0
- package/dist/cli/summarize.d.ts +15 -0
- package/dist/cli/summarize.js +49 -0
- package/dist/cli/summarize.js.map +1 -0
- package/dist/cli/uninstall.d.ts +6 -0
- package/dist/cli/uninstall.js +277 -0
- package/dist/cli/uninstall.js.map +1 -0
- package/dist/cli/walk.d.ts +13 -0
- package/dist/cli/walk.js +62 -0
- package/dist/cli/walk.js.map +1 -0
- package/dist/cli/walker.d.ts +14 -0
- package/dist/cli/walker.js +120 -0
- package/dist/cli/walker.js.map +1 -0
- package/dist/hooks/pre-compact.d.ts +15 -0
- package/dist/hooks/pre-compact.js +127 -0
- package/dist/hooks/pre-compact.js.map +1 -0
- package/dist/hooks/pre-tool-use.d.ts +15 -0
- package/dist/hooks/pre-tool-use.js +25 -0
- package/dist/hooks/pre-tool-use.js.map +1 -0
- package/dist/hooks/session-end.d.ts +21 -0
- package/dist/hooks/session-end.js +186 -0
- package/dist/hooks/session-end.js.map +1 -0
- package/dist/hooks/session-start.d.ts +15 -0
- package/dist/hooks/session-start.js +233 -0
- package/dist/hooks/session-start.js.map +1 -0
- package/dist/hooks/turn-end-post.d.ts +17 -0
- package/dist/hooks/turn-end-post.js +66 -0
- package/dist/hooks/turn-end-post.js.map +1 -0
- package/dist/hooks/turn-end.d.ts +29 -0
- package/dist/hooks/turn-end.js +295 -0
- package/dist/hooks/turn-end.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +1547 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +45 -0
- package/dist/init.js +839 -0
- package/dist/init.js.map +1 -0
- package/dist/lib/active-project.d.ts +14 -0
- package/dist/lib/active-project.js +65 -0
- package/dist/lib/active-project.js.map +1 -0
- package/dist/lib/buffer.d.ts +34 -0
- package/dist/lib/buffer.js +79 -0
- package/dist/lib/buffer.js.map +1 -0
- package/dist/scripts/compile.d.ts +25 -0
- package/dist/scripts/compile.js +185 -0
- package/dist/scripts/compile.js.map +1 -0
- package/dist/scripts/config.d.ts +30 -0
- package/dist/scripts/config.js +68 -0
- package/dist/scripts/config.js.map +1 -0
- package/dist/scripts/flush.d.ts +23 -0
- package/dist/scripts/flush.js +230 -0
- package/dist/scripts/flush.js.map +1 -0
- package/dist/scripts/lint.d.ts +21 -0
- package/dist/scripts/lint.js +242 -0
- package/dist/scripts/lint.js.map +1 -0
- package/dist/scripts/utils.d.ts +43 -0
- package/dist/scripts/utils.js +165 -0
- package/dist/scripts/utils.js.map +1 -0
- package/package.json +74 -0
- package/scripts/postinstall.mjs +56 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin HTTP client for the Ricord API. Sends the API key as a Bearer
|
|
3
|
+
* token. The CLI doesn't ship Firebase auth — keys are the surface.
|
|
4
|
+
*
|
|
5
|
+
* `request` throws on non-2xx with a structured error message.
|
|
6
|
+
*/
|
|
7
|
+
export async function request(auth, path, init = {}) {
|
|
8
|
+
const headers = {
|
|
9
|
+
Authorization: `Bearer ${auth.apiKey}`,
|
|
10
|
+
"Content-Type": "application/json",
|
|
11
|
+
"User-Agent": "ricord-cli",
|
|
12
|
+
...init.headers,
|
|
13
|
+
};
|
|
14
|
+
const res = await fetch(`${auth.apiUrl}${path}`, { ...init, headers });
|
|
15
|
+
const text = await res.text();
|
|
16
|
+
let body = text;
|
|
17
|
+
if (text && res.headers.get("content-type")?.includes("application/json")) {
|
|
18
|
+
try {
|
|
19
|
+
body = JSON.parse(text);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// leave as text
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (!res.ok) {
|
|
26
|
+
const err = new Error(typeof body === "object" && body && "error" in body
|
|
27
|
+
? JSON.stringify(body.error)
|
|
28
|
+
: `HTTP ${res.status}`);
|
|
29
|
+
err.status = res.status;
|
|
30
|
+
err.body = body;
|
|
31
|
+
throw err;
|
|
32
|
+
}
|
|
33
|
+
return body;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,IAAkB,EAClB,IAAY,EACZ,OAAoB,EAAE;IAEtB,MAAM,OAAO,GAA2B;QACtC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;QACtC,cAAc,EAAE,kBAAkB;QAClC,YAAY,EAAE,YAAY;QAC1B,GAAI,IAAI,CAAC,OAA8C;KACxD,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,IAAI,GAAY,IAAI,CAAC;IACzB,IAAI,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC1E,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;QAClB,CAAC;IACH,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,IAAI,KAAK,CACnB,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI;YACjD,CAAC,CAAC,IAAI,CAAC,SAAS,CAAE,IAA2B,CAAC,KAAK,CAAC;YACpD,CAAC,CAAC,QAAQ,GAAG,CAAC,MAAM,EAAE,CACb,CAAC;QACd,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QACxB,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAChB,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,OAAO,IAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ricord build` — agentic wiki authoring via the local `claude` CLI.
|
|
3
|
+
*
|
|
4
|
+
* Spawns claude as a tool-using agent (Read/Write/Edit/Glob/Grep/Bash)
|
|
5
|
+
* with a brief mission: walk this repo, decide 10-20 page boundaries,
|
|
6
|
+
* write each as `.ricord/pages/<slug>.md`. Claude does the file
|
|
7
|
+
* walking + reading + writing itself; we only set up the workspace and
|
|
8
|
+
* scan results afterwards.
|
|
9
|
+
*
|
|
10
|
+
* Auto-initializes the workspace on first run: if `.ricord/ledger.json`
|
|
11
|
+
* is missing, derives a project_id from the git remote URL (or the
|
|
12
|
+
* directory basename as a fallback), writes the ledger, scaffolds
|
|
13
|
+
* `.ricord/pages/` + `.ricord/README.md`, then proceeds. Pass
|
|
14
|
+
* `--project <id>` to override the derivation; pass `--team <uuid>`
|
|
15
|
+
* to bind the directory to a team space at the same time.
|
|
16
|
+
*
|
|
17
|
+
* NO PAID-API FALLBACK by design. NO `--dangerously-skip-permissions`.
|
|
18
|
+
* Permission gate is `--allowedTools` — listed tools run without
|
|
19
|
+
* prompts, anything else would prompt and block, never destruct.
|
|
20
|
+
*
|
|
21
|
+
* See `_pinned_top_never_paid_api_for_heavy_work` memory.
|
|
22
|
+
*/
|
|
23
|
+
import { stat } from "node:fs/promises";
|
|
24
|
+
interface BuildOpts {
|
|
25
|
+
repoRoot: string;
|
|
26
|
+
projectId?: string;
|
|
27
|
+
/** Optional team UUID override for the chained --push. Falls back to
|
|
28
|
+
* ledger.team_id. Builds themselves are local-file generation only, so
|
|
29
|
+
* team_id only matters when --push is set. */
|
|
30
|
+
teamId?: string;
|
|
31
|
+
/** Force personal scope on the chained --push even if ledger has team_id. */
|
|
32
|
+
noTeam?: boolean;
|
|
33
|
+
/** dry run — print the mission + planned spawn, don't call claude */
|
|
34
|
+
dryRun: boolean;
|
|
35
|
+
/** Drop Bash from the toolset for paranoid environments */
|
|
36
|
+
safe: boolean;
|
|
37
|
+
/** Cap on agent turns */
|
|
38
|
+
maxTurns: number;
|
|
39
|
+
/** After a successful build, automatically `ricord push --all` so the
|
|
40
|
+
* cloud mirror catches up in one command. */
|
|
41
|
+
push: boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare function buildCommand(opts: BuildOpts): Promise<number>;
|
|
44
|
+
export { stat };
|
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ricord build` — agentic wiki authoring via the local `claude` CLI.
|
|
3
|
+
*
|
|
4
|
+
* Spawns claude as a tool-using agent (Read/Write/Edit/Glob/Grep/Bash)
|
|
5
|
+
* with a brief mission: walk this repo, decide 10-20 page boundaries,
|
|
6
|
+
* write each as `.ricord/pages/<slug>.md`. Claude does the file
|
|
7
|
+
* walking + reading + writing itself; we only set up the workspace and
|
|
8
|
+
* scan results afterwards.
|
|
9
|
+
*
|
|
10
|
+
* Auto-initializes the workspace on first run: if `.ricord/ledger.json`
|
|
11
|
+
* is missing, derives a project_id from the git remote URL (or the
|
|
12
|
+
* directory basename as a fallback), writes the ledger, scaffolds
|
|
13
|
+
* `.ricord/pages/` + `.ricord/README.md`, then proceeds. Pass
|
|
14
|
+
* `--project <id>` to override the derivation; pass `--team <uuid>`
|
|
15
|
+
* to bind the directory to a team space at the same time.
|
|
16
|
+
*
|
|
17
|
+
* NO PAID-API FALLBACK by design. NO `--dangerously-skip-permissions`.
|
|
18
|
+
* Permission gate is `--allowedTools` — listed tools run without
|
|
19
|
+
* prompts, anything else would prompt and block, never destruct.
|
|
20
|
+
*
|
|
21
|
+
* See `_pinned_top_never_paid_api_for_heavy_work` memory.
|
|
22
|
+
*/
|
|
23
|
+
import { mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
24
|
+
import { existsSync } from "node:fs";
|
|
25
|
+
import { basename, join, resolve } from "node:path";
|
|
26
|
+
import { spawn } from "node:child_process";
|
|
27
|
+
import { execFile } from "node:child_process";
|
|
28
|
+
import { promisify } from "node:util";
|
|
29
|
+
import kleur from "kleur";
|
|
30
|
+
import { readLedger, writeLedger, ledgerDir } from "../ledger.js";
|
|
31
|
+
import { pushCommand } from "./push.js";
|
|
32
|
+
const execFileP = promisify(execFile);
|
|
33
|
+
// Matches Almanac's BASE_OPERATION_TOOLS spec (read/write/edit/search/shell)
|
|
34
|
+
// mapped to Claude Code's tool names. `--safe` strips Bash.
|
|
35
|
+
const FULL_TOOLS = ["Read", "Write", "Edit", "Glob", "Grep", "Bash"];
|
|
36
|
+
const SAFE_TOOLS = ["Read", "Write", "Edit", "Glob", "Grep"];
|
|
37
|
+
function buildMission(repoRoot, pagesDir, transcriptsDir) {
|
|
38
|
+
const repoName = resolve(repoRoot).split("/").pop() ?? "repo";
|
|
39
|
+
const transcriptsBlock = transcriptsDir
|
|
40
|
+
? `\n## Conversation transcripts (extra signal)\n\nClaude Code transcripts for this repo live at \`${transcriptsDir}\` (JSONL — one record per line). Skim recent ones with Glob + Read for **decisions, gotchas, failed attempts, and reasoning** that the code alone doesn't capture. Treat them as supplementary sources — a page about "${repoName} deploy pipeline" gets richer if you also find the conversation where the deploy method was decided.\n\nSignal rules:\n- type:"user" → intent, requirements, reversals — high value\n- type:"assistant" text → analysis, decisions, root-cause writeups — high value\n- tool_use / tool_result → SKIP (operational noise)\n- Long files >50KB → almost always tool dumps, skip\n`
|
|
41
|
+
: "";
|
|
42
|
+
return `You are authoring a thorough wiki for the codebase \`${repoName}\` at \`${repoRoot}\`. Output goes to \`${pagesDir}/<slug>.md\`.
|
|
43
|
+
|
|
44
|
+
## Purpose
|
|
45
|
+
|
|
46
|
+
This wiki is **cultivated project memory** — a deep-research cache that preserves understanding that an expert would build after reading, tracing, and connecting raw inputs. Future readers (humans + AI agents) should start from this distilled understanding instead of reorienting from raw files.
|
|
47
|
+
|
|
48
|
+
The codebase is the anchor, not the boundary. Pages may cover things OUTSIDE the repo when they materially shape work on it (\`stripe.md\`, \`postgres.md\`, \`claude-agent-sdk.md\` are all valid pages if the project leans on them). For external things, describe their **role in this project**: what we use, what we don't use, what versions matter, what conclusions we reached, what they connect to.
|
|
49
|
+
|
|
50
|
+
A wiki change is valuable when it preserves **durable, reusable understanding that would be costly, useful, or risky to reconstruct later**. Conversely:
|
|
51
|
+
|
|
52
|
+
**Do NOT write a page that is only:**
|
|
53
|
+
- a file-by-file summary
|
|
54
|
+
- a folder tree in prose
|
|
55
|
+
- generic API documentation copied from external docs
|
|
56
|
+
- "this file contains…" style content
|
|
57
|
+
- a roadmap, task log, or progress diary
|
|
58
|
+
- a guess about intent the code doesn't support
|
|
59
|
+
- a one-off fact obvious from one nearby file
|
|
60
|
+
- a page whose only claim is that something exists
|
|
61
|
+
|
|
62
|
+
If the useful part can be folded into a parent page, do that instead of creating a new page.
|
|
63
|
+
|
|
64
|
+
## Page genres (vocabulary, not enforcement)
|
|
65
|
+
|
|
66
|
+
Use these as a thinking tool. Create a different shape when material genuinely needs it:
|
|
67
|
+
|
|
68
|
+
- **Entity** — a named thing the project reasons about (\`provider\`, \`stripe\`, \`postgres\`, \`claude-agent-sdk\`). First-class. Use the natural name as the slug.
|
|
69
|
+
- **Subsystem** — an internal area with clear responsibility and boundaries
|
|
70
|
+
- **Flow** — behavior that crosses files, commands, or systems end-to-end
|
|
71
|
+
- **Contract** — obligations between callers, providers, schemas, APIs, file formats
|
|
72
|
+
- **Data model** — records, schemas, storage formats, indexes whose shape affects behavior
|
|
73
|
+
- **Operation** — a recurring action with inputs, outputs, side effects, verification
|
|
74
|
+
- **Decision / rationale** — why the project chose one path over alternatives. Pull from CLAUDE.md, READMEs, commits, transcripts.
|
|
75
|
+
- **Risk / invariant** — a rule, coupling, or fragile behavior future work must preserve
|
|
76
|
+
- **Dependency** — external runtime/service/SDK/framework as used by this project
|
|
77
|
+
- **Influence** — external idea/paper/prior-art that shaped this project
|
|
78
|
+
- **Research synthesis** — conclusions from docs, papers, design exploration
|
|
79
|
+
- **Incident / postmortem** — what happened, what was learned, what changed
|
|
80
|
+
- **Hub** — a standalone page that EXPLAINS a dense cluster (auth, deploy, knowledge-graph, embedding, etc.) in one place. **Required** whenever ≥3 specialty pages share a topic. The hub is not a nav stub — it has its own body explaining the concept and how the cluster fits together. The specialty pages drill into individual decisions/flows; the hub gives the reader the unified picture. Slug = the unprefixed concept name (\`auth.md\`, not \`auth-overview.md\` or \`auth-hub.md\`).
|
|
81
|
+
- **Person / team** — the user, contributors, or teams the project reasons about. **Always create at least ONE \`type: person\` page for the repo owner/user** (mine name + role from \`git config user.name\`, \`git log\`, CLAUDE.md "user role" / "ceo" / "engineer" hints, and \`~/.claude/projects/*/memory/user_*.md\`). Slug = kebab-case of the person's name, e.g. \`ravindra\` or \`me\`.
|
|
82
|
+
${transcriptsBlock}
|
|
83
|
+
## Algorithm (8-step deep first construction pass)
|
|
84
|
+
|
|
85
|
+
Do not stop after the first 10-15 pages. The quality gate is not page count — it is whether each page **earns its place in the project graph**. Be thorough. Create many pages when many are justified. **Target 25-60 pages for a real-world project.**
|
|
86
|
+
|
|
87
|
+
1. **Orient to the corpus** — repo layout, package/config files, commands, entrypoints, docs, tests, schemas, data files, external dependencies. **Read these instruction/memory files FIRST** before anything else:
|
|
88
|
+
- \`CLAUDE.md\`, \`AGENTS.md\`, \`README.md\`, \`CONTRIBUTING.md\` at repo root
|
|
89
|
+
- \`~/.claude/projects/<repo-hash>/memory/MEMORY.md\` and \`~/.claude/projects/<repo-hash>/memory/*.md\` (the agent's per-project memory — contains user identity, preferences, decisions, gotchas, project facts that the code alone won't show). \`<repo-hash>\` is the abs repo path with \`/\` replaced by \`-\`. Use \`Bash ls ~/.claude/projects/\` to discover it.
|
|
90
|
+
- \`~/.claude/CLAUDE.md\` (the user's global instructions — coding style, deploy rules, decisions about tooling)
|
|
91
|
+
- \`package.json\` / \`Cargo.toml\` / equivalent for stack identification
|
|
92
|
+
These files contain the **most important durable knowledge** about the project — decisions, gotchas, conventions, user identity, team — that the code itself doesn't surface. Mine them aggressively.
|
|
93
|
+
2. **Build a working map from multiple angles** — entities, subsystems, flows, contracts, data models, operations, external systems, product/project concepts, dense clusters.
|
|
94
|
+
3. **Investigate important areas deeply** — explain how they work and how they connect. **Tests are often the clearest source of intended behavior.**
|
|
95
|
+
4. **Compare code against existing docs and research** — preserve the applied conclusions and project-specific meaning. Do not copy docs.
|
|
96
|
+
5. **Identify page candidates by future value** — for each, ask: would reconstructing this understanding later be costly, useful, or risky?
|
|
97
|
+
6. **Design the initial graph** — pages, topics, links, **and one hub per dense cluster**. Topics are reading neighborhoods (\`provider-harness\`, \`prompt-system\`, \`wiki-indexing\`) — NOT bookkeeping labels (\`misc\`, \`notes\`, \`external\`). **Hub rule:** whenever you plan ≥3 specialty pages in the same area (e.g. \`decision-cloud-run-only\`, \`deploy-script-cloudbuild\`, \`gotcha-website-deploy\`) you MUST also plan ONE hub page (e.g. \`deploy.md\`) that explains the area as a whole and links the specialty pages. The hub is a real page with its own 800-2500 char body — not a stub or link list. Common required hubs: \`auth.md\`, \`deploy.md\`, \`knowledge-graph.md\`, \`memory.md\`, \`provider.md\` — create whichever apply to this codebase.
|
|
98
|
+
7. **Write detailed, grounded pages** directly to \`${pagesDir}/\`.
|
|
99
|
+
8. **Re-read the wiki as a future agent** — fix weak leads, duplicate pages, unsupported claims, missing links, thin placeholders. **For each page, count backticks: \`grep -oE '\\\`[^\\\`]+\\\`' <page> | wc -l\`. If under 25, revise: convert vague prose into named symbols/paths/types/commands. Target ≥ 40 per page.**
|
|
100
|
+
|
|
101
|
+
## getting-started.md — required navigation page
|
|
102
|
+
|
|
103
|
+
Write \`${pagesDir}/getting-started.md\` LAST, once the rest of the graph exists. It is the canonical front door — orient a fresh reader, name the dense clusters, point at which pages to read first for common work areas. Link directly to the most important pages with \`[[wikilinks]]\`. Not a setup guide; a reading-order guide.
|
|
104
|
+
|
|
105
|
+
## Page shape
|
|
106
|
+
|
|
107
|
+
Start with a **lead paragraph** that stands alone — a future reader should know what the page is about, why it exists, and whether to keep reading after just the first 2-3 sentences.
|
|
108
|
+
|
|
109
|
+
After the lead, use **5-8 \`## H2 sections\`** drawn from this menu as fits the page:
|
|
110
|
+
|
|
111
|
+
- What it is in this project
|
|
112
|
+
- Where it lives
|
|
113
|
+
- How it works
|
|
114
|
+
- What we use
|
|
115
|
+
- What we don't use
|
|
116
|
+
- Contracts and assumptions
|
|
117
|
+
- Sequence (numbered, for flows)
|
|
118
|
+
- Failure modes / Gotchas
|
|
119
|
+
- Decisions and rationale
|
|
120
|
+
- Related flows
|
|
121
|
+
- Current synthesis
|
|
122
|
+
- Open questions
|
|
123
|
+
- Verification (how to know it works)
|
|
124
|
+
- Related pages
|
|
125
|
+
|
|
126
|
+
Prose for explanation. Bullets only for real lists. Tables only for structured comparison.
|
|
127
|
+
|
|
128
|
+
## Frontmatter
|
|
129
|
+
|
|
130
|
+
\`\`\`
|
|
131
|
+
---
|
|
132
|
+
slug: <kebab-case>
|
|
133
|
+
title: "<short human title>"
|
|
134
|
+
summary: "<ONE direct sentence — used as the search-result snippet>"
|
|
135
|
+
type: <person|team|company|community|mentorship|relationship|
|
|
136
|
+
system|component|service|library|tool|module|
|
|
137
|
+
decision|policy|rationale|flow|pipeline|process|
|
|
138
|
+
gotcha|bug|constraint|limitation|task|
|
|
139
|
+
concept|overview|architecture>
|
|
140
|
+
topics: [<reading-neighborhood-1>, <reading-neighborhood-2>]
|
|
141
|
+
files:
|
|
142
|
+
- "<repo-relative path>"
|
|
143
|
+
sources:
|
|
144
|
+
- <URL or absolute path to external doc/research/transcript that supports this page>
|
|
145
|
+
status: fresh
|
|
146
|
+
built_at: <ISO8601>
|
|
147
|
+
---
|
|
148
|
+
\`\`\`
|
|
149
|
+
|
|
150
|
+
\`summary:\` is one factual sentence, not a paragraph — it's literally the search-result snippet. \`sources:\` is for external docs/URLs/transcripts that ground the page (separate from \`files:\` which is repo-internal).
|
|
151
|
+
|
|
152
|
+
## Body — depth requirements
|
|
153
|
+
|
|
154
|
+
**Target 800-2500 chars per body** (aim for the upper end on important concepts). A page with under 800 chars is suspect — fold into a parent or skip it.
|
|
155
|
+
|
|
156
|
+
**Code references everywhere — hard floor: 40 backtick refs per page (warning under 25).** Every symbol, function, file path, type, env var, schema name, table, command, route, or constant must appear in \`backticks\`. Reference real exports — \`signInWithEmailAndPassword\`, \`POST /api/session\`, \`src/lib/auth-context.tsx\`, \`AuthProvider\`, \`process.env.FIREBASE_KEY\`, \`users.id\`, \`pnpm run build\`. **Before saving any page, count the backtick refs.** If a 1000-word page has under 25 backticks, it is prose-heavy — revise: replace prose like "the auth context" with \`AuthContext\`, "the signin function" with \`signIn()\`, "the session cookie" with the actual cookie name in backticks. Concrete > generic. **A page with zero backticks is broken; a page with fewer than 25 is half-broken.**
|
|
157
|
+
|
|
158
|
+
**Numbered sequences for flows.** Multi-step processes get numbered lists with concrete arrows: \`1. User submits form → \\\`signIn(...)\\\` returns promise → onAuthStateChanged fires → ...\`
|
|
159
|
+
|
|
160
|
+
**\`[[wikilinks]]\` for related concepts** — link the first meaningful mention of each related page. Liberal linking is good, but the page must STAND ALONE: a reader should learn the concept from this page, not just see a list of links to other pages.
|
|
161
|
+
|
|
162
|
+
## Grounding (non-negotiable)
|
|
163
|
+
|
|
164
|
+
Ground non-obvious claims in code, tests, docs, sources, commits, prior pages, or explicit user context. **Do not pretend uncertainty is fact.** If a claim matters and cannot be grounded, omit it or mark it as an open question. Inspect tests when you need to confirm behavior.
|
|
165
|
+
|
|
166
|
+
## Style
|
|
167
|
+
|
|
168
|
+
Direct, factual, dense. Write for future coding agents and engineers picking up the project.
|
|
169
|
+
|
|
170
|
+
**Avoid:**
|
|
171
|
+
- generic library tutorials
|
|
172
|
+
- vague claims ("uses modern tech")
|
|
173
|
+
- marketing prose
|
|
174
|
+
- unsupported rationale ("for performance" with no measurement)
|
|
175
|
+
- transcript language ("we discussed and decided…")
|
|
176
|
+
- "this file contains…" summaries
|
|
177
|
+
- conclusions that don't connect to future work
|
|
178
|
+
- chips-only index pages with no real content
|
|
179
|
+
|
|
180
|
+
## How to work
|
|
181
|
+
|
|
182
|
+
Use Glob/Grep/Read to survey. Use Bash for \`git log\`, \`find\`, \`grep\` when faster than the dedicated tools. Use Write to create pages under \`${pagesDir}/\`. Skip if a slug already exists — don't clobber prior work. **Re-read your own pages after writing the first batch** and improve them; the agent's first draft is rarely the best draft.
|
|
183
|
+
|
|
184
|
+
## Required minimum coverage
|
|
185
|
+
|
|
186
|
+
Before printing the final count, verify the wiki has at least:
|
|
187
|
+
- **≥1 \`type: person\` page** — the repo owner / user (mine from \`git config\`, CLAUDE.md, \`~/.claude\` memory). Title = their human name. The "People" bucket in the dashboard depends on this.
|
|
188
|
+
- **≥3 \`type: decision\` pages** — design choices the project made (e.g. "why postgres not sqlite", "why claude CLI not paid API"). Mine from CLAUDE.md, commit messages with words like "decided / chose / instead of", ADR docs, transcript moments where alternatives were rejected.
|
|
189
|
+
- **≥3 \`type: gotcha\` pages** — known issues, footguns, "don't do X" rules. Mine from CLAUDE.md sections labeled "Don't", "Never", "Watch out", from comments containing TODO/FIXME/HACK, from commits with "fix:", and from transcripts where something broke.
|
|
190
|
+
|
|
191
|
+
If a real repo genuinely has none of these (rare), document the absence in \`getting-started.md\` so future agents know to look elsewhere.
|
|
192
|
+
|
|
193
|
+
When done, print ONE line: \`WROTE N PAGES\` where N is the count.
|
|
194
|
+
|
|
195
|
+
## Out of scope
|
|
196
|
+
|
|
197
|
+
- Do not run \`git push\`, \`rm -rf\`, install packages, or modify files outside \`${pagesDir}\`.
|
|
198
|
+
- Do not include large file dumps in pages — pages document *what the code MEANS*, not what each file contains.
|
|
199
|
+
|
|
200
|
+
Begin. Be thorough; the user wants a wiki rich enough to navigate as a graph AND deep enough to read as standalone essays.`;
|
|
201
|
+
}
|
|
202
|
+
/** Locate Claude Code transcripts for this repo (~/.claude/projects/<hash>).
|
|
203
|
+
* The hash is the absolute repo path with slashes replaced by dashes. */
|
|
204
|
+
async function findTranscriptsDir(repoRoot) {
|
|
205
|
+
const { existsSync: e } = await import("node:fs");
|
|
206
|
+
const { homedir } = await import("node:os");
|
|
207
|
+
const abs = resolve(repoRoot);
|
|
208
|
+
const hash = abs.replace(/\//g, "-"); // /Users/a/b → -Users-a-b
|
|
209
|
+
const dir = join(homedir(), ".claude", "projects", hash);
|
|
210
|
+
return e(dir) ? dir : null;
|
|
211
|
+
}
|
|
212
|
+
/** Derive a project_id from `git remote get-url origin` basename. Falls
|
|
213
|
+
* back to the directory basename when no git remote is configured. */
|
|
214
|
+
async function deriveProjectId(repoRoot) {
|
|
215
|
+
try {
|
|
216
|
+
const { stdout } = await execFileP("git", ["-C", repoRoot, "remote", "get-url", "origin"]);
|
|
217
|
+
const url = stdout.trim();
|
|
218
|
+
// git@github.com:foo/bar.git → bar; https://github.com/foo/bar(.git) → bar
|
|
219
|
+
const match = url.match(/[/:]([^/:]+?)(?:\.git)?$/);
|
|
220
|
+
if (match)
|
|
221
|
+
return match[1];
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// no remote → fall through
|
|
225
|
+
}
|
|
226
|
+
return basename(resolve(repoRoot));
|
|
227
|
+
}
|
|
228
|
+
/** Initialize the workspace on first run (or refresh team binding on
|
|
229
|
+
* subsequent runs). Writes ledger.json + scaffolds .ricord/README.md
|
|
230
|
+
* if missing. Returns the resolved project_id, or null on failure. */
|
|
231
|
+
async function ensureWorkspace(opts) {
|
|
232
|
+
const dir = ledgerDir(opts.repoRoot);
|
|
233
|
+
const ledger = await readLedger(opts.repoRoot);
|
|
234
|
+
const projectId = opts.projectId ?? ledger.project_id ?? (await deriveProjectId(opts.repoRoot));
|
|
235
|
+
if (!projectId) {
|
|
236
|
+
console.error(kleur.red("could not resolve project_id — pass --project <id>"));
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
const teamId = opts.noTeam ? undefined : (opts.teamId ?? ledger.team_id);
|
|
240
|
+
const isFirstRun = !ledger.project_id;
|
|
241
|
+
const projectChanged = ledger.project_id && ledger.project_id !== projectId;
|
|
242
|
+
const teamChanged = ledger.team_id !== teamId;
|
|
243
|
+
if (isFirstRun || projectChanged || teamChanged) {
|
|
244
|
+
await writeLedger(opts.repoRoot, {
|
|
245
|
+
...ledger,
|
|
246
|
+
project_id: projectId,
|
|
247
|
+
team_id: teamId,
|
|
248
|
+
repo: ledger.repo ?? { remote_url: `file://${resolve(opts.repoRoot)}` },
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
// First-run scaffolding: pages dir + README explaining the layout.
|
|
252
|
+
await mkdir(join(dir, "pages"), { recursive: true });
|
|
253
|
+
const readme = join(dir, "README.md");
|
|
254
|
+
if (!existsSync(readme)) {
|
|
255
|
+
await writeFile(readme, [
|
|
256
|
+
"# .ricord/",
|
|
257
|
+
"",
|
|
258
|
+
"Local-first Ricord wiki for this repo. **`pages/` is the source of truth** —",
|
|
259
|
+
"commit it. The hosted ricord.ai dashboard mirrors what you push.",
|
|
260
|
+
"",
|
|
261
|
+
"- `pages/*.md` — wiki pages (git-tracked)",
|
|
262
|
+
"- `ledger.json` — per-machine sync state (gitignored)",
|
|
263
|
+
"- `.gitignore` — only ignores ledger + tmp files",
|
|
264
|
+
"",
|
|
265
|
+
"Run `ricord build` to (re)author pages with claude. `ricord push` to sync",
|
|
266
|
+
"local edits up. `ricord pull` to pull cloud edits down.",
|
|
267
|
+
"",
|
|
268
|
+
].join("\n"), "utf8");
|
|
269
|
+
}
|
|
270
|
+
if (isFirstRun) {
|
|
271
|
+
const teamSuffix = teamId ? kleur.dim(` (team ${teamId.slice(0, 8)}…)`) : "";
|
|
272
|
+
console.log(kleur.green("✓"), `bound to project ${projectId}${teamSuffix}`);
|
|
273
|
+
}
|
|
274
|
+
return projectId;
|
|
275
|
+
}
|
|
276
|
+
export async function buildCommand(opts) {
|
|
277
|
+
const projectId = await ensureWorkspace(opts);
|
|
278
|
+
if (!projectId)
|
|
279
|
+
return 1;
|
|
280
|
+
const pagesDir = join(ledgerDir(opts.repoRoot), "pages");
|
|
281
|
+
await mkdir(pagesDir, { recursive: true });
|
|
282
|
+
const tools = opts.safe ? SAFE_TOOLS : FULL_TOOLS;
|
|
283
|
+
const transcriptsDir = await findTranscriptsDir(opts.repoRoot);
|
|
284
|
+
const mission = buildMission(opts.repoRoot, pagesDir, transcriptsDir);
|
|
285
|
+
console.log(kleur.bold("ricord build"), kleur.dim(`(repo: ${resolve(opts.repoRoot).split("/").pop()}, tools: ${tools.join(",")}, max_turns: ${opts.maxTurns})`));
|
|
286
|
+
if (transcriptsDir) {
|
|
287
|
+
console.log(kleur.dim(` + transcripts: ${transcriptsDir}`));
|
|
288
|
+
}
|
|
289
|
+
if (opts.dryRun) {
|
|
290
|
+
console.log(kleur.dim("\n--- mission ---"));
|
|
291
|
+
console.log(mission);
|
|
292
|
+
console.log(kleur.dim("\n--- spawn ---"));
|
|
293
|
+
console.log(`claude -p --output-format json --allowedTools "${tools.join(",")}" --add-dir ${pagesDir} --max-turns ${opts.maxTurns}`);
|
|
294
|
+
return 0;
|
|
295
|
+
}
|
|
296
|
+
const before = await pageSlugsOnDisk(pagesDir);
|
|
297
|
+
const extraDirs = transcriptsDir ? [transcriptsDir] : [];
|
|
298
|
+
const exit = await spawnClaude(opts.repoRoot, mission, tools, opts.maxTurns, extraDirs);
|
|
299
|
+
const after = await pageSlugsOnDisk(pagesDir);
|
|
300
|
+
const wrote = after.filter((s) => !before.includes(s));
|
|
301
|
+
if (wrote.length > 0) {
|
|
302
|
+
console.log(kleur.green(`\n✓ built ${wrote.length} new pages → ${pagesDir.replace(opts.repoRoot, ".")}/`));
|
|
303
|
+
for (const s of wrote.slice(0, 30))
|
|
304
|
+
console.log(kleur.dim(` ${s}`));
|
|
305
|
+
if (wrote.length > 30)
|
|
306
|
+
console.log(kleur.dim(` …${wrote.length - 30} more`));
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
console.log(kleur.yellow(`\nbuilt 0 new pages (claude exit ${exit}). agent may have decided existing pages already cover this repo.`));
|
|
310
|
+
}
|
|
311
|
+
// G19 — derive .ricord/topics.yaml from the local pages' frontmatter
|
|
312
|
+
// so the topic surface is populated even before a `ricord push`. Same
|
|
313
|
+
// list-of-objects shape the cloud export uses so the file is
|
|
314
|
+
// round-trip stable.
|
|
315
|
+
if (after.length > 0) {
|
|
316
|
+
const yamlPath = join(ledgerDir(opts.repoRoot), "topics.yaml");
|
|
317
|
+
const yaml = await deriveTopicsYaml(pagesDir, after);
|
|
318
|
+
await writeFile(yamlPath, yaml, "utf8");
|
|
319
|
+
}
|
|
320
|
+
if (opts.push && wrote.length > 0) {
|
|
321
|
+
console.log(kleur.dim("\n→ pushing to cloud mirror…"));
|
|
322
|
+
const pushExit = await pushCommand({
|
|
323
|
+
repoRoot: opts.repoRoot,
|
|
324
|
+
from: ".ricord/pages",
|
|
325
|
+
projectId,
|
|
326
|
+
teamId: opts.teamId,
|
|
327
|
+
noTeam: opts.noTeam,
|
|
328
|
+
dryRun: false,
|
|
329
|
+
all: true,
|
|
330
|
+
});
|
|
331
|
+
return pushExit;
|
|
332
|
+
}
|
|
333
|
+
console.log(kleur.dim("next: review with `ricord curate --local`, then `ricord push` (or rerun with --push)."));
|
|
334
|
+
return wrote.length > 0 ? 0 : exit;
|
|
335
|
+
}
|
|
336
|
+
/** G19 — walk every .md in pagesDir, collect unique topic slugs from
|
|
337
|
+
* frontmatter `topics: [a, b, c]`, and emit `.ricord/topics.yaml` in
|
|
338
|
+
* the same list-of-objects shape the cloud export uses. */
|
|
339
|
+
async function deriveTopicsYaml(pagesDir, slugs) {
|
|
340
|
+
const counts = new Map();
|
|
341
|
+
for (const f of slugs) {
|
|
342
|
+
const text = await readFile(join(pagesDir, f), "utf8").catch(() => "");
|
|
343
|
+
if (!text.startsWith("---"))
|
|
344
|
+
continue;
|
|
345
|
+
const end = text.indexOf("\n---", 3);
|
|
346
|
+
if (end < 0)
|
|
347
|
+
continue;
|
|
348
|
+
const fm = text.slice(3, end);
|
|
349
|
+
const m = fm.match(/^topics:\s*\[(.*)\]/m);
|
|
350
|
+
if (!m)
|
|
351
|
+
continue;
|
|
352
|
+
for (const raw of m[1].split(",")) {
|
|
353
|
+
const t = raw.trim().replace(/^["']|["']$/g, "").toLowerCase();
|
|
354
|
+
if (!t)
|
|
355
|
+
continue;
|
|
356
|
+
counts.set(t, (counts.get(t) ?? 0) + 1);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
const lines = [
|
|
360
|
+
"# Ricord topics — local mirror, derived from .ricord/pages/*.md.",
|
|
361
|
+
"# Edit the page frontmatter to change topics; this file is regenerated",
|
|
362
|
+
"# on every `ricord build`.",
|
|
363
|
+
"topics:",
|
|
364
|
+
];
|
|
365
|
+
if (counts.size === 0) {
|
|
366
|
+
lines.push(" []");
|
|
367
|
+
return lines.join("\n") + "\n";
|
|
368
|
+
}
|
|
369
|
+
const sorted = [...counts.entries()].sort(([a], [b]) => a.localeCompare(b));
|
|
370
|
+
for (const [slug, n] of sorted) {
|
|
371
|
+
const title = slug.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
372
|
+
lines.push(` - slug: ${slug}`);
|
|
373
|
+
lines.push(` title: ${JSON.stringify(title)}`);
|
|
374
|
+
lines.push(` page_count: ${n}`);
|
|
375
|
+
}
|
|
376
|
+
return lines.join("\n") + "\n";
|
|
377
|
+
}
|
|
378
|
+
async function pageSlugsOnDisk(pagesDir) {
|
|
379
|
+
if (!existsSync(pagesDir))
|
|
380
|
+
return [];
|
|
381
|
+
const entries = await readdir(pagesDir);
|
|
382
|
+
return entries.filter((e) => e.endsWith(".md")).sort();
|
|
383
|
+
}
|
|
384
|
+
async function spawnClaude(cwd, prompt, tools, maxTurns, extraDirs = []) {
|
|
385
|
+
return await new Promise((res) => {
|
|
386
|
+
const args = [
|
|
387
|
+
"-p",
|
|
388
|
+
"--output-format", "json",
|
|
389
|
+
"--allowedTools", tools.join(","),
|
|
390
|
+
"--add-dir", cwd,
|
|
391
|
+
...extraDirs.flatMap((d) => ["--add-dir", d]),
|
|
392
|
+
"--max-turns", String(maxTurns),
|
|
393
|
+
];
|
|
394
|
+
const child = spawn("claude", args, { stdio: ["pipe", "pipe", "pipe"], cwd });
|
|
395
|
+
let stdout = "";
|
|
396
|
+
let stderr = "";
|
|
397
|
+
child.stdout.on("data", (b) => {
|
|
398
|
+
const chunk = b.toString("utf8");
|
|
399
|
+
stdout += chunk;
|
|
400
|
+
// Stream a single live "claude working…" dot so the user knows
|
|
401
|
+
// the agent is alive without dumping its full chatter.
|
|
402
|
+
process.stdout.write(".");
|
|
403
|
+
});
|
|
404
|
+
child.stderr.on("data", (b) => { stderr += b.toString("utf8"); });
|
|
405
|
+
child.on("error", (e) => {
|
|
406
|
+
console.error(kleur.red(`\nclaude spawn failed: ${e.message}. Install Claude Code: https://claude.com/claude-code`));
|
|
407
|
+
res(1);
|
|
408
|
+
});
|
|
409
|
+
child.on("close", (code) => {
|
|
410
|
+
process.stdout.write("\n");
|
|
411
|
+
if (code !== 0) {
|
|
412
|
+
const tail = (stderr || stdout).slice(-400);
|
|
413
|
+
console.error(kleur.red(`claude exit ${code}: ${tail}`));
|
|
414
|
+
res(code ?? 1);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
// Surface claude's final one-liner (per the mission, "WROTE N PAGES").
|
|
418
|
+
try {
|
|
419
|
+
const wrapper = JSON.parse(stdout);
|
|
420
|
+
const final = (wrapper.result ?? "").trim();
|
|
421
|
+
if (final)
|
|
422
|
+
console.log(kleur.dim(` agent: ${final.slice(0, 200)}`));
|
|
423
|
+
if (wrapper.num_turns !== undefined)
|
|
424
|
+
console.log(kleur.dim(` turns: ${wrapper.num_turns}`));
|
|
425
|
+
}
|
|
426
|
+
catch {
|
|
427
|
+
/* ignore parse errors — file scan tells us what actually landed */
|
|
428
|
+
}
|
|
429
|
+
res(0);
|
|
430
|
+
});
|
|
431
|
+
child.stdin.write(prompt, "utf8");
|
|
432
|
+
child.stdin.end();
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
// Re-export stat for ergonomics if a caller wants to introspect later
|
|
436
|
+
export { stat };
|
|
437
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/cli/commands/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ricord curate [--apply]` — wiki curation pass (F3 / S8).
|
|
3
|
+
*
|
|
4
|
+
* Default behavior (no flag) is a dry-run preview: fetches the server's
|
|
5
|
+
* curation suggestions and prints them. `--apply` posts the approved
|
|
6
|
+
* operations back to the server. Operations are server-defined:
|
|
7
|
+
*
|
|
8
|
+
* - move: retag / re-anchor a page
|
|
9
|
+
* - merge: fold two pages into one (keeps the better title)
|
|
10
|
+
* - archive: mark a page archived (kb_pages.archived_at)
|
|
11
|
+
* - supersede: B replaces A (kb_pages.superseded_by)
|
|
12
|
+
*
|
|
13
|
+
* The CLI does not run an LLM. The server invokes the CURATION_PROMPT
|
|
14
|
+
* inside /v1/kb/curate/preview; the CLI only orchestrates approval.
|
|
15
|
+
*/
|
|
16
|
+
interface CurateOpts {
|
|
17
|
+
repoRoot: string;
|
|
18
|
+
projectId?: string;
|
|
19
|
+
apply: boolean;
|
|
20
|
+
/** --prepare prints the CURATION_PROMPT + a page batch the user can
|
|
21
|
+
* pipe into a host LLM. The LLM's JSON output is then POST'd back
|
|
22
|
+
* via `ricord curate --apply-from <file>`. Mirrors `ricord ingest
|
|
23
|
+
* --prepare`. */
|
|
24
|
+
prepare: boolean;
|
|
25
|
+
/** --local scans .ricord/pages/ on disk and reports issues without
|
|
26
|
+
* hitting the cloud. G11 tick 27 — local-first curation surface. */
|
|
27
|
+
local: boolean;
|
|
28
|
+
/** --local + --stale-days N: warn on pages older than N days. */
|
|
29
|
+
staleDays: number;
|
|
30
|
+
}
|
|
31
|
+
export declare function curateCommand(opts: CurateOpts): Promise<number>;
|
|
32
|
+
export {};
|