@integrity-labs/agt-cli 0.28.176 → 0.28.178

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/bin/agt.js CHANGED
@@ -37,7 +37,7 @@ import {
37
37
  success,
38
38
  table,
39
39
  warn
40
- } from "../chunk-YNCNFORO.js";
40
+ } from "../chunk-MRY24Y4V.js";
41
41
  import {
42
42
  CHANNEL_REGISTRY,
43
43
  DEFAULT_FRAMEWORK,
@@ -65,7 +65,7 @@ import {
65
65
  renderTemplate,
66
66
  resolveChannels,
67
67
  serializeManifestForSlackCli
68
- } from "../chunk-ULPUDU4J.js";
68
+ } from "../chunk-ODMNVKDO.js";
69
69
 
70
70
  // src/bin/agt.ts
71
71
  import { join as join22 } from "path";
@@ -4749,7 +4749,7 @@ import { execFileSync, execSync } from "child_process";
4749
4749
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4750
4750
  import chalk18 from "chalk";
4751
4751
  import ora16 from "ora";
4752
- var cliVersion = true ? "0.28.176" : "dev";
4752
+ var cliVersion = true ? "0.28.178" : "dev";
4753
4753
  async function fetchLatestVersion() {
4754
4754
  const host2 = getHost();
4755
4755
  if (!host2) return null;
@@ -5763,7 +5763,7 @@ function handleError(err) {
5763
5763
  }
5764
5764
 
5765
5765
  // src/bin/agt.ts
5766
- var cliVersion2 = true ? "0.28.176" : "dev";
5766
+ var cliVersion2 = true ? "0.28.178" : "dev";
5767
5767
  var program = new Command();
5768
5768
  program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
5769
5769
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -3,7 +3,7 @@ import {
3
3
  formatMissingVar,
4
4
  isClaudeFastMode,
5
5
  probeMcpEnvSubstitution
6
- } from "./chunk-ULPUDU4J.js";
6
+ } from "./chunk-ODMNVKDO.js";
7
7
  import {
8
8
  reapOrphanChannelMcps
9
9
  } from "./chunk-XWVM4KPK.js";
@@ -1588,4 +1588,4 @@ export {
1588
1588
  stopAllSessionsAndWait,
1589
1589
  getProjectDir
1590
1590
  };
1591
- //# sourceMappingURL=chunk-NZLZICAD.js.map
1591
+ //# sourceMappingURL=chunk-4LMNQ2V7.js.map
@@ -16,7 +16,7 @@ import {
16
16
  resolveConnectivityProbe,
17
17
  worseConnectivityOutcome,
18
18
  wrapScheduledTaskPrompt
19
- } from "./chunk-ULPUDU4J.js";
19
+ } from "./chunk-ODMNVKDO.js";
20
20
 
21
21
  // ../../packages/core/dist/provisioning/mcp-config-guards.js
22
22
  import { chmodSync, existsSync, readFileSync, renameSync, writeFileSync, unlinkSync } from "fs";
