unfairly 0.5.1 → 0.6.0

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +16 -7
  3. package/dist/cmd/init.d.ts +2 -3
  4. package/dist/cmd/init.d.ts.map +1 -1
  5. package/dist/cmd/init.js +60 -44
  6. package/dist/cmd/init.js.map +1 -1
  7. package/dist/cmd/pull.d.ts.map +1 -1
  8. package/dist/cmd/pull.js +16 -2
  9. package/dist/cmd/pull.js.map +1 -1
  10. package/dist/cmd/setup.d.ts +19 -19
  11. package/dist/cmd/setup.d.ts.map +1 -1
  12. package/dist/cmd/setup.js +143 -84
  13. package/dist/cmd/setup.js.map +1 -1
  14. package/dist/cmd/status-card.d.ts +2 -0
  15. package/dist/cmd/status-card.d.ts.map +1 -0
  16. package/dist/cmd/status-card.js +156 -0
  17. package/dist/cmd/status-card.js.map +1 -0
  18. package/dist/cmd/status.d.ts.map +1 -1
  19. package/dist/cmd/status.js +3 -0
  20. package/dist/cmd/status.js.map +1 -1
  21. package/dist/hosts/claude-desktop.d.ts +47 -0
  22. package/dist/hosts/claude-desktop.d.ts.map +1 -0
  23. package/dist/hosts/claude-desktop.js +83 -0
  24. package/dist/hosts/claude-desktop.js.map +1 -0
  25. package/dist/index.js +58 -27
  26. package/dist/index.js.map +1 -1
  27. package/dist/sync/repo-root.d.ts +7 -0
  28. package/dist/sync/repo-root.d.ts.map +1 -0
  29. package/dist/sync/repo-root.js +24 -0
  30. package/dist/sync/repo-root.js.map +1 -0
  31. package/dist/sync/stitch-claude-md.d.ts +9 -0
  32. package/dist/sync/stitch-claude-md.d.ts.map +1 -0
  33. package/dist/sync/stitch-claude-md.js +48 -0
  34. package/dist/sync/stitch-claude-md.js.map +1 -0
  35. package/dist/ui/colors.d.ts +17 -0
  36. package/dist/ui/colors.d.ts.map +1 -0
  37. package/dist/ui/colors.js +28 -0
  38. package/dist/ui/colors.js.map +1 -0
  39. package/dist/ui/screens.d.ts +44 -0
  40. package/dist/ui/screens.d.ts.map +1 -0
  41. package/dist/ui/screens.js +135 -0
  42. package/dist/ui/screens.js.map +1 -0
  43. package/package.json +32 -7
