demobite 1.3.0 → 1.3.1
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 +1 -2
- package/package.json +4 -4
- package/scripts/check-release.mjs +8 -0
- package/scripts/release.mjs +48 -0
- package/scripts/check-aliases.mjs +0 -42
package/README.md
CHANGED
|
@@ -150,9 +150,8 @@ The default installer also attempts to register that MCP with Claude Code when t
|
|
|
150
150
|
| `skill/` | Studio-connected recorder instructions, login, upload, and Retake. |
|
|
151
151
|
| `scripts/` | Shared browser recording, trimming, and timing calibration. |
|
|
152
152
|
| `recorder/` | Standalone skill and local video finishing tools. |
|
|
153
|
-
| `aliases/` | `agentic-recorder` and `demobites` aliases for the same launcher. |
|
|
154
153
|
|
|
155
|
-
|
|
154
|
+
The same package is published under three names, `demobite`, `agentic-recorder` and `demobites`, always at the same version; `npx agentic-recorder@latest` and `npx demobites@latest` do exactly what `npx demobite@latest` does. Run it again to update the installed skill. For publishing instructions, see [RELEASING.md](RELEASING.md).
|
|
156
155
|
|
|
157
156
|
Found something confusing or have an example to share? [Open an issue](https://github.com/demobites/agentic-recorder/issues). Include your operating system, agent, and recorder version. Remove keys, cookies, and private app data from logs or recordings before attaching them.
|
|
158
157
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "demobite",
|
|
3
|
-
"version": "1.3.
|
|
4
|
-
"description": "The DemoBites agentic recorder
|
|
3
|
+
"version": "1.3.1",
|
|
4
|
+
"description": "The DemoBites agentic recorder — you prompt, it films a real browser, and DemoBites turns the take into an editable demo bite.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"demobite": "launcher/index.mjs"
|
|
7
7
|
},
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"type": "module",
|
|
38
38
|
"scripts": {
|
|
39
|
-
"
|
|
40
|
-
"prepublishOnly": "node scripts/check-
|
|
39
|
+
"release": "node scripts/release.mjs",
|
|
40
|
+
"prepublishOnly": "node scripts/check-release.mjs"
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// prepublishOnly guard: a bare `npm publish` ships ONE of the three names and
|
|
3
|
+
// leaves the other two behind, which is exactly what the founder refused on
|
|
4
|
+
// 2026-09-15. Publish through `npm run release`.
|
|
5
|
+
if (process.env.DEMOBITE_RELEASE !== "1") {
|
|
6
|
+
console.error("Refusing a bare npm publish: demobite, agentic-recorder and demobites ship together. Run: npm run release");
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// RELEASE (founder law, 2026-09-15): one package, three names, one version.
|
|
3
|
+
// `demobite`, `agentic-recorder` and `demobites` on npm are the SAME full
|
|
4
|
+
// package (launcher, skill, recorder, scripts), published together at the
|
|
5
|
+
// same version. No aliases, no caret ranges, nothing to strand.
|
|
6
|
+
//
|
|
7
|
+
// npm run release publish package.json's version under all three names
|
|
8
|
+
// npm run release -- --dry-run
|
|
9
|
+
//
|
|
10
|
+
// For each name the script writes package.json with that name and a bin of
|
|
11
|
+
// the same name, runs `npm publish`, and restores the original package.json
|
|
12
|
+
// (also on failure). A bare `npm publish` is refused by prepublishOnly unless
|
|
13
|
+
// this script set DEMOBITE_RELEASE, so nobody ships one name alone.
|
|
14
|
+
import fs from "node:fs";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
import { spawnSync } from "node:child_process";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
|
|
19
|
+
export const NAMES = ["demobite", "agentic-recorder", "demobites"];
|
|
20
|
+
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
21
|
+
const pkgPath = path.join(root, "package.json");
|
|
22
|
+
const original = fs.readFileSync(pkgPath, "utf8");
|
|
23
|
+
const base = JSON.parse(original);
|
|
24
|
+
const dryRun = process.argv.includes("--dry-run");
|
|
25
|
+
if (base.name !== "demobite") { console.error(`package.json name is ${base.name}; expected demobite (a previous release did not restore it?)`); process.exit(1); }
|
|
26
|
+
|
|
27
|
+
const published = [];
|
|
28
|
+
try {
|
|
29
|
+
for (const name of NAMES) {
|
|
30
|
+
const pkg = { ...base, name, bin: { [name]: "launcher/index.mjs" } };
|
|
31
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
32
|
+
console.log(`\n── ${name}@${base.version}${dryRun ? " (dry run)" : ""}`);
|
|
33
|
+
const r = spawnSync("npm", ["publish", "--access", "public", ...(dryRun ? ["--dry-run"] : [])], { cwd: root, stdio: "inherit", env: { ...process.env, DEMOBITE_RELEASE: "1" } });
|
|
34
|
+
if (r.status !== 0) { console.error(`\n${name}@${base.version} did not publish (exit ${r.status}). Published so far: ${published.join(", ") || "none"}. Fix and rerun; npm refuses to republish a version that already landed, so bump the patch if some names went out.`); process.exit(r.status ?? 1); }
|
|
35
|
+
published.push(name);
|
|
36
|
+
}
|
|
37
|
+
} finally {
|
|
38
|
+
fs.writeFileSync(pkgPath, original);
|
|
39
|
+
}
|
|
40
|
+
if (dryRun) { console.log(`\nDry run ok for ${NAMES.join(", ")} at ${base.version}.`); process.exit(0); }
|
|
41
|
+
console.log(`\nPublished ${NAMES.join(", ")} at ${base.version}. Verifying the registry…`);
|
|
42
|
+
let bad = false;
|
|
43
|
+
for (const name of NAMES) {
|
|
44
|
+
const v = spawnSync("npm", ["view", `${name}@${base.version}`, "version"], { encoding: "utf8" }).stdout.trim();
|
|
45
|
+
console.log(` ${v.endsWith(base.version) ? "✓" : "✗"} ${name} → ${v || "(not visible yet)"}`);
|
|
46
|
+
if (!v.endsWith(base.version)) bad = true;
|
|
47
|
+
}
|
|
48
|
+
if (bad) console.error("Some names are not visible yet; npm can take a minute. Check again with: npm view <name> version");
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// ALIAS GUARD (founder law, 2026-09-09): `agentic-recorder` and `demobites` on
|
|
3
|
-
// npm are aliases of this package. They depend on `demobite` with a caret
|
|
4
|
-
// range, so minor and patch releases flow through automatically, but a MAJOR
|
|
5
|
-
// bump silently strands them on the old major. This guard runs before every
|
|
6
|
-
// publish of demobite (prepublishOnly) and in CI, and refuses to continue if
|
|
7
|
-
// any alias's dependency range no longer covers the version about to ship.
|
|
8
|
-
//
|
|
9
|
-
// When it fails: bump the range in aliases/<name>/package.json (and the alias
|
|
10
|
-
// version), publish each alias from the founder's own terminal, then publish
|
|
11
|
-
// demobite. See RELEASING.md.
|
|
12
|
-
import fs from "node:fs";
|
|
13
|
-
import path from "node:path";
|
|
14
|
-
import { fileURLToPath } from "node:url";
|
|
15
|
-
|
|
16
|
-
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
17
|
-
const main = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
|
|
18
|
-
const aliasesDir = path.join(root, "aliases");
|
|
19
|
-
const [major] = main.version.split(".").map(Number);
|
|
20
|
-
|
|
21
|
-
let failed = false;
|
|
22
|
-
for (const name of fs.readdirSync(aliasesDir)) {
|
|
23
|
-
const pkgPath = path.join(aliasesDir, name, "package.json");
|
|
24
|
-
if (!fs.existsSync(pkgPath)) continue;
|
|
25
|
-
const alias = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
26
|
-
const range = alias.dependencies?.demobite ?? "";
|
|
27
|
-
const m = /^\^(\d+)\./.exec(range);
|
|
28
|
-
const covered = m && Number(m[1]) === major;
|
|
29
|
-
const line = `${alias.name.padEnd(18)} depends on demobite ${range.padEnd(8)} → ${covered ? "covers" : "DOES NOT COVER"} ${main.version}`;
|
|
30
|
-
console.log((covered ? " ✓ " : " ✗ ") + line);
|
|
31
|
-
if (!covered) failed = true;
|
|
32
|
-
const bin = fs.readFileSync(path.join(aliasesDir, name, "index.mjs"), "utf8");
|
|
33
|
-
if (!bin.includes('import "demobite/launcher/index.mjs"')) {
|
|
34
|
-
console.log(` ✗ ${alias.name} does not import the demobite launcher`);
|
|
35
|
-
failed = true;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if (failed) {
|
|
39
|
-
console.error("\nAlias guard failed: an npm alias would strand on the old major. Update aliases/*/package.json (range + version), publish the aliases, then publish demobite. See RELEASING.md.");
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
console.log("alias guard: ok");
|