dockai 0.2.2 → 0.2.4

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 +42 -22
  2. package/dist/commands/__tests__/claude-default.test.js +25 -0
  3. package/dist/commands/__tests__/claude-default.test.js.map +1 -0
  4. package/dist/commands/accounts.js +186 -0
  5. package/dist/commands/accounts.js.map +1 -0
  6. package/dist/commands/claude.js +32 -10
  7. package/dist/commands/claude.js.map +1 -1
  8. package/dist/commands/connect.js +6 -1
  9. package/dist/commands/connect.js.map +1 -1
  10. package/dist/commands/deploy.js +2 -2
  11. package/dist/commands/deploy.js.map +1 -1
  12. package/dist/commands/login.js +26 -1
  13. package/dist/commands/login.js.map +1 -1
  14. package/dist/commands/logs.js +10 -6
  15. package/dist/commands/logs.js.map +1 -1
  16. package/dist/commands/open.js +11 -12
  17. package/dist/commands/open.js.map +1 -1
  18. package/dist/commands/projects.js +14 -6
  19. package/dist/commands/projects.js.map +1 -1
  20. package/dist/commands/start-stop.js +8 -10
  21. package/dist/commands/start-stop.js.map +1 -1
  22. package/dist/commands/status.js +5 -2
  23. package/dist/commands/status.js.map +1 -1
  24. package/dist/index.js +51 -22
  25. package/dist/index.js.map +1 -1
  26. package/dist/lib/__tests__/accounts.test.js +40 -0
  27. package/dist/lib/__tests__/accounts.test.js.map +1 -0
  28. package/dist/lib/__tests__/fail.test.js +33 -0
  29. package/dist/lib/__tests__/fail.test.js.map +1 -0
  30. package/dist/lib/__tests__/remote.test.js +81 -0
  31. package/dist/lib/__tests__/remote.test.js.map +1 -0
  32. package/dist/lib/accounts.js +90 -0
  33. package/dist/lib/accounts.js.map +1 -0
  34. package/dist/lib/fail.js +48 -0
  35. package/dist/lib/fail.js.map +1 -0
  36. package/dist/lib/pick-project.js +7 -0
  37. package/dist/lib/pick-project.js.map +1 -1
  38. package/dist/lib/remote.js +11 -2
  39. package/dist/lib/remote.js.map +1 -1
  40. package/dist/terminal.js +11 -6
  41. package/dist/terminal.js.map +1 -1
  42. package/dist/version.js +1 -1
  43. package/package.json +6 -3
