project-memory-cli 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 (56) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +153 -0
  3. package/SPEC.md +445 -0
  4. package/dist/commands/init.d.ts +8 -0
  5. package/dist/commands/init.d.ts.map +1 -0
  6. package/dist/commands/init.js +163 -0
  7. package/dist/commands/init.js.map +1 -0
  8. package/dist/commands/new-task.d.ts +2 -0
  9. package/dist/commands/new-task.d.ts.map +1 -0
  10. package/dist/commands/new-task.js +54 -0
  11. package/dist/commands/new-task.js.map +1 -0
  12. package/dist/commands/new-workflow.d.ts +2 -0
  13. package/dist/commands/new-workflow.d.ts.map +1 -0
  14. package/dist/commands/new-workflow.js +29 -0
  15. package/dist/commands/new-workflow.js.map +1 -0
  16. package/dist/commands/tree.d.ts +2 -0
  17. package/dist/commands/tree.d.ts.map +1 -0
  18. package/dist/commands/tree.js +55 -0
  19. package/dist/commands/tree.js.map +1 -0
  20. package/dist/commands/validate.d.ts +2 -0
  21. package/dist/commands/validate.d.ts.map +1 -0
  22. package/dist/commands/validate.js +36 -0
  23. package/dist/commands/validate.js.map +1 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +68 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/lib/detector.d.ts +12 -0
  29. package/dist/lib/detector.d.ts.map +1 -0
  30. package/dist/lib/detector.js +131 -0
  31. package/dist/lib/detector.js.map +1 -0
  32. package/dist/lib/fs.d.ts +7 -0
  33. package/dist/lib/fs.d.ts.map +1 -0
  34. package/dist/lib/fs.js +27 -0
  35. package/dist/lib/fs.js.map +1 -0
  36. package/dist/lib/ids.d.ts +8 -0
  37. package/dist/lib/ids.d.ts.map +1 -0
  38. package/dist/lib/ids.js +19 -0
  39. package/dist/lib/ids.js.map +1 -0
  40. package/dist/lib/planner.d.ts +23 -0
  41. package/dist/lib/planner.d.ts.map +1 -0
  42. package/dist/lib/planner.js +44 -0
  43. package/dist/lib/planner.js.map +1 -0
  44. package/dist/lib/rules.d.ts +18 -0
  45. package/dist/lib/rules.d.ts.map +1 -0
  46. package/dist/lib/rules.js +97 -0
  47. package/dist/lib/rules.js.map +1 -0
  48. package/dist/lib/templates.d.ts +24 -0
  49. package/dist/lib/templates.d.ts.map +1 -0
  50. package/dist/lib/templates.js +391 -0
  51. package/dist/lib/templates.js.map +1 -0
  52. package/dist/lib/validator.d.ts +8 -0
  53. package/dist/lib/validator.d.ts.map +1 -0
  54. package/dist/lib/validator.js +77 -0
  55. package/dist/lib/validator.js.map +1 -0
  56. package/package.json +57 -0
