@ozyman42/ozy-cli 0.4.8 → 0.4.9-darwin-x64.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 (207) hide show
  1. package/multi-call-binary +0 -0
  2. package/package.json +11 -52
  3. package/bin/ozy +0 -191
  4. package/bin/ozy-signing-agent +0 -191
  5. package/bin/ozy-ssh-keygen +0 -191
  6. package/bin/ozy-virtual-security-key +0 -191
  7. package/dist/commands/git/hosts.js +0 -18
  8. package/dist/commands/git/hosts.js.map +0 -1
  9. package/dist/commands/git/index.js +0 -8
  10. package/dist/commands/git/index.js.map +0 -1
  11. package/dist/commands/git/setup.js +0 -145
  12. package/dist/commands/git/setup.js.map +0 -1
  13. package/dist/commands/index.js +0 -13
  14. package/dist/commands/index.js.map +0 -1
  15. package/dist/commands/npm/index.js +0 -7
  16. package/dist/commands/npm/index.js.map +0 -1
  17. package/dist/commands/npm/setup/git-remote.js +0 -66
  18. package/dist/commands/npm/setup/git-remote.js.map +0 -1
  19. package/dist/commands/npm/setup/index.js +0 -168
  20. package/dist/commands/npm/setup/index.js.map +0 -1
  21. package/dist/commands/npm/setup/npm-auth.js +0 -62
  22. package/dist/commands/npm/setup/npm-auth.js.map +0 -1
  23. package/dist/commands/npm/setup/package-json-validate.js +0 -47
  24. package/dist/commands/npm/setup/package-json-validate.js.map +0 -1
  25. package/dist/commands/npm/setup/package-registry.js +0 -20
  26. package/dist/commands/npm/setup/package-registry.js.map +0 -1
  27. package/dist/commands/npm/setup/setup.test.js +0 -95
  28. package/dist/commands/npm/setup/setup.test.js.map +0 -1
  29. package/dist/commands/npm/setup/trusted-publishing.js +0 -84
  30. package/dist/commands/npm/setup/trusted-publishing.js.map +0 -1
  31. package/dist/commands/npm/setup/workflow.js +0 -19
  32. package/dist/commands/npm/setup/workflow.js.map +0 -1
  33. package/dist/commands/ssh/get-sk-credential.js +0 -104
  34. package/dist/commands/ssh/get-sk-credential.js.map +0 -1
  35. package/dist/commands/ssh/index.js +0 -7
  36. package/dist/commands/ssh/index.js.map +0 -1
  37. package/dist/commands/upgrade.js +0 -199
  38. package/dist/commands/upgrade.js.map +0 -1
  39. package/dist/common/command.js +0 -15
  40. package/dist/common/command.js.map +0 -1
  41. package/dist/common/constants.js +0 -25
  42. package/dist/common/constants.js.map +0 -1
  43. package/dist/common/effective-modules-extensions.js +0 -13
  44. package/dist/common/effective-modules-extensions.js.map +0 -1
  45. package/dist/common/log.js +0 -4
  46. package/dist/common/log.js.map +0 -1
  47. package/dist/common/render-caller-tree.js +0 -20
  48. package/dist/common/render-caller-tree.js.map +0 -1
  49. package/dist/entrypoints/ozy-signing-agent.js +0 -48
  50. package/dist/entrypoints/ozy-signing-agent.js.map +0 -1
  51. package/dist/entrypoints/ozy-ssh-keygen.js +0 -9
  52. package/dist/entrypoints/ozy-ssh-keygen.js.map +0 -1
  53. package/dist/entrypoints/ozy-virtual-security-key.js +0 -18
  54. package/dist/entrypoints/ozy-virtual-security-key.js.map +0 -1
  55. package/dist/entrypoints/ozy.js +0 -3
  56. package/dist/entrypoints/ozy.js.map +0 -1
  57. package/dist/index.js +0 -2
  58. package/dist/index.js.map +0 -1
  59. package/dist/internal/thing.js +0 -4
  60. package/dist/internal/thing.js.map +0 -1
  61. package/dist/modules/cli/agent-client/impl.js +0 -109
  62. package/dist/modules/cli/agent-client/impl.js.map +0 -1
  63. package/dist/modules/cli/agent-client/interface.js +0 -11
  64. package/dist/modules/cli/agent-client/interface.js.map +0 -1
  65. package/dist/modules/cli/git/impl.js +0 -124
  66. package/dist/modules/cli/git/impl.js.map +0 -1
  67. package/dist/modules/cli/git/interface.js +0 -3
  68. package/dist/modules/cli/git/interface.js.map +0 -1
  69. package/dist/modules/cli/git/submodule/fix.js +0 -257
  70. package/dist/modules/cli/git/submodule/fix.js.map +0 -1
  71. package/dist/modules/cli/git/submodule/git-state.js +0 -154
  72. package/dist/modules/cli/git/submodule/git-state.js.map +0 -1
  73. package/dist/modules/cli/git/submodule/gitmodules.js +0 -113
  74. package/dist/modules/cli/git/submodule/gitmodules.js.map +0 -1
  75. package/dist/modules/cli/git/submodule/printer.js +0 -232
  76. package/dist/modules/cli/git/submodule/printer.js.map +0 -1
  77. package/dist/modules/cli/git/submodule/resolve-git-dir.js +0 -16
  78. package/dist/modules/cli/git/submodule/resolve-git-dir.js.map +0 -1
  79. package/dist/modules/cli/github/impl.js +0 -137
  80. package/dist/modules/cli/github/impl.js.map +0 -1
  81. package/dist/modules/cli/github/interface.js +0 -2
  82. package/dist/modules/cli/github/interface.js.map +0 -1
  83. package/dist/modules/cli/index.js +0 -9
  84. package/dist/modules/cli/index.js.map +0 -1
  85. package/dist/modules/common/crypto/impl.js +0 -133
  86. package/dist/modules/common/crypto/impl.js.map +0 -1
  87. package/dist/modules/common/crypto/interface.js +0 -2
  88. package/dist/modules/common/crypto/interface.js.map +0 -1
  89. package/dist/modules/common/index.js +0 -10
  90. package/dist/modules/common/index.js.map +0 -1
  91. package/dist/modules/common/kep-map-store/impl.js +0 -42
  92. package/dist/modules/common/kep-map-store/impl.js.map +0 -1
  93. package/dist/modules/common/kep-map-store/interface.js +0 -2
  94. package/dist/modules/common/kep-map-store/interface.js.map +0 -1
  95. package/dist/modules/common/os-platform/caller-info.js +0 -132
  96. package/dist/modules/common/os-platform/caller-info.js.map +0 -1
  97. package/dist/modules/common/os-platform/impl.js +0 -95
  98. package/dist/modules/common/os-platform/impl.js.map +0 -1
  99. package/dist/modules/common/os-platform/interface.js +0 -2
  100. package/dist/modules/common/os-platform/interface.js.map +0 -1
  101. package/dist/modules/common/os-platform/virtual-hid/index.js +0 -12
  102. package/dist/modules/common/os-platform/virtual-hid/index.js.map +0 -1
  103. package/dist/modules/common/os-platform/virtual-hid/linux.js +0 -5
  104. package/dist/modules/common/os-platform/virtual-hid/linux.js.map +0 -1
  105. package/dist/modules/common/os-platform/virtual-hid/mac.js +0 -119
  106. package/dist/modules/common/os-platform/virtual-hid/mac.js.map +0 -1
  107. package/dist/modules/common/os-platform/virtual-hid/windows.js +0 -5
  108. package/dist/modules/common/os-platform/virtual-hid/windows.js.map +0 -1
  109. package/dist/modules/common/ssh-config/impl.js +0 -116
  110. package/dist/modules/common/ssh-config/impl.js.map +0 -1
  111. package/dist/modules/common/ssh-config/interface.js +0 -10
  112. package/dist/modules/common/ssh-config/interface.js.map +0 -1
  113. package/dist/modules/ssh-agent/index.js +0 -8
  114. package/dist/modules/ssh-agent/index.js.map +0 -1
  115. package/dist/modules/ssh-agent/session/impl.js +0 -265
  116. package/dist/modules/ssh-agent/session/impl.js.map +0 -1
  117. package/dist/modules/ssh-agent/session/interface-rpc.js +0 -20
  118. package/dist/modules/ssh-agent/session/interface-rpc.js.map +0 -1
  119. package/dist/modules/ssh-agent/session/interface.js +0 -32
  120. package/dist/modules/ssh-agent/session/interface.js.map +0 -1
  121. package/dist/modules/ssh-agent/session/passkey-prf-page.js +0 -204
  122. package/dist/modules/ssh-agent/session/passkey-prf-page.js.map +0 -1
  123. package/dist/modules/ssh-agent/session/prf-flow.js +0 -103
  124. package/dist/modules/ssh-agent/session/prf-flow.js.map +0 -1
  125. package/dist/modules/ssh-agent/ssh-agent/impl.js +0 -117
  126. package/dist/modules/ssh-agent/ssh-agent/impl.js.map +0 -1
  127. package/dist/modules/ssh-agent/ssh-agent/interface.js +0 -2
  128. package/dist/modules/ssh-agent/ssh-agent/interface.js.map +0 -1
  129. package/dist/scripts/build.js +0 -410
  130. package/dist/scripts/build.js.map +0 -1
  131. package/dist/scripts/check-npm-version.js +0 -8
  132. package/dist/scripts/check-npm-version.js.map +0 -1
  133. package/dist/scripts/kill-existing-agent.js +0 -21
  134. package/dist/scripts/kill-existing-agent.js.map +0 -1
  135. package/dist/scripts/publish.js +0 -46
  136. package/dist/scripts/publish.js.map +0 -1
  137. package/src/commands/git/hosts.ts +0 -20
  138. package/src/commands/git/index.ts +0 -9
  139. package/src/commands/git/setup.ts +0 -182
  140. package/src/commands/index.ts +0 -15
  141. package/src/commands/npm/index.ts +0 -8
  142. package/src/commands/npm/setup/git-remote.ts +0 -78
  143. package/src/commands/npm/setup/index.ts +0 -189
  144. package/src/commands/npm/setup/npm-auth.ts +0 -58
  145. package/src/commands/npm/setup/package-json-validate.ts +0 -68
  146. package/src/commands/npm/setup/package-registry.ts +0 -24
  147. package/src/commands/npm/setup/publish-workflow.yml +0 -35
  148. package/src/commands/npm/setup/setup.test.ts +0 -117
  149. package/src/commands/npm/setup/trusted-publishing.ts +0 -106
  150. package/src/commands/npm/setup/workflow.ts +0 -20
  151. package/src/commands/ssh/get-sk-credential.ts +0 -110
  152. package/src/commands/ssh/index.ts +0 -8
  153. package/src/commands/upgrade.ts +0 -220
  154. package/src/common/command.ts +0 -16
  155. package/src/common/constants.ts +0 -26
  156. package/src/common/effective-modules-extensions.ts +0 -24
  157. package/src/common/log.ts +0 -3
  158. package/src/common/render-caller-tree.ts +0 -22
  159. package/src/entrypoints/ozy-signing-agent.ts +0 -48
  160. package/src/entrypoints/ozy-ssh-keygen.ts +0 -10
  161. package/src/entrypoints/ozy-virtual-security-key.ts +0 -21
  162. package/src/entrypoints/ozy.ts +0 -2
  163. package/src/index.ts +0 -1
  164. package/src/internal/thing.ts +0 -3
  165. package/src/modules/cli/agent-client/impl.ts +0 -152
  166. package/src/modules/cli/agent-client/interface.ts +0 -17
  167. package/src/modules/cli/git/impl.ts +0 -133
  168. package/src/modules/cli/git/interface.ts +0 -23
  169. package/src/modules/cli/git/submodule/fix.ts +0 -298
  170. package/src/modules/cli/git/submodule/git-state.ts +0 -217
  171. package/src/modules/cli/git/submodule/gitmodules.ts +0 -126
  172. package/src/modules/cli/git/submodule/printer.ts +0 -256
  173. package/src/modules/cli/git/submodule/resolve-git-dir.ts +0 -14
  174. package/src/modules/cli/github/impl.ts +0 -169
  175. package/src/modules/cli/github/interface.ts +0 -29
  176. package/src/modules/cli/index.ts +0 -16
  177. package/src/modules/common/crypto/impl.ts +0 -173
  178. package/src/modules/common/crypto/interface.ts +0 -20
  179. package/src/modules/common/index.ts +0 -19
  180. package/src/modules/common/kep-map-store/impl.ts +0 -47
  181. package/src/modules/common/kep-map-store/interface.ts +0 -9
  182. package/src/modules/common/os-platform/caller-info.ts +0 -152
  183. package/src/modules/common/os-platform/impl.ts +0 -91
  184. package/src/modules/common/os-platform/interface.ts +0 -16
  185. package/src/modules/common/os-platform/virtual-hid/index.ts +0 -12
  186. package/src/modules/common/os-platform/virtual-hid/linux.ts +0 -7
  187. package/src/modules/common/os-platform/virtual-hid/mac.ts +0 -150
  188. package/src/modules/common/os-platform/virtual-hid/windows.ts +0 -7
  189. package/src/modules/common/ssh-config/impl.ts +0 -130
  190. package/src/modules/common/ssh-config/interface.ts +0 -33
  191. package/src/modules/ssh-agent/index.ts +0 -13
  192. package/src/modules/ssh-agent/session/agent-notes.md +0 -210
  193. package/src/modules/ssh-agent/session/design.md +0 -2
  194. package/src/modules/ssh-agent/session/html-refactor.md +0 -23
  195. package/src/modules/ssh-agent/session/impl.ts +0 -328
  196. package/src/modules/ssh-agent/session/interface-rpc.ts +0 -24
  197. package/src/modules/ssh-agent/session/interface.ts +0 -62
  198. package/src/modules/ssh-agent/session/passkey-prf-page.ts +0 -224
  199. package/src/modules/ssh-agent/session/prf-flow.ts +0 -152
  200. package/src/modules/ssh-agent/ssh-agent/impl.ts +0 -136
  201. package/src/modules/ssh-agent/ssh-agent/interface.ts +0 -9
  202. package/src/scripts/build.ts +0 -504
  203. package/src/scripts/check-npm-version.ts +0 -7
  204. package/src/scripts/command-launcher.js.ejs +0 -168
  205. package/src/scripts/kill-existing-agent.ts +0 -22
  206. package/src/scripts/publish.ts +0 -47
  207. package/src/scripts/windows-bin-shims.md +0 -1104
