up-cc 0.1.2 → 0.1.4
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/agents/up-executor.md +1 -1
- package/agents/up-planejador.md +1 -1
- package/bin/up-tools.cjs +522 -4
- package/commands/depurar.md +163 -0
- package/package.json +1 -1
- package/references/git-integration.md +2 -2
- package/workflows/discutir-fase.md +1 -1
- package/workflows/executar-fase.md +1 -1
- package/workflows/executar-plano.md +1 -1
- package/workflows/novo-projeto.md +1 -1
- package/workflows/planejar-fase.md +1 -1
- package/workflows/progresso.md +1 -1
- package/workflows/rapido.md +1 -1
- package/workflows/retomar.md +1 -1
- package/workflows/verificar-trabalho.md +1 -1
package/agents/up-executor.md
CHANGED
|
@@ -33,7 +33,7 @@ Antes de executar, descubra o contexto do projeto:
|
|
|
33
33
|
Carregue o contexto de execucao:
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init
|
|
36
|
+
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init executar-fase "${PHASE}")
|
|
37
37
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
38
38
|
```
|
|
39
39
|
|
package/agents/up-planejador.md
CHANGED
|
@@ -241,7 +241,7 @@ Se qualquer item falhar, corrija ANTES de retornar. Nao dependa de checker exter
|
|
|
241
241
|
### Passo 1: Carregar Estado do Projeto
|
|
242
242
|
|
|
243
243
|
```bash
|
|
244
|
-
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init
|
|
244
|
+
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init planejar-fase "${PHASE}")
|
|
245
245
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
246
246
|
```
|
|
247
247
|
|
package/bin/up-tools.cjs
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* Usage: node up-tools.cjs <command> [args] [--raw] [--cwd <path>]
|
|
9
9
|
*
|
|
10
10
|
* Commands:
|
|
11
|
-
* init planejar-fase|executar-fase|novo-projeto|rapido|retomar
|
|
12
|
-
* state load|get|update|advance-plan|update-progress|add-decision|record-session
|
|
11
|
+
* init planejar-fase|executar-fase|novo-projeto|rapido|retomar|operacao-fase|progresso|verificar-trabalho
|
|
12
|
+
* state load|get|update|advance-plan|update-progress|add-decision|record-session|record-metric|snapshot
|
|
13
13
|
* roadmap get-phase|analyze|update-plan-progress
|
|
14
14
|
* phase add|remove|find|complete
|
|
15
15
|
* config get|set
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
* progress [json|table|bar]
|
|
19
19
|
* timestamp [full|date|filename]
|
|
20
20
|
* slug <text>
|
|
21
|
+
* phase-plan-index <phase>
|
|
22
|
+
* state-snapshot
|
|
23
|
+
* summary-extract <path> [--fields field1,field2]
|
|
21
24
|
*/
|
|
22
25
|
|
|
23
26
|
const fs = require('fs');
|
|
@@ -29,6 +32,85 @@ const {
|
|
|
29
32
|
pathExistsInternal, generateSlugInternal, toPosixPath,
|
|
30
33
|
} = require('./lib/core.cjs');
|
|
31
34
|
|
|
35
|
+
// --- Frontmatter helpers ---
|
|
36
|
+
|
|
37
|
+
function extractFrontmatter(content) {
|
|
38
|
+
const frontmatter = {};
|
|
39
|
+
const match = content.match(/^---\n([\s\S]+?)\n---/);
|
|
40
|
+
if (!match) return frontmatter;
|
|
41
|
+
|
|
42
|
+
const yaml = match[1];
|
|
43
|
+
const lines = yaml.split('\n');
|
|
44
|
+
let stack = [{ obj: frontmatter, key: null, indent: -1 }];
|
|
45
|
+
|
|
46
|
+
for (const line of lines) {
|
|
47
|
+
if (line.trim() === '') continue;
|
|
48
|
+
const indentMatch = line.match(/^(\s*)/);
|
|
49
|
+
const indent = indentMatch ? indentMatch[1].length : 0;
|
|
50
|
+
while (stack.length > 1 && indent <= stack[stack.length - 1].indent) {
|
|
51
|
+
stack.pop();
|
|
52
|
+
}
|
|
53
|
+
const current = stack[stack.length - 1];
|
|
54
|
+
const keyMatch = line.match(/^(\s*)([a-zA-Z0-9_-]+):\s*(.*)/);
|
|
55
|
+
if (keyMatch) {
|
|
56
|
+
const key = keyMatch[2];
|
|
57
|
+
const value = keyMatch[3].trim();
|
|
58
|
+
if (value === '' || value === '[') {
|
|
59
|
+
current.obj[key] = value === '[' ? [] : {};
|
|
60
|
+
current.key = null;
|
|
61
|
+
stack.push({ obj: current.obj[key], key: null, indent });
|
|
62
|
+
} else if (value.startsWith('[') && value.endsWith(']')) {
|
|
63
|
+
current.obj[key] = value.slice(1, -1).split(',').map(s => s.trim().replace(/^["']|["']$/g, '')).filter(Boolean);
|
|
64
|
+
current.key = null;
|
|
65
|
+
} else {
|
|
66
|
+
current.obj[key] = value.replace(/^["']|["']$/g, '');
|
|
67
|
+
current.key = null;
|
|
68
|
+
}
|
|
69
|
+
} else if (line.trim().startsWith('- ')) {
|
|
70
|
+
const itemValue = line.trim().slice(2).replace(/^["']|["']$/g, '');
|
|
71
|
+
if (typeof current.obj === 'object' && !Array.isArray(current.obj) && Object.keys(current.obj).length === 0) {
|
|
72
|
+
const parent = stack.length > 1 ? stack[stack.length - 2] : null;
|
|
73
|
+
if (parent) {
|
|
74
|
+
for (const k of Object.keys(parent.obj)) {
|
|
75
|
+
if (parent.obj[k] === current.obj) {
|
|
76
|
+
parent.obj[k] = [itemValue];
|
|
77
|
+
current.obj = parent.obj[k];
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
} else if (Array.isArray(current.obj)) {
|
|
83
|
+
current.obj.push(itemValue);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return frontmatter;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function extractObjective(content) {
|
|
91
|
+
const m = content.match(/<objective>\s*\n?\s*(.+)/);
|
|
92
|
+
return m ? m[1].trim() : null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function getMilestoneInfo(cwd) {
|
|
96
|
+
try {
|
|
97
|
+
const roadmap = fs.readFileSync(path.join(cwd, '.plano', 'ROADMAP.md'), 'utf-8');
|
|
98
|
+
const inProgressMatch = roadmap.match(/🚧\s*\*\*v(\d+\.\d+)\s+([^*]+)\*\*/);
|
|
99
|
+
if (inProgressMatch) {
|
|
100
|
+
return { version: 'v' + inProgressMatch[1], name: inProgressMatch[2].trim() };
|
|
101
|
+
}
|
|
102
|
+
const cleaned = roadmap.replace(/<details>[\s\S]*?<\/details>/gi, '');
|
|
103
|
+
const headingMatch = cleaned.match(/## .*v(\d+\.\d+)[:\s]+([^\n(]+)/);
|
|
104
|
+
if (headingMatch) {
|
|
105
|
+
return { version: 'v' + headingMatch[1], name: headingMatch[2].trim() };
|
|
106
|
+
}
|
|
107
|
+
const versionMatch = cleaned.match(/v(\d+\.\d+)/);
|
|
108
|
+
return { version: versionMatch ? 'v' + versionMatch[1] : 'v0.1', name: 'MVP' };
|
|
109
|
+
} catch {
|
|
110
|
+
return { version: 'v0.1', name: 'MVP' };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
32
114
|
// --- State helpers ---
|
|
33
115
|
|
|
34
116
|
function stateExtractField(content, fieldName) {
|
|
@@ -109,8 +191,17 @@ function main() {
|
|
|
109
191
|
case 'retomar':
|
|
110
192
|
cmdInitRetomar(cwd, raw);
|
|
111
193
|
break;
|
|
194
|
+
case 'operacao-fase':
|
|
195
|
+
cmdInitOperacaoFase(cwd, args[2], raw);
|
|
196
|
+
break;
|
|
197
|
+
case 'progresso':
|
|
198
|
+
cmdInitProgresso(cwd, raw);
|
|
199
|
+
break;
|
|
200
|
+
case 'verificar-trabalho':
|
|
201
|
+
cmdInitVerificarTrabalho(cwd, args[2], raw);
|
|
202
|
+
break;
|
|
112
203
|
default:
|
|
113
|
-
error(`Unknown init workflow: ${workflow}\nAvailable: planejar-fase, executar-fase, novo-projeto, rapido, retomar`);
|
|
204
|
+
error(`Unknown init workflow: ${workflow}\nAvailable: planejar-fase, executar-fase, novo-projeto, rapido, retomar, operacao-fase, progresso, verificar-trabalho`);
|
|
114
205
|
}
|
|
115
206
|
break;
|
|
116
207
|
}
|
|
@@ -140,8 +231,23 @@ function main() {
|
|
|
140
231
|
cmdStateRecordSession(cwd, {
|
|
141
232
|
stopped_at: stoppedIdx !== -1 ? args[stoppedIdx + 1] : null,
|
|
142
233
|
}, raw);
|
|
234
|
+
} else if (sub === 'record-metric') {
|
|
235
|
+
const phaseIdx = args.indexOf('--phase');
|
|
236
|
+
const planIdx = args.indexOf('--plan');
|
|
237
|
+
const durationIdx = args.indexOf('--duration');
|
|
238
|
+
const tasksIdx = args.indexOf('--tasks');
|
|
239
|
+
const filesIdx = args.indexOf('--files');
|
|
240
|
+
cmdStateRecordMetric(cwd, {
|
|
241
|
+
phase: phaseIdx !== -1 ? args[phaseIdx + 1] : null,
|
|
242
|
+
plan: planIdx !== -1 ? args[planIdx + 1] : null,
|
|
243
|
+
duration: durationIdx !== -1 ? args[durationIdx + 1] : null,
|
|
244
|
+
tasks: tasksIdx !== -1 ? args[tasksIdx + 1] : null,
|
|
245
|
+
files: filesIdx !== -1 ? args[filesIdx + 1] : null,
|
|
246
|
+
}, raw);
|
|
247
|
+
} else if (sub === 'snapshot') {
|
|
248
|
+
cmdStateSnapshot(cwd, raw);
|
|
143
249
|
} else {
|
|
144
|
-
error('Unknown state subcommand. Available: load, get, update, advance-plan, update-progress, add-decision, record-session');
|
|
250
|
+
error('Unknown state subcommand. Available: load, get, update, advance-plan, update-progress, add-decision, record-session, record-metric, snapshot');
|
|
145
251
|
}
|
|
146
252
|
break;
|
|
147
253
|
}
|
|
@@ -232,6 +338,26 @@ function main() {
|
|
|
232
338
|
break;
|
|
233
339
|
}
|
|
234
340
|
|
|
341
|
+
// ==================== PHASE-PLAN-INDEX ====================
|
|
342
|
+
case 'phase-plan-index': {
|
|
343
|
+
cmdPhasePlanIndex(cwd, args[1], raw);
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// ==================== STATE-SNAPSHOT ====================
|
|
348
|
+
case 'state-snapshot': {
|
|
349
|
+
cmdStateSnapshot(cwd, raw);
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// ==================== SUMMARY-EXTRACT ====================
|
|
354
|
+
case 'summary-extract': {
|
|
355
|
+
const fieldsIdx = args.indexOf('--fields');
|
|
356
|
+
const fields = fieldsIdx !== -1 ? args[fieldsIdx + 1].split(',') : [];
|
|
357
|
+
cmdSummaryExtract(cwd, args[1], fields, raw);
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
|
|
235
361
|
default:
|
|
236
362
|
error(`Unknown command: ${command}`);
|
|
237
363
|
}
|
|
@@ -385,6 +511,174 @@ function cmdInitRetomar(cwd, raw) {
|
|
|
385
511
|
output(result, raw);
|
|
386
512
|
}
|
|
387
513
|
|
|
514
|
+
function cmdInitOperacaoFase(cwd, phase, raw) {
|
|
515
|
+
const config = loadConfig(cwd);
|
|
516
|
+
let phaseInfo = findPhaseInternal(cwd, phase);
|
|
517
|
+
|
|
518
|
+
if (!phaseInfo) {
|
|
519
|
+
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
|
|
520
|
+
if (roadmapPhase?.found) {
|
|
521
|
+
const phaseName = roadmapPhase.phase_name;
|
|
522
|
+
phaseInfo = {
|
|
523
|
+
found: true,
|
|
524
|
+
directory: null,
|
|
525
|
+
phase_number: roadmapPhase.phase_number,
|
|
526
|
+
phase_name: phaseName,
|
|
527
|
+
phase_slug: phaseName ? phaseName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') : null,
|
|
528
|
+
plans: [],
|
|
529
|
+
summaries: [],
|
|
530
|
+
incomplete_plans: [],
|
|
531
|
+
has_research: false,
|
|
532
|
+
has_context: false,
|
|
533
|
+
has_verification: false,
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
const result = {
|
|
539
|
+
commit_docs: config.commit_docs,
|
|
540
|
+
phase_found: !!phaseInfo,
|
|
541
|
+
phase_dir: phaseInfo?.directory || null,
|
|
542
|
+
phase_number: phaseInfo?.phase_number || null,
|
|
543
|
+
phase_name: phaseInfo?.phase_name || null,
|
|
544
|
+
phase_slug: phaseInfo?.phase_slug || null,
|
|
545
|
+
padded_phase: phaseInfo?.phase_number?.padStart(2, '0') || null,
|
|
546
|
+
has_research: phaseInfo?.has_research || false,
|
|
547
|
+
has_context: phaseInfo?.has_context || false,
|
|
548
|
+
has_plans: (phaseInfo?.plans?.length || 0) > 0,
|
|
549
|
+
has_verification: false,
|
|
550
|
+
plan_count: phaseInfo?.plans?.length || 0,
|
|
551
|
+
roadmap_exists: pathExistsInternal(cwd, '.plano/ROADMAP.md'),
|
|
552
|
+
plano_exists: pathExistsInternal(cwd, '.plano'),
|
|
553
|
+
state_path: '.plano/STATE.md',
|
|
554
|
+
roadmap_path: '.plano/ROADMAP.md',
|
|
555
|
+
};
|
|
556
|
+
|
|
557
|
+
if (phaseInfo?.directory) {
|
|
558
|
+
const phaseDirFull = path.join(cwd, phaseInfo.directory);
|
|
559
|
+
try {
|
|
560
|
+
const files = fs.readdirSync(phaseDirFull);
|
|
561
|
+
const contextFile = files.find(f => f.endsWith('-CONTEXT.md') || f === 'CONTEXT.md');
|
|
562
|
+
if (contextFile) result.context_path = toPosixPath(path.join(phaseInfo.directory, contextFile));
|
|
563
|
+
const researchFile = files.find(f => f.endsWith('-RESEARCH.md') || f === 'RESEARCH.md');
|
|
564
|
+
if (researchFile) result.research_path = toPosixPath(path.join(phaseInfo.directory, researchFile));
|
|
565
|
+
const verificationFile = files.find(f => f.endsWith('-VERIFICATION.md') || f === 'VERIFICATION.md');
|
|
566
|
+
if (verificationFile) {
|
|
567
|
+
result.verification_path = toPosixPath(path.join(phaseInfo.directory, verificationFile));
|
|
568
|
+
result.has_verification = true;
|
|
569
|
+
}
|
|
570
|
+
} catch {}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
output(result, raw);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
function cmdInitProgresso(cwd, raw) {
|
|
577
|
+
const config = loadConfig(cwd);
|
|
578
|
+
const milestone = getMilestoneInfo(cwd);
|
|
579
|
+
|
|
580
|
+
const fasesDir = path.join(cwd, '.plano', 'fases');
|
|
581
|
+
const phases = [];
|
|
582
|
+
let currentPhase = null;
|
|
583
|
+
let nextPhase = null;
|
|
584
|
+
|
|
585
|
+
try {
|
|
586
|
+
const entries = fs.readdirSync(fasesDir, { withFileTypes: true });
|
|
587
|
+
const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).sort();
|
|
588
|
+
|
|
589
|
+
for (const dir of dirs) {
|
|
590
|
+
const match = dir.match(/^(\d+(?:\.\d+)*)-?(.*)/);
|
|
591
|
+
const phaseNumber = match ? match[1] : dir;
|
|
592
|
+
const phaseName = match && match[2] ? match[2] : null;
|
|
593
|
+
|
|
594
|
+
const phasePath = path.join(fasesDir, dir);
|
|
595
|
+
const phaseFiles = fs.readdirSync(phasePath);
|
|
596
|
+
|
|
597
|
+
const plans = phaseFiles.filter(f => f.endsWith('-PLAN.md') || f === 'PLAN.md');
|
|
598
|
+
const summaries = phaseFiles.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
|
|
599
|
+
const hasResearch = phaseFiles.some(f => f.endsWith('-RESEARCH.md') || f === 'RESEARCH.md');
|
|
600
|
+
|
|
601
|
+
const status = summaries.length >= plans.length && plans.length > 0 ? 'complete' :
|
|
602
|
+
plans.length > 0 ? 'in_progress' :
|
|
603
|
+
hasResearch ? 'researched' : 'pending';
|
|
604
|
+
|
|
605
|
+
const phaseInfo = {
|
|
606
|
+
number: phaseNumber,
|
|
607
|
+
name: phaseName,
|
|
608
|
+
directory: '.plano/fases/' + dir,
|
|
609
|
+
status,
|
|
610
|
+
plan_count: plans.length,
|
|
611
|
+
summary_count: summaries.length,
|
|
612
|
+
has_research: hasResearch,
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
phases.push(phaseInfo);
|
|
616
|
+
|
|
617
|
+
if (!currentPhase && (status === 'in_progress' || status === 'researched')) {
|
|
618
|
+
currentPhase = phaseInfo;
|
|
619
|
+
}
|
|
620
|
+
if (!nextPhase && status === 'pending') {
|
|
621
|
+
nextPhase = phaseInfo;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
} catch {}
|
|
625
|
+
|
|
626
|
+
let pausedAt = null;
|
|
627
|
+
try {
|
|
628
|
+
const state = fs.readFileSync(path.join(cwd, '.plano', 'STATE.md'), 'utf-8');
|
|
629
|
+
const pauseMatch = state.match(/\*\*Paused At:\*\*\s*(.+)/);
|
|
630
|
+
if (pauseMatch) pausedAt = pauseMatch[1].trim();
|
|
631
|
+
} catch {}
|
|
632
|
+
|
|
633
|
+
const result = {
|
|
634
|
+
commit_docs: config.commit_docs,
|
|
635
|
+
milestone_version: milestone.version,
|
|
636
|
+
milestone_name: milestone.name,
|
|
637
|
+
phases,
|
|
638
|
+
phase_count: phases.length,
|
|
639
|
+
completed_count: phases.filter(p => p.status === 'complete').length,
|
|
640
|
+
in_progress_count: phases.filter(p => p.status === 'in_progress').length,
|
|
641
|
+
current_phase: currentPhase,
|
|
642
|
+
next_phase: nextPhase,
|
|
643
|
+
paused_at: pausedAt,
|
|
644
|
+
has_work_in_progress: !!currentPhase,
|
|
645
|
+
state_exists: pathExistsInternal(cwd, '.plano/STATE.md'),
|
|
646
|
+
roadmap_exists: pathExistsInternal(cwd, '.plano/ROADMAP.md'),
|
|
647
|
+
project_exists: pathExistsInternal(cwd, '.plano/PROJECT.md'),
|
|
648
|
+
state_path: '.plano/STATE.md',
|
|
649
|
+
roadmap_path: '.plano/ROADMAP.md',
|
|
650
|
+
project_path: '.plano/PROJECT.md',
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
output(result, raw);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
function cmdInitVerificarTrabalho(cwd, phase, raw) {
|
|
657
|
+
if (!phase) error('phase required for init verificar-trabalho');
|
|
658
|
+
|
|
659
|
+
const config = loadConfig(cwd);
|
|
660
|
+
const phaseInfo = findPhaseInternal(cwd, phase);
|
|
661
|
+
|
|
662
|
+
let hasVerification = false;
|
|
663
|
+
if (phaseInfo?.directory) {
|
|
664
|
+
try {
|
|
665
|
+
const files = fs.readdirSync(path.join(cwd, phaseInfo.directory));
|
|
666
|
+
hasVerification = files.some(f => f.endsWith('-VERIFICATION.md') || f === 'VERIFICATION.md');
|
|
667
|
+
} catch {}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
const result = {
|
|
671
|
+
commit_docs: config.commit_docs,
|
|
672
|
+
phase_found: !!phaseInfo,
|
|
673
|
+
phase_dir: phaseInfo?.directory || null,
|
|
674
|
+
phase_number: phaseInfo?.phase_number || null,
|
|
675
|
+
phase_name: phaseInfo?.phase_name || null,
|
|
676
|
+
has_verification: hasVerification,
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
output(result, raw);
|
|
680
|
+
}
|
|
681
|
+
|
|
388
682
|
// =====================================================================
|
|
389
683
|
// STATE COMMANDS
|
|
390
684
|
// =====================================================================
|
|
@@ -593,6 +887,108 @@ function cmdStateRecordSession(cwd, options, raw) {
|
|
|
593
887
|
}
|
|
594
888
|
}
|
|
595
889
|
|
|
890
|
+
function cmdStateRecordMetric(cwd, options, raw) {
|
|
891
|
+
const statePath = path.join(cwd, '.plano', 'STATE.md');
|
|
892
|
+
if (!fs.existsSync(statePath)) { output({ error: 'STATE.md not found' }, raw); return; }
|
|
893
|
+
|
|
894
|
+
let content = fs.readFileSync(statePath, 'utf-8');
|
|
895
|
+
const { phase, plan, duration, tasks, files } = options;
|
|
896
|
+
|
|
897
|
+
if (!phase || !plan || !duration) {
|
|
898
|
+
output({ error: 'phase, plan, and duration required' }, raw);
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
const metricsPattern = /(##\s*Performance Metrics[\s\S]*?\n\|[^\n]+\n\|[-|\s]+\n)([\s\S]*?)(?=\n##|\n$|$)/i;
|
|
903
|
+
const metricsMatch = content.match(metricsPattern);
|
|
904
|
+
|
|
905
|
+
if (metricsMatch) {
|
|
906
|
+
let tableBody = metricsMatch[2].trimEnd();
|
|
907
|
+
const newRow = `| Phase ${phase} P${plan} | ${duration} | ${tasks || '-'} tasks | ${files || '-'} files |`;
|
|
908
|
+
|
|
909
|
+
if (tableBody.trim() === '' || tableBody.includes('None yet')) {
|
|
910
|
+
tableBody = newRow;
|
|
911
|
+
} else {
|
|
912
|
+
tableBody = tableBody + '\n' + newRow;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
content = content.replace(metricsPattern, (_match, header) => `${header}${tableBody}\n`);
|
|
916
|
+
fs.writeFileSync(statePath, content, 'utf-8');
|
|
917
|
+
output({ recorded: true, phase, plan, duration }, raw, 'true');
|
|
918
|
+
} else {
|
|
919
|
+
output({ recorded: false, reason: 'Performance Metrics section not found in STATE.md' }, raw, 'false');
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
function cmdStateSnapshot(cwd, raw) {
|
|
924
|
+
const statePath = path.join(cwd, '.plano', 'STATE.md');
|
|
925
|
+
if (!fs.existsSync(statePath)) { output({ error: 'STATE.md not found' }, raw); return; }
|
|
926
|
+
|
|
927
|
+
const content = fs.readFileSync(statePath, 'utf-8');
|
|
928
|
+
|
|
929
|
+
const currentPhase = stateExtractField(content, 'Current Phase');
|
|
930
|
+
const currentPhaseName = stateExtractField(content, 'Current Phase Name');
|
|
931
|
+
const totalPhasesRaw = stateExtractField(content, 'Total Phases');
|
|
932
|
+
const currentPlan = stateExtractField(content, 'Current Plan');
|
|
933
|
+
const totalPlansRaw = stateExtractField(content, 'Total Plans in Phase');
|
|
934
|
+
const status = stateExtractField(content, 'Status');
|
|
935
|
+
const progressRaw = stateExtractField(content, 'Progress');
|
|
936
|
+
const lastActivity = stateExtractField(content, 'Last Activity');
|
|
937
|
+
const pausedAt = stateExtractField(content, 'Paused At');
|
|
938
|
+
|
|
939
|
+
const totalPhases = totalPhasesRaw ? parseInt(totalPhasesRaw, 10) : null;
|
|
940
|
+
const totalPlansInPhase = totalPlansRaw ? parseInt(totalPlansRaw, 10) : null;
|
|
941
|
+
const progressPercent = progressRaw ? parseInt(progressRaw.replace('%', ''), 10) : null;
|
|
942
|
+
|
|
943
|
+
const decisions = [];
|
|
944
|
+
const decisionsMatch = content.match(/##\s*Decisions Made[\s\S]*?\n\|[^\n]+\n\|[-|\s]+\n([\s\S]*?)(?=\n##|\n$|$)/i);
|
|
945
|
+
if (decisionsMatch) {
|
|
946
|
+
const rows = decisionsMatch[1].trim().split('\n').filter(r => r.includes('|'));
|
|
947
|
+
for (const row of rows) {
|
|
948
|
+
const cells = row.split('|').map(c => c.trim()).filter(Boolean);
|
|
949
|
+
if (cells.length >= 3) {
|
|
950
|
+
decisions.push({ phase: cells[0], summary: cells[1], rationale: cells[2] });
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
const blockers = [];
|
|
956
|
+
const blockersMatch = content.match(/##\s*Blockers\s*\n([\s\S]*?)(?=\n##|$)/i);
|
|
957
|
+
if (blockersMatch) {
|
|
958
|
+
const items = blockersMatch[1].match(/^-\s+(.+)$/gm) || [];
|
|
959
|
+
for (const item of items) {
|
|
960
|
+
blockers.push(item.replace(/^-\s+/, '').trim());
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
const session = { last_date: null, stopped_at: null, resume_file: null };
|
|
965
|
+
const sessionMatch = content.match(/##\s*Session\s*\n([\s\S]*?)(?=\n##|$)/i);
|
|
966
|
+
if (sessionMatch) {
|
|
967
|
+
const s = sessionMatch[1];
|
|
968
|
+
const ld = s.match(/\*\*Last Date:\*\*\s*(.+)/i) || s.match(/^Last Date:\s*(.+)/im);
|
|
969
|
+
const sa = s.match(/\*\*Stopped At:\*\*\s*(.+)/i) || s.match(/^Stopped At:\s*(.+)/im);
|
|
970
|
+
const rf = s.match(/\*\*Resume File:\*\*\s*(.+)/i) || s.match(/^Resume File:\s*(.+)/im);
|
|
971
|
+
if (ld) session.last_date = ld[1].trim();
|
|
972
|
+
if (sa) session.stopped_at = sa[1].trim();
|
|
973
|
+
if (rf) session.resume_file = rf[1].trim();
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
output({
|
|
977
|
+
current_phase: currentPhase,
|
|
978
|
+
current_phase_name: currentPhaseName,
|
|
979
|
+
total_phases: totalPhases,
|
|
980
|
+
current_plan: currentPlan,
|
|
981
|
+
total_plans_in_phase: totalPlansInPhase,
|
|
982
|
+
status,
|
|
983
|
+
progress_percent: progressPercent,
|
|
984
|
+
last_activity: lastActivity,
|
|
985
|
+
decisions,
|
|
986
|
+
blockers,
|
|
987
|
+
paused_at: pausedAt,
|
|
988
|
+
session,
|
|
989
|
+
}, raw);
|
|
990
|
+
}
|
|
991
|
+
|
|
596
992
|
// =====================================================================
|
|
597
993
|
// ROADMAP COMMANDS
|
|
598
994
|
// =====================================================================
|
|
@@ -1116,6 +1512,128 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
|
|
|
1116
1512
|
}, raw);
|
|
1117
1513
|
}
|
|
1118
1514
|
|
|
1515
|
+
function cmdPhasePlanIndex(cwd, phase, raw) {
|
|
1516
|
+
if (!phase) error('phase required for phase-plan-index');
|
|
1517
|
+
|
|
1518
|
+
const fasesDir = path.join(cwd, '.plano', 'fases');
|
|
1519
|
+
const normalized = normalizePhaseName(phase);
|
|
1520
|
+
|
|
1521
|
+
let phaseDir = null;
|
|
1522
|
+
try {
|
|
1523
|
+
const entries = fs.readdirSync(fasesDir, { withFileTypes: true });
|
|
1524
|
+
const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).sort((a, b) => comparePhaseNum(a, b));
|
|
1525
|
+
const match = dirs.find(d => d.startsWith(normalized));
|
|
1526
|
+
if (match) phaseDir = path.join(fasesDir, match);
|
|
1527
|
+
} catch {}
|
|
1528
|
+
|
|
1529
|
+
if (!phaseDir) {
|
|
1530
|
+
output({ phase: normalized, error: 'Phase not found', plans: [], waves: {}, incomplete: [], has_checkpoints: false }, raw);
|
|
1531
|
+
return;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
const phaseFiles = fs.readdirSync(phaseDir);
|
|
1535
|
+
const planFiles = phaseFiles.filter(f => f.endsWith('-PLAN.md') || f === 'PLAN.md').sort();
|
|
1536
|
+
const summaryFiles = phaseFiles.filter(f => f.endsWith('-SUMMARY.md') || f === 'SUMMARY.md');
|
|
1537
|
+
|
|
1538
|
+
const completedPlanIds = new Set(
|
|
1539
|
+
summaryFiles.map(s => s.replace('-SUMMARY.md', '').replace('SUMMARY.md', ''))
|
|
1540
|
+
);
|
|
1541
|
+
|
|
1542
|
+
const plans = [];
|
|
1543
|
+
const waves = {};
|
|
1544
|
+
const incomplete = [];
|
|
1545
|
+
let hasCheckpoints = false;
|
|
1546
|
+
|
|
1547
|
+
for (const planFile of planFiles) {
|
|
1548
|
+
const planId = planFile.replace('-PLAN.md', '').replace('PLAN.md', '');
|
|
1549
|
+
const planPath = path.join(phaseDir, planFile);
|
|
1550
|
+
const content = fs.readFileSync(planPath, 'utf-8');
|
|
1551
|
+
const fm = extractFrontmatter(content);
|
|
1552
|
+
|
|
1553
|
+
const xmlTasks = content.match(/<task[\s>]/gi) || [];
|
|
1554
|
+
const mdTasks = content.match(/##\s*Task\s*\d+/gi) || [];
|
|
1555
|
+
const taskCount = xmlTasks.length || mdTasks.length;
|
|
1556
|
+
|
|
1557
|
+
const wave = parseInt(fm.wave, 10) || 1;
|
|
1558
|
+
|
|
1559
|
+
let autonomous = true;
|
|
1560
|
+
if (fm.autonomous !== undefined) {
|
|
1561
|
+
autonomous = fm.autonomous === 'true' || fm.autonomous === true;
|
|
1562
|
+
}
|
|
1563
|
+
if (!autonomous) hasCheckpoints = true;
|
|
1564
|
+
|
|
1565
|
+
let filesModified = [];
|
|
1566
|
+
const fmFiles = fm['files_modified'] || fm['files-modified'];
|
|
1567
|
+
if (fmFiles) {
|
|
1568
|
+
filesModified = Array.isArray(fmFiles) ? fmFiles : [fmFiles];
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
const hasSummary = completedPlanIds.has(planId);
|
|
1572
|
+
if (!hasSummary) incomplete.push(planId);
|
|
1573
|
+
|
|
1574
|
+
plans.push({
|
|
1575
|
+
id: planId,
|
|
1576
|
+
wave,
|
|
1577
|
+
autonomous,
|
|
1578
|
+
objective: extractObjective(content) || fm.objective || null,
|
|
1579
|
+
files_modified: filesModified,
|
|
1580
|
+
task_count: taskCount,
|
|
1581
|
+
has_summary: hasSummary,
|
|
1582
|
+
});
|
|
1583
|
+
|
|
1584
|
+
const waveKey = String(wave);
|
|
1585
|
+
if (!waves[waveKey]) waves[waveKey] = [];
|
|
1586
|
+
waves[waveKey].push(planId);
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
output({ phase: normalized, plans, waves, incomplete, has_checkpoints: hasCheckpoints }, raw);
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
function cmdSummaryExtract(cwd, summaryPath, fields, raw) {
|
|
1593
|
+
if (!summaryPath) error('summary-path required for summary-extract');
|
|
1594
|
+
|
|
1595
|
+
const fullPath = path.join(cwd, summaryPath);
|
|
1596
|
+
if (!fs.existsSync(fullPath)) {
|
|
1597
|
+
output({ error: 'File not found', path: summaryPath }, raw);
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
1602
|
+
const fm = extractFrontmatter(content);
|
|
1603
|
+
|
|
1604
|
+
const parseDecisions = (decisionsList) => {
|
|
1605
|
+
if (!decisionsList || !Array.isArray(decisionsList)) return [];
|
|
1606
|
+
return decisionsList.map(d => {
|
|
1607
|
+
const colonIdx = d.indexOf(':');
|
|
1608
|
+
if (colonIdx > 0) {
|
|
1609
|
+
return { summary: d.substring(0, colonIdx).trim(), rationale: d.substring(colonIdx + 1).trim() };
|
|
1610
|
+
}
|
|
1611
|
+
return { summary: d, rationale: null };
|
|
1612
|
+
});
|
|
1613
|
+
};
|
|
1614
|
+
|
|
1615
|
+
const fullResult = {
|
|
1616
|
+
path: summaryPath,
|
|
1617
|
+
one_liner: fm['one-liner'] || null,
|
|
1618
|
+
key_files: fm['key-files'] || [],
|
|
1619
|
+
tech_added: (fm['tech-stack'] && fm['tech-stack'].added) || [],
|
|
1620
|
+
patterns: fm['patterns-established'] || [],
|
|
1621
|
+
decisions: parseDecisions(fm['key-decisions']),
|
|
1622
|
+
requirements_completed: fm['requirements-completed'] || [],
|
|
1623
|
+
};
|
|
1624
|
+
|
|
1625
|
+
if (fields && fields.length > 0) {
|
|
1626
|
+
const filtered = { path: summaryPath };
|
|
1627
|
+
for (const field of fields) {
|
|
1628
|
+
if (fullResult[field] !== undefined) filtered[field] = fullResult[field];
|
|
1629
|
+
}
|
|
1630
|
+
output(filtered, raw);
|
|
1631
|
+
return;
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1634
|
+
output(fullResult, raw);
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1119
1637
|
// =====================================================================
|
|
1120
1638
|
// CONFIG COMMANDS
|
|
1121
1639
|
// =====================================================================
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: up:depurar
|
|
3
|
+
description: Depuracao sistematica com estado persistente entre resets de contexto
|
|
4
|
+
argument-hint: [descricao do problema]
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Bash
|
|
8
|
+
- Task
|
|
9
|
+
- AskUserQuestion
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<objective>
|
|
13
|
+
Depurar problemas usando metodo cientifico com isolamento em subagente.
|
|
14
|
+
|
|
15
|
+
**Papel do orquestrador:** Coletar sintomas, spawnar agente up-depurador, lidar com checkpoints, spawnar continuacoes.
|
|
16
|
+
|
|
17
|
+
**Por que subagente:** Investigacao consome contexto rapidamente (lendo arquivos, formando hipoteses, testando). Contexto fresco de 200k por investigacao. Contexto principal permanece enxuto para interacao com usuario.
|
|
18
|
+
</objective>
|
|
19
|
+
|
|
20
|
+
<context>
|
|
21
|
+
Problema do usuario: $ARGUMENTS
|
|
22
|
+
|
|
23
|
+
Verificar sessoes ativas:
|
|
24
|
+
```bash
|
|
25
|
+
ls .plano/debug/*.md 2>/dev/null | grep -v resolved | head -5
|
|
26
|
+
```
|
|
27
|
+
</context>
|
|
28
|
+
|
|
29
|
+
<process>
|
|
30
|
+
|
|
31
|
+
## 0. Inicializar Contexto
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" state load)
|
|
35
|
+
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Extrair `commit_docs` do JSON de init.
|
|
39
|
+
|
|
40
|
+
## 1. Verificar Sessoes Ativas
|
|
41
|
+
|
|
42
|
+
Se sessoes ativas existem E sem $ARGUMENTS:
|
|
43
|
+
- Listar sessoes com status, hipotese, proxima acao
|
|
44
|
+
- Usuario escolhe numero para retomar OU descreve novo problema
|
|
45
|
+
|
|
46
|
+
Se $ARGUMENTS fornecido OU usuario descreve novo problema:
|
|
47
|
+
- Continuar para coleta de sintomas
|
|
48
|
+
|
|
49
|
+
## 2. Coletar Sintomas (se novo problema)
|
|
50
|
+
|
|
51
|
+
Usar AskUserQuestion para cada:
|
|
52
|
+
|
|
53
|
+
1. **Comportamento esperado** - O que deveria acontecer?
|
|
54
|
+
2. **Comportamento real** - O que acontece de fato?
|
|
55
|
+
3. **Mensagens de erro** - Algum erro? (colar ou descrever)
|
|
56
|
+
4. **Timeline** - Quando comecou? Ja funcionou antes?
|
|
57
|
+
5. **Reproducao** - Como reproduzir?
|
|
58
|
+
|
|
59
|
+
Apos coletar tudo, confirmar pronto para investigar.
|
|
60
|
+
|
|
61
|
+
## 3. Spawnar Agente up-depurador
|
|
62
|
+
|
|
63
|
+
Preencher prompt e spawnar:
|
|
64
|
+
|
|
65
|
+
```markdown
|
|
66
|
+
<objective>
|
|
67
|
+
Investigar problema: {slug}
|
|
68
|
+
|
|
69
|
+
**Resumo:** {trigger}
|
|
70
|
+
</objective>
|
|
71
|
+
|
|
72
|
+
<symptoms>
|
|
73
|
+
expected: {expected}
|
|
74
|
+
actual: {actual}
|
|
75
|
+
errors: {errors}
|
|
76
|
+
reproduction: {reproduction}
|
|
77
|
+
timeline: {timeline}
|
|
78
|
+
</symptoms>
|
|
79
|
+
|
|
80
|
+
<mode>
|
|
81
|
+
symptoms_prefilled: true
|
|
82
|
+
goal: find_and_fix
|
|
83
|
+
</mode>
|
|
84
|
+
|
|
85
|
+
<debug_file>
|
|
86
|
+
Criar: .plano/debug/{slug}.md
|
|
87
|
+
</debug_file>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
Agent(
|
|
92
|
+
prompt=filled_prompt,
|
|
93
|
+
subagent_type="up-depurador",
|
|
94
|
+
description="Depurar {slug}"
|
|
95
|
+
)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 4. Lidar com Retorno do Agente
|
|
99
|
+
|
|
100
|
+
**Se `## ROOT CAUSE FOUND`:**
|
|
101
|
+
- Exibir causa raiz e resumo de evidencias
|
|
102
|
+
- Oferecer opcoes:
|
|
103
|
+
- "Corrigir agora" - spawnar subagente de correcao
|
|
104
|
+
- "Planejar correcao" - sugerir /up:planejar-fase
|
|
105
|
+
- "Correcao manual" - encerrar
|
|
106
|
+
|
|
107
|
+
**Se `## CHECKPOINT REACHED`:**
|
|
108
|
+
- Apresentar detalhes do checkpoint ao usuario
|
|
109
|
+
- Obter resposta do usuario
|
|
110
|
+
- Se tipo `human-verify`:
|
|
111
|
+
- Se usuario confirma corrigido: continuar para agente finalizar/resolver/arquivar
|
|
112
|
+
- Se usuario reporta problemas: continuar para agente retomar investigacao/correcao
|
|
113
|
+
- Spawnar agente de continuacao (ver passo 5)
|
|
114
|
+
|
|
115
|
+
**Se `## INVESTIGATION INCONCLUSIVE`:**
|
|
116
|
+
- Mostrar o que foi verificado e eliminado
|
|
117
|
+
- Oferecer opcoes:
|
|
118
|
+
- "Continuar investigando" - spawnar novo agente com contexto adicional
|
|
119
|
+
- "Investigacao manual" - encerrar
|
|
120
|
+
- "Adicionar mais contexto" - coletar mais sintomas, spawnar novamente
|
|
121
|
+
|
|
122
|
+
## 5. Spawnar Agente de Continuacao (Apos Checkpoint)
|
|
123
|
+
|
|
124
|
+
Quando usuario responde ao checkpoint, spawnar agente fresco:
|
|
125
|
+
|
|
126
|
+
```markdown
|
|
127
|
+
<objective>
|
|
128
|
+
Continuar depuracao {slug}. Evidencias estao no arquivo de debug.
|
|
129
|
+
</objective>
|
|
130
|
+
|
|
131
|
+
<prior_state>
|
|
132
|
+
<files_to_read>
|
|
133
|
+
- .plano/debug/{slug}.md (Estado da sessao de debug)
|
|
134
|
+
</files_to_read>
|
|
135
|
+
</prior_state>
|
|
136
|
+
|
|
137
|
+
<checkpoint_response>
|
|
138
|
+
**Type:** {checkpoint_type}
|
|
139
|
+
**Response:** {user_response}
|
|
140
|
+
</checkpoint_response>
|
|
141
|
+
|
|
142
|
+
<mode>
|
|
143
|
+
goal: find_and_fix
|
|
144
|
+
</mode>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
Agent(
|
|
149
|
+
prompt=continuation_prompt,
|
|
150
|
+
subagent_type="up-depurador",
|
|
151
|
+
description="Continuar depuracao {slug}"
|
|
152
|
+
)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
</process>
|
|
156
|
+
|
|
157
|
+
<success_criteria>
|
|
158
|
+
- [ ] Sessoes ativas verificadas
|
|
159
|
+
- [ ] Sintomas coletados (se novo)
|
|
160
|
+
- [ ] up-depurador spawnado com contexto
|
|
161
|
+
- [ ] Checkpoints tratados corretamente
|
|
162
|
+
- [ ] Causa raiz confirmada antes de corrigir
|
|
163
|
+
</success_criteria>
|
package/package.json
CHANGED
|
@@ -122,13 +122,13 @@ Tasks completed: [N]/[N]
|
|
|
122
122
|
- [Task 2 name]
|
|
123
123
|
- [Task 3 name]
|
|
124
124
|
|
|
125
|
-
SUMMARY: .plano/
|
|
125
|
+
SUMMARY: .plano/fases/XX-name/{phase}-{plan}-SUMMARY.md
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
What to commit:
|
|
129
129
|
|
|
130
130
|
```bash
|
|
131
|
-
node "$HOME/.claude/up/bin/up-tools.cjs" commit "docs({phase}-{plan}): complete [plan-name] plan" --files .plano/
|
|
131
|
+
node "$HOME/.claude/up/bin/up-tools.cjs" commit "docs({phase}-{plan}): complete [plan-name] plan" --files .plano/fases/XX-name/{phase}-{plan}-PLAN.md .plano/fases/XX-name/{phase}-{plan}-SUMMARY.md .plano/STATE.md .plano/ROADMAP.md
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
**Note:** Code files NOT included - already committed per-task.
|
|
@@ -34,7 +34,7 @@ Capturar a ideia em secao "Ideias Adiadas". Nao perca, nao atue sobre ela.
|
|
|
34
34
|
Numero da fase do argumento (obrigatorio).
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init
|
|
37
|
+
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init operacao-fase "${PHASE}")
|
|
38
38
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
39
39
|
```
|
|
40
40
|
|
|
@@ -12,7 +12,7 @@ Orquestrador coordena, nao executa. Cada subagente carrega o contexto completo d
|
|
|
12
12
|
Carregar contexto:
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init
|
|
15
|
+
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init executar-fase "${PHASE_ARG}")
|
|
16
16
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
17
17
|
```
|
|
18
18
|
|
|
@@ -13,7 +13,7 @@ Ler config.json para configuracoes de comportamento de planejamento.
|
|
|
13
13
|
Carregar contexto de execucao:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init
|
|
16
|
+
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init executar-fase "${PHASE}")
|
|
17
17
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
18
18
|
```
|
|
19
19
|
|
|
@@ -9,7 +9,7 @@ Inicializar um novo projeto: questionamento, pesquisa (opcional), requisitos, ro
|
|
|
9
9
|
**PRIMEIRO PASSO OBRIGATORIO -- Execute antes de qualquer interacao:**
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init
|
|
12
|
+
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init novo-projeto)
|
|
13
13
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
14
14
|
```
|
|
15
15
|
|
|
@@ -9,7 +9,7 @@ Flags: --pesquisar (pesquisa profunda), --sem-pesquisa (pular), --auto (encadear
|
|
|
9
9
|
## 1. Inicializar
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init
|
|
12
|
+
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init planejar-fase "$PHASE")
|
|
13
13
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
14
14
|
```
|
|
15
15
|
|
package/workflows/progresso.md
CHANGED
|
@@ -8,7 +8,7 @@ Verificar progresso do projeto, resumir trabalho recente e o que vem a seguir, e
|
|
|
8
8
|
**Carregar contexto de progresso:**
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init
|
|
11
|
+
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init progresso)
|
|
12
12
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
13
13
|
```
|
|
14
14
|
|
package/workflows/rapido.md
CHANGED
|
@@ -34,7 +34,7 @@ Exibir banner:
|
|
|
34
34
|
**Passo 2: Inicializar**
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init
|
|
37
|
+
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init rapido "$DESCRIPTION")
|
|
38
38
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
39
39
|
```
|
|
40
40
|
|
package/workflows/retomar.md
CHANGED
|
@@ -16,7 +16,7 @@ Restaurar instantaneamente contexto completo do projeto para que "Onde paramos?"
|
|
|
16
16
|
Carregar contexto:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init
|
|
19
|
+
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init retomar)
|
|
20
20
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
21
21
|
```
|
|
22
22
|
|
|
@@ -18,7 +18,7 @@ Claude apresenta o que DEVERIA acontecer. Usuario confirma ou descreve o que est
|
|
|
18
18
|
Se $ARGUMENTS contem numero de fase, carregar contexto:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init
|
|
21
|
+
INIT=$(node "$HOME/.claude/up/bin/up-tools.cjs" init verificar-trabalho "${PHASE_ARG}")
|
|
22
22
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
23
23
|
```
|
|
24
24
|
|