deepspace 0.28.0 → 0.28.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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();
@@ -1774,6 +1800,24 @@ function healBlocker(appDir, wranglerEnv) {
1774
1800
  }
1775
1801
  return null;
1776
1802
  }
1803
+ async function registerForLocalRun(appDir, token, wranglerEnv) {
1804
+ try {
1805
+ return (await ensureAppRegistered(appDir, token, wranglerEnv))?.appId ?? null;
1806
+ } catch (registrationError) {
1807
+ let hasUsableId = false;
1808
+ try {
1809
+ hasUsableId = readAppId(appDir, wranglerEnv) !== null;
1810
+ } catch {
1811
+ }
1812
+ if (!hasUsableId) throw registrationError;
1813
+ const firstLine = registrationError instanceof Error ? registrationError.message.split("\n")[0] : String(registrationError);
1814
+ process.stderr.write(
1815
+ `warning: could not register the app (${firstLine}) \u2014 continuing without app secrets.
1816
+ `
1817
+ );
1818
+ return null;
1819
+ }
1820
+ }
1777
1821
  function healRefusal(appDir, wranglerEnv) {
1778
1822
  const blocker = healBlocker(appDir, wranglerEnv);
1779
1823
  if (blocker === "placeholder_committed") {
@@ -2306,7 +2350,7 @@ function resolveWorkspaceWorktree(worktrees, workspaceId) {
2306
2350
  // src/cli/lib/source-api.ts
2307
2351
  function githubSourceRefusal(appId, repository) {
2308
2352
  return new Refusal(
2309
- `This app uses GitHub source (${repository}). Use normal Git/GitHub for source operations (clone, fetch, push); \`deepspace deploy\` ships the local working tree without changing Git.`,
2353
+ `This app uses GitHub source (${repository}). Use normal Git/GitHub for source operations. \`deepspace deploy\` ships the local working tree without changing Git.`,
2310
2354
  "source_managed_by_github",
2311
2355
  { extra: { appId, repository } }
2312
2356
  );
@@ -3750,7 +3794,11 @@ async function ensurePortFree(port, host, waitMs = 15e3) {
3750
3794
  `Port ${port} is already in use.
3751
3795
  Free it with \`${killArgv.join(" ")}\`, or use another port: \`--port <other>\`.`,
3752
3796
  "port_in_use",
3753
- { extra: { port } }
3797
+ // The machine action the contract documents for this refusal — the prose
3798
+ // named it while `--json` carried none (2026-08-28 coldstart AX). Not
3799
+ // actionRequired: freeing the port and choosing another port are both
3800
+ // legitimate, so the choice stays the caller's.
3801
+ { extra: { port }, action: { cwd: process.cwd(), argv: killArgv } }
3754
3802
  );
3755
3803
  }
3756
3804
  async function isHttpResponding(port, timeoutMs = 2e3) {
@@ -3892,6 +3940,7 @@ var dev_default = defineDeepspaceCommand({
3892
3940
  writeLaunchConfigIfMissing(appDir, detectAppName(appDir) ?? basename2(appDir), port, {
3893
3941
  updatePort: explicitPort
3894
3942
  });
3943
+ ensureInstallReady(appDir);
3895
3944
  let token;
3896
3945
  try {
3897
3946
  token = await ensureToken();
@@ -3914,21 +3963,12 @@ var dev_default = defineDeepspaceCommand({
3914
3963
  if (wranglerEnv) say(`Wrangler env: ${wranglerEnv}`);
3915
3964
  say(`Port: ${port}`);
3916
3965
  if (host !== DEFAULT_DEV_HOST) say(`Host: ${host}`);
3917
- ensureInstallReady(appDir);
3918
3966
  const lintFindings = await lintProjectSchemas(appDir);
3919
3967
  if (lintFindings && lintFindings.length > 0 && !args.json) {
3920
3968
  for (const line of formatSchemaLintFindings(lintFindings)) console.warn(line);
3921
3969
  }
3922
3970
  let generatedSecretsCache;
3923
- let appIdForSecrets = null;
3924
- try {
3925
- appIdForSecrets = (await ensureAppRegistered(appDir, token, wranglerEnv))?.appId ?? null;
3926
- } catch (registrationError) {
3927
- process.stderr.write(
3928
- `warning: could not register the app (${registrationError instanceof Error ? registrationError.message.split("\n")[0] : String(registrationError)}) \u2014 continuing without app secrets.
3929
- `
3930
- );
3931
- }
3971
+ const appIdForSecrets = await registerForLocalRun(appDir, token, wranglerEnv);
3932
3972
  if (appIdForSecrets) {
3933
3973
  try {
3934
3974
  const refreshed = await refreshSecretsCache(DEPLOY_URL2, token, appIdForSecrets, wranglerEnv);
@@ -4436,7 +4476,6 @@ function saveTestAccountStore(store) {
4436
4476
  }
4437
4477
 
4438
4478
  // src/cli/lib/test-account-service.ts
4439
- var SESSION_COOKIE2 = "__Secure-better-auth.session_token";
4440
4479
  var TestAccountServiceError = class extends Error {
4441
4480
  constructor(message, code) {
4442
4481
  super(message);
@@ -4449,7 +4488,7 @@ function serviceError(data, fallback) {
4449
4488
  var AUTH_URL4 = process.env.DEEPSPACE_AUTH_URL ?? PLATFORM_URLS.auth;
4450
4489
  function sessionCookie() {
4451
4490
  const token = readFileSync12(SESSION_PATH, "utf-8").trim();
4452
- return `${SESSION_COOKIE2}=${encodeURIComponent(token)}`;
4491
+ return `${SESSION_COOKIE}=${encodeURIComponent(token)}`;
4453
4492
  }
4454
4493
  async function fetchRemoteTestAccounts() {
4455
4494
  const response = await fetch(`${AUTH_URL4}/api/auth/test-accounts`, {
@@ -4619,6 +4658,7 @@ var test_default = defineDeepspaceCommand({
4619
4658
  arg: args.port,
4620
4659
  worktree: () => resolveWorktreePort(appDir)
4621
4660
  });
4661
+ ensureInstallReady(appDir);
4622
4662
  if (suite !== "unit") await ensurePortFree(port, "0.0.0.0");
4623
4663
  let token;
4624
4664
  let ownerId;
@@ -4633,17 +4673,8 @@ var test_default = defineDeepspaceCommand({
4633
4673
  { action: cliAction("deepspace", "auth", "login") }
4634
4674
  );
4635
4675
  }
4636
- ensureInstallReady(appDir);
4637
4676
  let generatedSecretsCache;
4638
- let appIdForSecrets = null;
4639
- try {
4640
- appIdForSecrets = (await ensureAppRegistered(appDir, token, wranglerEnv))?.appId ?? null;
4641
- } catch (registrationError) {
4642
- process.stderr.write(
4643
- `warning: could not register the app (${registrationError instanceof Error ? registrationError.message.split("\n")[0] : String(registrationError)}) \u2014 continuing without app secrets.
4644
- `
4645
- );
4646
- }
4677
+ const appIdForSecrets = await registerForLocalRun(appDir, token, wranglerEnv);
4647
4678
  if (appIdForSecrets) {
4648
4679
  try {
4649
4680
  const refreshed = await refreshSecretsCache(DEPLOY_URL3, token, appIdForSecrets, wranglerEnv);
@@ -4903,7 +4934,8 @@ async function requireConsent(opts) {
4903
4934
 
4904
4935
  // src/cli/commands/test-accounts.ts
4905
4936
  function testAccountFailure(err, fallbackCode) {
4906
- const message = err instanceof Error ? err.message : String(err);
4937
+ const raw = err instanceof Error ? err.message : String(err);
4938
+ const message = raw.replace(/\.\s*$/, "");
4907
4939
  const code = err instanceof TestAccountServiceError ? err.code : void 0;
4908
4940
  if (code === "test_account_cap") {
4909
4941
  return new Refusal(
@@ -4923,7 +4955,7 @@ function testAccountFailure(err, fallbackCode) {
4923
4955
  "not_authenticated"
4924
4956
  );
4925
4957
  }
4926
- return new Refusal(`Failed: ${message}`, code ?? fallbackCode);
4958
+ return new Refusal(`Failed: ${raw}`, code ?? fallbackCode);
4927
4959
  }
4928
4960
  var create = defineDeepspaceCommand({
4929
4961
  meta: {
@@ -5266,7 +5298,7 @@ var recover = defineDeepspaceCommand({
5266
5298
  targets = remote.filter((account) => !known.has(account.id));
5267
5299
  if (targets.length === 0) {
5268
5300
  if (!args.json) console.log("Every pool account already has a local credential.");
5269
- return { data: { recovered: [], alreadyLocal: remote.length } };
5301
+ return { data: { recovered: [], alreadyLocal: remote.length, savedTo: TEST_ACCOUNTS_PATH } };
5270
5302
  }
5271
5303
  } else {
5272
5304
  const match = args.id ? remote.find((account) => account.id === args.id) : remote.find((account) => account.email === args.email);
@@ -5317,7 +5349,7 @@ Stored in ${TEST_ACCOUNTS_PATH}. ${rotatedCount} account(s) had no stored creden
5317
5349
  Stored in ${TEST_ACCOUNTS_PATH}. Passwords were retrieved, not reset \u2014 other machines' credentials still work.`
5318
5350
  );
5319
5351
  }
5320
- return { data: { recovered, requested: targets.length, failures: [] } };
5352
+ return { data: { recovered, requested: targets.length, failures: [], savedTo: TEST_ACCOUNTS_PATH } };
5321
5353
  }
5322
5354
  });
5323
5355
  var test_accounts_default = defineCommand2({
@@ -8030,6 +8062,9 @@ var whoami_default = defineDeepspaceCommand({
8030
8062
  console.log(`Email: ${payload.email ?? "(none)"}`);
8031
8063
  console.log(`Type: ${accountType}`);
8032
8064
  if (payload.iss) console.log(`Issuer: ${payload.iss}`);
8065
+ if (payload.exp) {
8066
+ console.log(`Expires: ${new Date(payload.exp * 1e3).toISOString()} (renews on use)`);
8067
+ }
8033
8068
  console.log(`Dashboard: ${DASHBOARD_URL}`);
8034
8069
  if (isTestAccount) {
8035
8070
  console.log("");
@@ -8512,7 +8547,7 @@ function renderSummary(summary) {
8512
8547
  var usage_default = defineDeepspaceCommand({
8513
8548
  meta: {
8514
8549
  name: "usage",
8515
- description: "Show account-wide credits and integration spend (all apps)"
8550
+ description: "Show account-wide credits and integration spend (all apps). Storage is per app: `deepspace app files list`"
8516
8551
  },
8517
8552
  async run({ args }) {
8518
8553
  const token = await ensureToken();
@@ -10975,6 +11010,412 @@ var integrations_default = defineCommand9({
10975
11010
  }
10976
11011
  });
10977
11012
 
11013
+ // src/cli/commands/agent.ts
11014
+ import { createReadStream } from "fs";
11015
+ import { defineCommand as defineCommand10 } from "citty";
11016
+
11017
+ // src/server/agent-target.ts
11018
+ var PRODUCTION_OFFICIAL_AGENT_ORIGINS = ["https://admin.deep.space"];
11019
+ var PRODUCTION_APP_DOMAIN = "app.space";
11020
+ function normalizeAgentTargetOrigin(value, policy) {
11021
+ if (typeof value !== "string" || !value) return null;
11022
+ let url;
11023
+ try {
11024
+ url = new URL(value);
11025
+ } catch {
11026
+ return null;
11027
+ }
11028
+ if (url.username || url.password || url.search || url.hash || url.pathname !== "/") return null;
11029
+ const hostname = url.hostname.toLowerCase();
11030
+ const loopback = ["localhost", "127.0.0.1", "[::1]"].includes(hostname);
11031
+ if (loopback) {
11032
+ return policy.allowLoopback && ["http:", "https:"].includes(url.protocol) ? url.origin : null;
11033
+ }
11034
+ if (url.protocol !== "https:" || url.port) return null;
11035
+ if (policy.appDomain.toLowerCase() === PRODUCTION_APP_DOMAIN && PRODUCTION_OFFICIAL_AGENT_ORIGINS.includes(url.origin)) {
11036
+ return url.origin;
11037
+ }
11038
+ const suffix = `.${policy.appDomain.toLowerCase()}`;
11039
+ if (!hostname.endsWith(suffix)) return null;
11040
+ const label = hostname.slice(0, -suffix.length);
11041
+ return !label.includes(".") && validateAppName(label).valid ? url.origin : null;
11042
+ }
11043
+
11044
+ // src/shared/bounded-body.ts
11045
+ var BodyTooLargeError = class extends Error {
11046
+ constructor(maxBytes) {
11047
+ super(`Body exceeds ${maxBytes} bytes`);
11048
+ this.maxBytes = maxBytes;
11049
+ this.name = "BodyTooLargeError";
11050
+ }
11051
+ };
11052
+ async function readBoundedBodyText(source, maxBytes) {
11053
+ if (!Number.isSafeInteger(maxBytes) || maxBytes <= 0) {
11054
+ throw new TypeError("maxBytes must be a positive safe integer");
11055
+ }
11056
+ const declared = source.headers.get("content-length");
11057
+ if (declared && /^\d+$/.test(declared.trim()) && Number(declared) > maxBytes) {
11058
+ await source.body?.cancel().catch(() => void 0);
11059
+ throw new BodyTooLargeError(maxBytes);
11060
+ }
11061
+ if (!source.body) return "";
11062
+ const reader = source.body.getReader();
11063
+ const decoder = new TextDecoder();
11064
+ let bytes = 0;
11065
+ let text2 = "";
11066
+ try {
11067
+ while (true) {
11068
+ const chunk = await reader.read();
11069
+ if (chunk.done) break;
11070
+ bytes += chunk.value.byteLength;
11071
+ if (bytes > maxBytes) {
11072
+ await reader.cancel().catch(() => void 0);
11073
+ throw new BodyTooLargeError(maxBytes);
11074
+ }
11075
+ text2 += decoder.decode(chunk.value, { stream: true });
11076
+ }
11077
+ return text2 + decoder.decode();
11078
+ } finally {
11079
+ reader.releaseLock();
11080
+ }
11081
+ }
11082
+
11083
+ // src/shared/agent-tool-protocol.ts
11084
+ var AGENT_TOOL_REQUEST_BODY_CAP = 64 * 1024;
11085
+ var AGENT_TOOL_RESPONSE_BODY_CAP = 1024 * 1024;
11086
+
11087
+ // src/cli/commands/agent.ts
11088
+ var DEFAULT_TIMEOUT_MS2 = 12e4;
11089
+ var MAX_TIMEOUT_MS = 6e5;
11090
+ var MAX_INPUT_BYTES = AGENT_TOOL_REQUEST_BODY_CAP;
11091
+ var MAX_RESPONSE_BYTES = AGENT_TOOL_RESPONSE_BODY_CAP;
11092
+ function badApp(message) {
11093
+ throw new Refusal(message, "invalid_agent_app");
11094
+ }
11095
+ function isCanonicalAppLabel(value) {
11096
+ return value.length >= APP_NAME_RULES.minLength && value.length <= APP_NAME_RULES.maxLength && APP_NAME_RULES.pattern.test(value);
11097
+ }
11098
+ function resolveAgentTarget(app2, plane = DEEPSPACE_ENV) {
11099
+ if (typeof app2 !== "string" || !app2)
11100
+ badApp("App must be a canonical app name or canonical app URL.");
11101
+ const appDomain = appDomainForEnv(plane);
11102
+ if (!appDomain) badApp("The selected DeepSpace environment is invalid.");
11103
+ if (app2.toLowerCase() === "localhost") {
11104
+ badApp("Pass an explicit loopback URL for local development (e.g. 'http://localhost:8787').");
11105
+ }
11106
+ if (isCanonicalAppLabel(app2)) {
11107
+ return { url: `https://${app2}.${appDomain}` };
11108
+ }
11109
+ const url = normalizeAgentTargetOrigin(app2, {
11110
+ appDomain,
11111
+ allowLoopback: true
11112
+ });
11113
+ if (!url) {
11114
+ badApp(
11115
+ "App URL must be an exact canonical app origin (or a root loopback URL for local development)."
11116
+ );
11117
+ }
11118
+ return { url };
11119
+ }
11120
+ function parseAgentTimeout(raw) {
11121
+ if (raw == null) return DEFAULT_TIMEOUT_MS2;
11122
+ const value = typeof raw === "number" ? raw : Number(raw);
11123
+ if (!Number.isInteger(value) || value <= 0 || value > MAX_TIMEOUT_MS) {
11124
+ throw new Refusal(
11125
+ `Invalid --timeout '${String(raw)}'. Must be a positive integer up to ${MAX_TIMEOUT_MS} milliseconds.`,
11126
+ "invalid_timeout"
11127
+ );
11128
+ }
11129
+ return value;
11130
+ }
11131
+ function assertInputSize(value) {
11132
+ if (Buffer.byteLength(value) > MAX_INPUT_BYTES) {
11133
+ throw new Refusal(`Input exceeds the ${MAX_INPUT_BYTES}-byte limit.`, "input_too_large");
11134
+ }
11135
+ }
11136
+ function serializeAgentInput(input) {
11137
+ const body = JSON.stringify({ input });
11138
+ if (Buffer.byteLength(body) > AGENT_TOOL_REQUEST_BODY_CAP) {
11139
+ throw new Refusal(
11140
+ `Tool request exceeds the ${AGENT_TOOL_REQUEST_BODY_CAP}-byte limit.`,
11141
+ "input_too_large"
11142
+ );
11143
+ }
11144
+ return body;
11145
+ }
11146
+ async function readBoundedLocalInput(source) {
11147
+ const chunks = [];
11148
+ let size = 0;
11149
+ for await (const chunk of source) {
11150
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
11151
+ size += buffer.length;
11152
+ if (size > MAX_INPUT_BYTES) {
11153
+ throw new Refusal(`Input exceeds the ${MAX_INPUT_BYTES}-byte limit.`, "input_too_large");
11154
+ }
11155
+ chunks.push(buffer);
11156
+ }
11157
+ return Buffer.concat(chunks).toString("utf8");
11158
+ }
11159
+ async function resolveAgentInput(opts) {
11160
+ if (opts.input != null && opts.inputFile != null) {
11161
+ throw new Refusal("Pass either --input or --input-file, not both.", "conflicting_input_args");
11162
+ }
11163
+ let raw = "{}";
11164
+ if (opts.input != null) {
11165
+ raw = opts.input;
11166
+ assertInputSize(raw);
11167
+ } else if (opts.inputFile != null) {
11168
+ if (opts.inputFile === "-") {
11169
+ raw = await readBoundedLocalInput(process.stdin);
11170
+ } else {
11171
+ try {
11172
+ raw = await readBoundedLocalInput(createReadStream(opts.inputFile));
11173
+ } catch (error) {
11174
+ if (error instanceof Refusal) throw error;
11175
+ throw new Refusal(`Could not read input file '${opts.inputFile}'.`, "input_file_unreadable");
11176
+ }
11177
+ }
11178
+ }
11179
+ try {
11180
+ return JSON.parse(raw);
11181
+ } catch {
11182
+ throw new Refusal("Input is not valid JSON.", "invalid_input_json");
11183
+ }
11184
+ }
11185
+ function isRecord(value) {
11186
+ return typeof value === "object" && value !== null && !Array.isArray(value);
11187
+ }
11188
+ function validApp(value) {
11189
+ return isRecord(value) && typeof value.id === "string" && typeof value.name === "string";
11190
+ }
11191
+ function validTool(value) {
11192
+ return isRecord(value) && typeof value.name === "string" && typeof value.description === "string" && Object.prototype.hasOwnProperty.call(value, "inputSchema");
11193
+ }
11194
+ function parseToolsResponse(value) {
11195
+ if (!isRecord(value) || value.ok !== true || !validApp(value.app) || !Array.isArray(value.tools)) {
11196
+ throw new Refusal("The app returned an unexpected tools response.", "invalid_agent_response");
11197
+ }
11198
+ if (!value.tools.every(validTool)) {
11199
+ throw new Refusal("The app returned an invalid tool definition.", "invalid_agent_response");
11200
+ }
11201
+ return { ok: true, app: value.app, tools: value.tools };
11202
+ }
11203
+ function parseInvokeResponse(value) {
11204
+ if (!isRecord(value) || value.ok !== true || !Object.prototype.hasOwnProperty.call(value, "result")) {
11205
+ throw new Refusal("The app returned an unexpected tool response.", "invalid_agent_response");
11206
+ }
11207
+ return { ok: true, result: value.result };
11208
+ }
11209
+ function safeServerCode(value) {
11210
+ return typeof value === "string" && /^[a-z][a-z0-9_]{0,63}$/.test(value) ? value : void 0;
11211
+ }
11212
+ function redact(value, tokens) {
11213
+ return tokens.reduce(
11214
+ (text2, token) => token ? text2.split(token).join("[redacted]") : text2,
11215
+ value
11216
+ );
11217
+ }
11218
+ function redactValue(value, tokens) {
11219
+ if (typeof value === "string") return redact(value, tokens);
11220
+ if (Array.isArray(value)) return value.map((item) => redactValue(item, tokens));
11221
+ if (isRecord(value)) {
11222
+ return Object.fromEntries(
11223
+ Object.entries(value).map(([key, item]) => [redact(key, tokens), redactValue(item, tokens)])
11224
+ );
11225
+ }
11226
+ return value;
11227
+ }
11228
+ async function readResponseText(response) {
11229
+ try {
11230
+ return await readBoundedBodyText(response, MAX_RESPONSE_BYTES);
11231
+ } catch (error) {
11232
+ if (error instanceof BodyTooLargeError) {
11233
+ throw new Refusal(
11234
+ `App response exceeds the ${MAX_RESPONSE_BYTES}-byte limit.`,
11235
+ "response_too_large"
11236
+ );
11237
+ }
11238
+ throw error;
11239
+ }
11240
+ }
11241
+ async function requestJson(url, init, token, timeout) {
11242
+ const controller = new AbortController();
11243
+ const timer = setTimeout(() => controller.abort(), timeout);
11244
+ try {
11245
+ let response;
11246
+ try {
11247
+ response = await fetch(url, {
11248
+ ...init,
11249
+ headers: { ...init.headers, authorization: `Bearer ${token}` },
11250
+ redirect: "manual",
11251
+ signal: controller.signal
11252
+ });
11253
+ } catch (error) {
11254
+ if (controller.signal.aborted || error instanceof Error && error.name === "AbortError") {
11255
+ throw new Refusal(`Request timed out after ${timeout}ms.`, "agent_timeout");
11256
+ }
11257
+ throw new Refusal("Could not reach the app agent endpoint.", "agent_network_error");
11258
+ }
11259
+ if (response.status >= 300 && response.status < 400) {
11260
+ await response.body?.cancel().catch(() => void 0);
11261
+ throw new Refusal(
11262
+ "App agent endpoint redirected; refusing to forward credentials.",
11263
+ "agent_redirect_refused"
11264
+ );
11265
+ }
11266
+ let text2;
11267
+ try {
11268
+ text2 = await readResponseText(response);
11269
+ } catch (error) {
11270
+ if (error instanceof Refusal) throw error;
11271
+ if (controller.signal.aborted || error instanceof Error && error.name === "AbortError") {
11272
+ throw new Refusal(`Request timed out after ${timeout}ms.`, "agent_timeout");
11273
+ }
11274
+ throw new Refusal("Could not read the app agent response.", "agent_network_error");
11275
+ }
11276
+ let body = null;
11277
+ if (text2) {
11278
+ try {
11279
+ body = JSON.parse(text2);
11280
+ } catch {
11281
+ if (response.ok)
11282
+ throw new Refusal("The app returned a non-JSON response.", "invalid_agent_response");
11283
+ }
11284
+ }
11285
+ return { status: response.status, body, text: text2 };
11286
+ } finally {
11287
+ clearTimeout(timer);
11288
+ }
11289
+ }
11290
+ function httpRefusal(response, tokens) {
11291
+ const server = isRecord(response.body) ? response.body : void 0;
11292
+ const code = safeServerCode(server?.code);
11293
+ const message = typeof server?.error === "string" ? redact(server.error, tokens).slice(0, 500) : "";
11294
+ if (response.status === 403) {
11295
+ return new Refusal(
11296
+ message || "You are not allowed to use this app agent.",
11297
+ code ?? "agent_forbidden"
11298
+ );
11299
+ }
11300
+ if (response.status === 404 && !server) {
11301
+ return new Refusal(
11302
+ "No agent endpoint answered for this app. Either the app name/id is wrong (`deepspace app list` shows yours), or the app does not register assistant tools \u2014 its worker needs `registerAgent(app, { tools, inApp: false })` deployed.",
11303
+ "agent_endpoint_not_found"
11304
+ );
11305
+ }
11306
+ return new Refusal(
11307
+ message || `App agent request failed (${response.status}).`,
11308
+ code ?? (response.status === 404 ? "agent_endpoint_not_found" : "agent_request_failed")
11309
+ );
11310
+ }
11311
+ async function callAgent(target2, path, init, timeout) {
11312
+ let token = await mintAgentToken(target2.url);
11313
+ const tokens = [token];
11314
+ let retried = false;
11315
+ for (; ; ) {
11316
+ const response = await requestJson(`${target2.url}${path}`, init, token, timeout);
11317
+ if (response.status !== 401) {
11318
+ if (response.status < 200 || response.status >= 300) throw httpRefusal(response, tokens);
11319
+ return redactValue(response.body, tokens);
11320
+ }
11321
+ if (!retried) {
11322
+ retried = true;
11323
+ token = await mintAgentToken(target2.url);
11324
+ tokens.push(token);
11325
+ continue;
11326
+ }
11327
+ throw new Refusal(
11328
+ "Authentication was rejected. Run `deepspace auth login` and try again.",
11329
+ "not_authenticated",
11330
+ { action: cliAction("deepspace", "auth", "login") }
11331
+ );
11332
+ }
11333
+ }
11334
+ async function runAgentTools(args) {
11335
+ const target2 = resolveAgentTarget(args.app);
11336
+ const body = parseToolsResponse(
11337
+ await callAgent(target2, "/_deepspace/agent/tools", { method: "GET" }, DEFAULT_TIMEOUT_MS2)
11338
+ );
11339
+ if (!args.json) {
11340
+ console.log(`App: ${body.app.name} (${body.app.id}, ${target2.url})`);
11341
+ if (body.tools.length === 0) console.log("Tools: none");
11342
+ else {
11343
+ console.log("Tools:");
11344
+ for (const tool of body.tools) {
11345
+ console.log(`- ${tool.name}: ${tool.description}`);
11346
+ console.log(` Input: ${JSON.stringify(tool.inputSchema)}`);
11347
+ if (tool.outputSchema !== void 0) {
11348
+ console.log(` Output: ${JSON.stringify(tool.outputSchema)}`);
11349
+ }
11350
+ }
11351
+ }
11352
+ }
11353
+ return { data: { app: body.app, url: target2.url, tools: body.tools } };
11354
+ }
11355
+ async function runAgentInvoke(args) {
11356
+ const target2 = resolveAgentTarget(args.app);
11357
+ const input = await resolveAgentInput({ input: args.input, inputFile: args.inputFile });
11358
+ const tool = args.tool;
11359
+ if (typeof tool !== "string" || !tool)
11360
+ throw new Refusal("Tool name is required.", "invalid_agent_tool");
11361
+ const requestBody = serializeAgentInput(input);
11362
+ const body = parseInvokeResponse(
11363
+ await callAgent(
11364
+ target2,
11365
+ `/_deepspace/agent/tools/${encodeURIComponent(tool)}`,
11366
+ {
11367
+ method: "POST",
11368
+ headers: { "content-type": "application/json" },
11369
+ body: requestBody
11370
+ },
11371
+ parseAgentTimeout(args.timeout)
11372
+ )
11373
+ );
11374
+ if (!args.json) {
11375
+ console.log(`App: ${args.app} (${target2.url})`);
11376
+ console.log(`Tool: ${tool}`);
11377
+ console.log("Result:");
11378
+ console.log(JSON.stringify(body.result, null, 2));
11379
+ }
11380
+ return { data: { app: args.app, url: target2.url, tool, result: body.result } };
11381
+ }
11382
+ var tools = defineDeepspaceCommand({
11383
+ meta: { name: "tools", description: "List the agent tools exposed by an app" },
11384
+ args: {
11385
+ app: { type: "positional", description: "Canonical app name or URL", required: true }
11386
+ },
11387
+ async run({ args }) {
11388
+ return runAgentTools({ app: args.app, json: args.json });
11389
+ }
11390
+ });
11391
+ var invoke2 = defineDeepspaceCommand({
11392
+ meta: { name: "invoke", description: "Invoke an agent tool exposed by an app" },
11393
+ args: {
11394
+ app: { type: "positional", description: "Canonical app name or URL", required: true },
11395
+ tool: { type: "positional", description: "Tool name", required: true },
11396
+ input: { type: "string", description: "Inline JSON tool input" },
11397
+ "input-file": { type: "string", description: "JSON input file (use - for stdin)" },
11398
+ timeout: {
11399
+ type: "string",
11400
+ description: `Request timeout in milliseconds (default: ${DEFAULT_TIMEOUT_MS2})`
11401
+ }
11402
+ },
11403
+ async run({ args }) {
11404
+ return runAgentInvoke({
11405
+ app: args.app,
11406
+ tool: args.tool,
11407
+ input: args.input,
11408
+ inputFile: args["input-file"],
11409
+ timeout: args.timeout,
11410
+ json: args.json
11411
+ });
11412
+ }
11413
+ });
11414
+ var agent_default = defineCommand10({
11415
+ meta: { name: "agent", description: "List and invoke an app\u2019s stateless local agent tools" },
11416
+ subCommands: { tools, invoke: invoke2 }
11417
+ });
11418
+
10978
11419
  // src/cli/commands/feedback.ts
10979
11420
  import * as p16 from "@clack/prompts";
10980
11421
  import { existsSync as existsSync25, readFileSync as readFileSync21 } from "fs";
@@ -11201,7 +11642,7 @@ Context: deepspace ${payload.cliVersion} \xB7 ${payload.nodeVersion} \xB7 ${payl
11201
11642
  });
11202
11643
 
11203
11644
  // src/cli/commands/secrets.ts
11204
- import { defineCommand as defineCommand10 } from "citty";
11645
+ import { defineCommand as defineCommand11 } from "citty";
11205
11646
  import { readFileSync as readFileSync22 } from "fs";
11206
11647
 
11207
11648
  // src/cli/lib/citty-args.ts
@@ -11284,7 +11725,7 @@ function warnIfDebugRoutesEnabled(secrets) {
11284
11725
  var APPLY_HINT = "Run `deepspace deploy` to apply \u2014 secrets take effect at deploy time.";
11285
11726
  var APPLIES_AT_DEPLOY = { appliesAtDeploy: true, devRestartRequired: true };
11286
11727
  var LOCAL_DEV_HINT = "Running `deepspace dev start`? Restart it to load the change locally.";
11287
- var list6 = defineCommand10({
11728
+ var list6 = defineCommand11({
11288
11729
  meta: { name: "list", description: "List masked secrets in a config" },
11289
11730
  args: {
11290
11731
  ...COMMON_ARGS,
@@ -11310,7 +11751,7 @@ var list6 = defineCommand10({
11310
11751
  }
11311
11752
  }
11312
11753
  });
11313
- var set = defineCommand10({
11754
+ var set = defineCommand11({
11314
11755
  meta: { name: "set", description: "Set secrets from KEY=value pairs, or KEY --stdin" },
11315
11756
  args: {
11316
11757
  ...COMMON_ARGS,
@@ -11394,7 +11835,7 @@ var set = defineCommand10({
11394
11835
  );
11395
11836
  }
11396
11837
  });
11397
- var get2 = defineCommand10({
11838
+ var get2 = defineCommand11({
11398
11839
  meta: { name: "get", description: "Get a secret; pass --plain to print the value" },
11399
11840
  args: {
11400
11841
  ...COMMON_ARGS,
@@ -11432,7 +11873,7 @@ var get2 = defineCommand10({
11432
11873
  );
11433
11874
  }
11434
11875
  });
11435
- var del2 = defineCommand10({
11876
+ var del2 = defineCommand11({
11436
11877
  meta: { name: "delete", description: "Delete one or more secrets" },
11437
11878
  args: {
11438
11879
  ...COMMON_ARGS,
@@ -11468,7 +11909,7 @@ var del2 = defineCommand10({
11468
11909
  );
11469
11910
  }
11470
11911
  });
11471
- var upload = defineCommand10({
11912
+ var upload = defineCommand11({
11472
11913
  meta: { name: "upload", description: "Upload secrets from a dotenv or JSON file" },
11473
11914
  args: {
11474
11915
  ...COMMON_ARGS,
@@ -11527,7 +11968,7 @@ async function readUploadSource(file) {
11527
11968
  );
11528
11969
  }
11529
11970
  }
11530
- var download = defineCommand10({
11971
+ var download = defineCommand11({
11531
11972
  meta: { name: "download", description: "Download a config\u2019s secrets (dotenv/json/shell)" },
11532
11973
  args: {
11533
11974
  ...COMMON_ARGS,
@@ -11567,7 +12008,7 @@ var download = defineCommand10({
11567
12008
  process.stdout.write(formatSecretsDownload(secrets, format));
11568
12009
  }
11569
12010
  });
11570
- var pull = defineCommand10({
12011
+ var pull = defineCommand11({
11571
12012
  meta: { name: "pull", description: "Refresh the .dev.vars cache from the app store" },
11572
12013
  args: { ...COMMON_ARGS },
11573
12014
  async run({ args }) {
@@ -11608,7 +12049,7 @@ var pull = defineCommand10({
11608
12049
  );
11609
12050
  }
11610
12051
  });
11611
- var configsList = defineCommand10({
12052
+ var configsList = defineCommand11({
11612
12053
  meta: { name: "list", description: "List the app\u2019s configs" },
11613
12054
  args: { ...COMMON_ARGS },
11614
12055
  async run({ args }) {
@@ -11625,7 +12066,7 @@ var configsList = defineCommand10({
11625
12066
  });
11626
12067
  }
11627
12068
  });
11628
- var configsCreate = defineCommand10({
12069
+ var configsCreate = defineCommand11({
11629
12070
  meta: { name: "create", description: "Create a config (optionally copying another)" },
11630
12071
  args: {
11631
12072
  ...COMMON_ARGS,
@@ -11659,7 +12100,7 @@ var configsCreate = defineCommand10({
11659
12100
  );
11660
12101
  }
11661
12102
  });
11662
- var configsDelete = defineCommand10({
12103
+ var configsDelete = defineCommand11({
11663
12104
  meta: { name: "delete", description: "Delete a config and all of its secrets" },
11664
12105
  args: {
11665
12106
  ...COMMON_ARGS,
@@ -11704,11 +12145,11 @@ var configsDelete = defineCommand10({
11704
12145
  );
11705
12146
  }
11706
12147
  });
11707
- var configs = defineCommand10({
12148
+ var configs = defineCommand11({
11708
12149
  meta: { name: "configs", description: "Manage the app\u2019s secrets configs" },
11709
12150
  subCommands: { list: configsList, create: configsCreate, delete: configsDelete }
11710
12151
  });
11711
- var secrets_default = defineCommand10({
12152
+ var secrets_default = defineCommand11({
11712
12153
  meta: { name: "secrets", description: "Manage the app\u2019s secrets store" },
11713
12154
  subCommands: {
11714
12155
  list: list6,
@@ -11821,6 +12262,9 @@ var init_default = defineDeepspaceCommand({
11821
12262
  console.log(
11822
12263
  `Registered on ${DEEPSPACE_ENV} as a NEW app under ${accountLabel(token)}; the original is untouched.`
11823
12264
  );
12265
+ console.log(
12266
+ "Note: the fork keeps the wrangler `name` \u2014 its first deploy targets the SAME subdomain as the original. For a separate URL, change `name` in wrangler.toml (and APP_NAME) before deploying."
12267
+ );
11824
12268
  } else {
11825
12269
  console.log(`Registered ${appId}${envSuffix} on ${DEEPSPACE_ENV} to ${accountLabel(token)}${commitNote}`);
11826
12270
  if (replacedMalformed !== null) {
@@ -11869,7 +12313,7 @@ var init_default = defineDeepspaceCommand({
11869
12313
  });
11870
12314
 
11871
12315
  // src/cli/commands/status.ts
11872
- import { defineCommand as defineCommand11 } from "citty";
12316
+ import { defineCommand as defineCommand12 } from "citty";
11873
12317
  import * as p17 from "@clack/prompts";
11874
12318
  import { existsSync as existsSync26, readFileSync as readFileSync23 } from "fs";
11875
12319
  function timeAgo(iso) {
@@ -11913,7 +12357,7 @@ function resolveStatusApp(appDir, wranglerEnv) {
11913
12357
  return { appName, appId: null, appIdError: err.message };
11914
12358
  }
11915
12359
  }
11916
- var status_default = defineCommand11({
12360
+ var status_default = defineCommand12({
11917
12361
  meta: {
11918
12362
  name: "status",
11919
12363
  description: "One screenful of current state \u2014 always names the platform plane (env, services) \u2014 plus session, app, workspace, and live release"
@@ -11972,6 +12416,7 @@ var status_default = defineCommand11({
11972
12416
  json.sessionError = sessionError("Not logged in. Run `deepspace auth login` first.");
11973
12417
  } else {
11974
12418
  let who = null;
12419
+ let undecodableToken = false;
11975
12420
  try {
11976
12421
  const payload = decodeJwtPayload(
11977
12422
  readFileSync23(TOKEN_PATH, "utf-8").trim()
@@ -11979,13 +12424,39 @@ var status_default = defineCommand11({
11979
12424
  if (payload.email) who = payload.email;
11980
12425
  userId = payload.sub ?? null;
11981
12426
  } catch {
12427
+ undecodableToken = existsSync26(TOKEN_PATH);
12428
+ }
12429
+ let sessionLineEmitted = false;
12430
+ if (undecodableToken) {
12431
+ try {
12432
+ const healed = await ensureToken();
12433
+ const payload = decodeJwtPayload(healed);
12434
+ if (payload.email) who = payload.email;
12435
+ userId = payload.sub ?? null;
12436
+ } catch (err) {
12437
+ sessionLineEmitted = true;
12438
+ const offline = err instanceof TypeError || errorCode(err) === "network_error";
12439
+ if (offline) {
12440
+ lines.push(["Session", "logged in \xB7 stored token unreadable, could not verify offline"]);
12441
+ json.loggedIn = true;
12442
+ } else {
12443
+ lines.push(["Session", "stored credentials unusable \u2014 run `deepspace auth login`"]);
12444
+ facts.loggedIn = false;
12445
+ json.loggedIn = false;
12446
+ json.sessionError = sessionError(
12447
+ "Stored credentials are unusable. Run `deepspace auth login`."
12448
+ );
12449
+ }
12450
+ }
12451
+ }
12452
+ if (!sessionLineEmitted) {
12453
+ lines.push([
12454
+ "Session",
12455
+ `${who ?? "logged in"} \xB7 renews on use (re-login only after 30 idle days)`
12456
+ ]);
12457
+ json.loggedIn = true;
12458
+ if (who) json.user = who;
11982
12459
  }
11983
- lines.push([
11984
- "Session",
11985
- `${who ?? "logged in"} \xB7 renews on use (re-login only after 30 idle days)`
11986
- ]);
11987
- json.loggedIn = true;
11988
- if (who) json.user = who;
11989
12460
  }
11990
12461
  const appDir = findAppDir();
11991
12462
  if (!appDir) {
@@ -12120,9 +12591,10 @@ var status_default = defineCommand11({
12120
12591
  ]);
12121
12592
  json.source = { ...source, revision: sourceResult.value.revision };
12122
12593
  } else {
12594
+ const observed = inferredGithub ? observedGitHubRepository(appDir) : null;
12123
12595
  lines.push([
12124
12596
  "Source",
12125
- `unclaimed \xB7 ${inferredGithub ? "first release claims GitHub (from this checkout\u2019s remote), permanently" : "first deploy or push claims DeepSpace, permanently"}`
12597
+ `unclaimed \xB7 ${inferredGithub ? `first release claims GitHub${observed ? ` (${observed})` : ""} from this checkout\u2019s remote, permanently` : "first deploy or push claims DeepSpace, permanently"}`
12126
12598
  ]);
12127
12599
  json.source = null;
12128
12600
  json.sourceInference = inferredGithub ? "github" : "deepspace";
@@ -13156,7 +13628,7 @@ Re-run with --allow-do-deletion to accept the data loss.`,
13156
13628
  });
13157
13629
 
13158
13630
  // src/cli/commands/workspace.ts
13159
- import { defineCommand as defineCommand12 } from "citty";
13631
+ import { defineCommand as defineCommand13 } from "citty";
13160
13632
 
13161
13633
  // src/cli/commands/workspace/new.ts
13162
13634
  import * as p25 from "@clack/prompts";
@@ -13744,9 +14216,9 @@ var newWorkspaceCommand = defineDeepspaceCommand({
13744
14216
  },
13745
14217
  async run({ args }) {
13746
14218
  const task = typeof args.task === "string" ? args.task.trim() : "";
13747
- if (!task) {
14219
+ if (!task || task.startsWith("-")) {
13748
14220
  throw new Refusal(
13749
- 'A workspace needs a task \u2014 pass -t "<what this workspace is for>" (it is shown to every collaborator and agent).',
14221
+ 'A workspace needs a task \u2014 pass -t "<what this workspace is for>" (quote it, and put flags like --json after it; it is shown to every collaborator and agent).',
13750
14222
  "invalid_task"
13751
14223
  );
13752
14224
  }
@@ -15048,7 +15520,7 @@ var dropWorkspaceCommand = defineDeepspaceCommand({
15048
15520
  });
15049
15521
 
15050
15522
  // src/cli/commands/workspace.ts
15051
- var workspace_default = defineCommand12({
15523
+ var workspace_default = defineCommand13({
15052
15524
  meta: {
15053
15525
  name: "workspace",
15054
15526
  description: "Durable parallel-agent workspaces (new/attach/sync/list/status/land/drop)"
@@ -15097,7 +15569,7 @@ function formatEvent2(e, lands, actors) {
15097
15569
  detail = `"${String(s.task ?? "")}" from ${short(s.baseOid)}`;
15098
15570
  break;
15099
15571
  case "workspace.synced":
15100
- detail = `${e.subjectId ? `${e.subjectId} ` : ""}\u2192 ${short(s.headOid)}`;
15572
+ detail = `${e.subjectId ? `${e.subjectId} ` : ""}${typeof s.task === "string" && s.task ? `"${s.task}" ` : ""}\u2192 ${short(s.headOid)}`;
15101
15573
  break;
15102
15574
  case "workspace.landed":
15103
15575
  detail = `"${String(s.task ?? "")}" \u2192 ${short(s.landedOid)} on ${String(s.into ?? "trunk")}`;
@@ -15227,7 +15699,7 @@ var activity_default = defineDeepspaceCommand({
15227
15699
  });
15228
15700
 
15229
15701
  // src/cli/commands/git-credential.ts
15230
- import { defineCommand as defineCommand13 } from "citty";
15702
+ import { defineCommand as defineCommand14 } from "citty";
15231
15703
  function parseFields(input) {
15232
15704
  const fields = /* @__PURE__ */ new Map();
15233
15705
  for (const line of input.split("\n")) {
@@ -15269,7 +15741,7 @@ function declineHint(op, input, token, deployUrl) {
15269
15741
  }
15270
15742
  return "";
15271
15743
  }
15272
- var git_credential_default = defineCommand13({
15744
+ var git_credential_default = defineCommand14({
15273
15745
  meta: {
15274
15746
  name: "git-credential",
15275
15747
  description: "Git credential helper (installed automatically; not for direct use)"
@@ -15368,6 +15840,7 @@ function reportSource(appId, state, json) {
15368
15840
  );
15369
15841
  }
15370
15842
  console.log(`Revision: ${state.revision}`);
15843
+ console.log(`Registered: ${state.registered ? "yes" : "no"}`);
15371
15844
  }
15372
15845
 
15373
15846
  // src/cli/commands/update.ts
@@ -15378,7 +15851,7 @@ import { join as join28, resolve as resolve22 } from "path";
15378
15851
  // package.json
15379
15852
  var package_default = {
15380
15853
  name: "deepspace",
15381
- version: "0.28.0",
15854
+ version: "0.28.2",
15382
15855
  engines: {
15383
15856
  node: ">=22.15.0 <23 || >=24 <25 || >=26 <27"
15384
15857
  },
@@ -15700,7 +16173,7 @@ var pkg = JSON.parse(readFileSync27(join29(__dirname, "..", "package.json"), "ut
15700
16173
  if (process.platform === "linux" && !process.env.SSL_CERT_FILE && existsSync31("/etc/ssl/certs/ca-certificates.crt")) {
15701
16174
  process.env.SSL_CERT_FILE = "/etc/ssl/certs/ca-certificates.crt";
15702
16175
  }
15703
- var create2 = defineCommand14({
16176
+ var create2 = defineCommand15({
15704
16177
  meta: {
15705
16178
  name: "create",
15706
16179
  description: "Create a new DeepSpace app (runs create-deepspace; all flags are forwarded)"
@@ -15749,11 +16222,11 @@ var create2 = defineCommand14({
15749
16222
  }
15750
16223
  });
15751
16224
  var rename = (cmd, name) => ({ ...cmd, meta: { ...cmd.meta ?? {}, name } });
15752
- var auth = defineCommand14({
16225
+ var auth = defineCommand15({
15753
16226
  meta: { name: "auth", description: "Session: login, logout, whoami" },
15754
16227
  subCommands: { login: login_default, logout: logout_default, whoami: whoami_default }
15755
16228
  });
15756
- var app = defineCommand14({
16229
+ var app = defineCommand15({
15757
16230
  meta: {
15758
16231
  name: "app",
15759
16232
  description: "The app itself: create, init, list, files, source, update, undeploy, transfer, collaborators, domain, usage"
@@ -15772,11 +16245,11 @@ var app = defineCommand14({
15772
16245
  update: update_default
15773
16246
  }
15774
16247
  });
15775
- var devGroup = defineCommand14({
16248
+ var devGroup = defineCommand15({
15776
16249
  meta: { name: "dev", description: "Local development" },
15777
16250
  subCommands: { start: rename(dev_default, "start"), kill: kill_default }
15778
16251
  });
15779
- var testGroup = defineCommand14({
16252
+ var testGroup = defineCommand15({
15780
16253
  meta: { name: "test", description: "App tests and test tooling" },
15781
16254
  subCommands: {
15782
16255
  run: rename(test_default, "run"),
@@ -15784,7 +16257,7 @@ var testGroup = defineCommand14({
15784
16257
  accounts: rename(test_accounts_default, "accounts")
15785
16258
  }
15786
16259
  });
15787
- var main = defineCommand14({
16260
+ var main = defineCommand15({
15788
16261
  meta: {
15789
16262
  name: "deepspace",
15790
16263
  version: pkg.version,
@@ -15810,6 +16283,7 @@ var main = defineCommand14({
15810
16283
  add: add_default,
15811
16284
  secrets: secrets_default,
15812
16285
  integrations: integrations_default,
16286
+ agent: agent_default,
15813
16287
  auth,
15814
16288
  app,
15815
16289
  feedback: feedback_default,