@yemi33/minions 0.1.1788 → 0.1.1790

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,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1790 (2026-05-08)
4
+
5
+ ### Fixes
6
+ - restrict CC watch creation
7
+
8
+ ## 0.1.1789 (2026-05-08)
9
+
10
+ ### Other
11
+ - Fix Claude CC resume bookkeeping
12
+
3
13
  ## 0.1.1788 (2026-05-08)
4
14
 
5
15
  ### Other
package/dashboard.js CHANGED
@@ -1434,6 +1434,21 @@ function _ccRuntimeNeedsResumeCarryover(runtimeName) {
1434
1434
  }
1435
1435
  }
1436
1436
 
1437
+ const CC_RESUME_BOOKKEEPING_GUARD = [
1438
+ 'System note for this resumed Minions Command Center request:',
1439
+ 'Some runtimes insert synthetic resume bookkeeping turns such as `Continue from where you left off.` followed by `No response requested.`',
1440
+ 'Do not treat those bookkeeping turns as user requests when answering questions about what the user asked or what happened in the conversation.',
1441
+ ].join('\n');
1442
+
1443
+ function _ccRuntimeNeedsResumeBookkeepingGuard(runtimeName) {
1444
+ try {
1445
+ const runtime = resolveRuntime(runtimeName);
1446
+ return !!runtime?.capabilities?.resumeBookkeepingTurn;
1447
+ } catch {
1448
+ return false;
1449
+ }
1450
+ }
1451
+
1437
1452
  function _joinCcPromptParts(...parts) {
1438
1453
  return parts.filter(Boolean).join('\n\n---\n\n');
1439
1454
  }
