dockai 0.2.5 → 0.2.6

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/README.md +13 -5
  2. package/dist/commands/claude.js +3 -5
  3. package/dist/commands/claude.js.map +1 -1
  4. package/dist/commands/completion.js +129 -0
  5. package/dist/commands/completion.js.map +1 -0
  6. package/dist/commands/doctor.js +159 -0
  7. package/dist/commands/doctor.js.map +1 -0
  8. package/dist/commands/logs.js +33 -2
  9. package/dist/commands/logs.js.map +1 -1
  10. package/dist/commands/sessions.js +6 -14
  11. package/dist/commands/sessions.js.map +1 -1
  12. package/dist/commands/ssh-config.js +10 -0
  13. package/dist/commands/ssh-config.js.map +1 -1
  14. package/dist/commands/start-stop.js +32 -0
  15. package/dist/commands/start-stop.js.map +1 -1
  16. package/dist/index.js +29 -8
  17. package/dist/index.js.map +1 -1
  18. package/dist/lib/__tests__/doctor.test.js +41 -0
  19. package/dist/lib/__tests__/doctor.test.js.map +1 -0
  20. package/dist/lib/__tests__/git-remote.test.js +26 -0
  21. package/dist/lib/__tests__/git-remote.test.js.map +1 -0
  22. package/dist/lib/__tests__/recent.test.js +11 -0
  23. package/dist/lib/__tests__/recent.test.js.map +1 -1
  24. package/dist/lib/__tests__/select.test.js +50 -0
  25. package/dist/lib/__tests__/select.test.js.map +1 -0
  26. package/dist/lib/follow.js +32 -0
  27. package/dist/lib/follow.js.map +1 -0
  28. package/dist/lib/format.js +71 -0
  29. package/dist/lib/format.js.map +1 -0
  30. package/dist/lib/git-remote.js +42 -0
  31. package/dist/lib/git-remote.js.map +1 -0
  32. package/dist/lib/pick-project.js +7 -89
  33. package/dist/lib/pick-project.js.map +1 -1
  34. package/dist/lib/recent.js +12 -5
  35. package/dist/lib/recent.js.map +1 -1
  36. package/dist/lib/remote.js +21 -0
  37. package/dist/lib/remote.js.map +1 -1
  38. package/dist/lib/select.js +148 -0
  39. package/dist/lib/select.js.map +1 -0
  40. package/dist/lib/update-check.js +92 -0
  41. package/dist/lib/update-check.js.map +1 -0
  42. package/dist/version.js +1 -1
  43. package/package.json +1 -1
@@ -90,6 +90,16 @@ export function ensureSshConfig() {
90
90
  writeFileSync(file, `${current}${sep}${current.length ? "\n" : ""}${block}\n`, { mode: 0o600 });
91
91
  return "written";
92
92
  }
