nomoreide 0.1.70 → 0.1.72
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/core/agent-profiles/apply.d.ts +36 -0
- package/dist/core/agent-profiles/apply.js +160 -0
- package/dist/core/agent-profiles/apply.js.map +1 -0
- package/dist/core/agent-profiles/credentials.d.ts +26 -0
- package/dist/core/agent-profiles/credentials.js +151 -0
- package/dist/core/agent-profiles/credentials.js.map +1 -0
- package/dist/core/agent-profiles/index.d.ts +14 -0
- package/dist/core/agent-profiles/index.js +15 -0
- package/dist/core/agent-profiles/index.js.map +1 -0
- package/dist/core/agent-profiles/registry-auth.d.ts +25 -0
- package/dist/core/agent-profiles/registry-auth.js +78 -0
- package/dist/core/agent-profiles/registry-auth.js.map +1 -0
- package/dist/core/agent-profiles/registry-client.d.ts +65 -0
- package/dist/core/agent-profiles/registry-client.js +97 -0
- package/dist/core/agent-profiles/registry-client.js.map +1 -0
- package/dist/core/agent-profiles/registry-config.d.ts +48 -0
- package/dist/core/agent-profiles/registry-config.js +164 -0
- package/dist/core/agent-profiles/registry-config.js.map +1 -0
- package/dist/core/agent-profiles/registry-transfer.d.ts +42 -0
- package/dist/core/agent-profiles/registry-transfer.js +102 -0
- package/dist/core/agent-profiles/registry-transfer.js.map +1 -0
- package/dist/core/agent-profiles/store.d.ts +35 -0
- package/dist/core/agent-profiles/store.js +210 -0
- package/dist/core/agent-profiles/store.js.map +1 -0
- package/dist/core/agent-profiles/transfer.d.ts +26 -0
- package/dist/core/agent-profiles/transfer.js +141 -0
- package/dist/core/agent-profiles/transfer.js.map +1 -0
- package/dist/core/agent-profiles/types.d.ts +250 -0
- package/dist/core/agent-profiles/types.js +63 -0
- package/dist/core/agent-profiles/types.js.map +1 -0
- package/dist/mcp/tools/agent-profiles.d.ts +9 -0
- package/dist/mcp/tools/agent-profiles.js +165 -0
- package/dist/mcp/tools/agent-profiles.js.map +1 -0
- package/dist/mcp/tools/agent-registry.d.ts +9 -0
- package/dist/mcp/tools/agent-registry.js +81 -0
- package/dist/mcp/tools/agent-registry.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +1 -1
- package/dist/mcp/tools/index.js +6 -0
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/web/client/assets/{code-editor-tF2NdMJV.js → code-editor-fZ2dpXfw.js} +1 -1
- package/dist/web/client/assets/{index-CQmdoyuK.js → index-CraqLFuO.js} +140 -140
- package/dist/web/client/assets/index-n7aEcfkd.css +1 -0
- package/dist/web/client/index.html +2 -2
- package/dist/web/routes/agent-profile-routes.d.ts +8 -0
- package/dist/web/routes/agent-profile-routes.js +180 -0
- package/dist/web/routes/agent-profile-routes.js.map +1 -0
- package/dist/web/routes/agent-registry-routes.d.ts +2 -0
- package/dist/web/routes/agent-registry-routes.js +295 -0
- package/dist/web/routes/agent-registry-routes.js.map +1 -0
- package/dist/web/routes/index.js +6 -0
- package/dist/web/routes/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/web/client/assets/index-C7lI87cF.css +0 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type AgentName } from "../agent-env/index.js";
|
|
2
|
+
import { type ProfileStoreOptions } from "./store.js";
|
|
3
|
+
export type ProfileItemStatus = "add" | "identical" | "conflict";
|
|
4
|
+
export interface ProfileApplyItem {
|
|
5
|
+
category: "mcp" | "skill";
|
|
6
|
+
name: string;
|
|
7
|
+
status: ProfileItemStatus;
|
|
8
|
+
warnings: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface ProfileApplyPreview {
|
|
11
|
+
profile: string;
|
|
12
|
+
agent: AgentName;
|
|
13
|
+
items: ProfileApplyItem[];
|
|
14
|
+
/** `${credentials.*}` keys still unresolved in the profile — applied as-is. */
|
|
15
|
+
unresolvedCredentials: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface ProfileApplyOptions extends ProfileStoreOptions {
|
|
18
|
+
cwd: string;
|
|
19
|
+
name: string;
|
|
20
|
+
agent: AgentName;
|
|
21
|
+
/** Item names (per category) to leave untouched — typically conflicts the user kept. */
|
|
22
|
+
skip?: {
|
|
23
|
+
mcps?: string[];
|
|
24
|
+
skills?: string[];
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export declare function previewProfileApply(options: Omit<ProfileApplyOptions, "skip">): Promise<ProfileApplyPreview>;
|
|
28
|
+
export interface ProfileApplyResult {
|
|
29
|
+
profile: string;
|
|
30
|
+
agent: AgentName;
|
|
31
|
+
mcpsApplied: string[];
|
|
32
|
+
skillsApplied: string[];
|
|
33
|
+
skipped: string[];
|
|
34
|
+
backups: string[];
|
|
35
|
+
}
|
|
36
|
+
export declare function applyProfile(options: ProfileApplyOptions): Promise<ProfileApplyResult>;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Apply a profile to an agent — the write-gated half of Agent Profiles.
|
|
3
|
+
* Mirrors the ROR-61 staged-writes gate: `previewProfileApply` classifies
|
|
4
|
+
* every item (add / identical / conflict) and surfaces warnings, then
|
|
5
|
+
* `applyProfile` snapshots the agent's config, writes through the
|
|
6
|
+
* write-guarded agent-env-writers layer, and reports every backup created.
|
|
7
|
+
*/
|
|
8
|
+
import { cp, mkdir, rm } from "node:fs/promises";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { addMcp, getSkillDir, snapshotAgentConfig } from "../agent-env-writers.js";
|
|
11
|
+
import { readAllAgentConfigs, } from "../agent-env/index.js";
|
|
12
|
+
import { findUnresolvedCredentialKeys } from "./credentials.js";
|
|
13
|
+
import { getProfile, profileSkillsDir, pathExists } from "./store.js";
|
|
14
|
+
export async function previewProfileApply(options) {
|
|
15
|
+
const [profile, live] = await Promise.all([
|
|
16
|
+
getProfile(options.name, options),
|
|
17
|
+
readLiveConfig(options),
|
|
18
|
+
]);
|
|
19
|
+
const items = [];
|
|
20
|
+
for (const [key, mcp] of Object.entries(profile.mcps)) {
|
|
21
|
+
const existing = findLiveMcp(live, key);
|
|
22
|
+
const warnings = [];
|
|
23
|
+
if (options.agent === "codex" &&
|
|
24
|
+
mcp.kind === "remote" &&
|
|
25
|
+
(mcp.headers || mcp.transport === "sse")) {
|
|
26
|
+
warnings.push("Codex config only stores a URL for remote MCPs; transport and headers will be dropped.");
|
|
27
|
+
}
|
|
28
|
+
items.push({
|
|
29
|
+
category: "mcp",
|
|
30
|
+
name: key,
|
|
31
|
+
status: existing === undefined ? "add" : sameMcp(existing, mcp) ? "identical" : "conflict",
|
|
32
|
+
warnings,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
const liveSkillNames = new Set(live.skills.filter((skill) => skill.scope === "user").map((skill) => skill.name));
|
|
36
|
+
for (const skill of profile.skills) {
|
|
37
|
+
items.push({
|
|
38
|
+
category: "skill",
|
|
39
|
+
name: skill.name,
|
|
40
|
+
// Skill contents aren't diffed — an existing dir with the same name is a conflict.
|
|
41
|
+
status: liveSkillNames.has(skill.name) ? "conflict" : "add",
|
|
42
|
+
warnings: [],
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
profile: profile.name,
|
|
47
|
+
agent: options.agent,
|
|
48
|
+
items,
|
|
49
|
+
unresolvedCredentials: findUnresolvedCredentialKeys(profile.mcps),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export async function applyProfile(options) {
|
|
53
|
+
const profile = await getProfile(options.name, options);
|
|
54
|
+
const base = { cwd: options.cwd, homeDir: options.homeDir };
|
|
55
|
+
const skipMcps = new Set(options.skip?.mcps ?? []);
|
|
56
|
+
const skipSkills = new Set(options.skip?.skills ?? []);
|
|
57
|
+
const backups = [];
|
|
58
|
+
const skipped = [];
|
|
59
|
+
// One snapshot of the agent's config file before the batch (plus the
|
|
60
|
+
// per-write .bak.* copies the writers create anyway).
|
|
61
|
+
const snapshot = await snapshotAgentConfig({ ...base, agent: options.agent });
|
|
62
|
+
backups.push(...snapshot.backups);
|
|
63
|
+
const mcpsApplied = [];
|
|
64
|
+
for (const [key, mcp] of Object.entries(profile.mcps)) {
|
|
65
|
+
if (skipMcps.has(key)) {
|
|
66
|
+
skipped.push(`mcp "${key}"`);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const outcome = await addMcp({
|
|
70
|
+
...base,
|
|
71
|
+
agent: options.agent,
|
|
72
|
+
key,
|
|
73
|
+
scope: "user",
|
|
74
|
+
entry: mcp.kind === "local"
|
|
75
|
+
? { command: mcp.command, args: mcp.args, env: mcp.env }
|
|
76
|
+
: undefined,
|
|
77
|
+
remoteEntry: mcp.kind === "remote"
|
|
78
|
+
? { transport: mcp.transport, url: mcp.url, headers: mcp.headers, env: mcp.env }
|
|
79
|
+
: undefined,
|
|
80
|
+
});
|
|
81
|
+
backups.push(...outcome.backups);
|
|
82
|
+
mcpsApplied.push(key);
|
|
83
|
+
}
|
|
84
|
+
const skillsApplied = [];
|
|
85
|
+
for (const skill of profile.skills) {
|
|
86
|
+
if (skipSkills.has(skill.name)) {
|
|
87
|
+
skipped.push(`skill "${skill.name}"`);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const sourceDir = path.join(profileSkillsDir(options.name, options), path.basename(skill.name));
|
|
91
|
+
if (!(await pathExists(sourceDir))) {
|
|
92
|
+
skipped.push(`skill "${skill.name}" (missing from profile bundle)`);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
await installProfileSkill(sourceDir, skill.name, options);
|
|
96
|
+
skillsApplied.push(skill.name);
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
profile: profile.name,
|
|
100
|
+
agent: options.agent,
|
|
101
|
+
mcpsApplied,
|
|
102
|
+
skillsApplied,
|
|
103
|
+
skipped,
|
|
104
|
+
backups,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/** Copy a bundled skill dir into the agent's user skills dir (idempotent overwrite). */
|
|
108
|
+
async function installProfileSkill(sourceDir, skillName, options) {
|
|
109
|
+
const targetDir = getSkillDir({ agent: options.agent, skillName, scope: "user" }, options.cwd, options.homeDir);
|
|
110
|
+
await mkdir(path.dirname(targetDir), { recursive: true });
|
|
111
|
+
await rm(targetDir, { recursive: true, force: true });
|
|
112
|
+
await cp(sourceDir, targetDir, { recursive: true });
|
|
113
|
+
}
|
|
114
|
+
async function readLiveConfig(options) {
|
|
115
|
+
const configs = await readAllAgentConfigs({ cwd: options.cwd, homeDir: options.homeDir });
|
|
116
|
+
const config = configs.find((candidate) => candidate.agent === options.agent);
|
|
117
|
+
if (!config)
|
|
118
|
+
throw new Error(`Unknown agent "${options.agent}".`);
|
|
119
|
+
return config;
|
|
120
|
+
}
|
|
121
|
+
function findLiveMcp(config, key) {
|
|
122
|
+
const local = config.mcpServers[key];
|
|
123
|
+
if (local)
|
|
124
|
+
return { kind: "local", command: local.command, args: local.args, env: local.env };
|
|
125
|
+
const remote = config.remoteMcpServers[key];
|
|
126
|
+
if (remote) {
|
|
127
|
+
return {
|
|
128
|
+
kind: "remote",
|
|
129
|
+
transport: remote.transport,
|
|
130
|
+
url: remote.url,
|
|
131
|
+
headers: remote.headers,
|
|
132
|
+
env: remote.env,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
function sameMcp(left, right) {
|
|
138
|
+
return JSON.stringify(normalizeMcp(left)) === JSON.stringify(normalizeMcp(right));
|
|
139
|
+
}
|
|
140
|
+
function normalizeMcp(mcp) {
|
|
141
|
+
if (mcp.kind === "local") {
|
|
142
|
+
return {
|
|
143
|
+
kind: "local",
|
|
144
|
+
command: mcp.command,
|
|
145
|
+
args: mcp.args ?? [],
|
|
146
|
+
env: sortedEntries(mcp.env),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
kind: "remote",
|
|
151
|
+
transport: mcp.transport,
|
|
152
|
+
url: mcp.url,
|
|
153
|
+
headers: sortedEntries(mcp.headers),
|
|
154
|
+
env: sortedEntries(mcp.env),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function sortedEntries(map) {
|
|
158
|
+
return Object.entries(map ?? {}).sort(([a], [b]) => a.localeCompare(b));
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/core/agent-profiles/apply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential redaction (export) and resolution (import) for portable
|
|
3
|
+
* profiles, ported from brainctl's credential services. Exported archives
|
|
4
|
+
* must never contain raw secrets: secret-looking env/header values become
|
|
5
|
+
* `${credentials.<key>}` placeholders plus a spec describing what the
|
|
6
|
+
* importer has to supply.
|
|
7
|
+
*/
|
|
8
|
+
import type { CredentialSpec, ProfileMcp } from "./types.js";
|
|
9
|
+
export interface RedactionResult {
|
|
10
|
+
redacted: ProfileMcp;
|
|
11
|
+
credentials: CredentialSpec[];
|
|
12
|
+
/** Original secret values, keyed by normalized credential key (kept out of archives). */
|
|
13
|
+
rawValues: Record<string, string>;
|
|
14
|
+
}
|
|
15
|
+
export declare function redactMcpCredentials(config: ProfileMcp): RedactionResult;
|
|
16
|
+
export interface ResolutionResult {
|
|
17
|
+
resolved: ProfileMcp;
|
|
18
|
+
missing: CredentialSpec[];
|
|
19
|
+
}
|
|
20
|
+
export declare function resolveMcpCredentials(config: ProfileMcp, options?: {
|
|
21
|
+
credentials?: Record<string, string>;
|
|
22
|
+
credentialSpecs?: CredentialSpec[];
|
|
23
|
+
environment?: Record<string, string | undefined>;
|
|
24
|
+
}): ResolutionResult;
|
|
25
|
+
/** Every `${credentials.*}` key still present anywhere in the given MCPs. */
|
|
26
|
+
export declare function findUnresolvedCredentialKeys(mcps: Record<string, ProfileMcp>): string[];
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
export function redactMcpCredentials(config) {
|
|
2
|
+
const specs = new Map();
|
|
3
|
+
const rawValues = {};
|
|
4
|
+
const env = redactStringMap(config.env, "env", specs, rawValues);
|
|
5
|
+
const redacted = config.kind === "remote"
|
|
6
|
+
? {
|
|
7
|
+
...config,
|
|
8
|
+
...(env ? { env } : {}),
|
|
9
|
+
...((() => {
|
|
10
|
+
const headers = redactStringMap(config.headers, "header", specs, rawValues);
|
|
11
|
+
return headers ? { headers } : {};
|
|
12
|
+
})()),
|
|
13
|
+
}
|
|
14
|
+
: { ...config, ...(env ? { env } : {}) };
|
|
15
|
+
return {
|
|
16
|
+
redacted,
|
|
17
|
+
credentials: Array.from(specs.values())
|
|
18
|
+
.sort((left, right) => left.key.localeCompare(right.key))
|
|
19
|
+
.map((entry) => ({
|
|
20
|
+
key: entry.key,
|
|
21
|
+
required: true,
|
|
22
|
+
description: `${Array.from(entry.descriptions).sort().join("; ")} required for MCP access`,
|
|
23
|
+
})),
|
|
24
|
+
rawValues,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function redactStringMap(values, source, specs, rawValues) {
|
|
28
|
+
if (!values)
|
|
29
|
+
return undefined;
|
|
30
|
+
const redacted = {};
|
|
31
|
+
for (const [key, value] of Object.entries(values)) {
|
|
32
|
+
if (!shouldRedact(key)) {
|
|
33
|
+
redacted[key] = value;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const credentialKey = tokenizeCredentialKey(key).join("_");
|
|
37
|
+
const description = source === "env" ? `Environment variable ${key}` : `Header ${key}`;
|
|
38
|
+
const existing = specs.get(credentialKey);
|
|
39
|
+
if (existing)
|
|
40
|
+
existing.descriptions.add(description);
|
|
41
|
+
else
|
|
42
|
+
specs.set(credentialKey, { key: credentialKey, descriptions: new Set([description]) });
|
|
43
|
+
if (isCredentialPlaceholder(value)) {
|
|
44
|
+
redacted[key] = value; // already a placeholder — keep as-is
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
rawValues[credentialKey] = value;
|
|
48
|
+
redacted[key] = `\${credentials.${credentialKey}}`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return redacted;
|
|
52
|
+
}
|
|
53
|
+
function shouldRedact(key) {
|
|
54
|
+
const tokens = tokenizeCredentialKey(key);
|
|
55
|
+
if (tokens.length === 0)
|
|
56
|
+
return false;
|
|
57
|
+
const last = tokens[tokens.length - 1];
|
|
58
|
+
return (last === "authorization" ||
|
|
59
|
+
last === "password" ||
|
|
60
|
+
last === "secret" ||
|
|
61
|
+
last === "token" ||
|
|
62
|
+
(last === "key" && (tokens.includes("api") || tokens.includes("auth"))));
|
|
63
|
+
}
|
|
64
|
+
function tokenizeCredentialKey(key) {
|
|
65
|
+
return key
|
|
66
|
+
.trim()
|
|
67
|
+
.replace(/([A-Z]+)([A-Z][a-z0-9])/g, "$1 $2")
|
|
68
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
69
|
+
.toLowerCase()
|
|
70
|
+
.split(/[^a-z0-9]+/g)
|
|
71
|
+
.filter(Boolean);
|
|
72
|
+
}
|
|
73
|
+
function isCredentialPlaceholder(value) {
|
|
74
|
+
return (/^\$\{credentials\.[^}]+\}$/.test(value) ||
|
|
75
|
+
/^(Bearer|Token)\s+\$\{credentials\.[^}]+\}$/i.test(value));
|
|
76
|
+
}
|
|
77
|
+
export function resolveMcpCredentials(config, options = {}) {
|
|
78
|
+
const specs = new Map((options.credentialSpecs ?? []).map((spec) => [spec.key, spec]));
|
|
79
|
+
const missing = new Map();
|
|
80
|
+
const env = resolveStringMap(config.env, specs, missing, options);
|
|
81
|
+
const resolved = config.kind === "remote"
|
|
82
|
+
? {
|
|
83
|
+
...config,
|
|
84
|
+
...(env ? { env } : {}),
|
|
85
|
+
...((() => {
|
|
86
|
+
const headers = resolveStringMap(config.headers, specs, missing, options);
|
|
87
|
+
return headers ? { headers } : {};
|
|
88
|
+
})()),
|
|
89
|
+
}
|
|
90
|
+
: { ...config, ...(env ? { env } : {}) };
|
|
91
|
+
return { resolved, missing: Array.from(missing.values()) };
|
|
92
|
+
}
|
|
93
|
+
function resolveStringMap(values, specs, missing, options) {
|
|
94
|
+
if (!values)
|
|
95
|
+
return undefined;
|
|
96
|
+
const resolved = {};
|
|
97
|
+
for (const [key, value] of Object.entries(values)) {
|
|
98
|
+
const placeholder = parseCredentialPlaceholder(value);
|
|
99
|
+
if (!placeholder) {
|
|
100
|
+
resolved[key] = value;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const supplied = options.credentials?.[placeholder.key] ?? options.environment?.[placeholder.key];
|
|
104
|
+
if (typeof supplied === "string" && supplied.length > 0) {
|
|
105
|
+
resolved[key] = placeholder.prefix ? `${placeholder.prefix} ${supplied}` : supplied;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const spec = specs.get(placeholder.key) ?? {
|
|
109
|
+
key: placeholder.key,
|
|
110
|
+
required: true,
|
|
111
|
+
description: `Credential ${placeholder.key} is required`,
|
|
112
|
+
};
|
|
113
|
+
if (spec.required)
|
|
114
|
+
missing.set(spec.key, spec);
|
|
115
|
+
resolved[key] = value; // keep the placeholder; the user can fill it later
|
|
116
|
+
}
|
|
117
|
+
return resolved;
|
|
118
|
+
}
|
|
119
|
+
function parseCredentialPlaceholder(value) {
|
|
120
|
+
const bare = value.match(/^\$\{credentials\.([^}]+)\}$/);
|
|
121
|
+
if (bare)
|
|
122
|
+
return { key: bare[1] };
|
|
123
|
+
const prefixed = value.match(/^(Bearer|Token)\s+\$\{credentials\.([^}]+)\}$/i);
|
|
124
|
+
if (prefixed) {
|
|
125
|
+
return {
|
|
126
|
+
key: prefixed[2],
|
|
127
|
+
prefix: prefixed[1].toLowerCase() === "bearer" ? "Bearer" : "Token",
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const PLACEHOLDER_PATTERN = /\$\{\s*credentials\.([^}\s]+)\s*\}/g;
|
|
133
|
+
/** Every `${credentials.*}` key still present anywhere in the given MCPs. */
|
|
134
|
+
export function findUnresolvedCredentialKeys(mcps) {
|
|
135
|
+
const keys = new Set();
|
|
136
|
+
const visit = (value) => {
|
|
137
|
+
if (typeof value === "string") {
|
|
138
|
+
for (const match of value.matchAll(PLACEHOLDER_PATTERN))
|
|
139
|
+
keys.add(match[1]);
|
|
140
|
+
}
|
|
141
|
+
else if (Array.isArray(value)) {
|
|
142
|
+
value.forEach(visit);
|
|
143
|
+
}
|
|
144
|
+
else if (value && typeof value === "object") {
|
|
145
|
+
Object.values(value).forEach(visit);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
visit(mcps);
|
|
149
|
+
return Array.from(keys).sort();
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../src/core/agent-profiles/credentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Profiles (ROR-62): named MCP+skill bundles stored under
|
|
3
|
+
* `~/.config/nomoreide/agent-profiles/`, applied to agents through the
|
|
4
|
+
* write-guarded agent-env layer, shared as credential-redacted tarballs.
|
|
5
|
+
*/
|
|
6
|
+
export { applyProfile, previewProfileApply, type ProfileApplyItem, type ProfileApplyPreview, type ProfileApplyResult, type ProfileItemStatus, } from "./apply.js";
|
|
7
|
+
export { findUnresolvedCredentialKeys, redactMcpCredentials, resolveMcpCredentials, } from "./credentials.js";
|
|
8
|
+
export { assertValidProfileName, copySkillBetweenProfiles, createProfile, deleteProfile, getProfile, listProfiles, profileDir, profilesRoot, profileSkillsDir, snapshotProfileFromAgent, updateProfile, writeProfile, type ProfileStoreOptions, } from "./store.js";
|
|
9
|
+
export { exportProfile, importProfile, type ExportResult, type ImportResult } from "./transfer.js";
|
|
10
|
+
export { createRegistryConfigService, DEFAULT_REGISTRY_API_BASE_URL, DEFAULT_REGISTRY_FRONTEND_URL, registryConfigPath, resolveRegistryApiBaseUrl, resolveRegistryApiTarget, resolveRegistryApiToken, resolveRegistryFrontendUrl, type RegistryApiTarget, type RegistryConfigOptions, type RegistryConfigService, } from "./registry-config.js";
|
|
11
|
+
export { createRegistryTokenManager, type RegistryTokenManager, type RegistryTokenManagerOptions, } from "./registry-auth.js";
|
|
12
|
+
export { createRegistryClient, type RegisterGithubProfileInput, type RegistryClient, type RegistryInstallDescriptor, type RegistryProfile, } from "./registry-client.js";
|
|
13
|
+
export { installProfileFromRegistry, publishProfileToRegistry, type InstallFromRegistryInput, type InstallFromRegistryResult, type PublishProfileInput, type PublishProfileResult, } from "./registry-transfer.js";
|
|
14
|
+
export { PROFILE_NAME_PATTERN, profileManifestSchema, profileMcpSchema, profileSchema, slugifyProfileName, type CredentialSpec, type Profile, type ProfileManifest, type ProfileMcp, type ProfileSummary, } from "./types.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Profiles (ROR-62): named MCP+skill bundles stored under
|
|
3
|
+
* `~/.config/nomoreide/agent-profiles/`, applied to agents through the
|
|
4
|
+
* write-guarded agent-env layer, shared as credential-redacted tarballs.
|
|
5
|
+
*/
|
|
6
|
+
export { applyProfile, previewProfileApply, } from "./apply.js";
|
|
7
|
+
export { findUnresolvedCredentialKeys, redactMcpCredentials, resolveMcpCredentials, } from "./credentials.js";
|
|
8
|
+
export { assertValidProfileName, copySkillBetweenProfiles, createProfile, deleteProfile, getProfile, listProfiles, profileDir, profilesRoot, profileSkillsDir, snapshotProfileFromAgent, updateProfile, writeProfile, } from "./store.js";
|
|
9
|
+
export { exportProfile, importProfile } from "./transfer.js";
|
|
10
|
+
export { createRegistryConfigService, DEFAULT_REGISTRY_API_BASE_URL, DEFAULT_REGISTRY_FRONTEND_URL, registryConfigPath, resolveRegistryApiBaseUrl, resolveRegistryApiTarget, resolveRegistryApiToken, resolveRegistryFrontendUrl, } from "./registry-config.js";
|
|
11
|
+
export { createRegistryTokenManager, } from "./registry-auth.js";
|
|
12
|
+
export { createRegistryClient, } from "./registry-client.js";
|
|
13
|
+
export { installProfileFromRegistry, publishProfileToRegistry, } from "./registry-transfer.js";
|
|
14
|
+
export { PROFILE_NAME_PATTERN, profileManifestSchema, profileMcpSchema, profileSchema, slugifyProfileName, } from "./types.js";
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/agent-profiles/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,YAAY,EACZ,mBAAmB,GAKpB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,aAAa,EACb,aAAa,EACb,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,YAAY,GAEb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAwC,MAAM,eAAe,CAAC;AACnG,OAAO,EACL,2BAA2B,EAC3B,6BAA6B,EAC7B,6BAA6B,EAC7B,kBAAkB,EAClB,yBAAyB,EACzB,wBAAwB,EACxB,uBAAuB,EACvB,0BAA0B,GAI3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,0BAA0B,GAG3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oBAAoB,GAKrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,GAKzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,GAMnB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bearer-token manager for the profile registry: reads the stored access
|
|
3
|
+
* token, transparently refreshes it once on a 401, and persists rotated
|
|
4
|
+
* tokens back to the registry config file.
|
|
5
|
+
*/
|
|
6
|
+
import { type RegistryConfigOptions, type RegistryConfigService } from "./registry-config.js";
|
|
7
|
+
export interface RegistryTokenManager {
|
|
8
|
+
/** Current access token, or null when signed out. */
|
|
9
|
+
getAccessToken(): Promise<string | null>;
|
|
10
|
+
/** Authenticated fetch that refreshes once on 401 and retries. */
|
|
11
|
+
authenticatedFetch(pathOrUrl: string, init?: RequestInit): Promise<Response>;
|
|
12
|
+
/** Persist tokens after a fresh sign-in. */
|
|
13
|
+
saveTokens(input: {
|
|
14
|
+
accessToken: string;
|
|
15
|
+
refreshToken?: string;
|
|
16
|
+
}): Promise<void>;
|
|
17
|
+
/** Sign out: drop both tokens. */
|
|
18
|
+
clear(): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export interface RegistryTokenManagerOptions extends RegistryConfigOptions {
|
|
21
|
+
configService?: RegistryConfigService;
|
|
22
|
+
apiBaseUrl?: string;
|
|
23
|
+
fetch?: typeof fetch;
|
|
24
|
+
}
|
|
25
|
+
export declare function createRegistryTokenManager(options?: RegistryTokenManagerOptions): RegistryTokenManager;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bearer-token manager for the profile registry: reads the stored access
|
|
3
|
+
* token, transparently refreshes it once on a 401, and persists rotated
|
|
4
|
+
* tokens back to the registry config file.
|
|
5
|
+
*/
|
|
6
|
+
import { createRegistryConfigService, resolveRegistryApiBaseUrl, resolveRegistryApiToken, } from "./registry-config.js";
|
|
7
|
+
export function createRegistryTokenManager(options = {}) {
|
|
8
|
+
const config = options.configService ?? createRegistryConfigService(options);
|
|
9
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
10
|
+
let refreshInFlight = null;
|
|
11
|
+
async function apiBase() {
|
|
12
|
+
return (options.apiBaseUrl ??
|
|
13
|
+
(await resolveRegistryApiBaseUrl({ ...options, configService: config }))).replace(/\/$/, "");
|
|
14
|
+
}
|
|
15
|
+
async function readAccessToken() {
|
|
16
|
+
const resolved = await resolveRegistryApiToken({ ...options, configService: config });
|
|
17
|
+
return resolved?.token ?? null;
|
|
18
|
+
}
|
|
19
|
+
async function refresh() {
|
|
20
|
+
if (refreshInFlight)
|
|
21
|
+
return refreshInFlight;
|
|
22
|
+
refreshInFlight = (async () => {
|
|
23
|
+
const refreshToken = (await config.get("apiRefreshToken")) ?? null;
|
|
24
|
+
if (!refreshToken)
|
|
25
|
+
return null;
|
|
26
|
+
const res = await fetchImpl(`${await apiBase()}/auth/refresh`, {
|
|
27
|
+
method: "POST",
|
|
28
|
+
headers: { "content-type": "application/json" },
|
|
29
|
+
body: JSON.stringify({ refresh_token: refreshToken }),
|
|
30
|
+
});
|
|
31
|
+
if (!res.ok) {
|
|
32
|
+
// Refresh token is dead — drop both so status reports signed-out.
|
|
33
|
+
await config.unset("apiRefreshToken");
|
|
34
|
+
await config.unset("apiToken");
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const data = (await res.json());
|
|
38
|
+
await config.set("apiToken", data.access_token);
|
|
39
|
+
if (data.refresh_token)
|
|
40
|
+
await config.set("apiRefreshToken", data.refresh_token);
|
|
41
|
+
return data.access_token;
|
|
42
|
+
})().finally(() => {
|
|
43
|
+
refreshInFlight = null;
|
|
44
|
+
});
|
|
45
|
+
return refreshInFlight;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
getAccessToken: readAccessToken,
|
|
49
|
+
async saveTokens({ accessToken, refreshToken }) {
|
|
50
|
+
await config.set("apiToken", accessToken);
|
|
51
|
+
if (refreshToken)
|
|
52
|
+
await config.set("apiRefreshToken", refreshToken);
|
|
53
|
+
},
|
|
54
|
+
async clear() {
|
|
55
|
+
await config.unset("apiToken");
|
|
56
|
+
await config.unset("apiRefreshToken");
|
|
57
|
+
},
|
|
58
|
+
async authenticatedFetch(pathOrUrl, init = {}) {
|
|
59
|
+
const url = pathOrUrl.startsWith("http")
|
|
60
|
+
? pathOrUrl
|
|
61
|
+
: `${await apiBase()}${pathOrUrl.startsWith("/") ? "" : "/"}${pathOrUrl}`;
|
|
62
|
+
const send = (token) => {
|
|
63
|
+
const headers = new Headers(init.headers);
|
|
64
|
+
if (token)
|
|
65
|
+
headers.set("authorization", `Bearer ${token}`);
|
|
66
|
+
return fetchImpl(url, { ...init, headers });
|
|
67
|
+
};
|
|
68
|
+
const first = await send(await readAccessToken());
|
|
69
|
+
if (first.status !== 401)
|
|
70
|
+
return first;
|
|
71
|
+
const refreshed = await refresh();
|
|
72
|
+
if (!refreshed)
|
|
73
|
+
return first;
|
|
74
|
+
return send(refreshed);
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=registry-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-auth.js","sourceRoot":"","sources":["../../../src/core/agent-profiles/registry-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for the hosted profile registry (the brainctl platform).
|
|
3
|
+
* Thin wrapper over its REST API: profile CRUD, version + package upload,
|
|
4
|
+
* publish, install descriptors, and GitHub-repo registration. Auth is the
|
|
5
|
+
* caller's job — pass a token or an already-authenticated `fetch`.
|
|
6
|
+
*/
|
|
7
|
+
export interface RegistryProfile {
|
|
8
|
+
id: string;
|
|
9
|
+
slug: string;
|
|
10
|
+
title: string;
|
|
11
|
+
summary: string;
|
|
12
|
+
}
|
|
13
|
+
export interface RegistryProfileVersion {
|
|
14
|
+
id: string;
|
|
15
|
+
profile_id: string;
|
|
16
|
+
version: string;
|
|
17
|
+
}
|
|
18
|
+
export interface RegistryInstallDescriptor {
|
|
19
|
+
slug: string;
|
|
20
|
+
version: string;
|
|
21
|
+
source_kind: "brainctl" | "github" | string;
|
|
22
|
+
download_url: string;
|
|
23
|
+
checksum_sha256?: string | null;
|
|
24
|
+
}
|
|
25
|
+
export interface RegisterGithubProfileInput {
|
|
26
|
+
repoUrl: string;
|
|
27
|
+
slug: string;
|
|
28
|
+
title: string;
|
|
29
|
+
summary?: string;
|
|
30
|
+
refName?: string;
|
|
31
|
+
profilePath?: string;
|
|
32
|
+
manifestJson: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
export interface RegistryClient {
|
|
35
|
+
getProfileBySlug(slug: string): Promise<RegistryProfile | null>;
|
|
36
|
+
createProfile(input: {
|
|
37
|
+
slug: string;
|
|
38
|
+
title: string;
|
|
39
|
+
summary?: string;
|
|
40
|
+
visibility?: "public" | "private";
|
|
41
|
+
}): Promise<RegistryProfile>;
|
|
42
|
+
createProfileVersion(input: {
|
|
43
|
+
profileId: string;
|
|
44
|
+
version: string;
|
|
45
|
+
changelog?: string;
|
|
46
|
+
manifestJson: Record<string, unknown>;
|
|
47
|
+
}): Promise<RegistryProfileVersion>;
|
|
48
|
+
uploadPackage(input: {
|
|
49
|
+
profileId: string;
|
|
50
|
+
versionId: string;
|
|
51
|
+
bytes: Uint8Array;
|
|
52
|
+
mimeType?: string;
|
|
53
|
+
}): Promise<unknown>;
|
|
54
|
+
publishProfileVersion(input: {
|
|
55
|
+
profileId: string;
|
|
56
|
+
versionId: string;
|
|
57
|
+
}): Promise<unknown>;
|
|
58
|
+
getInstallDescriptor(slug: string): Promise<RegistryInstallDescriptor>;
|
|
59
|
+
registerGithubProfile(input: RegisterGithubProfileInput): Promise<unknown>;
|
|
60
|
+
}
|
|
61
|
+
export declare function createRegistryClient(options: {
|
|
62
|
+
baseUrl: string;
|
|
63
|
+
token?: string;
|
|
64
|
+
fetch?: typeof fetch;
|
|
65
|
+
}): RegistryClient;
|