clankerbend 0.1.0 → 0.1.2

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 (38) hide show
  1. package/DEVELOPERS.md +6 -6
  2. package/README.md +31 -14
  3. package/apps/README.md +3 -3
  4. package/apps/sticky-notes/README.md +2 -2
  5. package/apps/sticky-notes/{onewhack.manifest.json → clankerbend.manifest.json} +1 -1
  6. package/apps/sticky-notes/package.json +3 -3
  7. package/apps/sticky-notes/public/app.js +42 -9
  8. package/apps/sticky-notes/src/sticky-notes-app.js +17 -21
  9. package/apps/vim-nav/README.md +22 -22
  10. package/apps/vim-nav/{onewhack.manifest.json → clankerbend.manifest.json} +4 -4
  11. package/apps/vim-nav/package.json +3 -3
  12. package/apps/vim-nav/public/app.js +44 -11
  13. package/apps/vim-nav/public/index.html +2 -2
  14. package/apps/vim-nav/server.mjs +2 -2
  15. package/apps/vim-nav/src/vim-nav-app.js +5 -5
  16. package/assets/clankerbend-banner.webp +0 -0
  17. package/assets/clankerbend-demo-thumbnail.webp +0 -0
  18. package/assets/clankerbend.svg +26 -0
  19. package/cli.mjs +22 -11
  20. package/docs/app-lifecycle.md +9 -9
  21. package/docs/app-manifest.md +4 -4
  22. package/docs/author-guide.md +5 -5
  23. package/docs/launcher-profiles.md +45 -10
  24. package/docs/protocol.md +248 -241
  25. package/host/README.md +4 -4
  26. package/host/src/app-registry.js +8 -6
  27. package/host/src/codex-desktop-cdp-adapter.js +85 -65
  28. package/host/src/codex-desktop-renderer-bridge.js +839 -270
  29. package/host/src/index.js +186 -34
  30. package/launch/accounts.mjs +360 -0
  31. package/launch/codex-mux-adapter.mjs +175 -0
  32. package/launch/profiles.mjs +40 -16
  33. package/launch/runtime-paths.mjs +9 -6
  34. package/launch/test-accounts.mjs +71 -0
  35. package/package.json +12 -10
  36. package/scripts/release-npm.mjs +1 -2
  37. package/server.mjs +21 -14
  38. package/assets/onewhack.jpg +0 -0
