wkappbot-code 0.3.7 → 0.3.8
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/bin/prepack.js +55 -0
- package/bin/wkappbot-code.js +15 -5
- package/package.json +4 -2
package/bin/prepack.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// prepack -- bakes the minimal web harness INTO the npm package (harness/), so `npm install wkappbot-code` wires the
|
|
3
|
+
// Claude Code hooks from the package alone: no kih or WKAppBot checkout and no reach to the harness web page (a
|
|
4
|
+
// Default-environment cloud VM allows the package registries and little else; spokesman order 2026-11-06).
|
|
5
|
+
// harness/ holds the same four files the web page serves: install.sh, wk-harness-min.tar.gz, its .sha256, version.json.
|
|
6
|
+
// The tarball is the manifest bake (tools/wk-harness-min-copy.sh, scrub gate included) minus .git and bin/linux-x64, the
|
|
7
|
+
// core binary the installer fetches on its own (part: bin); 4 MB instead of 35 MB.
|
|
8
|
+
// Env: WKAPPBOT_CODE_HARNESS_STAGE = an already baked tree to pack (selftest.sh bakes once per run; 50 s per pack saved).
|
|
9
|
+
import { spawnSync } from "node:child_process";
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
12
|
+
import { tmpdir } from "node:os";
|
|
13
|
+
import { dirname, join, resolve } from "node:path";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
|
|
16
|
+
const PKG_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
17
|
+
const KIH = resolve(PKG_DIR, "..");
|
|
18
|
+
const OUT = join(PKG_DIR, "harness");
|
|
19
|
+
const PKG = JSON.parse(readFileSync(join(PKG_DIR, "package.json"), "utf8"));
|
|
20
|
+
const die = (m) => { console.error("[wkappbot-code prepack] " + m); process.exit(1); };
|
|
21
|
+
const sh = (p) => process.platform === "win32" ? p.replace(/\\/g, "/") : p;
|
|
22
|
+
|
|
23
|
+
let stage = process.env.WKAPPBOT_CODE_HARNESS_STAGE || "";
|
|
24
|
+
let tmp = "";
|
|
25
|
+
const copy = join(KIH, "tools", "wk-harness-min-copy.sh");
|
|
26
|
+
const install = join(KIH, "webvm", "x64-build", "harness-install.sh");
|
|
27
|
+
// A copy of the package packed OUTSIDE a kih checkout (the self-update selftest's tree) has nothing to bake from: it
|
|
28
|
+
// packs without harness/ and its install falls back to the web harness. The publish packs from the checkout, and
|
|
29
|
+
// selftest x16 refuses a tgz that carries no harness/.
|
|
30
|
+
if (!existsSync(install) || (!stage && !existsSync(copy))) {
|
|
31
|
+
console.error("[wkappbot-code prepack] no kih checkout at " + KIH + ": harness/ not baked (install falls back to the web harness)");
|
|
32
|
+
process.exit(0);
|
|
33
|
+
}
|
|
34
|
+
if (!stage) {
|
|
35
|
+
tmp = mkdtempSync(join(tmpdir(), "wkc-prepack-"));
|
|
36
|
+
stage = join(tmp, "h");
|
|
37
|
+
const r = spawnSync("bash", [sh(copy), sh(KIH), sh(stage), sh(join(KIH, "tools", "wk-harness-min-manifest.txt"))],
|
|
38
|
+
{ encoding: "utf8", env: { ...process.env, GIT_CONFIG_GLOBAL: "/dev/null" } });
|
|
39
|
+
if (r.status !== 0) die("harness bake rc " + r.status + "\n" + String(r.stderr).slice(-800));
|
|
40
|
+
}
|
|
41
|
+
if (!existsSync(join(stage, "tools", "wkharness-lite.sh"))) die("the baked tree " + stage + " has no tools/wkharness-lite.sh");
|
|
42
|
+
|
|
43
|
+
rmSync(OUT, { recursive: true, force: true });
|
|
44
|
+
mkdirSync(OUT, { recursive: true });
|
|
45
|
+
const tgz = join(OUT, "wk-harness-min.tar.gz");
|
|
46
|
+
const t = spawnSync("tar", ["--exclude=./.git", "--exclude=./bin/linux-x64", "-czf", sh(tgz), "-C", sh(stage), "."], { encoding: "utf8" });
|
|
47
|
+
if (t.status !== 0) die("tar rc " + t.status + " " + t.stderr);
|
|
48
|
+
const sha = createHash("sha256").update(readFileSync(tgz)).digest("hex");
|
|
49
|
+
writeFileSync(tgz + ".sha256", sha + " wk-harness-min.tar.gz\n");
|
|
50
|
+
const count = (d) => readdirSync(d, { withFileTypes: true }).reduce((n, e) => n + (e.isDirectory() ? (e.name === ".git" ? 0 : count(join(d, e.name))) : 1), 0);
|
|
51
|
+
writeFileSync(join(OUT, "version.json"), JSON.stringify({ version: "npm-" + PKG.version + "-" + sha.slice(0, 12), sha256: sha,
|
|
52
|
+
built: new Date().toISOString().replace(/\.\d+Z$/, "Z"), files: count(stage) }) + "\n");
|
|
53
|
+
copyFileSync(install, join(OUT, "install.sh"));
|
|
54
|
+
if (tmp) rmSync(tmp, { recursive: true, force: true });
|
|
55
|
+
console.error("[wkappbot-code prepack] harness/ baked: " + sha.slice(0, 12) + " (" + readFileSync(tgz).length + " bytes)");
|
package/bin/wkappbot-code.js
CHANGED
|
@@ -45,7 +45,11 @@ const PKG_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
|
45
45
|
const PKG = JSON.parse(readFileSync(join(PKG_DIR, "package.json"), "utf8"));
|
|
46
46
|
const OPENCODE_VERSION = PKG.wkAppbotCode.opencodeVersion;
|
|
47
47
|
const OWNER_LOGIN = "kiexpert";
|
|
48
|
-
|
|
48
|
+
// The harness this package carries (harness/, baked by bin/prepack.js at pack time) comes first: it needs no checkout
|
|
49
|
+
// and no network (spokesman 2026-11-06, a Default-environment VM). WK_HARNESS_BASE overrides; the web page serves an unbaked tree.
|
|
50
|
+
const BUNDLED_HARNESS = () => join(PKG_DIR, "harness");
|
|
51
|
+
const HARNESS_BASE = () => (process.env.WK_HARNESS_BASE || (existsSync(join(BUNDLED_HARNESS(), "install.sh")) ? pathToFileURL(BUNDLED_HARNESS()).href
|
|
52
|
+
: "https://kiexpert.github.io/wkappbot-kih/webvm/x64/harness")).replace(/\/+$/, "");
|
|
49
53
|
const HARNESS_DIR = () => process.env.WK_HARNESS_DIR || join(homedir(), ".wk-harness");
|
|
50
54
|
const HOOKS_DIR = () => join(homedir(), ".wk-harness-hooks"); // tools/wk-global-hooks.sh install default
|
|
51
55
|
const SETTINGS = () => process.env.WK_SETTINGS || join(homedir(), ".claude", "settings.json");
|
|
@@ -485,8 +489,14 @@ function uninstall(o) {
|
|
|
485
489
|
if (isSymlink(p) || existsSync(p)) { rmSync(p, { force: true }); log("shim: removed " + p); }
|
|
486
490
|
}
|
|
487
491
|
// 4. the harness dirs we created, the plugin entry and our config folder
|
|
488
|
-
|
|
489
|
-
|
|
492
|
+
// Windows releases a just-closed handle late (EBUSY/EPERM/ENOTEMPTY), so every tree delete retries and, when it
|
|
493
|
+
// still fails, names the path and goes on with the rest instead of aborting the uninstall half way.
|
|
494
|
+
const rmTree = (p, what) => {
|
|
495
|
+
try { rmSync(p, { recursive: true, force: true, maxRetries: 10, retryDelay: 300 }); if (what) log(what + ": removed " + p); }
|
|
496
|
+
catch (e) { rc = 1; log((what || "remove") + ": could not remove " + p + " (" + (e.code || e.message) + ") -- delete it by hand"); }
|
|
497
|
+
};
|
|
498
|
+
if (st.harness && st.harness.mode === "web" && pr.harnessDirExisted !== true && existsSync(HARNESS_DIR())) rmTree(HARNESS_DIR(), "harness");
|
|
499
|
+
if (pr.hooksDirExisted !== true && existsSync(HOOKS_DIR())) rmTree(HOOKS_DIR(), "push-gate");
|
|
490
500
|
const cfgFile = join(configDir(o), "opencode.json");
|
|
491
501
|
try {
|
|
492
502
|
const c = JSON.parse(readFileSync(cfgFile, "utf8"));
|
|
@@ -498,8 +508,8 @@ function uninstall(o) {
|
|
|
498
508
|
log("config: plugin entry removed from " + cfgFile);
|
|
499
509
|
}
|
|
500
510
|
} catch {}
|
|
501
|
-
|
|
502
|
-
|
|
511
|
+
rmTree(STATE_HOME());
|
|
512
|
+
rmTree(join(configDir(o), "wkappbot-code"));
|
|
503
513
|
log("uninstall done. Kept: opencode-ai, the wkappbot core (" + ((st.bin && st.bin.dest) || binDest(o)) + ") and its skills, and this CLI (npm rm -g wkappbot-code)");
|
|
504
514
|
return rc;
|
|
505
515
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wkappbot-code",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "wkappbot-code -- Wisdom Kernel: the pinned OpenCode bridge plus the reflex harness plugin, the wkappbot core, the web harness and the latest public skills in one install",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
+
"prepack": "node bin/prepack.js",
|
|
7
8
|
"postinstall": "node bin/postinstall.js"
|
|
8
9
|
},
|
|
9
10
|
"bin": {
|
|
@@ -17,7 +18,8 @@
|
|
|
17
18
|
"plugin/*.js",
|
|
18
19
|
"opencode.json",
|
|
19
20
|
"install.sh",
|
|
20
|
-
"README.md"
|
|
21
|
+
"README.md",
|
|
22
|
+
"harness/*"
|
|
21
23
|
],
|
|
22
24
|
"wkAppbotCode": {
|
|
23
25
|
"opencodeVersion": "1.19.5"
|