expandai 0.0.2 → 0.0.3

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 (271) hide show
  1. package/README.md +42 -5
  2. package/build/dts/ApiClient.d.ts +128 -194
  3. package/build/dts/ApiClient.d.ts.map +1 -1
  4. package/build/dts/Auth/Domain.d.ts +95 -0
  5. package/build/dts/Auth/Domain.d.ts.map +1 -0
  6. package/build/dts/Auth/ManualAuthorization.d.ts +107 -0
  7. package/build/dts/Auth/ManualAuthorization.d.ts.map +1 -0
  8. package/build/dts/Auth/PendingInit.d.ts +35 -0
  9. package/build/dts/Auth/PendingInit.d.ts.map +1 -0
  10. package/build/dts/Auth/Pkce.d.ts +10 -0
  11. package/build/dts/Auth/Pkce.d.ts.map +1 -0
  12. package/build/dts/Auth/SetupGrantAuthorization.d.ts +34 -0
  13. package/build/dts/Auth/SetupGrantAuthorization.d.ts.map +1 -0
  14. package/build/dts/Authentication.d.ts +10 -9
  15. package/build/dts/Authentication.d.ts.map +1 -1
  16. package/build/dts/BrowserOAuth.d.ts +7 -7
  17. package/build/dts/BrowserOAuth.d.ts.map +1 -1
  18. package/build/dts/CommandPath.d.ts +2 -0
  19. package/build/dts/CommandPath.d.ts.map +1 -0
  20. package/build/dts/Commands/Fetch.d.ts.map +1 -1
  21. package/build/dts/Commands/Hook.d.ts +5 -5
  22. package/build/dts/Commands/Init.d.ts +55 -0
  23. package/build/dts/Commands/Init.d.ts.map +1 -0
  24. package/build/dts/Commands/Mcp.d.ts +6 -6
  25. package/build/dts/Commands/Search.d.ts.map +1 -1
  26. package/build/dts/Commands/Skill.d.ts +4 -4
  27. package/build/dts/Commands/Status.d.ts +27 -0
  28. package/build/dts/Commands/Status.d.ts.map +1 -0
  29. package/build/dts/Commands/Telemetry.d.ts +7 -0
  30. package/build/dts/Commands/Telemetry.d.ts.map +1 -0
  31. package/build/dts/Commands/Uninstall.d.ts +4 -4
  32. package/build/dts/Config.d.ts +108 -17
  33. package/build/dts/Config.d.ts.map +1 -1
  34. package/build/dts/Hook/SnapshotNote.d.ts +8 -4
  35. package/build/dts/Hook/SnapshotNote.d.ts.map +1 -1
  36. package/build/dts/Init/ClaudeAdapter.d.ts +61 -0
  37. package/build/dts/Init/ClaudeAdapter.d.ts.map +1 -0
  38. package/build/dts/Init/ClaudeProfile.d.ts +78 -0
  39. package/build/dts/Init/ClaudeProfile.d.ts.map +1 -0
  40. package/build/dts/Init/Domain.d.ts +139 -0
  41. package/build/dts/Init/Domain.d.ts.map +1 -0
  42. package/build/dts/Init/HarnessAdapter.d.ts +33 -0
  43. package/build/dts/Init/HarnessAdapter.d.ts.map +1 -0
  44. package/build/dts/Init/HarnessDetector.d.ts +19 -0
  45. package/build/dts/Init/HarnessDetector.d.ts.map +1 -0
  46. package/build/dts/Init/HarnessRegistry.d.ts +50 -0
  47. package/build/dts/Init/HarnessRegistry.d.ts.map +1 -0
  48. package/build/dts/Init/MutationTransaction.d.ts +96 -0
  49. package/build/dts/Init/MutationTransaction.d.ts.map +1 -0
  50. package/build/dts/Init/Service.d.ts +72 -0
  51. package/build/dts/Init/Service.d.ts.map +1 -0
  52. package/build/dts/Init/StandardAdapters.d.ts +42 -0
  53. package/build/dts/Init/StandardAdapters.d.ts.map +1 -0
  54. package/build/dts/Init/Status.d.ts +149 -0
  55. package/build/dts/Init/Status.d.ts.map +1 -0
  56. package/build/dts/Install/Claude/Hook.d.ts +85 -25
  57. package/build/dts/Install/Claude/Hook.d.ts.map +1 -1
  58. package/build/dts/Install/Claude/Mcp.d.ts +21 -18
  59. package/build/dts/Install/Claude/Mcp.d.ts.map +1 -1
  60. package/build/dts/Install/Claude/Skill.d.ts +14 -15
  61. package/build/dts/Install/Claude/Skill.d.ts.map +1 -1
  62. package/build/dts/Install/Codex/Mcp.d.ts +14 -8
  63. package/build/dts/Install/Codex/Mcp.d.ts.map +1 -1
  64. package/build/dts/Install/Codex/Skill.d.ts +4 -2
  65. package/build/dts/Install/Codex/Skill.d.ts.map +1 -1
  66. package/build/dts/Install/Cursor/Mcp.d.ts +13 -13
  67. package/build/dts/Install/Cursor/Mcp.d.ts.map +1 -1
  68. package/build/dts/Install/Cursor/Skill.d.ts +4 -2
  69. package/build/dts/Install/Cursor/Skill.d.ts.map +1 -1
  70. package/build/dts/Install/Domain.d.ts +35 -5
  71. package/build/dts/Install/Domain.d.ts.map +1 -1
  72. package/build/dts/Install/Hook.d.ts +4 -4
  73. package/build/dts/Install/Hook.d.ts.map +1 -1
  74. package/build/dts/Install/Mcp.d.ts +5 -5
  75. package/build/dts/Install/Mcp.d.ts.map +1 -1
  76. package/build/dts/Install/Opencode/Hook.d.ts +4 -3
  77. package/build/dts/Install/Opencode/Hook.d.ts.map +1 -1
  78. package/build/dts/Install/Opencode/Mcp.d.ts +11 -11
  79. package/build/dts/Install/Opencode/Mcp.d.ts.map +1 -1
  80. package/build/dts/Install/Opencode/Skill.d.ts +4 -2
  81. package/build/dts/Install/Opencode/Skill.d.ts.map +1 -1
  82. package/build/dts/Install/Skill.d.ts +3 -3
  83. package/build/dts/Install/Uninstall.d.ts +6 -6
  84. package/build/dts/Install/Uninstall.d.ts.map +1 -1
  85. package/build/dts/MarkdownAnsi.d.ts +29 -0
  86. package/build/dts/MarkdownAnsi.d.ts.map +1 -0
  87. package/build/dts/Mcp/ExpandDocs.d.ts +17 -5
  88. package/build/dts/Mcp/ExpandDocs.d.ts.map +1 -1
  89. package/build/dts/Mcp/Server.d.ts +1 -1
  90. package/build/dts/Mcp/Server.d.ts.map +1 -1
  91. package/build/dts/Mcp/tools/Citations.d.ts +100 -71
  92. package/build/dts/Mcp/tools/Citations.d.ts.map +1 -1
  93. package/build/dts/Mcp/tools/Fetch.d.ts +16 -15
  94. package/build/dts/Mcp/tools/Fetch.d.ts.map +1 -1
  95. package/build/dts/SecureFile.d.ts +23 -0
  96. package/build/dts/SecureFile.d.ts.map +1 -0
  97. package/build/dts/Snippets.d.ts +11 -12
  98. package/build/dts/Snippets.d.ts.map +1 -1
  99. package/build/dts/Telemetry.d.ts +30 -0
  100. package/build/dts/Telemetry.d.ts.map +1 -0
  101. package/build/dts/Version.d.ts +2 -0
  102. package/build/dts/Version.d.ts.map +1 -0
  103. package/build/dts/Xdg.d.ts +11 -0
  104. package/build/dts/Xdg.d.ts.map +1 -0
  105. package/build/esm/ApiClient.js +133 -10
  106. package/build/esm/ApiClient.js.map +1 -1
  107. package/build/esm/Auth/Domain.js +56 -0
  108. package/build/esm/Auth/Domain.js.map +1 -0
  109. package/build/esm/Auth/ManualAuthorization.js +253 -0
  110. package/build/esm/Auth/ManualAuthorization.js.map +1 -0
  111. package/build/esm/Auth/PendingInit.js +267 -0
  112. package/build/esm/Auth/PendingInit.js.map +1 -0
  113. package/build/esm/Auth/Pkce.js +23 -0
  114. package/build/esm/Auth/Pkce.js.map +1 -0
  115. package/build/esm/Auth/SetupGrantAuthorization.js +91 -0
  116. package/build/esm/Auth/SetupGrantAuthorization.js.map +1 -0
  117. package/build/esm/Authentication.js +38 -7
  118. package/build/esm/Authentication.js.map +1 -1
  119. package/build/esm/BrowserOAuth.js +7 -10
  120. package/build/esm/BrowserOAuth.js.map +1 -1
  121. package/build/esm/CommandPath.js +31 -0
  122. package/build/esm/CommandPath.js.map +1 -0
  123. package/build/esm/Commands/Fetch.js +30 -6
  124. package/build/esm/Commands/Fetch.js.map +1 -1
  125. package/build/esm/Commands/Init.js +371 -0
  126. package/build/esm/Commands/Init.js.map +1 -0
  127. package/build/esm/Commands/Search.js +6 -3
  128. package/build/esm/Commands/Search.js.map +1 -1
  129. package/build/esm/Commands/Status.js +186 -0
  130. package/build/esm/Commands/Status.js.map +1 -0
  131. package/build/esm/Commands/Telemetry.js +23 -0
  132. package/build/esm/Commands/Telemetry.js.map +1 -0
  133. package/build/esm/Config.js +502 -28
  134. package/build/esm/Config.js.map +1 -1
  135. package/build/esm/Hook/Claude.js +1 -1
  136. package/build/esm/Hook/Claude.js.map +1 -1
  137. package/build/esm/Hook/SnapshotNote.js +54 -7
  138. package/build/esm/Hook/SnapshotNote.js.map +1 -1
  139. package/build/esm/Init/ClaudeAdapter.js +137 -0
  140. package/build/esm/Init/ClaudeAdapter.js.map +1 -0
  141. package/build/esm/Init/ClaudeProfile.js +380 -0
  142. package/build/esm/Init/ClaudeProfile.js.map +1 -0
  143. package/build/esm/Init/Domain.js +118 -0
  144. package/build/esm/Init/Domain.js.map +1 -0
  145. package/build/esm/Init/HarnessAdapter.js +21 -0
  146. package/build/esm/Init/HarnessAdapter.js.map +1 -0
  147. package/build/esm/Init/HarnessDetector.js +65 -0
  148. package/build/esm/Init/HarnessDetector.js.map +1 -0
  149. package/build/esm/Init/HarnessRegistry.js +58 -0
  150. package/build/esm/Init/HarnessRegistry.js.map +1 -0
  151. package/build/esm/Init/MutationTransaction.js +494 -0
  152. package/build/esm/Init/MutationTransaction.js.map +1 -0
  153. package/build/esm/Init/Service.js +319 -0
  154. package/build/esm/Init/Service.js.map +1 -0
  155. package/build/esm/Init/StandardAdapters.js +116 -0
  156. package/build/esm/Init/StandardAdapters.js.map +1 -0
  157. package/build/esm/Init/Status.js +215 -0
  158. package/build/esm/Init/Status.js.map +1 -0
  159. package/build/esm/Install/Claude/Hook.js +182 -50
  160. package/build/esm/Install/Claude/Hook.js.map +1 -1
  161. package/build/esm/Install/Claude/Mcp.js +56 -26
  162. package/build/esm/Install/Claude/Mcp.js.map +1 -1
  163. package/build/esm/Install/Claude/Skill.js +49 -27
  164. package/build/esm/Install/Claude/Skill.js.map +1 -1
  165. package/build/esm/Install/Codex/Mcp.js +9 -4
  166. package/build/esm/Install/Codex/Mcp.js.map +1 -1
  167. package/build/esm/Install/Codex/Skill.js +4 -1
  168. package/build/esm/Install/Codex/Skill.js.map +1 -1
  169. package/build/esm/Install/Cursor/Mcp.js +7 -4
  170. package/build/esm/Install/Cursor/Mcp.js.map +1 -1
  171. package/build/esm/Install/Cursor/Skill.js +4 -1
  172. package/build/esm/Install/Cursor/Skill.js.map +1 -1
  173. package/build/esm/Install/Domain.js +60 -3
  174. package/build/esm/Install/Domain.js.map +1 -1
  175. package/build/esm/Install/Hook.js.map +1 -1
  176. package/build/esm/Install/Mcp.js +1 -1
  177. package/build/esm/Install/Mcp.js.map +1 -1
  178. package/build/esm/Install/Opencode/Hook.js +1 -1
  179. package/build/esm/Install/Opencode/Hook.js.map +1 -1
  180. package/build/esm/Install/Opencode/Mcp.js +6 -3
  181. package/build/esm/Install/Opencode/Mcp.js.map +1 -1
  182. package/build/esm/Install/Opencode/Skill.js +4 -1
  183. package/build/esm/Install/Opencode/Skill.js.map +1 -1
  184. package/build/esm/Install/Opencode/expandai-webfetch.js +27 -9
  185. package/build/esm/Install/Skill.js.map +1 -1
  186. package/build/esm/Install/Uninstall.js +2 -2
  187. package/build/esm/Install/Uninstall.js.map +1 -1
  188. package/build/esm/MarkdownAnsi.js +142 -0
  189. package/build/esm/MarkdownAnsi.js.map +1 -0
  190. package/build/esm/Mcp/ExpandDocs.js +44 -52
  191. package/build/esm/Mcp/ExpandDocs.js.map +1 -1
  192. package/build/esm/Mcp/RequestHeaders.js.map +1 -1
  193. package/build/esm/Mcp/Server.js +2 -1
  194. package/build/esm/Mcp/Server.js.map +1 -1
  195. package/build/esm/Mcp/tools/Citations.js +109 -8
  196. package/build/esm/Mcp/tools/Citations.js.map +1 -1
  197. package/build/esm/Mcp/tools/Fetch.js +36 -12
  198. package/build/esm/Mcp/tools/Fetch.js.map +1 -1
  199. package/build/esm/SecureFile.js +36 -0
  200. package/build/esm/SecureFile.js.map +1 -0
  201. package/build/esm/Snippets.js +12 -1
  202. package/build/esm/Snippets.js.map +1 -1
  203. package/build/esm/Telemetry.js +157 -0
  204. package/build/esm/Telemetry.js.map +1 -0
  205. package/build/esm/Version.js +4 -0
  206. package/build/esm/Version.js.map +1 -0
  207. package/build/esm/Xdg.js +15 -0
  208. package/build/esm/Xdg.js.map +1 -0
  209. package/build/esm/main.js +122 -14
  210. package/build/esm/main.js.map +1 -1
  211. package/build/skills/expandai/SKILL.md +26 -3
  212. package/package.json +4 -4
  213. package/src/ApiClient.ts +206 -13
  214. package/src/Auth/Domain.ts +63 -0
  215. package/src/Auth/ManualAuthorization.ts +296 -0
  216. package/src/Auth/PendingInit.ts +338 -0
  217. package/src/Auth/Pkce.ts +26 -0
  218. package/src/Auth/SetupGrantAuthorization.ts +116 -0
  219. package/src/Authentication.ts +49 -11
  220. package/src/BrowserOAuth.ts +10 -12
  221. package/src/CommandPath.ts +30 -0
  222. package/src/Commands/Fetch.ts +42 -11
  223. package/src/Commands/Init.ts +489 -0
  224. package/src/Commands/Search.ts +8 -3
  225. package/src/Commands/Status.ts +228 -0
  226. package/src/Commands/Telemetry.ts +42 -0
  227. package/src/Config.ts +695 -50
  228. package/src/Hook/Claude.ts +1 -1
  229. package/src/Hook/SnapshotNote.ts +55 -7
  230. package/src/Init/ClaudeAdapter.ts +191 -0
  231. package/src/Init/ClaudeProfile.ts +496 -0
  232. package/src/Init/Domain.ts +153 -0
  233. package/src/Init/HarnessAdapter.ts +35 -0
  234. package/src/Init/HarnessDetector.ts +77 -0
  235. package/src/Init/HarnessRegistry.ts +87 -0
  236. package/src/Init/MutationTransaction.ts +747 -0
  237. package/src/Init/Service.ts +385 -0
  238. package/src/Init/StandardAdapters.ts +141 -0
  239. package/src/Init/Status.ts +253 -0
  240. package/src/Install/Claude/Hook.ts +234 -81
  241. package/src/Install/Claude/Mcp.ts +80 -33
  242. package/src/Install/Claude/Skill.ts +70 -37
  243. package/src/Install/Codex/Mcp.ts +14 -9
  244. package/src/Install/Codex/Skill.ts +9 -5
  245. package/src/Install/Cursor/Mcp.ts +12 -9
  246. package/src/Install/Cursor/Skill.ts +9 -5
  247. package/src/Install/Domain.ts +77 -4
  248. package/src/Install/Hook.ts +3 -3
  249. package/src/Install/Mcp.ts +6 -6
  250. package/src/Install/Opencode/Hook.ts +5 -5
  251. package/src/Install/Opencode/Mcp.ts +11 -8
  252. package/src/Install/Opencode/Skill.ts +9 -5
  253. package/src/Install/Opencode/expandai-webfetch.js +27 -9
  254. package/src/Install/Skill.ts +3 -3
  255. package/src/Install/Uninstall.ts +3 -3
  256. package/src/MarkdownAnsi.ts +162 -0
  257. package/src/Mcp/ExpandDocs.ts +46 -55
  258. package/src/Mcp/Server.ts +2 -1
  259. package/src/Mcp/tools/Citations.ts +117 -8
  260. package/src/Mcp/tools/Fetch.ts +40 -14
  261. package/src/SecureFile.ts +70 -0
  262. package/src/Snippets.ts +19 -12
  263. package/src/Telemetry.ts +186 -0
  264. package/src/Version.ts +3 -0
  265. package/src/Xdg.ts +18 -0
  266. package/src/main.ts +171 -12
  267. package/build/dts/DeviceAuth.d.ts +0 -87
  268. package/build/dts/DeviceAuth.d.ts.map +0 -1
  269. package/build/esm/DeviceAuth.js +0 -127
  270. package/build/esm/DeviceAuth.js.map +0 -1
  271. package/src/DeviceAuth.ts +0 -193
