@yemi33/minions 0.1.2315 → 0.1.2317
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/engine/meeting.js +6 -10
- package/engine/pipeline.js +6 -10
- package/engine/pr-clone-keep.js +2 -17
- package/engine/pr-devbox.js +2 -17
- package/engine/pr-fix-target.js +2 -16
- package/engine/pr-remote-patch.js +2 -17
- package/engine/pr-resolve.js +38 -0
- package/engine/pr-temp-clone.js +2 -17
- package/engine/pr-track.js +2 -17
- package/package.json +1 -1
package/engine/meeting.js
CHANGED
|
@@ -231,18 +231,14 @@ function resolveMeetingContributionContent(output, structuredCompletion) {
|
|
|
231
231
|
return resolveStructuredMeetingContent(structuredCompletion);
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
function truncateMeetingContext(text, maxBytes, label) {
|
|
235
|
-
return shared.truncateTextBytes(text, maxBytes, `\n\n_...${label} truncated — review the meeting transcript if needed._`);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
234
|
function formatMeetingContributions(entries, agents, emptyText, label, maxBytes) {
|
|
239
235
|
const pairs = Object.entries(typeof entries === 'object' && entries ? entries : {});
|
|
240
236
|
if (pairs.length === 0) return emptyText;
|
|
241
237
|
const perEntryBytes = Math.max(1024, Math.floor(maxBytes / Math.max(1, pairs.length)));
|
|
242
238
|
const combined = pairs.map(([agent, value]) =>
|
|
243
|
-
`### ${agents[agent]?.name || agent}\n\n${
|
|
239
|
+
`### ${agents[agent]?.name || agent}\n\n${shared.truncateTextBytes(value?.content || emptyText, perEntryBytes, `\n\n_...${label} entry truncated — review the meeting transcript if needed._`)}`
|
|
244
240
|
).join('\n\n---\n\n');
|
|
245
|
-
return
|
|
241
|
+
return shared.truncateTextBytes(combined, maxBytes, `\n\n_...${label} truncated — review the meeting transcript if needed._`);
|
|
246
242
|
}
|
|
247
243
|
|
|
248
244
|
function stripMeetingSummaryMarkdown(text) {
|
|
@@ -542,10 +538,10 @@ function discoverMeetingWork(config) {
|
|
|
542
538
|
const key = `${concludePrefix}${concluder}`;
|
|
543
539
|
if (activeKeys.has(key)) continue;
|
|
544
540
|
|
|
545
|
-
const humanNotes =
|
|
541
|
+
const humanNotes = shared.truncateTextBytes(
|
|
546
542
|
(Array.isArray(meeting.humanNotes) ? meeting.humanNotes : []).map(n => '- ' + n).join('\n'),
|
|
547
543
|
ENGINE_DEFAULTS.maxMeetingHumanNotesBytes,
|
|
548
|
-
'human meeting notes'
|
|
544
|
+
'\n\n_...human meeting notes truncated — review the meeting transcript if needed._'
|
|
549
545
|
);
|
|
550
546
|
const allFindings = formatMeetingContributions(
|
|
551
547
|
meeting.findings,
|
|
@@ -605,10 +601,10 @@ function discoverMeetingWork(config) {
|
|
|
605
601
|
const key = `meeting-${meeting.id}-r${round}-${agentId}`;
|
|
606
602
|
if (activeKeys.has(key)) continue;
|
|
607
603
|
|
|
608
|
-
const humanNotes =
|
|
604
|
+
const humanNotes = shared.truncateTextBytes(
|
|
609
605
|
(meeting.humanNotes || []).map(n => '- ' + n).join('\n'),
|
|
610
606
|
ENGINE_DEFAULTS.maxMeetingHumanNotesBytes,
|
|
611
|
-
'human meeting notes'
|
|
607
|
+
'\n\n_...human meeting notes truncated — review the meeting transcript if needed._'
|
|
612
608
|
);
|
|
613
609
|
const vars = {
|
|
614
610
|
agent_name: agents[agentId]?.name || agentId,
|
package/engine/pipeline.js
CHANGED
|
@@ -26,10 +26,6 @@ const NOTES_INBOX_DIR = path.join(MINIONS_DIR, 'notes', 'inbox');
|
|
|
26
26
|
const NOTES_ARCHIVE_DIR = path.join(MINIONS_DIR, 'notes', 'archive');
|
|
27
27
|
const CONFIG_PATH = path.join(MINIONS_DIR, 'config.json');
|
|
28
28
|
|
|
29
|
-
function truncatePipelineContext(text, maxBytes, label) {
|
|
30
|
-
return shared.truncateTextBytes(text, maxBytes, `\n\n_...${label} truncated — inspect the upstream artifacts if needed._`);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
29
|
// ── Pipeline CRUD ────────────────────────────────────────────────────────────
|
|
34
30
|
|
|
35
31
|
function getPipelines() {
|
|
@@ -619,10 +615,10 @@ async function executePlanStage(stage, stageState, run, config, pipeline = {}) {
|
|
|
619
615
|
try {
|
|
620
616
|
const mtg = safeJson(path.join(MEETINGS_DIR, mid + '.json'));
|
|
621
617
|
if (mtg) {
|
|
622
|
-
const transcript =
|
|
618
|
+
const transcript = shared.truncateTextBytes(
|
|
623
619
|
(mtg.transcript || []).map(formatTranscriptEntry).join('\n\n---\n\n'),
|
|
624
620
|
ENGINE_DEFAULTS.maxPipelineMeetingContextBytes,
|
|
625
|
-
|
|
621
|
+
`\n\n_...meeting transcript for ${mtg.title || mid} truncated — inspect the upstream artifacts if needed._`
|
|
626
622
|
);
|
|
627
623
|
meetingContext += '# Meeting: ' + (mtg.title || mid) + '\n\n**Agenda:** ' + (mtg.agenda || '') + '\n\n' + transcript + '\n\n';
|
|
628
624
|
}
|
|
@@ -633,15 +629,15 @@ async function executePlanStage(stage, stageState, run, config, pipeline = {}) {
|
|
|
633
629
|
for (const depId of stage.dependsOn) {
|
|
634
630
|
const depStage = run.stages[depId];
|
|
635
631
|
if (depStage?.output && !depStage.artifacts?.meetings?.length) {
|
|
636
|
-
meetingContext += '## From: ' + depId + '\n\n' +
|
|
632
|
+
meetingContext += '## From: ' + depId + '\n\n' + shared.truncateTextBytes(
|
|
637
633
|
depStage.output,
|
|
638
634
|
ENGINE_DEFAULTS.maxPipelineMeetingContextBytes,
|
|
639
|
-
|
|
635
|
+
`\n\n_...pipeline stage output from ${depId} truncated — inspect the upstream artifacts if needed._`
|
|
640
636
|
) + '\n\n';
|
|
641
637
|
}
|
|
642
638
|
}
|
|
643
639
|
}
|
|
644
|
-
meetingContext =
|
|
640
|
+
meetingContext = shared.truncateTextBytes(meetingContext, ENGINE_DEFAULTS.maxPipelineMeetingContextBytes, '\n\n_...pipeline meeting context truncated — inspect the upstream artifacts if needed._');
|
|
645
641
|
|
|
646
642
|
// Use LLM to generate a structured plan (same approach as dashboard "Create Plan from Meeting" button)
|
|
647
643
|
let content = '';
|
|
@@ -1259,7 +1255,7 @@ module.exports = {
|
|
|
1259
1255
|
getPipelineRuns, getActiveRun, startRun, updateRunStage, upsertRunStage, completeRun,
|
|
1260
1256
|
discoverPipelineWork,
|
|
1261
1257
|
evaluateCondition, // exported for testing
|
|
1262
|
-
|
|
1258
|
+
executeTaskStage, executePlanStage, executeScheduleStage, executeApiStage, executeMeetingStage, executeMergePrsStage, isStageComplete, resolveTemplate, // exported for testing
|
|
1263
1259
|
_resolvePipelineProjects, // exported for testing
|
|
1264
1260
|
_findMeetingsInRun, _findExistingPlanForMeeting, _findExistingPrdForPlan, _canonicalPlanName, // exported for testing
|
|
1265
1261
|
};
|
package/engine/pr-clone-keep.js
CHANGED
|
@@ -69,24 +69,9 @@ const GIT_OP_TIMEOUT_MS = 60 * 1000;
|
|
|
69
69
|
* `PrActionError` (400) on missing/unrecognized input — mirrors the read-only,
|
|
70
70
|
* choice-surface, and temp-clone paths so the dashboard reflects a 400, not a 500.
|
|
71
71
|
*/
|
|
72
|
-
|
|
73
|
-
if (input && typeof input === 'object') {
|
|
74
|
-
if (input.host && input.slug && input.number) return input; // already normalized
|
|
75
|
-
if (input.ref && input.ref.host) return input.ref; // plan/handle carrying a ref
|
|
76
|
-
}
|
|
77
|
-
const rawUrl = input && typeof input === 'object'
|
|
78
|
-
? (typeof input.url === 'string' ? input.url.trim() : '')
|
|
79
|
-
: (typeof input === 'string' ? input.trim() : '');
|
|
80
|
-
if (!rawUrl) throw new PrActionError('url required');
|
|
81
|
-
const ref = prResolve.normalizePrRef(rawUrl);
|
|
82
|
-
if (!ref) throw new PrActionError(`unrecognized PR reference: ${JSON.stringify(rawUrl.slice(0, 120))}`);
|
|
83
|
-
return ref;
|
|
84
|
-
}
|
|
72
|
+
const _resolveRef = (input) => prResolve.resolvePrActionRef(input, PrActionError);
|
|
85
73
|
|
|
86
|
-
|
|
87
|
-
if (!ref) return null;
|
|
88
|
-
return ref.id || (ref.host && ref.slug && ref.number ? `${ref.host}:${ref.slug}#${ref.number}` : null);
|
|
89
|
-
}
|
|
74
|
+
const _prId = prResolve.prIdFromRef;
|
|
90
75
|
|
|
91
76
|
/** Filesystem-safe slug for the persistent project dir name (from the repo name). */
|
|
92
77
|
function _safeDirSlug(name) {
|
package/engine/pr-devbox.js
CHANGED
|
@@ -60,24 +60,9 @@ const DEFAULT_REMOTE_TMP_ROOT = 'C:/minions-devbox-tmp';
|
|
|
60
60
|
* `PrActionError` (400) on missing/unrecognized input — mirrors the other
|
|
61
61
|
* projectless paths so the dashboard reflects a 400, not a 500.
|
|
62
62
|
*/
|
|
63
|
-
|
|
64
|
-
if (input && typeof input === 'object') {
|
|
65
|
-
if (input.host && input.slug && input.number) return input; // already normalized
|
|
66
|
-
if (input.ref && input.ref.host) return input.ref; // plan/handle carrying a ref
|
|
67
|
-
}
|
|
68
|
-
const rawUrl = input && typeof input === 'object'
|
|
69
|
-
? (typeof input.url === 'string' ? input.url.trim() : '')
|
|
70
|
-
: (typeof input === 'string' ? input.trim() : '');
|
|
71
|
-
if (!rawUrl) throw new PrActionError('url required');
|
|
72
|
-
const ref = prResolve.normalizePrRef(rawUrl);
|
|
73
|
-
if (!ref) throw new PrActionError(`unrecognized PR reference: ${JSON.stringify(rawUrl.slice(0, 120))}`);
|
|
74
|
-
return ref;
|
|
75
|
-
}
|
|
63
|
+
const _resolveRef = (input) => prResolve.resolvePrActionRef(input, PrActionError);
|
|
76
64
|
|
|
77
|
-
|
|
78
|
-
if (!ref) return null;
|
|
79
|
-
return ref.id || (ref.host && ref.slug && ref.number ? `${ref.host}:${ref.slug}#${ref.number}` : null);
|
|
80
|
-
}
|
|
65
|
+
const _prId = prResolve.prIdFromRef;
|
|
81
66
|
|
|
82
67
|
/** Filesystem-safe slug for a PR id (used in the remote dir name). */
|
|
83
68
|
function _safeDirSlug(prId) {
|
package/engine/pr-fix-target.js
CHANGED
|
@@ -143,21 +143,7 @@ function _routedRecord(plan, target, extra = {}) {
|
|
|
143
143
|
* a normalized PR ref. Throws `PrActionError` (400) on missing/unrecognized input
|
|
144
144
|
* so the dashboard handler reflects it as a 400 (matching the read-only path).
|
|
145
145
|
*/
|
|
146
|
-
|
|
147
|
-
if (input && typeof input === 'object' && input.host && input.slug && input.number) {
|
|
148
|
-
return input; // already normalized
|
|
149
|
-
}
|
|
150
|
-
if (input && typeof input === 'object' && input.ref && input.ref.host) {
|
|
151
|
-
return input.ref; // a plan/handle carrying a ref
|
|
152
|
-
}
|
|
153
|
-
const rawUrl = input && typeof input === 'object'
|
|
154
|
-
? (typeof input.url === 'string' ? input.url.trim() : '')
|
|
155
|
-
: (typeof input === 'string' ? input.trim() : '');
|
|
156
|
-
if (!rawUrl) throw new PrActionError('url required');
|
|
157
|
-
const ref = prResolve.normalizePrRef(rawUrl);
|
|
158
|
-
if (!ref) throw new PrActionError(`unrecognized PR reference: ${JSON.stringify(rawUrl.slice(0, 120))}`);
|
|
159
|
-
return ref;
|
|
160
|
-
}
|
|
146
|
+
const _resolveRef = (input) => prResolve.resolvePrActionRef(input, PrActionError);
|
|
161
147
|
|
|
162
148
|
// ── Configured-project detection ──────────────────────────────────────────────
|
|
163
149
|
|
|
@@ -309,7 +295,7 @@ function buildPrFixTargetModal(plan) {
|
|
|
309
295
|
function planPrFix(input = {}, opts = {}) {
|
|
310
296
|
const ref = _resolveRef(input);
|
|
311
297
|
const prUrl = opts.prUrl || (input && typeof input === 'object' ? input.url : undefined) || null;
|
|
312
|
-
const prId =
|
|
298
|
+
const prId = prResolve.prIdFromRef(ref);
|
|
313
299
|
|
|
314
300
|
const project = findConfiguredProjectForRef(ref, opts.config);
|
|
315
301
|
if (project) {
|
|
@@ -59,24 +59,9 @@ const REMOTE_PATCH_NO_VALIDATION_LABEL =
|
|
|
59
59
|
* `PrActionError` (400) on missing/unrecognized input — mirrors the read-only,
|
|
60
60
|
* choice-surface, and temp-clone paths so the dashboard reflects a 400, not 500.
|
|
61
61
|
*/
|
|
62
|
-
|
|
63
|
-
if (input && typeof input === 'object') {
|
|
64
|
-
if (input.host && input.slug && input.number) return input; // already normalized
|
|
65
|
-
if (input.ref && input.ref.host) return input.ref; // plan/handle carrying a ref
|
|
66
|
-
}
|
|
67
|
-
const rawUrl = input && typeof input === 'object'
|
|
68
|
-
? (typeof input.url === 'string' ? input.url.trim() : '')
|
|
69
|
-
: (typeof input === 'string' ? input.trim() : '');
|
|
70
|
-
if (!rawUrl) throw new PrActionError('url required');
|
|
71
|
-
const ref = prResolve.normalizePrRef(rawUrl);
|
|
72
|
-
if (!ref) throw new PrActionError(`unrecognized PR reference: ${JSON.stringify(rawUrl.slice(0, 120))}`);
|
|
73
|
-
return ref;
|
|
74
|
-
}
|
|
62
|
+
const _resolveRef = (input) => prResolve.resolvePrActionRef(input, PrActionError);
|
|
75
63
|
|
|
76
|
-
|
|
77
|
-
if (!ref) return null;
|
|
78
|
-
return ref.id || (ref.host && ref.slug && ref.number ? `${ref.host}:${ref.slug}#${ref.number}` : null);
|
|
79
|
-
}
|
|
64
|
+
const _prId = prResolve.prIdFromRef;
|
|
80
65
|
|
|
81
66
|
// ── Patch normalization (the trivial-single-file guardrail) ───────────────────
|
|
82
67
|
|
package/engine/pr-resolve.js
CHANGED
|
@@ -102,6 +102,42 @@ function normalizePrRef(input) {
|
|
|
102
102
|
return _normalizeFromScope(parsed.scope, parsed.prNumber);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
// ── Shared ref resolution for the PR-action executors ───────────────────────
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Resolve `{ url }` (raw PR URL / canonical id), an already-normalized ref, or a
|
|
109
|
+
* plan/handle carrying `.ref` into a normalized PR ref. Throws `PrActionError`
|
|
110
|
+
* (400) on missing/unrecognized input so callers reflect a 400, not a 500.
|
|
111
|
+
*
|
|
112
|
+
* Shared by the 6 PR-action executor modules (pr-clone-keep, pr-devbox,
|
|
113
|
+
* pr-remote-patch, pr-temp-clone, pr-track, pr-fix-target), which previously
|
|
114
|
+
* each defined a byte-identical copy of this function. `PrActionError` must be
|
|
115
|
+
* passed in by the caller — pr-resolve.js does not import engine/pr-action.js
|
|
116
|
+
* (that would introduce a new cross-module dependency in that direction).
|
|
117
|
+
*/
|
|
118
|
+
function resolvePrActionRef(input, PrActionError) {
|
|
119
|
+
if (input && typeof input === 'object') {
|
|
120
|
+
if (input.host && input.slug && input.number) return input; // already normalized
|
|
121
|
+
if (input.ref && input.ref.host) return input.ref; // plan/handle carrying a ref
|
|
122
|
+
}
|
|
123
|
+
const rawUrl = input && typeof input === 'object'
|
|
124
|
+
? (typeof input.url === 'string' ? input.url.trim() : '')
|
|
125
|
+
: (typeof input === 'string' ? input.trim() : '');
|
|
126
|
+
if (!rawUrl) throw new PrActionError('url required');
|
|
127
|
+
const ref = normalizePrRef(rawUrl);
|
|
128
|
+
if (!ref) throw new PrActionError(`unrecognized PR reference: ${JSON.stringify(rawUrl.slice(0, 120))}`);
|
|
129
|
+
return ref;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Derive the canonical `host:slug#number` PR id string from a normalized ref
|
|
134
|
+
* (or its already-computed `.id`). Returns null when `ref` is falsy.
|
|
135
|
+
*/
|
|
136
|
+
function prIdFromRef(ref) {
|
|
137
|
+
if (!ref) return null;
|
|
138
|
+
return ref.id || (ref.host && ref.slug && ref.number ? `${ref.host}:${ref.slug}#${ref.number}` : null);
|
|
139
|
+
}
|
|
140
|
+
|
|
105
141
|
// ── Config (for the unknown-slug account fallback) ───────────────────────────
|
|
106
142
|
|
|
107
143
|
function _readConfig(opts = {}) {
|
|
@@ -432,6 +468,8 @@ async function fetchPrPayload(refOrInput, opts = {}) {
|
|
|
432
468
|
|
|
433
469
|
module.exports = {
|
|
434
470
|
normalizePrRef,
|
|
471
|
+
resolvePrActionRef,
|
|
472
|
+
prIdFromRef,
|
|
435
473
|
fetchPrPayload,
|
|
436
474
|
fetchPrBranches,
|
|
437
475
|
// Exported for testing.
|
package/engine/pr-temp-clone.js
CHANGED
|
@@ -57,24 +57,9 @@ const GIT_OP_TIMEOUT_MS = 60 * 1000;
|
|
|
57
57
|
* `PrActionError` (400) on missing/unrecognized input — mirrors the read-only
|
|
58
58
|
* and choice-surface paths so the dashboard reflects a 400, not a 500.
|
|
59
59
|
*/
|
|
60
|
-
|
|
61
|
-
if (input && typeof input === 'object') {
|
|
62
|
-
if (input.host && input.slug && input.number) return input; // already normalized
|
|
63
|
-
if (input.ref && input.ref.host) return input.ref; // plan/handle carrying a ref
|
|
64
|
-
}
|
|
65
|
-
const rawUrl = input && typeof input === 'object'
|
|
66
|
-
? (typeof input.url === 'string' ? input.url.trim() : '')
|
|
67
|
-
: (typeof input === 'string' ? input.trim() : '');
|
|
68
|
-
if (!rawUrl) throw new PrActionError('url required');
|
|
69
|
-
const ref = prResolve.normalizePrRef(rawUrl);
|
|
70
|
-
if (!ref) throw new PrActionError(`unrecognized PR reference: ${JSON.stringify(rawUrl.slice(0, 120))}`);
|
|
71
|
-
return ref;
|
|
72
|
-
}
|
|
60
|
+
const _resolveRef = (input) => prResolve.resolvePrActionRef(input, PrActionError);
|
|
73
61
|
|
|
74
|
-
|
|
75
|
-
if (!ref) return null;
|
|
76
|
-
return ref.id || (ref.host && ref.slug && ref.number ? `${ref.host}:${ref.slug}#${ref.number}` : null);
|
|
77
|
-
}
|
|
62
|
+
const _prId = prResolve.prIdFromRef;
|
|
78
63
|
|
|
79
64
|
/** Filesystem-safe slug for a PR id (used in the ephemeral dir name). */
|
|
80
65
|
function _safeDirSlug(prId) {
|
package/engine/pr-track.js
CHANGED
|
@@ -56,24 +56,9 @@ const TRACK_RECOMMENDED_TARGET = 'clone-keep';
|
|
|
56
56
|
* missing/unrecognized input so the dashboard reflects a 400 — mirrors the
|
|
57
57
|
* read-only and choice-surface paths.
|
|
58
58
|
*/
|
|
59
|
-
|
|
60
|
-
if (input && typeof input === 'object') {
|
|
61
|
-
if (input.host && input.slug && input.number) return input; // already normalized
|
|
62
|
-
if (input.ref && input.ref.host) return input.ref; // plan/handle carrying a ref
|
|
63
|
-
}
|
|
64
|
-
const rawUrl = input && typeof input === 'object'
|
|
65
|
-
? (typeof input.url === 'string' ? input.url.trim() : '')
|
|
66
|
-
: (typeof input === 'string' ? input.trim() : '');
|
|
67
|
-
if (!rawUrl) throw new PrActionError('url required');
|
|
68
|
-
const ref = prResolve.normalizePrRef(rawUrl);
|
|
69
|
-
if (!ref) throw new PrActionError(`unrecognized PR reference: ${JSON.stringify(rawUrl.slice(0, 120))}`);
|
|
70
|
-
return ref;
|
|
71
|
-
}
|
|
59
|
+
const _resolveRef = (input) => prResolve.resolvePrActionRef(input, PrActionError);
|
|
72
60
|
|
|
73
|
-
|
|
74
|
-
if (!ref) return null;
|
|
75
|
-
return ref.id || (ref.host && ref.slug && ref.number ? `${ref.host}:${ref.slug}#${ref.number}` : null);
|
|
76
|
-
}
|
|
61
|
+
const _prId = prResolve.prIdFromRef;
|
|
77
62
|
|
|
78
63
|
// ── Choice surface (Clone & keep implied) ─────────────────────────────────────
|
|
79
64
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2317",
|
|
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"
|