@yemi33/minions 0.1.881 → 0.1.883

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/CHANGELOG.md CHANGED
@@ -1,11 +1,12 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.881 (2026-04-11)
3
+ ## 0.1.883 (2026-04-11)
4
4
 
5
5
  ### Features
6
6
  - add 13 missing CC action types for full dashboard parity
7
7
 
8
8
  ### Fixes
9
+ - regenerate-plan now dispatches diff-aware plan-to-prd agent
9
10
  - suppress false [steering-failed] banner when agent responded (closes #894) (#896)
10
11
  - delete .backup sidecar when archiving PRD
11
12
  - CC action bugs + security guard on generic fallback
@@ -13,6 +14,7 @@
13
14
  - include started_at in done/error agent status so duration renders
14
15
 
15
16
  ### Other
17
+ - simplify: fix CC regenerate-plan field name, remove dead revise-and-regenerate handler
16
18
  - remove doc-chat plan auto-pause in favour of stale banner only
17
19
  - simplify: CC actions cleanup — missing wakeEngine, redundant refresh, hardened fallback
18
20
 
@@ -1072,8 +1072,8 @@ async function ccExecuteAction(action, targetTabId) {
1072
1072
  break;
1073
1073
  }
1074
1074
  case 'regenerate-plan': {
1075
- await _ccFetch('/api/plans/regenerate', { file: action.file });
1076
- status.innerHTML = '&#10003; Plan regenerated: <strong>' + escHtml(action.file) + '</strong>';
1075
+ await _ccFetch('/api/plans/approve', { file: action.file, forceRegen: true });
1076
+ status.innerHTML = '&#10003; PRD regeneration queued: <strong>' + escHtml(action.file) + '</strong>';
1077
1077
  status.style.color = 'var(--green)';
1078
1078
  wakeEngine();
1079
1079
  break;
package/dashboard.js CHANGED
@@ -2292,7 +2292,7 @@ If nothing to do: { "duplicates": [], "reclassify": [], "remove": [] }`;
2292
2292
  // Diff-aware PRD update: if plan was stale (source .md revised), dispatch plan-to-prd
2293
2293
  // to compare the revised plan against existing PRD and produce an updated version
2294
2294
  let diffAwareQueued = false;
2295
- if (plan.source_plan && plan.missing_features && wasStale && !body.skipRegen) {
2295
+ if (plan.source_plan && plan.missing_features && (wasStale || body.forceRegen) && !body.skipRegen) {
2296
2296
  const config = queries.getConfig();
2297
2297
  const allWorkItems = queries.getWorkItems(config);
2298
2298
  const planWis = allWorkItems.filter(w => w.sourcePlan === body.file && w.itemType !== 'pr' && w.itemType !== 'verify');
@@ -2697,146 +2697,6 @@ If nothing to do: { "duplicates": [], "reclassify": [], "remove": [] }`;
2697
2697
 
2698
2698
  // POST /api/plans/revise-and-regenerate — REMOVED: plan versioning now handled by /api/doc-chat
2699
2699
  // The "Replace old PRD" flow uses qaReplacePrd (frontend) which calls /api/plans/pause + /api/plans/regenerate + planExecute
2700
- async function handlePlansReviseAndRegenerate(req, res) {
2701
- try {
2702
- const body = await readBody(req);
2703
- if (!body.source || !body.instruction) return jsonReply(res, 400, { error: 'source and instruction required' });
2704
-
2705
- // Find the source plan .md file for this PRD
2706
- // Convention: PRD JSON references plan via plan_summary containing the work item ID,
2707
- // or the .md file has a matching name prefix
2708
- const prdPath = path.join(PRD_DIR, body.source);
2709
- if (!fs.existsSync(prdPath)) return jsonReply(res, 404, { error: 'PRD file not found' });
2710
-
2711
- // Look for corresponding .md plan file
2712
- let sourcePlanFile = null;
2713
- const planFiles = safeReadDir(PLANS_DIR).filter(f => f.endsWith('.md'));
2714
- if (body.sourcePlan) {
2715
- // Explicit source plan provided
2716
- sourcePlanFile = body.sourcePlan;
2717
- } else {
2718
- // Heuristic: find .md plan by matching prefix or by reading PRD's generated_from field
2719
- const prd = safeJsonObj(prdPath);
2720
- if (prd.source_plan) {
2721
- sourcePlanFile = prd.source_plan;
2722
- } else {
2723
- // Match by prefix: officeagent-2026-03-15.json → plan-*officeagent* or plan-w025*.md
2724
- const prdBase = body.source.replace('.json', '');
2725
- for (const f of planFiles) {
2726
- // Check if plan file mentions the same project or was created around same time
2727
- const content = safeRead(path.join(PLANS_DIR, f)) || '';
2728
- if (content.includes(prd.project || '___nomatch___') || content.includes(prd.plan_summary?.slice(0, 40) || '___nomatch___')) {
2729
- sourcePlanFile = f;
2730
- break;
2731
- }
2732
- }
2733
- // Last resort: most recent .md plan
2734
- if (!sourcePlanFile && planFiles.length > 0) {
2735
- sourcePlanFile = planFiles.sort((a, b) => {
2736
- try { return fs.statSync(path.join(PLANS_DIR, b)).mtimeMs - fs.statSync(path.join(PLANS_DIR, a)).mtimeMs; } catch { return 0; }
2737
- })[0];
2738
- }
2739
- }
2740
- }
2741
-
2742
- if (!sourcePlanFile) {
2743
- return jsonReply(res, 404, { error: 'No source plan (.md) found for this PRD. You can edit the PRD JSON directly using "Edit Plan".' });
2744
- }
2745
-
2746
- const sourcePlanPath = path.join(PLANS_DIR, sourcePlanFile);
2747
- const planContent = safeRead(sourcePlanPath);
2748
- if (!planContent) return jsonReply(res, 404, { error: 'Source plan file not readable: ' + sourcePlanFile });
2749
-
2750
- // Step 1: Steer the source plan with the user's instruction via CC
2751
- const result = await ccDocCall({
2752
- message: body.instruction,
2753
- document: planContent,
2754
- title: sourcePlanFile,
2755
- filePath: 'plans/' + sourcePlanFile,
2756
- selection: body.selection || '',
2757
- canEdit: true,
2758
- isJson: false,
2759
- });
2760
-
2761
- if (!result.content) {
2762
- return jsonReply(res, 200, { ok: true, answer: result.answer, updated: false });
2763
- }
2764
-
2765
- // Save the revised plan
2766
- safeWrite(sourcePlanPath, result.content);
2767
-
2768
- // Step 2: Pause the old PRD so it stops materializing items
2769
- const prd = safeJsonObj(prdPath);
2770
- prd.status = 'revision-requested';
2771
- prd.revision_feedback = body.instruction;
2772
- prd.revisionRequestedAt = new Date().toISOString();
2773
- safeWrite(prdPath, prd);
2774
-
2775
- // Step 3: Clean up pending/failed work items from old PRD
2776
- let reset = 0, kept = 0;
2777
- const wiPaths = [{ path: path.join(MINIONS_DIR, 'work-items.json'), label: 'central' }];
2778
- for (const proj of PROJECTS) {
2779
- wiPaths.push({ path: shared.projectWorkItemsPath(proj), label: proj.name });
2780
- }
2781
- const deletedItemIds = [];
2782
- for (const wiInfo of wiPaths) {
2783
- try {
2784
- mutateWorkItems(wiInfo.path, items => {
2785
- const filtered = [];
2786
- for (const w of items) {
2787
- if (w.sourcePlan === body.source) {
2788
- if (w.status === WI_STATUS.PENDING || w.status === WI_STATUS.FAILED) {
2789
- reset++;
2790
- deletedItemIds.push(w.id);
2791
- } else {
2792
- kept++;
2793
- filtered.push(w);
2794
- }
2795
- } else {
2796
- filtered.push(w);
2797
- }
2798
- }
2799
- if (filtered.length < items.length) return filtered;
2800
- });
2801
- } catch (e) { console.error('work item deletion:', e.message); }
2802
- }
2803
- for (const itemId of deletedItemIds) {
2804
- cleanDispatchEntries(d =>
2805
- d.meta?.item?.sourcePlan === body.source && d.meta?.item?.id === itemId
2806
- );
2807
- }
2808
-
2809
- // Step 4: Dispatch plan-to-prd to regenerate PRD from revised plan
2810
- const centralWiPath = path.join(MINIONS_DIR, 'work-items.json');
2811
- const wiId = 'W-' + shared.uid();
2812
- mutateWorkItems(centralWiPath, items => {
2813
- items.push({
2814
- id: wiId,
2815
- title: 'Regenerate PRD from revised plan: ' + sourcePlanFile,
2816
- type: 'plan-to-prd',
2817
- priority: 'high',
2818
- description: `The source plan \`${sourcePlanFile}\` has been revised. Convert it into a fresh PRD JSON.\n\nRevision instruction: ${body.instruction}\n\nRead the revised plan, generate updated PRD items (missing_features), and write to \`prd/${body.source}\`. Set status to "approved". Include \`"source_plan": "${sourcePlanFile}"\` in the JSON root.\n\nPreserve items that are already done (status "implemented" or "complete"). Reset or replace items that were pending/failed.`,
2819
- status: WI_STATUS.PENDING,
2820
- created: new Date().toISOString(),
2821
- createdBy: 'dashboard:revise-and-regenerate',
2822
- project: prd.project || '',
2823
- planFile: sourcePlanFile,
2824
- });
2825
- });
2826
-
2827
- return jsonReply(res, 200, {
2828
- ok: true,
2829
- answer: result.answer,
2830
- updated: true,
2831
- sourcePlan: sourcePlanFile,
2832
- prdPaused: true,
2833
- reset,
2834
- kept,
2835
- workItemId: wiId,
2836
- });
2837
- } catch (e) { return jsonReply(res, 500, { error: e.message }); }
2838
- }
2839
-
2840
2700
  async function handlePlansDiscuss(req, res) {
2841
2701
  try {
2842
2702
  const body = await readBody(req);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.881",
3
+ "version": "0.1.883",
4
4
  "description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
5
5
  "bin": {
6
6
  "minions": "bin/minions.js"