balladeer 0.0.4 → 1.0.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.
Files changed (60) hide show
  1. package/LICENSE +200 -5
  2. package/README.md +154 -68
  3. package/dist/agent.d.ts +126 -0
  4. package/dist/agent.js +209 -0
  5. package/dist/cli.d.ts +34 -0
  6. package/dist/cli.js +392 -0
  7. package/dist/client.d.ts +44 -0
  8. package/dist/client.js +114 -0
  9. package/dist/commands/affected.d.ts +22 -0
  10. package/dist/commands/affected.js +122 -0
  11. package/dist/commands/check-seals.d.ts +37 -0
  12. package/dist/commands/check-seals.js +289 -0
  13. package/dist/commands/discover.d.ts +68 -0
  14. package/dist/commands/discover.js +395 -0
  15. package/dist/commands/explain.d.ts +35 -0
  16. package/dist/commands/explain.js +90 -0
  17. package/dist/commands/invite.d.ts +24 -0
  18. package/dist/commands/invite.js +197 -0
  19. package/dist/commands/mcp.d.ts +65 -0
  20. package/dist/commands/mcp.js +202 -0
  21. package/dist/commands/propose.d.ts +59 -0
  22. package/dist/commands/propose.js +262 -0
  23. package/dist/commands/repositories.d.ts +18 -0
  24. package/dist/commands/repositories.js +185 -0
  25. package/dist/commands/setup.d.ts +75 -0
  26. package/dist/commands/setup.js +1471 -0
  27. package/dist/commands/status.d.ts +35 -0
  28. package/dist/commands/status.js +482 -0
  29. package/dist/commands/touch-map.d.ts +42 -0
  30. package/dist/commands/touch-map.js +251 -0
  31. package/dist/commands/whoami.d.ts +8 -0
  32. package/dist/commands/whoami.js +79 -0
  33. package/dist/conventions.d.ts +69 -0
  34. package/dist/conventions.js +175 -0
  35. package/dist/copy.d.ts +148 -0
  36. package/dist/copy.js +459 -0
  37. package/dist/currency.d.ts +31 -0
  38. package/dist/currency.js +72 -0
  39. package/dist/gh.d.ts +80 -0
  40. package/dist/gh.js +188 -0
  41. package/dist/git.d.ts +76 -0
  42. package/dist/git.js +203 -0
  43. package/dist/markers.d.ts +76 -0
  44. package/dist/markers.js +125 -0
  45. package/dist/mcp-config.d.ts +99 -0
  46. package/dist/mcp-config.js +230 -0
  47. package/dist/release.d.ts +55 -0
  48. package/dist/release.js +67 -0
  49. package/dist/repository.d.ts +8 -0
  50. package/dist/repository.js +32 -0
  51. package/dist/seals.d.ts +48 -0
  52. package/dist/seals.js +112 -0
  53. package/dist/store.d.ts +98 -0
  54. package/dist/store.js +225 -0
  55. package/dist/touch-map.d.ts +241 -0
  56. package/dist/touch-map.js +487 -0
  57. package/dist/wire.d.ts +588 -0
  58. package/dist/wire.js +20 -0
  59. package/package.json +19 -10
  60. package/bin/balladeer.js +0 -136
