specsmd 0.1.41 → 0.1.42

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.
@@ -1137,6 +1137,58 @@ function getNoCurrentMessage(flow) {
1137
1137
  return 'No active run';
1138
1138
  }
1139
1139
 
1140
+ function buildFireCurrentRunGroups(snapshot) {
1141
+ const run = getCurrentRun(snapshot);
1142
+ if (!run) {
1143
+ return [];
1144
+ }
1145
+
1146
+ const workItems = Array.isArray(run.workItems) ? run.workItems : [];
1147
+ const completed = workItems.filter((item) => item.status === 'completed').length;
1148
+ const currentWorkItem = workItems.find((item) => item.id === run.currentItem)
1149
+ || workItems.find((item) => item.status === 'in_progress')
1150
+ || workItems[0]
1151
+ || null;
1152
+
1153
+ const currentPhase = getCurrentPhaseLabel(run, currentWorkItem);
1154
+ const phaseTrack = buildPhaseTrack(currentPhase);
1155
+ const mode = String(currentWorkItem?.mode || 'confirm').toUpperCase();
1156
+ const status = currentWorkItem?.status || 'pending';
1157
+ const statusTag = status === 'in_progress' ? 'current' : status;
1158
+
1159
+ const currentWorkItemFiles = currentWorkItem?.filePath
1160
+ ? [{
1161
+ label: `${currentWorkItem.id || 'work-item'} [${mode}] [${statusTag}] ${phaseTrack}`,
1162
+ path: currentWorkItem.filePath,
1163
+ scope: 'active'
1164
+ }]
1165
+ : [];
1166
+
1167
+ const currentRunFiles = collectFireRunFiles(run).map((fileEntry) => ({
1168
+ ...fileEntry,
1169
+ label: path.basename(fileEntry.path || fileEntry.label || ''),
1170
+ scope: 'active'
1171
+ }));
1172
+
1173
+ return [
1174
+ {
1175
+ key: `current:run:${run.id}:summary`,
1176
+ label: `${run.id} [${run.scope}] ${completed}/${workItems.length} items`,
1177
+ files: []
1178
+ },
1179
+ {
1180
+ key: `current:run:${run.id}:work-items`,
1181
+ label: 'WORK ITEMS',
1182
+ files: filterExistingFiles(currentWorkItemFiles)
1183
+ },
1184
+ {
1185
+ key: `current:run:${run.id}:run-files`,
1186
+ label: 'RUN FILES',
1187
+ files: filterExistingFiles(currentRunFiles)
1188
+ }
1189
+ ];
1190
+ }
1191
+
1140
1192
  function buildCurrentGroups(snapshot, flow) {
1141
1193
  const effectiveFlow = getEffectiveFlow(flow, snapshot);
1142
1194
 
@@ -1169,17 +1221,7 @@ function buildCurrentGroups(snapshot, flow) {
1169
1221
  }];
1170
1222
  }
1171
1223
 
1172
- const run = getCurrentRun(snapshot);
1173
- if (!run) {
1174
- return [];
1175
- }
1176
- const workItems = Array.isArray(run.workItems) ? run.workItems : [];
1177
- const completed = workItems.filter((item) => item.status === 'completed').length;
1178
- return [{
1179
- key: `current:run:${run.id}`,
1180
- label: `${run.id} [${run.scope}] ${completed}/${workItems.length} items`,
1181
- files: filterExistingFiles(collectFireRunFiles(run).map((file) => ({ ...file, scope: 'active' })))
1182
- }];
1224
+ return buildFireCurrentRunGroups(snapshot);
1183
1225
  }
1184
1226
 
1185
1227
  function buildRunFileGroups(fileEntries) {
@@ -1375,26 +1417,41 @@ function buildOverviewIntentGroups(snapshot, flow, filter = 'next') {
1375
1417
  });
1376
1418
  }
1377
1419
 
1378
- function buildStandardsGroups(snapshot, flow) {
1420
+ function buildStandardsRows(snapshot, flow) {
1379
1421
  const effectiveFlow = getEffectiveFlow(flow, snapshot);
1380
1422
  if (effectiveFlow === 'simple') {
1381
- return [];
1423
+ return [{
1424
+ kind: 'info',
1425
+ key: 'standards:empty:simple',
1426
+ label: 'No standards for SIMPLE flow',
1427
+ selectable: false
1428
+ }];
1382
1429
  }
1383
1430
 
1384
1431
  const standards = Array.isArray(snapshot?.standards) ? snapshot.standards : [];
1385
- return standards.map((standard, index) => {
1386
- const id = standard?.type || standard?.name || String(index);
1387
- const name = `${standard?.name || standard?.type || 'standard'}.md`;
1388
- return {
1389
- key: `standards:${id}`,
1390
- label: name,
1391
- files: filterExistingFiles([{
1392
- label: name,
1393
- path: standard?.filePath,
1394
- scope: 'file'
1395
- }])
1396
- };
1397
- });
1432
+ const files = filterExistingFiles(standards.map((standard, index) => ({
1433
+ label: `${standard?.name || standard?.type || `standard-${index}`}.md`,
1434
+ path: standard?.filePath,
1435
+ scope: 'file'
1436
+ })));
1437
+
1438
+ if (files.length === 0) {
1439
+ return [{
1440
+ kind: 'info',
1441
+ key: 'standards:empty',
1442
+ label: 'No standards found',
1443
+ selectable: false
1444
+ }];
1445
+ }
1446
+
1447
+ return files.map((file, index) => ({
1448
+ kind: 'file',
1449
+ key: `standards:file:${file.path}:${index}`,
1450
+ label: file.label,
1451
+ path: file.path,
1452
+ scope: 'file',
1453
+ selectable: true
1454
+ }));
1398
1455
  }
1399
1456
 
1400
1457
  function buildProjectGroups(snapshot, flow) {
@@ -2281,11 +2338,7 @@ function createDashboardApp(deps) {
2281
2338
  )
2282
2339
  : toLoadingRows('Loading completed items...', 'completed-loading');
2283
2340
  const standardsRows = shouldHydrateSecondaryTabs
2284
- ? toExpandableRows(
2285
- buildStandardsGroups(snapshot, activeFlow),
2286
- effectiveFlow === 'simple' ? 'No standards for SIMPLE flow' : 'No standards found',
2287
- expandedGroups
2288
- )
2341
+ ? buildStandardsRows(snapshot, activeFlow)
2289
2342
  : toLoadingRows('Loading standards...', 'standards-loading');
2290
2343
  const statsRows = shouldHydrateSecondaryTabs
2291
2344
  ? toInfoRows(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specsmd",
3
- "version": "0.1.41",
3
+ "version": "0.1.42",
4
4
  "description": "Multi-agent orchestration system for AI-native software development. Delivers AI-DLC, Agile, and custom SDLC flows as markdown-based agent systems.",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {