promptkit-os 2.0.0 → 2.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jonell (lowqualityloey)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # `promptkit-os` (npm)
2
2
 
3
- The open-source engineering control plane for AI coding agents (Claude Code, Cursor, Copilot, Antigravity, Gemini CLI) — managing task ceremony levels (L0–L3), context economy, JIT stack playbooks, and evidence-gated verification.
3
+ The open-source engineering control plane for AI coding agents (Claude Code, Cursor, Windsurf, GitHub Copilot, Cline/Roo Code, Trae, OpenCode, Aider, Gemini CLI/Antigravity) — managing task ceremony levels (L0–L3), context economy, JIT stack playbooks, and evidence-gated verification.
4
4
 
5
5
  > **Note**: This npm package is the **courier**, not the product. PromptKit OS itself is pure repository-native markdown with no runtime, no daemon, and no model lock-in — it lives at [lowqualityloey/promptkit-os](https://github.com/lowqualityloey/promptkit-os).
6
6
 
@@ -16,9 +16,11 @@ npx promptkit-os@latest --turbo --experimental
16
16
  npx promptkit-os@latest /path/to/project
17
17
  ```
18
18
 
19
- Pass-through flags: `--lite`, `--balanced`, `--turbo`, `--experimental`, `--host=`, `--target=`, `--tracking=`, `--reconfigure`.
19
+ Pass-through flags: `--lite`, `--balanced`, `--turbo`, `--experimental`, `--host=`, `--add-host=`, `--target=`, `--tracking=`, `--reconfigure`.
20
20
 
21
- Requires Node 18+ (the courier runs on Node; the installed product does not). On Windows it also requires **PowerShell 7 (`pwsh`)**, which is what `init.ps1` targets — stock Windows PowerShell 5.1 is not supported.
21
+ Requires Node 18+ (the courier runs on Node; the installed product does not) — the courier checks at startup and prints a clear error on older runtimes instead of failing on a missing `fetch`. On Windows it also requires **PowerShell 7 (`pwsh`)**, which is what `init.ps1` targets — stock Windows PowerShell 5.1 is not supported.
22
+
23
+ > The `version` in this repository's `package/package.json` is intentionally `0.0.0`: the release workflow stamps the real version from the git tag and mints the tarball integrity pin at publish time (`docs/internal/release-evaluation.md` §1 records the mechanics). Running the courier from an unstamped checkout refuses with a clear error.
22
24
 
23
25
  ## Updating an existing install
24
26
 
@@ -12,7 +12,6 @@ const { spawnSync } = require("node:child_process");
12
12
  const crypto = require("node:crypto");
13
13
  const fs = require("node:fs");
14
14
  const path = require("node:path");
15
- const os = require("node:os");
16
15
 
17
16
  const PKG = require("../package.json");
18
17
  const REPO = "lowqualityloey/promptkit-os";
@@ -39,7 +38,7 @@ const KIT_DIR = ".promptkit";
39
38
  const TARBALL_SHA256_BY_VERSION = {
40
39
  "1.10.1": "1e55459914a1c46aa71df8f9cb8ce4c9ff37d1c02d67f70e5607b3bfd4f48d4b",
41
40
  "1.11.0": "6503fdfcde286055b8c053aa0ffa8bdf244cf77df3321cccd6a8d8f780195ade",
42
- "2.0.0": "4fb5b9d85e0f19bfe333c361e00465705b60636a8026edd62c15c6f2d61cbf4b",
41
+ "2.1.0": "44a8a25e16c7abf31b412b8129ecead8bf1f0d1e3c75deb7d1cb1059d1ba9b17",
43
42
  // @pin-insert
44
43
  };
45
44
 
@@ -61,12 +60,12 @@ function passthroughFlags(argv) {
61
60
  const out = [];
62
61
  for (const arg of argv) {
63
62
  if (arg === "--force") continue; // courier-only flag, never forwarded to the installer
64
- if (known.has(arg) || arg.startsWith("--host=") || arg.startsWith("--target=") || arg.startsWith("--tracking=")) {
63
+ if (known.has(arg) || arg.startsWith("--host=") || arg.startsWith("--add-host=") || arg.startsWith("--target=") || arg.startsWith("--tracking=")) {
65
64
  out.push(arg);
66
65
  } else if (!arg.startsWith("-")) {
67
66
  out.push(arg); // positional project root
68
67
  } else {
69
- die(`unknown flag '${arg}' — pass it through after the install target, or see init --help`);
68
+ die(`unknown flag '${arg}' — the courier forwards a fixed allowlist; run the installer directly for full flags (init.sh --help / init.ps1 --help)`);
70
69
  }
71
70
  }
72
71
  return out;
@@ -144,13 +143,21 @@ async function download(url) {
144
143
  }
145
144
 
146
145
  async function extract(tarball, dest) {
147
- const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "promptkit-os-"));
148
- const tarPath = path.join(tmp, "release.tar.gz");
149
- fs.writeFileSync(tarPath, tarball);
150
-
151
- const res = spawnSync("tar", ["-xzf", tarPath, "-C", dest, "--strip-components=1"], { stdio: "inherit" });
152
- if (res.status !== 0) die("failed to extract release tarball (is `tar` available?)");
153
- fs.rmSync(tmp, { recursive: true, force: true });
146
+ // Every tar operand must stay relative: GNU tar — the first `tar` on PATH inside
147
+ // Git Bash — reads `C:\...` operands as remote host:path and dies with
148
+ // "Cannot connect to C: resolve failed", so the staging-temp-dir + absolute -C
149
+ // form broke the Windows leg wherever Git Bash leads PATH. Staging the archive
150
+ // inside `dest` (created by the caller) and extracting with cwd=dest leaves no
151
+ // absolute path in argv at all, on GNU tar, bsdtar, and POSIX tar alike.
152
+ const stagedTarball = path.join(dest, ".promptkit-release.tar.gz");
153
+ fs.writeFileSync(stagedTarball, tarball);
154
+ const res = spawnSync("tar", ["-xzf", ".promptkit-release.tar.gz", "--strip-components=1"], { cwd: dest, stdio: "inherit" });
155
+ fs.rmSync(stagedTarball, { force: true });
156
+ if (res.error) {
157
+ const hint = res.error.code === "ENOENT" ? "tar not found on PATH" : res.error.message;
158
+ die(`failed to extract release tarball: ${hint}`);
159
+ }
160
+ if (res.status !== 0) die(`failed to extract release tarball (tar exit ${res.status ?? res.signal})`);
154
161
  }
155
162
 
156
163
  function runInstaller(kitDir, args) {
@@ -159,13 +166,25 @@ function runInstaller(kitDir, args) {
159
166
  const ps = path.join(kitDir, "init.ps1");
160
167
  if (!fs.existsSync(ps)) die("init.ps1 missing from release tarball");
161
168
  const res = spawnSync("pwsh", ["-NoProfile", "-File", ps, ...args], { stdio: "inherit" });
162
- if (res.status !== 0) die("init.ps1 failed");
169
+ if (res.error) {
170
+ const hint = res.error.code === "ENOENT"
171
+ ? "pwsh not found — PowerShell 7 is required on Windows (aka.ms/powershell); or use the git-submodule door and run bash .promptkit/init.sh"
172
+ : res.error.message;
173
+ die(`failed to launch init.ps1: ${hint}`);
174
+ }
175
+ if (res.status !== 0) die(`init.ps1 failed (exit ${res.status ?? res.signal})`);
163
176
  } else {
164
177
  const sh = path.join(kitDir, "init.sh");
165
178
  if (!fs.existsSync(sh)) die("init.sh missing from release tarball");
166
179
  fs.chmodSync(sh, 0o755);
167
180
  const res = spawnSync("bash", [sh, ...args], { stdio: "inherit" });
168
- if (res.status !== 0) die("init.sh failed");
181
+ if (res.error) {
182
+ const hint = res.error.code === "ENOENT"
183
+ ? "bash not found — a POSIX shell is required to run init.sh"
184
+ : res.error.message;
185
+ die(`failed to launch init.sh: ${hint}`);
186
+ }
187
+ if (res.status !== 0) die(`init.sh failed (exit ${res.status ?? res.signal})`);
169
188
  }
170
189
  }
171
190
 
@@ -174,6 +193,14 @@ function installerArgs(args, version) {
174
193
  }
175
194
 
176
195
  async function main() {
196
+ const nodeMajor = parseInt(String(process.versions.node).split(".")[0], 10);
197
+ if (nodeMajor < 18 || typeof fetch !== "function") {
198
+ die(
199
+ `Node 18+ is required (found ${process.versions.node}) — the courier uses global fetch.\n` +
200
+ ` upgrade Node, or install via the canonical git submodule path:\n` +
201
+ ` git submodule add https://github.com/${REPO}.git .promptkit && ./.promptkit/init.sh`
202
+ );
203
+ }
177
204
  const version = PKG.version;
