crewly 1.20.123 → 1.20.124

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 (165) hide show
  1. package/dist/backend/backend/src/constants.d.ts +118 -0
  2. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  3. package/dist/backend/backend/src/constants.js +118 -0
  4. package/dist/backend/backend/src/constants.js.map +1 -1
  5. package/dist/backend/backend/src/controllers/harness/harness.controller.d.ts +54 -0
  6. package/dist/backend/backend/src/controllers/harness/harness.controller.d.ts.map +1 -0
  7. package/dist/backend/backend/src/controllers/harness/harness.controller.js +204 -0
  8. package/dist/backend/backend/src/controllers/harness/harness.controller.js.map +1 -0
  9. package/dist/backend/backend/src/controllers/harness/harness.routes.d.ts +27 -0
  10. package/dist/backend/backend/src/controllers/harness/harness.routes.d.ts.map +1 -0
  11. package/dist/backend/backend/src/controllers/harness/harness.routes.js +43 -0
  12. package/dist/backend/backend/src/controllers/harness/harness.routes.js.map +1 -0
  13. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  14. package/dist/backend/backend/src/routes/api.routes.js +4 -0
  15. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  16. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +5 -0
  17. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  18. package/dist/backend/backend/src/services/agent/agent-registration.service.js +7 -0
  19. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  20. package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts +2 -1
  21. package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -1
  22. package/dist/backend/backend/src/services/cloud/cloud-client.service.js +4 -3
  23. package/dist/backend/backend/src/services/cloud/cloud-client.service.js.map +1 -1
  24. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.d.ts.map +1 -1
  25. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js +14 -0
  26. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js.map +1 -1
  27. package/dist/backend/backend/src/services/harness/claude-config.utils.d.ts +67 -0
  28. package/dist/backend/backend/src/services/harness/claude-config.utils.d.ts.map +1 -0
  29. package/dist/backend/backend/src/services/harness/claude-config.utils.js +118 -0
  30. package/dist/backend/backend/src/services/harness/claude-config.utils.js.map +1 -0
  31. package/dist/backend/backend/src/services/harness/harness-api-key.service.d.ts +99 -0
  32. package/dist/backend/backend/src/services/harness/harness-api-key.service.d.ts.map +1 -0
  33. package/dist/backend/backend/src/services/harness/harness-api-key.service.js +157 -0
  34. package/dist/backend/backend/src/services/harness/harness-api-key.service.js.map +1 -0
  35. package/dist/backend/backend/src/services/harness/harness-credentials.store.d.ts +135 -0
  36. package/dist/backend/backend/src/services/harness/harness-credentials.store.d.ts.map +1 -0
  37. package/dist/backend/backend/src/services/harness/harness-credentials.store.js +208 -0
  38. package/dist/backend/backend/src/services/harness/harness-credentials.store.js.map +1 -0
  39. package/dist/backend/backend/src/services/harness/harness-exec.utils.d.ts +85 -0
  40. package/dist/backend/backend/src/services/harness/harness-exec.utils.d.ts.map +1 -0
  41. package/dist/backend/backend/src/services/harness/harness-exec.utils.js +183 -0
  42. package/dist/backend/backend/src/services/harness/harness-exec.utils.js.map +1 -0
  43. package/dist/backend/backend/src/services/harness/harness-install.service.d.ts +106 -0
  44. package/dist/backend/backend/src/services/harness/harness-install.service.d.ts.map +1 -0
  45. package/dist/backend/backend/src/services/harness/harness-install.service.js +205 -0
  46. package/dist/backend/backend/src/services/harness/harness-install.service.js.map +1 -0
  47. package/dist/backend/backend/src/services/harness/harness-registry.d.ts +86 -0
  48. package/dist/backend/backend/src/services/harness/harness-registry.d.ts.map +1 -0
  49. package/dist/backend/backend/src/services/harness/harness-registry.js +121 -0
  50. package/dist/backend/backend/src/services/harness/harness-registry.js.map +1 -0
  51. package/dist/backend/backend/src/services/harness/harness-status.service.d.ts +173 -0
  52. package/dist/backend/backend/src/services/harness/harness-status.service.d.ts.map +1 -0
  53. package/dist/backend/backend/src/services/harness/harness-status.service.js +324 -0
  54. package/dist/backend/backend/src/services/harness/harness-status.service.js.map +1 -0
  55. package/dist/backend/backend/src/services/harness/harness.service.d.ts +146 -0
  56. package/dist/backend/backend/src/services/harness/harness.service.d.ts.map +1 -0
  57. package/dist/backend/backend/src/services/harness/harness.service.js +193 -0
  58. package/dist/backend/backend/src/services/harness/harness.service.js.map +1 -0
  59. package/dist/backend/backend/src/services/harness/harness.types.d.ts +138 -0
  60. package/dist/backend/backend/src/services/harness/harness.types.d.ts.map +1 -0
  61. package/dist/backend/backend/src/services/harness/harness.types.js +51 -0
  62. package/dist/backend/backend/src/services/harness/harness.types.js.map +1 -0
  63. package/dist/backend/backend/src/services/harness/login-broker.service.d.ts +238 -0
  64. package/dist/backend/backend/src/services/harness/login-broker.service.d.ts.map +1 -0
  65. package/dist/backend/backend/src/services/harness/login-broker.service.js +495 -0
  66. package/dist/backend/backend/src/services/harness/login-broker.service.js.map +1 -0
  67. package/dist/backend/backend/src/services/harness/login-rules.d.ts +162 -0
  68. package/dist/backend/backend/src/services/harness/login-rules.d.ts.map +1 -0
  69. package/dist/backend/backend/src/services/harness/login-rules.js +344 -0
  70. package/dist/backend/backend/src/services/harness/login-rules.js.map +1 -0
  71. package/dist/backend/backend/src/services/harness/orc-harness.store.d.ts +59 -0
  72. package/dist/backend/backend/src/services/harness/orc-harness.store.d.ts.map +1 -0
  73. package/dist/backend/backend/src/services/harness/orc-harness.store.js +108 -0
  74. package/dist/backend/backend/src/services/harness/orc-harness.store.js.map +1 -0
  75. package/dist/backend/build-info.json +2 -2
  76. package/dist/cli/backend/src/constants.d.ts +118 -0
  77. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  78. package/dist/cli/backend/src/constants.js +118 -0
  79. package/dist/cli/backend/src/constants.js.map +1 -1
  80. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +5 -0
  81. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  82. package/dist/cli/backend/src/services/agent/agent-registration.service.js +7 -0
  83. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  84. package/dist/cli/backend/src/services/cloud/cloud-client.service.d.ts +2 -1
  85. package/dist/cli/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -1
  86. package/dist/cli/backend/src/services/cloud/cloud-client.service.js +4 -3
  87. package/dist/cli/backend/src/services/cloud/cloud-client.service.js.map +1 -1
  88. package/dist/cli/backend/src/services/harness/claude-config.utils.d.ts +67 -0
  89. package/dist/cli/backend/src/services/harness/claude-config.utils.d.ts.map +1 -0
  90. package/dist/cli/backend/src/services/harness/claude-config.utils.js +118 -0
  91. package/dist/cli/backend/src/services/harness/claude-config.utils.js.map +1 -0
  92. package/dist/cli/backend/src/services/harness/harness-api-key.service.d.ts +99 -0
  93. package/dist/cli/backend/src/services/harness/harness-api-key.service.d.ts.map +1 -0
  94. package/dist/cli/backend/src/services/harness/harness-api-key.service.js +157 -0
  95. package/dist/cli/backend/src/services/harness/harness-api-key.service.js.map +1 -0
  96. package/dist/cli/backend/src/services/harness/harness-credentials.store.d.ts +135 -0
  97. package/dist/cli/backend/src/services/harness/harness-credentials.store.d.ts.map +1 -0
  98. package/dist/cli/backend/src/services/harness/harness-credentials.store.js +208 -0
  99. package/dist/cli/backend/src/services/harness/harness-credentials.store.js.map +1 -0
  100. package/dist/cli/backend/src/services/harness/harness-exec.utils.d.ts +85 -0
  101. package/dist/cli/backend/src/services/harness/harness-exec.utils.d.ts.map +1 -0
  102. package/dist/cli/backend/src/services/harness/harness-exec.utils.js +183 -0
  103. package/dist/cli/backend/src/services/harness/harness-exec.utils.js.map +1 -0
  104. package/dist/cli/backend/src/services/harness/harness-install.service.d.ts +106 -0
  105. package/dist/cli/backend/src/services/harness/harness-install.service.d.ts.map +1 -0
  106. package/dist/cli/backend/src/services/harness/harness-install.service.js +205 -0
  107. package/dist/cli/backend/src/services/harness/harness-install.service.js.map +1 -0
  108. package/dist/cli/backend/src/services/harness/harness-registry.d.ts +86 -0
  109. package/dist/cli/backend/src/services/harness/harness-registry.d.ts.map +1 -0
  110. package/dist/cli/backend/src/services/harness/harness-registry.js +121 -0
  111. package/dist/cli/backend/src/services/harness/harness-registry.js.map +1 -0
  112. package/dist/cli/backend/src/services/harness/harness-status.service.d.ts +173 -0
  113. package/dist/cli/backend/src/services/harness/harness-status.service.d.ts.map +1 -0
  114. package/dist/cli/backend/src/services/harness/harness-status.service.js +324 -0
  115. package/dist/cli/backend/src/services/harness/harness-status.service.js.map +1 -0
  116. package/dist/cli/backend/src/services/harness/harness.service.d.ts +146 -0
  117. package/dist/cli/backend/src/services/harness/harness.service.d.ts.map +1 -0
  118. package/dist/cli/backend/src/services/harness/harness.service.js +193 -0
  119. package/dist/cli/backend/src/services/harness/harness.service.js.map +1 -0
  120. package/dist/cli/backend/src/services/harness/harness.types.d.ts +138 -0
  121. package/dist/cli/backend/src/services/harness/harness.types.d.ts.map +1 -0
  122. package/dist/cli/backend/src/services/harness/harness.types.js +51 -0
  123. package/dist/cli/backend/src/services/harness/harness.types.js.map +1 -0
  124. package/dist/cli/backend/src/services/harness/login-broker.service.d.ts +238 -0
  125. package/dist/cli/backend/src/services/harness/login-broker.service.d.ts.map +1 -0
  126. package/dist/cli/backend/src/services/harness/login-broker.service.js +495 -0
  127. package/dist/cli/backend/src/services/harness/login-broker.service.js.map +1 -0
  128. package/dist/cli/backend/src/services/harness/login-rules.d.ts +162 -0
  129. package/dist/cli/backend/src/services/harness/login-rules.d.ts.map +1 -0
  130. package/dist/cli/backend/src/services/harness/login-rules.js +344 -0
  131. package/dist/cli/backend/src/services/harness/login-rules.js.map +1 -0
  132. package/dist/cli/backend/src/services/harness/orc-harness.store.d.ts +59 -0
  133. package/dist/cli/backend/src/services/harness/orc-harness.store.d.ts.map +1 -0
  134. package/dist/cli/backend/src/services/harness/orc-harness.store.js +108 -0
  135. package/dist/cli/backend/src/services/harness/orc-harness.store.js.map +1 -0
  136. package/dist/cli/cli/src/commands/harness-setup.d.ts +159 -0
  137. package/dist/cli/cli/src/commands/harness-setup.d.ts.map +1 -0
  138. package/dist/cli/cli/src/commands/harness-setup.js +377 -0
  139. package/dist/cli/cli/src/commands/harness-setup.js.map +1 -0
  140. package/dist/cli/cli/src/commands/harness.d.ts +56 -0
  141. package/dist/cli/cli/src/commands/harness.d.ts.map +1 -0
  142. package/dist/cli/cli/src/commands/harness.js +97 -0
  143. package/dist/cli/cli/src/commands/harness.js.map +1 -0
  144. package/dist/cli/cli/src/commands/onboard.d.ts +108 -50
  145. package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
  146. package/dist/cli/cli/src/commands/onboard.js +200 -191
  147. package/dist/cli/cli/src/commands/onboard.js.map +1 -1
  148. package/dist/cli/cli/src/constants.d.ts +18 -0
  149. package/dist/cli/cli/src/constants.d.ts.map +1 -1
  150. package/dist/cli/cli/src/constants.js +18 -0
  151. package/dist/cli/cli/src/constants.js.map +1 -1
  152. package/dist/cli/cli/src/index.js +22 -3
  153. package/dist/cli/cli/src/index.js.map +1 -1
  154. package/dist/cli/cli/src/utils/harness-engine.d.ts +99 -0
  155. package/dist/cli/cli/src/utils/harness-engine.d.ts.map +1 -0
  156. package/dist/cli/cli/src/utils/harness-engine.js +143 -0
  157. package/dist/cli/cli/src/utils/harness-engine.js.map +1 -0
  158. package/dist/cli/cli/src/utils/prompt-io.d.ts +25 -0
  159. package/dist/cli/cli/src/utils/prompt-io.d.ts.map +1 -0
  160. package/dist/cli/cli/src/utils/prompt-io.js +47 -0
  161. package/dist/cli/cli/src/utils/prompt-io.js.map +1 -0
  162. package/frontend/dist/assets/{index-8327e63e.css → index-0a2f783c.css} +1 -1
  163. package/frontend/dist/assets/{index-daf43f1a.js → index-aaf65055.js} +309 -309
  164. package/frontend/dist/index.html +2 -2
  165. package/package.json +1 -1
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Harness status — is each harness installed, which version, is a newer one
3
+ * published, and is it logged in?
4
+ *
5
+ * Detection reads files, env var names and the exit codes of probe commands;
6
+ * it never prints or returns a secret. Login sources are labels such as
7
+ * `crewly-subscription` or `macos-keychain`.
8
+ *
9
+ * - Claude Code: a credential Crewly stores, `CLAUDE_CODE_OAUTH_TOKEN` /
10
+ * `ANTHROPIC_API_KEY` in the env, `~/.claude/.credentials.json`, or the macOS
11
+ * keychain item "Claude Code-credentials" (existence only: `security
12
+ * find-generic-password -s …` without `-w`/`-g`, so no secret is printed).
13
+ * - Codex: `codex login status`; falls back to `$CODEX_HOME/auth.json`.
14
+ * - Gemini CLI (detect only): Google-login credentials file or an API key env var.
15
+ *
16
+ * @module services/harness/harness-status.service
17
+ */
18
+ import { HarnessCredentialsStore } from './harness-credentials.store.js';
19
+ import { type HarnessDefinition } from './harness-registry.js';
20
+ import { type HarnessId, type HarnessLogger, type HarnessStatus, type LoginState, type RunCommand, type SystemToolStatus } from './harness.types.js';
21
+ /** Injectable dependencies. */
22
+ export interface HarnessStatusDeps {
23
+ run?: RunCommand;
24
+ env?: NodeJS.ProcessEnv;
25
+ homeDir?: string;
26
+ platform?: NodeJS.Platform;
27
+ fileExists?: (file: string) => boolean;
28
+ /** PATH lookup; defaults to {@link resolveExecutable} on the harness PATH */
29
+ resolveCommand?: (command: string) => string | null;
30
+ credentials?: HarnessCredentialsStore;
31
+ now?: () => number;
32
+ logger?: HarnessLogger;
33
+ }
34
+ /** Installed binary facts. */
35
+ export interface InstalledInfo {
36
+ installed: boolean;
37
+ /** Absolute path of the binary */
38
+ path: string | null;
39
+ version: string | null;
40
+ }
41
+ /** Login facts. */
42
+ export interface LoginInfo {
43
+ loginState: LoginState;
44
+ loginSource: string | null;
45
+ }
46
+ /**
47
+ * Pull a version number out of `--version` output.
48
+ *
49
+ * @param output - Command output, e.g. `2.1.282 (Claude Code)` or `codex-cli 0.156.1`
50
+ * @returns The version, or null
51
+ */
52
+ export declare function parseVersion(output: string): string | null;
53
+ /**
54
+ * Compare two dotted versions numerically (pre-release suffixes ignored).
55
+ *
56
+ * @param a - Version
57
+ * @param b - Version
58
+ * @returns Positive when a > b, negative when a < b, 0 when equal
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * compareVersions('2.1.282', '2.1.99'); // > 0
63
+ * ```
64
+ */
65
+ export declare function compareVersions(a: string, b: string): number;
66
+ /**
67
+ * Classify `codex login status` output.
68
+ *
69
+ * @param output - stdout + stderr (may mention a masked key; never returned)
70
+ * @returns `chatgpt`, `api_key` or `codex`
71
+ */
72
+ export declare function parseCodexLoginSource(output: string): string;
73
+ /** Detects install, version and login state of each harness. */
74
+ export declare class HarnessStatusService {
75
+ private readonly run;
76
+ private readonly env;
77
+ private readonly homeDir;
78
+ private readonly platform;
79
+ private readonly fileExists;
80
+ private readonly resolveCommand;
81
+ private readonly credentials;
82
+ private readonly now;
83
+ private readonly logger;
84
+ private readonly latestCache;
85
+ /**
86
+ * @param deps - Injectable dependencies (all optional)
87
+ */
88
+ constructor(deps?: HarnessStatusDeps);
89
+ /**
90
+ * Environment for probe commands (harness PATH).
91
+ *
92
+ * @returns Env copy
93
+ */
94
+ private probeEnv;
95
+ /**
96
+ * Whether the binary is on PATH and which version it reports.
97
+ *
98
+ * @param def - Harness definition
99
+ * @returns Installed facts
100
+ */
101
+ getInstalledInfo(def: HarnessDefinition): Promise<InstalledInfo>;
102
+ /**
103
+ * Latest published version (`npm view <pkg> version`), cached.
104
+ *
105
+ * @param def - Harness definition
106
+ * @returns The version, or null when npm could not be asked
107
+ */
108
+ getLatestVersion(def: HarnessDefinition): Promise<string | null>;
109
+ /** Forget cached latest versions. */
110
+ clearLatestVersionCache(): void;
111
+ /**
112
+ * First env var (by name) that has a value.
113
+ *
114
+ * @param names - Candidates
115
+ * @returns The name, or null
116
+ */
117
+ private firstSetEnv;
118
+ /**
119
+ * Claude Code login detection.
120
+ *
121
+ * @returns Login facts
122
+ */
123
+ private getClaudeLogin;
124
+ /**
125
+ * Whether `~/.claude.json` records an OAuth account or a primary API key.
126
+ *
127
+ * @param file - Config path
128
+ * @returns True when an account is recorded
129
+ */
130
+ private claudeConfigHasAccount;
131
+ /**
132
+ * Codex login detection.
133
+ *
134
+ * @param binary - Codex binary path, when installed
135
+ * @returns Login facts
136
+ */
137
+ private getCodexLogin;
138
+ /**
139
+ * Gemini CLI login detection (detect only).
140
+ *
141
+ * @returns Login facts
142
+ */
143
+ private getGeminiLogin;
144
+ /**
145
+ * Login state of a harness.
146
+ *
147
+ * @param def - Harness definition
148
+ * @param binary - Binary path when installed (Codex asks the binary itself)
149
+ * @returns Login facts
150
+ */
151
+ getLoginInfo(def: HarnessDefinition, binary: string | null): Promise<LoginInfo>;
152
+ /**
153
+ * Full status of one harness.
154
+ *
155
+ * @param id - Harness id
156
+ * @returns The status
157
+ * @throws Error for an unknown harness id
158
+ */
159
+ getStatus(id: HarnessId): Promise<HarnessStatus>;
160
+ /**
161
+ * Status of every harness, in registry order.
162
+ *
163
+ * @returns Statuses
164
+ */
165
+ listStatuses(): Promise<HarnessStatus[]>;
166
+ /**
167
+ * Required system tools (jq).
168
+ *
169
+ * @returns One entry per tool
170
+ */
171
+ getSystemTools(): SystemToolStatus[];
172
+ }
173
+ //# sourceMappingURL=harness-status.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-status.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/harness/harness-status.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,324 @@
1
+ /**
2
+ * Harness status — is each harness installed, which version, is a newer one
3
+ * published, and is it logged in?
4
+ *
5
+ * Detection reads files, env var names and the exit codes of probe commands;
6
+ * it never prints or returns a secret. Login sources are labels such as
7
+ * `crewly-subscription` or `macos-keychain`.
8
+ *
9
+ * - Claude Code: a credential Crewly stores, `CLAUDE_CODE_OAUTH_TOKEN` /
10
+ * `ANTHROPIC_API_KEY` in the env, `~/.claude/.credentials.json`, or the macOS
11
+ * keychain item "Claude Code-credentials" (existence only: `security
12
+ * find-generic-password -s …` without `-w`/`-g`, so no secret is printed).
13
+ * - Codex: `codex login status`; falls back to `$CODEX_HOME/auth.json`.
14
+ * - Gemini CLI (detect only): Google-login credentials file or an API key env var.
15
+ *
16
+ * @module services/harness/harness-status.service
17
+ */
18
+ import * as fs from 'fs';
19
+ import * as os from 'os';
20
+ import * as path from 'path';
21
+ import { HARNESS_CONSTANTS } from '../../constants.js';
22
+ import { getClaudeConfigFile, getClaudeCredentialsFile } from './claude-config.utils.js';
23
+ import { getHarnessCredentialsStore } from './harness-credentials.store.js';
24
+ import { buildHarnessPath, buildNpmPath, resolveExecutable, runCommand } from './harness-exec.utils.js';
25
+ import { getHarnessDefinition, listHarnessDefinitions, toPublicLoginMethods } from './harness-registry.js';
26
+ import { SILENT_HARNESS_LOGGER, } from './harness.types.js';
27
+ /** Exit code of `security find-generic-password` when the item does not exist. */
28
+ const KEYCHAIN_ITEM_NOT_FOUND_EXIT_CODE = 44;
29
+ /**
30
+ * Pull a version number out of `--version` output.
31
+ *
32
+ * @param output - Command output, e.g. `2.1.282 (Claude Code)` or `codex-cli 0.156.1`
33
+ * @returns The version, or null
34
+ */
35
+ export function parseVersion(output) {
36
+ const match = HARNESS_CONSTANTS.VERSION_PATTERN.exec(output);
37
+ return match ? match[0] : null;
38
+ }
39
+ /**
40
+ * Compare two dotted versions numerically (pre-release suffixes ignored).
41
+ *
42
+ * @param a - Version
43
+ * @param b - Version
44
+ * @returns Positive when a > b, negative when a < b, 0 when equal
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * compareVersions('2.1.282', '2.1.99'); // > 0
49
+ * ```
50
+ */
51
+ export function compareVersions(a, b) {
52
+ const parts = (value) => value
53
+ .split(/[-+]/)[0]
54
+ .split('.')
55
+ .map((part) => Number.parseInt(part, 10) || 0);
56
+ const left = parts(a);
57
+ const right = parts(b);
58
+ for (let i = 0; i < Math.max(left.length, right.length); i++) {
59
+ const diff = (left[i] ?? 0) - (right[i] ?? 0);
60
+ if (diff !== 0)
61
+ return diff;
62
+ }
63
+ return 0;
64
+ }
65
+ /**
66
+ * Classify `codex login status` output.
67
+ *
68
+ * @param output - stdout + stderr (may mention a masked key; never returned)
69
+ * @returns `chatgpt`, `api_key` or `codex`
70
+ */
71
+ export function parseCodexLoginSource(output) {
72
+ if (/chatgpt/i.test(output))
73
+ return 'chatgpt';
74
+ if (/api\s*key/i.test(output))
75
+ return 'api_key';
76
+ return 'codex';
77
+ }
78
+ /** Detects install, version and login state of each harness. */
79
+ export class HarnessStatusService {
80
+ run;
81
+ env;
82
+ homeDir;
83
+ platform;
84
+ fileExists;
85
+ resolveCommand;
86
+ credentials;
87
+ now;
88
+ logger;
89
+ latestCache = new Map();
90
+ /**
91
+ * @param deps - Injectable dependencies (all optional)
92
+ */
93
+ constructor(deps = {}) {
94
+ this.run = deps.run ?? runCommand;
95
+ this.env = deps.env ?? process.env;
96
+ this.homeDir = deps.homeDir ?? os.homedir();
97
+ this.platform = deps.platform ?? process.platform;
98
+ this.fileExists = deps.fileExists ?? ((file) => fs.existsSync(file));
99
+ this.resolveCommand = deps.resolveCommand ?? ((command) => resolveExecutable(command, buildHarnessPath(this.env.PATH, this.homeDir)));
100
+ this.credentials = deps.credentials ?? getHarnessCredentialsStore();
101
+ this.now = deps.now ?? Date.now;
102
+ this.logger = deps.logger ?? SILENT_HARNESS_LOGGER;
103
+ }
104
+ /**
105
+ * Environment for probe commands (harness PATH).
106
+ *
107
+ * @returns Env copy
108
+ */
109
+ probeEnv() {
110
+ return { ...this.env, PATH: buildHarnessPath(this.env.PATH, this.homeDir) };
111
+ }
112
+ /**
113
+ * Whether the binary is on PATH and which version it reports.
114
+ *
115
+ * @param def - Harness definition
116
+ * @returns Installed facts
117
+ */
118
+ async getInstalledInfo(def) {
119
+ const binary = this.resolveCommand(def.command);
120
+ if (!binary)
121
+ return { installed: false, path: null, version: null };
122
+ const result = await this.run(binary, def.versionArgs, { env: this.probeEnv(), timeoutMs: HARNESS_CONSTANTS.PROBE_TIMEOUT_MS });
123
+ // Only a clean exit reports a version: a broken install's crash output
124
+ // ("Node.js v22.14.0") must not pass for the harness's version.
125
+ const version = result.code === 0 ? parseVersion(`${result.stdout}\n${result.stderr}`) : null;
126
+ return { installed: true, path: binary, version };
127
+ }
128
+ /**
129
+ * Latest published version (`npm view <pkg> version`), cached.
130
+ *
131
+ * @param def - Harness definition
132
+ * @returns The version, or null when npm could not be asked
133
+ */
134
+ async getLatestVersion(def) {
135
+ const cached = this.latestCache.get(def.npmPackage);
136
+ if (cached && cached.expiresAt > this.now())
137
+ return cached.value;
138
+ const result = await this.run('npm', ['view', def.npmPackage, 'version'], {
139
+ env: { ...this.env, PATH: buildNpmPath(this.env.PATH, this.homeDir) },
140
+ timeoutMs: HARNESS_CONSTANTS.NPM_VIEW_TIMEOUT_MS,
141
+ });
142
+ const value = result.code === 0 ? parseVersion(result.stdout) : null;
143
+ if (value === null) {
144
+ this.logger.debug('npm view failed', { pkg: def.npmPackage, code: result.code, error: result.error });
145
+ }
146
+ this.latestCache.set(def.npmPackage, {
147
+ value,
148
+ expiresAt: this.now() + (value ? HARNESS_CONSTANTS.LATEST_VERSION_CACHE_TTL_MS : HARNESS_CONSTANTS.LATEST_VERSION_FAILURE_TTL_MS),
149
+ });
150
+ return value;
151
+ }
152
+ /** Forget cached latest versions. */
153
+ clearLatestVersionCache() {
154
+ this.latestCache.clear();
155
+ }
156
+ /**
157
+ * First env var (by name) that has a value.
158
+ *
159
+ * @param names - Candidates
160
+ * @returns The name, or null
161
+ */
162
+ firstSetEnv(names) {
163
+ return names.find((name) => (this.env[name] ?? '').trim().length > 0) ?? null;
164
+ }
165
+ /**
166
+ * Claude Code login detection.
167
+ *
168
+ * @returns Login facts
169
+ */
170
+ async getClaudeLogin() {
171
+ const stored = this.credentials.getClaudeCredentialKind();
172
+ if (stored === 'oauth_token')
173
+ return { loginState: 'logged_in', loginSource: 'crewly-subscription' };
174
+ if (stored === 'api_key')
175
+ return { loginState: 'logged_in', loginSource: 'crewly-api-key' };
176
+ const envName = this.firstSetEnv([HARNESS_CONSTANTS.CLAUDE.OAUTH_TOKEN_ENV, HARNESS_CONSTANTS.CLAUDE.API_KEY_ENV]);
177
+ if (envName)
178
+ return { loginState: 'logged_in', loginSource: `env:${envName}` };
179
+ const location = { env: this.env, homeDir: this.homeDir };
180
+ if (this.fileExists(getClaudeCredentialsFile(location))) {
181
+ return { loginState: 'logged_in', loginSource: 'claude-credentials-file' };
182
+ }
183
+ if (this.platform === 'darwin') {
184
+ // Existence only: no -w / -g, so the secret is never printed.
185
+ const result = await this.run('security', ['find-generic-password', '-s', HARNESS_CONSTANTS.CLAUDE.KEYCHAIN_SERVICE], {
186
+ env: this.probeEnv(),
187
+ timeoutMs: HARNESS_CONSTANTS.PROBE_TIMEOUT_MS,
188
+ });
189
+ if (result.code === 0)
190
+ return { loginState: 'logged_in', loginSource: 'macos-keychain' };
191
+ if (result.code !== KEYCHAIN_ITEM_NOT_FOUND_EXIT_CODE) {
192
+ return { loginState: 'unknown', loginSource: null };
193
+ }
194
+ }
195
+ // A config file naming an account is a weaker signal than a credential;
196
+ // report it as unknown rather than claiming a working login.
197
+ if (this.fileExists(getClaudeConfigFile(location)) && this.claudeConfigHasAccount(getClaudeConfigFile(location))) {
198
+ return { loginState: 'unknown', loginSource: 'claude-config' };
199
+ }
200
+ return { loginState: 'logged_out', loginSource: null };
201
+ }
202
+ /**
203
+ * Whether `~/.claude.json` records an OAuth account or a primary API key.
204
+ *
205
+ * @param file - Config path
206
+ * @returns True when an account is recorded
207
+ */
208
+ claudeConfigHasAccount(file) {
209
+ try {
210
+ const parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
211
+ return Boolean(parsed.oauthAccount) || Boolean(parsed.primaryApiKey);
212
+ }
213
+ catch {
214
+ return false;
215
+ }
216
+ }
217
+ /**
218
+ * Codex login detection.
219
+ *
220
+ * @param binary - Codex binary path, when installed
221
+ * @returns Login facts
222
+ */
223
+ async getCodexLogin(binary) {
224
+ const codexHome = this.env[HARNESS_CONSTANTS.CODEX.HOME_ENV] || path.join(this.homeDir, HARNESS_CONSTANTS.CODEX.HOME_DIR);
225
+ const authFileExists = this.fileExists(path.join(codexHome, HARNESS_CONSTANTS.CODEX.AUTH_FILE));
226
+ if (binary) {
227
+ const result = await this.run(binary, ['login', 'status'], { env: this.probeEnv(), timeoutMs: HARNESS_CONSTANTS.PROBE_TIMEOUT_MS });
228
+ if (result.code === 0) {
229
+ return { loginState: 'logged_in', loginSource: parseCodexLoginSource(`${result.stdout}\n${result.stderr}`) };
230
+ }
231
+ if (result.code !== null)
232
+ return { loginState: 'logged_out', loginSource: null };
233
+ this.logger.debug('codex login status could not run', { error: result.error });
234
+ }
235
+ return authFileExists ? { loginState: 'logged_in', loginSource: 'codex-auth-file' } : { loginState: binary ? 'unknown' : 'logged_out', loginSource: null };
236
+ }
237
+ /**
238
+ * Gemini CLI login detection (detect only).
239
+ *
240
+ * @returns Login facts
241
+ */
242
+ getGeminiLogin() {
243
+ if (this.fileExists(path.join(this.homeDir, HARNESS_CONSTANTS.GEMINI.OAUTH_CREDS_FILE))) {
244
+ return { loginState: 'logged_in', loginSource: 'gemini-google-login' };
245
+ }
246
+ const envName = this.firstSetEnv(HARNESS_CONSTANTS.GEMINI.KEY_ENV);
247
+ if (envName)
248
+ return { loginState: 'logged_in', loginSource: `env:${envName}` };
249
+ return { loginState: 'unknown', loginSource: null };
250
+ }
251
+ /**
252
+ * Login state of a harness.
253
+ *
254
+ * @param def - Harness definition
255
+ * @param binary - Binary path when installed (Codex asks the binary itself)
256
+ * @returns Login facts
257
+ */
258
+ async getLoginInfo(def, binary) {
259
+ try {
260
+ switch (def.id) {
261
+ case HARNESS_CONSTANTS.IDS.CLAUDE_CODE:
262
+ return await this.getClaudeLogin();
263
+ case HARNESS_CONSTANTS.IDS.CODEX_CLI:
264
+ return await this.getCodexLogin(binary);
265
+ default:
266
+ return this.getGeminiLogin();
267
+ }
268
+ }
269
+ catch (error) {
270
+ this.logger.warn('Harness login detection failed', { harnessId: def.id, error: error instanceof Error ? error.message : String(error) });
271
+ return { loginState: 'unknown', loginSource: null };
272
+ }
273
+ }
274
+ /**
275
+ * Full status of one harness.
276
+ *
277
+ * @param id - Harness id
278
+ * @returns The status
279
+ * @throws Error for an unknown harness id
280
+ */
281
+ async getStatus(id) {
282
+ const def = getHarnessDefinition(id);
283
+ if (!def)
284
+ throw new Error(`Unknown harness: ${id}`);
285
+ const [installedInfo, latestVersion] = await Promise.all([this.getInstalledInfo(def), this.getLatestVersion(def)]);
286
+ const login = await this.getLoginInfo(def, installedInfo.path);
287
+ const updateAvailable = Boolean(installedInfo.installed && installedInfo.version && latestVersion && compareVersions(latestVersion, installedInfo.version) > 0);
288
+ return {
289
+ id: def.id,
290
+ displayName: def.displayName,
291
+ installed: installedInfo.installed,
292
+ version: installedInfo.version,
293
+ latestVersion,
294
+ updateAvailable,
295
+ loginState: login.loginState,
296
+ loginSource: login.loginSource,
297
+ loginMethods: toPublicLoginMethods(def),
298
+ };
299
+ }
300
+ /**
301
+ * Status of every harness, in registry order.
302
+ *
303
+ * @returns Statuses
304
+ */
305
+ async listStatuses() {
306
+ return Promise.all(listHarnessDefinitions().map((def) => this.getStatus(def.id)));
307
+ }
308
+ /**
309
+ * Required system tools (jq).
310
+ *
311
+ * @returns One entry per tool
312
+ */
313
+ getSystemTools() {
314
+ const jq = HARNESS_CONSTANTS.SYSTEM_TOOLS.JQ;
315
+ return [
316
+ {
317
+ id: jq.ID,
318
+ installed: this.resolveCommand(jq.ID) !== null,
319
+ installHint: this.platform === 'darwin' ? jq.INSTALL_HINT_MACOS : jq.INSTALL_HINT_LINUX,
320
+ },
321
+ ];
322
+ }
323
+ }
324
+ //# sourceMappingURL=harness-status.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-status.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/harness/harness-status.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Harness service — the one engine behind both setup front ends.
3
+ *
4
+ * The REST API (`/api/harness`, used by the web setup page) and the `crewly`
5
+ * CLI (`crewly onboard`, `crewly login`, `crewly harness`) both call this
6
+ * facade, so detection, install, orc choice and login behave identically.
7
+ * The backend uses the process-wide {@link getHarnessService}; the CLI builds
8
+ * its own instance with {@link createHarnessService} (silent logger, no
9
+ * backend running required).
10
+ *
11
+ * @module services/harness/harness.service
12
+ */
13
+ import { HarnessApiKeyService } from './harness-api-key.service.js';
14
+ import { HarnessInstallService } from './harness-install.service.js';
15
+ import { HarnessStatusService } from './harness-status.service.js';
16
+ import { type HarnessId, type HarnessLogger, type HarnessOverview, type HarnessStatus, type InstallJob, type LoginSession } from './harness.types.js';
17
+ import { LoginBrokerService } from './login-broker.service.js';
18
+ import { OrcHarnessStore, type DefaultRuntimeUpdater } from './orc-harness.store.js';
19
+ /** Error for an id that is not a harness (REST: 404). */
20
+ export declare class UnknownHarnessError extends Error {
21
+ readonly id: string;
22
+ /**
23
+ * @param id - The id that was asked for
24
+ */
25
+ constructor(id: string);
26
+ }
27
+ /** Parts of the service (each injectable for tests). */
28
+ export interface HarnessServiceParts {
29
+ status: HarnessStatusService;
30
+ install: HarnessInstallService;
31
+ broker: LoginBrokerService;
32
+ apiKeys: HarnessApiKeyService;
33
+ orc: OrcHarnessStore;
34
+ }
35
+ /** Facade over status, install, orc choice, broker login and API-key login. */
36
+ export declare class HarnessService {
37
+ readonly status: HarnessStatusService;
38
+ readonly install: HarnessInstallService;
39
+ readonly broker: LoginBrokerService;
40
+ readonly apiKeys: HarnessApiKeyService;
41
+ readonly orc: OrcHarnessStore;
42
+ /**
43
+ * @param parts - Service parts
44
+ */
45
+ constructor(parts: HarnessServiceParts);
46
+ /**
47
+ * Validate a harness id.
48
+ *
49
+ * @param id - Candidate
50
+ * @returns The id, typed
51
+ * @throws UnknownHarnessError for an unknown id
52
+ */
53
+ requireHarnessId(id: string): HarnessId;
54
+ /**
55
+ * Everything the setup screen needs.
56
+ *
57
+ * @returns Harness statuses, the orc harness and system tools
58
+ */
59
+ getOverview(): Promise<HarnessOverview>;
60
+ /**
61
+ * Status of one harness.
62
+ *
63
+ * @param id - Harness id
64
+ * @returns The status
65
+ * @throws UnknownHarnessError for an unknown id
66
+ */
67
+ getStatus(id: string): Promise<HarnessStatus>;
68
+ /**
69
+ * Start installing (or updating) a harness.
70
+ *
71
+ * @param id - Harness id
72
+ * @returns The install job
73
+ * @throws UnknownHarnessError for an unknown id
74
+ */
75
+ startInstall(id: string): InstallJob;
76
+ /**
77
+ * Read an install job.
78
+ *
79
+ * @param jobId - Job id
80
+ * @returns The job
81
+ * @throws HarnessInstallError job_not_found
82
+ */
83
+ getInstallJob(jobId: string): InstallJob;
84
+ /**
85
+ * Set the orchestrator's harness.
86
+ *
87
+ * @param id - Harness id
88
+ * @returns The recorded harness id
89
+ * @throws UnknownHarnessError for an unknown id
90
+ */
91
+ setOrcHarness(id: string): Promise<string>;
92
+ /**
93
+ * Start a broker login.
94
+ *
95
+ * @param id - Harness id
96
+ * @param method - Broker login method
97
+ * @returns The login session
98
+ * @throws UnknownHarnessError | LoginBrokerError
99
+ */
100
+ startLogin(id: string, method: string): LoginSession;
101
+ /**
102
+ * Store an API key for a harness and return its fresh status.
103
+ *
104
+ * @param id - Harness id
105
+ * @param key - The key (never echoed)
106
+ * @returns The harness status after login
107
+ * @throws UnknownHarnessError | HarnessApiKeyError
108
+ */
109
+ submitApiKey(id: string, key: unknown): Promise<HarnessStatus>;
110
+ }
111
+ /** Options for {@link createHarnessService}. */
112
+ export interface CreateHarnessServiceOptions {
113
+ logger?: HarnessLogger;
114
+ /** How `settings.general.defaultRuntime` is updated (the CLI passes a fresh SettingsService) */
115
+ updateDefaultRuntime?: DefaultRuntimeUpdater;
116
+ env?: NodeJS.ProcessEnv;
117
+ }
118
+ /**
119
+ * Build a harness service with real dependencies.
120
+ *
121
+ * Codex broker logins are confirmed with `codex login status` through the
122
+ * status service.
123
+ *
124
+ * @param options - Logger, settings updater, env
125
+ * @returns A new service
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * const harness = createHarnessService({ logger: SILENT_HARNESS_LOGGER });
130
+ * const overview = await harness.getOverview();
131
+ * ```
132
+ */
133
+ export declare function createHarnessService(options?: CreateHarnessServiceOptions): HarnessService;
134
+ /**
135
+ * The backend's harness service (logs through LoggerService).
136
+ *
137
+ * @returns The singleton
138
+ */
139
+ export declare function getHarnessService(): HarnessService;
140
+ /**
141
+ * Replace or clear the backend singleton (tests).
142
+ *
143
+ * @param service - Service to use, or null to clear
144
+ */
145
+ export declare function setHarnessServiceForTesting(service: HarnessService | null): void;
146
+ //# sourceMappingURL=harness.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/harness/harness.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAGN,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAErF,yDAAyD;AACzD,qBAAa,mBAAoB,SAAQ,KAAK;aAIjB,EAAE,EAAE,MAAM;IAHtC;;OAEG;gBACyB,EAAE,EAAE,MAAM;CAItC;AAED,wDAAwD;AACxD,MAAM,WAAW,mBAAmB;IACnC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,OAAO,EAAE,qBAAqB,CAAC;IAC/B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,OAAO,EAAE,oBAAoB,CAAC;IAC9B,GAAG,EAAE,eAAe,CAAC;CACrB;AAED,+EAA+E;AAC/E,qBAAa,cAAc;IAC1B,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAE9B;;OAEG;gBACS,KAAK,EAAE,mBAAmB;IAQtC;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS;IAKvC;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC;IAK7C;;;;;;OAMG;IACG,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAInD;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU;IAIpC;;;;;;OAMG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU;IAIxC;;;;;;OAMG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIhD;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY;IAIpD;;;;;;;OAOG;IACG,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC;CAKpE;AAED,gDAAgD;AAChD,MAAM,WAAW,2BAA2B;IAC3C,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,gGAAgG;IAChG,oBAAoB,CAAC,EAAE,qBAAqB,CAAC;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,2BAAgC,GAAG,cAAc,CAmB9F;AAKD;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAKlD;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CAEhF"}