zk-credits 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/dist/cli-runtime.d.ts +1 -0
- package/dist/cli-runtime.js +9 -1
- package/dist/cli.js +12 -4
- package/dist/cline-launcher.d.ts +18 -0
- package/dist/cline-launcher.js +85 -0
- package/dist/sidecar.js +1 -1
- package/dist/zk-credits.js +135 -26
- package/package.json +1 -1
package/dist/cli-runtime.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export interface CliCommandDependencies {
|
|
|
10
10
|
isCodexProfileInstalled(): Promise<boolean>;
|
|
11
11
|
isSidecarHealthy(): Promise<boolean>;
|
|
12
12
|
launchCodex(args: readonly string[]): Promise<number>;
|
|
13
|
+
launchCline(args: readonly string[], localToken: string): Promise<number>;
|
|
13
14
|
}
|
|
14
15
|
/** Handles the non-server CLI commands independently from terminal I/O. */
|
|
15
16
|
export declare function runCliCommand(args: readonly string[], dependencies: CliCommandDependencies): Promise<number>;
|
package/dist/cli-runtime.js
CHANGED
|
@@ -49,7 +49,15 @@ export async function runCliCommand(args, dependencies) {
|
|
|
49
49
|
await dependencies.ensureSidecar();
|
|
50
50
|
return dependencies.launchCodex(args.slice(1));
|
|
51
51
|
}
|
|
52
|
+
case 'cline': {
|
|
53
|
+
if (!await dependencies.isIdentityConfigured()) {
|
|
54
|
+
await dependencies.importMnemonic(await dependencies.readMnemonic());
|
|
55
|
+
dependencies.write('ZK Credits identity imported into the system credential store.');
|
|
56
|
+
}
|
|
57
|
+
const localToken = await dependencies.ensureSidecar();
|
|
58
|
+
return dependencies.launchCline(args.slice(1), localToken);
|
|
59
|
+
}
|
|
52
60
|
default:
|
|
53
|
-
throw new Error('Usage: zk-credits <setup codex|codex|status|token|import-mnemonic|serve|env>');
|
|
61
|
+
throw new Error('Usage: zk-credits <cline|setup codex|codex|status|token|import-mnemonic|serve|env>');
|
|
54
62
|
}
|
|
55
63
|
}
|
package/dist/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { launchCodexProcess } from './codex-launcher.js';
|
|
5
|
+
import { launchClineProcess } from './cline-launcher.js';
|
|
5
6
|
import { isCodexProfileInstalled, resolveCodexHome, writeCodexProfile, } from './codex-profile.js';
|
|
6
7
|
import { IdentityStore } from './identity.js';
|
|
7
8
|
import { createLocalProofGenerator } from './local-prover.js';
|
|
@@ -77,6 +78,7 @@ async function readHiddenMnemonic() {
|
|
|
77
78
|
}
|
|
78
79
|
function printHelp() {
|
|
79
80
|
console.log(`Usage:
|
|
81
|
+
zk-credits cline [cline arguments...]
|
|
80
82
|
zk-credits setup codex [--model <model>]
|
|
81
83
|
zk-credits codex [codex arguments...]
|
|
82
84
|
zk-credits status
|
|
@@ -84,10 +86,10 @@ function printHelp() {
|
|
|
84
86
|
zk-credits serve [--port <port>]
|
|
85
87
|
eval "$(zk-credits env)"
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
"zk-credits cline" is the zero-configuration coding-agent path: it starts the
|
|
90
|
+
sidecar, configures an isolated OpenAI-compatible Cline profile, and forwards
|
|
91
|
+
all Cline arguments. The Codex companion remains available through setup codex.
|
|
92
|
+
Set ZK_CREDITS_MNEMONIC only for a headless process; it is not persisted.`);
|
|
91
93
|
}
|
|
92
94
|
async function serve(args) {
|
|
93
95
|
const port = readPort(args);
|
|
@@ -165,6 +167,12 @@ async function main() {
|
|
|
165
167
|
isCodexProfileInstalled: () => isCodexProfileInstalled(codexHome),
|
|
166
168
|
isSidecarHealthy: () => lifecycle.isHealthy(),
|
|
167
169
|
launchCodex: (codexArgs) => launchCodexProcess(codexArgs),
|
|
170
|
+
launchCline: (clineArgs, localToken) => launchClineProcess({
|
|
171
|
+
args: clineArgs,
|
|
172
|
+
loopbackBaseUrl: loopbackBaseUrl(),
|
|
173
|
+
localToken,
|
|
174
|
+
stateDirectory: sidecarHome,
|
|
175
|
+
}),
|
|
168
176
|
});
|
|
169
177
|
if (exitCode !== 0)
|
|
170
178
|
process.exitCode = exitCode;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface SpawnedProcess {
|
|
2
|
+
once(event: 'error', listener: (error: NodeJS.ErrnoException) => void): this;
|
|
3
|
+
once(event: 'exit', listener: (code: number | null, signal: NodeJS.Signals | null) => void): this;
|
|
4
|
+
}
|
|
5
|
+
type ClineStdio = 'inherit' | ['ignore', 'ignore', 'inherit'];
|
|
6
|
+
export type ClineSpawnCommand = (command: string, args: readonly string[], options: {
|
|
7
|
+
stdio: ClineStdio;
|
|
8
|
+
env: NodeJS.ProcessEnv;
|
|
9
|
+
}) => SpawnedProcess;
|
|
10
|
+
export interface LaunchClineOptions {
|
|
11
|
+
args: readonly string[];
|
|
12
|
+
loopbackBaseUrl: string;
|
|
13
|
+
localToken: string;
|
|
14
|
+
stateDirectory: string;
|
|
15
|
+
}
|
|
16
|
+
/** Configures and launches Cline against the proof-aware loopback transport. */
|
|
17
|
+
export declare function launchClineProcess(options: LaunchClineOptions, spawnImpl?: ClineSpawnCommand): Promise<number>;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { chmod, mkdir } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
const DEFAULT_CLINE_MODEL = 'openai/gpt-4o-mini';
|
|
5
|
+
const spawnCommand = (command, args, options) => spawn(command, [...args], options);
|
|
6
|
+
function openAiBaseUrl(loopbackBaseUrl) {
|
|
7
|
+
const url = new URL(loopbackBaseUrl);
|
|
8
|
+
if (url.protocol !== 'http:' || url.hostname !== '127.0.0.1') {
|
|
9
|
+
throw new Error('Cline companion must use a 127.0.0.1 HTTP sidecar URL');
|
|
10
|
+
}
|
|
11
|
+
return `${url.origin}/v1`;
|
|
12
|
+
}
|
|
13
|
+
function selectedModel(args) {
|
|
14
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
15
|
+
const argument = args[index];
|
|
16
|
+
if (argument === '--model' || argument === '-m') {
|
|
17
|
+
const model = args[index + 1]?.trim();
|
|
18
|
+
if (!model)
|
|
19
|
+
throw new Error(`${argument} requires a model ID`);
|
|
20
|
+
return model;
|
|
21
|
+
}
|
|
22
|
+
if (argument?.startsWith('--model=')) {
|
|
23
|
+
const model = argument.slice('--model='.length).trim();
|
|
24
|
+
if (!model)
|
|
25
|
+
throw new Error('--model requires a model ID');
|
|
26
|
+
return model;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return DEFAULT_CLINE_MODEL;
|
|
30
|
+
}
|
|
31
|
+
function assertManagedProviderArguments(args) {
|
|
32
|
+
const managed = new Set(['--provider', '-P', '--key', '-k', '--config', '--data-dir']);
|
|
33
|
+
if (args.some((argument) => managed.has(argument) || argument.startsWith('--provider='))) {
|
|
34
|
+
throw new Error('zk-credits cline manages the provider, API key, and profile directory');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function waitForCline(child) {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
child.once('error', (error) => {
|
|
40
|
+
if (error.code === 'ENOENT') {
|
|
41
|
+
reject(new Error('Cline CLI was not found; install it with npm install --global cline'));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
reject(error);
|
|
45
|
+
});
|
|
46
|
+
child.once('exit', (code) => resolve(code ?? 1));
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Configures and launches Cline against the proof-aware loopback transport. */
|
|
50
|
+
export async function launchClineProcess(options, spawnImpl = spawnCommand) {
|
|
51
|
+
assertManagedProviderArguments(options.args);
|
|
52
|
+
const baseUrl = openAiBaseUrl(options.loopbackBaseUrl);
|
|
53
|
+
const model = selectedModel(options.args);
|
|
54
|
+
const dataDirectory = join(options.stateDirectory, 'cline');
|
|
55
|
+
await mkdir(dataDirectory, { recursive: true, mode: 0o700 });
|
|
56
|
+
await chmod(dataDirectory, 0o700);
|
|
57
|
+
const environment = {
|
|
58
|
+
...process.env,
|
|
59
|
+
OPENAI_BASE_URL: baseUrl,
|
|
60
|
+
OPENAI_API_KEY: options.localToken,
|
|
61
|
+
};
|
|
62
|
+
const authCode = await waitForCline(spawnImpl('cline', [
|
|
63
|
+
'auth',
|
|
64
|
+
'--provider', 'openai-compatible',
|
|
65
|
+
'--apikey', options.localToken,
|
|
66
|
+
'--modelid', model,
|
|
67
|
+
'--baseurl', baseUrl,
|
|
68
|
+
'--data-dir', dataDirectory,
|
|
69
|
+
], {
|
|
70
|
+
stdio: ['ignore', 'ignore', 'inherit'],
|
|
71
|
+
env: environment,
|
|
72
|
+
}));
|
|
73
|
+
if (authCode !== 0) {
|
|
74
|
+
throw new Error(`Cline OpenAI-compatible provider setup failed with exit code ${authCode}`);
|
|
75
|
+
}
|
|
76
|
+
return waitForCline(spawnImpl('cline', [
|
|
77
|
+
'--provider', 'openai-compatible',
|
|
78
|
+
'--model', model,
|
|
79
|
+
'--data-dir', dataDirectory,
|
|
80
|
+
...options.args,
|
|
81
|
+
], {
|
|
82
|
+
stdio: 'inherit',
|
|
83
|
+
env: environment,
|
|
84
|
+
}));
|
|
85
|
+
}
|
package/dist/sidecar.js
CHANGED
|
@@ -104,7 +104,7 @@ export function createSidecarServer(options) {
|
|
|
104
104
|
body: body.raw,
|
|
105
105
|
});
|
|
106
106
|
await relayGatewayResponse(res, upstream);
|
|
107
|
-
if (upstream.status >= 200 && upstream.status < 300) {
|
|
107
|
+
if (upstream.status >= 200 && upstream.status < 300 && upstream.status !== 202) {
|
|
108
108
|
await options.ledger.consume(reservation.requestDigest);
|
|
109
109
|
}
|
|
110
110
|
}
|
package/dist/zk-credits.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createRequire as __createNodeRequire } from 'node:module'; const requir
|
|
|
3
3
|
|
|
4
4
|
// dist/cli.js
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
|
-
import { join as
|
|
6
|
+
import { join as join5 } from "node:path";
|
|
7
7
|
|
|
8
8
|
// dist/codex-launcher.js
|
|
9
9
|
import { spawn } from "node:child_process";
|
|
@@ -127,6 +127,100 @@ async function launchCodexProcess(args, spawnImpl = spawnCommand) {
|
|
|
127
127
|
});
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
// dist/cline-launcher.js
|
|
131
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
132
|
+
import { chmod as chmod2, mkdir as mkdir2 } from "node:fs/promises";
|
|
133
|
+
import { join as join2 } from "node:path";
|
|
134
|
+
var DEFAULT_CLINE_MODEL = "openai/gpt-4o-mini";
|
|
135
|
+
var spawnCommand2 = (command, args, options) => spawn2(command, [...args], options);
|
|
136
|
+
function openAiBaseUrl(loopbackBaseUrl2) {
|
|
137
|
+
const url = new URL(loopbackBaseUrl2);
|
|
138
|
+
if (url.protocol !== "http:" || url.hostname !== "127.0.0.1") {
|
|
139
|
+
throw new Error("Cline companion must use a 127.0.0.1 HTTP sidecar URL");
|
|
140
|
+
}
|
|
141
|
+
return `${url.origin}/v1`;
|
|
142
|
+
}
|
|
143
|
+
function selectedModel(args) {
|
|
144
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
145
|
+
const argument = args[index];
|
|
146
|
+
if (argument === "--model" || argument === "-m") {
|
|
147
|
+
const model = args[index + 1]?.trim();
|
|
148
|
+
if (!model)
|
|
149
|
+
throw new Error(`${argument} requires a model ID`);
|
|
150
|
+
return model;
|
|
151
|
+
}
|
|
152
|
+
if (argument?.startsWith("--model=")) {
|
|
153
|
+
const model = argument.slice("--model=".length).trim();
|
|
154
|
+
if (!model)
|
|
155
|
+
throw new Error("--model requires a model ID");
|
|
156
|
+
return model;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return DEFAULT_CLINE_MODEL;
|
|
160
|
+
}
|
|
161
|
+
function assertManagedProviderArguments(args) {
|
|
162
|
+
const managed = /* @__PURE__ */ new Set(["--provider", "-P", "--key", "-k", "--config", "--data-dir"]);
|
|
163
|
+
if (args.some((argument) => managed.has(argument) || argument.startsWith("--provider="))) {
|
|
164
|
+
throw new Error("zk-credits cline manages the provider, API key, and profile directory");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function waitForCline(child) {
|
|
168
|
+
return new Promise((resolve2, reject) => {
|
|
169
|
+
child.once("error", (error) => {
|
|
170
|
+
if (error.code === "ENOENT") {
|
|
171
|
+
reject(new Error("Cline CLI was not found; install it with npm install --global cline"));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
reject(error);
|
|
175
|
+
});
|
|
176
|
+
child.once("exit", (code) => resolve2(code ?? 1));
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
async function launchClineProcess(options, spawnImpl = spawnCommand2) {
|
|
180
|
+
assertManagedProviderArguments(options.args);
|
|
181
|
+
const baseUrl = openAiBaseUrl(options.loopbackBaseUrl);
|
|
182
|
+
const model = selectedModel(options.args);
|
|
183
|
+
const dataDirectory = join2(options.stateDirectory, "cline");
|
|
184
|
+
await mkdir2(dataDirectory, { recursive: true, mode: 448 });
|
|
185
|
+
await chmod2(dataDirectory, 448);
|
|
186
|
+
const environment = {
|
|
187
|
+
...process.env,
|
|
188
|
+
OPENAI_BASE_URL: baseUrl,
|
|
189
|
+
OPENAI_API_KEY: options.localToken
|
|
190
|
+
};
|
|
191
|
+
const authCode = await waitForCline(spawnImpl("cline", [
|
|
192
|
+
"auth",
|
|
193
|
+
"--provider",
|
|
194
|
+
"openai-compatible",
|
|
195
|
+
"--apikey",
|
|
196
|
+
options.localToken,
|
|
197
|
+
"--modelid",
|
|
198
|
+
model,
|
|
199
|
+
"--baseurl",
|
|
200
|
+
baseUrl,
|
|
201
|
+
"--data-dir",
|
|
202
|
+
dataDirectory
|
|
203
|
+
], {
|
|
204
|
+
stdio: ["ignore", "ignore", "inherit"],
|
|
205
|
+
env: environment
|
|
206
|
+
}));
|
|
207
|
+
if (authCode !== 0) {
|
|
208
|
+
throw new Error(`Cline OpenAI-compatible provider setup failed with exit code ${authCode}`);
|
|
209
|
+
}
|
|
210
|
+
return waitForCline(spawnImpl("cline", [
|
|
211
|
+
"--provider",
|
|
212
|
+
"openai-compatible",
|
|
213
|
+
"--model",
|
|
214
|
+
model,
|
|
215
|
+
"--data-dir",
|
|
216
|
+
dataDirectory,
|
|
217
|
+
...options.args
|
|
218
|
+
], {
|
|
219
|
+
stdio: "inherit",
|
|
220
|
+
env: environment
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
223
|
+
|
|
130
224
|
// dist/identity.js
|
|
131
225
|
import * as keytar from "keytar";
|
|
132
226
|
|
|
@@ -398,7 +492,7 @@ import { resolve } from "node:path";
|
|
|
398
492
|
// dist/artifact-manifest.js
|
|
399
493
|
import { createHash } from "node:crypto";
|
|
400
494
|
import { readFile } from "node:fs/promises";
|
|
401
|
-
import { join as
|
|
495
|
+
import { join as join3 } from "node:path";
|
|
402
496
|
var CIRCUIT_MANIFEST = [
|
|
403
497
|
{
|
|
404
498
|
file: "rln_nullifier.wasm",
|
|
@@ -415,7 +509,7 @@ var CIRCUIT_MANIFEST = [
|
|
|
415
509
|
];
|
|
416
510
|
async function verifyArtifactManifest(artifactDirectory, manifest = CIRCUIT_MANIFEST) {
|
|
417
511
|
for (const artifact of manifest) {
|
|
418
|
-
const content = await readFile(
|
|
512
|
+
const content = await readFile(join3(artifactDirectory, artifact.file));
|
|
419
513
|
const digest = createHash("sha256").update(content).digest("hex");
|
|
420
514
|
if (digest !== artifact.sha256) {
|
|
421
515
|
throw new Error(`Circuit artifact hash mismatch: ${artifact.file}`);
|
|
@@ -509,15 +603,15 @@ var MembershipClient = class {
|
|
|
509
603
|
|
|
510
604
|
// dist/sidecar-config.js
|
|
511
605
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
512
|
-
import { join as
|
|
606
|
+
import { join as join4 } from "node:path";
|
|
513
607
|
function createLoopbackToken() {
|
|
514
608
|
return randomBytes2(32).toString("base64url");
|
|
515
609
|
}
|
|
516
610
|
function sidecarStatePaths(stateDirectory2) {
|
|
517
611
|
return {
|
|
518
|
-
ledgerPath:
|
|
519
|
-
tokenPath:
|
|
520
|
-
logPath:
|
|
612
|
+
ledgerPath: join4(stateDirectory2, "tickets.json"),
|
|
613
|
+
tokenPath: join4(stateDirectory2, "loopback-token"),
|
|
614
|
+
logPath: join4(stateDirectory2, "sidecar.log")
|
|
521
615
|
};
|
|
522
616
|
}
|
|
523
617
|
function formatOpenAiEnvironment(loopbackBaseUrl2, localToken) {
|
|
@@ -581,29 +675,37 @@ async function runCliCommand(args, dependencies) {
|
|
|
581
675
|
await dependencies.ensureSidecar();
|
|
582
676
|
return dependencies.launchCodex(args.slice(1));
|
|
583
677
|
}
|
|
678
|
+
case "cline": {
|
|
679
|
+
if (!await dependencies.isIdentityConfigured()) {
|
|
680
|
+
await dependencies.importMnemonic(await dependencies.readMnemonic());
|
|
681
|
+
dependencies.write("ZK Credits identity imported into the system credential store.");
|
|
682
|
+
}
|
|
683
|
+
const localToken = await dependencies.ensureSidecar();
|
|
684
|
+
return dependencies.launchCline(args.slice(1), localToken);
|
|
685
|
+
}
|
|
584
686
|
default:
|
|
585
|
-
throw new Error("Usage: zk-credits <setup codex|codex|status|token|import-mnemonic|serve|env>");
|
|
687
|
+
throw new Error("Usage: zk-credits <cline|setup codex|codex|status|token|import-mnemonic|serve|env>");
|
|
586
688
|
}
|
|
587
689
|
}
|
|
588
690
|
|
|
589
691
|
// dist/node-sidecar-lifecycle.js
|
|
590
|
-
import { spawn as
|
|
591
|
-
import { chmod as
|
|
692
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
693
|
+
import { chmod as chmod4, mkdir as mkdir4, open } from "node:fs/promises";
|
|
592
694
|
import { dirname as dirname2 } from "node:path";
|
|
593
695
|
|
|
594
696
|
// dist/sidecar-state.js
|
|
595
|
-
import { chmod as
|
|
697
|
+
import { chmod as chmod3, mkdir as mkdir3, readFile as readFile3, rename as rename2, writeFile as writeFile2 } from "node:fs/promises";
|
|
596
698
|
import { dirname } from "node:path";
|
|
597
699
|
async function writeLoopbackToken(tokenPath, token) {
|
|
598
700
|
if (!token)
|
|
599
701
|
throw new Error("Loopback token is required");
|
|
600
|
-
await
|
|
702
|
+
await mkdir3(dirname(tokenPath), { recursive: true, mode: 448 });
|
|
601
703
|
const temporaryPath = `${tokenPath}.tmp`;
|
|
602
704
|
await writeFile2(temporaryPath, `${token}
|
|
603
705
|
`, { encoding: "utf8", mode: 384 });
|
|
604
|
-
await
|
|
706
|
+
await chmod3(temporaryPath, 384);
|
|
605
707
|
await rename2(temporaryPath, tokenPath);
|
|
606
|
-
await
|
|
708
|
+
await chmod3(tokenPath, 384);
|
|
607
709
|
}
|
|
608
710
|
async function readLoopbackToken(tokenPath) {
|
|
609
711
|
const token = (await readFile3(tokenPath, "utf8")).trim();
|
|
@@ -614,11 +716,11 @@ async function readLoopbackToken(tokenPath) {
|
|
|
614
716
|
|
|
615
717
|
// dist/node-sidecar-lifecycle.js
|
|
616
718
|
async function startDetachedProcess(specification) {
|
|
617
|
-
await
|
|
719
|
+
await mkdir4(dirname2(specification.logPath), { recursive: true, mode: 448 });
|
|
618
720
|
const log = await open(specification.logPath, "a", 384);
|
|
619
|
-
await
|
|
721
|
+
await chmod4(specification.logPath, 384);
|
|
620
722
|
try {
|
|
621
|
-
const child =
|
|
723
|
+
const child = spawn3(specification.executable, specification.args, {
|
|
622
724
|
detached: true,
|
|
623
725
|
env: specification.env,
|
|
624
726
|
stdio: ["ignore", log.fd, log.fd]
|
|
@@ -794,7 +896,7 @@ function createSidecarServer(options) {
|
|
|
794
896
|
body: body.raw
|
|
795
897
|
});
|
|
796
898
|
await relayGatewayResponse(res, upstream);
|
|
797
|
-
if (upstream.status >= 200 && upstream.status < 300) {
|
|
899
|
+
if (upstream.status >= 200 && upstream.status < 300 && upstream.status !== 202) {
|
|
798
900
|
await options.ledger.consume(reservation.requestDigest);
|
|
799
901
|
}
|
|
800
902
|
} catch (error) {
|
|
@@ -841,7 +943,7 @@ function createSidecarServer(options) {
|
|
|
841
943
|
}
|
|
842
944
|
|
|
843
945
|
// dist/ticket-ledger.js
|
|
844
|
-
import { mkdir as
|
|
946
|
+
import { mkdir as mkdir5, readFile as readFile4, rename as rename3, writeFile as writeFile3 } from "node:fs/promises";
|
|
845
947
|
import { dirname as dirname3 } from "node:path";
|
|
846
948
|
function parseLedger(raw) {
|
|
847
949
|
const parsed = JSON.parse(raw);
|
|
@@ -914,7 +1016,7 @@ var TicketLedger = class {
|
|
|
914
1016
|
}
|
|
915
1017
|
}
|
|
916
1018
|
async write(ledger) {
|
|
917
|
-
await
|
|
1019
|
+
await mkdir5(dirname3(this.filePath), { recursive: true, mode: 448 });
|
|
918
1020
|
const temporaryPath = `${this.filePath}.tmp`;
|
|
919
1021
|
await writeFile3(temporaryPath, JSON.stringify(ledger), { encoding: "utf8", mode: 384 });
|
|
920
1022
|
await rename3(temporaryPath, this.filePath);
|
|
@@ -925,7 +1027,7 @@ var TicketLedger = class {
|
|
|
925
1027
|
var DEFAULT_GATEWAY_URL = "https://zk-credits-gateway.onrender.com";
|
|
926
1028
|
var DEFAULT_PORT = 3210;
|
|
927
1029
|
function stateDirectory() {
|
|
928
|
-
return process.env.ZK_CREDITS_HOME ||
|
|
1030
|
+
return process.env.ZK_CREDITS_HOME || join5(homedir(), ".zk-credits");
|
|
929
1031
|
}
|
|
930
1032
|
function loopbackBaseUrl() {
|
|
931
1033
|
const port = Number(process.env.ZK_CREDITS_SIDECAR_PORT || DEFAULT_PORT);
|
|
@@ -984,6 +1086,7 @@ async function readHiddenMnemonic() {
|
|
|
984
1086
|
}
|
|
985
1087
|
function printHelp() {
|
|
986
1088
|
console.log(`Usage:
|
|
1089
|
+
zk-credits cline [cline arguments...]
|
|
987
1090
|
zk-credits setup codex [--model <model>]
|
|
988
1091
|
zk-credits codex [codex arguments...]
|
|
989
1092
|
zk-credits status
|
|
@@ -991,10 +1094,10 @@ function printHelp() {
|
|
|
991
1094
|
zk-credits serve [--port <port>]
|
|
992
1095
|
eval "$(zk-credits env)"
|
|
993
1096
|
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1097
|
+
"zk-credits cline" is the zero-configuration coding-agent path: it starts the
|
|
1098
|
+
sidecar, configures an isolated OpenAI-compatible Cline profile, and forwards
|
|
1099
|
+
all Cline arguments. The Codex companion remains available through setup codex.
|
|
1100
|
+
Set ZK_CREDITS_MNEMONIC only for a headless process; it is not persisted.`);
|
|
998
1101
|
}
|
|
999
1102
|
async function serve(args) {
|
|
1000
1103
|
const port = readPort(args);
|
|
@@ -1076,7 +1179,13 @@ async function main() {
|
|
|
1076
1179
|
ensureSidecar: () => ensureSidecarReady(lifecycle),
|
|
1077
1180
|
isCodexProfileInstalled: () => isCodexProfileInstalled(codexHome),
|
|
1078
1181
|
isSidecarHealthy: () => lifecycle.isHealthy(),
|
|
1079
|
-
launchCodex: (codexArgs) => launchCodexProcess(codexArgs)
|
|
1182
|
+
launchCodex: (codexArgs) => launchCodexProcess(codexArgs),
|
|
1183
|
+
launchCline: (clineArgs, localToken) => launchClineProcess({
|
|
1184
|
+
args: clineArgs,
|
|
1185
|
+
loopbackBaseUrl: loopbackBaseUrl(),
|
|
1186
|
+
localToken,
|
|
1187
|
+
stateDirectory: sidecarHome
|
|
1188
|
+
})
|
|
1080
1189
|
});
|
|
1081
1190
|
if (exitCode !== 0)
|
|
1082
1191
|
process.exitCode = exitCode;
|