@dench.com/cli 0.2.0 → 0.3.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.
- package/README.md +2 -2
- package/dench.ts +1 -1
- package/fs-daemon.ts +19 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,13 +7,13 @@ Agent-facing CLI for the Dench agent workspace.
|
|
|
7
7
|
Run without installing:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npx -y dench
|
|
10
|
+
npx -y @dench.com/cli login --name "AI Agent - Billing Repo"
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Or install globally:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
npm install -g dench
|
|
16
|
+
npm install -g @dench.com/cli
|
|
17
17
|
dench login --name "AI Agent - Billing Repo"
|
|
18
18
|
```
|
|
19
19
|
|
package/dench.ts
CHANGED
package/fs-daemon.ts
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
*/
|
|
34
34
|
import { createHash } from "node:crypto";
|
|
35
35
|
import { mkdirSync } from "node:fs";
|
|
36
|
-
import { mkdir, readFile, stat,
|
|
36
|
+
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
37
37
|
import { dirname, relative } from "node:path";
|
|
38
38
|
import { ConvexClient, ConvexHttpClient } from "convex/browser";
|
|
39
39
|
import { makeFunctionReference } from "convex/server";
|
|
@@ -67,9 +67,13 @@ function parseArgs(argv: string[]): Args {
|
|
|
67
67
|
break;
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
|
|
70
|
+
out.orgId ??= process.env.DENCH_ORG_ID?.trim() || undefined;
|
|
71
|
+
out.workspace ??= process.env.DENCH_VOLUME_PATH?.trim() || "/workspace";
|
|
72
|
+
out.hotCache ??=
|
|
73
|
+
process.env.DENCH_HOT_CACHE_PATH?.trim() || "/tmp/dench-cache";
|
|
74
|
+
if (!out.orgId) {
|
|
71
75
|
throw new Error(
|
|
72
|
-
"dench-fs-daemon:
|
|
76
|
+
"dench-fs-daemon: org id is required. Set DENCH_ORG_ID env var or pass --org-id.",
|
|
73
77
|
);
|
|
74
78
|
}
|
|
75
79
|
return out as Args;
|
|
@@ -144,7 +148,9 @@ class HashTracker {
|
|
|
144
148
|
setTimeout(() => {
|
|
145
149
|
this.paused.delete(absPath);
|
|
146
150
|
this.recentSyncs.delete(absPath);
|
|
147
|
-
console.warn(
|
|
151
|
+
console.warn(
|
|
152
|
+
`[dench-fs-daemon] circuit breaker released for ${absPath}`,
|
|
153
|
+
);
|
|
148
154
|
}, 60_000);
|
|
149
155
|
return true;
|
|
150
156
|
}
|
|
@@ -177,9 +183,7 @@ const api = {
|
|
|
177
183
|
commitFileUpload: makeFunctionReference<"mutation">(
|
|
178
184
|
"functions/files:commitFileUpload",
|
|
179
185
|
),
|
|
180
|
-
deleteFile: makeFunctionReference<"mutation">(
|
|
181
|
-
"functions/files:deleteFile",
|
|
182
|
-
),
|
|
186
|
+
deleteFile: makeFunctionReference<"mutation">("functions/files:deleteFile"),
|
|
183
187
|
listTree: makeFunctionReference<"query">("functions/files:listTree"),
|
|
184
188
|
appendLiveBuffer: makeFunctionReference<"mutation">(
|
|
185
189
|
"functions/files:appendLiveBuffer",
|
|
@@ -248,7 +252,7 @@ class DenchFileClient {
|
|
|
248
252
|
) {
|
|
249
253
|
// Convex serializes ConvexError data into the message; pull
|
|
250
254
|
// currentHash if present.
|
|
251
|
-
const m = /currentHash[
|
|
255
|
+
const m = /currentHash["']?:["']?([a-f0-9]{64})/.exec(message);
|
|
252
256
|
return { versionConflict: true, currentHash: m?.[1] };
|
|
253
257
|
}
|
|
254
258
|
throw error;
|
|
@@ -260,10 +264,9 @@ class DenchFileClient {
|
|
|
260
264
|
}
|
|
261
265
|
|
|
262
266
|
async getSignedDownloadUrl(path: string): Promise<string | null> {
|
|
263
|
-
const url = (await this.http.action(
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
)) as string | null;
|
|
267
|
+
const url = (await this.http.action(api.files.getFileSignedDownloadUrl, {
|
|
268
|
+
path,
|
|
269
|
+
})) as string | null;
|
|
267
270
|
return url ?? null;
|
|
268
271
|
}
|
|
269
272
|
|
|
@@ -518,8 +521,7 @@ async function runStreamOpen(args: string[]): Promise<void> {
|
|
|
518
521
|
if (!path) {
|
|
519
522
|
throw new Error("dench-fs-daemon stream-open requires <path>");
|
|
520
523
|
}
|
|
521
|
-
const runId =
|
|
522
|
-
process.env.DENCH_RUN_ID?.trim() ?? `manual-${Date.now()}`;
|
|
524
|
+
const runId = process.env.DENCH_RUN_ID?.trim() ?? `manual-${Date.now()}`;
|
|
523
525
|
const token = newToken();
|
|
524
526
|
const store = await readTokenStore();
|
|
525
527
|
store[token] = { path, runId };
|
|
@@ -531,9 +533,7 @@ async function runStreamAppend(args: string[]): Promise<void> {
|
|
|
531
533
|
const token = args[0];
|
|
532
534
|
const chunk = args.slice(1).join(" ");
|
|
533
535
|
if (!token || chunk === undefined) {
|
|
534
|
-
throw new Error(
|
|
535
|
-
"dench-fs-daemon stream-append requires <token> <chunk>",
|
|
536
|
-
);
|
|
536
|
+
throw new Error("dench-fs-daemon stream-append requires <token> <chunk>");
|
|
537
537
|
}
|
|
538
538
|
const store = await readTokenStore();
|
|
539
539
|
const entry = store[token];
|
|
@@ -616,9 +616,7 @@ async function runInitialSync(argv: string[]): Promise<void> {
|
|
|
616
616
|
const convexUrl = process.env.CONVEX_URL?.trim();
|
|
617
617
|
const apiKey = process.env.DENCH_API_KEY?.trim();
|
|
618
618
|
if (!convexUrl || !apiKey) {
|
|
619
|
-
throw new Error(
|
|
620
|
-
"dench fs sync requires CONVEX_URL + DENCH_API_KEY in env",
|
|
621
|
-
);
|
|
619
|
+
throw new Error("dench fs sync requires CONVEX_URL + DENCH_API_KEY in env");
|
|
622
620
|
}
|
|
623
621
|
const client = new DenchFileClient(convexUrl, apiKey);
|
|
624
622
|
const fs = await import("node:fs/promises");
|
|
@@ -670,7 +668,7 @@ async function runInitialSync(argv: string[]): Promise<void> {
|
|
|
670
668
|
main().catch((error) => {
|
|
671
669
|
console.error(
|
|
672
670
|
`[dench-fs-daemon] fatal: ${
|
|
673
|
-
error instanceof Error ? error.stack ?? error.message : String(error)
|
|
671
|
+
error instanceof Error ? (error.stack ?? error.message) : String(error)
|
|
674
672
|
}`,
|
|
675
673
|
);
|
|
676
674
|
// Long-running daemon: don't exit on transient errors. One-shot
|