@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.
- package/README.md +182 -0
- package/bin/knbase +5 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +143 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/agents-doc.d.ts +6 -0
- package/dist/core/agents-doc.js +50 -0
- package/dist/core/agents-doc.js.map +1 -0
- package/dist/core/config.d.ts +30 -0
- package/dist/core/config.js +89 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/engine.d.ts +101 -0
- package/dist/core/engine.js +350 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/files.d.ts +23 -0
- package/dist/core/files.js +66 -0
- package/dist/core/files.js.map +1 -0
- package/dist/core/index-store.d.ts +17 -0
- package/dist/core/index-store.js +97 -0
- package/dist/core/index-store.js.map +1 -0
- package/dist/core/log.d.ts +11 -0
- package/dist/core/log.js +38 -0
- package/dist/core/log.js.map +1 -0
- package/dist/core/mindmap.d.ts +11 -0
- package/dist/core/mindmap.js +71 -0
- package/dist/core/mindmap.js.map +1 -0
- package/dist/core/session.d.ts +15 -0
- package/dist/core/session.js +53 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/templates.d.ts +16 -0
- package/dist/core/templates.js +163 -0
- package/dist/core/templates.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.js +39 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +2 -0
- package/dist/mcp/tools.js +129 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/types.d.ts +67 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- 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,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":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EACL,gBAAgB,GAGjB,MAAM,aAAa,CAAC;AAErB,6CAA6C;AAC7C,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC;AACpC,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAE9C,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,OAAO,EAAE,cAAc;IACvB,OAAO,EAAE,gBAAgB;IACzB,KAAK,EAAE,CAAC,GAAG,gBAAgB,CAAC;IAC5B,iBAAiB,EAAE,GAAG;CACvB,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IACjE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IACxC,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChC,qCAAqC;IACrC,kEAAkE;IAClE,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAAE,OAAO,OAAO,CAAC;QAC1D,IAAI,CAAC,WAAW,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAAE,WAAW,GAAG,OAAO,CAAC;QAC7E,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,MAAM,KAAK,OAAO;YAAE,MAAM;QAC9B,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;IACD,OAAO,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAeD,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,MAAoB;IACtD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC;QACxC,CAAC,CAAC,MAAM,CAAC,OAAO;QAChB,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO;QACL,IAAI;QACJ,SAAS;QACT,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC;QAC1C,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC;QACxC,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC;QAC1C,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC;QACxC,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC;QAC5C,OAAO;QACP,OAAO,EAAE,CAAC,GAAsB,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,KAAK,CAAC;KAChE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC1D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAA0B,CAAC;QAClF,OAAO;YACL,GAAG,cAAc;YACjB,GAAG,GAAG;YACN,KAAK,EACH,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;gBAC9C,CAAC,CAAE,GAAG,CAAC,KAA6B;gBACpC,CAAC,CAAC,cAAc,CAAC,KAAK;SAC3B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,MAAoB;IAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;IACzD,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAC/B,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -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, };
|