@@ -0,0 +1,26 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 520" role="img" aria-labelledby="title desc">
2
+ <title id="title">ClankerBend</title>
3
+ <desc id="desc">ClankerBend banner: mod your clanker with OneWill.ai</desc>
4
+ <rect width="1200" height="520" fill="#fbfbf8"/>
5
+ <g transform="translate(600 208)">
6
+ <rect x="-162" y="-118" width="324" height="236" rx="42" fill="#f7fbff" stroke="#17324d" stroke-width="10"/>
7
+ <rect x="-108" y="-58" width="216" height="104" rx="28" fill="#17324d"/>
8
+ <circle cx="-48" cy="-7" r="9" fill="#f7fbff"/>
9
+ <path d="M33 -7h50" stroke="#f7fbff" stroke-width="10" stroke-linecap="round"/>
10
+ <path d="M-92 68c34 25 150 25 184 0" fill="none" stroke="#2368a2" stroke-width="12" stroke-linecap="round"/>
11
+ <path d="M-174 -34h-68M174 -34h68" stroke="#17324d" stroke-width="12" stroke-linecap="round"/>
12
+ <circle cx="-256" cy="-34" r="18" fill="#2b83c6" stroke="#17324d" stroke-width="8"/>
13
+ <circle cx="256" cy="-34" r="18" fill="#2b83c6" stroke="#17324d" stroke-width="8"/>
14
+ <path d="M-78 120l-30 64M78 120l30 64" stroke="#17324d" stroke-width="12" stroke-linecap="round"/>
15
+ <circle cx="-118" cy="204" r="26" fill="#2b83c6" stroke="#17324d" stroke-width="8"/>
16
+ <circle cx="118" cy="204" r="26" fill="#2b83c6" stroke="#17324d" stroke-width="8"/>
17
+ <g transform="translate(196 -126) rotate(-28)">
18
+ <rect x="-22" y="-18" width="222" height="36" rx="18" fill="#17324d"/>
19
+ <rect x="-144" y="-55" width="150" height="110" rx="24" fill="#df9441" stroke="#17324d" stroke-width="8"/>
20
+ <path d="M-118 -40v80M-82 -48v96M-46 -44v88" stroke="#f0b56a" stroke-width="7" stroke-linecap="round"/>
21
+ </g>
22
+ </g>
23
+ <text x="600" y="405" text-anchor="middle" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="58" font-weight="800" fill="#080808">mod your clanker</text>
24
+ <text x="600" y="462" text-anchor="middle" font-family="ui-monospace, SFMono-Regular, Menlo, monospace" font-size="46" fill="#080808">with OneWill.ai</text>
25
+ <text x="600" y="76" text-anchor="middle" font-family="Arial Black, Arial, sans-serif" font-size="62" font-weight="900" fill="#df6f24" stroke="#742f16" stroke-width="4" paint-order="stroke">CLANKERBEND</text>
26
+ </svg>
package/cli.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import { readFileSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
- import { launchOneWhackCodex } from "./server.mjs";
5
+ import { launchClankerBendCodex } from "./server.mjs";
6
6
 
7
7
  const ROOT = dirname(fileURLToPath(import.meta.url));
8
8
  const PACKAGE_JSON = JSON.parse(readFileSync(join(ROOT, "package.json"), "utf8"));
@@ -17,7 +17,7 @@ try {
17
17
  async function main(argv) {
18
18
  const [command, ...args] = argv;
19
19
 
20
- if (!command || command === "help" || command === "--help" || command === "-h") {
20
+ if (command === "help" || command === "--help" || command === "-h") {
21
21
  printHelp();
22
22
  return;
23
23
  }
@@ -27,9 +27,15 @@ async function main(argv) {
27
27
  return;
28
28
  }
29
29
 
30
+ if (!command || command.startsWith("-")) {
31
+ const options = parseCodexArgs(argv);
32
+ await launchClankerBendCodex(options);
33
+ return;
34
+ }
35
+
30
36
  if (command === "codex") {
31
37
  const options = parseCodexArgs(args);
32
- await launchOneWhackCodex(options);
38
+ await launchClankerBendCodex(options);
33
39
  return;
34
40
  }
35
41
 
@@ -48,6 +54,8 @@ function parseCodexArgs(args) {
48
54
  options.mock = true;
49
55
  } else if (arg === "--state-dir") {
50
56
  options.stateDir = requiredArg(args[++index], "--state-dir value");
57
+ } else if (arg === "--account") {
58
+ options.accountId = requiredArg(args[++index], "--account id");
51
59
  } else if (arg === "--help" || arg === "-h") {
52
60
  printCodexHelp();
53
61
  process.exit(0);
@@ -59,29 +67,32 @@ function parseCodexArgs(args) {
59
67
  }
60
68
 
61
69
  function printHelp() {
62
- console.log(`OneWhack
70
+ console.log(`ClankerBend
63
71
 
64
72
  Usage:
65
- clankerbend codex [--mock] [--state-dir path]
73
+ clankerbend [--mock] [--state-dir path] [--account id]
74
+ clankerbend codex [--mock] [--state-dir path] [--account id]
66
75
  clankerbend help
67
76
  clankerbend --version
68
77
 
69
78
  Environment:
70
- ONEWILL_ONEWHACK_STATE_DIR Override OneWhack runtime state directory.
71
- ONEWILL_ONEWHACK_TOKEN Use a specific bearer token for host endpoints.
72
- ONEWILL_ONEWHACK_DISABLE_AUTH=1 Disable bearer auth for local development only.
79
+ ONEWILL_CLANKERBEND_STATE_DIR Override ClankerBend runtime state directory.
80
+ ONEWILL_CLANKERBEND_TOKEN Use a specific bearer token for host endpoints.
81
+ ONEWILL_CLANKERBEND_DISABLE_AUTH=1 Disable bearer auth for local development only.
73
82
  `);
74
83
  }
75
84
 
76
85
  function printCodexHelp() {
77
- console.log(`OneWhack Codex launcher
86
+ console.log(`ClankerBend Codex launcher
78
87
 
79
88
  Usage:
80
- clankerbend codex [--mock] [--state-dir path]
89
+ clankerbend [--mock] [--state-dir path] [--account id]
90
+ clankerbend codex [--mock] [--state-dir path] [--account id]
81
91
 
82
92
  Options:
83
93
  --mock Start against a mock transcript instead of Codex Desktop.
84
- --state-dir path Override OneWhack runtime state directory.
94
+ --state-dir path Override ClankerBend runtime state directory.
95
+ --account id Start with a saved ClankerBend Codex account profile.
85
96
  `);
86
97
  }
87
98
 
@@ -1,12 +1,12 @@
1
- # OneWhack App Lifecycle
1
+ # ClankerBend App Lifecycle
2
2
 
3
- OneWhack separates app installation from profile activation.
3
+ ClankerBend separates app installation from profile activation.
4
4
 
5
5
  ## Install
6
6
 
7
- Installing records a manifest in the runtime registry. The public `onewhack`
7
+ Installing records a manifest in the runtime registry. The public `clankerbend`
8
8
  CLI intentionally does not expose app-management commands; app installation is
9
- a product configuration concern for the running OneWhack experience.
9
+ a product configuration concern for the running ClankerBend experience.
10
10
 
11
11
  The registry stores app id, version, manifest path, distribution metadata,
12
12
  bundle kind, source path, and install time. The current host loads bundled
@@ -14,10 +14,10 @@ manifests and additional manifest paths from this registry; copying directories
14
14
  or tarballs into a managed app store is reserved for installer tooling. The
15
15
  runtime root defaults to:
16
16
 
17
- - macOS: `~/Library/Application Support/OneWill/OneWhack`
18
- - Linux: `~/.local/state/onewill/onewhack`
17
+ - macOS: `~/Library/Application Support/OneWill/ClankerBend`
18
+ - Linux: `~/.local/state/onewill/clankerbend`
19
19
 
20
- Set `ONEWILL_ONEWHACK_STATE_DIR` to override the root location.
20
+ Set `ONEWILL_CLANKERBEND_STATE_DIR` to override the root location.
21
21
 
22
22
  `distribution.integrity` is required. Local development installs can use
23
23
  `integrity: "dev-local"`. Downloaded packages should be installed with a real
@@ -30,7 +30,7 @@ Profiles decide which installed apps are active.
30
30
  Enablement is profile-scoped. A host can launch with the default profile or a
31
31
  custom user profile while using the same app registry. The default registry
32
32
  config path is `registry.json` under the runtime state directory, and launchers
33
- may override it with `ONEWILL_ONEWHACK_REGISTRY_CONFIG`.
33
+ may override it with `ONEWILL_CLANKERBEND_REGISTRY_CONFIG`.
34
34
 
35
35
  ## Start
36
36
 
@@ -52,7 +52,7 @@ revalidate a replacement manifest and update the installed app record while
52
52
  preserving profile enablement.
53
53
 
54
54
  A future updater can replace the app bundle, validate the new manifest, compare
55
- `oneWhackVersion`, and update the registry atomically.
55
+ `clankerbendVersion`, and update the registry atomically.
56
56
 
57
57
  ## Remove
58
58
 
@@ -1,6 +1,6 @@
1
- # OneWhack App Manifest
1
+ # ClankerBend App Manifest
2
2
 
3
- OneWhack apps are installed and launched from a `onewhack.manifest.json` file.
3
+ ClankerBend apps are installed and launched from a `clankerbend.manifest.json` file.
4
4
  The manifest is the stable contract between the app bundle and the host. The
5
5
  host loads local manifests through this schema. The schema also reserves npm
6
6
  packages, tarballs, and binary-style bundles for installer tooling.
@@ -9,7 +9,7 @@ packages, tarballs, and binary-style bundles for installer tooling.
9
9
 
10
10
  ```json
11
11
  {
12
- "oneWhackVersion": "0.1",
12
+ "clankerbendVersion": "0.1",
13
13
  "appId": "onewill.example.app",
14
14
  "version": "0.1.0",
15
15
  "name": "Example App",
@@ -69,7 +69,7 @@ Every app package must declare the same capabilities and permissions regardless
69
69
  of distribution shape.
70
70
 
71
71
  The current host accepts manifest paths. Future installers may accept an app
72
- directory containing `onewhack.manifest.json`, a `.tgz`/`.tar.gz` bundle, or an
72
+ directory containing `clankerbend.manifest.json`, a `.tgz`/`.tar.gz` bundle, or an
73
73
  `npm:<package>` spec. Packaged sources should be verified with an external
74
74
  `sha256-...` integrity value before extraction. The manifest still carries
75
75
  `distribution.integrity` so registries and update tools can reason about the
@@ -1,4 +1,4 @@
1
- # OneWhack App Author Guide
1
+ # ClankerBend App Author Guide
2
2
 
3
3
  The public reference apps are `apps/vim-nav` and `apps/sticky-notes`. VimNav
4
4
  demonstrates transcript navigation and annotations. Sticky Notes demonstrates
@@ -57,7 +57,7 @@ export function createExampleApp(options = {}) {
57
57
  }
58
58
  ```
59
59
 
60
- The host wraps app state and actions in OneWhack HTTP envelopes. The app should
60
+ The host wraps app state and actions in ClankerBend HTTP envelopes. The app should
61
61
  throw `context.httpError(...)` for expected validation failures.
62
62
 
63
63
  ## Transcript Annotations
@@ -87,7 +87,7 @@ own final placement, sorting, and collision avoidance:
87
87
  ```
88
88
 
89
89
  Apps should not mutate Codex Desktop DOM directly for placement. Renderer
90
- bridges register through `window.__oneWhackRuntime` and call host-owned
90
+ bridges register through `window.__clankerbendRuntime` and call host-owned
91
91
  annotation APIs.
92
92
 
93
93
  ## Text Ranges And Composer Context
@@ -100,14 +100,14 @@ contribute `selectionActions` from app state. Apps request overlays through
100
100
 
101
101
  Apps should not query Codex Desktop DOM, position floating menus, render
102
102
  composer chips, or write into the composer directly. Those details belong in
103
- the OneWhack host adapter and renderer runtime.
103
+ the ClankerBend host adapter and renderer runtime.
104
104
 
105
105
  ## Actions
106
106
 
107
107
  Actions are routed through:
108
108
 
109
109
  ```text
110
- POST /onewhack/apps/:appId/actions
110
+ POST /clankerbend/apps/:appId/actions
111
111
  ```
112
112
 
113
113
  An action must include non-empty `appId`, `actionId`, and `type`. Action IDs are
@@ -1,4 +1,4 @@
1
- # OneWhack Launcher Profiles
1
+ # ClankerBend Launcher Profiles
2
2
 
3
3
  A launcher profile is the host configuration for one Codex Desktop session. It
4
4
  selects app manifests, chooses the default side-panel app, and decides which
@@ -7,11 +7,14 @@ renderer bridge provides transcript primitives.
7
7
  ## Commands
8
8
 
9
9
  ```sh
10
- npx clankerbend codex
11
- npx clankerbend codex --mock
10
+ npx clankerbend
11
+ npx clankerbend --mock
12
12
  ```
13
13
 
14
- In this repository, `npm start` runs `clankerbend codex` through the local package.
14
+ `npx clankerbend codex` is equivalent to `npx clankerbend` while Codex is the
15
+ only supported surface.
16
+
17
+ In this repository, `npm start` runs `clankerbend` through the local package.
15
18
  `npm run start:mock` runs the same profile without Codex Desktop.
16
19
 
17
20
  ## Profile Construction
@@ -28,20 +31,52 @@ Provider selection comes from renderer bridge metadata. The first primary bridge
28
31
  normally provides transcript snapshot, order, navigation, and highlight.
29
32
 
30
33
  The built-in Navigate profile always includes VimNav and Sticky Notes.
31
- Additional apps are product configuration owned by the running OneWhack
34
+ Additional apps are product configuration owned by the running ClankerBend
32
35
  experience and stored in the runtime registry.
33
36
 
34
- The launcher also reads `ONEWILL_ONEWHACK_REGISTRY_CONFIG`, defaulting to
37
+ The launcher also reads `ONEWILL_CLANKERBEND_REGISTRY_CONFIG`, defaulting to
35
38
  `registry.json` under the runtime state directory, and merges enabled app
36
- manifests from the selected registry profile. Set `ONEWILL_ONEWHACK_PROFILE` to
39
+ manifests from the selected registry profile. Set `ONEWILL_CLANKERBEND_PROFILE` to
37
40
  override the selected registry profile when building a custom launcher.
38
41
 
39
42
  Runtime state defaults to:
40
43
 
41
- - macOS: `~/Library/Application Support/OneWill/OneWhack`
42
- - Linux: `~/.local/state/onewill/onewhack`
44
+ - macOS: `~/Library/Application Support/OneWill/ClankerBend`
45
+ - Linux: `~/.local/state/onewill/clankerbend`
46
+
47
+ Set `ONEWILL_CLANKERBEND_STATE_DIR` to override the root state directory.
48
+
49
+ ## Codex Account Profiles
50
+
51
+ ClankerBend can remember up to 20 Codex account profiles. It still launches at
52
+ most one Codex Desktop instance at a time. Switching accounts stops the current
53
+ ClankerBend-launched Desktop process and starts the selected profile.
54
+
55
+ The `primary` profile always points at the normal Codex home:
56
+
57
+ - `CODEX_HOME` when set
58
+ - otherwise `~/.codex`
59
+
60
+ Managed profiles are created empty under the ClankerBend state directory. Each
61
+ managed profile gets its own `codex-home` and Electron user-data directory. No
62
+ auth, sessions, skills, plugins, or history are copied from the primary profile.
63
+ If the primary profile is file-auth based, the managed profile receives only a
64
+ minimal `config.toml` auth-store setting so Codex can use the same auth mode.
65
+
66
+ ClankerID exposes these operations:
43
67
 
44
- Set `ONEWILL_ONEWHACK_STATE_DIR` to override the root state directory.
68
+ - **Switch**: stop the current Desktop process and launch the selected profile.
69
+ - **Launch by default**: choose which profile ClankerBend starts next time. This
70
+ does not change the primary Codex home.
71
+ - **Make primary**: promote a managed profile into the primary Codex home.
72
+ ClankerBend first moves the old primary home to
73
+ `<primary>.backup_<timestamp>` (normally `~/.codex.backup_<timestamp>`),
74
+ preserves it as a managed account, then moves the selected managed home into
75
+ the primary Codex home.
76
+ - **Rollback**: restore a previous primary backup and move the replaced primary
77
+ to `<primary>.rollback_replaced_<timestamp>`.
78
+ - **Archive**: remove a managed profile from the active account list and move
79
+ its directories into deleted-account storage.
45
80
 
46
81
  ## Ports And Cleanup
47
82