@tofrankie/agents-sync 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/dist/cli.mjs +72 -45
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
package/dist/cli.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import process
|
|
2
|
+
import process from "node:process";
|
|
3
3
|
import * as p from "@clack/prompts";
|
|
4
4
|
import c from "ansis";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import fs from "node:fs/promises";
|
|
7
7
|
import path from "node:path";
|
|
8
|
-
import { loadConfig } from "c12";
|
|
9
|
-
import jiti from "jiti";
|
|
10
8
|
import os from "node:os";
|
|
9
|
+
import { loadConfig } from "c12";
|
|
10
|
+
import { createJiti } from "jiti";
|
|
11
11
|
//#region src/core/agent-profiles.ts
|
|
12
12
|
const AGENT_PROFILES = {
|
|
13
13
|
cursor: {
|
|
@@ -93,22 +93,20 @@ const DEFAULTS = {
|
|
|
93
93
|
source: "~/.agents",
|
|
94
94
|
targetAgent: "cursor"
|
|
95
95
|
};
|
|
96
|
-
function pickFirst(value) {
|
|
97
|
-
if (Array.isArray(value)) return value[0];
|
|
98
|
-
return value;
|
|
99
|
-
}
|
|
100
96
|
async function loadUserConfig(cwd, configPath) {
|
|
101
97
|
if (configPath) {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
return loaded
|
|
98
|
+
const resolvedConfig = path.resolve(cwd, configPath);
|
|
99
|
+
const loaded = await createJiti(resolvedConfig, { interopDefault: true }).import(resolvedConfig, { default: true });
|
|
100
|
+
return loaded && typeof loaded === "object" ? loaded : {};
|
|
105
101
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
102
|
+
const projectDir = path.resolve(cwd);
|
|
103
|
+
const homeDir = path.resolve(os.homedir());
|
|
104
|
+
if (projectDir === homeDir) return loadHomeAgentsSyncConfig(homeDir);
|
|
105
|
+
const projectLayer = await loadAgentsSyncConfigFromDir(projectDir);
|
|
106
|
+
return {
|
|
107
|
+
...await loadHomeAgentsSyncConfig(homeDir),
|
|
108
|
+
...projectLayer
|
|
109
|
+
};
|
|
112
110
|
}
|
|
113
111
|
function resolveOptions(config, cli) {
|
|
114
112
|
const sourceFromConfig = pickFirst(config.sourceDir);
|
|
@@ -122,26 +120,37 @@ function resolveOptions(config, cli) {
|
|
|
122
120
|
yes: Boolean(cli.yes)
|
|
123
121
|
};
|
|
124
122
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
try {
|
|
129
|
-
await fs.access(filePath);
|
|
130
|
-
return true;
|
|
131
|
-
} catch {
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
123
|
+
function pickFirst(value) {
|
|
124
|
+
if (Array.isArray(value)) return value[0];
|
|
125
|
+
return value;
|
|
134
126
|
}
|
|
135
|
-
async function
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
127
|
+
async function loadAgentsSyncConfigFromDir(dir) {
|
|
128
|
+
return (await loadC12AgentsSync(dir)).config ?? {};
|
|
129
|
+
}
|
|
130
|
+
/** Standard `agents-sync.config.*` (+ c12 rc / layers for that name). */
|
|
131
|
+
async function loadC12AgentsSync(dir) {
|
|
132
|
+
return loadConfig({
|
|
133
|
+
cwd: dir,
|
|
134
|
+
name: "agents-sync",
|
|
135
|
+
defaults: {},
|
|
136
|
+
jitiOptions: { interopDefault: true }
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* User home only: hidden `.agents-sync.config.*` (not `agents-sync.config.*`).
|
|
141
|
+
* Keeps `name: 'agents-sync'` so `~/.agents-syncrc` still merges when present.
|
|
142
|
+
*/
|
|
143
|
+
async function loadHomeAgentsSyncConfig(homeDir) {
|
|
144
|
+
return (await loadConfig({
|
|
145
|
+
cwd: homeDir,
|
|
146
|
+
name: "agents-sync",
|
|
147
|
+
configFile: ".agents-sync.config",
|
|
148
|
+
defaults: {},
|
|
149
|
+
jitiOptions: { interopDefault: true }
|
|
150
|
+
})).config ?? {};
|
|
144
151
|
}
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region src/core/sync-engine.ts
|
|
145
154
|
async function discoverSkills(source) {
|
|
146
155
|
const candidates = [path.join(source, "skills"), source];
|
|
147
156
|
const found = [];
|
|
@@ -232,6 +241,24 @@ function renderMcpConfigByAgent(model, targetAgent) {
|
|
|
232
241
|
if (targetAgent !== "cursor") throw new Error(`unsupported mcp target: ${targetAgent}`);
|
|
233
242
|
return `${JSON.stringify(model, null, 2)}\n`;
|
|
234
243
|
}
|
|
244
|
+
async function exists(filePath) {
|
|
245
|
+
try {
|
|
246
|
+
await fs.access(filePath);
|
|
247
|
+
return true;
|
|
248
|
+
} catch {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
async function listFilesRecursively(root) {
|
|
253
|
+
const out = [];
|
|
254
|
+
const entries = await fs.readdir(root, { withFileTypes: true });
|
|
255
|
+
for (const entry of entries) {
|
|
256
|
+
const abs = path.join(root, entry.name);
|
|
257
|
+
if (entry.isDirectory()) out.push(...await listFilesRecursively(abs));
|
|
258
|
+
else out.push(abs);
|
|
259
|
+
}
|
|
260
|
+
return out;
|
|
261
|
+
}
|
|
235
262
|
//#endregion
|
|
236
263
|
//#region src/cli/commands/mcp.ts
|
|
237
264
|
async function runMcpCommand(cwd, options) {
|
|
@@ -285,7 +312,7 @@ async function runSkillCommand(cwd, options) {
|
|
|
285
312
|
let selected = skillDirs;
|
|
286
313
|
if (!runtime.yes) {
|
|
287
314
|
const picked = await p.multiselect({
|
|
288
|
-
message: `Select ${c.green("skills")} to sync`,
|
|
315
|
+
message: `Select ${c.green("skills")} to sync ${c.dim(runtime.source)}`,
|
|
289
316
|
options: skillDirs.map((dir) => ({
|
|
290
317
|
label: path.basename(dir),
|
|
291
318
|
value: dir
|
|
@@ -328,31 +355,31 @@ async function runSkillCommand(cwd, options) {
|
|
|
328
355
|
//#endregion
|
|
329
356
|
//#region package.json
|
|
330
357
|
var name = "@tofrankie/agents-sync";
|
|
331
|
-
var version = "0.0.
|
|
358
|
+
var version = "0.0.2";
|
|
332
359
|
//#endregion
|
|
333
360
|
//#region src/cli/index.ts
|
|
334
361
|
main().catch((error) => {
|
|
335
|
-
process
|
|
336
|
-
process
|
|
337
|
-
process
|
|
338
|
-
process
|
|
362
|
+
process.stdout.write("\n");
|
|
363
|
+
process.stderr.write(`${String(error)}\n`);
|
|
364
|
+
process.stdout.write("\n");
|
|
365
|
+
process.exitCode = 1;
|
|
339
366
|
});
|
|
340
367
|
async function main() {
|
|
341
368
|
const program = new Command();
|
|
342
369
|
program.name("agents-sync").description("Sync skills, cursor rules, and cursor mcp config from a source folder.").version(version, "-v, --version", "output the version number").hook("preAction", () => {
|
|
343
|
-
process
|
|
370
|
+
process.stdout.write("\n");
|
|
344
371
|
p.intro(`${name} ${c.dim(`v${version}`)}`);
|
|
345
372
|
});
|
|
346
373
|
applySharedOptions(program.command("skill").description("sync skills")).action(async (options) => {
|
|
347
|
-
await runSkillCommand(process
|
|
374
|
+
await runSkillCommand(process.cwd(), options);
|
|
348
375
|
});
|
|
349
376
|
applySharedOptions(program.command("rule").description("sync rules (cursor only)")).action(async (options) => {
|
|
350
|
-
await runRuleCommand(process
|
|
377
|
+
await runRuleCommand(process.cwd(), options);
|
|
351
378
|
});
|
|
352
379
|
applySharedOptions(program.command("mcp").description("sync mcp config (cursor only)")).action(async (options) => {
|
|
353
|
-
await runMcpCommand(process
|
|
380
|
+
await runMcpCommand(process.cwd(), options);
|
|
354
381
|
});
|
|
355
|
-
await program.parseAsync(process
|
|
382
|
+
await program.parseAsync(process.argv);
|
|
356
383
|
}
|
|
357
384
|
function applySharedOptions(cmd) {
|
|
358
385
|
return cmd.option("-s, --source <path>", "source path, default ~/.agents").option("-t, --target-agent <agent>", "target agent, default cursor").option("-c, --config <path>", "config file path").option("--dry-run", "show planned operations without writing files").option("-y, --yes", "skip prompts and overwrite conflicts");
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tofrankie/agents-sync",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2",
|
|
5
5
|
"description": "Sync skills, rules, and MCP from a configurable source into your project",
|
|
6
6
|
"author": "Frankie <1426203851@qq.com> (https://github.com/tofrankie)",
|
|
7
7
|
"license": "MIT",
|
|
@@ -83,6 +83,6 @@
|
|
|
83
83
|
"typecheck": "tsc --noEmit",
|
|
84
84
|
"test": "vitest run",
|
|
85
85
|
"publint": "publint",
|
|
86
|
-
"github:release": "tfr"
|
|
86
|
+
"github:release": "tfr --package @tofrankie/agents-sync"
|
|
87
87
|
}
|
|
88
88
|
}
|