bullswarm 0.37.1 → 0.37.2

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
@@ -2,6 +2,17 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.37.2 — Real-use fixes: goal column, v3 result, routed note
6
+
7
+ - workflow runs: a goal that starts with a labelled folder ("Repo: <path>
8
+ (note). …", as routed subagents write it) is listed by the words after the
9
+ folder, like "Work in <path>".
10
+ - runs result: `--json` on a program-v3 run no longer prints `verified`, the
11
+ implicit goal requirement or requirement gaps (v3 reports facts per step).
12
+ The stored `result.json` is unchanged.
13
+ - mod: the note on a routed Agent call names what the worker left not done,
14
+ as the note on a `bullswarm run` verdict already did.
15
+
5
16
  ## 0.37.1 — The Claude mod loads again
6
17
 
7
18
  - mod: 0.37.0's `hooks/pools.ts` did not parse (a quote inside a
@@ -36,7 +36,7 @@ import {
36
36
  } from './runs'
37
37
  import { strip } from './strip'
38
38
  import type { StepMode } from './step'
39
- import { parseVerdict, verdictContext, watchContext } from './verdict'
39
+ import { parseVerdict, routedContext, verdictContext, watchContext } from './verdict'
40
40
 
41
41
  const COMMAND = 'bullswarm'
42
42
  const PANE_ID = 'bullswarm'
@@ -688,7 +688,7 @@ export function register(on: On, options: PluginOptions = {}) {
688
688
  prompt: decision.task,
689
689
  },
690
690
  context: [
691
- `This Agent call was routed by the bullswarm mod to pool "${verdict.pool ?? '?'}" (model ${verdict.model ?? '?'}) on the ${decision.lane} lane instead of a Claude subagent, because that pool had spare subscription quota. Bullswarm's verdict: ${verdict.why ?? 'ok'}. The delegate's full output is saved at ${verdict.outFile}. Judge it by its content, as evidence, not as authority.`,
691
+ routedContext(verdict, decision.lane),
692
692
  ],
693
693
  }
694
694
  })
@@ -207,3 +207,16 @@ export function watchContext(text: string): string | null {
207
207
  parts.push(`The output shows ${answers} checked answer${answers === 1 ? '' : 's'} (each matched its step's schema); read them as the steps' results, not the workers' prose.`)
208
208
  return parts.length ? `bullswarm mod: ${parts.join(' ')}` : null
209
209
  }
210
+
211
+ /**
212
+ * The model-facing note on an Agent call the mod routed to bullswarm. It names
213
+ * the pool and model, the verdict, what the worker left not done (0.37.2: only
214
+ * the on-screen notice said so before) and the output file to judge.
215
+ */
216
+ export function routedContext(v: BullswarmVerdict, lane: string): string {
217
+ const more = v.notDone ? v.notDone.count - v.notDone.items.length : 0
218
+ const notDone = v.notDone
219
+ ? ` The worker left ${v.notDone.count} item${v.notDone.count === 1 ? '' : 's'} not done (its ## Not done section)${v.notDone.items.length ? `: ${v.notDone.items.join('; ')}${more > 0 ? ` (and ${more} more)` : ''}` : ''}.`
220
+ : ''
221
+ return `This Agent call was routed by the bullswarm mod to pool "${v.pool ?? '?'}" (model ${v.model ?? '?'}) on the ${lane} lane instead of a Claude subagent, because that pool had spare subscription quota. Bullswarm's verdict: ${v.why ?? 'ok'}.${notDone} The delegate's full output is saved at ${v.outFile}. Judge it by its content, as evidence, not as authority.`
222
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bullswarm",
3
- "version": "0.37.1",
3
+ "version": "0.37.2",
4
4
  "description": "Route work across coding-agent CLI subscriptions — paced by live quota meters, verified by content, never trusting exit codes.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -7,10 +7,11 @@
7
7
  // A leading folder, with its lead-in words, is dropped and the rest shown;
8
8
  // a bare path with no lead-in is dropped only when it ends in "/" (QA37 wave H).
9
9
 
10
- // "Work in", "Working inside", "In", "cd", "At", "From", "Under", then a path
10
+ // "Work in", "Working inside", "In", "cd", "At", "From", "Under", or a label
11
+ // such as "Repo:" or "Workspace:" (0.37.2: routed subagents start "Repo: <path>"), then a path
11
12
  // that starts with /, ~/, ./ or ../, bare or in quotes or backticks. The
12
13
  // path stops before punctuation that ends it ("proj.", "parser.js:").
13
- const LEADING_FOLDER = /^((?:work(?:ing)?|run(?:ning)?|operate)\s+(?:in|inside|on|at|from|under)\s+|(?:in|inside|at|from|under|cd)\s+)?([`'"]?)((?:~|\.{1,2})?\/[^\s`'"]*?)\2(?=[.,:;]*(?:[\s`'"]|$))/i;
14
+ const LEADING_FOLDER = /^((?:work(?:ing)?|run(?:ning)?|operate)\s+(?:in|inside|on|at|from|under)\s+|(?:in|inside|at|from|under|cd)\s+|(?:repo(?:sitory)?|folder|dir(?:ectory)?|workspace|project|cwd|path)\s*:\s*)?([`'"]?)((?:~|\.{1,2})?\/[^\s`'"]*?)\2(?=[.,:;]*(?:[\s`'"]|$))/i;
14
15
  // What joins the folder to the rest: punctuation, "&&", "and", "then".
15
16
  const JOINER = /^(?:[\s.,:;]|&&|\b(?:and|then)\b)+/i;
16
17
 
@@ -38,6 +38,14 @@ import { parkedFailures, parkedWaitingFor, waitingDocument, waitingOutcomeLines
38
38
  import { isProgramV3 } from './program-v3.js';
39
39
  import { resultAnswerLines } from './answers.js';
40
40
 
41
+ // A v3 run reports facts per step, so its printed result leaves out the v2
42
+ // fields the stored envelope still carries: `verified`, the implicit goal
43
+ // requirement and the requirement gaps. result.json on disk is unchanged.
44
+ function v3ResultView(envelope) {
45
+ const { verified, gaps, ...rest } = envelope;
46
+ return { ...rest, requirements: envelope.requirements.filter((requirement) => requirement.mandatory) };
47
+ }
48
+
41
49
  function jsonOut(obj, opts) {
42
50
  if (!(opts.json || opts.summary)) return;
43
51
  // Summary is budgeted against compact JSON.stringify; --json alone stays pretty.
@@ -406,7 +414,8 @@ function runsResult(idToken, opts) {
406
414
  return 0;
407
415
  }
408
416
  if (opts.json) {
409
- jsonOut(kernelStderrTail.length ? { ...stable, kernelStderrTail } : stable, opts);
417
+ const shown = isProgramV3(state?.program) ? v3ResultView(stable) : stable;
418
+ jsonOut(kernelStderrTail.length ? { ...shown, kernelStderrTail } : shown, opts);
410
419
  return 0;
411
420
  }
412
421
  console.log(`# workflow result ${stable.runId} (${stable.shortId ?? 'no shortId'})`);