@@ -1706,8 +1706,15 @@ var INTEGRATION_REGISTRY = [
1706
1706
  remoteMcp: {
1707
1707
  type: "http",
1708
1708
  url: "https://api.anchorbrowser.io/mcp",
1709
+ // ENG-6993 / ADR-0033: the api-key credential header now goes through the
1710
+ // structured `auth` field — the env var (ANCHOR_BROWSER_API_KEY) is
1711
+ // DERIVED from this integration's definition_id + credential_ref, so it
1712
+ // is scoped to Anchor and can't reference another integration's secret
1713
+ // (C1). Renders byte-identically to the previous verbatim header.
1714
+ auth: { scheme: "header", header_name: "anchor-api-key", credential_ref: "api_key" },
1715
+ // The dynamic session header stays here (not a credential — minted per
1716
+ // session by ENG-5857; empty default below until then).
1709
1717
  headers: {
1710
- "anchor-api-key": "${ANCHOR_BROWSER_API_KEY}",
1711
1718
  "anchor-session-id": "${ANCHOR_BROWSER_SESSION_ID}"
1712
1719
  },
1713
1720
  // ENG-5857 mints the real session id; default empty so the header
@@ -1744,10 +1751,60 @@ var INTEGRATION_REGISTRY = [
1744
1751
  beta: true,
1745
1752
  // ENG-6920: Deck is the first PREMIUM integration. Unlike the customer-auth
1746
1753
  // integrations, every Deck run bills back to Augmented's single account
1747
- // key, and Deck is usage-priced (compute time + agent runs) so it is
1748
- // gated on a per-org opt-in and metered. Pricing amounts are deferred to
1749
- // the billing mechanism (Stripe); this only declares the model.
1750
- premium: { pricing: "usage", note: "Billed on Deck compute time and agent runs." }
1754
+ // key, and Deck is usage-priced so it is gated on a per-org opt-in and
1755
+ // metered. ENG-7032: `meters` declares the billable operation (run_task,
1756
+ // billed per run); the priced rate card (integration_rate_cards) holds the
1757
+ // amount ($1.00 USD / A$1.50 per run, the per-run v1 decision). The
1758
+ // event_type must match what deck-broker writes to integration_usage_events.
1759
+ premium: {
1760
+ pricing: "usage",
1761
+ note: "Billed per Deck task run.",
1762
+ meters: [{ event_type: "run_task", unit: "run" }]
1763
+ }
1764
+ },
1765
+ {
1766
+ id: "elevenlabs",
1767
+ name: "ElevenLabs",
1768
+ category: "media",
1769
+ description: "Speech-to-text for inbound voice notes. When a teammate sends an agent a voice message (Slack, Telegram, etc.), the agent uploads the audio and gets back an accurate transcript via ElevenLabs Scribe, so a voice note is no longer a black box. Augmented Team manages ElevenLabs access for you - there is no key to enter.",
1770
+ // ElevenLabs is REST-only for our use (POST /v1/speech-to-text, `xi-api-key`
1771
+ // header, NOT Bearer) — it ships no MCP server, so the agent-facing tools are
1772
+ // brokered server-side (scribe-broker.ts). It is a PREMIUM integration on the
1773
+ // Deck model (ADR-0031, epic ENG-6920): Augmented owns ONE ElevenLabs account
1774
+ // that every customer agent's transcriptions bill back to, so the account key
1775
+ // is a single platform-held secret (`ELEVENLABS_ACCOUNT_KEY`), NOT a per-agent
1776
+ // credential. Auth type is therefore `none` — customers never enter a key.
1777
+ // Usage is metered in audio-seconds at the broker chokepoint and gated on a
1778
+ // per-org opt-in + monthly cap. (TTS for Augmented Live voiceover is a
1779
+ // separate surface — ENG-7048 — that reuses the same account key.)
1780
+ supported_auth_types: ["none"],
1781
+ capabilities: [
1782
+ { id: "elevenlabs:transcribe", name: "Transcribe Voice Notes", description: "Upload an inbound audio file and transcribe it to text via ElevenLabs Scribe (scribe_create_upload, scribe_transcribe)", access: "write" },
1783
+ // ENG-7048: text-to-speech voiceover for Augmented Live. Surfaced as the
1784
+ // agt_live.generate_voiceover tool (not a standalone scribe_* tool); shares
1785
+ // this one platform account key + the same per-org budget.
1786
+ { id: "elevenlabs:tts", name: "Generate Voiceover", description: "Synthesize a spoken-voice MP3 voiceover from text for an Augmented Live page via ElevenLabs text-to-speech (agt_live.generate_voiceover)", access: "write" }
1787
+ ],
1788
+ // Capabilities index — covers both speech-to-text and text-to-speech, since
1789
+ // the integration now advertises elevenlabs:transcribe AND elevenlabs:tts.
1790
+ docs_url: "https://elevenlabs.io/docs/capabilities",
1791
+ beta: true,
1792
+ // ENG-7005 / ENG-7048: premium (billable). Both surfaces bill back to
1793
+ // Augmented's single account key and are usage-priced, so the integration is
1794
+ // gated on a per-org opt-in and metered. The two surfaces share the one
1795
+ // `elevenlabs` definition (and so the one per-org monthly budget). Pricing
1796
+ // amounts live in integration_rate_cards; this only declares the model.
1797
+ premium: {
1798
+ pricing: "usage",
1799
+ note: "Billed on audio transcribed (per second) and voiceover synthesized (per character).",
1800
+ // ENG-7032: each surface meters its own event in its own physical unit; the
1801
+ // matching integration_rate_cards rows price them. Until a rate is seeded,
1802
+ // that event prices at 0.
1803
+ meters: [
1804
+ { event_type: "transcribe", unit: "audio_second" },
1805
+ { event_type: "tts", unit: "character" }
1806
+ ]
1807
+ }
1751
1808
  },
1752
1809
  {
1753
1810
  id: "postiz",
@@ -1994,6 +2051,28 @@ var INTEGRATION_REGISTRY = [
1994
2051
  { id: "augmented-admin:read-diagnostics", name: "Read Diagnostics", description: "Cross-org read of agent, host, integration, and alert diagnostics (projection only \u2014 never credentials or transcripts).", access: "read" }
1995
2052
  ]
1996
2053
  },
2054
+ {
2055
+ // ENG-7023 (ADR-0031/0032): the per-org self-troubleshoot surface for the
2056
+ // `system_support` concierge agent. Provisions the
2057
+ // @integrity-labs/augmented-support-mcp stdio broker, which reads the
2058
+ // agent's OWN org diagnostics and proposes self-remediation writes
2059
+ // (create_agent) through the server-rendered HITL approval gate, all via
2060
+ // /host/support/*. `beta` while the concierge rolls out gradually (ENG-6975);
2061
+ // auth `none` - no end-user OAuth, the host JWT (org_id claim) is the
2062
+ // credential and the org-lock. NOT a customer-selectable integration: it is
2063
+ // attached automatically to system_support agents at provisioning.
2064
+ id: "augmented-support",
2065
+ name: "Augmented Support",
2066
+ category: "infrastructure",
2067
+ description: "Per-org self-troubleshoot concierge: reads your org's agents, hosts, integrations, alerts, flags, and audit log, files support/feature requests, and proposes new agents for human approval - all scoped to your own organization.",
2068
+ supported_auth_types: ["none"],
2069
+ beta: true,
2070
+ capabilities: [
2071
+ { id: "augmented-support:read-diagnostics", name: "Read Diagnostics", description: "Read your own org's agents, hosts, integrations, alerts, flags, and audit log (projection only - never credentials or transcripts).", access: "read" },
2072
+ { id: "augmented-support:file-requests", name: "File Requests", description: "File bug / feature / integration requests to Augmented Team support.", access: "write" },
2073
+ { id: "augmented-support:propose-writes", name: "Propose Self-Remediation", description: "Propose creating an agent in your own org; executed only after a human approves a server-rendered diff.", access: "write" }
2074
+ ]
2075
+ },
1997
2076
  {
1998
2077
  id: "custom",
1999
2078
  name: "Custom Integration",
@@ -2337,15 +2416,56 @@ function decryptIntegrationCredentials(credentials) {
2337
2416
  function envVarForToken(definitionId) {
2338
2417
  return `${definitionId.replace(/-/g, "_").toUpperCase()}_ACCESS_TOKEN`;
2339
2418
  }
2340
- function buildRemoteMcpEntry(definitionId) {
2341
- const def = INTEGRATION_REGISTRY.find((d) => d.id === definitionId);
2342
- if (def?.remoteMcp) {
2343
- const spec = def.remoteMcp;
2344
- return {
2345
- type: spec.type ?? "http",
2346
- url: spec.url,
2347
- ...spec.headers ? { headers: { ...spec.headers } } : {}
2348
- };
2419
+ function credentialEnvVar(definitionId, credentialRef) {
2420
+ const idPart = definitionId.replace(/-/g, "_").toUpperCase();
2421
+ const credPart = credentialRef.replace(/-/g, "_").toUpperCase();
2422
+ return `${idPart}_${credPart}`;
2423
+ }
2424
+ function assertSafeRemoteMcpUrl(url, definitionId) {
2425
+ let u;
2426
+ try {
2427
+ u = new URL(url);
2428
+ } catch {
2429
+ throw new Error(`remoteMcp.url for '${definitionId}' is not a valid URL: ${url}`);
2430
+ }
2431
+ if (u.protocol !== "https:") {
2432
+ throw new Error(`remoteMcp.url for '${definitionId}' must be https (got ${u.protocol}//): ${url}`);
2433
+ }
2434
+ const host = u.hostname.toLowerCase();
2435
+ const blocked = host === "localhost" || host === "169.254.169.254" || // AWS/GCP/Azure instance metadata
2436
+ host === "metadata.google.internal" || /^127\./.test(host) || /^10\./.test(host) || /^192\.168\./.test(host) || /^169\.254\./.test(host) || // link-local
2437
+ /^172\.(1[6-9]|2\d|3[01])\./.test(host) || // 172.16.0.0/12
2438
+ host.endsWith(".internal") || host.endsWith(".local");
2439
+ if (blocked) {
2440
+ throw new Error(`remoteMcp.url for '${definitionId}' resolves to a disallowed (internal/link-local/metadata) host: ${host}`);
2441
+ }
2442
+ }
2443
+ function renderRemoteMcpSpec(definitionId, spec) {
2444
+ assertSafeRemoteMcpUrl(spec.url, definitionId);
2445
+ const headers = {};
2446
+ if (spec.auth) {
2447
+ const envVar = credentialEnvVar(definitionId, spec.auth.credential_ref);
2448
+ const value = `\${${envVar}}`;
2449
+ if (spec.auth.scheme === "bearer") {
2450
+ headers["Authorization"] = `Bearer ${value}`;
2451
+ } else {
2452
+ if (!spec.auth.header_name) {
2453
+ throw new Error(`remoteMcp.auth for '${definitionId}' uses scheme 'header' but no header_name`);
2454
+ }
2455
+ headers[spec.auth.header_name] = value;
2456
+ }
2457
+ }
2458
+ Object.assign(headers, spec.headers ?? {});
2459
+ return {
2460
+ type: spec.type ?? "http",
2461
+ url: spec.url,
2462
+ ...Object.keys(headers).length > 0 ? { headers } : {}
2463
+ };
2464
+ }
2465
+ function buildRemoteMcpEntry(definitionId, dbSpec) {
2466
+ const spec = dbSpec ?? INTEGRATION_REGISTRY.find((d) => d.id === definitionId)?.remoteMcp;
2467
+ if (spec) {
2468
+ return renderRemoteMcpSpec(definitionId, spec);
2349
2469
  }
2350
2470
  const provider = OAUTH_PROVIDERS[definitionId];
2351
2471
  if (!provider?.mcpUrl)
@@ -4328,7 +4448,7 @@ function buildMcpJson(input) {
4328
4448
  mcpServers[integration.definition_id] = proxyEntry;
4329
4449
  continue;
4330
4450
  }
4331
- const entry = buildRemoteMcpEntry(integration.definition_id);
4451
+ const entry = buildRemoteMcpEntry(integration.definition_id, integration.remoteMcp);
4332
4452
  if (entry) {
4333
4453
  mcpServers[integration.definition_id] = entry;
4334
4454
  }
@@ -4395,6 +4515,20 @@ function buildMcpJson(input) {
4395
4515
  }
4396
4516
  };
4397
4517
  }
4518
+ const hasSupport = input.integrations?.some((i) => i.definition_id === "augmented-support") ?? false;
4519
+ if (hasSupport) {
4520
+ const localSupportMcpPath = join2(getHomeDir(), ".augmented", "_mcp", "augmented-support.js");
4521
+ mcpServers["augmented-support"] = {
4522
+ command: "node",
4523
+ args: [localSupportMcpPath],
4524
+ env: {
4525
+ AGT_HOST: "${AGT_HOST}",
4526
+ AGT_AGENT_ID: input.agent.agent_id,
4527
+ AGT_RUN_ID: "${AGT_RUN_ID}",
4528
+ AGT_API_KEY: "${AGT_API_KEY}"
4529
+ }
4530
+ };
4531
+ }
4398
4532
  return { mcpServers };
4399
4533
  }
4400
4534
  function parseIntervalMinutes(scheduleEvery) {
@@ -5372,8 +5506,7 @@ ${sections}`
5372
5506
  }
5373
5507
  }
5374
5508
  for (const integration of decryptedIntegrations) {
5375
- const def = INTEGRATION_REGISTRY.find((d) => d.id === integration.definition_id);
5376
- const defaults = def?.remoteMcp?.envDefaults;
5509
+ const defaults = integration.remoteMcp?.envDefaults ?? INTEGRATION_REGISTRY.find((d) => d.id === integration.definition_id)?.remoteMcp?.envDefaults;
5377
5510
  if (!defaults)
5378
5511
  continue;
5379
5512
  for (const [key, value] of Object.entries(defaults)) {
@@ -5437,7 +5570,7 @@ ${sections}`
5437
5570
  this.writeMcpServer(codeName, integration.definition_id, proxyEntry);
5438
5571
  continue;
5439
5572
  }
5440
- const entry = buildRemoteMcpEntry(integration.definition_id);
5573
+ const entry = buildRemoteMcpEntry(integration.definition_id, integration.remoteMcp);
5441
5574
  if (entry) {
5442
5575
  this.writeMcpServer(codeName, integration.definition_id, entry);
5443
5576
  }
@@ -5515,6 +5648,20 @@ ${sections}`
5515
5648
  }
5516
5649
  });
5517
5650
  }
5651
+ const hasSupport = integrations.some((i) => i.definition_id === "augmented-support");
5652
+ if (hasSupport) {
5653
+ const localSupportMcpPath = join2(getHomeDir(), ".augmented", "_mcp", "augmented-support.js");
5654
+ this.writeMcpServer(codeName, "augmented-support", {
5655
+ command: "node",
5656
+ args: [localSupportMcpPath],
5657
+ env: {
5658
+ AGT_HOST: "${AGT_HOST}",
5659
+ AGT_AGENT_ID: resolveBrokerAgentId(codeName) ?? agentId ?? "",
5660
+ AGT_RUN_ID: "${AGT_RUN_ID}",
5661
+ AGT_API_KEY: "${AGT_API_KEY}"
5662
+ }
5663
+ });
5664
+ }
5518
5665
  if (this.removeMcpServer) {
5519
5666
  const nativeMcpKeys = INTEGRATION_REGISTRY.filter((d) => d.nativeMcp !== void 0).map((d) => d.nativeMcp.key ?? d.id);
5520
5667
  const integrationDerivedKeys = /* @__PURE__ */ new Set([
@@ -5523,6 +5670,7 @@ ${sections}`
5523
5670
  "cloud-broker",
5524
5671
  "xero-broker",
5525
5672
  "augmented-admin",
5673
+ "augmented-support",
5526
5674
  ...nativeMcpKeys,
5527
5675
  ...Object.entries(OAUTH_PROVIDERS).filter(([, provider]) => Boolean(provider.mcpUrl)).map(([id]) => id)
5528
5676
  ]);
@@ -5537,12 +5685,14 @@ ${sections}`
5537
5685
  expectedKeys.add("xero-broker");
5538
5686
  if (hasAdminDebug)
5539
5687
  expectedKeys.add("augmented-admin");
5688
+ if (hasSupport)
5689
+ expectedKeys.add("augmented-support");
5540
5690
  for (const integration of integrations) {
5541
5691
  const def = INTEGRATION_REGISTRY.find((d) => d.id === integration.definition_id);
5542
5692
  if (def?.nativeMcp) {
5543
5693
  expectedKeys.add(def.nativeMcp.key ?? integration.definition_id);
5544
5694
  }
5545
- if (buildRemoteMcpEntry(integration.definition_id)) {
5695
+ if (buildRemoteMcpEntry(integration.definition_id, integration.remoteMcp)) {
5546
5696
  expectedKeys.add(integration.definition_id);
5547
5697
  }
5548
5698
  }
@@ -5964,7 +6114,7 @@ function requireHost() {
5964
6114
  }
5965
6115
 
5966
6116
  // src/lib/api-client.ts
5967
- var agtCliVersion = true ? "0.28.176" : "dev";
6117
+ var agtCliVersion = true ? "0.28.178" : "dev";
5968
6118
  var lastConfigHash = null;
5969
6119
  function setConfigHash(hash) {
5970
6120
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -7269,4 +7419,4 @@ export {
7269
7419
  managerInstallSystemUnitCommand,
7270
7420
  managerUninstallSystemUnitCommand
7271
7421
  };
7272
- //# sourceMappingURL=chunk-YNCNFORO.js.map
7422
+ //# sourceMappingURL=chunk-MRY24Y4V.js.map