benjamin-docs 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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +352 -0
  3. package/dist/src/anchors.d.ts +1 -0
  4. package/dist/src/anchors.js +50 -0
  5. package/dist/src/anchors.js.map +1 -0
  6. package/dist/src/cli.d.ts +2 -0
  7. package/dist/src/cli.js +231 -0
  8. package/dist/src/cli.js.map +1 -0
  9. package/dist/src/constants.d.ts +12 -0
  10. package/dist/src/constants.js +13 -0
  11. package/dist/src/constants.js.map +1 -0
  12. package/dist/src/export.d.ts +1 -0
  13. package/dist/src/export.js +70 -0
  14. package/dist/src/export.js.map +1 -0
  15. package/dist/src/frontmatter.d.ts +3 -0
  16. package/dist/src/frontmatter.js +119 -0
  17. package/dist/src/frontmatter.js.map +1 -0
  18. package/dist/src/fsx.d.ts +14 -0
  19. package/dist/src/fsx.js +129 -0
  20. package/dist/src/fsx.js.map +1 -0
  21. package/dist/src/info.d.ts +3 -0
  22. package/dist/src/info.js +65 -0
  23. package/dist/src/info.js.map +1 -0
  24. package/dist/src/init.d.ts +12 -0
  25. package/dist/src/init.js +145 -0
  26. package/dist/src/init.js.map +1 -0
  27. package/dist/src/next.d.ts +2 -0
  28. package/dist/src/next.js +65 -0
  29. package/dist/src/next.js.map +1 -0
  30. package/dist/src/project-config.d.ts +6 -0
  31. package/dist/src/project-config.js +41 -0
  32. package/dist/src/project-config.js.map +1 -0
  33. package/dist/src/scopes.d.ts +1 -0
  34. package/dist/src/scopes.js +52 -0
  35. package/dist/src/scopes.js.map +1 -0
  36. package/dist/src/status.d.ts +1 -0
  37. package/dist/src/status.js +38 -0
  38. package/dist/src/status.js.map +1 -0
  39. package/dist/src/templates.d.ts +19 -0
  40. package/dist/src/templates.js +82 -0
  41. package/dist/src/templates.js.map +1 -0
  42. package/dist/src/types.d.ts +51 -0
  43. package/dist/src/types.js +2 -0
  44. package/dist/src/types.js.map +1 -0
  45. package/dist/src/validate.d.ts +5 -0
  46. package/dist/src/validate.js +542 -0
  47. package/dist/src/validate.js.map +1 -0
  48. package/package.json +45 -0
  49. package/skills/benjamin-docs/SKILL.md +129 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function getNextPrompt(root: string): string;
