t3code-cli 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/README.md +42 -10
  2. package/dist/application.js +2 -2
  3. package/dist/auth.js +1 -1
  4. package/dist/bin.js +85526 -2662
  5. package/dist/cli.js +15 -2
  6. package/dist/config.js +120 -2
  7. package/dist/connection.js +2 -2
  8. package/dist/index.js +1 -1
  9. package/dist/node.js +6 -2
  10. package/dist/orchestration.js +2 -2
  11. package/dist/rpc.js +1 -1
  12. package/dist/runtime.js +2 -2
  13. package/dist/shared.js +42956 -38119
  14. package/dist/src/application/actions.d.ts +25 -0
  15. package/dist/src/application/index.d.ts +3 -3
  16. package/dist/src/application/layer.d.ts +51 -35
  17. package/dist/src/application/model-selection.d.ts +2 -2
  18. package/dist/src/application/models.d.ts +1 -1
  19. package/dist/src/application/project-commands.d.ts +22 -2
  20. package/dist/src/application/projects.d.ts +7 -7
  21. package/dist/src/application/service.d.ts +65 -2
  22. package/dist/src/application/shell-sequence.d.ts +11 -0
  23. package/dist/src/application/terminals.d.ts +2 -2
  24. package/dist/src/application/thread-commands.d.ts +1 -1
  25. package/dist/src/application/thread-wait.d.ts +9 -0
  26. package/dist/src/application/threads.d.ts +56 -5
  27. package/dist/src/auth/error.d.ts +2 -1
  28. package/dist/src/auth/index.d.ts +1 -1
  29. package/dist/src/auth/layer.d.ts +34 -6
  30. package/dist/src/auth/local-base-dir.d.ts +5 -2
  31. package/dist/src/auth/local-origin.d.ts +3 -3
  32. package/dist/src/auth/local-token.d.ts +3 -3
  33. package/dist/src/auth/service.d.ts +15 -3
  34. package/dist/src/auth/type.d.ts +40 -1
  35. package/dist/src/cli/env/flag.d.ts +2 -0
  36. package/dist/src/cli/env/index.d.ts +2 -0
  37. package/dist/src/cli/env/selection-layer.d.ts +3 -0
  38. package/dist/src/cli/flags.d.ts +2 -0
  39. package/dist/src/cli/format/index.d.ts +1 -0
  40. package/dist/src/cli/format/output.d.ts +12 -0
  41. package/dist/src/cli/index.d.ts +4 -0
  42. package/dist/src/cli/runtime/index.d.ts +1 -0
  43. package/dist/src/cli/runtime/service.d.ts +16 -0
  44. package/dist/src/{scope → cli/scope}/resolve.d.ts +5 -4
  45. package/dist/src/config/config.d.ts +49 -0
  46. package/dist/src/config/credential/cipher-node.d.ts +3 -0
  47. package/dist/src/config/credential/cipher-web.d.ts +3 -0
  48. package/dist/src/config/credential/cipher.d.ts +29 -0
  49. package/dist/src/config/credential/env.d.ts +3 -0
  50. package/dist/src/config/credential/error.d.ts +8 -0
  51. package/dist/src/config/credential/index.d.ts +6 -0
  52. package/dist/src/config/credential/service.d.ts +34 -0
  53. package/dist/src/config/env/env.d.ts +55 -0
  54. package/dist/src/config/env/index.d.ts +2 -0
  55. package/dist/src/{layout/base-dir.d.ts → config/env/layout.d.ts} +0 -1
  56. package/dist/src/config/environment-name/index.d.ts +1 -0
  57. package/dist/src/config/environment-name/name.d.ts +10 -0
  58. package/dist/src/config/error.d.ts +4 -11
  59. package/dist/src/config/index.d.ts +10 -5
  60. package/dist/src/config/keystore/error.d.ts +8 -0
  61. package/dist/src/config/keystore/file.d.ts +9 -0
  62. package/dist/src/config/keystore/index.d.ts +4 -0
  63. package/dist/src/config/keystore/keyring-node.d.ts +4 -0
  64. package/dist/src/config/keystore/service.d.ts +33 -0
  65. package/dist/src/config/paths/index.d.ts +1 -0
  66. package/dist/src/config/paths/paths.d.ts +6 -0
  67. package/dist/src/config/persist/file-mode.d.ts +4 -0
  68. package/dist/src/config/persist/migration.d.ts +68 -0
  69. package/dist/src/config/persist/persist.d.ts +40 -0
  70. package/dist/src/config/persist/schema.d.ts +68 -0
  71. package/dist/src/config/resolve/resolve.d.ts +40 -0
  72. package/dist/src/config/selection/index.d.ts +1 -0
  73. package/dist/src/config/selection/resolve.d.ts +4 -0
  74. package/dist/src/config/selection/service.d.ts +10 -0
  75. package/dist/src/config/types.d.ts +36 -0
  76. package/dist/src/config/url/error.d.ts +10 -0
  77. package/dist/src/config/url/index.d.ts +2 -0
  78. package/dist/src/connection/index.d.ts +0 -1
  79. package/dist/src/contracts/index.d.ts +1 -1
  80. package/dist/src/domain/error.d.ts +14 -1
  81. package/dist/src/domain/helpers.d.ts +16 -1
  82. package/dist/src/domain/model-config.d.ts +4 -1
  83. package/dist/src/domain/thread-activities.d.ts +1 -1
  84. package/dist/src/domain/thread-lifecycle.d.ts +10 -1
  85. package/dist/src/index.d.ts +1 -2
  86. package/dist/src/{connection/node.d.ts → node/connection.d.ts} +1 -1
  87. package/dist/src/node/index.d.ts +1 -2
  88. package/dist/src/orchestration/index.d.ts +0 -1
  89. package/dist/src/orchestration/layer.d.ts +153 -7
  90. package/dist/src/orchestration/service.d.ts +1 -1
  91. package/dist/src/rpc/error.d.ts +2 -2
  92. package/dist/src/rpc/index.d.ts +2 -3
  93. package/dist/src/rpc/layer.d.ts +574 -46
  94. package/dist/src/rpc/operation.d.ts +574 -46
  95. package/dist/src/rpc/ws-group.d.ts +184 -19
  96. package/dist/src/runtime/index.d.ts +1 -2
  97. package/dist/src/runtime/layer.d.ts +12 -8
  98. package/dist/src/t3tools/index.d.ts +1 -1
  99. package/dist/t3tools.js +2 -2
  100. package/package.json +25 -21
  101. package/src/application/actions.test.ts +328 -0
  102. package/src/application/actions.ts +475 -0
  103. package/src/application/index.ts +9 -5
  104. package/src/application/layer.ts +9 -0
  105. package/src/application/model-selection.ts +2 -2
  106. package/src/application/project-commands.ts +23 -5
  107. package/src/application/projects.ts +6 -7
  108. package/src/application/service.ts +79 -1
  109. package/src/application/shell-sequence.ts +1 -1
  110. package/src/application/terminals.ts +2 -1
  111. package/src/application/thread-commands.ts +1 -1
  112. package/src/application/thread-update.ts +1 -1
  113. package/src/application/thread-wait.ts +1 -1
  114. package/src/application/threads.test.ts +9 -3
  115. package/src/application/threads.ts +6 -6
  116. package/src/auth/error.ts +2 -1
  117. package/src/auth/index.ts +7 -0
  118. package/src/auth/layer.test-utils.ts +34 -0
  119. package/src/auth/layer.ts +116 -34
  120. package/src/auth/local-base-dir.ts +13 -6
  121. package/src/auth/local-origin.ts +10 -7
  122. package/src/auth/local-token.ts +28 -23
  123. package/src/auth/service.test.ts +200 -0
  124. package/src/auth/service.ts +27 -3
  125. package/src/auth/transport.ts +2 -2
  126. package/src/auth/type.ts +47 -1
  127. package/src/bin.ts +24 -6
  128. package/src/cli/action-format.ts +110 -0
  129. package/src/cli/action.ts +398 -0
  130. package/src/cli/app.ts +6 -0
  131. package/src/cli/auth.ts +76 -23
  132. package/src/cli/env/flag.ts +8 -0
  133. package/src/cli/env/index.ts +2 -0
  134. package/src/cli/env/selection-layer.test.ts +49 -0
  135. package/src/cli/env/selection-layer.ts +27 -0
  136. package/src/cli/env.ts +107 -0
  137. package/src/cli/extra-args.test.ts +32 -0
  138. package/src/cli/extra-args.ts +22 -0
  139. package/src/cli/flags.ts +11 -1
  140. package/src/cli/format/auth.ts +92 -0
  141. package/src/cli/format/human.ts +131 -0
  142. package/src/cli/format/index.ts +12 -0
  143. package/src/cli/format/model.ts +29 -0
  144. package/src/cli/format/output.ts +51 -0
  145. package/src/cli/format/project.ts +32 -0
  146. package/src/cli/format/terminal.ts +87 -0
  147. package/src/cli/{thread-format.test.ts → format/thread.test.ts} +6 -4
  148. package/src/cli/format/thread.ts +185 -0
  149. package/src/cli/index.ts +20 -0
  150. package/src/cli/interaction/confirm.ts +64 -0
  151. package/src/cli/{self-action.ts → interaction/self-action.ts} +8 -6
  152. package/src/cli/message-input.ts +1 -1
  153. package/src/cli/model.ts +9 -5
  154. package/src/cli/project.ts +13 -7
  155. package/src/cli/projects/delete.ts +13 -12
  156. package/src/cli/require.ts +9 -7
  157. package/src/cli/runtime/index.ts +1 -0
  158. package/src/cli/runtime/service.ts +28 -0
  159. package/src/{scope → cli/scope}/resolve.ts +11 -9
  160. package/src/cli/terminal/attach.ts +3 -6
  161. package/src/cli/terminal/create.ts +10 -9
  162. package/src/cli/terminal/destroy.ts +13 -11
  163. package/src/cli/terminal/list.ts +10 -9
  164. package/src/cli/terminal/read.test-utils.ts +48 -0
  165. package/src/cli/terminal/read.test.ts +35 -0
  166. package/src/cli/terminal/read.ts +3 -6
  167. package/src/cli/terminal/scope.ts +10 -5
  168. package/src/cli/terminal/shared.ts +1 -1
  169. package/src/cli/terminal/stream.ts +3 -6
  170. package/src/cli/terminal/wait.test.ts +5 -3
  171. package/src/cli/terminal/wait.ts +10 -9
  172. package/src/cli/terminal/write.test.ts +34 -0
  173. package/src/cli/terminal/write.ts +10 -9
  174. package/src/cli/threads/approve.ts +11 -7
  175. package/src/cli/threads/archive.ts +14 -9
  176. package/src/cli/threads/callback.ts +6 -4
  177. package/src/cli/threads/delete.ts +17 -11
  178. package/src/cli/threads/interrupt.ts +14 -9
  179. package/src/cli/threads/list.test.ts +5 -3
  180. package/src/cli/threads/list.ts +10 -10
  181. package/src/cli/threads/messages.ts +11 -7
  182. package/src/cli/threads/respond.ts +11 -7
  183. package/src/cli/threads/send.ts +19 -9
  184. package/src/cli/threads/show.ts +11 -7
  185. package/src/cli/threads/start.ts +18 -13
  186. package/src/cli/threads/unarchive.ts +11 -7
  187. package/src/cli/threads/update.ts +14 -9
  188. package/src/cli/threads/wait.ts +11 -7
  189. package/src/cli/wait-events.ts +1 -1
  190. package/src/config/config.ts +260 -0
  191. package/src/config/credential/cipher-node.ts +40 -0
  192. package/src/config/credential/cipher-web.ts +82 -0
  193. package/src/config/credential/cipher.ts +39 -0
  194. package/src/config/credential/env.ts +13 -0
  195. package/src/config/credential/error.ts +9 -0
  196. package/src/config/credential/index.ts +6 -0
  197. package/src/config/credential/service.test-utils.ts +25 -0
  198. package/src/config/credential/service.test.ts +116 -0
  199. package/src/config/credential/service.ts +205 -0
  200. package/src/config/env/env.test-utils.ts +14 -0
  201. package/src/config/env/env.ts +81 -0
  202. package/src/config/env/index.ts +2 -0
  203. package/src/{layout/base-dir.ts → config/env/layout.ts} +0 -9
  204. package/src/config/environment-name/index.ts +7 -0
  205. package/src/config/environment-name/name.test.ts +66 -0
  206. package/src/config/environment-name/name.ts +49 -0
  207. package/src/config/error.ts +6 -8
  208. package/src/config/index.ts +16 -5
  209. package/src/config/keystore/error.ts +9 -0
  210. package/src/config/keystore/file.ts +96 -0
  211. package/src/config/keystore/index.ts +4 -0
  212. package/src/config/keystore/keyring-node.test.ts +12 -0
  213. package/src/config/keystore/keyring-node.ts +100 -0
  214. package/src/config/keystore/service.test-utils.ts +15 -0
  215. package/src/config/keystore/service.test.ts +18 -0
  216. package/src/config/keystore/service.ts +29 -0
  217. package/src/config/layer.test-utils.ts +45 -0
  218. package/src/config/layer.test.ts +209 -0
  219. package/src/config/paths/index.ts +1 -0
  220. package/src/config/paths/paths.ts +36 -0
  221. package/src/config/persist/file-mode.ts +21 -0
  222. package/src/config/persist/migration.test.ts +71 -0
  223. package/src/config/persist/migration.ts +82 -0
  224. package/src/config/persist/persist.test.ts +113 -0
  225. package/src/config/persist/persist.ts +65 -0
  226. package/src/config/persist/schema.ts +37 -0
  227. package/src/config/platform.test-utils.ts +20 -0
  228. package/src/config/resolve/resolve.test-utils.ts +20 -0
  229. package/src/config/resolve/resolve.test.ts +137 -0
  230. package/src/config/resolve/resolve.ts +104 -0
  231. package/src/config/selection/index.ts +1 -0
  232. package/src/config/selection/resolve.ts +14 -0
  233. package/src/config/selection/service.ts +29 -0
  234. package/src/config/temp-home.test-utils.ts +7 -0
  235. package/src/config/types.ts +49 -0
  236. package/src/config/url/error.ts +8 -0
  237. package/src/config/url/index.ts +7 -0
  238. package/src/config/url/url.test.ts +31 -0
  239. package/src/connection/index.ts +0 -1
  240. package/src/contracts/index.ts +1 -1
  241. package/src/domain/error.ts +20 -1
  242. package/src/domain/helpers.test.ts +1 -1
  243. package/src/domain/helpers.ts +1 -1
  244. package/src/domain/model-config.ts +1 -1
  245. package/src/domain/thread-activities.test.ts +1 -1
  246. package/src/domain/thread-activities.ts +1 -1
  247. package/src/domain/thread-lifecycle.test.ts +1 -1
  248. package/src/domain/thread-lifecycle.ts +1 -1
  249. package/src/effect.test-utils.ts +25 -0
  250. package/src/index.ts +1 -1
  251. package/src/{connection/node.ts → node/connection.ts} +1 -1
  252. package/src/node/index.ts +1 -2
  253. package/src/orchestration/index.ts +0 -1
  254. package/src/orchestration/layer.ts +1 -1
  255. package/src/orchestration/service.ts +1 -1
  256. package/src/rpc/error.ts +2 -2
  257. package/src/rpc/index.ts +2 -3
  258. package/src/rpc/layer.ts +1 -1
  259. package/src/rpc/ws-group.ts +1 -1
  260. package/src/runtime/index.ts +2 -1
  261. package/src/runtime/layer.test-utils.ts +32 -0
  262. package/src/runtime/layer.test.ts +66 -0
  263. package/src/runtime/layer.ts +15 -9
  264. package/src/t3tools/index.ts +1 -1
  265. package/src/types/marked-terminal.d.ts +11 -0
  266. package/dist/layout.js +0 -2
  267. package/dist/scope.js +0 -2
  268. package/dist/src/cli/output-format.d.ts +0 -11
  269. package/dist/src/config/layer.d.ts +0 -22
  270. package/dist/src/config/service.d.ts +0 -22
  271. package/dist/src/environment/layer.d.ts +0 -3
  272. package/dist/src/environment/service.d.ts +0 -12
  273. package/dist/src/layout/index.d.ts +0 -1
  274. package/dist/upstream-t3code/packages/contracts/src/auth.d.ts +0 -441
  275. package/dist/upstream-t3code/packages/contracts/src/baseSchemas.d.ts +0 -38
  276. package/dist/upstream-t3code/packages/contracts/src/desktopBootstrap.d.ts +0 -14
  277. package/dist/upstream-t3code/packages/contracts/src/editor.d.ts +0 -124
  278. package/dist/upstream-t3code/packages/contracts/src/environment.d.ts +0 -64
  279. package/dist/upstream-t3code/packages/contracts/src/environmentHttp.d.ts +0 -762
  280. package/dist/upstream-t3code/packages/contracts/src/filesystem.d.ts +0 -26
  281. package/dist/upstream-t3code/packages/contracts/src/git.d.ts +0 -500
  282. package/dist/upstream-t3code/packages/contracts/src/index.d.ts +0 -25
  283. package/dist/upstream-t3code/packages/contracts/src/ipc.d.ts +0 -490
  284. package/dist/upstream-t3code/packages/contracts/src/keybindings.d.ts +0 -133
  285. package/dist/upstream-t3code/packages/contracts/src/model.d.ts +0 -112
  286. package/dist/upstream-t3code/packages/contracts/src/orchestration.d.ts +0 -6682
  287. package/dist/upstream-t3code/packages/contracts/src/project.d.ts +0 -45
  288. package/dist/upstream-t3code/packages/contracts/src/provider.d.ts +0 -116
  289. package/dist/upstream-t3code/packages/contracts/src/providerInstance.d.ts +0 -99
  290. package/dist/upstream-t3code/packages/contracts/src/providerRuntime.d.ts +0 -4276
  291. package/dist/upstream-t3code/packages/contracts/src/relay.d.ts +0 -1262
  292. package/dist/upstream-t3code/packages/contracts/src/relayClient.d.ts +0 -48
  293. package/dist/upstream-t3code/packages/contracts/src/remoteAccess.d.ts +0 -45
  294. package/dist/upstream-t3code/packages/contracts/src/review.d.ts +0 -37
  295. package/dist/upstream-t3code/packages/contracts/src/rpc.d.ts +0 -8218
  296. package/dist/upstream-t3code/packages/contracts/src/server.d.ts +0 -2291
  297. package/dist/upstream-t3code/packages/contracts/src/settings.d.ts +0 -271
  298. package/dist/upstream-t3code/packages/contracts/src/sourceControl.d.ts +0 -177
  299. package/dist/upstream-t3code/packages/contracts/src/terminal.d.ts +0 -330
  300. package/dist/upstream-t3code/packages/contracts/src/vcs.d.ts +0 -148
  301. package/src/cli/auth-format.ts +0 -45
  302. package/src/cli/confirm.ts +0 -31
  303. package/src/cli/model-format.ts +0 -18
  304. package/src/cli/output-format.ts +0 -45
  305. package/src/cli/project-format.ts +0 -18
  306. package/src/cli/terminal/commands.test.ts +0 -101
  307. package/src/cli/terminal-format.ts +0 -167
  308. package/src/cli/thread-format.ts +0 -128
  309. package/src/config/layer.ts +0 -105
  310. package/src/config/service.ts +0 -26
  311. package/src/environment/layer.ts +0 -12
  312. package/src/environment/service.ts +0 -13
  313. package/src/layout/index.ts +0 -1
  314. /package/dist/src/{scope → cli/scope}/index.d.ts +0 -0
  315. /package/dist/src/config/{url.d.ts → url/url.d.ts} +0 -0
  316. /package/src/{scope → cli/scope}/index.ts +0 -0
  317. /package/src/config/{url.ts → url/url.ts} +0 -0