@@ -1 +1 @@
1
- {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAY,EACZ,OAA0B;IAE1B,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC;IAEjD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAc,CAAC;QAC/D,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,YAAY,IAAI,cAAc,CAAC,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAErE,CAAC;QACF,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAY,EACZ,OAA0B;IAE1B,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,6DAA6D;IAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3C,OAAO,CAAC,KAAK,CAAC,wCAAwC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEtC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAc,CAAC;QAC/D,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAChC,CAAC;QAED,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAErE,CAAC;QACF,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,EAAE,0BAA0B,CAAC,CAAC;IACxC,CAAC;AACH,CAAC"}
@@ -1,26 +1,25 @@
1
1
  import open from "open";
2
2
  import { createApiClient } from "../api.js";
3
+ import { getServerUrl } from "../config.js";
4
+ import { fail, noSuchProject } from "../lib/fail.js";
3
5
  export async function openCommand(slug) {
4
6
  const api = createApiClient();
5
7
  try {
6
8
  const projects = (await api.project.list.query());
7
9
  const project = projects.find((p) => p.slug === slug);
8
10
  if (!project) {
9
- console.error(`Project "${slug}" not found.`);
10
- process.exit(1);
11
- }
12
- if (project.container?.sessionUrl) {
13
- console.log(`Opening ${project.container.sessionUrl}...`);
14
- await open(project.container.sessionUrl);
15
- }
16
- else {
17
- console.log("No active session URL. Is the project running?");
11
+ noSuchProject(slug, projects);
18
12
  }
13
+ // This used to read `container.sessionUrl`, a column nothing in the
14
+ // server ever writes — so it answered "No active session URL. Is the
15
+ // project running?" on a running project, every time (audit 6 §3). What
16
+ // a person means by `dockai open <slug>` is the project's page.
17
+ const url = `${getServerUrl().replace(/\/$/, "")}/projects/${project.slug}`;
18
+ console.log(`Opening ${url}`);
19
+ await open(url);
19
20
  }
20
21
  catch (err) {
21
- const msg = err instanceof Error ? err.message : String(err);
22
- console.error("Failed:", msg);
23
- process.exit(1);
22
+ fail(err);
24
23
  }
25
24
  }
26
25
  //# sourceMappingURL=open.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAc,CAAC;QAC/D,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,YAAY,IAAI,cAAc,CAAC,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,OAAO,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,CAAC,SAAS,CAAC,UAAU,KAAK,CAAC,CAAC;YAC1D,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAc,CAAC;QAC/D,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAChC,CAAC;QAED,oEAAoE;QACpE,qEAAqE;QACrE,wEAAwE;QACxE,gEAAgE;QAChE,MAAM,GAAG,GAAG,GAAG,YAAY,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;QAC9B,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { createApiClient } from "../api.js";
2
+ import { fail } from "../lib/fail.js";
2
3
  const statusIcons = {
3
4
  RUNNING: "\x1b[32m●\x1b[0m",
4
5
  STARTING: "\x1b[33m◐\x1b[0m",
@@ -6,10 +7,17 @@ const statusIcons = {
6
7
  ERROR: "\x1b[31m●\x1b[0m",
7
8
  STOPPED: "\x1b[90m○\x1b[0m",
8
9
  };
9
- export async function projectsCommand() {
10
+ export async function projectsCommand(options = {}) {
10
11
  const api = createApiClient();
11
12
  try {
12
13
  const projects = (await api.project.list.query());
14
+ // The list was unparsable for scripting except by stripping ANSI, which
15
+ // is the kind of thing a person writes once and then maintains for ever
16
+ // (audit 6 §17).
17
+ if (options.json) {
18
+ console.log(JSON.stringify(projects.map((p) => ({ name: p.name, slug: p.slug, status: p.status })), null, 2));
19
+ return;
20
+ }
13
21
  if (!projects.length) {
14
22
  console.log("No projects found. Create one in the dashboard.");
15
23
  return;
@@ -17,15 +25,15 @@ export async function projectsCommand() {
17
25
  console.log("\nProjects:\n");
18
26
  for (const p of projects) {
19
27
  const icon = statusIcons[p.status] || "?";
20
- const session = p.container?.sessionUrl ? ` → ${p.container.sessionUrl}` : "";
21
- console.log(` ${icon} ${p.name} (${p.slug}) [${p.status}]${session}`);
28
+ // `container.sessionUrl` is a column nothing in the server writes, so
29
+ // this suffix never appeared (audit 6 §3, the same dead field `open`
30
+ // was reading).
31
+ console.log(` ${icon} ${p.name} (${p.slug}) [${p.status}]`);
22
32
  }
23
33
  console.log();
24
34
  }
25
35
  catch (err) {
26
- const msg = err instanceof Error ? err.message : String(err);
27
- console.error("Failed to list projects:", msg);
28
- process.exit(1);
36
+ fail(err, "Could not list your projects");
29
37
  }
30
38
  }
31
39
  //# sourceMappingURL=projects.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAE1D,MAAM,WAAW,GAA2B;IAC1C,OAAO,EAAE,kBAAkB;IAC3B,QAAQ,EAAE,kBAAkB;IAC5B,QAAQ,EAAE,kBAAkB;IAC5B,KAAK,EAAE,kBAAkB;IACzB,OAAO,EAAE,kBAAkB;CAC5B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAc,CAAC;QAE/D,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;YAC1C,MAAM,OAAO,GAAG,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9E,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,MAAM,WAAW,GAA2B;IAC1C,OAAO,EAAE,kBAAkB;IAC3B,QAAQ,EAAE,kBAAkB;IAC5B,QAAQ,EAAE,kBAAkB;IAC5B,KAAK,EAAE,kBAAkB;IACzB,OAAO,EAAE,kBAAkB;CAC5B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAO,GAAuB,EAAE;IACpE,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAc,CAAC;QAE/D,wEAAwE;QACxE,wEAAwE;QACxE,iBAAiB;QACjB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC9G,OAAO;QACT,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;YAC1C,sEAAsE;YACtE,qEAAqE;YACrE,gBAAgB;YAChB,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,EAAE,8BAA8B,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC"}
@@ -1,37 +1,35 @@
1
1
  import { createApiClient } from "../api.js";
2
+ import { fail, noSuchProject } from "../lib/fail.js";
2
3
  async function findProject(api, slug) {
3
4
  const projects = (await api.project.list.query());
4
5
  const project = projects.find((p) => p.slug === slug);
5
6
  if (!project) {
6
- console.error(`Project "${slug}" not found.`);
7
- process.exit(1);
7
+ noSuchProject(slug, projects);
8
8
  }
9
9
  return project;
10
10
  }
11
11
  export async function startCommand(slug) {
12
12
  const api = createApiClient();
13
- const project = await findProject(api, slug);
13
+ // Inside the try: `findProject` is an API call, and with the server down it
14
+ // threw a raw `TRPCClientError` straight to the terminal (audit 6 §9).
14
15
  try {
16
+ const project = await findProject(api, slug);
15
17
  await api.project.start.mutate({ id: project.id });
16
18
  console.log(`Starting ${project.name}...`);
17
19
  }
18
20
  catch (err) {
19
- const msg = err instanceof Error ? err.message : String(err);
20
- console.error("Failed to start:", msg);
21
- process.exit(1);
21
+ fail(err, "Could not start it");
22
22
  }
23
23
  }
24
24
  export async function stopCommand(slug) {
25
25
  const api = createApiClient();
26
- const project = await findProject(api, slug);
27
26
  try {
27
+ const project = await findProject(api, slug);
28
28
  await api.project.stop.mutate({ id: project.id });
29
29
  console.log(`Stopping ${project.name}...`);
30
30
  }
31
31
  catch (err) {
32
- const msg = err instanceof Error ? err.message : String(err);
33
- console.error("Failed to stop:", msg);
34
- process.exit(1);
32
+ fail(err, "Could not stop it");
35
33
  }
36
34
  }
37
35
  //# 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;AAE1E,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,OAAO,CAAC,KAAK,CAAC,YAAY,IAAI,cAAc,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY;IAC7C,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAE7C,IAAI,CAAC;QACH,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,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAE7C,IAAI,CAAC;QACH,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,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
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"}
@@ -14,11 +14,14 @@ export async function statusCommand() {
14
14
  catch {
15
15
  console.log(`\nServer: ${serverUrl}`);
16
16
  console.log(`Status: \x1b[31munreachable\x1b[0m\n`);
17
- return;
17
+ // Exit non-zero, or `dockai status` cannot be used as a health check —
18
+ // it reported success for an unreachable server and for a missing login
19
+ // alike (audit 6 §17).
20
+ process.exit(1);
18
21
  }
19
22
  if (!token) {
20
23
  console.log("\nNot logged in. Run 'dockai login' first.\n");
21
- return;
24
+ process.exit(1);
22
25
  }
23
26
  try {
24
27
  const projects = (await api.project.list.query());
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,SAAS,aAAa,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0C,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,aAAa,SAAS,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,aAAa,SAAS,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAc,CAAC;QAC/D,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,CAAC,MAAM,WAAW,OAAO,YAAY,CAAC,CAAC;IAC5E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,IAAI,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACxD,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,+BAA+B,GAAG,IAAI,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,SAAS,aAAa,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0C,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,aAAa,SAAS,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,aAAa,SAAS,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,uEAAuE;QACvE,wEAAwE;QACxE,uBAAuB;QACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAc,CAAC;QAC/D,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,CAAC,MAAM,WAAW,OAAO,YAAY,CAAC,CAAC;IAC5E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,IAAI,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACxD,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,+BAA+B,GAAG,IAAI,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;AACH,CAAC"}
package/dist/index.js CHANGED
@@ -17,15 +17,29 @@ import { sessionsPushCommand, sessionsListCommand, sessionsResumeCommand, sessio
17
17
  import { deployCommand } from "./commands/deploy.js";
18
18
  import { ensureSlug } from "./lib/pick-project.js";
19
19
  import { pasteCommand } from "./commands/paste.js";
20
+ import { accountsCommand, accountsLoginCommand } from "./commands/accounts.js";
20
21
  import { CLI_VERSION } from "./version.js";
21
22
  const program = new Command();
22
23
  program
23
24
  .name("dockai")
24
- .description("CLI for DockAI — self-hosted Claude Code session manager")
25
+ .description("CLI for DockAI — self-hosted Claude Code workers")
25
26
  .version(CLI_VERSION)
26
27
  // Lets `dockai claude <slug> --resume x -r` hand every flag after the slug to
27
28
  // claude untouched, without a `--` separator.
28
- .enablePositionalOptions();
29
+ .enablePositionalOptions()
30
+ // There were no examples anywhere, and the three flag rules a person cannot
31
+ // guess live in four different command descriptions (audit 6 §17).
32
+ .addHelpText("after", `
33
+ Examples:
34
+ $ dockai login set the server and token, once per laptop
35
+ $ dockai projects --json machine-readable, for scripts
36
+ $ dockai claude app Claude Code in the "app" worker, in tmux
37
+ $ dockai claude app --permission-mode bypassPermissions
38
+ flags AFTER the project name go to claude
39
+ $ dockai claude -s scratch app flags BEFORE it are dockai's own
40
+ $ ssh dockai-app the same worker as a plain ssh host
41
+ $ dockai status exits non-zero if the server is unreachable
42
+ `);
29
43
  program
30
44
  .command("login")
31
45
  .description("Authenticate with the DockAI server")
@@ -43,6 +57,7 @@ program
43
57
  program
44
58
  .command("projects")
45
59
  .description("List all projects with status")
60
+ .option("--json", "Print the raw list, for scripts")
46
61
  .action(projectsCommand);
47
62
  program
48
63
  .command("start <slug>")
@@ -54,8 +69,8 @@ program
54
69
  .action(stopCommand);
55
70
  program
56
71
  .command("connect <slug>")
57
- .description("Connect to a worker container terminal")
58
- .option("--claude", "Drop into interactive Claude session")
72
+ .description("Open a terminal in the project's worker")
73
+ .option("--claude", "Open Claude instead of a shell")
59
74
  .option("--ssh", "Connect via SSH instead of WebSocket")
60
75
  .action(connectCommand);
61
76
  program
@@ -65,7 +80,7 @@ program
65
80
  .action(logsCommand);
66
81
  program
67
82
  .command("open <slug>")
68
- .description("Open the Claude.ai session URL in browser")
83
+ .description("Open the conversation's claude.ai URL in a browser")
69
84
  .action(openCommand);
70
85
  program
71
86
  .command("ssh-config")
@@ -78,15 +93,15 @@ program
78
93
  .action(codeCommand);
79
94
  program
80
95
  .command("claude <slug> [claudeArgs...]")
81
- .description("Run Claude Code inside the project's worker, in tmux — joining the conversation your phone is on when there is one. -r / --resume <id|title> picks among the project's conversations; other flags after the project name go to claude: dockai claude app --permission-mode bypassPermissions")
96
+ .description("Run Claude Code inside the project's worker, in tmux. At a terminal it asks: a new conversation, or which one to join. --resume <id|title> goes straight to one; other flags after the project name go to claude: dockai claude app --permission-mode bypassPermissions")
82
97
  // No default here: an unset session is what lets the command join the
83
98
  // conversation the phone is on; naming one is an explicit choice.
84
99
  .option("-s, --session <name>", "tmux session to attach to or create (before the project name; default claude-cli)")
85
100
  .option("--no-tmux", "Skip tmux — the session ends when you disconnect (before the project name)")
86
- .option("--no-chrome", "Don't forward this machine's Claude in Chrome bridge into the worker (before the project name)")
87
- .option("--no-client", "Don't offer this machine's files and clipboard to the session (before the project name)")
88
- .option("--root <dir>", "Directory the session may read from on this machine; repeatable (default: the current directory)", (v, prev) => [...(prev ?? []), v], [])
89
- .option("--allow-run", "Let the session run commands on this machine (each run is logged here); the project's own setting is the default")
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")
90
105
  .option("--no-allow-run", "Refuse commands on this machine even if the project allows them by default")
91
106
  .passThroughOptions()
92
107
  .action((slug, claudeArgs, options) => claudeCommand(slug, options, claudeArgs));
@@ -95,16 +110,28 @@ program
95
110
  .description("Copy local files into the project's workspace — the .env and scripts a clone doesn't carry")
96
111
  .option("--keep-existing", "Leave files that already exist on the worker untouched")
97
112
  .action(pushCommand);
113
+ const accounts = program
114
+ .command("accounts")
115
+ .description("Your Claude accounts: signed in or not, plan, and usage (session and weekly windows)")
116
+ .action(accountsCommand);
117
+ accounts
118
+ .command("login [name]")
119
+ .description("Sign a Claude account in with this computer's browser — the same sign-in as the dashboard's")
120
+ .action(accountsLoginCommand);
121
+ program
122
+ .command("usage")
123
+ .description("Claude usage per account — the same as `dockai accounts`")
124
+ .action(accountsCommand);
98
125
  const sessions = program
99
126
  .command("sessions")
100
- .description("Move Claude Code sessions from this machine into a project");
127
+ .description("Move this laptop's Claude conversations into a project");
101
128
  sessions
102
129
  .command("list <slug>")
103
- .description("Conversations on the worker, with ids and whether each is live on the phone")
130
+ .description("Conversations on the worker, with ids and whether each is live")
104
131
  .action(sessionsListCommand);
105
132
  sessions
106
133
  .command("resume <slug> <session>")
107
- .description("Open a conversation by id, id prefix or name — in a terminal here, or on the phone with --remote")
134
+ .description("Open a conversation by id, id prefix or name — in a terminal here, or in the Claude app with --remote")
108
135
  .option("--remote", "Register it with Remote Control through DockAI instead of opening a terminal")
109
136
  .action(sessionsResumeCommand);
110
137
  sessions
@@ -114,21 +141,21 @@ sessions
114
141
  .option("--title <title>", "Title for the new conversation (default: the old one's)")
115
142
  .option("--file-only", "Write the hand-off file without creating a conversation, to send the message in one that already exists")
116
143
  .option("--into <id>", "Continue in this existing conversation instead of creating one: a cse_… id (environment) or a local id with --terminal")
117
- .option("--terminal", "Continue in an interactive Remote Control conversation — on the phone and joinable with dockai claude — instead of a server-bound one")
144
+ .option("--terminal", "Continue in a terminal conversation — in the Claude app and joinable with dockai claude — instead of an app-only one")
118
145
  .action(sessionsHandoffCommand);
119
146
  sessions
120
147
  .command("push <slug>")
121
- .description("Copy this directory's Claude sessions and memory into the project, with paths rewritten to the workspace")
122
- .option("--from <dir>", "Local project directory whose sessions to push (default: current directory)")
123
- .option("--latest <n>", "Only the n most recently used sessions")
124
- .option("--session <id...>", "Only these sessions (id or unique prefix); repeatable")
125
- .option("--overwrite", "Replace sessions that already exist on the worker")
126
- .option("--remote", "Then resume each pushed session in the worker with Remote Control, so it appears in the Claude app and claude.ai/code")
148
+ .description("Copy this directory's Claude conversations and memory into the project, with paths rewritten to the workspace")
149
+ .option("--from <dir>", "Local project directory whose conversations to push (default: current directory)")
150
+ .option("--latest <n>", "Only the n most recently used conversations")
151
+ .option("--session <id...>", "Only these conversations (id or unique prefix); repeatable")
152
+ .option("--overwrite", "Replace conversations that already exist on the worker")
153
+ .option("--remote", "Then register each pushed conversation with Remote Control, so it appears in the Claude app")
127
154
  .option("--dry-run", "Show what would be pushed without sending anything")
128
155
  .action(sessionsPushCommand);
129
156
  program
130
157
  .command("paste <slug>")
131
- .description("Paste the image on your clipboard into a running dockai claude session (macOS)")
158
+ .description("Paste the image on your clipboard into a running dockai claude conversation (macOS)")
132
159
  .option("-s, --session <name>", "tmux session to type into", "claude-cli")
133
160
  .action(pasteCommand);
134
161
  program
@@ -147,7 +174,9 @@ program
147
174
  // Commands that take a project first: ask for it when it was left out.
148
175
  let argv = process.argv;
149
176
  argv = await ensureSlug(argv, ["claude"], { flags: ["--no-tmux", "--tmux", "--no-chrome", "--chrome", "--no-client", "--allow-run", "--no-allow-run"], valued: ["-s", "--session", "--root"] });
150
- for (const path of [["push"], ["paste"], ["sessions", "list"], ["sessions", "resume"], ["sessions", "push"]]) {
177
+ // `sessions handoff` was missing from this list, so it alone asked for a slug
178
+ // differently from its three siblings (audit 6 §17).
179
+ for (const path of [["push"], ["paste"], ["sessions", "list"], ["sessions", "resume"], ["sessions", "push"], ["sessions", "handoff"]]) {
151
180
  argv = await ensureSlug(argv, path);
152
181
  }
153
182
  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,40 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { accountState, findAccount, findLoginUrl, planLabel, usageLine } from "../accounts.js";
3
+ const accounts = [
4
+ { id: "cmA", label: "FrogJump", isValid: true },
5
+ { id: "cmB", label: "Personal", isValid: false, hasSdkToken: true },
6
+ { id: "cmC", label: "Personal old", isValid: false },
7
+ ];
8
+ describe("dockai accounts", () => {
9
+ it("says the dashboard's three states", () => {
10
+ expect(accounts.map(accountState)).toEqual(["signed in", "token only", "not signed in"]);
11
+ });
12
+ it("never prints a raw tier", () => {
13
+ expect(planLabel("default_claude_max_20x")).toBe("Max 20x");
14
+ expect(planLabel(null)).toBeNull();
15
+ expect(planLabel("default_claude_ultra_plus")).toBe("ultra plus");
16
+ });
17
+ it("prints the windows, and says why when there are none", () => {
18
+ expect(usageLine({ fiveHour: { utilization: 2.4, resetsIn: "4h 8m" }, sevenDay: { utilization: 90, resetsIn: "1d 8h" }, scoped: [{ name: "Fable", utilization: 83 }], source: "api" }, true))
19
+ .toBe("session 2% (resets in 4h 8m) · weekly 90% (resets in 1d 8h) · Fable 83%");
20
+ expect(usageLine(null, false)).toMatch(/start a project/);
21
+ expect(usageLine({ fiveHour: null, sevenDay: null, source: "error", error: "Rate limited" }, true)).toBe("usage: Rate limited");
22
+ });
23
+ it("finds an account by id, exact name or unique prefix, and refuses to guess", () => {
24
+ expect(findAccount(accounts, "cmB")).toMatchObject({ label: "Personal" });
25
+ expect(findAccount(accounts, "personal")).toMatchObject({ label: "Personal" });
26
+ expect(findAccount(accounts, "frog")).toMatchObject({ label: "FrogJump" });
27
+ expect(findAccount(accounts, "pers")).toMatch(/matches 2 accounts/);
28
+ expect(findAccount(accounts, "nope")).toMatch(/No Claude account matches/);
29
+ });
30
+ });
31
+ describe("the sign-in link in claude auth login's output", () => {
32
+ it("is found across a wrap and escape codes", () => {
33
+ const out = "Browser didn't open? Use the url below to sign in:\r\n\r\n\u001b[1mhttps://claude.ai/oauth/authorize?code=true&client_id=abc\r\n&state=xyz\u001b[22m \r\n";
34
+ expect(findLoginUrl(out)).toBe("https://claude.ai/oauth/authorize?code=true&client_id=abc&state=xyz");
35
+ });
36
+ it("is null until it has arrived", () => {
37
+ expect(findLoginUrl("Opening browser to sign in…")).toBeNull();
38
+ });
39
+ });
40
+ //# sourceMappingURL=accounts.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/accounts.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+ vi.mock("../../config.js", () => ({ getServerUrl: () => "https://dockai.example.com" }));
3
+ const { explain } = await import("../fail.js");
4
+ /**
5
+ * One sentence, never a stack.
6
+ *
7
+ * `start`, `stop` and `ssh-config` called the API outside their `try`, so a
8
+ * server that was down printed twelve lines of `node_modules` paths and an
9
+ * undici frame — while `dockai projects`, in the same situation, printed one
10
+ * sentence. Four more commands let a bare `UNAUTHORIZED` reach the screen as
11
+ * their entire output (audit 6 §9).
12
+ */
13
+ describe("explain", () => {
14
+ it("names the server when it cannot be reached", () => {
15
+ const msg = explain(new Error("fetch failed"));
16
+ expect(msg).toContain("dockai.example.com");
17
+ expect(msg).toMatch(/dockai login/);
18
+ });
19
+ it("says what a rejected token is, not its code", () => {
20
+ expect(explain(new Error("UNAUTHORIZED"))).toMatch(/token was rejected/i);
21
+ expect(explain(new Error("UNAUTHORIZED"))).not.toMatch(/UNAUTHORIZED/);
22
+ });
23
+ it("keeps a tRPC message written for a person", () => {
24
+ expect(explain(new Error("Start the project first"))).toBe("Start the project first");
25
+ });
26
+ it("drops the stack, which is what used to be the output", () => {
27
+ const err = new Error("TRPCClientError: fetch failed\n\n at node:internal/deps/undici/undici:15157:13\n at process.processTicksAndRejections");
28
+ const msg = explain(err);
29
+ expect(msg, "a node_modules frame reached the terminal").not.toMatch(/node:internal|at process/);
30
+ expect(msg.split("\n").length).toBeLessThanOrEqual(3);
31
+ });
32
+ });
33
+ //# sourceMappingURL=fail.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fail.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/fail.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAElD,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,4BAA4B,EAAE,CAAC,CAAC,CAAC;AAEzF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;AAE/C;;;;;;;;GAQG;AACH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAC1E,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,GAAG,GAAG,IAAI,KAAK,CACnB,6HAA6H,CAC9H,CAAC;QACF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QACzB,MAAM,CAAC,GAAG,EAAE,2CAA2C,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;QACjG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { execFileSync } from "node:child_process";
3
+ import { sq, dq } from "../remote.js";
4
+ /**
5
+ * The quoting that carries a command across two shells.
6
+ *
7
+ * `dockai claude <slug>` builds one string that ssh hands to `sh -c`, which
8
+ * hands part of it to tmux, which hands that to `sh -c` again. CLAUDE.md §7
9
+ * says these are "verified against `$VAR`, quotes, backticks, and directories
10
+ * containing spaces — change `sq`/`dq` only with an equivalent test". There
11
+ * was no test: `pnpm -r test:run` skipped this package entirely, because it
12
+ * had no `test:run`, so no failure was possible in the one part of the repo
13
+ * that ships to npm (audit 5 §8.2).
14
+ *
15
+ * These run a real `/bin/sh`. Asserting the escaped string looks right is
16
+ * asserting a guess about a shell; asking the shell is the contract.
17
+ */
18
+ const HOSTILE = [
19
+ "plain",
20
+ "with spaces",
21
+ "$HOME",
22
+ "${HOME}",
23
+ "`id`",
24
+ "$(id)",
25
+ 'double"quote',
26
+ "single'quote",
27
+ "back\\slash",
28
+ "semi;colon && echo pwned",
29
+ "new\nline",
30
+ "tab\there",
31
+ "a|b&c<d>e*f?g[h]i{j}k",
32
+ "emoji 🐸 and accents ñáü",
33
+ ];
34
+ /** What `sh -c <script>` prints on stdout, exactly. */
35
+ const shell = (script) => execFileSync("/bin/sh", ["-c", script], { encoding: "utf8" });
36
+ describe("sq — POSIX single-quote", () => {
37
+ it.each(HOSTILE)("survives one shell unchanged: %j", (value) => {
38
+ expect(shell(`printf %s ${sq(value)}`)).toBe(value);
39
+ });
40
+ it("is what makes a workspace path with a space work", () => {
41
+ // The real call site: `cd ${sq(workspace)} && exec …`
42
+ expect(shell(`cd ${sq("/tmp")} && printf %s "$PWD"`)).toBe("/tmp");
43
+ });
44
+ });
45
+ describe("dq — survives one round of double-quoted expansion", () => {
46
+ it.each(HOSTILE)("survives being inside double quotes: %j", (value) => {
47
+ expect(shell(`printf %s ${dq(value)}`)).toBe(value);
48
+ });
49
+ it("carries a whole command through the outer shell to the inner one", () => {
50
+ // The real call site: `tmux new-session … ${dq(claudeCmd)}`, where tmux
51
+ // runs the result through a shell of its own.
52
+ const inner = `printf %s ${sq("it survived $HOME `id`")}`;
53
+ expect(shell(`sh -c ${dq(inner)}`)).toBe("it survived $HOME `id`");
54
+ });
55
+ });
56
+ /**
57
+ * `--help` reaches Commander.
58
+ *
59
+ * `ensureSlug` runs before `program.parseAsync` and treated `--help` as a
60
+ * missing project: logged out, `dockai claude --help` answered *"Not logged
61
+ * in. Run `dockai login` first."* and exited 1; logged in, it opened an
62
+ * interactive picker. Five commands, including the flagship one and the four
63
+ * with the subtlest flag rules — among them the rule a person cannot guess,
64
+ * that flags *after* the project name go to `claude` untouched, documented in
65
+ * the help you could not print (audit 6 §3).
66
+ */
67
+ describe("ensureSlug", () => {
68
+ it("leaves --help alone instead of asking which project", async () => {
69
+ const { ensureSlug } = await import("../pick-project.js");
70
+ for (const argv of [
71
+ ["node", "dockai", "claude", "--help"],
72
+ ["node", "dockai", "claude", "-h"],
73
+ ["node", "dockai", "push", "--help"],
74
+ ]) {
75
+ // Returns untouched, and — the half that matters — never reaches the
76
+ // network, so this resolves with no server and no token.
77
+ await expect(ensureSlug([...argv], [argv[2]])).resolves.toEqual(argv);
78
+ }
79
+ });
80
+ });
81
+ //# sourceMappingURL=remote.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/remote.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAEtC;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,GAAG;IACd,OAAO;IACP,aAAa;IACb,OAAO;IACP,SAAS;IACT,MAAM;IACN,OAAO;IACP,cAAc;IACd,cAAc;IACd,aAAa;IACb,0BAA0B;IAC1B,WAAW;IACX,WAAW;IACX,uBAAuB;IACvB,0BAA0B;CAC3B,CAAC;AAEF,uDAAuD;AACvD,MAAM,KAAK,GAAG,CAAC,MAAc,EAAE,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;AAEhG,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,kCAAkC,EAAE,CAAC,KAAK,EAAE,EAAE;QAC7D,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,sDAAsD;QACtD,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oDAAoD,EAAE,GAAG,EAAE;IAClE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,yCAAyC,EAAE,CAAC,KAAK,EAAE,EAAE;QACpE,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,wEAAwE;QACxE,8CAA8C;QAC9C,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC,wBAAwB,CAAC,EAAE,CAAC;QAC1D,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAC1D,KAAK,MAAM,IAAI,IAAI;YACjB,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;YACtC,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC;YAClC,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACrC,EAAE,CAAC;YACF,qEAAqE;YACrE,yDAAyD;YACzD,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACxE,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}