@@ -3058,13 +3073,16 @@ async function ccCall(message, { store = 'cc', sessionKey, extraContext, label =
3058
3073
 
3059
3074
  const existing = resolveSession(store, sessionKey);
3060
3075
  let sessionId = existing ? existing.sessionId : null;
3061
- const resumeNeedsCarryover = !!sessionId && _ccRuntimeNeedsResumeCarryover(shared.resolveCcCli(CONFIG.engine));
3076
+ const currentRuntime = shared.resolveCcCli(CONFIG.engine);
3077
+ const resumeNeedsCarryover = !!sessionId && _ccRuntimeNeedsResumeCarryover(currentRuntime);
3078
+ const resumeNeedsBookkeepingGuard = !!sessionId && _ccRuntimeNeedsResumeBookkeepingGuard(currentRuntime);
3062
3079
  const resumeHasOutOfBandCarryover = !!sessionId && _transcriptHasCarryoverContext(transcript, { outOfBandOnly: true, currentMessage: message });
3063
3080
  const freshNeedsCarryover = _transcriptHasCarryoverContext(transcript, { currentMessage: message });
3064
3081
 
3065
- function buildPrompt({ includePreamble = true, includeCarryover = false, outOfBandOnly = false } = {}) {
3082
+ function buildPrompt({ includePreamble = true, includeCarryover = false, includeResumeGuard = false, outOfBandOnly = false } = {}) {
3066
3083
  const parts = (!skipStatePreamble && includePreamble) ? [`## Current Minions State (${new Date().toISOString().slice(0, 16)})\n\n${buildCCStatePreamble()}`] : [];
3067
3084
  if (extraContext) parts.push(extraContext);
3085
+ if (includeResumeGuard) parts.push(CC_RESUME_BOOKKEEPING_GUARD);
3068
3086
  if (includeCarryover) {
3069
3087
  const carryover = _buildTranscriptCarryover(transcript, { currentMessage: message, outOfBandOnly });
3070
3088
  if (carryover) parts.push(carryover);
@@ -3079,6 +3097,7 @@ async function ccCall(message, { store = 'cc', sessionKey, extraContext, label =
3079
3097
  if (sessionId && maxTurns > 1) {
3080
3098
  const p1 = llm.callLLM(buildPrompt({
3081
3099
  includePreamble: false,
3100
+ includeResumeGuard: resumeNeedsBookkeepingGuard,
3082
3101
  includeCarryover: resumeNeedsCarryover || resumeHasOutOfBandCarryover,
3083
3102
  outOfBandOnly: !resumeNeedsCarryover,
3084
3103
  }), '', {
@@ -3165,13 +3184,16 @@ async function ccCallStreaming(message, { store = 'cc', sessionKey, extraContext
3165
3184
 
3166
3185
  const existing = resolveSession(store, sessionKey);
3167
3186
  let sessionId = existing ? existing.sessionId : null;
3168
- const resumeNeedsCarryover = !!sessionId && _ccRuntimeNeedsResumeCarryover(shared.resolveCcCli(CONFIG.engine));
3187
+ const currentRuntime = shared.resolveCcCli(CONFIG.engine);
3188
+ const resumeNeedsCarryover = !!sessionId && _ccRuntimeNeedsResumeCarryover(currentRuntime);
3189
+ const resumeNeedsBookkeepingGuard = !!sessionId && _ccRuntimeNeedsResumeBookkeepingGuard(currentRuntime);
3169
3190
  const resumeHasOutOfBandCarryover = !!sessionId && _transcriptHasCarryoverContext(transcript, { outOfBandOnly: true, currentMessage: message });
3170
3191
  const freshNeedsCarryover = _transcriptHasCarryoverContext(transcript, { currentMessage: message });
3171
3192
 
3172
- function buildPrompt({ includePreamble = true, includeCarryover = false, outOfBandOnly = false } = {}) {
3193
+ function buildPrompt({ includePreamble = true, includeCarryover = false, includeResumeGuard = false, outOfBandOnly = false } = {}) {
3173
3194
  const parts = (!skipStatePreamble && includePreamble) ? [`## Current Minions State (${new Date().toISOString().slice(0, 16)})\n\n${buildCCStatePreamble()}`] : [];
3174
3195
  if (extraContext) parts.push(extraContext);
3196
+ if (includeResumeGuard) parts.push(CC_RESUME_BOOKKEEPING_GUARD);
3175
3197
  if (includeCarryover) {
3176
3198
  const carryover = _buildTranscriptCarryover(transcript, { currentMessage: message, outOfBandOnly });
3177
3199
  if (carryover) parts.push(carryover);
@@ -3185,6 +3207,7 @@ async function ccCallStreaming(message, { store = 'cc', sessionKey, extraContext
3185
3207
  if (sessionId && maxTurns > 1) {
3186
3208
  const p1 = llm.callLLMStreaming(buildPrompt({
3187
3209
  includePreamble: false,
3210
+ includeResumeGuard: resumeNeedsBookkeepingGuard,
3188
3211
  includeCarryover: resumeNeedsCarryover || resumeHasOutOfBandCarryover,
3189
3212
  outOfBandOnly: !resumeNeedsCarryover,
3190
3213
  }), '', {
@@ -6708,9 +6731,11 @@ What would you like to discuss or change? When you're happy, say "approve" and I
6708
6731
  const wasResume = !!tabSessionId;
6709
6732
  const sessionId = tabSessionId || null;
6710
6733
  const resumeNeedsCarryover = wasResume && _ccRuntimeNeedsResumeCarryover(currentRuntime);
6734
+ const resumeNeedsBookkeepingGuard = wasResume && _ccRuntimeNeedsResumeBookkeepingGuard(currentRuntime);
6711
6735
  const resumeHasOutOfBandCarryover = wasResume && _transcriptHasCarryoverContext(body.transcript, { outOfBandOnly: true, currentMessage: body.message });
6712
6736
  const preamble = wasResume ? '' : buildCCStatePreamble();
6713
6737
  const includeFullCarryover = sessionReset || resumeNeedsCarryover;
6738
+ const resumeGuard = resumeNeedsBookkeepingGuard ? CC_RESUME_BOOKKEEPING_GUARD : '';
6714
6739
  const carryover = (includeFullCarryover || resumeHasOutOfBandCarryover)
6715
6740
  ? _buildTranscriptCarryover(body.transcript, {
6716
6741
  previousRuntime: sessionReset ? previousRuntime : null,
@@ -6718,7 +6743,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
6718
6743
  outOfBandOnly: !includeFullCarryover,
6719
6744
  })
6720
6745
  : '';
6721
- const prompt = _joinCcPromptParts(preamble, carryover, body.message);
6746
+ const prompt = _joinCcPromptParts(preamble, resumeGuard, carryover, body.message);
6722
6747
 
6723
6748
  const { trackEngineUsage: trackUsage } = require('./engine/llm');
6724
6749
  const streamModel = CONFIG.engine?.ccModel || shared.ENGINE_DEFAULTS.ccModel;
@@ -8462,6 +8487,7 @@ module.exports = {
8462
8487
  _buildTranscriptCarryover,
8463
8488
  _transcriptHasCarryoverContext,
8464
8489
  _ccRuntimeNeedsResumeCarryover,
8490
+ _ccRuntimeNeedsResumeBookkeepingGuard,
8465
8491
  _joinCcPromptParts,
8466
8492
  _captureApiRoutesMeta,
8467
8493
  _formatCcApiRoutesIndex,
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "runtime": "copilot",
3
3
  "models": null,
4
- "cachedAt": "2026-05-08T04:24:46.560Z"
4
+ "cachedAt": "2026-05-08T07:51:34.436Z"
5
5
  }
@@ -719,6 +719,9 @@ const capabilities = {
719
719
  sessionPersistenceControl: true,
720
720
  // Claude resume reliably restores prior turns; do not duplicate browser transcript.
721
721
  resumePromptCarryover: false,
722
+ // Claude CLI injects a synthetic "Continue from where you left off." meta
723
+ // turn on --resume; CC prompts must tell the model not to treat it as user intent.
724
+ resumeBookkeepingTurn: true,
722
725
  // Adapter implements createStreamConsumer(ctx) — required by llm.js accumulator
723
726
  streamConsumer: true,
724
727
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1788",
3
+ "version": "0.1.1790",
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"
@@ -129,8 +129,9 @@ Additional actions (all take `id` or `file` as primary key):
129
129
  - Work item ops: delete-work-item (id, source), cancel-work-item (id, source?, reason? — cancel a pending/dispatched/failed item, kills running agent), archive-work-item (id), work-item-feedback (id, rating: up/down, comment), reopen-work-item (id, project[, description] — reopen a done/failed item back to pending)
130
130
  - PRD ops: edit-prd-item, remove-prd-item, reopen-prd-item (id, file — re-dispatches on existing branch)
131
131
  - **create-watch**: target, targetType (pr/work-item), condition (merged/build-fail/build-pass/completed/failed/status-change/any/new-comments/vote-change), interval ("15m", "1h", "30s" — default "5m"), owner (agent id or "human"), description, project, stopAfter (0=run forever, 1=expire on first match, N=expire after N matches), onNotMet (null=do nothing, "notify"=write to inbox each poll while condition not met)
132
- **NEVER use the /loop skill for monitoring tasks.** Always use the `create-watch` action — it persists across engine restarts and appears in the Watches page. /loop runs ephemerally in the session and leaves no trace.
133
- Trigger phrases: user says "keep an eye on X", "watch X every N min", "monitor X", "check X periodically", "ping me when X" always emit `create-watch`.
132
+ **NEVER use the /loop skill for explicit persistent monitoring tasks.** Use the `create-watch` action for those tasks — it persists across engine restarts and appears in the Watches page. /loop runs ephemerally in the session and leaves no trace.
133
+ Explicit watch intent means the human asks for persistent monitoring, periodic checks, or future notification after the current CC turn. Runtime waiting for a long-running task, background command, agent dispatch, build, test, or pipeline outcome is not watch intent and must not create a watch.
134
+ Trigger phrases require that explicit persistent intent: user says "keep an eye on X", "watch X every N min", "monitor X", "check X periodically", "ping me when X" → emit `create-watch`.
134
135
  Example: user says "check PR 1065 build every 15 min until green" → `{"type":"create-watch","target":"1065","targetType":"pr","condition":"build-pass","interval":"15m","stopAfter":1,"description":"Watch PR 1065 build until green"}`
135
136
  Example: user says "ping me every 15 min while build is still failing" → `{"type":"create-watch","target":"1065","targetType":"pr","condition":"build-pass","interval":"15m","stopAfter":1,"onNotMet":"notify","description":"Watch PR 1065 build — notify each poll"}`
136
137
  Example: user says "keep an eye on PR 200 every 5 min" → `{"type":"create-watch","target":"200","targetType":"pr","condition":"any","interval":"5m","stopAfter":0,"description":"Monitor PR 200"}`