2
+ export declare function formatNextMessage(prompt: string): string;
@@ -0,0 +1,65 @@
1
+ import { CONFIG_DIR, MANIFEST_FILE } from "./constants.js";
2
+ import { readGeneratedJson } from "./fsx.js";
3
+ import { readConfig } from "./project-config.js";
4
+ const METADATA_LABEL = "Metadata path";
5
+ export function getNextPrompt(root) {
6
+ const config = readConfig(root);
7
+ const manifest = readGeneratedJson(root, `${CONFIG_DIR}/${MANIFEST_FILE}`, METADATA_LABEL);
8
+ const docsRoot = config.docsRoot;
9
+ if (config.focus === "feature") {
10
+ const feature = config.feature ?? findLatestFeature(manifest, docsRoot);
11
+ if (feature)
12
+ return featurePrompt(docsRoot, feature, config.mode === "codebase");
13
+ }
14
+ if (config.focus === "codebase" || config.mode === "codebase") {
15
+ return codebasePrompt(docsRoot);
16
+ }
17
+ return planningPrompt(docsRoot);
18
+ }
19
+ export function formatNextMessage(prompt) {
20
+ return ["Next, ask your agent:", "", prompt].join("\n");
21
+ }
22
+ function planningPrompt(docsRoot) {
23
+ return [
24
+ "Capture the current project plan with benjamin-docs.",
25
+ `Update ${docsRoot}/project/brief.md, ${docsRoot}/project/roadmap.md,`,
26
+ `${docsRoot}/project/open-questions.md, and ${docsRoot}/handoff/agent-brief.md.`,
27
+ "Use plain language. Summarize decisions, rejected options, risks, and next steps.",
28
+ "Mark uncertain items clearly.",
29
+ ].join("\n");
30
+ }
31
+ function codebasePrompt(docsRoot) {
32
+ return [
33
+ "Capture the current project baseline with benjamin-docs.",
34
+ "Read the existing codebase and any existing docs as context. Then update",
35
+ `${docsRoot}/project/brief.md, ${docsRoot}/project/roadmap.md,`,
36
+ `${docsRoot}/project/open-questions.md, ${docsRoot}/engineering/architecture.md,`,
37
+ `${docsRoot}/engineering/code-map.md, and ${docsRoot}/handoff/agent-brief.md.`,
38
+ "Keep project docs understandable for non-technical readers.",
39
+ "Mark uncertain items, call out risks, and add useful code anchors where relevant.",
40
+ ].join("\n");
41
+ }
42
+ function featurePrompt(docsRoot, feature, codebaseMode) {
43
+ const codebaseInstruction = codebaseMode
44
+ ? "First read the existing codebase and Benjamin docs."
45
+ : "First read the current Benjamin docs and any planning notes.";
46
+ return [
47
+ `Capture the ${feature} feature with benjamin-docs.`,
48
+ codebaseInstruction,
49
+ `Then update ${docsRoot}/project/roadmap.md, ${docsRoot}/project/open-questions.md,`,
50
+ `${docsRoot}/handoff/agent-brief.md, and the feature docs under`,
51
+ `${docsRoot}/features/${feature}/.`,
52
+ "Include decisions, rejected options, risks, implementation notes, and next steps.",
53
+ "Keep the brief and handoff understandable for non-technical readers.",
54
+ "Mark uncertain items clearly.",
55
+ ].join("\n");
56
+ }
57
+ function findLatestFeature(manifest, docsRoot) {
58
+ const prefix = `${docsRoot}/features/`;
59
+ const featurePaths = manifest.docs.filter((doc) => doc.startsWith(prefix) && doc !== `${docsRoot}/features/index.md`);
60
+ const latest = featurePaths.at(-1);
61
+ if (!latest)
62
+ return undefined;
63
+ return latest.slice(prefix.length).split("/", 1)[0];
64
+ }
65
+ //# sourceMappingURL=next.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.js","sourceRoot":"","sources":["../../src/next.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { BenjaminDocsConfig } from "./types.js";
2
+ export declare function defaultConfig(overrides?: Partial<BenjaminDocsConfig>): BenjaminDocsConfig;
3
+ export declare function readConfig(root: string): BenjaminDocsConfig;
4
+ export declare function normalizeConfig(config: BenjaminDocsConfig): BenjaminDocsConfig;
5
+ export declare function assertSafeDocsRoot(docsRoot: string): void;
6
+ export declare function isSafeDocsRoot(docsRoot: string): boolean;
@@ -0,0 +1,41 @@
1
+ import { isAbsolute, win32 } from "node:path";
2
+ import { CONFIG_DIR, CONFIG_FILE, DEFAULT_DOCS_ROOT } from "./constants.js";
3
+ import { readGeneratedJson } from "./fsx.js";
4
+ const METADATA_LABEL = "Metadata path";
5
+ export function defaultConfig(overrides = {}) {
6
+ return {
7
+ version: 1,
8
+ mode: "planning",
9
+ docsRoot: DEFAULT_DOCS_ROOT,
10
+ focus: "project",
11
+ ...overrides,
12
+ };
13
+ }
14
+ export function readConfig(root) {
15
+ return normalizeConfig(readGeneratedJson(root, `${CONFIG_DIR}/${CONFIG_FILE}`, METADATA_LABEL));
16
+ }
17
+ export function normalizeConfig(config) {
18
+ return {
19
+ version: config.version,
20
+ mode: config.mode,
21
+ docsRoot: config.docsRoot ?? DEFAULT_DOCS_ROOT,
22
+ focus: config.focus ?? defaultFocusForMode(config.mode),
23
+ feature: config.feature,
24
+ };
25
+ }
26
+ export function assertSafeDocsRoot(docsRoot) {
27
+ if (!isSafeDocsRoot(docsRoot)) {
28
+ throw new Error(`Invalid docs root: ${docsRoot}`);
29
+ }
30
+ }
31
+ export function isSafeDocsRoot(docsRoot) {
32
+ return (Boolean(docsRoot) &&
33
+ !docsRoot.includes("\\") &&
34
+ !isAbsolute(docsRoot) &&
35
+ !win32.isAbsolute(docsRoot) &&
36
+ !docsRoot.split("/").some((part) => part === "" || part === "." || part === ".."));
37
+ }
38
+ function defaultFocusForMode(mode) {
39
+ return mode === "codebase" ? "codebase" : "project";
40
+ }
41
+ //# sourceMappingURL=project-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-config.js","sourceRoot":"","sources":["../../src/project-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAG7C,MAAM,cAAc,GAAG,eAAe,CAAC;AAEvC,MAAM,UAAU,aAAa,CAAC,YAAyC,EAAE;IACvE,OAAO;QACL,OAAO,EAAE,CAAC;QACV,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,iBAAiB;QAC3B,KAAK,EAAE,SAAS;QAChB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,eAAe,CAAC,iBAAiB,CAAqB,IAAI,EAAE,GAAG,UAAU,IAAI,WAAW,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;AACtH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAA0B;IACxD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,iBAAiB;QAC9C,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC;QACvD,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,EAAE,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,CACL,OAAO,CAAC,QAAQ,CAAC;QACjB,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;QACxB,CAAC,UAAU,CAAC,QAAQ,CAAC;QACrB,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC;QAC3B,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,CAClF,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAgC;IAC3D,OAAO,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;AACtD,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function createScope(root: string, kind: string, id: string): string[];
@@ -0,0 +1,52 @@
1
+ import { CONFIG_DIR, MANIFEST_FILE, SCOPES_FILE } from "./constants.js";
2
+ import { readGeneratedJson, writeGeneratedJson, writeGeneratedTextIfMissing } from "./fsx.js";
3
+ import { readConfig } from "./project-config.js";
4
+ import { featureDocs } from "./templates.js";
5
+ const SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
6
+ const METADATA_LABEL = "Metadata path";
7
+ export function createScope(root, kind, id) {
8
+ if (kind !== "feature") {
9
+ throw new Error("V1 scope creation supports feature scopes");
10
+ }
11
+ if (!SLUG_PATTERN.test(id)) {
12
+ throw new Error(`Invalid feature slug: ${id}`);
13
+ }
14
+ const scopesPath = `${CONFIG_DIR}/${SCOPES_FILE}`;
15
+ const scopes = readGeneratedJson(root, scopesPath, METADATA_LABEL);
16
+ const manifestPath = `${CONFIG_DIR}/${MANIFEST_FILE}`;
17
+ const manifest = readGeneratedJson(root, manifestPath, METADATA_LABEL);
18
+ const config = readConfig(root);
19
+ if (scopes.scopes.some((scope) => scope.id === id)) {
20
+ throw new Error(`Scope already exists: ${id}`);
21
+ }
22
+ const written = [];
23
+ const docs = featureDocs(id, config.docsRoot);
24
+ for (const file of docs) {
25
+ if (writeGeneratedTextIfMissing(root, file.path, file.content)) {
26
+ written.push(file.path);
27
+ }
28
+ }
29
+ const record = {
30
+ id,
31
+ kind: "feature",
32
+ title: titleFromSlug(id),
33
+ path: `${config.docsRoot}/features/${id}`,
34
+ status: "draft",
35
+ };
36
+ scopes.scopes.push(record);
37
+ writeGeneratedJson(root, scopesPath, scopes, METADATA_LABEL);
38
+ for (const file of docs) {
39
+ if (!manifest.docs.includes(file.path))
40
+ manifest.docs.push(file.path);
41
+ }
42
+ writeGeneratedJson(root, manifestPath, manifest, METADATA_LABEL);
43
+ return written;
44
+ }
45
+ function titleFromSlug(slug) {
46
+ return slug
47
+ .split("-")
48
+ .filter(Boolean)
49
+ .map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)
50
+ .join(" ");
51
+ }
52
+ //# sourceMappingURL=scopes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scopes.js","sourceRoot":"","sources":["../../src/scopes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function getStatus(root: string): string;
@@ -0,0 +1,38 @@
1
+ import { existsSync } from "node:fs";
2
+ import { CONFIG_DIR, CONFIG_FILE, MANIFEST_FILE, SCOPES_FILE } from "./constants.js";
3
+ import { readJson, rootPath } from "./fsx.js";
4
+ import { normalizeConfig } from "./project-config.js";
5
+ export function getStatus(root) {
6
+ const configPath = rootPath(root, CONFIG_DIR, CONFIG_FILE);
7
+ const manifestPath = rootPath(root, CONFIG_DIR, MANIFEST_FILE);
8
+ const scopesPath = rootPath(root, CONFIG_DIR, SCOPES_FILE);
9
+ if (!existsSync(configPath) || !existsSync(manifestPath) || !existsSync(scopesPath)) {
10
+ throw new Error("benjamin-docs is not initialized. Run benjamin-docs init first.");
11
+ }
12
+ let config;
13
+ let manifest;
14
+ let scopes;
15
+ try {
16
+ config = normalizeConfig(readJson(configPath));
17
+ manifest = readJson(manifestPath);
18
+ scopes = readJson(scopesPath);
19
+ }
20
+ catch (error) {
21
+ throw new Error(`Cannot read benjamin-docs status metadata: ${error instanceof Error ? error.message : String(error)}`);
22
+ }
23
+ if ((config.mode !== "planning" && config.mode !== "codebase") ||
24
+ typeof config.docsRoot !== "string" ||
25
+ !Array.isArray(manifest.docs) ||
26
+ !Array.isArray(scopes.scopes)) {
27
+ throw new Error("Cannot read benjamin-docs status metadata: expected config, manifest, and scopes metadata.");
28
+ }
29
+ return [
30
+ "benjamin-docs status",
31
+ `mode: ${config.mode}`,
32
+ `focus: ${config.focus}`,
33
+ `docsRoot: ${config.docsRoot}`,
34
+ `docs: ${manifest.docs.length}`,
35
+ `scopes: ${scopes.scopes.length}`,
36
+ ].join("\n");
37
+ }
38
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGtD,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IAE3D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACpF,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IAED,IAAI,MAA0B,CAAC;IAC/B,IAAI,QAAsB,CAAC;IAC3B,IAAI,MAAkB,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAqB,UAAU,CAAC,CAAC,CAAC;QACnE,QAAQ,GAAG,QAAQ,CAAe,YAAY,CAAC,CAAC;QAChD,MAAM,GAAG,QAAQ,CAAa,UAAU,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,8CAA8C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC1H,CAAC;IAED,IACE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC;QAC1D,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ;QACnC,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC7B,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAC7B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,4FAA4F,CAAC,CAAC;IAChH,CAAC;IAED,OAAO;QACL,sBAAsB;QACtB,SAAS,MAAM,CAAC,IAAI,EAAE;QACtB,UAAU,MAAM,CAAC,KAAK,EAAE;QACxB,aAAa,MAAM,CAAC,QAAQ,EAAE;QAC9B,SAAS,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE;QAC/B,WAAW,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE;KAClC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { DocFrontmatter } from "./types.js";
2
+ export declare function today(): string;
3
+ export declare function doc(title: string, scope: DocFrontmatter["scope"], scopeId: string, audience: DocFrontmatter["audience"], body: string): string;
4
+ export declare function workspaceDocs(docsRoot: string): Array<{
5
+ path: string;
6
+ content: string;
7
+ }>;
8
+ export declare const starterDocs: Array<{
9
+ path: string;
10
+ content: string;
11
+ }>;
12
+ export declare function codebaseDocs(docsRoot: string): Array<{
13
+ path: string;
14
+ content: string;
15
+ }>;
16
+ export declare function featureDocs(slug: string, docsRoot?: string): Array<{
17
+ path: string;
18
+ content: string;
19
+ }>;
@@ -0,0 +1,82 @@
1
+ import { DEFAULT_DOCS_ROOT } from "./constants.js";
2
+ import { serializeMarkdown } from "./frontmatter.js";
3
+ export function today() {
4
+ return new Date().toISOString().slice(0, 10);
5
+ }
6
+ export function doc(title, scope, scopeId, audience, body) {
7
+ return serializeMarkdown({
8
+ title,
9
+ scope,
10
+ scope_id: scopeId,
11
+ audience,
12
+ status: "draft",
13
+ visibility: "private",
14
+ updated: today(),
15
+ source: "manual",
16
+ }, body);
17
+ }
18
+ export function workspaceDocs(docsRoot) {
19
+ return [
20
+ {
21
+ path: `${docsRoot}/project/brief.md`,
22
+ content: doc("Project Brief", "project", "project", ["developer", "designer", "business", "agent"], "# Project Brief\n\nCapture what this project is, who it serves, and why it matters.\n"),
23
+ },
24
+ {
25
+ path: `${docsRoot}/project/roadmap.md`,
26
+ content: doc("Roadmap", "project", "project", ["developer", "business", "agent"], "# Roadmap\n\nCapture the current MVP, near-term next steps, and deferred ideas.\n"),
27
+ },
28
+ {
29
+ path: `${docsRoot}/project/open-questions.md`,
30
+ content: doc("Open Questions", "project", "project", ["developer", "designer", "business", "agent"], "# Open Questions\n\nTrack decisions that are not settled yet.\n"),
31
+ },
32
+ {
33
+ path: `${docsRoot}/handoff/human-brief.md`,
34
+ content: doc("Human Brief", "handoff", "human-brief", ["developer", "designer", "business", "advisor"], "# Human Brief\n\nUse this for a concise handoff to another person.\n"),
35
+ },
36
+ {
37
+ path: `${docsRoot}/handoff/agent-brief.md`,
38
+ content: doc("Agent Brief", "handoff", "agent-brief", ["agent"], "# Agent Brief\n\nUse this to orient future AI agents quickly.\n"),
39
+ },
40
+ {
41
+ path: `${docsRoot}/engineering/architecture.md`,
42
+ content: doc("Architecture", "project", "project", ["developer", "agent"], "# Architecture\n\nCapture the planned or current system shape, major boundaries, and important constraints.\n"),
43
+ },
44
+ {
45
+ path: `${docsRoot}/engineering/code-map.md`,
46
+ content: doc("Code Map", "project", "project", ["developer", "agent"], "# Code Map\n\nCapture important files, modules, routes, schemas, and tests when code exists.\n"),
47
+ },
48
+ {
49
+ path: `${docsRoot}/features/index.md`,
50
+ content: doc("Features Index", "project", "project", ["developer", "designer", "agent", "business"], "# Features Index\n\nTrack feature scopes that are planned, in progress, shipped, or deferred.\n"),
51
+ },
52
+ {
53
+ path: `${docsRoot}/releases/changelog.md`,
54
+ content: doc("Changelog", "release", "release", ["developer", "business", "public"], "# Changelog\n\nTrack notable changes.\n"),
55
+ },
56
+ ];
57
+ }
58
+ export const starterDocs = workspaceDocs(DEFAULT_DOCS_ROOT);
59
+ export function codebaseDocs(docsRoot) {
60
+ return workspaceDocs(docsRoot).filter((item) => item.path.startsWith(`${docsRoot}/engineering/`) || item.path.startsWith(`${docsRoot}/releases/`));
61
+ }
62
+ export function featureDocs(slug, docsRoot = DEFAULT_DOCS_ROOT) {
63
+ return [
64
+ {
65
+ path: `${docsRoot}/features/${slug}/brief.md`,
66
+ content: doc(`${slug} Brief`, "feature", slug, ["developer", "designer", "agent"], `# ${slug} Brief\n\nCapture what this feature is meant to accomplish.\n`),
67
+ },
68
+ {
69
+ path: `${docsRoot}/features/${slug}/plan.md`,
70
+ content: doc(`${slug} Plan`, "feature", slug, ["developer", "agent"], `# ${slug} Plan\n\nCapture the implementation or execution plan.\n`),
71
+ },
72
+ {
73
+ path: `${docsRoot}/features/${slug}/decisions.md`,
74
+ content: doc(`${slug} Decisions`, "feature", slug, ["developer", "agent"], `# ${slug} Decisions\n\nCapture durable decisions, rejected options, and reasoning.\n`),
75
+ },
76
+ {
77
+ path: `${docsRoot}/features/${slug}/handoff.md`,
78
+ content: doc(`${slug} Handoff`, "feature", slug, ["developer", "agent"], `# ${slug} Handoff\n\nCapture status, open questions, and next actions for this feature.\n`),
79
+ },
80
+ ];
81
+ }
82
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/templates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import type { KNOWN_AUDIENCES, KNOWN_FOCUS_TYPES, KNOWN_SCOPES, KNOWN_SOURCES, KNOWN_STATUSES, KNOWN_VISIBILITIES } from "./constants.js";
2
+ export type ScopeKind = (typeof KNOWN_SCOPES)[number];
3
+ export type FocusType = (typeof KNOWN_FOCUS_TYPES)[number];
4
+ export type Audience = (typeof KNOWN_AUDIENCES)[number];
5
+ export type DocStatus = (typeof KNOWN_STATUSES)[number];
6
+ export type Visibility = (typeof KNOWN_VISIBILITIES)[number];
7
+ export type DocSource = (typeof KNOWN_SOURCES)[number];
8
+ export interface DocFrontmatter {
9
+ title: string;
10
+ scope: ScopeKind;
11
+ scope_id: string;
12
+ audience: Audience[];
13
+ status: DocStatus;
14
+ visibility: Visibility;
15
+ updated: string;
16
+ source: DocSource;
17
+ }
18
+ export interface ParsedMarkdown {
19
+ frontmatter: DocFrontmatter;
20
+ body: string;
21
+ }
22
+ export interface BenjaminDocsConfig {
23
+ version: 1;
24
+ mode: "planning" | "codebase";
25
+ docsRoot: string;
26
+ focus: FocusType;
27
+ feature?: string;
28
+ }
29
+ export interface ScopeRecord {
30
+ id: string;
31
+ kind: ScopeKind;
32
+ title: string;
33
+ path: string;
34
+ status: DocStatus;
35
+ }
36
+ export interface ScopesFile {
37
+ version: 1;
38
+ scopes: ScopeRecord[];
39
+ }
40
+ export interface AnchorRecord {
41
+ file: string;
42
+ docs: string[];
43
+ }
44
+ export interface AnchorsFile {
45
+ version: 1;
46
+ anchors: Record<string, AnchorRecord>;
47
+ }
48
+ export interface ManifestFile {
49
+ version: 1;
50
+ docs: string[];
51
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ export interface ValidationResult {
2
+ errors: string[];
3
+ warnings: string[];
4
+ }
5
+ export declare function validateProject(root: string): ValidationResult;