@leji-org/leji 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +36 -0
  2. package/assets-manifest.json +25 -0
  3. package/cli.json +82 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +4 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/conformance.d.ts +24 -0
  8. package/dist/commands/conformance.js +111 -0
  9. package/dist/commands/conformance.js.map +1 -0
  10. package/dist/commands/docs.d.ts +32 -0
  11. package/dist/commands/docs.js +196 -0
  12. package/dist/commands/docs.js.map +1 -0
  13. package/dist/commands/freshness.d.ts +21 -0
  14. package/dist/commands/freshness.js +41 -0
  15. package/dist/commands/freshness.js.map +1 -0
  16. package/dist/commands/indexgen.d.ts +55 -0
  17. package/dist/commands/indexgen.js +256 -0
  18. package/dist/commands/indexgen.js.map +1 -0
  19. package/dist/commands/init.d.ts +28 -0
  20. package/dist/commands/init.js +378 -0
  21. package/dist/commands/init.js.map +1 -0
  22. package/dist/commands/validate.d.ts +25 -0
  23. package/dist/commands/validate.js +359 -0
  24. package/dist/commands/validate.js.map +1 -0
  25. package/dist/index.d.ts +17 -0
  26. package/dist/index.js +324 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/lib/findings.d.ts +17 -0
  29. package/dist/lib/findings.js +29 -0
  30. package/dist/lib/findings.js.map +1 -0
  31. package/dist/lib/frontmatter.d.ts +14 -0
  32. package/dist/lib/frontmatter.js +28 -0
  33. package/dist/lib/frontmatter.js.map +1 -0
  34. package/dist/lib/fsx.d.ts +21 -0
  35. package/dist/lib/fsx.js +100 -0
  36. package/dist/lib/fsx.js.map +1 -0
  37. package/dist/lib/git.d.ts +10 -0
  38. package/dist/lib/git.js +55 -0
  39. package/dist/lib/git.js.map +1 -0
  40. package/dist/lib/layer.d.ts +32 -0
  41. package/dist/lib/layer.js +138 -0
  42. package/dist/lib/layer.js.map +1 -0
  43. package/dist/lib/manifest.d.ts +62 -0
  44. package/dist/lib/manifest.js +54 -0
  45. package/dist/lib/manifest.js.map +1 -0
  46. package/dist/lib/schemas.d.ts +38 -0
  47. package/dist/lib/schemas.js +57 -0
  48. package/dist/lib/schemas.js.map +1 -0
  49. package/package.json +61 -0
  50. package/schemas/README.md +3 -0
  51. package/schemas/agent-profile.schema.json +129 -0
  52. package/schemas/context-changelog.schema.json +150 -0
  53. package/schemas/context-index.schema.json +137 -0
  54. package/schemas/context-manifest.schema.json +253 -0
  55. package/schemas/decision-record.schema.json +84 -0
  56. package/templates/README.md +5 -0
  57. package/templates/agent-profile.md +25 -0
  58. package/templates/agents/core.md +27 -0
  59. package/templates/boot-profile.md +39 -0
  60. package/templates/decision-record.md +28 -0
  61. package/templates/docs-viewer-assets/PROVENANCE.txt +18 -0
  62. package/templates/docs-viewer-assets/docsify-sidebar-collapse.min.css +24 -0
  63. package/templates/docs-viewer-assets/docsify-sidebar-collapse.min.js +149 -0
  64. package/templates/docs-viewer-assets/docsify.min.js +1 -0
  65. package/templates/docs-viewer-assets/search.min.js +314 -0
  66. package/templates/docs-viewer-assets/vue.css +1063 -0
  67. package/templates/docs-viewer.html +63 -0
  68. package/templates/leji.json +56 -0
