@nac3/forge-cli 0.2.0-alpha.10 → 0.2.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/yf.d.ts.map +1 -1
- package/dist/bin/yf.js +5 -0
- package/dist/bin/yf.js.map +1 -1
- package/dist/commands/discover.d.ts +30 -0
- package/dist/commands/discover.d.ts.map +1 -0
- package/dist/commands/discover.js +178 -0
- package/dist/commands/discover.js.map +1 -0
- package/dist/commands/triage.d.ts +34 -0
- package/dist/commands/triage.d.ts.map +1 -0
- package/dist/commands/triage.js +228 -0
- package/dist/commands/triage.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/workflow/state.d.ts +190 -0
- package/dist/workflow/state.d.ts.map +1 -0
- package/dist/workflow/state.js +119 -0
- package/dist/workflow/state.js.map +1 -0
- package/package.json +1 -1
package/dist/bin/yf.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yf.d.ts","sourceRoot":"","sources":["../../src/bin/yf.ts"],"names":[],"mappings":";AAUA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"yf.d.ts","sourceRoot":"","sources":["../../src/bin/yf.ts"],"names":[],"mappings":";AAUA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8BpC,wBAAgB,YAAY,IAAI,OAAO,CAyCtC"}
|
package/dist/bin/yf.js
CHANGED
|
@@ -35,6 +35,8 @@ import { registerKeysSetupCommand } from '../commands/keys_setup.js';
|
|
|
35
35
|
import { registerRepoCommand } from '../commands/repo.js';
|
|
36
36
|
import { registerMobileCommand } from '../commands/mobile.js';
|
|
37
37
|
import { registerLogCommand } from '../commands/log.js';
|
|
38
|
+
import { registerTriageCommand } from '../commands/triage.js';
|
|
39
|
+
import { registerDiscoverCommand } from '../commands/discover.js';
|
|
38
40
|
import { VERSION } from '../version.js';
|
|
39
41
|
export function buildProgram() {
|
|
40
42
|
const program = new Command();
|
|
@@ -71,6 +73,9 @@ export function buildProgram() {
|
|
|
71
73
|
registerRepoCommand(program);
|
|
72
74
|
registerMobileCommand(program);
|
|
73
75
|
registerLogCommand(program);
|
|
76
|
+
/* PRODUCT_WORKFLOW.md commands (Phase I onwards). */
|
|
77
|
+
registerTriageCommand(program);
|
|
78
|
+
registerDiscoverCommand(program);
|
|
74
79
|
return program;
|
|
75
80
|
}
|
|
76
81
|
async function main() {
|
package/dist/bin/yf.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yf.js","sourceRoot":"","sources":["../../src/bin/yf.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"yf.js","sourceRoot":"","sources":["../../src/bin/yf.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `yf discover` -- Phase I step 3 of PRODUCT_WORKFLOW.md.
|
|
3
|
+
*
|
|
4
|
+
* Asks the user what they actually want to build + how they
|
|
5
|
+
* want to talk to Forge while doing it. Output is a structured
|
|
6
|
+
* intent object persisted to yujin.forge.json::workflow.intent.
|
|
7
|
+
*
|
|
8
|
+
* Questions:
|
|
9
|
+
* 1. Operation type (migrate legacy / create new / modify existing)
|
|
10
|
+
* 2. Target devices (desktop / mobile / responsive / both native)
|
|
11
|
+
* 3. Input channel (chat-text / voice / document-paste)
|
|
12
|
+
* 4. Project state (no-code / local-repo / remote-repo / deployed)
|
|
13
|
+
* 5. Legacy framework (if migrating) -- text input
|
|
14
|
+
* 6. Preferred stack (if creating new) -- text input
|
|
15
|
+
* 7. Use case (hobby / POC / internal / commercial)
|
|
16
|
+
*
|
|
17
|
+
* Pre-requisite: yf triage must have been run (workflow.tier set).
|
|
18
|
+
* The triage tier influences which subsequent steps Forge will
|
|
19
|
+
* recommend after discover completes.
|
|
20
|
+
*
|
|
21
|
+
* ASCII-only.
|
|
22
|
+
*/
|
|
23
|
+
import type { Command } from 'commander';
|
|
24
|
+
export interface DiscoverOptions {
|
|
25
|
+
cwd?: string;
|
|
26
|
+
yes?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare function runDiscover(opts: DiscoverOptions): Promise<void>;
|
|
29
|
+
export declare function registerDiscoverCommand(program: Command): void;
|
|
30
|
+
//# sourceMappingURL=discover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/commands/discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA+ItE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAc9D"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `yf discover` -- Phase I step 3 of PRODUCT_WORKFLOW.md.
|
|
3
|
+
*
|
|
4
|
+
* Asks the user what they actually want to build + how they
|
|
5
|
+
* want to talk to Forge while doing it. Output is a structured
|
|
6
|
+
* intent object persisted to yujin.forge.json::workflow.intent.
|
|
7
|
+
*
|
|
8
|
+
* Questions:
|
|
9
|
+
* 1. Operation type (migrate legacy / create new / modify existing)
|
|
10
|
+
* 2. Target devices (desktop / mobile / responsive / both native)
|
|
11
|
+
* 3. Input channel (chat-text / voice / document-paste)
|
|
12
|
+
* 4. Project state (no-code / local-repo / remote-repo / deployed)
|
|
13
|
+
* 5. Legacy framework (if migrating) -- text input
|
|
14
|
+
* 6. Preferred stack (if creating new) -- text input
|
|
15
|
+
* 7. Use case (hobby / POC / internal / commercial)
|
|
16
|
+
*
|
|
17
|
+
* Pre-requisite: yf triage must have been run (workflow.tier set).
|
|
18
|
+
* The triage tier influences which subsequent steps Forge will
|
|
19
|
+
* recommend after discover completes.
|
|
20
|
+
*
|
|
21
|
+
* ASCII-only.
|
|
22
|
+
*/
|
|
23
|
+
import path from 'node:path';
|
|
24
|
+
import prompts from 'prompts';
|
|
25
|
+
import { c, header } from '../ui/colors.js';
|
|
26
|
+
import { readWorkflow, patchWorkflowGroup, } from '../workflow/state.js';
|
|
27
|
+
export async function runDiscover(opts) {
|
|
28
|
+
header('Yujin Forge -- discover intent');
|
|
29
|
+
console.log('');
|
|
30
|
+
const projectRoot = opts.cwd ? path.resolve(opts.cwd) : process.cwd();
|
|
31
|
+
const wf = await readWorkflow(projectRoot);
|
|
32
|
+
if (!wf.tier) {
|
|
33
|
+
console.log(c.error('No hay triage previo. Corre primero ') + c.code('yf triage'));
|
|
34
|
+
process.exitCode = 1;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (wf.intent && !opts.yes) {
|
|
38
|
+
console.log(c.dim('Intent previo: ') + c.brand(wf.intent.operation ?? '?')
|
|
39
|
+
+ c.dim(' / target ') + c.brand(wf.intent.target ?? '?')
|
|
40
|
+
+ c.dim(' / use case ') + c.brand(wf.intent.use_case ?? '?'));
|
|
41
|
+
console.log(c.dim('Para volver a registrar, corre `yf discover --yes`.'));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
console.log(c.dim('Tier: ') + c.brand(wf.tier));
|
|
45
|
+
console.log(c.dim('7 preguntas para registrar QUE estamos construyendo.'));
|
|
46
|
+
console.log('');
|
|
47
|
+
/* Operation type first -- conditional questions depend on it. */
|
|
48
|
+
const opAns = await prompts({
|
|
49
|
+
type: 'select',
|
|
50
|
+
name: 'operation',
|
|
51
|
+
message: 'Tipo de operacion:',
|
|
52
|
+
choices: [
|
|
53
|
+
{ title: 'Migrar proyecto legacy a NAC-3', value: 'migrate' },
|
|
54
|
+
{ title: 'Crear proyecto NUEVO desde cero', value: 'new' },
|
|
55
|
+
{ title: 'Modificar proyecto existente', value: 'modify' },
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
if (!opAns.operation) {
|
|
59
|
+
console.log(c.warn('Discover abortado.'));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const rest = await prompts([
|
|
63
|
+
{
|
|
64
|
+
type: 'select',
|
|
65
|
+
name: 'target',
|
|
66
|
+
message: 'Target devices:',
|
|
67
|
+
choices: [
|
|
68
|
+
{ title: 'Desktop only', value: 'desktop' },
|
|
69
|
+
{ title: 'Mobile only', value: 'mobile' },
|
|
70
|
+
{ title: 'Responsive web (desktop + mobile)', value: 'responsive' },
|
|
71
|
+
{ title: 'Web nativo + Mobile nativo', value: 'web-and-mobile' },
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: 'select',
|
|
76
|
+
name: 'input_channel',
|
|
77
|
+
message: 'Canal preferido para hablar con Forge:',
|
|
78
|
+
choices: [
|
|
79
|
+
{ title: 'Chat texto', value: 'chat-text' },
|
|
80
|
+
{ title: 'Voz (push-to-talk)', value: 'voice' },
|
|
81
|
+
{ title: 'Pegar documento (PDF / DOCX / etc)', value: 'document-paste' },
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
type: 'select',
|
|
86
|
+
name: 'project_state',
|
|
87
|
+
message: 'Estado actual del proyecto:',
|
|
88
|
+
choices: [
|
|
89
|
+
{ title: 'Cero codigo', value: 'no-code' },
|
|
90
|
+
{ title: 'Tengo repo local sin push', value: 'local-repo' },
|
|
91
|
+
{ title: 'Repo remoto (GitHub / GitLab / Bitbucket)', value: 'remote-repo' },
|
|
92
|
+
{ title: 'Ya esta deployed en algun lado', value: 'deployed' },
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
type: opAns.operation === 'migrate' || opAns.operation === 'modify' ? 'text' : null,
|
|
97
|
+
name: 'legacy_framework',
|
|
98
|
+
message: 'Framework actual + version (ej: "React 16.14", "Angular 12", "Vue 2", "jQuery"):',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
type: opAns.operation === 'new' ? 'text' : null,
|
|
102
|
+
name: 'preferred_stack',
|
|
103
|
+
message: 'Stack preferido (vacio = default Forge: React + Vite + NAC-3 + Expo mobile):',
|
|
104
|
+
initial: '',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
type: 'select',
|
|
108
|
+
name: 'use_case',
|
|
109
|
+
message: 'Caso de uso real:',
|
|
110
|
+
choices: [
|
|
111
|
+
{ title: 'Hobby / aprender', value: 'hobby' },
|
|
112
|
+
{ title: 'POC / prototype', value: 'poc' },
|
|
113
|
+
{ title: 'Herramienta interna de una empresa', value: 'internal' },
|
|
114
|
+
{ title: 'Producto comercial publico', value: 'commercial' },
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
]);
|
|
118
|
+
if (!rest.target || !rest.input_channel || !rest.project_state || !rest.use_case) {
|
|
119
|
+
console.log(c.warn('Discover abortado (faltan respuestas).'));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const intent = {
|
|
123
|
+
operation: opAns.operation,
|
|
124
|
+
target: rest.target,
|
|
125
|
+
input_channel: rest.input_channel,
|
|
126
|
+
project_state: rest.project_state,
|
|
127
|
+
legacy_framework: rest.legacy_framework ?? null,
|
|
128
|
+
preferred_stack: rest.preferred_stack || null,
|
|
129
|
+
use_case: rest.use_case,
|
|
130
|
+
decided_at: new Date().toISOString(),
|
|
131
|
+
};
|
|
132
|
+
await patchWorkflowGroup(projectRoot, 'intent', intent);
|
|
133
|
+
console.log('');
|
|
134
|
+
console.log(c.success('Intent registrado:'));
|
|
135
|
+
console.log(c.dim(' Operacion: ') + c.brand(intent.operation));
|
|
136
|
+
console.log(c.dim(' Target: ') + c.brand(intent.target));
|
|
137
|
+
console.log(c.dim(' Canal: ') + c.brand(intent.input_channel));
|
|
138
|
+
console.log(c.dim(' Estado: ') + c.brand(intent.project_state));
|
|
139
|
+
if (intent.legacy_framework) {
|
|
140
|
+
console.log(c.dim(' Legacy: ') + c.brand(intent.legacy_framework));
|
|
141
|
+
}
|
|
142
|
+
if (intent.preferred_stack) {
|
|
143
|
+
console.log(c.dim(' Stack: ') + c.brand(intent.preferred_stack));
|
|
144
|
+
}
|
|
145
|
+
console.log(c.dim(' Caso de uso: ') + c.brand(intent.use_case));
|
|
146
|
+
console.log('');
|
|
147
|
+
/* Next-step hint based on what we now know. */
|
|
148
|
+
const tier = wf.tier;
|
|
149
|
+
if (intent.operation === 'migrate' || intent.operation === 'modify') {
|
|
150
|
+
console.log(c.dim('Siguiente paso: ') + c.code('yf legacy audit')
|
|
151
|
+
+ c.dim(' (escanea el proyecto existente)'));
|
|
152
|
+
}
|
|
153
|
+
else if (tier === 'simple') {
|
|
154
|
+
console.log(c.dim('Siguiente paso: ') + c.code('yf bootstrap')
|
|
155
|
+
+ c.dim(' (scaffolding directo, tier=simple salta clarification)'));
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
console.log(c.dim('Siguiente paso: ') + c.code('yf clarify functional')
|
|
159
|
+
+ c.dim(' (primera ronda de NFR)'));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
export function registerDiscoverCommand(program) {
|
|
163
|
+
program
|
|
164
|
+
.command('discover')
|
|
165
|
+
.description('Phase I step 3: discover user intent (migrate / new / modify + target + channel).')
|
|
166
|
+
.option('--cwd <path>', 'project root (default: current directory)')
|
|
167
|
+
.option('--yes', 'overwrite a prior discover decision without prompting')
|
|
168
|
+
.action(async (opts) => {
|
|
169
|
+
try {
|
|
170
|
+
await runDiscover(opts);
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
console.error(c.error(err instanceof Error ? err.message : String(err)));
|
|
174
|
+
process.exitCode = 1;
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=discover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/commands/discover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `yf triage` -- Phase I step 1 of PRODUCT_WORKFLOW.md.
|
|
3
|
+
*
|
|
4
|
+
* Asks the user 5 questions, classifies the project into one of
|
|
5
|
+
* three complexity tiers (Simple / Medium / Full), and persists
|
|
6
|
+
* the decision to yujin.forge.json::workflow. The result drives
|
|
7
|
+
* which subsequent phases apply (see PRODUCT_WORKFLOW.md sec 1).
|
|
8
|
+
*
|
|
9
|
+
* Questions:
|
|
10
|
+
* 1. Output type (landing / blog / CRUD app / SaaS / regulated system)
|
|
11
|
+
* 2. Volumetria 12m (numeric: expected concurrent users at 12 months)
|
|
12
|
+
* 3. Industry context (general / health / finance / education / government)
|
|
13
|
+
* 4. Region (LATAM / US / EU / global)
|
|
14
|
+
* 5. Team maintaining (solo / pair / team)
|
|
15
|
+
*
|
|
16
|
+
* Classification rules:
|
|
17
|
+
* Simple = output in {landing, blog, demo} OR volumetria < 50 AND
|
|
18
|
+
* industry = general AND team = solo
|
|
19
|
+
* Full = industry in {health, finance, government} OR volumetria > 5000
|
|
20
|
+
* OR output = regulated_system OR (region = EU AND volumetria > 100)
|
|
21
|
+
* Medium = everything else
|
|
22
|
+
*
|
|
23
|
+
* User can override the auto-tier in the final confirmation.
|
|
24
|
+
*
|
|
25
|
+
* ASCII-only.
|
|
26
|
+
*/
|
|
27
|
+
import type { Command } from 'commander';
|
|
28
|
+
export interface TriageOptions {
|
|
29
|
+
cwd?: string;
|
|
30
|
+
yes?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare function runTriage(opts: TriageOptions): Promise<void>;
|
|
33
|
+
export declare function registerTriageCommand(program: Command): void;
|
|
34
|
+
//# sourceMappingURL=triage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage.d.ts","sourceRoot":"","sources":["../../src/commands/triage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAsED,wBAAsB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA6HlE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAc5D"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `yf triage` -- Phase I step 1 of PRODUCT_WORKFLOW.md.
|
|
3
|
+
*
|
|
4
|
+
* Asks the user 5 questions, classifies the project into one of
|
|
5
|
+
* three complexity tiers (Simple / Medium / Full), and persists
|
|
6
|
+
* the decision to yujin.forge.json::workflow. The result drives
|
|
7
|
+
* which subsequent phases apply (see PRODUCT_WORKFLOW.md sec 1).
|
|
8
|
+
*
|
|
9
|
+
* Questions:
|
|
10
|
+
* 1. Output type (landing / blog / CRUD app / SaaS / regulated system)
|
|
11
|
+
* 2. Volumetria 12m (numeric: expected concurrent users at 12 months)
|
|
12
|
+
* 3. Industry context (general / health / finance / education / government)
|
|
13
|
+
* 4. Region (LATAM / US / EU / global)
|
|
14
|
+
* 5. Team maintaining (solo / pair / team)
|
|
15
|
+
*
|
|
16
|
+
* Classification rules:
|
|
17
|
+
* Simple = output in {landing, blog, demo} OR volumetria < 50 AND
|
|
18
|
+
* industry = general AND team = solo
|
|
19
|
+
* Full = industry in {health, finance, government} OR volumetria > 5000
|
|
20
|
+
* OR output = regulated_system OR (region = EU AND volumetria > 100)
|
|
21
|
+
* Medium = everything else
|
|
22
|
+
*
|
|
23
|
+
* User can override the auto-tier in the final confirmation.
|
|
24
|
+
*
|
|
25
|
+
* ASCII-only.
|
|
26
|
+
*/
|
|
27
|
+
import path from 'node:path';
|
|
28
|
+
import prompts from 'prompts';
|
|
29
|
+
import { c, header } from '../ui/colors.js';
|
|
30
|
+
import { writeWorkflow, readWorkflow, } from '../workflow/state.js';
|
|
31
|
+
function classify(a) {
|
|
32
|
+
const simpleOutputs = ['landing', 'blog'];
|
|
33
|
+
const regulated = ['health', 'finance', 'government'];
|
|
34
|
+
if (simpleOutputs.includes(a.output)
|
|
35
|
+
|| (a.volumetria < 50 && a.industry === 'general' && a.team === 'solo')) {
|
|
36
|
+
return {
|
|
37
|
+
tier: 'simple',
|
|
38
|
+
reason: a.output === 'landing' ? 'landing page'
|
|
39
|
+
: a.output === 'blog' ? 'blog'
|
|
40
|
+
: 'small single-user project (< 50 users / 12m, general industry, solo team)',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (regulated.includes(a.industry)
|
|
44
|
+
|| a.volumetria > 5000
|
|
45
|
+
|| a.output === 'regulated'
|
|
46
|
+
|| (a.region === 'eu' && a.volumetria > 100)) {
|
|
47
|
+
const reasons = [];
|
|
48
|
+
if (regulated.includes(a.industry))
|
|
49
|
+
reasons.push('regulated industry (' + a.industry + ')');
|
|
50
|
+
if (a.volumetria > 5000)
|
|
51
|
+
reasons.push('volumetria > 5000');
|
|
52
|
+
if (a.output === 'regulated')
|
|
53
|
+
reasons.push('output = regulated system');
|
|
54
|
+
if (a.region === 'eu' && a.volumetria > 100)
|
|
55
|
+
reasons.push('EU + > 100 users (GDPR compliance)');
|
|
56
|
+
return {
|
|
57
|
+
tier: 'full',
|
|
58
|
+
reason: reasons.join(' + '),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
tier: 'medium',
|
|
63
|
+
reason: 'CRUD/SaaS app with moderate volumetria, non-regulated industry',
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function describeAlcance(tier) {
|
|
67
|
+
switch (tier) {
|
|
68
|
+
case 'simple':
|
|
69
|
+
return [
|
|
70
|
+
' Phase I (intake) -> Phase II step 9 (blocks) -> Phase V (build) -> Phase VI (ship)',
|
|
71
|
+
' Skips: full clarification rounds, RFP+arch+design docs, approval gate',
|
|
72
|
+
].join('\n');
|
|
73
|
+
case 'medium':
|
|
74
|
+
return [
|
|
75
|
+
' Phase I + Phase II + Phase III (compact) + Phase IV gate + Phase V + Phase VI',
|
|
76
|
+
' Light RFP+arch+design; explicit approval before build starts',
|
|
77
|
+
].join('\n');
|
|
78
|
+
case 'full':
|
|
79
|
+
return [
|
|
80
|
+
' ALL 18 steps, all 4 NFR rounds, full RFP+arch+design,',
|
|
81
|
+
' hard approval gate, NAC-3 compliance auditing per block',
|
|
82
|
+
].join('\n');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export async function runTriage(opts) {
|
|
86
|
+
header('Yujin Forge -- triage');
|
|
87
|
+
console.log('');
|
|
88
|
+
const projectRoot = opts.cwd ? path.resolve(opts.cwd) : process.cwd();
|
|
89
|
+
const existing = await readWorkflow(projectRoot);
|
|
90
|
+
if (existing.tier && !opts.yes) {
|
|
91
|
+
console.log(c.dim('Triage previo: ') + c.brand(existing.tier)
|
|
92
|
+
+ c.dim(' (' + (existing.tier_reason ?? 'no reason') + ')'));
|
|
93
|
+
console.log(c.dim('Para volver a clasificar, corre `yf triage --yes`.'));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
console.log(c.dim('5 preguntas para clasificar la complejidad del proyecto.'));
|
|
97
|
+
console.log(c.dim('La clasificacion determina que fases del workflow se aplican.'));
|
|
98
|
+
console.log('');
|
|
99
|
+
const answers = await prompts([
|
|
100
|
+
{
|
|
101
|
+
type: 'select',
|
|
102
|
+
name: 'output',
|
|
103
|
+
message: 'Tipo de output:',
|
|
104
|
+
choices: [
|
|
105
|
+
{ title: 'Landing page', value: 'landing' },
|
|
106
|
+
{ title: 'Blog / sitio de contenido', value: 'blog' },
|
|
107
|
+
{ title: 'App CRUD con auth (multi-user)', value: 'crud' },
|
|
108
|
+
{ title: 'SaaS multi-tenant', value: 'saas' },
|
|
109
|
+
{ title: 'Sistema regulado / compliance critica', value: 'regulated' },
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
type: 'number',
|
|
114
|
+
name: 'volumetria',
|
|
115
|
+
message: 'Usuarios concurrentes esperados a 12 meses (entero):',
|
|
116
|
+
initial: 100,
|
|
117
|
+
min: 0,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
type: 'select',
|
|
121
|
+
name: 'industry',
|
|
122
|
+
message: 'Industria:',
|
|
123
|
+
choices: [
|
|
124
|
+
{ title: 'General', value: 'general' },
|
|
125
|
+
{ title: 'Salud (HIPAA / privacidad medica)', value: 'health' },
|
|
126
|
+
{ title: 'Finanzas (PCI / regulacion bancaria)', value: 'finance' },
|
|
127
|
+
{ title: 'Educacion', value: 'education' },
|
|
128
|
+
{ title: 'Gobierno / sector publico', value: 'government' },
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
type: 'select',
|
|
133
|
+
name: 'region',
|
|
134
|
+
message: 'Region de usuarios:',
|
|
135
|
+
choices: [
|
|
136
|
+
{ title: 'LATAM', value: 'latam' },
|
|
137
|
+
{ title: 'US', value: 'us' },
|
|
138
|
+
{ title: 'EU (aplican GDPR)', value: 'eu' },
|
|
139
|
+
{ title: 'Global', value: 'global' },
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
type: 'select',
|
|
144
|
+
name: 'team',
|
|
145
|
+
message: 'Equipo que mantiene:',
|
|
146
|
+
choices: [
|
|
147
|
+
{ title: 'Solo (vos)', value: 'solo' },
|
|
148
|
+
{ title: 'En pareja (2)', value: 'pair' },
|
|
149
|
+
{ title: 'Equipo (3 o mas)', value: 'team' },
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
]);
|
|
153
|
+
if (!answers.output || answers.volumetria === undefined || !answers.industry
|
|
154
|
+
|| !answers.region || !answers.team) {
|
|
155
|
+
console.log(c.warn('Triage abortado (faltan respuestas).'));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const { tier, reason } = classify(answers);
|
|
159
|
+
console.log('');
|
|
160
|
+
console.log(c.brand('Tier propuesto: ') + c.brand(tier.toUpperCase()));
|
|
161
|
+
console.log(c.dim(' Razon: ') + reason);
|
|
162
|
+
console.log('');
|
|
163
|
+
console.log(c.brand('Alcance del workflow para este tier:'));
|
|
164
|
+
console.log(describeAlcance(tier));
|
|
165
|
+
console.log('');
|
|
166
|
+
const confirm = await prompts({
|
|
167
|
+
type: 'select',
|
|
168
|
+
name: 'choice',
|
|
169
|
+
message: 'Confirmar tier?',
|
|
170
|
+
choices: [
|
|
171
|
+
{ title: 'Confirmar ' + tier, value: 'confirm' },
|
|
172
|
+
{ title: 'Override a SIMPLE (forzar workflow minimo)', value: 'simple' },
|
|
173
|
+
{ title: 'Override a MEDIUM', value: 'medium' },
|
|
174
|
+
{ title: 'Override a FULL (forzar workflow completo)', value: 'full' },
|
|
175
|
+
{ title: 'Cancelar', value: 'cancel' },
|
|
176
|
+
],
|
|
177
|
+
});
|
|
178
|
+
let finalTier;
|
|
179
|
+
let finalReason;
|
|
180
|
+
switch (confirm.choice) {
|
|
181
|
+
case 'confirm':
|
|
182
|
+
finalTier = tier;
|
|
183
|
+
finalReason = reason;
|
|
184
|
+
break;
|
|
185
|
+
case 'simple':
|
|
186
|
+
finalTier = 'simple';
|
|
187
|
+
finalReason = 'user override after auto: ' + tier;
|
|
188
|
+
break;
|
|
189
|
+
case 'medium':
|
|
190
|
+
finalTier = 'medium';
|
|
191
|
+
finalReason = 'user override after auto: ' + tier;
|
|
192
|
+
break;
|
|
193
|
+
case 'full':
|
|
194
|
+
finalTier = 'full';
|
|
195
|
+
finalReason = 'user override after auto: ' + tier;
|
|
196
|
+
break;
|
|
197
|
+
default:
|
|
198
|
+
console.log(c.warn('Triage cancelado.'));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
await writeWorkflow(projectRoot, {
|
|
202
|
+
tier: finalTier,
|
|
203
|
+
tier_reason: finalReason,
|
|
204
|
+
tier_decided_at: new Date().toISOString(),
|
|
205
|
+
});
|
|
206
|
+
console.log('');
|
|
207
|
+
console.log(c.success('Triage persistido. Tier: ' + c.brand(finalTier)));
|
|
208
|
+
console.log(c.dim(' Estado guardado en yujin.forge.json'));
|
|
209
|
+
console.log('');
|
|
210
|
+
console.log(c.dim('Siguiente paso: ') + c.code('yf discover'));
|
|
211
|
+
}
|
|
212
|
+
export function registerTriageCommand(program) {
|
|
213
|
+
program
|
|
214
|
+
.command('triage')
|
|
215
|
+
.description('Phase I step 1: classify project complexity (Simple / Medium / Full).')
|
|
216
|
+
.option('--cwd <path>', 'project root (default: current directory)')
|
|
217
|
+
.option('--yes', 'overwrite a prior triage decision without prompting')
|
|
218
|
+
.action(async (opts) => {
|
|
219
|
+
try {
|
|
220
|
+
await runTriage(opts);
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
console.error(c.error(err instanceof Error ? err.message : String(err)));
|
|
224
|
+
process.exitCode = 1;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=triage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage.js","sourceRoot":"","sources":["../../src/commands/triage.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yujin Forge -- Product Workflow state.
|
|
3
|
+
*
|
|
4
|
+
* Shared persistence layer for the 18-step methodology defined
|
|
5
|
+
* in docs/PRODUCT_WORKFLOW.md. State lives in the project's
|
|
6
|
+
* yujin.forge.json under `workflow.*` so it survives across
|
|
7
|
+
* sessions + can be inspected + shared via the git repo.
|
|
8
|
+
*
|
|
9
|
+
* Every command in the workflow (yf triage, yf discover, yf
|
|
10
|
+
* clarify, yf spec, yf approve, yf bootstrap, yf block dev, yf
|
|
11
|
+
* deploy, yf manual, yf metrics, yf iterate) reads + writes
|
|
12
|
+
* through this module. The chat tool surface (forge_triage,
|
|
13
|
+
* forge_discover, etc) does the same -- the underlying state
|
|
14
|
+
* is identical regardless of entry point.
|
|
15
|
+
*
|
|
16
|
+
* Schema:
|
|
17
|
+
*
|
|
18
|
+
* workflow: {
|
|
19
|
+
* tier: 'simple' | 'medium' | 'full' | null,
|
|
20
|
+
* tier_reason: string,
|
|
21
|
+
* tier_decided_at: ISO,
|
|
22
|
+
*
|
|
23
|
+
* intent: { ... } // Phase I step 3
|
|
24
|
+
* legacy_audit: { ... } // Phase I step 3.5
|
|
25
|
+
* vault_inventory: { ... } // Phase I step 2 audit
|
|
26
|
+
*
|
|
27
|
+
* clarification: {
|
|
28
|
+
* functional: { done_at, summary, doc_path }, // step 4
|
|
29
|
+
* nfr_quantitative: { done_at, summary, doc_path }, // step 5
|
|
30
|
+
* nfr_structural: { done_at, summary, doc_path }, // step 6
|
|
31
|
+
* nfr_governance: { done_at, summary, doc_path }, // step 7
|
|
32
|
+
* nfr_operational: { done_at, summary, doc_path }, // step 8
|
|
33
|
+
* blocks: { done_at, blocks: [...] }, // step 9
|
|
34
|
+
* },
|
|
35
|
+
*
|
|
36
|
+
* specs: {
|
|
37
|
+
* rfp: { done_at, version, doc_path, sha256 }, // step 10
|
|
38
|
+
* arch: { done_at, version, doc_path, sha256 }, // step 11
|
|
39
|
+
* design: { done_at, version, doc_path, sha256 }, // step 12
|
|
40
|
+
* },
|
|
41
|
+
*
|
|
42
|
+
* approvals: {
|
|
43
|
+
* rfp: { approved_at, version_sha256 }, // step 13
|
|
44
|
+
* arch: { approved_at, version_sha256 }, // step 13
|
|
45
|
+
* design: { approved_at, version_sha256 }, // step 13
|
|
46
|
+
* },
|
|
47
|
+
*
|
|
48
|
+
* bootstrap: { done_at, stack, ci_set }, // step 14
|
|
49
|
+
*
|
|
50
|
+
* blocks_progress: [ // step 15
|
|
51
|
+
* { block_id, status, tests_green_at, deployed_at }
|
|
52
|
+
* ],
|
|
53
|
+
*
|
|
54
|
+
* deploy: { ... } // step 16
|
|
55
|
+
* postlaunch:{ ... } // step 17
|
|
56
|
+
* iterations:[{ at, type, summary }] // step 18
|
|
57
|
+
* }
|
|
58
|
+
*
|
|
59
|
+
* ASCII-only.
|
|
60
|
+
*/
|
|
61
|
+
export type WorkflowTier = 'simple' | 'medium' | 'full';
|
|
62
|
+
export interface IntentState {
|
|
63
|
+
operation: 'migrate' | 'new' | 'modify' | null;
|
|
64
|
+
target: 'desktop' | 'mobile' | 'responsive' | 'web-and-mobile' | null;
|
|
65
|
+
input_channel: 'chat-text' | 'voice' | 'document-paste' | null;
|
|
66
|
+
project_state: 'no-code' | 'local-repo' | 'remote-repo' | 'deployed' | null;
|
|
67
|
+
legacy_framework: string | null;
|
|
68
|
+
preferred_stack: string | null;
|
|
69
|
+
use_case: 'hobby' | 'poc' | 'internal' | 'commercial' | null;
|
|
70
|
+
decided_at: string;
|
|
71
|
+
}
|
|
72
|
+
export interface LegacyAuditState {
|
|
73
|
+
ran_at: string;
|
|
74
|
+
framework: string;
|
|
75
|
+
framework_version: string;
|
|
76
|
+
total_files: number;
|
|
77
|
+
tsx_files: number;
|
|
78
|
+
has_tests: boolean;
|
|
79
|
+
nac3_readiness: number;
|
|
80
|
+
tech_debt_signals: string[];
|
|
81
|
+
deprecated_deps: string[];
|
|
82
|
+
}
|
|
83
|
+
export interface VaultInventoryState {
|
|
84
|
+
ran_at: string;
|
|
85
|
+
/** Per family: configured | skipped | unknown.
|
|
86
|
+
* Skipped families are flagged as debt for step 16 (deploy). */
|
|
87
|
+
families: Record<string, 'configured' | 'skipped' | 'unknown'>;
|
|
88
|
+
}
|
|
89
|
+
export interface ClarificationRoundState {
|
|
90
|
+
done_at: string;
|
|
91
|
+
summary: string;
|
|
92
|
+
doc_path?: string;
|
|
93
|
+
}
|
|
94
|
+
export interface BlockPlanItem {
|
|
95
|
+
id: string;
|
|
96
|
+
name: string;
|
|
97
|
+
effort: 'S' | 'M' | 'L' | 'XL';
|
|
98
|
+
dependencies: string[];
|
|
99
|
+
mvp: boolean;
|
|
100
|
+
}
|
|
101
|
+
export interface ClarificationState {
|
|
102
|
+
functional?: ClarificationRoundState;
|
|
103
|
+
nfr_quantitative?: ClarificationRoundState;
|
|
104
|
+
nfr_structural?: ClarificationRoundState;
|
|
105
|
+
nfr_governance?: ClarificationRoundState;
|
|
106
|
+
nfr_operational?: ClarificationRoundState;
|
|
107
|
+
blocks?: {
|
|
108
|
+
done_at: string;
|
|
109
|
+
blocks: BlockPlanItem[];
|
|
110
|
+
mvp_path: string[];
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
export interface SpecDocState {
|
|
114
|
+
done_at: string;
|
|
115
|
+
version: number;
|
|
116
|
+
doc_path: string;
|
|
117
|
+
sha256: string;
|
|
118
|
+
}
|
|
119
|
+
export interface ApprovalState {
|
|
120
|
+
approved_at: string;
|
|
121
|
+
version_sha256: string;
|
|
122
|
+
}
|
|
123
|
+
export interface BootstrapState {
|
|
124
|
+
done_at: string;
|
|
125
|
+
stack: string;
|
|
126
|
+
ci_set: boolean;
|
|
127
|
+
}
|
|
128
|
+
export interface BlockProgressState {
|
|
129
|
+
block_id: string;
|
|
130
|
+
status: 'pending' | 'in_progress' | 'green' | 'failed';
|
|
131
|
+
tests_green_at?: string;
|
|
132
|
+
deployed_at?: string;
|
|
133
|
+
}
|
|
134
|
+
export interface DeployState {
|
|
135
|
+
done_at: string;
|
|
136
|
+
pipeline: string;
|
|
137
|
+
url: string;
|
|
138
|
+
smoke_at: string;
|
|
139
|
+
}
|
|
140
|
+
export interface PostLaunchState {
|
|
141
|
+
manual_at: string;
|
|
142
|
+
dashboards_at: string;
|
|
143
|
+
feedback_channel: string;
|
|
144
|
+
}
|
|
145
|
+
export interface IterationEntry {
|
|
146
|
+
at: string;
|
|
147
|
+
type: 'bug' | 'feature_small' | 'feature_large' | 'nfr_change' | 'pivot';
|
|
148
|
+
summary: string;
|
|
149
|
+
}
|
|
150
|
+
export interface WorkflowState {
|
|
151
|
+
tier?: WorkflowTier;
|
|
152
|
+
tier_reason?: string;
|
|
153
|
+
tier_decided_at?: string;
|
|
154
|
+
intent?: IntentState;
|
|
155
|
+
legacy_audit?: LegacyAuditState;
|
|
156
|
+
vault_inventory?: VaultInventoryState;
|
|
157
|
+
clarification?: ClarificationState;
|
|
158
|
+
specs?: {
|
|
159
|
+
rfp?: SpecDocState;
|
|
160
|
+
arch?: SpecDocState;
|
|
161
|
+
design?: SpecDocState;
|
|
162
|
+
};
|
|
163
|
+
approvals?: {
|
|
164
|
+
rfp?: ApprovalState;
|
|
165
|
+
arch?: ApprovalState;
|
|
166
|
+
design?: ApprovalState;
|
|
167
|
+
};
|
|
168
|
+
bootstrap?: BootstrapState;
|
|
169
|
+
blocks_progress?: BlockProgressState[];
|
|
170
|
+
deploy?: DeployState;
|
|
171
|
+
postlaunch?: PostLaunchState;
|
|
172
|
+
iterations?: IterationEntry[];
|
|
173
|
+
}
|
|
174
|
+
interface ProjectConfig {
|
|
175
|
+
workflow?: WorkflowState;
|
|
176
|
+
[key: string]: unknown;
|
|
177
|
+
}
|
|
178
|
+
export declare function loadConfig(projectRoot: string): Promise<ProjectConfig>;
|
|
179
|
+
export declare function saveConfig(projectRoot: string, cfg: ProjectConfig): Promise<void>;
|
|
180
|
+
export declare function readWorkflow(projectRoot: string): Promise<WorkflowState>;
|
|
181
|
+
export declare function writeWorkflow(projectRoot: string, patch: Partial<WorkflowState>): Promise<WorkflowState>;
|
|
182
|
+
/** Update a NESTED key under workflow.<group> (clarification,
|
|
183
|
+
* specs, approvals, blocks_progress) without overwriting sibling
|
|
184
|
+
* keys at the same level. */
|
|
185
|
+
export declare function patchWorkflowGroup<K extends keyof WorkflowState>(projectRoot: string, group: K, patch: Partial<NonNullable<WorkflowState[K]>>): Promise<WorkflowState>;
|
|
186
|
+
/** Append to workflow.iterations[]. Idempotent: callers should
|
|
187
|
+
* generate a unique-ish `at` per call so duplicates do not stack. */
|
|
188
|
+
export declare function appendIteration(projectRoot: string, entry: IterationEntry): Promise<WorkflowState>;
|
|
189
|
+
export {};
|
|
190
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/workflow/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yujin Forge -- Product Workflow state.
|
|
3
|
+
*
|
|
4
|
+
* Shared persistence layer for the 18-step methodology defined
|
|
5
|
+
* in docs/PRODUCT_WORKFLOW.md. State lives in the project's
|
|
6
|
+
* yujin.forge.json under `workflow.*` so it survives across
|
|
7
|
+
* sessions + can be inspected + shared via the git repo.
|
|
8
|
+
*
|
|
9
|
+
* Every command in the workflow (yf triage, yf discover, yf
|
|
10
|
+
* clarify, yf spec, yf approve, yf bootstrap, yf block dev, yf
|
|
11
|
+
* deploy, yf manual, yf metrics, yf iterate) reads + writes
|
|
12
|
+
* through this module. The chat tool surface (forge_triage,
|
|
13
|
+
* forge_discover, etc) does the same -- the underlying state
|
|
14
|
+
* is identical regardless of entry point.
|
|
15
|
+
*
|
|
16
|
+
* Schema:
|
|
17
|
+
*
|
|
18
|
+
* workflow: {
|
|
19
|
+
* tier: 'simple' | 'medium' | 'full' | null,
|
|
20
|
+
* tier_reason: string,
|
|
21
|
+
* tier_decided_at: ISO,
|
|
22
|
+
*
|
|
23
|
+
* intent: { ... } // Phase I step 3
|
|
24
|
+
* legacy_audit: { ... } // Phase I step 3.5
|
|
25
|
+
* vault_inventory: { ... } // Phase I step 2 audit
|
|
26
|
+
*
|
|
27
|
+
* clarification: {
|
|
28
|
+
* functional: { done_at, summary, doc_path }, // step 4
|
|
29
|
+
* nfr_quantitative: { done_at, summary, doc_path }, // step 5
|
|
30
|
+
* nfr_structural: { done_at, summary, doc_path }, // step 6
|
|
31
|
+
* nfr_governance: { done_at, summary, doc_path }, // step 7
|
|
32
|
+
* nfr_operational: { done_at, summary, doc_path }, // step 8
|
|
33
|
+
* blocks: { done_at, blocks: [...] }, // step 9
|
|
34
|
+
* },
|
|
35
|
+
*
|
|
36
|
+
* specs: {
|
|
37
|
+
* rfp: { done_at, version, doc_path, sha256 }, // step 10
|
|
38
|
+
* arch: { done_at, version, doc_path, sha256 }, // step 11
|
|
39
|
+
* design: { done_at, version, doc_path, sha256 }, // step 12
|
|
40
|
+
* },
|
|
41
|
+
*
|
|
42
|
+
* approvals: {
|
|
43
|
+
* rfp: { approved_at, version_sha256 }, // step 13
|
|
44
|
+
* arch: { approved_at, version_sha256 }, // step 13
|
|
45
|
+
* design: { approved_at, version_sha256 }, // step 13
|
|
46
|
+
* },
|
|
47
|
+
*
|
|
48
|
+
* bootstrap: { done_at, stack, ci_set }, // step 14
|
|
49
|
+
*
|
|
50
|
+
* blocks_progress: [ // step 15
|
|
51
|
+
* { block_id, status, tests_green_at, deployed_at }
|
|
52
|
+
* ],
|
|
53
|
+
*
|
|
54
|
+
* deploy: { ... } // step 16
|
|
55
|
+
* postlaunch:{ ... } // step 17
|
|
56
|
+
* iterations:[{ at, type, summary }] // step 18
|
|
57
|
+
* }
|
|
58
|
+
*
|
|
59
|
+
* ASCII-only.
|
|
60
|
+
*/
|
|
61
|
+
import { promises as fs } from 'node:fs';
|
|
62
|
+
import path from 'node:path';
|
|
63
|
+
const CONFIG_FILE = 'yujin.forge.json';
|
|
64
|
+
function configPath(projectRoot) {
|
|
65
|
+
return path.join(projectRoot, CONFIG_FILE);
|
|
66
|
+
}
|
|
67
|
+
export async function loadConfig(projectRoot) {
|
|
68
|
+
try {
|
|
69
|
+
const raw = await fs.readFile(configPath(projectRoot), 'utf-8');
|
|
70
|
+
const parsed = JSON.parse(raw);
|
|
71
|
+
if (parsed && typeof parsed === 'object')
|
|
72
|
+
return parsed;
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
if (err.code !== 'ENOENT'
|
|
76
|
+
&& !(err instanceof SyntaxError)) {
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
82
|
+
export async function saveConfig(projectRoot, cfg) {
|
|
83
|
+
const text = JSON.stringify(cfg, null, 2) + '\n';
|
|
84
|
+
await fs.writeFile(configPath(projectRoot), text, 'utf-8');
|
|
85
|
+
}
|
|
86
|
+
export async function readWorkflow(projectRoot) {
|
|
87
|
+
const cfg = await loadConfig(projectRoot);
|
|
88
|
+
return cfg.workflow ?? {};
|
|
89
|
+
}
|
|
90
|
+
export async function writeWorkflow(projectRoot, patch) {
|
|
91
|
+
const cfg = await loadConfig(projectRoot);
|
|
92
|
+
cfg.workflow = { ...(cfg.workflow ?? {}), ...patch };
|
|
93
|
+
await saveConfig(projectRoot, cfg);
|
|
94
|
+
return cfg.workflow;
|
|
95
|
+
}
|
|
96
|
+
/** Update a NESTED key under workflow.<group> (clarification,
|
|
97
|
+
* specs, approvals, blocks_progress) without overwriting sibling
|
|
98
|
+
* keys at the same level. */
|
|
99
|
+
export async function patchWorkflowGroup(projectRoot, group, patch) {
|
|
100
|
+
const cfg = await loadConfig(projectRoot);
|
|
101
|
+
const wf = cfg.workflow ?? {};
|
|
102
|
+
const prev = (wf[group] ?? {});
|
|
103
|
+
const merged = { ...prev, ...patch };
|
|
104
|
+
cfg.workflow = { ...wf, [group]: merged };
|
|
105
|
+
await saveConfig(projectRoot, cfg);
|
|
106
|
+
return cfg.workflow;
|
|
107
|
+
}
|
|
108
|
+
/** Append to workflow.iterations[]. Idempotent: callers should
|
|
109
|
+
* generate a unique-ish `at` per call so duplicates do not stack. */
|
|
110
|
+
export async function appendIteration(projectRoot, entry) {
|
|
111
|
+
const cfg = await loadConfig(projectRoot);
|
|
112
|
+
const wf = cfg.workflow ?? {};
|
|
113
|
+
const list = Array.isArray(wf.iterations) ? wf.iterations : [];
|
|
114
|
+
list.push(entry);
|
|
115
|
+
cfg.workflow = { ...wf, iterations: list };
|
|
116
|
+
await saveConfig(projectRoot, cfg);
|
|
117
|
+
return cfg.workflow;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/workflow/state.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nac3/forge-cli",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.11",
|
|
4
4
|
"description": "Yujin Forge -- voice-first NAC-3 React development framework. CLI + chat panel + spec ingest + 10-format document reader + voice loop.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Pablo Kuschnirof <pablo@rpaforce.com>",
|