@@ -0,0 +1,163 @@
1
+ import path from 'path';
2
+ import readline from 'readline';
3
+ import chalk from 'chalk';
4
+ import ora from 'ora';
5
+ import { detect } from '../lib/detector.js';
6
+ import { plan } from '../lib/planner.js';
7
+ import { writeFile, fileExists } from '../lib/fs.js';
8
+ import { renderTemplate, aiMd } from '../lib/templates.js';
9
+ export async function initCommand(options = {}) {
10
+ const cwd = process.cwd();
11
+ // Guard: already initialized
12
+ if (fileExists(path.join(cwd, 'project-memory', 'README.md'))) {
13
+ console.log(chalk.yellow('⚠ project-memory is already initialized in this directory.'));
14
+ console.log(chalk.dim(' Run `project-memory validate` to check its health.'));
15
+ console.log(chalk.dim(' Run `project-memory tree` to view the structure.'));
16
+ process.exit(1);
17
+ }
18
+ // ── Step 1: Detect ──────────────────────────────────────────────────────────
19
+ let detection = detect(cwd);
20
+ // Force flags override detection
21
+ if (options.new && options.existing) {
22
+ console.log(chalk.red('✖ Cannot use --new and --existing together.'));
23
+ process.exit(1);
24
+ }
25
+ if (options.new) {
26
+ detection = { ...detection, isExisting: false };
27
+ }
28
+ if (options.existing) {
29
+ detection = { ...detection, isExisting: true };
30
+ }
31
+ // ── Step 2: New project questions ───────────────────────────────────────────
32
+ let projectName = detection.projectName;
33
+ if (!detection.isExisting && !options.yes) {
34
+ projectName = await askQuestion(`Project name [${detection.projectName}]: `);
35
+ if (!projectName.trim())
36
+ projectName = detection.projectName;
37
+ const typeAnswer = await askQuestion('Project type (web-app / api / cli / library / other) [other]: ');
38
+ if (typeAnswer.trim() === 'web-app') {
39
+ detection = { ...detection, type: 'web-app' };
40
+ }
41
+ }
42
+ detection = { ...detection, projectName };
43
+ // ── Step 3: Build plan ──────────────────────────────────────────────────────
44
+ const scaffold = plan(detection);
45
+ scaffold.projectName = projectName;
46
+ // ── Step 4: Print detection summary + plan ──────────────────────────────────
47
+ printPlan(scaffold);
48
+ // ── Step 5: AI.md prompt (existing projects only) ───────────────────────────
49
+ let writeAiMd = true;
50
+ if (detection.isExisting && !options.yes) {
51
+ const answer = await askQuestion('Add AI.md to repo root? (recommended) [Y/n]: ');
52
+ writeAiMd = answer.trim().toLowerCase() !== 'n';
53
+ }
54
+ // ── Step 6: Confirm ─────────────────────────────────────────────────────────
55
+ if (!options.yes) {
56
+ const confirm = await askQuestion('Proceed with scaffold? (y/n): ');
57
+ if (confirm.trim().toLowerCase() !== 'y') {
58
+ console.log('\n Nothing written.\n');
59
+ process.exit(0);
60
+ }
61
+ }
62
+ // ── Step 7: Write files ─────────────────────────────────────────────────────
63
+ const spinner = ora('Scaffolding project-memory...').start();
64
+ const skipped = [];
65
+ try {
66
+ const allItems = [...scaffold.base, ...scaffold.dynamic];
67
+ for (const item of allItems) {
68
+ const fullPath = path.join(cwd, item.path);
69
+ if (fileExists(fullPath)) {
70
+ skipped.push(item.path);
71
+ continue;
72
+ }
73
+ const content = renderTemplate(item.template, { name: projectName });
74
+ writeFile(fullPath, content);
75
+ }
76
+ // AI.md at repo root
77
+ if (writeAiMd) {
78
+ const aiPath = path.join(cwd, 'AI.md');
79
+ if (fileExists(aiPath)) {
80
+ skipped.push('AI.md');
81
+ }
82
+ else {
83
+ writeFile(aiPath, aiMd());
84
+ }
85
+ }
86
+ spinner.stop();
87
+ console.log('');
88
+ console.log(chalk.green(' ✔ project-memory initialized successfully.\n'));
89
+ if (skipped.length > 0) {
90
+ console.log(chalk.dim(' Skipped (already exist):'));
91
+ for (const s of skipped) {
92
+ console.log(chalk.dim(` ↳ ${s} already exists — skipped`));
93
+ }
94
+ console.log('');
95
+ }
96
+ printNextSteps(detection.isExisting);
97
+ }
98
+ catch (err) {
99
+ spinner.fail('Initialization failed.');
100
+ console.error(err);
101
+ process.exit(1);
102
+ }
103
+ }
104
+ // ── Plan printer ──────────────────────────────────────────────────────────────
105
+ function printPlan(scaffold) {
106
+ console.log('');
107
+ console.log(chalk.bold(' ─────────────────────────────────────────'));
108
+ console.log(chalk.bold(' Detected'));
109
+ console.log(chalk.bold(' ─────────────────────────────────────────'));
110
+ console.log(` Directory: ${chalk.cyan(scaffold.projectName)}`);
111
+ console.log(` Existing: ${scaffold.isExisting ? chalk.yellow('yes') : chalk.green('no')}`);
112
+ if (scaffold.isExisting) {
113
+ console.log(` Type: ${scaffold.detectedType}`);
114
+ console.log(` Signals: ${scaffold.signals.slice(0, 5).join(', ')}${scaffold.signals.length > 5 ? ', ...' : ''}`);
115
+ }
116
+ console.log('');
117
+ console.log(chalk.bold(' ─────────────────────────────────────────'));
118
+ console.log(chalk.bold(' Scaffold Plan'));
119
+ console.log(chalk.bold(' ─────────────────────────────────────────'));
120
+ console.log(chalk.dim(' Base layer:'));
121
+ for (const item of scaffold.base) {
122
+ console.log(` ${item.path}`);
123
+ }
124
+ console.log(` AI.md${scaffold.isExisting ? chalk.dim(' (will prompt)') : ''}`);
125
+ if (scaffold.dynamic.length > 0) {
126
+ console.log('');
127
+ console.log(chalk.dim(' Dynamic additions:'));
128
+ for (const item of scaffold.dynamic) {
129
+ console.log(` ${item.path}${chalk.dim(' ← ' + item.description)}`);
130
+ }
131
+ }
132
+ console.log('');
133
+ }
134
+ // ── Next steps ────────────────────────────────────────────────────────────────
135
+ function printNextSteps(isExisting) {
136
+ console.log(chalk.bold(' Next steps:'));
137
+ if (isExisting) {
138
+ console.log(chalk.dim(' 1. Review and fill in project-memory/project/overview.md'));
139
+ console.log(chalk.dim(' 2. Update project-memory/context/current-state.md if it was created'));
140
+ }
141
+ else {
142
+ console.log(chalk.dim(' 1. Fill in project-memory/project/overview.md'));
143
+ console.log(chalk.dim(' 2. Fill in project-memory/project/brief.md'));
144
+ }
145
+ console.log(chalk.dim(' 3. Create your first task:') + ' project-memory new task "Your task"');
146
+ console.log(chalk.dim(' 4. Validate the structure:') + ' project-memory validate');
147
+ console.log(chalk.dim(' 5. View the structure: ') + ' project-memory tree');
148
+ console.log('');
149
+ }
150
+ // ── Prompt helper ─────────────────────────────────────────────────────────────
151
+ function askQuestion(question) {
152
+ const rl = readline.createInterface({
153
+ input: process.stdin,
154
+ output: process.stdout,
155
+ });
156
+ return new Promise(resolve => {
157
+ rl.question(` ${question}`, answer => {
158
+ rl.close();
159
+ resolve(answer);
160
+ });
161
+ });
162
+ }
163
+ //# 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,2 @@
1
+ export declare function newTaskCommand(title: string): Promise<void>;
2
+ //# sourceMappingURL=new-task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new-task.d.ts","sourceRoot":"","sources":["../../src/commands/new-task.ts"],"names":[],"mappings":"AAWA,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCjE"}
@@ -0,0 +1,54 @@
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ import chalk from 'chalk';
4
+ import { writeFile, touchGitkeep, fileExists, readFile } from '../lib/fs.js';
5
+ import { nextId } from '../lib/ids.js';
6
+ import { taskInstructions, taskContext, taskOutput, } from '../lib/templates.js';
7
+ export async function newTaskCommand(title) {
8
+ const cwd = process.cwd();
9
+ const activePath = path.join(cwd, 'project-memory', 'tasks', 'active.md');
10
+ // Guard: must be an initialized project
11
+ if (!fileExists(activePath)) {
12
+ console.log(chalk.red('✖ No project-memory structure found.'));
13
+ console.log(chalk.dim(' Run `project-memory init` first.'));
14
+ process.exit(1);
15
+ }
16
+ const id = nextId(cwd, 'TASK');
17
+ const taskDir = path.join(cwd, 'project-memory', 'tasks', id);
18
+ if (fileExists(taskDir)) {
19
+ console.log(chalk.red(`✖ ${id} already exists.`));
20
+ process.exit(1);
21
+ }
22
+ // ── Create task files ──────────────────────────────────────────────────────
23
+ writeFile(path.join(taskDir, 'instructions.md'), taskInstructions(id, title));
24
+ writeFile(path.join(taskDir, 'context.md'), taskContext(id));
25
+ writeFile(path.join(taskDir, 'output.md'), taskOutput(id));
26
+ touchGitkeep(path.join(taskDir, 'data'));
27
+ // ── Update active.md ───────────────────────────────────────────────────────
28
+ updateActiveTasks(activePath, id, title);
29
+ console.log('');
30
+ console.log(chalk.green(` ✔ Created ${chalk.bold(id)}: ${title}`));
31
+ console.log('');
32
+ console.log(chalk.dim(` project-memory/tasks/${id}/`));
33
+ console.log(chalk.dim(` ├── instructions.md ← define the work here`));
34
+ console.log(chalk.dim(` ├── context.md ← add background and relevant files`));
35
+ console.log(chalk.dim(` ├── output.md ← fill in when task is complete`));
36
+ console.log(chalk.dim(` └── data/`));
37
+ console.log('');
38
+ console.log(chalk.dim(` project-memory/tasks/active.md updated — ${id} added as "planned"`));
39
+ console.log('');
40
+ }
41
+ function updateActiveTasks(activePath, id, title) {
42
+ const current = readFile(activePath);
43
+ const newRow = `| ${id} | ${title} | planned | |`;
44
+ // Insert new row after the table separator line
45
+ const separatorPattern = /(\|[-| :]+\|)\n/;
46
+ if (separatorPattern.test(current)) {
47
+ const updated = current.replace(separatorPattern, `$1\n${newRow}\n`);
48
+ fs.writeFileSync(activePath, updated, 'utf8');
49
+ }
50
+ else {
51
+ fs.appendFileSync(activePath, `\n${newRow}\n`, 'utf8');
52
+ }
53
+ }
54
+ //# sourceMappingURL=new-task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new-task.js","sourceRoot":"","sources":["../../src/commands/new-task.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function newWorkflowCommand(title: string): Promise<void>;
2
+ //# sourceMappingURL=new-workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new-workflow.d.ts","sourceRoot":"","sources":["../../src/commands/new-workflow.ts"],"names":[],"mappings":"AAMA,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BrE"}
@@ -0,0 +1,29 @@
1
+ import path from 'path';
2
+ import chalk from 'chalk';
3
+ import { writeFile, fileExists } from '../lib/fs.js';
4
+ import { nextId } from '../lib/ids.js';
5
+ import { workflowOverview } from '../lib/templates.js';
6
+ export async function newWorkflowCommand(title) {
7
+ const cwd = process.cwd();
8
+ const activePath = path.join(cwd, 'project-memory', 'tasks', 'active.md');
9
+ // Guard: must be an initialized project
10
+ if (!fileExists(activePath)) {
11
+ console.log(chalk.red('✖ No project-memory structure found.'));
12
+ console.log(chalk.dim(' Run `project-memory init` first.'));
13
+ process.exit(1);
14
+ }
15
+ const id = nextId(cwd, 'WORKFLOW');
16
+ const workflowDir = path.join(cwd, 'project-memory', 'workflows', id);
17
+ if (fileExists(workflowDir)) {
18
+ console.log(chalk.red(`✖ ${id} already exists.`));
19
+ process.exit(1);
20
+ }
21
+ writeFile(path.join(workflowDir, 'overview.md'), workflowOverview(id, title));
22
+ console.log('');
23
+ console.log(chalk.green(` ✔ Created ${chalk.bold(id)}: ${title}`));
24
+ console.log('');
25
+ console.log(chalk.dim(` project-memory/workflows/${id}/`));
26
+ console.log(chalk.dim(` └── overview.md ← define goal, tasks, and completion criteria`));
27
+ console.log('');
28
+ }
29
+ //# sourceMappingURL=new-workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new-workflow.js","sourceRoot":"","sources":["../../src/commands/new-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAAa;IACpD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IAE1E,wCAAwC;IACxC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACnC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;IAEtE,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,gBAAgB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;IAE9E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAC,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function treeCommand(): void;
2
+ //# sourceMappingURL=tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/commands/tree.ts"],"names":[],"mappings":"AAaA,wBAAgB,WAAW,IAAI,IAAI,CAclC"}
@@ -0,0 +1,55 @@
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ import chalk from 'chalk';
4
+ // ─── Tree Command ─────────────────────────────────────────────────────────────
5
+ //
6
+ // Prints a deterministic ASCII tree of the project-memory/ directory.
7
+ // Pure Node.js fs — no external dependencies.
8
+ // Rules: folders first, files second, alphabetical within each group.
9
+ // .gitkeep files are hidden. No color. No metadata.
10
+ const HIDDEN_FILES = new Set(['.gitkeep', '.DS_Store']);
11
+ export function treeCommand() {
12
+ const cwd = process.cwd();
13
+ const pmDir = path.join(cwd, 'project-memory');
14
+ if (!fs.existsSync(pmDir)) {
15
+ console.log(chalk.red('✖ No project-memory structure found.'));
16
+ console.log(chalk.dim(' Run `project-memory init` to initialize.'));
17
+ process.exit(1);
18
+ }
19
+ console.log('');
20
+ console.log('project-memory/');
21
+ printTree(pmDir, '');
22
+ console.log('');
23
+ }
24
+ function printTree(dirPath, prefix) {
25
+ let entries;
26
+ try {
27
+ entries = fs.readdirSync(dirPath, { withFileTypes: true });
28
+ }
29
+ catch {
30
+ return;
31
+ }
32
+ // Separate and sort: folders first (alpha), then files (alpha)
33
+ const dirs = entries
34
+ .filter(e => e.isDirectory())
35
+ .map(e => e.name)
36
+ .sort((a, b) => a.localeCompare(b));
37
+ const files = entries
38
+ .filter(e => e.isFile() && !HIDDEN_FILES.has(e.name))
39
+ .map(e => e.name)
40
+ .sort((a, b) => a.localeCompare(b));
41
+ const all = [...dirs.map(n => ({ name: n, isDir: true })),
42
+ ...files.map(n => ({ name: n, isDir: false }))];
43
+ for (let i = 0; i < all.length; i++) {
44
+ const item = all[i];
45
+ const isLast = i === all.length - 1;
46
+ const connector = isLast ? '└── ' : '├── ';
47
+ const childPrefix = isLast ? ' ' : '│ ';
48
+ const label = item.isDir ? `${item.name}/` : item.name;
49
+ console.log(`${prefix}${connector}${label}`);
50
+ if (item.isDir) {
51
+ printTree(path.join(dirPath, item.name), prefix + childPrefix);
52
+ }
53
+ }
54
+ }
55
+ //# sourceMappingURL=tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.js","sourceRoot":"","sources":["../../src/commands/tree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function validateCommand(): Promise<void>;
2
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAGA,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAuCrD"}
@@ -0,0 +1,36 @@
1
+ import chalk from 'chalk';
2
+ import { validateProject } from '../lib/validator.js';
3
+ export async function validateCommand() {
4
+ const cwd = process.cwd();
5
+ const result = validateProject(cwd);
6
+ console.log('');
7
+ console.log(chalk.bold(' project-memory validate'));
8
+ console.log('');
9
+ if (result.errors.length === 0) {
10
+ console.log(chalk.green(' ✔ Base structure valid.'));
11
+ }
12
+ if (result.errors.length > 0) {
13
+ console.log(chalk.red(` ✖ ${result.errors.length} error${result.errors.length > 1 ? 's' : ''}:`));
14
+ for (const err of result.errors) {
15
+ console.log(chalk.red(` • ${err}`));
16
+ }
17
+ }
18
+ if (result.warnings.length > 0) {
19
+ console.log('');
20
+ console.log(chalk.yellow(` ⚠ ${result.warnings.length} warning${result.warnings.length > 1 ? 's' : ''}:`));
21
+ for (const warn of result.warnings) {
22
+ console.log(chalk.yellow(` • ${warn}`));
23
+ }
24
+ }
25
+ if (result.info.length > 0) {
26
+ console.log('');
27
+ for (const note of result.info) {
28
+ console.log(chalk.dim(` ℹ ${note}`));
29
+ }
30
+ }
31
+ console.log('');
32
+ if (!result.valid) {
33
+ process.exit(1);
34
+ }
35
+ }
36
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAEpC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,MAAM,CAAC,MAAM,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACpG,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,MAAM,CAAC,QAAQ,CAAC,MAAM,WAAW,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC7G,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { initCommand } from './commands/init.js';
5
+ import { newTaskCommand } from './commands/new-task.js';
6
+ import { newWorkflowCommand } from './commands/new-workflow.js';
7
+ import { validateCommand } from './commands/validate.js';
8
+ import { treeCommand } from './commands/tree.js';
9
+ const program = new Command();
10
+ program
11
+ .name('project-memory')
12
+ .description('A file-tree standard that makes any AI coding tool more effective.\n' +
13
+ chalk.dim(' The file system is the system.'))
14
+ .version('0.1.0');
15
+ // ── project-memory init ───────────────────────────────────────────────────────
16
+ program
17
+ .command('init')
18
+ .description('Detect, plan, confirm, and scaffold project-memory structure')
19
+ .option('--new', 'Force new project flow')
20
+ .option('--existing', 'Force existing project flow')
21
+ .option('--yes, -y', 'Skip confirmation prompt (still prints plan)')
22
+ .action(async (options) => {
23
+ await initCommand(options);
24
+ });
25
+ // ── project-memory new ────────────────────────────────────────────────────────
26
+ const newCmd = program.command('new').description('Create a new task or workflow');
27
+ newCmd
28
+ .command('task <title>')
29
+ .description('Create a new task folder and update active.md')
30
+ .action(async (title) => {
31
+ await newTaskCommand(title);
32
+ });
33
+ newCmd
34
+ .command('workflow <title>')
35
+ .description('Create a new workflow folder')
36
+ .action(async (title) => {
37
+ await newWorkflowCommand(title);
38
+ });
39
+ // ── project-memory validate ───────────────────────────────────────────────────
40
+ program
41
+ .command('validate')
42
+ .description('Validate the project-memory structure against the base layer spec')
43
+ .action(async () => {
44
+ await validateCommand();
45
+ });
46
+ // ── project-memory tree ───────────────────────────────────────────────────────
47
+ program
48
+ .command('tree')
49
+ .description('Print an ASCII tree of the project-memory/ structure')
50
+ .action(() => {
51
+ treeCommand();
52
+ });
53
+ // ── Help text ─────────────────────────────────────────────────────────────────
54
+ program.addHelpText('after', `
55
+ ${chalk.bold('Examples:')}
56
+ ${chalk.dim('$')} project-memory init
57
+ ${chalk.dim('$')} project-memory init --new
58
+ ${chalk.dim('$')} project-memory init --existing --yes
59
+ ${chalk.dim('$')} project-memory new task "Build login page"
60
+ ${chalk.dim('$')} project-memory new workflow "User onboarding"
61
+ ${chalk.dim('$')} project-memory validate
62
+ ${chalk.dim('$')} project-memory tree
63
+
64
+ ${chalk.bold('Spec:')}
65
+ ${chalk.dim('https://github.com/JoelHayward/project-memory-cli/blob/main/SPEC.md')}
66
+ `);
67
+ program.parse(process.argv);
68
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,gBAAgB,CAAC;KACtB,WAAW,CACV,sEAAsE;IACtE,KAAK,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAC9C;KACA,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,iFAAiF;AACjF,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8DAA8D,CAAC;KAC3E,MAAM,CAAC,OAAO,EAAE,wBAAwB,CAAC;KACzC,MAAM,CAAC,YAAY,EAAE,6BAA6B,CAAC;KACnD,MAAM,CAAC,WAAW,EAAE,8CAA8C,CAAC;KACnE,MAAM,CAAC,KAAK,EAAE,OAA6D,EAAE,EAAE;IAC9E,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEL,iFAAiF;AACjF,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,+BAA+B,CAAC,CAAC;AAEnF,MAAM;KACH,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,+CAA+C,CAAC;KAC5D,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,EAAE;IAC9B,MAAM,cAAc,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC,CAAC,CAAC;AAEL,MAAM;KACH,OAAO,CAAC,kBAAkB,CAAC;KAC3B,WAAW,CAAC,8BAA8B,CAAC;KAC3C,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,EAAE;IAC9B,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEL,iFAAiF;AACjF,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,mEAAmE,CAAC;KAChF,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,eAAe,EAAE,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEL,iFAAiF;AACjF,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,sDAAsD,CAAC;KACnE,MAAM,CAAC,GAAG,EAAE;IACX,WAAW,EAAE,CAAC;AAChB,CAAC,CAAC,CAAC;AAEL,iFAAiF;AACjF,OAAO,CAAC,WAAW,CACjB,OAAO,EACP;EACA,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC;IACrB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;IACd,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;;EAEhB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;IACjB,KAAK,CAAC,GAAG,CAAC,qEAAqE,CAAC;CACnF,CACA,CAAC;AAEF,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ export type ProjectType = 'web-app' | 'node' | 'python' | 'rust' | 'go' | 'ruby' | 'java' | 'generic';
2
+ export interface DetectionResult {
3
+ isExisting: boolean;
4
+ type: ProjectType;
5
+ signals: string[];
6
+ maturitySignals: string[];
7
+ projectName: string;
8
+ hasDocker: boolean;
9
+ hasMultipleManifests: boolean;
10
+ }
11
+ export declare function detect(cwd: string): DetectionResult;
12
+ //# sourceMappingURL=detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/lib/detector.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,MAAM,GACN,QAAQ,GACR,MAAM,GACN,IAAI,GACJ,MAAM,GACN,MAAM,GACN,SAAS,CAAC;AAEd,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AA8FD,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAwCnD"}