@integrity-labs/agt-cli 0.10.2 → 0.10.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.
@@ -1859,7 +1859,7 @@ function extractAllowedDomains(input) {
1859
1859
  registerFramework(nemoClawAdapter);
1860
1860
 
1861
1861
  // ../../packages/core/dist/provisioning/frameworks/claudecode/index.js
1862
- 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";
1863
1863
  import { join as join3, relative } from "path";
1864
1864
  import { homedir as homedir2 } from "os";
1865
1865
  import { execFile as execFile3 } from "child_process";
@@ -1931,7 +1931,7 @@ function buildKnowledgeSection2(knowledge) {
1931
1931
  return "";
1932
1932
  const orgEntries = knowledge.filter((k) => k.scope === "org");
1933
1933
  const teamEntries = knowledge.filter((k) => k.scope === "team");
1934
- const formatEntry = (k) => `- **${k.title}** (skill: \`knowledge-${k.slug}\`)`;
1934
+ const formatEntry = (k) => `- **${k.title}**`;
1935
1935
  let body = "";
1936
1936
  if (orgEntries.length) {
1937
1937
  body += `### Organization
@@ -1950,9 +1950,9 @@ ${teamEntries.map(formatEntry).join("\n")}
1950
1950
  }
1951
1951
  return `## Core Knowledge
1952
1952
 
1953
- Your team has provided the following core knowledge as skills. These are
1954
- automatically available \u2014 Claude Code will surface the relevant skill when
1955
- 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.
1956
1956
 
1957
1957
  ${body}
1958
1958
  `;
@@ -2149,15 +2149,61 @@ function deployArtifactsToProject(codeName, provisionDir) {
2149
2149
  const projectDir = getProjectDir(codeName);
2150
2150
  mkdirSync3(projectDir, { recursive: true });
2151
2151
  const artifactFiles = ["CLAUDE.md", "settings.json", ".mcp.json", "CHARTER.md", "TOOLS.md"];
2152
+ const SKILLS_START = "<!-- AGT:SKILLS_INDEX_START -->";
2153
+ const SKILLS_END = "<!-- AGT:SKILLS_INDEX_END -->";
2152
2154
  for (const file of artifactFiles) {
2153
2155
  const src = join3(provisionDir, file);
2154
2156
  const dest = join3(projectDir, file);
2155
2157
  try {
2156
- const content = readFileSync3(src, "utf-8");
2157
- writeFileSync3(dest, content);
2158
+ const srcContent = readFileSync3(src, "utf-8");
2159
+ if (file === "CLAUDE.md" && existsSync3(dest)) {
2160
+ const destContent = readFileSync3(dest, "utf-8");
2161
+ const stripIndex = (s) => s.replace(new RegExp(`${SKILLS_START}[\\s\\S]*?${SKILLS_END}`), "").trimEnd();
2162
+ if (stripIndex(srcContent) === stripIndex(destContent))
2163
+ continue;
2164
+ const indexMatch = destContent.match(new RegExp(`${SKILLS_START}[\\s\\S]*?${SKILLS_END}`));
2165
+ if (indexMatch) {
2166
+ writeFileSync3(dest, srcContent.trimEnd() + "\n\n" + indexMatch[0] + "\n");
2167
+ continue;
2168
+ }
2169
+ }
2170
+ writeFileSync3(dest, srcContent);
2158
2171
  } catch {
2159
2172
  }
2160
2173
  }
2174
+ const skillsDir = join3(provisionDir, ".claude", "skills");
2175
+ const destSkillsDir = join3(projectDir, ".claude", "skills");
2176
+ try {
2177
+ if (existsSync3(destSkillsDir)) {
2178
+ const srcFolders = existsSync3(skillsDir) ? new Set(readdirSync(skillsDir)) : /* @__PURE__ */ new Set();
2179
+ for (const folder of readdirSync(destSkillsDir)) {
2180
+ if (folder.startsWith("knowledge-") || folder === "core-knowledge" && !srcFolders.has(folder)) {
2181
+ try {
2182
+ rmSync(join3(destSkillsDir, folder), { recursive: true });
2183
+ } catch {
2184
+ }
2185
+ }
2186
+ }
2187
+ }
2188
+ if (existsSync3(skillsDir)) {
2189
+ for (const skillFolder of readdirSync(skillsDir)) {
2190
+ const srcSkillFile = join3(skillsDir, skillFolder, "SKILL.md");
2191
+ if (!existsSync3(srcSkillFile))
2192
+ continue;
2193
+ const destFolder = join3(destSkillsDir, skillFolder);
2194
+ const destFile = join3(destFolder, "SKILL.md");
2195
+ const srcContent = readFileSync3(srcSkillFile, "utf-8");
2196
+ try {
2197
+ if (existsSync3(destFile) && readFileSync3(destFile, "utf-8") === srcContent)
2198
+ continue;
2199
+ } catch {
2200
+ }
2201
+ mkdirSync3(destFolder, { recursive: true });
2202
+ writeFileSync3(destFile, srcContent);
2203
+ }
2204
+ }
2205
+ } catch {
2206
+ }
2161
2207
  const agentMcpPath = join3(getAgentDir(codeName), "provision", ".mcp.json");
2162
2208
  const projectMcpPath = join3(projectDir, ".mcp.json");
2163
2209
  try {
@@ -2474,20 +2520,28 @@ var claudeCodeAdapter = {
2474
2520
  { relativePath: "CHARTER.md", content: input.charterContent },
2475
2521
  { relativePath: "TOOLS.md", content: input.toolsContent }
2476
2522
  ];
2477
- for (const entry of input.knowledge ?? []) {
2478
- const skillPath = `.claude/skills/knowledge-${entry.slug}/SKILL.md`;
2479
- assertSafeRelativePath(skillPath);
2480
- const scopeLabel = entry.scope === "org" ? "organization" : "team";
2523
+ const knowledgeEntries = input.knowledge ?? [];
2524
+ if (knowledgeEntries.length > 0) {
2525
+ const safeTitles = knowledgeEntries.map((k) => k.title.replace(/[\n\r"\\]/g, " ").trim().toLowerCase()).filter(Boolean);
2526
+ const sections = knowledgeEntries.map((entry) => {
2527
+ const scopeLabel = entry.scope === "org" ? "Organization" : "Team";
2528
+ const safeTitle = entry.title.replace(/[\n\r]/g, " ").trim();
2529
+ return `## ${safeTitle}
2530
+ *${scopeLabel} knowledge*
2531
+
2532
+ ${entry.content}`;
2533
+ }).join("\n\n---\n\n");
2534
+ 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.`;
2481
2535
  artifacts.push({
2482
- relativePath: skillPath,
2536
+ relativePath: ".claude/skills/core-knowledge/SKILL.md",
2483
2537
  content: `---
2484
- name: knowledge-${entry.slug}
2485
- description: "${entry.title} \u2014 ${scopeLabel}-level core knowledge. Use when you need context about ${entry.title.toLowerCase()}."
2538
+ name: core-knowledge
2539
+ description: ${JSON.stringify(description)}
2486
2540
  ---
2487
2541
 
2488
- # ${entry.title}
2542
+ # Core Knowledge
2489
2543
 
2490
- ${entry.content}`
2544
+ ${sections}`
2491
2545
  });
2492
2546
  }
2493
2547
  return artifacts;
@@ -2503,8 +2557,8 @@ ${entry.content}`
2503
2557
  const augDir = join3(homeDir, ".augmented");
2504
2558
  const agents = /* @__PURE__ */ new Set();
2505
2559
  try {
2506
- const { readdirSync, statSync } = await import("fs");
2507
- const entries = readdirSync(augDir);
2560
+ const { readdirSync: readdirSync2, statSync } = await import("fs");
2561
+ const entries = readdirSync2(augDir);
2508
2562
  for (const entry of entries) {
2509
2563
  const ccDir = join3(augDir, entry, "claudecode");
2510
2564
  try {
@@ -2874,6 +2928,9 @@ ${entry.content}`
2874
2928
  },
2875
2929
  installSkillFiles(codeName, skillId, files) {
2876
2930
  assertValidCodeName(skillId);
2931
+ const isPluginManaged = skillId.startsWith("plugin-");
2932
+ const READ_ONLY_MODE = 292;
2933
+ const READ_WRITE_MODE = 420;
2877
2934
  const agentDir = getAgentDir(codeName);
2878
2935
  const projectDir = getProjectDir(codeName);
2879
2936
  for (const baseDir of [join3(agentDir, "skills"), join3(projectDir, ".claude", "skills")]) {
@@ -2887,7 +2944,19 @@ ${entry.content}`
2887
2944
  throw new Error(`Path traversal detected: ${file.relativePath} resolves outside ${skillDir}`);
2888
2945
  }
2889
2946
  mkdirSync3(join3(filePath, ".."), { recursive: true });
2947
+ if (isPluginManaged && existsSync3(filePath)) {
2948
+ try {
2949
+ chmodSync3(filePath, READ_WRITE_MODE);
2950
+ } catch {
2951
+ }
2952
+ }
2890
2953
  writeFileSync3(filePath, file.content);
2954
+ if (isPluginManaged) {
2955
+ try {
2956
+ chmodSync3(filePath, READ_ONLY_MODE);
2957
+ } catch {
2958
+ }
2959
+ }
2891
2960
  }
2892
2961
  }
2893
2962
  },
@@ -2971,6 +3040,250 @@ ${entry.content}`
2971
3040
  };
2972
3041
  registerFramework(claudeCodeAdapter);
2973
3042
 
3043
+ // ../../packages/core/dist/provisioning/frameworks/managed-agents/system-prompt.js
3044
+ function generateSystemPrompt(input) {
3045
+ const { agent, charterFrontmatter, charterContent, resolvedChannels, integrations } = input;
3046
+ const sections = [];
3047
+ sections.push(`# Agent Identity
3048
+
3049
+ **Name**: ${agent.display_name} (\`${agent.code_name}\`)
3050
+ **Environment**: ${agent.environment}
3051
+ **Risk Tier**: ${agent.risk_tier}
3052
+ **Owner**: ${charterFrontmatter.owner.name}${charterFrontmatter.owner.email ? ` <${charterFrontmatter.owner.email}>` : ""}
3053
+ **Augmented Agent ID**: ${agent.agent_id}`);
3054
+ const bodyContent = stripFrontmatter(charterContent).trim();
3055
+ if (bodyContent) {
3056
+ sections.push(bodyContent);
3057
+ }
3058
+ if (resolvedChannels.length > 0) {
3059
+ sections.push(`## Allowed Channels
3060
+
3061
+ This agent is permitted to communicate via the following channels:
3062
+ ${resolvedChannels.map((ch) => `- ${ch}`).join("\n")}`);
3063
+ }
3064
+ const budget = charterFrontmatter.budget;
3065
+ const limits = charterFrontmatter.limits;
3066
+ if (budget || limits) {
3067
+ const budgetLines = [];
3068
+ if (budget) {
3069
+ const window = budget.window;
3070
+ if (budget.type === "tokens" || budget.type === "both") {
3071
+ budgetLines.push(`- Token budget: ${(budget.limit_tokens ?? budget.limit).toLocaleString()} tokens per ${window}`);
3072
+ }
3073
+ if (budget.type === "dollars" || budget.type === "both") {
3074
+ budgetLines.push(`- Cost budget: $${(budget.limit_dollars ?? budget.limit).toFixed(2)} per ${window}`);
3075
+ }
3076
+ if (budget.enforcement) {
3077
+ budgetLines.push(`- Enforcement: ${budget.enforcement}`);
3078
+ }
3079
+ }
3080
+ if (limits) {
3081
+ budgetLines.push(`- Max tokens per request: ${limits.max_tokens_per_request.toLocaleString()}`);
3082
+ budgetLines.push(`- Max tokens per run: ${limits.max_tokens_per_run.toLocaleString()}`);
3083
+ }
3084
+ sections.push(`## Budget Constraints
3085
+
3086
+ ${budgetLines.join("\n")}`);
3087
+ }
3088
+ const apiKeyIntegrations = (integrations ?? []).filter((i) => i.auth_type === "api_key" && i.credentials.api_key);
3089
+ if (apiKeyIntegrations.length > 0) {
3090
+ const credLines = apiKeyIntegrations.map((i) => {
3091
+ const envKey = `${i.definition_id.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_API_KEY`;
3092
+ return `- **${i.display_name}**: API key available as \`${envKey}\``;
3093
+ });
3094
+ sections.push(`## Available Integrations (API Keys)
3095
+
3096
+ The following integration credentials are available for use in this session:
3097
+ ${credLines.join("\n")}
3098
+
3099
+ These credentials are pre-loaded. Reference them by their environment variable names when invoking tools.`);
3100
+ }
3101
+ return sections.join("\n\n");
3102
+ }
3103
+ function stripFrontmatter(content) {
3104
+ if (!content.startsWith("---"))
3105
+ return content;
3106
+ const secondDelimiter = content.indexOf("\n---", 3);
3107
+ if (secondDelimiter === -1)
3108
+ return content;
3109
+ return content.slice(secondDelimiter + 4);
3110
+ }
3111
+
3112
+ // ../../packages/core/dist/provisioning/frameworks/managed-agents/tools-mapper.js
3113
+ var TOOL_ID_TO_ANTHROPIC = [
3114
+ ["bash", "bash"],
3115
+ ["shell", "bash"],
3116
+ ["exec", "bash"],
3117
+ ["read", "read"],
3118
+ ["fs_read", "read"],
3119
+ ["file_read", "read"],
3120
+ ["write", "write"],
3121
+ ["fs_write", "write"],
3122
+ ["file_write", "write"],
3123
+ ["edit", "edit"],
3124
+ ["fs_edit", "edit"],
3125
+ ["file_edit", "edit"],
3126
+ ["glob", "glob"],
3127
+ ["fs_glob", "glob"],
3128
+ ["grep", "grep"],
3129
+ ["fs_grep", "grep"],
3130
+ ["web_fetch", "web_fetch"],
3131
+ ["fetch", "web_fetch"],
3132
+ ["http", "web_fetch"],
3133
+ ["web_search", "web_search"],
3134
+ ["search", "web_search"]
3135
+ ];
3136
+ function mapToolsToAgentToolset(toolsFrontmatter) {
3137
+ const enabledTools = /* @__PURE__ */ new Set();
3138
+ for (const tool of toolsFrontmatter.tools) {
3139
+ const id = tool.id.toLowerCase();
3140
+ for (const [prefix, anthropicTool] of TOOL_ID_TO_ANTHROPIC) {
3141
+ if (id === prefix || id.startsWith(`${prefix}_`) || id.startsWith(`${prefix}-`)) {
3142
+ enabledTools.add(anthropicTool);
3143
+ break;
3144
+ }
3145
+ }
3146
+ }
3147
+ const allTools = [
3148
+ "bash",
3149
+ "read",
3150
+ "write",
3151
+ "edit",
3152
+ "glob",
3153
+ "grep",
3154
+ "web_fetch",
3155
+ "web_search"
3156
+ ];
3157
+ return {
3158
+ type: "agent_toolset_20260401",
3159
+ default_config: { enabled: false },
3160
+ configs: allTools.map((name) => ({ name, enabled: enabledTools.has(name) }))
3161
+ };
3162
+ }
3163
+ function extractAllowedHosts(toolsFrontmatter) {
3164
+ const hosts = /* @__PURE__ */ new Set();
3165
+ for (const tool of toolsFrontmatter.tools) {
3166
+ for (const domain of tool.network?.allowlist_domains ?? []) {
3167
+ hosts.add(domain);
3168
+ }
3169
+ }
3170
+ return [...hosts];
3171
+ }
3172
+
3173
+ // ../../packages/core/dist/provisioning/frameworks/managed-agents/environment-config.js
3174
+ function buildEnvironmentConfig(riskTier, allowedHosts) {
3175
+ switch (riskTier) {
3176
+ case "Low":
3177
+ return {
3178
+ type: "cloud",
3179
+ networking: { type: "unrestricted" }
3180
+ };
3181
+ case "Medium":
3182
+ return {
3183
+ type: "cloud",
3184
+ networking: {
3185
+ type: "limited",
3186
+ allowed_hosts: allowedHosts,
3187
+ allow_mcp_servers: true,
3188
+ allow_package_managers: true
3189
+ }
3190
+ };
3191
+ case "High":
3192
+ return {
3193
+ type: "cloud",
3194
+ networking: {
3195
+ type: "limited",
3196
+ allowed_hosts: [],
3197
+ allow_mcp_servers: true,
3198
+ allow_package_managers: false
3199
+ }
3200
+ };
3201
+ }
3202
+ }
3203
+
3204
+ // ../../packages/core/dist/provisioning/frameworks/managed-agents/index.js
3205
+ function buildMcpServers(input) {
3206
+ const servers = [];
3207
+ for (const integration of input.integrations ?? []) {
3208
+ if (integration.auth_type !== "managed")
3209
+ continue;
3210
+ const config = integration.config;
3211
+ const mcpUrl = config["mcp_server_url"];
3212
+ if (!mcpUrl)
3213
+ continue;
3214
+ const connectedAccountId = integration.credentials["connected_account_id"];
3215
+ const apiKey = integration.credentials["api_key"];
3216
+ const headers = {};
3217
+ if (apiKey)
3218
+ headers["Authorization"] = `secret_ref://${integration.definition_id}/api_key`;
3219
+ if (connectedAccountId)
3220
+ headers["X-Connected-Account-Id"] = String(connectedAccountId);
3221
+ servers.push({
3222
+ type: "url",
3223
+ name: integration.definition_id.replace(/[^a-z0-9-]/gi, "-").toLowerCase(),
3224
+ url: mcpUrl,
3225
+ ...Object.keys(headers).length > 0 ? { headers } : {}
3226
+ });
3227
+ }
3228
+ return servers;
3229
+ }
3230
+ var ManagedAgentsAdapter = {
3231
+ id: "managed-agents",
3232
+ label: "Managed Agents (Anthropic Cloud)",
3233
+ buildArtifacts(input) {
3234
+ const { agent, toolsFrontmatter } = input;
3235
+ const toolset = mapToolsToAgentToolset(toolsFrontmatter);
3236
+ const allowedHosts = extractAllowedHosts(toolsFrontmatter);
3237
+ const environmentConfig = buildEnvironmentConfig(agent.risk_tier, allowedHosts);
3238
+ const mcpServers = buildMcpServers(input);
3239
+ const tools = [toolset];
3240
+ for (const server of mcpServers) {
3241
+ tools.push({ type: "mcp_toolset", mcp_server_name: server.name });
3242
+ }
3243
+ const config = {
3244
+ name: agent.display_name,
3245
+ model: agent.primary_model ?? "claude-sonnet-4-6",
3246
+ system: generateSystemPrompt(input),
3247
+ tools,
3248
+ mcp_servers: mcpServers,
3249
+ description: agent.description,
3250
+ metadata: {
3251
+ augmented_agent_id: agent.agent_id,
3252
+ augmented_code_name: agent.code_name,
3253
+ augmented_environment: agent.environment,
3254
+ augmented_risk_tier: agent.risk_tier,
3255
+ augmented_framework: "managed-agents"
3256
+ },
3257
+ _environment_config: environmentConfig
3258
+ };
3259
+ return [
3260
+ {
3261
+ relativePath: "managed-agent.json",
3262
+ content: JSON.stringify(config, null, 2)
3263
+ }
3264
+ ];
3265
+ },
3266
+ driftTrackedFiles() {
3267
+ return ["managed-agent.json"];
3268
+ },
3269
+ // -------------------------------------------------------------------------
3270
+ // No local runtime — all execution is in Anthropic's cloud.
3271
+ // These methods are intentional no-ops.
3272
+ // -------------------------------------------------------------------------
3273
+ async getRegisteredAgents() {
3274
+ return /* @__PURE__ */ new Set();
3275
+ },
3276
+ async registerAgent(_codeName, _teamDir) {
3277
+ return true;
3278
+ },
3279
+ async deregisterAgent(_codeName) {
3280
+ return true;
3281
+ },
3282
+ writeAuthProfiles(_codeName, _profiles) {
3283
+ }
3284
+ };
3285
+ registerFramework(ManagedAgentsAdapter);
3286
+
2974
3287
  // src/lib/config.ts
2975
3288
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync4 } from "fs";
2976
3289
  import { join as join4 } from "path";
@@ -4780,8 +5093,10 @@ var ROLE_PERMISSIONS = {
4780
5093
  "agent.view",
4781
5094
  "audit_log.view",
4782
5095
  "host.view",
5096
+ "plugin.view",
4783
5097
  "plugin.install",
4784
- "plugin.view"
5098
+ "plugin.configure",
5099
+ "plugin.manage_scopes"
4785
5100
  ],
4786
5101
  viewer: [
4787
5102
  "agent.view",
@@ -5244,4 +5559,4 @@ export {
5244
5559
  detectDrift,
5245
5560
  provision
5246
5561
  };
5247
- //# sourceMappingURL=chunk-VCKY6MN2.js.map
5562
+ //# sourceMappingURL=chunk-CVQD6XGB.js.map