@hanzlaa/rcode 4.9.1 → 4.10.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzlaa/rcode",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.10.0",
|
|
4
4
|
"description": "rcode — the AI team that never forgets. Persistent memory, specialist agents, and slash commands for AI IDEs. Works in Claude Code, Cursor, Gemini, VS Code, and Antigravity.",
|
|
5
5
|
"main": "cli/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -332,18 +332,37 @@ export function TaskCard({ task: t }) {
|
|
|
332
332
|
const done = t.status === 'done' || t.status === 'completed';
|
|
333
333
|
const running = isSessionRunning(t.id);
|
|
334
334
|
|
|
335
|
-
// Build cmd hints for this task
|
|
335
|
+
// Build cmd hints for this task. rcode has two separate tracking pipelines
|
|
336
|
+
// that both use "sprint" terminology: phase -> SPRINT.md plan -> task
|
|
337
|
+
// (t.phaseId set; this is the real, execution-backed pipeline) vs.
|
|
338
|
+
// epic -> story (no t.phaseId; dev-story/create-story/verify-work). Using
|
|
339
|
+
// dev-story/create-story commands against a phase-pipeline task id (e.g.
|
|
340
|
+
// "1.1.2") doesn't parse — those commands only accept 2-part epic.story
|
|
341
|
+
// ids. Branch on t.phaseId so the hints (and the RunBtn below) actually
|
|
342
|
+
// resolve to a real command for whichever pipeline this task is from.
|
|
343
|
+
const isPhaseTask = !!t.phaseId;
|
|
344
|
+
const runCmd = isPhaseTask ? '/rcode-execute ' + t.phaseId : '/rcode-dev-story ' + t.id;
|
|
336
345
|
const taskCmds = [];
|
|
337
346
|
if (t.id) {
|
|
338
|
-
if (
|
|
339
|
-
|
|
340
|
-
|
|
347
|
+
if (isPhaseTask) {
|
|
348
|
+
if (!done) {
|
|
349
|
+
taskCmds.push(['/rcode-execute ' + t.phaseId, 'Execute phase ' + t.phaseId]);
|
|
350
|
+
} else {
|
|
351
|
+
taskCmds.push(['/rcode-verify-phase ' + t.phaseId, 'Verify phase ' + t.phaseId]);
|
|
352
|
+
taskCmds.push(['/rcode-review --phase ' + t.phaseId + ' --all', 'Review code for this phase']);
|
|
353
|
+
}
|
|
354
|
+
taskCmds.push(['/rcode-progress', 'Overall project status']);
|
|
341
355
|
} else {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
356
|
+
if (!done) {
|
|
357
|
+
taskCmds.push(['/rcode-dev-story ' + t.id, 'Implement this story']);
|
|
358
|
+
taskCmds.push(['/rcode-create-story ' + (t.sprintId || ''), 'Add related story']);
|
|
359
|
+
} else {
|
|
360
|
+
taskCmds.push(['/rcode-verify-work ' + t.id, 'Verify this story']);
|
|
361
|
+
taskCmds.push(['/rcode-review ' + t.id, 'Review code for this story']);
|
|
362
|
+
}
|
|
363
|
+
if (t.sprintId) {
|
|
364
|
+
taskCmds.push(['/rcode-sprint-status ' + t.sprintId, 'Sprint ' + t.sprintId + ' status']);
|
|
365
|
+
}
|
|
347
366
|
}
|
|
348
367
|
}
|
|
349
368
|
|
|
@@ -357,7 +376,7 @@ export function TaskCard({ task: t }) {
|
|
|
357
376
|
aria-expanded=${expanded}
|
|
358
377
|
...${pressable(() => setExpanded(e => !e))}>
|
|
359
378
|
<div class="item-title" style=${done ? 'text-decoration:line-through' : ''}>
|
|
360
|
-
${t.id && !done ? html`<${RunBtn} storyId=${t.id} cmd=${'
|
|
379
|
+
${t.id && !done ? html`<${RunBtn} storyId=${t.id} cmd=${runCmd} label=${isPhaseTask ? 'Phase ' + t.phaseId : 'Story ' + t.id}/>` : null}
|
|
361
380
|
${t.file ? html`
|
|
362
381
|
<button class="card-file-btn" title=${'View ' + t.file} onClick=${handleViewFile}>
|
|
363
382
|
<${Icon} name="file-text" size=${11}/> File
|
package/server/lib/scanner.js
CHANGED
|
@@ -195,7 +195,7 @@ function buildPhaseTree(projectDir, rawPhases, listCached, overrides) {
|
|
|
195
195
|
// Status: a *-SUMMARY.md sibling means the sprint shipped.
|
|
196
196
|
const hasSummary = files.includes(f.replace(/-SPRINT\.md$/i, '-SUMMARY.md'));
|
|
197
197
|
const status = hasSummary ? 'complete'
|
|
198
|
-
: (p.status === 'active'
|
|
198
|
+
: toState(p.status) === 'active' ? 'in_progress'
|
|
199
199
|
: 'planned';
|
|
200
200
|
|
|
201
201
|
// Project-relative path to this sprint's SPRINT.md — same shape as the
|
|
@@ -383,7 +383,7 @@ function buildDashboard(state) {
|
|
|
383
383
|
date: fmtISODate(p.completed || s.completed_at || p.created),
|
|
384
384
|
file: s.file || null,
|
|
385
385
|
});
|
|
386
|
-
} else if (p.
|
|
386
|
+
} else if (toState(p.status) === 'active') {
|
|
387
387
|
// No per-task progress tracking exists — pct stays null and the UI
|
|
388
388
|
// omits the percent pill rather than inventing a number.
|
|
389
389
|
inProgressTasks.push({ title: st.title || st.id, pct: null, file: s.file || null });
|
|
@@ -393,10 +393,10 @@ function buildDashboard(state) {
|
|
|
393
393
|
}
|
|
394
394
|
// Fallbacks so the cards are never empty when stories are unregistered in state.json.
|
|
395
395
|
if (!completedTasks.length) {
|
|
396
|
-
phases.filter(p => p.
|
|
396
|
+
phases.filter(p => toState(p.status) === 'done').slice(-6).forEach(p =>
|
|
397
397
|
completedTasks.push({ title: p.name, date: fmtISODate(p.completed || p.created), file: null }));
|
|
398
398
|
}
|
|
399
|
-
if (!inProgressTasks.length && activePhase && activePhase.
|
|
399
|
+
if (!inProgressTasks.length && activePhase && toState(activePhase.status) === 'active') {
|
|
400
400
|
inProgressTasks.push({ title: activePhase.name, pct: null, file: null });
|
|
401
401
|
}
|
|
402
402
|
const tasks = {
|