@integrity-labs/agt-cli 0.10.0 → 0.10.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.
- package/dist/bin/agt.js +242 -8
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-2TSCVXHE.js → chunk-QU7FBXH3.js} +4 -2
- package/dist/chunk-QU7FBXH3.js.map +1 -0
- package/dist/{chunk-UWH2MMKY.js → chunk-VCKY6MN2.js} +400 -17
- package/dist/chunk-VCKY6MN2.js.map +1 -0
- package/dist/{claude-scheduler-VFBZFE6U.js → claude-scheduler-7PVWQHWU.js} +2 -2
- package/dist/lib/manager-worker.js +385 -99
- package/dist/lib/manager-worker.js.map +1 -1
- package/mcp/direct-chat-channel.js +13985 -0
- package/mcp/index.js +181 -0
- package/package.json +1 -1
- package/dist/chunk-2TSCVXHE.js.map +0 -1
- package/dist/chunk-UWH2MMKY.js.map +0 -1
- /package/dist/{claude-scheduler-VFBZFE6U.js.map → claude-scheduler-7PVWQHWU.js.map} +0 -0
|
@@ -30,7 +30,9 @@ function computeNextFire(kind, expr, every, at, timezone, afterMs) {
|
|
|
30
30
|
}
|
|
31
31
|
if (kind === "at" && at) {
|
|
32
32
|
const ts = new Date(at).getTime();
|
|
33
|
-
|
|
33
|
+
if (isNaN(ts)) return null;
|
|
34
|
+
if (afterMs && ts <= afterMs) return null;
|
|
35
|
+
return ts;
|
|
34
36
|
}
|
|
35
37
|
return null;
|
|
36
38
|
}
|
|
@@ -190,4 +192,4 @@ export {
|
|
|
190
192
|
findTaskByTemplate,
|
|
191
193
|
getProjectDir
|
|
192
194
|
};
|
|
193
|
-
//# sourceMappingURL=chunk-
|
|
195
|
+
//# sourceMappingURL=chunk-QU7FBXH3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/claude-scheduler.ts"],"sourcesContent":["/**\n * In-process scheduler for Claude Code agents.\n *\n * On each manager poll cycle, checks if any tasks are due and fires them\n * via `claude -p`. State persists to disk so nextFireAt/lastFireAt survive\n * manager restarts.\n */\n\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { Cron } from 'croner';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface SchedulerTaskState {\n taskId: string;\n templateId: string;\n name: string;\n agentCodeName: string;\n agentId: string;\n scheduleKind: 'cron' | 'every' | 'at';\n scheduleExpr: string | null;\n scheduleEvery: string | null;\n scheduleAt: string | null;\n timezone: string;\n prompt: string;\n sessionTarget: string;\n deliveryMode: string;\n deliveryChannel: string | null;\n deliveryTo: string | null;\n enabled: boolean;\n triggeredAt: number | null; // epoch ms — manual trigger from webapp\n nextFireAt: number | null; // epoch ms, null = completed one-shot\n lastFireAt: number | null;\n lastStatus: 'ok' | 'error' | null;\n firedCount: number;\n}\n\nexport interface SchedulerState {\n version: 1;\n tasks: Record<string, SchedulerTaskState>;\n updatedAt: string;\n}\n\nexport interface SchedulerTaskInput {\n id: string;\n template_id: string;\n name: string;\n schedule_kind: 'cron' | 'every' | 'at';\n schedule_expr: string | null;\n schedule_every: string | null;\n schedule_at: string | null;\n timezone: string;\n prompt: string;\n session_target: string;\n delivery_mode: string;\n delivery_channel: string | null;\n delivery_to: string | null;\n enabled: boolean;\n triggered_at?: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Interval parsing (reused from Claude Code adapter)\n// ---------------------------------------------------------------------------\n\nfunction parseIntervalMs(scheduleEvery: string | null): number {\n if (!scheduleEvery) return 60 * 60_000; // 1hr default\n const match = scheduleEvery.match(/^(\\d+)\\s*(m|min|h|hr|d)$/i);\n if (!match) return 60 * 60_000;\n const value = parseInt(match[1]!, 10);\n const unit = match[2]!.toLowerCase();\n if (unit === 'h' || unit === 'hr') return value * 60 * 60_000;\n if (unit === 'd') return value * 24 * 60 * 60_000;\n return value * 60_000; // minutes\n}\n\n// ---------------------------------------------------------------------------\n// Next-fire computation\n// ---------------------------------------------------------------------------\n\nexport function computeNextFire(\n kind: 'cron' | 'every' | 'at',\n expr: string | null,\n every: string | null,\n at: string | null,\n timezone: string,\n afterMs?: number,\n): number | null {\n const now = afterMs ?? Date.now();\n\n if (kind === 'cron' && expr) {\n try {\n const cron = new Cron(expr, { timezone: timezone || undefined });\n const next = cron.nextRun(new Date(now));\n return next ? next.getTime() : null;\n } catch {\n return null;\n }\n }\n\n if (kind === 'every') {\n const intervalMs = parseIntervalMs(every);\n return now + intervalMs;\n }\n\n if (kind === 'at' && at) {\n const ts = new Date(at).getTime();\n if (isNaN(ts)) return null;\n // If the 'at' timestamp is in the past and afterMs is set (meaning we already\n // fired), return null to prevent re-firing on state rebuild.\n if (afterMs && ts <= afterMs) return null;\n return ts;\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// State persistence\n// ---------------------------------------------------------------------------\n\nfunction getStateDir(codeName: string): string {\n return join(homedir(), '.augmented', codeName, 'claudecode');\n}\n\nfunction getStatePath(codeName: string): string {\n return join(getStateDir(codeName), 'scheduler-state.json');\n}\n\nexport function loadSchedulerState(codeName: string): SchedulerState {\n const path = getStatePath(codeName);\n if (existsSync(path)) {\n try {\n return JSON.parse(readFileSync(path, 'utf-8'));\n } catch { /* corrupted — start fresh */ }\n }\n return { version: 1, tasks: {}, updatedAt: new Date().toISOString() };\n}\n\nexport function saveSchedulerState(codeName: string, state: SchedulerState): void {\n const dir = getStateDir(codeName);\n mkdirSync(dir, { recursive: true });\n state.updatedAt = new Date().toISOString();\n const path = getStatePath(codeName);\n const tmpPath = path + '.tmp';\n writeFileSync(tmpPath, JSON.stringify(state, null, 2));\n renameSync(tmpPath, path);\n}\n\n// ---------------------------------------------------------------------------\n// Sync API tasks → scheduler state\n// ---------------------------------------------------------------------------\n\nexport function syncTasksToScheduler(\n codeName: string,\n agentId: string,\n tasks: SchedulerTaskInput[],\n): SchedulerState {\n const state = loadSchedulerState(codeName);\n const desiredIds = new Set(tasks.map((t) => t.id));\n\n // Remove tasks no longer in API\n for (const id of Object.keys(state.tasks)) {\n if (!desiredIds.has(id)) {\n delete state.tasks[id];\n }\n }\n\n // Add or update tasks\n for (const t of tasks) {\n const existing = state.tasks[t.id];\n if (existing) {\n // Only recompute nextFireAt if the schedule definition actually changed.\n // Without this guard, every sync cycle resets nextFireAt from \"now\",\n // preventing past-due tasks from ever being detected as ready.\n const scheduleChanged =\n existing.scheduleKind !== t.schedule_kind ||\n existing.scheduleExpr !== t.schedule_expr ||\n existing.scheduleEvery !== t.schedule_every ||\n existing.scheduleAt !== t.schedule_at ||\n existing.timezone !== t.timezone;\n\n // Update mutable fields, preserve fire history\n existing.name = t.name;\n existing.templateId = t.template_id;\n existing.scheduleKind = t.schedule_kind;\n existing.scheduleExpr = t.schedule_expr;\n existing.scheduleEvery = t.schedule_every;\n existing.scheduleAt = t.schedule_at;\n existing.timezone = t.timezone;\n existing.prompt = t.prompt;\n existing.sessionTarget = t.session_target;\n existing.deliveryMode = t.delivery_mode;\n existing.deliveryChannel = t.delivery_channel;\n existing.deliveryTo = t.delivery_to;\n existing.enabled = t.enabled;\n if (t.triggered_at) existing.triggeredAt = new Date(t.triggered_at).getTime();\n if (scheduleChanged) {\n existing.nextFireAt = computeNextFire(\n t.schedule_kind, t.schedule_expr, t.schedule_every, t.schedule_at,\n t.timezone, existing.lastFireAt ?? undefined,\n );\n }\n } else {\n // New task\n state.tasks[t.id] = {\n taskId: t.id,\n templateId: t.template_id,\n name: t.name,\n agentCodeName: codeName,\n agentId,\n scheduleKind: t.schedule_kind,\n scheduleExpr: t.schedule_expr,\n scheduleEvery: t.schedule_every,\n scheduleAt: t.schedule_at,\n timezone: t.timezone,\n prompt: t.prompt,\n sessionTarget: t.session_target,\n deliveryMode: t.delivery_mode,\n deliveryChannel: t.delivery_channel,\n deliveryTo: t.delivery_to,\n enabled: t.enabled,\n triggeredAt: t.triggered_at ? new Date(t.triggered_at).getTime() : null,\n nextFireAt: computeNextFire(\n t.schedule_kind, t.schedule_expr, t.schedule_every, t.schedule_at, t.timezone,\n ),\n lastFireAt: null,\n lastStatus: null,\n firedCount: 0,\n };\n }\n }\n\n saveSchedulerState(codeName, state);\n return state;\n}\n\n// ---------------------------------------------------------------------------\n// Ready-task detection\n// ---------------------------------------------------------------------------\n\nexport function getReadyTasks(state: SchedulerState): SchedulerTaskState[] {\n const now = Date.now();\n const ready = Object.values(state.tasks).filter((t) => {\n if (!t.enabled) return false;\n // Manual trigger: triggered_at is set and hasn't been fired yet\n if (t.triggeredAt) {\n const triggerReady = !t.lastFireAt || t.triggeredAt > t.lastFireAt;\n if (!triggerReady) {\n // Debug: trigger was already consumed\n }\n if (triggerReady) return true;\n }\n // Normal schedule\n return t.nextFireAt !== null && t.nextFireAt <= now;\n });\n // Deduplicate by templateId — only fire one task per template per cycle\n const seen = new Set<string>();\n return ready.filter((t) => {\n if (seen.has(t.templateId)) return false;\n seen.add(t.templateId);\n return true;\n });\n}\n\n// ---------------------------------------------------------------------------\n// Post-execution state update\n// ---------------------------------------------------------------------------\n\nexport function markTaskFired(\n codeName: string,\n taskId: string,\n status: 'ok' | 'error',\n): SchedulerState {\n const state = loadSchedulerState(codeName);\n const task = state.tasks[taskId];\n if (!task) return state;\n\n task.lastFireAt = Date.now();\n task.lastStatus = status;\n task.firedCount++;\n\n // Compute next fire\n if (task.scheduleKind === 'at') {\n // One-shot — mark as completed\n task.nextFireAt = null;\n } else {\n task.nextFireAt = computeNextFire(\n task.scheduleKind, task.scheduleExpr, task.scheduleEvery, task.scheduleAt,\n task.timezone, task.lastFireAt,\n );\n }\n\n saveSchedulerState(codeName, state);\n return state;\n}\n\n// ---------------------------------------------------------------------------\n// Find a task by template ID (for work triggers)\n// ---------------------------------------------------------------------------\n\nexport function findTaskByTemplate(state: SchedulerState, templateId: string): SchedulerTaskState | undefined {\n return Object.values(state.tasks).find(\n (t) => t.templateId === templateId && t.enabled,\n );\n}\n\nexport function getProjectDir(codeName: string): string {\n return join(homedir(), '.augmented', codeName, 'project');\n}\n"],"mappings":"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","names":[]}
|
|
@@ -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",
|
|
@@ -464,12 +483,30 @@ you need context about who you work for or how to operate.
|
|
|
464
483
|
|
|
465
484
|
${body}`;
|
|
466
485
|
}
|
|
486
|
+
function buildReportsToSection(reportsTo) {
|
|
487
|
+
if (!reportsTo)
|
|
488
|
+
return "";
|
|
489
|
+
const typeLabel = reportsTo.type === "agent" ? "Agent" : "Person";
|
|
490
|
+
let section = `
|
|
491
|
+
## Reports To
|
|
492
|
+
|
|
493
|
+
- **${reportsTo.name}** (${typeLabel})`;
|
|
494
|
+
if (reportsTo.title)
|
|
495
|
+
section += `
|
|
496
|
+
- Title: ${reportsTo.title}`;
|
|
497
|
+
if (reportsTo.description)
|
|
498
|
+
section += `
|
|
499
|
+
- ${reportsTo.description}`;
|
|
500
|
+
section += "\n";
|
|
501
|
+
return section;
|
|
502
|
+
}
|
|
467
503
|
function generateSoulMd(input) {
|
|
468
|
-
const { frontmatter, role, description, resolvedChannels, team, knowledge } = input;
|
|
504
|
+
const { frontmatter, role, description, resolvedChannels, team, knowledge, reportsTo } = input;
|
|
469
505
|
const channelList = resolvedChannels?.length ? resolvedChannels.join(", ") : "none";
|
|
470
506
|
const roleDisplay = role ?? "Agent";
|
|
471
507
|
const desc = description?.trim();
|
|
472
508
|
const knowledgeSection = buildKnowledgeSection(knowledge);
|
|
509
|
+
const reportsToSection = buildReportsToSection(reportsTo);
|
|
473
510
|
return `# ${frontmatter.display_name}
|
|
474
511
|
|
|
475
512
|
You are **${frontmatter.display_name}**, **${roleDisplay}**${team ? ` at **${team.name}**` : ""}.
|
|
@@ -479,7 +516,7 @@ ${desc}
|
|
|
479
516
|
- Owner: ${frontmatter.owner.name}
|
|
480
517
|
- Environment: ${frontmatter.environment}
|
|
481
518
|
- Channels: ${channelList}
|
|
482
|
-
${knowledgeSection}`;
|
|
519
|
+
${reportsToSection}${knowledgeSection}`;
|
|
483
520
|
}
|
|
484
521
|
function generateAgentsMd(input) {
|
|
485
522
|
const { frontmatter, role, description, team } = input;
|
|
@@ -688,7 +725,8 @@ var openclawAdapter = {
|
|
|
688
725
|
description: input.agent.description,
|
|
689
726
|
resolvedChannels: input.resolvedChannels,
|
|
690
727
|
team: input.team,
|
|
691
|
-
knowledge: knowledgeRefs.length > 0 ? knowledgeRefs : void 0
|
|
728
|
+
knowledge: knowledgeRefs.length > 0 ? knowledgeRefs : void 0,
|
|
729
|
+
reportsTo: input.reportsTo
|
|
692
730
|
};
|
|
693
731
|
const artifacts = [
|
|
694
732
|
{ relativePath: "openclaw.json5", content: serializeOpenClawConfig(config) },
|
|
@@ -1314,6 +1352,38 @@ ${entry.content}`
|
|
|
1314
1352
|
return changed;
|
|
1315
1353
|
}, codeName);
|
|
1316
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
|
+
},
|
|
1317
1387
|
readGatewayToken(codeName) {
|
|
1318
1388
|
const homeDir = getHomeDir();
|
|
1319
1389
|
try {
|
|
@@ -1792,6 +1862,7 @@ registerFramework(nemoClawAdapter);
|
|
|
1792
1862
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync3, chmodSync as chmodSync3 } from "fs";
|
|
1793
1863
|
import { join as join3, relative } from "path";
|
|
1794
1864
|
import { homedir as homedir2 } from "os";
|
|
1865
|
+
import { execFile as execFile3 } from "child_process";
|
|
1795
1866
|
|
|
1796
1867
|
// ../../packages/core/dist/provisioning/frameworks/claudecode/identity.js
|
|
1797
1868
|
function buildMemorySection(hasQmd) {
|
|
@@ -1916,8 +1987,29 @@ ${seed.trim()}
|
|
|
1916
1987
|
|
|
1917
1988
|
`;
|
|
1918
1989
|
}
|
|
1990
|
+
function buildReportsToSection2(reportsTo) {
|
|
1991
|
+
if (!reportsTo)
|
|
1992
|
+
return "";
|
|
1993
|
+
const typeLabel = reportsTo.type === "agent" ? "Agent" : "Person";
|
|
1994
|
+
let section = `## Reports To
|
|
1995
|
+
|
|
1996
|
+
- **${reportsTo.name}** (${typeLabel})`;
|
|
1997
|
+
if (reportsTo.title)
|
|
1998
|
+
section += `
|
|
1999
|
+
- Title: ${reportsTo.title}`;
|
|
2000
|
+
if (reportsTo.description)
|
|
2001
|
+
section += `
|
|
2002
|
+
- ${reportsTo.description}`;
|
|
2003
|
+
section += `
|
|
2004
|
+
|
|
2005
|
+
Escalate blockers, questions, and important decisions to your manager.
|
|
2006
|
+
When your manager sends you a message, prioritize it.
|
|
2007
|
+
|
|
2008
|
+
`;
|
|
2009
|
+
return section;
|
|
2010
|
+
}
|
|
1919
2011
|
function generateClaudeMd(input) {
|
|
1920
|
-
const { frontmatter, role, description, resolvedChannels, team, consoleUrl, hasQmd, integrations, knowledge, timezone, personalitySeed } = input;
|
|
2012
|
+
const { frontmatter, role, description, resolvedChannels, team, consoleUrl, hasQmd, integrations, knowledge, timezone, reportsTo, personalitySeed } = input;
|
|
1921
2013
|
const channelList = resolvedChannels?.length ? resolvedChannels.join(", ") : "none";
|
|
1922
2014
|
const roleDisplay = role ?? "Agent";
|
|
1923
2015
|
const desc = description?.trim();
|
|
@@ -1926,6 +2018,7 @@ function generateClaudeMd(input) {
|
|
|
1926
2018
|
const integrationsSection = buildIntegrationsSection(integrations);
|
|
1927
2019
|
const knowledgeSection = buildKnowledgeSection2(knowledge);
|
|
1928
2020
|
const personalitySection = buildPersonalitySection(personalitySeed);
|
|
2021
|
+
const reportsToSection = buildReportsToSection2(reportsTo);
|
|
1929
2022
|
return `# ${frontmatter.display_name}
|
|
1930
2023
|
|
|
1931
2024
|
You are **${frontmatter.display_name}**, **${roleDisplay}**${team ? ` at **${team.name}**` : ""}.
|
|
@@ -1981,7 +2074,7 @@ first to load your recent board state. This gives you context about completed an
|
|
|
1981
2074
|
in-progress items so you can answer accurately.
|
|
1982
2075
|
|
|
1983
2076
|
${memorySection}
|
|
1984
|
-
${integrationsSection}${knowledgeSection}## Development Workflow
|
|
2077
|
+
${reportsToSection}${integrationsSection}${knowledgeSection}## Development Workflow
|
|
1985
2078
|
|
|
1986
2079
|
### Repository Management
|
|
1987
2080
|
|
|
@@ -2149,6 +2242,88 @@ function provisionStopHook(codeName) {
|
|
|
2149
2242
|
settings["hooks"] = hooks;
|
|
2150
2243
|
writeFileSync3(settingsPath, JSON.stringify(settings, null, 2));
|
|
2151
2244
|
}
|
|
2245
|
+
function provisionIsolationHook(codeName) {
|
|
2246
|
+
const projectDir = getProjectDir(codeName);
|
|
2247
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
2248
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
2249
|
+
const homeDir = getHomeDir3();
|
|
2250
|
+
const augmentedBase = join3(homeDir, ".augmented");
|
|
2251
|
+
const ownAgentDir = join3(augmentedBase, codeName);
|
|
2252
|
+
const logFile = join3(ownAgentDir, "isolation.log");
|
|
2253
|
+
const hookScriptPath = join3(claudeDir, "agt-isolation-hook.sh");
|
|
2254
|
+
const hookScript = [
|
|
2255
|
+
"#!/bin/bash",
|
|
2256
|
+
"# Auto-generated by Augmented \u2014 prevents cross-agent file access.",
|
|
2257
|
+
"# Exit 0 = allow, Exit 2 = block (with stderr message shown to agent)",
|
|
2258
|
+
"set -euo pipefail",
|
|
2259
|
+
"INPUT=$(cat)",
|
|
2260
|
+
`TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty')`,
|
|
2261
|
+
"",
|
|
2262
|
+
"# Only check file-access tools",
|
|
2263
|
+
'case "$TOOL" in',
|
|
2264
|
+
" Read|Edit|Write|Glob|Grep|MultiEdit) ;;",
|
|
2265
|
+
" Bash)",
|
|
2266
|
+
" # For Bash, we can't reliably parse arbitrary commands \u2014 rely on allowedDirectories.",
|
|
2267
|
+
" # But block obvious attempts to read other agent dirs.",
|
|
2268
|
+
` CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty')`,
|
|
2269
|
+
` if echo "$CMD" | grep -qE '${augmentedBase}/[^/]+/' 2>/dev/null; then`,
|
|
2270
|
+
` MATCH=$(echo "$CMD" | grep -oE '${augmentedBase}/[^/]+' | head -1)`,
|
|
2271
|
+
` AGENT_DIR=$(basename "$MATCH")`,
|
|
2272
|
+
` if [ "$AGENT_DIR" != "${codeName}" ] && [ "$AGENT_DIR" != "_mcp" ]; then`,
|
|
2273
|
+
` echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) BLOCKED bash targeting $MATCH" >> "${logFile}"`,
|
|
2274
|
+
` echo "Access denied: you cannot access other agents' directories." >&2`,
|
|
2275
|
+
" exit 2",
|
|
2276
|
+
" fi",
|
|
2277
|
+
" fi",
|
|
2278
|
+
" exit 0 ;;",
|
|
2279
|
+
" *) exit 0 ;;",
|
|
2280
|
+
"esac",
|
|
2281
|
+
"",
|
|
2282
|
+
"# Extract file_path from tool input",
|
|
2283
|
+
`FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // empty')`,
|
|
2284
|
+
'[ -z "$FILE_PATH" ] && exit 0',
|
|
2285
|
+
"",
|
|
2286
|
+
"# Resolve to absolute path",
|
|
2287
|
+
'if [[ "$FILE_PATH" != /* ]]; then',
|
|
2288
|
+
` CWD=$(echo "$INPUT" | jq -r '.cwd // empty')`,
|
|
2289
|
+
' [ -n "$CWD" ] && FILE_PATH="$CWD/$FILE_PATH"',
|
|
2290
|
+
"fi",
|
|
2291
|
+
"",
|
|
2292
|
+
"# Check if path targets another agent's directory",
|
|
2293
|
+
`AUGMENTED_BASE="${augmentedBase}"`,
|
|
2294
|
+
'case "$FILE_PATH" in',
|
|
2295
|
+
' "$AUGMENTED_BASE"/*/*) ',
|
|
2296
|
+
' AGENT_DIR=$(echo "$FILE_PATH" | sed "s|$AUGMENTED_BASE/||" | cut -d/ -f1)',
|
|
2297
|
+
` if [ "$AGENT_DIR" != "${codeName}" ] && [ "$AGENT_DIR" != "_mcp" ]; then`,
|
|
2298
|
+
` echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) BLOCKED $TOOL on $FILE_PATH" >> "${logFile}"`,
|
|
2299
|
+
` echo "Access denied: you cannot access other agents' directories." >&2`,
|
|
2300
|
+
" exit 2",
|
|
2301
|
+
" fi ;;",
|
|
2302
|
+
"esac",
|
|
2303
|
+
"",
|
|
2304
|
+
"exit 0"
|
|
2305
|
+
].join("\n") + "\n";
|
|
2306
|
+
writeFileSync3(hookScriptPath, hookScript, { mode: 493 });
|
|
2307
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
2308
|
+
let settings = {};
|
|
2309
|
+
try {
|
|
2310
|
+
settings = JSON.parse(readFileSync3(settingsPath, "utf-8"));
|
|
2311
|
+
} catch {
|
|
2312
|
+
}
|
|
2313
|
+
const hooks = settings["hooks"] ?? {};
|
|
2314
|
+
hooks["PreToolUse"] = [
|
|
2315
|
+
{
|
|
2316
|
+
hooks: [
|
|
2317
|
+
{
|
|
2318
|
+
type: "command",
|
|
2319
|
+
command: hookScriptPath
|
|
2320
|
+
}
|
|
2321
|
+
]
|
|
2322
|
+
}
|
|
2323
|
+
];
|
|
2324
|
+
settings["hooks"] = hooks;
|
|
2325
|
+
writeFileSync3(settingsPath, JSON.stringify(settings, null, 2));
|
|
2326
|
+
}
|
|
2152
2327
|
function modifyJsonConfig(filePath, fn) {
|
|
2153
2328
|
let originalContent;
|
|
2154
2329
|
let config;
|
|
@@ -2184,6 +2359,19 @@ function buildSettingsJson(input) {
|
|
|
2184
2359
|
if (agent.primary_model) {
|
|
2185
2360
|
settings["model"] = agent.primary_model;
|
|
2186
2361
|
}
|
|
2362
|
+
const projectDir = getProjectDir(agent.code_name);
|
|
2363
|
+
const agentDir = getAgentDir(agent.code_name);
|
|
2364
|
+
const homeDir = getHomeDir3();
|
|
2365
|
+
settings["allowedDirectories"] = [
|
|
2366
|
+
projectDir,
|
|
2367
|
+
// Agent's project dir (CLAUDE.md, settings.json, etc.)
|
|
2368
|
+
agentDir,
|
|
2369
|
+
// Agent's config dir (.env, schedules, registration)
|
|
2370
|
+
join3(homeDir, ".augmented", "_mcp"),
|
|
2371
|
+
// Shared MCP binaries
|
|
2372
|
+
"/tmp"
|
|
2373
|
+
// Temp files
|
|
2374
|
+
];
|
|
2187
2375
|
return settings;
|
|
2188
2376
|
}
|
|
2189
2377
|
function buildMcpJson(input) {
|
|
@@ -2384,9 +2572,9 @@ ${entry.content}`
|
|
|
2384
2572
|
// so ensureGatewayRunning() returns early with running=false
|
|
2385
2573
|
async getVersion() {
|
|
2386
2574
|
try {
|
|
2387
|
-
const { execFile:
|
|
2575
|
+
const { execFile: execFile4 } = await import("child_process");
|
|
2388
2576
|
return new Promise((resolve3) => {
|
|
2389
|
-
|
|
2577
|
+
execFile4("claude", ["--version"], { timeout: 5e3 }, (err, stdout) => {
|
|
2390
2578
|
if (err) {
|
|
2391
2579
|
resolve3(null);
|
|
2392
2580
|
return;
|
|
@@ -2634,6 +2822,23 @@ ${entry.content}`
|
|
|
2634
2822
|
args: ["-y", "@composio/mcp", "start", "--url", config.url],
|
|
2635
2823
|
env: config.headers ?? {}
|
|
2636
2824
|
};
|
|
2825
|
+
} else if (config.url.includes("mcp.pipedream.net")) {
|
|
2826
|
+
const pdUrl = new URL(config.url);
|
|
2827
|
+
const pathParts = pdUrl.pathname.split("/").filter(Boolean);
|
|
2828
|
+
const externalUserId = decodeURIComponent(pathParts[0] ?? "");
|
|
2829
|
+
const appSlug = decodeURIComponent(pathParts[1] ?? "");
|
|
2830
|
+
const headers = config.headers ?? {};
|
|
2831
|
+
const authToken = (headers["Authorization"] ?? "").replace("Bearer ", "");
|
|
2832
|
+
serverEntry = {
|
|
2833
|
+
command: "npx",
|
|
2834
|
+
args: ["-y", "@pipedream/mcp", "stdio", "--app", appSlug, "--external-user-id", externalUserId],
|
|
2835
|
+
env: {
|
|
2836
|
+
PIPEDREAM_PROJECT_ID: headers["x-pd-project-id"] ?? process.env["PIPEDREAM_PROJECT_ID"] ?? "",
|
|
2837
|
+
PIPEDREAM_CLIENT_ID: headers["x-pd-client-id"] ?? process.env["PIPEDREAM_CLIENT_ID"] ?? "",
|
|
2838
|
+
PIPEDREAM_CLIENT_SECRET: headers["x-pd-client-secret"] ?? process.env["PIPEDREAM_CLIENT_SECRET"] ?? "",
|
|
2839
|
+
PIPEDREAM_PROJECT_ENVIRONMENT: headers["x-pd-environment"] ?? process.env["PIPEDREAM_ENVIRONMENT"] ?? "development"
|
|
2840
|
+
}
|
|
2841
|
+
};
|
|
2637
2842
|
} else {
|
|
2638
2843
|
serverEntry = {
|
|
2639
2844
|
command: "npx",
|
|
@@ -2707,6 +2912,40 @@ ${entry.content}`
|
|
|
2707
2912
|
};
|
|
2708
2913
|
writeFileSync3(pluginsJsonPath, JSON.stringify(pluginsConfig, null, 2));
|
|
2709
2914
|
},
|
|
2915
|
+
executePluginHook(ctx) {
|
|
2916
|
+
assertValidCodeName(ctx.codeName);
|
|
2917
|
+
const agentRootDir = join3(getHomeDir3(), ".augmented", ctx.codeName);
|
|
2918
|
+
const projectDir = getProjectDir(ctx.codeName);
|
|
2919
|
+
mkdirSync3(agentRootDir, { recursive: true });
|
|
2920
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
2921
|
+
const startedAt = Date.now();
|
|
2922
|
+
return new Promise((resolve3) => {
|
|
2923
|
+
const child = execFile3("bash", ["-c", ctx.script], {
|
|
2924
|
+
cwd: agentRootDir,
|
|
2925
|
+
timeout: 6e4,
|
|
2926
|
+
maxBuffer: 1024 * 1024,
|
|
2927
|
+
env: {
|
|
2928
|
+
...process.env,
|
|
2929
|
+
AGENT_CODE_NAME: ctx.codeName,
|
|
2930
|
+
AGENT_DIR: agentRootDir,
|
|
2931
|
+
AGENT_PROJECT_DIR: projectDir,
|
|
2932
|
+
AGENT_FRAMEWORK: "claude-code"
|
|
2933
|
+
}
|
|
2934
|
+
}, (error, stdout, stderr) => {
|
|
2935
|
+
const durationMs = Date.now() - startedAt;
|
|
2936
|
+
const timedOut = !!error && error.code === "ETIMEDOUT";
|
|
2937
|
+
resolve3({
|
|
2938
|
+
exitCode: error ? typeof error.code === "number" ? error.code : 1 : 0,
|
|
2939
|
+
stdout: stdout?.toString() ?? "",
|
|
2940
|
+
stderr: stderr?.toString() ?? "",
|
|
2941
|
+
durationMs,
|
|
2942
|
+
timedOut
|
|
2943
|
+
});
|
|
2944
|
+
});
|
|
2945
|
+
child.on("error", () => {
|
|
2946
|
+
});
|
|
2947
|
+
});
|
|
2948
|
+
},
|
|
2710
2949
|
writeTokenFile(codeName, integrations) {
|
|
2711
2950
|
const agentDir = getAgentDir(codeName);
|
|
2712
2951
|
mkdirSync3(agentDir, { recursive: true });
|
|
@@ -2798,12 +3037,16 @@ function setActiveTeam(slug) {
|
|
|
2798
3037
|
config.active_team = slug;
|
|
2799
3038
|
saveConfig(config);
|
|
2800
3039
|
}
|
|
3040
|
+
function getHost() {
|
|
3041
|
+
return process.env["AGT_HOST"];
|
|
3042
|
+
}
|
|
2801
3043
|
var AGT_HOST = process.env["AGT_HOST"];
|
|
2802
3044
|
function requireHost() {
|
|
2803
|
-
|
|
3045
|
+
const host = getHost();
|
|
3046
|
+
if (!host) {
|
|
2804
3047
|
throw new Error("AGT_HOST is not set. Export it to point at the Augmented API (e.g. export AGT_HOST=https://your-api.example.com)");
|
|
2805
3048
|
}
|
|
2806
|
-
return
|
|
3049
|
+
return host;
|
|
2807
3050
|
}
|
|
2808
3051
|
|
|
2809
3052
|
// src/lib/api-client.ts
|
|
@@ -2843,6 +3086,11 @@ async function doExchange(rawKey, retried) {
|
|
|
2843
3086
|
if (!res.ok) {
|
|
2844
3087
|
const body = await res.json().catch(() => ({}));
|
|
2845
3088
|
const errorMsg = String(body["error"] ?? res.statusText);
|
|
3089
|
+
const host = requireHost();
|
|
3090
|
+
const obfuscated = rawKey.length > 12 ? `${rawKey.slice(0, 8)}${"*".repeat(rawKey.length - 12)}${rawKey.slice(-4)}` : rawKey.slice(0, 4) + "****";
|
|
3091
|
+
if (res.status >= 502 && res.status <= 504) {
|
|
3092
|
+
throw new Error(`API unreachable (${res.status}): ${host} \u2014 is the API server running?`);
|
|
3093
|
+
}
|
|
2846
3094
|
if (errorMsg.includes("revoked") && !retried) {
|
|
2847
3095
|
reloadFromShellProfile();
|
|
2848
3096
|
const freshKey = getApiKey();
|
|
@@ -2850,8 +3098,6 @@ async function doExchange(rawKey, retried) {
|
|
|
2850
3098
|
return doExchange(freshKey, true);
|
|
2851
3099
|
}
|
|
2852
3100
|
}
|
|
2853
|
-
const host = requireHost();
|
|
2854
|
-
const obfuscated = rawKey.length > 12 ? `${rawKey.slice(0, 8)}${"*".repeat(rawKey.length - 12)}${rawKey.slice(-4)}` : rawKey.slice(0, 4) + "****";
|
|
2855
3101
|
throw new Error(`API key exchange failed: ${errorMsg} (host=${host}, key=${obfuscated})`);
|
|
2856
3102
|
}
|
|
2857
3103
|
const data = await res.json();
|
|
@@ -4501,7 +4747,12 @@ var ROLE_PERMISSIONS = {
|
|
|
4501
4747
|
"audit_log.view",
|
|
4502
4748
|
"host.create",
|
|
4503
4749
|
"host.manage",
|
|
4504
|
-
"host.view"
|
|
4750
|
+
"host.view",
|
|
4751
|
+
"plugin.view",
|
|
4752
|
+
"plugin.install",
|
|
4753
|
+
"plugin.configure",
|
|
4754
|
+
"plugin.manage_scopes",
|
|
4755
|
+
"plugin.approve_requests"
|
|
4505
4756
|
],
|
|
4506
4757
|
admin: [
|
|
4507
4758
|
"team.manage_members",
|
|
@@ -4515,7 +4766,12 @@ var ROLE_PERMISSIONS = {
|
|
|
4515
4766
|
"audit_log.view",
|
|
4516
4767
|
"host.create",
|
|
4517
4768
|
"host.manage",
|
|
4518
|
-
"host.view"
|
|
4769
|
+
"host.view",
|
|
4770
|
+
"plugin.view",
|
|
4771
|
+
"plugin.install",
|
|
4772
|
+
"plugin.configure",
|
|
4773
|
+
"plugin.manage_scopes",
|
|
4774
|
+
"plugin.approve_requests"
|
|
4519
4775
|
],
|
|
4520
4776
|
member: [
|
|
4521
4777
|
"agent.create",
|
|
@@ -4523,12 +4779,15 @@ var ROLE_PERMISSIONS = {
|
|
|
4523
4779
|
"agent.deploy",
|
|
4524
4780
|
"agent.view",
|
|
4525
4781
|
"audit_log.view",
|
|
4526
|
-
"host.view"
|
|
4782
|
+
"host.view",
|
|
4783
|
+
"plugin.install",
|
|
4784
|
+
"plugin.view"
|
|
4527
4785
|
],
|
|
4528
4786
|
viewer: [
|
|
4529
4787
|
"agent.view",
|
|
4530
4788
|
"audit_log.view",
|
|
4531
|
-
"host.view"
|
|
4789
|
+
"host.view",
|
|
4790
|
+
"plugin.view"
|
|
4532
4791
|
]
|
|
4533
4792
|
};
|
|
4534
4793
|
var permissionSets = new Map(Object.entries(ROLE_PERMISSIONS).map(([role, actions]) => [role, new Set(actions)]));
|
|
@@ -4635,6 +4894,129 @@ function getTemplate(id) {
|
|
|
4635
4894
|
return DEPLOYMENT_TEMPLATES.find((t) => t.id === id);
|
|
4636
4895
|
}
|
|
4637
4896
|
|
|
4897
|
+
// ../../packages/core/dist/plugins/context-validator.js
|
|
4898
|
+
import Ajv20202 from "ajv/dist/2020.js";
|
|
4899
|
+
import addFormats2 from "ajv-formats";
|
|
4900
|
+
|
|
4901
|
+
// ../../packages/core/dist/plugins/context-meta-schema.json
|
|
4902
|
+
var context_meta_schema_default = {
|
|
4903
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
4904
|
+
$id: "https://augmented.dev/schemas/plugin-context.meta.schema.json",
|
|
4905
|
+
title: "Plugin Context Schema (meta)",
|
|
4906
|
+
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.",
|
|
4907
|
+
type: "object",
|
|
4908
|
+
required: ["type", "properties"],
|
|
4909
|
+
additionalProperties: false,
|
|
4910
|
+
properties: {
|
|
4911
|
+
$schema: {
|
|
4912
|
+
type: "string"
|
|
4913
|
+
},
|
|
4914
|
+
type: {
|
|
4915
|
+
type: "string",
|
|
4916
|
+
const: "object"
|
|
4917
|
+
},
|
|
4918
|
+
properties: {
|
|
4919
|
+
type: "object",
|
|
4920
|
+
minProperties: 0,
|
|
4921
|
+
additionalProperties: {
|
|
4922
|
+
$ref: "#/$defs/field"
|
|
4923
|
+
}
|
|
4924
|
+
},
|
|
4925
|
+
required: {
|
|
4926
|
+
type: "array",
|
|
4927
|
+
items: { type: "string" },
|
|
4928
|
+
uniqueItems: true
|
|
4929
|
+
}
|
|
4930
|
+
},
|
|
4931
|
+
$defs: {
|
|
4932
|
+
field: {
|
|
4933
|
+
oneOf: [
|
|
4934
|
+
{ $ref: "#/$defs/stringField" },
|
|
4935
|
+
{ $ref: "#/$defs/booleanField" },
|
|
4936
|
+
{ $ref: "#/$defs/stringArrayField" },
|
|
4937
|
+
{ $ref: "#/$defs/stringMapField" }
|
|
4938
|
+
]
|
|
4939
|
+
},
|
|
4940
|
+
stringField: {
|
|
4941
|
+
type: "object",
|
|
4942
|
+
required: ["type"],
|
|
4943
|
+
additionalProperties: false,
|
|
4944
|
+
properties: {
|
|
4945
|
+
type: { const: "string" },
|
|
4946
|
+
title: { type: "string" },
|
|
4947
|
+
description: { type: "string" },
|
|
4948
|
+
enum: {
|
|
4949
|
+
type: "array",
|
|
4950
|
+
items: { type: "string" },
|
|
4951
|
+
minItems: 1,
|
|
4952
|
+
uniqueItems: true
|
|
4953
|
+
},
|
|
4954
|
+
default: { type: "string" }
|
|
4955
|
+
}
|
|
4956
|
+
},
|
|
4957
|
+
booleanField: {
|
|
4958
|
+
type: "object",
|
|
4959
|
+
required: ["type"],
|
|
4960
|
+
additionalProperties: false,
|
|
4961
|
+
properties: {
|
|
4962
|
+
type: { const: "boolean" },
|
|
4963
|
+
title: { type: "string" },
|
|
4964
|
+
description: { type: "string" },
|
|
4965
|
+
default: { type: "boolean" }
|
|
4966
|
+
}
|
|
4967
|
+
},
|
|
4968
|
+
stringArrayField: {
|
|
4969
|
+
type: "object",
|
|
4970
|
+
required: ["type", "items"],
|
|
4971
|
+
additionalProperties: false,
|
|
4972
|
+
properties: {
|
|
4973
|
+
type: { const: "array" },
|
|
4974
|
+
items: {
|
|
4975
|
+
type: "object",
|
|
4976
|
+
required: ["type"],
|
|
4977
|
+
additionalProperties: false,
|
|
4978
|
+
properties: {
|
|
4979
|
+
type: { const: "string" }
|
|
4980
|
+
}
|
|
4981
|
+
},
|
|
4982
|
+
title: { type: "string" },
|
|
4983
|
+
description: { type: "string" },
|
|
4984
|
+
default: {
|
|
4985
|
+
type: "array",
|
|
4986
|
+
items: { type: "string" }
|
|
4987
|
+
}
|
|
4988
|
+
}
|
|
4989
|
+
},
|
|
4990
|
+
stringMapField: {
|
|
4991
|
+
type: "object",
|
|
4992
|
+
required: ["type", "additionalProperties"],
|
|
4993
|
+
additionalProperties: false,
|
|
4994
|
+
properties: {
|
|
4995
|
+
type: { const: "object" },
|
|
4996
|
+
additionalProperties: {
|
|
4997
|
+
type: "object",
|
|
4998
|
+
required: ["type"],
|
|
4999
|
+
additionalProperties: false,
|
|
5000
|
+
properties: {
|
|
5001
|
+
type: { const: "string" }
|
|
5002
|
+
}
|
|
5003
|
+
},
|
|
5004
|
+
title: { type: "string" },
|
|
5005
|
+
description: { type: "string" },
|
|
5006
|
+
default: {
|
|
5007
|
+
type: "object",
|
|
5008
|
+
additionalProperties: { type: "string" }
|
|
5009
|
+
}
|
|
5010
|
+
}
|
|
5011
|
+
}
|
|
5012
|
+
}
|
|
5013
|
+
};
|
|
5014
|
+
|
|
5015
|
+
// ../../packages/core/dist/plugins/context-validator.js
|
|
5016
|
+
var ajv2 = new Ajv20202({ allErrors: true, strict: false });
|
|
5017
|
+
addFormats2(ajv2);
|
|
5018
|
+
var compiledMetaSchema = ajv2.compile(context_meta_schema_default);
|
|
5019
|
+
|
|
4638
5020
|
// ../../packages/core/dist/drift/comparators.js
|
|
4639
5021
|
function compareToolPolicy(expected, actual) {
|
|
4640
5022
|
const findings = [];
|
|
@@ -4831,10 +5213,11 @@ export {
|
|
|
4831
5213
|
getChannel,
|
|
4832
5214
|
getAllChannelIds,
|
|
4833
5215
|
provisionStopHook,
|
|
5216
|
+
provisionIsolationHook,
|
|
4834
5217
|
getApiKey,
|
|
4835
5218
|
getActiveTeam,
|
|
4836
5219
|
setActiveTeam,
|
|
4837
|
-
|
|
5220
|
+
getHost,
|
|
4838
5221
|
requireHost,
|
|
4839
5222
|
exchangeApiKey,
|
|
4840
5223
|
ApiError,
|
|
@@ -4861,4 +5244,4 @@ export {
|
|
|
4861
5244
|
detectDrift,
|
|
4862
5245
|
provision
|
|
4863
5246
|
};
|
|
4864
|
-
//# sourceMappingURL=chunk-
|
|
5247
|
+
//# sourceMappingURL=chunk-VCKY6MN2.js.map
|