flowsync-cli 0.0.2 → 0.0.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/dist/cli.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { styleText } from "node:util";
2
3
  import { runPull } from "./commands/pull.js";
3
4
  import { runPush } from "./commands/push.js";
4
5
  import { runScan } from "./commands/scan.js";
@@ -21,8 +22,8 @@ async function main(argv) {
21
22
  case "pull":
22
23
  return runPull();
23
24
  default:
24
- console.error(`flowsync: unknown command "${command}"`);
25
- console.error(`Run "flowsync --help" to see available commands.`);
25
+ console.error(styleText("red", `✖ flowsync: unknown command "${command}"`, { stream: process.stderr }));
26
+ console.error(` Run "flowsync-cli --help" to see available commands.`);
26
27
  return 1;
27
28
  }
28
29
  }
package/dist/cli.js.map CHANGED
@@ -1 +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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,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,CACX,SAAS,CAAC,KAAK,EAAE,gCAAgC,OAAO,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CACzF,CAAC;YACF,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;YACxE,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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAAA,wBAAgB,OAAO,IAAI,MAAM,CAGhC"}
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAIA,wBAAgB,OAAO,IAAI,MAAM,CAMhC"}
@@ -1,5 +1,10 @@
1
+ import * as p from "@clack/prompts";
2
+ import { badge, banner } from "../ui/banner.js";
1
3
  export function runPull() {
2
- console.log("flowsync pull: not implemented yet");
4
+ console.log(banner());
5
+ p.intro(badge("flowsync pull"));
6
+ p.log.warn("pull is not implemented yet");
7
+ p.outro("Nothing to do");
3
8
  return 0;
4
9
  }
5
10
  //# sourceMappingURL=pull.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,UAAU,OAAO;IACrB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACtB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC1C,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACzB,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAAA,wBAAgB,OAAO,IAAI,MAAM,CAGhC"}
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAIA,wBAAgB,OAAO,IAAI,MAAM,CAMhC"}
@@ -1,5 +1,10 @@
1
+ import * as p from "@clack/prompts";
2
+ import { badge, banner } from "../ui/banner.js";
1
3
  export function runPush() {
2
- console.log("flowsync push: not implemented yet");
4
+ console.log(banner());
5
+ p.intro(badge("flowsync push"));
6
+ p.log.warn("push is not implemented yet");
7
+ p.outro("Nothing to do");
3
8
  return 0;
4
9
  }
5
10
  //# sourceMappingURL=push.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,UAAU,OAAO;IACrB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACtB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC1C,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACzB,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -1 +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"}
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AASA,wBAAsB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CA+B/C"}
@@ -1,24 +1,34 @@
1
1
  import { homedir } from "node:os";
2
+ import { styleText } from "node:util";
3
+ import * as p from "@clack/prompts";
2
4
  import { scanProjectScope, scanUserScope } from "../scanner/index.js";
3
- import { select } from "../ui/prompt.js";
4
- import { renderScopeInventory } from "../ui/render.js";
5
+ import { badge, banner } from "../ui/banner.js";
6
+ import { artifactCountLine, renderScopeInventory } from "../ui/render.js";
5
7
  export async function runScan() {
6
8
  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
+ const cross = styleText("red", "✖", { stream: process.stderr });
10
+ console.error(`${cross} flowsync scan: an interactive terminal is required (stdin is not a TTY).`);
11
+ console.error(" Run scan from an interactive terminal.");
9
12
  return 1;
10
13
  }
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)
14
+ console.log(banner());
15
+ p.intro(badge("flowsync scan"));
16
+ const scope = await p.select({
17
+ message: "What do you want to scan?",
18
+ options: [
19
+ { value: "project", label: "Project level", hint: ".claude/ in this repo" },
20
+ { value: "user", label: "Global level", hint: "~/.claude/, all projects" },
21
+ ],
22
+ });
23
+ if (p.isCancel(scope)) {
24
+ p.cancel("Cancelled");
16
25
  return 130;
17
- const inventory = choice === 0
26
+ }
27
+ const inventory = scope === "project"
18
28
  ? await scanProjectScope(process.cwd(), homedir())
