@tonbo/cli 0.3.3 → 0.3.4

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/bin/tonbo.js +75 -16
  2. package/package.json +1 -1
package/dist/bin/tonbo.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/app.ts
4
- import { randomUUID as randomUUID4 } from "node:crypto";
4
+ import { randomUUID as randomUUID5 } from "node:crypto";
5
5
  import { Command } from "commander";
6
6
  import { readFileSync } from "node:fs";
7
7
 
@@ -524,6 +524,9 @@ var TonboApi = class {
524
524
  this.accountOrigin = accountOrigin;
525
525
  this.managementOrigin = managementOrigin;
526
526
  }
527
+ cancelActivities(agentId, token, body) {
528
+ return this.management("POST", `/v1/agents/${agentId}/production/cancellations`, token, body);
529
+ }
527
530
  async listRegions(oauthToken) {
528
531
  return parseRegionDiscovery(
529
532
  await requestJson(this.fetcher, `${this.accountOrigin}/api/cli/regions`, {
@@ -559,7 +562,7 @@ var TonboApi = class {
559
562
  }
560
563
  ).then((body) => body.organizations);
561
564
  }
562
- createAgent(oauthToken, name, organizationId) {
565
+ createAgent(oauthToken, name, organizationId, requestId = randomUUID()) {
563
566
  return requestJson(
564
567
  this.fetcher,
565
568
  `${this.accountOrigin}/api/cli/agents`,
@@ -569,9 +572,28 @@ var TonboApi = class {
569
572
  authorization: `Bearer ${oauthToken}`,
570
573
  "content-type": "application/json"
571
574
  },
572
- body: JSON.stringify(organizationId ? { name, orgId: organizationId } : { name })
575
+ body: JSON.stringify({
576
+ name,
577
+ requestId,
578
+ ...organizationId ? { orgId: organizationId } : {}
579
+ })
573
580
  }
574
- ).then((body) => body.agent);
581
+ ).then((body) => body.agent).catch((cause) => {
582
+ if (cause instanceof Error && "status" in cause && typeof cause.status === "number" && cause.status >= 400 && cause.status < 500)
583
+ throw cause;
584
+ throw new Error(
585
+ `Agent creation was not confirmed. Query \`tonbo agent creation ${requestId}${organizationId ? ` --account ${organizationId}` : ""}\` or retry creation with --request-id ${requestId} and the same name and account.`,
586
+ { cause }
587
+ );
588
+ });
589
+ }
590
+ readAgentCreationRequest(oauthToken, requestId, accountId) {
591
+ const account = accountId ? `?account=${encodeURIComponent(accountId)}` : "";
592
+ return requestJson(
593
+ this.fetcher,
594
+ `${this.accountOrigin}/api/cli/agents/creations/${encodeURIComponent(requestId)}${account}`,
595
+ { headers: { authorization: `Bearer ${oauthToken}` } }
596
+ );
575
597
  }
576
598
  registerSshKey(oauthToken, key) {
577
599
  return requestJson(
@@ -1257,8 +1279,9 @@ async function openBrowser(url) {
1257
1279
 
1258
1280
  // ../../packages/agent-source-bundler/dist/src/generated/contracts.js
1259
1281
  var inferenceDefault = { "model": "claude-sonnet-5" };
1260
- var sourceBundleContract = { "version": 1, "format": "tar-v1", "key_prefix": "agent-source-bundles", "content_type": "application/vnd.tonbo.source+tar", "max_bytes": 67108864 };
1282
+ var sourceBundleContract = { "version": 1, "format": "tar-v1", "key_prefix": "agent-source-bundles", "content_type": "application/vnd.tonbo.source+tar", "max_bytes": 67108864, "runtime_cache_directories": [".pi/npm", ".pi/git"] };
1261
1283
  var piSessionContract = { "version": 1, "adapter": "pi-jsonl-v3", "format_version": 3, "durable_completion_timeout_seconds": 30, "turn_claim_seconds": 30, "turn_claim_renew_seconds": 10, "session_directory": "/sessions", "path_template": "/sessions/{session_id}.jsonl", "preflight_command": ["/usr/local/bin/artifacts", "runtime", "session-preflight"] };
1284
+ var piSlackTemplate = { "repository": "tonbo-io/pi-slack-agent", "source_directory": "examples/pi-slack-agent", "service": { "command": ["node", "slack/server.mjs"], "secrets": ["SLACK_SIGNING_SECRET", "SLACK_BOT_TOKEN", "SLACK_BOT_USER_ID", "SLACK_TEAM_ID", "TONBO_AGENT_API_KEY", "TONBO_AGENT_API_ORIGIN", "TONBO_IAM_ORIGIN"] } };
1262
1285
 
1263
1286
  // ../../packages/agent-source-bundler/dist/src/inference-default.js
1264
1287
  var DEFAULT_INFERENCE_MODEL = inferenceDefault.model;
@@ -1293,6 +1316,7 @@ function githubRepositoryUrl(remote) {
1293
1316
 
1294
1317
  // src/commands.ts
1295
1318
  import path4 from "node:path";
1319
+ import { randomUUID as randomUUID3 } from "node:crypto";
1296
1320
 
1297
1321
  // src/build.ts
1298
1322
  import { spawn } from "node:child_process";
@@ -1321,11 +1345,13 @@ async function runBuildCommand(root, command) {
1321
1345
 
1322
1346
  // ../../packages/agent-source-bundler/dist/src/native-pi.js
1323
1347
  import { stringify } from "smol-toml";
1324
- function nativePiDeclaration(model) {
1348
+ var PI_SLACK_TEMPLATE_SERVICE = piSlackTemplate.service;
1349
+ function nativePiDeclaration(model, service) {
1325
1350
  return {
1326
1351
  version: 2,
1327
1352
  harness: { runtime: "pi", driver: { kind: "native" } },
1328
- inference: { model }
1353
+ inference: { model },
1354
+ ...service ? { service } : {}
1329
1355
  };
1330
1356
  }
1331
1357
 
@@ -1447,8 +1473,7 @@ var DEFAULT_IGNORES = [
1447
1473
  "!.env.example",
1448
1474
  ".tonbo-cache/",
1449
1475
  ".tonbo-system/",
1450
- ".pi/npm/",
1451
- ".pi/git/"
1476
+ ...sourceBundleContract.runtime_cache_directories.map((directory) => `${directory}/`)
1452
1477
  ];
1453
1478
  var EXACT_NPM_VERSION = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
1454
1479
  var GIT_COMMIT = /^[0-9a-f]{40}$/i;
@@ -2130,7 +2155,7 @@ async function agentUseCommand(deps, selector, force = false) {
2130
2155
  await bindDeclarationAgent(root, agent.publicHostname);
2131
2156
  deps.output({ message: `Bound .tonbo to agent ${agent.publicHostname}.`, agent });
2132
2157
  }
2133
- async function agentCreateCommand(deps, name) {
2158
+ async function agentCreateCommand(deps, name, options = {}) {
2134
2159
  const root = await findDeclarationRoot(deps.cwd());
2135
2160
  const declaration = await loadDeclaration(root);
2136
2161
  if (declaration.agent) {
@@ -2140,7 +2165,8 @@ async function agentCreateCommand(deps, name) {
2140
2165
  }
2141
2166
  const oauthToken = await deps.auth.accessToken();
2142
2167
  validateAgentName(name);
2143
- const agent = await deps.api.createAgent(oauthToken, name);
2168
+ const requestId = options.requestId ?? randomUUID3();
2169
+ const agent = await deps.api.createAgent(oauthToken, name, options.account, requestId);
2144
2170
  try {
2145
2171
  await bindDeclarationAgent(root, agent.publicHostname);
2146
2172
  } catch (error) {
@@ -2149,7 +2175,11 @@ async function agentCreateCommand(deps, name) {
2149
2175
  { cause: error }
2150
2176
  );
2151
2177
  }
2152
- deps.output({ message: `Created agent ${agent.name} and bound it in .tonbo.`, agent });
2178
+ deps.output({
2179
+ message: `Created agent ${agent.name} and bound it in .tonbo.`,
2180
+ agent,
2181
+ requestId
2182
+ });
2153
2183
  }
2154
2184
  async function deployCommand(deps, options = { promote: true }) {
2155
2185
  const { declaration, oauthToken, agent, root } = await resolveAgent(deps);
@@ -2441,9 +2471,23 @@ async function secretRemoveCommand(deps, name) {
2441
2471
  await deps.api.deleteAgentSecret(agent.id, name, token);
2442
2472
  deps.output({ message: `Removed agent secret ${name}.`, agent, name });
2443
2473
  }
2474
+ async function cancelActivitiesCommand(deps, options) {
2475
+ const { oauthToken, agent } = await resolveAgent(deps);
2476
+ const token = await deps.api.exchangeManagementToken(oauthToken, agent.id);
2477
+ const result = await deps.api.cancelActivities(agent.id, token, {
2478
+ sandbox_id: options.sandbox,
2479
+ runtime_session_id: options.runtimeSession,
2480
+ work_keys: options.workKey,
2481
+ reason: options.reason
2482
+ });
2483
+ deps.output({
2484
+ message: "Activity cancellation requested. Physical retirement and application checkpoint cancellation must still be verified.",
2485
+ cancellation: result
2486
+ });
2487
+ }
2444
2488
 
2445
2489
  // src/credentials.ts
2446
- import { randomUUID as randomUUID3 } from "node:crypto";
2490
+ import { randomUUID as randomUUID4 } from "node:crypto";
2447
2491
  import { chmod, lstat as lstat4, mkdir, open as open2, readFile as readFile5, rename as rename2, rm as rm2 } from "node:fs/promises";
2448
2492
  import os from "node:os";
2449
2493
  import path5 from "node:path";
@@ -2474,7 +2518,7 @@ var FileCredentialStore = class {
2474
2518
  await assertExistingDestinationIsSafe(this.filename);
2475
2519
  const temporary = path5.join(
2476
2520
  directory,
2477
- `.${path5.basename(this.filename)}.${process.pid}.${randomUUID3()}.tmp`
2521
+ `.${path5.basename(this.filename)}.${process.pid}.${randomUUID4()}.tmp`
2478
2522
  );
2479
2523
  let handle = null;
2480
2524
  try {
@@ -2725,7 +2769,7 @@ function createProgram(dependencies = createDependencies) {
2725
2769
  "stable allocation request UUID; reuse it after an uncertain response"
2726
2770
  ).action(async (options) => {
2727
2771
  const deps = dependencies(jsonOutput(program));
2728
- const requestId = options.requestId ?? randomUUID4();
2772
+ const requestId = options.requestId ?? randomUUID5();
2729
2773
  try {
2730
2774
  const result = await deps.api.machineRequest(await deps.auth.accessToken(), "", "POST", {
2731
2775
  accountId: options.account,
@@ -2786,7 +2830,19 @@ function createProgram(dependencies = createDependencies) {
2786
2830
  );
2787
2831
  });
2788
2832
  const agent = program.command("agent").description("manage the Agent bound to this source directory");
2789
- agent.command("create <name>").description("create an agent and bind this directory to it").action(async (name) => agentCreateCommand(dependencies(jsonOutput(program)), name));
2833
+ agent.command("create <name>").description("create an agent and bind this directory to it").option("--account <account>", "owning account UUID; defaults to your personal account").option("--request-id <uuid>", "reuse the same creation UUID after an uncertain response").action(
2834
+ async (name, options) => agentCreateCommand(dependencies(jsonOutput(program)), name, options)
2835
+ );
2836
+ agent.command("creation <requestId>").description("query the original Agent for a creation request").option("--account <account>", "owning account UUID; defaults to your personal account").action(async (requestId, options) => {
2837
+ const deps = dependencies(jsonOutput(program));
2838
+ deps.output(
2839
+ await deps.api.readAgentCreationRequest(
2840
+ await deps.auth.accessToken(),
2841
+ requestId,
2842
+ options.account
2843
+ )
2844
+ );
2845
+ });
2790
2846
  agent.command("list").description("list the agents available to your account").action(async () => agentListCommand(dependencies(jsonOutput(program))));
2791
2847
  const sshKey = program.command("ssh-key").description("manage public keys used by native agent SSH");
2792
2848
  sshKey.command("add <public-key>").description("register an OpenSSH public key with the current Tonbo account").action(async (path6) => sshKeyAddCommand(dependencies(jsonOutput(program)), path6));
@@ -2808,6 +2864,9 @@ function createProgram(dependencies = createDependencies) {
2808
2864
  deployments.command("promote <deployment>").description("move Production to a Deployment by id prefix").action(
2809
2865
  async (prefix) => deploymentsPromoteCommand(dependencies(jsonOutput(program)), prefix)
2810
2866
  );
2867
+ deployments.command("cancel-activities").description("cancel selected named work on an exact retired runtime").requiredOption("--sandbox <id>", "retired Sandbox UUID").requiredOption("--runtime-session <id>", "exact activation UUID").requiredOption("--work-key <keys...>", "named work keys to cancel").requiredOption("--reason <reason>", "reason retained in the cancellation audit").action(
2868
+ async (options) => cancelActivitiesCommand(dependencies(jsonOutput(program)), options)
2869
+ );
2811
2870
  deployments.command("rollback [deployment]").description("move Production back to the previous Production Deployment, or to a named one").action(
2812
2871
  async (prefix) => deploymentsRollbackCommand(dependencies(jsonOutput(program)), prefix)
2813
2872
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonbo/cli",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Deploy persistent Agents and manage their Machines from the command line.",
5
5
  "homepage": "https://tonbo.dev",
6
6
  "bugs": {