t3code-cli 0.11.0 → 0.13.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 (330) 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 +85549 -2668
  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/rolldown-runtime.js +1 -1
  12. package/dist/rpc.js +1 -1
  13. package/dist/runtime.js +2 -2
  14. package/dist/shared.js +23313 -8022
  15. package/dist/src/application/actions.d.ts +25 -0
  16. package/dist/src/application/index.d.ts +3 -3
  17. package/dist/src/application/layer.d.ts +66 -50
  18. package/dist/src/application/model-selection.d.ts +2 -2
  19. package/dist/src/application/models.d.ts +1 -1
  20. package/dist/src/application/project-commands.d.ts +23 -3
  21. package/dist/src/application/projects.d.ts +7 -7
  22. package/dist/src/application/service.d.ts +65 -2
  23. package/dist/src/application/shell-sequence.d.ts +25 -19
  24. package/dist/src/application/terminals.d.ts +8 -8
  25. package/dist/src/application/thread-commands.d.ts +19 -19
  26. package/dist/src/application/thread-update.d.ts +1 -1
  27. package/dist/src/application/thread-wait.d.ts +19 -15
  28. package/dist/src/application/threads.d.ts +134 -108
  29. package/dist/src/auth/error.d.ts +3 -3
  30. package/dist/src/auth/index.d.ts +1 -1
  31. package/dist/src/auth/layer.d.ts +36 -8
  32. package/dist/src/auth/local-base-dir.d.ts +5 -2
  33. package/dist/src/auth/local-origin.d.ts +3 -3
  34. package/dist/src/auth/local-token.d.ts +3 -3
  35. package/dist/src/auth/remote-error.d.ts +3 -0
  36. package/dist/src/auth/service.d.ts +15 -3
  37. package/dist/src/auth/type.d.ts +40 -1
  38. package/dist/src/cli/env/flag.d.ts +2 -0
  39. package/dist/src/cli/env/index.d.ts +2 -0
  40. package/dist/src/cli/env/selection-layer.d.ts +3 -0
  41. package/dist/src/cli/flags.d.ts +2 -0
  42. package/dist/src/cli/format/index.d.ts +1 -0
  43. package/dist/src/cli/format/output.d.ts +12 -0
  44. package/dist/src/cli/index.d.ts +4 -0
  45. package/dist/src/cli/runtime/index.d.ts +1 -0
  46. package/dist/src/cli/runtime/service.d.ts +16 -0
  47. package/dist/src/{scope → cli/scope}/resolve.d.ts +5 -4
  48. package/dist/src/config/config.d.ts +49 -0
  49. package/dist/src/config/credential/cipher-node.d.ts +3 -0
  50. package/dist/src/config/credential/cipher-web.d.ts +3 -0
  51. package/dist/src/config/credential/cipher.d.ts +29 -0
  52. package/dist/src/config/credential/env.d.ts +3 -0
  53. package/dist/src/config/credential/error.d.ts +8 -0
  54. package/dist/src/config/credential/index.d.ts +6 -0
  55. package/dist/src/config/credential/service.d.ts +34 -0
  56. package/dist/src/config/env/env.d.ts +55 -0
  57. package/dist/src/config/env/index.d.ts +2 -0
  58. package/dist/src/{layout/base-dir.d.ts → config/env/layout.d.ts} +0 -1
  59. package/dist/src/config/environment-name/index.d.ts +1 -0
  60. package/dist/src/config/environment-name/name.d.ts +10 -0
  61. package/dist/src/config/error.d.ts +4 -11
  62. package/dist/src/config/index.d.ts +10 -5
  63. package/dist/src/config/keystore/error.d.ts +8 -0
  64. package/dist/src/config/keystore/file.d.ts +9 -0
  65. package/dist/src/config/keystore/index.d.ts +4 -0
  66. package/dist/src/config/keystore/keyring-node.d.ts +4 -0
  67. package/dist/src/config/keystore/service.d.ts +33 -0
  68. package/dist/src/config/paths/index.d.ts +1 -0
  69. package/dist/src/config/paths/paths.d.ts +6 -0
  70. package/dist/src/config/persist/file-mode.d.ts +4 -0
  71. package/dist/src/config/persist/migration.d.ts +68 -0
  72. package/dist/src/config/persist/persist.d.ts +40 -0
  73. package/dist/src/config/persist/schema.d.ts +68 -0
  74. package/dist/src/config/resolve/resolve.d.ts +40 -0
  75. package/dist/src/config/selection/index.d.ts +1 -0
  76. package/dist/src/config/selection/resolve.d.ts +4 -0
  77. package/dist/src/config/selection/service.d.ts +10 -0
  78. package/dist/src/config/types.d.ts +36 -0
  79. package/dist/src/config/url/error.d.ts +10 -0
  80. package/dist/src/config/url/index.d.ts +2 -0
  81. package/dist/src/connection/error.d.ts +3 -1
  82. package/dist/src/connection/index.d.ts +0 -1
  83. package/dist/src/connection/prepared.d.ts +14 -0
  84. package/dist/src/contracts/index.d.ts +1 -1
  85. package/dist/src/domain/error.d.ts +14 -1
  86. package/dist/src/domain/helpers.d.ts +53 -43
  87. package/dist/src/domain/model-config.d.ts +92 -84
  88. package/dist/src/domain/thread-activities.d.ts +1 -1
  89. package/dist/src/domain/thread-lifecycle.d.ts +24 -20
  90. package/dist/src/index.d.ts +1 -2
  91. package/dist/src/{connection/node.d.ts → node/connection.d.ts} +1 -1
  92. package/dist/src/node/index.d.ts +1 -2
  93. package/dist/src/orchestration/index.d.ts +0 -1
  94. package/dist/src/orchestration/layer.d.ts +321 -390
  95. package/dist/src/orchestration/service.d.ts +1 -1
  96. package/dist/src/rpc/error.d.ts +4 -6
  97. package/dist/src/rpc/layer.d.ts +2036 -1917
  98. package/dist/src/rpc/operation.d.ts +4 -5732
  99. package/dist/src/rpc/service.d.ts +1 -1
  100. package/dist/src/rpc/session.d.ts +22 -0
  101. package/dist/src/rpc/ws-group.d.ts +456 -1032
  102. package/dist/src/runtime/index.d.ts +1 -2
  103. package/dist/src/runtime/layer.d.ts +12 -8
  104. package/dist/src/sql/node-sqlite-client.d.ts +1 -1
  105. package/dist/src/t3tools/index.d.ts +1 -1
  106. package/dist/t3tools.js +2 -2
  107. package/package.json +30 -25
  108. package/src/application/actions.test.ts +328 -0
  109. package/src/application/actions.ts +475 -0
  110. package/src/application/index.ts +9 -5
  111. package/src/application/layer.ts +9 -0
  112. package/src/application/model-selection.ts +2 -2
  113. package/src/application/project-commands.ts +23 -5
  114. package/src/application/projects.ts +6 -7
  115. package/src/application/service.ts +79 -1
  116. package/src/application/shell-sequence.ts +1 -1
  117. package/src/application/terminals.ts +2 -1
  118. package/src/application/thread-commands.ts +1 -1
  119. package/src/application/thread-update.ts +1 -1
  120. package/src/application/thread-wait.ts +5 -1
  121. package/src/application/threads.test.ts +9 -3
  122. package/src/application/threads.ts +6 -6
  123. package/src/auth/error.ts +4 -9
  124. package/src/auth/index.ts +7 -0
  125. package/src/auth/layer.test-utils.ts +34 -0
  126. package/src/auth/layer.ts +116 -34
  127. package/src/auth/local-base-dir.ts +13 -6
  128. package/src/auth/local-origin.ts +10 -7
  129. package/src/auth/local-token.ts +28 -23
  130. package/src/auth/remote-error.ts +17 -0
  131. package/src/auth/service.test.ts +200 -0
  132. package/src/auth/service.ts +27 -3
  133. package/src/auth/transport.ts +45 -114
  134. package/src/auth/type.ts +47 -1
  135. package/src/bin.ts +24 -6
  136. package/src/cli/action-format.ts +110 -0
  137. package/src/cli/action.ts +398 -0
  138. package/src/cli/app.ts +6 -0
  139. package/src/cli/auth.ts +76 -23
  140. package/src/cli/env/flag.ts +8 -0
  141. package/src/cli/env/index.ts +2 -0
  142. package/src/cli/env/selection-layer.test.ts +49 -0
  143. package/src/cli/env/selection-layer.ts +27 -0
  144. package/src/cli/env.ts +107 -0
  145. package/src/cli/extra-args.test.ts +32 -0
  146. package/src/cli/extra-args.ts +22 -0
  147. package/src/cli/flags.ts +11 -1
  148. package/src/cli/format/auth.ts +92 -0
  149. package/src/cli/format/human.ts +131 -0
  150. package/src/cli/format/index.ts +12 -0
  151. package/src/cli/format/model.ts +29 -0
  152. package/src/cli/format/output.ts +51 -0
  153. package/src/cli/format/project.ts +32 -0
  154. package/src/cli/format/terminal.ts +87 -0
  155. package/src/cli/{thread-format.test.ts → format/thread.test.ts} +6 -4
  156. package/src/cli/format/thread.ts +185 -0
  157. package/src/cli/index.ts +20 -0
  158. package/src/cli/interaction/confirm.ts +64 -0
  159. package/src/cli/{self-action.ts → interaction/self-action.ts} +8 -6
  160. package/src/cli/message-input.ts +1 -1
  161. package/src/cli/model.ts +9 -5
  162. package/src/cli/project.ts +13 -7
  163. package/src/cli/projects/delete.ts +13 -12
  164. package/src/cli/require.ts +9 -7
  165. package/src/cli/runtime/index.ts +1 -0
  166. package/src/cli/runtime/service.ts +28 -0
  167. package/src/{scope → cli/scope}/resolve.ts +11 -9
  168. package/src/cli/terminal/attach.ts +3 -6
  169. package/src/cli/terminal/create.ts +10 -9
  170. package/src/cli/terminal/destroy.ts +13 -11
  171. package/src/cli/terminal/list.ts +10 -9
  172. package/src/cli/terminal/read.test-utils.ts +48 -0
  173. package/src/cli/terminal/read.test.ts +35 -0
  174. package/src/cli/terminal/read.ts +3 -6
  175. package/src/cli/terminal/scope.ts +10 -5
  176. package/src/cli/terminal/shared.ts +1 -1
  177. package/src/cli/terminal/stream.ts +3 -6
  178. package/src/cli/terminal/wait.test.ts +5 -3
  179. package/src/cli/terminal/wait.ts +10 -9
  180. package/src/cli/terminal/write.test.ts +34 -0
  181. package/src/cli/terminal/write.ts +10 -9
  182. package/src/cli/threads/approve.ts +11 -7
  183. package/src/cli/threads/archive.ts +14 -9
  184. package/src/cli/threads/callback.ts +6 -4
  185. package/src/cli/threads/delete.ts +17 -11
  186. package/src/cli/threads/interrupt.ts +14 -9
  187. package/src/cli/threads/list.test.ts +5 -3
  188. package/src/cli/threads/list.ts +10 -10
  189. package/src/cli/threads/messages.ts +11 -7
  190. package/src/cli/threads/respond.ts +11 -7
  191. package/src/cli/threads/send.ts +19 -9
  192. package/src/cli/threads/show.ts +11 -7
  193. package/src/cli/threads/start.ts +18 -13
  194. package/src/cli/threads/unarchive.ts +11 -7
  195. package/src/cli/threads/update.ts +14 -9
  196. package/src/cli/threads/wait.ts +11 -7
  197. package/src/cli/wait-events.ts +1 -1
  198. package/src/config/config.ts +260 -0
  199. package/src/config/credential/cipher-node.ts +40 -0
  200. package/src/config/credential/cipher-web.ts +82 -0
  201. package/src/config/credential/cipher.ts +39 -0
  202. package/src/config/credential/env.ts +13 -0
  203. package/src/config/credential/error.ts +9 -0
  204. package/src/config/credential/index.ts +6 -0
  205. package/src/config/credential/service.test-utils.ts +25 -0
  206. package/src/config/credential/service.test.ts +116 -0
  207. package/src/config/credential/service.ts +205 -0
  208. package/src/config/env/env.test-utils.ts +14 -0
  209. package/src/config/env/env.ts +81 -0
  210. package/src/config/env/index.ts +2 -0
  211. package/src/{layout/base-dir.ts → config/env/layout.ts} +0 -9
  212. package/src/config/environment-name/index.ts +7 -0
  213. package/src/config/environment-name/name.test.ts +66 -0
  214. package/src/config/environment-name/name.ts +49 -0
  215. package/src/config/error.ts +6 -8
  216. package/src/config/index.ts +16 -5
  217. package/src/config/keystore/error.ts +9 -0
  218. package/src/config/keystore/file.ts +96 -0
  219. package/src/config/keystore/index.ts +4 -0
  220. package/src/config/keystore/keyring-node.test.ts +12 -0
  221. package/src/config/keystore/keyring-node.ts +100 -0
  222. package/src/config/keystore/service.test-utils.ts +15 -0
  223. package/src/config/keystore/service.test.ts +18 -0
  224. package/src/config/keystore/service.ts +29 -0
  225. package/src/config/layer.test-utils.ts +45 -0
  226. package/src/config/layer.test.ts +209 -0
  227. package/src/config/paths/index.ts +1 -0
  228. package/src/config/paths/paths.ts +36 -0
  229. package/src/config/persist/file-mode.ts +21 -0
  230. package/src/config/persist/migration.test.ts +71 -0
  231. package/src/config/persist/migration.ts +82 -0
  232. package/src/config/persist/persist.test.ts +113 -0
  233. package/src/config/persist/persist.ts +65 -0
  234. package/src/config/persist/schema.ts +37 -0
  235. package/src/config/platform.test-utils.ts +20 -0
  236. package/src/config/resolve/resolve.test-utils.ts +20 -0
  237. package/src/config/resolve/resolve.test.ts +137 -0
  238. package/src/config/resolve/resolve.ts +104 -0
  239. package/src/config/selection/index.ts +1 -0
  240. package/src/config/selection/resolve.ts +14 -0
  241. package/src/config/selection/service.ts +29 -0
  242. package/src/config/temp-home.test-utils.ts +7 -0
  243. package/src/config/types.ts +49 -0
  244. package/src/config/url/error.ts +8 -0
  245. package/src/config/url/index.ts +7 -0
  246. package/src/config/url/url.test.ts +31 -0
  247. package/src/connection/error.ts +4 -1
  248. package/src/connection/index.ts +0 -1
  249. package/src/connection/layer.ts +5 -2
  250. package/src/connection/prepared.ts +83 -0
  251. package/src/contracts/index.ts +1 -1
  252. package/src/domain/error.ts +20 -1
  253. package/src/domain/helpers.test.ts +1 -1
  254. package/src/domain/helpers.ts +1 -1
  255. package/src/domain/model-config.ts +1 -1
  256. package/src/domain/thread-activities.test.ts +1 -1
  257. package/src/domain/thread-activities.ts +1 -1
  258. package/src/domain/thread-lifecycle.test.ts +1 -1
  259. package/src/domain/thread-lifecycle.ts +1 -1
  260. package/src/effect.test-utils.ts +25 -0
  261. package/src/index.ts +1 -1
  262. package/src/{connection/node.ts → node/connection.ts} +1 -1
  263. package/src/node/index.ts +1 -2
  264. package/src/orchestration/index.ts +0 -1
  265. package/src/orchestration/layer.ts +3 -2
  266. package/src/orchestration/service.ts +1 -1
  267. package/src/rpc/error.ts +10 -17
  268. package/src/rpc/layer.ts +17 -51
  269. package/src/rpc/operation.ts +16 -2
  270. package/src/rpc/service.ts +2 -1
  271. package/src/rpc/session.ts +168 -0
  272. package/src/rpc/ws-group.ts +13 -27
  273. package/src/runtime/index.ts +2 -1
  274. package/src/runtime/layer.test-utils.ts +32 -0
  275. package/src/runtime/layer.test.ts +66 -0
  276. package/src/runtime/layer.ts +21 -12
  277. package/src/t3tools/index.ts +1 -1
  278. package/src/types/marked-terminal.d.ts +11 -0
  279. package/dist/layout.js +0 -2
  280. package/dist/scope.js +0 -2
  281. package/dist/src/cli/output-format.d.ts +0 -11
  282. package/dist/src/config/layer.d.ts +0 -22
  283. package/dist/src/config/service.d.ts +0 -22
  284. package/dist/src/environment/layer.d.ts +0 -3
  285. package/dist/src/environment/service.d.ts +0 -12
  286. package/dist/src/layout/index.d.ts +0 -1
  287. package/dist/upstream-t3code/packages/contracts/src/auth.d.ts +0 -441
  288. package/dist/upstream-t3code/packages/contracts/src/baseSchemas.d.ts +0 -38
  289. package/dist/upstream-t3code/packages/contracts/src/desktopBootstrap.d.ts +0 -14
  290. package/dist/upstream-t3code/packages/contracts/src/editor.d.ts +0 -124
  291. package/dist/upstream-t3code/packages/contracts/src/environment.d.ts +0 -64
  292. package/dist/upstream-t3code/packages/contracts/src/environmentHttp.d.ts +0 -762
  293. package/dist/upstream-t3code/packages/contracts/src/filesystem.d.ts +0 -26
  294. package/dist/upstream-t3code/packages/contracts/src/git.d.ts +0 -500
  295. package/dist/upstream-t3code/packages/contracts/src/index.d.ts +0 -25
  296. package/dist/upstream-t3code/packages/contracts/src/ipc.d.ts +0 -490
  297. package/dist/upstream-t3code/packages/contracts/src/keybindings.d.ts +0 -133
  298. package/dist/upstream-t3code/packages/contracts/src/model.d.ts +0 -112
  299. package/dist/upstream-t3code/packages/contracts/src/orchestration.d.ts +0 -6682
  300. package/dist/upstream-t3code/packages/contracts/src/project.d.ts +0 -45
  301. package/dist/upstream-t3code/packages/contracts/src/provider.d.ts +0 -116
  302. package/dist/upstream-t3code/packages/contracts/src/providerInstance.d.ts +0 -99
  303. package/dist/upstream-t3code/packages/contracts/src/providerRuntime.d.ts +0 -4276
  304. package/dist/upstream-t3code/packages/contracts/src/relay.d.ts +0 -1262
  305. package/dist/upstream-t3code/packages/contracts/src/relayClient.d.ts +0 -48
  306. package/dist/upstream-t3code/packages/contracts/src/remoteAccess.d.ts +0 -45
  307. package/dist/upstream-t3code/packages/contracts/src/review.d.ts +0 -37
  308. package/dist/upstream-t3code/packages/contracts/src/rpc.d.ts +0 -8218
  309. package/dist/upstream-t3code/packages/contracts/src/server.d.ts +0 -2291
  310. package/dist/upstream-t3code/packages/contracts/src/settings.d.ts +0 -271
  311. package/dist/upstream-t3code/packages/contracts/src/sourceControl.d.ts +0 -177
  312. package/dist/upstream-t3code/packages/contracts/src/terminal.d.ts +0 -330
  313. package/dist/upstream-t3code/packages/contracts/src/vcs.d.ts +0 -148
  314. package/src/cli/auth-format.ts +0 -45
  315. package/src/cli/confirm.ts +0 -31
  316. package/src/cli/model-format.ts +0 -18
  317. package/src/cli/output-format.ts +0 -45
  318. package/src/cli/project-format.ts +0 -18
  319. package/src/cli/terminal/commands.test.ts +0 -101
  320. package/src/cli/terminal-format.ts +0 -167
  321. package/src/cli/thread-format.ts +0 -128
  322. package/src/config/layer.ts +0 -105
  323. package/src/config/service.ts +0 -26
  324. package/src/environment/layer.ts +0 -12
  325. package/src/environment/service.ts +0 -13
  326. package/src/layout/index.ts +0 -1
  327. /package/dist/src/{scope → cli/scope}/index.d.ts +0 -0
  328. /package/dist/src/config/{url.d.ts → url/url.d.ts} +0 -0
  329. /package/src/{scope → cli/scope}/index.ts +0 -0
  330. /package/src/config/{url.ts → url/url.ts} +0 -0
