acuvo-code 0.4.2 → 0.4.3

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/ENTERPRISE.md CHANGED
@@ -189,7 +189,7 @@ are the numbers to quote. Counting is the first thing a reviewer does.
189
189
 
190
190
  ⚠️ **This said "18 shipped files", then "41", then "90", then "101", then "108", and every
191
191
  one went stale in turn.** The package ships **120 files — 118 in `lib/`, 2 in
192
- `bin/` — about 77954 lines**, with **236 test files** beside them (counted 2026-08-22).
192
+ `bin/` — about 78091 lines**, with **237 test files** beside them (counted 2026-08-22).
193
193
 
194
194
  ⭐ **AND THE 108 WENT STALE IN THE MOST INSTRUCTIVE WAY POSSIBLE: THREE OF THE FILES IT
195
195
  MISSED WERE REACHABLE FROM NOTHING.** `wiring-reach.test.mjs` was naming
package/lib/turn.mjs CHANGED
@@ -5135,8 +5135,54 @@ function providerPinWarning(outcome) {
5135
5135
  * and no file on disk. The counted lines below come from the executor's return
5136
5136
  * values, which is the only place that knows.
5137
5137
  */
5138
+ /**
5139
+ * ── ⭐⭐⭐ A CONVERSATION IS NOT A BUILD, AND MUST NOT REPORT LIKE ONE ────────
5140
+ *
5141
+ * Roman asked "hi how are you" and got back: a round header, the answer twice,
5142
+ * "No files changed", "⚠ NOTHING WAS RUN, so nothing here is verified", a token
5143
+ * count, a cache percentage and a budget ledger. *"it shouldn't say that stuff."*
5144
+ *
5145
+ * ⭐ HE IS RIGHT, AND EVERY ONE OF THOSE LINES IS CORRECT. They exist because a
5146
+ * BUILD that silently changed nothing, or claimed a test passed without running
5147
+ * it, is a real and expensive failure — those lines are the honesty machinery.
5148
+ * But honesty machinery aimed at a greeting is just noise, and noise is how a
5149
+ * user learns to stop reading the warnings that matter.
5150
+ *
5151
+ * ⚠️ THE RULE IS NOT "BE QUIET", IT IS "REPORT WHAT HAPPENED". A turn that wrote
5152
+ * nothing and ran nothing has nothing to verify, so the verification notice is
5153
+ * answering a question nobody asked. The moment a file is written or a command
5154
+ * runs, every line comes back — including on the same session's next turn.
5155
+ *
5156
+ * ⚠️ ERRORS, WARNINGS AND STOP REASONS ARE NEVER SUPPRESSED. Quiet applies only
5157
+ * to the accounting of a turn that did nothing; a turn that FAILED did something
5158
+ * and says so.
5159
+ */
5160
+ export function isConversationalTurn(outcome) {
5161
+ if (!outcome?.ok) return false;
5162
+ /**
5163
+ * ── ⚠️ ZERO TOOL CALLS, NOT "WROTE NOTHING" — MY FIRST RULE WAS TOO BROAD ──
5164
+ *
5165
+ * It asked "did it write or run anything", which made a turn that READ a file
5166
+ * conversational. That is wrong: the user asked it to look at something, it
5167
+ * did, and "No files changed" is a real answer to a real question. An existing
5168
+ * guard caught it — *"a run that truly did nothing still says so plainly"*,
5169
+ * driven with a single `read_file`.
5170
+ *
5171
+ * ⭐ The line is between USING A TOOL and answering from the conversation. A
5172
+ * greeting calls nothing at all, and that is the only case with no work to
5173
+ * account for.
5174
+ */
5175
+ return (outcome.executed ?? []).length === 0;
5176
+ }
5177
+
5138
5178
  export function formatSummary(outcome) {
5139
5179
  const lines = [];
5180
+ /**
5181
+ * Computed once, up here, so every gate below reads the same fact — the shape
5182
+ * where two call sites recompute "did anything happen" and quietly disagree is
5183
+ * one this codebase has paid for repeatedly.
5184
+ */
5185
+ const quiet = isConversationalTurn(outcome);
5140
5186
 
5141
5187
  if (!outcome.ok) {
5142
5188
  lines.push('');
@@ -5216,7 +5262,12 @@ export function formatSummary(outcome) {
5216
5262
  * ours to make.
5217
5263
  */
5218
5264
  const ranAProcess = outcome.executed.some((e) => PROCESS_STARTING_VERBS.has(e.name) && e.result?.ok === true);
5219
- lines.push(ranAProcess
5265
+ /**
5266
+ * ⚠️ NOT ON A CONVERSATIONAL TURN. "No files changed" answers "did the build
5267
+ * do anything?" — a question nobody asked by saying hello. The sentence is
5268
+ * correct and, aimed at a greeting, it is noise.
5269
+ */
5270
+ if (!quiet) lines.push(ranAProcess
5220
5271
  ? 'No files were written through the file tools — but a command ran, and a command can '
5221
5272
  + 'change files this count cannot see. Check `git status` if that matters.'
5222
5273
  : 'No files changed.');
@@ -5350,7 +5401,17 @@ export function formatSummary(outcome) {
5350
5401
  for (const f of p.findings.slice(0, 4)) lines.push(` ${f}`);
5351
5402
  }
5352
5403
  }
5353
- } else if (outcome.allowRun && (outcome.maxRounds ?? 1) > 1) {
5404
+ } else if (outcome.allowRun && (outcome.maxRounds ?? 1) > 1 && !quiet) {
5405
+ /**
5406
+ * ⚠️ `!quiet` — A TURN THAT WROTE NOTHING HAS NOTHING TO VERIFY. This
5407
+ * warning exists because a BUILD that claims a test passed without running
5408
+ * it is an expensive lie. Printed under a greeting it is answering a
5409
+ * question nobody asked, and a warning that fires when it does not apply
5410
+ * is how people learn to stop reading warnings.
5411
+ *
5412
+ * ⚠️ IT COMES STRAIGHT BACK the moment a file is written or a command
5413
+ * runs — including on the very next turn of the same session.
5414
+ */
5354
5415
  /**
5355
5416
  * ⚠️ IT NAMES THE CATEGORY, NOT ONE TOOL. This line used to end "the model
5356
5417
  * never called run_command", and by the time three separate verbs could
@@ -5476,7 +5537,8 @@ export function formatSummary(outcome) {
5476
5537
  }
5477
5538
 
5478
5539
  const cost = outcome.usage?.cost;
5479
- if (typeof cost === 'number') {
5540
+ // ⚠️ A greeting does not need a token count, a cache percentage and a price.
5541
+ if (typeof cost === 'number' && !quiet) {
5480
5542
  const tokens = outcome.usage?.total_tokens;
5481
5543
  const roundsPart = outcome.roundsUsed > 1 ? ` · ${outcome.roundsUsed} rounds` : '';
5482
5544
  lines.push('');
@@ -5512,7 +5574,12 @@ export function formatSummary(outcome) {
5512
5574
  * cost, so the total is an estimate" clause, and a second copy of that
5513
5575
  * arithmetic is how the two would disagree.
5514
5576
  */
5515
- if (typeof outcome.budgetReport === 'string' && outcome.budgetReport) {
5577
+ /**
5578
+ * ⚠️ `!quiet` — a budget ledger under a greeting is the same noise as the
5579
+ * token count above it. `/cost` exists for anyone who wants the number, and a
5580
+ * turn that spends anything real prints it unprompted.
5581
+ */
5582
+ if (typeof outcome.budgetReport === 'string' && outcome.budgetReport && !quiet) {
5516
5583
  lines.push('');
5517
5584
  lines.push(outcome.budgetReport);
5518
5585
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "acuvo-code",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "Acuvo Code — the terminal client for the Acuvo capability registry. Zero dependencies, by design.",
5
5
  "type": "module",
6
6
  "bin": {