@@ -0,0 +1,83 @@
1
+ import fs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ /**
5
+ * Path to Claude Desktop's config file by platform. Returns null on Linux
6
+ * (Claude Desktop is Mac/Windows only per official docs).
7
+ */
8
+ export function configPath() {
9
+ const home = os.homedir();
10
+ if (process.platform === "darwin") {
11
+ return path.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
12
+ }
13
+ if (process.platform === "win32") {
14
+ const appdata = process.env.APPDATA ?? path.join(home, "AppData", "Roaming");
15
+ return path.join(appdata, "Claude", "claude_desktop_config.json");
16
+ }
17
+ return null;
18
+ }
19
+ export function buildEntry(apiUrl) {
20
+ const url = `${apiUrl.replace(/\/$/, "")}/api/mcp`;
21
+ return {
22
+ type: "http",
23
+ url,
24
+ headers: { Authorization: "Bearer ${UNFAIRLY_MCP_TOKEN}" },
25
+ };
26
+ }
27
+ /**
28
+ * Merge our canonical unfairly entry into an existing config object.
29
+ * - Preserves other mcpServers
30
+ * - Replaces any existing unfairly entry
31
+ * - Preserves all unrelated top-level keys
32
+ */
33
+ export function mergeIntoConfig(existing, apiUrl) {
34
+ const next = { ...existing };
35
+ const servers = { ...(existing.mcpServers ?? {}) };
36
+ servers.unfairly = buildEntry(apiUrl);
37
+ next.mcpServers = servers;
38
+ return next;
39
+ }
40
+ /**
41
+ * Patch Claude Desktop's config to wire the Unfairly MCP server.
42
+ * - If config file does not exist → not-installed (do NOT create).
43
+ * - If file exists but is malformed JSON → error (don't overwrite precious config).
44
+ * - Otherwise → merge canonical block, write back.
45
+ */
46
+ export async function configureClaudeDesktop(apiUrl) {
47
+ const cfgPath = configPath();
48
+ if (!cfgPath) {
49
+ return { status: "not-installed", path: "(Claude Desktop not available on this platform)" };
50
+ }
51
+ let existing;
52
+ try {
53
+ existing = await fs.readFile(cfgPath, "utf8");
54
+ }
55
+ catch (err) {
56
+ const e = err;
57
+ if (e.code === "ENOENT")
58
+ return { status: "not-installed", path: cfgPath };
59
+ return { status: "error", path: cfgPath, message: `Could not read ${cfgPath}: ${e.message}` };
60
+ }
61
+ let parsed;
62
+ try {
63
+ parsed = existing.trim() === "" ? {} : JSON.parse(existing);
64
+ }
65
+ catch (err) {
66
+ return {
67
+ status: "error",
68
+ path: cfgPath,
69
+ message: `Refusing to overwrite — config is not valid JSON: ${err.message}`,
70
+ };
71
+ }
72
+ const had = parsed.mcpServers && parsed.mcpServers.unfairly !== undefined;
73
+ const merged = mergeIntoConfig(parsed, apiUrl);
74
+ const serialized = JSON.stringify(merged, null, 2) + "\n";
75
+ try {
76
+ await fs.writeFile(cfgPath, serialized, "utf8");
77
+ }
78
+ catch (err) {
79
+ return { status: "error", path: cfgPath, message: err.message };
80
+ }
81
+ return { status: "configured", path: cfgPath, action: had ? "updated" : "created" };
82
+ }
83
+ //# sourceMappingURL=claude-desktop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-desktop.js","sourceRoot":"","sources":["../../src/hosts/claude-desktop.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { readFileSync } from "node:fs";
3
+ import { promises as fs } from "node:fs";
3
4
  import { fileURLToPath } from "node:url";
4
5
  import { dirname, join } from "node:path";
5
6
  import yargs from "yargs";
@@ -7,37 +8,28 @@ import { hideBin } from "yargs/helpers";
7
8
  const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf8"));
8
9
  await yargs(hideBin(process.argv))
9
10
  .scriptName("unfairly")
10
- .usage("$0 <cmd> [args]")
11
+ .usage("$0 [cmd] [args]")
11
12
  .version(pkg.version)
