crewly 1.20.123 → 1.20.125

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 (180) hide show
  1. package/dist/backend/backend/src/constants.d.ts +120 -0
  2. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  3. package/dist/backend/backend/src/constants.js +120 -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/backend/src/services/slack/slack-agent-post.service.d.ts +15 -0
  76. package/dist/backend/backend/src/services/slack/slack-agent-post.service.d.ts.map +1 -1
  77. package/dist/backend/backend/src/services/slack/slack-agent-post.service.js +24 -3
  78. package/dist/backend/backend/src/services/slack/slack-agent-post.service.js.map +1 -1
  79. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  80. package/dist/backend/backend/src/services/slack/slack-initializer.js +2 -0
  81. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  82. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts +14 -1
  83. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  84. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +69 -4
  85. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  86. package/dist/backend/build-info.json +2 -2
  87. package/dist/cli/backend/src/constants.d.ts +120 -0
  88. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  89. package/dist/cli/backend/src/constants.js +120 -0
  90. package/dist/cli/backend/src/constants.js.map +1 -1
  91. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +5 -0
  92. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  93. package/dist/cli/backend/src/services/agent/agent-registration.service.js +7 -0
  94. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  95. package/dist/cli/backend/src/services/cloud/cloud-client.service.d.ts +2 -1
  96. package/dist/cli/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -1
  97. package/dist/cli/backend/src/services/cloud/cloud-client.service.js +4 -3
  98. package/dist/cli/backend/src/services/cloud/cloud-client.service.js.map +1 -1
  99. package/dist/cli/backend/src/services/harness/claude-config.utils.d.ts +67 -0
  100. package/dist/cli/backend/src/services/harness/claude-config.utils.d.ts.map +1 -0
  101. package/dist/cli/backend/src/services/harness/claude-config.utils.js +118 -0
  102. package/dist/cli/backend/src/services/harness/claude-config.utils.js.map +1 -0
  103. package/dist/cli/backend/src/services/harness/harness-api-key.service.d.ts +99 -0
  104. package/dist/cli/backend/src/services/harness/harness-api-key.service.d.ts.map +1 -0
  105. package/dist/cli/backend/src/services/harness/harness-api-key.service.js +157 -0
  106. package/dist/cli/backend/src/services/harness/harness-api-key.service.js.map +1 -0
  107. package/dist/cli/backend/src/services/harness/harness-credentials.store.d.ts +135 -0
  108. package/dist/cli/backend/src/services/harness/harness-credentials.store.d.ts.map +1 -0
  109. package/dist/cli/backend/src/services/harness/harness-credentials.store.js +208 -0
  110. package/dist/cli/backend/src/services/harness/harness-credentials.store.js.map +1 -0
  111. package/dist/cli/backend/src/services/harness/harness-exec.utils.d.ts +85 -0
  112. package/dist/cli/backend/src/services/harness/harness-exec.utils.d.ts.map +1 -0
  113. package/dist/cli/backend/src/services/harness/harness-exec.utils.js +183 -0
  114. package/dist/cli/backend/src/services/harness/harness-exec.utils.js.map +1 -0
  115. package/dist/cli/backend/src/services/harness/harness-install.service.d.ts +106 -0
  116. package/dist/cli/backend/src/services/harness/harness-install.service.d.ts.map +1 -0
  117. package/dist/cli/backend/src/services/harness/harness-install.service.js +205 -0
  118. package/dist/cli/backend/src/services/harness/harness-install.service.js.map +1 -0
  119. package/dist/cli/backend/src/services/harness/harness-registry.d.ts +86 -0
  120. package/dist/cli/backend/src/services/harness/harness-registry.d.ts.map +1 -0
  121. package/dist/cli/backend/src/services/harness/harness-registry.js +121 -0
  122. package/dist/cli/backend/src/services/harness/harness-registry.js.map +1 -0
  123. package/dist/cli/backend/src/services/harness/harness-status.service.d.ts +173 -0
  124. package/dist/cli/backend/src/services/harness/harness-status.service.d.ts.map +1 -0
  125. package/dist/cli/backend/src/services/harness/harness-status.service.js +324 -0
  126. package/dist/cli/backend/src/services/harness/harness-status.service.js.map +1 -0
  127. package/dist/cli/backend/src/services/harness/harness.service.d.ts +146 -0
  128. package/dist/cli/backend/src/services/harness/harness.service.d.ts.map +1 -0
  129. package/dist/cli/backend/src/services/harness/harness.service.js +193 -0
  130. package/dist/cli/backend/src/services/harness/harness.service.js.map +1 -0
  131. package/dist/cli/backend/src/services/harness/harness.types.d.ts +138 -0
  132. package/dist/cli/backend/src/services/harness/harness.types.d.ts.map +1 -0
  133. package/dist/cli/backend/src/services/harness/harness.types.js +51 -0
  134. package/dist/cli/backend/src/services/harness/harness.types.js.map +1 -0
  135. package/dist/cli/backend/src/services/harness/login-broker.service.d.ts +238 -0
  136. package/dist/cli/backend/src/services/harness/login-broker.service.d.ts.map +1 -0
  137. package/dist/cli/backend/src/services/harness/login-broker.service.js +495 -0
  138. package/dist/cli/backend/src/services/harness/login-broker.service.js.map +1 -0
  139. package/dist/cli/backend/src/services/harness/login-rules.d.ts +162 -0
  140. package/dist/cli/backend/src/services/harness/login-rules.d.ts.map +1 -0
  141. package/dist/cli/backend/src/services/harness/login-rules.js +344 -0
  142. package/dist/cli/backend/src/services/harness/login-rules.js.map +1 -0
  143. package/dist/cli/backend/src/services/harness/orc-harness.store.d.ts +59 -0
  144. package/dist/cli/backend/src/services/harness/orc-harness.store.d.ts.map +1 -0
  145. package/dist/cli/backend/src/services/harness/orc-harness.store.js +108 -0
  146. package/dist/cli/backend/src/services/harness/orc-harness.store.js.map +1 -0
  147. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts +14 -1
  148. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  149. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +69 -4
  150. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  151. package/dist/cli/cli/src/commands/harness-setup.d.ts +159 -0
  152. package/dist/cli/cli/src/commands/harness-setup.d.ts.map +1 -0
  153. package/dist/cli/cli/src/commands/harness-setup.js +377 -0
  154. package/dist/cli/cli/src/commands/harness-setup.js.map +1 -0
  155. package/dist/cli/cli/src/commands/harness.d.ts +56 -0
  156. package/dist/cli/cli/src/commands/harness.d.ts.map +1 -0
  157. package/dist/cli/cli/src/commands/harness.js +97 -0
  158. package/dist/cli/cli/src/commands/harness.js.map +1 -0
  159. package/dist/cli/cli/src/commands/onboard.d.ts +108 -50
  160. package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
  161. package/dist/cli/cli/src/commands/onboard.js +200 -191
  162. package/dist/cli/cli/src/commands/onboard.js.map +1 -1
  163. package/dist/cli/cli/src/constants.d.ts +18 -0
  164. package/dist/cli/cli/src/constants.d.ts.map +1 -1
  165. package/dist/cli/cli/src/constants.js +18 -0
  166. package/dist/cli/cli/src/constants.js.map +1 -1
  167. package/dist/cli/cli/src/index.js +22 -3
  168. package/dist/cli/cli/src/index.js.map +1 -1
  169. package/dist/cli/cli/src/utils/harness-engine.d.ts +99 -0
  170. package/dist/cli/cli/src/utils/harness-engine.d.ts.map +1 -0
  171. package/dist/cli/cli/src/utils/harness-engine.js +143 -0
  172. package/dist/cli/cli/src/utils/harness-engine.js.map +1 -0
  173. package/dist/cli/cli/src/utils/prompt-io.d.ts +25 -0
  174. package/dist/cli/cli/src/utils/prompt-io.d.ts.map +1 -0
  175. package/dist/cli/cli/src/utils/prompt-io.js +47 -0
  176. package/dist/cli/cli/src/utils/prompt-io.js.map +1 -0
  177. package/frontend/dist/assets/{index-8327e63e.css → index-0a2f783c.css} +1 -1
  178. package/frontend/dist/assets/{index-daf43f1a.js → index-aaf65055.js} +309 -309
  179. package/frontend/dist/index.html +2 -2
  180. package/package.json +1 -1