package/src/main.ts CHANGED
@@ -3,21 +3,46 @@ import { CliConfig, Command, ValidationError } from '@effect/cli'
3
3
  import { Terminal } from '@effect/platform'
4
4
  import { NodeContext, NodeRuntime } from '@effect/platform-node'
5
5
  import { Cause, Config, Console, Effect, Layer, Logger, LogLevel, Option, Schema, String } from 'effect'
6
+ import { ManualAuthorization } from './Auth/ManualAuthorization.js'
7
+ import { PendingInitStore } from './Auth/PendingInit.js'
8
+ import { SetupGrantAuthorization } from './Auth/SetupGrantAuthorization.js'
6
9
  import { Authentication, LoginCommand, LogoutCommand, WhoamiCommand } from './Authentication.js'
10
+ import { commandFromArgv } from './CommandPath.js'
7
11
  import { FetchCommand } from './Commands/Fetch.js'
8
12
  import { AgentHookCommand, HumanHookCommand } from './Commands/Hook.js'
13
+ import {
14
+ AgentInitCommand,
15
+ HumanInitCommand,
16
+ InitTerminalInteraction,
17
+ preflightAgentInitArgv,
18
+ resolveInitExecutionMode,
19
+ } from './Commands/Init.js'
9
20
  import { InstallSubCommand, UninstallSubCommand } from './Commands/Mcp.js'