@@ -0,0 +1,378 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as readline from 'node:readline';
4
+ import { execFileSync } from 'node:child_process';
5
+ import { templatesDir } from '../lib/schemas.js';
6
+ import { writeIndex } from './indexgen.js';
7
+ function gitConfig(key) {
8
+ try {
9
+ const out = execFileSync('git', ['config', '--get', key], {
10
+ encoding: 'utf8',
11
+ stdio: ['ignore', 'pipe', 'ignore'],
12
+ }).trim();
13
+ return out || null;
14
+ }
15
+ catch {
16
+ return null;
17
+ }
18
+ }
19
+ function defaultAnswers(dir, options) {
20
+ const base = path
21
+ .basename(path.resolve(dir))
22
+ .toLowerCase()
23
+ .replace(/[^a-z0-9]+/g, '-')
24
+ // The line above collapses each run of non-alphanumerics to a single '-',
25
+ // so dashes are never consecutive — trimming one per end is sufficient and
26
+ // avoids the polynomial-backtracking `-+$` (js/polynomial-redos).
27
+ .replace(/^-|-$/g, '');
28
+ return {
29
+ name: options.name ?? `${base}-context`,
30
+ description: 'Shared context layer for this repository.',
31
+ rootPath: 'docs/',
32
+ ownerName: gitConfig('user.name') ?? '<named owner>',
33
+ ownerContact: gitConfig('user.email') ?? '',
34
+ categories: ['domain', 'system', 'decisions'],
35
+ level: options.level ?? 'core',
36
+ };
37
+ }
38
+ /**
39
+ * Queued line reader: unlike readline/promises' question(), lines arriving
40
+ * while no question is pending (piped stdin delivers everything at once) are
41
+ * buffered instead of dropped.
42
+ */
43
+ const EOF = Symbol('eof');
44
+ class LineReader {
45
+ lines = [];
46
+ waiters = [];
47
+ closed = false;
48
+ rl;
49
+ constructor() {
50
+ this.rl = readline.createInterface({ input: process.stdin });
51
+ this.rl.on('line', (line) => {
52
+ const waiter = this.waiters.shift();
53
+ if (waiter)
54
+ waiter(line);
55
+ else
56
+ this.lines.push(line);
57
+ });
58
+ this.rl.on('close', () => {
59
+ this.closed = true;
60
+ for (const waiter of this.waiters.splice(0))
61
+ waiter(EOF);
62
+ });
63
+ }
64
+ /** Next input line, or EOF when stdin closed (Ctrl-D) with nothing buffered. */
65
+ next() {
66
+ if (this.lines.length > 0)
67
+ return Promise.resolve(this.lines.shift());
68
+ if (this.closed)
69
+ return Promise.resolve(EOF);
70
+ return new Promise((resolve) => this.waiters.push(resolve));
71
+ }
72
+ close() {
73
+ this.rl.close();
74
+ }
75
+ }
76
+ async function prompt(options) {
77
+ const defaults = defaultAnswers(options.dir, options);
78
+ if (options.yes)
79
+ return defaults;
80
+ const reader = new LineReader();
81
+ const readLine = async () => {
82
+ const a = await reader.next();
83
+ if (a === EOF) {
84
+ throw new Error('init aborted: end of input before all questions were answered');
85
+ }
86
+ return a;
87
+ };
88
+ const ask = async (q, fallback) => {
89
+ process.stdout.write(fallback ? `${q} (${fallback}): ` : `${q}: `);
90
+ const a = (await readLine()).trim();
91
+ return a || fallback;
92
+ };
93
+ const askYesNo = async (q, fallback) => {
94
+ process.stdout.write(`${q} [${fallback ? 'Y/n' : 'y/N'}]: `);
95
+ const a = (await readLine()).trim().toLowerCase();
96
+ if (a === '')
97
+ return fallback;
98
+ return a === 'y' || a === 'yes';
99
+ };
100
+ try {
101
+ const name = await ask('Layer name', defaults.name);
102
+ const description = await ask('One-line description', defaults.description);
103
+ let rootPath = await ask('Context root', defaults.rootPath);
104
+ if (!rootPath.endsWith('/'))
105
+ rootPath += '/';
106
+ const ownerName = await ask('Primary owner (name)', defaults.ownerName);
107
+ const ownerContact = await ask('Primary owner (contact)', defaults.ownerContact);
108
+ const categories = [];
109
+ if (await askYesNo('Map domain (business language, product semantics)?', true))
110
+ categories.push('domain');
111
+ if (await askYesNo('Map system (architecture, invariants)?', true))
112
+ categories.push('system');
113
+ if (await askYesNo('Map practice (conventions, proven patterns)?', false))
114
+ categories.push('practice');
115
+ if (await askYesNo('Map governance (agent guardrails, operating rules)?', false))
116
+ categories.push('governance');
117
+ categories.push('decisions');
118
+ if (!categories.includes('domain') && !categories.includes('system')) {
119
+ // The spec minimum: at least domain or system, plus decisions.
120
+ categories.unshift('domain');
121
+ console.log('At least domain or system is required; mapping domain.');
122
+ }
123
+ const indexed = await askYesNo('Generate the machine index and changelog now (indexed level)?', false);
124
+ return {
125
+ name,
126
+ description,
127
+ rootPath,
128
+ ownerName,
129
+ ownerContact,
130
+ categories,
131
+ level: indexed ? 'indexed' : 'core',
132
+ };
133
+ }
134
+ finally {
135
+ reader.close();
136
+ }
137
+ }
138
+ function readTemplate(name) {
139
+ return fs.readFileSync(path.join(templatesDir(), name), 'utf8');
140
+ }
141
+ /**
142
+ * The manifest schema's relative-path rule: rejects absolute paths, `./`
143
+ * prefixes, any `..` segment, and backslashes. Mirrored here so init refuses
144
+ * traversal before it writes anything.
145
+ */
146
+ const RELATIVE_PATH_RE = /^(?!\/)(?!\.\/)(?!.*(^|\/)\.\.(\/|$))(?!.*\\).*$/;
147
+ function assertRelativePath(rel) {
148
+ if (!RELATIVE_PATH_RE.test(rel)) {
149
+ throw new Error(`refusing unsafe path "${rel}": must be repository-root-relative (no absolute, .., ./, or \\)`);
150
+ }
151
+ }
152
+ /** Resolve `rel` under `root` and assert it stays within the resolved root. */
153
+ function safeResolve(rootAbs, rel) {
154
+ assertRelativePath(rel);
155
+ const abs = path.resolve(rootAbs, rel);
156
+ if (abs !== rootAbs && !abs.startsWith(rootAbs + path.sep)) {
157
+ throw new Error(`refusing to write outside the target directory: "${rel}"`);
158
+ }
159
+ return abs;
160
+ }
161
+ function writeFileOnce(rootAbs, rel, content, written) {
162
+ const abs = safeResolve(rootAbs, rel);
163
+ if (fs.existsSync(abs))
164
+ return;
165
+ fs.mkdirSync(path.dirname(abs), { recursive: true });
166
+ fs.writeFileSync(abs, content);
167
+ written.push(rel);
168
+ }
169
+ const CATEGORY_STUBS = {
170
+ domain: {
171
+ file: 'glossary.md',
172
+ title: 'Glossary',
173
+ summary: 'What the core terms of this product mean, in our own words.',
174
+ body: '- **<Term>**: <what it means here, including what it does not mean>.\n',
175
+ },
176
+ system: {
177
+ file: 'invariants.md',
178
+ title: 'System Invariants',
179
+ summary: 'The constraints every change lives with.',
180
+ body: '- <An invariant every change must respect, e.g. "money values are integer minor units">.\n',
181
+ },
182
+ practice: {
183
+ file: 'conventions.md',
184
+ title: 'Conventions',
185
+ summary: 'Conventions and patterns applied automatically.',
186
+ body: '- <A convention that has proven out at least twice (the proven-twice gate)>.\n',
187
+ },
188
+ governance: {
189
+ file: 'operating-rules.md',
190
+ title: 'Operating Rules',
191
+ summary: 'What agents may do unprompted and what needs a human gate.',
192
+ body: '- Proceed without asking when: <defaults>.\n- Stop and ask when: <escalation triggers>.\n',
193
+ },
194
+ };
195
+ function categoryStub(title, summary, body) {
196
+ return `---\nsummary: ${summary}\n---\n\n# ${title}\n\n${body}`;
197
+ }
198
+ function buildManifest(answers) {
199
+ const template = JSON.parse(readTemplate('leji.json'));
200
+ const r = answers.rootPath;
201
+ const manifest = {
202
+ $schema: template.$schema,
203
+ leji: '1.0',
204
+ name: answers.name,
205
+ description: answers.description,
206
+ rootPath: r,
207
+ bootProfilePath: `${r}boot-profile.md`,
208
+ categories: {},
209
+ machine: {
210
+ agentProfilesPath: `${r}agents/`,
211
+ decisionRecordsPath: `${r}decisions/`,
212
+ },
213
+ owners: {
214
+ primary: answers.ownerContact
215
+ ? { name: answers.ownerName, contact: answers.ownerContact }
216
+ : { name: answers.ownerName },
217
+ },
218
+ conformance: {
219
+ claimedLevel: answers.level,
220
+ claimedAt: new Date().toISOString().slice(0, 10),
221
+ },
222
+ };
223
+ if (answers.level === 'indexed') {
224
+ manifest.machine = {
225
+ indexPath: `${r}context-index.json`,
226
+ changelogPath: `${r}context-changelog.json`,
227
+ ...manifest.machine,
228
+ };
229
+ }
230
+ for (const category of answers.categories) {
231
+ manifest.categories[category] = { paths: [`${r}${category}/`] };
232
+ }
233
+ return manifest;
234
+ }
235
+ function buildBootProfile(answers) {
236
+ let text = readTemplate('boot-profile.md');
237
+ // The template speaks in docs/ defaults; rewrite for the chosen root.
238
+ if (answers.rootPath !== 'docs/') {
239
+ text = text.replaceAll('docs/', answers.rootPath);
240
+ }
241
+ text = text.replace('<One paragraph: what this repository/product is, who it serves, what stage it is at.>', answers.description);
242
+ const r = answers.rootPath;
243
+ const loadLines = answers.categories
244
+ .map((c) => {
245
+ const purpose = {
246
+ domain: 'what our core terms mean',
247
+ system: 'architecture and the invariants every change lives with',
248
+ practice: 'conventions and patterns applied automatically',
249
+ governance: 'agent guardrails and operating rules',
250
+ decisions: 'why things are the way they are (check before proposing a reversal)',
251
+ };
252
+ return `- \`${r}${c}/\`: ${purpose[c]}`;
253
+ })
254
+ .join('\n');
255
+ text = text.replace(/- `[^`]+domain\/`[^\n]*\n- `[^`]+system\/`[^\n]*\n- `[^`]+decisions\/`[^\n]*/, loadLines);
256
+ if (answers.level === 'core') {
257
+ text = text.replace(/\nThe generated map of this layer is `[^`]+`\.\n/, '\n');
258
+ text = text.replace(/- Append an entry to `[^`]+context-changelog\.json`[^\n]*\n/, '');
259
+ text = text.replace(/- Regenerate `[^`]+context-index\.json`[^\n]*\n/, '');
260
+ }
261
+ return text;
262
+ }
263
+ function buildCoreProfile(answers) {
264
+ let text = readTemplate(path.join('agents', 'core.md'));
265
+ if (answers.rootPath !== 'docs/') {
266
+ text = text.replaceAll('docs/', answers.rootPath);
267
+ }
268
+ if (!answers.categories.includes('governance')) {
269
+ text = text.replace(/^ {2}- .*governance\/\n/m, ` - ${answers.rootPath}decisions/\n`);
270
+ }
271
+ return text;
272
+ }
273
+ function buildFirstDecision(answers) {
274
+ const today = new Date().toISOString().slice(0, 10);
275
+ const indexedLine = answers.level === 'indexed'
276
+ ? 'manifest, boot profile, category content, decision records, generated index, machine changelog'
277
+ : 'manifest, boot profile, category content, decision records';
278
+ return `---
279
+ id: adopt-leji
280
+ title: Adopt the Leji context layer
281
+ status: accepted
282
+ date: ${today}
283
+ deciders:
284
+ - ${answers.ownerName}
285
+ ---
286
+
287
+ # Adopt the Leji context layer
288
+
289
+ ## Context
290
+
291
+ Engineering knowledge lived in heads, chat threads, and per-tool config files. People and agents had no single place to read how this team thinks.
292
+
293
+ ## Decision
294
+
295
+ Adopt Leji at the \`${answers.level}\` level: ${indexedLine}.
296
+
297
+ ## Consequences
298
+
299
+ Vendor config files become one-line redirects. Context fixes ride the same review gate as the work that surfaces them. ${answers.ownerName} owns the layer.
300
+ `;
301
+ }
302
+ function buildChangelog(answers, written) {
303
+ const today = new Date().toISOString().slice(0, 10);
304
+ const changelog = {
305
+ $schema: 'https://leji.org/schemas/v1.0/context-changelog.schema.json',
306
+ schemaVersion: '1.0',
307
+ entries: [
308
+ {
309
+ id: 'seed-layer',
310
+ date: today,
311
+ type: 'added',
312
+ summary: 'Seeded the context layer with leji init.',
313
+ paths: written,
314
+ proposedBy: 'leji init',
315
+ approvedBy: answers.ownerName,
316
+ },
317
+ ],
318
+ };
319
+ return JSON.stringify(changelog, null, 2) + '\n';
320
+ }
321
+ /**
322
+ * Bootstrap a context layer from the vendored templates. Interactive unless
323
+ * --yes. Refuses to run when leji.json already exists; never overwrites
324
+ * existing files (seeds land only where nothing is in the way).
325
+ */
326
+ export async function initLayer(options) {
327
+ const root = path.resolve(options.dir);
328
+ if (fs.existsSync(path.join(root, 'leji.json'))) {
329
+ throw new Error('leji.json already exists here; init refuses to overwrite an existing layer');
330
+ }
331
+ const answers = await prompt(options);
332
+ // Guard rootPath (and so every derived write path) before any write: reject
333
+ // absolute paths, .. segments, ./ prefixes, and backslashes.
334
+ assertRelativePath(answers.rootPath);
335
+ const manifest = buildManifest(answers);
336
+ const written = [];
337
+ const r = answers.rootPath;
338
+ // Write leji.json FIRST so the overwrite guard is effective on a retry after
339
+ // an interrupted run (no orphan half-scaffold the guard can't catch).
340
+ fs.mkdirSync(root, { recursive: true });
341
+ fs.writeFileSync(path.join(root, 'leji.json'), JSON.stringify(manifest, null, 2) + '\n');
342
+ written.push('leji.json');
343
+ writeFileOnce(root, manifest.bootProfilePath, buildBootProfile(answers), written);
344
+ for (const category of answers.categories) {
345
+ if (category === 'decisions')
346
+ continue;
347
+ const stub = CATEGORY_STUBS[category];
348
+ writeFileOnce(root, `${r}${category}/${stub.file}`, categoryStub(stub.title, stub.summary, stub.body), written);
349
+ }
350
+ writeFileOnce(root, `${r}decisions/0001-adopt-leji.md`, buildFirstDecision(answers), written);
351
+ writeFileOnce(root, `${r}agents/core.md`, buildCoreProfile(answers), written);
352
+ if (answers.level === 'indexed') {
353
+ writeFileOnce(root, manifest.machine.changelogPath, buildChangelog(answers, [...written]), written);
354
+ }
355
+ if (answers.level === 'indexed') {
356
+ writeIndex(root, manifest);
357
+ written.push(manifest.machine.indexPath);
358
+ }
359
+ return { written: written.sort(), manifest };
360
+ }
361
+ /** Post-init guidance, printed by the CLI. */
362
+ export function enteringTheLayer(manifest) {
363
+ const boot = manifest.bootProfilePath;
364
+ return [
365
+ '',
366
+ "Enter the layer by direct invocation, so the boot profile is the agent's first context:",
367
+ '',
368
+ ` claude "Read ./${boot}, follow all instructions, and tell me when you are ready to begin."`,
369
+ ` codex "Read ./${boot} and follow it before doing anything else."`,
370
+ '',
371
+ 'Package the invocation for the whole team (package.json):',
372
+ '',
373
+ ` "start": "claude 'Read ./${boot}, follow all instructions, and tell me when you are ready to begin.'"`,
374
+ '',
375
+ 'Next: fill in the seeded documents, then run `leji validate` and `leji conformance`.',
376
+ ].join('\n');
377
+ }
378
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type Finding } from '../lib/findings.js';
2
+ import { type Manifest } from '../lib/manifest.js';
3
+ /** Vendor entrypoint files checked for the redirect rule even when undeclared. */
4
+ export declare const KNOWN_VENDOR_FILES: string[];
5
+ export interface ValidateResult {
6
+ findings: Finding[];
7
+ manifest: Manifest | null;
8
+ }
9
+ export interface ChangelogCheckResult {
10
+ findings: Finding[];
11
+ verified: boolean;
12
+ }
13
+ /**
14
+ * Append-only discipline: every entry present at HEAD must be unchanged and in
15
+ * the same position; new entries only append. Without a git baseline the
16
+ * property is unverifiable and reported as a warning (error under --strict).
17
+ */
18
+ export declare function checkChangelogAppendOnly(root: string, rel: string, strict?: boolean): ChangelogCheckResult;
19
+ /**
20
+ * Full layer validation: manifest, level-aware artifact requirements, schema
21
+ * checks, frontmatter contracts, lint rules. Index and changelog are required
22
+ * from `indexed`; at least one valid agent profile from `governed`. Artifacts
23
+ * present below their required level are still schema-validated.
24
+ */
25
+ export declare function validateLayer(root: string): ValidateResult;