178
205
  if (version === "0.0.0") {
179
206
  die(
@@ -193,7 +220,7 @@ async function main() {
193
220
  " npx promptkit-os@latest --lite\n" +
194
221
  " npx promptkit-os@latest --turbo --experimental\n" +
195
222
  " npx promptkit-os@latest /path/to/project\n\n" +
196
- "Pass-through flags: --lite --balanced --turbo --experimental --host= --target= --tracking= --reconfigure\n" +
223
+ "Pass-through flags: --lite --balanced --turbo --experimental --host= --add-host= --target= --tracking= --reconfigure\n" +
197
224
  "Courier flags: --force (overlay a non-empty .promptkit/; not recommended)\n\n" +
198
225
  "Updating an existing install? Use the canonical path instead:\n" +
199
226
  " git submodule update --remote --merge .promptkit && bash .promptkit/init.sh\n\n" +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "promptkit-os",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Courier for PromptKit OS: fetches a pinned release tarball and runs the canonical installer. Not a runtime dependency.",
5
5
  "keywords": [
6
6
  "promptkit",
@@ -25,13 +25,14 @@
25
25
  },
26
26
  "files": [
27
27
  "bin/promptkit-os.js",
28
- "README.md"
28
+ "README.md",
29
+ "LICENSE"
29
30
  ],
30
31
  "engines": {
31
32
  "node": ">=18"
32
33
  },
33
34
  "scripts": {
34
- "test": "bash test/smoke.sh"
35
+ "test": "bash -c 'if [ -d test ]; then bash test/smoke.sh; fi'"
35
36
  },
36
37
  "publishConfig": {
37
38
  "access": "public",