@agentuity/cli 1.0.1 → 1.0.3
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/AGENTS.md +40 -24
- package/bin/cli.ts +47 -22
- package/dist/agent-detection.d.ts +23 -38
- package/dist/agent-detection.d.ts.map +1 -1
- package/dist/agent-detection.js +412 -153
- package/dist/agent-detection.js.map +1 -1
- package/dist/ai-help.d.ts +23 -0
- package/dist/ai-help.d.ts.map +1 -0
- package/dist/ai-help.js +328 -0
- package/dist/ai-help.js.map +1 -0
- package/dist/api.js +1 -1
- package/dist/api.js.map +1 -1
- package/dist/auth.d.ts +10 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +176 -16
- package/dist/auth.js.map +1 -1
- package/dist/banner.d.ts.map +1 -1
- package/dist/banner.js +5 -0
- package/dist/banner.js.map +1 -1
- package/dist/cache/agent-intro.d.ts +13 -0
- package/dist/cache/agent-intro.d.ts.map +1 -0
- package/dist/cache/agent-intro.js +54 -0
- package/dist/cache/agent-intro.js.map +1 -0
- package/dist/cache/index.d.ts +1 -0
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +1 -0
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/resource-region.d.ts +3 -2
- package/dist/cache/resource-region.d.ts.map +1 -1
- package/dist/cache/resource-region.js +13 -4
- package/dist/cache/resource-region.js.map +1 -1
- package/dist/catalyst.d.ts +7 -0
- package/dist/catalyst.d.ts.map +1 -0
- package/dist/catalyst.js +15 -0
- package/dist/catalyst.js.map +1 -0
- package/dist/cli.d.ts +12 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +290 -67
- package/dist/cli.js.map +1 -1
- package/dist/cmd/ai/detect.d.ts +3 -0
- package/dist/cmd/ai/detect.d.ts.map +1 -0
- package/dist/cmd/ai/detect.js +49 -0
- package/dist/cmd/ai/detect.js.map +1 -0
- package/dist/cmd/ai/index.d.ts.map +1 -1
- package/dist/cmd/ai/index.js +18 -1
- package/dist/cmd/ai/index.js.map +1 -1
- package/dist/cmd/ai/intro.d.ts +7 -0
- package/dist/cmd/ai/intro.d.ts.map +1 -0
- package/dist/cmd/ai/intro.js +141 -0
- package/dist/cmd/ai/intro.js.map +1 -0
- package/dist/cmd/ai/opencode/run.d.ts.map +1 -1
- package/dist/cmd/ai/opencode/run.js +5 -0
- package/dist/cmd/ai/opencode/run.js.map +1 -1
- package/dist/cmd/build/ast.d.ts.map +1 -1
- package/dist/cmd/build/ast.js +79 -0
- package/dist/cmd/build/ast.js.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.js +2 -0
- package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
- package/dist/cmd/build/vite/docs-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/docs-generator.js +15 -1
- package/dist/cmd/build/vite/docs-generator.js.map +1 -1
- package/dist/cmd/build/vite/env-types-generator.d.ts +26 -0
- package/dist/cmd/build/vite/env-types-generator.d.ts.map +1 -0
- package/dist/cmd/build/vite/env-types-generator.js +110 -0
- package/dist/cmd/build/vite/env-types-generator.js.map +1 -0
- package/dist/cmd/build/vite/index.d.ts +2 -0
- package/dist/cmd/build/vite/index.d.ts.map +1 -1
- package/dist/cmd/build/vite/index.js +12 -1
- package/dist/cmd/build/vite/index.js.map +1 -1
- package/dist/cmd/build/vite/public-asset-path-plugin.d.ts.map +1 -1
- package/dist/cmd/build/vite/public-asset-path-plugin.js.map +1 -1
- package/dist/cmd/build/vite/vite-builder.d.ts +2 -0
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-builder.js +10 -1
- package/dist/cmd/build/vite/vite-builder.js.map +1 -1
- package/dist/cmd/cloud/db/create.js.map +1 -1
- package/dist/cmd/cloud/db/delete.js.map +1 -1
- package/dist/cmd/cloud/db/get.d.ts.map +1 -1
- package/dist/cmd/cloud/db/get.js +27 -12
- package/dist/cmd/cloud/db/get.js.map +1 -1
- package/dist/cmd/cloud/deploy-fork.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy-fork.js +2 -0
- package/dist/cmd/cloud/deploy-fork.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +17 -0
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/env/import.js.map +1 -1
- package/dist/cmd/cloud/env/list.js.map +1 -1
- package/dist/cmd/cloud/env/push.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/util.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/util.js +3 -3
- package/dist/cmd/cloud/keyvalue/util.js.map +1 -1
- package/dist/cmd/cloud/machine/list.js +3 -3
- package/dist/cmd/cloud/machine/list.js.map +1 -1
- package/dist/cmd/cloud/region/index.js.map +1 -1
- package/dist/cmd/cloud/region-lookup.d.ts +7 -4
- package/dist/cmd/cloud/region-lookup.d.ts.map +1 -1
- package/dist/cmd/cloud/region-lookup.js +59 -14
- package/dist/cmd/cloud/region-lookup.js.map +1 -1
- package/dist/cmd/cloud/sandbox/cp.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/cp.js +7 -5
- package/dist/cmd/cloud/sandbox/cp.js.map +1 -1
- package/dist/cmd/cloud/sandbox/create.js +2 -2
- package/dist/cmd/cloud/sandbox/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/delete.js +8 -7
- package/dist/cmd/cloud/sandbox/delete.js.map +1 -1
- package/dist/cmd/cloud/sandbox/download.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/download.js +7 -5
- package/dist/cmd/cloud/sandbox/download.js.map +1 -1
- package/dist/cmd/cloud/sandbox/env.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/env.js +7 -5
- package/dist/cmd/cloud/sandbox/env.js.map +1 -1
- package/dist/cmd/cloud/sandbox/exec.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/exec.js +7 -5
- package/dist/cmd/cloud/sandbox/exec.js.map +1 -1
- package/dist/cmd/cloud/sandbox/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/get.js +12 -7
- package/dist/cmd/cloud/sandbox/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/list.js +40 -63
- package/dist/cmd/cloud/sandbox/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/ls.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/ls.js +7 -5
- package/dist/cmd/cloud/sandbox/ls.js.map +1 -1
- package/dist/cmd/cloud/sandbox/mkdir.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/mkdir.js +7 -5
- package/dist/cmd/cloud/sandbox/mkdir.js.map +1 -1
- package/dist/cmd/cloud/sandbox/rm.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/rm.js +7 -5
- package/dist/cmd/cloud/sandbox/rm.js.map +1 -1
- package/dist/cmd/cloud/sandbox/rmdir.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/rmdir.js +7 -5
- package/dist/cmd/cloud/sandbox/rmdir.js.map +1 -1
- package/dist/cmd/cloud/sandbox/run.js +1 -1
- package/dist/cmd/cloud/sandbox/run.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/build.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/upload.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/upload.js +7 -5
- package/dist/cmd/cloud/sandbox/upload.js.map +1 -1
- package/dist/cmd/cloud/sandbox/util.d.ts +2 -2
- package/dist/cmd/cloud/sandbox/util.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/util.js +14 -13
- package/dist/cmd/cloud/sandbox/util.js.map +1 -1
- package/dist/cmd/cloud/ssh.d.ts.map +1 -1
- package/dist/cmd/cloud/ssh.js +3 -3
- package/dist/cmd/cloud/ssh.js.map +1 -1
- package/dist/cmd/cloud/storage/create.js.map +1 -1
- package/dist/cmd/cloud/storage/delete.js.map +1 -1
- package/dist/cmd/cloud/storage/get.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/get.js +5 -11
- package/dist/cmd/cloud/storage/get.js.map +1 -1
- package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/list.js +6 -6
- package/dist/cmd/cloud/storage/list.js.map +1 -1
- package/dist/cmd/cloud/stream/create.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/create.js +7 -4
- package/dist/cmd/cloud/stream/create.js.map +1 -1
- package/dist/cmd/cloud/stream/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/delete.js +25 -4
- package/dist/cmd/cloud/stream/delete.js.map +1 -1
- package/dist/cmd/cloud/stream/get.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/get.js +91 -62
- package/dist/cmd/cloud/stream/get.js.map +1 -1
- package/dist/cmd/cloud/stream/list.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/list.js +66 -38
- package/dist/cmd/cloud/stream/list.js.map +1 -1
- package/dist/cmd/cloud/stream/util.d.ts +20 -0
- package/dist/cmd/cloud/stream/util.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/util.js +27 -3
- package/dist/cmd/cloud/stream/util.js.map +1 -1
- package/dist/cmd/cloud/vector/util.d.ts.map +1 -1
- package/dist/cmd/cloud/vector/util.js +3 -3
- package/dist/cmd/cloud/vector/util.js.map +1 -1
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/git/account/add.js.map +1 -1
- package/dist/cmd/git/list.js.map +1 -1
- package/dist/cmd/project/add/database.d.ts +2 -0
- package/dist/cmd/project/add/database.d.ts.map +1 -0
- package/dist/cmd/project/add/database.js +123 -0
- package/dist/cmd/project/add/database.js.map +1 -0
- package/dist/cmd/project/add/domain.d.ts +2 -0
- package/dist/cmd/project/add/domain.d.ts.map +1 -0
- package/dist/cmd/project/add/domain.js +152 -0
- package/dist/cmd/project/add/domain.js.map +1 -0
- package/dist/cmd/project/add/index.d.ts +2 -0
- package/dist/cmd/project/add/index.d.ts.map +1 -0
- package/dist/cmd/project/add/index.js +35 -0
- package/dist/cmd/project/add/index.js.map +1 -0
- package/dist/cmd/project/add/storage.d.ts +2 -0
- package/dist/cmd/project/add/storage.d.ts.map +1 -0
- package/dist/cmd/project/add/storage.js +123 -0
- package/dist/cmd/project/add/storage.js.map +1 -0
- package/dist/cmd/project/auth/init.js.map +1 -1
- package/dist/cmd/project/index.d.ts.map +1 -1
- package/dist/cmd/project/index.js +7 -0
- package/dist/cmd/project/index.js.map +1 -1
- package/dist/cmd/project/reconcile.d.ts.map +1 -1
- package/dist/cmd/project/reconcile.js +32 -0
- package/dist/cmd/project/reconcile.js.map +1 -1
- package/dist/cmd/support/report.js.map +1 -1
- package/dist/cmd/support/system.js +2 -2
- package/dist/cmd/support/system.js.map +1 -1
- package/dist/config.d.ts +6 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +31 -7
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +2 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +5 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/repl.js +2 -1
- package/dist/repl.js.map +1 -1
- package/dist/tui/box.d.ts +3 -1
- package/dist/tui/box.d.ts.map +1 -1
- package/dist/tui/box.js +22 -7
- package/dist/tui/box.js.map +1 -1
- package/dist/tui/colors.d.ts +0 -3
- package/dist/tui/colors.d.ts.map +1 -1
- package/dist/tui/colors.js +76 -23
- package/dist/tui/colors.js.map +1 -1
- package/dist/tui/prompt.d.ts +2 -0
- package/dist/tui/prompt.d.ts.map +1 -1
- package/dist/tui/prompt.js +44 -3
- package/dist/tui/prompt.js.map +1 -1
- package/dist/tui/symbols.d.ts +0 -4
- package/dist/tui/symbols.d.ts.map +1 -1
- package/dist/tui/symbols.js +5 -0
- package/dist/tui/symbols.js.map +1 -1
- package/dist/tui.d.ts +8 -0
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +54 -9
- package/dist/tui.js.map +1 -1
- package/dist/types.d.ts +37 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/version-check.d.ts.map +1 -1
- package/dist/version-check.js +5 -0
- package/dist/version-check.js.map +1 -1
- package/package.json +6 -6
- package/src/agent-detection.ts +457 -160
- package/src/ai-help.ts +393 -0
- package/src/api.ts +1 -1
- package/src/auth.ts +226 -17
- package/src/banner.ts +5 -0
- package/src/cache/agent-intro.ts +62 -0
- package/src/cache/index.ts +2 -0
- package/src/cache/resource-region.ts +28 -7
- package/src/catalyst.ts +16 -0
- package/src/cli.ts +375 -93
- package/src/cmd/ai/detect.ts +54 -0
- package/src/cmd/ai/index.ts +18 -1
- package/src/cmd/ai/intro.ts +154 -0
- package/src/cmd/ai/opencode/run.ts +5 -0
- package/src/cmd/build/ast.ts +97 -0
- package/src/cmd/build/vite/bun-dev-server.ts +2 -0
- package/src/cmd/build/vite/docs-generator.ts +15 -1
- package/src/cmd/build/vite/env-types-generator.ts +145 -0
- package/src/cmd/build/vite/index.ts +15 -0
- package/src/cmd/build/vite/public-asset-path-plugin.ts +8 -2
- package/src/cmd/build/vite/vite-builder.ts +31 -11
- package/src/cmd/cloud/db/create.ts +16 -16
- package/src/cmd/cloud/db/delete.ts +19 -19
- package/src/cmd/cloud/db/get.ts +32 -17
- package/src/cmd/cloud/deploy-fork.ts +2 -0
- package/src/cmd/cloud/deploy.ts +17 -0
- package/src/cmd/cloud/env/import.ts +6 -6
- package/src/cmd/cloud/env/list.ts +11 -11
- package/src/cmd/cloud/env/push.ts +6 -6
- package/src/cmd/cloud/keyvalue/util.ts +3 -3
- package/src/cmd/cloud/machine/list.ts +3 -3
- package/src/cmd/cloud/region/index.ts +3 -3
- package/src/cmd/cloud/region-lookup.ts +82 -22
- package/src/cmd/cloud/sandbox/cp.ts +9 -4
- package/src/cmd/cloud/sandbox/create.ts +2 -2
- package/src/cmd/cloud/sandbox/delete.ts +10 -7
- package/src/cmd/cloud/sandbox/download.ts +8 -5
- package/src/cmd/cloud/sandbox/env.ts +8 -5
- package/src/cmd/cloud/sandbox/exec.ts +10 -5
- package/src/cmd/cloud/sandbox/get.ts +13 -7
- package/src/cmd/cloud/sandbox/list.ts +47 -73
- package/src/cmd/cloud/sandbox/ls.ts +9 -5
- package/src/cmd/cloud/sandbox/mkdir.ts +9 -5
- package/src/cmd/cloud/sandbox/rm.ts +9 -5
- package/src/cmd/cloud/sandbox/rmdir.ts +9 -5
- package/src/cmd/cloud/sandbox/run.ts +1 -1
- package/src/cmd/cloud/sandbox/snapshot/build.ts +31 -31
- package/src/cmd/cloud/sandbox/snapshot/get.ts +17 -17
- package/src/cmd/cloud/sandbox/upload.ts +8 -5
- package/src/cmd/cloud/sandbox/util.ts +15 -14
- package/src/cmd/cloud/ssh.ts +2 -4
- package/src/cmd/cloud/storage/create.ts +16 -16
- package/src/cmd/cloud/storage/delete.ts +19 -19
- package/src/cmd/cloud/storage/get.ts +5 -16
- package/src/cmd/cloud/storage/list.ts +12 -6
- package/src/cmd/cloud/stream/create.ts +8 -4
- package/src/cmd/cloud/stream/delete.ts +28 -4
- package/src/cmd/cloud/stream/get.ts +102 -64
- package/src/cmd/cloud/stream/list.ts +76 -44
- package/src/cmd/cloud/stream/util.ts +39 -3
- package/src/cmd/cloud/vector/util.ts +3 -3
- package/src/cmd/dev/index.ts +4 -4
- package/src/cmd/git/account/add.ts +5 -5
- package/src/cmd/git/list.ts +7 -7
- package/src/cmd/project/add/database.ts +145 -0
- package/src/cmd/project/add/domain.ts +181 -0
- package/src/cmd/project/add/index.ts +35 -0
- package/src/cmd/project/add/storage.ts +147 -0
- package/src/cmd/project/auth/init.ts +6 -6
- package/src/cmd/project/index.ts +7 -0
- package/src/cmd/project/reconcile.ts +40 -0
- package/src/cmd/support/report.ts +5 -5
- package/src/cmd/support/system.ts +2 -2
- package/src/config.ts +40 -12
- package/src/errors.ts +7 -0
- package/src/index.ts +11 -0
- package/src/repl.ts +4 -1
- package/src/tui/box.ts +24 -9
- package/src/tui/colors.ts +83 -26
- package/src/tui/prompt.ts +55 -3
- package/src/tui/symbols.ts +6 -0
- package/src/tui.ts +55 -9
- package/src/types.ts +46 -2
- package/src/version-check.ts +6 -0
|
@@ -183,26 +183,26 @@ function buildFileTree(files: SnapshotFileInfo[]): TreeNode {
|
|
|
183
183
|
const parts = file.path.split('/');
|
|
184
184
|
let current = root;
|
|
185
185
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
186
|
+
for (let i = 0; i < parts.length; i++) {
|
|
187
|
+
const part = parts[i];
|
|
188
|
+
if (!part) continue;
|
|
189
|
+
if (!current.children.has(part)) {
|
|
190
|
+
current.children.set(part, {
|
|
191
|
+
name: part,
|
|
192
|
+
isFile: i === parts.length - 1,
|
|
193
|
+
children: new Map(),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
const child = current.children.get(part);
|
|
197
|
+
if (!child) continue;
|
|
198
|
+
current = child;
|
|
199
199
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
if (i === parts.length - 1) {
|
|
201
|
+
current.size = file.size;
|
|
202
|
+
current.isFile = true;
|
|
203
|
+
}
|
|
203
204
|
}
|
|
204
205
|
}
|
|
205
|
-
}
|
|
206
206
|
|
|
207
207
|
return root;
|
|
208
208
|
}
|
|
@@ -2,16 +2,16 @@ import { z } from 'zod';
|
|
|
2
2
|
import { readFileSync, statSync } from 'node:fs';
|
|
3
3
|
import { createCommand } from '../../../types';
|
|
4
4
|
import * as tui from '../../../tui';
|
|
5
|
-
import { createSandboxClient
|
|
5
|
+
import { createSandboxClient } from './util';
|
|
6
6
|
import { getCommand } from '../../../command-prefix';
|
|
7
|
-
import { sandboxUploadArchive } from '@agentuity/server';
|
|
7
|
+
import { sandboxUploadArchive, sandboxResolve } from '@agentuity/server';
|
|
8
8
|
|
|
9
9
|
export const uploadSubcommand = createCommand({
|
|
10
10
|
name: 'upload',
|
|
11
11
|
aliases: ['ul'],
|
|
12
12
|
description: 'Upload a compressed archive to a sandbox and extract it',
|
|
13
13
|
tags: ['slow', 'requires-auth'],
|
|
14
|
-
requires: { auth: true,
|
|
14
|
+
requires: { auth: true, apiClient: true },
|
|
15
15
|
examples: [
|
|
16
16
|
{
|
|
17
17
|
command: getCommand('cloud sandbox upload sbx_abc123 ./archive.tar.gz'),
|
|
@@ -45,9 +45,12 @@ export const uploadSubcommand = createCommand({
|
|
|
45
45
|
},
|
|
46
46
|
|
|
47
47
|
async handler(ctx) {
|
|
48
|
-
const { args, opts, options, auth, logger,
|
|
48
|
+
const { args, opts, options, auth, logger, apiClient } = ctx;
|
|
49
|
+
|
|
50
|
+
// Resolve sandbox to get region and orgId using CLI API
|
|
51
|
+
const sandboxInfo = await sandboxResolve(apiClient, args.sandboxId);
|
|
52
|
+
const { region, orgId } = sandboxInfo;
|
|
49
53
|
|
|
50
|
-
const region = await getSandboxRegion(logger, auth, config?.name, args.sandboxId, orgId);
|
|
51
54
|
const client = createSandboxClient(logger, auth, region);
|
|
52
55
|
|
|
53
56
|
const stat = statSync(args.archive);
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import type { Logger, FileToWrite } from '@agentuity/core';
|
|
4
|
-
import { APIClient,
|
|
4
|
+
import { APIClient, sandboxGet, getServiceUrls } from '@agentuity/server';
|
|
5
5
|
import type { AuthData } from '../../../types';
|
|
6
6
|
import { getGlobalCatalystAPIClient } from '../../../config';
|
|
7
|
-
import {
|
|
7
|
+
import { getResourceInfo, setResourceInfo, deleteResourceRegion } from '../../../cache';
|
|
8
8
|
import * as tui from '../../../tui';
|
|
9
9
|
import { ErrorCode } from '../../../errors';
|
|
10
10
|
|
|
11
11
|
export function createSandboxClient(logger: Logger, auth: AuthData, region: string): APIClient {
|
|
12
|
-
|
|
13
|
-
return new APIClient(urls.catalyst, logger, auth.apiKey);
|
|
12
|
+
return new APIClient(getServiceUrls(region).catalyst, logger, auth.apiKey);
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
/**
|
|
@@ -22,13 +21,13 @@ export async function getSandboxRegion(
|
|
|
22
21
|
auth: AuthData,
|
|
23
22
|
profileName = 'production',
|
|
24
23
|
sandboxId: string,
|
|
25
|
-
orgId
|
|
24
|
+
orgId?: string
|
|
26
25
|
): Promise<string> {
|
|
27
26
|
// Check cache first
|
|
28
|
-
const
|
|
29
|
-
if (
|
|
30
|
-
logger.trace(`[sandbox] Found cached region for ${sandboxId}: ${
|
|
31
|
-
return
|
|
27
|
+
const cachedInfo = await getResourceInfo('sandbox', profileName, sandboxId);
|
|
28
|
+
if (cachedInfo?.region) {
|
|
29
|
+
logger.trace(`[sandbox] Found cached region for ${sandboxId}: ${cachedInfo.region}`);
|
|
30
|
+
return cachedInfo.region;
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
// Fallback to API lookup using global client
|
|
@@ -41,7 +40,7 @@ export async function getSandboxRegion(
|
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
// Cache the result
|
|
44
|
-
await
|
|
43
|
+
await setResourceInfo('sandbox', profileName, sandboxId, sandbox.region, orgId);
|
|
45
44
|
logger.trace(`[sandbox] Cached region for ${sandboxId}: ${sandbox.region}`);
|
|
46
45
|
|
|
47
46
|
return sandbox.region;
|
|
@@ -55,7 +54,7 @@ export async function cacheSandboxRegion(
|
|
|
55
54
|
sandboxId: string,
|
|
56
55
|
region: string
|
|
57
56
|
): Promise<void> {
|
|
58
|
-
await
|
|
57
|
+
await setResourceInfo('sandbox', profileName, sandboxId, region);
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
/**
|
|
@@ -77,7 +76,7 @@ export async function clearSandboxRegionCache(
|
|
|
77
76
|
*
|
|
78
77
|
* @returns Array of FileToWrite objects
|
|
79
78
|
*/
|
|
80
|
-
export function parseFileArgs(fileArgs: string[] | undefined): FileToWrite[] {
|
|
79
|
+
export async function parseFileArgs(fileArgs: string[] | undefined): Promise<FileToWrite[]> {
|
|
81
80
|
if (!fileArgs || fileArgs.length === 0) {
|
|
82
81
|
return [];
|
|
83
82
|
}
|
|
@@ -106,7 +105,9 @@ export function parseFileArgs(fileArgs: string[] | undefined): FileToWrite[] {
|
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
const resolvedPath = resolve(localPath);
|
|
109
|
-
|
|
108
|
+
// Use Bun.file().exists() instead of Node's existsSync per coding guidelines
|
|
109
|
+
const fileExists = await Bun.file(resolvedPath).exists();
|
|
110
|
+
if (!fileExists) {
|
|
110
111
|
throw new Error(`File not found: ${localPath} (resolved to ${resolvedPath})`);
|
|
111
112
|
}
|
|
112
113
|
|
package/src/cmd/cloud/ssh.ts
CHANGED
|
@@ -71,16 +71,14 @@ export const sshSubcommand = createSubcommand({
|
|
|
71
71
|
const profileName = config?.name;
|
|
72
72
|
const targetIdentifier = identifier ?? projectId!;
|
|
73
73
|
|
|
74
|
-
//
|
|
75
|
-
const orgId = targetIdentifier.startsWith('sbx_') ? config?.preferences?.orgId : undefined;
|
|
76
|
-
|
|
74
|
+
// Region lookup handles org resolution automatically via CLI API
|
|
77
75
|
const region = await getIdentifierRegion(
|
|
78
76
|
logger,
|
|
79
77
|
auth,
|
|
80
78
|
apiClient,
|
|
81
79
|
profileName,
|
|
82
80
|
targetIdentifier,
|
|
83
|
-
orgId
|
|
81
|
+
undefined, // orgId resolved automatically for sandboxes
|
|
84
82
|
config
|
|
85
83
|
);
|
|
86
84
|
|
|
@@ -67,24 +67,24 @@ export const createSubcommand = defineSubcommand({
|
|
|
67
67
|
},
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
const resource = created[0];
|
|
71
|
+
if (resource) {
|
|
72
|
+
// Write environment variables to .env if running inside a project
|
|
73
|
+
if (ctx.projectDir && resource.env && Object.keys(resource.env).length > 0) {
|
|
74
|
+
await addResourceEnvVars(ctx.projectDir, resource.env);
|
|
75
|
+
if (!options.json) {
|
|
76
|
+
tui.info('Environment variables written to .env');
|
|
77
|
+
}
|
|
77
78
|
}
|
|
78
|
-
}
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
80
|
+
if (!options.json) {
|
|
81
|
+
tui.success(`Created storage: ${tui.bold(resource.name)}`);
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
success: true,
|
|
85
|
+
name: resource.name,
|
|
86
|
+
};
|
|
87
|
+
} else {
|
|
88
88
|
tui.fatal('Failed to create storage');
|
|
89
89
|
}
|
|
90
90
|
},
|
|
@@ -242,27 +242,27 @@ export const deleteSubcommand = createSubcommand({
|
|
|
242
242
|
},
|
|
243
243
|
});
|
|
244
244
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
245
|
+
const resource = deleted[0];
|
|
246
|
+
if (resource) {
|
|
247
|
+
// Clear cache entry for deleted bucket
|
|
248
|
+
await deleteResourceRegion('bucket', profileName, resource.name);
|
|
249
|
+
|
|
250
|
+
// Remove env vars from .env if running inside a project
|
|
251
|
+
if (ctx.projectDir && resource.env_keys.length > 0) {
|
|
252
|
+
await removeResourceEnvVars(ctx.projectDir, resource.env_keys);
|
|
253
|
+
if (!options.json) {
|
|
254
|
+
tui.info(`Removed ${resource.env_keys.join(', ')} from .env`);
|
|
255
|
+
}
|
|
255
256
|
}
|
|
256
|
-
}
|
|
257
257
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
258
|
+
if (!options.json) {
|
|
259
|
+
tui.success(`Deleted storage bucket: ${tui.bold(resource.name)}`);
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
success: true,
|
|
263
|
+
name: resource.name,
|
|
264
|
+
};
|
|
265
|
+
} else {
|
|
266
266
|
tui.error('Failed to delete storage bucket');
|
|
267
267
|
return { success: false, name: bucketName };
|
|
268
268
|
}
|
|
@@ -5,7 +5,7 @@ import * as tui from '../../../tui';
|
|
|
5
5
|
import { getGlobalCatalystAPIClient } from '../../../config';
|
|
6
6
|
import { getCommand } from '../../../command-prefix';
|
|
7
7
|
import { ErrorCode } from '../../../errors';
|
|
8
|
-
import {
|
|
8
|
+
import { setResourceInfo } from '../../../cache';
|
|
9
9
|
|
|
10
10
|
const StorageGetResponseSchema = z.object({
|
|
11
11
|
bucket_name: z.string().describe('Storage bucket name'),
|
|
@@ -26,7 +26,6 @@ export const getSubcommand = createSubcommand({
|
|
|
26
26
|
description: 'Show details about a specific storage bucket',
|
|
27
27
|
tags: ['read-only', 'fast', 'requires-auth'],
|
|
28
28
|
requires: { auth: true },
|
|
29
|
-
optional: { org: true },
|
|
30
29
|
idempotent: true,
|
|
31
30
|
examples: [
|
|
32
31
|
{
|
|
@@ -64,35 +63,25 @@ export const getSubcommand = createSubcommand({
|
|
|
64
63
|
const profileName = config?.name ?? 'production';
|
|
65
64
|
const catalystClient = await getGlobalCatalystAPIClient(logger, auth, profileName);
|
|
66
65
|
|
|
67
|
-
//
|
|
68
|
-
const cachedInfo = await getResourceInfo('bucket', profileName, args.name);
|
|
69
|
-
const orgId = ctx.orgId ?? cachedInfo?.orgId;
|
|
70
|
-
|
|
71
|
-
if (!orgId) {
|
|
72
|
-
tui.fatal(
|
|
73
|
-
`Organization not found for bucket '${args.name}'. Run 'agentuity cloud storage list' first or specify --org-id.`,
|
|
74
|
-
ErrorCode.INVALID_ARGUMENT
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
66
|
+
// Search across all orgs the user has access to
|
|
78
67
|
const resources = await tui.spinner({
|
|
79
68
|
message: `Fetching storage bucket ${args.name}`,
|
|
80
69
|
clearOnSuccess: true,
|
|
81
70
|
callback: async () => {
|
|
82
|
-
return listOrgResources(catalystClient, { type: 's3'
|
|
71
|
+
return listOrgResources(catalystClient, { type: 's3' });
|
|
83
72
|
},
|
|
84
73
|
});
|
|
85
74
|
|
|
86
75
|
const bucket = resources.s3.find((s3) => s3.bucket_name === args.name);
|
|
87
76
|
|
|
88
77
|
// Cache the bucket info for future lookups
|
|
89
|
-
if (bucket?.cloud_region) {
|
|
78
|
+
if (bucket?.cloud_region && bucket.org_id) {
|
|
90
79
|
await setResourceInfo(
|
|
91
80
|
'bucket',
|
|
92
81
|
profileName,
|
|
93
82
|
bucket.bucket_name,
|
|
94
83
|
bucket.cloud_region,
|
|
95
|
-
|
|
84
|
+
bucket.org_id
|
|
96
85
|
);
|
|
97
86
|
}
|
|
98
87
|
|
|
@@ -44,7 +44,7 @@ export const listSubcommand = createSubcommand({
|
|
|
44
44
|
aliases: ['ls'],
|
|
45
45
|
description: 'List storage resources or files in a bucket',
|
|
46
46
|
tags: ['read-only', 'fast', 'requires-auth'],
|
|
47
|
-
requires: { auth: true
|
|
47
|
+
requires: { auth: true },
|
|
48
48
|
idempotent: true,
|
|
49
49
|
examples: [
|
|
50
50
|
{ command: getCommand('cloud storage list'), description: 'List items' },
|
|
@@ -85,23 +85,29 @@ export const listSubcommand = createSubcommand({
|
|
|
85
85
|
: '/services/storage',
|
|
86
86
|
|
|
87
87
|
async handler(ctx) {
|
|
88
|
-
const { logger, args, opts, options,
|
|
88
|
+
const { logger, args, opts, options, auth, config } = ctx;
|
|
89
89
|
|
|
90
90
|
const catalystClient = await getGlobalCatalystAPIClient(logger, auth, config?.name);
|
|
91
91
|
|
|
92
92
|
const profileName = config?.name ?? 'production';
|
|
93
93
|
const resources = await tui.spinner({
|
|
94
|
-
message:
|
|
94
|
+
message: 'Fetching storage',
|
|
95
95
|
clearOnSuccess: true,
|
|
96
96
|
callback: async () => {
|
|
97
|
-
return listOrgResources(catalystClient, { type: 's3'
|
|
97
|
+
return listOrgResources(catalystClient, { type: 's3' });
|
|
98
98
|
},
|
|
99
99
|
});
|
|
100
100
|
|
|
101
101
|
// Cache each bucket with its region and orgId for future lookups
|
|
102
102
|
for (const s3 of resources.s3) {
|
|
103
|
-
if (s3.cloud_region) {
|
|
104
|
-
await setResourceInfo(
|
|
103
|
+
if (s3.cloud_region && s3.org_id) {
|
|
104
|
+
await setResourceInfo(
|
|
105
|
+
'bucket',
|
|
106
|
+
profileName,
|
|
107
|
+
s3.bucket_name,
|
|
108
|
+
s3.cloud_region,
|
|
109
|
+
s3.org_id
|
|
110
|
+
);
|
|
105
111
|
}
|
|
106
112
|
}
|
|
107
113
|
|
|
@@ -4,6 +4,7 @@ import { createCommand } from '../../../types';
|
|
|
4
4
|
import * as tui from '../../../tui';
|
|
5
5
|
import { createStorageAdapter } from './util';
|
|
6
6
|
import { getCommand } from '../../../command-prefix';
|
|
7
|
+
import { getDefaultRegion } from '../../../config';
|
|
7
8
|
|
|
8
9
|
const StreamCreateResponseSchema = z.object({
|
|
9
10
|
id: z.string().describe('Stream ID'),
|
|
@@ -19,8 +20,8 @@ export const createSubcommand = createCommand({
|
|
|
19
20
|
aliases: ['new'],
|
|
20
21
|
description: 'Create a new stream and upload content',
|
|
21
22
|
tags: ['mutating', 'creates-resource', 'slow', 'requires-auth', 'uses-stdin'],
|
|
22
|
-
requires: { auth: true
|
|
23
|
-
optional: { project: true },
|
|
23
|
+
requires: { auth: true },
|
|
24
|
+
optional: { project: true, region: true, org: true },
|
|
24
25
|
idempotent: false,
|
|
25
26
|
examples: [
|
|
26
27
|
{
|
|
@@ -77,9 +78,12 @@ export const createSubcommand = createCommand({
|
|
|
77
78
|
webUrl: '/services/stream',
|
|
78
79
|
|
|
79
80
|
async handler(ctx) {
|
|
80
|
-
const { args, opts, options } = ctx;
|
|
81
|
+
const { args, opts, options, config } = ctx;
|
|
81
82
|
const started = Date.now();
|
|
82
|
-
|
|
83
|
+
|
|
84
|
+
// Resolve region from config if not provided
|
|
85
|
+
const region = ctx.region ?? (await getDefaultRegion(config?.name, config));
|
|
86
|
+
const storage = await createStorageAdapter({ ...ctx, region });
|
|
83
87
|
|
|
84
88
|
// Parse metadata if provided
|
|
85
89
|
let metadata: Record<string, string> | undefined;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { streamGet } from '@agentuity/server';
|
|
2
3
|
import { createCommand } from '../../../types';
|
|
3
4
|
import * as tui from '../../../tui';
|
|
4
|
-
import {
|
|
5
|
+
import { createStorageAdapterForOrg } from './util';
|
|
5
6
|
import { getCommand } from '../../../command-prefix';
|
|
6
7
|
const DeleteStreamResponseSchema = z.object({
|
|
7
8
|
id: z.string().describe('Stream ID'),
|
|
@@ -13,7 +14,7 @@ export const deleteSubcommand = createCommand({
|
|
|
13
14
|
description: 'Delete a stream by ID (soft delete)',
|
|
14
15
|
tags: ['destructive', 'deletes-resource', 'slow', 'requires-auth'],
|
|
15
16
|
idempotent: true,
|
|
16
|
-
requires: { auth: true,
|
|
17
|
+
requires: { auth: true, apiClient: true },
|
|
17
18
|
optional: { project: true },
|
|
18
19
|
examples: [
|
|
19
20
|
{ command: getCommand('stream delete stream-id-123'), description: 'Delete a stream' },
|
|
@@ -34,9 +35,32 @@ export const deleteSubcommand = createCommand({
|
|
|
34
35
|
},
|
|
35
36
|
|
|
36
37
|
async handler(ctx) {
|
|
37
|
-
const { args, options } = ctx;
|
|
38
|
+
const { args, options, logger, auth, apiClient } = ctx;
|
|
38
39
|
const started = Date.now();
|
|
39
|
-
|
|
40
|
+
|
|
41
|
+
if (!apiClient) {
|
|
42
|
+
tui.fatal('API client is required for stream delete');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Look up the stream to get its org and region
|
|
46
|
+
const streamInfo = await streamGet(apiClient, args.id);
|
|
47
|
+
|
|
48
|
+
// Extract region from the stream URL (e.g., https://streams-use.agentuity.cloud/...)
|
|
49
|
+
let region = 'usc'; // default
|
|
50
|
+
const urlMatch = streamInfo.url.match(/https:\/\/streams-([^.]+)\.agentuity\.cloud/);
|
|
51
|
+
if (urlMatch?.[1]) {
|
|
52
|
+
region = urlMatch[1];
|
|
53
|
+
} else if (streamInfo.url.includes('streams.agentuity.io')) {
|
|
54
|
+
region = 'local';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Use the stream's orgId for auth
|
|
58
|
+
const storage = createStorageAdapterForOrg({
|
|
59
|
+
logger,
|
|
60
|
+
auth,
|
|
61
|
+
region,
|
|
62
|
+
orgId: streamInfo.orgId,
|
|
63
|
+
});
|
|
40
64
|
|
|
41
65
|
await storage.delete(args.id);
|
|
42
66
|
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { streamGet } from '@agentuity/server';
|
|
3
|
+
import { StructuredError } from '@agentuity/core';
|
|
2
4
|
import { createCommand } from '../../../types';
|
|
3
5
|
import * as tui from '../../../tui';
|
|
4
|
-
import { createStorageAdapter } from './util';
|
|
5
6
|
import { getCommand } from '../../../command-prefix';
|
|
6
7
|
|
|
8
|
+
const StreamGetError = StructuredError('StreamGetError')<{
|
|
9
|
+
streamId?: string;
|
|
10
|
+
}>();
|
|
11
|
+
const StreamDownloadError = StructuredError('StreamDownloadError')<{
|
|
12
|
+
statusCode?: number;
|
|
13
|
+
statusText?: string;
|
|
14
|
+
}>();
|
|
15
|
+
const StreamReaderError = StructuredError('StreamReaderError');
|
|
16
|
+
|
|
7
17
|
const GetStreamResponseSchema = z.object({
|
|
8
18
|
id: z.string().describe('Stream ID'),
|
|
9
19
|
namespace: z.string().describe('Stream namespace'),
|
|
@@ -16,19 +26,21 @@ export const getSubcommand = createCommand({
|
|
|
16
26
|
name: 'get',
|
|
17
27
|
description: 'Get detailed information about a specific stream',
|
|
18
28
|
tags: ['read-only', 'slow', 'requires-auth'],
|
|
19
|
-
requires: { auth: true,
|
|
29
|
+
requires: { auth: true, apiClient: true },
|
|
20
30
|
optional: { project: true },
|
|
21
31
|
idempotent: true,
|
|
22
32
|
examples: [
|
|
23
|
-
{ command: getCommand('stream get stream-id-123'), description: 'Get stream details' },
|
|
24
|
-
{ command: getCommand('stream get stream-id-123 --json'), description: 'Get stream as JSON' },
|
|
25
33
|
{
|
|
26
|
-
command: getCommand('stream get
|
|
27
|
-
description: '
|
|
34
|
+
command: getCommand('stream get stream_abc123'),
|
|
35
|
+
description: 'Get stream details',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
command: getCommand('stream get stream_abc123 --json'),
|
|
39
|
+
description: 'Get stream as JSON',
|
|
28
40
|
},
|
|
29
41
|
{
|
|
30
|
-
command: getCommand('stream get
|
|
31
|
-
description: 'Download stream
|
|
42
|
+
command: getCommand('stream get stream_abc123 --output stream.dat'),
|
|
43
|
+
description: 'Download stream to file',
|
|
32
44
|
},
|
|
33
45
|
],
|
|
34
46
|
schema: {
|
|
@@ -43,75 +55,101 @@ export const getSubcommand = createCommand({
|
|
|
43
55
|
webUrl: (ctx) => `/services/stream/${encodeURIComponent(ctx.args.id)}`,
|
|
44
56
|
|
|
45
57
|
async handler(ctx) {
|
|
46
|
-
const { args, opts, options } = ctx;
|
|
58
|
+
const { args, opts, options, apiClient } = ctx;
|
|
47
59
|
const started = Date.now();
|
|
48
|
-
const storage = await createStorageAdapter(ctx);
|
|
49
60
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
61
|
+
try {
|
|
62
|
+
// Get stream metadata using the new API
|
|
63
|
+
const stream = await streamGet(apiClient, args.id);
|
|
64
|
+
const durationMs = Date.now() - started;
|
|
65
|
+
|
|
66
|
+
// If --output is specified, download the stream content
|
|
67
|
+
if (opts.output) {
|
|
68
|
+
const downloadStarted = Date.now();
|
|
55
69
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
70
|
+
// Fetch the stream content from the URL
|
|
71
|
+
const response = await fetch(stream.url);
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
throw new StreamDownloadError({
|
|
74
|
+
message: `Failed to download stream: ${response.status} ${response.statusText}`,
|
|
75
|
+
statusCode: response.status,
|
|
76
|
+
statusText: response.statusText,
|
|
77
|
+
});
|
|
62
78
|
}
|
|
63
|
-
await writer.end();
|
|
64
|
-
const durationMs = Date.now() - started;
|
|
65
|
-
const stats = await Bun.file(opts.output).stat();
|
|
66
|
-
tui.success(
|
|
67
|
-
`downloaded ${tui.formatBytes(stats.size)} to ${opts.output} in ${durationMs.toFixed(1)}ms`
|
|
68
|
-
);
|
|
69
79
|
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
return {
|
|
73
|
-
id: args.id,
|
|
74
|
-
namespace: stream.namespace ?? '',
|
|
75
|
-
metadata: stream.metadata ?? {},
|
|
76
|
-
url: stream.url ?? '',
|
|
77
|
-
sizeBytes: stats.size,
|
|
78
|
-
};
|
|
79
|
-
} finally {
|
|
80
|
-
reader.releaseLock();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
80
|
+
const file = Bun.file(opts.output);
|
|
81
|
+
const writer = file.writer();
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
const reader = response.body?.getReader();
|
|
84
|
+
if (!reader) {
|
|
85
|
+
throw new StreamReaderError({ message: 'Failed to get stream reader' });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
while (true) {
|
|
90
|
+
const { done, value } = await reader.read();
|
|
91
|
+
if (done) break;
|
|
92
|
+
writer.write(value);
|
|
93
|
+
}
|
|
94
|
+
await writer.end();
|
|
95
|
+
const downloadDurationMs = Date.now() - downloadStarted;
|
|
96
|
+
const stats = await Bun.file(opts.output).stat();
|
|
97
|
+
tui.success(
|
|
98
|
+
`downloaded ${tui.formatBytes(stats.size)} to ${opts.output} in ${downloadDurationMs.toFixed(1)}ms`
|
|
99
|
+
);
|
|
87
100
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
101
|
+
return {
|
|
102
|
+
id: stream.id,
|
|
103
|
+
namespace: stream.namespace ?? '',
|
|
104
|
+
metadata: stream.metadata ?? {},
|
|
105
|
+
url: stream.url ?? '',
|
|
106
|
+
sizeBytes: stats.size,
|
|
107
|
+
};
|
|
108
|
+
} finally {
|
|
109
|
+
reader.releaseLock();
|
|
110
|
+
}
|
|
91
111
|
}
|
|
92
112
|
|
|
93
|
-
|
|
113
|
+
// Display metadata
|
|
114
|
+
if (!options.json) {
|
|
115
|
+
const sizeBytes = stream.sizeBytes ?? 0;
|
|
94
116
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
117
|
+
console.log(`Namespace: ${tui.bold(stream.namespace ?? 'unknown')}`);
|
|
118
|
+
console.log(`ID: ${stream.id}`);
|
|
119
|
+
console.log(`Size: ${tui.formatBytes(sizeBytes)}`);
|
|
120
|
+
console.log(`URL: ${tui.link(stream.url ?? 'unknown')}`);
|
|
121
|
+
if (stream.metadata && Object.keys(stream.metadata).length > 0) {
|
|
122
|
+
console.log(`Metadata:`);
|
|
123
|
+
for (const [key, value] of Object.entries(stream.metadata)) {
|
|
124
|
+
console.log(` ${key}: ${value}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (stream.completed !== undefined) {
|
|
128
|
+
console.log(`Completed: ${stream.completed ? 'yes' : 'no'}`);
|
|
103
129
|
}
|
|
130
|
+
if (stream.expiresAt) {
|
|
131
|
+
console.log(`Expires: ${stream.expiresAt}`);
|
|
132
|
+
}
|
|
133
|
+
tui.success(`retrieved in ${durationMs.toFixed(1)}ms`);
|
|
104
134
|
}
|
|
105
|
-
tui.success(`retrieved in ${durationMs.toFixed(1)}ms`);
|
|
106
|
-
}
|
|
107
135
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
136
|
+
return {
|
|
137
|
+
id: stream.id,
|
|
138
|
+
namespace: stream.namespace,
|
|
139
|
+
metadata: stream.metadata,
|
|
140
|
+
url: stream.url,
|
|
141
|
+
sizeBytes: stream.sizeBytes,
|
|
142
|
+
};
|
|
143
|
+
} catch (ex) {
|
|
144
|
+
if (
|
|
145
|
+
ex instanceof StreamGetError ||
|
|
146
|
+
ex instanceof StreamDownloadError ||
|
|
147
|
+
ex instanceof StreamReaderError
|
|
148
|
+
) {
|
|
149
|
+
throw ex;
|
|
150
|
+
}
|
|
151
|
+
throw new StreamGetError({ message: `Failed to get stream: ${ex}`, streamId: args.id });
|
|
152
|
+
}
|
|
115
153
|
},
|
|
116
154
|
});
|
|
117
155
|
|