@seemseam/ccb 7.4.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.
package/VERSION ADDED
@@ -0,0 +1 @@
1
+ 7.4.2
package/bin/ask.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ require("./ccb-npm-runner").run("ask");
package/bin/autonew.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ require("./ccb-npm-runner").run("autonew");
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const childProcess = require("child_process");
5
+ const crypto = require("crypto");
6
+ const fs = require("fs");
7
+ const https = require("https");
8
+ const os = require("os");
9
+ const path = require("path");
10
+
11
+ const root = path.resolve(__dirname, "..");
12
+ const manifest = require(path.join(root, "package.json"));
13
+ const version = manifest.version;
14
+ const vendorRoot = path.join(root, ".ccb-release");
15
+
16
+ function artifactForHost() {
17
+ if (process.platform === "darwin") {
18
+ return {
19
+ directory: "ccb-macos-universal",
20
+ file: "ccb-macos-universal.tar.gz",
21
+ };
22
+ }
23
+ if (process.platform === "linux" && process.arch === "x64") {
24
+ return {
25
+ directory: "ccb-linux-x86_64",
26
+ file: "ccb-linux-x86_64.tar.gz",
27
+ };
28
+ }
29
+ throw new Error(
30
+ `Unsupported platform for @seemseam/ccb: ${process.platform}/${process.arch}. ` +
31
+ "Use Linux x64, macOS x64, macOS arm64, or install the GitHub release manually."
32
+ );
33
+ }
34
+
35
+ function installDir(info) {
36
+ return path.join(vendorRoot, info.directory);
37
+ }
38
+
39
+ function executablePath(command = "ccb") {
40
+ const info = artifactForHost();
41
+ const base = installDir(info);
42
+ return command === "ccb" ? path.join(base, "ccb") : path.join(base, "bin", command);
43
+ }
44
+
45
+ function isInstalled(info) {
46
+ const dir = installDir(info);
47
+ const versionFile = path.join(dir, "VERSION");
48
+ const ccbPath = path.join(dir, "ccb");
49
+ if (!fs.existsSync(versionFile) || !fs.existsSync(ccbPath)) {
50
+ return false;
51
+ }
52
+ return fs.readFileSync(versionFile, "utf8").trim() === version;
53
+ }
54
+
55
+ function download(url, destination, redirects = 0) {
56
+ if (redirects > 5) {
57
+ throw new Error(`Too many redirects while downloading ${url}`);
58
+ }
59
+ return new Promise((resolve, reject) => {
60
+ const request = https.get(url, (response) => {
61
+ const status = response.statusCode || 0;
62
+ if ([301, 302, 303, 307, 308].includes(status) && response.headers.location) {
63
+ response.resume();
64
+ const redirected = new URL(response.headers.location, url).toString();
65
+ download(redirected, destination, redirects + 1).then(resolve, reject);
66
+ return;
67
+ }
68
+ if (status < 200 || status >= 300) {
69
+ response.resume();
70
+ reject(new Error(`Download failed for ${url}: HTTP ${status}`));
71
+ return;
72
+ }
73
+ const file = fs.createWriteStream(destination);
74
+ response.pipe(file);
75
+ file.on("finish", () => file.close(resolve));
76
+ file.on("error", reject);
77
+ });
78
+ request.on("error", reject);
79
+ });
80
+ }
81
+
82
+ function parseSha256Sums(text) {
83
+ const checksums = new Map();
84
+ for (const line of text.split(/\r?\n/)) {
85
+ const trimmed = line.trim();
86
+ if (!trimmed) {
87
+ continue;
88
+ }
89
+ const match = trimmed.match(/^([a-fA-F0-9]{64})\s+\*?(.+)$/);
90
+ if (match) {
91
+ checksums.set(path.basename(match[2]), match[1].toLowerCase());
92
+ }
93
+ }
94
+ return checksums;
95
+ }
96
+
97
+ function sha256File(filePath) {
98
+ const hash = crypto.createHash("sha256");
99
+ hash.update(fs.readFileSync(filePath));
100
+ return hash.digest("hex");
101
+ }
102
+
103
+ function run(command, args) {
104
+ const completed = childProcess.spawnSync(command, args, {
105
+ stdio: "inherit",
106
+ });
107
+ if (completed.error) {
108
+ throw completed.error;
109
+ }
110
+ if (completed.status !== 0) {
111
+ throw new Error(`${command} ${args.join(" ")} failed with exit ${completed.status}`);
112
+ }
113
+ }
114
+
115
+ async function install() {
116
+ const info = artifactForHost();
117
+ if (isInstalled(info)) {
118
+ return;
119
+ }
120
+ if (process.env.CCB_NPM_SKIP_DOWNLOAD === "1") {
121
+ console.warn("Skipping CCB release download because CCB_NPM_SKIP_DOWNLOAD=1.");
122
+ return;
123
+ }
124
+
125
+ const baseUrl =
126
+ process.env.CCB_NPM_RELEASE_BASE_URL ||
127
+ `https://github.com/SeemSeam/claude_codex_bridge/releases/download/v${version}`;
128
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "ccb-npm-"));
129
+ const archivePath = path.join(tmpDir, info.file);
130
+ const sumsPath = path.join(tmpDir, "SHA256SUMS");
131
+
132
+ try {
133
+ await download(`${baseUrl}/${info.file}`, archivePath);
134
+ await download(`${baseUrl}/SHA256SUMS`, sumsPath);
135
+ const checksums = parseSha256Sums(fs.readFileSync(sumsPath, "utf8"));
136
+ const expected = checksums.get(info.file);
137
+ if (!expected) {
138
+ throw new Error(`SHA256SUMS does not contain ${info.file}`);
139
+ }
140
+ const actual = sha256File(archivePath);
141
+ if (actual !== expected) {
142
+ throw new Error(`Checksum mismatch for ${info.file}: expected ${expected}, got ${actual}`);
143
+ }
144
+
145
+ fs.rmSync(vendorRoot, { recursive: true, force: true });
146
+ fs.mkdirSync(vendorRoot, { recursive: true });
147
+ run("tar", ["-xzf", archivePath, "-C", vendorRoot]);
148
+ if (!fs.existsSync(executablePath("ccb"))) {
149
+ throw new Error(`Installed CCB executable not found at ${executablePath("ccb")}`);
150
+ }
151
+ console.log(`Installed CCB v${version} from ${info.file}.`);
152
+ } finally {
153
+ fs.rmSync(tmpDir, { recursive: true, force: true });
154
+ }
155
+ }
156
+
157
+ if (require.main === module) {
158
+ install().catch((error) => {
159
+ console.error(error.message || error);
160
+ process.exit(1);
161
+ });
162
+ }
163
+
164
+ module.exports = {
165
+ executablePath,
166
+ install,
167
+ };
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ const childProcess = require("child_process");
4
+ const { executablePath, install } = require("./ccb-npm-install");
5
+
6
+ async function run(command) {
7
+ await install();
8
+ const target = executablePath(command);
9
+ const child = childProcess.spawn(target, process.argv.slice(2), {
10
+ stdio: "inherit",
11
+ env: process.env,
12
+ });
13
+ child.on("error", (error) => {
14
+ console.error(error.message || error);
15
+ process.exit(1);
16
+ });
17
+ child.on("exit", (code, signal) => {
18
+ if (signal) {
19
+ process.kill(process.pid, signal);
20
+ return;
21
+ }
22
+ process.exit(code === null ? 1 : code);
23
+ });
24
+ }
25
+
26
+ module.exports = {
27
+ run,
28
+ };
package/bin/ccb.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ require("./ccb-npm-runner").run("ccb");
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ require("./ccb-npm-runner").run("ctx-transfer");
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@seemseam/ccb",
3
+ "version": "7.4.2",
4
+ "description": "Visible, controllable multi-agent CLI workspace for Codex, Claude, Gemini, OpenCode, and Antigravity.",
5
+ "license": "MIT",
6
+ "homepage": "https://github.com/SeemSeam/claude_codex_bridge#readme",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/SeemSeam/claude_codex_bridge.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/SeemSeam/claude_codex_bridge/issues"
13
+ },
14
+ "keywords": [
15
+ "ccb",
16
+ "multi-agent",
17
+ "codex",
18
+ "claude",
19
+ "gemini",
20
+ "tmux",
21
+ "cli"
22
+ ],
23
+ "bin": {
24
+ "ccb": "bin/ccb.js",
25
+ "ask": "bin/ask.js",
26
+ "autonew": "bin/autonew.js",
27
+ "ctx-transfer": "bin/ctx-transfer.js"
28
+ },
29
+ "files": [
30
+ "bin/ccb.js",
31
+ "bin/ask.js",
32
+ "bin/autonew.js",
33
+ "bin/ctx-transfer.js",
34
+ "bin/ccb-npm-install.js",
35
+ "bin/ccb-npm-runner.js",
36
+ "README.md",
37
+ "README_zh.md",
38
+ "LICENSE",
39
+ "VERSION"
40
+ ],
41
+ "scripts": {
42
+ "postinstall": "node bin/ccb-npm-install.js",
43
+ "pack:check": "npm pack --dry-run"
44
+ },
45
+ "engines": {
46
+ "node": ">=18"
47
+ },
48
+ "os": [
49
+ "linux",
50
+ "darwin"
51
+ ],
52
+ "cpu": [
53
+ "x64",
54
+ "arm64"
55
+ ],
56
+ "publishConfig": {
57
+ "access": "public"
58
+ }
59
+ }