@vonneollc/knbase 0.1.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.
Files changed (45) hide show
  1. package/README.md +182 -0
  2. package/bin/knbase +5 -0
  3. package/dist/cli/index.d.ts +2 -0
  4. package/dist/cli/index.js +143 -0
  5. package/dist/cli/index.js.map +1 -0
  6. package/dist/core/agents-doc.d.ts +6 -0
  7. package/dist/core/agents-doc.js +50 -0
  8. package/dist/core/agents-doc.js.map +1 -0
  9. package/dist/core/config.d.ts +30 -0
  10. package/dist/core/config.js +89 -0
  11. package/dist/core/config.js.map +1 -0
  12. package/dist/core/engine.d.ts +101 -0
  13. package/dist/core/engine.js +350 -0
  14. package/dist/core/engine.js.map +1 -0
  15. package/dist/core/files.d.ts +23 -0
  16. package/dist/core/files.js +66 -0
  17. package/dist/core/files.js.map +1 -0
  18. package/dist/core/index-store.d.ts +17 -0
  19. package/dist/core/index-store.js +97 -0
  20. package/dist/core/index-store.js.map +1 -0
  21. package/dist/core/log.d.ts +11 -0
  22. package/dist/core/log.js +38 -0
  23. package/dist/core/log.js.map +1 -0
  24. package/dist/core/mindmap.d.ts +11 -0
  25. package/dist/core/mindmap.js +71 -0
  26. package/dist/core/mindmap.js.map +1 -0
  27. package/dist/core/session.d.ts +15 -0
  28. package/dist/core/session.js +53 -0
  29. package/dist/core/session.js.map +1 -0
  30. package/dist/core/templates.d.ts +16 -0
  31. package/dist/core/templates.js +163 -0
  32. package/dist/core/templates.js.map +1 -0
  33. package/dist/index.d.ts +3 -0
  34. package/dist/index.js +4 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/mcp/server.d.ts +3 -0
  37. package/dist/mcp/server.js +39 -0
  38. package/dist/mcp/server.js.map +1 -0
  39. package/dist/mcp/tools.d.ts +2 -0
  40. package/dist/mcp/tools.js +129 -0
  41. package/dist/mcp/tools.js.map +1 -0
  42. package/dist/types.d.ts +67 -0
  43. package/dist/types.js +13 -0
  44. package/dist/types.js.map +1 -0
  45. package/package.json +55 -0
