nomoreide 0.1.96 → 0.1.97
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/cli/profile.js +12 -8
- package/dist/cli/profile.js.map +1 -1
- package/dist/core/agent-env/claude-reader.js +12 -4
- package/dist/core/agent-env/claude-reader.js.map +1 -1
- package/dist/core/agent-env/codex-reader.js +5 -4
- package/dist/core/agent-env/codex-reader.js.map +1 -1
- package/dist/core/agent-env/managed-plugins.d.ts +5 -0
- package/dist/core/agent-env/managed-plugins.js +43 -11
- package/dist/core/agent-env/managed-plugins.js.map +1 -1
- package/dist/core/agent-env-plugin-uninstall.js +36 -19
- package/dist/core/agent-env-plugin-uninstall.js.map +1 -1
- package/dist/core/agent-profiles/apply.d.ts +6 -1
- package/dist/core/agent-profiles/apply.js +37 -1
- package/dist/core/agent-profiles/apply.js.map +1 -1
- package/dist/core/agent-profiles/index.d.ts +3 -2
- package/dist/core/agent-profiles/index.js +3 -2
- package/dist/core/agent-profiles/index.js.map +1 -1
- package/dist/core/agent-profiles/plugin-apply.d.ts +16 -0
- package/dist/core/agent-profiles/plugin-apply.js +383 -0
- package/dist/core/agent-profiles/plugin-apply.js.map +1 -0
- package/dist/core/agent-profiles/plugin-bundle.d.ts +6 -0
- package/dist/core/agent-profiles/plugin-bundle.js +32 -0
- package/dist/core/agent-profiles/plugin-bundle.js.map +1 -0
- package/dist/core/agent-profiles/registry-transfer.js +6 -1
- package/dist/core/agent-profiles/registry-transfer.js.map +1 -1
- package/dist/core/agent-profiles/store.d.ts +3 -1
- package/dist/core/agent-profiles/store.js +92 -5
- package/dist/core/agent-profiles/store.js.map +1 -1
- package/dist/core/agent-profiles/transfer.d.ts +1 -0
- package/dist/core/agent-profiles/transfer.js +183 -5
- package/dist/core/agent-profiles/transfer.js.map +1 -1
- package/dist/core/agent-profiles/types.d.ts +105 -3
- package/dist/core/agent-profiles/types.js +15 -1
- package/dist/core/agent-profiles/types.js.map +1 -1
- package/dist/core/agent-transcripts.d.ts +6 -4
- package/dist/core/agent-transcripts.js +20 -12
- package/dist/core/agent-transcripts.js.map +1 -1
- package/dist/core/docker-stats.d.ts +2 -0
- package/dist/core/docker-stats.js +24 -0
- package/dist/core/docker-stats.js.map +1 -1
- package/dist/core/metrics-store.d.ts +11 -1
- package/dist/core/metrics-store.js +63 -5
- package/dist/core/metrics-store.js.map +1 -1
- package/dist/core/one-time-skills.d.ts +27 -0
- package/dist/core/one-time-skills.js +185 -0
- package/dist/core/one-time-skills.js.map +1 -0
- package/dist/core/system-processes.d.ts +29 -0
- package/dist/core/system-processes.js +119 -0
- package/dist/core/system-processes.js.map +1 -0
- package/dist/mcp/tools/agent-profiles.js +42 -10
- package/dist/mcp/tools/agent-profiles.js.map +1 -1
- package/dist/web/client/assets/{code-editor-0KKgooZa.js → code-editor-Bv3tCQrj.js} +1 -1
- package/dist/web/client/assets/index-BeJHDwLO.css +1 -0
- package/dist/web/client/assets/index-zb3rhV5y.js +308 -0
- package/dist/web/client/assets/system-process-table-q3WxburN.js +1 -0
- package/dist/web/client/index.html +2 -2
- package/dist/web/routes/agent-profile-routes.js +2 -1
- package/dist/web/routes/agent-profile-routes.js.map +1 -1
- package/dist/web/routes/git-routes.js +5 -0
- package/dist/web/routes/git-routes.js.map +1 -1
- package/dist/web/routes/index.js +2 -0
- package/dist/web/routes/index.js.map +1 -1
- package/dist/web/routes/metrics-routes.js +30 -4
- package/dist/web/routes/metrics-routes.js.map +1 -1
- package/dist/web/routes/skills-routes.d.ts +2 -0
- package/dist/web/routes/skills-routes.js +49 -0
- package/dist/web/routes/skills-routes.js.map +1 -0
- package/dist/web/routes/terminal-routes.js +28 -3
- package/dist/web/routes/terminal-routes.js.map +1 -1
- package/package.json +2 -1
- package/dist/web/client/assets/index-BT_kqOsy.css +0 -1
- package/dist/web/client/assets/index-CWkw1l1F.js +0 -242
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
const SKILLS_SEARCH_URL = "https://skills.sh/api/search";
|
|
3
|
+
const SKILLS_CLI_VERSION = "1.5.20";
|
|
4
|
+
const SEARCH_LIMIT = 6;
|
|
5
|
+
const SEARCH_TIMEOUT_MS = 8_000;
|
|
6
|
+
const USE_TIMEOUT_MS = 60_000;
|
|
7
|
+
const MAX_SEARCH_RESPONSE_BYTES = 256 * 1024;
|
|
8
|
+
const MAX_SKILL_PROMPT_BYTES = 256 * 1024;
|
|
9
|
+
const MAX_COMBINED_PROMPT_BYTES = 512 * 1024;
|
|
10
|
+
const GITHUB_SOURCE = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,99})\/[A-Za-z0-9](?:[A-Za-z0-9._-]{0,99})$/;
|
|
11
|
+
const SKILL_SELECTOR = /^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,199})$/;
|
|
12
|
+
export class OneTimeSkillError extends Error {
|
|
13
|
+
code;
|
|
14
|
+
constructor(code, message) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.code = code;
|
|
17
|
+
this.name = "OneTimeSkillError";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function selectorFor(id, source) {
|
|
21
|
+
const prefix = `${source}/`;
|
|
22
|
+
if (!id.startsWith(prefix))
|
|
23
|
+
return null;
|
|
24
|
+
const selector = id.slice(prefix.length);
|
|
25
|
+
return SKILL_SELECTOR.test(selector) ? selector : null;
|
|
26
|
+
}
|
|
27
|
+
function normalizeSearchEntry(value) {
|
|
28
|
+
if (!value || typeof value !== "object")
|
|
29
|
+
return null;
|
|
30
|
+
const entry = value;
|
|
31
|
+
if (typeof entry.id !== "string" ||
|
|
32
|
+
typeof entry.name !== "string" ||
|
|
33
|
+
typeof entry.source !== "string" ||
|
|
34
|
+
!GITHUB_SOURCE.test(entry.source)) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const selector = selectorFor(entry.id, entry.source);
|
|
38
|
+
if (!selector)
|
|
39
|
+
return null;
|
|
40
|
+
return {
|
|
41
|
+
id: entry.id,
|
|
42
|
+
name: entry.name.slice(0, 200),
|
|
43
|
+
source: entry.source,
|
|
44
|
+
useSource: `${entry.source}@${selector}`,
|
|
45
|
+
installs: typeof entry.installs === "number" && Number.isFinite(entry.installs)
|
|
46
|
+
? Math.max(0, Math.trunc(entry.installs))
|
|
47
|
+
: 0,
|
|
48
|
+
url: `https://skills.sh/${entry.id}`,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
async function readResponseText(response, maximumBytes) {
|
|
52
|
+
if (!response.body)
|
|
53
|
+
return "";
|
|
54
|
+
const reader = response.body.getReader();
|
|
55
|
+
const chunks = [];
|
|
56
|
+
let total = 0;
|
|
57
|
+
try {
|
|
58
|
+
while (true) {
|
|
59
|
+
const { done, value } = await reader.read();
|
|
60
|
+
if (done)
|
|
61
|
+
break;
|
|
62
|
+
total += value.byteLength;
|
|
63
|
+
if (total > maximumBytes) {
|
|
64
|
+
await reader.cancel();
|
|
65
|
+
throw new OneTimeSkillError("invalid_response", "skills.sh returned too much search data.");
|
|
66
|
+
}
|
|
67
|
+
chunks.push(value);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
reader.releaseLock();
|
|
72
|
+
}
|
|
73
|
+
return Buffer.concat(chunks.map((chunk) => Buffer.from(chunk)), total).toString("utf8");
|
|
74
|
+
}
|
|
75
|
+
export async function searchRemoteSkills(rawQuery, options = {}) {
|
|
76
|
+
const query = rawQuery.trim();
|
|
77
|
+
if (query.length < 2 || query.length > 100) {
|
|
78
|
+
throw new OneTimeSkillError("invalid_query", "Skill search must be 2–100 characters.");
|
|
79
|
+
}
|
|
80
|
+
const timeout = AbortSignal.timeout(SEARCH_TIMEOUT_MS);
|
|
81
|
+
const signal = options.signal
|
|
82
|
+
? AbortSignal.any([options.signal, timeout])
|
|
83
|
+
: timeout;
|
|
84
|
+
const url = new URL(SKILLS_SEARCH_URL);
|
|
85
|
+
url.searchParams.set("q", query);
|
|
86
|
+
url.searchParams.set("limit", String(SEARCH_LIMIT));
|
|
87
|
+
let response;
|
|
88
|
+
try {
|
|
89
|
+
response = await (options.fetch ?? fetch)(url, { signal });
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
if (signal.aborted) {
|
|
93
|
+
throw new OneTimeSkillError("timeout", "Skill search timed out.");
|
|
94
|
+
}
|
|
95
|
+
throw new OneTimeSkillError("network", `Could not search skills.sh: ${error instanceof Error ? error.message : String(error)}`);
|
|
96
|
+
}
|
|
97
|
+
if (!response.ok) {
|
|
98
|
+
throw new OneTimeSkillError("network", `skills.sh search failed with HTTP ${response.status}.`);
|
|
99
|
+
}
|
|
100
|
+
const declaredLength = Number(response.headers.get("content-length"));
|
|
101
|
+
if (Number.isFinite(declaredLength) &&
|
|
102
|
+
declaredLength > MAX_SEARCH_RESPONSE_BYTES) {
|
|
103
|
+
throw new OneTimeSkillError("invalid_response", "skills.sh returned too much search data.");
|
|
104
|
+
}
|
|
105
|
+
let payload;
|
|
106
|
+
try {
|
|
107
|
+
const text = await readResponseText(response, MAX_SEARCH_RESPONSE_BYTES);
|
|
108
|
+
payload = JSON.parse(text);
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
if (error instanceof OneTimeSkillError)
|
|
112
|
+
throw error;
|
|
113
|
+
throw new OneTimeSkillError("invalid_response", "skills.sh returned invalid JSON.");
|
|
114
|
+
}
|
|
115
|
+
if (!Array.isArray(payload.skills)) {
|
|
116
|
+
throw new OneTimeSkillError("invalid_response", "skills.sh returned an invalid search result.");
|
|
117
|
+
}
|
|
118
|
+
return payload.skills
|
|
119
|
+
.map(normalizeSearchEntry)
|
|
120
|
+
.filter((item) => item !== null)
|
|
121
|
+
.slice(0, SEARCH_LIMIT);
|
|
122
|
+
}
|
|
123
|
+
export function validateOneTimeSkill(selection) {
|
|
124
|
+
const at = selection.source.lastIndexOf("@");
|
|
125
|
+
const repository = selection.source.slice(0, at);
|
|
126
|
+
const selector = selection.source.slice(at + 1);
|
|
127
|
+
if (at <= 0 ||
|
|
128
|
+
!GITHUB_SOURCE.test(repository) ||
|
|
129
|
+
!SKILL_SELECTOR.test(selector) ||
|
|
130
|
+
selection.name.trim().length === 0 ||
|
|
131
|
+
selection.name.length > 200) {
|
|
132
|
+
throw new OneTimeSkillError("invalid_source", "The selected skill source is invalid.");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export function resolveOneTimeSkill(selection, options = {}) {
|
|
136
|
+
validateOneTimeSkill(selection);
|
|
137
|
+
const executable = (options.platform ?? process.platform) === "win32" ? "npx.cmd" : "npx";
|
|
138
|
+
const run = options.execFile ?? execFile;
|
|
139
|
+
return new Promise((resolve, reject) => {
|
|
140
|
+
run(executable, ["--yes", `skills@${SKILLS_CLI_VERSION}`, "use", selection.source], {
|
|
141
|
+
env: {
|
|
142
|
+
...process.env,
|
|
143
|
+
CI: "1",
|
|
144
|
+
NO_COLOR: "1",
|
|
145
|
+
npm_config_yes: "true",
|
|
146
|
+
},
|
|
147
|
+
maxBuffer: MAX_SKILL_PROMPT_BYTES,
|
|
148
|
+
timeout: USE_TIMEOUT_MS,
|
|
149
|
+
windowsHide: true,
|
|
150
|
+
}, (error, stdout, stderr) => {
|
|
151
|
+
if (!error) {
|
|
152
|
+
const prompt = stdout.toString();
|
|
153
|
+
if (!prompt.trim()) {
|
|
154
|
+
reject(new OneTimeSkillError("skill_unavailable", "The skills CLI returned an empty skill."));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
resolve(prompt);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const processError = error;
|
|
161
|
+
if (processError.code === "ENOENT") {
|
|
162
|
+
reject(new OneTimeSkillError("runtime_missing", "Node.js and npm are required to use a temporary skill."));
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (processError.killed || processError.code === "ETIMEDOUT") {
|
|
166
|
+
reject(new OneTimeSkillError("timeout", "Loading the temporary skill timed out."));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (processError.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") {
|
|
170
|
+
reject(new OneTimeSkillError("too_large", "The temporary skill is too large to use."));
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const detail = stderr.toString().trim();
|
|
174
|
+
reject(new OneTimeSkillError("skill_unavailable", detail || "The temporary skill could not be loaded."));
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
export function composeOneTimeSkillPrompt(skillPrompt, userPrompt) {
|
|
179
|
+
const combined = `${skillPrompt.trimEnd()}\n\nUser's request:\n${userPrompt}`;
|
|
180
|
+
if (Buffer.byteLength(combined, "utf8") > MAX_COMBINED_PROMPT_BYTES) {
|
|
181
|
+
throw new OneTimeSkillError("too_large", "The temporary skill and task are too large to send together.");
|
|
182
|
+
}
|
|
183
|
+
return combined;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=one-time-skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"one-time-skills.js","sourceRoot":"","sources":["../../src/core/one-time-skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type ProcessProtection = "managed" | "permission" | "system" | "this-app";
|
|
2
|
+
export interface SystemProcess {
|
|
3
|
+
pid: number;
|
|
4
|
+
ppid: number;
|
|
5
|
+
uid: number;
|
|
6
|
+
user: string;
|
|
7
|
+
cpuPercent: number;
|
|
8
|
+
rssMb: number;
|
|
9
|
+
command: string;
|
|
10
|
+
managedService?: string;
|
|
11
|
+
canTerminate: boolean;
|
|
12
|
+
protection?: ProcessProtection;
|
|
13
|
+
}
|
|
14
|
+
export interface ManagedProcessRoot {
|
|
15
|
+
pid: number;
|
|
16
|
+
service: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function parseSystemProcesses(raw: string): SystemProcess[];
|
|
19
|
+
export declare function readSystemProcesses(): Promise<SystemProcess[]>;
|
|
20
|
+
export declare function classifySystemProcesses(rows: SystemProcess[], managedRoots: ManagedProcessRoot[], options?: {
|
|
21
|
+
currentPid?: number;
|
|
22
|
+
currentUid?: number;
|
|
23
|
+
}): SystemProcess[];
|
|
24
|
+
export declare function terminateSystemProcess(pid: number, expectedCommand: string, managedRoots: ManagedProcessRoot[], options?: {
|
|
25
|
+
currentPid?: number;
|
|
26
|
+
currentUid?: number;
|
|
27
|
+
read?: () => Promise<SystemProcess[]>;
|
|
28
|
+
signal?: (pid: number) => void;
|
|
29
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
const execFileAsync = promisify(execFile);
|
|
4
|
+
export function parseSystemProcesses(raw) {
|
|
5
|
+
return raw
|
|
6
|
+
.trim()
|
|
7
|
+
.split(/\n/)
|
|
8
|
+
.map((line) => {
|
|
9
|
+
const match = line
|
|
10
|
+
.trim()
|
|
11
|
+
.match(/^(\d+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\d+)\s+(.+)$/);
|
|
12
|
+
if (!match)
|
|
13
|
+
return undefined;
|
|
14
|
+
return {
|
|
15
|
+
uid: Number(match[1]),
|
|
16
|
+
user: match[2],
|
|
17
|
+
pid: Number(match[3]),
|
|
18
|
+
ppid: Number(match[4]),
|
|
19
|
+
cpuPercent: Number(match[5]),
|
|
20
|
+
rssMb: Number(match[6]) / 1024,
|
|
21
|
+
command: match[7],
|
|
22
|
+
canTerminate: false,
|
|
23
|
+
};
|
|
24
|
+
})
|
|
25
|
+
.filter((row) => Boolean(row));
|
|
26
|
+
}
|
|
27
|
+
export async function readSystemProcesses() {
|
|
28
|
+
const { stdout } = await execFileAsync("ps", [
|
|
29
|
+
"-ax",
|
|
30
|
+
"-o",
|
|
31
|
+
"uid=,user=,pid=,ppid=,%cpu=,rss=,command=",
|
|
32
|
+
]);
|
|
33
|
+
return parseSystemProcesses(stdout);
|
|
34
|
+
}
|
|
35
|
+
export function classifySystemProcesses(rows, managedRoots, options = {}) {
|
|
36
|
+
const currentPid = options.currentPid ?? process.pid;
|
|
37
|
+
const currentUid = options.currentUid ?? process.getuid?.();
|
|
38
|
+
const appTree = appTreePids(rows, currentPid);
|
|
39
|
+
const managed = managedServices(rows, managedRoots);
|
|
40
|
+
return rows.map((row) => {
|
|
41
|
+
const managedService = managed.get(row.pid);
|
|
42
|
+
const protection = managedService
|
|
43
|
+
? "managed"
|
|
44
|
+
: row.pid <= 1
|
|
45
|
+
? "system"
|
|
46
|
+
: appTree.has(row.pid)
|
|
47
|
+
? "this-app"
|
|
48
|
+
: currentUid === undefined || row.uid !== currentUid
|
|
49
|
+
? "permission"
|
|
50
|
+
: undefined;
|
|
51
|
+
return {
|
|
52
|
+
...row,
|
|
53
|
+
managedService,
|
|
54
|
+
canTerminate: protection === undefined,
|
|
55
|
+
protection,
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
export async function terminateSystemProcess(pid, expectedCommand, managedRoots, options = {}) {
|
|
60
|
+
if (!Number.isSafeInteger(pid) || pid <= 1) {
|
|
61
|
+
throw new Error("Invalid process id.");
|
|
62
|
+
}
|
|
63
|
+
const rows = await (options.read ?? readSystemProcesses)();
|
|
64
|
+
const target = classifySystemProcesses(rows, managedRoots, options).find((row) => row.pid === pid);
|
|
65
|
+
if (!target)
|
|
66
|
+
throw new Error(`Process ${pid} is no longer running.`);
|
|
67
|
+
if (target.command !== expectedCommand) {
|
|
68
|
+
throw new Error(`Process ${pid} changed before it could be terminated.`);
|
|
69
|
+
}
|
|
70
|
+
if (!target.canTerminate) {
|
|
71
|
+
throw new Error(`Process ${pid} is protected (${target.protection}).`);
|
|
72
|
+
}
|
|
73
|
+
(options.signal ?? ((targetPid) => process.kill(targetPid, "SIGTERM")))(pid);
|
|
74
|
+
}
|
|
75
|
+
function appTreePids(rows, pid) {
|
|
76
|
+
const byPid = new Map(rows.map((row) => [row.pid, row]));
|
|
77
|
+
const related = new Set([pid]);
|
|
78
|
+
let parent = byPid.get(pid)?.ppid;
|
|
79
|
+
while (parent && parent > 0 && !related.has(parent)) {
|
|
80
|
+
related.add(parent);
|
|
81
|
+
parent = byPid.get(parent)?.ppid;
|
|
82
|
+
}
|
|
83
|
+
const children = new Map();
|
|
84
|
+
for (const row of rows) {
|
|
85
|
+
const siblings = children.get(row.ppid) ?? [];
|
|
86
|
+
siblings.push(row.pid);
|
|
87
|
+
children.set(row.ppid, siblings);
|
|
88
|
+
}
|
|
89
|
+
const stack = [...(children.get(pid) ?? [])];
|
|
90
|
+
while (stack.length > 0) {
|
|
91
|
+
const child = stack.pop();
|
|
92
|
+
if (child === undefined || related.has(child))
|
|
93
|
+
continue;
|
|
94
|
+
related.add(child);
|
|
95
|
+
stack.push(...(children.get(child) ?? []));
|
|
96
|
+
}
|
|
97
|
+
return related;
|
|
98
|
+
}
|
|
99
|
+
function managedServices(rows, roots) {
|
|
100
|
+
const children = new Map();
|
|
101
|
+
for (const row of rows) {
|
|
102
|
+
const siblings = children.get(row.ppid) ?? [];
|
|
103
|
+
siblings.push(row.pid);
|
|
104
|
+
children.set(row.ppid, siblings);
|
|
105
|
+
}
|
|
106
|
+
const result = new Map();
|
|
107
|
+
for (const root of roots) {
|
|
108
|
+
const stack = [root.pid];
|
|
109
|
+
while (stack.length > 0) {
|
|
110
|
+
const pid = stack.pop();
|
|
111
|
+
if (pid === undefined || result.has(pid))
|
|
112
|
+
continue;
|
|
113
|
+
result.set(pid, root.service);
|
|
114
|
+
stack.push(...(children.get(pid) ?? []));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=system-processes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-processes.js","sourceRoot":"","sources":["../../src/core/system-processes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { applyProfile, copySkillBetweenProfiles, createProfile, deleteProfile, exportProfile, getProfile, importProfile, listProfiles, previewProfileApply, profileMcpSchema, snapshotProfileFromAgent, updateProfile, } from "../../core/agent-profiles/index.js";
|
|
2
|
+
import { applyProfile, copyPluginBetweenProfiles, copySkillBetweenProfiles, createProfile, deleteProfile, exportProfile, getProfile, importProfile, listProfiles, previewProfileApply, pluginIdentity, profileMcpSchema, profilePluginSchema, snapshotProfileFromAgent, updateProfile, } from "../../core/agent-profiles/index.js";
|
|
3
3
|
import { stringify } from "./context.js";
|
|
4
4
|
export const AGENT_PROFILE_TOOL_NAMES = [
|
|
5
5
|
"nomoreide_profiles_list",
|
|
@@ -28,13 +28,13 @@ const cwdField = z
|
|
|
28
28
|
export function registerAgentProfileTools(server, _ctx) {
|
|
29
29
|
server.addTool({
|
|
30
30
|
name: "nomoreide_profiles_list",
|
|
31
|
-
description: "List saved agent profiles (named bundles of MCP servers
|
|
31
|
+
description: "List saved agent profiles (named bundles of MCP servers, skills, and plugins).",
|
|
32
32
|
parameters: z.object({}),
|
|
33
33
|
execute: async () => stringify(await listProfiles()),
|
|
34
34
|
});
|
|
35
35
|
server.addTool({
|
|
36
36
|
name: "nomoreide_profiles_get",
|
|
37
|
-
description: "Get a profile's full config: MCP servers
|
|
37
|
+
description: "Get a profile's full config: MCP servers, bundled skills, and plugins.",
|
|
38
38
|
parameters: z.object({ name: nameField }),
|
|
39
39
|
execute: async ({ name }) => stringify(await getProfile(name)),
|
|
40
40
|
});
|
|
@@ -46,12 +46,13 @@ export function registerAgentProfileTools(server, _ctx) {
|
|
|
46
46
|
});
|
|
47
47
|
server.addTool({
|
|
48
48
|
name: "nomoreide_profiles_update",
|
|
49
|
-
description: "Update a profile's description, MCP map, or
|
|
49
|
+
description: "Update a profile's description, MCP map, skill list, or plugin list (name is immutable).",
|
|
50
50
|
parameters: z.object({
|
|
51
51
|
name: nameField,
|
|
52
52
|
description: z.string().optional(),
|
|
53
53
|
mcps: z.record(profileMcpSchema).optional(),
|
|
54
54
|
skills: z.array(z.object({ name: z.string().min(1) })).optional(),
|
|
55
|
+
plugins: z.array(profilePluginSchema).optional(),
|
|
55
56
|
}),
|
|
56
57
|
execute: async ({ name, ...patch }) => stringify(await updateProfile(name, patch)),
|
|
57
58
|
});
|
|
@@ -66,7 +67,7 @@ export function registerAgentProfileTools(server, _ctx) {
|
|
|
66
67
|
});
|
|
67
68
|
server.addTool({
|
|
68
69
|
name: "nomoreide_profiles_snapshot",
|
|
69
|
-
description: "Snapshot an agent's live MCPs
|
|
70
|
+
description: "Snapshot an agent's live MCPs, user skills, and installed plugins into a new profile.",
|
|
70
71
|
parameters: z.object({
|
|
71
72
|
agent: agentSchema,
|
|
72
73
|
name: nameField,
|
|
@@ -77,13 +78,14 @@ export function registerAgentProfileTools(server, _ctx) {
|
|
|
77
78
|
});
|
|
78
79
|
server.addTool({
|
|
79
80
|
name: "nomoreide_profiles_apply",
|
|
80
|
-
description: "Apply a profile's MCPs and
|
|
81
|
+
description: "Apply a profile's MCPs, skills, and plugins to an agent. Set dryRun=true for a conflict preview.",
|
|
81
82
|
parameters: z.object({
|
|
82
83
|
name: nameField,
|
|
83
84
|
agent: agentSchema,
|
|
84
85
|
dryRun: z.boolean().default(false),
|
|
85
86
|
skipMcps: z.array(z.string()).optional().describe("MCP keys to leave untouched."),
|
|
86
87
|
skipSkills: z.array(z.string()).optional().describe("Skill names to leave untouched."),
|
|
88
|
+
skipPlugins: z.array(z.string()).optional().describe("Plugin names to leave untouched."),
|
|
87
89
|
cwd: cwdField,
|
|
88
90
|
}),
|
|
89
91
|
execute: async (input) => {
|
|
@@ -95,7 +97,11 @@ export function registerAgentProfileTools(server, _ctx) {
|
|
|
95
97
|
cwd,
|
|
96
98
|
name: input.name,
|
|
97
99
|
agent: input.agent,
|
|
98
|
-
skip: {
|
|
100
|
+
skip: {
|
|
101
|
+
mcps: input.skipMcps,
|
|
102
|
+
skills: input.skipSkills,
|
|
103
|
+
plugins: input.skipPlugins,
|
|
104
|
+
},
|
|
99
105
|
}));
|
|
100
106
|
},
|
|
101
107
|
});
|
|
@@ -126,12 +132,16 @@ export function registerAgentProfileTools(server, _ctx) {
|
|
|
126
132
|
});
|
|
127
133
|
server.addTool({
|
|
128
134
|
name: "nomoreide_profiles_copy_items",
|
|
129
|
-
description: "Copy selected MCPs and/or
|
|
135
|
+
description: "Copy selected MCPs, skills, and/or plugins from one profile into another.",
|
|
130
136
|
parameters: z.object({
|
|
131
137
|
from: z.string().min(1),
|
|
132
138
|
to: z.string().min(1),
|
|
133
139
|
mcps: z.array(z.string()).optional().describe("MCP keys to copy."),
|
|
134
140
|
skills: z.array(z.string()).optional().describe("Skill names to copy."),
|
|
141
|
+
plugins: z
|
|
142
|
+
.array(z.string())
|
|
143
|
+
.optional()
|
|
144
|
+
.describe("Canonical plugin IDs to copy; an unambiguous plugin name is also accepted."),
|
|
135
145
|
}),
|
|
136
146
|
execute: async (input) => {
|
|
137
147
|
const source = await getProfile(input.from);
|
|
@@ -157,8 +167,30 @@ export function registerAgentProfileTools(server, _ctx) {
|
|
|
157
167
|
}
|
|
158
168
|
copiedSkills.push(skillName);
|
|
159
169
|
}
|
|
160
|
-
|
|
161
|
-
|
|
170
|
+
const plugins = [...target.plugins];
|
|
171
|
+
const copiedPlugins = [];
|
|
172
|
+
for (const pluginSelector of input.plugins ?? []) {
|
|
173
|
+
const pluginById = source.plugins.find((entry) => pluginIdentity(entry) === pluginSelector);
|
|
174
|
+
const pluginsByName = source.plugins.filter((entry) => entry.name === pluginSelector);
|
|
175
|
+
if (!pluginById && pluginsByName.length > 1) {
|
|
176
|
+
throw new Error(`Plugin name "${pluginSelector}" is ambiguous in profile "${input.from}". Use one of: ${pluginsByName.map(pluginIdentity).join(", ")}.`);
|
|
177
|
+
}
|
|
178
|
+
const plugin = pluginById ?? pluginsByName[0];
|
|
179
|
+
if (!plugin) {
|
|
180
|
+
throw new Error(`Plugin "${pluginSelector}" not found in profile "${input.from}".`);
|
|
181
|
+
}
|
|
182
|
+
await copyPluginBetweenProfiles(input.from, input.to, plugin.bundleKey);
|
|
183
|
+
const existing = plugins.findIndex((entry) => entry.name === plugin.name &&
|
|
184
|
+
entry.sourceAgent === plugin.sourceAgent &&
|
|
185
|
+
entry.source === plugin.source);
|
|
186
|
+
if (existing >= 0)
|
|
187
|
+
plugins[existing] = plugin;
|
|
188
|
+
else
|
|
189
|
+
plugins.push(plugin);
|
|
190
|
+
copiedPlugins.push(pluginIdentity(plugin));
|
|
191
|
+
}
|
|
192
|
+
await updateProfile(input.to, { mcps, skills, plugins });
|
|
193
|
+
return stringify({ ok: true, copiedMcps, copiedSkills, copiedPlugins });
|
|
162
194
|
},
|
|
163
195
|
});
|
|
164
196
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-profiles.js","sourceRoot":"","sources":["../../../src/mcp/tools/agent-profiles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,aAAa,EACb,aAAa,EACb,aAAa,EACb,UAAU,EACV,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,GACd,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAoB,MAAM,cAAc,CAAC;AAE3D,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,yBAAyB;IACzB,wBAAwB;IACxB,2BAA2B;IAC3B,2BAA2B;IAC3B,2BAA2B;IAC3B,6BAA6B;IAC7B,0BAA0B;IAC1B,2BAA2B;IAC3B,2BAA2B;IAC3B,+BAA+B;CACvB,CAAC;AAEX,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;AAC/D,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;AAC9D,MAAM,QAAQ,GAAG,CAAC;KACf,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,QAAQ,EAAE;KACV,QAAQ,CAAC,mDAAmD,CAAC,CAAC;AAEjE;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAe,EAAE,IAAiB;IAC1E,MAAM,CAAC,OAAO,CAAC;QACb,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"agent-profiles.js","sourceRoot":"","sources":["../../../src/mcp/tools/agent-profiles.ts"],"names":[],"mappings":"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"}
|