@@ -0,0 +1,377 @@
1
+ /**
2
+ * Harness setup steps shared by `crewly onboard`, `crewly login` and
3
+ * `crewly harness`: detect the harnesses, choose the orchestrator's one,
4
+ * install it, record the choice, and log in.
5
+ *
6
+ * Everything goes through the backend's harness engine (see
7
+ * cli/utils/harness-engine), so the CLI and the web setup page behave the
8
+ * same. The owner is assumed NOT to be at the machine: nothing here opens a
9
+ * local browser; login URLs and codes are printed so they can be opened on a
10
+ * phone, and in non-interactive mode (`--yes`) nothing ever prompts.
11
+ *
12
+ * @module cli/commands/harness-setup
13
+ */
14
+ import chalk from 'chalk';
15
+ import { HARNESS_CONSTANTS } from '../../../backend/src/constants.js';
16
+ import { getBrokerLoginMethod, getHarnessDefinition, resolveHarnessAlias } from '../../../backend/src/services/harness/harness-registry.js';
17
+ import { isTerminalLoginState, } from '../../../backend/src/services/harness/harness.types.js';
18
+ import { getLoginRules } from '../../../backend/src/services/harness/login-rules.js';
19
+ import { CLI_CONSTANTS } from '../constants.js';
20
+ /** Default timing. */
21
+ export const DEFAULT_SETUP_TIMING = {
22
+ pollIntervalMs: CLI_CONSTANTS.HARNESS_SETUP.POLL_INTERVAL_MS,
23
+ urlWaitMs: CLI_CONSTANTS.HARNESS_SETUP.URL_WAIT_MS,
24
+ screenFallbackMs: CLI_CONSTANTS.HARNESS_SETUP.SCREEN_FALLBACK_MS,
25
+ maxWaitMs: HARNESS_CONSTANTS.LOGIN.TIMEOUT_MS + CLI_CONSTANTS.HARNESS_SETUP.WAIT_GRACE_MS,
26
+ sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
27
+ now: Date.now,
28
+ };
29
+ /**
30
+ * Whether an answer means yes (empty = the default).
31
+ *
32
+ * @param answer - User input
33
+ * @param defaultYes - Value for an empty answer
34
+ * @returns True for yes
35
+ */
36
+ export function isYes(answer, defaultYes) {
37
+ const value = answer.trim().toLowerCase();
38
+ if (value === '')
39
+ return defaultYes;
40
+ return value === 'y' || value === 'yes';
41
+ }
42
+ /**
43
+ * One status line for a harness.
44
+ *
45
+ * @param status - Harness status
46
+ * @param isOrc - Whether it is the orchestrator's harness
47
+ * @returns Printable line (no colours)
48
+ */
49
+ export function describeHarness(status, isOrc = false) {
50
+ const install = status.installed
51
+ ? `v${status.version ?? '?'}${status.updateAvailable && status.latestVersion ? ` (update: v${status.latestVersion})` : ''}`
52
+ : `not installed${status.latestVersion ? ` (latest v${status.latestVersion})` : ''}`;
53
+ const login = status.loginState === 'logged_in'
54
+ ? `logged in${status.loginSource ? ` (${status.loginSource})` : ''}`
55
+ : status.loginState === 'logged_out'
56
+ ? 'not logged in'
57
+ : 'login unknown';
58
+ return `${status.displayName.padEnd(12)} ${install.padEnd(34)} ${login}${isOrc ? ' ← orchestrator' : ''}`;
59
+ }
60
+ /**
61
+ * Print every harness and the required system tools.
62
+ *
63
+ * @param io - Output
64
+ * @param overview - Engine overview
65
+ */
66
+ export function printHarnessOverview(io, overview) {
67
+ for (const status of overview.harnesses) {
68
+ const line = describeHarness(status, status.id === overview.orcHarness);
69
+ io.log(` ${status.installed ? chalk.green('✓') : chalk.gray('·')} ${line}`);
70
+ }
71
+ for (const tool of overview.systemTools) {
72
+ io.log(tool.installed ? chalk.gray(` ✓ ${tool.id}`) : chalk.yellow(` ✖ ${tool.id} missing — ${tool.installHint}`));
73
+ }
74
+ }
75
+ /**
76
+ * Choose the orchestrator's harness.
77
+ *
78
+ * Non-interactive: the preset (`--harness`), else Claude Code.
79
+ *
80
+ * @param io - Prompting
81
+ * @param overview - Engine overview
82
+ * @param options - `interactive`, `preset` (id or alias)
83
+ * @returns Harness id
84
+ * @throws Error when the preset is not a harness
85
+ */
86
+ export async function chooseOrcHarness(io, overview, options) {
87
+ if (options.preset) {
88
+ const resolved = resolveHarnessAlias(options.preset);
89
+ if (!resolved)
90
+ throw new Error(`Unknown harness "${options.preset}" (use claude, codex or gemini)`);
91
+ return resolved;
92
+ }
93
+ const fallback = HARNESS_CONSTANTS.DEFAULT_ORC_HARNESS;
94
+ if (!options.interactive)
95
+ return fallback;
96
+ io.log(' Which harness should the orchestrator use?');
97
+ overview.harnesses.forEach((status, index) => {
98
+ const tag = status.id === fallback ? chalk.green(' (recommended)') : '';
99
+ const detectOnly = status.loginMethods.length === 0 ? chalk.gray(' — log in yourself by running it once') : '';
100
+ io.log(` ${index + 1}. ${status.displayName}${tag}${detectOnly}`);
101
+ });
102
+ const defaultIndex = Math.max(0, overview.harnesses.findIndex((status) => status.id === fallback)) + 1;
103
+ for (;;) {
104
+ const answer = await io.ask(` Enter choice (1-${overview.harnesses.length}) [${defaultIndex}]: `);
105
+ if (answer.trim() === '')
106
+ return overview.harnesses[defaultIndex - 1].id;
107
+ const index = Number.parseInt(answer, 10);
108
+ if (index >= 1 && index <= overview.harnesses.length)
109
+ return overview.harnesses[index - 1].id;
110
+ const byName = resolveHarnessAlias(answer);
111
+ if (byName)
112
+ return byName;
113
+ io.log(chalk.yellow(` Please enter a number from 1 to ${overview.harnesses.length}.`));
114
+ }
115
+ }
116
+ /**
117
+ * Install or update the harness when it is missing or outdated.
118
+ *
119
+ * Interactive mode asks first (default yes for a missing harness, no for an
120
+ * update); `--yes` installs a missing harness and applies updates.
121
+ *
122
+ * @param io - Prompting
123
+ * @param service - Harness engine
124
+ * @param status - Current status
125
+ * @param options - `interactive`
126
+ * @returns True when the harness is installed afterwards
127
+ */
128
+ export async function ensureHarnessInstalled(io, service, status, options) {
129
+ const missing = !status.installed;
130
+ if (!missing && !status.updateAvailable) {
131
+ io.log(chalk.green(` ✓ ${status.displayName} v${status.version ?? '?'} is installed`));
132
+ return true;
133
+ }
134
+ const def = getHarnessDefinition(status.id);
135
+ const what = missing ? `Install ${status.displayName}` : `Update ${status.displayName} v${status.version} → v${status.latestVersion}`;
136
+ if (options.interactive) {
137
+ const answer = await io.ask(` ${what} (npm install -g ${def?.npmPackage})? [${missing ? 'Y/n' : 'y/N'}] `);
138
+ if (!isYes(answer, missing)) {
139
+ io.log(chalk.gray(missing ? ` Skipped. Install it later: npm install -g ${def?.npmPackage}` : ' Keeping the installed version.'));
140
+ return !missing;
141
+ }
142
+ }
143
+ else {
144
+ io.log(chalk.blue(` ${what}…`));
145
+ }
146
+ const job = service.startInstall(status.id);
147
+ const done = await service.install.waitForJob(job.jobId);
148
+ if (done.state === 'succeeded') {
149
+ io.log(chalk.green(` ✓ ${status.displayName} ${missing ? 'installed' : 'updated'}${done.usedUserPrefix ? ' (under ~/.crewly/npm-global: no permission for the global npm folder)' : ''}`));
150
+ return true;
151
+ }
152
+ const tail = done.log.trim().split('\n').slice(-8).join('\n ');
153
+ io.log(chalk.red(` ✖ ${what} failed:`));
154
+ io.log(chalk.gray(` ${tail}`));
155
+ return !missing;
156
+ }
157
+ /**
158
+ * Print what the owner has to do for a login session (URL, code, message).
159
+ *
160
+ * @param io - Output
161
+ * @param session - Current session
162
+ * @param shown - What was already printed (mutated)
163
+ */
164
+ function printSessionNews(io, session, shown) {
165
+ if (session.url && session.url !== shown.url) {
166
+ shown.url = session.url;
167
+ io.log('');
168
+ io.log(' Open this link on any device — your phone is fine:');
169
+ io.log(chalk.cyan(` ${session.url}`));
170
+ }
171
+ if (session.userCode && session.userCode !== shown.code) {
172
+ shown.code = session.userCode;
173
+ io.log(` Then enter this one-time code: ${chalk.bold(session.userCode)}`);
174
+ }
175
+ if (session.message && session.message !== shown.message && !isTerminalLoginState(session.state)) {
176
+ shown.message = session.message;
177
+ io.log(chalk.yellow(` ${session.message}`));
178
+ }
179
+ }
180
+ /**
181
+ * Drive a broker login to its end (or hand it off, non-interactive).
182
+ *
183
+ * @param io - Prompting and output
184
+ * @param driver - Where the session lives
185
+ * @param harnessId - Harness
186
+ * @param method - Broker login method
187
+ * @param options - `interactive`; timing for tests
188
+ * @returns Outcome
189
+ */
190
+ export async function driveBrokerLogin(io, driver, harnessId, method, options) {
191
+ const timing = options.timing ?? DEFAULT_SETUP_TIMING;
192
+ const handOff = !options.interactive && driver.where === 'backend';
193
+ let session = await driver.start(harnessId, method);
194
+ const startedAt = timing.now();
195
+ const shown = {};
196
+ let screenShown = false;
197
+ let waitingNoted = false;
198
+ for (;;) {
199
+ printSessionNews(io, session, shown);
200
+ if (!waitingNoted && !handOff && (shown.url || shown.code) && !session.needsInput && !isTerminalLoginState(session.state)) {
201
+ waitingNoted = true;
202
+ io.log(chalk.gray(' Waiting for the sign-in to finish (up to 15 minutes; Ctrl+C to stop)…'));
203
+ }
204
+ if (isTerminalLoginState(session.state)) {
205
+ if (session.state === 'succeeded') {
206
+ io.log(chalk.green(` ✓ ${session.message ?? 'Logged in.'}`));
207
+ return 'succeeded';
208
+ }
209
+ io.log(chalk.red(` ✖ Login ${session.state.replace('_', ' ')}${session.message ? `: ${session.message}` : ''}`));
210
+ if (session.state === 'failed' && session.screen)
211
+ io.log(chalk.gray(` Last screen:\n${indent(session.screen)}`));
212
+ return 'failed';
213
+ }
214
+ if (handOff && (shown.url || shown.code || session.needsInput)) {
215
+ io.log('');
216
+ io.log(` Finish on your phone or any browser: ${session.needsInput ? 'paste the code you get into Crewly → Setup (web app or phone app) — it shows this same login.' : 'Crewly picks the login up by itself.'}`);
217
+ return 'pending';
218
+ }
219
+ if (session.needsInput && options.interactive) {
220
+ const answer = await io.ask(' Paste the code from the sign-in page here: ');
221
+ if (answer.trim() === '')
222
+ continue;
223
+ session = await driver.input(session.id, answer.trim());
224
+ continue;
225
+ }
226
+ const elapsed = timing.now() - startedAt;
227
+ if (!screenShown && !shown.url && !shown.code && elapsed >= timing.screenFallbackMs && session.screen) {
228
+ screenShown = true;
229
+ io.log(chalk.yellow(' No sign-in link found yet. This is what the login command shows:'));
230
+ io.log(chalk.gray(indent(session.screen)));
231
+ }
232
+ if ((handOff && elapsed >= timing.urlWaitMs) || elapsed >= timing.maxWaitMs) {
233
+ if (!handOff)
234
+ await driver.cancel(session.id).catch(() => undefined);
235
+ io.log(chalk.yellow(handOff ? ' The login did not show a link in time; finish it from Crewly → Setup.' : ' Stopped waiting for the login.'));
236
+ return handOff ? 'pending' : 'failed';
237
+ }
238
+ await timing.sleep(timing.pollIntervalMs);
239
+ session = await driver.get(session.id);
240
+ }
241
+ }
242
+ /**
243
+ * Indent every line of a block.
244
+ *
245
+ * @param text - Text
246
+ * @returns Indented text
247
+ */
248
+ function indent(text) {
249
+ return text
250
+ .split('\n')
251
+ .map((line) => ` ${line}`)
252
+ .join('\n');
253
+ }
254
+ /**
255
+ * Log a harness in: pick a method, then broker or API key.
256
+ *
257
+ * Non-interactive (`--yes`) never prompts. It starts a brokered login only
258
+ * when someone can finish it without this terminal: through the running
259
+ * backend (the web app / phone see the session), or a device-code login
260
+ * that needs no reply. Otherwise it prints how to finish later.
261
+ *
262
+ * @param io - Prompting and output
263
+ * @param service - Harness engine (API keys, status)
264
+ * @param getDriver - Resolves the login driver
265
+ * @param status - Current harness status
266
+ * @param options - `interactive`, `force` (log in again), `method`, timing
267
+ * @returns Outcome
268
+ */
269
+ export async function loginHarness(io, service, getDriver, status, options) {
270
+ if (status.loginMethods.length === 0) {
271
+ io.log(chalk.gray(` ${status.displayName}: Crewly does not log it in. Run \`${getHarnessDefinition(status.id)?.command}\` once and sign in.`));
272
+ return 'skipped';
273
+ }
274
+ if (status.loginState === 'logged_in' && !options.force) {
275
+ if (!options.interactive) {
276
+ io.log(chalk.green(` ✓ ${status.displayName} is already logged in${status.loginSource ? ` (${status.loginSource})` : ''}`));
277
+ return 'already_logged_in';
278
+ }
279
+ const again = await io.ask(` ${status.displayName} is already logged in (${status.loginSource ?? 'found'}). Log in again? [y/N] `);
280
+ if (!isYes(again, false))
281
+ return 'already_logged_in';
282
+ }
283
+ let method = options.method ?? getBrokerLoginMethod(status.id)?.id ?? status.loginMethods[0].id;
284
+ if (options.interactive && !options.method && status.loginMethods.length > 1) {
285
+ io.log(` How do you want to log in to ${status.displayName}?`);
286
+ status.loginMethods.forEach((m, index) => io.log(` ${index + 1}. ${m.label}`));
287
+ const answer = await io.ask(` Enter choice (1-${status.loginMethods.length}) [1]: `);
288
+ const index = Number.parseInt(answer, 10);
289
+ method = index >= 1 && index <= status.loginMethods.length ? status.loginMethods[index - 1].id : status.loginMethods[0].id;
290
+ }
291
+ const methodDef = status.loginMethods.find((m) => m.id === method);
292
+ if (!methodDef) {
293
+ io.log(chalk.red(` ✖ ${status.displayName} has no "${method}" login.`));
294
+ return 'failed';
295
+ }
296
+ if (methodDef.kind === 'api_key') {
297
+ if (!options.interactive) {
298
+ io.log(chalk.gray(` Skipped: an API key has to be pasted. Run \`crewly login ${cliAlias(status.id)}\` or use Crewly → Setup.`));
299
+ return 'skipped';
300
+ }
301
+ const key = await (io.askSecret ?? io.ask)(` Paste your ${methodDef.label} (not shown): `);
302
+ if (key.trim() === '') {
303
+ io.log(chalk.gray(' Skipped.'));
304
+ return 'skipped';
305
+ }
306
+ try {
307
+ const after = await service.submitApiKey(status.id, key);
308
+ io.log(chalk.green(` ✓ ${status.displayName} ${after.loginState === 'logged_in' ? 'is logged in' : 'key saved'}`));
309
+ return 'succeeded';
310
+ }
311
+ catch (error) {
312
+ io.log(chalk.red(` ✖ ${error instanceof Error ? error.message : String(error)}`));
313
+ return 'failed';
314
+ }
315
+ }
316
+ const driver = await getDriver();
317
+ const needsReply = Boolean(getLoginRules(status.id, method)?.inputPromptPattern);
318
+ if (!options.interactive && driver.where === 'in-process' && needsReply) {
319
+ io.log(chalk.gray(` Login skipped (--yes): ${status.displayName}'s sign-in needs a code typed back.`));
320
+ io.log(chalk.gray(` Finish it from your phone: start Crewly (\`crewly start\`) and open Crewly → Setup, or run \`crewly login ${cliAlias(status.id)}\`.`));
321
+ return 'skipped';
322
+ }
323
+ if (driver.where === 'backend')
324
+ io.log(chalk.gray(' (Crewly is running: this login is also visible in Crewly → Setup on the web and phone.)'));
325
+ try {
326
+ return await driveBrokerLogin(io, driver, status.id, method, { interactive: options.interactive, timing: options.timing });
327
+ }
328
+ catch (error) {
329
+ io.log(chalk.red(` ✖ ${error instanceof Error ? error.message : String(error)}`));
330
+ return 'failed';
331
+ }
332
+ }
333
+ /**
334
+ * Short CLI name for a harness (`claude`, `codex`, `gemini`).
335
+ *
336
+ * @param id - Harness id
337
+ * @returns Alias
338
+ */
339
+ export function cliAlias(id) {
340
+ const entry = Object.entries(HARNESS_CONSTANTS.CLI_ALIASES).find(([, value]) => value === id);
341
+ return entry ? entry[0] : id;
342
+ }
343
+ /**
344
+ * The whole harness step of onboarding: detect → choose → install → record → log in.
345
+ *
346
+ * Only the orchestrator's harness is installed.
347
+ *
348
+ * @param io - Prompting and output
349
+ * @param service - Harness engine
350
+ * @param getDriver - Resolves the login driver
351
+ * @param options - `interactive`, `preset` harness, `loginHeader` printed before the login, timing
352
+ * @returns What was set up
353
+ */
354
+ export async function runHarnessSetup(io, service, getDriver, options) {
355
+ io.log(' Detecting harnesses…');
356
+ const overview = await service.getOverview();
357
+ printHarnessOverview(io, overview);
358
+ io.log('');
359
+ const harnessId = await chooseOrcHarness(io, overview, { interactive: options.interactive, preset: options.preset });
360
+ const status = overview.harnesses.find((s) => s.id === harnessId) ?? (await service.getStatus(harnessId));
361
+ io.log(chalk.green(` ✓ Orchestrator harness: ${status.displayName}`));
362
+ const installed = await ensureHarnessInstalled(io, service, status, { interactive: options.interactive });
363
+ await service.setOrcHarness(harnessId);
364
+ io.log('');
365
+ if (!installed) {
366
+ if (options.loginHeader)
367
+ io.log(options.loginHeader);
368
+ io.log(chalk.gray(` Log in after installing: crewly login ${cliAlias(harnessId)}`));
369
+ return { harnessId, installed, login: 'skipped' };
370
+ }
371
+ if (options.loginHeader)
372
+ io.log(options.loginHeader);
373
+ const fresh = await service.getStatus(harnessId);
374
+ const login = await loginHarness(io, service, getDriver, fresh, { interactive: options.interactive, timing: options.timing });
375
+ return { harnessId, installed, login };
376
+ }
377
+ //# sourceMappingURL=harness-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-setup.js","sourceRoot":"","sources":["../../../../../cli/src/commands/harness-setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * `crewly harness` and `crewly login <claude|codex>`.
3
+ *
4
+ * - `crewly harness` prints each harness (installed version, newer version,
5
+ * login state), the orchestrator's harness and the system tools.
6
+ * - `crewly login <name>` logs a harness in with the same broker the web
7
+ * setup page uses: it prints the sign-in link (open it on any device) and
8
+ * reads Claude's code from this terminal. When Crewly is running, the
9
+ * session lives in the backend, so it can also be finished from the web
10
+ * app or phone.
11
+ *
12
+ * @module cli/commands/harness
13
+ */
14
+ import type { HarnessService } from '../../../backend/src/services/harness/harness.service.js';
15
+ import { type LoginDriver } from '../utils/harness-engine.js';
16
+ import { type PromptIO } from '../utils/prompt-io.js';
17
+ import { type SetupTiming } from './harness-setup.js';
18
+ /** Options for `crewly login`. */
19
+ export interface LoginCommandOptions {
20
+ /** Login method id (`subscription`, `device`, `api_key`) */
21
+ method?: string;
22
+ /** Log in again even when already logged in */
23
+ force?: boolean;
24
+ /** Never prompt (hand the login to the web app / phone when possible) */
25
+ yes?: boolean;
26
+ }
27
+ /** Injectable dependencies (tests). */
28
+ export interface HarnessCommandDeps {
29
+ service?: HarnessService;
30
+ io?: PromptIO;
31
+ getDriver?: () => Promise<LoginDriver>;
32
+ timing?: SetupTiming;
33
+ /** Stdin is a terminal */
34
+ interactive?: boolean;
35
+ }
36
+ /** Error thrown when stdin closes during `crewly login`. */
37
+ export declare class LoginInputClosedError extends Error {
38
+ constructor();
39
+ }
40
+ /**
41
+ * `crewly harness`: print harness status.
42
+ *
43
+ * @param deps - Injectable dependencies
44
+ * @returns Exit code
45
+ */
46
+ export declare function harnessCommand(deps?: HarnessCommandDeps): Promise<number>;
47
+ /**
48
+ * `crewly login <name>`: log a harness in.
49
+ *
50
+ * @param name - `claude`, `codex` (or a full harness id)
51
+ * @param options - Command options
52
+ * @param deps - Injectable dependencies
53
+ * @returns Exit code
54
+ */
55
+ export declare function loginCommand(name: string, options?: LoginCommandOptions, deps?: HarnessCommandDeps): Promise<number>;
56
+ //# sourceMappingURL=harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../../../../cli/src/commands/harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAE/F,OAAO,EAA4C,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACxG,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAyD,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE7G,kCAAkC;AAClC,MAAM,WAAW,mBAAmB;IACnC,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yEAAyE;IACzE,GAAG,CAAC,EAAE,OAAO,CAAC;CACd;AAED,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IAClC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,EAAE,CAAC,EAAE,QAAQ,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,0BAA0B;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,4DAA4D;AAC5D,qBAAa,qBAAsB,SAAQ,KAAK;;CAK/C;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CASnF;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyClI"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * `crewly harness` and `crewly login <claude|codex>`.
3
+ *
4
+ * - `crewly harness` prints each harness (installed version, newer version,
5
+ * login state), the orchestrator's harness and the system tools.
6
+ * - `crewly login <name>` logs a harness in with the same broker the web
7
+ * setup page uses: it prints the sign-in link (open it on any device) and
8
+ * reads Claude's code from this terminal. When Crewly is running, the
9
+ * session lives in the backend, so it can also be finished from the web
10
+ * app or phone.
11
+ *
12
+ * @module cli/commands/harness
13
+ */
14
+ import chalk from 'chalk';
15
+ import { createInterface } from 'readline';
16
+ import { getHarnessDefinition, resolveHarnessAlias } from '../../../backend/src/services/harness/harness-registry.js';
17
+ import { CLI_CONSTANTS } from '../constants.js';
18
+ import { createCliHarnessService, pickLoginDriver } from '../utils/harness-engine.js';
19
+ import { createReadlineIO } from '../utils/prompt-io.js';
20
+ import { loginHarness, printHarnessOverview } from './harness-setup.js';
21
+ /** Error thrown when stdin closes during `crewly login`. */
22
+ export class LoginInputClosedError extends Error {
23
+ constructor() {
24
+ super('Input closed before the login finished');
25
+ this.name = 'LoginInputClosedError';
26
+ }
27
+ }
28
+ /**
29
+ * `crewly harness`: print harness status.
30
+ *
31
+ * @param deps - Injectable dependencies
32
+ * @returns Exit code
33
+ */
34
+ export async function harnessCommand(deps = {}) {
35
+ const service = deps.service ?? createCliHarnessService();
36
+ const io = deps.io ?? { ask: async () => '', askSecret: async () => '', log: (line) => console.log(line) };
37
+ const overview = await service.getOverview();
38
+ io.log(chalk.bold('Harnesses'));
39
+ printHarnessOverview(io, overview);
40
+ io.log('');
41
+ io.log(`Orchestrator harness: ${overview.orcHarness ?? chalk.gray('not chosen yet (crewly onboard)')}`);
42
+ return CLI_CONSTANTS.EXIT_CODES.SUCCESS;
43
+ }
44
+ /**
45
+ * `crewly login <name>`: log a harness in.
46
+ *
47
+ * @param name - `claude`, `codex` (or a full harness id)
48
+ * @param options - Command options
49
+ * @param deps - Injectable dependencies
50
+ * @returns Exit code
51
+ */
52
+ export async function loginCommand(name, options = {}, deps = {}) {
53
+ const harnessId = resolveHarnessAlias(name);
54
+ if (!harnessId) {
55
+ console.log(chalk.red(`Unknown harness "${name}". Use: crewly login claude | codex`));
56
+ return CLI_CONSTANTS.EXIT_CODES.INVALID_ARGS;
57
+ }
58
+ const service = deps.service ?? createCliHarnessService();
59
+ const interactive = options.yes !== true && (deps.interactive ?? process.stdin.isTTY === true);
60
+ let rl = null;
61
+ let io;
62
+ if (deps.io) {
63
+ io = deps.io;
64
+ }
65
+ else {
66
+ rl = createInterface({ input: process.stdin, output: process.stdout });
67
+ io = createReadlineIO(rl, () => new LoginInputClosedError());
68
+ }
69
+ const getDriver = deps.getDriver ?? (() => pickLoginDriver(service));
70
+ let outcome = 'failed';
71
+ try {
72
+ const status = await service.getStatus(harnessId);
73
+ if (!status.installed) {
74
+ io.log(chalk.red(`${status.displayName} is not installed. Run \`crewly onboard\` or: npm install -g ${getHarnessDefinition(harnessId)?.npmPackage}`));
75
+ return CLI_CONSTANTS.EXIT_CODES.ERROR;
76
+ }
77
+ io.log(chalk.bold(`Logging in to ${status.displayName}`));
78
+ outcome = await loginHarness(io, service, getDriver, status, {
79
+ interactive,
80
+ force: options.force,
81
+ method: options.method,
82
+ timing: deps.timing,
83
+ });
84
+ }
85
+ catch (error) {
86
+ if (!(error instanceof LoginInputClosedError))
87
+ throw error;
88
+ io.log(chalk.yellow('Input closed; login not finished.'));
89
+ outcome = 'failed';
90
+ }
91
+ finally {
92
+ rl?.close();
93
+ service.broker.shutdown();
94
+ }
95
+ return outcome === 'failed' ? CLI_CONSTANTS.EXIT_CODES.ERROR : CLI_CONSTANTS.EXIT_CODES.SUCCESS;
96
+ }
97
+ //# sourceMappingURL=harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../../../cli/src/commands/harness.ts"],"names":[],"mappings":"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"}