10
21
  import { McpRunCommand } from './Commands/McpRun.js'
11
22
  import { SearchCommand } from './Commands/Search.js'
12
23
  import { SkillCommand } from './Commands/Skill.js'
24
+ import {
25
+ AgentStatusCommand,
26
+ HumanStatusCommand,
27
+ preflightAgentStatusArgv,
28
+ resolveStatusExecutionMode,
29
+ StatusTerminalInteraction,
30
+ } from './Commands/Status.js'
31
+ import { TelemetryCommand } from './Commands/Telemetry.js'
13
32
  import { UninstallCommand } from './Commands/Uninstall.js'
14
- import { ConfigManager } from './Config.js'
33
+ import { ConfigManager, envFlag, envLiteral } from './Config.js'
15
34
  import { ClaudeHook } from './Hook/Claude.js'
16
35
  import { OpencodeHook } from './Hook/Opencode.js'
36
+ import { HarnessDetector } from './Init/HarnessDetector.js'
37
+ import { HarnessRegistry } from './Init/HarnessRegistry.js'
38
+ import { InitService } from './Init/Service.js'
39
+ import { StatusService } from './Init/Status.js'
17
40
  import { HookInstaller } from './Install/Hook.js'
18
41
  import { Mcp } from './Install/Mcp.js'