@@ -1,48 +0,0 @@
1
- import { appendFileSync } from "node:fs";
2
- import { Effect, Layer, pipe } from "effect";
3
- import { OSPlatformImpl } from "@/modules/common/os-platform/impl";
4
- import { CryptoImpl } from "@/modules/common/crypto/impl";
5
- import { KeyMapStoreImpl } from "@/modules/common/kep-map-store/impl";
6
- import { SSHConfigImpl } from "@/modules/common/ssh-config/impl";
7
- import { SSHAgentImpl } from "@/modules/ssh-agent/ssh-agent/impl";
8
- import { SessionImpl } from "@/modules/ssh-agent/session/impl";
9
- import { AGENT_LOG_FILE_PATH, AGENT_PID_FILE_PATH, AGENT_PORT_FILE_PATH, AGENT_SOCK_FILE_PATH } from "@/common/constants";
10
- import { rmSync } from "node:fs";
11
-
12
- const origLog = console.log.bind(console);
13
- const origError = console.error.bind(console);
14
- const origWarn = console.warn.bind(console);
15
-
16
- function logToFile(...args: any[]) {
17
- try {
18
- appendFileSync(AGENT_LOG_FILE_PATH, args.map(arg => {
19
- try { return JSON.stringify(arg) }
20
- catch(e) { return String(e); }
21
- }).join(' ') + '\n');
22
- } catch {}
23
- }
24
-
25
- console.log = (...args: any[]) => { logToFile(...args); origLog(...args); };
26
- console.error = (...args: any[]) => { logToFile(...args); origError(...args); };
27
- console.warn = (...args: any[]) => { logToFile(...args); origWarn(...args); };
28
-
29
- function cleanup() {
30
- try { rmSync(AGENT_PID_FILE_PATH); } catch {}
31
- try { rmSync(AGENT_PORT_FILE_PATH); } catch {}
32
- try { rmSync(AGENT_SOCK_FILE_PATH); } catch {}
33
- }
34
-
35
- process.on("exit", cleanup);
36
- process.on("SIGTERM", () => { cleanup(); process.exit(0); });
37
- process.on("SIGINT", () => { cleanup(); process.exit(0); });
38
-
39
- pipe(
40
- SSHAgentImpl.ServiceLayer,
41
- Layer.provideMerge(SessionImpl.makeRpcLayer()),
42
- Layer.provideMerge(KeyMapStoreImpl.Layer),
43
- Layer.provideMerge(SSHConfigImpl.Layer),
44
- Layer.provideMerge(CryptoImpl.Layer),
45
- Layer.provideMerge(OSPlatformImpl.Layer),
46
- Layer.launch,
47
- Effect.runPromise
48
- );
@@ -1,10 +0,0 @@
1
- import { AGENT_SOCK_FILE_PATH } from "@/common/constants";
2
-
3
- const result = Bun.spawnSync(["ssh-keygen", ...Bun.argv.slice(2)], {
4
- stdin: "inherit",
5
- stdout: "inherit",
6
- stderr: "inherit",
7
- env: { ...process.env, SSH_AUTH_SOCK: AGENT_SOCK_FILE_PATH },
8
- });
9
-
10
- process.exit(result.exitCode ?? 1);
@@ -1,21 +0,0 @@
1
- import { Effect } from "effect";
2
- import { appendFileSync } from "node:fs";
3
- import { commonModules } from "@/modules/common";
4
- import { OSPlatformImpl } from "@/modules/common/os-platform/impl";
5
- import { VIRTUAL_KEY_LOG_FILE_PATH } from "@/common/constants";
6
-
7
- const program = Effect.gen(function* () {
8
- const platform = yield* commonModules.OSPlatform;
9
- yield* platform.registerVirtualHID((data) =>
10
- Effect.sync(() => {
11
- appendFileSync(VIRTUAL_KEY_LOG_FILE_PATH, `[vhid] received ${data.length} bytes: ${data.toString('hex')}\n`);
12
- return Buffer.alloc(64);
13
- })
14
- );
15
- yield* Effect.never;
16
- }).pipe(Effect.provide(OSPlatformImpl.Layer));
17
-
18
- Effect.runPromise(program).catch(e => {
19
- console.error('Virtual security key failed:', e);
20
- process.exit(1);
21
- });
@@ -1,2 +0,0 @@
1
- // TODO: we should move commands to its own layer
2
- import '@/commands';
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,3 +0,0 @@
1
- export function time() {
2
- console.log("is with us all");
3
- }
@@ -1,152 +0,0 @@
1
- import { Effect, Layer, Match, Option, pipe, Data, FileSystem, Schedule, Result } from "effect";
2
- import { effunct, implementing, type EffectGen } from "effective-modules";
3
- import { FetchHttpClient } from "effect/unstable/http";
4
- import { RpcClient, RpcSerialization } from "effect/unstable/rpc";
5
- import { AgentRpcGroup } from "@/modules/ssh-agent/session/interface-rpc";
6
- import { cliModules } from "..";
7
- import { type AgentRpcClient, type IAgentClient, AgentClientError } from "./interface";
8
- import { AGENT_CMD_PATH, AGENT_PID_FILE_PATH, AGENT_PORT_FILE_PATH, AGENT_SOCK_FILE_PATH, CURRENT_VERSION } from "@/common/constants";
9
- import { readFileSync, rmSync } from "node:fs";
10
- import { log } from "@/common/log";
11
-
12
- function makeAgentClientLayer(port: number) {
13
- return pipe(
14
- RpcClient.layerProtocolHttp({ url: `http://localhost:${port}/rpc` }),
15
- Layer.provideMerge(RpcSerialization.layerJson),
16
- Layer.provideMerge(FetchHttpClient.layer)
17
- );
18
- }
19
-
20
- class NoResponseError extends Data.TaggedError("NoResponseError")<{}> {
21
- public toString() { return "No response from agent."; }
22
- }
23
-
24
- class NonMatchingVersionError extends Data.TaggedError("NonMatchingVersionError")<{
25
- cliVersion: string;
26
- agentVersion: string;
27
- }> {
28
- public toString() {
29
- return `Agent running but with mismatched version ${this.agentVersion} compared to CLI version ${this.cliVersion}`;
30
- }
31
- }
32
-
33
- type PingError = NoResponseError | NonMatchingVersionError;
34
-
35
- export class AgentClientImpl extends implementing(cliModules.AgentClient).uses(FileSystem.FileSystem) implements IAgentClient {
36
- private *readPortFromFile(): EffectGen<Option.Option<number>, never> {
37
- const result = yield* pipe(
38
- this.getDependency(FileSystem.FileSystem).readFileString(AGENT_PORT_FILE_PATH),
39
- Effect.result
40
- );
41
- if (Result.isFailure(result)) return Option.none();
42
- const port = parseInt(result.success.trim());
43
- if (isNaN(port) || port <= 0 || port > 65535) {
44
- log(`Read out of bounds port ${port}`);
45
- return Option.none();
46
- }
47
- return Option.some(port);
48
- }
49
-
50
- private *pingAtPort(port: number): EffectGen<void, PingError> {
51
- yield* Effect.scoped(
52
- Effect.gen(function* () {
53
- const client = yield* RpcClient.make(AgentRpcGroup);
54
- const { version } = yield* pipe(
55
- client.GetVersion({}),
56
- Effect.catchTag("RpcClientError", () => new NoResponseError())
57
- );
58
- if (version !== CURRENT_VERSION)
59
- yield* new NonMatchingVersionError({ cliVersion: CURRENT_VERSION, agentVersion: version });
60
- })
61
- ).pipe(Effect.provide(makeAgentClientLayer(port)));
62
- }
63
-
64
- private *ping(): EffectGen<{ port: number }, PingError> {
65
- const portOption = yield* effunct(this.readPortFromFile)();
66
- if (Option.isNone(portOption)) return yield* new NoResponseError();
67
- const port = portOption.value;
68
- yield* effunct(this.pingAtPort)(port);
69
- return { port };
70
- }
71
-
72
- private *waitForPidFile(expectedPid: number): EffectGen<void, string> {
73
- const fs = this.getDependency(FileSystem.FileSystem);
74
- yield* pipe(
75
- Effect.retry(
76
- pipe(
77
- fs.readFileString(AGENT_PID_FILE_PATH),
78
- Effect.catchTag("PlatformError", () => Effect.fail("pid file not yet written")),
79
- Effect.flatMap(content => {
80
- const pid = parseInt(content.trim());
81
- return pid === expectedPid
82
- ? Effect.void
83
- : Effect.fail(`PID mismatch: expected ${expectedPid}, got ${pid}`);
84
- })
85
- ),
86
- Schedule.spaced("50 millis")
87
- ),
88
- Effect.timeout("5 seconds"),
89
- Effect.mapError(() => "Agent did not start within 5 seconds")
90
- );
91
- }
92
-
93
- private *startAgent(): EffectGen<{ pid: number; port: number }, string | PingError> {
94
- const proc = Bun.spawn([AGENT_CMD_PATH], { stdout: "ignore", stderr: "ignore" });
95
- yield* effunct(this.waitForPidFile)(proc.pid);
96
- const { port } = yield* effunct(this.ping)();
97
- log(`Started agent at PID ${proc.pid}`);
98
- return { pid: proc.pid, port };
99
- }
100
-
101
- *killIfRunning(): EffectGen<void, string> {
102
- try {
103
- // Throws if file missing
104
- const pidFileContent = readFileSync(AGENT_PID_FILE_PATH, "utf-8");
105
- const PID = parseInt(pidFileContent.trim());
106
- // If doesn't exist, below line throws
107
- process.kill(PID, 0);
108
- log(`Killing agent on PID ${PID}`);
109
- process.kill(PID, "SIGTERM");
110
- yield* Effect.sleep(500);
111
- } catch { }
112
- try { rmSync(AGENT_PID_FILE_PATH); } catch {}
113
- try { rmSync(AGENT_PORT_FILE_PATH); } catch {}
114
- try { rmSync(AGENT_SOCK_FILE_PATH); } catch {}
115
- }
116
-
117
- private *ensureRunning(): EffectGen<{ port: number }, string> {
118
- const pingResult = yield* pipe(effunct(this.ping)(), Effect.result);
119
- if (Result.isSuccess(pingResult)) return pingResult.success;
120
- log(pingResult.failure.toString());
121
- yield* Match.value(pingResult.failure).pipe(
122
- Match.tag("NonMatchingVersionError", () => effunct(this.killIfRunning)()),
123
- Match.tag("NoResponseError", () => effunct(this.killIfRunning)()),
124
- Match.exhaustive
125
- );
126
- return yield* pipe(
127
- effunct(this.startAgent)(),
128
- Effect.mapError(err =>
129
- typeof err === "string" ?
130
- err :
131
- `Failed to start agent due to ${err.name}: ${err.toString()}`
132
- )
133
- );
134
- }
135
-
136
- *usingClient<A, E>(use: (client: AgentRpcClient) => EffectGen<A, E>): EffectGen<A, AgentClientError<E>> {
137
- const { port } = yield* pipe(
138
- effunct(this.ensureRunning)(),
139
- Effect.mapError(reason => new AgentClientError.ClientError({ reason }))
140
- );
141
- return yield* pipe(
142
- Effect.scoped(
143
- Effect.gen(function* () {
144
- const client = yield* RpcClient.make(AgentRpcGroup);
145
- return yield* use(client);
146
- })
147
- ),
148
- Effect.provide(makeAgentClientLayer(port)),
149
- Effect.mapError(e => new AgentClientError.UsageError({ cause: e }))
150
- );
151
- }
152
- }
@@ -1,17 +0,0 @@
1
- import type { EffectGen } from "effective-modules";
2
- import type { AgentRpcGroup } from "@/modules/ssh-agent/session/interface-rpc";
3
- import type { RpcClient, RpcClientError as RpcClientErrorModule, RpcGroup } from "effect/unstable/rpc";
4
- import { Data } from "effect";
5
-
6
- export type AgentRpcClient = RpcClient.RpcClient<RpcGroup.Rpcs<AgentRpcGroup>, RpcClientErrorModule.RpcClientError>;
7
-
8
- export namespace AgentClientError {
9
- export class UsageError<E> extends Data.TaggedError("AgentClientUsageError")<{ readonly cause: E }> {}
10
- export class ClientError extends Data.TaggedError("AgentClientError")<{ readonly reason: string }> {}
11
- }
12
- export type AgentClientError<E> = AgentClientError.UsageError<E> | AgentClientError.ClientError;
13
-
14
- export interface IAgentClient {
15
- killIfRunning(): EffectGen<void, string>;
16
- usingClient<A, E>(use: (client: AgentRpcClient) => EffectGen<A, E>): EffectGen<A, AgentClientError<E>>;
17
- }
@@ -1,133 +0,0 @@
1
- import { implementing, type EffectGen } from "effective-modules";
2
- import { cliModules } from "..";
3
- import { commonModules } from "@/modules/common";
4
- import { $ } from 'bun';
5
- import type { IGit, SetupRepoInput } from "./interface";
6
- import { Effect, Option, pipe } from "effect";
7
- import { existsSync } from "node:fs";
8
- import { resolve } from "node:path";
9
- import { SSH_KEYGEN_CMD_PATH, STANDARD_REMOTE_PREFIX } from "@/common/constants";
10
- import { Gitmodules } from "./submodule/gitmodules";
11
- import { readGitState } from "./submodule/git-state";
12
- import { fixGitConfig, fixModuleDirs, fixIndexGitlinks } from "./submodule/fix";
13
- import { printSyncState, printFixes } from "./submodule/printer";
14
-
15
- export class GitImpl extends implementing(cliModules.Git).uses(commonModules.OSPlatform, commonModules.SSHConfig) implements IGit {
16
- private parseOwnerRepo(remote: string): Effect.Effect<{ owner: string; repo: string }, string> {
17
- const sshMatch = remote.match(/^git@[^:]+:([^/]+)\/(.+?)(?:\.git)?$/);
18
- if (sshMatch) return Effect.succeed({ owner: sshMatch[1]!, repo: sshMatch[2]! });
19
- const httpsMatch = remote.match(/^https?:\/\/[^/]+\/([^/]+)\/(.+?)(?:\.git)?$/);
20
- if (httpsMatch) return Effect.succeed({ owner: httpsMatch[1]!, repo: httpsMatch[2]! });
21
- return Effect.fail(`Cannot parse owner/repo from remote: ${remote}`);
22
- }
23
-
24
- *resolveOwnerAndRepo(maybeOwnerAndRepo: Option.Option<string>): EffectGen<{ owner: string; repo: string; }, string> {
25
- if (Option.isSome(maybeOwnerAndRepo)) {
26
- const parts = maybeOwnerAndRepo.value.split('/');
27
- const [owner, repo] = parts;
28
- if (parts.length !== 2 || !owner || !repo)
29
- return yield* Effect.fail(`Cannot parse remote error: Expected "owner/repo", got "${maybeOwnerAndRepo.value}"`);
30
- return { owner, repo };
31
- }
32
-
33
- if (!(yield* this.isGitRepository())) {
34
- yield* Effect.fail(`not in git repo: Current directory is not a git repository`);
35
- }
36
-
37
- const remoteOption = yield* this.getRemoteOrigin();
38
- if (Option.isNone(remoteOption)) {
39
- return yield* Effect.fail(`no remote origin: No remote.origin.url — pass owner/repo as argument to clone instead`);
40
- }
41
-
42
- return yield* this.parseOwnerRepo(remoteOption.value);
43
- }
44
- *isGitRepository(): EffectGen<boolean> {
45
- return yield* pipe(
46
- Effect.tryPromise(async () => {
47
- await $`git rev-parse --is-inside-work-tree`.quiet();
48
- return true;
49
- }),
50
- Effect.catchTag("UnknownError", () => Effect.succeed(false))
51
- );
52
- }
53
- *getRemoteOrigin(): EffectGen<Option.Option<string>> {
54
- return yield* pipe(
55
- Effect.tryPromise(async() => {
56
- return Option.some((await $`git config --get remote.origin.url`.quiet()).text().trim());
57
- }),
58
- Effect.catchTag("UnknownError", () => Effect.succeed(Option.none()))
59
- )
60
- }
61
- *clone(owner: string, repo: string): EffectGen<void, string> {
62
- const result = Bun.spawnSync(['git', 'clone', '--recurse-submodules', `${STANDARD_REMOTE_PREFIX}${owner}/${repo}.git`], { stdout: 'inherit', stderr: 'inherit' });
63
- if (result.exitCode !== 0)
64
- return yield* Effect.fail(`git clone failed with exit code ${result.exitCode}`);
65
- process.chdir(`./${repo}`);
66
- }
67
- *setLocalConfig(key: string, value: string): EffectGen<void, string> {
68
- yield* Effect.tryPromise({
69
- try: async () => { await $`git config --local ${key} ${value}`.quiet(); },
70
- catch: (e) => `git config ${key}: ${e instanceof Error ? e.message : String(e)}`,
71
- });
72
- }
73
- private *configureRepo({ dir, remoteURL, user, pubkeyPath }: SetupRepoInput): EffectGen<void, string> {
74
- yield* Effect.log(`Configuring ${dir}`);
75
- yield* Effect.tryPromise({
76
- try: async () => {
77
- const configs: [string, string][] = [
78
- ['remote.origin.url', remoteURL],
79
- ['user.name', user.name],
80
- ['user.email', user.email],
81
- ['user.signingkey', pubkeyPath],
82
- ['gpg.format', 'ssh'],
83
- ['gpg.ssh.program', SSH_KEYGEN_CMD_PATH],
84
- ['commit.gpgsign', 'true'],
85
- ['tag.gpgsign', 'true'],
86
- ];
87
- for (const [k, v] of configs) {
88
- const r = Bun.spawnSync(['git', 'config', '--local', k, v], { cwd: dir, stdout: 'pipe', stderr: 'pipe' });
89
- if (r.exitCode !== 0) {
90
- const err = new TextDecoder().decode(r.stderr);
91
- throw new Error(`git config ${k} failed: ${err.trim()}`);
92
- }
93
- }
94
- },
95
- catch: (e) => e instanceof Error ? e.message : String(e),
96
- });
97
- }
98
- private *syncSubmoduleState(repoRoot: string, topLevelRoot: string): EffectGen<Gitmodules, string> {
99
- const gitmodules = yield* Gitmodules.fromRepoRoot(repoRoot);
100
- if (gitmodules.list.length === 0) return gitmodules;
101
- const submodulePaths = gitmodules.list.map(m => m.path);
102
- const state = yield* readGitState(repoRoot, submodulePaths);
103
- printSyncState(gitmodules, state);
104
- const fixResults = yield* Effect.all(
105
- [
106
- fixGitConfig(repoRoot, gitmodules),
107
- fixModuleDirs(repoRoot, gitmodules, state.moduleDirs, state.orphanModuleDirs, topLevelRoot),
108
- fixIndexGitlinks(repoRoot, gitmodules, state.index),
109
- ],
110
- { concurrency: "unbounded" },
111
- );
112
- printFixes(fixResults.flat());
113
- return gitmodules;
114
- }
115
- *setupRepo(input: SetupRepoInput): EffectGen<void, string> {
116
- yield* this.setupRepoAt(input, input.dir);
117
- }
118
- private *setupRepoAt(input: SetupRepoInput, topLevelRoot: string): EffectGen<void, string> {
119
- yield* this.configureRepo(input);
120
- if (!existsSync(resolve(input.dir, '.gitmodules'))) return;
121
- const gitmodules = yield* this.syncSubmoduleState(input.dir, topLevelRoot);
122
- for (const m of gitmodules.list) {
123
- const subDir = resolve(input.dir, m.path);
124
- if (!existsSync(subDir)) continue;
125
- yield* this.setupRepoAt({
126
- dir: subDir,
127
- remoteURL: m.url,
128
- user: input.user,
129
- pubkeyPath: input.pubkeyPath
130
- }, topLevelRoot);
131
- }
132
- }
133
- }
@@ -1,23 +0,0 @@
1
- import { type EffectGen} from "effective-modules";
2
- import { Option } from "effect";
3
-
4
- export interface GitUser {
5
- name: string;
6
- email: string;
7
- }
8
-
9
- export interface SetupRepoInput {
10
- dir: string;
11
- user: GitUser;
12
- pubkeyPath: string;
13
- remoteURL: string;
14
- }
15
-
16
- export interface IGit {
17
- isGitRepository(): EffectGen<boolean>;
18
- getRemoteOrigin(): EffectGen<Option.Option<string>>;
19
- resolveOwnerAndRepo(maybeOwnerAndRepo: Option.Option<string>): EffectGen<{owner: string; repo: string;}, string>;
20
- clone(owner: string, repo: string): EffectGen<void, string>;
21
- setLocalConfig(key: string, value: string): EffectGen<void, string>;
22
- setupRepo(params: SetupRepoInput): EffectGen<void, string>;
23
- }