19
29
  : await scanUserScope(homedir());
20
- console.log();
21
- console.log(renderScopeInventory(inventory));
30
+ p.log.message(renderScopeInventory(inventory, true));
31
+ p.outro(artifactCountLine(inventory.artifacts.length));
22
32
  return 0;
23
33
  }
24
34
  //# sourceMappingURL=scan.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE1E,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,2EAA2E,CAAC,CAAC;QACnG,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACtB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;IAEhC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC;QAC3B,OAAO,EAAE,2BAA2B;QACpC,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,uBAAuB,EAAE;YAC3E,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,0BAA0B,EAAE;SAC3E;KACF,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACtB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,SAAS,GACb,KAAK,KAAK,SAAS;QACjB,CAAC,CAAC,MAAM,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC;QAClD,CAAC,CAAC,MAAM,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAErC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -1,3 +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";
1
+ export declare const VERSION: string;
2
+ export declare const HELP: string;
3
3
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,OAAO,QAA4B,CAAC;AAMjD,eAAO,MAAM,IAAI,QAahB,CAAC"}
package/dist/constants.js CHANGED
@@ -1,16 +1,22 @@
1
- export const VERSION = "flowsync 1.0.0";
2
- export const HELP = `flowsync-cli — move your AI coding setup between machines and repos
1
+ import { readFileSync } from "node:fs";
2
+ import { styleText } from "node:util";
3
+ const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
4
+ export const VERSION = `flowsync ${pkg.version}`;
5
+ const heading = (text) => styleText("bold", text);
6
+ const cmd = (text) => styleText("cyan", text);
7
+ const dim = (text) => styleText("dim", text);
8
+ export const HELP = `${heading("flowsync")} — move your AI coding setup between machines and repos
3
9
 
4
- Usage:
5
- flowsync-cli <command>
10
+ ${heading("Usage")}
11
+ flowsync-cli ${cmd("<command>")}
6
12
 
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
13
+ ${heading("Commands")}
14
+ ${cmd("scan")} ${dim("Inventory Claude Code config at user and project scope")}
15
+ ${cmd("push")} ${dim("Send the scanned inventory to a remote")}
16
+ ${cmd("pull")} ${dim("Restore an inventory from a remote")}
11
17
 