19
42
  import { Skill as SkillInstaller } from './Install/Skill.js'
20
43
  import { Uninstall } from './Install/Uninstall.js'
44
+ import { Telemetry } from './Telemetry.js'
45
+ import { CLI_VERSION } from './Version.js'
21
46
 
22
47
  /**
23
48
  * Where this process is running:
@@ -27,18 +52,39 @@ import { Uninstall } from './Install/Uninstall.js'
27
52
  * - 'mcp': the binary is serving as the MCP transport. MCP only runs in agents.
28
53
  */
29
54
 
55
+ // envFlag / envLiteral read leniently: a malformed value (CLAUDECODE=banana,
56
+ // EXPANDAI_CLI_CONTEXT=bogus) must degrade instead of crashing the CLI —
57
+ // Config.option / Config.withDefault only absorb missing data, not invalid.
30
58
  const EnvironmentSignals = Config.all({
31
- override: Schema.Config('EXPANDAI_CLI_CONTEXT', Schema.Literal('human', 'agent')).pipe(Config.option),
59
+ override: envLiteral('EXPANDAI_CLI_CONTEXT', Schema.Literal('human', 'agent')),
32
60
  mcpTransport: Config.string('MCP_TRANSPORT').pipe(Config.option, Config.map(Option.isSome)),
33
- claudeCode: Config.boolean('CLAUDECODE').pipe(Config.withDefault(false)),
61
+ claudeCode: envFlag('CLAUDECODE'),
34
62
  cursor: Config.string('CURSOR_TRACE_ID').pipe(Config.option, Config.map(Option.isSome)),
35
63
  codex: Config.string('CODEX_RUN_ID').pipe(Config.option, Config.map(Option.isSome)),
36
64
  })
37
65
 
