acuvo-code 0.2.0
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 +328 -0
- package/ENTERPRISE.md +927 -0
- package/LICENSE +120 -0
- package/README.md +1245 -0
- package/ROADMAP.md +556 -0
- package/bin/acuvo-mcp.mjs +208 -0
- package/bin/acuvo.mjs +3108 -0
- package/lib/acceptance-consent.mjs +168 -0
- package/lib/acceptance.mjs +859 -0
- package/lib/account.mjs +226 -0
- package/lib/acuvo-dir.mjs +72 -0
- package/lib/acuvo-models.mjs +141 -0
- package/lib/apply-patch.mjs +570 -0
- package/lib/ask-user.mjs +173 -0
- package/lib/audit.mjs +530 -0
- package/lib/auto-lease.mjs +174 -0
- package/lib/background.mjs +842 -0
- package/lib/best-of.mjs +334 -0
- package/lib/board.mjs +232 -0
- package/lib/breaker.mjs +93 -0
- package/lib/budget.mjs +1375 -0
- package/lib/builtin-skills.mjs +135 -0
- package/lib/cache-floor.mjs +204 -0
- package/lib/chain.mjs +303 -0
- package/lib/changed-paths.mjs +84 -0
- package/lib/chat.mjs +434 -0
- package/lib/checkpoint.mjs +637 -0
- package/lib/child-lifetime.mjs +71 -0
- package/lib/cli-args.mjs +1255 -0
- package/lib/code-review.mjs +1382 -0
- package/lib/colour.mjs +82 -0
- package/lib/command.mjs +2847 -0
- package/lib/compact.mjs +1151 -0
- package/lib/completion.mjs +515 -0
- package/lib/creative-engines.mjs +779 -0
- package/lib/db-inspect.mjs +1624 -0
- package/lib/delete.mjs +111 -0
- package/lib/design-loop.mjs +570 -0
- package/lib/diff-preview.mjs +1044 -0
- package/lib/doctor.mjs +2139 -0
- package/lib/dropped.mjs +216 -0
- package/lib/edit-diagnostics.mjs +277 -0
- package/lib/edit.mjs +460 -0
- package/lib/env-file.mjs +250 -0
- package/lib/escalate.mjs +702 -0
- package/lib/evaluate.mjs +284 -0
- package/lib/fetch-text.mjs +952 -0
- package/lib/fleet-budget.mjs +256 -0
- package/lib/gh.mjs +1536 -0
- package/lib/git.mjs +1341 -0
- package/lib/github.mjs +261 -0
- package/lib/h2.mjs +194 -0
- package/lib/handoff.mjs +417 -0
- package/lib/hooks.mjs +626 -0
- package/lib/http-probe.mjs +907 -0
- package/lib/image-director.mjs +322 -0
- package/lib/image-edit.mjs +522 -0
- package/lib/imagegen.mjs +998 -0
- package/lib/interrupt.mjs +234 -0
- package/lib/learned.mjs +353 -0
- package/lib/lease-watch.mjs +115 -0
- package/lib/lease.mjs +868 -0
- package/lib/localize.mjs +834 -0
- package/lib/log-tail.mjs +1052 -0
- package/lib/login.mjs +157 -0
- package/lib/lsp.mjs +1613 -0
- package/lib/mcp-consent.mjs +377 -0
- package/lib/mcp-defaults.mjs +780 -0
- package/lib/mcp-server.mjs +1343 -0
- package/lib/mcp.mjs +1263 -0
- package/lib/media.mjs +1283 -0
- package/lib/memory-workspace.mjs +179 -0
- package/lib/model-json.mjs +132 -0
- package/lib/model-tier.mjs +171 -0
- package/lib/model.mjs +1445 -0
- package/lib/parallel.mjs +144 -0
- package/lib/perchance.mjs +210 -0
- package/lib/plan-coherence.mjs +1461 -0
- package/lib/plan-ledger.mjs +981 -0
- package/lib/plan.mjs +461 -0
- package/lib/policy.mjs +783 -0
- package/lib/prefix-order.mjs +38 -0
- package/lib/project-memory.mjs +127 -0
- package/lib/prompt.mjs +109 -0
- package/lib/python.mjs +862 -0
- package/lib/rcfile.mjs +853 -0
- package/lib/read-window.mjs +743 -0
- package/lib/refute-tools.mjs +34 -0
- package/lib/refute.mjs +806 -0
- package/lib/repl-driver.mjs +264 -0
- package/lib/repl.mjs +324 -0
- package/lib/replay.mjs +1218 -0
- package/lib/repo-map.mjs +1101 -0
- package/lib/report.mjs +419 -0
- package/lib/search-rank.mjs +99 -0
- package/lib/search.mjs +659 -0
- package/lib/secret-paths.mjs +54 -0
- package/lib/session.mjs +1017 -0
- package/lib/skills.mjs +703 -0
- package/lib/slash.mjs +356 -0
- package/lib/spawn-argv.mjs +1151 -0
- package/lib/spend.mjs +250 -0
- package/lib/steer.mjs +280 -0
- package/lib/stream.mjs +253 -0
- package/lib/stuck.mjs +712 -0
- package/lib/subagent.mjs +749 -0
- package/lib/terminal-graphics.mjs +171 -0
- package/lib/tool-prefix.mjs +226 -0
- package/lib/tool-shortlist.mjs +162 -0
- package/lib/tools.mjs +2333 -0
- package/lib/tsserver.mjs +423 -0
- package/lib/turn.mjs +5672 -0
- package/lib/untrusted-block.mjs +271 -0
- package/lib/verify-claim.mjs +299 -0
- package/lib/vision.mjs +330 -0
- package/lib/voice-task.mjs +561 -0
- package/lib/warm-provider.mjs +255 -0
- package/lib/websearch.mjs +401 -0
- package/lib/workspace.mjs +928 -0
- package/lib/write-approval.mjs +235 -0
- package/lib/write-many.mjs +162 -0
- package/package.json +62 -0
- package/scripts/bundle.mjs +768 -0
- package/scripts/cache-floor.mjs +176 -0
- package/scripts/machine.mjs +226 -0
- package/scripts/test.mjs +139 -0
- package/skills/accessibility.md +87 -0
- package/skills/acuvo-design-system.md +123 -0
- package/skills/animation.md +84 -0
- package/skills/api-design.md +82 -0
- package/skills/auth-and-sessions.md +78 -0
- package/skills/build-with-a-framework.md +101 -0
- package/skills/colour-and-contrast.md +112 -0
- package/skills/creative-engines.md +81 -0
- package/skills/css-layout.md +85 -0
- package/skills/data-and-charts.md +77 -0
- package/skills/debugging.md +76 -0
- package/skills/designing-by-looking.md +84 -0
- package/skills/error-handling.md +78 -0
- package/skills/forms-and-validation.md +93 -0
- package/skills/nextjs-app-router.md +75 -0
- package/skills/page-composition.md +103 -0
- package/skills/performance.md +77 -0
- package/skills/plan-before-building.md +52 -0
- package/skills/planning-and-delegating.md +72 -0
- package/skills/refactoring.md +70 -0
- package/skills/security-basics.md +76 -0
- package/skills/state-management.md +73 -0
- package/skills/supabase-multitenant.md +72 -0
- package/skills/typescript-strict.md +90 -0
- package/skills/typography.md +135 -0
- package/skills/verify-your-own-work.md +62 -0
- package/skills/web-app-quality.md +62 -0
- package/skills/working-in-the-background.md +64 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ── ⚠️⚠️ A HELPER CHILD MUST NEVER DECIDE WHEN ITS OWNER EXITS ──────────────
|
|
3
|
+
*
|
|
4
|
+
* This module exists because the same defect was found FOUR times in one night,
|
|
5
|
+
* in four unrelated files, and each time it presented as something else.
|
|
6
|
+
*
|
|
7
|
+
* The shape: we `spawn` a long-lived helper — a REPL driver, tsserver, an LSP,
|
|
8
|
+
* an MCP server — with `stdio: ['pipe','pipe','pipe']`. Node then keeps the
|
|
9
|
+
* event loop alive for that child AND, separately, for each of its three pipes.
|
|
10
|
+
* A process with no work left cannot exit. It does not crash and it does not
|
|
11
|
+
* report anything; it simply sits there, which is indistinguishable from being
|
|
12
|
+
* busy. Measured 2026-08-12: it made a 44-second test suite look like a
|
|
13
|
+
* five-minute one, and a stranger's fresh clone of the public repo exit 1.
|
|
14
|
+
*
|
|
15
|
+
* ⭐ THE FOUR HANDLES ARE SEPARATE. `child.unref()` releases the process handle
|
|
16
|
+
* and NOTHING ELSE — stdin, stdout and stderr are three more libuv handles and
|
|
17
|
+
* any one of them holds the loop open on its own. Unreffing three of four is a
|
|
18
|
+
* hang. That is precisely the mistake this file exists to stop repeating.
|
|
19
|
+
*
|
|
20
|
+
* ⭐ UNREF DOES NOT DETACH OR SILENCE. Data still flows, replies still arrive,
|
|
21
|
+
* the child still runs. Unref removes exactly one thing: "a helper is open" as
|
|
22
|
+
* a reason for the owner to stay alive. While a request is genuinely in flight,
|
|
23
|
+
* that request's own timeout timer keeps the loop up — which is the correct
|
|
24
|
+
* reason to be waiting, and the only one.
|
|
25
|
+
*
|
|
26
|
+
* ⚠️ AND KILLING IS NOT A SUBSTITUTE. `killProcessTree` spawns `taskkill` on
|
|
27
|
+
* Windows and returns before the child is gone, so a kill-then-exit path is a
|
|
28
|
+
* race that the busy machine loses. Detaching is a guarantee; killing is
|
|
29
|
+
* housekeeping. Do both, in that order of trust.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Stop a spawned helper from holding its owner's event loop open.
|
|
34
|
+
*
|
|
35
|
+
* Safe to call on a stubbed child in a test, on a child that has already
|
|
36
|
+
* exited, and more than once.
|
|
37
|
+
*
|
|
38
|
+
* @param {import('node:child_process').ChildProcess | null | undefined} child
|
|
39
|
+
* @returns {boolean} whether anything was unref'd — false for a stub with no handles
|
|
40
|
+
*/
|
|
41
|
+
export function detachChild(child) {
|
|
42
|
+
if (!child) return false;
|
|
43
|
+
let touched = false;
|
|
44
|
+
try { if (typeof child.unref === 'function') { child.unref(); touched = true; } } catch { /* stub */ }
|
|
45
|
+
for (const pipe of [child.stdin, child.stdout, child.stderr]) {
|
|
46
|
+
try { if (pipe && typeof pipe.unref === 'function') { pipe.unref(); touched = true; } } catch { /* closed */ }
|
|
47
|
+
}
|
|
48
|
+
return touched;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Remove a session from a registry ONLY if that registry still holds this exact
|
|
53
|
+
* session.
|
|
54
|
+
*
|
|
55
|
+
* ⚠️ THE BUG THIS PREVENTS: `child.on('exit')` fires asynchronously — long after
|
|
56
|
+
* a reset removed the entry and a later call registered a REPLACEMENT under the
|
|
57
|
+
* same key. An unconditional `map.delete(key)` in that late handler removes the
|
|
58
|
+
* LIVE successor, so the next reset answers "nothing was running" while a real
|
|
59
|
+
* child is still there, and no code path can ever release it.
|
|
60
|
+
*
|
|
61
|
+
* @param {Map<any, any>} registry
|
|
62
|
+
* @param {any} key
|
|
63
|
+
* @param {any} session the session THIS handler belongs to
|
|
64
|
+
* @returns {boolean} whether the entry was removed
|
|
65
|
+
*/
|
|
66
|
+
export function deleteIfCurrent(registry, key, session) {
|
|
67
|
+
if (!registry || typeof registry.get !== 'function') return false;
|
|
68
|
+
if (registry.get(key) !== session) return false;
|
|
69
|
+
registry.delete(key);
|
|
70
|
+
return true;
|
|
71
|
+
}
|