package/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # knbase
2
+
3
+ Agent-agnostic AI project governance and memory system.
4
+
5
+ `knbase` forces any AI agent to work on a project the *right* way:
6
+
7
+ 1. **Read before acting.** Before doing anything, an agent must load the project's
8
+ governance context (a compact mind map + per-file summaries + current phase).
9
+ 2. **Bootstrap if missing.** If the governance docs don't exist, the system
10
+ generates templates and instructs the agent to author them *first*, based on
11
+ its understanding of the user's request.
12
+ 3. **Gate every task.** An agent must open a task before making changes and close
13
+ it afterwards; closing is refused until project memory is updated.
14
+ 4. **Build a knowledge base.** Every task appends to `memory.md`, regenerates a
15
+ combined mind map, and writes an activity log, so the next agent can extend the
16
+ project from existing code and design instead of re-deriving everything.
17
+ 5. **Save tokens.** Full documents are only loaded on demand; by default agents
18
+ get compact summaries + a mind map.
19
+
20
+ ## Governance documents
21
+
22
+ Stored in `memory-bank/` (configurable) in each project root:
23
+
24
+ | File | Purpose |
25
+ | --- | --- |
26
+ | `prd.md` | Product requirements: what we're building and why |
27
+ | `architecture.md` | System structure, components, data flow |
28
+ | `design.md` | Detailed design, interfaces, decisions |
29
+ | `phase.md` | Current phase and roadmap |
30
+ | `rules.md` | Hard rules and guardrails every agent must obey |
31
+ | `memory.md` | Running knowledge base, updated after every task |
32
+
33
+ System artifacts live in `.knbase/` (`config.json`, `index.json`,
34
+ `mindmap.md`, `activity.log`, `session.json`) and should not be edited by hand.
35
+
36
+ ## Quick setup (recommended, no clone)
37
+
38
+ Once `knbase` is published to npm (see [Publishing to npm](#publishing-to-npm)),
39
+ you can use it without cloning this repo.
40
+
41
+ Install it once, globally:
42
+
43
+ ```bash
44
+ npm install -g knbase
45
+ ```
46
+
47
+ **1. Initialize governance in your project:**
48
+
49
+ ```bash
50
+ cd /path/to/your/project
51
+ knbase init
52
+ ```
53
+
54
+ **2. Register the MCP server** with your agent. Cursor example
55
+ (`~/.cursor/mcp.json` for all projects, or `.cursor/mcp.json` for one project):
56
+
57
+ ```json
58
+ {
59
+ "mcpServers": {
60
+ "knbase": {
61
+ "command": "knbase-mcp",
62
+ "env": { "KNBASE_ROOT": "/absolute/path/to/your/project" }
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
68
+ Prefer not to install globally? Use `npx` instead — no install step at all:
69
+
70
+ ```json
71
+ {
72
+ "mcpServers": {
73
+ "knbase": {
74
+ "command": "npx",
75
+ "args": ["-y", "--package", "knbase", "knbase-mcp"],
76
+ "env": { "KNBASE_ROOT": "/absolute/path/to/your/project" }
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ …and run CLI commands with `npx knbase <command>` (e.g. `npx knbase init`).
83
+
84
+ `KNBASE_ROOT` is optional; if omitted the server resolves the project root by
85
+ walking up from the working directory (looking for `.knbase/` or `.git`). Each
86
+ tool also accepts an explicit `root` argument.
87
+
88
+ ## Complete setup (from source)
89
+
90
+ Use this while developing knbase, or before it is published to npm.
91
+
92
+ ```bash
93
+ git clone <repo-url> knbase
94
+ cd knbase
95
+ npm install
96
+ npm run build # compiles TypeScript into dist/
97
+ ```
98
+
99
+ Then either expose the binaries on your PATH with `npm link`:
100
+
101
+ ```bash
102
+ npm link # makes `knbase` and `knbase-mcp` available globally
103
+ cd /path/to/your/project
104
+ knbase init
105
+ ```
106
+
107
+ …or reference the built files directly by absolute path.
108
+
109
+ MCP config (from source):
110
+
111
+ ```json
112
+ {
113
+ "mcpServers": {
114
+ "knbase": {
115
+ "command": "node",
116
+ "args": ["/absolute/path/to/knbase/dist/mcp/server.js"],
117
+ "env": { "KNBASE_ROOT": "/absolute/path/to/your/project" }
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ CLI (from source):
124
+
125
+ ```bash
126
+ node /absolute/path/to/knbase/dist/cli/index.js init
127
+ ```
128
+
129
+ ### MCP tools
130
+
131
+ | Tool | Description |
132
+ | --- | --- |
133
+ | `start_session` | **Mandatory first call.** Loads compact context, or returns bootstrap templates if docs are missing. |
134
+ | `get_context` | Returns compact context; pass `files=[...] full=true` to fetch specific docs in full. |
135
+ | `write_governance_file` | Create/update a doc (validates required sections, refreshes index + mind map). |
136
+ | `begin_task` | Gate: refuses unless context was loaded this session. |
137
+ | `complete_task` | Gate: refuses unless `memory.md` was updated for the task. |
138
+ | `get_mindmap` | Returns the combined mermaid mind map + index. |
139
+ | `get_status` | Session state, missing files, active task, recent log. |
140
+
141
+ ## CLI commands
142
+
143
+ ```bash
144
+ knbase init # scaffold governance docs, index, mind map, AGENTS.md
145
+ knbase status # show session state, missing files, recent log
146
+ knbase check # exit 0 only if context is loaded and current
147
+ knbase guard -- <command> # run a command only if governance context is loaded
148
+ knbase install-hooks # install a git pre-commit hook that enforces updates
149
+ knbase agents-doc # print the AGENTS.md contract
150
+ ```
151
+
152
+ ## Enforcement model
153
+
154
+ A stdio MCP server cannot intercept another process's file edits at the OS level,
155
+ so enforcement is layered:
156
+
157
+ 1. **State machine** — MCP tools refuse out-of-order calls
158
+ (`UNINITIALIZED -> NEEDS_BOOTSTRAP -> CONTEXT_LOADED -> TASK_ACTIVE -> ...`).
159
+ 2. **Contract** — `init` writes an `AGENTS.md` that every agent reads by convention.
160
+ 3. **Hard gates** — the `git pre-commit` hook and `knbase guard` wrapper block
161
+ real actions (commits, shell commands) until governance is satisfied.
162
+
163
+ ## Token discipline
164
+
165
+ - `start_session` / `get_context` return only the mind map, one-line summaries,
166
+ and current phase by default.
167
+ - Summaries are supplied by the agent at write time, so the server makes **no LLM
168
+ calls** and adds no API cost.
169
+ - The mind map is built deterministically from headings + summaries.
170
+ - Checksums in `index.json` skip regeneration for unchanged files.
171
+
172
+ ## Development
173
+
174
+ ```bash
175
+ npm run typecheck
176
+ npm run dev:mcp # run the MCP server with tsx
177
+ npm run dev:cli -- status
178
+ ```
179
+
180
+ ## License
181
+
182
+ MIT
package/bin/knbase ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import("../dist/cli/index.js").catch((err) => {
3
+ console.error("[knbase] Failed to start CLI:", err);
4
+ process.exit(1);
5
+ });
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env node
2
+ import { spawn, spawnSync } from "node:child_process";
3
+ import { chmodSync, existsSync, readFileSync, writeFileSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { Command } from "commander";
6
+ import { appendLog, getStatus, guardDecision, hasTaskCompletedSince, initProject, openProject, } from "../core/engine.js";
7
+ import { renderAgentsDoc } from "../core/agents-doc.js";
8
+ import { isInitialized } from "../core/config.js";
9
+ const program = new Command();
10
+ program
11
+ .name("knbase")
12
+ .description("Agent-agnostic AI project governance and memory system")
13
+ .version("0.1.0");
14
+ /* -------------------------------------------------------------------- init --- */
15
+ program
16
+ .command("init")
17
+ .description("Initialize governance in the current project (scaffold docs, index, mind map, AGENTS.md)")
18
+ .option("-d, --docs-dir <dir>", "Directory for governance docs (default: memory-bank)")
19
+ .action((opts) => {
20
+ const result = initProject(process.cwd(), opts.docsDir);
21
+ const project = openProject(result.root);
22
+ const agentsPath = join(result.root, "AGENTS.md");
23
+ if (!existsSync(agentsPath)) {
24
+ writeFileSync(agentsPath, renderAgentsDoc(project.config), "utf8");
25
+ }
26
+ console.log(`knbase initialized at ${result.root}`);
27
+ console.log(` docs dir: ${project.config.docsDir}/`);
28
+ console.log(` scaffolded: ${result.scaffolded.join(", ") || "(none)"}`);
29
+ console.log(` already set: ${result.alreadyPresent.join(", ") || "(none)"}`);
30
+ console.log(` AGENTS.md: ${existsSync(agentsPath) ? "written" : "present"}`);
31
+ console.log("\nNext: agents should call the `start_session` MCP tool, or run `knbase status`.");
32
+ });
33
+ /* ------------------------------------------------------------------ status --- */
34
+ program
35
+ .command("status")
36
+ .description("Show governance status (session state, missing files, recent log)")
37
+ .action(() => {
38
+ const status = getStatus(openProject(process.cwd()));
39
+ console.log(JSON.stringify(status, null, 2));
40
+ });
41
+ /* ------------------------------------------------------------------- check --- */
42
+ program
43
+ .command("check")
44
+ .description("Exit 0 only if initialized, no files missing, and a fresh session exists")
45
+ .action(() => {
46
+ const project = openProject(process.cwd());
47
+ const decision = guardDecision(project);
48
+ console.log(decision.allow ? `OK: ${decision.reason}` : `BLOCKED: ${decision.reason}`);
49
+ process.exit(decision.allow ? 0 : 1);
50
+ });
51
+ /* ------------------------------------------------------------------- guard --- */
52
+ program
53
+ .command("guard")
54
+ .description("Run a command only if governance context is loaded and current")
55
+ .allowUnknownOption(true)
56
+ .argument("[command...]", "Command to run after `--`")
57
+ .action((command) => {
58
+ const project = openProject(process.cwd());
59
+ const decision = guardDecision(project);
60
+ if (!decision.allow) {
61
+ if (isInitialized(project.root)) {
62
+ appendLog(project.p, { event: "guard_block", detail: decision.reason });
63
+ }
64
+ console.error(`[knbase] BLOCKED: ${decision.reason}`);
65
+ process.exit(1);
66
+ }
67
+ if (!command || command.length === 0) {
68
+ console.log(`[knbase] OK: ${decision.reason} (no command supplied)`);
69
+ return;
70
+ }
71
+ appendLog(project.p, { event: "guard_allow", detail: command.join(" ") });
72
+ const [cmd, ...args] = command;
73
+ const child = spawn(cmd, args, { stdio: "inherit", shell: false });
74
+ child.on("exit", (code) => process.exit(code ?? 0));
75
+ child.on("error", (err) => {
76
+ console.error(`[knbase] Failed to run command: ${err.message}`);
77
+ process.exit(1);
78
+ });
79
+ });
80
+ /* ----------------------------------------------------------- install-hooks --- */
81
+ program
82
+ .command("install-hooks")
83
+ .description("Install a git pre-commit hook that enforces governance updates")
84
+ .action(() => {
85
+ const project = openProject(process.cwd());
86
+ const gitDir = join(project.root, ".git");
87
+ if (!existsSync(gitDir)) {
88
+ console.error("[knbase] Not a git repository (no .git dir). Run `git init` first.");
89
+ process.exit(1);
90
+ }
91
+ const hookPath = join(gitDir, "hooks", "pre-commit");
92
+ const script = `#!/bin/sh
93
+ # Installed by knbase. Blocks commits unless governance is satisfied.
94
+ exec npx --no-install knbase precommit || knbase precommit
95
+ `;
96
+ writeFileSync(hookPath, script, "utf8");
97
+ chmodSync(hookPath, 0o755);
98
+ console.log(`[knbase] Installed pre-commit hook at ${hookPath}`);
99
+ });
100
+ /* --------------------------------------------------------------- precommit --- */
101
+ program
102
+ .command("precommit")
103
+ .description("Internal: git pre-commit gate. Exits non-zero to block the commit.")
104
+ .action(() => {
105
+ const project = openProject(process.cwd());
106
+ if (!isInitialized(project.root)) {
107
+ console.error("[knbase] pre-commit: not initialized. Run `knbase init`.");
108
+ process.exit(1);
109
+ }
110
+ const status = getStatus(project);
111
+ if (status.missing.length > 0) {
112
+ console.error(`[knbase] pre-commit BLOCKED: governance files missing/empty: ${status.missing.join(", ")}`);
113
+ process.exit(1);
114
+ }
115
+ const lastCommit = spawnSync("git", ["log", "-1", "--format=%cI"], {
116
+ cwd: project.root,
117
+ encoding: "utf8",
118
+ });
119
+ const sinceIso = lastCommit.status === 0 ? lastCommit.stdout.trim() || null : null;
120
+ if (!hasTaskCompletedSince(project.p, sinceIso)) {
121
+ console.error("[knbase] pre-commit BLOCKED: no task completed since last commit. " +
122
+ "Complete a task (update memory.md) via the MCP `complete_task` tool before committing.");
123
+ process.exit(1);
124
+ }
125
+ console.error("[knbase] pre-commit OK: governance satisfied.");
126
+ process.exit(0);
127
+ });
128
+ /* ------------------------------------------------------------ agents-doc --- */
129
+ program
130
+ .command("agents-doc")
131
+ .description("Print the AGENTS.md governance contract for this project")
132
+ .action(() => {
133
+ const project = openProject(process.cwd());
134
+ const path = join(project.root, "AGENTS.md");
135
+ if (existsSync(path)) {
136
+ process.stdout.write(readFileSync(path, "utf8"));
137
+ }
138
+ else {
139
+ process.stdout.write(renderAgentsDoc(project.config));
140
+ }
141
+ });
142
+ program.parseAsync(process.argv);
143
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { KnbaseConfig } from "../types.js";
2
+ /**
3
+ * Generates the AGENTS.md contract placed at the project root. Every agent reads
4
+ * this by convention; it is the primary "soft" enforcement layer.
5
+ */
6
+ export declare function renderAgentsDoc(config: KnbaseConfig): string;
@@ -0,0 +1,50 @@
1
+ import { TEMPLATES } from "./templates.js";
2
+ /**
3
+ * Generates the AGENTS.md contract placed at the project root. Every agent reads
4
+ * this by convention; it is the primary "soft" enforcement layer.
5
+ */
6
+ export function renderAgentsDoc(config) {
7
+ const fileList = config.files
8
+ .map((k) => `- \`${config.docsDir}/${k}.md\` — ${TEMPLATES[k].purpose}`)
9
+ .join("\n");
10
+ return `# AGENTS.md — Governance Contract (managed by knbase)
11
+
12
+ This project is governed by **knbase**. Any AI agent working here MUST follow
13
+ this workflow. Do not skip steps. This exists so any agent can safely extend the
14
+ project from existing code and design without re-deriving context.
15
+
16
+ ## Governance documents (${config.docsDir}/)
17
+
18
+ ${fileList}
19
+
20
+ Plus system artifacts in \`.knbase/\` (index, mind map, activity log) — do not edit by hand.
21
+
22
+ ## Required workflow
23
+
24
+ 1. **Read before acting.** Call the \`start_session\` MCP tool first. It returns a
25
+ compact mind map, per-file summaries, and the current phase. Fetch a full doc
26
+ only when needed via \`get_context(files=[...], full=true)\` to conserve tokens.
27
+ 2. **Bootstrap if missing.** If \`start_session\` reports \`NEEDS_BOOTSTRAP\`, author
28
+ every missing file with \`write_governance_file\` (all required sections) based on
29
+ your understanding of the user's request, BEFORE doing any other work.
30
+ 3. **Gate every task.** Call \`begin_task\` before making changes and \`complete_task\`
31
+ after. \`begin_task\` refuses until context is loaded; \`complete_task\` refuses
32
+ until \`memory.md\` was updated for that task.
33
+ 4. **Update knowledge after each task.** Append what changed to \`memory.md\`
34
+ ("Recent Changes", "Learnings & Gotchas") and advance \`phase.md\` when relevant.
35
+
36
+ ## Without MCP (any agent / shell)
37
+
38
+ - Initialize: \`npx knbase init\`
39
+ - Check status / gate: \`knbase status\` or \`knbase check\`
40
+ - Run gated commands: \`knbase guard -- <your command>\` (refuses until context is loaded)
41
+ - A git \`pre-commit\` hook (via \`knbase install-hooks\`) blocks commits unless a task
42
+ was completed with a memory update.
43
+
44
+ ## Token discipline
45
+
46
+ Prefer summaries and the mind map over full files. Only load full document content
47
+ when a task truly requires it.
48
+ `;
49
+ }
50
+ //# sourceMappingURL=agents-doc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-doc.js","sourceRoot":"","sources":["../../src/core/agents-doc.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAoB;IAClD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,MAAM,CAAC,OAAO,IAAI,CAAC,WAAW,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACvE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;;;;;;2BAMkB,MAAM,CAAC,OAAO;;EAEvC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BT,CAAC;AACF,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { type KnbaseConfig, type GovernanceFileKey } from "../types.js";
2
+ /** Name of the system artifact directory. */
3
+ export declare const SYSTEM_DIR = ".knbase";
4
+ /** Default directory (relative to project root) for the governance docs. */
5
+ export declare const DEFAULT_DOCS_DIR = "memory-bank";
6
+ export declare const DEFAULT_CONFIG: KnbaseConfig;
7
+ /**
8
+ * Resolves the project root. Honors the KNBASE_ROOT env var, otherwise walks
9
+ * up from `startDir` looking for an existing `.knbase` dir or a `.git` dir,
10
+ * falling back to `startDir` itself.
11
+ */
12
+ export declare function resolveProjectRoot(startDir?: string): string;
13
+ export interface ResolvedPaths {
14
+ root: string;
15
+ systemDir: string;
16
+ configPath: string;
17
+ indexPath: string;
18
+ mindmapPath: string;
19
+ logPath: string;
20
+ sessionPath: string;
21
+ docsDir: string;
22
+ /** Absolute path for a given governance file key. */
23
+ docPath: (key: GovernanceFileKey) => string;
24
+ }
25
+ export declare function paths(root: string, config: KnbaseConfig): ResolvedPaths;
26
+ export declare function loadConfig(root: string): KnbaseConfig;
27
+ export declare function saveConfig(root: string, config: KnbaseConfig): void;
28
+ export declare function ensureDir(dir: string): void;
29
+ /** Whether knbase has been initialized in the given root. */
30
+ export declare function isInitialized(root: string): boolean;
@@ -0,0 +1,89 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { dirname, isAbsolute, join, resolve } from "node:path";
3
+ import { GOVERNANCE_FILES, } from "../types.js";
4
+ /** Name of the system artifact directory. */
5
+ export const SYSTEM_DIR = ".knbase";
6
+ /** Default directory (relative to project root) for the governance docs. */
7
+ export const DEFAULT_DOCS_DIR = "memory-bank";
8
+ const CONFIG_VERSION = 1;
9
+ export const DEFAULT_CONFIG = {
10
+ version: CONFIG_VERSION,
11
+ docsDir: DEFAULT_DOCS_DIR,
12
+ files: [...GOVERNANCE_FILES],
13
+ sessionTtlMinutes: 120,
14
+ };
15
+ /**
16
+ * Resolves the project root. Honors the KNBASE_ROOT env var, otherwise walks
17
+ * up from `startDir` looking for an existing `.knbase` dir or a `.git` dir,
18
+ * falling back to `startDir` itself.
19
+ */
20
+ export function resolveProjectRoot(startDir = process.cwd()) {
21
+ const envRoot = process.env.KNBASE_ROOT;
22
+ if (envRoot && envRoot.trim()) {
23
+ return resolve(envRoot.trim());
24
+ }
25
+ let current = resolve(startDir);
26
+ // Walk upward until filesystem root.
27
+ // Prefer an existing .knbase dir; otherwise use the nearest .git.
28
+ let gitFallback = null;
29
+ while (true) {
30
+ if (existsSync(join(current, SYSTEM_DIR)))
31
+ return current;
32
+ if (!gitFallback && existsSync(join(current, ".git")))
33
+ gitFallback = current;
34
+ const parent = dirname(current);
35
+ if (parent === current)
36
+ break;
37
+ current = parent;
38
+ }
39
+ return gitFallback ?? resolve(startDir);
40
+ }
41
+ export function paths(root, config) {
42
+ const systemDir = join(root, SYSTEM_DIR);
43
+ const docsDir = isAbsolute(config.docsDir)
44
+ ? config.docsDir
45
+ : join(root, config.docsDir);
46
+ return {
47
+ root,
48
+ systemDir,
49
+ configPath: join(systemDir, "config.json"),
50
+ indexPath: join(systemDir, "index.json"),
51
+ mindmapPath: join(systemDir, "mindmap.md"),
52
+ logPath: join(systemDir, "activity.log"),
53
+ sessionPath: join(systemDir, "session.json"),
54
+ docsDir,
55
+ docPath: (key) => join(docsDir, `${key}.md`),
56
+ };
57
+ }
58
+ export function loadConfig(root) {
59
+ const configPath = join(root, SYSTEM_DIR, "config.json");
60
+ if (!existsSync(configPath))
61
+ return { ...DEFAULT_CONFIG };
62
+ try {
63
+ const raw = JSON.parse(readFileSync(configPath, "utf8"));
64
+ return {
65
+ ...DEFAULT_CONFIG,
66
+ ...raw,
67
+ files: Array.isArray(raw.files) && raw.files.length > 0
68
+ ? raw.files
69
+ : DEFAULT_CONFIG.files,
70
+ };
71
+ }
72
+ catch {
73
+ return { ...DEFAULT_CONFIG };
74
+ }
75
+ }
76
+ export function saveConfig(root, config) {
77
+ const configPath = join(root, SYSTEM_DIR, "config.json");
78
+ ensureDir(dirname(configPath));
79
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf8");
80
+ }
81
+ export function ensureDir(dir) {
82
+ if (!existsSync(dir))
83
+ mkdirSync(dir, { recursive: true });
84
+ }
85
+ /** Whether knbase has been initialized in the given root. */
86
+ export function isInitialized(root) {
87
+ return existsSync(join(root, SYSTEM_DIR, "config.json"));
88
+ }
89
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ import { type ResolvedPaths } from "./config.js";
2
+ import { appendLog, hasTaskCompletedSince, readLog } from "./log.js";
3
+ import { clearSession, loadSession } from "./session.js";
4
+ import type { KnbaseConfig, GovernanceFileKey, SessionData } from "../types.js";
5
+ export interface Project {
6
+ root: string;
7
+ config: KnbaseConfig;
8
+ p: ResolvedPaths;
9
+ }
10
+ /** Open a project handle (does not create anything). */
11
+ export declare function openProject(startDir?: string): Project;
12
+ export declare function isKnownFile(config: KnbaseConfig, key: string): key is GovernanceFileKey;
13
+ export interface InitResult {
14
+ root: string;
15
+ createdConfig: boolean;
16
+ scaffolded: GovernanceFileKey[];
17
+ alreadyPresent: GovernanceFileKey[];
18
+ }
19
+ /**
20
+ * Initialize knbase in a project: create `.knbase/`, write config, scaffold
21
+ * any missing governance docs with templates, build index + mindmap.
22
+ */
23
+ export declare function initProject(startDir?: string, docsDir?: string): InitResult;
24
+ export interface StartSessionResult {
25
+ sessionId: string;
26
+ state: SessionData["state"];
27
+ needsBootstrap: boolean;
28
+ missing: GovernanceFileKey[];
29
+ instructions: string;
30
+ compactContext?: CompactContext;
31
+ bootstrapTemplates?: {
32
+ key: GovernanceFileKey;
33
+ requiredSections: string[];
34
+ }[];
35
+ }
36
+ export interface CompactContext {
37
+ currentPhase: string;
38
+ mindmap: string;
39
+ files: {
40
+ key: GovernanceFileKey;
41
+ exists: boolean;
42
+ summary: string;
43
+ headings: string[];
44
+ bytes: number;
45
+ updatedAt: string | null;
46
+ }[];
47
+ }
48
+ export declare function startSession(project: Project): StartSessionResult;
49
+ export interface GetContextResult {
50
+ compact: CompactContext;
51
+ fullContents?: {
52
+ key: GovernanceFileKey;
53
+ content: string;
54
+ }[];
55
+ }
56
+ export declare function getContext(project: Project, files?: string[], full?: boolean): GetContextResult;
57
+ export interface WriteResult {
58
+ key: GovernanceFileKey;
59
+ bytes: number;
60
+ ok: boolean;
61
+ missingSections: string[];
62
+ remainingBootstrap: GovernanceFileKey[];
63
+ state: SessionData["state"];
64
+ }
65
+ export declare function writeGovernanceFile(project: Project, key: string, content: string, summary: string): WriteResult;
66
+ export interface BeginTaskResult {
67
+ ok: boolean;
68
+ taskId?: string;
69
+ error?: string;
70
+ reminder?: string;
71
+ }
72
+ export declare function beginTask(project: Project, description: string): BeginTaskResult;
73
+ export interface CompleteTaskResult {
74
+ ok: boolean;
75
+ error?: string;
76
+ updatedFiles?: GovernanceFileKey[];
77
+ state?: SessionData["state"];
78
+ }
79
+ export declare function completeTask(project: Project, taskId: string, summary: string): CompleteTaskResult;
80
+ export interface StatusResult {
81
+ initialized: boolean;
82
+ root: string;
83
+ docsDir: string;
84
+ state: SessionData["state"];
85
+ sessionFresh: boolean;
86
+ missing: GovernanceFileKey[];
87
+ activeTask: SessionData["activeTask"];
88
+ recentLog: ReturnType<typeof readLog>;
89
+ }
90
+ export declare function getStatus(project: Project): StatusResult;
91
+ export interface GuardDecision {
92
+ allow: boolean;
93
+ reason: string;
94
+ }
95
+ /**
96
+ * Decide whether a gated shell command may run. Requires: initialized project,
97
+ * all governance files present, and a fresh CONTEXT_LOADED/TASK_ACTIVE session
98
+ * whose loaded context still matches disk.
99
+ */
100
+ export declare function guardDecision(project: Project): GuardDecision;
101
+ export { appendLog, clearSession, hasTaskCompletedSince, loadSession, readLog, };