93
+ /** Read-only: is the block there, and is it the one this install would write? */
94
+ export function sshConfigState() {
95
+ const file = path.join(homedir(), ".ssh", "config");
96
+ const current = existsSync(file) ? readFileSync(file, "utf8") : "";
97
+ const start = current.indexOf(BEGIN);
98
+ const end = current.indexOf(END);
99
+ if (start === -1 || end === -1 || end < start)
100
+ return "missing";
101
+ return current.slice(start, end + END.length) === sshConfigBlock() ? "current" : "stale";
102
+ }
93
103
  export async function sshConfigCommand(options) {
94
104
  const api = createApiClient();
95
105
  const projects = (await api.project.list.query());
@@ -1 +1 @@
1
- {"version":3,"file":"ssh-config.js","sourceRoot":"","sources":["../../src/commands/ssh-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ssh-config.js","sourceRoot":"","sources":["../../src/commands/ssh-config.ts"],"names":[],"mappings":"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"}
@@ -32,4 +32,36 @@ export async function stopCommand(slug) {
32
32
  fail(err, "Could not stop it");
33
33
  }
34
34
  }
35
+ /**
36
+ * Start a project and wait until its worker is up, printing a dot while it
37
+ * comes. A cold start can take two minutes (the worker agent has to answer
38
+ * before the orchestrator calls it running), so the deadline is generous.
39
+ * Returns whether it got there.
40
+ */
41
+ export async function startAndWait(api, project, timeoutMs = 180_000) {
42
+ await api.project.start.mutate({ id: project.id });
43
+ process.stdout.write(`Starting ${project.name}`);
44
+ const deadline = Date.now() + timeoutMs;
45
+ while (Date.now() < deadline) {
46
+ await new Promise((r) => setTimeout(r, 3000));
47
+ let status;
48
+ try {
49
+ status = (await api.project.list.query()).find((p) => p.id === project.id)?.status;
50
+ }
51
+ catch {
52
+ // The orchestrator can blip while a worker is created; keep waiting.
53
+ }
54
+ if (status === "RUNNING") {
55
+ process.stdout.write(" running.\n");
56
+ return true;
57
+ }
58
+ if (status === "ERROR") {
59
+ process.stdout.write(" failed.\n");
60
+ return false;
61
+ }
62
+ process.stdout.write(".");
63
+ }
64
+ process.stdout.write(" still starting.\n");
65
+ return false;
66
+ }
35
67
  //# sourceMappingURL=start-stop.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"start-stop.js","sourceRoot":"","sources":["../../src/commands/start-stop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAgC,MAAM,WAAW,CAAC;AAC1E,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAErD,KAAK,UAAU,WAAW,CAAC,GAAc,EAAE,IAAY;IACrD,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAc,CAAC;IAC/D,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACtD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY;IAC7C,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,4EAA4E;IAC5E,uEAAuE;IACvE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7C,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7C,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;IACjC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"start-stop.js","sourceRoot":"","sources":["../../src/commands/start-stop.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -19,6 +19,9 @@ import { ensureSlug } from "./lib/pick-project.js";
19
19
  import { pasteCommand } from "./commands/paste.js";
20
20
  import { accountsCommand, accountsLoginCommand } from "./commands/accounts.js";
21
21
  import { CLI_VERSION } from "./version.js";
22
+ import { checkForUpdate } from "./lib/update-check.js";
23
+ import { doctorCommand } from "./commands/doctor.js";
24
+ import { completeCommand, completionCommand } from "./commands/completion.js";
22
25
  const program = new Command();
23
26
  program
24
27
  .name("dockai")
@@ -31,7 +34,7 @@ program
31
34
  // guess live in four different command descriptions (audit 6 §17).
32
35
  .addHelpText("after", `
33
36
  Examples:
34
- $ dockai login set the server and token, once per laptop
37
+ $ dockai login set the server and token, once per computer
35
38
  $ dockai projects --json machine-readable, for scripts
36
39
  $ dockai claude app Claude Code in the "app" worker, in tmux
37
40
  $ dockai claude app --permission-mode bypassPermissions
@@ -77,10 +80,11 @@ program
77
80
  .command("logs <slug>")
78
81
  .description("Fetch project logs")
79
82
  .option("-t, --tail <lines>", "Number of lines", "100")
83
+ .option("-f, --follow", "Keep printing new lines as they arrive (Ctrl-C to stop)")
80
84
  .action(logsCommand);
81
85
  program
82
86
  .command("open <slug>")
83
- .description("Open the conversation's claude.ai URL in a browser")
87
+ .description("Open the project's page in the dashboard")
84
88
  .action(openCommand);
85
89
  program
86
90
  .command("ssh-config")
@@ -98,10 +102,10 @@ program
98
102
  // conversation the phone is on; naming one is an explicit choice.
99
103
  .option("-s, --session <name>", "tmux session to attach to or create (before the project name; default claude-cli)")
100
104
  .option("--no-tmux", "Skip tmux — the session ends when you disconnect (before the project name)")
101
- .option("--no-chrome", "Don't forward this laptop's Claude in Chrome bridge into the worker (before the project name)")
102
- .option("--no-client", "Don't offer this laptop's files and clipboard to the conversation (before the project name)")
103
- .option("--root <dir>", "Directory the conversation may read from on this laptop; repeatable (default: the current directory)", (v, prev) => [...(prev ?? []), v], [])
104
- .option("--allow-run", "Let the conversation run commands on this laptop (each run is logged here); the project's own setting is the default")
105
+ .option("--no-chrome", "Don't forward this computer's Claude in Chrome bridge into the worker (before the project name)")
106
+ .option("--no-client", "Don't offer this computer's files and clipboard to the conversation (before the project name)")
107
+ .option("--root <dir>", "Directory the conversation may read from on this computer; repeatable (default: the current directory)", (v, prev) => [...(prev ?? []), v], [])
108
+ .option("--allow-run", "Let the conversation run commands on this computer (each run is logged here); the project's own setting is the default")
105
109
  .option("--no-allow-run", "Refuse commands on this machine even if the project allows them by default")
106
110
  .passThroughOptions()
107
111
  .action((slug, claudeArgs, options) => claudeCommand(slug, options, claudeArgs));
@@ -124,7 +128,8 @@ program
124
128
  .action(accountsCommand);
125
129
  const sessions = program
126
130
  .command("sessions")
127
- .description("Move this laptop's Claude conversations into a project");
131
+ .alias("conversations")
132
+ .description("A project's conversations: list, resume, hand off, and bring this computer's into it");
128
133
  sessions
129
134
  .command("list <slug>")
130
135
  .description("Conversations on the worker, with ids and whether each is live")
@@ -167,16 +172,32 @@ program
167
172
  .command("proxy <host>")
168
173
  .description("SSH ProxyCommand transport (used by ssh, not run directly)")
169
174
  .action(proxyCommand);
175
+ program
176
+ .command("doctor")
177
+ .description("Check this computer's setup — which dockai runs, its version, the server, the login, ssh — and say how to fix what is wrong")
178
+ .option("--fix", "Also apply the safe fixes (rewrite the ~/.ssh/config block)")
179
+ .action(doctorCommand);
180
+ program
181
+ .command("completion [shell]")
182
+ .description("Print tab completion for zsh or bash; dockai completion zsh > ~/.dockai-completion.zsh, then source it from ~/.zshrc")
183
+ .action(completionCommand);
184
+ program
185
+ .command("__complete <kind>", { hidden: true })
186
+ .action((kind) => completeCommand(program, kind));
170
187
  program
171
188
  .command("status")
172
189
  .description("Show server status and project overview")
173
190
  .action(statusCommand);
191
+ checkForUpdate(CLI_VERSION, process.argv);
174
192
  // Commands that take a project first: ask for it when it was left out.
175
193
  let argv = process.argv;
176
194
  argv = await ensureSlug(argv, ["claude"], { flags: ["--no-tmux", "--tmux", "--no-chrome", "--chrome", "--no-client", "--allow-run", "--no-allow-run"], valued: ["-s", "--session", "--root"] });
177
195
  // `sessions handoff` was missing from this list, so it alone asked for a slug
178
196
  // differently from its three siblings (audit 6 §17).
179
- for (const path of [["push"], ["paste"], ["sessions", "list"], ["sessions", "resume"], ["sessions", "push"], ["sessions", "handoff"]]) {
197
+ for (const path of [
198
+ ["push"], ["paste"],
199
+ ...["sessions", "conversations"].flatMap((group) => ["list", "resume", "push", "handoff"].map((sub) => [group, sub])),
200
+ ]) {
180
201
  argv = await ensureSlug(argv, path);
181
202
  }
182
203
  await program.parseAsync(argv);
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,41 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { chmodSync, mkdirSync, mkdtempSync, symlinkSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import { compareVersions, updateNotice } from "../update-check.js";
6
+ import { dockaiOnPath } from "../../commands/doctor.js";
7
+ describe("the update notice", () => {
8
+ it("compares versions numerically", () => {
9
+ expect(compareVersions("0.2.10", "0.2.9")).toBe(1);
10
+ expect(compareVersions("0.2.5", "0.2.5")).toBe(0);
11
+ expect(compareVersions("0.1.0", "0.2.5")).toBe(-1);
12
+ expect(compareVersions("1.0.0", "1.0.0-beta")).toBe(1);
13
+ });
14
+ it("speaks only when a newer one exists", () => {
15
+ expect(updateNotice("0.1.0", "0.2.5")).toContain("0.2.5 is available (you have 0.1.0)");
16
+ expect(updateNotice("0.2.5", "0.2.5")).toBeNull();
17
+ expect(updateNotice("0.2.6", "0.2.5")).toBeNull();
18
+ expect(updateNotice("0.2.5", null)).toBeNull();
19
+ });
20
+ });
21
+ describe("which dockai a shell runs", () => {
22
+ // The case that prompted doctor: a symlink in ~/.local/bin into a stale
23
+ // checkout, ahead of the installed release on PATH.
24
+ it("lists every copy in PATH order, resolved through symlinks", () => {
25
+ const root = mkdtempSync(path.join(tmpdir(), "dockai-path-"));
26
+ const checkout = path.join(root, "Projects/DockAI/apps/cli/dist");
27
+ const local = path.join(root, ".local/bin");
28
+ const npm = path.join(root, "npm/bin");
29
+ for (const d of [checkout, local, npm])
30
+ mkdirSync(d, { recursive: true });
31
+ writeFileSync(path.join(checkout, "index.js"), "#!/usr/bin/env node\n");
32
+ chmodSync(path.join(checkout, "index.js"), 0o755);
33
+ symlinkSync(path.join(checkout, "index.js"), path.join(local, "dockai"));
34
+ writeFileSync(path.join(npm, "dockai"), "#!/bin/sh\n");
35
+ chmodSync(path.join(npm, "dockai"), 0o755);
36
+ const found = dockaiOnPath([local, path.join(root, "nothing"), npm, local].join(path.delimiter), ["dockai"]);
37
+ expect(found.map((f) => f.entry)).toEqual([path.join(local, "dockai"), path.join(npm, "dockai")]);
38
+ expect(found[0].target).toMatch(/apps\/cli\/dist\/index\.js$/);
39
+ });
40
+ });
41
+ //# sourceMappingURL=doctor.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/doctor.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { projectsForRemotes, repoKey } from "../git-remote.js";
3
+ describe("matching a folder's git remote to a project", () => {
4
+ it("reads every remote spelling as one key", () => {
5
+ for (const url of [
6
+ "git@github.com:polamoros/DockAI.git",
7
+ "https://github.com/polamoros/dockai",
8
+ "https://github.com/polamoros/DockAI.git/",
9
+ "ssh://git@github.com/polamoros/DockAI.git",
10
+ "https://x-access-token:abc@github.com/polamoros/DockAI.git",
11
+ ])
12
+ expect(repoKey(url)).toBe("github.com/polamoros/dockai");
13
+ expect(repoKey("not a url")).toBeNull();
14
+ expect(repoKey(null)).toBeNull();
15
+ });
16
+ it("finds the projects on that repository and nothing else", () => {
17
+ const projects = [
18
+ { slug: "dockai", githubRepoUrl: "https://github.com/polamoros/DockAI" },
19
+ { slug: "dockai-test", githubRepoUrl: null },
20
+ { slug: "wedding", githubRepoUrl: "https://github.com/polamoros/wedding" },
21
+ ];
22
+ expect(projectsForRemotes(projects, ["github.com/polamoros/dockai"])).toEqual(["dockai"]);
23
+ expect(projectsForRemotes(projects, [])).toEqual([]);
24
+ });
25
+ });
26
+ //# sourceMappingURL=git-remote.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-remote.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/git-remote.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE/D,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;IAC3D,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,KAAK,MAAM,GAAG,IAAI;YAChB,qCAAqC;YACrC,qCAAqC;YACrC,0CAA0C;YAC1C,2CAA2C;YAC3C,4DAA4D;SAC7D;YAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC5D,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,QAAQ,GAAG;YACf,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,qCAAqC,EAAE;YACxE,EAAE,IAAI,EAAE,aAAa,EAAE,aAAa,EAAE,IAAI,EAAE;YAC5C,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,sCAAsC,EAAE;SAC3E,CAAC;QACF,MAAM,CAAC,kBAAkB,CAAC,QAAQ,EAAE,CAAC,6BAA6B,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1F,MAAM,CAAC,kBAAkB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -35,4 +35,15 @@ describe("the project picker, per folder", () => {
35
35
  expect(readRecent(file)["/p/DockAI"][0].slug).toBe("dockai");
36
36
  });
37
37
  });
38
+ describe("the project picker and the folder's git remote", () => {
39
+ it("defaults to the checkout's project in a folder with no history", () => {
40
+ const { ordered, usedHere } = orderForDir(projects, {}, "/p/Wedding", ["wedding"]);
41
+ expect(ordered[0].slug).toBe("wedding");
42
+ expect(usedHere).toBe(1);
43
+ });
44
+ it("lets history outrank the remote — the last choice here wins", () => {
45
+ const { ordered } = orderForDir(projects, withUse({}, "/p/DockAI", "notestack", 1), "/p/DockAI", ["dockai"]);
46
+ expect(ordered.map((p) => p.slug).slice(0, 2)).toEqual(["notestack", "dockai"]);
47
+ });
48
+ });
38
49
  //# sourceMappingURL=recent.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"recent.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/recent.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"recent.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/recent.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { filterItems, windowFor } from "../select.js";
3
+ import { newLines } from "../follow.js";
4
+ import { ago, compact, conversationRow, modelLabel } from "../format.js";
5
+ const items = ["Camper 3.0", "DockAI", "Wedding Assistant", "Home Assistant"].map((l) => ({ label: `\x1b[2m${l}\x1b[22m`, value: l }));
6
+ describe("typing to filter a list", () => {
7
+ it("matches every word, any order, any case, ignoring colour codes", () => {
8
+ expect(filterItems(items, "assist").map((i) => i.value)).toEqual(["Wedding Assistant", "Home Assistant"]);
9
+ expect(filterItems(items, "ASS wed").map((i) => i.value)).toEqual(["Wedding Assistant"]);
10
+ expect(filterItems(items, "").length).toBe(4);
11
+ expect(filterItems(items, "nope")).toEqual([]);
12
+ });
13
+ it("scrolls a long list so the selection stays in view", () => {
14
+ expect(windowFor(5, 4, 10)).toEqual({ start: 0, end: 5 });
15
+ expect(windowFor(100, 0, 10)).toEqual({ start: 0, end: 10 });
16
+ expect(windowFor(100, 50, 10)).toEqual({ start: 45, end: 55 });
17
+ expect(windowFor(100, 99, 10)).toEqual({ start: 90, end: 100 });
18
+ });
19
+ });
20
+ describe("following logs", () => {
21
+ it("prints only what came after the last lines printed, even when lines repeat", () => {
22
+ expect(newLines(["a", "b", "c"], ["b", "c", "d", "e"]).lines).toEqual(["d", "e"]);
23
+ expect(newLines(["x", "ok", "ok"], ["ok", "ok", "y", "ok", "ok", "z"], 2).lines).toEqual(["z"]);
24
+ expect(newLines(["a", "b"], ["a", "b"]).lines).toEqual([]);
25
+ });
26
+ it("says when more arrived than one snapshot holds", () => {
27
+ expect(newLines(["a", "b"], ["q", "r"])).toEqual({ lines: ["q", "r"], gap: true });
28
+ });
29
+ });
30
+ describe("a conversation row", () => {
31
+ const now = Date.UTC(2026, 8, 23, 12);
32
+ it("says when, how long, how full and which model", () => {
33
+ const row = conversationRow({
34
+ id: "826b6bcf", title: "DockAI", firstPrompt: "", messageCount: 412, updatedAt: now - 3 * 3600_000,
35
+ remoteId: "cse_1", remoteState: "interactive", model: "claude-opus-5-5", contextTokens: 142_300,
36
+ }, now).replace(/\x1b\[[0-9;]*m/g, "");
37
+ for (const part of ["DockAI", "live", "3h ago", "412 msgs", "142k ctx", "Opus 5.5"])
38
+ expect(row).toContain(part);
39
+ });
40
+ it("formats its parts", () => {
41
+ expect(ago(now - 30_000, now)).toBe("just now");
42
+ expect(ago(now - 2 * 86400_000, now)).toBe("2d ago");
43
+ expect(compact(950)).toBe("950");
44
+ expect(compact(1_420_000)).toBe("1.4M");
45
+ expect(modelLabel("claude-haiku-4-5-20251001")).toBe("Haiku 4.5");
46
+ expect(modelLabel("claude-sonnet-5")).toBe("Sonnet 5");
47
+ expect(modelLabel("claude-fable-5-1")).toBe("Fable 5.1");
48
+ });
49
+ });
50
+ //# sourceMappingURL=select.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/select.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The lines of a fresh log snapshot that were not in the last one.
3
+ *
4
+ * Both snapshots are tails of the same stream, so the new one overlaps the
5
+ * old one's end. The last few lines printed are found in the new snapshot —
6
+ * the *last* place they occur, because log lines repeat — and what follows
7
+ * them is new. When they cannot be found the stream moved on by more than a
8
+ * whole snapshot between polls, and everything is new; `gap` says so.
9
+ */
10
+ export function newLines(printed, snapshot, window = 5) {
11
+ if (!printed.length)
12
+ return { lines: snapshot, gap: false };
13
+ // The longest overlap first, since a short one can match by accident on
14
+ // repeated lines; shorter ones only when the snapshot starts part-way into
15
+ // the window.
16
+ for (let w = Math.min(window, printed.length); w >= 1; w--) {
17
+ const tail = printed.slice(-w);
18
+ for (let end = snapshot.length - 1; end >= w - 1; end--) {
19
+ let match = true;
20
+ for (let k = 0; k < w; k++) {
21
+ if (snapshot[end - w + 1 + k] !== tail[k]) {
22
+ match = false;
23
+ break;
24
+ }
25
+ }
26
+ if (match)
27
+ return { lines: snapshot.slice(end + 1), gap: false };
28
+ }
29
+ }
30
+ return { lines: snapshot, gap: true };
31
+ }
32
+ //# sourceMappingURL=follow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"follow.js","sourceRoot":"","sources":["../../src/lib/follow.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAiB,EAAE,QAAkB,EAAE,MAAM,GAAG,CAAC;IACxE,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IAC5D,wEAAwE;IACxE,2EAA2E;IAC3E,cAAc;IACd,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,KAAK,IAAI,GAAG,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC;YACxD,IAAI,KAAK,GAAG,IAAI,CAAC;YACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,IAAI,QAAQ,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBAAC,KAAK,GAAG,KAAK,CAAC;oBAAC,MAAM;gBAAC,CAAC;YACtE,CAAC;YACD,IAAI,KAAK;gBAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QACnE,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACxC,CAAC"}
@@ -0,0 +1,71 @@
1
+ import { pad } from "./select.js";
2
+ const DIM = "\x1b[2m";
3
+ const RESET_DIM = "\x1b[22m";
4
+ const GREEN = "\x1b[32m";
5
+ const YELLOW = "\x1b[33m";
6
+ const RESET_FG = "\x1b[39m";
7
+ /** "just now", "12m ago", "3h ago", "2d ago", then a date. */
8
+ export function ago(ms, now = Date.now()) {
9
+ if (!ms)
10
+ return "";
11
+ const s = Math.max(0, Math.round((now - ms) / 1000));
12
+ if (s < 60)
13
+ return "just now";
14
+ if (s < 3600)
15
+ return `${Math.floor(s / 60)}m ago`;
16
+ if (s < 86400)
17
+ return `${Math.floor(s / 3600)}h ago`;
18
+ if (s < 86400 * 30)
19
+ return `${Math.floor(s / 86400)}d ago`;
20
+ return new Date(ms).toISOString().slice(0, 10);
21
+ }
22
+ /** 950 → "950", 14_200 → "14k", 1_420_000 → "1.4M". */
23
+ export function compact(n) {
24
+ if (n == null)
25
+ return "";
26
+ if (n < 1000)
27
+ return String(n);
28
+ if (n < 1_000_000)
29
+ return `${Math.round(n / 1000)}k`;
30
+ return `${(n / 1_000_000).toFixed(1).replace(/\.0$/, "")}M`;
31
+ }
32
+ /** `claude-opus-5-5` → "Opus 5.5", `claude-haiku-4-5-20251001` → "Haiku 4.5". */
33
+ export function modelLabel(id) {
34
+ if (!id)
35
+ return "";
36
+ const m = /^claude-([a-z]+)-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?/i.exec(id);
37
+ if (!m)
38
+ return id;
39
+ return `${m[1][0].toUpperCase()}${m[1].slice(1)} ${m[2]}${m[3] ? `.${m[3]}` : ""}`;
40
+ }
41
+ /** Where a conversation is, in the dashboard's words. */
42
+ export function conversationState(s) {
43
+ if (s.remoteState === "interactive")
44
+ return `${GREEN}live${RESET_FG}`;
45
+ if (s.remoteState === "server")
46
+ return `${YELLOW}app only${RESET_FG}`;
47
+ return `${DIM}${s.remoteId ? "idle" : "local"}${RESET_DIM}`;
48
+ }
49
+ /**
50
+ * One picker row: title, where it is, when it was last used, how long it is,
51
+ * how full its context is, and the model — the things that tell six
52
+ * similar-looking conversations apart. It was the title cut to 60 characters
53
+ * and a state, so two runs of the same schedule could not be told apart
54
+ * (asked for, 2026-09-23). Columns that a conversation has no figure for are
55
+ * left blank rather than dropped, so the rest stay aligned.
56
+ */
57
+ export function conversationRow(s, now = Date.now(), titleWidth = 44) {
58
+ const raw = (s.title || s.firstPrompt || s.id.slice(0, 8)).replace(/\s+/g, " ").trim();
59
+ const title = raw.length > titleWidth ? `${raw.slice(0, titleWidth - 1)}…` : raw;
60
+ const msgs = s.messageCount ? `${s.messageCount} msg${s.messageCount === 1 ? "" : "s"}` : "";
61
+ const ctx = s.contextTokens ? `${compact(s.contextTokens)} ctx` : "";
62
+ return [
63
+ pad(title, titleWidth + 2),
64
+ pad(conversationState(s), 10),
65
+ pad(`${DIM}${ago(s.updatedAt, now)}${RESET_DIM}`, 10),
66
+ pad(`${DIM}${msgs}${RESET_DIM}`, 10),
67
+ pad(`${DIM}${ctx}${RESET_DIM}`, 10),
68
+ `${DIM}${modelLabel(s.model)}${RESET_DIM}`,
69
+ ].join("").trimEnd();
70
+ }
71
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/lib/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { execFileSync } from "node:child_process";
2
+ /**
3
+ * `git@github.com:owner/repo.git`, `https://github.com/owner/repo`,
4
+ * `ssh://git@github.com/owner/repo.git` → `github.com/owner/repo`.
5
+ * Lower-cased, since GitHub treats owner and repo case-insensitively.
6
+ */
7
+ export function repoKey(url) {
8
+ if (!url)
9
+ return null;
10
+ let u = url.trim();
11
+ const scp = /^[\w.-]+@([\w.-]+):(.+)$/.exec(u); // git@host:owner/repo
12
+ if (scp)
13
+ u = `${scp[1]}/${scp[2]}`;
14
+ else
15
+ u = u.replace(/^[a-z+]+:\/\//i, "").replace(/^[^@/]+@/, ""); // scheme, user@
16
+ u = u.replace(/\/+$/, "").replace(/\.git$/i, "");
17
+ const parts = u.split("/");
18
+ if (parts.length < 3)
19
+ return null;
20
+ return parts.slice(0, 3).join("/").toLowerCase();
21
+ }
22
+ /** Every remote of the git checkout at `dir`, as repo keys. Empty outside one. */
23
+ export function remotesOf(dir) {
24
+ try {
25
+ const out = execFileSync("git", ["-C", dir, "remote", "-v"], { encoding: "utf8", timeout: 1500, stdio: ["ignore", "pipe", "ignore"] });
26
+ const keys = out.split("\n").map((l) => repoKey(l.split(/\s+/)[1])).filter((k) => Boolean(k));
27
+ return [...new Set(keys)];
28
+ }
29
+ catch {
30
+ return [];
31
+ }
32
+ }
33
+ /** Slugs of the projects whose repository is one of this folder's remotes. */
34
+ export function projectsForRemotes(projects, remotes) {
35
+ if (!remotes.length)
36
+ return [];
37
+ return projects.filter((p) => {
38
+ const key = repoKey(p.githubRepoUrl);
39
+ return key !== null && remotes.includes(key);
40
+ }).map((p) => p.slug);
41
+ }
42
+ //# sourceMappingURL=git-remote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-remote.js","sourceRoot":"","sources":["../../src/lib/git-remote.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,GAA8B;IACpD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACnB,MAAM,GAAG,GAAG,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB;IACtE,IAAI,GAAG;QAAE,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;;QAC9B,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB;IAClF,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AACnD,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QACvI,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3G,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,kBAAkB,CAA4D,QAAa,EAAE,OAAiB;IAC5H,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAC/B,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;QACrC,OAAO,GAAG,KAAK,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC"}