@integrity-labs/agt-cli 0.10.1 → 0.10.3

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.
@@ -215,6 +215,25 @@ var INTEGRATION_REGISTRY = [
215
215
  },
216
216
  docs_url: "https://github.com/Pika-Labs/Pika-Skills"
217
217
  },
218
+ {
219
+ id: "claude-code",
220
+ name: "Claude Code",
221
+ category: "code",
222
+ description: "Claude Code AI agent runtime \u2014 code editing, task execution, file management, and development workflows",
223
+ supported_auth_types: ["api_key", "none"],
224
+ capabilities: [
225
+ { id: "claude-code:edit-code", name: "Edit Code", description: "Read, write, and edit source files", access: "write" },
226
+ { id: "claude-code:run-tasks", name: "Run Tasks", description: "Execute bash commands and development tasks", access: "write" },
227
+ { id: "claude-code:search", name: "Search Code", description: "Search files and grep codebase", access: "read" },
228
+ { id: "claude-code:git", name: "Git Operations", description: "Commit, branch, push, and manage version control", access: "write" }
229
+ ],
230
+ cli_tool: {
231
+ package: "@anthropic-ai/claude-code",
232
+ binary: "claude",
233
+ env_key: "ANTHROPIC_API_KEY"
234
+ },
235
+ docs_url: "https://docs.anthropic.com/en/docs/claude-code"
236
+ },
218
237
  {
219
238
  id: "custom",
220
239
  name: "Custom Integration",
@@ -1333,6 +1352,38 @@ ${entry.content}`
1333
1352
  return changed;
1334
1353
  }, codeName);
1335
1354
  },
1355
+ executePluginHook(ctx) {
1356
+ const agentDir = join(AUGMENTED_DIR, ctx.codeName);
1357
+ const projectDir = join(agentDir, "project");
1358
+ mkdirSync(agentDir, { recursive: true });
1359
+ const startedAt = Date.now();
1360
+ return new Promise((resolve3) => {
1361
+ const child = execFile("bash", ["-c", ctx.script], {
1362
+ cwd: agentDir,
1363
+ timeout: 6e4,
1364
+ maxBuffer: 1024 * 1024,
1365
+ env: {
1366
+ ...process.env,
1367
+ AGENT_CODE_NAME: ctx.codeName,
1368
+ AGENT_DIR: agentDir,
1369
+ AGENT_PROJECT_DIR: projectDir,
1370
+ AGENT_FRAMEWORK: "openclaw"
1371
+ }
1372
+ }, (error, stdout, stderr) => {
1373
+ const durationMs = Date.now() - startedAt;
1374
+ const timedOut = !!error && error.code === "ETIMEDOUT";
1375
+ resolve3({
1376
+ exitCode: error ? typeof error.code === "number" ? error.code : 1 : 0,
1377
+ stdout: stdout?.toString() ?? "",
1378
+ stderr: stderr?.toString() ?? "",
1379
+ durationMs,
1380
+ timedOut
1381
+ });
1382
+ });
1383
+ child.on("error", () => {
1384
+ });
1385
+ });
1386
+ },
1336
1387
  readGatewayToken(codeName) {
1337
1388
  const homeDir = getHomeDir();
1338
1389
  try {
@@ -1808,9 +1859,10 @@ function extractAllowedDomains(input) {
1808
1859
  registerFramework(nemoClawAdapter);
1809
1860
 
1810
1861
  // ../../packages/core/dist/provisioning/frameworks/claudecode/index.js
1811
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync3, chmodSync as chmodSync3 } from "fs";
1862
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync3, chmodSync as chmodSync3, readdirSync, rmSync } from "fs";
1812
1863
  import { join as join3, relative } from "path";
1813
1864
  import { homedir as homedir2 } from "os";
1865
+ import { execFile as execFile3 } from "child_process";
1814
1866
 
1815
1867
  // ../../packages/core/dist/provisioning/frameworks/claudecode/identity.js
1816
1868
  function buildMemorySection(hasQmd) {
@@ -1879,7 +1931,7 @@ function buildKnowledgeSection2(knowledge) {
1879
1931
  return "";
1880
1932
  const orgEntries = knowledge.filter((k) => k.scope === "org");
1881
1933
  const teamEntries = knowledge.filter((k) => k.scope === "team");
1882
- const formatEntry = (k) => `- **${k.title}** (skill: \`knowledge-${k.slug}\`)`;
1934
+ const formatEntry = (k) => `- **${k.title}**`;
1883
1935
  let body = "";
1884
1936
  if (orgEntries.length) {
1885
1937
  body += `### Organization
@@ -1898,9 +1950,9 @@ ${teamEntries.map(formatEntry).join("\n")}
1898
1950
  }
1899
1951
  return `## Core Knowledge
1900
1952
 
1901
- Your team has provided the following core knowledge as skills. These are
1902
- automatically available \u2014 Claude Code will surface the relevant skill when
1903
- you need context. You do not need to read files manually.
1953
+ Your team has provided core knowledge via the \`core-knowledge\` skill.
1954
+ It is automatically available \u2014 Claude Code will surface it when you need
1955
+ context. You do not need to read files manually.
1904
1956
 
1905
1957
  ${body}
1906
1958
  `;
@@ -2106,6 +2158,32 @@ function deployArtifactsToProject(codeName, provisionDir) {
2106
2158
  } catch {
2107
2159
  }
2108
2160
  }
2161
+ const skillsDir = join3(provisionDir, ".claude", "skills");
2162
+ const destSkillsDir = join3(projectDir, ".claude", "skills");
2163
+ try {
2164
+ if (existsSync3(destSkillsDir)) {
2165
+ const srcFolders = existsSync3(skillsDir) ? new Set(readdirSync(skillsDir)) : /* @__PURE__ */ new Set();
2166
+ for (const folder of readdirSync(destSkillsDir)) {
2167
+ if (folder.startsWith("knowledge-") || folder === "core-knowledge" && !srcFolders.has(folder)) {
2168
+ try {
2169
+ rmSync(join3(destSkillsDir, folder), { recursive: true });
2170
+ } catch {
2171
+ }
2172
+ }
2173
+ }
2174
+ }
2175
+ if (existsSync3(skillsDir)) {
2176
+ for (const skillFolder of readdirSync(skillsDir)) {
2177
+ const srcSkillFile = join3(skillsDir, skillFolder, "SKILL.md");
2178
+ if (!existsSync3(srcSkillFile))
2179
+ continue;
2180
+ const destFolder = join3(destSkillsDir, skillFolder);
2181
+ mkdirSync3(destFolder, { recursive: true });
2182
+ writeFileSync3(join3(destFolder, "SKILL.md"), readFileSync3(srcSkillFile, "utf-8"));
2183
+ }
2184
+ }
2185
+ } catch {
2186
+ }
2109
2187
  const agentMcpPath = join3(getAgentDir(codeName), "provision", ".mcp.json");
2110
2188
  const projectMcpPath = join3(projectDir, ".mcp.json");
2111
2189
  try {
@@ -2190,6 +2268,88 @@ function provisionStopHook(codeName) {
2190
2268
  settings["hooks"] = hooks;
2191
2269
  writeFileSync3(settingsPath, JSON.stringify(settings, null, 2));
2192
2270
  }
2271
+ function provisionIsolationHook(codeName) {
2272
+ const projectDir = getProjectDir(codeName);
2273
+ const claudeDir = join3(projectDir, ".claude");
2274
+ mkdirSync3(claudeDir, { recursive: true });
2275
+ const homeDir = getHomeDir3();
2276
+ const augmentedBase = join3(homeDir, ".augmented");
2277
+ const ownAgentDir = join3(augmentedBase, codeName);
2278
+ const logFile = join3(ownAgentDir, "isolation.log");
2279
+ const hookScriptPath = join3(claudeDir, "agt-isolation-hook.sh");
2280
+ const hookScript = [
2281
+ "#!/bin/bash",
2282
+ "# Auto-generated by Augmented \u2014 prevents cross-agent file access.",
2283
+ "# Exit 0 = allow, Exit 2 = block (with stderr message shown to agent)",
2284
+ "set -euo pipefail",
2285
+ "INPUT=$(cat)",
2286
+ `TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty')`,
2287
+ "",
2288
+ "# Only check file-access tools",
2289
+ 'case "$TOOL" in',
2290
+ " Read|Edit|Write|Glob|Grep|MultiEdit) ;;",
2291
+ " Bash)",
2292
+ " # For Bash, we can't reliably parse arbitrary commands \u2014 rely on allowedDirectories.",
2293
+ " # But block obvious attempts to read other agent dirs.",
2294
+ ` CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty')`,
2295
+ ` if echo "$CMD" | grep -qE '${augmentedBase}/[^/]+/' 2>/dev/null; then`,
2296
+ ` MATCH=$(echo "$CMD" | grep -oE '${augmentedBase}/[^/]+' | head -1)`,
2297
+ ` AGENT_DIR=$(basename "$MATCH")`,
2298
+ ` if [ "$AGENT_DIR" != "${codeName}" ] && [ "$AGENT_DIR" != "_mcp" ]; then`,
2299
+ ` echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) BLOCKED bash targeting $MATCH" >> "${logFile}"`,
2300
+ ` echo "Access denied: you cannot access other agents' directories." >&2`,
2301
+ " exit 2",
2302
+ " fi",
2303
+ " fi",
2304
+ " exit 0 ;;",
2305
+ " *) exit 0 ;;",
2306
+ "esac",
2307
+ "",
2308
+ "# Extract file_path from tool input",
2309
+ `FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // empty')`,
2310
+ '[ -z "$FILE_PATH" ] && exit 0',
2311
+ "",
2312
+ "# Resolve to absolute path",
2313
+ 'if [[ "$FILE_PATH" != /* ]]; then',
2314
+ ` CWD=$(echo "$INPUT" | jq -r '.cwd // empty')`,
2315
+ ' [ -n "$CWD" ] && FILE_PATH="$CWD/$FILE_PATH"',
2316
+ "fi",
2317
+ "",
2318
+ "# Check if path targets another agent's directory",
2319
+ `AUGMENTED_BASE="${augmentedBase}"`,
2320
+ 'case "$FILE_PATH" in',
2321
+ ' "$AUGMENTED_BASE"/*/*) ',
2322
+ ' AGENT_DIR=$(echo "$FILE_PATH" | sed "s|$AUGMENTED_BASE/||" | cut -d/ -f1)',
2323
+ ` if [ "$AGENT_DIR" != "${codeName}" ] && [ "$AGENT_DIR" != "_mcp" ]; then`,
2324
+ ` echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) BLOCKED $TOOL on $FILE_PATH" >> "${logFile}"`,
2325
+ ` echo "Access denied: you cannot access other agents' directories." >&2`,
2326
+ " exit 2",
2327
+ " fi ;;",
2328
+ "esac",
2329
+ "",
2330
+ "exit 0"
2331
+ ].join("\n") + "\n";
2332
+ writeFileSync3(hookScriptPath, hookScript, { mode: 493 });
2333
+ const settingsPath = join3(claudeDir, "settings.local.json");
2334
+ let settings = {};
2335
+ try {
2336
+ settings = JSON.parse(readFileSync3(settingsPath, "utf-8"));
2337
+ } catch {
2338
+ }
2339
+ const hooks = settings["hooks"] ?? {};
2340
+ hooks["PreToolUse"] = [
2341
+ {
2342
+ hooks: [
2343
+ {
2344
+ type: "command",
2345
+ command: hookScriptPath
2346
+ }
2347
+ ]
2348
+ }
2349
+ ];
2350
+ settings["hooks"] = hooks;
2351
+ writeFileSync3(settingsPath, JSON.stringify(settings, null, 2));
2352
+ }
2193
2353
  function modifyJsonConfig(filePath, fn) {
2194
2354
  let originalContent;
2195
2355
  let config;
@@ -2225,6 +2385,19 @@ function buildSettingsJson(input) {
2225
2385
  if (agent.primary_model) {
2226
2386
  settings["model"] = agent.primary_model;
2227
2387
  }
2388
+ const projectDir = getProjectDir(agent.code_name);
2389
+ const agentDir = getAgentDir(agent.code_name);
2390
+ const homeDir = getHomeDir3();
2391
+ settings["allowedDirectories"] = [
2392
+ projectDir,
2393
+ // Agent's project dir (CLAUDE.md, settings.json, etc.)
2394
+ agentDir,
2395
+ // Agent's config dir (.env, schedules, registration)
2396
+ join3(homeDir, ".augmented", "_mcp"),
2397
+ // Shared MCP binaries
2398
+ "/tmp"
2399
+ // Temp files
2400
+ ];
2228
2401
  return settings;
2229
2402
  }
2230
2403
  function buildMcpJson(input) {
@@ -2327,20 +2500,28 @@ var claudeCodeAdapter = {
2327
2500
  { relativePath: "CHARTER.md", content: input.charterContent },
2328
2501
  { relativePath: "TOOLS.md", content: input.toolsContent }
2329
2502
  ];
2330
- for (const entry of input.knowledge ?? []) {
2331
- const skillPath = `.claude/skills/knowledge-${entry.slug}/SKILL.md`;
2332
- assertSafeRelativePath(skillPath);
2333
- const scopeLabel = entry.scope === "org" ? "organization" : "team";
2503
+ const knowledgeEntries = input.knowledge ?? [];
2504
+ if (knowledgeEntries.length > 0) {
2505
+ const safeTitles = knowledgeEntries.map((k) => k.title.replace(/[\n\r"\\]/g, " ").trim().toLowerCase()).filter(Boolean);
2506
+ const sections = knowledgeEntries.map((entry) => {
2507
+ const scopeLabel = entry.scope === "org" ? "Organization" : "Team";
2508
+ const safeTitle = entry.title.replace(/[\n\r]/g, " ").trim();
2509
+ return `## ${safeTitle}
2510
+ *${scopeLabel} knowledge*
2511
+
2512
+ ${entry.content}`;
2513
+ }).join("\n\n---\n\n");
2514
+ const description = `Use this skill when the user asks about the company, organization, team, products, or any of: ${safeTitles.join(", ")}. Provides core reference material from the knowledge base.`;
2334
2515
  artifacts.push({
2335
- relativePath: skillPath,
2516
+ relativePath: ".claude/skills/core-knowledge/SKILL.md",
2336
2517
  content: `---
2337
- name: knowledge-${entry.slug}
2338
- description: "${entry.title} \u2014 ${scopeLabel}-level core knowledge. Use when you need context about ${entry.title.toLowerCase()}."
2518
+ name: core-knowledge
2519
+ description: ${JSON.stringify(description)}
2339
2520
  ---
2340
2521
 
2341
- # ${entry.title}
2522
+ # Core Knowledge
2342
2523
 
2343
- ${entry.content}`
2524
+ ${sections}`
2344
2525
  });
2345
2526
  }
2346
2527
  return artifacts;
@@ -2356,8 +2537,8 @@ ${entry.content}`
2356
2537
  const augDir = join3(homeDir, ".augmented");
2357
2538
  const agents = /* @__PURE__ */ new Set();
2358
2539
  try {
2359
- const { readdirSync, statSync } = await import("fs");
2360
- const entries = readdirSync(augDir);
2540
+ const { readdirSync: readdirSync2, statSync } = await import("fs");
2541
+ const entries = readdirSync2(augDir);
2361
2542
  for (const entry of entries) {
2362
2543
  const ccDir = join3(augDir, entry, "claudecode");
2363
2544
  try {
@@ -2425,9 +2606,9 @@ ${entry.content}`
2425
2606
  // so ensureGatewayRunning() returns early with running=false
2426
2607
  async getVersion() {
2427
2608
  try {
2428
- const { execFile: execFile3 } = await import("child_process");
2609
+ const { execFile: execFile4 } = await import("child_process");
2429
2610
  return new Promise((resolve3) => {
2430
- execFile3("claude", ["--version"], { timeout: 5e3 }, (err, stdout) => {
2611
+ execFile4("claude", ["--version"], { timeout: 5e3 }, (err, stdout) => {
2431
2612
  if (err) {
2432
2613
  resolve3(null);
2433
2614
  return;
@@ -2675,6 +2856,23 @@ ${entry.content}`
2675
2856
  args: ["-y", "@composio/mcp", "start", "--url", config.url],
2676
2857
  env: config.headers ?? {}
2677
2858
  };
2859
+ } else if (config.url.includes("mcp.pipedream.net")) {
2860
+ const pdUrl = new URL(config.url);
2861
+ const pathParts = pdUrl.pathname.split("/").filter(Boolean);
2862
+ const externalUserId = decodeURIComponent(pathParts[0] ?? "");
2863
+ const appSlug = decodeURIComponent(pathParts[1] ?? "");
2864
+ const headers = config.headers ?? {};
2865
+ const authToken = (headers["Authorization"] ?? "").replace("Bearer ", "");
2866
+ serverEntry = {
2867
+ command: "npx",
2868
+ args: ["-y", "@pipedream/mcp", "stdio", "--app", appSlug, "--external-user-id", externalUserId],
2869
+ env: {
2870
+ PIPEDREAM_PROJECT_ID: headers["x-pd-project-id"] ?? process.env["PIPEDREAM_PROJECT_ID"] ?? "",
2871
+ PIPEDREAM_CLIENT_ID: headers["x-pd-client-id"] ?? process.env["PIPEDREAM_CLIENT_ID"] ?? "",
2872
+ PIPEDREAM_CLIENT_SECRET: headers["x-pd-client-secret"] ?? process.env["PIPEDREAM_CLIENT_SECRET"] ?? "",
2873
+ PIPEDREAM_PROJECT_ENVIRONMENT: headers["x-pd-environment"] ?? process.env["PIPEDREAM_ENVIRONMENT"] ?? "development"
2874
+ }
2875
+ };
2678
2876
  } else {
2679
2877
  serverEntry = {
2680
2878
  command: "npx",
@@ -2710,6 +2908,9 @@ ${entry.content}`
2710
2908
  },
2711
2909
  installSkillFiles(codeName, skillId, files) {
2712
2910
  assertValidCodeName(skillId);
2911
+ const isPluginManaged = skillId.startsWith("plugin-");
2912
+ const READ_ONLY_MODE = 292;
2913
+ const READ_WRITE_MODE = 420;
2713
2914
  const agentDir = getAgentDir(codeName);
2714
2915
  const projectDir = getProjectDir(codeName);
2715
2916
  for (const baseDir of [join3(agentDir, "skills"), join3(projectDir, ".claude", "skills")]) {
@@ -2723,7 +2924,19 @@ ${entry.content}`
2723
2924
  throw new Error(`Path traversal detected: ${file.relativePath} resolves outside ${skillDir}`);
2724
2925
  }
2725
2926
  mkdirSync3(join3(filePath, ".."), { recursive: true });
2927
+ if (isPluginManaged && existsSync3(filePath)) {
2928
+ try {
2929
+ chmodSync3(filePath, READ_WRITE_MODE);
2930
+ } catch {
2931
+ }
2932
+ }
2726
2933
  writeFileSync3(filePath, file.content);
2934
+ if (isPluginManaged) {
2935
+ try {
2936
+ chmodSync3(filePath, READ_ONLY_MODE);
2937
+ } catch {
2938
+ }
2939
+ }
2727
2940
  }
2728
2941
  }
2729
2942
  },
@@ -2748,6 +2961,40 @@ ${entry.content}`
2748
2961
  };
2749
2962
  writeFileSync3(pluginsJsonPath, JSON.stringify(pluginsConfig, null, 2));
2750
2963
  },
2964
+ executePluginHook(ctx) {
2965
+ assertValidCodeName(ctx.codeName);
2966
+ const agentRootDir = join3(getHomeDir3(), ".augmented", ctx.codeName);
2967
+ const projectDir = getProjectDir(ctx.codeName);
2968
+ mkdirSync3(agentRootDir, { recursive: true });
2969
+ mkdirSync3(projectDir, { recursive: true });
2970
+ const startedAt = Date.now();
2971
+ return new Promise((resolve3) => {
2972
+ const child = execFile3("bash", ["-c", ctx.script], {
2973
+ cwd: agentRootDir,
2974
+ timeout: 6e4,
2975
+ maxBuffer: 1024 * 1024,
2976
+ env: {
2977
+ ...process.env,
2978
+ AGENT_CODE_NAME: ctx.codeName,
2979
+ AGENT_DIR: agentRootDir,
2980
+ AGENT_PROJECT_DIR: projectDir,
2981
+ AGENT_FRAMEWORK: "claude-code"
2982
+ }
2983
+ }, (error, stdout, stderr) => {
2984
+ const durationMs = Date.now() - startedAt;
2985
+ const timedOut = !!error && error.code === "ETIMEDOUT";
2986
+ resolve3({
2987
+ exitCode: error ? typeof error.code === "number" ? error.code : 1 : 0,
2988
+ stdout: stdout?.toString() ?? "",
2989
+ stderr: stderr?.toString() ?? "",
2990
+ durationMs,
2991
+ timedOut
2992
+ });
2993
+ });
2994
+ child.on("error", () => {
2995
+ });
2996
+ });
2997
+ },
2751
2998
  writeTokenFile(codeName, integrations) {
2752
2999
  const agentDir = getAgentDir(codeName);
2753
3000
  mkdirSync3(agentDir, { recursive: true });
@@ -2773,6 +3020,250 @@ ${entry.content}`
2773
3020
  };
2774
3021
  registerFramework(claudeCodeAdapter);
2775
3022
 
3023
+ // ../../packages/core/dist/provisioning/frameworks/managed-agents/system-prompt.js
3024
+ function generateSystemPrompt(input) {
3025
+ const { agent, charterFrontmatter, charterContent, resolvedChannels, integrations } = input;
3026
+ const sections = [];
3027
+ sections.push(`# Agent Identity
3028
+
3029
+ **Name**: ${agent.display_name} (\`${agent.code_name}\`)
3030
+ **Environment**: ${agent.environment}
3031
+ **Risk Tier**: ${agent.risk_tier}
3032
+ **Owner**: ${charterFrontmatter.owner.name}${charterFrontmatter.owner.email ? ` <${charterFrontmatter.owner.email}>` : ""}
3033
+ **Augmented Agent ID**: ${agent.agent_id}`);
3034
+ const bodyContent = stripFrontmatter(charterContent).trim();
3035
+ if (bodyContent) {
3036
+ sections.push(bodyContent);
3037
+ }
3038
+ if (resolvedChannels.length > 0) {
3039
+ sections.push(`## Allowed Channels
3040
+
3041
+ This agent is permitted to communicate via the following channels:
3042
+ ${resolvedChannels.map((ch) => `- ${ch}`).join("\n")}`);
3043
+ }
3044
+ const budget = charterFrontmatter.budget;
3045
+ const limits = charterFrontmatter.limits;
3046
+ if (budget || limits) {
3047
+ const budgetLines = [];
3048
+ if (budget) {
3049
+ const window = budget.window;
3050
+ if (budget.type === "tokens" || budget.type === "both") {
3051
+ budgetLines.push(`- Token budget: ${(budget.limit_tokens ?? budget.limit).toLocaleString()} tokens per ${window}`);
3052
+ }
3053
+ if (budget.type === "dollars" || budget.type === "both") {
3054
+ budgetLines.push(`- Cost budget: $${(budget.limit_dollars ?? budget.limit).toFixed(2)} per ${window}`);
3055
+ }
3056
+ if (budget.enforcement) {
3057
+ budgetLines.push(`- Enforcement: ${budget.enforcement}`);
3058
+ }
3059
+ }
3060
+ if (limits) {
3061
+ budgetLines.push(`- Max tokens per request: ${limits.max_tokens_per_request.toLocaleString()}`);
3062
+ budgetLines.push(`- Max tokens per run: ${limits.max_tokens_per_run.toLocaleString()}`);
3063
+ }
3064
+ sections.push(`## Budget Constraints
3065
+
3066
+ ${budgetLines.join("\n")}`);
3067
+ }
3068
+ const apiKeyIntegrations = (integrations ?? []).filter((i) => i.auth_type === "api_key" && i.credentials.api_key);
3069
+ if (apiKeyIntegrations.length > 0) {
3070
+ const credLines = apiKeyIntegrations.map((i) => {
3071
+ const envKey = `${i.definition_id.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_API_KEY`;
3072
+ return `- **${i.display_name}**: API key available as \`${envKey}\``;
3073
+ });
3074
+ sections.push(`## Available Integrations (API Keys)
3075
+
3076
+ The following integration credentials are available for use in this session:
3077
+ ${credLines.join("\n")}
3078
+
3079
+ These credentials are pre-loaded. Reference them by their environment variable names when invoking tools.`);
3080
+ }
3081
+ return sections.join("\n\n");
3082
+ }
3083
+ function stripFrontmatter(content) {
3084
+ if (!content.startsWith("---"))
3085
+ return content;
3086
+ const secondDelimiter = content.indexOf("\n---", 3);
3087
+ if (secondDelimiter === -1)
3088
+ return content;
3089
+ return content.slice(secondDelimiter + 4);
3090
+ }
3091
+
3092
+ // ../../packages/core/dist/provisioning/frameworks/managed-agents/tools-mapper.js
3093
+ var TOOL_ID_TO_ANTHROPIC = [
3094
+ ["bash", "bash"],
3095
+ ["shell", "bash"],
3096
+ ["exec", "bash"],
3097
+ ["read", "read"],
3098
+ ["fs_read", "read"],
3099
+ ["file_read", "read"],
3100
+ ["write", "write"],
3101
+ ["fs_write", "write"],
3102
+ ["file_write", "write"],
3103
+ ["edit", "edit"],
3104
+ ["fs_edit", "edit"],
3105
+ ["file_edit", "edit"],
3106
+ ["glob", "glob"],
3107
+ ["fs_glob", "glob"],
3108
+ ["grep", "grep"],
3109
+ ["fs_grep", "grep"],
3110
+ ["web_fetch", "web_fetch"],
3111
+ ["fetch", "web_fetch"],
3112
+ ["http", "web_fetch"],
3113
+ ["web_search", "web_search"],
3114
+ ["search", "web_search"]
3115
+ ];
3116
+ function mapToolsToAgentToolset(toolsFrontmatter) {
3117
+ const enabledTools = /* @__PURE__ */ new Set();
3118
+ for (const tool of toolsFrontmatter.tools) {
3119
+ const id = tool.id.toLowerCase();
3120
+ for (const [prefix, anthropicTool] of TOOL_ID_TO_ANTHROPIC) {
3121
+ if (id === prefix || id.startsWith(`${prefix}_`) || id.startsWith(`${prefix}-`)) {
3122
+ enabledTools.add(anthropicTool);
3123
+ break;
3124
+ }
3125
+ }
3126
+ }
3127
+ const allTools = [
3128
+ "bash",
3129
+ "read",
3130
+ "write",
3131
+ "edit",
3132
+ "glob",
3133
+ "grep",
3134
+ "web_fetch",
3135
+ "web_search"
3136
+ ];
3137
+ return {
3138
+ type: "agent_toolset_20260401",
3139
+ default_config: { enabled: false },
3140
+ configs: allTools.map((name) => ({ name, enabled: enabledTools.has(name) }))
3141
+ };
3142
+ }
3143
+ function extractAllowedHosts(toolsFrontmatter) {
3144
+ const hosts = /* @__PURE__ */ new Set();
3145
+ for (const tool of toolsFrontmatter.tools) {
3146
+ for (const domain of tool.network?.allowlist_domains ?? []) {
3147
+ hosts.add(domain);
3148
+ }
3149
+ }
3150
+ return [...hosts];
3151
+ }
3152
+
3153
+ // ../../packages/core/dist/provisioning/frameworks/managed-agents/environment-config.js
3154
+ function buildEnvironmentConfig(riskTier, allowedHosts) {
3155
+ switch (riskTier) {
3156
+ case "Low":
3157
+ return {
3158
+ type: "cloud",
3159
+ networking: { type: "unrestricted" }
3160
+ };
3161
+ case "Medium":
3162
+ return {
3163
+ type: "cloud",
3164
+ networking: {
3165
+ type: "limited",
3166
+ allowed_hosts: allowedHosts,
3167
+ allow_mcp_servers: true,
3168
+ allow_package_managers: true
3169
+ }
3170
+ };
3171
+ case "High":
3172
+ return {
3173
+ type: "cloud",
3174
+ networking: {
3175
+ type: "limited",
3176
+ allowed_hosts: [],
3177
+ allow_mcp_servers: true,
3178
+ allow_package_managers: false
3179
+ }
3180
+ };
3181
+ }
3182
+ }
3183
+
3184
+ // ../../packages/core/dist/provisioning/frameworks/managed-agents/index.js
3185
+ function buildMcpServers(input) {
3186
+ const servers = [];
3187
+ for (const integration of input.integrations ?? []) {
3188
+ if (integration.auth_type !== "managed")
3189
+ continue;
3190
+ const config = integration.config;
3191
+ const mcpUrl = config["mcp_server_url"];
3192
+ if (!mcpUrl)
3193
+ continue;
3194
+ const connectedAccountId = integration.credentials["connected_account_id"];
3195
+ const apiKey = integration.credentials["api_key"];
3196
+ const headers = {};
3197
+ if (apiKey)
3198
+ headers["Authorization"] = `secret_ref://${integration.definition_id}/api_key`;
3199
+ if (connectedAccountId)
3200
+ headers["X-Connected-Account-Id"] = String(connectedAccountId);
3201
+ servers.push({
3202
+ type: "url",
3203
+ name: integration.definition_id.replace(/[^a-z0-9-]/gi, "-").toLowerCase(),
3204
+ url: mcpUrl,
3205
+ ...Object.keys(headers).length > 0 ? { headers } : {}
3206
+ });
3207
+ }
3208
+ return servers;
3209
+ }
3210
+ var ManagedAgentsAdapter = {
3211
+ id: "managed-agents",
3212
+ label: "Managed Agents (Anthropic Cloud)",
3213
+ buildArtifacts(input) {
3214
+ const { agent, toolsFrontmatter } = input;
3215
+ const toolset = mapToolsToAgentToolset(toolsFrontmatter);
3216
+ const allowedHosts = extractAllowedHosts(toolsFrontmatter);
3217
+ const environmentConfig = buildEnvironmentConfig(agent.risk_tier, allowedHosts);
3218
+ const mcpServers = buildMcpServers(input);
3219
+ const tools = [toolset];
3220
+ for (const server of mcpServers) {
3221
+ tools.push({ type: "mcp_toolset", mcp_server_name: server.name });
3222
+ }
3223
+ const config = {
3224
+ name: agent.display_name,
3225
+ model: agent.primary_model ?? "claude-sonnet-4-6",
3226
+ system: generateSystemPrompt(input),
3227
+ tools,
3228
+ mcp_servers: mcpServers,
3229
+ description: agent.description,
3230
+ metadata: {
3231
+ augmented_agent_id: agent.agent_id,
3232
+ augmented_code_name: agent.code_name,
3233
+ augmented_environment: agent.environment,
3234
+ augmented_risk_tier: agent.risk_tier,
3235
+ augmented_framework: "managed-agents"
3236
+ },
3237
+ _environment_config: environmentConfig
3238
+ };
3239
+ return [
3240
+ {
3241
+ relativePath: "managed-agent.json",
3242
+ content: JSON.stringify(config, null, 2)
3243
+ }
3244
+ ];
3245
+ },
3246
+ driftTrackedFiles() {
3247
+ return ["managed-agent.json"];
3248
+ },
3249
+ // -------------------------------------------------------------------------
3250
+ // No local runtime — all execution is in Anthropic's cloud.
3251
+ // These methods are intentional no-ops.
3252
+ // -------------------------------------------------------------------------
3253
+ async getRegisteredAgents() {
3254
+ return /* @__PURE__ */ new Set();
3255
+ },
3256
+ async registerAgent(_codeName, _teamDir) {
3257
+ return true;
3258
+ },
3259
+ async deregisterAgent(_codeName) {
3260
+ return true;
3261
+ },
3262
+ writeAuthProfiles(_codeName, _profiles) {
3263
+ }
3264
+ };
3265
+ registerFramework(ManagedAgentsAdapter);
3266
+
2776
3267
  // src/lib/config.ts
2777
3268
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync4 } from "fs";
2778
3269
  import { join as join4 } from "path";
@@ -2888,6 +3379,11 @@ async function doExchange(rawKey, retried) {
2888
3379
  if (!res.ok) {
2889
3380
  const body = await res.json().catch(() => ({}));
2890
3381
  const errorMsg = String(body["error"] ?? res.statusText);
3382
+ const host = requireHost();
3383
+ const obfuscated = rawKey.length > 12 ? `${rawKey.slice(0, 8)}${"*".repeat(rawKey.length - 12)}${rawKey.slice(-4)}` : rawKey.slice(0, 4) + "****";
3384
+ if (res.status >= 502 && res.status <= 504) {
3385
+ throw new Error(`API unreachable (${res.status}): ${host} \u2014 is the API server running?`);
3386
+ }
2891
3387
  if (errorMsg.includes("revoked") && !retried) {
2892
3388
  reloadFromShellProfile();
2893
3389
  const freshKey = getApiKey();
@@ -2895,8 +3391,6 @@ async function doExchange(rawKey, retried) {
2895
3391
  return doExchange(freshKey, true);
2896
3392
  }
2897
3393
  }
2898
- const host = requireHost();
2899
- const obfuscated = rawKey.length > 12 ? `${rawKey.slice(0, 8)}${"*".repeat(rawKey.length - 12)}${rawKey.slice(-4)}` : rawKey.slice(0, 4) + "****";
2900
3394
  throw new Error(`API key exchange failed: ${errorMsg} (host=${host}, key=${obfuscated})`);
2901
3395
  }
2902
3396
  const data = await res.json();
@@ -4546,7 +5040,12 @@ var ROLE_PERMISSIONS = {
4546
5040
  "audit_log.view",
4547
5041
  "host.create",
4548
5042
  "host.manage",
4549
- "host.view"
5043
+ "host.view",
5044
+ "plugin.view",
5045
+ "plugin.install",
5046
+ "plugin.configure",
5047
+ "plugin.manage_scopes",
5048
+ "plugin.approve_requests"
4550
5049
  ],
4551
5050
  admin: [
4552
5051
  "team.manage_members",
@@ -4560,7 +5059,12 @@ var ROLE_PERMISSIONS = {
4560
5059
  "audit_log.view",
4561
5060
  "host.create",
4562
5061
  "host.manage",
4563
- "host.view"
5062
+ "host.view",
5063
+ "plugin.view",
5064
+ "plugin.install",
5065
+ "plugin.configure",
5066
+ "plugin.manage_scopes",
5067
+ "plugin.approve_requests"
4564
5068
  ],
4565
5069
  member: [
4566
5070
  "agent.create",
@@ -4568,12 +5072,17 @@ var ROLE_PERMISSIONS = {
4568
5072
  "agent.deploy",
4569
5073
  "agent.view",
4570
5074
  "audit_log.view",
4571
- "host.view"
5075
+ "host.view",
5076
+ "plugin.view",
5077
+ "plugin.install",
5078
+ "plugin.configure",
5079
+ "plugin.manage_scopes"
4572
5080
  ],
4573
5081
  viewer: [
4574
5082
  "agent.view",
4575
5083
  "audit_log.view",
4576
- "host.view"
5084
+ "host.view",
5085
+ "plugin.view"
4577
5086
  ]
4578
5087
  };
4579
5088
  var permissionSets = new Map(Object.entries(ROLE_PERMISSIONS).map(([role, actions]) => [role, new Set(actions)]));
@@ -4680,6 +5189,129 @@ function getTemplate(id) {
4680
5189
  return DEPLOYMENT_TEMPLATES.find((t) => t.id === id);
4681
5190
  }
4682
5191
 
5192
+ // ../../packages/core/dist/plugins/context-validator.js
5193
+ import Ajv20202 from "ajv/dist/2020.js";
5194
+ import addFormats2 from "ajv-formats";
5195
+
5196
+ // ../../packages/core/dist/plugins/context-meta-schema.json
5197
+ var context_meta_schema_default = {
5198
+ $schema: "https://json-schema.org/draft/2020-12/schema",
5199
+ $id: "https://augmented.dev/schemas/plugin-context.meta.schema.json",
5200
+ title: "Plugin Context Schema (meta)",
5201
+ description: "Meta-schema for the constrained subset of JSON Schema that plugin authors may declare for their plugin context. Anything outside this subset is rejected at PUT time. See ENG-4341 / docs/plugins/plugin-context-rfc.md.",
5202
+ type: "object",
5203
+ required: ["type", "properties"],
5204
+ additionalProperties: false,
5205
+ properties: {
5206
+ $schema: {
5207
+ type: "string"
5208
+ },
5209
+ type: {
5210
+ type: "string",
5211
+ const: "object"
5212
+ },
5213
+ properties: {
5214
+ type: "object",
5215
+ minProperties: 0,
5216
+ additionalProperties: {
5217
+ $ref: "#/$defs/field"
5218
+ }
5219
+ },
5220
+ required: {
5221
+ type: "array",
5222
+ items: { type: "string" },
5223
+ uniqueItems: true
5224
+ }
5225
+ },
5226
+ $defs: {
5227
+ field: {
5228
+ oneOf: [
5229
+ { $ref: "#/$defs/stringField" },
5230
+ { $ref: "#/$defs/booleanField" },
5231
+ { $ref: "#/$defs/stringArrayField" },
5232
+ { $ref: "#/$defs/stringMapField" }
5233
+ ]
5234
+ },
5235
+ stringField: {
5236
+ type: "object",
5237
+ required: ["type"],
5238
+ additionalProperties: false,
5239
+ properties: {
5240
+ type: { const: "string" },
5241
+ title: { type: "string" },
5242
+ description: { type: "string" },
5243
+ enum: {
5244
+ type: "array",
5245
+ items: { type: "string" },
5246
+ minItems: 1,
5247
+ uniqueItems: true
5248
+ },
5249
+ default: { type: "string" }
5250
+ }
5251
+ },
5252
+ booleanField: {
5253
+ type: "object",
5254
+ required: ["type"],
5255
+ additionalProperties: false,
5256
+ properties: {
5257
+ type: { const: "boolean" },
5258
+ title: { type: "string" },
5259
+ description: { type: "string" },
5260
+ default: { type: "boolean" }
5261
+ }
5262
+ },
5263
+ stringArrayField: {
5264
+ type: "object",
5265
+ required: ["type", "items"],
5266
+ additionalProperties: false,
5267
+ properties: {
5268
+ type: { const: "array" },
5269
+ items: {
5270
+ type: "object",
5271
+ required: ["type"],
5272
+ additionalProperties: false,
5273
+ properties: {
5274
+ type: { const: "string" }
5275
+ }
5276
+ },
5277
+ title: { type: "string" },
5278
+ description: { type: "string" },
5279
+ default: {
5280
+ type: "array",
5281
+ items: { type: "string" }
5282
+ }
5283
+ }
5284
+ },
5285
+ stringMapField: {
5286
+ type: "object",
5287
+ required: ["type", "additionalProperties"],
5288
+ additionalProperties: false,
5289
+ properties: {
5290
+ type: { const: "object" },
5291
+ additionalProperties: {
5292
+ type: "object",
5293
+ required: ["type"],
5294
+ additionalProperties: false,
5295
+ properties: {
5296
+ type: { const: "string" }
5297
+ }
5298
+ },
5299
+ title: { type: "string" },
5300
+ description: { type: "string" },
5301
+ default: {
5302
+ type: "object",
5303
+ additionalProperties: { type: "string" }
5304
+ }
5305
+ }
5306
+ }
5307
+ }
5308
+ };
5309
+
5310
+ // ../../packages/core/dist/plugins/context-validator.js
5311
+ var ajv2 = new Ajv20202({ allErrors: true, strict: false });
5312
+ addFormats2(ajv2);
5313
+ var compiledMetaSchema = ajv2.compile(context_meta_schema_default);
5314
+
4683
5315
  // ../../packages/core/dist/drift/comparators.js
4684
5316
  function compareToolPolicy(expected, actual) {
4685
5317
  const findings = [];
@@ -4876,6 +5508,7 @@ export {
4876
5508
  getChannel,
4877
5509
  getAllChannelIds,
4878
5510
  provisionStopHook,
5511
+ provisionIsolationHook,
4879
5512
  getApiKey,
4880
5513
  getActiveTeam,
4881
5514
  setActiveTeam,
@@ -4906,4 +5539,4 @@ export {
4906
5539
  detectDrift,
4907
5540
  provision
4908
5541
  };
4909
- //# sourceMappingURL=chunk-N7TRKQMT.js.map
5542
+ //# sourceMappingURL=chunk-6YGOQRAR.js.map