@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
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { writeFileSync } from "node:fs";
|
|
2
|
+
import { ensureDir } from "./config.js";
|
|
3
|
+
import { TEMPLATES } from "./templates.js";
|
|
4
|
+
/** Escape a label for use inside a mermaid mindmap node. */
|
|
5
|
+
function safeLabel(text) {
|
|
6
|
+
return text
|
|
7
|
+
.replace(/[\r\n]+/g, " ")
|
|
8
|
+
.replace(/["`]/g, "'")
|
|
9
|
+
.replace(/[()]/g, "")
|
|
10
|
+
.replace(/[[\]{}]/g, "")
|
|
11
|
+
.trim();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Build a deterministic mermaid `mindmap` from the index: root -> one node per
|
|
15
|
+
* governance file (with its one-line summary) -> child nodes per H2 heading.
|
|
16
|
+
* No LLM involved; purely structural, so it is cheap and reproducible.
|
|
17
|
+
*/
|
|
18
|
+
export function buildMindmap(config, index) {
|
|
19
|
+
const lines = ["mindmap", " root((Project))"];
|
|
20
|
+
for (const key of config.files) {
|
|
21
|
+
const entry = index.files[key];
|
|
22
|
+
const tpl = TEMPLATES[key];
|
|
23
|
+
const title = tpl?.title ?? key;
|
|
24
|
+
const status = entry.exists ? "" : " [missing]";
|
|
25
|
+
lines.push(` ${safeLabel(title)}${status}`);
|
|
26
|
+
if (entry.summary) {
|
|
27
|
+
lines.push(` ::icon(fa fa-info)`);
|
|
28
|
+
lines.push(` ${safeLabel(entry.summary)}`);
|
|
29
|
+
}
|
|
30
|
+
for (const heading of entry.headings) {
|
|
31
|
+
lines.push(` ${safeLabel(heading)}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return lines.join("\n");
|
|
35
|
+
}
|
|
36
|
+
/** Render the full mindmap.md document (fenced mermaid + text summary table). */
|
|
37
|
+
export function renderMindmapDoc(config, index) {
|
|
38
|
+
const mermaid = buildMindmap(config, index);
|
|
39
|
+
const rows = config.files.map((key) => {
|
|
40
|
+
const e = index.files[key];
|
|
41
|
+
const tpl = TEMPLATES[key];
|
|
42
|
+
const state = e.exists ? "ok" : "missing";
|
|
43
|
+
const summary = e.summary || (tpl ? tpl.purpose : "");
|
|
44
|
+
return `| ${key} | ${state} | ${summary.replace(/\|/g, "\\|")} |`;
|
|
45
|
+
});
|
|
46
|
+
return [
|
|
47
|
+
"# Project Mind Map",
|
|
48
|
+
"",
|
|
49
|
+
"<!-- Auto-generated by knbase. Do not edit by hand. -->",
|
|
50
|
+
"",
|
|
51
|
+
"```mermaid",
|
|
52
|
+
mermaid,
|
|
53
|
+
"```",
|
|
54
|
+
"",
|
|
55
|
+
"## Index",
|
|
56
|
+
"",
|
|
57
|
+
"| File | State | Summary |",
|
|
58
|
+
"| --- | --- | --- |",
|
|
59
|
+
...rows,
|
|
60
|
+
"",
|
|
61
|
+
`_Updated: ${new Date().toISOString()}_`,
|
|
62
|
+
"",
|
|
63
|
+
].join("\n");
|
|
64
|
+
}
|
|
65
|
+
export function writeMindmap(p, config, index) {
|
|
66
|
+
ensureDir(p.systemDir);
|
|
67
|
+
const doc = renderMindmapDoc(config, index);
|
|
68
|
+
writeFileSync(p.mindmapPath, doc, "utf8");
|
|
69
|
+
return doc;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=mindmap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mindmap.js","sourceRoot":"","sources":["../../src/core/mindmap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ResolvedPaths } from "./config.js";
|
|
2
|
+
import type { KnbaseConfig, SessionData } from "../types.js";
|
|
3
|
+
export declare function loadSession(p: ResolvedPaths): SessionData | null;
|
|
4
|
+
export declare function saveSession(p: ResolvedPaths, session: SessionData): void;
|
|
5
|
+
export declare function clearSession(p: ResolvedPaths): void;
|
|
6
|
+
export declare function newSessionId(): string;
|
|
7
|
+
export declare function newTaskId(): string;
|
|
8
|
+
/**
|
|
9
|
+
* A session is fresh when it exists, is in a usable state, and started within
|
|
10
|
+
* the configured TTL. Stale sessions force the agent to re-load context, which
|
|
11
|
+
* is the CLI guard's primary gate.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isSessionFresh(session: SessionData | null, config: KnbaseConfig): boolean;
|
|
14
|
+
/** True when context loaded during the session matches files currently on disk. */
|
|
15
|
+
export declare function contextMatchesDisk(session: SessionData | null, current: Record<string, string>): boolean;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { ensureDir } from "./config.js";
|
|
4
|
+
export function loadSession(p) {
|
|
5
|
+
if (!existsSync(p.sessionPath))
|
|
6
|
+
return null;
|
|
7
|
+
try {
|
|
8
|
+
return JSON.parse(readFileSync(p.sessionPath, "utf8"));
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function saveSession(p, session) {
|
|
15
|
+
ensureDir(p.systemDir);
|
|
16
|
+
writeFileSync(p.sessionPath, JSON.stringify(session, null, 2) + "\n", "utf8");
|
|
17
|
+
}
|
|
18
|
+
export function clearSession(p) {
|
|
19
|
+
if (existsSync(p.sessionPath))
|
|
20
|
+
rmSync(p.sessionPath);
|
|
21
|
+
}
|
|
22
|
+
export function newSessionId() {
|
|
23
|
+
return `s_${randomUUID().slice(0, 8)}`;
|
|
24
|
+
}
|
|
25
|
+
export function newTaskId() {
|
|
26
|
+
return `t_${randomUUID().slice(0, 8)}`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A session is fresh when it exists, is in a usable state, and started within
|
|
30
|
+
* the configured TTL. Stale sessions force the agent to re-load context, which
|
|
31
|
+
* is the CLI guard's primary gate.
|
|
32
|
+
*/
|
|
33
|
+
export function isSessionFresh(session, config) {
|
|
34
|
+
if (!session)
|
|
35
|
+
return false;
|
|
36
|
+
if (session.state === "UNINITIALIZED" || session.state === "NEEDS_BOOTSTRAP") {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
const ageMs = Date.now() - Date.parse(session.startedAt);
|
|
40
|
+
const ttlMs = config.sessionTtlMinutes * 60_000;
|
|
41
|
+
return ageMs <= ttlMs;
|
|
42
|
+
}
|
|
43
|
+
/** True when context loaded during the session matches files currently on disk. */
|
|
44
|
+
export function contextMatchesDisk(session, current) {
|
|
45
|
+
if (!session)
|
|
46
|
+
return false;
|
|
47
|
+
for (const [key, sum] of Object.entries(current)) {
|
|
48
|
+
if (session.contextChecksums[key] !== sum)
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAsB,MAAM,aAAa,CAAC;AAG5D,MAAM,UAAU,WAAW,CAAC,CAAgB;IAC1C,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,CAAgB,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,CAAgB,EAAE,OAAoB;IAChE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACvB,aAAa,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAgB;IAC3C,IAAI,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;QAAE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,KAAK,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,KAAK,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,OAA2B,EAC3B,MAAoB;IAEpB,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,OAAO,CAAC,KAAK,KAAK,eAAe,IAAI,OAAO,CAAC,KAAK,KAAK,iBAAiB,EAAE,CAAC;QAC7E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,MAAM,CAAC,iBAAiB,GAAG,MAAM,CAAC;IAChD,OAAO,KAAK,IAAI,KAAK,CAAC;AACxB,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,kBAAkB,CAChC,OAA2B,EAC3B,OAA+B;IAE/B,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,IAAI,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,GAAG;YAAE,OAAO,KAAK,CAAC;IAC1D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GovernanceFileKey } from "../types.js";
|
|
2
|
+
export interface TemplateDef {
|
|
3
|
+
key: GovernanceFileKey;
|
|
4
|
+
title: string;
|
|
5
|
+
/** One-line description of the file's purpose. */
|
|
6
|
+
purpose: string;
|
|
7
|
+
/**
|
|
8
|
+
* Required H2 (##) section headings. Bootstrap templates include them, and
|
|
9
|
+
* `write_governance_file` validates that these are present.
|
|
10
|
+
*/
|
|
11
|
+
requiredSections: string[];
|
|
12
|
+
/** Full markdown scaffold written when the file is missing. */
|
|
13
|
+
scaffold: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const TEMPLATES: Record<GovernanceFileKey, TemplateDef>;
|
|
16
|
+
export declare function templateFor(key: GovernanceFileKey): TemplateDef;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
function scaffoldFrom(title, purpose, sections) {
|
|
2
|
+
const body = sections
|
|
3
|
+
.map((s) => `## ${s.heading}\n\n> ${s.hint}\n`)
|
|
4
|
+
.join("\n");
|
|
5
|
+
return `# ${title}\n\n<!-- ${purpose} -->\n<!-- Managed by knbase. Replace the guidance blockquotes with real content. -->\n\n${body}`;
|
|
6
|
+
}
|
|
7
|
+
export const TEMPLATES = {
|
|
8
|
+
prd: {
|
|
9
|
+
key: "prd",
|
|
10
|
+
title: "Product Requirements (PRD)",
|
|
11
|
+
purpose: "What we are building and why. The single source of product truth.",
|
|
12
|
+
requiredSections: [
|
|
13
|
+
"Problem",
|
|
14
|
+
"Goals",
|
|
15
|
+
"Users & Personas",
|
|
16
|
+
"Functional Requirements",
|
|
17
|
+
"Non-Goals",
|
|
18
|
+
"Success Metrics",
|
|
19
|
+
],
|
|
20
|
+
scaffold: scaffoldFrom("Product Requirements (PRD)", "What we are building and why.", [
|
|
21
|
+
{ heading: "Problem", hint: "What problem does this solve? For whom?" },
|
|
22
|
+
{ heading: "Goals", hint: "The concrete outcomes this project must achieve." },
|
|
23
|
+
{ heading: "Users & Personas", hint: "Who uses this and what they need." },
|
|
24
|
+
{
|
|
25
|
+
heading: "Functional Requirements",
|
|
26
|
+
hint: "Numbered list of what the system must do.",
|
|
27
|
+
},
|
|
28
|
+
{ heading: "Non-Goals", hint: "Explicitly out of scope, to prevent drift." },
|
|
29
|
+
{ heading: "Success Metrics", hint: "How we measure that it works." },
|
|
30
|
+
]),
|
|
31
|
+
},
|
|
32
|
+
architecture: {
|
|
33
|
+
key: "architecture",
|
|
34
|
+
title: "Architecture",
|
|
35
|
+
purpose: "High-level system structure, components, and data flow.",
|
|
36
|
+
requiredSections: [
|
|
37
|
+
"Overview",
|
|
38
|
+
"Components",
|
|
39
|
+
"Data Flow",
|
|
40
|
+
"Tech Stack",
|
|
41
|
+
"External Dependencies",
|
|
42
|
+
],
|
|
43
|
+
scaffold: scaffoldFrom("Architecture", "High-level system structure and data flow.", [
|
|
44
|
+
{ heading: "Overview", hint: "A paragraph describing the system shape." },
|
|
45
|
+
{
|
|
46
|
+
heading: "Components",
|
|
47
|
+
hint: "Each major component, its responsibility, and its location in the repo.",
|
|
48
|
+
},
|
|
49
|
+
{ heading: "Data Flow", hint: "How data/requests move through components." },
|
|
50
|
+
{ heading: "Tech Stack", hint: "Languages, frameworks, runtimes, databases." },
|
|
51
|
+
{
|
|
52
|
+
heading: "External Dependencies",
|
|
53
|
+
hint: "Third-party services, APIs, and libraries with a role.",
|
|
54
|
+
},
|
|
55
|
+
]),
|
|
56
|
+
},
|
|
57
|
+
design: {
|
|
58
|
+
key: "design",
|
|
59
|
+
title: "Design",
|
|
60
|
+
purpose: "Detailed design decisions, interfaces, and conventions.",
|
|
61
|
+
requiredSections: [
|
|
62
|
+
"Modules & Interfaces",
|
|
63
|
+
"Key Decisions",
|
|
64
|
+
"Data Models",
|
|
65
|
+
"Conventions",
|
|
66
|
+
"Open Questions",
|
|
67
|
+
],
|
|
68
|
+
scaffold: scaffoldFrom("Design", "Detailed design decisions and interfaces.", [
|
|
69
|
+
{
|
|
70
|
+
heading: "Modules & Interfaces",
|
|
71
|
+
hint: "Public APIs, function/class signatures, and contracts between modules.",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
heading: "Key Decisions",
|
|
75
|
+
hint: "Decisions taken and the rationale/trade-offs (ADR-style).",
|
|
76
|
+
},
|
|
77
|
+
{ heading: "Data Models", hint: "Schemas, types, and their relationships." },
|
|
78
|
+
{
|
|
79
|
+
heading: "Conventions",
|
|
80
|
+
hint: "Naming, error handling, folder layout, and style rules.",
|
|
81
|
+
},
|
|
82
|
+
{ heading: "Open Questions", hint: "Unresolved design questions to revisit." },
|
|
83
|
+
]),
|
|
84
|
+
},
|
|
85
|
+
phase: {
|
|
86
|
+
key: "phase",
|
|
87
|
+
title: "Phases & Roadmap",
|
|
88
|
+
purpose: "Where the project is now and what comes next.",
|
|
89
|
+
requiredSections: [
|
|
90
|
+
"Current Phase",
|
|
91
|
+
"Completed",
|
|
92
|
+
"In Progress",
|
|
93
|
+
"Next Up",
|
|
94
|
+
"Backlog",
|
|
95
|
+
],
|
|
96
|
+
scaffold: scaffoldFrom("Phases & Roadmap", "Where the project is now and what comes next.", [
|
|
97
|
+
{
|
|
98
|
+
heading: "Current Phase",
|
|
99
|
+
hint: "Name and one-line status of the phase currently in flight.",
|
|
100
|
+
},
|
|
101
|
+
{ heading: "Completed", hint: "Checklist of finished milestones." },
|
|
102
|
+
{ heading: "In Progress", hint: "What is actively being worked on." },
|
|
103
|
+
{ heading: "Next Up", hint: "The next 1-3 items to pick up." },
|
|
104
|
+
{ heading: "Backlog", hint: "Everything else, unordered." },
|
|
105
|
+
]),
|
|
106
|
+
},
|
|
107
|
+
rules: {
|
|
108
|
+
key: "rules",
|
|
109
|
+
title: "Rules & Constraints",
|
|
110
|
+
purpose: "Hard rules every agent must obey when working in this project.",
|
|
111
|
+
requiredSections: [
|
|
112
|
+
"Must Do",
|
|
113
|
+
"Must Not Do",
|
|
114
|
+
"Coding Standards",
|
|
115
|
+
"Guardrails",
|
|
116
|
+
],
|
|
117
|
+
scaffold: scaffoldFrom("Rules & Constraints", "Hard rules every agent must obey.", [
|
|
118
|
+
{ heading: "Must Do", hint: "Non-negotiable practices (tests, reviews, etc.)." },
|
|
119
|
+
{
|
|
120
|
+
heading: "Must Not Do",
|
|
121
|
+
hint: "Forbidden actions (e.g. never touch prod secrets).",
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
heading: "Coding Standards",
|
|
125
|
+
hint: "Language/style rules specific to this project.",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
heading: "Guardrails",
|
|
129
|
+
hint: "Safety limits: files that are off-limits, destructive ops to avoid.",
|
|
130
|
+
},
|
|
131
|
+
]),
|
|
132
|
+
},
|
|
133
|
+
memory: {
|
|
134
|
+
key: "memory",
|
|
135
|
+
title: "Project Memory",
|
|
136
|
+
purpose: "Running knowledge base updated after every task so future agents can extend the project.",
|
|
137
|
+
requiredSections: [
|
|
138
|
+
"Summary",
|
|
139
|
+
"Recent Changes",
|
|
140
|
+
"Learnings & Gotchas",
|
|
141
|
+
"Known Issues",
|
|
142
|
+
],
|
|
143
|
+
scaffold: scaffoldFrom("Project Memory", "Running knowledge base updated after every task.", [
|
|
144
|
+
{
|
|
145
|
+
heading: "Summary",
|
|
146
|
+
hint: "Current state of the project in a few sentences.",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
heading: "Recent Changes",
|
|
150
|
+
hint: "Reverse-chronological log of notable changes (append after each task).",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
heading: "Learnings & Gotchas",
|
|
154
|
+
hint: "Things discovered that future agents must know.",
|
|
155
|
+
},
|
|
156
|
+
{ heading: "Known Issues", hint: "Bugs, tech debt, and workarounds." },
|
|
157
|
+
]),
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
export function templateFor(key) {
|
|
161
|
+
return TEMPLATES[key];
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/core/templates.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { realpathSync } from "node:fs";
|
|
4
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
+
import { registerTools } from "./tools.js";
|
|
7
|
+
export function createServer() {
|
|
8
|
+
const server = new McpServer({
|
|
9
|
+
name: "knbase",
|
|
10
|
+
version: "0.1.0",
|
|
11
|
+
});
|
|
12
|
+
registerTools(server);
|
|
13
|
+
return server;
|
|
14
|
+
}
|
|
15
|
+
async function main() {
|
|
16
|
+
const server = createServer();
|
|
17
|
+
const transport = new StdioServerTransport();
|
|
18
|
+
await server.connect(transport);
|
|
19
|
+
// stderr is safe for logging; stdout is reserved for the MCP protocol.
|
|
20
|
+
process.stderr.write("[knbase] MCP server running on stdio\n");
|
|
21
|
+
}
|
|
22
|
+
function isMain() {
|
|
23
|
+
const entry = process.argv[1];
|
|
24
|
+
if (!entry)
|
|
25
|
+
return false;
|
|
26
|
+
try {
|
|
27
|
+
return realpathSync(entry) === realpathSync(fileURLToPath(import.meta.url));
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (isMain()) {
|
|
34
|
+
main().catch((err) => {
|
|
35
|
+
process.stderr.write(`[knbase] Fatal: ${err.stack ?? err}\n`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IACH,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,uEAAuE;IACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,MAAM;IACb,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,IAAI,MAAM,EAAE,EAAE,CAAC;IACb,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAoB,GAAa,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { beginTask, completeTask, getContext, getStatus, openProject, startSession, writeGovernanceFile, } from "../core/engine.js";
|
|
3
|
+
import { renderMindmapDoc } from "../core/mindmap.js";
|
|
4
|
+
import { refreshIndex, saveIndex } from "../core/index-store.js";
|
|
5
|
+
import { GOVERNANCE_FILES } from "../types.js";
|
|
6
|
+
function ok(payload) {
|
|
7
|
+
return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] };
|
|
8
|
+
}
|
|
9
|
+
function fail(message, extra) {
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{ type: "text", text: JSON.stringify({ error: message, ...(extra ? { extra } : {}) }, null, 2) },
|
|
13
|
+
],
|
|
14
|
+
isError: true,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Determines the project root for a tool call. The client may pass an explicit
|
|
19
|
+
* `root`; otherwise the server falls back to KNBASE_ROOT / cwd resolution.
|
|
20
|
+
*/
|
|
21
|
+
function project(root) {
|
|
22
|
+
return openProject(root);
|
|
23
|
+
}
|
|
24
|
+
export function registerTools(server) {
|
|
25
|
+
const fileEnum = z.enum(GOVERNANCE_FILES);
|
|
26
|
+
const rootArg = { root: z.string().optional().describe("Absolute project root. Defaults to KNBASE_ROOT or cwd.") };
|
|
27
|
+
server.registerTool("start_session", {
|
|
28
|
+
title: "Start governance session",
|
|
29
|
+
description: "MANDATORY FIRST CALL. Loads project governance context (mind map + summaries + current phase) token-efficiently. If governance files are missing, returns bootstrap templates and instructs you to author them before doing any work.",
|
|
30
|
+
inputSchema: { ...rootArg },
|
|
31
|
+
}, async ({ root }) => {
|
|
32
|
+
try {
|
|
33
|
+
return ok(startSession(project(root)));
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
return fail(e.message);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
server.registerTool("get_context", {
|
|
40
|
+
title: "Get governance context",
|
|
41
|
+
description: "Returns the compact context (mind map + summaries + phase). Pass files=[...] with full=true to fetch full contents of specific docs ONLY when needed, to conserve tokens.",
|
|
42
|
+
inputSchema: {
|
|
43
|
+
...rootArg,
|
|
44
|
+
files: z.array(fileEnum).optional().describe("Governance files to fetch in full."),
|
|
45
|
+
full: z.boolean().optional().describe("If true, include full contents of `files`."),
|
|
46
|
+
},
|
|
47
|
+
}, async ({ root, files, full }) => {
|
|
48
|
+
try {
|
|
49
|
+
return ok(getContext(project(root), files, full));
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
return fail(e.message);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
server.registerTool("write_governance_file", {
|
|
56
|
+
title: "Write/update a governance file",
|
|
57
|
+
description: "Create or update one governance doc (prd, architecture, design, phase, rules, memory). Validates that all required sections are present, then refreshes the index and mind map. Use for bootstrap AND for post-task updates.",
|
|
58
|
+
inputSchema: {
|
|
59
|
+
...rootArg,
|
|
60
|
+
file: fileEnum.describe("Which governance file to write."),
|
|
61
|
+
content: z.string().describe("Full markdown content (must include all required H2 sections)."),
|
|
62
|
+
summary: z
|
|
63
|
+
.string()
|
|
64
|
+
.describe("One-line summary of this file (shown in mind map to save tokens)."),
|
|
65
|
+
},
|
|
66
|
+
}, async ({ root, file, content, summary }) => {
|
|
67
|
+
try {
|
|
68
|
+
const result = writeGovernanceFile(project(root), file, content, summary);
|
|
69
|
+
if (!result.ok) {
|
|
70
|
+
return fail(`Missing required sections in ${file}.md: ${result.missingSections.join(", ")}`, result);
|
|
71
|
+
}
|
|
72
|
+
return ok(result);
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
return fail(e.message);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
server.registerTool("begin_task", {
|
|
79
|
+
title: "Begin a task (gated)",
|
|
80
|
+
description: "Call BEFORE making any changes. Refuses unless context has been loaded this session (the read-before-action gate). Returns a taskId.",
|
|
81
|
+
inputSchema: {
|
|
82
|
+
...rootArg,
|
|
83
|
+
description: z.string().describe("What this task will accomplish."),
|
|
84
|
+
},
|
|
85
|
+
}, async ({ root, description }) => {
|
|
86
|
+
const result = beginTask(project(root), description);
|
|
87
|
+
return result.ok ? ok(result) : fail(result.error ?? "begin_task failed", result);
|
|
88
|
+
});
|
|
89
|
+
server.registerTool("complete_task", {
|
|
90
|
+
title: "Complete a task (gated)",
|
|
91
|
+
description: "Call AFTER finishing work. Refuses unless memory.md was updated during the task (the update-after-action gate). Regenerates the mind map and appends the activity log.",
|
|
92
|
+
inputSchema: {
|
|
93
|
+
...rootArg,
|
|
94
|
+
taskId: z.string().describe("The taskId returned by begin_task."),
|
|
95
|
+
summary: z.string().describe("What was accomplished (recorded in the activity log)."),
|
|
96
|
+
},
|
|
97
|
+
}, async ({ root, taskId, summary }) => {
|
|
98
|
+
const result = completeTask(project(root), taskId, summary);
|
|
99
|
+
return result.ok ? ok(result) : fail(result.error ?? "complete_task failed", result);
|
|
100
|
+
});
|
|
101
|
+
server.registerTool("get_mindmap", {
|
|
102
|
+
title: "Get combined mind map",
|
|
103
|
+
description: "Returns the auto-generated mermaid mind map + index table combining all governance docs.",
|
|
104
|
+
inputSchema: { ...rootArg },
|
|
105
|
+
}, async ({ root }) => {
|
|
106
|
+
try {
|
|
107
|
+
const proj = project(root);
|
|
108
|
+
const index = refreshIndex(proj.p, proj.config);
|
|
109
|
+
saveIndex(proj.p, index);
|
|
110
|
+
return ok({ mindmap: renderMindmapDoc(proj.config, index) });
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
return fail(e.message);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
server.registerTool("get_status", {
|
|
117
|
+
title: "Get governance status",
|
|
118
|
+
description: "Returns session state, missing files, active task, and recent activity log.",
|
|
119
|
+
inputSchema: { ...rootArg },
|
|
120
|
+
}, async ({ root }) => {
|
|
121
|
+
try {
|
|
122
|
+
return ok(getStatus(project(root)));
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
return fail(e.message);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/C,SAAS,EAAE,CAAC,OAAgB;IAC1B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACjF,CAAC;AAED,SAAS,IAAI,CAAC,OAAe,EAAE,KAAe;IAC5C,OAAO;QACL,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;SACjG;QACD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,IAAa;IAC5B,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAiB;IAC7C,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC,EAAE,CAAC;IAEnH,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,KAAK,EAAE,0BAA0B;QACjC,WAAW,EACT,uOAAuO;QACzO,WAAW,EAAE,EAAE,GAAG,OAAO,EAAE;KAC5B,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACjB,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,2KAA2K;QAC7K,WAAW,EAAE;YACX,GAAG,OAAO;YACV,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;YAClF,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;SACpF;KACF,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;QAC9B,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,gCAAgC;QACvC,WAAW,EACT,8NAA8N;QAChO,WAAW,EAAE;YACX,GAAG,OAAO;YACV,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,iCAAiC,CAAC;YAC1D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gEAAgE,CAAC;YAC9F,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,QAAQ,CAAC,mEAAmE,CAAC;SACjF;KACF,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAC1E,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,OAAO,IAAI,CACT,gCAAgC,IAAI,QAAQ,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAC/E,MAAM,CACP,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,sIAAsI;QACxI,WAAW,EAAE;YACX,GAAG,OAAO;YACV,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;SACpE;KACF,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE;QAC9B,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC;QACrD,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,mBAAmB,EAAE,MAAM,CAAC,CAAC;IACpF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EACT,wKAAwK;QAC1K,WAAW,EAAE;YACX,GAAG,OAAO;YACV,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;YACjE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uDAAuD,CAAC;SACtF;KACF,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QAClC,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAC5D,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,sBAAsB,EAAE,MAAM,CAAC,CAAC;IACvF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EAAE,0FAA0F;QACvG,WAAW,EAAE,EAAE,GAAG,OAAO,EAAE;KAC5B,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAC3B,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAChD,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YACzB,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EAAE,6EAA6E;QAC1F,WAAW,EAAE,EAAE,GAAG,OAAO,EAAE;KAC5B,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACjB,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the knbase governance system.
|
|
3
|
+
*/
|
|
4
|
+
/** Canonical governance document keys. Order defines display order everywhere. */
|
|
5
|
+
export declare const GOVERNANCE_FILES: readonly ["prd", "architecture", "design", "phase", "rules", "memory"];
|
|
6
|
+
export type GovernanceFileKey = (typeof GOVERNANCE_FILES)[number];
|
|
7
|
+
/** Session gate states. The state machine enforces the read -> act -> update flow. */
|
|
8
|
+
export type SessionState = "UNINITIALIZED" | "NEEDS_BOOTSTRAP" | "CONTEXT_LOADED" | "TASK_ACTIVE";
|
|
9
|
+
/** Per-file metadata cached in .knbase/index.json. */
|
|
10
|
+
export interface FileIndexEntry {
|
|
11
|
+
/** Governance file key. */
|
|
12
|
+
key: GovernanceFileKey;
|
|
13
|
+
/** Relative path from project root. */
|
|
14
|
+
path: string;
|
|
15
|
+
/** Whether the file currently exists on disk. */
|
|
16
|
+
exists: boolean;
|
|
17
|
+
/** SHA-256 checksum of file contents (empty string when missing). */
|
|
18
|
+
checksum: string;
|
|
19
|
+
/** Size in bytes. */
|
|
20
|
+
bytes: number;
|
|
21
|
+
/** One-line summary supplied by the agent at write time. */
|
|
22
|
+
summary: string;
|
|
23
|
+
/** Markdown H2 (##) section headings extracted from the file. */
|
|
24
|
+
headings: string[];
|
|
25
|
+
/** ISO timestamp of the last write through the system. */
|
|
26
|
+
updatedAt: string | null;
|
|
27
|
+
}
|
|
28
|
+
export interface IndexData {
|
|
29
|
+
version: number;
|
|
30
|
+
updatedAt: string;
|
|
31
|
+
files: Record<GovernanceFileKey, FileIndexEntry>;
|
|
32
|
+
}
|
|
33
|
+
export interface SessionData {
|
|
34
|
+
sessionId: string;
|
|
35
|
+
state: SessionState;
|
|
36
|
+
startedAt: string;
|
|
37
|
+
/** Checksums of governance files at the moment context was loaded. */
|
|
38
|
+
contextChecksums: Record<string, string>;
|
|
39
|
+
activeTask: ActiveTask | null;
|
|
40
|
+
}
|
|
41
|
+
export interface ActiveTask {
|
|
42
|
+
taskId: string;
|
|
43
|
+
description: string;
|
|
44
|
+
startedAt: string;
|
|
45
|
+
/** Checksums of governance files when the task began (to detect updates). */
|
|
46
|
+
startChecksums: Record<string, string>;
|
|
47
|
+
}
|
|
48
|
+
export interface KnbaseConfig {
|
|
49
|
+
version: number;
|
|
50
|
+
/** Directory (relative to project root) holding the governance docs. */
|
|
51
|
+
docsDir: string;
|
|
52
|
+
/** Governance file keys managed by the system. */
|
|
53
|
+
files: GovernanceFileKey[];
|
|
54
|
+
/**
|
|
55
|
+
* Session freshness TTL in minutes. A session older than this is considered
|
|
56
|
+
* stale and the agent must re-load context. Used by the CLI guard.
|
|
57
|
+
*/
|
|
58
|
+
sessionTtlMinutes: number;
|
|
59
|
+
}
|
|
60
|
+
/** A single append-only activity log record. */
|
|
61
|
+
export interface LogRecord {
|
|
62
|
+
ts: string;
|
|
63
|
+
sessionId?: string;
|
|
64
|
+
event: "session_start" | "bootstrap_required" | "file_written" | "task_begin" | "task_complete" | "guard_allow" | "guard_block" | "init";
|
|
65
|
+
detail: string;
|
|
66
|
+
meta?: Record<string, unknown>;
|
|
67
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the knbase governance system.
|
|
3
|
+
*/
|
|
4
|
+
/** Canonical governance document keys. Order defines display order everywhere. */
|
|
5
|
+
export const GOVERNANCE_FILES = [
|
|
6
|
+
"prd",
|
|
7
|
+
"architecture",
|
|
8
|
+
"design",
|
|
9
|
+
"phase",
|
|
10
|
+
"rules",
|
|
11
|
+
"memory",
|
|
12
|
+
];
|
|
13
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,kFAAkF;AAClF,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,KAAK;IACL,cAAc;IACd,QAAQ;IACR,OAAO;IACP,OAAO;IACP,QAAQ;CACA,CAAC"}
|