@miniidealab/openlogos 0.2.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.
@@ -0,0 +1,2 @@
1
+ export declare function archive(slug?: string): void;
2
+ //# sourceMappingURL=archive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/commands/archive.ts"],"names":[],"mappings":"AAIA,wBAAgB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,QAuCpC"}
@@ -0,0 +1,35 @@
1
+ import { existsSync, mkdirSync, renameSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { readLocale, t } from '../i18n.js';
4
+ export function archive(slug) {
5
+ const root = process.cwd();
6
+ const configPath = join(root, 'logos', 'logos.config.json');
7
+ if (!existsSync(configPath)) {
8
+ console.error('Error: logos/logos.config.json not found.');
9
+ console.error('Run `openlogos init` first to initialize the project.');
10
+ process.exit(1);
11
+ }
12
+ const locale = readLocale(root);
13
+ if (!slug) {
14
+ console.error('Error: Missing change proposal name.');
15
+ console.error('Usage: openlogos archive <slug>');
16
+ console.error('Example: openlogos archive add-remember-me');
17
+ process.exit(1);
18
+ }
19
+ const changePath = join(root, 'logos', 'changes', slug);
20
+ if (!existsSync(changePath)) {
21
+ console.error(`Error: Change proposal '${slug}' not found.`);
22
+ process.exit(1);
23
+ }
24
+ const archiveDir = join(root, 'logos', 'changes', 'archive');
25
+ const archivePath = join(archiveDir, slug);
26
+ if (existsSync(archivePath)) {
27
+ console.error(`Error: Archive '${slug}' already exists in logos/changes/archive/.`);
28
+ process.exit(1);
29
+ }
30
+ mkdirSync(archiveDir, { recursive: true });
31
+ renameSync(changePath, archivePath);
32
+ console.log(`\n${t(locale, 'archive.done', { slug })}`);
33
+ console.log(`${t(locale, 'archive.path', { slug })}\n`);
34
+ }
35
+ //# sourceMappingURL=archive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/commands/archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,UAAU,OAAO,CAAC,IAAa;IACnC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC;IAE5D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC3D,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAEhC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACtD,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACjD,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAExD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,2BAA2B,IAAI,cAAc,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAE3C,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,mBAAmB,IAAI,6CAA6C,CAAC,CAAC;QACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,UAAU,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAEpC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function change(slug?: string): void;
2
+ //# sourceMappingURL=change.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"change.d.ts","sourceRoot":"","sources":["../../src/commands/change.ts"],"names":[],"mappings":"AAIA,wBAAgB,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,QAgDnC"}
@@ -0,0 +1,41 @@
1
+ import { mkdirSync, writeFileSync, existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { readLocale, t, proposalTemplate, tasksTemplate } from '../i18n.js';
4
+ export function change(slug) {
5
+ const root = process.cwd();
6
+ const configPath = join(root, 'logos', 'logos.config.json');
7
+ if (!existsSync(configPath)) {
8
+ console.error('Error: logos/logos.config.json not found.');
9
+ console.error('Run `openlogos init` first to initialize the project.');
10
+ process.exit(1);
11
+ }
12
+ if (!slug) {
13
+ console.error('Error: Missing change proposal name.');
14
+ console.error('Usage: openlogos change <slug>');
15
+ console.error('Example: openlogos change add-remember-me');
16
+ process.exit(1);
17
+ }
18
+ const changePath = join(root, 'logos', 'changes', slug);
19
+ if (existsSync(changePath)) {
20
+ console.error(`Error: Change proposal '${slug}' already exists.`);
21
+ process.exit(1);
22
+ }
23
+ const locale = readLocale(root);
24
+ console.log(`\n${t(locale, 'change.creating', { slug })}\n`);
25
+ const deltaDirs = ['deltas/prd', 'deltas/api', 'deltas/database', 'deltas/scenario'];
26
+ mkdirSync(changePath, { recursive: true });
27
+ for (const dir of deltaDirs) {
28
+ mkdirSync(join(changePath, dir), { recursive: true });
29
+ }
30
+ writeFileSync(join(changePath, 'proposal.md'), proposalTemplate(locale, slug));
31
+ console.log(` āœ“ logos/changes/${slug}/proposal.md`);
32
+ writeFileSync(join(changePath, 'tasks.md'), tasksTemplate(locale));
33
+ console.log(` āœ“ logos/changes/${slug}/tasks.md`);
34
+ console.log(` āœ“ logos/changes/${slug}/deltas/`);
35
+ console.log(`\n${t(locale, 'change.done')}`);
36
+ console.log(t(locale, 'change.step1', { slug }));
37
+ console.log(t(locale, 'change.step2'));
38
+ console.log(t(locale, 'change.step3'));
39
+ console.log(t(locale, 'change.step4', { slug }) + '\n');
40
+ }
41
+ //# sourceMappingURL=change.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"change.js","sourceRoot":"","sources":["../../src/commands/change.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type Locale } from '../i18n.js';
2
+ type NameSource = 'argument' | 'package.json' | 'Cargo.toml' | 'pyproject.toml' | 'directory';
3
+ interface NameResult {
4
+ name: string;
5
+ source: NameSource;
6
+ }
7
+ export declare function readConfigName(root: string): NameResult | null;
8
+ export declare function detectProjectName(root: string): NameResult;
9
+ export declare function createLogosConfig(name: string, locale: Locale): string;
10
+ export declare function createLogosProject(name: string, locale: Locale): string;
11
+ export declare function createAgentsMd(locale: Locale): string;
12
+ export declare function init(name?: string): Promise<void>;
13
+ export {};
14
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,MAAM,EAAiD,MAAM,YAAY,CAAC;AAExF,KAAK,UAAU,GAAG,UAAU,GAAG,cAAc,GAAG,YAAY,GAAG,gBAAgB,GAAG,WAAW,CAAC;AAE9F,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CA+B9D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAI1D;AAqED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAyCtE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAYvE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAuCrD;AAED,wBAAsB,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,iBAmDvC"}
@@ -0,0 +1,237 @@
1
+ import { mkdirSync, writeFileSync, readFileSync, existsSync } from 'node:fs';
2
+ import { join, basename } from 'node:path';
3
+ import { createInterface } from 'node:readline';
4
+ import { t, conventionsForYaml, conventionsForAgentsMd } from '../i18n.js';
5
+ export function readConfigName(root) {
6
+ const pkgPath = join(root, 'package.json');
7
+ if (existsSync(pkgPath)) {
8
+ try {
9
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
10
+ if (pkg.name && typeof pkg.name === 'string') {
11
+ const name = pkg.name.replace(/^@[^/]+\//, '');
12
+ return { name, source: 'package.json' };
13
+ }
14
+ }
15
+ catch { /* ignore parse errors */ }
16
+ }
17
+ const cargoPath = join(root, 'Cargo.toml');
18
+ if (existsSync(cargoPath)) {
19
+ try {
20
+ const content = readFileSync(cargoPath, 'utf-8');
21
+ const match = content.match(/^\s*name\s*=\s*"([^"]+)"/m);
22
+ if (match)
23
+ return { name: match[1], source: 'Cargo.toml' };
24
+ }
25
+ catch { /* ignore */ }
26
+ }
27
+ const pyprojectPath = join(root, 'pyproject.toml');
28
+ if (existsSync(pyprojectPath)) {
29
+ try {
30
+ const content = readFileSync(pyprojectPath, 'utf-8');
31
+ const match = content.match(/^\s*name\s*=\s*"([^"]+)"/m);
32
+ if (match)
33
+ return { name: match[1], source: 'pyproject.toml' };
34
+ }
35
+ catch { /* ignore */ }
36
+ }
37
+ return null;
38
+ }
39
+ export function detectProjectName(root) {
40
+ const configName = readConfigName(root);
41
+ if (configName)
42
+ return configName;
43
+ return { name: basename(root), source: 'directory' };
44
+ }
45
+ function askQuestion(prompt) {
46
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
47
+ return new Promise((resolve) => {
48
+ rl.question(prompt, (answer) => {
49
+ rl.close();
50
+ resolve(answer.trim());
51
+ });
52
+ });
53
+ }
54
+ function isTTY() {
55
+ return Boolean(process.stdin.isTTY);
56
+ }
57
+ async function resolveProjectName(locale, root, explicitName) {
58
+ if (!explicitName) {
59
+ return detectProjectName(root);
60
+ }
61
+ const configName = readConfigName(root);
62
+ if (!configName || configName.name === explicitName) {
63
+ return { name: explicitName, source: 'argument' };
64
+ }
65
+ console.log(`\n⚠ ${t(locale, 'init.nameConflict')}`);
66
+ console.log(t(locale, 'init.nameChoice1', { name: explicitName }));
67
+ console.log(t(locale, 'init.nameChoice2', { name: configName.name, source: configName.source }) + '\n');
68
+ if (!isTTY()) {
69
+ return { name: explicitName, source: 'argument' };
70
+ }
71
+ const answer = await askQuestion(t(locale, 'init.namePrompt'));
72
+ if (answer === '2') {
73
+ return configName;
74
+ }
75
+ return { name: explicitName, source: 'argument' };
76
+ }
77
+ async function chooseLocale() {
78
+ if (!isTTY())
79
+ return 'en';
80
+ console.log('\nChoose language / 选择语言:');
81
+ console.log(' 1. English (default)');
82
+ console.log(' 2. äø­ę–‡\n');
83
+ const answer = await askQuestion('Your choice [1/2] (default: 1): ');
84
+ return answer === '2' ? 'zh' : 'en';
85
+ }
86
+ const DIRECTORIES = [
87
+ 'logos/resources/prd/1-product-requirements',
88
+ 'logos/resources/prd/2-product-design/1-feature-specs',
89
+ 'logos/resources/prd/2-product-design/2-page-design',
90
+ 'logos/resources/prd/3-technical-plan/1-architecture',
91
+ 'logos/resources/prd/3-technical-plan/2-scenario-implementation',
92
+ 'logos/resources/api',
93
+ 'logos/resources/database',
94
+ 'logos/resources/test',
95
+ 'logos/resources/scenario',
96
+ 'logos/resources/verify',
97
+ 'logos/changes',
98
+ 'logos/changes/archive',
99
+ ];
100
+ export function createLogosConfig(name, locale) {
101
+ return JSON.stringify({
102
+ name,
103
+ locale,
104
+ description: '',
105
+ documents: {
106
+ prd: {
107
+ label: { en: 'Product Docs', zh: '产品文攣' },
108
+ path: './resources/prd',
109
+ pattern: '**/*.{md,html,htm,pdf}',
110
+ },
111
+ api: {
112
+ label: { en: 'API Docs', zh: 'API 文攣' },
113
+ path: './resources/api',
114
+ pattern: '**/*.{yaml,yml,json}',
115
+ },
116
+ test: {
117
+ label: { en: 'Test Cases', zh: '测试用例' },
118
+ path: './resources/test',
119
+ pattern: '**/*.md',
120
+ },
121
+ scenario: {
122
+ label: { en: 'Scenarios', zh: 'äøšåŠ”åœŗę™Æ' },
123
+ path: './resources/scenario',
124
+ pattern: '**/*.json',
125
+ },
126
+ database: {
127
+ label: { en: 'Database', zh: 'ę•°ę®åŗ“' },
128
+ path: './resources/database',
129
+ pattern: '**/*.sql',
130
+ },
131
+ verify: {
132
+ label: { en: 'Verify Reports', zh: 'éŖŒę”¶ęŠ„å‘Š' },
133
+ path: './resources/verify',
134
+ pattern: '**/*.{jsonl,md}',
135
+ },
136
+ },
137
+ verify: {
138
+ result_path: 'logos/resources/verify/test-results.jsonl',
139
+ },
140
+ }, null, 2);
141
+ }
142
+ export function createLogosProject(name, locale) {
143
+ return `project:
144
+ name: "${name}"
145
+ description: ""
146
+ methodology: "OpenLogos"
147
+
148
+ tech_stack: {}
149
+
150
+ resource_index: []
151
+
152
+ ${conventionsForYaml(locale)}
153
+ `;
154
+ }
155
+ export function createAgentsMd(locale) {
156
+ return `# AI Assistant Instructions
157
+
158
+ This project follows the **OpenLogos** methodology.
159
+ Read \`logos/logos-project.yaml\` first to understand the project resource index.
160
+
161
+ ## Project Context
162
+ - Config: \`logos/logos.config.json\`
163
+ - Resource Index: \`logos/logos-project.yaml\`
164
+
165
+ ## Methodology Rules
166
+ 1. Never write code without first completing the design documents
167
+ 2. Follow the Why → What → How progression
168
+ 3. All API designs must originate from scenario sequence diagrams
169
+ 4. All code changes must have corresponding API orchestration tests
170
+ 5. Use the Delta change workflow for iterations (see logos/changes/ directory)
171
+ 6. All generated test code must include an OpenLogos reporter (see spec/test-results.md)
172
+
173
+ ## Interaction Guidelines
174
+ When the user's request is vague or they ask "what should I do next":
175
+ 1. Scan \`logos/resources/\` to determine the current project phase
176
+ 2. Suggest the specific next step based on what's missing
177
+ 3. Provide a ready-to-use prompt the user can directly say
178
+ 4. Never start generating documents without confirming key information
179
+
180
+ Phase detection logic:
181
+ - \`logos/resources/prd/1-product-requirements/\` is empty → suggest Phase 1 (prd-writer)
182
+ - requirements exist but \`2-product-design/\` is empty → suggest Phase 2 (product-designer)
183
+ - design exists but \`3-technical-plan/1-architecture/\` is empty → suggest Phase 3 Step 0 (architecture-designer)
184
+ - architecture exists but \`3-technical-plan/2-scenario-implementation/\` is empty → suggest Phase 3 Step 1 (scenario-architect)
185
+ - scenarios exist but \`logos/resources/api/\` is empty → suggest Phase 3 Step 2 (api-designer + db-designer)
186
+ - API exists but \`logos/resources/test/\` is empty → suggest Phase 3 Step 3a (test-writer)
187
+ - test cases exist but \`logos/resources/scenario/\` is empty → suggest Phase 3 Step 3b (test-orchestrator, API projects only)
188
+ - All above exist → suggest Phase 3 Step 4 (code generation)
189
+ - code generated but \`logos/resources/verify/\` is empty → suggest Phase 3 Step 5 (run tests then \`openlogos verify\`)
190
+
191
+ ## Conventions
192
+ ${conventionsForAgentsMd(locale)}
193
+ `;
194
+ }
195
+ export async function init(name) {
196
+ const root = process.cwd();
197
+ if (existsSync(join(root, 'logos', 'logos.config.json'))) {
198
+ console.error('Error: logos/logos.config.json already exists in current directory.');
199
+ console.error('This directory has already been initialized as an OpenLogos project.');
200
+ process.exit(1);
201
+ }
202
+ const locale = await chooseLocale();
203
+ const { name: projectName, source: nameSource } = await resolveProjectName(locale, root, name);
204
+ const sourceLabel = {
205
+ 'argument': '',
206
+ 'package.json': ' ← from package.json',
207
+ 'Cargo.toml': ' ← from Cargo.toml',
208
+ 'pyproject.toml': ' ← from pyproject.toml',
209
+ 'directory': ' ← from directory name',
210
+ };
211
+ console.log(`\n${t(locale, 'init.creating', { name: projectName, source: sourceLabel[nameSource] })}\n`);
212
+ for (const dir of DIRECTORIES) {
213
+ const fullPath = join(root, dir);
214
+ mkdirSync(fullPath, { recursive: true });
215
+ writeFileSync(join(fullPath, '.gitkeep'), '');
216
+ console.log(` āœ“ ${dir}/`);
217
+ }
218
+ writeFileSync(join(root, 'logos', 'logos.config.json'), createLogosConfig(projectName, locale));
219
+ console.log(` āœ“ logos/logos.config.json`);
220
+ writeFileSync(join(root, 'logos', 'logos-project.yaml'), createLogosProject(projectName, locale));
221
+ console.log(` āœ“ logos/logos-project.yaml`);
222
+ writeFileSync(join(root, 'AGENTS.md'), createAgentsMd(locale));
223
+ console.log(` āœ“ AGENTS.md`);
224
+ writeFileSync(join(root, 'CLAUDE.md'), createAgentsMd(locale));
225
+ console.log(` āœ“ CLAUDE.md`);
226
+ const isAutoDetected = nameSource !== 'argument';
227
+ const nameHint = isAutoDetected
228
+ ? `\n${t(locale, 'init.nameTip', { name: projectName, source: sourceLabel[nameSource] })}\n`
229
+ : '';
230
+ console.log(`\n${t(locale, 'init.done')}`);
231
+ console.log(t(locale, 'init.step1'));
232
+ if (nameHint)
233
+ console.log(nameHint);
234
+ console.log(t(locale, 'init.step2'));
235
+ console.log(t(locale, 'init.step3') + '\n');
236
+ }
237
+ //# 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,9 @@
1
+ interface DeltaFile {
2
+ deltaPath: string;
3
+ targetDir: string;
4
+ relativePath: string;
5
+ }
6
+ export declare function scanDeltas(deltasDir: string): DeltaFile[];
7
+ export declare function merge(slug?: string): void;
8
+ export {};
9
+ //# sourceMappingURL=merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/commands/merge.ts"],"names":[],"mappings":"AAWA,UAAU,SAAS;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,CA0BzD;AAED,wBAAgB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,QA4DlC"}
@@ -0,0 +1,83 @@
1
+ import { readFileSync, writeFileSync, existsSync, readdirSync, statSync } from 'node:fs';
2
+ import { join, relative } from 'node:path';
3
+ import { readLocale, t, mergePromptTemplate } from '../i18n.js';
4
+ const DELTA_TO_RESOURCE = {
5
+ 'prd': 'logos/resources/prd',
6
+ 'api': 'logos/resources/api',
7
+ 'database': 'logos/resources/database',
8
+ 'scenario': 'logos/resources/scenario',
9
+ };
10
+ export function scanDeltas(deltasDir) {
11
+ const results = [];
12
+ if (!existsSync(deltasDir))
13
+ return results;
14
+ for (const category of readdirSync(deltasDir)) {
15
+ const categoryDir = join(deltasDir, category);
16
+ if (!statSync(categoryDir).isDirectory())
17
+ continue;
18
+ const targetDir = DELTA_TO_RESOURCE[category];
19
+ if (!targetDir)
20
+ continue;
21
+ const files = readdirSync(categoryDir).filter(f => {
22
+ const full = join(categoryDir, f);
23
+ return statSync(full).isFile() && !f.startsWith('.');
24
+ });
25
+ for (const file of files) {
26
+ results.push({
27
+ deltaPath: join(categoryDir, file),
28
+ targetDir,
29
+ relativePath: `deltas/${category}/${file}`,
30
+ });
31
+ }
32
+ }
33
+ return results;
34
+ }
35
+ export function merge(slug) {
36
+ const root = process.cwd();
37
+ const configPath = join(root, 'logos', 'logos.config.json');
38
+ if (!existsSync(configPath)) {
39
+ console.error('Error: logos/logos.config.json not found.');
40
+ console.error('Run `openlogos init` first to initialize the project.');
41
+ process.exit(1);
42
+ }
43
+ if (!slug) {
44
+ console.error('Error: Missing change proposal name.');
45
+ console.error('Usage: openlogos merge <slug>');
46
+ console.error('Example: openlogos merge add-remember-me');
47
+ process.exit(1);
48
+ }
49
+ const changePath = join(root, 'logos', 'changes', slug);
50
+ if (!existsSync(changePath)) {
51
+ console.error(`Error: Change proposal '${slug}' not found.`);
52
+ process.exit(1);
53
+ }
54
+ const deltasDir = join(changePath, 'deltas');
55
+ const deltas = scanDeltas(deltasDir);
56
+ if (deltas.length === 0) {
57
+ console.error(`Error: No delta files found in logos/changes/${slug}/deltas/.`);
58
+ console.error('Add delta files before running merge.');
59
+ process.exit(1);
60
+ }
61
+ const locale = readLocale(root);
62
+ const proposalPath = join(changePath, 'proposal.md');
63
+ const proposalContent = existsSync(proposalPath)
64
+ ? readFileSync(proposalPath, 'utf-8')
65
+ : '(proposal.md not found)';
66
+ const promptContent = mergePromptTemplate(locale, slug, proposalContent, deltas.map(d => ({
67
+ relativePath: d.relativePath,
68
+ deltaFullPath: relative(root, d.deltaPath),
69
+ targetDir: d.targetDir,
70
+ })));
71
+ const promptPath = join(changePath, 'MERGE_PROMPT.md');
72
+ writeFileSync(promptPath, promptContent);
73
+ console.log(`\nšŸ“‹ ${t(locale, 'merge.summary')}`);
74
+ console.log(t(locale, 'merge.proposal', { slug }));
75
+ console.log(t(locale, 'merge.deltaCount', { count: String(deltas.length) }));
76
+ for (const d of deltas) {
77
+ console.log(` ${d.relativePath} → ${d.targetDir}/`);
78
+ }
79
+ console.log(`\n āœ“ logos/changes/${slug}/MERGE_PROMPT.md`);
80
+ console.log(`\nšŸ’” ${t(locale, 'merge.aiHint', { slug })}`);
81
+ console.log(`\n${t(locale, 'merge.archiveHint', { slug })}\n`);
82
+ }
83
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/commands/merge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function listFiles(dir: string): string[];
2
+ export declare function status(): void;
3
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAYA,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAY/C;AAED,wBAAgB,MAAM,SA4FrB"}
@@ -0,0 +1,101 @@
1
+ import { existsSync, readdirSync, statSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { readLocale, t, PHASE_KEYS, SUGGEST_KEYS } from '../i18n.js';
4
+ export function listFiles(dir) {
5
+ if (!existsSync(dir))
6
+ return [];
7
+ try {
8
+ return readdirSync(dir, { recursive: true })
9
+ .map(f => String(f))
10
+ .filter(f => {
11
+ const full = join(dir, f);
12
+ return statSync(full).isFile() && !f.endsWith('.gitkeep');
13
+ });
14
+ }
15
+ catch {
16
+ return [];
17
+ }
18
+ }
19
+ export function status() {
20
+ const root = process.cwd();
21
+ const configPath = join(root, 'logos', 'logos.config.json');
22
+ if (!existsSync(configPath)) {
23
+ console.error('Error: logos/logos.config.json not found.');
24
+ console.error('Run `openlogos init` first to initialize the project.');
25
+ process.exit(1);
26
+ }
27
+ const locale = readLocale(root);
28
+ const phasePaths = [
29
+ join(root, 'logos/resources/prd/1-product-requirements'),
30
+ join(root, 'logos/resources/prd/2-product-design'),
31
+ join(root, 'logos/resources/prd/3-technical-plan/1-architecture'),
32
+ join(root, 'logos/resources/prd/3-technical-plan/2-scenario-implementation'),
33
+ join(root, 'logos/resources/api'),
34
+ join(root, 'logos/resources/database'),
35
+ join(root, 'logos/resources/test'),
36
+ join(root, 'logos/resources/scenario'),
37
+ join(root, 'logos/resources/verify'),
38
+ ];
39
+ const phases = PHASE_KEYS.map((key, i) => ({
40
+ key,
41
+ label: t(locale, key),
42
+ path: phasePaths[i],
43
+ done: false,
44
+ files: [],
45
+ }));
46
+ for (const phase of phases) {
47
+ phase.files = listFiles(phase.path);
48
+ phase.done = phase.files.length > 0;
49
+ }
50
+ console.log('\nšŸ“Š OpenLogos Project Status\n');
51
+ console.log('─'.repeat(50));
52
+ for (const phase of phases) {
53
+ const icon = phase.done ? 'āœ…' : 'šŸ”²';
54
+ console.log(`${icon} ${phase.label}`);
55
+ if (phase.done) {
56
+ for (const f of phase.files) {
57
+ console.log(` └─ ${f}`);
58
+ }
59
+ }
60
+ }
61
+ console.log('─'.repeat(50));
62
+ const changesDir = join(root, 'logos', 'changes');
63
+ const activeProposals = [];
64
+ if (existsSync(changesDir)) {
65
+ for (const entry of readdirSync(changesDir)) {
66
+ if (entry === 'archive' || entry === '.gitkeep')
67
+ continue;
68
+ const entryPath = join(changesDir, entry);
69
+ if (!statSync(entryPath).isDirectory())
70
+ continue;
71
+ const hasProposal = existsSync(join(entryPath, 'proposal.md'));
72
+ const hasTasks = existsSync(join(entryPath, 'tasks.md'));
73
+ const deltasDir = join(entryPath, 'deltas');
74
+ const deltaCount = existsSync(deltasDir) ? listFiles(deltasDir).length : 0;
75
+ activeProposals.push({ name: entry, hasProposal, hasTasks, deltaCount });
76
+ }
77
+ }
78
+ if (activeProposals.length > 0) {
79
+ console.log(`\nšŸ“ ${t(locale, 'status.activeProposals')}`);
80
+ for (const p of activeProposals) {
81
+ const parts = [
82
+ p.hasProposal ? 'proposal.md āœ“' : 'proposal.md āœ—',
83
+ p.hasTasks ? 'tasks.md āœ“' : 'tasks.md āœ—',
84
+ `deltas: ${p.deltaCount} files`,
85
+ ];
86
+ console.log(` └─ ${p.name} (${parts.join(' | ')})`);
87
+ }
88
+ console.log('─'.repeat(50));
89
+ }
90
+ const firstIncomplete = phases.find(p => !p.done);
91
+ if (!firstIncomplete) {
92
+ console.log(`\nšŸŽ‰ ${t(locale, 'status.allDone')}`);
93
+ console.log(t(locale, 'status.allDoneHint') + '\n');
94
+ }
95
+ else {
96
+ console.log(`\nšŸ’” ${t(locale, 'status.suggestNext', { label: firstIncomplete.label })}`);
97
+ const suggestKey = SUGGEST_KEYS[firstIncomplete.key];
98
+ console.log(` → ${suggestKey ? t(locale, suggestKey) : t(locale, 'suggest.fallback')}\n`);
99
+ }
100
+ }
101
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function syncLogosProjectName(root: string, projectName: string): boolean;
2
+ export declare function sync(): void;
3
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAIA,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,WAerE;AAED,wBAAgB,IAAI,SAmEnB"}