flowsync-cli 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/README.md +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +32 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/pull.d.ts +2 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +5 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/push.d.ts +2 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +5 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/scan.d.ts +2 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +24 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +16 -0
- package/dist/constants.js.map +1 -0
- package/dist/inventory.d.ts +15 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +2 -0
- package/dist/inventory.js.map +1 -0
- package/dist/lib/fs.d.ts +6 -0
- package/dist/lib/fs.d.ts.map +1 -0
- package/dist/lib/fs.js +45 -0
- package/dist/lib/fs.js.map +1 -0
- package/dist/scanner/claude-dir.d.ts +6 -0
- package/dist/scanner/claude-dir.d.ts.map +1 -0
- package/dist/scanner/claude-dir.js +90 -0
- package/dist/scanner/claude-dir.js.map +1 -0
- package/dist/scanner/index.d.ts +5 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +29 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/mcp.d.ts +10 -0
- package/dist/scanner/mcp.d.ts.map +1 -0
- package/dist/scanner/mcp.js +38 -0
- package/dist/scanner/mcp.js.map +1 -0
- package/dist/scanner/project-root.d.ts +7 -0
- package/dist/scanner/project-root.d.ts.map +1 -0
- package/dist/scanner/project-root.js +21 -0
- package/dist/scanner/project-root.js.map +1 -0
- package/dist/ui/prompt.d.ts +11 -0
- package/dist/ui/prompt.d.ts.map +1 -0
- package/dist/ui/prompt.js +68 -0
- package/dist/ui/prompt.js.map +1 -0
- package/dist/ui/render.d.ts +3 -0
- package/dist/ui/render.d.ts.map +1 -0
- package/dist/ui/render.js +39 -0
- package/dist/ui/render.js.map +1 -0
- package/package.json +29 -0
package/README.md
ADDED
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runPull } from "./commands/pull.js";
|
|
3
|
+
import { runPush } from "./commands/push.js";
|
|
4
|
+
import { runScan } from "./commands/scan.js";
|
|
5
|
+
import { HELP, VERSION } from "./constants.js";
|
|
6
|
+
async function main(argv) {
|
|
7
|
+
const command = argv[0];
|
|
8
|
+
if (command === undefined || command === "-h" || command === "--help") {
|
|
9
|
+
console.log(HELP);
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
if (command === "-v" || command === "--version") {
|
|
13
|
+
console.log(VERSION);
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
switch (command) {
|
|
17
|
+
case "scan":
|
|
18
|
+
return runScan();
|
|
19
|
+
case "push":
|
|
20
|
+
return runPush();
|
|
21
|
+
case "pull":
|
|
22
|
+
return runPull();
|
|
23
|
+
default:
|
|
24
|
+
console.error(`flowsync: unknown command "${command}"`);
|
|
25
|
+
console.error(`Run "flowsync --help" to see available commands.`);
|
|
26
|
+
return 1;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
main(process.argv.slice(2)).then((code) => {
|
|
30
|
+
process.exitCode = code;
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE/C,KAAK,UAAU,IAAI,CAAC,IAAc;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAExB,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,OAAO,EAAE,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,OAAO,EAAE,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,OAAO,EAAE,CAAC;QACnB;YACE,OAAO,CAAC,KAAK,CAAC,8BAA8B,OAAO,GAAG,CAAC,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;YAClE,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;IACxC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAAA,wBAAgB,OAAO,IAAI,MAAM,CAGhC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,OAAO;IACrB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAClD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAAA,wBAAgB,OAAO,IAAI,MAAM,CAGhC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,OAAO;IACrB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAClD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAMA,wBAAsB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAqB/C"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { scanProjectScope, scanUserScope } from "../scanner/index.js";
|
|
3
|
+
import { select } from "../ui/prompt.js";
|
|
4
|
+
import { renderScopeInventory } from "../ui/render.js";
|
|
5
|
+
export async function runScan() {
|
|
6
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
7
|
+
console.error("flowsync scan: an interactive terminal is required (stdin is not a TTY).");
|
|
8
|
+
console.error("Run scan from an interactive terminal.");
|
|
9
|
+
return 1;
|
|
10
|
+
}
|
|
11
|
+
const choice = await select("What do you want to scan?", [
|
|
12
|
+
{ label: "Project level", hint: ".claude/ in this repo" },
|
|
13
|
+
{ label: "Global level", hint: "~/.claude/, all projects" },
|
|
14
|
+
]);
|
|
15
|
+
if (choice === null)
|
|
16
|
+
return 130;
|
|
17
|
+
const inventory = choice === 0
|
|
18
|
+
? await scanProjectScope(process.cwd(), homedir())
|
|
19
|
+
: await scanUserScope(homedir());
|
|
20
|
+
console.log();
|
|
21
|
+
console.log(renderScopeInventory(inventory));
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClD,OAAO,CAAC,KAAK,CAAC,0EAA0E,CAAC,CAAC;QAC1F,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;QACxD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,2BAA2B,EAAE;QACvD,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,uBAAuB,EAAE;QACzD,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,0BAA0B,EAAE;KAC5D,CAAC,CAAC;IACH,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAEhC,MAAM,SAAS,GACb,MAAM,KAAK,CAAC;QACV,CAAC,CAAC,MAAM,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC;QAClD,CAAC,CAAC,MAAM,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAErC,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const VERSION = "flowsync 1.0.0";
|
|
2
|
+
export declare const HELP = "flowsync-cli \u2014 move your AI coding setup between machines and repos\n\nUsage:\n flowsync-cli <command>\n\nCommands:\n scan Inventory Claude Code config at user and project scope\n push Send the scanned inventory to a remote\n pull Restore an inventory from a remote\n\nOptions:\n -h, --help Show this help\n -v, --version Show version\n";
|
|
3
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,mBAAmB,CAAC;AAExC,eAAO,MAAM,IAAI,kXAahB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const VERSION = "flowsync 1.0.0";
|
|
2
|
+
export const HELP = `flowsync-cli — move your AI coding setup between machines and repos
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
flowsync-cli <command>
|
|
6
|
+
|
|
7
|
+
Commands:
|
|
8
|
+
scan Inventory Claude Code config at user and project scope
|
|
9
|
+
push Send the scanned inventory to a remote
|
|
10
|
+
pull Restore an inventory from a remote
|
|
11
|
+
|
|
12
|
+
Options:
|
|
13
|
+
-h, --help Show this help
|
|
14
|
+
-v, --version Show version
|
|
15
|
+
`;
|
|
16
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,gBAAgB,CAAC;AAExC,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;;;;;;;;CAanB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type ArtifactType = "settings" | "agent" | "skill" | "command" | "mcp-server" | "claude-md";
|
|
2
|
+
export interface Artifact {
|
|
3
|
+
type: ArtifactType;
|
|
4
|
+
/** Logical name: skill dir name, agent basename, MCP server key, settings filename. */
|
|
5
|
+
name: string;
|
|
6
|
+
/** Absolute path where it was found; for MCP servers, the config file defining it. */
|
|
7
|
+
path: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ScopeInventory {
|
|
10
|
+
scope: "user" | "project";
|
|
11
|
+
/** ~/.claude for user scope; project root for project scope; null if no project root was found. */
|
|
12
|
+
root: string | null;
|
|
13
|
+
artifacts: Artifact[];
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=inventory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GACpB,UAAU,GACV,OAAO,GACP,OAAO,GACP,SAAS,GACT,YAAY,GACZ,WAAW,CAAC;AAEhB,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAC;IACnB,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,mGAAmG;IACnG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inventory.js","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":""}
|
package/dist/lib/fs.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function isDirectory(path: string): Promise<boolean>;
|
|
2
|
+
export declare function isFile(path: string): Promise<boolean>;
|
|
3
|
+
export declare function pathExists(path: string): Promise<boolean>;
|
|
4
|
+
/** Read and parse a JSON file. Missing file → undefined; malformed JSON → warn and undefined. */
|
|
5
|
+
export declare function readJsonFile(path: string): Promise<unknown>;
|
|
6
|
+
//# sourceMappingURL=fs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/lib/fs.ts"],"names":[],"mappings":"AAEA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMhE;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM3D;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED,iGAAiG;AACjG,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAcjE"}
|
package/dist/lib/fs.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readFile, stat } from "node:fs/promises";
|
|
2
|
+
export async function isDirectory(path) {
|
|
3
|
+
try {
|
|
4
|
+
return (await stat(path)).isDirectory();
|
|
5
|
+
}
|
|
6
|
+
catch {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export async function isFile(path) {
|
|
11
|
+
try {
|
|
12
|
+
return (await stat(path)).isFile();
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export async function pathExists(path) {
|
|
19
|
+
try {
|
|
20
|
+
await stat(path);
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** Read and parse a JSON file. Missing file → undefined; malformed JSON → warn and undefined. */
|
|
28
|
+
export async function readJsonFile(path) {
|
|
29
|
+
let text;
|
|
30
|
+
try {
|
|
31
|
+
text = await readFile(path, "utf8");
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
return JSON.parse(text);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
41
|
+
console.error(`flowsync: warning: skipping ${path}: ${reason}`);
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=fs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/lib/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY;IAC7C,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,OAAO,CAAC,KAAK,CAAC,+BAA+B,IAAI,KAAK,MAAM,EAAE,CAAC,CAAC;QAChE,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Artifact } from "../inventory.ts";
|
|
2
|
+
export declare function scanSettingsFile(path: string): Promise<Artifact[]>;
|
|
3
|
+
export declare function scanClaudeMd(path: string): Promise<Artifact[]>;
|
|
4
|
+
/** Shared layout under a .claude/ directory: settings, agents, skills, commands. */
|
|
5
|
+
export declare function scanClaudeDir(claudeDir: string): Promise<Artifact[]>;
|
|
6
|
+
//# sourceMappingURL=claude-dir.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-dir.d.ts","sourceRoot":"","sources":["../../src/scanner/claude-dir.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGhD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAGxE;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAGpE;AAqED,oFAAoF;AACpF,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAO1E"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { readdir } from "node:fs/promises";
|
|
2
|
+
import { basename, join, relative, sep } from "node:path";
|
|
3
|
+
import { isDirectory, isFile } from "../lib/fs.js";
|
|
4
|
+
export async function scanSettingsFile(path) {
|
|
5
|
+
if (!(await isFile(path)))
|
|
6
|
+
return [];
|
|
7
|
+
return [{ type: "settings", name: basename(path), path }];
|
|
8
|
+
}
|
|
9
|
+
export async function scanClaudeMd(path) {
|
|
10
|
+
if (!(await isFile(path)))
|
|
11
|
+
return [];
|
|
12
|
+
return [{ type: "claude-md", name: basename(path), path }];
|
|
13
|
+
}
|
|
14
|
+
/** agents/*.md — name is the basename without .md */
|
|
15
|
+
async function scanAgents(claudeDir) {
|
|
16
|
+
const dir = join(claudeDir, "agents");
|
|
17
|
+
const artifacts = [];
|
|
18
|
+
let entries;
|
|
19
|
+
try {
|
|
20
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
for (const entry of entries) {
|
|
26
|
+
const path = join(dir, entry.name);
|
|
27
|
+
if (entry.name.endsWith(".md") && (entry.isFile() || (await isFile(path)))) {
|
|
28
|
+
artifacts.push({ type: "agent", name: entry.name.slice(0, -3), path });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return artifacts;
|
|
32
|
+
}
|
|
33
|
+
/** skills/<name>/SKILL.md — name is the skill directory name */
|
|
34
|
+
async function scanSkills(claudeDir) {
|
|
35
|
+
const dir = join(claudeDir, "skills");
|
|
36
|
+
const artifacts = [];
|
|
37
|
+
let entries;
|
|
38
|
+
try {
|
|
39
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
for (const entry of entries) {
|
|
45
|
+
// Skill dirs are often symlinks (isDirectory() is false for those); stat follows them.
|
|
46
|
+
if (!entry.isDirectory() && !(await isDirectory(join(dir, entry.name))))
|
|
47
|
+
continue;
|
|
48
|
+
const skillFile = join(dir, entry.name, "SKILL.md");
|
|
49
|
+
if (await isFile(skillFile)) {
|
|
50
|
+
artifacts.push({ type: "skill", name: entry.name, path: skillFile });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return artifacts;
|
|
54
|
+
}
|
|
55
|
+
/** commands/**\/*.md, recursive — name is the path relative to commands/, without .md */
|
|
56
|
+
async function scanCommands(claudeDir) {
|
|
57
|
+
const root = join(claudeDir, "commands");
|
|
58
|
+
const artifacts = [];
|
|
59
|
+
async function walk(dir) {
|
|
60
|
+
let entries;
|
|
61
|
+
try {
|
|
62
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
for (const entry of entries) {
|
|
68
|
+
const path = join(dir, entry.name);
|
|
69
|
+
if (entry.isDirectory() || (entry.isSymbolicLink() && (await isDirectory(path)))) {
|
|
70
|
+
await walk(path);
|
|
71
|
+
}
|
|
72
|
+
else if (entry.name.endsWith(".md") && (entry.isFile() || (await isFile(path)))) {
|
|
73
|
+
const name = relative(root, path).slice(0, -3).split(sep).join("/");
|
|
74
|
+
artifacts.push({ type: "command", name, path });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
await walk(root);
|
|
79
|
+
return artifacts;
|
|
80
|
+
}
|
|
81
|
+
/** Shared layout under a .claude/ directory: settings, agents, skills, commands. */
|
|
82
|
+
export async function scanClaudeDir(claudeDir) {
|
|
83
|
+
return [
|
|
84
|
+
...(await scanSettingsFile(join(claudeDir, "settings.json"))),
|
|
85
|
+
...(await scanAgents(claudeDir)),
|
|
86
|
+
...(await scanSkills(claudeDir)),
|
|
87
|
+
...(await scanCommands(claudeDir)),
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=claude-dir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-dir.js","sourceRoot":"","sources":["../../src/scanner/claude-dir.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ScopeInventory } from "../inventory.ts";
|
|
2
|
+
export { findProjectRoot } from "./project-root.ts";
|
|
3
|
+
export declare function scanUserScope(home: string): Promise<ScopeInventory>;
|
|
4
|
+
export declare function scanProjectScope(cwd: string, home: string): Promise<ScopeInventory>;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAY,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKhE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAQzE;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAczF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { scanClaudeDir, scanClaudeMd, scanSettingsFile } from "./claude-dir.js";
|
|
3
|
+
import { projectMcpServers, userMcpServers } from "./mcp.js";
|
|
4
|
+
import { findProjectRoot } from "./project-root.js";
|
|
5
|
+
export { findProjectRoot } from "./project-root.js";
|
|
6
|
+
export async function scanUserScope(home) {
|
|
7
|
+
const root = join(home, ".claude");
|
|
8
|
+
const artifacts = [
|
|
9
|
+
...(await scanClaudeDir(root)),
|
|
10
|
+
...(await userMcpServers(home)),
|
|
11
|
+
...(await scanClaudeMd(join(root, "CLAUDE.md"))),
|
|
12
|
+
];
|
|
13
|
+
return { scope: "user", root, artifacts };
|
|
14
|
+
}
|
|
15
|
+
export async function scanProjectScope(cwd, home) {
|
|
16
|
+
const root = await findProjectRoot(cwd);
|
|
17
|
+
if (root === null) {
|
|
18
|
+
return { scope: "project", root: null, artifacts: [] };
|
|
19
|
+
}
|
|
20
|
+
const claudeDir = join(root, ".claude");
|
|
21
|
+
const artifacts = [
|
|
22
|
+
...(await scanClaudeDir(claudeDir)),
|
|
23
|
+
...(await scanSettingsFile(join(claudeDir, "settings.local.json"))),
|
|
24
|
+
...(await projectMcpServers(root, home)),
|
|
25
|
+
...(await scanClaudeMd(join(root, "CLAUDE.md"))),
|
|
26
|
+
];
|
|
27
|
+
return { scope: "project", root, artifacts };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACnC,MAAM,SAAS,GAAe;QAC5B,GAAG,CAAC,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QAC9B,GAAG,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;QAC/B,GAAG,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;KACjD,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAW,EAAE,IAAY;IAC9D,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IACzD,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACxC,MAAM,SAAS,GAAe;QAC5B,GAAG,CAAC,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;QACnC,GAAG,CAAC,MAAM,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC,CAAC;QACnE,GAAG,CAAC,MAAM,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACxC,GAAG,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;KACjD,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Artifact } from "../inventory.ts";
|
|
2
|
+
/** User-scope servers: top-level mcpServers in ~/.claude.json. */
|
|
3
|
+
export declare function userMcpServers(home: string): Promise<Artifact[]>;
|
|
4
|
+
/**
|
|
5
|
+
* Project-scope servers come from two places: .mcp.json at the project root
|
|
6
|
+
* (shared, checked in) and projects.<abs root path>.mcpServers in
|
|
7
|
+
* ~/.claude.json (machine-local).
|
|
8
|
+
*/
|
|
9
|
+
export declare function projectMcpServers(root: string, home: string): Promise<Artifact[]>;
|
|
10
|
+
//# sourceMappingURL=mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/scanner/mcp.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAchD,kEAAkE;AAClE,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAGtE;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAcvF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { readJsonFile } from "../lib/fs.js";
|
|
3
|
+
function mcpServerNames(config) {
|
|
4
|
+
if (typeof config !== "object" || config === null)
|
|
5
|
+
return [];
|
|
6
|
+
const servers = config["mcpServers"];
|
|
7
|
+
if (typeof servers !== "object" || servers === null)
|
|
8
|
+
return [];
|
|
9
|
+
return Object.keys(servers);
|
|
10
|
+
}
|
|
11
|
+
function toArtifacts(names, path) {
|
|
12
|
+
return names.map((name) => ({ type: "mcp-server", name, path }));
|
|
13
|
+
}
|
|
14
|
+
/** User-scope servers: top-level mcpServers in ~/.claude.json. */
|
|
15
|
+
export async function userMcpServers(home) {
|
|
16
|
+
const claudeJsonPath = join(home, ".claude.json");
|
|
17
|
+
return toArtifacts(mcpServerNames(await readJsonFile(claudeJsonPath)), claudeJsonPath);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Project-scope servers come from two places: .mcp.json at the project root
|
|
21
|
+
* (shared, checked in) and projects.<abs root path>.mcpServers in
|
|
22
|
+
* ~/.claude.json (machine-local).
|
|
23
|
+
*/
|
|
24
|
+
export async function projectMcpServers(root, home) {
|
|
25
|
+
const mcpJsonPath = join(root, ".mcp.json");
|
|
26
|
+
const artifacts = toArtifacts(mcpServerNames(await readJsonFile(mcpJsonPath)), mcpJsonPath);
|
|
27
|
+
const claudeJsonPath = join(home, ".claude.json");
|
|
28
|
+
const claudeJson = await readJsonFile(claudeJsonPath);
|
|
29
|
+
if (typeof claudeJson === "object" && claudeJson !== null) {
|
|
30
|
+
const projects = claudeJson["projects"];
|
|
31
|
+
if (typeof projects === "object" && projects !== null) {
|
|
32
|
+
const projectEntry = projects[root];
|
|
33
|
+
artifacts.push(...toArtifacts(mcpServerNames(projectEntry), claudeJsonPath));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return artifacts;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/scanner/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,SAAS,cAAc,CAAC,MAAe;IACrC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAC7D,MAAM,OAAO,GAAI,MAAkC,CAAC,YAAY,CAAC,CAAC;IAClE,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAC/D,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,WAAW,CAAC,KAAe,EAAE,IAAY;IAChD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAClD,OAAO,WAAW,CAAC,cAAc,CAAC,MAAM,YAAY,CAAC,cAAc,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;AACzF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY,EAAE,IAAY;IAChE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,WAAW,CAAC,cAAc,CAAC,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IAE5F,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,cAAc,CAAC,CAAC;IACtD,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QAC1D,MAAM,QAAQ,GAAI,UAAsC,CAAC,UAAU,CAAC,CAAC;QACrE,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtD,MAAM,YAAY,GAAI,QAAoC,CAAC,IAAI,CAAC,CAAC;YACjE,SAAS,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walk up from cwd to the nearest directory containing .claude/ or .git/,
|
|
3
|
+
* the way git finds a repo root. Returns null if the filesystem root is
|
|
4
|
+
* reached without a hit.
|
|
5
|
+
*/
|
|
6
|
+
export declare function findProjectRoot(cwd: string): Promise<string | null>;
|
|
7
|
+
//# sourceMappingURL=project-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-root.d.ts","sourceRoot":"","sources":["../../src/scanner/project-root.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWzE"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { dirname, join, resolve } from "node:path";
|
|
2
|
+
import { isDirectory, pathExists } from "../lib/fs.js";
|
|
3
|
+
/**
|
|
4
|
+
* Walk up from cwd to the nearest directory containing .claude/ or .git/,
|
|
5
|
+
* the way git finds a repo root. Returns null if the filesystem root is
|
|
6
|
+
* reached without a hit.
|
|
7
|
+
*/
|
|
8
|
+
export async function findProjectRoot(cwd) {
|
|
9
|
+
let dir = resolve(cwd);
|
|
10
|
+
for (;;) {
|
|
11
|
+
// .git can be a file in worktrees, so existence is the right check.
|
|
12
|
+
if ((await isDirectory(join(dir, ".claude"))) || (await pathExists(join(dir, ".git")))) {
|
|
13
|
+
return dir;
|
|
14
|
+
}
|
|
15
|
+
const parent = dirname(dir);
|
|
16
|
+
if (parent === dir)
|
|
17
|
+
return null;
|
|
18
|
+
dir = parent;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=project-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-root.js","sourceRoot":"","sources":["../../src/scanner/project-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEvD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAW;IAC/C,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACvB,SAAS,CAAC;QACR,oEAAoE;QACpE,IAAI,CAAC,MAAM,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACvF,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAChC,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface SelectOption {
|
|
2
|
+
label: string;
|
|
3
|
+
hint?: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Arrow-key selector: ↑/↓ (or k/j) to move, Enter to confirm.
|
|
7
|
+
* Resolves with the selected index, or null on Ctrl+C / Ctrl+D.
|
|
8
|
+
* Caller must ensure stdin is a TTY before calling.
|
|
9
|
+
*/
|
|
10
|
+
export declare function select(question: string, options: SelectOption[]): Promise<number | null>;
|
|
11
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/ui/prompt.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAOD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA6DxF"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { emitKeypressEvents } from "node:readline";
|
|
2
|
+
/**
|
|
3
|
+
* Arrow-key selector: ↑/↓ (or k/j) to move, Enter to confirm.
|
|
4
|
+
* Resolves with the selected index, or null on Ctrl+C / Ctrl+D.
|
|
5
|
+
* Caller must ensure stdin is a TTY before calling.
|
|
6
|
+
*/
|
|
7
|
+
export function select(question, options) {
|
|
8
|
+
const stdin = process.stdin;
|
|
9
|
+
const stdout = process.stdout;
|
|
10
|
+
// question + one line per option + key-hint line
|
|
11
|
+
const lineCount = options.length + 2;
|
|
12
|
+
return new Promise((resolvePromise) => {
|
|
13
|
+
emitKeypressEvents(stdin);
|
|
14
|
+
const wasRaw = stdin.isRaw;
|
|
15
|
+
stdin.setRawMode(true);
|
|
16
|
+
stdin.resume();
|
|
17
|
+
let index = 0;
|
|
18
|
+
let drawn = false;
|
|
19
|
+
function draw() {
|
|
20
|
+
if (drawn)
|
|
21
|
+
stdout.write(`\x1b[${lineCount}A`);
|
|
22
|
+
drawn = true;
|
|
23
|
+
const lines = [
|
|
24
|
+
`? ${question}`,
|
|
25
|
+
...options.map((option, i) => {
|
|
26
|
+
const cursor = i === index ? "❯" : " ";
|
|
27
|
+
const hint = option.hint === undefined ? "" : ` (${option.hint})`;
|
|
28
|
+
return `${cursor} ${option.label}${hint}`;
|
|
29
|
+
}),
|
|
30
|
+
"(↑/↓ to move, Enter to select)",
|
|
31
|
+
];
|
|
32
|
+
for (const line of lines) {
|
|
33
|
+
stdout.write(`\x1b[2K${line}\n`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function finish(result) {
|
|
37
|
+
stdin.off("keypress", onKeypress);
|
|
38
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
39
|
+
stdin.pause();
|
|
40
|
+
// Collapse the menu to a single answer line.
|
|
41
|
+
stdout.write(`\x1b[${lineCount}A\x1b[0J`);
|
|
42
|
+
const answer = result === null ? "cancelled" : (options[result]?.label ?? "");
|
|
43
|
+
stdout.write(`? ${question} · ${answer}\n`);
|
|
44
|
+
resolvePromise(result);
|
|
45
|
+
}
|
|
46
|
+
function onKeypress(_chunk, key) {
|
|
47
|
+
if (key === undefined)
|
|
48
|
+
return;
|
|
49
|
+
if (key.ctrl === true && (key.name === "c" || key.name === "d")) {
|
|
50
|
+
finish(null);
|
|
51
|
+
}
|
|
52
|
+
else if (key.name === "up" || key.name === "k") {
|
|
53
|
+
index = (index - 1 + options.length) % options.length;
|
|
54
|
+
draw();
|
|
55
|
+
}
|
|
56
|
+
else if (key.name === "down" || key.name === "j") {
|
|
57
|
+
index = (index + 1) % options.length;
|
|
58
|
+
draw();
|
|
59
|
+
}
|
|
60
|
+
else if (key.name === "return" || key.name === "enter") {
|
|
61
|
+
finish(index);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
stdin.on("keypress", onKeypress);
|
|
65
|
+
draw();
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/ui/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/ui/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAapE,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,cAAc,GAAG,MAAM,CA8BtE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const GROUPS = [
|
|
2
|
+
{ type: "settings", label: "Settings" },
|
|
3
|
+
{ type: "agent", label: "Agents" },
|
|
4
|
+
{ type: "skill", label: "Skills" },
|
|
5
|
+
{ type: "command", label: "Commands" },
|
|
6
|
+
{ type: "mcp-server", label: "MCP servers" },
|
|
7
|
+
{ type: "claude-md", label: "CLAUDE.md" },
|
|
8
|
+
];
|
|
9
|
+
const LABEL_WIDTH = Math.max(...GROUPS.map((g) => g.label.length)) + 3;
|
|
10
|
+
export function renderScopeInventory(inventory) {
|
|
11
|
+
if (inventory.scope === "project" && inventory.root === null) {
|
|
12
|
+
return [
|
|
13
|
+
"Project scope",
|
|
14
|
+
"",
|
|
15
|
+
" No project detected from the current directory",
|
|
16
|
+
" (no .claude/ or .git/ found walking up).",
|
|
17
|
+
"",
|
|
18
|
+
].join("\n");
|
|
19
|
+
}
|
|
20
|
+
const title = inventory.scope === "user" ? "User scope" : "Project scope";
|
|
21
|
+
const lines = [`${title} ${inventory.root}`, ""];
|
|
22
|
+
for (const group of GROUPS) {
|
|
23
|
+
const items = inventory.artifacts.filter((a) => a.type === group.type);
|
|
24
|
+
const label = group.label.padEnd(LABEL_WIDTH);
|
|
25
|
+
if (items.length === 0) {
|
|
26
|
+
lines.push(` ${label}(none)`);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
items.forEach((artifact, i) => {
|
|
30
|
+
const prefix = i === 0 ? label : "".padEnd(LABEL_WIDTH);
|
|
31
|
+
lines.push(` ${prefix}${artifact.name}`);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const count = inventory.artifacts.length;
|
|
36
|
+
lines.push("", `${count} artifact${count === 1 ? "" : "s"} found`);
|
|
37
|
+
return lines.join("\n");
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/ui/render.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,GAAqD;IAC/D,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;IACvC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE;IAClC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE;IAClC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE;IACtC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE;IAC5C,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE;CAC1C,CAAC;AAEF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;AAEvE,MAAM,UAAU,oBAAoB,CAAC,SAAyB;IAC5D,IAAI,SAAS,CAAC,KAAK,KAAK,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAC7D,OAAO;YACL,eAAe;YACf,EAAE;YACF,kDAAkD;YAClD,4CAA4C;YAC5C,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC;IAC1E,MAAM,KAAK,GAAa,CAAC,GAAG,KAAK,KAAK,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAE5D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC;QACvE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE;gBAC5B,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBACxD,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5C,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC;IACzC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,KAAK,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;IACnE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "flowsync-cli",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "move your AI coding setup between machines and repos",
|
|
5
|
+
"main": "dist/cli.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"bin": {
|
|
11
|
+
"flowsync-cli": "dist/cli.js"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"dev": "node --watch src/cli.ts",
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"start": "node dist/cli.js",
|
|
17
|
+
"test": "node --test \"src/**/*.test.ts\"",
|
|
18
|
+
"clean": "rm -rf dist",
|
|
19
|
+
"prepublishOnly": "pnpm build"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [],
|
|
22
|
+
"author": "",
|
|
23
|
+
"license": "ISC",
|
|
24
|
+
"packageManager": "pnpm@10.12.4",
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^26.1.1",
|
|
27
|
+
"typescript": "^7.0.2"
|
|
28
|
+
}
|
|
29
|
+
}
|