38
- const detectContext = Effect.gen(function* () {
66
+ const detectContext = Effect.fnUntraced(function* (command: string) {
67
+ const initMode = resolveInitExecutionMode({
68
+ argv: process.argv,
69
+ environment: process.env,
70
+ stdinIsTty: process.stdin.isTTY === true,
71
+ stdoutIsTty: process.stdout.isTTY === true,
72
+ })
73
+ if (initMode !== undefined) return initMode === 'machine' ? ('agent' as const) : ('human' as const)
74
+ const statusMode = resolveStatusExecutionMode({
75
+ argv: process.argv,
76
+ environment: process.env,
77
+ stdinIsTty: process.stdin.isTTY === true,
78
+ stdoutIsTty: process.stdout.isTTY === true,
79
+ })
80
+ if (statusMode !== undefined) return statusMode === 'machine' ? ('agent' as const) : ('human' as const)
81
+
39
82
  const signals = yield* EnvironmentSignals
40
83
 
41
- const mcp = signals.mcpTransport ? Option.some('mcp' as const) : Option.none<'mcp'>()
84
+ // Installed MCP entries invoke `expandai mcp run` without any transport env
85
+ // var, so the resolved command is the reliable signal; MCP_TRANSPORT stays
86
+ // as a secondary hint for hand-written configs that set it.
87
+ const mcp = command === 'mcp run' || signals.mcpTransport ? Option.some('mcp' as const) : Option.none<'mcp'>()
42
88
  // Authentication.logout uses both stdout and stdin TTY checks because Prompt
43
89
  // reads from stdin; for context detection a non-TTY stdout alone is enough
44
90
  // to identify a non-interactive caller.
@@ -60,6 +106,21 @@ const AgentMcp = Command.make('mcp').pipe(
60
106
  Command.withSubcommands([McpRunCommand]),
61
107
  )
62
108
 
109
+ const InitServiceLive = InitService.DefaultWithoutDependencies.pipe(
110
+ Layer.provide(
111
+ Layer.mergeAll(
112
+ Authentication.Default,
113
+ ManualAuthorization.Default,
114
+ SetupGrantAuthorization.Default,
115
+ HarnessRegistry.Default,
116
+ ),
117
+ ),
118
+ )
119
+
120
+ const StatusServiceLive = StatusService.DefaultWithoutDependencies.pipe(
121
+ Layer.provide(Layer.mergeAll(ConfigManager.Default, PendingInitStore.Default, HarnessRegistry.Default)),
122
+ )
123
+
63
124
  const HumanCli = Command.make('expandai').pipe(
64
125
  Command.withDescription('expand.ai CLI and MCP server'),
65
126
  Command.withSubcommands([
@@ -68,10 +129,13 @@ const HumanCli = Command.make('expandai').pipe(
68
129
  LoginCommand,
69
130
  WhoamiCommand,
70
131
  LogoutCommand,
132
+ HumanInitCommand,
133
+ HumanStatusCommand,
71
134
  UninstallCommand,
72
135
  HumanMcp,
73
136
  SkillCommand,
74
137
  HumanHookCommand,
138
+ TelemetryCommand,
75
139
  ]),
76
140
  Command.provide(
77
141
  Layer.mergeAll(
@@ -83,6 +147,11 @@ const HumanCli = Command.make('expandai').pipe(
83
147
  Uninstall.Default,
84
148
  ClaudeHook.Default,
85
149
  OpencodeHook.Default,
150
+ InitServiceLive,
151
+ HarnessDetector.Default,
152
+ InitTerminalInteraction.Default,
153
+ StatusServiceLive,
154
+ StatusTerminalInteraction.Default,
86
155
  ),
87
156
  ),
88
157
  )
@@ -95,27 +164,98 @@ const AgentCli = Command.make('expandai').pipe(
95
164
  LoginCommand,
96
165
  WhoamiCommand,
97
166
  LogoutCommand,
167
+ AgentInitCommand,
168
+ AgentStatusCommand,
169
+ // The consent step tells the user `expandai uninstall` is how to undo
170
+ // setup — including removing the machine-wide `WebFetch` deny rule. That
171
+ // text is read by an agent, so the command has to exist in this tree too;
172
+ // it was human-only, and an agent running it got "Invalid subcommand".
173
+ UninstallCommand,
98
174
  AgentMcp,
99
175
  AgentHookCommand,
176
+ TelemetryCommand,
100
177
  ]),
101
178
  Command.provide(
102
- Layer.mergeAll(ConfigManager.Default, Authentication.Default, ClaudeHook.Default, OpencodeHook.Default),
179
+ Layer.mergeAll(
180
+ ConfigManager.Default,
181
+ Authentication.Default,
182
+ ClaudeHook.Default,
183
+ OpencodeHook.Default,
184
+ Mcp.Default,
185
+ HookInstaller.Default,
186
+ SkillInstaller.Default,
187
+ Uninstall.Default,
188
+ InitServiceLive,
189
+ HarnessDetector.Default,
190
+ StatusServiceLive,
191
+ ),
103
192
  ),
104
193
  )
105
194
 
106
195
  const LoggerLive = Layer.unwrapEffect(
107
196
  Effect.gen(function* () {
108
197
  const isDebug = yield* Config.boolean('DEBUG').pipe(Config.withDefault(false))
109
- return Logger.minimumLogLevel(isDebug ? LogLevel.All : LogLevel.Info)
198
+ // stdout is a protocol/data surface (hook JSON payloads, fetched
199
+ // markdown) — a log line ahead of the payload corrupts it for the
200
+ // consumer, so diagnostics go to stderr.
201
+ return Layer.mergeAll(
202
+ Logger.replace(Logger.defaultLogger, Logger.prettyLogger({ stderr: true })),
203
+ Logger.minimumLogLevel(isDebug ? LogLevel.All : LogLevel.Info),
204
+ )
110
205
  }),
111
206
  )
112
207
 
113
- const Env = Layer.mergeAll(NodeContext.layer, CliConfig.layer({ showBuiltIns: false }), LoggerLive)
208
+ // Status is a read-only diagnostic contract, and `init --detect` documents itself
209
+ // as changing nothing — the guide prints "This changes nothing:" directly above
210
+ // it. Select the no-op service before layer acquisition so Telemetry.Default
211
+ // cannot persist a distinct id, repair config permissions, display a notice, or
212
+ // send a request. A brand-new HOME came back from `--detect` with a config.json
213
+ // holding a telemetry id, which is a write however small. Other commands retain
214
+ // the ordinary telemetry service unchanged.
215
+ const writesNothing =
216
+ commandFromArgv(process.argv) === 'status' ||
217
+ (commandFromArgv(process.argv) === 'init' && process.argv.includes('--detect'))
218
+ const TelemetryLive = writesNothing ? Telemetry.DISABLED : Telemetry.Default
219
+ const Env = Layer.mergeAll(NodeContext.layer, CliConfig.layer({ showBuiltIns: false }), LoggerLive, TelemetryLive)
220
+
221
+ const errorTagFromCause = (cause: Cause.Cause<unknown>): string =>
222
+ Cause.failureOption(cause).pipe(
223
+ Option.match({
224
+ onNone: () => 'Defect',
225
+ onSome: (error) =>
226
+ typeof error === 'object' && error !== null && '_tag' in error && typeof error._tag === 'string'
227
+ ? error._tag
228
+ : 'UnknownError',
229
+ }),
230
+ )
231
+
232
+ function startupOnboardingPreflightError(): string | undefined {
233
+ const initMode = resolveInitExecutionMode({
234
+ argv: process.argv,
235
+ environment: process.env,
236
+ stdinIsTty: process.stdin.isTTY === true,
237
+ stdoutIsTty: process.stdout.isTTY === true,
238
+ })
239
+ if (initMode === 'machine') return preflightAgentInitArgv(process.argv)
240
+ const statusMode = resolveStatusExecutionMode({
241
+ argv: process.argv,
242
+ environment: process.env,
243
+ stdinIsTty: process.stdin.isTTY === true,
244
+ stdoutIsTty: process.stdout.isTTY === true,
245
+ })
246
+ return statusMode === 'machine' ? preflightAgentStatusArgv(process.argv) : undefined
247
+ }
114
248
 
115
249
  const program = Effect.gen(function* () {
116
- const context = yield* detectContext
250
+ const command = commandFromArgv(process.argv)
251
+ const context = yield* detectContext(command)
252
+ const telemetry = yield* Telemetry
253
+ if (context === 'human') {
254
+ yield* telemetry.showNoticeIfNeeded()
255
+ }
256
+ yield* telemetry.capture('cli_command_run', { command, context })
117
257
  const cli = context === 'human' ? HumanCli : AgentCli
118
- return yield* Command.run(cli, { name: 'expand.ai CLI', version: '0.0.1' })(process.argv)
258
+ return yield* Command.run(cli, { name: 'expand.ai CLI', version: CLI_VERSION })(process.argv)
119
259
  }).pipe(
120
260
  Effect.catchAllCause((cause) => {
121
261
  const failure = Cause.failureOption(cause)
@@ -138,9 +278,28 @@ const program = Effect.gen(function* () {
138
278
  ),
139
279
  })
140
280
  const debug = Effect.logDebug('Error cause').pipe(Effect.annotateLogs({ cause: Cause.pretty(cause) }))
141
- return print.pipe(Effect.zipRight(debug), Effect.zipRight(Effect.failCause(cause)))
281
+ const trackFailure = Effect.flatMap(Telemetry, (telemetry) =>
282
+ telemetry.capture('cli_command_failed', {
283
+ command: commandFromArgv(process.argv),
284
+ error_tag: errorTagFromCause(cause),
285
+ }),
286
+ )
287
+ return print.pipe(Effect.zipRight(debug), Effect.zipRight(trackFailure), Effect.zipRight(Effect.failCause(cause)))
142
288
  }),
289
+ // Deliver any pending telemetry before the process exits; capped at 1s by
290
+ // Telemetry.flush so it can never hold a short-lived invocation open.
291
+ Effect.ensuring(Effect.flatMap(Telemetry, (telemetry) => telemetry.flush)),
143
292
  Effect.provide(Env),
144
293
  )
145
294
 
146
- NodeRuntime.runMain(program, { disableErrorReporting: true })
295
+ // disablePrettyLogger: runMain's own pretty logger writes to stdout, which
296
+ // would put diagnostics back on the protocol/data stream LoggerLive keeps clean.
297
+ const preflightError = startupOnboardingPreflightError()
298
+ if (preflightError !== undefined) {
299
+ // This validation must finish before the Effect runtime acquires Telemetry,
300
+ // otherwise an invalid machine command could still create local state.
301
+ process.stderr.write(`${preflightError}\n`)
302
+ process.exitCode = 2
303
+ } else {
304
+ NodeRuntime.runMain(program, { disableErrorReporting: true, disablePrettyLogger: true })
305
+ }
@@ -1,87 +0,0 @@
1
- import { HttpClient } from '@effect/platform';
2
- import { Duration, Effect, Schema } from 'effect';
3
- import { ConfigManager } from './Config.js';
4
- declare const DeviceCodeResponse_base: Schema.Class<DeviceCodeResponse, {
5
- device_code: typeof Schema.String;
6
- user_code: Schema.transform<typeof Schema.String, typeof Schema.String>;
7
- verification_uri: typeof Schema.String;
8
- verification_uri_complete: typeof Schema.String;
9
- expires_in: Schema.transform<typeof Schema.Number, typeof Schema.DurationFromSelf>;
10
- interval: Schema.transform<typeof Schema.Number, typeof Schema.DurationFromSelf>;
11
- }, Schema.Struct.Encoded<{
12
- device_code: typeof Schema.String;
13
- user_code: Schema.transform<typeof Schema.String, typeof Schema.String>;
14
- verification_uri: typeof Schema.String;
15
- verification_uri_complete: typeof Schema.String;
16
- expires_in: Schema.transform<typeof Schema.Number, typeof Schema.DurationFromSelf>;
17
- interval: Schema.transform<typeof Schema.Number, typeof Schema.DurationFromSelf>;
18
- }>, never, {
19
- readonly expires_in: Duration.Duration;
20
- } & {
21
- readonly device_code: string;
22
- } & {
23
- readonly user_code: string;
24
- } & {
25
- readonly verification_uri: string;
26
- } & {
27
- readonly verification_uri_complete: string;
28
- } & {
29
- readonly interval: Duration.Duration;
30
- }, {}, {}>;
31
- export declare class DeviceCodeResponse extends DeviceCodeResponse_base {
32
- }
33
- declare const TokenResponse_base: Schema.Class<TokenResponse, {
34
- access_token: typeof Schema.String;
35
- expires_in: Schema.transform<typeof Schema.Number, typeof Schema.DurationFromSelf>;
36
- token_type: typeof Schema.String;
37
- scope: Schema.optional<typeof Schema.String>;
38
- }, Schema.Struct.Encoded<{
39
- access_token: typeof Schema.String;
40
- expires_in: Schema.transform<typeof Schema.Number, typeof Schema.DurationFromSelf>;
41
- token_type: typeof Schema.String;
42
- scope: Schema.optional<typeof Schema.String>;
43
- }>, never, {
44
- readonly access_token: string;
45
- } & {
46
- readonly expires_in: Duration.Duration;
47
- } & {
48
- readonly token_type: string;
49
- } & {
50
- readonly scope?: string | undefined;
51
- }, {}, {}>;
52
- export declare class TokenResponse extends TokenResponse_base {
53
- }
54
- declare const DeviceAuthRequestFailed_base: Schema.TaggedErrorClass<DeviceAuthRequestFailed, "DeviceAuthRequestFailed", {
55
- readonly _tag: Schema.tag<"DeviceAuthRequestFailed">;
56
- } & {
57
- endpoint: typeof Schema.String;
58
- error: typeof Schema.Defect;
59
- status: Schema.optional<typeof Schema.Number>;
60
- }>;
61
- export declare class DeviceAuthRequestFailed extends DeviceAuthRequestFailed_base {
62
- get message(): string;
63
- }
64
- declare const DeviceAuthorizationDenied_base: Schema.TaggedErrorClass<DeviceAuthorizationDenied, "DeviceAuthorizationDenied", {
65
- readonly _tag: Schema.tag<"DeviceAuthorizationDenied">;
66
- }>;
67
- export declare class DeviceAuthorizationDenied extends DeviceAuthorizationDenied_base {
68
- get message(): string;
69
- }
70
- declare const DeviceAuthorizationExpired_base: Schema.TaggedErrorClass<DeviceAuthorizationExpired, "DeviceAuthorizationExpired", {
71
- readonly _tag: Schema.tag<"DeviceAuthorizationExpired">;
72
- }>;
73
- export declare class DeviceAuthorizationExpired extends DeviceAuthorizationExpired_base {
74
- get message(): string;
75
- }
76
- declare const DeviceAuthService_base: Effect.Service.Class<DeviceAuthService, "@expandai/cli/DeviceAuthService", {
77
- readonly dependencies: readonly [import("effect/Layer").Layer<HttpClient.HttpClient, never, never>, import("effect/Layer").Layer<ConfigManager, import("effect/ConfigError").ConfigError, never>];
78
- readonly effect: Effect.Effect<{
79
- readonly requestDeviceCode: () => Effect.Effect<DeviceCodeResponse, import("@effect/platform/HttpBody").HttpBodyError | DeviceAuthRequestFailed, never>;
80
- readonly pollForToken: (deviceCode: string, interval: Duration.Duration, expiresIn: Duration.Duration) => Effect.Effect<TokenResponse, DeviceAuthRequestFailed | DeviceAuthorizationDenied | DeviceAuthorizationExpired, never>;
81
- readonly saveToken: (tokenResponse: TokenResponse) => Effect.Effect<void, import("./Config.js").ConfigNotWritable | import("effect/ParseResult").ParseError, never>;
82
- }, import("./Config.js").ConfigParseError | import("effect/ConfigError").ConfigError | import("@effect/platform/Error").PlatformError, ConfigManager | HttpClient.HttpClient>;
83
- }>;
84
- export declare class DeviceAuthService extends DeviceAuthService_base {
85
- }
86
- export {};
87
- //# sourceMappingURL=DeviceAuth.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DeviceAuth.d.ts","sourceRoot":"","sources":["../../src/DeviceAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAyC,MAAM,kBAAkB,CAAA;AAEpF,OAAO,EAAY,QAAQ,EAAE,MAAM,EAA6C,MAAM,EAAU,MAAM,QAAQ,CAAA;AAC9G,OAAO,EAAE,aAAa,EAAe,MAAM,aAAa,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBxD,qBAAa,kBAAmB,SAAQ,uBAOtC;CAAG;;;;;;;;;;;;;;;;;;;;AAEL,qBAAa,aAAc,SAAQ,kBAKjC;CAAG;;;;;;;;AAEL,qBAAa,uBAAwB,SAAQ,4BAI3C;IACD,IAAI,OAAO,WAEV;CACD;;;;AAED,qBAAa,yBAA0B,SAAQ,8BAG9C;IACA,IAAI,OAAO,WAEV;CACD;;;;AAED,qBAAa,0BAA2B,SAAQ,+BAG/C;IACA,IAAI,OAAO,WAEV;CACD;;;;;;;;;AAID,qBAAa,iBAAkB,SAAQ,sBA8HrC;CAAG"}
@@ -1,127 +0,0 @@
1
- import { HttpClient, HttpClientRequest, HttpClientResponse } from '@effect/platform';
2
- import { NodeHttpClient } from '@effect/platform-node';
3
- import { DateTime, Duration, Effect, Inspectable, Match, Option, Redacted, Ref, Schema, String } from 'effect';
4
- import { ConfigManager, OAuthConfig } from './Config.js';
5
- const FormattedUserCode = Schema.transform(Schema.String, Schema.String, {
6
- strict: true,
7
- decode: (raw) => {
8
- const upper = String.toUpperCase(raw);
9
- return upper.length > 4 ? `${String.takeLeft(upper, 4)}-${String.takeRight(upper, upper.length - 4)}` : upper;
10
- },
11
- encode: (formatted) => formatted.replace('-', ''),
12
- });
13
- const DurationFromSeconds = Schema.transform(Schema.Number, Schema.DurationFromSelf, {
14
- strict: true,
15
- decode: Duration.seconds,
16
- encode: Duration.toSeconds,
17
- });
18
- export class DeviceCodeResponse extends Schema.Class('DeviceCodeResponse')({
19
- device_code: Schema.String,
20
- user_code: FormattedUserCode,
21
- verification_uri: Schema.String,
22
- verification_uri_complete: Schema.String,
23
- expires_in: DurationFromSeconds,
24
- interval: DurationFromSeconds,
25
- }) {
26
- }
27
- export class TokenResponse extends Schema.Class('TokenResponse')({
28
- access_token: Schema.String,
29
- expires_in: DurationFromSeconds,
30
- token_type: Schema.String,
31
- scope: Schema.optional(Schema.String),
32
- }) {
33
- }
34
- export class DeviceAuthRequestFailed extends Schema.TaggedError()('DeviceAuthRequestFailed', {
35
- endpoint: Schema.String,
36
- error: Schema.Defect,
37
- status: Schema.optional(Schema.Number),
38
- }) {
39
- get message() {
40
- return `Device auth request to ${this.endpoint} failed${this.status ? ` (${this.status})` : ''}: ${Inspectable.format(this.error)}`;
41
- }
42
- }
43
- export class DeviceAuthorizationDenied extends Schema.TaggedError()('DeviceAuthorizationDenied', {}) {
44
- get message() {
45
- return 'Authorization was denied by the user';
46
- }
47
- }
48
- export class DeviceAuthorizationExpired extends Schema.TaggedError()('DeviceAuthorizationExpired', {}) {
49
- get message() {
50
- return 'Device authorization code expired';
51
- }
52
- }
53
- const CLIENT_ID = 'expandai-cli';
54
- export class DeviceAuthService extends Effect.Service()('@expandai/cli/DeviceAuthService', {
55
- dependencies: [NodeHttpClient.layer, ConfigManager.Default],
56
- effect: Effect.gen(function* () {
57
- const httpClient = yield* HttpClient.HttpClient;
58
- const configManager = yield* ConfigManager;
59
- const apiUrl = yield* configManager.getApiUrl();
60
- const requestDeviceCode = Effect.fn('DeviceAuthService.requestDeviceCode')(function* () {
61
- const DEVICE_AUTH_CODE_ENDPOINT = '/api/auth/device/code';
62
- const request = yield* HttpClientRequest.post(new URL(DEVICE_AUTH_CODE_ENDPOINT, apiUrl)).pipe(HttpClientRequest.bodyJson({ client_id: CLIENT_ID }));
63
- return yield* httpClient.execute(request).pipe(Effect.flatMap(HttpClientResponse.schemaBodyJson(DeviceCodeResponse)), Effect.mapError((error) => new DeviceAuthRequestFailed({
64
- endpoint: DEVICE_AUTH_CODE_ENDPOINT,
65
- error,
66
- })));
67
- });
68
- const pollForToken = Effect.fn('DeviceAuthService.pollForToken')(function* (deviceCode, interval, expiresIn) {
69
- const DEVICE_AUTH_TOKEN_ENDPOINT = '/api/auth/device/token';
70
- // RFC 8628 §3.5: on `slow_down`, the polling interval MUST be increased by 5
71
- // seconds for this and all subsequent requests.
72
- const SLOW_DOWN_BUMP = Duration.seconds(5);
73
- const intervalRef = yield* Ref.make(interval);
74
- const PollErrorBody = Schema.Struct({
75
- error: Schema.String,
76
- error_description: Schema.optional(Schema.String),
77
- });
78
- // better-auth's `deviceAuthorization` plugin accepts JSON; RFC 8628 §3.4
79
- // would normally require `application/x-www-form-urlencoded`. If we ever
80
- // target a non-better-auth server, switch to `HttpClientRequest.bodyUrlParams`.
81
- const singlePoll = HttpClientRequest.post(new URL(DEVICE_AUTH_TOKEN_ENDPOINT, apiUrl)).pipe(HttpClientRequest.bodyJson({
82
- grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
83
- device_code: deviceCode,
84
- client_id: CLIENT_ID,
85
- }), Effect.flatMap(httpClient.execute), Effect.flatMap(HttpClientResponse.matchStatus({
86
- '200': (response) => HttpClientResponse.schemaBodyJson(TokenResponse)(response).pipe(Effect.map(Option.some)),
87
- orElse: (response) => HttpClientResponse.schemaBodyJson(PollErrorBody)(response).pipe(Effect.flatMap(({ error, error_description }) => Match.value(error).pipe(Match.when('authorization_pending', () => Ref.get(intervalRef).pipe(Effect.flatMap(Effect.sleep), Effect.as(Option.none()))), Match.when('slow_down', () => Ref.updateAndGet(intervalRef, (current) => Duration.sum(current, SLOW_DOWN_BUMP)).pipe(Effect.flatMap(Effect.sleep), Effect.as(Option.none()))), Match.when('access_denied', () => Effect.fail(new DeviceAuthorizationDenied())), Match.when('expired_token', () => Effect.fail(new DeviceAuthorizationExpired())), Match.orElse(() => Effect.fail(new DeviceAuthRequestFailed({
88
- endpoint: DEVICE_AUTH_TOKEN_ENDPOINT,
89
- status: response.status,
90
- error: error_description ?? error,
91
- })))))),
92
- })), Effect.catchTags({
93
- RequestError: (error) => new DeviceAuthRequestFailed({ endpoint: DEVICE_AUTH_TOKEN_ENDPOINT, error }),
94
- ResponseError: (error) => new DeviceAuthRequestFailed({ endpoint: DEVICE_AUTH_TOKEN_ENDPOINT, error }),
95
- HttpBodyError: (error) => new DeviceAuthRequestFailed({ endpoint: DEVICE_AUTH_TOKEN_ENDPOINT, error }),
96
- ParseError: (error) => new DeviceAuthRequestFailed({ endpoint: DEVICE_AUTH_TOKEN_ENDPOINT, error }),
97
- }));
98
- const result = yield* Effect.repeat(singlePoll, { until: Option.isSome }).pipe(Effect.timeoutFail({
99
- duration: expiresIn,
100
- onTimeout: () => new DeviceAuthorizationExpired(),
101
- }));
102
- return yield* Option.match(result, {
103
- onNone: () => new DeviceAuthorizationExpired(),
104
- onSome: Effect.succeed,
105
- });
106
- });
107
- // INFO: better-auth's `deviceAuthorization` plugin issues access tokens
108
- // with no refresh flow — `/api/auth/device/token` only accepts
109
- // `grant_type=urn:ietf:params:oauth:grant-type:device_code`. Refresh is
110
- // not part of the auth surface we're using, so we don't persist the
111
- // refresh_token at all; ApiClient pre-empts the post-expiry 401 with
112
- // `OAuthTokenExpired` and asks the user to re-login.
113
- const saveToken = Effect.fn('DeviceAuthService.saveToken')(function* (tokenResponse) {
114
- const now = yield* DateTime.now;
115
- const expiresAt = DateTime.addDuration(now, tokenResponse.expires_in);
116
- yield* configManager.updateConfig({
117
- authMethod: OAuthConfig.make({
118
- accessToken: Redacted.make(tokenResponse.access_token),
119
- expiresAt,
120
- }),
121
- });
122
- });
123
- return { requestDeviceCode, pollForToken, saveToken };
124
- }),
125
- }) {
126
- }
127
- //# sourceMappingURL=DeviceAuth.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DeviceAuth.js","sourceRoot":"","sources":["../../src/DeviceAuth.ts"],"names":[],"mappings":"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"}