12
- .command("setup", "One-shot: authorize, write shell env, configure Codex + Claude Code", () => { }, async () => {
13
- const { runSetup } = await import("./cmd/setup.js");
14
- await runSetup();
15
- })
16
- .command("login", "Authorize via browser; print export lines for ~/.zshenv (Codex / scripts)", (y) => y.option("quiet", {
13
+ .command("$0", "First-run: wire MCP across hosts, bind workspace if in a repo, show status otherwise", (y) => y.option("yes", {
17
14
  type: "boolean",
18
- alias: "q",
15
+ alias: "y",
19
16
  default: false,
20
- describe: "Print only the export lines (for piping)",
17
+ describe: "Skip confirmation prompts",
21
18
  }), async (argv) => {
22
- const { runLogin } = await import("./cmd/login.js");
23
- await runLogin({ quiet: argv.quiet });
19
+ await runBare({ yes: argv.yes });
24
20
  })
25
- .command("init", "Initialize .unfairly/ in cwd and pull all accessible vaults", (y) => y
26
- .option("token", {
27
- type: "string",
28
- describe: "mcp_* token for non-interactive runs. Or set UNFAIRLY_TOKEN env. Default: browser OAuth.",
21
+ .command("setup", "Wire MCP for Claude Desktop / Claude Code / Codex on this machine", (y) => y.option("yes", { type: "boolean", alias: "y", default: false }), async (argv) => {
22
+ const { runSetup } = await import("./cmd/setup.js");
23
+ await runSetup({ chainInit: false, yes: argv.yes });
29
24
  })
30
- .option("yes", {
31
- type: "boolean",
32
- alias: "y",
33
- default: false,
34
- describe: "Skip the .unfairly/ overwrite confirmation",
25
+ .command("login", "Authorize via browser; print export lines for ~/.zshenv", (y) => y.option("quiet", { type: "boolean", alias: "q", default: false }), async (argv) => {
26
+ const { runLogin } = await import("./cmd/login.js");
27
+ await runLogin({ quiet: argv.quiet });
35
28
  })
36
- .option("no-browser", {
37
- type: "boolean",
38
- default: false,
39
- describe: "Skip browser-based OAuth; prompt for a manual token paste instead.",
40
- }), async (argv) => {
29
+ .command("init", "Bind .unfairly/ to cwd and pull all accessible vaults", (y) => y
30
+ .option("token", { type: "string" })
31
+ .option("yes", { type: "boolean", alias: "y", default: false })
32
+ .option("no-browser", { type: "boolean", default: false }), async (argv) => {
41
33
  const { runInit } = await import("./cmd/init.js");
42
34
  await runInit({
43
35
  token: argv.token,
@@ -61,16 +53,55 @@ await yargs(hideBin(process.argv))
61
53
  const { runResolve } = await import("./cmd/resolve.js");
62
54
  await runResolve(argv.path);
63
55
  })
64
- .command("watch", "Watch .unfairly/ for changes and auto-push", () => { }, async () => {
56
+ .command("watch", "Watch .unfairly/ for changes; debounced auto-push", () => { }, async () => {
65
57
  const { runWatch } = await import("./cmd/watch.js");
66
58
  await runWatch();
67
59
  })
68
- .command("mcp", "Run as a stdio MCP server (for agent host integration)", () => { }, async () => {
60
+ .command("mcp", "Run as stdio MCP server (sync tools)", () => { }, async () => {
69
61
  const { runMcp } = await import("./cmd/mcp.js");
70
62
  await runMcp();
71
63
  })
72
- .demandCommand(1)
73
64
  .strict()
74
65
  .help()
75
66
  .parse();
67
+ async function runBare(opts) {
68
+ const startCwd = process.cwd();
69
+ const { getToken } = await import("./sync/credentials.js");
70
+ const { findRepoRoot } = await import("./sync/repo-root.js");
71
+ const repoRoot = await findRepoRoot(startCwd);
72
+ // If we found a repo root and we're in a subdir, chdir up so init/pull/
73
+ // stitch all see the same .unfairly/ at the repo root. Explicit subcommands
74
+ // (`unfairly init`) keep their existing cwd-relative behavior — only the
75
+ // bare entrypoint promotes to repoRoot.
76
+ if (repoRoot && repoRoot !== startCwd) {
77
+ process.chdir(repoRoot);
78
+ }
79
+ const effectiveCwd = process.cwd();
80
+ const token = await getToken();
81
+ const manifestExists = await pathExists(join(effectiveCwd, ".unfairly", "manifest.json"));
82
+ if (!token) {
83
+ // Cold install — full setup, chain init when in repo
84
+ const { runSetup } = await import("./cmd/setup.js");
85
+ await runSetup({ chainInit: Boolean(repoRoot), yes: opts.yes });
86
+ return;
87
+ }
88
+ if (!manifestExists && repoRoot) {
89
+ // Token exists, no workspace bound, in a repo — offer init only
90
+ const { runInit } = await import("./cmd/init.js");
91
+ await runInit({ yes: opts.yes });
92
+ return;
93
+ }
94
+ // Daily check-in
95
+ const { runStatusCard } = await import("./cmd/status-card.js");
96
+ await runStatusCard();
97
+ }
98
+ async function pathExists(p) {
99
+ try {
100
+ await fs.access(p);
101
+ return true;
102
+ }
103
+ catch {
104
+ return false;
105
+ }
106
+ }
76
107
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Walk up from start until we find a directory containing `.git`. Returns
3
+ * the directory, or null if we reach the filesystem root with no hit.
4
+ * Accepts `.git` as either dir or file (worktrees use a `.git` file).
5
+ */
6
+ export declare function findRepoRoot(start: string): Promise<string | null>;
7
+ //# sourceMappingURL=repo-root.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-root.d.ts","sourceRoot":"","sources":["../../src/sync/repo-root.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAaxE"}
@@ -0,0 +1,24 @@
1
+ import { promises as fs } from "node:fs";
2
+ import path from "node:path";
3
+ /**
4
+ * Walk up from start until we find a directory containing `.git`. Returns
5
+ * the directory, or null if we reach the filesystem root with no hit.
6
+ * Accepts `.git` as either dir or file (worktrees use a `.git` file).
7
+ */
8
+ export async function findRepoRoot(start) {
9
+ let dir = path.resolve(start);
10
+ while (true) {
11
+ try {
12
+ await fs.stat(path.join(dir, ".git"));
13
+ return dir;
14
+ }
15
+ catch {
16
+ // not here, keep walking
17
+ }
18
+ const parent = path.dirname(dir);
19
+ if (parent === dir)
20
+ return null;
21
+ dir = parent;
22
+ }
23
+ }
24
+ //# sourceMappingURL=repo-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-root.js","sourceRoot":"","sources":["../../src/sync/repo-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAa;IAC9C,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9B,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;YACtC,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAChC,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const AUTOLOADER_LINE = "@.unfairly/CLAUDE.md";
2
+ export declare const SENTINEL = "<!-- unfairly: autoloader -->";
3
+ export type StitchResult = {
4
+ action: "created" | "appended" | "noop" | "not-a-repo" | "error";
5
+ path: string;
6
+ message?: string;
7
+ };
8
+ export declare function stitchClaudeMd(repoRoot: string): Promise<StitchResult>;
9
+ //# sourceMappingURL=stitch-claude-md.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stitch-claude-md.d.ts","sourceRoot":"","sources":["../../src/sync/stitch-claude-md.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,yBAAyB,CAAC;AACtD,eAAO,MAAM,QAAQ,kCAAkC,CAAC;AAExD,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,YAAY,GAAG,OAAO,CAAC;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAIF,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAwC5E"}
@@ -0,0 +1,48 @@
1
+ import { promises as fs } from "node:fs";
2
+ import path from "node:path";
3
+ export const AUTOLOADER_LINE = "@.unfairly/CLAUDE.md";
4
+ export const SENTINEL = "<!-- unfairly: autoloader -->";
5
+ const LINE_RE = /^@\.unfairly\/CLAUDE\.md\s*$/m;
6
+ export async function stitchClaudeMd(repoRoot) {
7
+ const gitDir = path.join(repoRoot, ".git");
8
+ try {
9
+ await fs.stat(gitDir);
10
+ }
11
+ catch {
12
+ return { action: "not-a-repo", path: path.join(repoRoot, "CLAUDE.md") };
13
+ }
14
+ const claudeMdPath = path.join(repoRoot, "CLAUDE.md");
15
+ let existing;
16
+ try {
17
+ existing = await fs.readFile(claudeMdPath, "utf8");
18
+ }
19
+ catch (err) {
20
+ const e = err;
21
+ if (e.code !== "ENOENT")
22
+ return { action: "error", path: claudeMdPath, message: e.message };
23
+ existing = null;
24
+ }
25
+ if (existing === null) {
26
+ const content = `${SENTINEL}\n${AUTOLOADER_LINE}\n`;
27
+ try {
28
+ await fs.writeFile(claudeMdPath, content, "utf8");
29
+ }
30
+ catch (err) {
31
+ return { action: "error", path: claudeMdPath, message: err.message };
32
+ }
33
+ return { action: "created", path: claudeMdPath };
34
+ }
35
+ if (LINE_RE.test(existing)) {
36
+ return { action: "noop", path: claudeMdPath };
37
+ }
38
+ const sep = existing.endsWith("\n") ? "" : "\n";
39
+ const next = `${existing}${sep}\n${SENTINEL}\n${AUTOLOADER_LINE}\n`;
40
+ try {
41
+ await fs.writeFile(claudeMdPath, next, "utf8");
42
+ }
43
+ catch (err) {
44
+ return { action: "error", path: claudeMdPath, message: err.message };
45
+ }
46
+ return { action: "appended", path: claudeMdPath };
47
+ }
48
+ //# sourceMappingURL=stitch-claude-md.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stitch-claude-md.js","sourceRoot":"","sources":["../../src/sync/stitch-claude-md.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,eAAe,GAAG,sBAAsB,CAAC;AACtD,MAAM,CAAC,MAAM,QAAQ,GAAG,+BAA+B,CAAC;AAQxD,MAAM,OAAO,GAAG,+BAA+B,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC;IAC1E,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACtD,IAAI,QAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,GAA4B,CAAC;QACvC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QAC5F,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,QAAQ,KAAK,eAAe,IAAI,CAAC;QACpD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC;QAClF,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IACnD,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAChD,MAAM,IAAI,GAAG,GAAG,QAAQ,GAAG,GAAG,KAAK,QAAQ,KAAK,eAAe,IAAI,CAAC;IACpE,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC;IAClF,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;AACpD,CAAC"}
@@ -0,0 +1,17 @@
1
+ export type ColorEnv = {
2
+ enabled: boolean;
3
+ };
4
+ export declare function isColorEnabled(isTTY: boolean): boolean;
5
+ export type Brand = {
6
+ coral: (s: string) => string;
7
+ gold: (s: string) => string;
8
+ silver: (s: string) => string;
9
+ bronze: (s: string) => string;
10
+ dim: (s: string) => string;
11
+ ok: (s: string) => string;
12
+ warn: (s: string) => string;
13
+ err: (s: string) => string;
14
+ bold: (s: string) => string;
15
+ };
16
+ export declare function brand(env?: ColorEnv): Brand;
17
+ //# sourceMappingURL=colors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/ui/colors.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGtD;AAED,MAAM,MAAM,KAAK,GAAG;IAClB,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7B,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9B,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3B,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5B,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CAC7B,CAAC;AAEF,wBAAgB,KAAK,CACnB,GAAG,GAAE,QAAqE,GACzE,KAAK,CAoBP"}
@@ -0,0 +1,28 @@
1
+ import { createColors } from "picocolors";
2
+ export function isColorEnabled(isTTY) {
3
+ if (process.env.NO_COLOR && process.env.NO_COLOR !== "")
4
+ return false;
5
+ return isTTY;
6
+ }
7
+ export function brand(env = { enabled: isColorEnabled(Boolean(process.stdout.isTTY)) }) {
8
+ if (!env.enabled) {
9
+ const identity = (s) => s;
10
+ return {
11
+ coral: identity, gold: identity, silver: identity, bronze: identity,
12
+ dim: identity, ok: identity, warn: identity, err: identity, bold: identity,
13
+ };
14
+ }
15
+ const pc = createColors(true);
16
+ return {
17
+ coral: (s) => pc.red(s),
18
+ gold: (s) => pc.yellow(s),
19
+ silver: (s) => pc.white(s),
20
+ bronze: (s) => pc.yellow(pc.dim(s)),
21
+ dim: (s) => pc.dim(s),
22
+ ok: (s) => pc.green(s),
23
+ warn: (s) => pc.yellow(s),
24
+ err: (s) => pc.red(s),
25
+ bold: (s) => pc.bold(s),
26
+ };
27
+ }
28
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/ui/colors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM1C,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IACtE,OAAO,KAAK,CAAC;AACf,CAAC;AAcD,MAAM,UAAU,KAAK,CACnB,MAAgB,EAAE,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;IAE1E,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC;QAClC,OAAO;YACL,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ;YACnE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ;SAC3E,CAAC;IACJ,CAAC;IACD,MAAM,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO;QACL,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACzB,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1B,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACnC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACrB,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QACtB,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACzB,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACrB,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;KACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,44 @@
1
+ export type ScreenOpts = {
2
+ color: boolean;
3
+ width: number;
4
+ };
5
+ export declare function defaultOpts(): ScreenOpts;
6
+ export declare function banner(opts: ScreenOpts): string;
7
+ export declare function stepHeader(n: number, total: number, label: string, opts: ScreenOpts): string;
8
+ export type ResultKind = "ok" | "err" | "warn" | "skip" | "progress";
9
+ export declare function result(kind: ResultKind, text: string, opts: ScreenOpts): string;
10
+ export declare function divider(opts: ScreenOpts): string;
11
+ export type HandoffState = {
12
+ vaultCount: number;
13
+ docCount: number;
14
+ recentMove: {
15
+ who: string;
16
+ room: string;
17
+ title: string;
18
+ ago: string;
19
+ } | null;
20
+ hint: string;
21
+ };
22
+ export declare function handoffCard(state: HandoffState, opts: ScreenOpts): string;
23
+ export type StatusState = {
24
+ hosts: {
25
+ claudeDesktop: "wired" | "missing" | "rotted";
26
+ claudeCode: "wired" | "missing" | "rotted";
27
+ codex: "wired" | "missing" | "rotted";
28
+ };
29
+ workspace: {
30
+ cwd: string;
31
+ vaultCount: number;
32
+ docCount: number;
33
+ lastPulledAt: string | null;
34
+ } | null;
35
+ recent: Array<{
36
+ who: string;
37
+ room: string;
38
+ ago: string;
39
+ title: string;
40
+ }>;
41
+ };
42
+ export declare function statusCard(state: StatusState, opts: ScreenOpts): string;
43
+ export declare function renderTo(write: (s: string) => unknown, lines: string[]): void;
44
+ //# sourceMappingURL=screens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screens.d.ts","sourceRoot":"","sources":["../../src/ui/screens.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,WAAW,IAAI,UAAU,CAMxC;AAMD,wBAAgB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAK/C;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAG5F;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAErE,wBAAgB,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAS/E;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAMhD;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAoCzE;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE;QAAE,aAAa,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;QAAC,UAAU,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;QAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAA;KAAE,CAAC;IAC5I,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACrG,MAAM,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1E,CAAC;AAEF,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CA0BvE;AAQD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAE7E"}
@@ -0,0 +1,135 @@
1
+ import { brand } from "./colors.js";
2
+ export function defaultOpts() {
3
+ const cols = Number(process.stdout.columns ?? 80);
4
+ return {
5
+ color: Boolean(process.stdout.isTTY) && !process.env.NO_COLOR,
6
+ width: cols > 0 ? cols : 80,
7
+ };
8
+ }
9
+ function colorsFor(opts) {
10
+ return brand({ enabled: opts.color });
11
+ }
12
+ export function banner(opts) {
13
+ const c = colorsFor(opts);
14
+ const line1 = " ✦ U N F A I R L Y ✦";
15
+ const line2 = " the multiplayer brain for ai";
16
+ return `${c.coral(line1)}\n${c.dim(line2)}`;
17
+ }
18
+ export function stepHeader(n, total, label, opts) {
19
+ const c = colorsFor(opts);
20
+ return `${c.dim(`[${n}/${total}]`)} ${c.dim(label)}`;
21
+ }
22
+ export function result(kind, text, opts) {
23
+ const c = colorsFor(opts);
24
+ const glyph = kind === "ok" ? c.ok("✓") :
25
+ kind === "err" ? c.err("✗") :
26
+ kind === "warn" ? c.warn("⚠") :
27
+ kind === "skip" ? c.dim("·") :
28
+ c.dim("◆");
29
+ return ` ${glyph} ${text}`;
30
+ }
31
+ export function divider(opts) {
32
+ const c = colorsFor(opts);
33
+ const len = Math.max(20, Math.min(45, opts.width - 4));
34
+ // Box-drawing dash for TTY; plain ASCII for piped/CI consumers.
35
+ const ch = opts.color ? "─" : "-";
36
+ return c.dim(ch.repeat(len));
37
+ }
38
+ export function handoffCard(state, opts) {
39
+ const c = colorsFor(opts);
40
+ // Inner width 50 fits the longest dynamic line ("You joined Unfairly · N vaults · M docs"
41
+ // for realistic N, M) plus 3-space inner padding on each side, with a couple cols slack.
42
+ const inner = 50;
43
+ const pad = (s) => s + " ".repeat(Math.max(0, inner - visibleLen(s)));
44
+ const lines = [];
45
+ // Box-drawing chars in TTY mode; ASCII in plain mode so piped/CI consumers
46
+ // don't end up with mangled unicode.
47
+ const tl = opts.color ? "╔" : "+";
48
+ const tr = opts.color ? "╗" : "+";
49
+ const bl = opts.color ? "╚" : "+";
50
+ const br = opts.color ? "╝" : "+";
51
+ const h = opts.color ? "═" : "-";
52
+ const v = opts.color ? "║" : "|";
53
+ const border = h.repeat(inner);
54
+ lines.push(` ${c.coral(`${tl}${border}${tr}`)}`);
55
+ lines.push(` ${c.coral(v)}${pad("")}${c.coral(v)}`);
56
+ lines.push(` ${c.coral(v)}${pad(centered(opts.color ? "✦ PLAYER 2 READY ✦" : "* PLAYER 2 READY *", inner, c.bold))}${c.coral(v)}`);
57
+ lines.push(` ${c.coral(v)}${pad("")}${c.coral(v)}`);
58
+ lines.push(` ${c.coral(v)}${pad(` You joined ${c.bold("Unfairly")} · ${c.dim(`${state.vaultCount} vaults · ${state.docCount} docs`)} `)}${c.coral(v)}`);
59
+ if (state.recentMove) {
60
+ const m = state.recentMove;
61
+ lines.push(` ${c.coral(v)}${pad(` ${c.silver(`${m.who} shipped "${truncate(m.title, 22)}" ${m.ago}`)} `)}${c.coral(v)}`);
62
+ }
63
+ lines.push(` ${c.coral(v)}${pad("")}${c.coral(v)}`);
64
+ const arrow = opts.color ? "▶" : ">";
65
+ lines.push(` ${c.coral(v)}${pad(` ${c.coral(arrow)} ${state.hint} `)}${c.coral(v)}`);
66
+ lines.push(` ${c.coral(v)}${pad(` ${c.dim("or run ")}${c.bold("claude")}${c.dim(" / ")}${c.bold("codex")}${c.dim(" here in this repo")} `)}${c.coral(v)}`);
67
+ lines.push(` ${c.coral(v)}${pad("")}${c.coral(v)}`);
68
+ lines.push(` ${c.coral(v)}${pad(` ${c.dim("the brain follows you across surfaces.")} `)}${c.coral(v)}`);
69
+ lines.push(` ${c.coral(v)}${pad("")}${c.coral(v)}`);
70
+ lines.push(` ${c.coral(`${bl}${border}${br}`)}`);
71
+ return lines.join("\n");
72
+ }
73
+ export function statusCard(state, opts) {
74
+ const c = colorsFor(opts);
75
+ const lines = [];
76
+ lines.push(` ${c.coral("✦ UNFAIRLY ✦")} ${c.dim("player 2 — daily check-in")}`);
77
+ lines.push("");
78
+ lines.push(` ${c.dim("HOSTS WIRED")}`);
79
+ lines.push(` ${hostGlyph(state.hosts.claudeDesktop, c)} Claude Desktop ${hostGlyph(state.hosts.claudeCode, c)} Claude Code ${hostGlyph(state.hosts.codex, c)} Codex`);
80
+ lines.push("");
81
+ if (state.workspace) {
82
+ lines.push(` ${c.dim("WORKSPACE")}`);
83
+ const ws = state.workspace;
84
+ const pulled = ws.lastPulledAt ? `last pulled ${timeAgo(ws.lastPulledAt)}` : c.warn("not pulled yet");
85
+ lines.push(` ${ws.cwd} ${c.dim("·")} ${ws.vaultCount} vaults · ${ws.docCount} docs ${c.dim("·")} ${c.dim(pulled)}`);
86
+ lines.push("");
87
+ }
88
+ if (state.recent.length > 0) {
89
+ lines.push(` ${c.dim("TEAM MOVES (last 24h)")}`);
90
+ for (const m of state.recent.slice(0, 5)) {
91
+ lines.push(` ${c.coral("●")} ${c.bold(m.who)} · ${m.room} · ${c.dim(m.ago)} · "${m.title}"`);
92
+ }
93
+ lines.push("");
94
+ }
95
+ lines.push(` ${c.coral("▶")} ${c.dim("run")} ${c.bold("unfairly pull")} ${c.dim("to refresh · or just open Claude Desktop.")}`);
96
+ return lines.join("\n");
97
+ }
98
+ function hostGlyph(s, c) {
99
+ if (s === "wired")
100
+ return c.ok("✓");
101
+ if (s === "rotted")
102
+ return c.warn("⚠");
103
+ return c.dim("·");
104
+ }
105
+ export function renderTo(write, lines) {
106
+ for (const l of lines)
107
+ write(`${l}\n`);
108
+ }
109
+ // --- helpers ---
110
+ function visibleLen(s) {
111
+ // eslint-disable-next-line no-control-regex
112
+ return s.replace(/\x1b\[[0-9;]*m/g, "").length;
113
+ }
114
+ function centered(s, width, decorator) {
115
+ const v = visibleLen(s);
116
+ const pad = Math.max(0, Math.floor((width - v) / 2));
117
+ const decorated = decorator ? decorator(s) : s;
118
+ return " ".repeat(pad) + decorated;
119
+ }
120
+ function truncate(s, max) {
121
+ return s.length <= max ? s : s.slice(0, max - 1) + "…";
122
+ }
123
+ function timeAgo(iso) {
124
+ const diff = Date.now() - new Date(iso).getTime();
125
+ const mins = Math.floor(diff / 60000);
126
+ if (mins < 1)
127
+ return "just now";
128
+ if (mins < 60)
129
+ return `${mins}m ago`;
130
+ const hrs = Math.floor(mins / 60);
131
+ if (hrs < 24)
132
+ return `${hrs}h ago`;
133
+ return `${Math.floor(hrs / 24)}d ago`;
134
+ }
135
+ //# sourceMappingURL=screens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screens.js","sourceRoot":"","sources":["../../src/ui/screens.ts"],"names":[],"mappings":"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"}