@@ -9,13 +9,15 @@ import type {
9
9
  OrchestrationShellSnapshot,
10
10
  OrchestrationThread,
11
11
  OrchestrationThreadShell,
12
+ ProjectScript,
13
+ ProjectScriptIcon,
12
14
  ProviderUserInputAnswers,
13
15
  ServerProvider,
14
16
  TerminalAttachStreamEvent,
15
17
  TerminalMetadataStreamEvent,
16
18
  TerminalSessionSnapshot,
17
19
  TerminalSummary,
18
- } from "#t3tools/contracts";
20
+ } from "@t3tools/contracts";
19
21
 
20
22
  import type { ApplicationError } from "./error.ts";
21
23
  import type { ThreadShow } from "./threads.ts";
@@ -34,6 +36,7 @@ export type CreateTerminalInput = {
34
36
  readonly threadId: string;
35
37
  readonly terminalId?: string;
36
38
  readonly command?: string;
39
+ readonly env?: Readonly<Record<string, string>>;
37
40
  };
38
41
 
39
42
  export type TerminalRef = {
@@ -80,6 +83,80 @@ export type WaitEvent =
80
83
  | { readonly type: "status"; readonly status: string; readonly threadId: string }
81
84
  | { readonly type: "done"; readonly thread: OrchestrationThread };
82
85
 
86
+ export type ProjectActionSelector =
87
+ | { readonly id: string; readonly name?: never }
88
+ | { readonly id?: never; readonly name: string };
89
+
90
+ export type AddProjectActionInput = {
91
+ readonly projectRef: string;
92
+ readonly id?: string;
93
+ readonly name: string;
94
+ readonly command: string;
95
+ readonly icon?: ProjectScriptIcon;
96
+ readonly setup?: boolean;
97
+ readonly previewUrl?: string;
98
+ readonly autoOpenPreview?: boolean;
99
+ };
100
+
101
+ export type UpdateProjectActionInput = {
102
+ readonly projectRef: string;
103
+ readonly selector: ProjectActionSelector;
104
+ readonly name?: string;
105
+ readonly command?: string;
106
+ readonly icon?: ProjectScriptIcon;
107
+ readonly setup?: boolean;
108
+ readonly previewUrl?: string | null;
109
+ readonly autoOpenPreview?: boolean | null;
110
+ };
111
+
112
+ export type ProjectActionMutationResult = {
113
+ readonly dispatch: DispatchResult;
114
+ readonly project: OrchestrationProjectShell;
115
+ readonly action: ProjectScript;
116
+ };
117
+
118
+ export type ProjectActionDeleteResult = {
119
+ readonly dispatch: DispatchResult;
120
+ readonly project: OrchestrationProjectShell;
121
+ readonly action: ProjectScript;
122
+ };
123
+
124
+ export type ProjectActionRunResult = {
125
+ readonly project: OrchestrationProjectShell;
126
+ readonly action: ProjectScript;
127
+ readonly terminal: TerminalSessionSnapshot;
128
+ };
129
+
130
+ export type T3ActionApplicationService = {
131
+ readonly listActions: (projectRef: string) => Effect.Effect<
132
+ {
133
+ readonly project: OrchestrationProjectShell;
134
+ readonly actions: ReadonlyArray<ProjectScript>;
135
+ },
136
+ ApplicationError
137
+ >;
138
+ readonly addAction: (
139
+ input: AddProjectActionInput,
140
+ ) => Effect.Effect<ProjectActionMutationResult, ApplicationError>;
141
+ readonly updateAction: (
142
+ input: UpdateProjectActionInput,
143
+ ) => Effect.Effect<ProjectActionMutationResult, ApplicationError>;
144
+ readonly deleteAction: (input: {
145
+ readonly projectRef: string;
146
+ readonly selector: ProjectActionSelector;
147
+ }) => Effect.Effect<ProjectActionDeleteResult, ApplicationError>;
148
+ readonly runAction: (input: {
149
+ readonly threadId: string;
150
+ readonly selector: ProjectActionSelector;
151
+ readonly terminalId?: string;
152
+ }) => Effect.Effect<ProjectActionRunResult, ApplicationError>;
153
+ };
154
+
155
+ export class T3ActionApplication extends Context.Service<
156
+ T3ActionApplication,
157
+ T3ActionApplicationService
158
+ >()("t3cli/T3ActionApplication") {}
159
+
83
160
  export type T3ModelApplicationService = {
84
161
  readonly listModels: (input: {
85
162
  readonly all?: boolean;
@@ -239,6 +316,7 @@ export class T3TerminalApplication extends Context.Service<
239
316
  >()("t3cli/T3TerminalApplication") {}
240
317
 
241
318
  export type T3ApplicationService = T3ModelApplicationService &
319
+ T3ActionApplicationService &
242
320
  T3ProjectApplicationService &
243
321
  T3ThreadApplicationService &
244
322
  T3TerminalApplicationService;
@@ -1,7 +1,7 @@
1
1
  import * as Effect from "effect/Effect";
2
2
  import * as Option from "effect/Option";
3
3
  import * as Stream from "effect/Stream";
4
- import { ORCHESTRATION_WS_METHODS } from "#t3tools/contracts";
4
+ import { ORCHESTRATION_WS_METHODS } from "@t3tools/contracts";
5
5
 
6
6
  import { T3Orchestration } from "../orchestration/service.ts";
7
7
  import { RpcError } from "../rpc/error.ts";
@@ -2,7 +2,7 @@ import * as Crypto from "effect/Crypto";
2
2
  import * as Effect from "effect/Effect";
3
3
  import * as Option from "effect/Option";
4
4
  import * as Stream from "effect/Stream";
5
- import { WS_METHODS, type TerminalSummary } from "#t3tools/contracts";
5
+ import { WS_METHODS, type TerminalSummary } from "@t3tools/contracts";
6
6
 
7
7
  import { ProjectLookupError, TerminalLookupError, ThreadLookupError } from "../domain/error.ts";
8
8
  import { findProjectById } from "../domain/helpers.ts";
@@ -124,6 +124,7 @@ export const makeTerminalApplication = Effect.fn("makeTerminalApplication")(func
124
124
  terminalId,
125
125
  cwd,
126
126
  worktreePath: thread.worktreePath ?? null,
127
+ ...(input.env !== undefined ? { env: input.env } : {}),
127
128
  }),
128
129
  );
129
130
 
@@ -12,7 +12,7 @@ import {
12
12
  type OrchestrationProjectShell,
13
13
  type ProviderApprovalDecision,
14
14
  type ProviderUserInputAnswers,
15
- } from "#t3tools/contracts";
15
+ } from "@t3tools/contracts";
16
16
  import type { ServerConfigForCli } from "../orchestration/service.ts";
17
17
  import { resolveModelSelection } from "./model-selection.ts";
18
18
  import type { SendThreadInput, StartThreadInput } from "./service.ts";
@@ -1,6 +1,6 @@
1
1
  import * as Crypto from "effect/Crypto";
2
2
  import * as Effect from "effect/Effect";
3
- import type { ModelSelection } from "#t3tools/contracts";
3
+ import type { ModelSelection } from "@t3tools/contracts";
4
4
 
5
5
  import { ModelSelectionError, ThreadEventError } from "../domain/error.ts";
6
6
  import { T3Orchestration } from "../orchestration/service.ts";
@@ -1,7 +1,7 @@
1
1
  import * as Effect from "effect/Effect";
2
2
  import * as Option from "effect/Option";
3
3
  import * as Stream from "effect/Stream";
4
- import type { OrchestrationMessage, OrchestrationThread } from "#t3tools/contracts";
4
+ import type { OrchestrationMessage, OrchestrationThread } from "@t3tools/contracts";
5
5
 
6
6
  import { ThreadSessionError } from "../domain/error.ts";
7
7
  import { T3Orchestration } from "../orchestration/service.ts";
@@ -42,6 +42,10 @@ export function watchThread(input: { readonly threadId: string }) {
42
42
  return Stream.fromIterable(events);
43
43
  }
44
44
 
45
+ if (item.kind === "synchronized") {
46
+ return Stream.empty;
47
+ }
48
+
45
49
  if (current === undefined || currentMessages === undefined) {
46
50
  return Stream.fail(
47
51
  new ThreadSessionError({
@@ -10,9 +10,10 @@ import type {
10
10
  OrchestrationShellSnapshot,
11
11
  OrchestrationThread,
12
12
  OrchestrationThreadShell,
13
- } from "#t3tools/contracts";
13
+ } from "@t3tools/contracts";
14
14
 
15
- import { NodeEnvironmentLive } from "../environment/layer.ts";
15
+ import * as CliRuntime from "../cli/runtime/service.ts";
16
+ import { t3CliEnvConfigLayer } from "../config/env/env.test-utils.ts";
16
17
  import { T3Orchestration, type Orchestration } from "../orchestration/service.ts";
17
18
  import { makeThreadApplication } from "./threads.ts";
18
19
 
@@ -58,7 +59,12 @@ function makeOrchestrationLayer(input: {
58
59
  }
59
60
 
60
61
  const testLayer = (orchestration: Layer.Layer<T3Orchestration>) =>
61
- Layer.mergeAll(orchestration, NodeServices.layer, NodeEnvironmentLive);
62
+ Layer.mergeAll(
63
+ orchestration,
64
+ NodeServices.layer,
65
+ CliRuntime.layer,
66
+ t3CliEnvConfigLayer("/tmp/t3cli-test"),
67
+ );
62
68
 
63
69
  describe("interruptThread", () => {
64
70
  it.layer(NodeServices.layer)("interruptThread", (t) => {
@@ -2,14 +2,14 @@ import * as Crypto from "effect/Crypto";
2
2
  import * as Effect from "effect/Effect";
3
3
  import * as Path from "effect/Path";
4
4
  import * as Stream from "effect/Stream";
5
- import { Environment } from "../environment/service.ts";
5
+ import { CliRuntime } from "../cli/runtime/service.ts";
6
6
  import { T3Orchestration } from "../orchestration/service.ts";
7
7
  import { ProjectLookupError, ThreadLookupError, ThreadSessionError } from "../domain/error.ts";
8
8
  import { resolveProjectScope } from "../domain/helpers.ts";
9
9
  import { type ListThreadsInclude, type StartThreadInput } from "./service.ts";
10
10
  import type { CallbackThreadInput, SendThreadInput } from "./service.ts";
11
11
  import type { T3ThreadApplicationService } from "./service.ts";
12
- import type { OrchestrationThreadShell } from "#t3tools/contracts";
12
+ import type { OrchestrationThreadShell } from "@t3tools/contracts";
13
13
  import { mergeModelOptions } from "./model-selection.ts";
14
14
  import { derivePendingApprovals, derivePendingUserInputs } from "../domain/thread-activities.ts";
15
15
  import {
@@ -17,8 +17,8 @@ import {
17
17
  threadStatus,
18
18
  type ThreadLifecycleStatus,
19
19
  } from "../domain/thread-lifecycle.ts";
20
- import type { OrchestrationThread } from "#t3tools/contracts";
21
- import type { ProviderApprovalDecision, ProviderUserInputAnswers } from "#t3tools/contracts";
20
+ import type { OrchestrationThread } from "@t3tools/contracts";
21
+ import type { ProviderApprovalDecision, ProviderUserInputAnswers } from "@t3tools/contracts";
22
22
  import {
23
23
  makeThreadApprovalRespondCommand,
24
24
  makeThreadArchiveCommand,
@@ -41,7 +41,7 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
41
41
  const orchestration = yield* T3Orchestration;
42
42
  const crypto = yield* Crypto.Crypto;
43
43
  const path = yield* Path.Path;
44
- const environment = yield* Environment;
44
+ const cliRuntime = yield* CliRuntime;
45
45
  const awaitShellSequence = (sequence: number) =>
46
46
  waitForShellSequence({ sequence }).pipe(Effect.provideService(T3Orchestration, orchestration));
47
47
  const awaitThreadCompletion = (threadId: string) =>
@@ -149,7 +149,7 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
149
149
  return yield* Effect.fail(
150
150
  new ProjectLookupError({
151
151
  message: "project is required",
152
- ref: environment.cwd,
152
+ ref: cliRuntime.cwd,
153
153
  }),
154
154
  );
155
155
  }
package/src/auth/error.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import * as Cause from "effect/Cause";
2
2
  import * as Schema from "effect/Schema";
3
3
  import { PlatformError } from "effect/PlatformError";
4
- import { HttpClientError } from "effect/unstable/http";
5
4
 
6
- import { ConfigError, UrlError } from "../config/error.ts";
5
+ import { ConfigError } from "../config/error.ts";
6
+ import { UrlError } from "../config/url/error.ts";
7
+ import { RemoteEnvironmentAuthErrorSchema } from "./remote-error.ts";
7
8
 
8
9
  export class AuthPairingUrlError extends Schema.TaggedErrorClass<AuthPairingUrlError>()(
9
10
  "AuthPairingUrlError",
@@ -22,13 +23,7 @@ export class AuthTransportError extends Schema.TaggedErrorClass<AuthTransportErr
22
23
  "AuthTransportError",
23
24
  {
24
25
  message: Schema.String,
25
- cause: Schema.optionalKey(
26
- Schema.Union([
27
- HttpClientError.HttpClientErrorSchema,
28
- Schema.instanceOf(Schema.SchemaError),
29
- UrlError,
30
- ]),
31
- ),
26
+ cause: RemoteEnvironmentAuthErrorSchema,
32
27
  },
33
28
  ) {}
34
29
 
package/src/auth/index.ts CHANGED
@@ -17,7 +17,13 @@ export type { AuthError } from "./error.ts";
17
17
  export type { AuthSessionState, AuthWebSocketTicketResult } from "./schema.ts";
18
18
  export type {
19
19
  AuthConfigInput,
20
+ AuthEnvironmentListItem,
21
+ AuthEnvironmentSummary,
22
+ AuthResolvedConfig,
20
23
  AuthSessionRole,
24
+ AuthStatusResult,
25
+ AuthUnpairResult,
26
+ AuthUseResult,
21
27
  LocalAuthInput,
22
28
  LocalAuthOriginInput,
23
29
  LocalAuthResult,
@@ -25,4 +31,5 @@ export type {
25
31
  LocalAuthTokenResult,
26
32
  PairingUrl,
27
33
  PairResult,
34
+ PersistEnvironmentInput,
28
35
  } from "./type.ts";
@@ -0,0 +1,34 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Layer from "effect/Layer";
3
+
4
+ import { T3AuthLive } from "./layer.ts";
5
+ import { T3LocalAuth } from "./local.ts";
6
+ import { T3AuthPairing } from "./pairing.ts";
7
+ import { T3AuthTransport } from "./transport.ts";
8
+ import { t3ConfigDepsLayer } from "../config/layer.test-utils.ts";
9
+ import { ConfigPlatformLayer } from "../config/platform.test-utils.ts";
10
+
11
+ export function t3AuthDepsLayer(homeDir: string) {
12
+ return T3AuthLive.pipe(
13
+ Layer.provide(
14
+ Layer.mergeAll(
15
+ t3ConfigDepsLayer(homeDir),
16
+ Layer.succeed(T3AuthTransport)({
17
+ bootstrapBearer: () => Effect.die("unused in test"),
18
+ getSession: () => Effect.succeed({ authenticated: false }),
19
+ issueWebSocketTicket: () => Effect.die("unused in test"),
20
+ }),
21
+ Layer.succeed(T3LocalAuth)({
22
+ local: () => Effect.die("unused in test"),
23
+ }),
24
+ Layer.succeed(T3AuthPairing)({
25
+ pair: () => Effect.die("unused in test"),
26
+ }),
27
+ ),
28
+ ),
29
+ );
30
+ }
31
+
32
+ export function t3AuthLayerTest(homeDir: string) {
33
+ return Layer.mergeAll(ConfigPlatformLayer, t3AuthDepsLayer(homeDir));
34
+ }
package/src/auth/layer.ts CHANGED
@@ -1,13 +1,23 @@
1
1
  import * as Effect from "effect/Effect";
2
2
  import * as Layer from "effect/Layer";
3
3
 
4
- import { T3Config } from "../config/service.ts";
4
+ import {
5
+ defaultEnvironmentNameForLocal,
6
+ defaultEnvironmentNameFromUrl,
7
+ } from "../config/environment-name/name.ts";
8
+ import type { EnvironmentSummary, ResolvedConfig } from "../config/types.ts";
9
+ import type { ConfigError } from "../config/error.ts";
10
+ import type { UrlError } from "../config/url/error.ts";
11
+ import { T3Config } from "../config/config.ts";
5
12
  import { AuthConfigError } from "./error.ts";
6
13
  import { T3LocalAuth } from "./local.ts";
7
14
  import { T3AuthPairing } from "./pairing.ts";
8
15
  import { T3Auth } from "./service.ts";
9
16
  import { T3AuthTransport } from "./transport.ts";
10
- import type { AuthConfigInput } from "./type.ts";
17
+ import type { AuthConfigInput, AuthEnvironmentListItem, AuthResolvedConfig } from "./type.ts";
18
+
19
+ const mapConfigError = (error: ConfigError | UrlError) =>
20
+ new AuthConfigError({ message: error.message, cause: error });
11
21
 
12
22
  export const makeT3Auth = Effect.fn("makeT3Auth")(function* () {
13
23
  const config = yield* T3Config;
@@ -16,58 +26,130 @@ export const makeT3Auth = Effect.fn("makeT3Auth")(function* () {
16
26
  const pairing = yield* T3AuthPairing;
17
27
 
18
28
  const status = Effect.fn("T3AuthLive.status")(function* () {
19
- const resolved = yield* config.resolve().pipe(
20
- Effect.catchTags({
21
- ConfigError: (error) =>
22
- Effect.fail(new AuthConfigError({ message: "auth config failed", cause: error })),
23
- UrlError: (error) =>
24
- Effect.fail(new AuthConfigError({ message: "auth config failed", cause: error })),
25
- }),
26
- );
27
- return yield* transport.getSession(resolved);
29
+ const resolved = yield* config.resolve().pipe(Effect.mapError(mapConfigError));
30
+ const session = yield* transport.getSession(resolved);
31
+ return { config: toAuthResolvedConfig(resolved), session } as const;
28
32
  });
29
33
 
30
34
  const issueWebSocketTicket = Effect.fn("T3AuthLive.issueWebSocketTicket")(function* () {
31
- const resolved = yield* config.resolve().pipe(
32
- Effect.catchTags({
33
- ConfigError: (error) =>
34
- Effect.fail(new AuthConfigError({ message: "auth config failed", cause: error })),
35
- UrlError: (error) =>
36
- Effect.fail(new AuthConfigError({ message: "auth config failed", cause: error })),
37
- }),
38
- );
35
+ const resolved = yield* config.resolve().pipe(Effect.mapError(mapConfigError));
39
36
  return yield* transport.issueWebSocketTicket(resolved);
40
37
  });
41
38
 
42
- const writeConfig = Effect.fn("T3AuthLive.writeConfig")(function* (input: AuthConfigInput) {
43
- const existing = yield* config.readStored().pipe(
44
- Effect.catchTags({
45
- ConfigError: (error) =>
46
- Effect.fail(new AuthConfigError({ message: "auth config failed", cause: error })),
47
- }),
48
- );
39
+ const persistEnvironment = Effect.fn("T3AuthLive.persistEnvironment")(function* (input: {
40
+ readonly name: string;
41
+ readonly url: string;
42
+ readonly token: string;
43
+ readonly local: boolean;
44
+ readonly replace?: boolean;
45
+ readonly allowReplace: boolean;
46
+ }) {
47
+ const exists = yield* config.hasEnvironment(input.name).pipe(Effect.mapError(mapConfigError));
48
+ if (exists && !input.allowReplace) {
49
+ return yield* Effect.fail(
50
+ new AuthConfigError({
51
+ message: `environment '${input.name}' already exists: pass --replace`,
52
+ }),
53
+ );
54
+ }
55
+ const makeDefault = exists && input.replace === true;
49
56
  yield* config
50
- .writeStored({
51
- ...existing,
57
+ .upsertEnvironment({
58
+ name: input.name,
52
59
  url: input.url,
53
60
  token: input.token,
54
- ...(input.local !== undefined ? { local: input.local } : {}),
61
+ local: input.local,
62
+ ...(makeDefault ? { makeDefault: true } : {}),
55
63
  })
56
- .pipe(
57
- Effect.catchTags({
58
- ConfigError: (error) =>
59
- Effect.fail(new AuthConfigError({ message: "auth config failed", cause: error })),
64
+ .pipe(Effect.mapError(mapConfigError));
65
+ return input.name;
66
+ });
67
+
68
+ const listEnvironments = Effect.fn("T3AuthLive.listEnvironments")(function* () {
69
+ const [environments, activeName] = yield* Effect.all(
70
+ [config.listEnvironments(), config.resolveActiveEnvironmentName()],
71
+ { concurrency: "unbounded" },
72
+ ).pipe(Effect.mapError(mapConfigError));
73
+ return environments.map((environment) => toAuthEnvironmentListItem(environment, activeName));
74
+ });
75
+
76
+ const resolveUnpairTarget = Effect.fn("T3AuthLive.resolveUnpairTarget")(function* (input: {
77
+ readonly name?: string;
78
+ }) {
79
+ if (input.name !== undefined && input.name.length > 0) {
80
+ return input.name;
81
+ }
82
+ const defaultName = yield* config
83
+ .getDefaultEnvironmentName()
84
+ .pipe(Effect.mapError(mapConfigError));
85
+ if (defaultName === undefined) {
86
+ return yield* Effect.fail(
87
+ new AuthConfigError({
88
+ message: "no environment selected: pass --name or run: t3cli env use <name>",
60
89
  }),
61
90
  );
91
+ }
92
+ return defaultName;
62
93
  });
63
94
 
64
95
  return {
65
96
  pair: pairing.pair,
66
97
  local: localAuth.local,
67
- writeConfig,
98
+ writeConfig: (input: AuthConfigInput) =>
99
+ config
100
+ .upsertEnvironment({
101
+ name: input.name,
102
+ url: input.url,
103
+ token: input.token,
104
+ local: input.local,
105
+ ...(input.makeDefault === true ? { makeDefault: true } : {}),
106
+ })
107
+ .pipe(Effect.mapError(mapConfigError)),
108
+ persistEnvironment,
109
+ environmentExists: (name: string) =>
110
+ config.hasEnvironment(name).pipe(Effect.mapError(mapConfigError)),
111
+ defaultNameFromUrl: (url: string) =>
112
+ defaultEnvironmentNameFromUrl(url).pipe(Effect.mapError(mapConfigError)),
113
+ defaultNameForLocal: () => Effect.succeed(defaultEnvironmentNameForLocal()),
114
+ listEnvironments,
115
+ useEnvironment: (name: string) =>
116
+ config
117
+ .setDefaultEnvironment(name)
118
+ .pipe(Effect.mapError(mapConfigError), Effect.as({ name, default: true as const })),
119
+ resolveUnpairTarget,
120
+ unpairEnvironment: (input: { readonly name: string }) =>
121
+ config
122
+ .removeEnvironment(input.name)
123
+ .pipe(
124
+ Effect.mapError(mapConfigError),
125
+ Effect.as({ name: input.name, removed: true as const }),
126
+ ),
68
127
  status,
69
128
  issueWebSocketTicket,
70
129
  };
71
130
  });
72
131
 
73
132
  export const T3AuthLive = Layer.effect(T3Auth, makeT3Auth());
133
+
134
+ function toAuthResolvedConfig(config: ResolvedConfig): AuthResolvedConfig {
135
+ return {
136
+ url: config.url,
137
+ token: config.token,
138
+ source: config.source,
139
+ local: config.local,
140
+ ...(config.environment !== undefined ? { environment: config.environment } : {}),
141
+ };
142
+ }
143
+
144
+ function toAuthEnvironmentListItem(
145
+ environment: EnvironmentSummary,
146
+ activeName: string | undefined,
147
+ ): AuthEnvironmentListItem {
148
+ return {
149
+ name: environment.name,
150
+ url: environment.url,
151
+ local: environment.local,
152
+ default: environment.default,
153
+ active: environment.name === activeName,
154
+ };
155
+ }
@@ -1,17 +1,24 @@
1
1
  import * as Effect from "effect/Effect";
2
+ import * as Option from "effect/Option";
2
3
 
3
- import { Environment } from "../environment/service.ts";
4
- import { resolveT3BaseDir } from "../layout/base-dir.ts";
4
+ import type { CliRuntime } from "../cli/runtime/service.ts";
5
+ import type { T3CliEnvShape } from "../config/env/env.ts";
6
+ import { resolveT3BaseDir } from "../config/env/layout.ts";
5
7
 
6
8
  export const resolveLocalBaseDir = Effect.fn("resolveLocalBaseDir")(function* (input: {
7
9
  readonly baseDir?: string | undefined;
10
+ readonly cliRuntime: CliRuntime["Service"];
11
+ readonly t3CliEnv: T3CliEnvShape;
8
12
  }) {
9
- const environment = yield* Environment;
13
+ const homeDir = yield* Option.match(input.t3CliEnv.home, {
14
+ onNone: () => Effect.die("HOME is not set"),
15
+ onSome: Effect.succeed,
16
+ });
10
17
  return yield* resolveT3BaseDir({
11
18
  layout: {
12
- cwd: environment.cwd,
13
- homeDir: environment.homeDir,
14
- t3codeHome: environment.env["T3CODE_HOME"],
19
+ cwd: input.cliRuntime.cwd,
20
+ homeDir,
21
+ t3codeHome: Option.getOrUndefined(input.t3CliEnv.t3codeHome),
15
22
  },
16
23
  baseDir: input.baseDir,
17
24
  });
@@ -4,8 +4,9 @@ import * as FileSystem from "effect/FileSystem";
4
4
  import * as Layer from "effect/Layer";
5
5
  import * as Path from "effect/Path";
6
6
 
7
- import { normalizeHttpBaseUrl } from "../config/url.ts";
8
- import { Environment } from "../environment/service.ts";
7
+ import { normalizeHttpBaseUrl } from "../config/url/url.ts";
8
+ import { loadT3CliEnv } from "../config/env/env.ts";
9
+ import { CliRuntime } from "../cli/runtime/service.ts";
9
10
  import { AuthLocalError } from "./error.ts";
10
11
  import { resolveLocalBaseDir } from "./local-base-dir.ts";
11
12
  import { decodeAuthLocalRuntimeStateFromJson } from "./schema.ts";
@@ -21,15 +22,17 @@ export class T3LocalAuthOrigin extends Context.Service<
21
22
  export const makeT3LocalAuthOrigin = Effect.fn("makeT3LocalAuthOrigin")(function* () {
22
23
  const fs = yield* FileSystem.FileSystem;
23
24
  const path = yield* Path.Path;
24
- const environment = yield* Environment;
25
+ const cliRuntime = yield* CliRuntime;
26
+ const t3CliEnv = yield* loadT3CliEnv;
25
27
 
26
28
  const resolve = Effect.fn("T3LocalAuthOriginLive.resolve")(function* (
27
29
  input?: LocalAuthOriginInput,
28
30
  ) {
29
- const baseDir = yield* resolveLocalBaseDir({ baseDir: input?.baseDir }).pipe(
30
- Effect.provideService(Environment, environment),
31
- Effect.provideService(Path.Path, path),
32
- );
31
+ const baseDir = yield* resolveLocalBaseDir({
32
+ baseDir: input?.baseDir,
33
+ cliRuntime,
34
+ t3CliEnv,
35
+ }).pipe(Effect.provideService(Path.Path, path));
33
36
  if (input?.origin !== undefined) {
34
37
  return yield* normalizeLocalOrigin(input.origin);
35
38
  }