agentloom 0.1.1 → 0.1.3
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/README.md +9 -8
- package/dist/cli.js +5 -1
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +14 -0
- package/dist/commands/mcp.js +2 -9
- package/dist/commands/skills.js +6 -27
- package/dist/commands/sync.d.ts +1 -0
- package/dist/commands/sync.js +82 -11
- package/dist/core/argv.js +3 -7
- package/dist/core/copy.d.ts +1 -0
- package/dist/core/copy.js +19 -3
- package/dist/core/migration.d.ts +28 -0
- package/dist/core/migration.js +809 -0
- package/dist/core/provider-paths.d.ts +16 -0
- package/dist/core/provider-paths.js +154 -0
- package/dist/core/router.d.ts +1 -1
- package/dist/core/router.js +1 -0
- package/dist/core/skills.js +2 -16
- package/dist/core/version-notifier.d.ts +1 -0
- package/dist/core/version-notifier.js +22 -4
- package/dist/sync/index.js +27 -104
- package/dist/types.d.ts +2 -1
- package/dist/types.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Provider, ScopePaths } from "../types.js";
|
|
2
|
+
export declare function getProviderAgentsDir(paths: ScopePaths, provider: Provider): string;
|
|
3
|
+
export declare function getProviderCommandsDir(paths: ScopePaths, provider: Provider): string;
|
|
4
|
+
export declare function getProviderSkillsPaths(paths: ScopePaths, providers: Provider[]): string[];
|
|
5
|
+
export declare function getCursorMcpPath(paths: ScopePaths): string;
|
|
6
|
+
export declare function getClaudeMcpPath(paths: ScopePaths): string;
|
|
7
|
+
export declare function getClaudeSettingsPath(paths: ScopePaths): string;
|
|
8
|
+
export declare function getOpenCodeConfigPath(paths: ScopePaths): string;
|
|
9
|
+
export declare function getGeminiSettingsPath(paths: ScopePaths): string;
|
|
10
|
+
export declare function getCopilotMcpPath(paths: ScopePaths): string;
|
|
11
|
+
export declare function getCodexRootDir(paths: ScopePaths): string;
|
|
12
|
+
export declare function getCodexConfigPath(paths: ScopePaths): string;
|
|
13
|
+
export declare function getCodexAgentsDir(paths: ScopePaths): string;
|
|
14
|
+
export declare function getCodexPromptsDir(paths: ScopePaths): string;
|
|
15
|
+
export declare function getPiMcpPath(paths: ScopePaths): string;
|
|
16
|
+
export declare function getVsCodeSettingsPath(homeDir: string): string;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import os from "node:os";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export function getProviderAgentsDir(paths, provider) {
|
|
4
|
+
const workspaceRoot = paths.workspaceRoot;
|
|
5
|
+
const home = paths.homeDir;
|
|
6
|
+
switch (provider) {
|
|
7
|
+
case "cursor":
|
|
8
|
+
return paths.scope === "local"
|
|
9
|
+
? path.join(workspaceRoot, ".cursor", "agents")
|
|
10
|
+
: path.join(home, ".cursor", "agents");
|
|
11
|
+
case "claude":
|
|
12
|
+
return paths.scope === "local"
|
|
13
|
+
? path.join(workspaceRoot, ".claude", "agents")
|
|
14
|
+
: path.join(home, ".claude", "agents");
|
|
15
|
+
case "codex":
|
|
16
|
+
return path.join(getCodexRootDir(paths), "agents");
|
|
17
|
+
case "opencode":
|
|
18
|
+
return paths.scope === "local"
|
|
19
|
+
? path.join(workspaceRoot, ".opencode", "agents")
|
|
20
|
+
: path.join(home, ".config", "opencode", "agents");
|
|
21
|
+
case "gemini":
|
|
22
|
+
return paths.scope === "local"
|
|
23
|
+
? path.join(workspaceRoot, ".gemini", "agents")
|
|
24
|
+
: path.join(home, ".gemini", "agents");
|
|
25
|
+
case "copilot":
|
|
26
|
+
return paths.scope === "local"
|
|
27
|
+
? path.join(workspaceRoot, ".github", "agents")
|
|
28
|
+
: path.join(home, ".vscode", "chatmodes");
|
|
29
|
+
case "pi":
|
|
30
|
+
return paths.scope === "local"
|
|
31
|
+
? path.join(workspaceRoot, ".pi", "agents")
|
|
32
|
+
: path.join(home, ".pi", "agent", "agents");
|
|
33
|
+
default:
|
|
34
|
+
return path.join(workspaceRoot, ".agents", "unknown");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function getProviderCommandsDir(paths, provider) {
|
|
38
|
+
const workspaceRoot = paths.workspaceRoot;
|
|
39
|
+
const home = paths.homeDir;
|
|
40
|
+
switch (provider) {
|
|
41
|
+
case "cursor":
|
|
42
|
+
return paths.scope === "local"
|
|
43
|
+
? path.join(workspaceRoot, ".cursor", "commands")
|
|
44
|
+
: path.join(home, ".cursor", "commands");
|
|
45
|
+
case "claude":
|
|
46
|
+
return paths.scope === "local"
|
|
47
|
+
? path.join(workspaceRoot, ".claude", "commands")
|
|
48
|
+
: path.join(home, ".claude", "commands");
|
|
49
|
+
case "codex":
|
|
50
|
+
return getCodexPromptsDir(paths);
|
|
51
|
+
case "opencode":
|
|
52
|
+
return paths.scope === "local"
|
|
53
|
+
? path.join(workspaceRoot, ".opencode", "commands")
|
|
54
|
+
: path.join(home, ".config", "opencode", "commands");
|
|
55
|
+
case "gemini":
|
|
56
|
+
return paths.scope === "local"
|
|
57
|
+
? path.join(workspaceRoot, ".gemini", "commands")
|
|
58
|
+
: path.join(home, ".gemini", "commands");
|
|
59
|
+
case "copilot":
|
|
60
|
+
return paths.scope === "local"
|
|
61
|
+
? path.join(workspaceRoot, ".github", "prompts")
|
|
62
|
+
: path.join(home, ".github", "prompts");
|
|
63
|
+
case "pi":
|
|
64
|
+
return paths.scope === "local"
|
|
65
|
+
? path.join(workspaceRoot, ".pi", "prompts")
|
|
66
|
+
: path.join(home, ".pi", "agent", "prompts");
|
|
67
|
+
default:
|
|
68
|
+
return path.join(workspaceRoot, ".agents", "unknown", "commands");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function getProviderSkillsPaths(paths, providers) {
|
|
72
|
+
const targets = new Set();
|
|
73
|
+
const hasClaudeStyleProvider = providers.includes("claude") || providers.includes("copilot");
|
|
74
|
+
if (hasClaudeStyleProvider) {
|
|
75
|
+
targets.add(paths.scope === "local"
|
|
76
|
+
? path.join(paths.workspaceRoot, ".claude", "skills")
|
|
77
|
+
: path.join(paths.homeDir, ".claude", "skills"));
|
|
78
|
+
}
|
|
79
|
+
if (providers.includes("cursor")) {
|
|
80
|
+
targets.add(paths.scope === "local"
|
|
81
|
+
? path.join(paths.workspaceRoot, ".cursor", "skills")
|
|
82
|
+
: path.join(paths.homeDir, ".cursor", "skills"));
|
|
83
|
+
}
|
|
84
|
+
if (providers.includes("pi")) {
|
|
85
|
+
targets.add(paths.scope === "local"
|
|
86
|
+
? path.join(paths.workspaceRoot, ".pi", "skills")
|
|
87
|
+
: path.join(paths.homeDir, ".pi", "agent", "skills"));
|
|
88
|
+
}
|
|
89
|
+
return [...targets];
|
|
90
|
+
}
|
|
91
|
+
export function getCursorMcpPath(paths) {
|
|
92
|
+
return paths.scope === "local"
|
|
93
|
+
? path.join(paths.workspaceRoot, ".cursor", "mcp.json")
|
|
94
|
+
: path.join(paths.homeDir, ".cursor", "mcp.json");
|
|
95
|
+
}
|
|
96
|
+
export function getClaudeMcpPath(paths) {
|
|
97
|
+
return paths.scope === "local"
|
|
98
|
+
? path.join(paths.workspaceRoot, ".mcp.json")
|
|
99
|
+
: path.join(paths.homeDir, ".mcp.json");
|
|
100
|
+
}
|
|
101
|
+
export function getClaudeSettingsPath(paths) {
|
|
102
|
+
return paths.scope === "local"
|
|
103
|
+
? path.join(paths.workspaceRoot, ".claude", "settings.json")
|
|
104
|
+
: path.join(paths.homeDir, ".claude.json");
|
|
105
|
+
}
|
|
106
|
+
export function getOpenCodeConfigPath(paths) {
|
|
107
|
+
return paths.scope === "local"
|
|
108
|
+
? path.join(paths.workspaceRoot, ".opencode", "opencode.json")
|
|
109
|
+
: path.join(paths.homeDir, ".config", "opencode", "opencode.json");
|
|
110
|
+
}
|
|
111
|
+
export function getGeminiSettingsPath(paths) {
|
|
112
|
+
return paths.scope === "local"
|
|
113
|
+
? path.join(paths.workspaceRoot, ".gemini", "settings.json")
|
|
114
|
+
: path.join(paths.homeDir, ".gemini", "settings.json");
|
|
115
|
+
}
|
|
116
|
+
export function getCopilotMcpPath(paths) {
|
|
117
|
+
return paths.scope === "local"
|
|
118
|
+
? path.join(paths.workspaceRoot, ".vscode", "mcp.json")
|
|
119
|
+
: path.join(paths.homeDir, ".vscode", "mcp.json");
|
|
120
|
+
}
|
|
121
|
+
export function getCodexRootDir(paths) {
|
|
122
|
+
return paths.scope === "local"
|
|
123
|
+
? path.join(paths.workspaceRoot, ".codex")
|
|
124
|
+
: path.join(paths.homeDir, ".codex");
|
|
125
|
+
}
|
|
126
|
+
export function getCodexConfigPath(paths) {
|
|
127
|
+
return path.join(getCodexRootDir(paths), "config.toml");
|
|
128
|
+
}
|
|
129
|
+
export function getCodexAgentsDir(paths) {
|
|
130
|
+
return path.join(getCodexRootDir(paths), "agents");
|
|
131
|
+
}
|
|
132
|
+
export function getCodexPromptsDir(paths) {
|
|
133
|
+
return path.join(paths.homeDir, ".codex", "prompts");
|
|
134
|
+
}
|
|
135
|
+
export function getPiMcpPath(paths) {
|
|
136
|
+
return paths.scope === "local"
|
|
137
|
+
? path.join(paths.workspaceRoot, ".pi", "mcp.json")
|
|
138
|
+
: path.join(paths.homeDir, ".pi", "agent", "mcp.json");
|
|
139
|
+
}
|
|
140
|
+
export function getVsCodeSettingsPath(homeDir) {
|
|
141
|
+
switch (os.platform()) {
|
|
142
|
+
case "darwin":
|
|
143
|
+
return path.join(homeDir, "Library", "Application Support", "Code", "User", "settings.json");
|
|
144
|
+
case "win32": {
|
|
145
|
+
const appData = process.env.APPDATA;
|
|
146
|
+
if (!appData) {
|
|
147
|
+
return path.join(homeDir, "AppData", "Roaming", "Code", "User", "settings.json");
|
|
148
|
+
}
|
|
149
|
+
return path.join(appData, "Code", "User", "settings.json");
|
|
150
|
+
}
|
|
151
|
+
default:
|
|
152
|
+
return path.join(homeDir, ".config", "Code", "User", "settings.json");
|
|
153
|
+
}
|
|
154
|
+
}
|
package/dist/core/router.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EntityType } from "../types.js";
|
|
2
|
-
export type AggregateVerb = "add" | "find" | "update" | "sync" | "delete";
|
|
2
|
+
export type AggregateVerb = "add" | "find" | "update" | "sync" | "delete" | "init";
|
|
3
3
|
export type EntityVerb = "add" | "list" | "delete" | "find" | "update" | "sync";
|
|
4
4
|
export type McpServerVerb = "add" | "list" | "delete";
|
|
5
5
|
export type CommandRoute = {
|
package/dist/core/router.js
CHANGED
package/dist/core/skills.js
CHANGED
|
@@ -2,6 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import matter from "gray-matter";
|
|
4
4
|
import { ensureDir, slugify } from "./fs.js";
|
|
5
|
+
import { getProviderSkillsPaths } from "./provider-paths.js";
|
|
5
6
|
export const ROOT_SKILL_ARTIFACT_DIRS = [
|
|
6
7
|
"references",
|
|
7
8
|
"assets",
|
|
@@ -123,7 +124,7 @@ export function skillContentMatchesTarget(skill, targetDir) {
|
|
|
123
124
|
return rootSkillArtifactsEqual(skill.sourcePath, targetDir);
|
|
124
125
|
}
|
|
125
126
|
export function applySkillProviderSideEffects(options) {
|
|
126
|
-
const pathsToSymlink =
|
|
127
|
+
const pathsToSymlink = getProviderSkillsPaths(options.paths, options.providers);
|
|
127
128
|
if (pathsToSymlink.length === 0)
|
|
128
129
|
return;
|
|
129
130
|
const canonicalSkillsDir = options.paths.skillsDir;
|
|
@@ -139,21 +140,6 @@ export function applySkillProviderSideEffects(options) {
|
|
|
139
140
|
});
|
|
140
141
|
}
|
|
141
142
|
}
|
|
142
|
-
function resolveProviderSkillsPaths(paths, providers) {
|
|
143
|
-
const targets = new Set();
|
|
144
|
-
const hasClaudeStyleProvider = providers.includes("claude") || providers.includes("copilot");
|
|
145
|
-
if (hasClaudeStyleProvider) {
|
|
146
|
-
targets.add(paths.scope === "local"
|
|
147
|
-
? path.join(paths.workspaceRoot, ".claude", "skills")
|
|
148
|
-
: path.join(paths.homeDir, ".claude", "skills"));
|
|
149
|
-
}
|
|
150
|
-
if (providers.includes("cursor")) {
|
|
151
|
-
targets.add(paths.scope === "local"
|
|
152
|
-
? path.join(paths.workspaceRoot, ".cursor", "skills")
|
|
153
|
-
: path.join(paths.homeDir, ".cursor", "skills"));
|
|
154
|
-
}
|
|
155
|
-
return [...targets];
|
|
156
|
-
}
|
|
157
143
|
function enforceProviderSkillsSymlink(options) {
|
|
158
144
|
const resolvedCanonical = realPathOrResolved(options.canonicalSkillsDir);
|
|
159
145
|
const targetDir = options.targetSkillsDir;
|
|
@@ -5,4 +5,5 @@ type MaybeNotifyOptions = {
|
|
|
5
5
|
};
|
|
6
6
|
export declare function maybeNotifyVersionUpdate(options: MaybeNotifyOptions): Promise<void>;
|
|
7
7
|
export declare function isNewerVersion(candidate: string, current: string): boolean;
|
|
8
|
+
export declare function promptAndUpdate(current: string, latest: string): Promise<"updated" | "declined" | "failed">;
|
|
8
9
|
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
1
2
|
import fs from "node:fs";
|
|
2
3
|
import https from "node:https";
|
|
3
4
|
import os from "node:os";
|
|
4
5
|
import path from "node:path";
|
|
6
|
+
import { confirm, isCancel } from "@clack/prompts";
|
|
5
7
|
import { ensureDir, writeJsonAtomic } from "./fs.js";
|
|
6
8
|
const UPDATE_CACHE_PATH = path.join(os.homedir(), ".agents", ".agentloom-version-cache.json");
|
|
7
9
|
const CHECK_INTERVAL_MS = 12 * 60 * 60 * 1000;
|
|
@@ -25,7 +27,7 @@ export async function maybeNotifyVersionUpdate(options) {
|
|
|
25
27
|
if (cache.latestVersion &&
|
|
26
28
|
isNewerVersion(cache.latestVersion, options.currentVersion) &&
|
|
27
29
|
cache.lastNotifiedVersion !== cache.latestVersion) {
|
|
28
|
-
|
|
30
|
+
await promptAndUpdate(options.currentVersion, cache.latestVersion);
|
|
29
31
|
cache.lastNotifiedVersion = cache.latestVersion;
|
|
30
32
|
writeVersionCache(cache);
|
|
31
33
|
}
|
|
@@ -44,7 +46,7 @@ export async function maybeNotifyVersionUpdate(options) {
|
|
|
44
46
|
cache.latestVersion = latest;
|
|
45
47
|
if (isNewerVersion(latest, options.currentVersion) &&
|
|
46
48
|
cache.lastNotifiedVersion !== latest) {
|
|
47
|
-
|
|
49
|
+
await promptAndUpdate(options.currentVersion, latest);
|
|
48
50
|
cache.lastNotifiedVersion = latest;
|
|
49
51
|
}
|
|
50
52
|
writeVersionCache(cache);
|
|
@@ -109,8 +111,24 @@ function fetchLatestVersion(packageName) {
|
|
|
109
111
|
req.on("error", () => resolve(null));
|
|
110
112
|
});
|
|
111
113
|
}
|
|
112
|
-
function
|
|
113
|
-
|
|
114
|
+
export async function promptAndUpdate(current, latest) {
|
|
115
|
+
const accepted = await confirm({
|
|
116
|
+
message: `Update available: ${current} → ${latest}. Update now?`,
|
|
117
|
+
initialValue: true,
|
|
118
|
+
});
|
|
119
|
+
if (isCancel(accepted) || !accepted)
|
|
120
|
+
return "declined";
|
|
121
|
+
console.log(`\nUpdating agentloom to ${latest}...\n`);
|
|
122
|
+
const result = spawnSync("npm", ["i", "-g", "agentloom"], {
|
|
123
|
+
stdio: "inherit",
|
|
124
|
+
});
|
|
125
|
+
if (result.status === 0) {
|
|
126
|
+
console.log(`\nUpdated to ${latest}. Please re-run your command.\n`);
|
|
127
|
+
process.exit(0);
|
|
128
|
+
return "updated"; // unreachable, but satisfies type checker
|
|
129
|
+
}
|
|
130
|
+
console.error(`\nUpdate failed. You can update manually: npm i -g agentloom\n`);
|
|
131
|
+
return "failed";
|
|
114
132
|
}
|
|
115
133
|
function readVersionCache() {
|
|
116
134
|
try {
|
package/dist/sync/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import os from "node:os";
|
|
3
2
|
import path from "node:path";
|
|
4
3
|
import { cancel, isCancel, multiselect } from "@clack/prompts";
|
|
5
4
|
import TOML from "@iarna/toml";
|
|
@@ -10,6 +9,7 @@ import { parseCommandsDir } from "../core/commands.js";
|
|
|
10
9
|
import { ensureDir, isObject, readJsonIfExists, relativePosix, removeFileIfExists, slugify, toPosixPath, writeJsonAtomic, writeTextAtomic, } from "../core/fs.js";
|
|
11
10
|
import { readManifest, writeManifest } from "../core/manifest.js";
|
|
12
11
|
import { readCanonicalMcp, resolveMcpForProvider } from "../core/mcp.js";
|
|
12
|
+
import { getClaudeMcpPath, getClaudeSettingsPath, getCodexAgentsDir, getCodexConfigPath, getCodexRootDir, getCopilotMcpPath, getCursorMcpPath, getGeminiSettingsPath, getOpenCodeConfigPath, getPiMcpPath, getProviderAgentsDir, getProviderCommandsDir, getVsCodeSettingsPath, } from "../core/provider-paths.js";
|
|
13
13
|
import { getGlobalSettingsPath, readSettings, updateLastScope, updateLastScopeBestEffort, } from "../core/settings.js";
|
|
14
14
|
export async function resolveProvidersForSync(options) {
|
|
15
15
|
const settings = readSettings(options.paths.settingsPath);
|
|
@@ -150,6 +150,7 @@ const PROVIDER_LABELS = {
|
|
|
150
150
|
opencode: "OpenCode",
|
|
151
151
|
gemini: "Gemini",
|
|
152
152
|
copilot: "Copilot",
|
|
153
|
+
pi: "Pi",
|
|
153
154
|
};
|
|
154
155
|
const MULTISELECT_HELP_TEXT = "↑↓ move, space select, enter confirm";
|
|
155
156
|
function withMultiselectHelp(message) {
|
|
@@ -226,38 +227,6 @@ function buildProviderAgentContent(provider, agent, providerConfig) {
|
|
|
226
227
|
const fm = YAML.stringify(frontmatter).trimEnd();
|
|
227
228
|
return `---\n${fm}\n---\n\n${agent.body.trimStart()}${agent.body.endsWith("\n") ? "" : "\n"}`;
|
|
228
229
|
}
|
|
229
|
-
function getProviderAgentsDir(paths, provider) {
|
|
230
|
-
const workspaceRoot = paths.workspaceRoot;
|
|
231
|
-
const home = paths.homeDir;
|
|
232
|
-
switch (provider) {
|
|
233
|
-
case "cursor":
|
|
234
|
-
return paths.scope === "local"
|
|
235
|
-
? path.join(workspaceRoot, ".cursor", "agents")
|
|
236
|
-
: path.join(home, ".cursor", "agents");
|
|
237
|
-
case "claude":
|
|
238
|
-
return paths.scope === "local"
|
|
239
|
-
? path.join(workspaceRoot, ".claude", "agents")
|
|
240
|
-
: path.join(home, ".claude", "agents");
|
|
241
|
-
case "codex":
|
|
242
|
-
return paths.scope === "local"
|
|
243
|
-
? path.join(workspaceRoot, ".codex", "agents")
|
|
244
|
-
: path.join(home, ".codex", "agents");
|
|
245
|
-
case "opencode":
|
|
246
|
-
return paths.scope === "local"
|
|
247
|
-
? path.join(workspaceRoot, ".opencode", "agents")
|
|
248
|
-
: path.join(home, ".config", "opencode", "agents");
|
|
249
|
-
case "gemini":
|
|
250
|
-
return paths.scope === "local"
|
|
251
|
-
? path.join(workspaceRoot, ".gemini", "agents")
|
|
252
|
-
: path.join(home, ".gemini", "agents");
|
|
253
|
-
case "copilot":
|
|
254
|
-
return paths.scope === "local"
|
|
255
|
-
? path.join(workspaceRoot, ".github", "agents")
|
|
256
|
-
: path.join(home, ".vscode", "chatmodes");
|
|
257
|
-
default:
|
|
258
|
-
return path.join(workspaceRoot, ".agents", "unknown");
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
230
|
function syncProviderCommands(options) {
|
|
262
231
|
const providerDir = getProviderCommandsDir(options.paths, options.provider);
|
|
263
232
|
for (const command of options.commands) {
|
|
@@ -292,45 +261,13 @@ function mapProviderCommandFileName(provider, fileName) {
|
|
|
292
261
|
}
|
|
293
262
|
return fileName;
|
|
294
263
|
}
|
|
295
|
-
function getProviderCommandsDir(paths, provider) {
|
|
296
|
-
const workspaceRoot = paths.workspaceRoot;
|
|
297
|
-
const home = paths.homeDir;
|
|
298
|
-
switch (provider) {
|
|
299
|
-
case "cursor":
|
|
300
|
-
return paths.scope === "local"
|
|
301
|
-
? path.join(workspaceRoot, ".cursor", "commands")
|
|
302
|
-
: path.join(home, ".cursor", "commands");
|
|
303
|
-
case "claude":
|
|
304
|
-
return paths.scope === "local"
|
|
305
|
-
? path.join(workspaceRoot, ".claude", "commands")
|
|
306
|
-
: path.join(home, ".claude", "commands");
|
|
307
|
-
case "codex":
|
|
308
|
-
return path.join(home, ".codex", "prompts");
|
|
309
|
-
case "opencode":
|
|
310
|
-
return paths.scope === "local"
|
|
311
|
-
? path.join(workspaceRoot, ".opencode", "commands")
|
|
312
|
-
: path.join(home, ".config", "opencode", "commands");
|
|
313
|
-
case "gemini":
|
|
314
|
-
return paths.scope === "local"
|
|
315
|
-
? path.join(workspaceRoot, ".gemini", "commands")
|
|
316
|
-
: path.join(home, ".gemini", "commands");
|
|
317
|
-
case "copilot":
|
|
318
|
-
return paths.scope === "local"
|
|
319
|
-
? path.join(workspaceRoot, ".github", "prompts")
|
|
320
|
-
: path.join(home, ".github", "prompts");
|
|
321
|
-
default:
|
|
322
|
-
return path.join(workspaceRoot, ".agents", "unknown", "commands");
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
264
|
function syncProviderMcp(options) {
|
|
326
265
|
for (const provider of options.providers) {
|
|
327
266
|
if (provider === "codex")
|
|
328
267
|
continue;
|
|
329
268
|
const resolved = resolveMcpForProvider(options.mcp, provider);
|
|
330
269
|
if (provider === "cursor") {
|
|
331
|
-
const outputPath = options.paths
|
|
332
|
-
? path.join(options.paths.workspaceRoot, ".cursor", "mcp.json")
|
|
333
|
-
: path.join(options.paths.homeDir, ".cursor", "mcp.json");
|
|
270
|
+
const outputPath = getCursorMcpPath(options.paths);
|
|
334
271
|
const payload = {
|
|
335
272
|
mcpServers: mapMcpServers(resolved, ["url", "command", "args", "env"]),
|
|
336
273
|
};
|
|
@@ -339,12 +276,8 @@ function syncProviderMcp(options) {
|
|
|
339
276
|
continue;
|
|
340
277
|
}
|
|
341
278
|
if (provider === "claude") {
|
|
342
|
-
const mcpPath = options.paths
|
|
343
|
-
|
|
344
|
-
: path.join(options.paths.homeDir, ".mcp.json");
|
|
345
|
-
const settingsPath = options.paths.scope === "local"
|
|
346
|
-
? path.join(options.paths.workspaceRoot, ".claude", "settings.json")
|
|
347
|
-
: path.join(options.paths.homeDir, ".claude.json");
|
|
279
|
+
const mcpPath = getClaudeMcpPath(options.paths);
|
|
280
|
+
const settingsPath = getClaudeSettingsPath(options.paths);
|
|
348
281
|
const claudeServers = mapMcpServers(resolved, [
|
|
349
282
|
"type",
|
|
350
283
|
"url",
|
|
@@ -366,9 +299,7 @@ function syncProviderMcp(options) {
|
|
|
366
299
|
continue;
|
|
367
300
|
}
|
|
368
301
|
if (provider === "opencode") {
|
|
369
|
-
const outputPath = options.paths
|
|
370
|
-
? path.join(options.paths.workspaceRoot, ".opencode", "opencode.json")
|
|
371
|
-
: path.join(options.paths.homeDir, ".config", "opencode", "opencode.json");
|
|
302
|
+
const outputPath = getOpenCodeConfigPath(options.paths);
|
|
372
303
|
const existing = readJsonIfExists(outputPath) ?? {};
|
|
373
304
|
const mcp = {};
|
|
374
305
|
for (const [serverName, config] of Object.entries(resolved)) {
|
|
@@ -398,9 +329,7 @@ function syncProviderMcp(options) {
|
|
|
398
329
|
continue;
|
|
399
330
|
}
|
|
400
331
|
if (provider === "gemini") {
|
|
401
|
-
const outputPath = options.paths
|
|
402
|
-
? path.join(options.paths.workspaceRoot, ".gemini", "settings.json")
|
|
403
|
-
: path.join(options.paths.homeDir, ".gemini", "settings.json");
|
|
332
|
+
const outputPath = getGeminiSettingsPath(options.paths);
|
|
404
333
|
const existing = readJsonIfExists(outputPath) ?? {};
|
|
405
334
|
const experimental = isObject(existing.experimental)
|
|
406
335
|
? { ...existing.experimental }
|
|
@@ -429,9 +358,7 @@ function syncProviderMcp(options) {
|
|
|
429
358
|
continue;
|
|
430
359
|
}
|
|
431
360
|
if (provider === "copilot") {
|
|
432
|
-
const profileMcpPath = options.paths
|
|
433
|
-
? path.join(options.paths.workspaceRoot, ".vscode", "mcp.json")
|
|
434
|
-
: path.join(options.paths.homeDir, ".vscode", "mcp.json");
|
|
361
|
+
const profileMcpPath = getCopilotMcpPath(options.paths);
|
|
435
362
|
const copilotServers = mapMcpServers(resolved, [
|
|
436
363
|
"type",
|
|
437
364
|
"url",
|
|
@@ -458,14 +385,21 @@ function syncProviderMcp(options) {
|
|
|
458
385
|
options.generated.add(settingsPath);
|
|
459
386
|
}
|
|
460
387
|
}
|
|
388
|
+
if (provider === "pi") {
|
|
389
|
+
const outputPath = getPiMcpPath(options.paths);
|
|
390
|
+
const payload = {
|
|
391
|
+
mcpServers: mapMcpServers(resolved, ["url", "command", "args", "env"]),
|
|
392
|
+
};
|
|
393
|
+
maybeWriteJson(outputPath, payload, options.dryRun);
|
|
394
|
+
options.generated.add(outputPath);
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
461
397
|
}
|
|
462
398
|
}
|
|
463
399
|
function syncCodex(options) {
|
|
464
|
-
const codexDir = options.paths
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
const codexConfigPath = path.join(codexDir, "config.toml");
|
|
468
|
-
const codexAgentsDir = path.join(codexDir, "agents");
|
|
400
|
+
const codexDir = getCodexRootDir(options.paths);
|
|
401
|
+
const codexConfigPath = getCodexConfigPath(options.paths);
|
|
402
|
+
const codexAgentsDir = getCodexAgentsDir(options.paths);
|
|
469
403
|
const rawConfig = fs.existsSync(codexConfigPath)
|
|
470
404
|
? fs.readFileSync(codexConfigPath, "utf8")
|
|
471
405
|
: "";
|
|
@@ -631,21 +565,6 @@ async function removeStaleGeneratedFiles(options) {
|
|
|
631
565
|
}
|
|
632
566
|
return stale;
|
|
633
567
|
}
|
|
634
|
-
function getVsCodeSettingsPath(homeDir) {
|
|
635
|
-
switch (os.platform()) {
|
|
636
|
-
case "darwin":
|
|
637
|
-
return path.join(homeDir, "Library", "Application Support", "Code", "User", "settings.json");
|
|
638
|
-
case "win32": {
|
|
639
|
-
const appData = process.env.APPDATA;
|
|
640
|
-
if (!appData) {
|
|
641
|
-
return path.join(homeDir, "AppData", "Roaming", "Code", "User", "settings.json");
|
|
642
|
-
}
|
|
643
|
-
return path.join(appData, "Code", "User", "settings.json");
|
|
644
|
-
}
|
|
645
|
-
default:
|
|
646
|
-
return path.join(homeDir, ".config", "Code", "User", "settings.json");
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
568
|
function normalizeGeneratedByEntity(manifest) {
|
|
650
569
|
const source = manifest.generatedByEntity;
|
|
651
570
|
if (!source || typeof source !== "object") {
|
|
@@ -695,7 +614,8 @@ function isLegacyCommandOutputPath(normalizedPath) {
|
|
|
695
614
|
normalizedPath.includes("/.opencode/commands/") ||
|
|
696
615
|
normalizedPath.includes("/.gemini/commands/") ||
|
|
697
616
|
normalizedPath.includes("/.github/prompts/") ||
|
|
698
|
-
normalizedPath.includes("/.codex/prompts/")
|
|
617
|
+
normalizedPath.includes("/.codex/prompts/") ||
|
|
618
|
+
normalizedPath.includes("/.pi/prompts/"));
|
|
699
619
|
}
|
|
700
620
|
function isLegacyAgentOutputPath(normalizedPath) {
|
|
701
621
|
return (normalizedPath.includes("/.cursor/agents/") ||
|
|
@@ -704,7 +624,8 @@ function isLegacyAgentOutputPath(normalizedPath) {
|
|
|
704
624
|
normalizedPath.includes("/.opencode/agents/") ||
|
|
705
625
|
normalizedPath.includes("/.gemini/agents/") ||
|
|
706
626
|
normalizedPath.includes("/.github/agents/") ||
|
|
707
|
-
normalizedPath.includes("/.codex/agents/")
|
|
627
|
+
normalizedPath.includes("/.codex/agents/") ||
|
|
628
|
+
normalizedPath.includes("/.pi/agents/"));
|
|
708
629
|
}
|
|
709
630
|
function isLegacyMcpOutputPath(normalizedPath) {
|
|
710
631
|
return (normalizedPath.endsWith("/.cursor/mcp.json") ||
|
|
@@ -713,7 +634,9 @@ function isLegacyMcpOutputPath(normalizedPath) {
|
|
|
713
634
|
normalizedPath.endsWith("/.opencode/opencode.json") ||
|
|
714
635
|
normalizedPath.endsWith("/.gemini/settings.json") ||
|
|
715
636
|
normalizedPath.endsWith("/.vscode/mcp.json") ||
|
|
716
|
-
normalizedPath.endsWith("/code/user/settings.json")
|
|
637
|
+
normalizedPath.endsWith("/code/user/settings.json") ||
|
|
638
|
+
normalizedPath.endsWith("/.pi/mcp.json") ||
|
|
639
|
+
normalizedPath.endsWith("/.pi/agent/mcp.json"));
|
|
717
640
|
}
|
|
718
641
|
function isLegacyCodexConfigPath(normalizedPath) {
|
|
719
642
|
return normalizedPath.endsWith("/.codex/config.toml");
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const ALL_PROVIDERS: readonly ["cursor", "claude", "codex", "opencode", "gemini", "copilot"];
|
|
1
|
+
export declare const ALL_PROVIDERS: readonly ["cursor", "claude", "codex", "opencode", "gemini", "copilot", "pi"];
|
|
2
2
|
export type Provider = (typeof ALL_PROVIDERS)[number];
|
|
3
3
|
export type Scope = "local" | "global";
|
|
4
4
|
export type EntityType = "agent" | "command" | "mcp" | "skill";
|
|
@@ -12,6 +12,7 @@ export interface AgentFrontmatter {
|
|
|
12
12
|
opencode?: Record<string, unknown> | false;
|
|
13
13
|
gemini?: Record<string, unknown> | false;
|
|
14
14
|
copilot?: Record<string, unknown> | false;
|
|
15
|
+
pi?: Record<string, unknown> | false;
|
|
15
16
|
[key: string]: unknown;
|
|
16
17
|
}
|
|
17
18
|
export interface CanonicalAgent {
|
package/dist/types.js
CHANGED