package/bin/balladeer.js DELETED
@@ -1,136 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Bootstrapper for the Balladeer client (npm name: balladeer).
4
- *
5
- * This package is not the client; it installs it. On consent it downloads the
6
- * current client tarball from Balladeer's central installer endpoints, verifies
7
- * the published sha256, and `npm install -g`s the verified file, which replaces
8
- * this package in place (the client ships under the same package name).
9
- *
10
- * Flags: --yes/-y skip the prompt; --download-only fetch + verify, print the path.
11
- */
12
- const { createHash } = require("node:crypto");
13
- const { existsSync, mkdtempSync, writeFileSync, rmSync } = require("node:fs");
14
- const { tmpdir } = require("node:os");
15
- const { join } = require("node:path");
16
- const { spawnSync } = require("node:child_process");
17
- const readline = require("node:readline");
18
-
19
- const BASE = process.env.BALLADEER_INSTALL_BASE ?? "https://get.balladeer.ai";
20
- const TGZ_URL = `${BASE}/install/client.tgz`;
21
- const SHA_URL = `${BASE}/install/client.tgz.sha256`;
22
-
23
- const args = process.argv.slice(2);
24
- const yes = args.includes("--yes") || args.includes("-y");
25
- const downloadOnly = args.includes("--download-only");
26
-
27
- function fail(msg, code = 1) {
28
- console.error(msg);
29
- process.exit(code);
30
- }
31
-
32
- async function fetchBytes(url) {
33
- const res = await fetch(url, { redirect: "follow" });
34
- if (!res.ok) {
35
- fail(
36
- `error: ${url} answered ${res.status}` +
37
- (res.status === 503 ? " (the client artifact is not available on the server yet)" : ""),
38
- );
39
- }
40
- return Buffer.from(await res.arrayBuffer());
41
- }
42
-
43
- async function main() {
44
- console.error(
45
- `balladeer: this npm package is the installer, not the client.\n` +
46
- `It downloads the current Balladeer client from ${BASE}, verifies its\n` +
47
- `sha256 checksum, and installs it globally (replacing this package).\n`,
48
- );
49
-
50
- if (!yes && !downloadOnly) {
51
- if (!process.stdin.isTTY) {
52
- fail(
53
- `Non-interactive shell: re-run with --yes to install, or use the script installer:\n\n` +
54
- ` curl -fsSL ${BASE} | sh\n`,
55
- );
56
- }
57
- const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
58
- const answer = await new Promise((res) => rl.question("Install the Balladeer client now? [Y/n] ", res));
59
- rl.close();
60
- if (answer.trim() !== "" && !/^y(es)?$/i.test(answer.trim())) fail("Nothing installed.");
61
- }
62
-
63
- console.error(`downloading ${TGZ_URL} ...`);
64
- const [tgz, shaFile] = await Promise.all([fetchBytes(TGZ_URL), fetchBytes(SHA_URL)]);
65
- const expected = shaFile.toString("utf8").trim().split(/\s+/)[0];
66
- const actual = createHash("sha256").update(tgz).digest("hex");
67
- if (!/^[0-9a-f]{64}$/.test(expected) || expected !== actual) {
68
- fail(
69
- `error: checksum mismatch; refusing to install a tampered download.\n` +
70
- ` expected ${expected}\n actual ${actual}`,
71
- );
72
- }
73
- console.error(`checksum OK (sha256 ${actual.slice(0, 16)}...)`);
74
-
75
- // A private mkdtemp dir, not a predictable name in the shared tmpdir: the same posture as
76
- // the script installer's `mktemp -d`, so nothing can pre-place a file/symlink at the path.
77
- const dir = mkdtempSync(join(tmpdir(), "balladeer-"));
78
- const file = join(dir, "balladeer-client.tgz");
79
- writeFileSync(file, tgz);
80
- if (downloadOnly) {
81
- console.log(file);
82
- return;
83
- }
84
-
85
- // Volta prepends its real-node bin dir to a child tool's PATH, so a bare `npm` spawned from
86
- // here resolves to the RAW npm inside the node image and installs into that image's globals,
87
- // while the `balladeer` on the user's PATH stays Volta's shim serving THIS bootstrapper — a
88
- // split-brain where every run is the installer again. Route the install through Volta's own
89
- // npm shim so its interception updates the package image the shim actually serves.
90
- const voltaNpm = process.env.VOLTA_HOME ? join(process.env.VOLTA_HOME, "bin", "npm") : null;
91
- const npmCmd = voltaNpm && existsSync(voltaNpm) ? voltaNpm : "npm";
92
- // --ignore-scripts: the client has no install hooks, and this keeps a hostile tarball from
93
- // running code at install time (the same flag the script installer passes).
94
- const r = spawnSync(npmCmd, ["install", "-g", "--ignore-scripts", file], {
95
- stdio: "inherit",
96
- shell: process.platform === "win32",
97
- });
98
- try {
99
- rmSync(dir, { recursive: true, force: true });
100
- } catch {}
101
- if (r.status !== 0) {
102
- fail(`error: npm install -g failed (exit ${r.status ?? "?"}). Fix the npm error above and re-run \`balladeer\`.`, r.status ?? 1);
103
- }
104
-
105
- // Never report success on npm's exit code alone: prove the world changed. If `balladeer` still
106
- // resolves to this installer (or to nothing), say so honestly instead of claiming victory.
107
- const probe = spawnSync("balladeer", ["--version"], { encoding: "utf8", shell: process.platform === "win32" });
108
- const probedVersion = (probe.stdout ?? "").trim();
109
- if (probe.status !== 0 || !/^\d+\.\d+\.\d+/.test(probedVersion)) {
110
- fail(
111
- `error: npm reported success, but \`balladeer\` on your PATH is not the client yet.\n` +
112
- `Your npm setup may install globals somewhere this shell does not look, or a version\n` +
113
- `manager may be serving a stale copy. Try a fresh shell and \`balladeer --version\`,\n` +
114
- `or use the script installer:\n\n curl -fsSL ${BASE} | sh\n`,
115
- );
116
- }
117
-
118
- // Plain `balladeer login` (the client defaults to hosted central). BASE is the INSTALL host
119
- // (get.balladeer.ai), an alias that exists only for downloading — teaching it as --server
120
- // would store it as the machine's permanent server URL. A custom BALLADEER_INSTALL_BASE
121
- // means a self-hosted deploy whose central URL this bootstrapper cannot derive, so point at
122
- // the flag rather than silently teaching the hosted default.
123
- const pairHint =
124
- BASE === "https://get.balladeer.ai"
125
- ? "balladeer login"
126
- : "balladeer login --server <your central server URL>";
127
- console.error(
128
- `\n✓ Balladeer client installed (${probedVersion}).\n\n` +
129
- ` next ${pairHint} # approve in your browser; no token to copy\n` +
130
- ` then your coding agent gains get_context / consult / propose_decision\n` +
131
- ` agent or let your agent finish the wiring: paste into it -> Read ${BASE}/agent and follow it.\n\n` +
132
- ` no workspace yet? create one at https://app.balladeer.ai`,
133
- );
134
- }
135
-
136
- main().catch((err) => fail(`error: ${err?.message ?? err}`));