create-kudzu 0.1.159 → 0.1.160
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/README.md +6 -4
- package/ai.mjs +19 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Use `--no-install` to create the files without installing dependencies.
|
|
|
16
16
|
|
|
17
17
|
## Optional AI authoring guidance
|
|
18
18
|
|
|
19
|
-
`create-kudzu@0.1.
|
|
19
|
+
`create-kudzu@0.1.160` provides optional local AI developer tools with managed check cancellation:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
22
|
npm create kudzu@latest my-app -- --ai
|
|
@@ -55,9 +55,11 @@ npm run ai -- check --timeout-ms 600000
|
|
|
55
55
|
process group on Unix or process tree on Windows and reports failure.
|
|
56
56
|
Under the existing `KUDZU_AI_DELIVERY_GROUP=1` managed-runner contract, Unix
|
|
57
57
|
checks inherit their outer group so a hard group cancellation also reaches
|
|
58
|
-
their ordinary descendants.
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
their ordinary descendants. On Linux, a check-local timeout or interruption
|
|
59
|
+
reads only that check's `/proc` subtree, including worker-thread children.
|
|
60
|
+
Other Unix hosts use bounded `ps` PID/parent-PID inspection. Both stop only
|
|
61
|
+
the check's descendant snapshot, preserve sibling work, and report inspection
|
|
62
|
+
errors as failures.
|
|
61
63
|
- Full stdout/stderr are retained in a unique `.kudzu-ai/check-*/output.log`.
|
|
62
64
|
Long successful checks return only the last 512 bytes. Failed checks return
|
|
63
65
|
bounded head/tail excerpts and the first recognized diagnostic in the first
|
package/ai.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn, spawnSync } from "node:child_process"
|
|
2
|
+
import { readFileSync, readdirSync } from "node:fs"
|
|
2
3
|
import { mkdir, mkdtemp, open, readFile, realpath } from "node:fs/promises"
|
|
3
4
|
import { dirname, join } from "node:path"
|
|
4
5
|
import { fileURLToPath } from "node:url"
|
|
@@ -56,7 +57,24 @@ export async function check(root, timeoutMs = 300000) {
|
|
|
56
57
|
if (killed.status !== 0) error = killed.error?.message ?? killed.stderr ?? "Could not terminate check tree"
|
|
57
58
|
} else {
|
|
58
59
|
const pids = [managed ? child.pid : -child.pid]
|
|
59
|
-
if (managed) {
|
|
60
|
+
if (managed && process.platform === "linux") {
|
|
61
|
+
// Inspect only this subtree; worker threads can also own child processes.
|
|
62
|
+
for (let index = 0; index < pids.length; index++) {
|
|
63
|
+
let tasks
|
|
64
|
+
try { tasks = readdirSync(`/proc/${pids[index]}/task`) } catch (failure) {
|
|
65
|
+
if (failure.code !== "ENOENT") error = failure.message
|
|
66
|
+
continue
|
|
67
|
+
}
|
|
68
|
+
for (const task of tasks) try {
|
|
69
|
+
const text = readFileSync(`/proc/${pids[index]}/task/${task}/children`, "utf8").trim()
|
|
70
|
+
const children = text ? text.split(/\s+/).map(Number) : []
|
|
71
|
+
if (children.some(pid => !Number.isSafeInteger(pid) || pid <= 1 || pid === process.pid)) throw new Error("Invalid managed check process children")
|
|
72
|
+
for (const pid of children) if (!pids.includes(pid)) pids.push(pid)
|
|
73
|
+
} catch (failure) {
|
|
74
|
+
if (failure.code !== "ENOENT") error = failure.message
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
} else if (managed) {
|
|
60
78
|
// Keep the outer group alive on this tool's timeout; stop only its ordinary descendants.
|
|
61
79
|
const table = spawnSync("ps", ["-A", "-o", "pid=", "-o", "ppid="], { encoding: "utf8", timeout: 5000, maxBuffer: 1024 * 1024 })
|
|
62
80
|
if (table.status !== 0) error = table.error?.message || table.stderr?.trim() || "Could not inspect managed check descendants"
|