@@ -1,101 +0,0 @@
1
- import "vite-plus/test/config";
2
-
3
- import * as Cause from "effect/Cause";
4
- import * as Effect from "effect/Effect";
5
- import * as Exit from "effect/Exit";
6
- import * as Layer from "effect/Layer";
7
- import * as NodeServices from "@effect/platform-node/NodeServices";
8
- import * as Option from "effect/Option";
9
- import { assert, describe, it } from "@effect/vitest";
10
- import { Command } from "effect/unstable/cli";
11
- import { fromPartial } from "@total-typescript/shoehorn";
12
-
13
- import { T3Application } from "../../application/service.ts";
14
- import { T3Config } from "../../config/service.ts";
15
- import { NodeEnvironmentLive } from "../../environment/layer.ts";
16
- import { InvalidFlagCombinationError } from "../error.ts";
17
- import { T3Input } from "../input/service.ts";
18
- import { T3Output } from "../output/service.ts";
19
- import { readTerminalCommand } from "./read.ts";
20
- import { writeTerminalCommand } from "./write.ts";
21
-
22
- const testLayer = Layer.mergeAll(
23
- Layer.succeed(
24
- T3Application,
25
- fromPartial({
26
- getTerminal: () => Effect.die("getTerminal should not be called"),
27
- attachTerminal: () => Effect.die("attachTerminal should not be called"),
28
- writeTerminal: () => Effect.die("writeTerminal should not be called"),
29
- }),
30
- ),
31
- Layer.succeed(
32
- T3Config,
33
- fromPartial({
34
- resolve: () =>
35
- Effect.succeed({
36
- url: "ws://localhost",
37
- token: "token",
38
- source: "config",
39
- local: true,
40
- }),
41
- }),
42
- ),
43
- Layer.succeed(T3Output, {
44
- writeStdout: () => Effect.void,
45
- writeStderr: () => Effect.void,
46
- printJson: () => Effect.void,
47
- printNdjson: () => Effect.void,
48
- printInfo: () => Effect.void,
49
- }),
50
- Layer.succeed(T3Input, {
51
- readStdin: () => Effect.die("readStdin should not be called"),
52
- readStdinBinary: () => Effect.die("readStdinBinary should not be called"),
53
- }),
54
- NodeServices.layer,
55
- NodeEnvironmentLive,
56
- );
57
-
58
- describe("readTerminalCommand", () => {
59
- it.layer(testLayer)("readTerminalCommand", (t) => {
60
- t.effect("rejects --from-sequence without --follow", () =>
61
- Effect.gen(function* () {
62
- const run = Command.runWith(readTerminalCommand, { version: "0.0.0-test" });
63
- const exit = yield* run(["--thread", "thread-1", "term-1", "--from-sequence", "1"]).pipe(
64
- Effect.exit,
65
- );
66
- assert.isTrue(Exit.isFailure(exit));
67
- if (!Exit.isFailure(exit)) {
68
- return;
69
- }
70
- const error = Cause.findErrorOption(exit.cause);
71
- assert.isTrue(Option.isSome(error));
72
- if (Option.isSome(error)) {
73
- assert.instanceOf(error.value, InvalidFlagCombinationError);
74
- assert.equal(error.value.message, "--from-sequence requires --follow");
75
- }
76
- }),
77
- );
78
- });
79
- });
80
-
81
- describe("writeTerminalCommand", () => {
82
- it.layer(testLayer)("writeTerminalCommand", (t) => {
83
- t.effect("rejects multiple payload sources", () =>
84
- Effect.gen(function* () {
85
- const run = Command.runWith(writeTerminalCommand, { version: "0.0.0-test" });
86
- const exit = yield* run(["--thread", "thread-1", "term-1", "hello", "--stdin"]).pipe(
87
- Effect.exit,
88
- );
89
- assert.isTrue(Exit.isFailure(exit));
90
- if (!Exit.isFailure(exit)) {
91
- return;
92
- }
93
- const error = Cause.findErrorOption(exit.cause);
94
- assert.isTrue(Option.isSome(error));
95
- if (Option.isSome(error)) {
96
- assert.instanceOf(error.value, InvalidFlagCombinationError);
97
- }
98
- }),
99
- );
100
- });
101
- });
@@ -1,167 +0,0 @@
1
- import type { TerminalSessionSnapshot, TerminalSummary } from "#t3tools/contracts";
2
-
3
- type TerminalRow = {
4
- readonly id: string;
5
- readonly status: string;
6
- readonly label: string;
7
- readonly cwd: string;
8
- readonly updated: string;
9
- readonly process: string;
10
- };
11
-
12
- export function formatTerminalListHuman(terminals: ReadonlyArray<TerminalSummary>) {
13
- if (terminals.length === 0) {
14
- return "no terminals\n";
15
- }
16
- return `${formatTerminalTable(terminals.map(toSummaryRow))}\n`;
17
- }
18
-
19
- export function formatTerminalCreatedHuman(snapshot: TerminalSessionSnapshot) {
20
- return `terminal created\n${formatTerminalTable([toSnapshotRow(snapshot)])}`;
21
- }
22
-
23
- export function formatTerminalWrittenHuman(input: {
24
- readonly terminalId: string;
25
- readonly threadId: string;
26
- readonly bytes: number;
27
- }) {
28
- return `wrote ${input.bytes} bytes to ${input.terminalId} (${input.threadId})`;
29
- }
30
-
31
- export function formatTerminalDestroyedHuman(input: {
32
- readonly terminalId: string;
33
- readonly threadId: string;
34
- }) {
35
- return `destroyed ${input.terminalId} (${input.threadId})`;
36
- }
37
-
38
- function formatTerminalTable(rows: ReadonlyArray<TerminalRow>) {
39
- const headers = {
40
- id: "id",
41
- status: "status",
42
- label: "label",
43
- cwd: "cwd",
44
- updated: "updated",
45
- process: "process",
46
- };
47
-
48
- const widths = {
49
- id: columnWidth(
50
- headers.id,
51
- rows.map((row) => row.id),
52
- 44,
53
- ),
54
- status: columnWidth(
55
- headers.status,
56
- rows.map((row) => row.status),
57
- 8,
58
- ),
59
- label: columnWidth(
60
- headers.label,
61
- rows.map((row) => row.label),
62
- 24,
63
- ),
64
- cwd: columnWidth(
65
- headers.cwd,
66
- rows.map((row) => row.cwd),
67
- 40,
68
- ),
69
- updated: columnWidth(
70
- headers.updated,
71
- rows.map((row) => row.updated),
72
- 24,
73
- ),
74
- process: columnWidth(
75
- headers.process,
76
- rows.map((row) => row.process),
77
- 20,
78
- ),
79
- };
80
-
81
- const header = [
82
- pad(headers.id, widths.id),
83
- pad(headers.status, widths.status),
84
- pad(headers.label, widths.label),
85
- pad(headers.cwd, widths.cwd),
86
- pad(headers.updated, widths.updated),
87
- pad(headers.process, widths.process),
88
- ].join(" ");
89
-
90
- const divider = [
91
- "-".repeat(widths.id),
92
- "-".repeat(widths.status),
93
- "-".repeat(widths.label),
94
- "-".repeat(widths.cwd),
95
- "-".repeat(widths.updated),
96
- "-".repeat(widths.process),
97
- ].join(" ");
98
-
99
- const body = rows
100
- .map((row) =>
101
- [
102
- pad(row.id, widths.id),
103
- pad(row.status, widths.status),
104
- pad(row.label, widths.label),
105
- pad(row.cwd, widths.cwd),
106
- pad(row.updated, widths.updated),
107
- pad(row.process, widths.process),
108
- ].join(" "),
109
- )
110
- .join("\n");
111
-
112
- return `${header}\n${divider}\n${body}`;
113
- }
114
-
115
- function toSummaryRow(terminal: TerminalSummary): TerminalRow {
116
- return {
117
- id: terminal.terminalId,
118
- status: terminal.status,
119
- label: terminal.label,
120
- cwd: terminal.cwd,
121
- updated: terminal.updatedAt,
122
- process: formatProcessInfo(terminal),
123
- };
124
- }
125
-
126
- function toSnapshotRow(snapshot: TerminalSessionSnapshot): TerminalRow {
127
- return {
128
- id: snapshot.terminalId,
129
- status: snapshot.status,
130
- label: snapshot.label,
131
- cwd: snapshot.cwd,
132
- updated: snapshot.updatedAt,
133
- process: formatProcessInfo(snapshot),
134
- };
135
- }
136
-
137
- function formatProcessInfo(input: {
138
- readonly pid: number | null;
139
- readonly exitCode: number | null;
140
- readonly exitSignal: number | null;
141
- }) {
142
- const parts = [
143
- typeof input.pid === "number" ? `pid ${input.pid}` : null,
144
- typeof input.exitCode === "number" ? `exit ${input.exitCode}` : null,
145
- typeof input.exitSignal === "number" ? `sig ${input.exitSignal}` : null,
146
- ].filter((part): part is string => part !== null);
147
- return parts.length > 0 ? parts.join(", ") : "-";
148
- }
149
-
150
- function columnWidth(header: string, values: ReadonlyArray<string>, maxWidth: number) {
151
- const widest = values.reduce((width, value) => Math.max(width, value.length), header.length);
152
- return Math.min(widest, maxWidth);
153
- }
154
-
155
- function pad(value: string, width: number) {
156
- return truncate(value, width).padEnd(width, " ");
157
- }
158
-
159
- function truncate(value: string, width: number) {
160
- if (value.length <= width) {
161
- return value;
162
- }
163
- if (width <= 3) {
164
- return value.slice(0, width);
165
- }
166
- return `${value.slice(0, width - 3)}...`;
167
- }
@@ -1,128 +0,0 @@
1
- import type { ThreadShow } from "../application/threads.ts";
2
- import type { WaitEvent } from "../application/service.ts";
3
- import type { OrchestrationThread, OrchestrationThreadShell } from "#t3tools/contracts";
4
- import { latestAssistantMessage, threadStatus } from "../domain/thread-lifecycle.ts";
5
-
6
- export function formatThreadShowJson(thread: ThreadShow) {
7
- return {
8
- id: thread.id,
9
- projectId: thread.projectId,
10
- title: thread.title,
11
- status: thread.status,
12
- session: thread.session,
13
- latestTurn: thread.latestTurn,
14
- modelSelection: thread.modelSelection,
15
- runtimeMode: thread.runtimeMode,
16
- interactionMode: thread.interactionMode,
17
- branch: thread.branch,
18
- worktreePath: thread.worktreePath,
19
- archivedAt: thread.archivedAt,
20
- createdAt: thread.createdAt,
21
- updatedAt: thread.updatedAt,
22
- messageCount: thread.messageCount,
23
- hasPendingApprovals: thread.hasPendingApprovals,
24
- hasPendingUserInput: thread.hasPendingUserInput,
25
- hasActionableProposedPlan: thread.hasActionableProposedPlan,
26
- pendingApprovals: thread.pendingApprovals,
27
- pendingUserInputs: thread.pendingUserInputs,
28
- };
29
- }
30
-
31
- export function formatThreadShowHuman(thread: ThreadShow) {
32
- const lines = [
33
- `title: ${thread.title}`,
34
- `id: ${thread.id}`,
35
- `status: ${thread.status}`,
36
- `model: ${thread.modelSelection.instanceId}/${thread.modelSelection.model}`,
37
- ...(thread.branch !== null ? [`branch: ${thread.branch}`] : []),
38
- ...(thread.worktreePath !== null ? [`worktree: ${thread.worktreePath}`] : []),
39
- `messages: ${thread.messageCount}`,
40
- ];
41
- if (thread.pendingApprovals.length > 0) {
42
- const requestIds = thread.pendingApprovals.map((approval) => approval.requestId).join(", ");
43
- lines.push(`pending approvals: ${thread.pendingApprovals.length} (${requestIds})`);
44
- }
45
- if (thread.pendingUserInputs.length > 0) {
46
- const requestIds = thread.pendingUserInputs.map((input) => input.requestId).join(", ");
47
- lines.push(`pending user inputs: ${thread.pendingUserInputs.length} (${requestIds})`);
48
- }
49
- return `${lines.join("\n")}\n`;
50
- }
51
-
52
- export function formatThreadsHuman(threads: ReadonlyArray<OrchestrationThreadShell>) {
53
- return threads
54
- .map(
55
- (thread) =>
56
- `- ${thread.title}${thread.archivedAt !== null ? " (archived)" : ""}\n id: ${thread.id}\n status: ${threadStatus(thread)}\n updated: ${thread.updatedAt}\n`,
57
- )
58
- .join("");
59
- }
60
-
61
- export function formatThreadDeletedHuman(input: {
62
- readonly threadId: string;
63
- readonly dispatch: { readonly sequence: number };
64
- }) {
65
- return `thread deleted: ${input.threadId}\nsequence: ${input.dispatch.sequence}`;
66
- }
67
-
68
- export function formatThreadStartedHuman(input: {
69
- readonly thread: OrchestrationThread;
70
- readonly sequence: number;
71
- }) {
72
- return `thread started: ${input.thread.title}\nid: ${input.thread.id}\nstatus: ${threadStatus(input.thread)}\nsequence: ${input.sequence}`;
73
- }
74
-
75
- export function formatThreadMessagesHuman(thread: OrchestrationThread, limit: number) {
76
- const messages = limit === 0 ? thread.messages : thread.messages.slice(-limit);
77
- return messages.map((message) => `\n### ${message.role}\n\n${message.text}\n`).join("");
78
- }
79
-
80
- export function formatWaitDoneHuman(thread: OrchestrationThread) {
81
- const latest = latestAssistantMessage(thread);
82
- return `status: ${threadStatus(thread)}\n${latest !== undefined ? `\n### ${latest.role}\n\n${latest.text}\n` : ""}`;
83
- }
84
-
85
- export function formatThreadMessagesJson(thread: OrchestrationThread, full: boolean) {
86
- return full ? thread : { thread: stripThreadMessages(thread), messages: thread.messages };
87
- }
88
-
89
- export function formatWaitEventNdjson(event: WaitEvent) {
90
- if (event.type !== "thread" && event.type !== "done") {
91
- return event;
92
- }
93
- const compactThread = stripThreadHeavy(event.thread);
94
- return event.type === "done"
95
- ? {
96
- type: "done",
97
- thread: compactThread,
98
- latestAssistantMessage: latestAssistantMessage(event.thread) ?? null,
99
- }
100
- : {
101
- type: "thread",
102
- thread: compactThread,
103
- messageCount: event.thread.messages.length,
104
- };
105
- }
106
-
107
- function stripThreadMessages<T extends { readonly messages: unknown }>(thread: T) {
108
- const { messages: _messages, ...rest } = thread;
109
- return rest;
110
- }
111
-
112
- function stripThreadHeavy<
113
- T extends {
114
- readonly messages: unknown;
115
- readonly activities?: unknown;
116
- readonly proposedPlans?: unknown;
117
- readonly checkpoints?: unknown;
118
- },
119
- >(thread: T) {
120
- const {
121
- messages: _messages,
122
- activities: _activities,
123
- proposedPlans: _proposedPlans,
124
- checkpoints: _checkpoints,
125
- ...rest
126
- } = thread;
127
- return rest;
128
- }
@@ -1,105 +0,0 @@
1
- import * as Effect from "effect/Effect";
2
- import * as FileSystem from "effect/FileSystem";
3
- import * as Filter from "effect/Filter";
4
- import * as Layer from "effect/Layer";
5
- import * as Path from "effect/Path";
6
- import * as Schema from "effect/Schema";
7
-
8
- import { Environment, type EnvironmentShape } from "../environment/service.ts";
9
- import { ConfigError } from "./error.ts";
10
- import { T3Config, type StoredConfig } from "./service.ts";
11
- import { normalizeHttpBaseUrl } from "./url.ts";
12
-
13
- export const makeT3Config = Effect.fn("makeT3Config")(function* () {
14
- const fs = yield* FileSystem.FileSystem;
15
- const path = yield* Path.Path;
16
- const environment = yield* Environment;
17
- const configFilePath = resolveConfigPath(path, environment);
18
- const readStored = Effect.fn("T3ConfigLive.readStored")(function* () {
19
- const raw = yield* fs.readFileString(configFilePath).pipe(
20
- Effect.catchFilter(Filter.reason("PlatformError", "NotFound"), () =>
21
- Effect.succeed(undefined),
22
- ),
23
- Effect.mapError(
24
- (error) => new ConfigError({ message: "failed to read config", cause: error }),
25
- ),
26
- );
27
- if (raw === undefined) {
28
- return {};
29
- }
30
- return yield* parseStoredConfig(raw);
31
- });
32
- const writeStored = Effect.fn("T3ConfigLive.writeStored")(function* (config: StoredConfig) {
33
- yield* fs
34
- .makeDirectory(path.dirname(configFilePath), { recursive: true, mode: 0o700 })
35
- .pipe(
36
- Effect.mapError(
37
- (error) => new ConfigError({ message: "failed to write config", cause: error }),
38
- ),
39
- );
40
- yield* fs
41
- .writeFileString(configFilePath, `${JSON.stringify(config, null, 2)}\n`, { mode: 0o600 })
42
- .pipe(
43
- Effect.mapError(
44
- (error) => new ConfigError({ message: "failed to write config", cause: error }),
45
- ),
46
- );
47
- });
48
- const resolve = Effect.fn("T3ConfigLive.resolve")(function* () {
49
- const stored = yield* readStored();
50
- const envUrl = environment.env["T3CODE_URL"];
51
- const envToken = environment.env["T3CODE_TOKEN"];
52
- const envUrlValue = envUrl?.trim();
53
- const envTokenValue = envToken?.trim();
54
- const url = envUrlValue !== undefined && envUrlValue.length > 0 ? envUrlValue : stored.url;
55
- const token =
56
- envTokenValue !== undefined && envTokenValue.length > 0 ? envTokenValue : stored.token;
57
- if (url === undefined || url.length === 0 || token === undefined || token.length === 0) {
58
- return yield* Effect.fail(
59
- new ConfigError({ message: "not authenticated. run: t3cli auth pair <pairing-url>" }),
60
- );
61
- }
62
- const source: "env" | "config" =
63
- (envUrlValue !== undefined && envUrlValue.length > 0) ||
64
- (envTokenValue !== undefined && envTokenValue.length > 0)
65
- ? "env"
66
- : "config";
67
- const normalizedUrl = yield* normalizeHttpBaseUrl(url);
68
- return {
69
- url: normalizedUrl,
70
- token,
71
- source,
72
- local: stored.local ?? false,
73
- };
74
- });
75
-
76
- return {
77
- readStored,
78
- writeStored,
79
- resolve,
80
- };
81
- });
82
-
83
- export const T3ConfigLive = Layer.effect(T3Config, makeT3Config());
84
-
85
- const StoredConfigSchema = Schema.Struct({
86
- url: Schema.optionalKey(Schema.String),
87
- token: Schema.optionalKey(Schema.String),
88
- local: Schema.optionalKey(Schema.Boolean),
89
- });
90
-
91
- function parseStoredConfig(raw: string) {
92
- return Schema.decodeUnknownEffect(Schema.fromJsonString(StoredConfigSchema))(raw).pipe(
93
- Effect.mapError((error) => new ConfigError({ message: "failed to read config", cause: error })),
94
- );
95
- }
96
-
97
- function resolveConfigPath(path: Path.Path, environment: EnvironmentShape) {
98
- const xdgConfigHome = environment.env["XDG_CONFIG_HOME"];
99
- const xdgConfigHomeValue = xdgConfigHome?.trim();
100
- const root =
101
- xdgConfigHomeValue !== undefined && xdgConfigHomeValue.length > 0
102
- ? xdgConfigHomeValue
103
- : path.join(environment.homeDir, ".config");
104
- return path.join(root, "t3cli", "config.json");
105
- }
@@ -1,26 +0,0 @@
1
- import * as Context from "effect/Context";
2
- import type * as Effect from "effect/Effect";
3
-
4
- import type { ConfigError, ConfigServiceError } from "./error.ts";
5
-
6
- export type StoredConfig = {
7
- readonly url?: string;
8
- readonly token?: string;
9
- readonly local?: boolean;
10
- };
11
-
12
- export type ResolvedConfig = {
13
- readonly url: string;
14
- readonly token: string;
15
- readonly source: "env" | "config";
16
- readonly local: boolean;
17
- };
18
-
19
- export class T3Config extends Context.Service<
20
- T3Config,
21
- {
22
- readonly readStored: () => Effect.Effect<StoredConfig, ConfigError>;
23
- readonly writeStored: (config: StoredConfig) => Effect.Effect<void, ConfigError>;
24
- readonly resolve: () => Effect.Effect<ResolvedConfig, ConfigServiceError>;
25
- }
26
- >()("t3cli/T3Config") {}
@@ -1,12 +0,0 @@
1
- import { homedir } from "node:os";
2
- import * as Layer from "effect/Layer";
3
-
4
- import { Environment } from "./service.ts";
5
-
6
- export const NodeEnvironmentLive = Layer.succeed(Environment)({
7
- cwd: process.cwd(),
8
- homeDir: homedir(),
9
- env: process.env,
10
- stdoutIsTTY: process.stdout.isTTY ?? false,
11
- stderrIsTTY: process.stderr.isTTY ?? false,
12
- });
@@ -1,13 +0,0 @@
1
- import * as Context from "effect/Context";
2
-
3
- export type EnvironmentShape = {
4
- readonly cwd: string;
5
- readonly homeDir: string;
6
- readonly env: Readonly<Record<string, string | undefined>>;
7
- readonly stdoutIsTTY: boolean;
8
- readonly stderrIsTTY: boolean;
9
- };
10
-
11
- export class Environment extends Context.Service<Environment, EnvironmentShape>()(
12
- "t3cli/Environment",
13
- ) {}
@@ -1 +0,0 @@
1
- export { readT3LayoutFromNodeProcess, resolveT3BaseDir, type T3Layout } from "./base-dir.ts";
File without changes
File without changes
File without changes
File without changes