deepspace 0.28.0 → 0.28.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.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/cli/cli.ts
4
4
  import {
5
- defineCommand as defineCommand14,
5
+ defineCommand as defineCommand15,
6
6
  runMain,
7
7
  runCommand,
8
8
  renderUsage
@@ -660,6 +660,9 @@ var INVALID_URLS = {
660
660
  platform: "http://127.0.0.1:9",
661
661
  deploy: "http://127.0.0.1:9"
662
662
  };
663
+ function appDomainForEnv(env) {
664
+ return env === "production" ? "app.space" : env === "staging" ? "spacestest.com" : null;
665
+ }
663
666
  var PLATFORM_URLS = DEEPSPACE_ENV === "production" ? PROD_URLS : DEEPSPACE_ENV === "staging" ? STAGING_URLS : INVALID_URLS;
664
667
  var PLANE_AUTH_URLS = {
665
668
  production: PROD_URLS.auth,
@@ -689,10 +692,11 @@ function decodeJwtPayload(token) {
689
692
  return JSON.parse(Buffer.from(payloadSegment, "base64url").toString("utf8"));
690
693
  }
691
694
 
692
- // src/cli/session.ts
695
+ // src/shared/auth-session.ts
693
696
  var SESSION_COOKIE = "__Secure-better-auth.session_token";
694
- async function exchangeSession(authUrl, sessionToken) {
695
- const path = "/api/auth/token";
697
+
698
+ // src/cli/session.ts
699
+ async function exchangeSessionToken(authUrl, sessionToken, path, action, body) {
696
700
  let res;
697
701
  try {
698
702
  res = await fetchWithTransientRetry(
@@ -701,8 +705,10 @@ async function exchangeSession(authUrl, sessionToken) {
701
705
  method: "POST",
702
706
  headers: {
703
707
  Cookie: `${SESSION_COOKIE}=${encodeURIComponent(sessionToken)}`,
704
- Origin: authUrl
705
- }
708
+ Origin: authUrl,
709
+ ...body === void 0 ? {} : { "Content-Type": "application/json" }
710
+ },
711
+ body
706
712
  }),
707
713
  { timeoutMs: 15e3 }
708
714
  );
@@ -717,7 +723,7 @@ async function exchangeSession(authUrl, sessionToken) {
717
723
  if (res.status === 401) return null;
718
724
  if (!res.ok) {
719
725
  throw new ApiError(
720
- `The auth service could not refresh the CLI token (HTTP ${res.status}). Retry without logging in again.`,
726
+ `The auth service could not ${action} (HTTP ${res.status}). Retry without logging in again.`,
721
727
  res.status,
722
728
  res.status === 429 ? "rate_limited" : "auth_service_unavailable",
723
729
  path
@@ -744,6 +750,18 @@ async function exchangeSession(authUrl, sessionToken) {
744
750
  }
745
751
  return data.token;
746
752
  }
753
+ function exchangeSession(authUrl, sessionToken) {
754
+ return exchangeSessionToken(authUrl, sessionToken, "/api/auth/token", "refresh the CLI token");
755
+ }
756
+ function exchangeAgentSession(authUrl, sessionToken, target2) {
757
+ return exchangeSessionToken(
758
+ authUrl,
759
+ sessionToken,
760
+ "/api/auth/agent-token",
761
+ "mint the app-specific agent token",
762
+ JSON.stringify({ target: target2 })
763
+ );
764
+ }
747
765
 
748
766
  // src/cli/lib/secure-file.ts
749
767
  import { chmodSync, writeFileSync } from "fs";
@@ -814,6 +832,14 @@ function isTokenValid(jwt, minimumValidityMs) {
814
832
  async function refreshTokenFromSession() {
815
833
  return await exchangeStoredSession();
816
834
  }
835
+ async function mintAgentToken(target2) {
836
+ if (!existsSync(SESSION_PATH)) throw notAuthenticated("Not logged in");
837
+ const sessionToken = readFileSync2(SESSION_PATH, "utf-8").trim();
838
+ const token = await exchangeAgentSession(AUTH_URL, sessionToken, target2);
839
+ if (!token)
840
+ throw notAuthenticated("The stored session is no longer valid (expired or unreadable)");
841
+ return token;
842
+ }
817
843
  async function exchangeStoredSession() {
818
844
  if (!existsSync(SESSION_PATH)) return null;
819
845
  const sessionToken = readFileSync2(SESSION_PATH, "utf-8").trim();
@@ -4436,7 +4462,6 @@ function saveTestAccountStore(store) {
4436
4462
  }
4437
4463
 
4438
4464
  // src/cli/lib/test-account-service.ts
4439
- var SESSION_COOKIE2 = "__Secure-better-auth.session_token";
4440
4465
  var TestAccountServiceError = class extends Error {
4441
4466
  constructor(message, code) {
4442
4467
  super(message);
@@ -4449,7 +4474,7 @@ function serviceError(data, fallback) {
4449
4474
  var AUTH_URL4 = process.env.DEEPSPACE_AUTH_URL ?? PLATFORM_URLS.auth;
4450
4475
  function sessionCookie() {
4451
4476
  const token = readFileSync12(SESSION_PATH, "utf-8").trim();
4452
- return `${SESSION_COOKIE2}=${encodeURIComponent(token)}`;
4477
+ return `${SESSION_COOKIE}=${encodeURIComponent(token)}`;
4453
4478
  }
4454
4479
  async function fetchRemoteTestAccounts() {
4455
4480
  const response = await fetch(`${AUTH_URL4}/api/auth/test-accounts`, {
@@ -10975,6 +11000,412 @@ var integrations_default = defineCommand9({
10975
11000
  }
10976
11001
  });
10977
11002
 
11003
+ // src/cli/commands/agent.ts
11004
+ import { createReadStream } from "fs";
11005
+ import { defineCommand as defineCommand10 } from "citty";
11006
+
11007
+ // src/server/agent-target.ts
11008
+ var PRODUCTION_OFFICIAL_AGENT_ORIGINS = ["https://admin.deep.space"];
11009
+ var PRODUCTION_APP_DOMAIN = "app.space";
11010
+ function normalizeAgentTargetOrigin(value, policy) {
11011
+ if (typeof value !== "string" || !value) return null;
11012
+ let url;
11013
+ try {
11014
+ url = new URL(value);
11015
+ } catch {
11016
+ return null;
11017
+ }
11018
+ if (url.username || url.password || url.search || url.hash || url.pathname !== "/") return null;
11019
+ const hostname = url.hostname.toLowerCase();
11020
+ const loopback = ["localhost", "127.0.0.1", "[::1]"].includes(hostname);
11021
+ if (loopback) {
11022
+ return policy.allowLoopback && ["http:", "https:"].includes(url.protocol) ? url.origin : null;
11023
+ }
11024
+ if (url.protocol !== "https:" || url.port) return null;
11025
+ if (policy.appDomain.toLowerCase() === PRODUCTION_APP_DOMAIN && PRODUCTION_OFFICIAL_AGENT_ORIGINS.includes(url.origin)) {
11026
+ return url.origin;
11027
+ }
11028
+ const suffix = `.${policy.appDomain.toLowerCase()}`;
11029
+ if (!hostname.endsWith(suffix)) return null;
11030
+ const label = hostname.slice(0, -suffix.length);
11031
+ return !label.includes(".") && validateAppName(label).valid ? url.origin : null;
11032
+ }
11033
+
11034
+ // src/shared/bounded-body.ts
11035
+ var BodyTooLargeError = class extends Error {
11036
+ constructor(maxBytes) {
11037
+ super(`Body exceeds ${maxBytes} bytes`);
11038
+ this.maxBytes = maxBytes;
11039
+ this.name = "BodyTooLargeError";
11040
+ }
11041
+ };
11042
+ async function readBoundedBodyText(source, maxBytes) {
11043
+ if (!Number.isSafeInteger(maxBytes) || maxBytes <= 0) {
11044
+ throw new TypeError("maxBytes must be a positive safe integer");
11045
+ }
11046
+ const declared = source.headers.get("content-length");
11047
+ if (declared && /^\d+$/.test(declared.trim()) && Number(declared) > maxBytes) {
11048
+ await source.body?.cancel().catch(() => void 0);
11049
+ throw new BodyTooLargeError(maxBytes);
11050
+ }
11051
+ if (!source.body) return "";
11052
+ const reader = source.body.getReader();
11053
+ const decoder = new TextDecoder();
11054
+ let bytes = 0;
11055
+ let text2 = "";
11056
+ try {
11057
+ while (true) {
11058
+ const chunk = await reader.read();
11059
+ if (chunk.done) break;
11060
+ bytes += chunk.value.byteLength;
11061
+ if (bytes > maxBytes) {
11062
+ await reader.cancel().catch(() => void 0);
11063
+ throw new BodyTooLargeError(maxBytes);
11064
+ }
11065
+ text2 += decoder.decode(chunk.value, { stream: true });
11066
+ }
11067
+ return text2 + decoder.decode();
11068
+ } finally {
11069
+ reader.releaseLock();
11070
+ }
11071
+ }
11072
+
11073
+ // src/shared/agent-tool-protocol.ts
11074
+ var AGENT_TOOL_REQUEST_BODY_CAP = 64 * 1024;
11075
+ var AGENT_TOOL_RESPONSE_BODY_CAP = 1024 * 1024;
11076
+
11077
+ // src/cli/commands/agent.ts
11078
+ var DEFAULT_TIMEOUT_MS2 = 12e4;
11079
+ var MAX_TIMEOUT_MS = 6e5;
11080
+ var MAX_INPUT_BYTES = AGENT_TOOL_REQUEST_BODY_CAP;
11081
+ var MAX_RESPONSE_BYTES = AGENT_TOOL_RESPONSE_BODY_CAP;
11082
+ function badApp(message) {
11083
+ throw new Refusal(message, "invalid_agent_app");
11084
+ }
11085
+ function isCanonicalAppLabel(value) {
11086
+ return value.length >= APP_NAME_RULES.minLength && value.length <= APP_NAME_RULES.maxLength && APP_NAME_RULES.pattern.test(value);
11087
+ }
11088
+ function resolveAgentTarget(app2, plane = DEEPSPACE_ENV) {
11089
+ if (typeof app2 !== "string" || !app2)
11090
+ badApp("App must be a canonical app name or canonical app URL.");
11091
+ const appDomain = appDomainForEnv(plane);
11092
+ if (!appDomain) badApp("The selected DeepSpace environment is invalid.");
11093
+ if (app2.toLowerCase() === "localhost") {
11094
+ badApp("Pass an explicit loopback URL for local development (e.g. 'http://localhost:8787').");
11095
+ }
11096
+ if (isCanonicalAppLabel(app2)) {
11097
+ return { url: `https://${app2}.${appDomain}` };
11098
+ }
11099
+ const url = normalizeAgentTargetOrigin(app2, {
11100
+ appDomain,
11101
+ allowLoopback: true
11102
+ });
11103
+ if (!url) {
11104
+ badApp(
11105
+ "App URL must be an exact canonical app origin (or a root loopback URL for local development)."
11106
+ );
11107
+ }
11108
+ return { url };
11109
+ }
11110
+ function parseAgentTimeout(raw) {
11111
+ if (raw == null) return DEFAULT_TIMEOUT_MS2;
11112
+ const value = typeof raw === "number" ? raw : Number(raw);
11113
+ if (!Number.isInteger(value) || value <= 0 || value > MAX_TIMEOUT_MS) {
11114
+ throw new Refusal(
11115
+ `Invalid --timeout '${String(raw)}'. Must be a positive integer up to ${MAX_TIMEOUT_MS} milliseconds.`,
11116
+ "invalid_timeout"
11117
+ );
11118
+ }
11119
+ return value;
11120
+ }
11121
+ function assertInputSize(value) {
11122
+ if (Buffer.byteLength(value) > MAX_INPUT_BYTES) {
11123
+ throw new Refusal(`Input exceeds the ${MAX_INPUT_BYTES}-byte limit.`, "input_too_large");
11124
+ }
11125
+ }
11126
+ function serializeAgentInput(input) {
11127
+ const body = JSON.stringify({ input });
11128
+ if (Buffer.byteLength(body) > AGENT_TOOL_REQUEST_BODY_CAP) {
11129
+ throw new Refusal(
11130
+ `Tool request exceeds the ${AGENT_TOOL_REQUEST_BODY_CAP}-byte limit.`,
11131
+ "input_too_large"
11132
+ );
11133
+ }
11134
+ return body;
11135
+ }
11136
+ async function readBoundedLocalInput(source) {
11137
+ const chunks = [];
11138
+ let size = 0;
11139
+ for await (const chunk of source) {
11140
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
11141
+ size += buffer.length;
11142
+ if (size > MAX_INPUT_BYTES) {
11143
+ throw new Refusal(`Input exceeds the ${MAX_INPUT_BYTES}-byte limit.`, "input_too_large");
11144
+ }
11145
+ chunks.push(buffer);
11146
+ }
11147
+ return Buffer.concat(chunks).toString("utf8");
11148
+ }
11149
+ async function resolveAgentInput(opts) {
11150
+ if (opts.input != null && opts.inputFile != null) {
11151
+ throw new Refusal("Pass either --input or --input-file, not both.", "conflicting_input_args");
11152
+ }
11153
+ let raw = "{}";
11154
+ if (opts.input != null) {
11155
+ raw = opts.input;
11156
+ assertInputSize(raw);
11157
+ } else if (opts.inputFile != null) {
11158
+ if (opts.inputFile === "-") {
11159
+ raw = await readBoundedLocalInput(process.stdin);
11160
+ } else {
11161
+ try {
11162
+ raw = await readBoundedLocalInput(createReadStream(opts.inputFile));
11163
+ } catch (error) {
11164
+ if (error instanceof Refusal) throw error;
11165
+ throw new Refusal(`Could not read input file '${opts.inputFile}'.`, "input_file_unreadable");
11166
+ }
11167
+ }
11168
+ }
11169
+ try {
11170
+ return JSON.parse(raw);
11171
+ } catch {
11172
+ throw new Refusal("Input is not valid JSON.", "invalid_input_json");
11173
+ }
11174
+ }
11175
+ function isRecord(value) {
11176
+ return typeof value === "object" && value !== null && !Array.isArray(value);
11177
+ }
11178
+ function validApp(value) {
11179
+ return isRecord(value) && typeof value.id === "string" && typeof value.name === "string";
11180
+ }
11181
+ function validTool(value) {
11182
+ return isRecord(value) && typeof value.name === "string" && typeof value.description === "string" && Object.prototype.hasOwnProperty.call(value, "inputSchema");
11183
+ }
11184
+ function parseToolsResponse(value) {
11185
+ if (!isRecord(value) || value.ok !== true || !validApp(value.app) || !Array.isArray(value.tools)) {
11186
+ throw new Refusal("The app returned an unexpected tools response.", "invalid_agent_response");
11187
+ }
11188
+ if (!value.tools.every(validTool)) {
11189
+ throw new Refusal("The app returned an invalid tool definition.", "invalid_agent_response");
11190
+ }
11191
+ return { ok: true, app: value.app, tools: value.tools };
11192
+ }
11193
+ function parseInvokeResponse(value) {
11194
+ if (!isRecord(value) || value.ok !== true || !Object.prototype.hasOwnProperty.call(value, "result")) {
11195
+ throw new Refusal("The app returned an unexpected tool response.", "invalid_agent_response");
11196
+ }
11197
+ return { ok: true, result: value.result };
11198
+ }
11199
+ function safeServerCode(value) {
11200
+ return typeof value === "string" && /^[a-z][a-z0-9_]{0,63}$/.test(value) ? value : void 0;
11201
+ }
11202
+ function redact(value, tokens) {
11203
+ return tokens.reduce(
11204
+ (text2, token) => token ? text2.split(token).join("[redacted]") : text2,
11205
+ value
11206
+ );
11207
+ }
11208
+ function redactValue(value, tokens) {
11209
+ if (typeof value === "string") return redact(value, tokens);
11210
+ if (Array.isArray(value)) return value.map((item) => redactValue(item, tokens));
11211
+ if (isRecord(value)) {
11212
+ return Object.fromEntries(
11213
+ Object.entries(value).map(([key, item]) => [redact(key, tokens), redactValue(item, tokens)])
11214
+ );
11215
+ }
11216
+ return value;
11217
+ }
11218
+ async function readResponseText(response) {
11219
+ try {
11220
+ return await readBoundedBodyText(response, MAX_RESPONSE_BYTES);
11221
+ } catch (error) {
11222
+ if (error instanceof BodyTooLargeError) {
11223
+ throw new Refusal(
11224
+ `App response exceeds the ${MAX_RESPONSE_BYTES}-byte limit.`,
11225
+ "response_too_large"
11226
+ );
11227
+ }
11228
+ throw error;
11229
+ }
11230
+ }
11231
+ async function requestJson(url, init, token, timeout) {
11232
+ const controller = new AbortController();
11233
+ const timer = setTimeout(() => controller.abort(), timeout);
11234
+ try {
11235
+ let response;
11236
+ try {
11237
+ response = await fetch(url, {
11238
+ ...init,
11239
+ headers: { ...init.headers, authorization: `Bearer ${token}` },
11240
+ redirect: "manual",
11241
+ signal: controller.signal
11242
+ });
11243
+ } catch (error) {
11244
+ if (controller.signal.aborted || error instanceof Error && error.name === "AbortError") {
11245
+ throw new Refusal(`Request timed out after ${timeout}ms.`, "agent_timeout");
11246
+ }
11247
+ throw new Refusal("Could not reach the app agent endpoint.", "agent_network_error");
11248
+ }
11249
+ if (response.status >= 300 && response.status < 400) {
11250
+ await response.body?.cancel().catch(() => void 0);
11251
+ throw new Refusal(
11252
+ "App agent endpoint redirected; refusing to forward credentials.",
11253
+ "agent_redirect_refused"
11254
+ );
11255
+ }
11256
+ let text2;
11257
+ try {
11258
+ text2 = await readResponseText(response);
11259
+ } catch (error) {
11260
+ if (error instanceof Refusal) throw error;
11261
+ if (controller.signal.aborted || error instanceof Error && error.name === "AbortError") {
11262
+ throw new Refusal(`Request timed out after ${timeout}ms.`, "agent_timeout");
11263
+ }
11264
+ throw new Refusal("Could not read the app agent response.", "agent_network_error");
11265
+ }
11266
+ let body = null;
11267
+ if (text2) {
11268
+ try {
11269
+ body = JSON.parse(text2);
11270
+ } catch {
11271
+ if (response.ok)
11272
+ throw new Refusal("The app returned a non-JSON response.", "invalid_agent_response");
11273
+ }
11274
+ }
11275
+ return { status: response.status, body, text: text2 };
11276
+ } finally {
11277
+ clearTimeout(timer);
11278
+ }
11279
+ }
11280
+ function httpRefusal(response, tokens) {
11281
+ const server = isRecord(response.body) ? response.body : void 0;
11282
+ const code = safeServerCode(server?.code);
11283
+ const message = typeof server?.error === "string" ? redact(server.error, tokens).slice(0, 500) : "";
11284
+ if (response.status === 403) {
11285
+ return new Refusal(
11286
+ message || "You are not allowed to use this app agent.",
11287
+ code ?? "agent_forbidden"
11288
+ );
11289
+ }
11290
+ if (response.status === 404 && !server) {
11291
+ return new Refusal(
11292
+ "This app does not expose the requested agent endpoint.",
11293
+ "agent_endpoint_not_found"
11294
+ );
11295
+ }
11296
+ return new Refusal(
11297
+ message || `App agent request failed (${response.status}).`,
11298
+ code ?? (response.status === 404 ? "agent_endpoint_not_found" : "agent_request_failed")
11299
+ );
11300
+ }
11301
+ async function callAgent(target2, path, init, timeout) {
11302
+ let token = await mintAgentToken(target2.url);
11303
+ const tokens = [token];
11304
+ let retried = false;
11305
+ for (; ; ) {
11306
+ const response = await requestJson(`${target2.url}${path}`, init, token, timeout);
11307
+ if (response.status !== 401) {
11308
+ if (response.status < 200 || response.status >= 300) throw httpRefusal(response, tokens);
11309
+ return redactValue(response.body, tokens);
11310
+ }
11311
+ if (!retried) {
11312
+ retried = true;
11313
+ token = await mintAgentToken(target2.url);
11314
+ tokens.push(token);
11315
+ continue;
11316
+ }
11317
+ throw new Refusal(
11318
+ "Authentication was rejected. Run `deepspace auth login` and try again.",
11319
+ "not_authenticated",
11320
+ { action: cliAction("deepspace", "auth", "login") }
11321
+ );
11322
+ }
11323
+ }
11324
+ async function runAgentTools(args) {
11325
+ const target2 = resolveAgentTarget(args.app);
11326
+ const body = parseToolsResponse(
11327
+ await callAgent(target2, "/_deepspace/agent/tools", { method: "GET" }, DEFAULT_TIMEOUT_MS2)
11328
+ );
11329
+ if (!args.json) {
11330
+ console.log(`App: ${body.app.name} (${body.app.id}, ${target2.url})`);
11331
+ if (body.tools.length === 0) console.log("Tools: none");
11332
+ else {
11333
+ console.log("Tools:");
11334
+ for (const tool of body.tools) {
11335
+ console.log(`- ${tool.name}: ${tool.description}`);
11336
+ console.log(` Input: ${JSON.stringify(tool.inputSchema)}`);
11337
+ if (tool.outputSchema !== void 0) {
11338
+ console.log(` Output: ${JSON.stringify(tool.outputSchema)}`);
11339
+ }
11340
+ }
11341
+ }
11342
+ }
11343
+ return { data: { app: body.app, url: target2.url, tools: body.tools } };
11344
+ }
11345
+ async function runAgentInvoke(args) {
11346
+ const target2 = resolveAgentTarget(args.app);
11347
+ const input = await resolveAgentInput({ input: args.input, inputFile: args.inputFile });
11348
+ const tool = args.tool;
11349
+ if (typeof tool !== "string" || !tool)
11350
+ throw new Refusal("Tool name is required.", "invalid_agent_tool");
11351
+ const requestBody = serializeAgentInput(input);
11352
+ const body = parseInvokeResponse(
11353
+ await callAgent(
11354
+ target2,
11355
+ `/_deepspace/agent/tools/${encodeURIComponent(tool)}`,
11356
+ {
11357
+ method: "POST",
11358
+ headers: { "content-type": "application/json" },
11359
+ body: requestBody
11360
+ },
11361
+ parseAgentTimeout(args.timeout)
11362
+ )
11363
+ );
11364
+ if (!args.json) {
11365
+ console.log(`App: ${args.app} (${target2.url})`);
11366
+ console.log(`Tool: ${tool}`);
11367
+ console.log("Result:");
11368
+ console.log(JSON.stringify(body.result, null, 2));
11369
+ }
11370
+ return { data: { app: args.app, url: target2.url, tool, result: body.result } };
11371
+ }
11372
+ var tools = defineDeepspaceCommand({
11373
+ meta: { name: "tools", description: "List the agent tools exposed by an app" },
11374
+ args: {
11375
+ app: { type: "positional", description: "Canonical app name or URL", required: true }
11376
+ },
11377
+ async run({ args }) {
11378
+ return runAgentTools({ app: args.app, json: args.json });
11379
+ }
11380
+ });
11381
+ var invoke2 = defineDeepspaceCommand({
11382
+ meta: { name: "invoke", description: "Invoke an agent tool exposed by an app" },
11383
+ args: {
11384
+ app: { type: "positional", description: "Canonical app name or URL", required: true },
11385
+ tool: { type: "positional", description: "Tool name", required: true },
11386
+ input: { type: "string", description: "Inline JSON tool input" },
11387
+ "input-file": { type: "string", description: "JSON input file (use - for stdin)" },
11388
+ timeout: {
11389
+ type: "string",
11390
+ description: `Request timeout in milliseconds (default: ${DEFAULT_TIMEOUT_MS2})`
11391
+ }
11392
+ },
11393
+ async run({ args }) {
11394
+ return runAgentInvoke({
11395
+ app: args.app,
11396
+ tool: args.tool,
11397
+ input: args.input,
11398
+ inputFile: args["input-file"],
11399
+ timeout: args.timeout,
11400
+ json: args.json
11401
+ });
11402
+ }
11403
+ });
11404
+ var agent_default = defineCommand10({
11405
+ meta: { name: "agent", description: "List and invoke an app\u2019s stateless local agent tools" },
11406
+ subCommands: { tools, invoke: invoke2 }
11407
+ });
11408
+
10978
11409
  // src/cli/commands/feedback.ts
10979
11410
  import * as p16 from "@clack/prompts";
10980
11411
  import { existsSync as existsSync25, readFileSync as readFileSync21 } from "fs";
@@ -11201,7 +11632,7 @@ Context: deepspace ${payload.cliVersion} \xB7 ${payload.nodeVersion} \xB7 ${payl
11201
11632
  });
11202
11633
 
11203
11634
  // src/cli/commands/secrets.ts
11204
- import { defineCommand as defineCommand10 } from "citty";
11635
+ import { defineCommand as defineCommand11 } from "citty";
11205
11636
  import { readFileSync as readFileSync22 } from "fs";
11206
11637
 
11207
11638
  // src/cli/lib/citty-args.ts
@@ -11284,7 +11715,7 @@ function warnIfDebugRoutesEnabled(secrets) {
11284
11715
  var APPLY_HINT = "Run `deepspace deploy` to apply \u2014 secrets take effect at deploy time.";
11285
11716
  var APPLIES_AT_DEPLOY = { appliesAtDeploy: true, devRestartRequired: true };
11286
11717
  var LOCAL_DEV_HINT = "Running `deepspace dev start`? Restart it to load the change locally.";
11287
- var list6 = defineCommand10({
11718
+ var list6 = defineCommand11({
11288
11719
  meta: { name: "list", description: "List masked secrets in a config" },
11289
11720
  args: {
11290
11721
  ...COMMON_ARGS,
@@ -11310,7 +11741,7 @@ var list6 = defineCommand10({
11310
11741
  }
11311
11742
  }
11312
11743
  });
11313
- var set = defineCommand10({
11744
+ var set = defineCommand11({
11314
11745
  meta: { name: "set", description: "Set secrets from KEY=value pairs, or KEY --stdin" },
11315
11746
  args: {
11316
11747
  ...COMMON_ARGS,
@@ -11394,7 +11825,7 @@ var set = defineCommand10({
11394
11825
  );
11395
11826
  }
11396
11827
  });
11397
- var get2 = defineCommand10({
11828
+ var get2 = defineCommand11({
11398
11829
  meta: { name: "get", description: "Get a secret; pass --plain to print the value" },
11399
11830
  args: {
11400
11831
  ...COMMON_ARGS,
@@ -11432,7 +11863,7 @@ var get2 = defineCommand10({
11432
11863
  );
11433
11864
  }
11434
11865
  });
11435
- var del2 = defineCommand10({
11866
+ var del2 = defineCommand11({
11436
11867
  meta: { name: "delete", description: "Delete one or more secrets" },
11437
11868
  args: {
11438
11869
  ...COMMON_ARGS,
@@ -11468,7 +11899,7 @@ var del2 = defineCommand10({
11468
11899
  );
11469
11900
  }
11470
11901
  });
11471
- var upload = defineCommand10({
11902
+ var upload = defineCommand11({
11472
11903
  meta: { name: "upload", description: "Upload secrets from a dotenv or JSON file" },
11473
11904
  args: {
11474
11905
  ...COMMON_ARGS,
@@ -11527,7 +11958,7 @@ async function readUploadSource(file) {
11527
11958
  );
11528
11959
  }
11529
11960
  }
11530
- var download = defineCommand10({
11961
+ var download = defineCommand11({
11531
11962
  meta: { name: "download", description: "Download a config\u2019s secrets (dotenv/json/shell)" },
11532
11963
  args: {
11533
11964
  ...COMMON_ARGS,
@@ -11567,7 +11998,7 @@ var download = defineCommand10({
11567
11998
  process.stdout.write(formatSecretsDownload(secrets, format));
11568
11999
  }
11569
12000
  });
11570
- var pull = defineCommand10({
12001
+ var pull = defineCommand11({
11571
12002
  meta: { name: "pull", description: "Refresh the .dev.vars cache from the app store" },
11572
12003
  args: { ...COMMON_ARGS },
11573
12004
  async run({ args }) {
@@ -11608,7 +12039,7 @@ var pull = defineCommand10({
11608
12039
  );
11609
12040
  }
11610
12041
  });
11611
- var configsList = defineCommand10({
12042
+ var configsList = defineCommand11({
11612
12043
  meta: { name: "list", description: "List the app\u2019s configs" },
11613
12044
  args: { ...COMMON_ARGS },
11614
12045
  async run({ args }) {
@@ -11625,7 +12056,7 @@ var configsList = defineCommand10({
11625
12056
  });
11626
12057
  }
11627
12058
  });
11628
- var configsCreate = defineCommand10({
12059
+ var configsCreate = defineCommand11({
11629
12060
  meta: { name: "create", description: "Create a config (optionally copying another)" },
11630
12061
  args: {
11631
12062
  ...COMMON_ARGS,
@@ -11659,7 +12090,7 @@ var configsCreate = defineCommand10({
11659
12090
  );
11660
12091
  }
11661
12092
  });
11662
- var configsDelete = defineCommand10({
12093
+ var configsDelete = defineCommand11({
11663
12094
  meta: { name: "delete", description: "Delete a config and all of its secrets" },
11664
12095
  args: {
11665
12096
  ...COMMON_ARGS,
@@ -11704,11 +12135,11 @@ var configsDelete = defineCommand10({
11704
12135
  );
11705
12136
  }
11706
12137
  });
11707
- var configs = defineCommand10({
12138
+ var configs = defineCommand11({
11708
12139
  meta: { name: "configs", description: "Manage the app\u2019s secrets configs" },
11709
12140
  subCommands: { list: configsList, create: configsCreate, delete: configsDelete }
11710
12141
  });
11711
- var secrets_default = defineCommand10({
12142
+ var secrets_default = defineCommand11({
11712
12143
  meta: { name: "secrets", description: "Manage the app\u2019s secrets store" },
11713
12144
  subCommands: {
11714
12145
  list: list6,
@@ -11869,7 +12300,7 @@ var init_default = defineDeepspaceCommand({
11869
12300
  });
11870
12301
 
11871
12302
  // src/cli/commands/status.ts
11872
- import { defineCommand as defineCommand11 } from "citty";
12303
+ import { defineCommand as defineCommand12 } from "citty";
11873
12304
  import * as p17 from "@clack/prompts";
11874
12305
  import { existsSync as existsSync26, readFileSync as readFileSync23 } from "fs";
11875
12306
  function timeAgo(iso) {
@@ -11913,7 +12344,7 @@ function resolveStatusApp(appDir, wranglerEnv) {
11913
12344
  return { appName, appId: null, appIdError: err.message };
11914
12345
  }
11915
12346
  }
11916
- var status_default = defineCommand11({
12347
+ var status_default = defineCommand12({
11917
12348
  meta: {
11918
12349
  name: "status",
11919
12350
  description: "One screenful of current state \u2014 always names the platform plane (env, services) \u2014 plus session, app, workspace, and live release"
@@ -13156,7 +13587,7 @@ Re-run with --allow-do-deletion to accept the data loss.`,
13156
13587
  });
13157
13588
 
13158
13589
  // src/cli/commands/workspace.ts
13159
- import { defineCommand as defineCommand12 } from "citty";
13590
+ import { defineCommand as defineCommand13 } from "citty";
13160
13591
 
13161
13592
  // src/cli/commands/workspace/new.ts
13162
13593
  import * as p25 from "@clack/prompts";
@@ -15048,7 +15479,7 @@ var dropWorkspaceCommand = defineDeepspaceCommand({
15048
15479
  });
15049
15480
 
15050
15481
  // src/cli/commands/workspace.ts
15051
- var workspace_default = defineCommand12({
15482
+ var workspace_default = defineCommand13({
15052
15483
  meta: {
15053
15484
  name: "workspace",
15054
15485
  description: "Durable parallel-agent workspaces (new/attach/sync/list/status/land/drop)"
@@ -15227,7 +15658,7 @@ var activity_default = defineDeepspaceCommand({
15227
15658
  });
15228
15659
 
15229
15660
  // src/cli/commands/git-credential.ts
15230
- import { defineCommand as defineCommand13 } from "citty";
15661
+ import { defineCommand as defineCommand14 } from "citty";
15231
15662
  function parseFields(input) {
15232
15663
  const fields = /* @__PURE__ */ new Map();
15233
15664
  for (const line of input.split("\n")) {
@@ -15269,7 +15700,7 @@ function declineHint(op, input, token, deployUrl) {
15269
15700
  }
15270
15701
  return "";
15271
15702
  }
15272
- var git_credential_default = defineCommand13({
15703
+ var git_credential_default = defineCommand14({
15273
15704
  meta: {
15274
15705
  name: "git-credential",
15275
15706
  description: "Git credential helper (installed automatically; not for direct use)"
@@ -15378,7 +15809,7 @@ import { join as join28, resolve as resolve22 } from "path";
15378
15809
  // package.json
15379
15810
  var package_default = {
15380
15811
  name: "deepspace",
15381
- version: "0.28.0",
15812
+ version: "0.28.1",
15382
15813
  engines: {
15383
15814
  node: ">=22.15.0 <23 || >=24 <25 || >=26 <27"
15384
15815
  },
@@ -15700,7 +16131,7 @@ var pkg = JSON.parse(readFileSync27(join29(__dirname, "..", "package.json"), "ut
15700
16131
  if (process.platform === "linux" && !process.env.SSL_CERT_FILE && existsSync31("/etc/ssl/certs/ca-certificates.crt")) {
15701
16132
  process.env.SSL_CERT_FILE = "/etc/ssl/certs/ca-certificates.crt";
15702
16133
  }
15703
- var create2 = defineCommand14({
16134
+ var create2 = defineCommand15({
15704
16135
  meta: {
15705
16136
  name: "create",
15706
16137
  description: "Create a new DeepSpace app (runs create-deepspace; all flags are forwarded)"
@@ -15749,11 +16180,11 @@ var create2 = defineCommand14({
15749
16180
  }
15750
16181
  });
15751
16182
  var rename = (cmd, name) => ({ ...cmd, meta: { ...cmd.meta ?? {}, name } });
15752
- var auth = defineCommand14({
16183
+ var auth = defineCommand15({
15753
16184
  meta: { name: "auth", description: "Session: login, logout, whoami" },
15754
16185
  subCommands: { login: login_default, logout: logout_default, whoami: whoami_default }
15755
16186
  });
15756
- var app = defineCommand14({
16187
+ var app = defineCommand15({
15757
16188
  meta: {
15758
16189
  name: "app",
15759
16190
  description: "The app itself: create, init, list, files, source, update, undeploy, transfer, collaborators, domain, usage"
@@ -15772,11 +16203,11 @@ var app = defineCommand14({
15772
16203
  update: update_default
15773
16204
  }
15774
16205
  });
15775
- var devGroup = defineCommand14({
16206
+ var devGroup = defineCommand15({
15776
16207
  meta: { name: "dev", description: "Local development" },
15777
16208
  subCommands: { start: rename(dev_default, "start"), kill: kill_default }
15778
16209
  });
15779
- var testGroup = defineCommand14({
16210
+ var testGroup = defineCommand15({
15780
16211
  meta: { name: "test", description: "App tests and test tooling" },
15781
16212
  subCommands: {
15782
16213
  run: rename(test_default, "run"),
@@ -15784,7 +16215,7 @@ var testGroup = defineCommand14({
15784
16215
  accounts: rename(test_accounts_default, "accounts")
15785
16216
  }
15786
16217
  });
15787
- var main = defineCommand14({
16218
+ var main = defineCommand15({
15788
16219
  meta: {
15789
16220
  name: "deepspace",
15790
16221
  version: pkg.version,
@@ -15810,6 +16241,7 @@ var main = defineCommand14({
15810
16241
  add: add_default,
15811
16242
  secrets: secrets_default,
15812
16243
  integrations: integrations_default,
16244
+ agent: agent_default,
15813
16245
  auth,
15814
16246
  app,
15815
16247
  feedback: feedback_default,