clankerbend 0.1.0 → 0.1.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/DEVELOPERS.md +6 -6
- package/README.md +17 -13
- package/apps/README.md +3 -3
- package/apps/sticky-notes/README.md +2 -2
- package/apps/sticky-notes/{onewhack.manifest.json → clankerbend.manifest.json} +1 -1
- package/apps/sticky-notes/package.json +3 -3
- package/apps/sticky-notes/public/app.js +8 -8
- package/apps/sticky-notes/src/sticky-notes-app.js +17 -21
- package/apps/vim-nav/README.md +22 -22
- package/apps/vim-nav/{onewhack.manifest.json → clankerbend.manifest.json} +4 -4
- package/apps/vim-nav/package.json +3 -3
- package/apps/vim-nav/public/app.js +10 -10
- package/apps/vim-nav/public/index.html +2 -2
- package/apps/vim-nav/server.mjs +2 -2
- package/apps/vim-nav/src/vim-nav-app.js +5 -5
- package/assets/clankerbend-banner.webp +0 -0
- package/assets/clankerbend-demo-thumbnail.webp +0 -0
- package/assets/clankerbend.svg +26 -0
- package/cli.mjs +17 -9
- package/docs/app-lifecycle.md +9 -9
- package/docs/app-manifest.md +4 -4
- package/docs/author-guide.md +5 -5
- package/docs/launcher-profiles.md +13 -10
- package/docs/protocol.md +234 -234
- package/host/README.md +4 -4
- package/host/src/app-registry.js +6 -6
- package/host/src/codex-desktop-cdp-adapter.js +62 -64
- package/host/src/codex-desktop-renderer-bridge.js +207 -270
- package/host/src/index.js +30 -30
- package/launch/profiles.mjs +13 -13
- package/launch/runtime-paths.mjs +6 -6
- package/package.json +12 -10
- package/scripts/release-npm.mjs +1 -2
- package/server.mjs +7 -7
- package/assets/onewhack.jpg +0 -0
package/host/src/index.js
CHANGED
|
@@ -3,9 +3,9 @@ import http from "node:http";
|
|
|
3
3
|
import { randomBytes } from "node:crypto";
|
|
4
4
|
import { extname, join, relative, resolve } from "node:path";
|
|
5
5
|
|
|
6
|
-
export const
|
|
6
|
+
export const CLANKERBEND_VERSION = "0.1";
|
|
7
7
|
|
|
8
|
-
export class
|
|
8
|
+
export class ClankerBendHttpError extends Error {
|
|
9
9
|
constructor(status, code, message, detail) {
|
|
10
10
|
super(message);
|
|
11
11
|
this.status = status;
|
|
@@ -15,7 +15,7 @@ export class OneWhackHttpError extends Error {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function httpError(status, code, message, detail) {
|
|
18
|
-
return new
|
|
18
|
+
return new ClankerBendHttpError(status, code, message, detail);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export function createMockTranscriptAdapter(options = {}) {
|
|
@@ -91,11 +91,11 @@ export function mockAnchor(anchorId, order, inferredRole, textPreview) {
|
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
export class
|
|
94
|
+
export class ClankerBendHost {
|
|
95
95
|
constructor(options = {}) {
|
|
96
|
-
this.protocolVersion = options.protocolVersion ||
|
|
97
|
-
this.hostId = options.hostId || "onewill.
|
|
98
|
-
this.hostName = options.hostName || "
|
|
96
|
+
this.protocolVersion = options.protocolVersion || CLANKERBEND_VERSION;
|
|
97
|
+
this.hostId = options.hostId || "onewill.clankerbend.host";
|
|
98
|
+
this.hostName = options.hostName || "ClankerBend Host";
|
|
99
99
|
this.localDevInsecure = options.localDevInsecure === true;
|
|
100
100
|
this.token = this.localDevInsecure ? "" : (isNonEmptyString(options.token) ? options.token : createSessionToken());
|
|
101
101
|
this.runDir = options.runDir || null;
|
|
@@ -274,12 +274,12 @@ export class OneWhackHost {
|
|
|
274
274
|
const app = this.apps.get(appId);
|
|
275
275
|
if (!app || !this.state.host.url) return null;
|
|
276
276
|
const base = `${this.state.host.url.replace(/\/$/, "")}/apps/${encodeURIComponent(app.appId)}/`;
|
|
277
|
-
return this.token ? `${base}#
|
|
277
|
+
return this.token ? `${base}#clankerbend_token=${encodeURIComponent(this.token)}` : base;
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
hostManifest() {
|
|
281
281
|
return {
|
|
282
|
-
|
|
282
|
+
clankerbendVersion: this.protocolVersion,
|
|
283
283
|
hostId: this.hostId,
|
|
284
284
|
hostName: this.hostName,
|
|
285
285
|
capabilities: this.capabilities(),
|
|
@@ -307,7 +307,7 @@ export class OneWhackHost {
|
|
|
307
307
|
}
|
|
308
308
|
return cleanObject({
|
|
309
309
|
...loadedManifest,
|
|
310
|
-
|
|
310
|
+
clankerbendVersion: this.protocolVersion,
|
|
311
311
|
appId: app.appId,
|
|
312
312
|
name: app.name || app.appId,
|
|
313
313
|
version: app.version || loadedManifest.version,
|
|
@@ -324,7 +324,7 @@ export class OneWhackHost {
|
|
|
324
324
|
|
|
325
325
|
publicState() {
|
|
326
326
|
return {
|
|
327
|
-
protocolName: "
|
|
327
|
+
protocolName: "clankerbend",
|
|
328
328
|
protocolVersion: this.protocolVersion,
|
|
329
329
|
sequence: this.state.sequence,
|
|
330
330
|
generatedAt: this.state.generatedAt,
|
|
@@ -481,26 +481,26 @@ export class OneWhackHost {
|
|
|
481
481
|
res.writeHead(204).end();
|
|
482
482
|
return;
|
|
483
483
|
}
|
|
484
|
-
if (url.pathname.startsWith("/
|
|
485
|
-
this.fail(res, 401, "unauthorized", "missing or invalid
|
|
484
|
+
if (url.pathname.startsWith("/clankerbend/") && !this.authorized(req)) {
|
|
485
|
+
this.fail(res, 401, "unauthorized", "missing or invalid ClankerBend token");
|
|
486
486
|
return;
|
|
487
487
|
}
|
|
488
488
|
|
|
489
|
-
if (url.pathname === "/
|
|
490
|
-
if (url.pathname === "/
|
|
491
|
-
if (url.pathname === "/
|
|
492
|
-
if (url.pathname === "/
|
|
493
|
-
if (url.pathname === "/
|
|
494
|
-
if (url.pathname === "/
|
|
495
|
-
if (url.pathname === "/
|
|
496
|
-
if (url.pathname === "/
|
|
497
|
-
if (url.pathname === "/
|
|
498
|
-
if (url.pathname === "/
|
|
499
|
-
if (url.pathname === "/
|
|
500
|
-
if (url.pathname === "/
|
|
501
|
-
if (url.pathname === "/
|
|
502
|
-
if (url.pathname === "/
|
|
503
|
-
if (url.pathname === "/
|
|
489
|
+
if (url.pathname === "/clankerbend/manifest" && req.method === "GET") return this.ok(res, this.hostManifest());
|
|
490
|
+
if (url.pathname === "/clankerbend/state" && req.method === "GET") return this.ok(res, this.publicState());
|
|
491
|
+
if (url.pathname === "/clankerbend/events" && req.method === "GET") return this.handleEvents(req, res);
|
|
492
|
+
if (url.pathname === "/clankerbend/apps" && req.method === "GET") return this.ok(res, { apps: this.appSummaries() });
|
|
493
|
+
if (url.pathname === "/clankerbend/panel/open" && req.method === "POST") return this.openPanelEndpoint(req, res);
|
|
494
|
+
if (url.pathname === "/clankerbend/transcript/scroll" && req.method === "POST") return this.scrollEndpoint(req, res);
|
|
495
|
+
if (url.pathname === "/clankerbend/transcript/highlight" && req.method === "POST") return this.highlightEndpoint(req, res);
|
|
496
|
+
if (url.pathname === "/clankerbend/transcript/highlight-range" && req.method === "POST") return this.highlightRangeEndpoint(req, res);
|
|
497
|
+
if (url.pathname === "/clankerbend/selection" && req.method === "POST") return this.selectionEndpoint(req, res);
|
|
498
|
+
if (url.pathname === "/clankerbend/overlay/open" && req.method === "POST") return this.overlayOpenEndpoint(req, res);
|
|
499
|
+
if (url.pathname === "/clankerbend/overlay/close" && req.method === "POST") return this.overlayCloseEndpoint(req, res);
|
|
500
|
+
if (url.pathname === "/clankerbend/composer/context" && req.method === "POST") return this.composerContextEndpoint(req, res);
|
|
501
|
+
if (url.pathname === "/clankerbend/composer/context/remove" && req.method === "POST") return this.composerContextRemoveEndpoint(req, res);
|
|
502
|
+
if (url.pathname === "/clankerbend/composer/draft" && req.method === "POST") return this.composerDraftEndpoint(req, res);
|
|
503
|
+
if (url.pathname === "/clankerbend/composer/submit" && req.method === "POST") return this.composerSubmitEndpoint(req, res);
|
|
504
504
|
|
|
505
505
|
const appRoute = this.parseAppRoute(url.pathname);
|
|
506
506
|
if (appRoute && req.method === "GET" && appRoute.tail === "/manifest") return this.ok(res, this.appManifest(appRoute.appId));
|
|
@@ -524,7 +524,7 @@ export class OneWhackHost {
|
|
|
524
524
|
}
|
|
525
525
|
|
|
526
526
|
parseAppRoute(pathname) {
|
|
527
|
-
if (!pathname.startsWith("/
|
|
527
|
+
if (!pathname.startsWith("/clankerbend/apps/")) return null;
|
|
528
528
|
const parts = pathname.split("/");
|
|
529
529
|
const appId = decodeURIComponent(parts[3] || "");
|
|
530
530
|
if (!appId) return null;
|
|
@@ -594,7 +594,7 @@ export class OneWhackHost {
|
|
|
594
594
|
this.state.panel.error = null;
|
|
595
595
|
} else {
|
|
596
596
|
this.state.panel.status = "waiting";
|
|
597
|
-
this.state.panel.error = result?.error || "Open a Codex thread, then try opening the
|
|
597
|
+
this.state.panel.error = result?.error || "Open a Codex thread, then try opening the ClankerBend panel again.";
|
|
598
598
|
}
|
|
599
599
|
this.touchAndBroadcast();
|
|
600
600
|
return this.ok(res, result || { ok: false, error: "panel unavailable" });
|
package/launch/profiles.mjs
CHANGED
|
@@ -8,33 +8,33 @@ import {
|
|
|
8
8
|
providersFromRendererBridges,
|
|
9
9
|
readAppManifest
|
|
10
10
|
} from "../host/src/app-registry.js";
|
|
11
|
-
import {
|
|
11
|
+
import { clankerbendRuntimePaths } from "./runtime-paths.mjs";
|
|
12
12
|
|
|
13
13
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
14
14
|
const ROOT_DIR = join(__dirname, "..");
|
|
15
15
|
|
|
16
16
|
export const PROFILE_NAVIGATE = "navigate";
|
|
17
|
-
export const VIM_NAV_MANIFEST_PATH = join(ROOT_DIR, "apps/vim-nav/
|
|
18
|
-
export const STICKY_NOTES_MANIFEST_PATH = join(ROOT_DIR, "apps/sticky-notes/
|
|
17
|
+
export const VIM_NAV_MANIFEST_PATH = join(ROOT_DIR, "apps/vim-nav/clankerbend.manifest.json");
|
|
18
|
+
export const STICKY_NOTES_MANIFEST_PATH = join(ROOT_DIR, "apps/sticky-notes/clankerbend.manifest.json");
|
|
19
19
|
export const CODEX_DESKTOP_RENDERER_BRIDGE_PATH = join(ROOT_DIR, "host/src/codex-desktop-renderer-bridge.js");
|
|
20
20
|
export const VIM_NAV_APP_ID = readAppManifest(VIM_NAV_MANIFEST_PATH).appId;
|
|
21
21
|
export const STICKY_NOTES_APP_ID = readAppManifest(STICKY_NOTES_MANIFEST_PATH).appId;
|
|
22
22
|
|
|
23
23
|
export async function navigateProfile(options = {}) {
|
|
24
|
-
const runtimePaths =
|
|
24
|
+
const runtimePaths = clankerbendRuntimePaths({ stateDir: options.stateDir });
|
|
25
25
|
const runDir = options.runDir || runtimePaths.runDir;
|
|
26
26
|
const profile = await loadProfileFromManifests({
|
|
27
27
|
profileId: PROFILE_NAVIGATE,
|
|
28
28
|
name: "Navigate",
|
|
29
29
|
description: "Codex Desktop with OneWill Navigate transcript controls.",
|
|
30
|
-
hostId: "onewill.
|
|
31
|
-
hostName: "
|
|
30
|
+
hostId: "onewill.clankerbend.host",
|
|
31
|
+
hostName: "ClankerBend Navigate",
|
|
32
32
|
runDir,
|
|
33
33
|
runtimePaths,
|
|
34
34
|
defaultPanelAppId: VIM_NAV_APP_ID,
|
|
35
35
|
manifestPaths: configuredManifestPaths([VIM_NAV_MANIFEST_PATH, STICKY_NOTES_MANIFEST_PATH], {
|
|
36
36
|
registryConfigPath: options.registryConfigPath || runtimePaths.registryConfigPath,
|
|
37
|
-
registryProfileId: options.registryProfileId
|
|
37
|
+
registryProfileId: options.registryProfileId
|
|
38
38
|
})
|
|
39
39
|
});
|
|
40
40
|
const bridge = codexDesktopRendererBridge();
|
|
@@ -44,9 +44,9 @@ export async function navigateProfile(options = {}) {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export function configuredManifestPaths(baseManifestPaths, options = {}) {
|
|
47
|
-
const runtimePaths =
|
|
48
|
-
const configPath = options.registryConfigPath || process.env.
|
|
49
|
-
const profileId = options.registryProfileId || process.env.
|
|
47
|
+
const runtimePaths = clankerbendRuntimePaths({ stateDir: options.stateDir });
|
|
48
|
+
const configPath = options.registryConfigPath || process.env.ONEWILL_CLANKERBEND_REGISTRY_CONFIG || runtimePaths.registryConfigPath;
|
|
49
|
+
const profileId = options.registryProfileId || process.env.ONEWILL_CLANKERBEND_PROFILE || "default";
|
|
50
50
|
const config = loadRegistryConfig(configPath);
|
|
51
51
|
return mergeManifestPaths(baseManifestPaths, enabledManifestPathsFromConfig(config, profileId));
|
|
52
52
|
}
|
|
@@ -81,13 +81,13 @@ function codexDesktopRendererBridge() {
|
|
|
81
81
|
export function printLaunchStatus(profile, host, options = {}) {
|
|
82
82
|
const mode = options.mockMode ? "Mock transcript" : "Codex Desktop";
|
|
83
83
|
console.log("");
|
|
84
|
-
console.log(`
|
|
84
|
+
console.log(`ClankerBend: ${profile.name}`);
|
|
85
85
|
console.log(`Status: ${mode} is running`);
|
|
86
86
|
console.log(`Panel: ${host.state.panel.url}`);
|
|
87
87
|
console.log(`Host: ${host.state.host.url}`);
|
|
88
88
|
if (!options.mockMode) {
|
|
89
|
-
console.log("Codex Desktop is open. Use the Browser side panel for
|
|
89
|
+
console.log("Codex Desktop is open. Use the Browser side panel for ClankerBend apps.");
|
|
90
90
|
}
|
|
91
|
-
console.log("Press Ctrl+C to stop
|
|
91
|
+
console.log("Press Ctrl+C to stop ClankerBend and the launched Codex Desktop process.");
|
|
92
92
|
console.log("");
|
|
93
93
|
}
|
package/launch/runtime-paths.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { homedir, platform } from "node:os";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
|
|
4
|
-
export function
|
|
5
|
-
if (process.env.
|
|
4
|
+
export function clankerbendStateDir() {
|
|
5
|
+
if (process.env.ONEWILL_CLANKERBEND_STATE_DIR) return process.env.ONEWILL_CLANKERBEND_STATE_DIR;
|
|
6
6
|
if (platform() === "darwin") {
|
|
7
|
-
return join(homedir(), "Library/Application Support/OneWill/
|
|
7
|
+
return join(homedir(), "Library/Application Support/OneWill/ClankerBend");
|
|
8
8
|
}
|
|
9
|
-
return join(homedir(), ".local/state/onewill/
|
|
9
|
+
return join(homedir(), ".local/state/onewill/clankerbend");
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export function
|
|
13
|
-
const root = options.stateDir ||
|
|
12
|
+
export function clankerbendRuntimePaths(options = {}) {
|
|
13
|
+
const root = options.stateDir || clankerbendStateDir();
|
|
14
14
|
return {
|
|
15
15
|
root,
|
|
16
16
|
runDir: join(root, "run"),
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clankerbend",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "OneWill
|
|
5
|
+
"description": "OneWill ClankerBend protocol host and public reference apps.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"codex",
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
"desktop",
|
|
11
11
|
"extensions"
|
|
12
12
|
],
|
|
13
|
-
"homepage": "https://github.com/OneWillAI/
|
|
13
|
+
"homepage": "https://github.com/OneWillAI/clankerbend#readme",
|
|
14
14
|
"bugs": {
|
|
15
|
-
"url": "https://github.com/OneWillAI/
|
|
15
|
+
"url": "https://github.com/OneWillAI/clankerbend/issues"
|
|
16
16
|
},
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
|
-
"url": "git+https://github.com/OneWillAI/
|
|
19
|
+
"url": "git+https://github.com/OneWillAI/clankerbend.git"
|
|
20
20
|
},
|
|
21
21
|
"bin": {
|
|
22
22
|
"clankerbend": "./cli.mjs"
|
|
@@ -24,17 +24,19 @@
|
|
|
24
24
|
"files": [
|
|
25
25
|
"cli.mjs",
|
|
26
26
|
"server.mjs",
|
|
27
|
-
"assets/
|
|
27
|
+
"assets/clankerbend-banner.webp",
|
|
28
|
+
"assets/clankerbend-demo-thumbnail.webp",
|
|
29
|
+
"assets/clankerbend.svg",
|
|
28
30
|
"scripts/release-npm.mjs",
|
|
29
31
|
"host/src",
|
|
30
32
|
"launch",
|
|
31
33
|
"apps/README.md",
|
|
32
|
-
"apps/vim-nav/
|
|
34
|
+
"apps/vim-nav/clankerbend.manifest.json",
|
|
33
35
|
"apps/vim-nav/package.json",
|
|
34
36
|
"apps/vim-nav/public",
|
|
35
37
|
"apps/vim-nav/src",
|
|
36
38
|
"apps/vim-nav/README.md",
|
|
37
|
-
"apps/sticky-notes/
|
|
39
|
+
"apps/sticky-notes/clankerbend.manifest.json",
|
|
38
40
|
"apps/sticky-notes/package.json",
|
|
39
41
|
"apps/sticky-notes/public",
|
|
40
42
|
"apps/sticky-notes/src",
|
|
@@ -49,8 +51,8 @@
|
|
|
49
51
|
"apps/*"
|
|
50
52
|
],
|
|
51
53
|
"scripts": {
|
|
52
|
-
"start": "node cli.mjs
|
|
53
|
-
"start:mock": "node cli.mjs
|
|
54
|
+
"start": "node cli.mjs",
|
|
55
|
+
"start:mock": "node cli.mjs --mock",
|
|
54
56
|
"test": "node scripts/test.mjs",
|
|
55
57
|
"test:vim-nav": "npm --prefix apps/vim-nav test",
|
|
56
58
|
"test:sticky-notes": "npm --prefix apps/sticky-notes test",
|
package/scripts/release-npm.mjs
CHANGED
|
@@ -95,7 +95,7 @@ function isKnownProvenanceCi() {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
async function repackWithName(tarball, packageName) {
|
|
98
|
-
const stageRoot = await mkdtemp(join(tmpdir(), "
|
|
98
|
+
const stageRoot = await mkdtemp(join(tmpdir(), "clankerbend-npm-release-"));
|
|
99
99
|
try {
|
|
100
100
|
await execFileAsync("tar", ["-xzf", tarball, "-C", stageRoot], { cwd: ROOT });
|
|
101
101
|
const packageDir = join(stageRoot, "package");
|
|
@@ -195,7 +195,6 @@ function splitCompoundName(part) {
|
|
|
195
195
|
const tokens = [part];
|
|
196
196
|
if (part.includes("clanker")) tokens.push("clanker");
|
|
197
197
|
if (part.includes("bend")) tokens.push("bend");
|
|
198
|
-
if (part.includes("whack")) tokens.push("whack");
|
|
199
198
|
if (part.includes("onewill")) tokens.push("onewill");
|
|
200
199
|
if (part.includes("ai")) tokens.push("ai");
|
|
201
200
|
return tokens;
|
package/server.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { pathToFileURL } from "node:url";
|
|
2
2
|
import { createCodexDesktopCdpAdapter } from "./host/src/codex-desktop-cdp-adapter.js";
|
|
3
|
-
import {
|
|
3
|
+
import { ClankerBendHost, createMockTranscriptAdapter } from "./host/src/index.js";
|
|
4
4
|
import { navigateProfile, printLaunchStatus } from "./launch/profiles.mjs";
|
|
5
5
|
|
|
6
|
-
export async function
|
|
6
|
+
export async function launchClankerBendCodex(options = {}) {
|
|
7
7
|
const mockMode = Boolean(options.mock);
|
|
8
|
-
const localDevInsecure = options.localDevInsecure === true || process.env.
|
|
8
|
+
const localDevInsecure = options.localDevInsecure === true || process.env.ONEWILL_CLANKERBEND_DISABLE_AUTH === "1";
|
|
9
9
|
const profile = await navigateProfile({
|
|
10
10
|
stateDir: options.stateDir,
|
|
11
11
|
runDir: options.runDir,
|
|
@@ -13,10 +13,10 @@ export async function launchOneWhackCodex(options = {}) {
|
|
|
13
13
|
registryProfileId: options.registryProfileId
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
const host = new
|
|
16
|
+
const host = new ClankerBendHost({
|
|
17
17
|
hostId: profile.hostId,
|
|
18
18
|
hostName: profile.hostName,
|
|
19
|
-
token: options.token || process.env.
|
|
19
|
+
token: options.token || process.env.ONEWILL_CLANKERBEND_TOKEN || undefined,
|
|
20
20
|
localDevInsecure,
|
|
21
21
|
runDir: profile.runDir,
|
|
22
22
|
transcriptAdapter: mockMode
|
|
@@ -41,7 +41,7 @@ export async function launchOneWhackCodex(options = {}) {
|
|
|
41
41
|
process.once("SIGINT", () => cleanupAndExit(0));
|
|
42
42
|
process.once("SIGTERM", () => cleanupAndExit(0));
|
|
43
43
|
process.once("uncaughtException", (err) => {
|
|
44
|
-
console.error(`
|
|
44
|
+
console.error(`ClankerBend could not start. Close any ClankerBend-launched Codex Desktop window, then run this command again. Details: ${err.message}`);
|
|
45
45
|
cleanupAndExit(1);
|
|
46
46
|
});
|
|
47
47
|
}
|
|
@@ -52,7 +52,7 @@ export async function launchOneWhackCodex(options = {}) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
if (import.meta.url === pathToFileURL(process.argv[1] || "").href) {
|
|
55
|
-
await
|
|
55
|
+
await launchClankerBendCodex({
|
|
56
56
|
mock: process.argv.includes("--mock")
|
|
57
57
|
});
|
|
58
58
|
}
|
package/assets/onewhack.jpg
DELETED
|
Binary file
|