@jamesaphoenix/tx-cli 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/cli-exit.d.ts +15 -0
  2. package/dist/cli-exit.d.ts.map +1 -0
  3. package/dist/cli-exit.js +18 -0
  4. package/dist/cli-exit.js.map +1 -0
  5. package/dist/cli.d.ts +8 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +349 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/commands/attempt.d.ts +9 -0
  10. package/dist/commands/attempt.d.ts.map +1 -0
  11. package/dist/commands/attempt.js +93 -0
  12. package/dist/commands/attempt.js.map +1 -0
  13. package/dist/commands/bulk.d.ts +8 -0
  14. package/dist/commands/bulk.d.ts.map +1 -0
  15. package/dist/commands/bulk.js +168 -0
  16. package/dist/commands/bulk.js.map +1 -0
  17. package/dist/commands/claim.d.ts +39 -0
  18. package/dist/commands/claim.d.ts.map +1 -0
  19. package/dist/commands/claim.js +96 -0
  20. package/dist/commands/claim.js.map +1 -0
  21. package/dist/commands/compact.d.ts +17 -0
  22. package/dist/commands/compact.d.ts.map +1 -0
  23. package/dist/commands/compact.js +167 -0
  24. package/dist/commands/compact.js.map +1 -0
  25. package/dist/commands/coordinator.d.ts +12 -0
  26. package/dist/commands/coordinator.d.ts.map +1 -0
  27. package/dist/commands/coordinator.js +124 -0
  28. package/dist/commands/coordinator.js.map +1 -0
  29. package/dist/commands/cycle.d.ts +12 -0
  30. package/dist/commands/cycle.d.ts.map +1 -0
  31. package/dist/commands/cycle.js +109 -0
  32. package/dist/commands/cycle.js.map +1 -0
  33. package/dist/commands/daemon.d.ts +16 -0
  34. package/dist/commands/daemon.d.ts.map +1 -0
  35. package/dist/commands/daemon.js +635 -0
  36. package/dist/commands/daemon.js.map +1 -0
  37. package/dist/commands/dashboard.d.ts +12 -0
  38. package/dist/commands/dashboard.d.ts.map +1 -0
  39. package/dist/commands/dashboard.js +105 -0
  40. package/dist/commands/dashboard.js.map +1 -0
  41. package/dist/commands/dashboard.test.d.ts +2 -0
  42. package/dist/commands/dashboard.test.d.ts.map +1 -0
  43. package/dist/commands/dashboard.test.js +99 -0
  44. package/dist/commands/dashboard.test.js.map +1 -0
  45. package/dist/commands/dep.d.ts +9 -0
  46. package/dist/commands/dep.d.ts.map +1 -0
  47. package/dist/commands/dep.js +50 -0
  48. package/dist/commands/dep.js.map +1 -0
  49. package/dist/commands/doc.d.ts +10 -0
  50. package/dist/commands/doc.d.ts.map +1 -0
  51. package/dist/commands/doc.js +397 -0
  52. package/dist/commands/doc.js.map +1 -0
  53. package/dist/commands/doctor.d.ts +9 -0
  54. package/dist/commands/doctor.d.ts.map +1 -0
  55. package/dist/commands/doctor.js +168 -0
  56. package/dist/commands/doctor.js.map +1 -0
  57. package/dist/commands/graph.d.ts +58 -0
  58. package/dist/commands/graph.d.ts.map +1 -0
  59. package/dist/commands/graph.js +441 -0
  60. package/dist/commands/graph.js.map +1 -0
  61. package/dist/commands/hierarchy.d.ts +9 -0
  62. package/dist/commands/hierarchy.d.ts.map +1 -0
  63. package/dist/commands/hierarchy.js +68 -0
  64. package/dist/commands/hierarchy.js.map +1 -0
  65. package/dist/commands/hooks.d.ts +56 -0
  66. package/dist/commands/hooks.d.ts.map +1 -0
  67. package/dist/commands/hooks.js +365 -0
  68. package/dist/commands/hooks.js.map +1 -0
  69. package/dist/commands/invariant.d.ts +9 -0
  70. package/dist/commands/invariant.d.ts.map +1 -0
  71. package/dist/commands/invariant.js +126 -0
  72. package/dist/commands/invariant.js.map +1 -0
  73. package/dist/commands/learning.d.ts +16 -0
  74. package/dist/commands/learning.d.ts.map +1 -0
  75. package/dist/commands/learning.js +362 -0
  76. package/dist/commands/learning.js.map +1 -0
  77. package/dist/commands/migrate.d.ts +9 -0
  78. package/dist/commands/migrate.d.ts.map +1 -0
  79. package/dist/commands/migrate.js +56 -0
  80. package/dist/commands/migrate.js.map +1 -0
  81. package/dist/commands/orchestrator.d.ts +11 -0
  82. package/dist/commands/orchestrator.d.ts.map +1 -0
  83. package/dist/commands/orchestrator.js +129 -0
  84. package/dist/commands/orchestrator.js.map +1 -0
  85. package/dist/commands/stats.d.ts +8 -0
  86. package/dist/commands/stats.d.ts.map +1 -0
  87. package/dist/commands/stats.js +128 -0
  88. package/dist/commands/stats.js.map +1 -0
  89. package/dist/commands/sync-platform.d.ts +12 -0
  90. package/dist/commands/sync-platform.d.ts.map +1 -0
  91. package/dist/commands/sync-platform.js +74 -0
  92. package/dist/commands/sync-platform.js.map +1 -0
  93. package/dist/commands/sync.d.ts +8 -0
  94. package/dist/commands/sync.d.ts.map +1 -0
  95. package/dist/commands/sync.js +128 -0
  96. package/dist/commands/sync.js.map +1 -0
  97. package/dist/commands/task.d.ts +15 -0
  98. package/dist/commands/task.d.ts.map +1 -0
  99. package/dist/commands/task.js +233 -0
  100. package/dist/commands/task.js.map +1 -0
  101. package/dist/commands/test.d.ts +16 -0
  102. package/dist/commands/test.d.ts.map +1 -0
  103. package/dist/commands/test.js +112 -0
  104. package/dist/commands/test.js.map +1 -0
  105. package/dist/commands/trace.d.ts +39 -0
  106. package/dist/commands/trace.d.ts.map +1 -0
  107. package/dist/commands/trace.js +620 -0
  108. package/dist/commands/trace.js.map +1 -0
  109. package/dist/commands/validate.d.ts +9 -0
  110. package/dist/commands/validate.d.ts.map +1 -0
  111. package/dist/commands/validate.js +94 -0
  112. package/dist/commands/validate.js.map +1 -0
  113. package/dist/commands/worker.d.ts +10 -0
  114. package/dist/commands/worker.d.ts.map +1 -0
  115. package/dist/commands/worker.js +204 -0
  116. package/dist/commands/worker.js.map +1 -0
  117. package/dist/help.d.ts +3 -0
  118. package/dist/help.d.ts.map +1 -0
  119. package/dist/help.js +1366 -0
  120. package/dist/help.js.map +1 -0
  121. package/dist/output.d.ts +12 -0
  122. package/dist/output.d.ts.map +1 -0
  123. package/dist/output.js +76 -0
  124. package/dist/output.js.map +1 -0
  125. package/dist/tx +0 -0
  126. package/dist/utils/parse.d.ts +45 -0
  127. package/dist/utils/parse.d.ts.map +1 -0
  128. package/dist/utils/parse.js +79 -0
  129. package/dist/utils/parse.js.map +1 -0
  130. package/dist/utils/parse.test.d.ts +2 -0
  131. package/dist/utils/parse.test.d.ts.map +1 -0
  132. package/dist/utils/parse.test.js +140 -0
  133. package/dist/utils/parse.test.js.map +1 -0
  134. package/dist/version.d.ts +2 -0
  135. package/dist/version.d.ts.map +1 -0
  136. package/dist/version.js +10 -0
  137. package/dist/version.js.map +1 -0
  138. package/package.json +58 -0
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Dashboard command: Start API server + Vite dev server and open in browser
3
+ *
4
+ * Usage:
5
+ * tx dashboard # Start and open in Brave/Chrome
6
+ * tx dashboard --no-open # Start without opening browser
7
+ * tx dashboard --port 3002 # Custom API port
8
+ */
9
+ import { Effect } from "effect";
10
+ import { type Flags } from "../utils/parse.js";
11
+ export declare const dashboard: (_pos: string[], flags: Flags) => Effect.Effect<void, never, never>;
12
+ //# sourceMappingURL=dashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/commands/dashboard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAI/B,OAAO,EAAE,KAAK,KAAK,EAAa,MAAM,mBAAmB,CAAA;AAyCzD,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,EAAE,OAAO,KAAK,sCAiElD,CAAA"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Dashboard command: Start API server + Vite dev server and open in browser
3
+ *
4
+ * Usage:
5
+ * tx dashboard # Start and open in Brave/Chrome
6
+ * tx dashboard --no-open # Start without opening browser
7
+ * tx dashboard --port 3002 # Custom API port
8
+ */
9
+ import { Effect } from "effect";
10
+ import { spawn, execSync } from "node:child_process";
11
+ import { resolve, dirname } from "node:path";
12
+ import { fileURLToPath } from "node:url";
13
+ import { flag, opt } from "../utils/parse.js";
14
+ const __dirname = dirname(fileURLToPath(import.meta.url));
15
+ const PROJECT_ROOT = resolve(__dirname, "../../../..");
16
+ const API_SERVER_ENTRY = resolve(PROJECT_ROOT, "apps/dashboard/server/index.ts");
17
+ const DASHBOARD_DIR = resolve(PROJECT_ROOT, "apps/dashboard");
18
+ function killPort(port) {
19
+ try {
20
+ const pid = execSync(`lsof -ti :${port} 2>/dev/null`, { encoding: "utf-8" }).trim();
21
+ if (pid) {
22
+ console.log(`Killing existing process on port ${port} (PID ${pid})`);
23
+ execSync(`kill ${pid} 2>/dev/null`);
24
+ }
25
+ }
26
+ catch {
27
+ // No process on port — that's fine
28
+ }
29
+ }
30
+ function openBrowser(url) {
31
+ try {
32
+ execSync(`open -a "Brave Browser" "${url}" 2>/dev/null`);
33
+ console.log("Opened in Brave Browser");
34
+ return;
35
+ }
36
+ catch { /* Brave not available */ }
37
+ try {
38
+ execSync(`open -a "Google Chrome" "${url}" 2>/dev/null`);
39
+ console.log("Opened in Google Chrome");
40
+ return;
41
+ }
42
+ catch { /* Chrome not available */ }
43
+ try {
44
+ execSync(`open "${url}" 2>/dev/null`);
45
+ console.log("Opened in default browser");
46
+ }
47
+ catch {
48
+ console.log(`Open ${url} in your browser`);
49
+ }
50
+ }
51
+ export const dashboard = (_pos, flags) => Effect.sync(() => {
52
+ const apiPort = Number(opt(flags, "port")) || 3001;
53
+ const vitePort = 5173;
54
+ const noOpen = flag(flags, "no-open");
55
+ console.log("Starting tx dashboard...");
56
+ // Kill existing processes on our ports
57
+ killPort(apiPort);
58
+ killPort(vitePort);
59
+ const runtime = process.argv[0];
60
+ // Start API server
61
+ console.log(`Starting API server on port ${apiPort}...`);
62
+ const apiProc = spawn(runtime, [API_SERVER_ENTRY], {
63
+ stdio: "pipe",
64
+ env: { ...process.env, PORT: String(apiPort) },
65
+ detached: false,
66
+ });
67
+ // Start Vite dev server
68
+ console.log(`Starting Vite dev server on port ${vitePort}...`);
69
+ const viteProc = spawn(runtime, ["run", "dev"], {
70
+ cwd: DASHBOARD_DIR,
71
+ stdio: "pipe",
72
+ detached: false,
73
+ });
74
+ const children = [apiProc, viteProc];
75
+ // Forward output
76
+ apiProc.stdout?.on("data", (d) => process.stdout.write(`[api] ${d}`));
77
+ apiProc.stderr?.on("data", (d) => process.stderr.write(`[api] ${d}`));
78
+ viteProc.stdout?.on("data", (d) => process.stdout.write(`[vite] ${d}`));
79
+ viteProc.stderr?.on("data", (d) => process.stderr.write(`[vite] ${d}`));
80
+ // Handle child exits
81
+ for (const child of children) {
82
+ child.on("error", (err) => console.error(`Process error: ${err.message}`));
83
+ }
84
+ // Cleanup on exit
85
+ const cleanup = () => {
86
+ console.log("\nShutting down dashboard...");
87
+ for (const child of children) {
88
+ child.kill();
89
+ }
90
+ };
91
+ process.on("SIGINT", () => { cleanup(); process.exit(0); });
92
+ process.on("SIGTERM", () => { cleanup(); process.exit(0); });
93
+ // Wait for servers then open browser
94
+ setTimeout(() => {
95
+ if (!noOpen) {
96
+ openBrowser(`http://localhost:${vitePort}`);
97
+ }
98
+ console.log("");
99
+ console.log(` API: http://localhost:${apiPort}`);
100
+ console.log(` Dashboard: http://localhost:${vitePort}`);
101
+ console.log("");
102
+ console.log("Press Ctrl+C to stop.");
103
+ }, 3000);
104
+ });
105
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/commands/dashboard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAc,IAAI,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AAEzD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AACzD,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;AAEtD,MAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY,EAAE,gCAAgC,CAAC,CAAA;AAChF,MAAM,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAA;AAE7D,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,IAAI,cAAc,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QACnF,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,CAAC,GAAG,CAAC,oCAAoC,IAAI,SAAS,GAAG,GAAG,CAAC,CAAA;YACpE,QAAQ,CAAC,QAAQ,GAAG,cAAc,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;IACrC,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,CAAC;QACH,QAAQ,CAAC,4BAA4B,GAAG,eAAe,CAAC,CAAA;QACxD,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;QACtC,OAAM;IACR,CAAC;IAAC,MAAM,CAAC,CAAC,yBAAyB,CAAC,CAAC;IAErC,IAAI,CAAC;QACH,QAAQ,CAAC,4BAA4B,GAAG,eAAe,CAAC,CAAA;QACxD,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;QACtC,OAAM;IACR,CAAC;IAAC,MAAM,CAAC,CAAC,0BAA0B,CAAC,CAAC;IAEtC,IAAI,CAAC;QACH,QAAQ,CAAC,SAAS,GAAG,eAAe,CAAC,CAAA;QACrC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAA;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,kBAAkB,CAAC,CAAA;IAC5C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAc,EAAE,KAAY,EAAE,EAAE,CACxD,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;IACf,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI,CAAA;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAA;IACrB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IAErC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAA;IAEvC,uCAAuC;IACvC,QAAQ,CAAC,OAAO,CAAC,CAAA;IACjB,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAElB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAE/B,mBAAmB;IACnB,OAAO,CAAC,GAAG,CAAC,+BAA+B,OAAO,KAAK,CAAC,CAAA;IACxD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,gBAAgB,CAAC,EAAE;QACjD,KAAK,EAAE,MAAM;QACb,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE;QAC9C,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAA;IAEF,wBAAwB;IACxB,OAAO,CAAC,GAAG,CAAC,oCAAoC,QAAQ,KAAK,CAAC,CAAA;IAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE;QAC9C,GAAG,EAAE,aAAa;QAClB,KAAK,EAAE,MAAM;QACb,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IAEpC,iBAAiB;IACjB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAA;IAC7E,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAA;IAC7E,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAA;IAC/E,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAA;IAE/E,qBAAqB;IACrB,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED,kBAAkB;IAClB,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;QAC3C,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,EAAE,CAAA;QACd,CAAC;IACH,CAAC,CAAA;IAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;IAC1D,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;IAE3D,qCAAqC;IACrC,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,WAAW,CAAC,oBAAoB,QAAQ,EAAE,CAAC,CAAA;QAC7C,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,OAAO,CAAC,GAAG,CAAC,iCAAiC,OAAO,EAAE,CAAC,CAAA;QACvD,OAAO,CAAC,GAAG,CAAC,iCAAiC,QAAQ,EAAE,CAAC,CAAA;QACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;IACtC,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dashboard.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.test.d.ts","sourceRoot":"","sources":["../../src/commands/dashboard.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Dashboard command tests
3
+ *
4
+ * Tests for `tx dashboard` — starts API server + Vite dev server.
5
+ */
6
+ import { describe, it, expect, afterEach } from "vitest";
7
+ import { spawn, spawnSync } from "node:child_process";
8
+ import { resolve } from "node:path";
9
+ const CLI_SRC = resolve(__dirname, "../cli.ts");
10
+ describe("tx dashboard", () => {
11
+ let proc = null;
12
+ afterEach(() => {
13
+ if (proc && !proc.killed) {
14
+ proc.kill("SIGTERM");
15
+ proc = null;
16
+ }
17
+ });
18
+ it("is registered as a CLI command", () => {
19
+ const result = spawnSync("bun", [CLI_SRC, "help"], {
20
+ encoding: "utf-8",
21
+ timeout: 10000,
22
+ });
23
+ expect(result.stdout).toContain("dashboard");
24
+ });
25
+ it("shows help text with --help flag", () => {
26
+ const result = spawnSync("bun", [CLI_SRC, "dashboard", "--help"], {
27
+ encoding: "utf-8",
28
+ timeout: 10000,
29
+ });
30
+ expect(result.stdout).toContain("tx dashboard");
31
+ expect(result.stdout).toContain("--no-open");
32
+ expect(result.stdout).toContain("--port");
33
+ });
34
+ it("starts servers that respond on expected ports", async () => {
35
+ proc = spawn("bun", [CLI_SRC, "dashboard", "--no-open"], {
36
+ stdio: "pipe",
37
+ });
38
+ // Wait for servers to start (up to 10 seconds)
39
+ let apiReady = false;
40
+ let viteReady = false;
41
+ for (let i = 0; i < 20; i++) {
42
+ await new Promise((r) => setTimeout(r, 500));
43
+ if (!apiReady) {
44
+ try {
45
+ const res = await fetch("http://localhost:3001/api/stats");
46
+ if (res.ok)
47
+ apiReady = true;
48
+ }
49
+ catch {
50
+ // not ready yet
51
+ }
52
+ }
53
+ if (!viteReady) {
54
+ try {
55
+ const res = await fetch("http://localhost:5173");
56
+ if (res.ok)
57
+ viteReady = true;
58
+ }
59
+ catch {
60
+ // not ready yet
61
+ }
62
+ }
63
+ if (apiReady && viteReady)
64
+ break;
65
+ }
66
+ expect(apiReady).toBe(true);
67
+ expect(viteReady).toBe(true);
68
+ }, 15000);
69
+ it("cleans up child processes on SIGTERM", async () => {
70
+ proc = spawn("bun", [CLI_SRC, "dashboard", "--no-open"], {
71
+ stdio: "pipe",
72
+ });
73
+ // Wait for servers to start
74
+ await new Promise((r) => setTimeout(r, 4000));
75
+ // Send SIGTERM
76
+ proc.kill("SIGTERM");
77
+ // Wait for cleanup
78
+ await new Promise((r) => setTimeout(r, 2000));
79
+ // Ports should be freed
80
+ let apiFreed = false;
81
+ let viteFreed = false;
82
+ try {
83
+ await fetch("http://localhost:3001/api/stats");
84
+ }
85
+ catch {
86
+ apiFreed = true;
87
+ }
88
+ try {
89
+ await fetch("http://localhost:5173");
90
+ }
91
+ catch {
92
+ viteFreed = true;
93
+ }
94
+ expect(apiFreed).toBe(true);
95
+ expect(viteFreed).toBe(true);
96
+ proc = null; // already killed
97
+ }, 15000);
98
+ });
99
+ //# sourceMappingURL=dashboard.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.test.js","sourceRoot":"","sources":["../../src/commands/dashboard.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Dependency commands: block, unblock
3
+ */
4
+ import { Effect } from "effect";
5
+ import { TaskService, DependencyService } from "@jamesaphoenix/tx-core";
6
+ import { type Flags } from "../utils/parse.js";
7
+ export declare const block: (pos: string[], flags: Flags) => Effect.Effect<void, import("@jamesaphoenix/tx-core").ValidationError | import("@jamesaphoenix/tx-core").DatabaseError | import("@jamesaphoenix/tx-core").TaskNotFoundError | import("@jamesaphoenix/tx-core").CircularDependencyError, TaskService | DependencyService>;
8
+ export declare const unblock: (pos: string[], flags: Flags) => Effect.Effect<void, import("@jamesaphoenix/tx-core").DatabaseError | import("@jamesaphoenix/tx-core").TaskNotFoundError | import("@jamesaphoenix/tx-core").DependencyNotFoundError, TaskService | DependencyService>;
9
+ //# sourceMappingURL=dep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dep.d.ts","sourceRoot":"","sources":["../../src/commands/dep.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAEvE,OAAO,EAAE,KAAK,KAAK,EAAqB,MAAM,mBAAmB,CAAA;AAEjE,eAAO,MAAM,KAAK,GAAI,KAAK,MAAM,EAAE,EAAE,OAAO,KAAK,4QAuB7C,CAAA;AAEJ,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,EAAE,EAAE,OAAO,KAAK,yNAuB/C,CAAA"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Dependency commands: block, unblock
3
+ */
4
+ import { Effect } from "effect";
5
+ import { TaskService, DependencyService } from "@jamesaphoenix/tx-core";
6
+ import { toJson } from "../output.js";
7
+ import { flag, parseTaskId } from "../utils/parse.js";
8
+ export const block = (pos, flags) => Effect.gen(function* () {
9
+ const rawId = pos[0];
10
+ const rawBlocker = pos[1];
11
+ if (!rawId || !rawBlocker) {
12
+ console.error("Usage: tx block <task-id> <blocker-id> [--json]");
13
+ process.exit(1);
14
+ }
15
+ const id = parseTaskId(rawId);
16
+ const blocker = parseTaskId(rawBlocker);
17
+ const depSvc = yield* DependencyService;
18
+ const taskSvc = yield* TaskService;
19
+ yield* depSvc.addBlocker(id, blocker);
20
+ const task = yield* taskSvc.getWithDeps(id);
21
+ if (flag(flags, "json")) {
22
+ console.log(toJson({ success: true, task }));
23
+ }
24
+ else {
25
+ console.log(`${blocker} now blocks ${id}`);
26
+ console.log(` ${id} blocked by: ${task.blockedBy.join(", ")}`);
27
+ }
28
+ });
29
+ export const unblock = (pos, flags) => Effect.gen(function* () {
30
+ const rawId = pos[0];
31
+ const rawBlocker = pos[1];
32
+ if (!rawId || !rawBlocker) {
33
+ console.error("Usage: tx unblock <task-id> <blocker-id> [--json]");
34
+ process.exit(1);
35
+ }
36
+ const id = parseTaskId(rawId);
37
+ const blocker = parseTaskId(rawBlocker);
38
+ const depSvc = yield* DependencyService;
39
+ const taskSvc = yield* TaskService;
40
+ yield* depSvc.removeBlocker(id, blocker);
41
+ const task = yield* taskSvc.getWithDeps(id);
42
+ if (flag(flags, "json")) {
43
+ console.log(toJson({ success: true, task }));
44
+ }
45
+ else {
46
+ console.log(`${blocker} no longer blocks ${id}`);
47
+ console.log(` ${id} blocked by: ${task.blockedBy.length > 0 ? task.blockedBy.join(", ") : "(none)"}`);
48
+ }
49
+ });
50
+ //# sourceMappingURL=dep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dep.js","sourceRoot":"","sources":["../../src/commands/dep.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Doc commands: doc add, doc edit, doc show, doc list, doc render, doc lock,
3
+ * doc version, doc link, doc attach, doc patch, doc validate, doc drift
4
+ */
5
+ import { Effect } from "effect";
6
+ import { DocService } from "@jamesaphoenix/tx-core";
7
+ import { type Flags } from "../utils/parse.js";
8
+ /** Dispatch doc subcommands. */
9
+ export declare const doc: (pos: string[], flags: Flags) => Effect.Effect<void, import("@jamesaphoenix/tx-core").ValidationError | import("@jamesaphoenix/tx-core").DatabaseError | import("@jamesaphoenix/tx-core").InvalidDocYamlError | import("@jamesaphoenix/tx-core").DocNotFoundError, DocService>;
10
+ //# sourceMappingURL=doc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc.d.ts","sourceRoot":"","sources":["../../src/commands/doc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAG/B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAInD,OAAO,EAAE,KAAK,KAAK,EAAa,MAAM,mBAAmB,CAAA;AAIzD,gCAAgC;AAChC,eAAO,MAAM,GAAG,GAAI,KAAK,MAAM,EAAE,EAAE,OAAO,KAAK,kPAwB9C,CAAA"}