@tinycloud-ai/tinycloud-cli 0.1.1 → 0.1.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.
Files changed (2) hide show
  1. package/dist/main.js +29 -28
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -5,6 +5,11 @@ import { existsSync as existsSync3, readFileSync as readFileSync4, writeFileSync
5
5
  import { basename, join as join5, resolve } from "node:path";
6
6
  import { createInterface } from "node:readline/promises";
7
7
 
8
+ // ../../packages/domain/src/cli.ts
9
+ var CLI_PACKAGE = "@tinycloud-ai/tinycloud-cli";
10
+ var CLI_VERSION = "0.1.2";
11
+ var CLI_SPEC = `${CLI_PACKAGE}@${CLI_VERSION}`;
12
+
8
13
  // ../../packages/domain/src/ids.ts
9
14
  var lastRandom = new Uint8Array(10);
10
15
 
@@ -15,6 +20,7 @@ var ERROR_CODES = {
15
20
  AUTH_PROVIDER_REQUIRED: 501,
16
21
  FORBIDDEN: 403,
17
22
  NOT_FOUND: 404,
23
+ METHOD_NOT_ALLOWED: 405,
18
24
  CONFLICT: 409,
19
25
  PRECONDITION_FAILED: 412,
20
26
  VALIDATION_FAILED: 422,
@@ -28,7 +34,6 @@ var ERROR_CODES = {
28
34
  MANIFEST_UNSUPPORTED_API_VERSION: 422,
29
35
  // Planning / provider
30
36
  TARGET_INCOMPATIBLE: 422,
31
- APPROVAL_REQUIRED: 409,
32
37
  PLAN_EXPIRED: 409,
33
38
  PLAN_STALE: 409,
34
39
  PROVIDER_UNAVAILABLE: 503,
@@ -89,9 +94,9 @@ var RETRYABLE = /* @__PURE__ */ new Set([
89
94
  ]);
90
95
  var DEFAULT_REMEDIATION = {
91
96
  UNAUTHENTICATED: "Run `tiny login` and retry.",
97
+ METHOD_NOT_ALLOWED: "Use one of the methods named in the Allow response header.",
92
98
  AUTH_PROVIDER_REQUIRED: "Configure a trusted OIDC provider for this gateway.",
93
99
  FORBIDDEN: "Ask an organization admin for the required role.",
94
- APPROVAL_REQUIRED: "Ask an organization admin to approve the plan, then deploy again with the approved plan ID.",
95
100
  PLAN_STALE: "Run `tiny plan` again; the manifest or policy changed since this plan was produced.",
96
101
  MIGRATION_CHECKSUM_CHANGED: "Restore the original migration file and add a new migration instead.",
97
102
  INTERACTION_REQUIRED: "Re-run interactively, or pass the flag named in details.missingInput.",
@@ -121,8 +126,6 @@ function parseDuration(value) {
121
126
  var DEFAULT_ORGANIZATION_POLICY = {
122
127
  allowPublicApps: false,
123
128
  allowRawSecrets: true,
124
- requireApprovalForCapabilities: true,
125
- requireApprovalForRawSecrets: true,
126
129
  maxAppsPerOrg: 500,
127
130
  maxPreviewTtlHours: 168,
128
131
  maxMemoryMiB: 2048,
@@ -1092,6 +1095,9 @@ var STORAGE_LIMITS = {
1092
1095
  maxConcurrentOperationsPerEnvironment: 16
1093
1096
  };
1094
1097
 
1098
+ // ../../packages/orchestrator/src/lifecycle.ts
1099
+ var MAX_DELETE_GRACE_MS = 90 * 864e5;
1100
+
1095
1101
  // ../../packages/db/src/store.ts
1096
1102
  import { dirname as dirname3, join as join3 } from "node:path";
1097
1103
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -1165,7 +1171,11 @@ var ApiClient = class {
1165
1171
  return this.request("DELETE", path, query ? { query } : {});
1166
1172
  }
1167
1173
  uploadDirectory(directory) {
1168
- return this.post("/v1/artifacts", createArtifactUpload(directory));
1174
+ return this.uploadArtifact(createArtifactUpload(directory));
1175
+ }
1176
+ /** Upload a source tree the caller has already packed, from wherever it read it. */
1177
+ uploadArtifact(upload) {
1178
+ return this.post("/v1/artifacts", upload);
1169
1179
  }
1170
1180
  };
1171
1181
 
@@ -1277,7 +1287,6 @@ var EXIT_BY_CODE = {
1277
1287
  MANIFEST_SCHEMA_INVALID: EXIT.validation,
1278
1288
  MANIFEST_POLICY_VIOLATION: EXIT.policy,
1279
1289
  MANIFEST_UNSUPPORTED_API_VERSION: EXIT.validation,
1280
- APPROVAL_REQUIRED: EXIT.policy,
1281
1290
  PLAN_STALE: EXIT.conflict,
1282
1291
  PLAN_EXPIRED: EXIT.conflict,
1283
1292
  TARGET_INCOMPATIBLE: EXIT.validation,
@@ -1388,7 +1397,7 @@ var USAGE = `tiny \u2014 governed runtime for small internal apps
1388
1397
  tiny init [name] Write a starter tiny.yaml
1389
1398
  tiny validate Parse and check tiny.yaml
1390
1399
  tiny plan [--env production] Show what a deploy would do (never mutates)
1391
- tiny deploy [--env production] [--yes] Deploy and watch it finish
1400
+ tiny deploy [--env production] Deploy and watch it finish
1392
1401
  [--no-wait] [--wait <seconds>]
1393
1402
  tiny status Show apps and their lifecycle status
1394
1403
  tiny logs [app] [--since 1h] [--limit 100] Read bounded logs
@@ -1397,12 +1406,13 @@ var USAGE = `tiny \u2014 governed runtime for small internal apps
1397
1406
 
1398
1407
  tiny access list|grant|revoke <subject> [--role user]
1399
1408
  tiny secrets set <name>|list
1400
- tiny capabilities list|request <operation> --connection <name>
1409
+ tiny capabilities list|grant <operation> --connection <name>
1401
1410
  tiny preview create [--ttl 72h]|delete <environment>
1402
1411
 
1403
1412
  tiny archive [app] Snapshot and deactivate
1404
1413
  tiny restore [app] Reactivate an archived app
1405
- tiny delete [app] --confirm <slug> Schedule deletion
1414
+ tiny delete [app] --confirm <slug> [--grace 7d]
1415
+ Schedule deletion (--grace 0 deletes now)
1406
1416
  tiny doctor Check auth, manifest files, and target reachability
1407
1417
 
1408
1418
  Global flags: --json --api <url> --token <token> --cwd <path> --idempotency-key <key>
@@ -1628,21 +1638,12 @@ Service account token (shown once): ${created.apiToken}`);
1628
1638
  environment: typeof args.flags.env === "string" ? args.flags.env : void 0
1629
1639
  });
1630
1640
  if (args.flags.json !== true) printPlan(output, planned.plan, planned.warnings);
1631
- if (planned.plan.approvals.length > 0 && args.flags.yes !== true && !isInteractive()) {
1632
- throw new TinyError("APPROVAL_REQUIRED", "This deployment needs approval and no terminal is attached.", {
1633
- details: { approvals: planned.plan.approvals, planId: planned.plan.planId, nextActions: [
1634
- "Ask an organization admin to approve the plan.",
1635
- "Re-run `tiny deploy --yes` once approved."
1636
- ] }
1637
- });
1638
- }
1639
1641
  output.progress("Deploying\u2026");
1640
1642
  const result = await client.post("/v1/apps:deploy", {
1641
1643
  artifactUri: artifact.artifactUri,
1642
1644
  manifest: source,
1643
1645
  environment: typeof args.flags.env === "string" ? args.flags.env : void 0,
1644
- planId: planned.plan.planId,
1645
- approve: args.flags.yes === true
1646
+ planId: planned.plan.planId
1646
1647
  }, typeof args.flags["idempotency-key"] === "string" ? args.flags["idempotency-key"] : void 0);
1647
1648
  const settled = args.flags["no-wait"] === true ? null : await awaitDeployment(
1648
1649
  () => client.get(`/v1/deployments/${result.deploymentId}`),
@@ -1812,10 +1813,10 @@ Service account token (shown once): ${created.apiToken}`);
1812
1813
  });
1813
1814
  return;
1814
1815
  }
1815
- if (args.subcommand === "request") {
1816
+ if (args.subcommand === "grant") {
1816
1817
  const operation = args.positional[0];
1817
1818
  const connection = typeof args.flags.connection === "string" ? args.flags.connection : null;
1818
- if (!operation || !connection) throw usageError("tiny capabilities request <operation> --connection <name>");
1819
+ if (!operation || !connection) throw usageError("tiny capabilities grant <operation> --connection <name>");
1819
1820
  const appRef = typeof args.flags.app === "string" ? args.flags.app : parseManifest(readManifest(cwd).source).normalized.metadata.name;
1820
1821
  const app = await resolveApp(client, appRef);
1821
1822
  const grant = await client.post(`/v1/apps/${app.id}/capability-grants`, {
@@ -1823,12 +1824,11 @@ Service account token (shown once): ${created.apiToken}`);
1823
1824
  operations: [operation]
1824
1825
  });
1825
1826
  output.result({ grantId: grant.id, status: grant.status, operation }, () => {
1826
- output.step(grant.status === "approved", `Grant ${grant.id} is ${grant.status}`);
1827
- if (grant.status === "pending") output.progress("An organization admin must approve it before the app can call the operation.");
1827
+ output.step(true, `${appRef} can now ${operation} on ${connection}.`);
1828
1828
  });
1829
1829
  return;
1830
1830
  }
1831
- throw usageError("tiny capabilities list|request");
1831
+ throw usageError("tiny capabilities list|grant");
1832
1832
  }
1833
1833
  // --------------------------------------------------------- preview
1834
1834
  case "preview": {
@@ -1884,10 +1884,11 @@ Service account token (shown once): ${created.apiToken}`);
1884
1884
  details: { missingInput: "--confirm", expected: app.slug }
1885
1885
  });
1886
1886
  }
1887
- const scheduled = await client.del(`/v1/apps/${app.id}`, { confirm });
1887
+ const grace = typeof args.flags.grace === "string" ? args.flags.grace : void 0;
1888
+ const scheduled = await client.del(`/v1/apps/${app.id}`, { confirm, grace });
1888
1889
  output.result(
1889
- { appId: app.id, deleteAfter: scheduled.deleteAfter },
1890
- () => output.step(true, `${app.slug} will be deleted after ${scheduled.deleteAfter}.`)
1890
+ { appId: app.id, status: scheduled.status, deleteAfter: scheduled.deleteAfter },
1891
+ () => output.step(true, scheduled.status === "deleted" ? `${app.slug} deleted.` : `${app.slug} will be deleted after ${scheduled.deleteAfter}. Run "tiny restore ${app.slug}" to cancel.`)
1891
1892
  );
1892
1893
  return;
1893
1894
  }
@@ -1922,7 +1923,7 @@ function printPlan(output, plan, warnings) {
1922
1923
  output.progress(` risk: ${plan.riskTier}${plan.estimatedMonthlyCents === null ? "" : ` estimate: $${(plan.estimatedMonthlyCents / 100).toFixed(2)}/mo`}`);
1923
1924
  for (const warning of [...warnings, ...plan.warnings]) output.warn(warning);
1924
1925
  for (const problem of plan.incompatibilities) output.warn(`incompatible: ${problem}`);
1925
- for (const approval of plan.approvals) output.warn(`approval required \u2014 ${approval.code}: ${approval.detail}`);
1926
+ for (const notice of plan.notices) output.warn(notice.detail);
1926
1927
  output.progress("");
1927
1928
  }
1928
1929
  function usageError(usage) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinycloud-ai/tinycloud-cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Command-line client for deploying and managing governed, isolated internal apps on Tinycloud.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",