t3code-cli 0.5.1 → 0.7.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.
- package/README.md +41 -16
- package/dist/Context-DueQ9iMH.js +4916 -0
- package/dist/Path-D8WPdPwR.js +11406 -0
- package/dist/Schema-DsQxYh6_.js +13581 -0
- package/dist/UrlParams-BA6gBvaY.js +205 -0
- package/dist/application.js +2 -0
- package/dist/auth.js +3 -0
- package/dist/base-dir-R12OMDso.js +20 -0
- package/dist/bin.js +236 -13526
- package/dist/chunk-B5meny8j.js +36 -0
- package/dist/cli.js +2 -0
- package/dist/config.js +4 -0
- package/dist/connection.js +15 -0
- package/dist/contracts.js +1 -0
- package/dist/error-B2t1bAP9.js +169 -0
- package/dist/error-BHRnjLux.js +15 -0
- package/dist/error-jwMt3VoW.js +54 -0
- package/dist/flags-CM7_iGdA.js +13371 -0
- package/dist/index.js +5 -12
- package/dist/layer-CfC5qZol.js +1508 -0
- package/dist/layer-DHhKS5jd.js +13 -0
- package/dist/layer-DUv99vsS.js +72 -0
- package/dist/layer-DvHnKBYj.js +29466 -0
- package/dist/layer-MqCKkIGD.js +1206 -0
- package/dist/layout.js +2 -0
- package/dist/orchestration.js +2 -0
- package/dist/rpc.js +2 -0
- package/dist/runtime.js +3 -0
- package/dist/scope-GycYiJ54.js +29 -0
- package/dist/scope.js +2 -0
- package/dist/service-CLmRO2Dp.js +8 -0
- package/dist/service-ybOWV9pL.js +5 -0
- package/dist/src/application/index.d.ts +3 -0
- package/dist/src/application/layer.d.ts +4 -4
- package/dist/src/application/projects.d.ts +1 -1
- package/dist/src/application/service.d.ts +1 -1
- package/dist/src/application/threads.d.ts +4 -4
- package/dist/src/auth/index.d.ts +10 -0
- package/dist/src/auth/local-base-dir.d.ts +5 -7
- package/dist/src/auth/local-token.d.ts +2 -2
- package/dist/src/auth/type.d.ts +1 -0
- package/dist/src/cli/flags.d.ts +15 -0
- package/dist/src/cli/index.d.ts +1 -0
- package/dist/src/cli/output-format.d.ts +9 -0
- package/dist/src/config/index.d.ts +5 -0
- package/dist/src/config/layer.d.ts +2 -0
- package/dist/src/config/service.d.ts +2 -0
- package/dist/src/connection/index.d.ts +5 -0
- package/dist/src/contracts/index.d.ts +1 -0
- package/dist/src/domain/helpers.d.ts +163 -32
- package/dist/src/index.d.ts +4 -28
- package/dist/src/layout/base-dir.d.ts +12 -0
- package/dist/src/layout/index.d.ts +1 -0
- package/dist/src/orchestration/index.d.ts +2 -0
- package/dist/src/rpc/index.d.ts +1 -0
- package/dist/src/runtime/index.d.ts +2 -0
- package/dist/src/runtime/layer.d.ts +11 -0
- package/dist/src/scope/index.d.ts +1 -0
- package/dist/src/scope/resolve.d.ts +19 -0
- package/dist/src/t3tools/index.d.ts +1 -0
- package/dist/src-KdbHqrex.js +8874 -0
- package/dist/t3tools.js +2 -0
- package/dist/transport-D3zBdZ1h.js +539 -0
- package/dist/url-SlsaG8nY.js +165 -0
- package/package.json +54 -2
- package/src/application/index.ts +3 -0
- package/src/application/service.ts +1 -1
- package/src/application/threads.ts +38 -11
- package/src/auth/index.ts +28 -0
- package/src/auth/layer.ts +13 -6
- package/src/auth/local-base-dir.ts +15 -19
- package/src/auth/local-origin.ts +4 -1
- package/src/auth/local-token.ts +4 -1
- package/src/auth/type.ts +1 -0
- package/src/bin.ts +1 -1
- package/src/cli/app.ts +6 -6
- package/src/cli/auth-format.ts +2 -0
- package/src/cli/auth.ts +19 -9
- package/src/cli/error.ts +7 -0
- package/src/cli/flags.ts +51 -0
- package/src/cli/index.ts +10 -0
- package/src/cli/{models.ts → model.ts} +5 -4
- package/src/cli/{projects.ts → project.ts} +8 -7
- package/src/cli/require.ts +31 -0
- package/src/cli/{threads.ts → thread.ts} +2 -2
- package/src/cli/threads/archive.ts +24 -8
- package/src/cli/threads/list.ts +12 -5
- package/src/cli/threads/messages.ts +20 -5
- package/src/cli/threads/send.ts +27 -23
- package/src/cli/threads/start.ts +22 -21
- package/src/cli/threads/wait.ts +22 -12
- package/src/config/index.ts +5 -0
- package/src/config/layer.ts +2 -0
- package/src/config/service.ts +2 -0
- package/src/connection/index.ts +9 -0
- package/src/contracts/index.ts +8 -0
- package/src/domain/helpers.test.ts +103 -0
- package/src/domain/helpers.ts +112 -16
- package/src/index.ts +4 -87
- package/src/layout/base-dir.ts +35 -0
- package/src/layout/index.ts +1 -0
- package/src/orchestration/index.ts +7 -0
- package/src/rpc/index.ts +1 -0
- package/src/runtime/index.ts +12 -0
- package/src/{runtime.ts → runtime/layer.ts} +15 -15
- package/src/scope/index.ts +6 -0
- package/src/scope/resolve.ts +62 -0
- package/src/t3tools/index.ts +1 -0
- package/dist/runtime-KQVRmRk-.js +0 -71499
- package/dist/src/connection.d.ts +0 -5
- package/dist/src/runtime.d.ts +0 -10
- package/src/connection.ts +0 -9
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { On as dual } from "./Context-DueQ9iMH.js";
|
|
2
|
+
import { H as fromResult, Tt as succeed, b as catchTags, cn as IllegalArgumentError, j as flatMap, k as fail, mi as try_ } from "./Path-D8WPdPwR.js";
|
|
3
|
+
import { n as UrlError } from "./error-BHRnjLux.js";
|
|
4
|
+
//#region node_modules/.pnpm/effect@4.0.0-beta.78/node_modules/effect/dist/unstable/http/Url.js
|
|
5
|
+
/**
|
|
6
|
+
* Immutable helpers for parsing and editing platform `URL` values.
|
|
7
|
+
*
|
|
8
|
+
* This module keeps the WHATWG `URL` object as the URL representation used by
|
|
9
|
+
* HTTP clients and servers, then adds safe parsing and pipeable setters for
|
|
10
|
+
* credentials, host, path, protocol, query, and hash components. Query strings
|
|
11
|
+
* can be read, replaced, or transformed through `UrlParams` so repeated keys and
|
|
12
|
+
* key/value encoding stay explicit.
|
|
13
|
+
*
|
|
14
|
+
* **Mental model**
|
|
15
|
+
*
|
|
16
|
+
* `fromString` returns a `Result` instead of throwing when URL construction
|
|
17
|
+
* fails. Setters never mutate the original `URL`; each one clones the input and
|
|
18
|
+
* assigns the requested component on the clone. Use `mutate` when several
|
|
19
|
+
* component assignments should happen on the same clone.
|
|
20
|
+
*
|
|
21
|
+
* **Common tasks**
|
|
22
|
+
*
|
|
23
|
+
* - Parse absolute URLs, or resolve relative URL strings against a base URL.
|
|
24
|
+
* - Pipe setters to adjust host, protocol, path, credentials, search, or hash.
|
|
25
|
+
* - Extract query parameters with `urlParams`.
|
|
26
|
+
* - Replace or transform query parameters with `setUrlParams` and
|
|
27
|
+
* `modifyUrlParams`.
|
|
28
|
+
*
|
|
29
|
+
* **Gotchas**
|
|
30
|
+
*
|
|
31
|
+
* Relative input needs an explicit base. Component assignment and serialization
|
|
32
|
+
* follow platform `URL` rules, so values may be normalized or percent-encoded.
|
|
33
|
+
* `setPassword` accepts `Redacted` input, but the resulting `URL` still contains
|
|
34
|
+
* the actual credential and should be treated as sensitive when serialized.
|
|
35
|
+
*
|
|
36
|
+
* @since 4.0.0
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* Parses a URL string safely into a `URL` object, returning a `Result` type for
|
|
40
|
+
* error handling.
|
|
41
|
+
*
|
|
42
|
+
* **Details**
|
|
43
|
+
*
|
|
44
|
+
* This function converts a string into a `URL` object, enabling safe URL
|
|
45
|
+
* parsing with built-in error handling. If the string is invalid or fails to
|
|
46
|
+
* parse, this function does not throw an error; instead, it wraps the error in
|
|
47
|
+
* a `IllegalArgumentError` and returns it as the `Failure` value of an
|
|
48
|
+
* `Result`. The `Success` value contains the successfully parsed `URL`.
|
|
49
|
+
*
|
|
50
|
+
* An optional `base` parameter can be provided to resolve relative URLs. If
|
|
51
|
+
* specified, the function interprets the input `url` as relative to this
|
|
52
|
+
* `base`. This is especially useful when dealing with URLs that might not be
|
|
53
|
+
* fully qualified.
|
|
54
|
+
*
|
|
55
|
+
* **Example** (Parsing absolute and relative URLs)
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* import { Result } from "effect"
|
|
59
|
+
* import { Url } from "effect/unstable/http"
|
|
60
|
+
*
|
|
61
|
+
* // Parse an absolute URL
|
|
62
|
+
* //
|
|
63
|
+
* // ┌─── Result<URL, IllegalArgumentError>
|
|
64
|
+
* // ▼
|
|
65
|
+
* const parsed = Url.fromString("https://example.com/path")
|
|
66
|
+
*
|
|
67
|
+
* if (Result.isSuccess(parsed)) {
|
|
68
|
+
* console.log("Parsed URL:", parsed.success.toString())
|
|
69
|
+
* } else {
|
|
70
|
+
* console.log("Error:", parsed.failure.message)
|
|
71
|
+
* }
|
|
72
|
+
* // Output: Parsed URL: https://example.com/path
|
|
73
|
+
*
|
|
74
|
+
* // Parse a relative URL with a base
|
|
75
|
+
* const relativeParsed = Url.fromString("/relative-path", "https://example.com")
|
|
76
|
+
*
|
|
77
|
+
* if (Result.isSuccess(relativeParsed)) {
|
|
78
|
+
* console.log("Parsed relative URL:", relativeParsed.success.toString())
|
|
79
|
+
* } else {
|
|
80
|
+
* console.log("Error:", relativeParsed.failure.message)
|
|
81
|
+
* }
|
|
82
|
+
* // Output: Parsed relative URL: https://example.com/relative-path
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* @category constructors
|
|
86
|
+
* @since 4.0.0
|
|
87
|
+
*/
|
|
88
|
+
const fromString = (url, base) => try_({
|
|
89
|
+
try: () => new URL(url, base),
|
|
90
|
+
catch: () => new IllegalArgumentError(`Invalid URL: "${url}"${base !== void 0 ? ` with base "${base}"` : ""}`)
|
|
91
|
+
});
|
|
92
|
+
/**
|
|
93
|
+
* Updates a cloned `URL` with a callback, allowing multiple changes at once.
|
|
94
|
+
*
|
|
95
|
+
* **Example** (Mutating URL credentials)
|
|
96
|
+
*
|
|
97
|
+
* ```ts
|
|
98
|
+
* import { Url } from "effect/unstable/http"
|
|
99
|
+
*
|
|
100
|
+
* const myUrl = new URL("https://example.com")
|
|
101
|
+
*
|
|
102
|
+
* const mutatedUrl = Url.mutate(myUrl, (url) => {
|
|
103
|
+
* url.username = "user"
|
|
104
|
+
* url.password = "pass"
|
|
105
|
+
* })
|
|
106
|
+
*
|
|
107
|
+
* console.log("Mutated:", mutatedUrl.toString())
|
|
108
|
+
* // Output: Mutated: https://user:pass@example.com/
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* @category modifiers
|
|
112
|
+
* @since 4.0.0
|
|
113
|
+
*/
|
|
114
|
+
const mutate = /*#__PURE__*/ dual(2, (self, f) => {
|
|
115
|
+
const copy = new URL(self);
|
|
116
|
+
f(copy);
|
|
117
|
+
return copy;
|
|
118
|
+
});
|
|
119
|
+
//#endregion
|
|
120
|
+
//#region src/config/url.ts
|
|
121
|
+
function normalizeHttpBaseUrl(value) {
|
|
122
|
+
return parseUrl(value).pipe(flatMap((url) => succeed(normalizeBaseUrl(url))));
|
|
123
|
+
}
|
|
124
|
+
function toHttpEndpointUrl(httpBaseUrl, pathname) {
|
|
125
|
+
return parseUrl(httpBaseUrl).pipe(flatMap((url) => succeed(withPathname(url, pathname).toString())));
|
|
126
|
+
}
|
|
127
|
+
function toWebSocketEndpointUrl(httpBaseUrl, pathname) {
|
|
128
|
+
return parseUrl(httpBaseUrl).pipe(flatMap((url) => {
|
|
129
|
+
if (url.protocol === "http:") return succeed(withPathname(url, pathname, "ws:").toString());
|
|
130
|
+
if (url.protocol === "https:") return succeed(withPathname(url, pathname, "wss:").toString());
|
|
131
|
+
return fail(new UrlError({
|
|
132
|
+
message: `unsupported server url protocol: ${url.protocol}`,
|
|
133
|
+
protocol: url.protocol
|
|
134
|
+
}));
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
function parseUrl(value) {
|
|
138
|
+
return fromResult(fromString(value)).pipe(catchTags({ IllegalArgumentError: (error) => fail(new UrlError({
|
|
139
|
+
message: "invalid url",
|
|
140
|
+
cause: error
|
|
141
|
+
})) }));
|
|
142
|
+
}
|
|
143
|
+
function normalizeBaseUrl(url) {
|
|
144
|
+
return mutate(url, (current) => {
|
|
145
|
+
current.hash = "";
|
|
146
|
+
current.search = "";
|
|
147
|
+
current.pathname = normalizePathname(current.pathname);
|
|
148
|
+
}).toString().replace(/\/$/, "");
|
|
149
|
+
}
|
|
150
|
+
function withPathname(url, pathname, protocol) {
|
|
151
|
+
return mutate(url, (current) => {
|
|
152
|
+
if (protocol !== void 0) current.protocol = protocol;
|
|
153
|
+
current.pathname = appendPathname(current.pathname, pathname);
|
|
154
|
+
current.search = "";
|
|
155
|
+
current.hash = "";
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function normalizePathname(pathname) {
|
|
159
|
+
return pathname === "/" ? "" : pathname.replace(/\/+$/u, "");
|
|
160
|
+
}
|
|
161
|
+
function appendPathname(basePathname, pathname) {
|
|
162
|
+
return `${normalizePathname(basePathname)}${pathname.startsWith("/") ? pathname : `/${pathname}`}`;
|
|
163
|
+
}
|
|
164
|
+
//#endregion
|
|
165
|
+
export { mutate as a, fromString as i, toHttpEndpointUrl as n, toWebSocketEndpointUrl as r, normalizeHttpBaseUrl as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "t3code-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "CLI for t3code",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -37,6 +37,54 @@
|
|
|
37
37
|
".": {
|
|
38
38
|
"types": "./dist/src/index.d.ts",
|
|
39
39
|
"default": "./dist/index.js"
|
|
40
|
+
},
|
|
41
|
+
"./application": {
|
|
42
|
+
"types": "./dist/src/application/index.d.ts",
|
|
43
|
+
"default": "./dist/application.js"
|
|
44
|
+
},
|
|
45
|
+
"./auth": {
|
|
46
|
+
"types": "./dist/src/auth/index.d.ts",
|
|
47
|
+
"default": "./dist/auth.js"
|
|
48
|
+
},
|
|
49
|
+
"./cli": {
|
|
50
|
+
"types": "./dist/src/cli/index.d.ts",
|
|
51
|
+
"default": "./dist/cli.js"
|
|
52
|
+
},
|
|
53
|
+
"./config": {
|
|
54
|
+
"types": "./dist/src/config/index.d.ts",
|
|
55
|
+
"default": "./dist/config.js"
|
|
56
|
+
},
|
|
57
|
+
"./connection": {
|
|
58
|
+
"types": "./dist/src/connection/index.d.ts",
|
|
59
|
+
"default": "./dist/connection.js"
|
|
60
|
+
},
|
|
61
|
+
"./contracts": {
|
|
62
|
+
"types": "./dist/src/contracts/index.d.ts",
|
|
63
|
+
"default": "./dist/contracts.js"
|
|
64
|
+
},
|
|
65
|
+
"./t3tools": {
|
|
66
|
+
"types": "./dist/upstream-t3code/packages/contracts/src/index.d.ts",
|
|
67
|
+
"default": "./dist/t3tools.js"
|
|
68
|
+
},
|
|
69
|
+
"./layout": {
|
|
70
|
+
"types": "./dist/src/layout/index.d.ts",
|
|
71
|
+
"default": "./dist/layout.js"
|
|
72
|
+
},
|
|
73
|
+
"./orchestration": {
|
|
74
|
+
"types": "./dist/src/orchestration/index.d.ts",
|
|
75
|
+
"default": "./dist/orchestration.js"
|
|
76
|
+
},
|
|
77
|
+
"./rpc": {
|
|
78
|
+
"types": "./dist/src/rpc/index.d.ts",
|
|
79
|
+
"default": "./dist/rpc.js"
|
|
80
|
+
},
|
|
81
|
+
"./runtime": {
|
|
82
|
+
"types": "./dist/src/runtime/index.d.ts",
|
|
83
|
+
"default": "./dist/runtime.js"
|
|
84
|
+
},
|
|
85
|
+
"./scope": {
|
|
86
|
+
"types": "./dist/src/scope/index.d.ts",
|
|
87
|
+
"default": "./dist/scope.js"
|
|
40
88
|
}
|
|
41
89
|
},
|
|
42
90
|
"dependencies": {
|
|
@@ -45,13 +93,15 @@
|
|
|
45
93
|
},
|
|
46
94
|
"devDependencies": {
|
|
47
95
|
"@changesets/cli": "^2.31.0",
|
|
96
|
+
"@effect/vitest": "4.0.0-beta.78",
|
|
97
|
+
"@total-typescript/shoehorn": "^0.1.2",
|
|
48
98
|
"@types/node": "^25.9.1",
|
|
49
99
|
"typescript": "^6.0.3",
|
|
50
100
|
"vite-plus": "^0.1.24",
|
|
51
101
|
"@t3tools/contracts": "0.0.24"
|
|
52
102
|
},
|
|
53
103
|
"engines": {
|
|
54
|
-
"node": "
|
|
104
|
+
"node": ">=24.0.0"
|
|
55
105
|
},
|
|
56
106
|
"scripts": {
|
|
57
107
|
"build": "vp pack && tsc -p tsconfig.dts.json",
|
|
@@ -60,7 +110,9 @@
|
|
|
60
110
|
"format:check": "vp fmt --check",
|
|
61
111
|
"lint": "vp lint",
|
|
62
112
|
"lint:fix": "vp lint --fix",
|
|
113
|
+
"test": "vp test run",
|
|
63
114
|
"changeset": "changeset",
|
|
115
|
+
"release:version": "changeset version && pnpm format",
|
|
64
116
|
"release:check": "pnpm check && pnpm typecheck && pnpm pack --dry-run",
|
|
65
117
|
"release:publish": "changeset publish",
|
|
66
118
|
"typecheck": "tsc --noEmit"
|
|
@@ -15,7 +15,7 @@ import type {
|
|
|
15
15
|
import type { ApplicationError } from "./error.ts";
|
|
16
16
|
|
|
17
17
|
export type StartThreadInput = {
|
|
18
|
-
readonly projectRef
|
|
18
|
+
readonly projectRef?: string;
|
|
19
19
|
readonly message: string;
|
|
20
20
|
readonly title?: string;
|
|
21
21
|
readonly provider?: string;
|
|
@@ -4,8 +4,8 @@ import * as Path from "effect/Path";
|
|
|
4
4
|
|
|
5
5
|
import { Environment } from "../environment/service.ts";
|
|
6
6
|
import { T3Orchestration } from "../orchestration/service.ts";
|
|
7
|
-
import { ThreadSessionError } from "../domain/error.ts";
|
|
8
|
-
import {
|
|
7
|
+
import { ProjectLookupError, ThreadSessionError } from "../domain/error.ts";
|
|
8
|
+
import { resolveProjectScope } from "../domain/helpers.ts";
|
|
9
9
|
import { type StartThreadInput } from "./service.ts";
|
|
10
10
|
import type { SendThreadInput } from "./service.ts";
|
|
11
11
|
import { mergeModelOptions } from "./model-selection.ts";
|
|
@@ -27,10 +27,17 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
|
|
|
27
27
|
const environment = yield* Environment;
|
|
28
28
|
const listThreads = Effect.fn("T3ApplicationLive.listThreads")(function* (projectRef: string) {
|
|
29
29
|
const snapshot = yield* orchestration.getShellSnapshot();
|
|
30
|
-
const
|
|
30
|
+
const scope = yield* resolveProjectScope(snapshot, {
|
|
31
|
+
ref: projectRef,
|
|
32
|
+
}).pipe(Effect.provideService(Path.Path, path));
|
|
33
|
+
if (scope === undefined) {
|
|
34
|
+
return yield* Effect.fail(
|
|
35
|
+
new ProjectLookupError({ message: `project not found: ${projectRef}`, ref: projectRef }),
|
|
36
|
+
);
|
|
37
|
+
}
|
|
31
38
|
return {
|
|
32
|
-
project,
|
|
33
|
-
threads: snapshot.threads.filter((thread) => thread.projectId === project.id),
|
|
39
|
+
project: scope.project,
|
|
40
|
+
threads: snapshot.threads.filter((thread) => thread.projectId === scope.project.id),
|
|
34
41
|
};
|
|
35
42
|
});
|
|
36
43
|
const getThreadMessages = Effect.fn("T3ApplicationLive.getThreadMessages")(function* (
|
|
@@ -51,11 +58,31 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
|
|
|
51
58
|
},
|
|
52
59
|
) {
|
|
53
60
|
const snapshot = yield* orchestration.getShellSnapshot();
|
|
54
|
-
const
|
|
61
|
+
const projectRef = startInput.projectRef;
|
|
62
|
+
if (projectRef === undefined) {
|
|
63
|
+
return yield* Effect.fail(
|
|
64
|
+
new ProjectLookupError({
|
|
65
|
+
message: "project is required",
|
|
66
|
+
ref: environment.cwd,
|
|
67
|
+
}),
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
const scope = yield* resolveProjectScope(snapshot, {
|
|
71
|
+
ref: projectRef,
|
|
72
|
+
}).pipe(Effect.provideService(Path.Path, path));
|
|
73
|
+
if (scope === undefined) {
|
|
74
|
+
return yield* Effect.fail(
|
|
75
|
+
new ProjectLookupError({ message: `project not found: ${projectRef}`, ref: projectRef }),
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
const worktreePath = startInput.worktreePath ?? scope.inferredWorktreePath;
|
|
55
79
|
const serverConfig = yield* orchestration.getServerConfig();
|
|
56
80
|
const commands = yield* makeThreadStartCommands({
|
|
57
|
-
start:
|
|
58
|
-
|
|
81
|
+
start: {
|
|
82
|
+
...startInput,
|
|
83
|
+
...(worktreePath !== undefined ? { worktreePath } : {}),
|
|
84
|
+
},
|
|
85
|
+
project: scope.project,
|
|
59
86
|
serverConfig,
|
|
60
87
|
}).pipe(Effect.provideService(Crypto.Crypto, crypto));
|
|
61
88
|
const createDispatch = yield* orchestration.dispatch(commands.createCommand);
|
|
@@ -67,7 +94,7 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
|
|
|
67
94
|
const threadId = commands.threadId;
|
|
68
95
|
const until = policy?.until ?? "dispatch";
|
|
69
96
|
if (until === "dispatch") {
|
|
70
|
-
return { dispatch, project, threadId };
|
|
97
|
+
return { dispatch, project: scope.project, threadId };
|
|
71
98
|
}
|
|
72
99
|
yield* waitForShellSequence({
|
|
73
100
|
orchestration,
|
|
@@ -80,14 +107,14 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
|
|
|
80
107
|
return opened.snapshot;
|
|
81
108
|
}),
|
|
82
109
|
);
|
|
83
|
-
return { dispatch, project, threadId, thread };
|
|
110
|
+
return { dispatch, project: scope.project, threadId, thread };
|
|
84
111
|
}
|
|
85
112
|
const thread = yield* waitForThreadUntilComplete({
|
|
86
113
|
orchestration,
|
|
87
114
|
threadId,
|
|
88
115
|
});
|
|
89
116
|
yield* failIfThreadError(thread);
|
|
90
|
-
return { dispatch, project, threadId, thread };
|
|
117
|
+
return { dispatch, project: scope.project, threadId, thread };
|
|
91
118
|
});
|
|
92
119
|
const sendThread = Effect.fn("T3ApplicationLive.sendThread")(function* (
|
|
93
120
|
input: SendThreadInput,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export { T3Auth } from "./service.ts";
|
|
2
|
+
export { T3AuthLive, makeT3Auth } from "./layer.ts";
|
|
3
|
+
export { T3LocalAuth, T3LocalAuthLive, makeT3LocalAuth } from "./local.ts";
|
|
4
|
+
export { T3LocalAuthOrigin, T3LocalAuthOriginLive, makeT3LocalAuthOrigin } from "./local-origin.ts";
|
|
5
|
+
export { T3LocalAuthToken, T3LocalAuthTokenLive, makeT3LocalAuthToken } from "./local-token.ts";
|
|
6
|
+
export { T3AuthPairing, T3AuthPairingLive, makeT3AuthPairing, parsePairingUrl } from "./pairing.ts";
|
|
7
|
+
export {
|
|
8
|
+
AuthConfigError,
|
|
9
|
+
AuthLocalDatabaseError,
|
|
10
|
+
AuthLocalError,
|
|
11
|
+
AuthLocalSecretError,
|
|
12
|
+
AuthLocalSigningError,
|
|
13
|
+
AuthPairingUrlError,
|
|
14
|
+
AuthTransportError,
|
|
15
|
+
} from "./error.ts";
|
|
16
|
+
export type { AuthError } from "./error.ts";
|
|
17
|
+
export type { AuthSessionState, AuthWebSocketTicketResult } from "./schema.ts";
|
|
18
|
+
export type {
|
|
19
|
+
AuthConfigInput,
|
|
20
|
+
AuthSessionRole,
|
|
21
|
+
LocalAuthInput,
|
|
22
|
+
LocalAuthOriginInput,
|
|
23
|
+
LocalAuthResult,
|
|
24
|
+
LocalAuthTokenInput,
|
|
25
|
+
LocalAuthTokenResult,
|
|
26
|
+
PairingUrl,
|
|
27
|
+
PairResult,
|
|
28
|
+
} from "./type.ts";
|
package/src/auth/layer.ts
CHANGED
|
@@ -46,12 +46,19 @@ export const makeT3Auth = Effect.fn("makeT3Auth")(function* () {
|
|
|
46
46
|
Effect.fail(new AuthConfigError({ message: "auth config failed", cause: error })),
|
|
47
47
|
}),
|
|
48
48
|
);
|
|
49
|
-
yield* config
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
yield* config
|
|
50
|
+
.writeStored({
|
|
51
|
+
...existing,
|
|
52
|
+
url: input.url,
|
|
53
|
+
token: input.token,
|
|
54
|
+
...(input.local !== undefined ? { local: input.local } : {}),
|
|
55
|
+
})
|
|
56
|
+
.pipe(
|
|
57
|
+
Effect.catchTags({
|
|
58
|
+
ConfigError: (error) =>
|
|
59
|
+
Effect.fail(new AuthConfigError({ message: "auth config failed", cause: error })),
|
|
60
|
+
}),
|
|
61
|
+
);
|
|
55
62
|
});
|
|
56
63
|
|
|
57
64
|
return {
|
|
@@ -1,22 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { Environment } from "../environment/service.ts";
|
|
4
|
+
import { resolveT3BaseDir } from "../layout/base-dir.ts";
|
|
4
5
|
|
|
5
|
-
export
|
|
6
|
-
readonly baseDir
|
|
7
|
-
readonly environment: EnvironmentShape;
|
|
8
|
-
readonly path: Path.Path;
|
|
6
|
+
export const resolveLocalBaseDir = Effect.fn("resolveLocalBaseDir")(function* (input: {
|
|
7
|
+
readonly baseDir?: string | undefined;
|
|
9
8
|
}) {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
return input.path.resolve(input.environment.cwd, raw);
|
|
22
|
-
}
|
|
9
|
+
const environment = yield* Environment;
|
|
10
|
+
return yield* resolveT3BaseDir({
|
|
11
|
+
layout: {
|
|
12
|
+
cwd: environment.cwd,
|
|
13
|
+
homeDir: environment.homeDir,
|
|
14
|
+
t3codeHome: environment.env["T3CODE_HOME"],
|
|
15
|
+
},
|
|
16
|
+
baseDir: input.baseDir,
|
|
17
|
+
});
|
|
18
|
+
});
|
package/src/auth/local-origin.ts
CHANGED
|
@@ -26,7 +26,10 @@ export const makeT3LocalAuthOrigin = Effect.fn("makeT3LocalAuthOrigin")(function
|
|
|
26
26
|
const resolve = Effect.fn("T3LocalAuthOriginLive.resolve")(function* (
|
|
27
27
|
input?: LocalAuthOriginInput,
|
|
28
28
|
) {
|
|
29
|
-
const baseDir = resolveLocalBaseDir({ baseDir: input?.baseDir
|
|
29
|
+
const baseDir = yield* resolveLocalBaseDir({ baseDir: input?.baseDir }).pipe(
|
|
30
|
+
Effect.provideService(Environment, environment),
|
|
31
|
+
Effect.provideService(Path.Path, path),
|
|
32
|
+
);
|
|
30
33
|
if (input?.origin !== undefined) {
|
|
31
34
|
return yield* normalizeLocalOrigin(input.origin);
|
|
32
35
|
}
|
package/src/auth/local-token.ts
CHANGED
|
@@ -185,7 +185,10 @@ export const makeT3LocalAuthToken = Effect.fn("makeT3LocalAuthToken")(function*
|
|
|
185
185
|
);
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
const baseDir = resolveLocalBaseDir({ baseDir: input.baseDir
|
|
188
|
+
const baseDir = yield* resolveLocalBaseDir({ baseDir: input.baseDir }).pipe(
|
|
189
|
+
Effect.provideService(Environment, environment),
|
|
190
|
+
Effect.provideService(Path.Path, path),
|
|
191
|
+
);
|
|
189
192
|
const session = yield* issueLocalDatabaseSession({
|
|
190
193
|
dbPath: path.join(baseDir, "userdata", "state.sqlite"),
|
|
191
194
|
secretsDir: path.join(baseDir, "userdata", "secrets"),
|
package/src/auth/type.ts
CHANGED
package/src/bin.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { NodeEnvironmentLive } from "./environment/layer.ts";
|
|
|
10
10
|
import { T3InputLive } from "./cli/input/layer.ts";
|
|
11
11
|
import { T3OutputLive } from "./cli/output/layer.ts";
|
|
12
12
|
import { T3Output } from "./cli/output/service.ts";
|
|
13
|
-
import { AppLayer } from "./runtime.ts";
|
|
13
|
+
import { AppLayer } from "./runtime/layer.ts";
|
|
14
14
|
import { T3VersionBundledLive, T3VersionPackageJsonLive } from "./version/layer.ts";
|
|
15
15
|
import { T3Version } from "./version/service.ts";
|
|
16
16
|
|
package/src/cli/app.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { Command } from "effect/unstable/cli";
|
|
2
2
|
|
|
3
3
|
import { createAuthCommand } from "./auth.ts";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { createModelCommand } from "./model.ts";
|
|
5
|
+
import { createProjectCommand } from "./project.ts";
|
|
6
|
+
import { createThreadCommand } from "./thread.ts";
|
|
7
7
|
|
|
8
8
|
export function createCliCommand() {
|
|
9
9
|
return Command.make("t3cli").pipe(
|
|
10
10
|
Command.withDescription("non-interactive cli for running t3code server"),
|
|
11
11
|
Command.withSubcommands([
|
|
12
12
|
createAuthCommand(),
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
createModelCommand(),
|
|
14
|
+
createProjectCommand(),
|
|
15
|
+
createThreadCommand(),
|
|
16
16
|
]),
|
|
17
17
|
);
|
|
18
18
|
}
|
package/src/cli/auth-format.ts
CHANGED
|
@@ -25,6 +25,7 @@ export function formatAuthStatusHuman(input: {
|
|
|
25
25
|
}) {
|
|
26
26
|
return [
|
|
27
27
|
`url: ${input.config.url}`,
|
|
28
|
+
`local: ${input.config.local ? "yes" : "no"}`,
|
|
28
29
|
`authenticated: ${input.result.authenticated ? "yes" : "no"}`,
|
|
29
30
|
...(input.result.role !== undefined ? [`role: ${input.result.role}`] : []),
|
|
30
31
|
...(input.result.expiresAt !== undefined ? [`expires: ${input.result.expiresAt}`] : []),
|
|
@@ -39,5 +40,6 @@ export function formatAuthStatusJson(input: {
|
|
|
39
40
|
...input.result,
|
|
40
41
|
url: input.config.url,
|
|
41
42
|
source: input.config.source,
|
|
43
|
+
local: input.config.local,
|
|
42
44
|
};
|
|
43
45
|
}
|
package/src/cli/auth.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as Effect from "effect/Effect";
|
|
2
2
|
import * as Option from "effect/Option";
|
|
3
|
-
import {
|
|
3
|
+
import { Command, Flag } from "effect/unstable/cli";
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
formatAuthLocalHuman,
|
|
@@ -12,7 +12,8 @@ import {
|
|
|
12
12
|
import { T3Auth } from "../auth/service.ts";
|
|
13
13
|
import { T3Config } from "../config/service.ts";
|
|
14
14
|
import { Environment } from "../environment/service.ts";
|
|
15
|
-
import {
|
|
15
|
+
import { formatFlag } from "./flags.ts";
|
|
16
|
+
import { resolveOutputFormat } from "./output-format.ts";
|
|
16
17
|
import { T3Output } from "./output/service.ts";
|
|
17
18
|
|
|
18
19
|
export function createAuthCommand() {
|
|
@@ -25,17 +26,22 @@ export function createAuthCommand() {
|
|
|
25
26
|
const pairCommand = Command.make(
|
|
26
27
|
"pair",
|
|
27
28
|
{
|
|
28
|
-
url:
|
|
29
|
-
|
|
29
|
+
url: Flag.string("url"),
|
|
30
|
+
local: Flag.boolean("local"),
|
|
31
|
+
format: formatFlag,
|
|
30
32
|
},
|
|
31
|
-
({ url, format }) =>
|
|
33
|
+
({ url, local, format }) =>
|
|
32
34
|
Effect.gen(function* () {
|
|
33
35
|
const auth = yield* T3Auth;
|
|
34
36
|
const environment = yield* Environment;
|
|
35
37
|
const output = yield* T3Output;
|
|
36
38
|
const resolvedFormat = resolveOutputFormat(format, environment, "json");
|
|
37
39
|
const result = yield* auth.pair(url);
|
|
38
|
-
yield* auth.writeConfig(
|
|
40
|
+
yield* auth.writeConfig({
|
|
41
|
+
url: result.url,
|
|
42
|
+
token: result.token,
|
|
43
|
+
local,
|
|
44
|
+
});
|
|
39
45
|
if (resolvedFormat === "json") {
|
|
40
46
|
yield* output.printJson(result);
|
|
41
47
|
} else {
|
|
@@ -52,7 +58,7 @@ const localCommand = Command.make(
|
|
|
52
58
|
role: Flag.choice("role", ["owner", "client"] as const).pipe(Flag.withDefault("owner")),
|
|
53
59
|
label: Flag.string("label").pipe(Flag.withDefault("t3cli")),
|
|
54
60
|
subject: Flag.string("subject").pipe(Flag.withDefault("t3cli-local")),
|
|
55
|
-
format:
|
|
61
|
+
format: formatFlag,
|
|
56
62
|
},
|
|
57
63
|
({ baseDir, origin, role, label, subject, format }) =>
|
|
58
64
|
Effect.gen(function* () {
|
|
@@ -67,7 +73,11 @@ const localCommand = Command.make(
|
|
|
67
73
|
...(Option.isSome(baseDir) ? { baseDir: baseDir.value } : {}),
|
|
68
74
|
...(Option.isSome(origin) ? { origin: origin.value } : {}),
|
|
69
75
|
});
|
|
70
|
-
yield* auth.writeConfig(
|
|
76
|
+
yield* auth.writeConfig({
|
|
77
|
+
url: result.url,
|
|
78
|
+
token: result.token,
|
|
79
|
+
local: true,
|
|
80
|
+
});
|
|
71
81
|
if (resolvedFormat === "json") {
|
|
72
82
|
yield* output.printJson(formatAuthLocalJson(result));
|
|
73
83
|
} else {
|
|
@@ -79,7 +89,7 @@ const localCommand = Command.make(
|
|
|
79
89
|
const statusCommand = Command.make(
|
|
80
90
|
"status",
|
|
81
91
|
{
|
|
82
|
-
format:
|
|
92
|
+
format: formatFlag,
|
|
83
93
|
},
|
|
84
94
|
({ format }) =>
|
|
85
95
|
Effect.gen(function* () {
|
package/src/cli/error.ts
CHANGED
|
@@ -14,3 +14,10 @@ export class InvalidLimitError extends Schema.TaggedErrorClass<InvalidLimitError
|
|
|
14
14
|
value: Schema.String,
|
|
15
15
|
},
|
|
16
16
|
) {}
|
|
17
|
+
|
|
18
|
+
export class MissingThreadError extends Schema.TaggedErrorClass<MissingThreadError>()(
|
|
19
|
+
"MissingThreadError",
|
|
20
|
+
{
|
|
21
|
+
message: Schema.String,
|
|
22
|
+
},
|
|
23
|
+
) {}
|