12
- Options:
13
- -h, --help Show this help
14
- -v, --version Show version
18
+ ${heading("Options")}
19
+ ${cmd("-h, --help")} ${dim("Show this help")}
20
+ ${cmd("-v, --version")} ${dim("Show version")}
15
21
  `;
16
22
  //# sourceMappingURL=constants.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAC3C,CAAC;AAEzB,MAAM,CAAC,MAAM,OAAO,GAAG,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC;AAEjD,MAAM,OAAO,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAClE,MAAM,GAAG,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAC9D,MAAM,GAAG,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAE7D,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC;;EAExC,OAAO,CAAC,OAAO,CAAC;iBACD,GAAG,CAAC,WAAW,CAAC;;EAE/B,OAAO,CAAC,UAAU,CAAC;IACjB,GAAG,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,wDAAwD,CAAC;IAC/E,GAAG,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,wCAAwC,CAAC;IAC/D,GAAG,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,oCAAoC,CAAC;;EAE7D,OAAO,CAAC,SAAS,CAAC;IAChB,GAAG,CAAC,YAAY,CAAC,UAAU,GAAG,CAAC,gBAAgB,CAAC;IAChD,GAAG,CAAC,eAAe,CAAC,OAAO,GAAG,CAAC,cAAc,CAAC;CACjD,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Block-letter FLOWSYNC banner with a top-to-bottom fade; falls back to a
3
+ * plain wordmark when the terminal is narrower than the banner.
4
+ */
5
+ export declare function banner(): string;
6
+ /** Badge-style intro label, e.g. " flowsync scan " on a cyan background. */
7
+ export declare function badge(text: string): string;
8
+ //# sourceMappingURL=banner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../src/ui/banner.ts"],"names":[],"mappings":"AAcA;;;GAGG;AACH,wBAAgB,MAAM,IAAI,MAAM,CAS/B;AAED,4EAA4E;AAC5E,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1C"}
@@ -0,0 +1,28 @@
1
+ import { styleText } from "node:util";
2
+ // "FLOWSYNC" in figlet ANSI-Shadow, precomputed — no font engine needed.
3
+ const BANNER_LINES = [
4
+ "███████╗██╗ ██████╗ ██╗ ██╗███████╗██╗ ██╗███╗ ██╗ ██████╗",
5
+ "██╔════╝██║ ██╔═══██╗██║ ██║██╔════╝╚██╗ ██╔╝████╗ ██║██╔════╝",
6
+ "█████╗ ██║ ██║ ██║██║ █╗ ██║███████╗ ╚████╔╝ ██╔██╗ ██║██║ ",
7
+ "██╔══╝ ██║ ██║ ██║██║███╗██║╚════██║ ╚██╔╝ ██║╚██╗██║██║ ",
8
+ "██║ ███████╗╚██████╔╝╚███╔███╔╝███████║ ██║ ██║ ╚████║╚██████╗",
9
+ "╚═╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝ ╚═╝ ╚═╝ ╚═══╝ ╚═════╝",
10
+ ];
11
+ const BANNER_WIDTH = 70;
12
+ /**
13
+ * Block-letter FLOWSYNC banner with a top-to-bottom fade; falls back to a
14
+ * plain wordmark when the terminal is narrower than the banner.
15
+ */
16
+ export function banner() {
17
+ const columns = process.stdout.columns;
18
+ if (columns !== undefined && columns < BANNER_WIDTH) {
19
+ return `\n${styleText(["bold", "white"], "FLOWSYNC")}\n`;
20
+ }
21
+ const faded = BANNER_LINES.map((line, i) => styleText(i < 3 ? ["white"] : ["dim", "white"], line));
22
+ return `\n${faded.join("\n")}\n`;
23
+ }
24
+ /** Badge-style intro label, e.g. " flowsync scan " on a cyan background. */
25
+ export function badge(text) {
26
+ return styleText(["bgCyan", "black"], ` ${text} `);
27
+ }
28
+ //# sourceMappingURL=banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/ui/banner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,yEAAyE;AACzE,MAAM,YAAY,GAAG;IACnB,wEAAwE;IACxE,wEAAwE;IACxE,wEAAwE;IACxE,wEAAwE;IACxE,wEAAwE;IACxE,wEAAwE;CACzE,CAAC;AAEF,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,MAAM;IACpB,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;IACvC,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,GAAG,YAAY,EAAE,CAAC;QACpD,OAAO,KAAK,SAAS,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC;IAC3D,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CACzC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CACtD,CAAC;IACF,OAAO,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACnC,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,OAAO,SAAS,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC;AACrD,CAAC"}
@@ -1,3 +1,10 @@
1
1
  import type { ScopeInventory } from "../inventory.ts";
2
- export declare function renderScopeInventory(inventory: ScopeInventory): string;
2
+ /**
3
+ * Renders the inventory body (title + grouped artifacts) without the trailing
4
+ * count line — the caller closes the clack rail with artifactCountLine().
5
+ * `colors` defaults to off so output is deterministic under test; when on,
6
+ * styleText still honors NO_COLOR and the actual stream capabilities.
7
+ */
8
+ export declare function renderScopeInventory(inventory: ScopeInventory, colors?: boolean): string;
9
+ export declare function artifactCountLine(count: number): string;
3
10
  //# sourceMappingURL=render.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/ui/render.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAapE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,cAAc,EAAE,MAAM,UAAQ,GAAG,MAAM,CA2BtF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD"}
package/dist/ui/render.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { styleText } from "node:util";
1
2
  const GROUPS = [
2
3
  { type: "settings", label: "Settings" },
3
4
  { type: "agent", label: "Agents" },
@@ -7,33 +8,38 @@ const GROUPS = [
7
8
  { type: "claude-md", label: "CLAUDE.md" },
8
9
  ];
9
10
  const LABEL_WIDTH = Math.max(...GROUPS.map((g) => g.label.length)) + 3;
10
- export function renderScopeInventory(inventory) {
11
+ /**
12
+ * Renders the inventory body (title + grouped artifacts) without the trailing
13
+ * count line — the caller closes the clack rail with artifactCountLine().
14
+ * `colors` defaults to off so output is deterministic under test; when on,
15
+ * styleText still honors NO_COLOR and the actual stream capabilities.
16
+ */
17
+ export function renderScopeInventory(inventory, colors = false) {
18
+ const paint = colors ? styleText : (_format, text) => text;
11
19
  if (inventory.scope === "project" && inventory.root === null) {
12
20
  return [
13
- "Project scope",
14
- "",
15
- " No project detected from the current directory",
16
- " (no .claude/ or .git/ found walking up).",
17
- "",
21
+ "No project detected from the current directory",
22
+ "(no .claude/ or .git/ found walking up).",
18
23
  ].join("\n");
19
24
  }
20
25
  const title = inventory.scope === "user" ? "User scope" : "Project scope";
21
- const lines = [`${title} ${inventory.root}`, ""];
26
+ const lines = [`${paint("bold", title)} ${paint("cyan", inventory.root ?? "")}`, ""];
22
27
  for (const group of GROUPS) {
23
28
  const items = inventory.artifacts.filter((a) => a.type === group.type);
24
29
  const label = group.label.padEnd(LABEL_WIDTH);
25
30
  if (items.length === 0) {
26
- lines.push(` ${label}(none)`);
31
+ lines.push(paint("dim", `${label}(none)`));
27
32
  }
28
33
  else {
29
34
  items.forEach((artifact, i) => {
30
- const prefix = i === 0 ? label : "".padEnd(LABEL_WIDTH);
31
- lines.push(` ${prefix}${artifact.name}`);
35
+ const prefix = i === 0 ? paint("dim", label) : "".padEnd(LABEL_WIDTH);
36
+ lines.push(`${prefix}${artifact.name}`);
32
37
  });
33
38
  }
34
39
  }
35
- const count = inventory.artifacts.length;
36
- lines.push("", `${count} artifact${count === 1 ? "" : "s"} found`);
37
40
  return lines.join("\n");
38
41
  }
42
+ export function artifactCountLine(count) {
43
+ return `${count} artifact${count === 1 ? "" : "s"} found`;
44
+ }
39
45
  //# sourceMappingURL=render.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/ui/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC,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;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAyB,EAAE,MAAM,GAAG,KAAK;IAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAA0B,EAAE,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC;IAE9F,IAAI,SAAS,CAAC,KAAK,KAAK,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAC7D,OAAO;YACL,gDAAgD;YAChD,0CAA0C;SAC3C,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,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAEhG,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,CAAC,KAAK,EAAE,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC;QAC7C,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,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBACtE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAO,GAAG,KAAK,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;AAC5D,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowsync-cli",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "move your AI coding setup between machines and repos",
5
5
  "main": "dist/cli.js",
6
6
  "type": "module",
@@ -14,9 +14,8 @@
14
14
  "dev": "node --watch src/cli.ts",
15
15
  "build": "tsc",
16
16
  "start": "node dist/cli.js",
17
- "test": "node --test \"src/**/*.test.ts\"",
18
17
  "clean": "rm -rf dist",
19
- "prepublishOnly": "pnpm build"
18
+ "prepublishOnly": "npm run build"
20
19
  },
21
20
  "keywords": [],
22
21
  "author": "",
@@ -25,5 +24,8 @@
25
24
  "devDependencies": {
26
25
  "@types/node": "^26.1.1",
27
26
  "typescript": "^7.0.2"
27
+ },
28
+ "dependencies": {
29
+ "@clack/prompts": "^1.7.0"
28
30
  }
29
31
  }
@@ -1,11 +0,0 @@
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
@@ -1 +0,0 @@
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"}
package/dist/ui/prompt.js DELETED
@@ -1,68 +0,0 @@
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
@@ -1 +0,0 @@
1
- {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/ui/prompt.ts"],"names":[],"mappings":"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"}