@integrity-labs/agt-cli 0.10.29 → 0.12.1
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 +6 -4
- package/dist/bin/agt.js.map +1 -1
- package/dist/{chunk-QU7FBXH3.js → chunk-M6FSTVGG.js} +2 -2
- package/dist/chunk-M6FSTVGG.js.map +1 -0
- package/dist/{chunk-6FGQFBJU.js → chunk-S5VHDDAJ.js} +879 -349
- package/dist/chunk-S5VHDDAJ.js.map +1 -0
- package/dist/{claude-scheduler-7PVWQHWU.js → claude-scheduler-CLSMSF5W.js} +2 -2
- package/dist/lib/manager-worker.js +340 -23
- package/dist/lib/manager-worker.js.map +1 -1
- package/mcp/index.js +23 -3
- package/mcp/slack-channel.js +191 -14
- package/package.json +1 -1
- package/dist/chunk-6FGQFBJU.js.map +0 -1
- package/dist/chunk-QU7FBXH3.js.map +0 -1
- /package/dist/{claude-scheduler-7PVWQHWU.js.map → claude-scheduler-CLSMSF5W.js.map} +0 -0
|
@@ -1,3 +1,216 @@
|
|
|
1
|
+
// ../../packages/core/dist/delivery/parse.js
|
|
2
|
+
function parseDeliveryTarget(raw) {
|
|
3
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
4
|
+
return {
|
|
5
|
+
ok: false,
|
|
6
|
+
code: "MALFORMED_DELIVERY_TARGET",
|
|
7
|
+
detail: "delivery_to must be a JSON object"
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
const obj = raw;
|
|
11
|
+
const kind = obj["kind"];
|
|
12
|
+
if (kind === "channel") {
|
|
13
|
+
return parseChannelTarget(obj);
|
|
14
|
+
}
|
|
15
|
+
if (kind === "dm") {
|
|
16
|
+
return parseDmTarget(obj);
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
ok: false,
|
|
20
|
+
code: "UNKNOWN_KIND",
|
|
21
|
+
detail: `delivery_to.kind must be 'channel' or 'dm' (got ${JSON.stringify(kind)})`
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function parseChannelTarget(obj) {
|
|
25
|
+
const provider = obj["provider"];
|
|
26
|
+
if (provider === "slack") {
|
|
27
|
+
const channelId = obj["channel_id"];
|
|
28
|
+
if (typeof channelId !== "string" || channelId.length === 0) {
|
|
29
|
+
return {
|
|
30
|
+
ok: false,
|
|
31
|
+
code: "MISSING_CHANNEL_ID",
|
|
32
|
+
detail: "channel:slack target requires a non-empty channel_id"
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return { kind: "channel", provider: "slack", channel_id: channelId };
|
|
36
|
+
}
|
|
37
|
+
if (provider === "telegram") {
|
|
38
|
+
const chatId = obj["chat_id"];
|
|
39
|
+
if (typeof chatId !== "string" || chatId.length === 0) {
|
|
40
|
+
return {
|
|
41
|
+
ok: false,
|
|
42
|
+
code: "MISSING_CHAT_ID",
|
|
43
|
+
detail: "channel:telegram target requires a non-empty chat_id"
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return { kind: "channel", provider: "telegram", chat_id: chatId };
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
ok: false,
|
|
50
|
+
code: "UNKNOWN_PROVIDER",
|
|
51
|
+
detail: `channel.provider must be 'slack' or 'telegram' (got ${JSON.stringify(provider)})`
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
var SUPPORTED_MEDIUMS = /* @__PURE__ */ new Set(["auto", "slack", "telegram"]);
|
|
55
|
+
var RESERVED_MEDIUMS = /* @__PURE__ */ new Set(["teams", "whatsapp", "imessage"]);
|
|
56
|
+
function parseDmTarget(obj) {
|
|
57
|
+
const personId = obj["person_id"];
|
|
58
|
+
if (typeof personId !== "string" || personId.length === 0) {
|
|
59
|
+
return {
|
|
60
|
+
ok: false,
|
|
61
|
+
code: "MISSING_PERSON_ID",
|
|
62
|
+
detail: "dm target requires a non-empty person_id"
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const followReportsTo = obj["follow_reports_to"];
|
|
66
|
+
if (typeof followReportsTo !== "boolean") {
|
|
67
|
+
return {
|
|
68
|
+
ok: false,
|
|
69
|
+
code: "MALFORMED_DELIVERY_TARGET",
|
|
70
|
+
detail: "dm.follow_reports_to must be a boolean"
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const medium = obj["medium"];
|
|
74
|
+
if (typeof medium !== "string") {
|
|
75
|
+
return {
|
|
76
|
+
ok: false,
|
|
77
|
+
code: "MALFORMED_DELIVERY_TARGET",
|
|
78
|
+
detail: "dm.medium must be a string"
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (RESERVED_MEDIUMS.has(medium)) {
|
|
82
|
+
return {
|
|
83
|
+
ok: false,
|
|
84
|
+
code: "DM_MEDIUM_NOT_SUPPORTED",
|
|
85
|
+
detail: `dm.medium '${medium}' is reserved but not yet dispatchable (ENG-4427)`
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (!SUPPORTED_MEDIUMS.has(medium)) {
|
|
89
|
+
return {
|
|
90
|
+
ok: false,
|
|
91
|
+
code: "UNKNOWN_MEDIUM",
|
|
92
|
+
detail: `dm.medium must be 'auto', 'slack', or 'telegram' (got ${JSON.stringify(medium)})`
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
kind: "dm",
|
|
97
|
+
person_id: personId,
|
|
98
|
+
follow_reports_to: followReportsTo,
|
|
99
|
+
medium
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function isParseError(v) {
|
|
103
|
+
return typeof v === "object" && v !== null && "ok" in v && v.ok === false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ../../packages/core/dist/delivery/format.js
|
|
107
|
+
function formatDmFooter(teamName, agentDisplayName) {
|
|
108
|
+
const team = teamName?.trim() || "unassigned team";
|
|
109
|
+
return `\u2014 scheduled by ${team} / ${agentDisplayName}`;
|
|
110
|
+
}
|
|
111
|
+
function appendDmFooter(body, teamName, agentDisplayName) {
|
|
112
|
+
const footer = formatDmFooter(teamName, agentDisplayName);
|
|
113
|
+
const trimmed = body.replace(/\s+$/, "");
|
|
114
|
+
if (trimmed.endsWith(footer))
|
|
115
|
+
return trimmed;
|
|
116
|
+
return `${trimmed}
|
|
117
|
+
|
|
118
|
+
${footer}`;
|
|
119
|
+
}
|
|
120
|
+
function formatForOpenClawCli(target) {
|
|
121
|
+
if (target.kind === "channel") {
|
|
122
|
+
if (target.provider === "slack") {
|
|
123
|
+
if (!target.channel_id) {
|
|
124
|
+
throw new Error("INVALID_DELIVERY_TARGET: slack channel target is missing channel_id");
|
|
125
|
+
}
|
|
126
|
+
return `channel:${target.channel_id}`;
|
|
127
|
+
}
|
|
128
|
+
if (!target.chat_id) {
|
|
129
|
+
throw new Error("INVALID_DELIVERY_TARGET: telegram channel target is missing chat_id");
|
|
130
|
+
}
|
|
131
|
+
return `chat:${target.chat_id}`;
|
|
132
|
+
}
|
|
133
|
+
throw new Error(`DM_NOT_SUPPORTED_ON_FRAMEWORK: dm targets can't be passed to openclaw cron add. See ENG-4423 \xA79.1 and the follow-up ENG-4431.`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ../../packages/core/dist/delivery/resolve.js
|
|
137
|
+
function resolveDmTarget(target, agent, people) {
|
|
138
|
+
if (target.kind === "channel") {
|
|
139
|
+
if (target.provider === "slack") {
|
|
140
|
+
return {
|
|
141
|
+
ok: true,
|
|
142
|
+
kind: "channel",
|
|
143
|
+
provider: "slack",
|
|
144
|
+
channel_id: target.channel_id ?? ""
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
ok: true,
|
|
149
|
+
kind: "channel",
|
|
150
|
+
provider: "telegram",
|
|
151
|
+
chat_id: target.chat_id ?? ""
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
const effectivePersonId = resolveEffectivePersonId(target, agent);
|
|
155
|
+
if ("ok" in effectivePersonId)
|
|
156
|
+
return effectivePersonId;
|
|
157
|
+
const person = people.get(effectivePersonId.person_id);
|
|
158
|
+
if (!person) {
|
|
159
|
+
return {
|
|
160
|
+
ok: false,
|
|
161
|
+
code: "DM_TARGET_PERSON_NOT_FOUND",
|
|
162
|
+
detail: `person ${effectivePersonId.person_id} not present in resolver people map`
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
const FALLBACK_ORDER = ["slack", "telegram"];
|
|
166
|
+
const preferredMedium = target.medium === "auto" ? null : target.medium;
|
|
167
|
+
const chosenMedium = preferredMedium ? agent.dm_capable_mediums.includes(preferredMedium) && personHasMedium(person, preferredMedium) ? preferredMedium : null : FALLBACK_ORDER.find((m) => agent.dm_capable_mediums.includes(m) && personHasMedium(person, m)) ?? null;
|
|
168
|
+
if (!chosenMedium) {
|
|
169
|
+
return {
|
|
170
|
+
ok: false,
|
|
171
|
+
code: "DM_TARGET_NO_REACHABLE_MEDIUM",
|
|
172
|
+
detail: `agent and person ${person.person_id} share no DM-capable medium`
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
if (chosenMedium === "slack") {
|
|
176
|
+
return {
|
|
177
|
+
ok: true,
|
|
178
|
+
kind: "dm",
|
|
179
|
+
medium: "slack",
|
|
180
|
+
slack_user_id: person.slack_user_id,
|
|
181
|
+
recipient_person_id: person.person_id
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
ok: true,
|
|
186
|
+
kind: "dm",
|
|
187
|
+
medium: "telegram",
|
|
188
|
+
telegram_chat_id: person.telegram_chat_id,
|
|
189
|
+
recipient_person_id: person.person_id
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function resolveEffectivePersonId(target, agent) {
|
|
193
|
+
if (target.follow_reports_to) {
|
|
194
|
+
if (agent.reports_to_type !== "person" || !agent.reports_to_person_id) {
|
|
195
|
+
return {
|
|
196
|
+
ok: false,
|
|
197
|
+
code: "DM_FOLLOW_TARGET_NOT_PERSON",
|
|
198
|
+
detail: "follow_reports_to=true but the agent has no person-typed reports_to at dispatch time"
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
return { person_id: agent.reports_to_person_id };
|
|
202
|
+
}
|
|
203
|
+
return { person_id: target.person_id };
|
|
204
|
+
}
|
|
205
|
+
function personHasMedium(person, medium) {
|
|
206
|
+
if (medium === "slack")
|
|
207
|
+
return Boolean(person.slack_user_id);
|
|
208
|
+
return Boolean(person.telegram_chat_id);
|
|
209
|
+
}
|
|
210
|
+
function isResolveError(v) {
|
|
211
|
+
return "ok" in v && v.ok === false;
|
|
212
|
+
}
|
|
213
|
+
|
|
1
214
|
// ../../packages/core/dist/provisioning/framework-registry.js
|
|
2
215
|
var adapters = /* @__PURE__ */ new Map();
|
|
3
216
|
function registerFramework(adapter) {
|
|
@@ -10,77 +223,6 @@ function getFramework(id) {
|
|
|
10
223
|
return adapter;
|
|
11
224
|
}
|
|
12
225
|
|
|
13
|
-
// ../../packages/core/dist/provisioning/frameworks/openclaw/index.js
|
|
14
|
-
import { execFile, spawn } from "child_process";
|
|
15
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync, chmodSync, renameSync, symlinkSync } from "fs";
|
|
16
|
-
import { join, dirname, resolve } from "path";
|
|
17
|
-
|
|
18
|
-
// ../../packages/core/dist/scheduled-tasks/prompt-wrapper.js
|
|
19
|
-
var EXECUTION_PREAMBLE = [
|
|
20
|
-
"[SCHEDULED TASK \u2014 EXECUTION MODE]",
|
|
21
|
-
"You are executing a scheduled task. There is no human user present; this is an automated run. Execute the instruction below and output the result directly.",
|
|
22
|
-
"",
|
|
23
|
-
"Rules for this run:",
|
|
24
|
-
`\u2022 Do not say "Sure", "I can help", "I'll draft", "Let me know", or any other conversational preamble or sign-off. Output the task result only.`,
|
|
25
|
-
'\u2022 Do not ask for clarification, confirmation, or missing details \u2014 no human will answer. If context is ambiguous or missing, choose the most reasonable default, proceed, and briefly note the assumption at the end of your output under a "[notes]" line.',
|
|
26
|
-
"\u2022 Do not announce what you are about to do. Just do it and produce the output.",
|
|
27
|
-
"",
|
|
28
|
-
"Instruction:"
|
|
29
|
-
].join("\n");
|
|
30
|
-
function wrapScheduledTaskPrompt(prompt) {
|
|
31
|
-
const trimmed = prompt.trim();
|
|
32
|
-
if (trimmed.length === 0)
|
|
33
|
-
return prompt;
|
|
34
|
-
if (trimmed === EXECUTION_PREAMBLE)
|
|
35
|
-
return prompt;
|
|
36
|
-
if (trimmed.startsWith(`${EXECUTION_PREAMBLE}
|
|
37
|
-
`))
|
|
38
|
-
return prompt;
|
|
39
|
-
if (trimmed.startsWith(`${EXECUTION_PREAMBLE}\r
|
|
40
|
-
`))
|
|
41
|
-
return prompt;
|
|
42
|
-
return `${EXECUTION_PREAMBLE}
|
|
43
|
-
${prompt}`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// ../../packages/core/dist/types/models.js
|
|
47
|
-
var DEFAULT_MODELS = {
|
|
48
|
-
primary: "openrouter/anthropic/claude-opus-4-6",
|
|
49
|
-
secondary: "openrouter/google/gemini-3.1-flash-lite-preview",
|
|
50
|
-
tertiary: "openrouter/openai/gpt-5.4-nano"
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// ../../packages/core/dist/channels/registry.js
|
|
54
|
-
var CHANNEL_REGISTRY = [
|
|
55
|
-
{ id: "slack", name: "Slack", securityTier: "standard", e2eEncrypted: false, auditTrail: true, publicExposureRisk: "Low" },
|
|
56
|
-
{ id: "msteams", name: "Microsoft Teams", securityTier: "standard", e2eEncrypted: false, auditTrail: true, publicExposureRisk: "Low" },
|
|
57
|
-
{ id: "telegram", name: "Telegram", securityTier: "standard", e2eEncrypted: "optional", auditTrail: "partial", publicExposureRisk: "Medium" },
|
|
58
|
-
{ id: "whatsapp", name: "WhatsApp", securityTier: "elevated", e2eEncrypted: true, auditTrail: false, publicExposureRisk: "Medium" },
|
|
59
|
-
{ id: "signal", name: "Signal", securityTier: "elevated", e2eEncrypted: true, auditTrail: false, publicExposureRisk: "Low" },
|
|
60
|
-
{ id: "discord", name: "Discord", securityTier: "limited", e2eEncrypted: false, auditTrail: false, publicExposureRisk: "High" },
|
|
61
|
-
{ id: "irc", name: "IRC", securityTier: "limited", e2eEncrypted: false, auditTrail: false, publicExposureRisk: "High" },
|
|
62
|
-
{ id: "matrix", name: "Matrix", securityTier: "standard", e2eEncrypted: "optional", auditTrail: true, publicExposureRisk: "Medium" },
|
|
63
|
-
{ id: "mattermost", name: "Mattermost", securityTier: "standard", e2eEncrypted: false, auditTrail: true, publicExposureRisk: "Low" },
|
|
64
|
-
{ id: "imessage", name: "iMessage", securityTier: "elevated", e2eEncrypted: true, auditTrail: false, publicExposureRisk: "Low" },
|
|
65
|
-
{ id: "google-chat", name: "Google Chat", securityTier: "standard", e2eEncrypted: false, auditTrail: true, publicExposureRisk: "Low" },
|
|
66
|
-
{ id: "nostr", name: "Nostr", securityTier: "limited", e2eEncrypted: "optional", auditTrail: false, publicExposureRisk: "High" },
|
|
67
|
-
{ id: "line", name: "LINE", securityTier: "standard", e2eEncrypted: "optional", auditTrail: "partial", publicExposureRisk: "Medium" },
|
|
68
|
-
{ id: "feishu", name: "Feishu", securityTier: "standard", e2eEncrypted: false, auditTrail: true, publicExposureRisk: "Low" },
|
|
69
|
-
{ id: "nextcloud-talk", name: "Nextcloud Talk", securityTier: "standard", e2eEncrypted: "optional", auditTrail: true, publicExposureRisk: "Low" },
|
|
70
|
-
{ id: "zalo", name: "Zalo", securityTier: "standard", e2eEncrypted: false, auditTrail: "partial", publicExposureRisk: "Medium" },
|
|
71
|
-
{ id: "tlon", name: "Tlon", securityTier: "standard", e2eEncrypted: true, auditTrail: true, publicExposureRisk: "Low" },
|
|
72
|
-
{ id: "bluebubbles", name: "BlueBubbles", securityTier: "limited", e2eEncrypted: false, auditTrail: false, publicExposureRisk: "Low" },
|
|
73
|
-
{ id: "beam", name: "Beam Protocol", securityTier: "elevated", e2eEncrypted: true, auditTrail: true, publicExposureRisk: "Low" },
|
|
74
|
-
{ id: "direct-chat", name: "Direct Chat", securityTier: "standard", e2eEncrypted: false, auditTrail: true, publicExposureRisk: "Low" }
|
|
75
|
-
];
|
|
76
|
-
var channelMap = new Map(CHANNEL_REGISTRY.map((c) => [c.id, c]));
|
|
77
|
-
function getChannel(id) {
|
|
78
|
-
return channelMap.get(id);
|
|
79
|
-
}
|
|
80
|
-
function getAllChannelIds() {
|
|
81
|
-
return CHANNEL_REGISTRY.map((c) => c.id);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
226
|
// ../../packages/core/dist/integrations/registry.js
|
|
85
227
|
var INTEGRATION_REGISTRY = [
|
|
86
228
|
{
|
|
@@ -99,7 +241,8 @@ var INTEGRATION_REGISTRY = [
|
|
|
99
241
|
binary: "linear",
|
|
100
242
|
env_key: "LINEAR_API_KEY",
|
|
101
243
|
skill_id: "linear-cli",
|
|
102
|
-
extra_env: { LINEAR_ISSUE_SORT: "priority" }
|
|
244
|
+
extra_env: { LINEAR_ISSUE_SORT: "priority" },
|
|
245
|
+
installer: "npm"
|
|
103
246
|
}
|
|
104
247
|
},
|
|
105
248
|
{
|
|
@@ -117,7 +260,8 @@ var INTEGRATION_REGISTRY = [
|
|
|
117
260
|
package: "gh",
|
|
118
261
|
binary: "gh",
|
|
119
262
|
env_key: "GITHUB_TOKEN",
|
|
120
|
-
skill_id: "gh-cli"
|
|
263
|
+
skill_id: "gh-cli",
|
|
264
|
+
installer: "brew"
|
|
121
265
|
}
|
|
122
266
|
},
|
|
123
267
|
{
|
|
@@ -143,7 +287,8 @@ var INTEGRATION_REGISTRY = [
|
|
|
143
287
|
package: "@googleworkspace/cli",
|
|
144
288
|
binary: "gws",
|
|
145
289
|
env_key: "GOOGLE_WORKSPACE_CLI_TOKEN",
|
|
146
|
-
skill_id: "gws-cli"
|
|
290
|
+
skill_id: "gws-cli",
|
|
291
|
+
installer: "npm"
|
|
147
292
|
}
|
|
148
293
|
},
|
|
149
294
|
{
|
|
@@ -169,7 +314,8 @@ var INTEGRATION_REGISTRY = [
|
|
|
169
314
|
cli_tool: {
|
|
170
315
|
package: "@tobilu/qmd",
|
|
171
316
|
binary: "qmd",
|
|
172
|
-
env_key: ""
|
|
317
|
+
env_key: "",
|
|
318
|
+
installer: "npm"
|
|
173
319
|
},
|
|
174
320
|
capabilities: [
|
|
175
321
|
{ id: "qmd:search", name: "Search Memory", description: "Semantic + keyword search over indexed memory files", access: "read" },
|
|
@@ -239,7 +385,10 @@ var INTEGRATION_REGISTRY = [
|
|
|
239
385
|
package: "pika-skills",
|
|
240
386
|
binary: "python3",
|
|
241
387
|
env_key: "PIKA_DEV_KEY",
|
|
242
|
-
skill_id: "pikastream-video-meeting"
|
|
388
|
+
skill_id: "pikastream-video-meeting",
|
|
389
|
+
// python3 is part of the host bootstrap baseline — skills are fetched
|
|
390
|
+
// separately. Don't try to auto-install python via npm/brew.
|
|
391
|
+
installer: "manual"
|
|
243
392
|
},
|
|
244
393
|
docs_url: "https://github.com/Pika-Labs/Pika-Skills"
|
|
245
394
|
},
|
|
@@ -258,10 +407,56 @@ var INTEGRATION_REGISTRY = [
|
|
|
258
407
|
cli_tool: {
|
|
259
408
|
package: "@anthropic-ai/claude-code",
|
|
260
409
|
binary: "claude",
|
|
261
|
-
env_key: "ANTHROPIC_API_KEY"
|
|
410
|
+
env_key: "ANTHROPIC_API_KEY",
|
|
411
|
+
// Claude Code is installed by the host bootstrap / operator setup —
|
|
412
|
+
// don't attempt a second install from the manager poll.
|
|
413
|
+
installer: "manual"
|
|
262
414
|
},
|
|
263
415
|
docs_url: "https://docs.anthropic.com/en/docs/claude-code"
|
|
264
416
|
},
|
|
417
|
+
{
|
|
418
|
+
id: "xurl",
|
|
419
|
+
name: "xurl (X API)",
|
|
420
|
+
category: "social",
|
|
421
|
+
description: "Official X (Twitter) API CLI \u2014 a curl-like tool for X's REST and streaming endpoints with OAuth 2.0 PKCE, OAuth 1.0a, and bearer-token auth",
|
|
422
|
+
supported_auth_types: ["api_key"],
|
|
423
|
+
capabilities: [
|
|
424
|
+
{ id: "xurl:read", name: "Read X API", description: "Call GET endpoints (users, tweets, timelines, search)", access: "read" },
|
|
425
|
+
{ id: "xurl:write", name: "Write X API", description: "Post tweets, reply, like, and retweet", access: "write" },
|
|
426
|
+
{ id: "xurl:stream", name: "Stream X API", description: "Consume filtered and sampled stream endpoints", access: "read" },
|
|
427
|
+
{ id: "xurl:media", name: "Upload Media", description: "Chunked upload of images and video to the X media endpoints", access: "write" }
|
|
428
|
+
],
|
|
429
|
+
cli_tool: {
|
|
430
|
+
package: "@xdevplatform/xurl",
|
|
431
|
+
binary: "xurl",
|
|
432
|
+
env_key: "X_BEARER_TOKEN",
|
|
433
|
+
skill_id: "xurl-cli",
|
|
434
|
+
// xurl is a Go binary distributed through homebrew tap; operator
|
|
435
|
+
// installs via `brew install xdevplatform/tap/xurl`. Mark manual
|
|
436
|
+
// for now — add a dedicated `tap` installer in a follow-up if more
|
|
437
|
+
// brew-tap tools land.
|
|
438
|
+
installer: "manual"
|
|
439
|
+
},
|
|
440
|
+
docs_url: "https://github.com/xdevplatform/xurl"
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
id: "coderabbit",
|
|
444
|
+
name: "CodeRabbit",
|
|
445
|
+
category: "code",
|
|
446
|
+
description: "AI-powered code review CLI for local and pre-push review runs",
|
|
447
|
+
supported_auth_types: ["none"],
|
|
448
|
+
capabilities: [
|
|
449
|
+
{ id: "coderabbit:review", name: "Review Changes", description: "Run a local CodeRabbit review over staged or branch changes", access: "read" }
|
|
450
|
+
],
|
|
451
|
+
cli_tool: {
|
|
452
|
+
package: "",
|
|
453
|
+
binary: "coderabbit",
|
|
454
|
+
env_key: "",
|
|
455
|
+
installer: "script",
|
|
456
|
+
script: "curl -fsSL https://cli.coderabbit.ai/install.sh | sh"
|
|
457
|
+
},
|
|
458
|
+
docs_url: "https://www.coderabbit.ai/cli"
|
|
459
|
+
},
|
|
265
460
|
{
|
|
266
461
|
id: "custom",
|
|
267
462
|
name: "Custom Integration",
|
|
@@ -278,6 +473,239 @@ function getIntegration(id) {
|
|
|
278
473
|
return integrationMap.get(id);
|
|
279
474
|
}
|
|
280
475
|
|
|
476
|
+
// ../../packages/core/dist/provisioning/frameworks/openclaw/index.js
|
|
477
|
+
import { execFile, spawn } from "child_process";
|
|
478
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync2, unlinkSync as unlinkSync2, chmodSync as chmodSync2, renameSync as renameSync2, symlinkSync } from "fs";
|
|
479
|
+
import { join as join2, dirname as dirname2, resolve } from "path";
|
|
480
|
+
|
|
481
|
+
// ../../packages/core/dist/scheduled-tasks/prompt-wrapper.js
|
|
482
|
+
var EXECUTION_PREAMBLE = [
|
|
483
|
+
"[SCHEDULED TASK \u2014 EXECUTION MODE]",
|
|
484
|
+
"You are executing a scheduled task. There is no human user present; this is an automated run. Execute the instruction below and output the result directly.",
|
|
485
|
+
"",
|
|
486
|
+
"Rules for this run:",
|
|
487
|
+
`\u2022 Do not say "Sure", "I can help", "I'll draft", "Let me know", or any other conversational preamble or sign-off. Output the task result only.`,
|
|
488
|
+
'\u2022 Do not ask for clarification, confirmation, or missing details \u2014 no human will answer. If context is ambiguous or missing, choose the most reasonable default, proceed, and briefly note the assumption at the end of your output under a "[notes]" line.',
|
|
489
|
+
"\u2022 Do not announce what you are about to do. Just do it and produce the output.",
|
|
490
|
+
"",
|
|
491
|
+
"Instruction:"
|
|
492
|
+
].join("\n");
|
|
493
|
+
function wrapScheduledTaskPrompt(prompt) {
|
|
494
|
+
const trimmed = prompt.trim();
|
|
495
|
+
if (trimmed.length === 0)
|
|
496
|
+
return prompt;
|
|
497
|
+
if (trimmed === EXECUTION_PREAMBLE)
|
|
498
|
+
return prompt;
|
|
499
|
+
if (trimmed.startsWith(`${EXECUTION_PREAMBLE}
|
|
500
|
+
`))
|
|
501
|
+
return prompt;
|
|
502
|
+
if (trimmed.startsWith(`${EXECUTION_PREAMBLE}\r
|
|
503
|
+
`))
|
|
504
|
+
return prompt;
|
|
505
|
+
return `${EXECUTION_PREAMBLE}
|
|
506
|
+
${prompt}`;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// ../../packages/core/dist/types/models.js
|
|
510
|
+
var DEFAULT_MODELS = {
|
|
511
|
+
primary: "openrouter/anthropic/claude-opus-4-6",
|
|
512
|
+
secondary: "openrouter/google/gemini-3.1-flash-lite-preview",
|
|
513
|
+
tertiary: "openrouter/openai/gpt-5.4-nano"
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
// ../../packages/core/dist/integrations/xurl-config.js
|
|
517
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "fs";
|
|
518
|
+
import { homedir } from "os";
|
|
519
|
+
import { dirname, join } from "path";
|
|
520
|
+
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
521
|
+
var XURL_FILE_MODE = 384;
|
|
522
|
+
var XURL_AGT_APP_PREFIX = "agt-";
|
|
523
|
+
function asString(v) {
|
|
524
|
+
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
525
|
+
}
|
|
526
|
+
function xurlAppNameFor(integration) {
|
|
527
|
+
const username = asString(integration.config?.["x_username"]);
|
|
528
|
+
const base = `${XURL_AGT_APP_PREFIX}${integration.definition_id}`;
|
|
529
|
+
return username ? `${base}-${username.toLowerCase()}` : base;
|
|
530
|
+
}
|
|
531
|
+
function buildXurlAppFromIntegration(integration) {
|
|
532
|
+
const cfg = integration.config ?? {};
|
|
533
|
+
const creds = integration.credentials ?? {};
|
|
534
|
+
const app = {
|
|
535
|
+
client_id: asString(cfg["client_id"]) ?? "",
|
|
536
|
+
client_secret: asString(cfg["client_secret"]) ?? ""
|
|
537
|
+
};
|
|
538
|
+
const apiKey = asString(creds["api_key"]);
|
|
539
|
+
if (integration.auth_type === "api_key" && apiKey) {
|
|
540
|
+
app.bearer_token = { type: "bearer", bearer: apiKey };
|
|
541
|
+
}
|
|
542
|
+
const accessToken = asString(creds["access_token"]);
|
|
543
|
+
if (integration.auth_type === "oauth2" && accessToken) {
|
|
544
|
+
const username = asString(cfg["x_username"]) ?? "default";
|
|
545
|
+
const expiresAt = asString(creds["token_expires_at"]);
|
|
546
|
+
const expirationTime = expiresAt ? Math.floor(Date.parse(expiresAt) / 1e3) : 0;
|
|
547
|
+
app.oauth2_tokens = {
|
|
548
|
+
[username]: {
|
|
549
|
+
type: "oauth2",
|
|
550
|
+
oauth2: {
|
|
551
|
+
access_token: accessToken,
|
|
552
|
+
refresh_token: asString(creds["refresh_token"]) ?? "",
|
|
553
|
+
expiration_time: Number.isFinite(expirationTime) ? expirationTime : 0
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
app.default_user = username;
|
|
558
|
+
}
|
|
559
|
+
const ck = asString(cfg["oauth1_consumer_key"]);
|
|
560
|
+
const cs = asString(cfg["oauth1_consumer_secret"]);
|
|
561
|
+
const at = asString(cfg["oauth1_access_token"]);
|
|
562
|
+
const ts = asString(cfg["oauth1_token_secret"]);
|
|
563
|
+
if (ck && cs && at && ts) {
|
|
564
|
+
app.oauth1_token = {
|
|
565
|
+
type: "oauth1",
|
|
566
|
+
oauth1: { access_token: at, token_secret: ts, consumer_key: ck, consumer_secret: cs }
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
if (!app.bearer_token && !app.oauth2_tokens && !app.oauth1_token) {
|
|
570
|
+
return null;
|
|
571
|
+
}
|
|
572
|
+
return app;
|
|
573
|
+
}
|
|
574
|
+
function mergeXurlStore(existing, agtApps) {
|
|
575
|
+
const apps = {};
|
|
576
|
+
for (const [name, app] of Object.entries(existing?.apps ?? {})) {
|
|
577
|
+
if (!name.startsWith(XURL_AGT_APP_PREFIX))
|
|
578
|
+
apps[name] = app;
|
|
579
|
+
}
|
|
580
|
+
for (const [name, app] of Object.entries(agtApps)) {
|
|
581
|
+
apps[name] = app;
|
|
582
|
+
}
|
|
583
|
+
let default_app = existing?.default_app;
|
|
584
|
+
if (default_app && !apps[default_app]) {
|
|
585
|
+
default_app = void 0;
|
|
586
|
+
}
|
|
587
|
+
if (!default_app) {
|
|
588
|
+
default_app = Object.keys(apps).find((n) => n.startsWith(XURL_AGT_APP_PREFIX));
|
|
589
|
+
}
|
|
590
|
+
const result = { apps };
|
|
591
|
+
if (default_app)
|
|
592
|
+
result.default_app = default_app;
|
|
593
|
+
return result;
|
|
594
|
+
}
|
|
595
|
+
function parseXurlStore(yaml) {
|
|
596
|
+
if (!yaml)
|
|
597
|
+
return null;
|
|
598
|
+
try {
|
|
599
|
+
const parsed = parseYaml(yaml);
|
|
600
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
601
|
+
return null;
|
|
602
|
+
const obj = parsed;
|
|
603
|
+
const hasApps = "apps" in obj;
|
|
604
|
+
const hasDefault = "default_app" in obj;
|
|
605
|
+
if (!hasApps && !hasDefault)
|
|
606
|
+
return null;
|
|
607
|
+
if (hasApps && obj["apps"] != null && (typeof obj["apps"] !== "object" || Array.isArray(obj["apps"]))) {
|
|
608
|
+
return null;
|
|
609
|
+
}
|
|
610
|
+
if (hasDefault && obj["default_app"] != null && typeof obj["default_app"] !== "string") {
|
|
611
|
+
return null;
|
|
612
|
+
}
|
|
613
|
+
return {
|
|
614
|
+
apps: obj["apps"] ?? {},
|
|
615
|
+
...typeof obj["default_app"] === "string" && obj["default_app"] ? { default_app: obj["default_app"] } : {}
|
|
616
|
+
};
|
|
617
|
+
} catch {
|
|
618
|
+
return null;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
function serializeXurlStore(store) {
|
|
622
|
+
return stringifyYaml(store);
|
|
623
|
+
}
|
|
624
|
+
function buildAgtXurlApps(integrations) {
|
|
625
|
+
const result = {};
|
|
626
|
+
for (const integration of integrations) {
|
|
627
|
+
if (integration.definition_id !== "xurl")
|
|
628
|
+
continue;
|
|
629
|
+
const app = buildXurlAppFromIntegration(integration);
|
|
630
|
+
if (app) {
|
|
631
|
+
result[xurlAppNameFor(integration)] = app;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
return result;
|
|
635
|
+
}
|
|
636
|
+
function getXurlStorePath() {
|
|
637
|
+
const home = process.env["HOME"] ?? process.env["USERPROFILE"] ?? homedir();
|
|
638
|
+
return join(home, ".xurl");
|
|
639
|
+
}
|
|
640
|
+
function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath()) {
|
|
641
|
+
const agtApps = buildAgtXurlApps(integrations);
|
|
642
|
+
if (Object.keys(agtApps).length === 0)
|
|
643
|
+
return null;
|
|
644
|
+
let existing = null;
|
|
645
|
+
if (existsSync(filePath)) {
|
|
646
|
+
let raw;
|
|
647
|
+
try {
|
|
648
|
+
raw = readFileSync(filePath, "utf-8");
|
|
649
|
+
} catch {
|
|
650
|
+
return null;
|
|
651
|
+
}
|
|
652
|
+
const parsed = parseXurlStore(raw);
|
|
653
|
+
if (!parsed && raw.trim().length > 0) {
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
656
|
+
existing = parsed;
|
|
657
|
+
}
|
|
658
|
+
const merged = mergeXurlStore(existing, agtApps);
|
|
659
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
660
|
+
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
661
|
+
writeFileSync(tmpPath, serializeXurlStore(merged), { mode: XURL_FILE_MODE });
|
|
662
|
+
try {
|
|
663
|
+
renameSync(tmpPath, filePath);
|
|
664
|
+
} catch (err) {
|
|
665
|
+
try {
|
|
666
|
+
unlinkSync(tmpPath);
|
|
667
|
+
} catch {
|
|
668
|
+
}
|
|
669
|
+
throw err;
|
|
670
|
+
}
|
|
671
|
+
try {
|
|
672
|
+
chmodSync(filePath, XURL_FILE_MODE);
|
|
673
|
+
} catch {
|
|
674
|
+
}
|
|
675
|
+
return filePath;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// ../../packages/core/dist/channels/registry.js
|
|
679
|
+
var CHANNEL_REGISTRY = [
|
|
680
|
+
{ id: "slack", name: "Slack", securityTier: "standard", e2eEncrypted: false, auditTrail: true, publicExposureRisk: "Low" },
|
|
681
|
+
{ id: "msteams", name: "Microsoft Teams", securityTier: "standard", e2eEncrypted: false, auditTrail: true, publicExposureRisk: "Low" },
|
|
682
|
+
{ id: "telegram", name: "Telegram", securityTier: "standard", e2eEncrypted: "optional", auditTrail: "partial", publicExposureRisk: "Medium" },
|
|
683
|
+
{ id: "whatsapp", name: "WhatsApp", securityTier: "elevated", e2eEncrypted: true, auditTrail: false, publicExposureRisk: "Medium" },
|
|
684
|
+
{ id: "signal", name: "Signal", securityTier: "elevated", e2eEncrypted: true, auditTrail: false, publicExposureRisk: "Low" },
|
|
685
|
+
{ id: "discord", name: "Discord", securityTier: "limited", e2eEncrypted: false, auditTrail: false, publicExposureRisk: "High" },
|
|
686
|
+
{ id: "irc", name: "IRC", securityTier: "limited", e2eEncrypted: false, auditTrail: false, publicExposureRisk: "High" },
|
|
687
|
+
{ id: "matrix", name: "Matrix", securityTier: "standard", e2eEncrypted: "optional", auditTrail: true, publicExposureRisk: "Medium" },
|
|
688
|
+
{ id: "mattermost", name: "Mattermost", securityTier: "standard", e2eEncrypted: false, auditTrail: true, publicExposureRisk: "Low" },
|
|
689
|
+
{ id: "imessage", name: "iMessage", securityTier: "elevated", e2eEncrypted: true, auditTrail: false, publicExposureRisk: "Low" },
|
|
690
|
+
{ id: "google-chat", name: "Google Chat", securityTier: "standard", e2eEncrypted: false, auditTrail: true, publicExposureRisk: "Low" },
|
|
691
|
+
{ id: "nostr", name: "Nostr", securityTier: "limited", e2eEncrypted: "optional", auditTrail: false, publicExposureRisk: "High" },
|
|
692
|
+
{ id: "line", name: "LINE", securityTier: "standard", e2eEncrypted: "optional", auditTrail: "partial", publicExposureRisk: "Medium" },
|
|
693
|
+
{ id: "feishu", name: "Feishu", securityTier: "standard", e2eEncrypted: false, auditTrail: true, publicExposureRisk: "Low" },
|
|
694
|
+
{ id: "nextcloud-talk", name: "Nextcloud Talk", securityTier: "standard", e2eEncrypted: "optional", auditTrail: true, publicExposureRisk: "Low" },
|
|
695
|
+
{ id: "zalo", name: "Zalo", securityTier: "standard", e2eEncrypted: false, auditTrail: "partial", publicExposureRisk: "Medium" },
|
|
696
|
+
{ id: "tlon", name: "Tlon", securityTier: "standard", e2eEncrypted: true, auditTrail: true, publicExposureRisk: "Low" },
|
|
697
|
+
{ id: "bluebubbles", name: "BlueBubbles", securityTier: "limited", e2eEncrypted: false, auditTrail: false, publicExposureRisk: "Low" },
|
|
698
|
+
{ id: "beam", name: "Beam Protocol", securityTier: "elevated", e2eEncrypted: true, auditTrail: true, publicExposureRisk: "Low" },
|
|
699
|
+
{ id: "direct-chat", name: "Direct Chat", securityTier: "standard", e2eEncrypted: false, auditTrail: true, publicExposureRisk: "Low" }
|
|
700
|
+
];
|
|
701
|
+
var channelMap = new Map(CHANNEL_REGISTRY.map((c) => [c.id, c]));
|
|
702
|
+
function getChannel(id) {
|
|
703
|
+
return channelMap.get(id);
|
|
704
|
+
}
|
|
705
|
+
function getAllChannelIds() {
|
|
706
|
+
return CHANNEL_REGISTRY.map((c) => c.id);
|
|
707
|
+
}
|
|
708
|
+
|
|
281
709
|
// ../../packages/core/dist/provisioning/frameworks/openclaw/mapper.js
|
|
282
710
|
function mapToolsToOpenClaw(tools) {
|
|
283
711
|
const allow = tools.tools.map((t) => t.id);
|
|
@@ -379,7 +807,7 @@ function mapIntegrationsToOpenClaw(integrations) {
|
|
|
379
807
|
}
|
|
380
808
|
var QMD_SEARCH_MODES = /* @__PURE__ */ new Set(["search", "vsearch", "query"]);
|
|
381
809
|
var QMD_CITATIONS = /* @__PURE__ */ new Set(["auto", "on", "off"]);
|
|
382
|
-
function
|
|
810
|
+
function asString2(v) {
|
|
383
811
|
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
384
812
|
}
|
|
385
813
|
function asBoolean(v) {
|
|
@@ -390,11 +818,11 @@ function asPositiveInt(v) {
|
|
|
390
818
|
}
|
|
391
819
|
function mapQmdConfig(cfg) {
|
|
392
820
|
const qmd = {};
|
|
393
|
-
const command =
|
|
821
|
+
const command = asString2(cfg.command);
|
|
394
822
|
if (command)
|
|
395
823
|
qmd.command = command;
|
|
396
824
|
if (cfg.searchMode !== void 0) {
|
|
397
|
-
const mode =
|
|
825
|
+
const mode = asString2(cfg.searchMode);
|
|
398
826
|
if (mode && QMD_SEARCH_MODES.has(mode)) {
|
|
399
827
|
qmd.searchMode = mode;
|
|
400
828
|
}
|
|
@@ -402,7 +830,7 @@ function mapQmdConfig(cfg) {
|
|
|
402
830
|
const includeDefaultMemory = asBoolean(cfg.includeDefaultMemory);
|
|
403
831
|
if (includeDefaultMemory !== void 0)
|
|
404
832
|
qmd.includeDefaultMemory = includeDefaultMemory;
|
|
405
|
-
const updateInterval =
|
|
833
|
+
const updateInterval = asString2(cfg.updateInterval);
|
|
406
834
|
const updateDebounceMs = asPositiveInt(cfg.updateDebounceMs);
|
|
407
835
|
if (updateInterval || updateDebounceMs !== void 0) {
|
|
408
836
|
qmd.update = {};
|
|
@@ -437,7 +865,7 @@ function mapQmdConfig(cfg) {
|
|
|
437
865
|
qmd
|
|
438
866
|
};
|
|
439
867
|
if (cfg.citations !== void 0) {
|
|
440
|
-
const citations =
|
|
868
|
+
const citations = asString2(cfg.citations);
|
|
441
869
|
if (citations && QMD_CITATIONS.has(citations)) {
|
|
442
870
|
result.citations = citations;
|
|
443
871
|
}
|
|
@@ -622,9 +1050,9 @@ function getHomeDir() {
|
|
|
622
1050
|
}
|
|
623
1051
|
function writeIntegrationTokenFile(codeName, integrations) {
|
|
624
1052
|
const homeDir = getHomeDir();
|
|
625
|
-
const dir =
|
|
626
|
-
const tokenFilePath =
|
|
627
|
-
const tmpFilePath =
|
|
1053
|
+
const dir = join2(homeDir, `.openclaw-${codeName}`);
|
|
1054
|
+
const tokenFilePath = join2(dir, ".tokens.json");
|
|
1055
|
+
const tmpFilePath = join2(dir, ".tokens.json.tmp");
|
|
628
1056
|
const tokens = {};
|
|
629
1057
|
for (const integration of integrations) {
|
|
630
1058
|
if (integration.auth_type !== "oauth2")
|
|
@@ -640,24 +1068,24 @@ function writeIntegrationTokenFile(codeName, integrations) {
|
|
|
640
1068
|
}
|
|
641
1069
|
if (Object.keys(tokens).length === 0)
|
|
642
1070
|
return;
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
1071
|
+
mkdirSync2(dir, { recursive: true });
|
|
1072
|
+
writeFileSync2(tmpFilePath, JSON.stringify(tokens, null, 2));
|
|
1073
|
+
chmodSync2(tmpFilePath, 384);
|
|
1074
|
+
renameSync2(tmpFilePath, tokenFilePath);
|
|
647
1075
|
}
|
|
648
1076
|
function getOpenClawConfigPath(profile) {
|
|
649
1077
|
const homeDir = getHomeDir();
|
|
650
1078
|
if (profile) {
|
|
651
|
-
return
|
|
1079
|
+
return join2(homeDir, `.openclaw-${profile}`, "openclaw.json");
|
|
652
1080
|
}
|
|
653
|
-
return
|
|
1081
|
+
return join2(homeDir, ".openclaw", "openclaw.json");
|
|
654
1082
|
}
|
|
655
1083
|
function modifyOpenClawConfig(fn, profile) {
|
|
656
1084
|
const configFile = getOpenClawConfigPath(profile);
|
|
657
1085
|
let originalContent;
|
|
658
1086
|
let config;
|
|
659
1087
|
try {
|
|
660
|
-
originalContent =
|
|
1088
|
+
originalContent = readFileSync2(configFile, "utf-8");
|
|
661
1089
|
config = JSON.parse(originalContent);
|
|
662
1090
|
} catch {
|
|
663
1091
|
return;
|
|
@@ -668,21 +1096,21 @@ function modifyOpenClawConfig(fn, profile) {
|
|
|
668
1096
|
const newContent = JSON.stringify(config, null, 2);
|
|
669
1097
|
if (newContent === originalContent)
|
|
670
1098
|
return;
|
|
671
|
-
|
|
1099
|
+
writeFileSync2(configFile, newContent);
|
|
672
1100
|
}
|
|
673
|
-
var AUGMENTED_DIR =
|
|
1101
|
+
var AUGMENTED_DIR = join2(getHomeDir(), ".augmented");
|
|
674
1102
|
function getGatewayPidPath(codeName) {
|
|
675
|
-
return
|
|
1103
|
+
return join2(AUGMENTED_DIR, codeName, "gateway.pid");
|
|
676
1104
|
}
|
|
677
1105
|
function getGatewayLogPath(codeName) {
|
|
678
|
-
return
|
|
1106
|
+
return join2(AUGMENTED_DIR, codeName, "gateway.log");
|
|
679
1107
|
}
|
|
680
1108
|
function getGatewayPortsPath() {
|
|
681
|
-
return
|
|
1109
|
+
return join2(AUGMENTED_DIR, "gateway-ports.json");
|
|
682
1110
|
}
|
|
683
1111
|
function readGatewayPid(codeName) {
|
|
684
1112
|
try {
|
|
685
|
-
const raw =
|
|
1113
|
+
const raw = readFileSync2(getGatewayPidPath(codeName), "utf-8").trim();
|
|
686
1114
|
const pid = parseInt(raw, 10);
|
|
687
1115
|
return isNaN(pid) ? null : pid;
|
|
688
1116
|
} catch {
|
|
@@ -730,14 +1158,14 @@ function execPromise(cmd, args) {
|
|
|
730
1158
|
}
|
|
731
1159
|
function readGatewayPorts() {
|
|
732
1160
|
try {
|
|
733
|
-
return JSON.parse(
|
|
1161
|
+
return JSON.parse(readFileSync2(getGatewayPortsPath(), "utf-8"));
|
|
734
1162
|
} catch {
|
|
735
1163
|
return {};
|
|
736
1164
|
}
|
|
737
1165
|
}
|
|
738
1166
|
function ensureCronEnabled(codeName) {
|
|
739
1167
|
const homeDir = getHomeDir();
|
|
740
|
-
const profileDir =
|
|
1168
|
+
const profileDir = join2(homeDir, `.openclaw-${codeName}`);
|
|
741
1169
|
modifyOpenClawConfig((config) => {
|
|
742
1170
|
const cron = config["cron"];
|
|
743
1171
|
if (cron?.["enabled"] === true)
|
|
@@ -745,7 +1173,7 @@ function ensureCronEnabled(codeName) {
|
|
|
745
1173
|
config["cron"] = {
|
|
746
1174
|
...cron ?? {},
|
|
747
1175
|
enabled: true,
|
|
748
|
-
store:
|
|
1176
|
+
store: join2(profileDir, "cron", "jobs.json"),
|
|
749
1177
|
maxConcurrentRuns: cron?.["maxConcurrentRuns"] ?? 1,
|
|
750
1178
|
retry: cron?.["retry"] ?? {
|
|
751
1179
|
maxAttempts: 3,
|
|
@@ -759,6 +1187,9 @@ var openclawAdapter = {
|
|
|
759
1187
|
id: "openclaw",
|
|
760
1188
|
label: "OpenClaw",
|
|
761
1189
|
cliBinary: "openclaw",
|
|
1190
|
+
getAgentDir(codeName) {
|
|
1191
|
+
return join2(getHomeDir(), ".augmented", codeName);
|
|
1192
|
+
},
|
|
762
1193
|
buildArtifacts(input) {
|
|
763
1194
|
const config = buildOpenClawConfig(input);
|
|
764
1195
|
const safeKnowledge = (input.knowledge ?? []).filter((k) => !/[/\\]|\.\./.test(k.slug));
|
|
@@ -998,11 +1429,11 @@ ${entry.content}`
|
|
|
998
1429
|
},
|
|
999
1430
|
writeAuthProfiles(codeName, profiles) {
|
|
1000
1431
|
const homeDir = getHomeDir();
|
|
1001
|
-
const authDir =
|
|
1002
|
-
const authFile =
|
|
1432
|
+
const authDir = join2(homeDir, `.openclaw-${codeName}`, "agents", codeName, "agent");
|
|
1433
|
+
const authFile = join2(authDir, "auth-profiles.json");
|
|
1003
1434
|
let existing = {};
|
|
1004
1435
|
try {
|
|
1005
|
-
existing = JSON.parse(
|
|
1436
|
+
existing = JSON.parse(readFileSync2(authFile, "utf-8"));
|
|
1006
1437
|
} catch {
|
|
1007
1438
|
}
|
|
1008
1439
|
const existingProfiles = existing["profiles"] ?? {};
|
|
@@ -1023,12 +1454,12 @@ ${entry.content}`
|
|
|
1023
1454
|
lastGood: existing["lastGood"] ?? {},
|
|
1024
1455
|
usageStats: existing["usageStats"] ?? {}
|
|
1025
1456
|
};
|
|
1026
|
-
|
|
1027
|
-
|
|
1457
|
+
mkdirSync2(authDir, { recursive: true });
|
|
1458
|
+
writeFileSync2(authFile, JSON.stringify(output, null, 2));
|
|
1028
1459
|
},
|
|
1029
1460
|
async startGateway(codeName, port) {
|
|
1030
|
-
const agentAugDir =
|
|
1031
|
-
|
|
1461
|
+
const agentAugDir = join2(AUGMENTED_DIR, codeName);
|
|
1462
|
+
mkdirSync2(agentAugDir, { recursive: true });
|
|
1032
1463
|
const logPath = getGatewayLogPath(codeName);
|
|
1033
1464
|
const pidPath = getGatewayPidPath(codeName);
|
|
1034
1465
|
const child = spawn("openclaw", ["--profile", codeName, "gateway", "--port", String(port)], {
|
|
@@ -1061,7 +1492,7 @@ ${entry.content}`
|
|
|
1061
1492
|
}
|
|
1062
1493
|
}
|
|
1063
1494
|
}
|
|
1064
|
-
|
|
1495
|
+
writeFileSync2(pidPath, String(gatewayPid));
|
|
1065
1496
|
return { pid: gatewayPid, port };
|
|
1066
1497
|
},
|
|
1067
1498
|
async stopGateway(codeName) {
|
|
@@ -1070,7 +1501,7 @@ ${entry.content}`
|
|
|
1070
1501
|
return false;
|
|
1071
1502
|
if (!isProcessAlive(pid)) {
|
|
1072
1503
|
try {
|
|
1073
|
-
|
|
1504
|
+
unlinkSync2(getGatewayPidPath(codeName));
|
|
1074
1505
|
} catch {
|
|
1075
1506
|
}
|
|
1076
1507
|
return false;
|
|
@@ -1085,7 +1516,7 @@ ${entry.content}`
|
|
|
1085
1516
|
await new Promise((r) => setTimeout(r, 200));
|
|
1086
1517
|
if (!isProcessAlive(pid)) {
|
|
1087
1518
|
try {
|
|
1088
|
-
|
|
1519
|
+
unlinkSync2(getGatewayPidPath(codeName));
|
|
1089
1520
|
} catch {
|
|
1090
1521
|
}
|
|
1091
1522
|
return true;
|
|
@@ -1096,7 +1527,7 @@ ${entry.content}`
|
|
|
1096
1527
|
} catch {
|
|
1097
1528
|
}
|
|
1098
1529
|
try {
|
|
1099
|
-
|
|
1530
|
+
unlinkSync2(getGatewayPidPath(codeName));
|
|
1100
1531
|
} catch {
|
|
1101
1532
|
}
|
|
1102
1533
|
return true;
|
|
@@ -1113,7 +1544,7 @@ ${entry.content}`
|
|
|
1113
1544
|
if (portPid) {
|
|
1114
1545
|
try {
|
|
1115
1546
|
const pidPath = getGatewayPidPath(codeName);
|
|
1116
|
-
|
|
1547
|
+
writeFileSync2(pidPath, String(portPid));
|
|
1117
1548
|
} catch {
|
|
1118
1549
|
}
|
|
1119
1550
|
return { running: true, pid: portPid, port };
|
|
@@ -1121,7 +1552,7 @@ ${entry.content}`
|
|
|
1121
1552
|
}
|
|
1122
1553
|
if (pid) {
|
|
1123
1554
|
try {
|
|
1124
|
-
|
|
1555
|
+
unlinkSync2(getGatewayPidPath(codeName));
|
|
1125
1556
|
} catch {
|
|
1126
1557
|
}
|
|
1127
1558
|
}
|
|
@@ -1129,18 +1560,18 @@ ${entry.content}`
|
|
|
1129
1560
|
},
|
|
1130
1561
|
seedProfileConfig(codeName) {
|
|
1131
1562
|
const homeDir = getHomeDir();
|
|
1132
|
-
const sharedConfigPath =
|
|
1133
|
-
const profileDir =
|
|
1134
|
-
const profileConfigPath =
|
|
1563
|
+
const sharedConfigPath = join2(homeDir, ".openclaw", "openclaw.json");
|
|
1564
|
+
const profileDir = join2(homeDir, `.openclaw-${codeName}`);
|
|
1565
|
+
const profileConfigPath = join2(profileDir, "openclaw.json");
|
|
1135
1566
|
let sharedConfig;
|
|
1136
1567
|
try {
|
|
1137
|
-
sharedConfig = JSON.parse(
|
|
1568
|
+
sharedConfig = JSON.parse(readFileSync2(sharedConfigPath, "utf-8"));
|
|
1138
1569
|
} catch {
|
|
1139
1570
|
sharedConfig = {};
|
|
1140
1571
|
}
|
|
1141
|
-
if (
|
|
1572
|
+
if (existsSync2(profileConfigPath)) {
|
|
1142
1573
|
try {
|
|
1143
|
-
const existing = JSON.parse(
|
|
1574
|
+
const existing = JSON.parse(readFileSync2(profileConfigPath, "utf-8"));
|
|
1144
1575
|
let changed = false;
|
|
1145
1576
|
if (!existing["gateway"]) {
|
|
1146
1577
|
if (sharedConfig["gateway"]) {
|
|
@@ -1158,7 +1589,7 @@ ${entry.content}`
|
|
|
1158
1589
|
changed = true;
|
|
1159
1590
|
}
|
|
1160
1591
|
if (changed) {
|
|
1161
|
-
|
|
1592
|
+
writeFileSync2(profileConfigPath, JSON.stringify(existing, null, 2));
|
|
1162
1593
|
}
|
|
1163
1594
|
} catch {
|
|
1164
1595
|
}
|
|
@@ -1173,7 +1604,7 @@ ${entry.content}`
|
|
|
1173
1604
|
const seedAgents = {};
|
|
1174
1605
|
if (agents["defaults"]) {
|
|
1175
1606
|
const defaults = JSON.parse(JSON.stringify(agents["defaults"]));
|
|
1176
|
-
const augmentedDir =
|
|
1607
|
+
const augmentedDir = join2(getHomeDir(), ".augmented", codeName, "provision");
|
|
1177
1608
|
defaults["workspace"] = augmentedDir;
|
|
1178
1609
|
seedAgents["defaults"] = defaults;
|
|
1179
1610
|
}
|
|
@@ -1197,21 +1628,21 @@ ${entry.content}`
|
|
|
1197
1628
|
profileConfig["bindings"] = [];
|
|
1198
1629
|
profileConfig["cron"] = {
|
|
1199
1630
|
enabled: true,
|
|
1200
|
-
store:
|
|
1631
|
+
store: join2(profileDir, "cron", "jobs.json"),
|
|
1201
1632
|
maxConcurrentRuns: 1,
|
|
1202
1633
|
retry: {
|
|
1203
1634
|
maxAttempts: 3,
|
|
1204
1635
|
backoffMs: [6e4, 12e4, 3e5]
|
|
1205
1636
|
}
|
|
1206
1637
|
};
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
const agentAuthDir =
|
|
1210
|
-
const mainAgentDir =
|
|
1638
|
+
mkdirSync2(profileDir, { recursive: true });
|
|
1639
|
+
writeFileSync2(profileConfigPath, JSON.stringify(profileConfig, null, 2));
|
|
1640
|
+
const agentAuthDir = join2(profileDir, "agents", codeName, "agent");
|
|
1641
|
+
const mainAgentDir = join2(profileDir, "agents", "main", "agent");
|
|
1211
1642
|
try {
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
if (!
|
|
1643
|
+
mkdirSync2(agentAuthDir, { recursive: true });
|
|
1644
|
+
mkdirSync2(join2(profileDir, "agents", "main"), { recursive: true });
|
|
1645
|
+
if (!existsSync2(mainAgentDir)) {
|
|
1215
1646
|
symlinkSync(agentAuthDir, mainAgentDir, "dir");
|
|
1216
1647
|
}
|
|
1217
1648
|
} catch {
|
|
@@ -1221,11 +1652,11 @@ ${entry.content}`
|
|
|
1221
1652
|
const integrationConfig = mapIntegrationsToOpenClaw(integrations);
|
|
1222
1653
|
if (Object.keys(integrationConfig.authProfiles).length > 0) {
|
|
1223
1654
|
const homeDir = getHomeDir();
|
|
1224
|
-
const authDir =
|
|
1225
|
-
const authFile =
|
|
1655
|
+
const authDir = join2(homeDir, `.openclaw-${codeName}`, "agents", codeName, "agent");
|
|
1656
|
+
const authFile = join2(authDir, "auth-profiles.json");
|
|
1226
1657
|
let existing = {};
|
|
1227
1658
|
try {
|
|
1228
|
-
existing = JSON.parse(
|
|
1659
|
+
existing = JSON.parse(readFileSync2(authFile, "utf-8"));
|
|
1229
1660
|
} catch {
|
|
1230
1661
|
}
|
|
1231
1662
|
const existingProfiles = existing["profiles"] ?? {};
|
|
@@ -1236,8 +1667,8 @@ ${entry.content}`
|
|
|
1236
1667
|
lastGood: existing["lastGood"] ?? {},
|
|
1237
1668
|
usageStats: existing["usageStats"] ?? {}
|
|
1238
1669
|
};
|
|
1239
|
-
|
|
1240
|
-
|
|
1670
|
+
mkdirSync2(authDir, { recursive: true });
|
|
1671
|
+
writeFileSync2(authFile, JSON.stringify(output, null, 2));
|
|
1241
1672
|
}
|
|
1242
1673
|
if (integrationConfig.toolAllow.length > 0) {
|
|
1243
1674
|
modifyOpenClawConfig((config) => {
|
|
@@ -1320,12 +1751,12 @@ ${entry.content}`
|
|
|
1320
1751
|
if (integrationConfig.memory) {
|
|
1321
1752
|
modifyOpenClawConfig((config) => {
|
|
1322
1753
|
const homeDir = getHomeDir();
|
|
1323
|
-
const qmdHome =
|
|
1754
|
+
const qmdHome = join2(homeDir, ".openclaw", "agents", codeName, "qmd");
|
|
1324
1755
|
const topEnv = config["env"] ?? {};
|
|
1325
1756
|
topEnv["QMD_HOME"] = qmdHome;
|
|
1326
1757
|
config["env"] = topEnv;
|
|
1327
1758
|
config["memory"] = integrationConfig.memory;
|
|
1328
|
-
|
|
1759
|
+
mkdirSync2(qmdHome, { recursive: true });
|
|
1329
1760
|
return true;
|
|
1330
1761
|
}, codeName);
|
|
1331
1762
|
} else {
|
|
@@ -1348,6 +1779,7 @@ ${entry.content}`
|
|
|
1348
1779
|
return changed;
|
|
1349
1780
|
}, codeName);
|
|
1350
1781
|
}
|
|
1782
|
+
writeXurlStoreForIntegrations(integrations);
|
|
1351
1783
|
writeIntegrationTokenFile(codeName, integrations);
|
|
1352
1784
|
},
|
|
1353
1785
|
writeTokenFile(codeName, integrations) {
|
|
@@ -1355,11 +1787,11 @@ ${entry.content}`
|
|
|
1355
1787
|
},
|
|
1356
1788
|
installSkillFiles(codeName, skillId, files) {
|
|
1357
1789
|
const homeDir = getHomeDir();
|
|
1358
|
-
const skillDir =
|
|
1790
|
+
const skillDir = join2(homeDir, `.openclaw-${codeName}`, "skills", skillId);
|
|
1359
1791
|
for (const file of files) {
|
|
1360
|
-
const filePath =
|
|
1361
|
-
|
|
1362
|
-
|
|
1792
|
+
const filePath = join2(skillDir, file.relativePath);
|
|
1793
|
+
mkdirSync2(dirname2(filePath), { recursive: true });
|
|
1794
|
+
writeFileSync2(filePath, file.content);
|
|
1363
1795
|
}
|
|
1364
1796
|
},
|
|
1365
1797
|
writeMcpServer(codeName, serverId, config) {
|
|
@@ -1401,9 +1833,9 @@ ${entry.content}`
|
|
|
1401
1833
|
}, codeName);
|
|
1402
1834
|
},
|
|
1403
1835
|
executePluginHook(ctx) {
|
|
1404
|
-
const agentDir =
|
|
1405
|
-
const projectDir =
|
|
1406
|
-
|
|
1836
|
+
const agentDir = join2(AUGMENTED_DIR, ctx.codeName);
|
|
1837
|
+
const projectDir = join2(agentDir, "project");
|
|
1838
|
+
mkdirSync2(agentDir, { recursive: true });
|
|
1407
1839
|
const startedAt = Date.now();
|
|
1408
1840
|
return new Promise((resolve3) => {
|
|
1409
1841
|
const child = execFile("bash", ["-c", ctx.script], {
|
|
@@ -1435,7 +1867,7 @@ ${entry.content}`
|
|
|
1435
1867
|
readGatewayToken(codeName) {
|
|
1436
1868
|
const homeDir = getHomeDir();
|
|
1437
1869
|
try {
|
|
1438
|
-
const config = JSON.parse(
|
|
1870
|
+
const config = JSON.parse(readFileSync2(join2(homeDir, `.openclaw-${codeName}`, "openclaw.json"), "utf-8"));
|
|
1439
1871
|
return config?.gateway?.auth?.token;
|
|
1440
1872
|
} catch {
|
|
1441
1873
|
return void 0;
|
|
@@ -1524,8 +1956,19 @@ ${entry.content}`
|
|
|
1524
1956
|
if (!useMainSession) {
|
|
1525
1957
|
if (task.delivery_mode === "announce") {
|
|
1526
1958
|
addArgs.push("--announce");
|
|
1527
|
-
if (task.delivery_to) {
|
|
1528
|
-
|
|
1959
|
+
if (task.delivery_to !== null && task.delivery_to !== void 0) {
|
|
1960
|
+
let toArg = null;
|
|
1961
|
+
if (typeof task.delivery_to === "string") {
|
|
1962
|
+
toArg = task.delivery_to;
|
|
1963
|
+
} else {
|
|
1964
|
+
const parsed = parseDeliveryTarget(task.delivery_to);
|
|
1965
|
+
if (isParseError(parsed)) {
|
|
1966
|
+
throw new Error(`OpenClaw cron add: malformed delivery_to on task '${task.name}': ${parsed.code} \u2014 ${parsed.detail}`);
|
|
1967
|
+
}
|
|
1968
|
+
toArg = formatForOpenClawCli(parsed);
|
|
1969
|
+
}
|
|
1970
|
+
if (toArg)
|
|
1971
|
+
addArgs.push("--to", toArg);
|
|
1529
1972
|
}
|
|
1530
1973
|
if (task.delivery_channel && task.delivery_channel !== "last") {
|
|
1531
1974
|
addArgs.push("--channel", task.delivery_channel);
|
|
@@ -1565,14 +2008,14 @@ ${entry.content}`
|
|
|
1565
2008
|
registerFramework(openclawAdapter);
|
|
1566
2009
|
|
|
1567
2010
|
// ../../packages/core/dist/provisioning/frameworks/nemoclaw/index.js
|
|
1568
|
-
import { readFileSync as
|
|
1569
|
-
import { join as
|
|
1570
|
-
import { homedir } from "os";
|
|
2011
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync3, chmodSync as chmodSync3 } from "fs";
|
|
2012
|
+
import { join as join3, dirname as dirname3, resolve as resolve2, sep } from "path";
|
|
2013
|
+
import { homedir as homedir2 } from "os";
|
|
1571
2014
|
import { execFile as execFile2 } from "child_process";
|
|
1572
2015
|
import { promisify } from "util";
|
|
1573
2016
|
var execAsync = promisify(execFile2);
|
|
1574
2017
|
function getHomeDir2() {
|
|
1575
|
-
return
|
|
2018
|
+
return homedir2();
|
|
1576
2019
|
}
|
|
1577
2020
|
function validateCodeName(codeName) {
|
|
1578
2021
|
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(codeName)) {
|
|
@@ -1581,16 +2024,16 @@ function validateCodeName(codeName) {
|
|
|
1581
2024
|
}
|
|
1582
2025
|
function getConfigDir(codeName) {
|
|
1583
2026
|
validateCodeName(codeName);
|
|
1584
|
-
return
|
|
2027
|
+
return join3(getHomeDir2(), ".augmented", codeName, "nemoclaw");
|
|
1585
2028
|
}
|
|
1586
2029
|
function ensureDir(dir) {
|
|
1587
|
-
|
|
2030
|
+
mkdirSync3(dir, { recursive: true });
|
|
1588
2031
|
}
|
|
1589
2032
|
function readDeploymentTarget(codeName) {
|
|
1590
|
-
const targetFile =
|
|
1591
|
-
if (!
|
|
2033
|
+
const targetFile = join3(getConfigDir(codeName), "target.json");
|
|
2034
|
+
if (!existsSync3(targetFile))
|
|
1592
2035
|
return null;
|
|
1593
|
-
return JSON.parse(
|
|
2036
|
+
return JSON.parse(readFileSync3(targetFile, "utf-8"));
|
|
1594
2037
|
}
|
|
1595
2038
|
async function sshExec(target, command, options) {
|
|
1596
2039
|
const sshArgs = [
|
|
@@ -1628,7 +2071,7 @@ async function syncLocalAssetsToRemote(codeName) {
|
|
|
1628
2071
|
if (!target)
|
|
1629
2072
|
return;
|
|
1630
2073
|
const localAssetsDir = getConfigDir(codeName);
|
|
1631
|
-
if (!
|
|
2074
|
+
if (!existsSync3(localAssetsDir))
|
|
1632
2075
|
return;
|
|
1633
2076
|
const remoteDir = `/opt/augmented/${codeName}`;
|
|
1634
2077
|
const remoteAssetsDir = `${remoteDir}/assets`;
|
|
@@ -1653,6 +2096,9 @@ var nemoClawAdapter = {
|
|
|
1653
2096
|
id: "nemoclaw",
|
|
1654
2097
|
label: "NemoClaw (Cloud)",
|
|
1655
2098
|
cliBinary: "nemoclaw",
|
|
2099
|
+
getAgentDir(codeName) {
|
|
2100
|
+
return join3(homedir2(), ".augmented", codeName);
|
|
2101
|
+
},
|
|
1656
2102
|
buildArtifacts(input) {
|
|
1657
2103
|
const blueprint = {
|
|
1658
2104
|
agentCodeName: input.agent.code_name,
|
|
@@ -1722,13 +2168,13 @@ var nemoClawAdapter = {
|
|
|
1722
2168
|
if (!target)
|
|
1723
2169
|
return false;
|
|
1724
2170
|
try {
|
|
1725
|
-
const blueprintPath =
|
|
2171
|
+
const blueprintPath = join3(teamDir, "blueprint.json");
|
|
1726
2172
|
const remoteDir = `/opt/augmented/${codeName}`;
|
|
1727
2173
|
await sshExec(target, `mkdir -p ${remoteDir}`);
|
|
1728
2174
|
await scpPush(target, blueprintPath, `${remoteDir}/blueprint.json`);
|
|
1729
2175
|
for (const file of ["CHARTER.md", "TOOLS.md"]) {
|
|
1730
|
-
const localPath =
|
|
1731
|
-
if (
|
|
2176
|
+
const localPath = join3(teamDir, file);
|
|
2177
|
+
if (existsSync3(localPath)) {
|
|
1732
2178
|
await scpPush(target, localPath, `${remoteDir}/${file}`);
|
|
1733
2179
|
}
|
|
1734
2180
|
}
|
|
@@ -1756,8 +2202,8 @@ var nemoClawAdapter = {
|
|
|
1756
2202
|
writeAuthProfiles(codeName, profiles) {
|
|
1757
2203
|
const configDir = getConfigDir(codeName);
|
|
1758
2204
|
ensureDir(configDir);
|
|
1759
|
-
const authFile =
|
|
1760
|
-
const existing =
|
|
2205
|
+
const authFile = join3(configDir, "auth-profiles.json");
|
|
2206
|
+
const existing = existsSync3(authFile) ? JSON.parse(readFileSync3(authFile, "utf-8")) : {};
|
|
1761
2207
|
for (const profile of profiles) {
|
|
1762
2208
|
const previous = existing[profile.profile_name];
|
|
1763
2209
|
existing[profile.profile_name] = {
|
|
@@ -1768,7 +2214,7 @@ var nemoClawAdapter = {
|
|
|
1768
2214
|
...profile.metadata
|
|
1769
2215
|
};
|
|
1770
2216
|
}
|
|
1771
|
-
|
|
2217
|
+
writeFileSync3(authFile, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
1772
2218
|
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
1773
2219
|
});
|
|
1774
2220
|
},
|
|
@@ -1790,7 +2236,7 @@ var nemoClawAdapter = {
|
|
|
1790
2236
|
}
|
|
1791
2237
|
const configDir = getConfigDir(codeName);
|
|
1792
2238
|
ensureDir(configDir);
|
|
1793
|
-
|
|
2239
|
+
writeFileSync3(join3(configDir, "gateway.json"), JSON.stringify({
|
|
1794
2240
|
pid: result.pid,
|
|
1795
2241
|
port: result.port,
|
|
1796
2242
|
host: target.host,
|
|
@@ -1826,8 +2272,8 @@ var nemoClawAdapter = {
|
|
|
1826
2272
|
},
|
|
1827
2273
|
readGatewayToken(codeName) {
|
|
1828
2274
|
try {
|
|
1829
|
-
const gatewayFile =
|
|
1830
|
-
const config = JSON.parse(
|
|
2275
|
+
const gatewayFile = join3(getConfigDir(codeName), "gateway.json");
|
|
2276
|
+
const config = JSON.parse(readFileSync3(gatewayFile, "utf-8"));
|
|
1831
2277
|
return config?.token;
|
|
1832
2278
|
} catch {
|
|
1833
2279
|
return void 0;
|
|
@@ -1836,7 +2282,7 @@ var nemoClawAdapter = {
|
|
|
1836
2282
|
writeIntegrations(codeName, integrations) {
|
|
1837
2283
|
const configDir = getConfigDir(codeName);
|
|
1838
2284
|
ensureDir(configDir);
|
|
1839
|
-
const envFile =
|
|
2285
|
+
const envFile = join3(configDir, "integration-env.json");
|
|
1840
2286
|
const env2 = {};
|
|
1841
2287
|
for (const integration of integrations) {
|
|
1842
2288
|
const apiKey = integration.credentials.api_key ?? integration.credentials.access_token;
|
|
@@ -1845,7 +2291,7 @@ var nemoClawAdapter = {
|
|
|
1845
2291
|
env2[envKey] = apiKey;
|
|
1846
2292
|
}
|
|
1847
2293
|
}
|
|
1848
|
-
|
|
2294
|
+
writeFileSync3(envFile, JSON.stringify(env2, null, 2), { mode: 384 });
|
|
1849
2295
|
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
1850
2296
|
});
|
|
1851
2297
|
},
|
|
@@ -1859,8 +2305,8 @@ var nemoClawAdapter = {
|
|
|
1859
2305
|
if (!filePath.startsWith(`${skillDir}${sep}`)) {
|
|
1860
2306
|
throw new Error(`Invalid skill path: ${file.relativePath}`);
|
|
1861
2307
|
}
|
|
1862
|
-
|
|
1863
|
-
|
|
2308
|
+
mkdirSync3(dirname3(filePath), { recursive: true });
|
|
2309
|
+
writeFileSync3(filePath, file.content);
|
|
1864
2310
|
}
|
|
1865
2311
|
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
1866
2312
|
});
|
|
@@ -1868,11 +2314,11 @@ var nemoClawAdapter = {
|
|
|
1868
2314
|
writeMcpServer(codeName, serverId, config) {
|
|
1869
2315
|
const configDir = getConfigDir(codeName);
|
|
1870
2316
|
ensureDir(configDir);
|
|
1871
|
-
const mcpFile =
|
|
1872
|
-
const existing =
|
|
2317
|
+
const mcpFile = join3(configDir, "mcp-servers.json");
|
|
2318
|
+
const existing = existsSync3(mcpFile) ? JSON.parse(readFileSync3(mcpFile, "utf-8")) : {};
|
|
1873
2319
|
existing[serverId] = config;
|
|
1874
|
-
|
|
1875
|
-
|
|
2320
|
+
writeFileSync3(mcpFile, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
2321
|
+
chmodSync3(mcpFile, 384);
|
|
1876
2322
|
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
1877
2323
|
});
|
|
1878
2324
|
},
|
|
@@ -1882,8 +2328,8 @@ var nemoClawAdapter = {
|
|
|
1882
2328
|
return;
|
|
1883
2329
|
const configDir = getConfigDir(codeName);
|
|
1884
2330
|
ensureDir(configDir);
|
|
1885
|
-
const tasksFile =
|
|
1886
|
-
|
|
2331
|
+
const tasksFile = join3(configDir, "scheduled-tasks.json");
|
|
2332
|
+
writeFileSync3(tasksFile, JSON.stringify(tasks, null, 2));
|
|
1887
2333
|
try {
|
|
1888
2334
|
const remoteDir = `/opt/augmented/${codeName}`;
|
|
1889
2335
|
await scpPush(target, tasksFile, `${remoteDir}/scheduled-tasks.json`);
|
|
@@ -1908,9 +2354,9 @@ function extractAllowedDomains(input) {
|
|
|
1908
2354
|
registerFramework(nemoClawAdapter);
|
|
1909
2355
|
|
|
1910
2356
|
// ../../packages/core/dist/provisioning/frameworks/claudecode/index.js
|
|
1911
|
-
import { readFileSync as
|
|
1912
|
-
import { join as
|
|
1913
|
-
import { homedir as
|
|
2357
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync4, chmodSync as chmodSync4, readdirSync, rmSync, copyFileSync } from "fs";
|
|
2358
|
+
import { join as join4, relative, dirname as dirname4 } from "path";
|
|
2359
|
+
import { homedir as homedir3 } from "os";
|
|
1914
2360
|
import { execFile as execFile3 } from "child_process";
|
|
1915
2361
|
|
|
1916
2362
|
// ../../packages/core/dist/provisioning/frameworks/claudecode/identity.js
|
|
@@ -2234,94 +2680,152 @@ function assertSafeRelativePath(relativePath) {
|
|
|
2234
2680
|
}
|
|
2235
2681
|
}
|
|
2236
2682
|
function getHomeDir3() {
|
|
2237
|
-
return process.env["HOME"] ?? process.env["USERPROFILE"] ??
|
|
2683
|
+
return process.env["HOME"] ?? process.env["USERPROFILE"] ?? homedir3();
|
|
2238
2684
|
}
|
|
2239
2685
|
function getAgentDir(codeName) {
|
|
2240
2686
|
assertValidCodeName(codeName);
|
|
2241
|
-
return
|
|
2687
|
+
return join4(getHomeDir3(), ".augmented", codeName);
|
|
2688
|
+
}
|
|
2689
|
+
var migratedCodeNames = /* @__PURE__ */ new Set();
|
|
2690
|
+
function migrateLegacyClaudecodeDir(codeName, log) {
|
|
2691
|
+
assertValidCodeName(codeName);
|
|
2692
|
+
if (migratedCodeNames.has(codeName))
|
|
2693
|
+
return;
|
|
2694
|
+
const legacyRoot = join4(getHomeDir3(), ".augmented", codeName, "claudecode");
|
|
2695
|
+
if (!existsSync4(legacyRoot)) {
|
|
2696
|
+
migratedCodeNames.add(codeName);
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
const newRoot = getAgentDir(codeName);
|
|
2700
|
+
const emit = (msg) => {
|
|
2701
|
+
log?.(msg);
|
|
2702
|
+
};
|
|
2703
|
+
try {
|
|
2704
|
+
const walkAndMigrate = (srcDir, destDir) => {
|
|
2705
|
+
mkdirSync4(destDir, { recursive: true });
|
|
2706
|
+
for (const entry of readdirSync(srcDir, { withFileTypes: true })) {
|
|
2707
|
+
const src = join4(srcDir, entry.name);
|
|
2708
|
+
const dest = join4(destDir, entry.name);
|
|
2709
|
+
if (entry.isDirectory()) {
|
|
2710
|
+
walkAndMigrate(src, dest);
|
|
2711
|
+
continue;
|
|
2712
|
+
}
|
|
2713
|
+
if (entry.name === ".mcp.json" && existsSync4(dest)) {
|
|
2714
|
+
try {
|
|
2715
|
+
const oldCfg = JSON.parse(readFileSync4(src, "utf-8"));
|
|
2716
|
+
const newCfg = JSON.parse(readFileSync4(dest, "utf-8"));
|
|
2717
|
+
const merged = { mcpServers: { ...oldCfg.mcpServers ?? {}, ...newCfg.mcpServers ?? {} } };
|
|
2718
|
+
writeFileSync4(dest, JSON.stringify(merged, null, 2));
|
|
2719
|
+
emit(`[migrate] '${codeName}' merged .mcp.json (${Object.keys(merged.mcpServers).length} servers)`);
|
|
2720
|
+
} catch (err) {
|
|
2721
|
+
throw new Error(`Failed merging .mcp.json (${src} \u2192 ${dest}): ${err.message}`);
|
|
2722
|
+
}
|
|
2723
|
+
continue;
|
|
2724
|
+
}
|
|
2725
|
+
if (!existsSync4(dest)) {
|
|
2726
|
+
copyFileSync(src, dest);
|
|
2727
|
+
continue;
|
|
2728
|
+
}
|
|
2729
|
+
try {
|
|
2730
|
+
const srcStat = readFileSync4(src);
|
|
2731
|
+
const destStat = readFileSync4(dest);
|
|
2732
|
+
if (!srcStat.equals(destStat)) {
|
|
2733
|
+
}
|
|
2734
|
+
} catch (err) {
|
|
2735
|
+
throw new Error(`Failed comparing ${src} vs ${dest}: ${err.message}`);
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
};
|
|
2739
|
+
walkAndMigrate(legacyRoot, newRoot);
|
|
2740
|
+
rmSync(legacyRoot, { recursive: true, force: true });
|
|
2741
|
+
emit(`[migrate] '${codeName}': collapsed ~/.augmented/${codeName}/claudecode/ into ~/.augmented/${codeName}/`);
|
|
2742
|
+
migratedCodeNames.add(codeName);
|
|
2743
|
+
} catch (err) {
|
|
2744
|
+
emit(`[migrate] '${codeName}': migration failed \u2014 leaving legacy dir in place: ${err.message}`);
|
|
2745
|
+
}
|
|
2242
2746
|
}
|
|
2243
2747
|
function getProjectDir(codeName) {
|
|
2244
2748
|
assertValidCodeName(codeName);
|
|
2245
|
-
return
|
|
2749
|
+
return join4(getHomeDir3(), ".augmented", codeName, "project");
|
|
2246
2750
|
}
|
|
2247
2751
|
function syncMcpToProject(codeName) {
|
|
2248
2752
|
const agentDir = getAgentDir(codeName);
|
|
2249
2753
|
const projectDir = getProjectDir(codeName);
|
|
2250
|
-
const provisionMcpPath =
|
|
2251
|
-
const projectMcpPath =
|
|
2754
|
+
const provisionMcpPath = join4(agentDir, "provision", ".mcp.json");
|
|
2755
|
+
const projectMcpPath = join4(projectDir, ".mcp.json");
|
|
2252
2756
|
try {
|
|
2253
|
-
const content =
|
|
2254
|
-
|
|
2255
|
-
|
|
2757
|
+
const content = readFileSync4(provisionMcpPath, "utf-8");
|
|
2758
|
+
mkdirSync4(projectDir, { recursive: true });
|
|
2759
|
+
writeFileSync4(projectMcpPath, content);
|
|
2256
2760
|
} catch {
|
|
2257
2761
|
}
|
|
2258
2762
|
}
|
|
2259
2763
|
function deployArtifactsToProject(codeName, provisionDir) {
|
|
2260
2764
|
const projectDir = getProjectDir(codeName);
|
|
2261
|
-
|
|
2765
|
+
mkdirSync4(projectDir, { recursive: true });
|
|
2262
2766
|
const artifactFiles = ["CLAUDE.md", "settings.json", ".mcp.json", "CHARTER.md", "TOOLS.md"];
|
|
2263
2767
|
const SKILLS_START = "<!-- AGT:SKILLS_INDEX_START -->";
|
|
2264
2768
|
const SKILLS_END = "<!-- AGT:SKILLS_INDEX_END -->";
|
|
2265
2769
|
for (const file of artifactFiles) {
|
|
2266
|
-
const src =
|
|
2267
|
-
const dest =
|
|
2770
|
+
const src = join4(provisionDir, file);
|
|
2771
|
+
const dest = join4(projectDir, file);
|
|
2268
2772
|
try {
|
|
2269
|
-
const srcContent =
|
|
2270
|
-
if (file === "CLAUDE.md" &&
|
|
2271
|
-
const destContent =
|
|
2773
|
+
const srcContent = readFileSync4(src, "utf-8");
|
|
2774
|
+
if (file === "CLAUDE.md" && existsSync4(dest)) {
|
|
2775
|
+
const destContent = readFileSync4(dest, "utf-8");
|
|
2272
2776
|
const stripIndex = (s) => s.replace(new RegExp(`${SKILLS_START}[\\s\\S]*?${SKILLS_END}`), "").trimEnd();
|
|
2273
2777
|
if (stripIndex(srcContent) === stripIndex(destContent))
|
|
2274
2778
|
continue;
|
|
2275
2779
|
const indexMatch = destContent.match(new RegExp(`${SKILLS_START}[\\s\\S]*?${SKILLS_END}`));
|
|
2276
2780
|
if (indexMatch) {
|
|
2277
|
-
|
|
2781
|
+
writeFileSync4(dest, srcContent.trimEnd() + "\n\n" + indexMatch[0] + "\n");
|
|
2278
2782
|
continue;
|
|
2279
2783
|
}
|
|
2280
2784
|
}
|
|
2281
|
-
|
|
2785
|
+
writeFileSync4(dest, srcContent);
|
|
2282
2786
|
} catch {
|
|
2283
2787
|
}
|
|
2284
2788
|
}
|
|
2285
|
-
const skillsDir =
|
|
2286
|
-
const destSkillsDir =
|
|
2789
|
+
const skillsDir = join4(provisionDir, ".claude", "skills");
|
|
2790
|
+
const destSkillsDir = join4(projectDir, ".claude", "skills");
|
|
2287
2791
|
try {
|
|
2288
|
-
if (
|
|
2289
|
-
const srcFolders =
|
|
2792
|
+
if (existsSync4(destSkillsDir)) {
|
|
2793
|
+
const srcFolders = existsSync4(skillsDir) ? new Set(readdirSync(skillsDir)) : /* @__PURE__ */ new Set();
|
|
2290
2794
|
for (const folder of readdirSync(destSkillsDir)) {
|
|
2291
2795
|
if (folder.startsWith("knowledge-") || folder === "core-knowledge" && !srcFolders.has(folder)) {
|
|
2292
2796
|
try {
|
|
2293
|
-
rmSync(
|
|
2797
|
+
rmSync(join4(destSkillsDir, folder), { recursive: true });
|
|
2294
2798
|
} catch {
|
|
2295
2799
|
}
|
|
2296
2800
|
}
|
|
2297
2801
|
}
|
|
2298
2802
|
}
|
|
2299
|
-
if (
|
|
2803
|
+
if (existsSync4(skillsDir)) {
|
|
2300
2804
|
for (const skillFolder of readdirSync(skillsDir)) {
|
|
2301
|
-
const srcSkillFile =
|
|
2302
|
-
if (!
|
|
2805
|
+
const srcSkillFile = join4(skillsDir, skillFolder, "SKILL.md");
|
|
2806
|
+
if (!existsSync4(srcSkillFile))
|
|
2303
2807
|
continue;
|
|
2304
|
-
const destFolder =
|
|
2305
|
-
const destFile =
|
|
2306
|
-
const srcContent =
|
|
2808
|
+
const destFolder = join4(destSkillsDir, skillFolder);
|
|
2809
|
+
const destFile = join4(destFolder, "SKILL.md");
|
|
2810
|
+
const srcContent = readFileSync4(srcSkillFile, "utf-8");
|
|
2307
2811
|
try {
|
|
2308
|
-
if (
|
|
2812
|
+
if (existsSync4(destFile) && readFileSync4(destFile, "utf-8") === srcContent)
|
|
2309
2813
|
continue;
|
|
2310
2814
|
} catch {
|
|
2311
2815
|
}
|
|
2312
|
-
|
|
2313
|
-
|
|
2816
|
+
mkdirSync4(destFolder, { recursive: true });
|
|
2817
|
+
writeFileSync4(destFile, srcContent);
|
|
2314
2818
|
}
|
|
2315
2819
|
}
|
|
2316
2820
|
} catch {
|
|
2317
2821
|
}
|
|
2318
|
-
const agentMcpPath =
|
|
2319
|
-
const projectMcpPath =
|
|
2822
|
+
const agentMcpPath = join4(getAgentDir(codeName), "provision", ".mcp.json");
|
|
2823
|
+
const projectMcpPath = join4(projectDir, ".mcp.json");
|
|
2320
2824
|
try {
|
|
2321
|
-
const agentMcp = JSON.parse(
|
|
2825
|
+
const agentMcp = JSON.parse(readFileSync4(agentMcpPath, "utf-8"));
|
|
2322
2826
|
let projectMcp;
|
|
2323
2827
|
try {
|
|
2324
|
-
projectMcp = JSON.parse(
|
|
2828
|
+
projectMcp = JSON.parse(readFileSync4(projectMcpPath, "utf-8"));
|
|
2325
2829
|
} catch {
|
|
2326
2830
|
projectMcp = { mcpServers: {} };
|
|
2327
2831
|
}
|
|
@@ -2332,23 +2836,23 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
2332
2836
|
return !(entry && typeof entry["url"] === "string" && entry["url"].startsWith("/"));
|
|
2333
2837
|
}));
|
|
2334
2838
|
projectMcp["mcpServers"] = { ...stripRelativeUrls(projectServers), ...stripRelativeUrls(agentServers) };
|
|
2335
|
-
|
|
2839
|
+
writeFileSync4(projectMcpPath, JSON.stringify(projectMcp, null, 2));
|
|
2336
2840
|
} catch {
|
|
2337
2841
|
}
|
|
2338
2842
|
const agentDir = getAgentDir(codeName);
|
|
2339
2843
|
for (const envFile of [".env", ".env.integrations"]) {
|
|
2340
2844
|
try {
|
|
2341
|
-
const content =
|
|
2342
|
-
|
|
2845
|
+
const content = readFileSync4(join4(agentDir, envFile), "utf-8");
|
|
2846
|
+
writeFileSync4(join4(projectDir, envFile), content);
|
|
2343
2847
|
} catch {
|
|
2344
2848
|
}
|
|
2345
2849
|
}
|
|
2346
2850
|
}
|
|
2347
2851
|
function provisionStopHook(codeName) {
|
|
2348
2852
|
const projectDir = getProjectDir(codeName);
|
|
2349
|
-
const claudeDir =
|
|
2350
|
-
|
|
2351
|
-
const hookScriptPath =
|
|
2853
|
+
const claudeDir = join4(projectDir, ".claude");
|
|
2854
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
2855
|
+
const hookScriptPath = join4(claudeDir, "agt-stop-hook.sh");
|
|
2352
2856
|
const hookScript = [
|
|
2353
2857
|
"#!/bin/bash",
|
|
2354
2858
|
"# Auto-generated by Augmented \u2014 captures persistent session task results.",
|
|
@@ -2378,11 +2882,11 @@ function provisionStopHook(codeName) {
|
|
|
2378
2882
|
"esac",
|
|
2379
2883
|
"exit 0"
|
|
2380
2884
|
].join("\n") + "\n";
|
|
2381
|
-
|
|
2382
|
-
const settingsPath =
|
|
2885
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
2886
|
+
const settingsPath = join4(claudeDir, "settings.local.json");
|
|
2383
2887
|
let settings = {};
|
|
2384
2888
|
try {
|
|
2385
|
-
settings = JSON.parse(
|
|
2889
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
2386
2890
|
} catch {
|
|
2387
2891
|
}
|
|
2388
2892
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -2397,17 +2901,17 @@ function provisionStopHook(codeName) {
|
|
|
2397
2901
|
}
|
|
2398
2902
|
];
|
|
2399
2903
|
settings["hooks"] = hooks;
|
|
2400
|
-
|
|
2904
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
2401
2905
|
}
|
|
2402
2906
|
function provisionIsolationHook(codeName) {
|
|
2403
2907
|
const projectDir = getProjectDir(codeName);
|
|
2404
|
-
const claudeDir =
|
|
2405
|
-
|
|
2908
|
+
const claudeDir = join4(projectDir, ".claude");
|
|
2909
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
2406
2910
|
const homeDir = getHomeDir3();
|
|
2407
|
-
const augmentedBase =
|
|
2408
|
-
const ownAgentDir =
|
|
2409
|
-
const logFile =
|
|
2410
|
-
const hookScriptPath =
|
|
2911
|
+
const augmentedBase = join4(homeDir, ".augmented");
|
|
2912
|
+
const ownAgentDir = join4(augmentedBase, codeName);
|
|
2913
|
+
const logFile = join4(ownAgentDir, "isolation.log");
|
|
2914
|
+
const hookScriptPath = join4(claudeDir, "agt-isolation-hook.sh");
|
|
2411
2915
|
const hookScript = [
|
|
2412
2916
|
"#!/bin/bash",
|
|
2413
2917
|
"# Auto-generated by Augmented \u2014 prevents cross-agent file access.",
|
|
@@ -2460,11 +2964,11 @@ function provisionIsolationHook(codeName) {
|
|
|
2460
2964
|
"",
|
|
2461
2965
|
"exit 0"
|
|
2462
2966
|
].join("\n") + "\n";
|
|
2463
|
-
|
|
2464
|
-
const settingsPath =
|
|
2967
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
2968
|
+
const settingsPath = join4(claudeDir, "settings.local.json");
|
|
2465
2969
|
let settings = {};
|
|
2466
2970
|
try {
|
|
2467
|
-
settings = JSON.parse(
|
|
2971
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
2468
2972
|
} catch {
|
|
2469
2973
|
}
|
|
2470
2974
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -2479,13 +2983,13 @@ function provisionIsolationHook(codeName) {
|
|
|
2479
2983
|
}
|
|
2480
2984
|
];
|
|
2481
2985
|
settings["hooks"] = hooks;
|
|
2482
|
-
|
|
2986
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
2483
2987
|
}
|
|
2484
2988
|
function modifyJsonConfig(filePath, fn) {
|
|
2485
2989
|
let originalContent;
|
|
2486
2990
|
let config;
|
|
2487
2991
|
try {
|
|
2488
|
-
originalContent =
|
|
2992
|
+
originalContent = readFileSync4(filePath, "utf-8");
|
|
2489
2993
|
config = JSON.parse(originalContent);
|
|
2490
2994
|
} catch {
|
|
2491
2995
|
return;
|
|
@@ -2496,7 +3000,7 @@ function modifyJsonConfig(filePath, fn) {
|
|
|
2496
3000
|
const newContent = JSON.stringify(config, null, 2);
|
|
2497
3001
|
if (newContent === originalContent)
|
|
2498
3002
|
return;
|
|
2499
|
-
|
|
3003
|
+
writeFileSync4(filePath, newContent);
|
|
2500
3004
|
}
|
|
2501
3005
|
function buildSettingsJson(input) {
|
|
2502
3006
|
const { agent, charterFrontmatter, toolsFrontmatter } = input;
|
|
@@ -2524,7 +3028,7 @@ function buildSettingsJson(input) {
|
|
|
2524
3028
|
// Agent's project dir (CLAUDE.md, settings.json, etc.)
|
|
2525
3029
|
agentDir,
|
|
2526
3030
|
// Agent's config dir (.env, schedules, registration)
|
|
2527
|
-
|
|
3031
|
+
join4(homeDir, ".augmented", "_mcp"),
|
|
2528
3032
|
// Shared MCP binaries
|
|
2529
3033
|
"/tmp"
|
|
2530
3034
|
// Temp files
|
|
@@ -2533,7 +3037,7 @@ function buildSettingsJson(input) {
|
|
|
2533
3037
|
}
|
|
2534
3038
|
function buildMcpJson(input) {
|
|
2535
3039
|
const mcpServers = {};
|
|
2536
|
-
const localMcpPath =
|
|
3040
|
+
const localMcpPath = join4(getHomeDir3(), ".augmented", "_mcp", "index.js");
|
|
2537
3041
|
mcpServers["augmented"] = {
|
|
2538
3042
|
command: "node",
|
|
2539
3043
|
args: [localMcpPath],
|
|
@@ -2595,6 +3099,11 @@ var claudeCodeAdapter = {
|
|
|
2595
3099
|
id: "claude-code",
|
|
2596
3100
|
label: "Claude Code",
|
|
2597
3101
|
cliBinary: "claude",
|
|
3102
|
+
getAgentDir(codeName) {
|
|
3103
|
+
const agentDir = getAgentDir(codeName);
|
|
3104
|
+
migrateLegacyClaudecodeDir(codeName);
|
|
3105
|
+
return agentDir;
|
|
3106
|
+
},
|
|
2598
3107
|
buildArtifacts(input) {
|
|
2599
3108
|
const integrationSummaries = (input.integrations ?? []).map((i) => {
|
|
2600
3109
|
const def = INTEGRATION_REGISTRY.find((d) => d.id === i.definition_id);
|
|
@@ -2667,18 +3176,23 @@ ${sections}`
|
|
|
2667
3176
|
},
|
|
2668
3177
|
async getRegisteredAgents(_profile) {
|
|
2669
3178
|
const homeDir = getHomeDir3();
|
|
2670
|
-
const augDir =
|
|
3179
|
+
const augDir = join4(homeDir, ".augmented");
|
|
2671
3180
|
const agents = /* @__PURE__ */ new Set();
|
|
2672
3181
|
try {
|
|
2673
3182
|
const { readdirSync: readdirSync2, statSync } = await import("fs");
|
|
2674
3183
|
const entries = readdirSync2(augDir);
|
|
2675
3184
|
for (const entry of entries) {
|
|
2676
|
-
|
|
3185
|
+
if (entry.startsWith("_") || entry.startsWith("."))
|
|
3186
|
+
continue;
|
|
3187
|
+
const agentRoot = join4(augDir, entry);
|
|
2677
3188
|
try {
|
|
2678
|
-
if (statSync(
|
|
2679
|
-
|
|
2680
|
-
}
|
|
3189
|
+
if (!statSync(agentRoot).isDirectory())
|
|
3190
|
+
continue;
|
|
2681
3191
|
} catch {
|
|
3192
|
+
continue;
|
|
3193
|
+
}
|
|
3194
|
+
if (existsSync4(join4(agentRoot, "registration.json"))) {
|
|
3195
|
+
agents.add(entry);
|
|
2682
3196
|
}
|
|
2683
3197
|
}
|
|
2684
3198
|
} catch {
|
|
@@ -2689,16 +3203,16 @@ ${sections}`
|
|
|
2689
3203
|
try {
|
|
2690
3204
|
const agentDir = getAgentDir(codeName);
|
|
2691
3205
|
const projectDir = getProjectDir(codeName);
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
3206
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
3207
|
+
mkdirSync4(projectDir, { recursive: true });
|
|
3208
|
+
writeFileSync4(join4(agentDir, "registration.json"), JSON.stringify({
|
|
2695
3209
|
code_name: codeName,
|
|
2696
3210
|
team_dir: teamDir,
|
|
2697
3211
|
project_dir: projectDir,
|
|
2698
3212
|
framework: "claude-code",
|
|
2699
3213
|
registered_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
2700
3214
|
}, null, 2));
|
|
2701
|
-
if (
|
|
3215
|
+
if (existsSync4(teamDir)) {
|
|
2702
3216
|
deployArtifactsToProject(codeName, teamDir);
|
|
2703
3217
|
}
|
|
2704
3218
|
return true;
|
|
@@ -2709,10 +3223,10 @@ ${sections}`
|
|
|
2709
3223
|
async deregisterAgent(codeName) {
|
|
2710
3224
|
try {
|
|
2711
3225
|
const agentDir = getAgentDir(codeName);
|
|
2712
|
-
const regFile =
|
|
2713
|
-
if (
|
|
2714
|
-
const { unlinkSync:
|
|
2715
|
-
|
|
3226
|
+
const regFile = join4(agentDir, "registration.json");
|
|
3227
|
+
if (existsSync4(regFile)) {
|
|
3228
|
+
const { unlinkSync: unlinkSync3 } = await import("fs");
|
|
3229
|
+
unlinkSync3(regFile);
|
|
2716
3230
|
}
|
|
2717
3231
|
return true;
|
|
2718
3232
|
} catch {
|
|
@@ -2721,7 +3235,7 @@ ${sections}`
|
|
|
2721
3235
|
},
|
|
2722
3236
|
writeAuthProfiles(codeName, profiles) {
|
|
2723
3237
|
const agentDir = getAgentDir(codeName);
|
|
2724
|
-
|
|
3238
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
2725
3239
|
const envLines = ["# Augmented auth profiles \u2014 auto-generated, do not edit"];
|
|
2726
3240
|
for (const p of profiles) {
|
|
2727
3241
|
if (!p.api_key)
|
|
@@ -2730,9 +3244,9 @@ ${sections}`
|
|
|
2730
3244
|
envLines.push(`${envKey}=${p.api_key}`);
|
|
2731
3245
|
}
|
|
2732
3246
|
if (envLines.length > 1) {
|
|
2733
|
-
const envPath =
|
|
2734
|
-
|
|
2735
|
-
|
|
3247
|
+
const envPath = join4(agentDir, ".env");
|
|
3248
|
+
writeFileSync4(envPath, envLines.join("\n") + "\n");
|
|
3249
|
+
chmodSync4(envPath, SECRET_FILE_MODE);
|
|
2736
3250
|
}
|
|
2737
3251
|
},
|
|
2738
3252
|
// Claude Code has no gateway process — methods intentionally omitted
|
|
@@ -2756,21 +3270,21 @@ ${sections}`
|
|
|
2756
3270
|
},
|
|
2757
3271
|
writeChannelCredentials(codeName, channelId, config, options) {
|
|
2758
3272
|
const agentDir = getAgentDir(codeName);
|
|
2759
|
-
|
|
3273
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
2760
3274
|
const isPersistent = options?.sessionMode === "persistent";
|
|
2761
3275
|
if (isPersistent && (channelId === "telegram" || channelId === "discord" || channelId === "slack")) {
|
|
2762
|
-
const channelDir =
|
|
2763
|
-
|
|
3276
|
+
const channelDir = join4(getHomeDir3(), ".claude", "channels", channelId);
|
|
3277
|
+
mkdirSync4(channelDir, { recursive: true });
|
|
2764
3278
|
if (channelId === "telegram") {
|
|
2765
3279
|
const botToken = config["bot_token"];
|
|
2766
3280
|
if (botToken) {
|
|
2767
|
-
|
|
3281
|
+
writeFileSync4(join4(channelDir, ".env"), `TELEGRAM_BOT_TOKEN=${botToken}
|
|
2768
3282
|
`);
|
|
2769
3283
|
}
|
|
2770
3284
|
} else if (channelId === "discord") {
|
|
2771
3285
|
const botToken = config["bot_token"];
|
|
2772
3286
|
if (botToken) {
|
|
2773
|
-
|
|
3287
|
+
writeFileSync4(join4(channelDir, ".env"), `DISCORD_BOT_TOKEN=${botToken}
|
|
2774
3288
|
`);
|
|
2775
3289
|
}
|
|
2776
3290
|
} else if (channelId === "slack") {
|
|
@@ -2778,30 +3292,32 @@ ${sections}`
|
|
|
2778
3292
|
const appToken = config["app_token"];
|
|
2779
3293
|
const threadAutoFollow = config["thread_auto_follow"];
|
|
2780
3294
|
if (botToken) {
|
|
2781
|
-
const localSlackChannel =
|
|
3295
|
+
const localSlackChannel = join4(getHomeDir3(), ".augmented", "_mcp", "slack-channel.js");
|
|
2782
3296
|
const slackEntry = {
|
|
2783
|
-
command:
|
|
2784
|
-
args:
|
|
3297
|
+
command: existsSync4(localSlackChannel) ? "node" : "npx",
|
|
3298
|
+
args: existsSync4(localSlackChannel) ? [localSlackChannel] : ["-y", "@augmented/claude-code-channel-slack"],
|
|
2785
3299
|
env: {
|
|
2786
3300
|
SLACK_BOT_TOKEN: botToken,
|
|
2787
3301
|
...appToken ? { SLACK_APP_TOKEN: appToken } : {},
|
|
2788
|
-
...threadAutoFollow && threadAutoFollow !== "off" ? { SLACK_THREAD_AUTO_FOLLOW: threadAutoFollow } : {}
|
|
3302
|
+
...threadAutoFollow && threadAutoFollow !== "off" ? { SLACK_THREAD_AUTO_FOLLOW: threadAutoFollow } : {},
|
|
3303
|
+
// Scopes slack.upload_file uploads to the agent's project dir.
|
|
3304
|
+
AGT_AGENT_CODE_NAME: codeName
|
|
2789
3305
|
}
|
|
2790
3306
|
};
|
|
2791
|
-
const provisionMcpPath =
|
|
2792
|
-
|
|
3307
|
+
const provisionMcpPath = join4(agentDir, "provision", ".mcp.json");
|
|
3308
|
+
mkdirSync4(dirname4(provisionMcpPath), { recursive: true });
|
|
2793
3309
|
let mcpConfig2 = { mcpServers: {} };
|
|
2794
3310
|
try {
|
|
2795
|
-
mcpConfig2 = JSON.parse(
|
|
3311
|
+
mcpConfig2 = JSON.parse(readFileSync4(provisionMcpPath, "utf-8"));
|
|
2796
3312
|
if (!mcpConfig2.mcpServers)
|
|
2797
3313
|
mcpConfig2.mcpServers = {};
|
|
2798
3314
|
} catch {
|
|
2799
3315
|
}
|
|
2800
3316
|
mcpConfig2.mcpServers["slack"] = slackEntry;
|
|
2801
|
-
|
|
3317
|
+
writeFileSync4(provisionMcpPath, JSON.stringify(mcpConfig2, null, 2));
|
|
2802
3318
|
syncMcpToProject(codeName);
|
|
2803
|
-
const staleChannelsPath =
|
|
2804
|
-
if (
|
|
3319
|
+
const staleChannelsPath = join4(getProjectDir(codeName), ".mcp-channels.json");
|
|
3320
|
+
if (existsSync4(staleChannelsPath)) {
|
|
2805
3321
|
try {
|
|
2806
3322
|
rmSync(staleChannelsPath, { force: true });
|
|
2807
3323
|
} catch {
|
|
@@ -2811,10 +3327,10 @@ ${sections}`
|
|
|
2811
3327
|
}
|
|
2812
3328
|
return;
|
|
2813
3329
|
}
|
|
2814
|
-
const mcpJsonPath =
|
|
3330
|
+
const mcpJsonPath = join4(agentDir, "provision", ".mcp.json");
|
|
2815
3331
|
let mcpConfig;
|
|
2816
3332
|
try {
|
|
2817
|
-
mcpConfig = JSON.parse(
|
|
3333
|
+
mcpConfig = JSON.parse(readFileSync4(mcpJsonPath, "utf-8"));
|
|
2818
3334
|
} catch {
|
|
2819
3335
|
mcpConfig = { mcpServers: {} };
|
|
2820
3336
|
}
|
|
@@ -2842,10 +3358,10 @@ ${sections}`
|
|
|
2842
3358
|
const appToken = config["app_token"];
|
|
2843
3359
|
if (!botToken)
|
|
2844
3360
|
return;
|
|
2845
|
-
const localSlackChannel =
|
|
3361
|
+
const localSlackChannel = join4(getHomeDir3(), ".augmented", "_mcp", "slack-channel.js");
|
|
2846
3362
|
const slackThreadAutoFollow = config["thread_auto_follow"];
|
|
2847
3363
|
const slackAutoFollowEnv = slackThreadAutoFollow && slackThreadAutoFollow !== "off" ? { SLACK_THREAD_AUTO_FOLLOW: slackThreadAutoFollow } : {};
|
|
2848
|
-
if (isPersistent &&
|
|
3364
|
+
if (isPersistent && existsSync4(localSlackChannel)) {
|
|
2849
3365
|
mcpServers["slack"] = {
|
|
2850
3366
|
command: "node",
|
|
2851
3367
|
args: [localSlackChannel],
|
|
@@ -2867,12 +3383,12 @@ ${sections}`
|
|
|
2867
3383
|
};
|
|
2868
3384
|
}
|
|
2869
3385
|
}
|
|
2870
|
-
|
|
3386
|
+
writeFileSync4(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
|
|
2871
3387
|
syncMcpToProject(codeName);
|
|
2872
3388
|
},
|
|
2873
3389
|
removeChannelCredentials(codeName, channelId) {
|
|
2874
3390
|
const agentDir = getAgentDir(codeName);
|
|
2875
|
-
const mcpJsonPath =
|
|
3391
|
+
const mcpJsonPath = join4(agentDir, "provision", ".mcp.json");
|
|
2876
3392
|
modifyJsonConfig(mcpJsonPath, (config) => {
|
|
2877
3393
|
const mcpServers = config["mcpServers"];
|
|
2878
3394
|
if (!mcpServers || !(channelId in mcpServers))
|
|
@@ -2884,7 +3400,7 @@ ${sections}`
|
|
|
2884
3400
|
},
|
|
2885
3401
|
async updateAgentModel(codeName, model) {
|
|
2886
3402
|
const agentDir = getAgentDir(codeName);
|
|
2887
|
-
const settingsPath =
|
|
3403
|
+
const settingsPath = join4(agentDir, "provision", "settings.json");
|
|
2888
3404
|
let changed = false;
|
|
2889
3405
|
modifyJsonConfig(settingsPath, (config) => {
|
|
2890
3406
|
config["model"] = model;
|
|
@@ -2896,20 +3412,20 @@ ${sections}`
|
|
|
2896
3412
|
seedProfileConfig(codeName) {
|
|
2897
3413
|
const agentDir = getAgentDir(codeName);
|
|
2898
3414
|
const projectDir = getProjectDir(codeName);
|
|
2899
|
-
|
|
2900
|
-
|
|
3415
|
+
mkdirSync4(join4(agentDir, "provision"), { recursive: true });
|
|
3416
|
+
mkdirSync4(projectDir, { recursive: true });
|
|
2901
3417
|
},
|
|
2902
3418
|
syncScheduledTasks(codeName, tasks) {
|
|
2903
3419
|
const agentDir = getAgentDir(codeName);
|
|
2904
|
-
const schedulesPath =
|
|
3420
|
+
const schedulesPath = join4(agentDir, "schedules.json");
|
|
2905
3421
|
const mapped = mapScheduledTasks(tasks);
|
|
2906
|
-
|
|
2907
|
-
|
|
3422
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
3423
|
+
writeFileSync4(schedulesPath, JSON.stringify({ schedules: mapped }, null, 2));
|
|
2908
3424
|
return Promise.resolve();
|
|
2909
3425
|
},
|
|
2910
3426
|
writeIntegrations(codeName, integrations) {
|
|
2911
3427
|
const agentDir = getAgentDir(codeName);
|
|
2912
|
-
|
|
3428
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
2913
3429
|
const envLines = ["# Augmented integrations \u2014 auto-generated, do not edit"];
|
|
2914
3430
|
for (const integration of integrations) {
|
|
2915
3431
|
const prefix = integration.definition_id.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
@@ -2936,18 +3452,19 @@ ${sections}`
|
|
|
2936
3452
|
}
|
|
2937
3453
|
}
|
|
2938
3454
|
if (envLines.length > 1) {
|
|
2939
|
-
const envPath =
|
|
2940
|
-
|
|
2941
|
-
|
|
3455
|
+
const envPath = join4(agentDir, ".env.integrations");
|
|
3456
|
+
writeFileSync4(envPath, envLines.join("\n") + "\n");
|
|
3457
|
+
chmodSync4(envPath, SECRET_FILE_MODE);
|
|
2942
3458
|
}
|
|
3459
|
+
writeXurlStoreForIntegrations(integrations);
|
|
2943
3460
|
const hasQmd = integrations.some((i) => i.definition_id === "qmd");
|
|
2944
3461
|
if (hasQmd) {
|
|
2945
3462
|
this.writeMcpServer(codeName, "qmd", { command: "qmd", args: ["mcp"] });
|
|
2946
3463
|
}
|
|
2947
3464
|
const projectDir = getProjectDir(codeName);
|
|
2948
|
-
const claudeMdPath =
|
|
3465
|
+
const claudeMdPath = join4(projectDir, "CLAUDE.md");
|
|
2949
3466
|
try {
|
|
2950
|
-
const existing =
|
|
3467
|
+
const existing = readFileSync4(claudeMdPath, "utf-8");
|
|
2951
3468
|
const summaries = integrations.map((i) => {
|
|
2952
3469
|
const def = INTEGRATION_REGISTRY.find((d) => d.id === i.definition_id);
|
|
2953
3470
|
return {
|
|
@@ -2964,12 +3481,12 @@ ${sections}`
|
|
|
2964
3481
|
} else {
|
|
2965
3482
|
updated = existing.replace("## Rules", `${newSection}## Rules`);
|
|
2966
3483
|
}
|
|
2967
|
-
|
|
3484
|
+
writeFileSync4(claudeMdPath, updated);
|
|
2968
3485
|
const agentDir2 = getAgentDir(codeName);
|
|
2969
|
-
const envSrc =
|
|
3486
|
+
const envSrc = join4(agentDir2, ".env.integrations");
|
|
2970
3487
|
try {
|
|
2971
|
-
const envContent =
|
|
2972
|
-
|
|
3488
|
+
const envContent = readFileSync4(envSrc, "utf-8");
|
|
3489
|
+
writeFileSync4(join4(projectDir, ".env.integrations"), envContent);
|
|
2973
3490
|
} catch {
|
|
2974
3491
|
}
|
|
2975
3492
|
} catch {
|
|
@@ -2977,11 +3494,11 @@ ${sections}`
|
|
|
2977
3494
|
},
|
|
2978
3495
|
writeMcpServer(codeName, serverId, config) {
|
|
2979
3496
|
const agentDir = getAgentDir(codeName);
|
|
2980
|
-
const mcpJsonPath =
|
|
2981
|
-
|
|
3497
|
+
const mcpJsonPath = join4(agentDir, "provision", ".mcp.json");
|
|
3498
|
+
mkdirSync4(join4(agentDir, "provision"), { recursive: true });
|
|
2982
3499
|
let mcpConfig;
|
|
2983
3500
|
try {
|
|
2984
|
-
mcpConfig = JSON.parse(
|
|
3501
|
+
mcpConfig = JSON.parse(readFileSync4(mcpJsonPath, "utf-8"));
|
|
2985
3502
|
} catch {
|
|
2986
3503
|
mcpConfig = { mcpServers: {} };
|
|
2987
3504
|
}
|
|
@@ -3028,15 +3545,15 @@ ${sections}`
|
|
|
3028
3545
|
serverEntry["env"] = config.env;
|
|
3029
3546
|
}
|
|
3030
3547
|
mcpServers[serverId] = serverEntry;
|
|
3031
|
-
|
|
3548
|
+
writeFileSync4(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
|
|
3032
3549
|
syncMcpToProject(codeName);
|
|
3033
3550
|
},
|
|
3034
3551
|
removeMcpServer(codeName, serverId) {
|
|
3035
3552
|
const agentDir = getAgentDir(codeName);
|
|
3036
|
-
const mcpJsonPath =
|
|
3553
|
+
const mcpJsonPath = join4(agentDir, "provision", ".mcp.json");
|
|
3037
3554
|
let mcpConfig;
|
|
3038
3555
|
try {
|
|
3039
|
-
mcpConfig = JSON.parse(
|
|
3556
|
+
mcpConfig = JSON.parse(readFileSync4(mcpJsonPath, "utf-8"));
|
|
3040
3557
|
} catch {
|
|
3041
3558
|
return;
|
|
3042
3559
|
}
|
|
@@ -3044,7 +3561,7 @@ ${sections}`
|
|
|
3044
3561
|
if (!mcpServers || !(serverId in mcpServers))
|
|
3045
3562
|
return;
|
|
3046
3563
|
delete mcpServers[serverId];
|
|
3047
|
-
|
|
3564
|
+
writeFileSync4(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
|
|
3048
3565
|
syncMcpToProject(codeName);
|
|
3049
3566
|
},
|
|
3050
3567
|
installSkillFiles(codeName, skillId, files) {
|
|
@@ -3054,27 +3571,27 @@ ${sections}`
|
|
|
3054
3571
|
const READ_WRITE_MODE = 420;
|
|
3055
3572
|
const agentDir = getAgentDir(codeName);
|
|
3056
3573
|
const projectDir = getProjectDir(codeName);
|
|
3057
|
-
for (const baseDir of [
|
|
3058
|
-
const skillDir =
|
|
3059
|
-
|
|
3574
|
+
for (const baseDir of [join4(agentDir, "skills"), join4(projectDir, ".claude", "skills")]) {
|
|
3575
|
+
const skillDir = join4(baseDir, skillId);
|
|
3576
|
+
mkdirSync4(skillDir, { recursive: true });
|
|
3060
3577
|
for (const file of files) {
|
|
3061
3578
|
assertSafeRelativePath(file.relativePath);
|
|
3062
|
-
const filePath =
|
|
3579
|
+
const filePath = join4(skillDir, file.relativePath);
|
|
3063
3580
|
const rel = relative(skillDir, filePath);
|
|
3064
3581
|
if (rel.startsWith("..") || rel === "") {
|
|
3065
3582
|
throw new Error(`Path traversal detected: ${file.relativePath} resolves outside ${skillDir}`);
|
|
3066
3583
|
}
|
|
3067
|
-
|
|
3068
|
-
if (isPluginManaged &&
|
|
3584
|
+
mkdirSync4(join4(filePath, ".."), { recursive: true });
|
|
3585
|
+
if (isPluginManaged && existsSync4(filePath)) {
|
|
3069
3586
|
try {
|
|
3070
|
-
|
|
3587
|
+
chmodSync4(filePath, READ_WRITE_MODE);
|
|
3071
3588
|
} catch {
|
|
3072
3589
|
}
|
|
3073
3590
|
}
|
|
3074
|
-
|
|
3591
|
+
writeFileSync4(filePath, file.content);
|
|
3075
3592
|
if (isPluginManaged) {
|
|
3076
3593
|
try {
|
|
3077
|
-
|
|
3594
|
+
chmodSync4(filePath, READ_ONLY_MODE);
|
|
3078
3595
|
} catch {
|
|
3079
3596
|
}
|
|
3080
3597
|
}
|
|
@@ -3083,11 +3600,11 @@ ${sections}`
|
|
|
3083
3600
|
},
|
|
3084
3601
|
installPlugin(codeName, pluginId, pluginPath, pluginConfig) {
|
|
3085
3602
|
const agentDir = getAgentDir(codeName);
|
|
3086
|
-
const pluginsJsonPath =
|
|
3087
|
-
|
|
3603
|
+
const pluginsJsonPath = join4(agentDir, "plugins.json");
|
|
3604
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
3088
3605
|
let pluginsConfig;
|
|
3089
3606
|
try {
|
|
3090
|
-
pluginsConfig = JSON.parse(
|
|
3607
|
+
pluginsConfig = JSON.parse(readFileSync4(pluginsJsonPath, "utf-8"));
|
|
3091
3608
|
} catch {
|
|
3092
3609
|
pluginsConfig = { plugins: {} };
|
|
3093
3610
|
}
|
|
@@ -3100,7 +3617,7 @@ ${sections}`
|
|
|
3100
3617
|
installed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3101
3618
|
...pluginConfig ? { config: pluginConfig } : {}
|
|
3102
3619
|
};
|
|
3103
|
-
|
|
3620
|
+
writeFileSync4(pluginsJsonPath, JSON.stringify(pluginsConfig, null, 2));
|
|
3104
3621
|
},
|
|
3105
3622
|
/**
|
|
3106
3623
|
* Full plugin provisioning: install scripts, register hooks, apply permissions,
|
|
@@ -3116,11 +3633,11 @@ ${sections}`
|
|
|
3116
3633
|
assertValidCodeName(codeName);
|
|
3117
3634
|
assertValidCodeName(plugin.slug);
|
|
3118
3635
|
const projectDir = getProjectDir(codeName);
|
|
3119
|
-
const claudeDir =
|
|
3120
|
-
|
|
3636
|
+
const claudeDir = join4(projectDir, ".claude");
|
|
3637
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
3121
3638
|
const sourceSpec = options?.scriptSource ?? `augmented-plugin:${plugin.slug}`;
|
|
3122
3639
|
this.installPlugin(codeName, plugin.slug, sourceSpec, contextValues);
|
|
3123
|
-
const installedDir =
|
|
3640
|
+
const installedDir = join4(projectDir, ".claude", "plugins", plugin.slug);
|
|
3124
3641
|
for (const skill of plugin.skills) {
|
|
3125
3642
|
const skillId = skill.id;
|
|
3126
3643
|
assertValidCodeName(skillId);
|
|
@@ -3132,10 +3649,10 @@ ${sections}`
|
|
|
3132
3649
|
}
|
|
3133
3650
|
const scriptsConfig = plugin.scripts;
|
|
3134
3651
|
if (scriptsConfig?.hooks) {
|
|
3135
|
-
const settingsPath =
|
|
3652
|
+
const settingsPath = join4(claudeDir, "settings.local.json");
|
|
3136
3653
|
let settings = {};
|
|
3137
3654
|
try {
|
|
3138
|
-
settings = JSON.parse(
|
|
3655
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
3139
3656
|
} catch {
|
|
3140
3657
|
}
|
|
3141
3658
|
const existingHooks = settings["hooks"] ?? {};
|
|
@@ -3169,13 +3686,13 @@ ${sections}`
|
|
|
3169
3686
|
}
|
|
3170
3687
|
}
|
|
3171
3688
|
settings["hooks"] = existingHooks;
|
|
3172
|
-
|
|
3689
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3173
3690
|
}
|
|
3174
3691
|
if (plugin.allowed_tools.length > 0) {
|
|
3175
|
-
const settingsPath =
|
|
3692
|
+
const settingsPath = join4(claudeDir, "settings.local.json");
|
|
3176
3693
|
let settings = {};
|
|
3177
3694
|
try {
|
|
3178
|
-
settings = JSON.parse(
|
|
3695
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
3179
3696
|
} catch {
|
|
3180
3697
|
}
|
|
3181
3698
|
const existingPerms = settings["permissions"] ?? {};
|
|
@@ -3187,20 +3704,20 @@ ${sections}`
|
|
|
3187
3704
|
}
|
|
3188
3705
|
existingPerms["allow"] = allowList;
|
|
3189
3706
|
settings["permissions"] = existingPerms;
|
|
3190
|
-
|
|
3707
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3191
3708
|
}
|
|
3192
3709
|
if (contextValues && Object.keys(contextValues).length > 0) {
|
|
3193
|
-
const configDir =
|
|
3194
|
-
|
|
3195
|
-
|
|
3710
|
+
const configDir = join4(projectDir, `.${plugin.slug}`);
|
|
3711
|
+
mkdirSync4(configDir, { recursive: true });
|
|
3712
|
+
writeFileSync4(join4(configDir, "config.json"), JSON.stringify(contextValues, null, 2));
|
|
3196
3713
|
}
|
|
3197
3714
|
},
|
|
3198
3715
|
executePluginHook(ctx) {
|
|
3199
3716
|
assertValidCodeName(ctx.codeName);
|
|
3200
|
-
const agentRootDir =
|
|
3717
|
+
const agentRootDir = join4(getHomeDir3(), ".augmented", ctx.codeName);
|
|
3201
3718
|
const projectDir = getProjectDir(ctx.codeName);
|
|
3202
|
-
|
|
3203
|
-
|
|
3719
|
+
mkdirSync4(agentRootDir, { recursive: true });
|
|
3720
|
+
mkdirSync4(projectDir, { recursive: true });
|
|
3204
3721
|
const startedAt = Date.now();
|
|
3205
3722
|
return new Promise((resolve3) => {
|
|
3206
3723
|
const child = execFile3("bash", ["-c", ctx.script], {
|
|
@@ -3231,7 +3748,7 @@ ${sections}`
|
|
|
3231
3748
|
},
|
|
3232
3749
|
writeTokenFile(codeName, integrations) {
|
|
3233
3750
|
const agentDir = getAgentDir(codeName);
|
|
3234
|
-
|
|
3751
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
3235
3752
|
const tokens = {};
|
|
3236
3753
|
for (const integration of integrations) {
|
|
3237
3754
|
if (integration.auth_type !== "oauth2")
|
|
@@ -3247,13 +3764,17 @@ ${sections}`
|
|
|
3247
3764
|
}
|
|
3248
3765
|
if (Object.keys(tokens).length === 0)
|
|
3249
3766
|
return;
|
|
3250
|
-
const tokenPath =
|
|
3251
|
-
|
|
3252
|
-
|
|
3767
|
+
const tokenPath = join4(agentDir, ".tokens.json");
|
|
3768
|
+
writeFileSync4(tokenPath, JSON.stringify(tokens, null, 2));
|
|
3769
|
+
chmodSync4(tokenPath, SECRET_FILE_MODE);
|
|
3253
3770
|
}
|
|
3254
3771
|
};
|
|
3255
3772
|
registerFramework(claudeCodeAdapter);
|
|
3256
3773
|
|
|
3774
|
+
// ../../packages/core/dist/provisioning/frameworks/managed-agents/index.js
|
|
3775
|
+
import { homedir as homedir4 } from "os";
|
|
3776
|
+
import { join as join5 } from "path";
|
|
3777
|
+
|
|
3257
3778
|
// ../../packages/core/dist/provisioning/frameworks/managed-agents/system-prompt.js
|
|
3258
3779
|
function generateSystemPrompt(input) {
|
|
3259
3780
|
const { agent, charterFrontmatter, charterContent, resolvedChannels, integrations } = input;
|
|
@@ -3451,6 +3972,9 @@ function buildMcpServers(input) {
|
|
|
3451
3972
|
var ManagedAgentsAdapter = {
|
|
3452
3973
|
id: "managed-agents",
|
|
3453
3974
|
label: "Managed Agents (Anthropic Cloud)",
|
|
3975
|
+
getAgentDir(codeName) {
|
|
3976
|
+
return join5(homedir4(), ".augmented", codeName);
|
|
3977
|
+
},
|
|
3454
3978
|
buildArtifacts(input) {
|
|
3455
3979
|
const { agent, toolsFrontmatter } = input;
|
|
3456
3980
|
const toolset = mapToolsToAgentToolset(toolsFrontmatter);
|
|
@@ -3506,14 +4030,14 @@ var ManagedAgentsAdapter = {
|
|
|
3506
4030
|
registerFramework(ManagedAgentsAdapter);
|
|
3507
4031
|
|
|
3508
4032
|
// src/lib/config.ts
|
|
3509
|
-
import { readFileSync as
|
|
3510
|
-
import { join as
|
|
3511
|
-
import { homedir as
|
|
3512
|
-
var AUGMENTED_DIR2 =
|
|
3513
|
-
var CONFIG_PATH =
|
|
4033
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync5 } from "fs";
|
|
4034
|
+
import { join as join6 } from "path";
|
|
4035
|
+
import { homedir as homedir5 } from "os";
|
|
4036
|
+
var AUGMENTED_DIR2 = join6(homedir5(), ".augmented");
|
|
4037
|
+
var CONFIG_PATH = join6(AUGMENTED_DIR2, "config.json");
|
|
3514
4038
|
function ensureAugmentedDir() {
|
|
3515
|
-
if (!
|
|
3516
|
-
|
|
4039
|
+
if (!existsSync5(AUGMENTED_DIR2)) {
|
|
4040
|
+
mkdirSync5(AUGMENTED_DIR2, { recursive: true });
|
|
3517
4041
|
}
|
|
3518
4042
|
}
|
|
3519
4043
|
function reloadFromShellProfile() {
|
|
@@ -3522,11 +4046,11 @@ function reloadFromShellProfile() {
|
|
|
3522
4046
|
function loadFromShellProfile(force = false) {
|
|
3523
4047
|
if (!force && process.env["AGT_HOST"] && process.env["AGT_API_KEY"]) return;
|
|
3524
4048
|
const shell = process.env["SHELL"] ?? "";
|
|
3525
|
-
const home =
|
|
3526
|
-
const candidates = shell.includes("zsh") ? [
|
|
4049
|
+
const home = homedir5();
|
|
4050
|
+
const candidates = shell.includes("zsh") ? [join6(home, ".zshrc"), join6(home, ".zprofile")] : shell.includes("fish") ? [join6(home, ".config", "fish", "config.fish")] : [join6(home, ".bashrc"), join6(home, ".bash_profile")];
|
|
3527
4051
|
for (const profile of candidates) {
|
|
3528
4052
|
try {
|
|
3529
|
-
const content =
|
|
4053
|
+
const content = readFileSync5(profile, "utf-8");
|
|
3530
4054
|
for (const key of ["AGT_HOST", "AGT_API_KEY", "AGT_TEAM"]) {
|
|
3531
4055
|
if (!force && process.env[key]) continue;
|
|
3532
4056
|
const match = content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).map(
|
|
@@ -3551,7 +4075,7 @@ function getApiKey() {
|
|
|
3551
4075
|
}
|
|
3552
4076
|
function getConfig() {
|
|
3553
4077
|
try {
|
|
3554
|
-
const raw =
|
|
4078
|
+
const raw = readFileSync5(CONFIG_PATH, "utf-8");
|
|
3555
4079
|
return JSON.parse(raw);
|
|
3556
4080
|
} catch {
|
|
3557
4081
|
return {};
|
|
@@ -3559,7 +4083,7 @@ function getConfig() {
|
|
|
3559
4083
|
}
|
|
3560
4084
|
function saveConfig(config) {
|
|
3561
4085
|
ensureAugmentedDir();
|
|
3562
|
-
|
|
4086
|
+
writeFileSync5(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
3563
4087
|
}
|
|
3564
4088
|
function getActiveTeam() {
|
|
3565
4089
|
const envTeam = process.env["AGT_TEAM"];
|
|
@@ -4157,7 +4681,7 @@ async function createSlackApp(configToken, manifest) {
|
|
|
4157
4681
|
}
|
|
4158
4682
|
|
|
4159
4683
|
// ../../packages/core/dist/parser/frontmatter.js
|
|
4160
|
-
import { parse as
|
|
4684
|
+
import { parse as parseYaml2 } from "yaml";
|
|
4161
4685
|
function extractFrontmatter(content) {
|
|
4162
4686
|
const lines = content.split("\n");
|
|
4163
4687
|
let startLine = -1;
|
|
@@ -4187,7 +4711,7 @@ function extractFrontmatter(content) {
|
|
|
4187
4711
|
return { frontmatter: null, body, preamble, error: "Empty frontmatter block" };
|
|
4188
4712
|
}
|
|
4189
4713
|
try {
|
|
4190
|
-
const parsed =
|
|
4714
|
+
const parsed = parseYaml2(yamlStr);
|
|
4191
4715
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
4192
4716
|
return { frontmatter: null, body, preamble, error: "Frontmatter must be a YAML mapping (object)" };
|
|
4193
4717
|
}
|
|
@@ -4840,7 +5364,7 @@ function validateToolsFrontmatter(data) {
|
|
|
4840
5364
|
}
|
|
4841
5365
|
|
|
4842
5366
|
// ../../packages/core/dist/generation/charter-generator.js
|
|
4843
|
-
import { stringify as
|
|
5367
|
+
import { stringify as stringifyYaml2 } from "yaml";
|
|
4844
5368
|
function generateCharterMd(input) {
|
|
4845
5369
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
4846
5370
|
const frontmatter = {
|
|
@@ -4855,7 +5379,7 @@ function generateCharterMd(input) {
|
|
|
4855
5379
|
created: today,
|
|
4856
5380
|
last_updated: today
|
|
4857
5381
|
};
|
|
4858
|
-
const yaml =
|
|
5382
|
+
const yaml = stringifyYaml2(frontmatter, { lineWidth: 0 });
|
|
4859
5383
|
const desc = input.description ?? "";
|
|
4860
5384
|
const roleDisplay = input.role ?? "";
|
|
4861
5385
|
const reportsTo = input.reports_to ? `
|
|
@@ -4885,7 +5409,7 @@ ${desc}
|
|
|
4885
5409
|
}
|
|
4886
5410
|
|
|
4887
5411
|
// ../../packages/core/dist/generation/tools-generator.js
|
|
4888
|
-
import { stringify as
|
|
5412
|
+
import { stringify as stringifyYaml3 } from "yaml";
|
|
4889
5413
|
function generateToolsMd(input) {
|
|
4890
5414
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
4891
5415
|
const globalControls = {
|
|
@@ -4906,7 +5430,7 @@ function generateToolsMd(input) {
|
|
|
4906
5430
|
global_controls: globalControls,
|
|
4907
5431
|
tools: input.tools ?? []
|
|
4908
5432
|
};
|
|
4909
|
-
const yaml =
|
|
5433
|
+
const yaml = stringifyYaml3(frontmatter, { lineWidth: 0 });
|
|
4910
5434
|
const toolsList = frontmatter.tools.length > 0 ? frontmatter.tools.map((t) => `- **${t.name}** (\`${t.id}\`): ${t.description} [${t.access}, ${t.limits.timeout_ms}ms, ${t.limits.rate_limit_rpm}rpm]`).join("\n") : "No tools configured.";
|
|
4911
5435
|
return `# TOOLS \u2014 ${input.display_name}
|
|
4912
5436
|
|
|
@@ -5755,10 +6279,16 @@ function provision(input, frameworkId = "openclaw") {
|
|
|
5755
6279
|
}
|
|
5756
6280
|
|
|
5757
6281
|
export {
|
|
6282
|
+
parseDeliveryTarget,
|
|
6283
|
+
isParseError,
|
|
6284
|
+
appendDmFooter,
|
|
6285
|
+
resolveDmTarget,
|
|
6286
|
+
isResolveError,
|
|
5758
6287
|
getFramework,
|
|
5759
6288
|
CHANNEL_REGISTRY,
|
|
5760
6289
|
getChannel,
|
|
5761
6290
|
getAllChannelIds,
|
|
6291
|
+
getIntegration,
|
|
5762
6292
|
provisionStopHook,
|
|
5763
6293
|
provisionIsolationHook,
|
|
5764
6294
|
getApiKey,
|
|
@@ -5791,4 +6321,4 @@ export {
|
|
|
5791
6321
|
detectDrift,
|
|
5792
6322
|
provision
|
|
5793
6323
|
};
|
|
5794
|
-
//# sourceMappingURL=chunk-
|
|
6324
|
+
//# sourceMappingURL=chunk-S5VHDDAJ.js.map
|