@yemi33/minions 0.1.1815 → 0.1.1816

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,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1816 (2026-05-09)
4
+
5
+ ### Features
6
+ - correlate CC action failures (#2254)
7
+
3
8
  ## 0.1.1815 (2026-05-09)
4
9
 
5
10
  ### Features
@@ -826,11 +826,15 @@ async function _ccDoSend(message, skipUserMsg, forceTabId, intentMetadata) {
826
826
  var failures = evt.actionResults.filter(function(r) { return r && r.error; });
827
827
  var warnings = evt.actionResults.filter(function(r) { return r && r.warning; });
828
828
  if (failures.length > 0) {
829
- var failHtml = failures.map(function(r) { return '<li>' + escHtml(r.type || 'action') + ': ' + escHtml(r.error) + '</li>'; }).join('');
829
+ var failHtml = failures.map(function(r) {
830
+ return '<li>' + escHtml(r.type || (r.actionContext && r.actionContext.type) || 'action') + ': ' + escHtml(r.error) + _ccActionContextSuffix(r.actionContext) + '</li>';
831
+ }).join('');
830
832
  addMsg('system', '<div style="padding:6px 12px;font-size:11px;color:var(--red);background:var(--surface2);border-radius:6px;margin:4px 0">⚠️ ' + failures.length + ' action' + (failures.length > 1 ? 's' : '') + ' failed:<ul style="margin:4px 0 0 16px;padding:0">' + failHtml + '</ul></div>', false, activeTabId);
831
833
  }
832
834
  if (warnings.length > 0) {
833
- var warnHtml = warnings.map(function(r) { return '<li>' + escHtml(r.type || 'action') + ': ' + escHtml(r.warning) + '</li>'; }).join('');
835
+ var warnHtml = warnings.map(function(r) {
836
+ return '<li>' + escHtml(r.type || (r.actionContext && r.actionContext.type) || 'action') + ': ' + escHtml(r.warning) + _ccActionContextSuffix(r.actionContext) + '</li>';
837
+ }).join('');
834
838
  addMsg('system', '<div style="padding:6px 12px;font-size:11px;color:var(--orange);background:var(--surface2);border-radius:6px;margin:4px 0">ℹ️ ' + warnings.length + ' action' + (warnings.length > 1 ? '' : '') + ' completed with warnings:<ul style="margin:4px 0 0 16px;padding:0">' + warnHtml + '</ul></div>', false, activeTabId);
835
839
  }
836
840
  }
@@ -1012,6 +1016,28 @@ async function _ccFetch(url, body, method) {
1012
1016
  return res;
1013
1017
  }
1014
1018
 
1019
+ var CC_ACTION_CONTEXT_STALE_MS = 2 * 60 * 1000;
1020
+ function _ccActionContextIsStale(ctx, nowMs) {
1021
+ if (!ctx || !ctx.requestedAt) return false;
1022
+ var ts = Date.parse(ctx.requestedAt);
1023
+ if (!Number.isFinite(ts)) return false;
1024
+ var now = Number.isFinite(nowMs) ? nowMs : Date.now();
1025
+ return now - ts > CC_ACTION_CONTEXT_STALE_MS;
1026
+ }
1027
+
1028
+ function _ccActionContextSuffix(ctx, nowMs) {
1029
+ if (!ctx || typeof ctx !== 'object') return '';
1030
+ var parts = [];
1031
+ if (ctx.title) parts.push('action "' + escHtml(ctx.title) + '"');
1032
+ if (ctx.request) parts.push('request "' + escHtml(ctx.request) + '"');
1033
+ if (ctx.requestedAt) parts.push('started ' + escHtml(ctx.requestedAt));
1034
+ if (parts.length === 0) return '';
1035
+ var stale = _ccActionContextIsStale(ctx, nowMs)
1036
+ ? ' <strong style="color:var(--orange)">possibly stale</strong>'
1037
+ : '';
1038
+ return '<div style="font-size:10px;color:var(--muted);margin-top:2px">Context: ' + parts.join(' | ') + stale + '</div>';
1039
+ }
1040
+
1015
1041
  // Tag actions that the server already executed so ccExecuteAction skips the API call
1016
1042
  function _tagServerExecuted(actions, actionResults) {
1017
1043
  if (!actionResults || !Array.isArray(actionResults)) return;
@@ -1022,10 +1048,12 @@ function _tagServerExecuted(actions, actionResults) {
1022
1048
  if (r.id) actions[i]._serverId = r.id;
1023
1049
  if (r.warning) actions[i]._serverWarning = r.warning;
1024
1050
  if (r.duplicate) actions[i]._serverDuplicate = true;
1051
+ if (r.actionContext) actions[i]._serverContext = r.actionContext;
1025
1052
  if (r.reusedFromAction !== undefined) actions[i]._serverHidden = true;
1026
1053
  } else if (r && r.error) {
1027
1054
  actions[i]._serverExecuted = true;
1028
1055
  actions[i]._serverError = r.error;
1056
+ if (r.actionContext) actions[i]._serverContext = r.actionContext;
1029
1057
  }
1030
1058
  // clientExecuted: false means server didn't handle it — frontend must execute
1031
1059
  }
@@ -1040,7 +1068,8 @@ async function ccExecuteAction(action, targetTabId) {
1040
1068
  if (action._serverExecuted) {
1041
1069
  if (action._serverHidden) return;
1042
1070
  if (action._serverError) {
1043
- status.innerHTML = '&#10007; ' + escHtml(action.type) + ' failed: ' + escHtml(action._serverError);
1071
+ status.innerHTML = '&#10007; ' + escHtml(action.type) + ' failed: ' + escHtml(action._serverError) +
1072
+ _ccActionContextSuffix(action._serverContext);
1044
1073
  status.style.color = 'var(--red)';
1045
1074
  } else {
1046
1075
  var label = action._serverId ? escHtml(action._serverId) : escHtml(action.title || action.type);
@@ -1048,7 +1077,8 @@ async function ccExecuteAction(action, targetTabId) {
1048
1077
  var successLabel = serverActionType === 'dispatch' ? 'Dispatched' : serverActionType;
1049
1078
  status.innerHTML = '&#10003; ' + escHtml(successLabel) + ': <strong>' + label + '</strong>' +
1050
1079
  (action._serverDuplicate ? '<div style="font-size:10px;color:var(--orange);margin-top:2px">Already existed from a previous request; no duplicate work item was created.</div>' : '') +
1051
- (action._serverWarning ? '<div style="font-size:10px;color:var(--muted);margin-top:2px">' + escHtml(action._serverWarning) + '</div>' : '');
1080
+ (action._serverWarning ? '<div style="font-size:10px;color:var(--muted);margin-top:2px">' + escHtml(action._serverWarning) + '</div>' : '') +
1081
+ _ccActionContextSuffix(action._serverContext);
1052
1082
  status.style.color = 'var(--green)';
1053
1083
  }
1054
1084
  ccAddMessage('action', status.outerHTML, false, targetTabId);
package/dashboard.js CHANGED
@@ -2202,6 +2202,34 @@ function _actionsWithIntentFallback(actions, opts = {}) {
2202
2202
  return [action];
2203
2203
  }
2204
2204
 
2205
+ function _ccActionContextValue(action) {
2206
+ if (!action || typeof action !== 'object') return '';
2207
+ const candidates = [action.title, action.id, action.file, action.target, action.pr, action.endpoint];
2208
+ for (const value of candidates) {
2209
+ const cleaned = _ccCleanIntentString(value, 160);
2210
+ if (cleaned) return cleaned;
2211
+ }
2212
+ return '';
2213
+ }
2214
+
2215
+ function _annotateCCActionResults(actions, actionResults, opts = {}) {
2216
+ if (!Array.isArray(actionResults)) return actionResults;
2217
+ const requestedAt = _ccCleanIntentString(opts.requestedAt || new Date().toISOString(), 80);
2218
+ const request = _ccCleanIntentString(opts.message, 180);
2219
+ return actionResults.map((result, idx) => {
2220
+ if (!result || typeof result !== 'object') return result;
2221
+ const action = Array.isArray(actions) ? normalizeCCAction(actions[idx]) : null;
2222
+ const context = {
2223
+ type: _ccCleanIntentString(result.type || action?.type || 'action', 80) || 'action',
2224
+ };
2225
+ const title = _ccActionContextValue(action);
2226
+ if (title) context.title = title;
2227
+ if (request) context.request = request;
2228
+ if (requestedAt) context.requestedAt = requestedAt;
2229
+ return { ...result, actionContext: context };
2230
+ });
2231
+ }
2232
+
2205
2233
  function parseCCActions(text) {
2206
2234
  let actions = [];
2207
2235
  let displayText = stripCCActionsForDisplay(text);
@@ -7100,6 +7128,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
7100
7128
  try {
7101
7129
  const body = await readBody(req);
7102
7130
  if (!body.message) return jsonReply(res, 400, { error: 'message required' });
7131
+ const actionRequestedAt = new Date().toISOString();
7103
7132
 
7104
7133
  // Per-tab concurrency guard
7105
7134
  tabId = body.tabId || 'default';
@@ -7155,7 +7184,11 @@ What would you like to discuss or change? When you're happy, say "approve" and I
7155
7184
  { message: body.message, intentMetadata: body.intentMetadata, source: 'command-center', answerText: parsed.text, toolUses }
7156
7185
  );
7157
7186
  if (parsed.actions.length > 0) {
7158
- parsed.actionResults = await executeCCActions(parsed.actions);
7187
+ parsed.actionResults = _annotateCCActionResults(
7188
+ parsed.actions,
7189
+ await executeCCActions(parsed.actions),
7190
+ { message: body.message, requestedAt: actionRequestedAt }
7191
+ );
7159
7192
  }
7160
7193
  // Mirror only user-facing text to Teams; never send the internal action block.
7161
7194
  if (!tabId.startsWith('teams-')) {
@@ -7259,6 +7292,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
7259
7292
  const body = await readBody(req);
7260
7293
  if (!body.message && !body.reconnect) { res.statusCode = 400; res.end('message required'); return; }
7261
7294
  tabId = body.tabId || 'default';
7295
+ const actionRequestedAt = new Date().toISOString();
7262
7296
  if (body.reconnect) {
7263
7297
  const live = _getCcLiveStream(tabId);
7264
7298
  if (!live) { res.statusCode = 409; res.end('No live command-center response to reconnect'); return; }
@@ -7487,7 +7521,11 @@ What would you like to discuss or change? When you're happy, say "approve" and I
7487
7521
  );
7488
7522
  let actionResults;
7489
7523
  if (actions.length > 0) {
7490
- actionResults = await executeCCActions(actions);
7524
+ actionResults = _annotateCCActionResults(
7525
+ actions,
7526
+ await executeCCActions(actions),
7527
+ { message: body.message, requestedAt: actionRequestedAt }
7528
+ );
7491
7529
  }
7492
7530
  const donePayload = { type: 'done', text: displayText, actions, actionResults, sessionId: responseSessionId, newSession: !wasResume };
7493
7531
  // Issue #1834: surface action JSON parse failures so the UI can warn
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "runtime": "copilot",
3
3
  "models": null,
4
- "cachedAt": "2026-05-09T15:24:57.566Z"
4
+ "cachedAt": "2026-05-09T15:27:55.877Z"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1815",
3
+ "version": "0.1.1816",
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"