@crewx/sdk 0.9.0-rc.16 → 0.9.0-rc.160

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 (304) hide show
  1. package/README.md +1 -1
  2. package/dist/account/auth-client.d.ts +61 -0
  3. package/dist/account/auth-json-v2.d.ts +1 -0
  4. package/dist/account/auth-json.d.ts +30 -0
  5. package/dist/account/config.d.ts +37 -0
  6. package/dist/account/env-bootstrap.d.ts +11 -0
  7. package/dist/account/errors.d.ts +24 -0
  8. package/dist/account/index.d.ts +12 -0
  9. package/dist/account/index.js +2 -0
  10. package/dist/account/session-manager.d.ts +47 -0
  11. package/dist/activity-log/builder.d.ts +59 -6
  12. package/dist/agent/agent-list-view.d.ts +19 -0
  13. package/dist/app/app.d.ts +148 -0
  14. package/dist/app/backend-env.d.ts +3 -0
  15. package/dist/app/content-media-types.d.ts +2 -0
  16. package/dist/app/context.d.ts +2 -0
  17. package/dist/app/entry.d.ts +7 -0
  18. package/dist/app/frame.d.ts +55 -0
  19. package/dist/app/index.d.ts +10 -0
  20. package/dist/app/index.js +10 -0
  21. package/dist/app/protocol.d.ts +9 -0
  22. package/dist/app/runtime.d.ts +21 -0
  23. package/dist/app/tool-mode.d.ts +3 -0
  24. package/dist/boxing/box.types.d.ts +4 -0
  25. package/dist/config/canonicalize-agent-options.d.ts +18 -0
  26. package/dist/config/default-agent-models.d.ts +11 -0
  27. package/dist/config/global-settings.d.ts +33 -0
  28. package/dist/config/migrate-grok-mode.d.ts +6 -0
  29. package/dist/config/model-compat.d.ts +31 -0
  30. package/dist/config/models.generated.d.ts +37 -0
  31. package/dist/config/models.remote.d.ts +1 -0
  32. package/dist/config/overdrive.d.ts +7 -0
  33. package/dist/config/pricing.d.ts +6 -3
  34. package/dist/config/pricing.generated.d.ts +4 -0
  35. package/dist/config/pricing.types.d.ts +4 -0
  36. package/dist/config/timeout.config.d.ts +4 -0
  37. package/dist/config/wi-boards.d.ts +19 -0
  38. package/dist/context-budget/continuity.d.ts +63 -0
  39. package/dist/context-budget/index.d.ts +142 -0
  40. package/dist/conversation/index.d.ts +1 -1
  41. package/dist/conversation/sqlite-provider.d.ts +6 -3
  42. package/dist/conversation/to-template-messages.d.ts +9 -0
  43. package/dist/conversation/types.d.ts +58 -1
  44. package/dist/desktop/command-runner.d.ts +4 -0
  45. package/dist/desktop/default-adapters.d.ts +4 -0
  46. package/dist/desktop/global-install.d.ts +19 -0
  47. package/dist/desktop/index.d.ts +3 -0
  48. package/dist/desktop/index.js +3 -0
  49. package/dist/desktop/install.d.ts +5 -0
  50. package/dist/desktop/lnk.d.ts +22 -0
  51. package/dist/desktop/manifest.d.ts +21 -0
  52. package/dist/desktop/types.d.ts +67 -0
  53. package/dist/desktop/version.d.ts +1 -0
  54. package/dist/desktop/windows-paths.d.ts +21 -0
  55. package/dist/desktop/wrapper.d.ts +18 -0
  56. package/dist/esm/account/index.js +2 -0
  57. package/dist/esm/app/index.js +10 -0
  58. package/dist/esm/desktop/index.js +3 -0
  59. package/dist/esm/index.js +1126 -224
  60. package/dist/esm/node/index.js +2 -0
  61. package/dist/esm/plugins/index.js +496 -214
  62. package/dist/esm/process/index.js +1 -0
  63. package/dist/esm/publish/index.js +2 -0
  64. package/dist/esm/repository/index.js +608 -211
  65. package/dist/esm/skills/index.js +2 -0
  66. package/dist/esm/testing/index.js +1 -1
  67. package/dist/events/types.d.ts +16 -0
  68. package/dist/facade/Crewx.d.ts +61 -5
  69. package/dist/facade/task-ticket.d.ts +14 -0
  70. package/dist/highlight/thread-highlight-prompt.d.ts +2 -0
  71. package/dist/highlight/thread-highlighter.d.ts +326 -0
  72. package/dist/index.browser.d.ts +19 -1
  73. package/dist/index.browser.js +6 -2
  74. package/dist/index.d.ts +131 -17
  75. package/dist/index.js +1128 -226
  76. package/dist/internal/console-decoder.d.ts +38 -0
  77. package/dist/internal/windows-spawn.d.ts +10 -0
  78. package/dist/layout/types.d.ts +18 -1
  79. package/dist/lifecycle/process-lease.d.ts +80 -0
  80. package/dist/lifecycle/process-owner.d.ts +20 -0
  81. package/dist/lifecycle/task-heartbeat.d.ts +41 -0
  82. package/dist/lifecycle/task-stop.d.ts +82 -0
  83. package/dist/lifecycle/update-admission.d.ts +45 -0
  84. package/dist/local-server/base-url.d.ts +18 -0
  85. package/dist/local-server/index.d.ts +8 -0
  86. package/dist/local-server/opencode.d.ts +8 -0
  87. package/dist/local-server/probe.d.ts +3 -0
  88. package/dist/local-server/runtime.d.ts +26 -0
  89. package/dist/local-server/types.d.ts +43 -0
  90. package/dist/mcp-app/agent-access.d.ts +26 -0
  91. package/dist/mcp-app/app-handoff.d.ts +109 -0
  92. package/dist/mcp-app/apps-context.d.ts +32 -0
  93. package/dist/mcp-app/bundle-provenance.d.ts +3 -0
  94. package/dist/mcp-app/candidate-registration.d.ts +4 -0
  95. package/dist/mcp-app/card-handler.d.ts +7 -0
  96. package/dist/mcp-app/catalog.d.ts +7 -0
  97. package/dist/mcp-app/content-channel.d.ts +86 -0
  98. package/dist/mcp-app/content-declarations.d.ts +31 -0
  99. package/dist/mcp-app/dev-checks.d.ts +29 -0
  100. package/dist/mcp-app/diagnostic-reason.d.ts +3 -0
  101. package/dist/mcp-app/discovery.d.ts +161 -0
  102. package/dist/mcp-app/errors.d.ts +7 -0
  103. package/dist/mcp-app/index.d.ts +37 -0
  104. package/dist/mcp-app/installed-app-ref.d.ts +25 -0
  105. package/dist/mcp-app/model-context.d.ts +29 -0
  106. package/dist/mcp-app/node-app-discovery-fs.d.ts +23 -0
  107. package/dist/mcp-app/product-bundle-assets.d.ts +27 -0
  108. package/dist/mcp-app/product-bundle-loader.d.ts +53 -0
  109. package/dist/mcp-app/projection.d.ts +14 -0
  110. package/dist/mcp-app/prompt-cards.d.ts +28 -0
  111. package/dist/mcp-app/registry.d.ts +28 -0
  112. package/dist/mcp-app/skill-backend.d.ts +132 -0
  113. package/dist/mcp-app/state-set.d.ts +9 -0
  114. package/dist/mcp-app/types.d.ts +488 -0
  115. package/dist/mcp-app/workspace-app-assets.d.ts +42 -0
  116. package/dist/mcp-app/workspace-app-scan-cache.d.ts +27 -0
  117. package/dist/mcp-app/workspace-snapshot.d.ts +72 -0
  118. package/dist/migrations/0011_far_black_tarantula.sql +1 -0
  119. package/dist/migrations/0012_blue_turbo.sql +23 -0
  120. package/dist/migrations/0013_hesitant_adam_destine.sql +15 -0
  121. package/dist/migrations/0014_organic_mongu.sql +73 -0
  122. package/dist/migrations/0015_panoramic_gorilla_man.sql +71 -0
  123. package/dist/migrations/0016_fuzzy_hemingway.sql +14 -0
  124. package/dist/migrations/0017_project_stage_sdk_migration.sql +29 -0
  125. package/dist/migrations/0018_bored_jackal.sql +33 -0
  126. package/dist/migrations/0019_backfill_task_thread_ids.sql +74 -0
  127. package/dist/migrations/0020_useful_iron_lad.sql +55 -0
  128. package/dist/migrations/0021_dashing_peter_quill.sql +51 -0
  129. package/dist/migrations/0022_wandering_bucky.sql +1 -0
  130. package/dist/migrations/0023_red_payback.sql +1 -0
  131. package/dist/migrations/0024_storage_metadata.sql +262 -0
  132. package/dist/migrations/0025_task_heartbeat.sql +8 -0
  133. package/dist/migrations/0025_thread_app_instance_ledger.sql +2 -0
  134. package/dist/migrations/0026_mcp_action_source.sql +47 -0
  135. package/dist/migrations/0027_task_stop_scope_cleanup.sql +5 -0
  136. package/dist/migrations/0027_ui_instance_active_unique.sql +2 -0
  137. package/dist/migrations/0029_nice_rhino.sql +1 -0
  138. package/dist/migrations/0031_petite_arclight.sql +6 -0
  139. package/dist/migrations/0032_ui_instance_opened_by.sql +1 -0
  140. package/dist/migrations/0033_thread_creator_boundary_guard.sql +38 -0
  141. package/dist/migrations/0034_keen_fallen_one.sql +36 -0
  142. package/dist/migrations/0035_request_log_daily.sql +11 -0
  143. package/dist/migrations/0036_ui_definition_archive.sql +8 -0
  144. package/dist/migrations/0037_ui_instance_agent_open_request.sql +1 -0
  145. package/dist/migrations/0038_task_rating.sql +3 -0
  146. package/dist/migrations/0039_aspiring_purifiers.sql +9 -0
  147. package/dist/migrations/0040_task_provider_inputs.sql +53 -0
  148. package/dist/migrations/meta/0011_snapshot.json +1342 -0
  149. package/dist/migrations/meta/0012_snapshot.json +1494 -0
  150. package/dist/migrations/meta/0013_snapshot.json +1592 -0
  151. package/dist/migrations/meta/0014_snapshot.json +1975 -0
  152. package/dist/migrations/meta/0015_snapshot.json +2315 -0
  153. package/dist/migrations/meta/0016_snapshot.json +2419 -0
  154. package/dist/migrations/meta/0017_snapshot.json +2419 -0
  155. package/dist/migrations/meta/0018_snapshot.json +2570 -0
  156. package/dist/migrations/meta/0020_snapshot.json +2895 -0
  157. package/dist/migrations/meta/0021_snapshot.json +3031 -0
  158. package/dist/migrations/meta/0022_snapshot.json +3039 -0
  159. package/dist/migrations/meta/0023_snapshot.json +3047 -0
  160. package/dist/migrations/meta/0029_snapshot.json +3206 -0
  161. package/dist/migrations/meta/0031_snapshot.json +3251 -0
  162. package/dist/migrations/meta/0034_snapshot.json +3473 -0
  163. package/dist/migrations/meta/0035_snapshot.json +3547 -0
  164. package/dist/migrations/meta/0036_snapshot.json +3591 -0
  165. package/dist/migrations/meta/0037_snapshot.json +3598 -0
  166. package/dist/migrations/meta/0038_snapshot.json +3626 -0
  167. package/dist/migrations/meta/0039_snapshot.json +3684 -0
  168. package/dist/migrations/meta/0040_snapshot.json +3759 -0
  169. package/dist/migrations/meta/_journal.json +210 -0
  170. package/dist/node/index.d.ts +1 -0
  171. package/dist/node/index.js +2 -0
  172. package/dist/paths.d.ts +1 -0
  173. package/dist/plugin/types.d.ts +1 -0
  174. package/dist/plugins/index.d.ts +1 -1
  175. package/dist/plugins/index.js +496 -214
  176. package/dist/plugins/sqlite-tracing.d.ts +46 -0
  177. package/dist/process/index.d.ts +2 -0
  178. package/dist/process/index.js +1 -0
  179. package/dist/process/process-control.d.ts +41 -0
  180. package/dist/prompt/tag-names.d.ts +22 -0
  181. package/dist/provider/acp/connection.d.ts +6 -0
  182. package/dist/provider/acp/meta.d.ts +11 -0
  183. package/dist/provider/bridge.d.ts +7 -1
  184. package/dist/provider/classify-task-error.d.ts +2 -0
  185. package/dist/provider/cli/adapter.types.d.ts +14 -2
  186. package/dist/provider/cli/adapters/agent-call.util.d.ts +1 -1
  187. package/dist/provider/cli/adapters/cli-knob.util.d.ts +7 -0
  188. package/dist/provider/cli/adapters/codex-item.d.ts +1 -0
  189. package/dist/provider/cli/adapters/event-timestamp.util.d.ts +1 -0
  190. package/dist/provider/cli/adapters/grok.d.ts +2 -0
  191. package/dist/provider/cli/adapters/index.d.ts +5 -0
  192. package/dist/provider/cli/index.d.ts +3 -2
  193. package/dist/provider/cli/meta.d.ts +5 -0
  194. package/dist/provider/cli/protocol-envelope.d.ts +3 -0
  195. package/dist/provider/errors.d.ts +5 -1
  196. package/dist/provider/idle-watchdog.d.ts +19 -0
  197. package/dist/provider/models.d.ts +17 -12
  198. package/dist/provider/order.d.ts +1 -1
  199. package/dist/provider/parse-usage.d.ts +6 -0
  200. package/dist/provider/provider-selection.d.ts +8 -0
  201. package/dist/provider/redact-technical-message.d.ts +1 -0
  202. package/dist/provider/task-error.types.d.ts +17 -0
  203. package/dist/publish/constants.d.ts +6 -0
  204. package/dist/publish/errors.d.ts +7 -0
  205. package/dist/publish/index.d.ts +50 -0
  206. package/dist/publish/index.js +2 -0
  207. package/dist/publish/manifest.d.ts +47 -0
  208. package/dist/publish/marketplace-api.constants.d.ts +1 -0
  209. package/dist/publish/pack.d.ts +6 -0
  210. package/dist/publish/scan.d.ts +10 -0
  211. package/dist/publish/secrets.d.ts +6 -0
  212. package/dist/publish/upload.d.ts +19 -0
  213. package/dist/remote/execution-profile.d.ts +9 -0
  214. package/dist/remote/index.d.ts +1 -0
  215. package/dist/remote/types.d.ts +28 -0
  216. package/dist/repository/agent-send-history.repository.d.ts +23 -0
  217. package/dist/repository/agent-suggestion.repository.d.ts +34 -0
  218. package/dist/repository/base-sqlite-repository.d.ts +1 -0
  219. package/dist/repository/common-code.repository.d.ts +45 -0
  220. package/dist/repository/db.d.ts +12 -1
  221. package/dist/repository/index.d.ts +49 -6
  222. package/dist/repository/index.js +608 -211
  223. package/dist/repository/logs-db.d.ts +12 -0
  224. package/dist/repository/notification.repository.d.ts +58 -0
  225. package/dist/repository/project.repository.d.ts +90 -0
  226. package/dist/repository/request-log-mover.d.ts +70 -0
  227. package/dist/repository/request-log.repository.d.ts +7 -3
  228. package/dist/repository/storage-metadata.repository.d.ts +64 -0
  229. package/dist/repository/task-log-migration.d.ts +74 -0
  230. package/dist/repository/task-log.repository.d.ts +44 -0
  231. package/dist/repository/task-status.d.ts +21 -0
  232. package/dist/repository/task.repository.d.ts +300 -7
  233. package/dist/repository/thread-history.repository.d.ts +193 -0
  234. package/dist/repository/thread-origin-verdict.d.ts +27 -0
  235. package/dist/repository/thread-title.types.d.ts +29 -0
  236. package/dist/repository/thread.repository.d.ts +118 -7
  237. package/dist/repository/usage-backfill.d.ts +62 -0
  238. package/dist/repository/usage-from-logs.d.ts +21 -0
  239. package/dist/repository/workspace.repository.d.ts +3 -0
  240. package/dist/schema/agent-send-history.d.ts +85 -0
  241. package/dist/schema/agent-suggestions.d.ts +199 -0
  242. package/dist/schema/common-codes.d.ts +216 -0
  243. package/dist/schema/index.d.ts +15 -0
  244. package/dist/schema/notifications.d.ts +303 -0
  245. package/dist/schema/projects.d.ts +610 -0
  246. package/dist/schema/request-log-daily.d.ts +151 -0
  247. package/dist/schema/storage-metadata.d.ts +181 -0
  248. package/dist/schema/task-log-events.d.ts +119 -0
  249. package/dist/schema/task-provider-inputs.d.ts +100 -0
  250. package/dist/schema/tasks.d.ts +1058 -1
  251. package/dist/schema/thread-creator-unverified.d.ts +45 -0
  252. package/dist/schema/thread-history.d.ts +734 -0
  253. package/dist/schema/threads.d.ts +59 -0
  254. package/dist/schema/ui-action-receipts.d.ts +358 -0
  255. package/dist/schema/ui-definition-archive.d.ts +63 -0
  256. package/dist/schema/ui-instance-repins.d.ts +222 -0
  257. package/dist/schema/ui-instances.d.ts +324 -0
  258. package/dist/schema/workspaces.d.ts +17 -0
  259. package/dist/skills/index.d.ts +15 -0
  260. package/dist/skills/index.js +2 -0
  261. package/dist/skills/types.d.ts +18 -0
  262. package/dist/task-log/anchor-child-tasks.d.ts +7 -0
  263. package/dist/task-log/delegation-trailer.d.ts +34 -0
  264. package/dist/template/engine.d.ts +2 -2
  265. package/dist/template/helpers/exec.browser.d.ts +4 -3
  266. package/dist/template/helpers/exec.d.ts +4 -3
  267. package/dist/template/helpers/format-conversation.d.ts +1 -0
  268. package/dist/template/types.d.ts +20 -0
  269. package/dist/testing/index.js +1 -1
  270. package/dist/types/index.d.ts +1578 -3
  271. package/dist/types/task-log.types.d.ts +3 -0
  272. package/dist/ui-card/index.d.ts +2 -0
  273. package/dist/ui-card/legacy-card-parser.d.ts +11 -0
  274. package/dist/ui-instance/definition.d.ts +6 -0
  275. package/dist/ui-instance/errors.d.ts +18 -0
  276. package/dist/ui-instance/index.d.ts +11 -0
  277. package/dist/ui-instance/json.d.ts +19 -0
  278. package/dist/ui-instance/lineage.d.ts +24 -0
  279. package/dist/ui-instance/runtime.d.ts +19 -0
  280. package/dist/ui-instance/store.d.ts +213 -0
  281. package/dist/ui-instance/types.d.ts +329 -0
  282. package/dist/ui-plugin/app-manifest.d.ts +64 -0
  283. package/dist/ui-plugin/csp.d.ts +28 -0
  284. package/dist/ui-plugin/index.d.ts +6 -0
  285. package/dist/ui-plugin/limits.d.ts +27 -0
  286. package/dist/ui-plugin/manifest.d.ts +3 -0
  287. package/dist/ui-plugin/types.d.ts +203 -0
  288. package/dist/ui-plugin/validator.d.ts +18 -0
  289. package/dist/utils/crewx-executable.d.ts +76 -0
  290. package/dist/utils/crewx-home.d.ts +1 -0
  291. package/dist/utils/env-defaults.d.ts +3 -0
  292. package/dist/utils/id.d.ts +1 -1
  293. package/dist/utils/local-identity.d.ts +2 -0
  294. package/dist/utils/runner-env.d.ts +3 -0
  295. package/dist/utils/timestamp.d.ts +1 -0
  296. package/dist/utils/workspace.d.ts +1 -0
  297. package/dist/wi/create.d.ts +48 -0
  298. package/dist/wi/select.d.ts +20 -0
  299. package/package.json +57 -3
  300. package/templates/agents/default.yaml +303 -128
  301. package/templates/documents/crewx-manual.md +138 -138
  302. package/templates/documents/crewx-quick-guide.md +8 -7
  303. package/templates/workflows/wi-default-flow.yaml +65 -0
  304. package/templates/workflows/wi-plan-flow.yaml +140 -0
@@ -1,16 +1,56 @@
1
+ import type { ThreadCreationOptions } from '../repository/thread.repository';
2
+ export type { ThreadCreationOptions } from '../repository/thread.repository';
1
3
  export interface ConversationMessage {
2
4
  id: string;
3
5
  userId?: string;
4
6
  text: string;
5
7
  isAssistant: boolean;
6
8
  timestamp: number;
9
+ taskId?: string;
7
10
  metadata?: Record<string, unknown>;
8
11
  }
9
12
  export type Platform = 'cli' | 'web' | 'api' | 'mcp' | `channel/${string}`;
13
+ export interface ConversationHighlight {
14
+ id: string;
15
+ text: string;
16
+ kind?: string;
17
+ source?: string;
18
+ coversFromTaskId?: string;
19
+ coversToTaskId?: string;
20
+ covers_from_task_id?: string;
21
+ covers_to_task_id?: string;
22
+ createdAt?: number | string;
23
+ created_at?: number | string;
24
+ }
25
+ export interface SemanticContinuityContext {
26
+ highlights: ConversationHighlight[];
27
+ truncatedHighlights?: number;
28
+ omittedTurns: {
29
+ count: number;
30
+ represented: number;
31
+ unrepresented: number;
32
+ taskIds: string[];
33
+ };
34
+ rendered?: string;
35
+ omittedRendered: string;
36
+ }
37
+ export type ConversationSemanticContinuityContext = SemanticContinuityContext;
38
+ export interface ConversationThreadStateValue {
39
+ code: string;
40
+ name: string;
41
+ }
42
+ export interface ConversationThreadState {
43
+ title?: string;
44
+ priority?: ConversationThreadStateValue;
45
+ state?: ConversationThreadStateValue;
46
+ rendered?: string;
47
+ }
48
+ export type ThreadStateContext = ConversationThreadState;
10
49
  export interface ConversationThread {
11
50
  threadId: string;
12
51
  platform: Platform;
13
52
  messages: ConversationMessage[];
53
+ highlights?: ConversationHighlight[];
14
54
  metadata?: {
15
55
  title?: string;
16
56
  firstMessage?: string;
@@ -19,27 +59,44 @@ export interface ConversationThread {
19
59
  updatedAt?: number;
20
60
  };
21
61
  }
62
+ export interface TemplateAppCard {
63
+ readonly instanceId: string;
64
+ readonly anchorTaskId: string;
65
+ readonly status: 'running' | 'waiting' | 'done' | 'failed' | 'expired';
66
+ readonly result?: 'saved' | 'deferred' | 'cancelled';
67
+ readonly agentId?: string;
68
+ readonly xml: string;
69
+ readonly replacesSlot?: boolean;
70
+ }
22
71
  export interface TemplateMessage {
72
+ id?: string;
23
73
  text: string;
24
74
  isAssistant: boolean;
75
+ taskId?: string;
25
76
  timestamp?: number;
26
77
  metadata?: Record<string, unknown>;
78
+ activity_log?: string;
27
79
  files?: Array<{
28
80
  name: string;
29
81
  size?: number;
30
82
  localPath?: string;
31
83
  }>;
84
+ appCard?: TemplateAppCard;
32
85
  }
33
86
  export interface FetchHistoryOptions {
34
87
  limit?: number;
35
88
  maxContextLength?: number;
89
+ includeHighlights?: boolean;
36
90
  currentTraceId?: string;
91
+ agentId?: string;
37
92
  }
38
93
  export interface IConversationHistoryProvider {
39
- ensureThread(threadId: string, platform: Platform, workspaceId?: string): Promise<{
94
+ ensureThread(threadId: string, platform: Platform, workspaceId?: string, creator?: ThreadCreationOptions): Promise<{
40
95
  created: boolean;
41
96
  }>;
42
97
  fetchHistory(threadId: string, options?: FetchHistoryOptions): Promise<ConversationThread>;
98
+ fetchThreadState?(threadId: string): Promise<ConversationThreadState | undefined>;
99
+ fetchHighlights?(threadId: string): Promise<ConversationHighlight[] | undefined>;
43
100
  saveUserMessage(threadId: string, text: string, userId?: string, metadata?: Record<string, unknown>): Promise<{
44
101
  id: string;
45
102
  firstMessage: boolean;
@@ -0,0 +1,4 @@
1
+ import { type ChildProcess } from 'node:child_process';
2
+ import type { CommandRunner } from './types';
3
+ export declare function killProcessTree(child: ChildProcess): void;
4
+ export declare const defaultCommandRunner: CommandRunner;
@@ -0,0 +1,4 @@
1
+ import { homedir } from 'node:os';
2
+ import type { ShortcutFsLike } from './types';
3
+ export declare const nodeShortcutFs: ShortcutFsLike;
4
+ export declare const osHomedir: typeof homedir;
@@ -0,0 +1,19 @@
1
+ import type { CommandRunner, GlobalCrewxInfo, ShortcutProgressEvent } from './types';
2
+ export interface DetectGlobalCrewxOptions {
3
+ env: NodeJS.ProcessEnv;
4
+ cwd: string;
5
+ run: CommandRunner;
6
+ }
7
+ export declare function detectGlobalCrewx(opts: DetectGlobalCrewxOptions): Promise<GlobalCrewxInfo>;
8
+ export interface EnsureGlobalCrewxOptions {
9
+ env: NodeJS.ProcessEnv;
10
+ cwd: string;
11
+ run: CommandRunner;
12
+ targetVersion: string;
13
+ currentInfo?: GlobalCrewxInfo;
14
+ installRoot?: string;
15
+ onProgress?: (event: ShortcutProgressEvent) => void;
16
+ }
17
+ export declare function ensureGlobalCrewx(opts: EnsureGlobalCrewxOptions): Promise<{
18
+ info: GlobalCrewxInfo;
19
+ }>;
@@ -0,0 +1,3 @@
1
+ export { getShortcutStatus, installShortcut, uninstallShortcut, dismissShortcutNotice, } from './install';
2
+ export { killProcessTree } from './command-runner';
3
+ export { ShortcutError, type ShortcutState, type DesktopSource, type GlobalCrewxInfo, type ShortcutStatus, type ShortcutInstallResult, type ShortcutProgressPhase, type ShortcutProgressEvent, type ShortcutEnvOptions, type InstallShortcutOptions, type ShortcutErrorCode, type CommandResult, type CommandRunner, type CommandRunOptions, type ShortcutFsLike, } from './types';
@@ -0,0 +1,3 @@
1
+ 'use strict';var p=require('path'),crypto=require('crypto'),fs=require('fs'),os=require('os'),child_process=require('child_process'),string_decoder=require('string_decoder'),module$1=require('module');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var p__namespace=/*#__PURE__*/_interopNamespace(p);var B=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var m=class extends Error{code;constructor(t,n){super(`${t}: ${n}`),this.code=t,this.name="ShortcutError";}};var q={existsSync:e=>fs.existsSync(e),readFileSync:e=>fs.readFileSync(e,"utf8"),readBinaryFileSync:e=>new Uint8Array(fs.readFileSync(e)),writeFileSync:(e,t)=>fs.writeFileSync(e,t,"utf8"),mkdirSync:e=>{fs.mkdirSync(e,{recursive:true});},unlinkSync:e=>{fs.unlinkSync(e);}},Y=os.homedir;function N(e){return typeof e!="string"?void 0:e.trim()||void 0}function O(e){return N(e)?.toLowerCase()??""}function b(e){try{return fs.statSync(e).isFile()}catch{return false}}function Ke(e,t){if(e===t)return true;let n=p__namespace.default.relative(e,t);return n!==""&&!n.startsWith("..")&&!p__namespace.default.isAbsolute(n)}function je(e,t){if(p__namespace.default.basename(e)!==".bin")return false;let n=p__namespace.default.dirname(e);if(p__namespace.default.basename(n)!=="node_modules")return false;let r=p__namespace.default.dirname(n);return Ke(r,t)}function Q(e,t={}){if(e.includes("/")||e.includes("\\")||p__namespace.default.isAbsolute(e))return e;let n=t.platform??process.platform,r=t.env??process.env,o=p__namespace.default.resolve(t.cwd??process.cwd()),c=(t.resolution??"global_first")==="global_first",s=r.PATH??r.Path??process.env.PATH??process.env.Path??"",i=n==="win32"?";":":",a=s.split(i).map(u=>u.trim()).filter(Boolean),l=p__namespace.default.extname(e).length>0,d=r.PATHEXT??r.Pathext??process.env.PATHEXT??process.env.Pathext??".EXE;.CMD;.BAT;.COM",f=n==="win32"?l?[""]:d.split(";").map(u=>u.trim()).filter(Boolean).map(u=>u.startsWith(".")?u:`.${u}`):[""];for(let u of a){let P=p__namespace.default.resolve(o,u);if(!(c&&je(P,o)))for(let h of f){let C=O(h),g=h.toUpperCase();for(let w of [h,C,g]){let y=p__namespace.default.join(P,`${e}${w}`);if(b(y))return y}}}return e}function ze(e){if(!b(e))return null;try{let t=fs.readFileSync(e,"utf8"),n=p__namespace.default.dirname(e),r=[];for(let i of t.matchAll(/"([^"\r\n]*)"/g)){let d=(i[1]??"").match(/%~?dp0%?\s*[\\/]*(.*)$/i)?.[1]?.trim();if(!d)continue;let f=d.replace(/[\\/]+/g,p__namespace.default.sep).replace(/^[\\/]+/,""),u=p__namespace.default.resolve(n,f);b(u)&&r.push(u);}let o=[],c=new Map;for(let i of t.matchAll(/SET\s+"(\w+)=%~?dp0%?[\\/]?([^"]+)"/gi)){let a=i[1].toUpperCase(),l=i[2].trim().replace(/[\\/]+/g,p__namespace.default.sep).replace(/^[\\/]+/,"");c.set(a,p__namespace.default.resolve(n,l));}for(let i of t.split(/\r?\n/))if(i.includes("%*"))for(let a of i.matchAll(/"%(\w+)%"/g)){let l=c.get(a[1].toUpperCase());l&&b(l)&&o.push(l);}let s=i=>i.find(a=>{let l=O(p__namespace.default.basename(a));return l!=="node.exe"&&l!=="node"})??null;return s(o)??s(r)}catch{return null}}function qe(e,t){if(typeof t=="string")return N(t)||null;if(!t||typeof t!="object")return null;if(e){let n=t[e],r=typeof n=="string"?N(n):void 0;if(r)return r}for(let n of Object.values(t)){let r=typeof n=="string"?N(n):void 0;if(r)return r}return null}function Ye(e,t){if(!t)return null;let n=p__namespace.default.dirname(e),r=[p__namespace.default.resolve(n,"..",t),p__namespace.default.resolve(n,"node_modules",t)];for(let o of r){let c=p__namespace.default.join(o,"package.json");if(b(c))try{let s=JSON.parse(fs.readFileSync(c,"utf8")),i=qe(t,s.bin);if(!i)continue;let a=p__namespace.default.resolve(o,i);if(b(a))return a}catch{}}return null}function Qe(e){let t=e.platform??process.platform,n=e.env??process.env,r=e.execPath??process.execPath,o=e.cwd,c=e.resolution;if(t!=="win32")return {command:Q(e.command,{cwd:o,env:n,platform:t,resolution:c}),leadingArgv:[],resolution:"direct"};let s=Q(e.command,{cwd:o,env:n,platform:t,resolution:c}),i=O(p__namespace.default.extname(s));if(i===".js"||i===".cjs"||i===".mjs")return {command:r,leadingArgv:[s],resolution:"node-entrypoint",windowsHide:true};if(i===".cmd"||i===".bat"){let a=ze(s)??Ye(s,e.packageName);return a?O(p__namespace.default.extname(a))===".exe"?{command:a,leadingArgv:[],resolution:"exe-entrypoint",windowsHide:true}:{command:r,leadingArgv:[a],resolution:"node-entrypoint",windowsHide:true}:{command:s,leadingArgv:[],resolution:"unresolved-wrapper"}}return {command:s,leadingArgv:[],resolution:"direct",windowsHide:true}}function Ze(e){if(e.candidate.resolution!=="unresolved-wrapper")return {command:e.candidate.command,leadingArgv:e.candidate.leadingArgv,resolution:e.candidate.resolution,windowsHide:e.candidate.windowsHide};throw new Error(`${p__namespace.default.basename(e.candidate.command)} wrapper resolved, but no executable/Node entrypoint could be resolved without shell execution.`)}function ee(e){let t=Qe(e);return Ze({candidate:t})}function te(e,t){return {command:e.command,argv:[...e.leadingArgv,...t],resolution:e.resolution,shell:e.shell,windowsHide:e.windowsHide}}var D="\uFFFD",$=8,re=1e3,tt=new Map([[437,"ibm437"],[720,"ibm720"],[737,"ibm737"],[775,"ibm775"],[850,"ibm850"],[852,"ibm852"],[855,"ibm855"],[857,"ibm857"],[858,"ibm858"],[862,"ibm862"],[864,"ibm864"],[932,"shift_jis"],[936,"gb18030"],[949,"euc-kr"],[950,"big5"],[866,"ibm866"],[869,"ibm869"],[1250,"windows-1250"],[1251,"windows-1251"],[1252,"windows-1252"],[1253,"windows-1253"],[1254,"windows-1254"],[1255,"windows-1255"],[1256,"windows-1256"],[1257,"windows-1257"],[1258,"windows-1258"]]),T;function U(e){let t=0;for(let n of e)n===D&&(t+=1);return t}function H(e,t){return U(t)<U(e)?t:e}function nt(e){let t=e.match(/(?:^|[^0-9])([0-9]{1,5})(?![0-9])/);if(!t)return null;let n=Number(t[1]);return Number.isInteger(n)&&n>0&&n<=65535?n:null}function rt(e){if(e!==65001)return tt.get(e)}function ot(e){let t=rt(e);if(!t)return null;try{return new TextDecoder(t)}catch{return null}}function st(){return new Promise(e=>{let t=false,n,r=o=>{t||(t=true,n&&clearTimeout(n),e(o));};n=setTimeout(()=>r(null),re),n.unref();try{child_process.execFile("chcp.com",[],{encoding:"ascii",timeout:re,windowsHide:!0},(c,s)=>{if(c){r(null);return}r(nt(String(s)));}).once("error",()=>r(null));}catch{r(null);}})}function ie(){return process.platform!=="win32"?Promise.resolve(null):(T||(T=st(),T.then(e=>{},()=>{})),T)}function it(){process.platform==="win32"&&ie();}function se(e,t){if(t.length>=$)return t.subarray(t.length-$);let n=$-t.length,r=e.length>n?e.subarray(e.length-n):e;return Buffer.concat([r,t])}var k=class{platform;detectCodePage;utf8Decoder=new string_decoder.StringDecoder("utf8");codePage;fallbackDecoder;replayTail=Buffer.alloc(0);pendingUtf8="";pendingFallback="";pendingBytes=Buffer.alloc(0);queue=Promise.resolve();ended=false;constructor(t={}){this.platform=t.platform??process.platform,this.detectCodePage=t.detectCodePage??ie,this.codePage=t.codePage;}write(t){let n=Buffer.from(t);return this.enqueue(()=>this.decodeChunk(n))}end(){return this.enqueue(()=>this.finish())}enqueue(t){let n=this.queue.then(t);return this.queue=n.then(()=>{},()=>{}),n}clearPendingCandidate(){this.pendingUtf8="",this.pendingFallback="",this.pendingBytes=Buffer.alloc(0);}async resolveCodePage(){if(this.codePage!==void 0)return this.codePage;try{this.codePage=await this.detectCodePage();}catch{this.codePage=null;}return this.codePage}async getFallbackDecoder(){if(this.fallbackDecoder!==void 0)return this.fallbackDecoder;let t=await this.resolveCodePage();return this.fallbackDecoder=t===null?null:ot(t),this.fallbackDecoder}async decodeChunk(t){if(this.ended)return "";let n=this.utf8Decoder.write(t),r=n.includes(D);if(r&&(this.utf8Decoder=new string_decoder.StringDecoder("utf8")),this.platform!=="win32")return n;if(this.fallbackDecoder){let a=this.fallbackDecoder.decode(t,{stream:true}),l=se(this.pendingBytes,t);if(r){let d=this.pendingUtf8+n,f=this.pendingFallback+a;return this.clearPendingCandidate(),H(d,f)}if(U(a)>0){let d=this.pendingUtf8+n;return this.clearPendingCandidate(),this.fallbackDecoder=void 0,this.replayTail=l,d}if(this.pendingUtf8||this.pendingFallback){if(this.pendingUtf8+=n,this.pendingFallback+=a,this.pendingBytes=l,n.length===0||a.length===0)return "";let d=this.pendingUtf8;return this.clearPendingCandidate(),d}return n.length===0&&a.length>0?(this.pendingUtf8=n,this.pendingFallback=a,this.pendingBytes=l,""):n}let o=this.replayTail;if(this.fallbackDecoder===void 0&&(this.replayTail=se(this.replayTail,t)),!r)return n;let c=this.fallbackDecoder===void 0,s=await this.getFallbackDecoder();if(!s)return this.replayTail=Buffer.alloc(0),n;c&&o.length>0&&s.decode(o,{stream:true}),this.replayTail=Buffer.alloc(0);let i=s.decode(t,{stream:true});return H(n,i)}async finish(){if(this.ended)return "";this.ended=true;let t=this.utf8Decoder.end();if(this.platform!=="win32")return t;if(this.fallbackDecoder===void 0&&t.includes(D)){let c=await this.getFallbackDecoder();c&&this.replayTail.length>0&&(c.decode(this.replayTail,{stream:true}),this.replayTail=Buffer.alloc(0));}let n=this.pendingUtf8+t,r=this.fallbackDecoder?.decode()??"",o=this.pendingFallback+r;return this.clearPendingCandidate(),n.includes(D)?H(n,o):n}};it();var ae=3e3;var ct=2e3,lt=25,ut=100;function ue(e){return e instanceof Error?e:e===void 0?void 0:new Error(String(e))}function ce(e){return typeof e=="object"&&e!==null&&"code"in e?String(e.code):void 0}function dt(e){return Number.isSafeInteger(e)&&e>0}function ft(e,t){return new Promise(n=>{let r;try{r=child_process.spawn(e,t,{windowsHide:!0});}catch(l){n({status:null,stdout:"",stderr:"",error:ue(l)});return}let o="",c="",s=false,i,a=setTimeout(()=>{try{r.kill();}catch{}i({status:null,stdout:o,stderr:c,error:new Error(`Command timed out after ${ae}ms`)});},ae);i=l=>{s||(s=true,clearTimeout(a),n(l));},r.stdout?.setEncoding("utf8"),r.stderr?.setEncoding("utf8"),r.stdout?.on("data",l=>{o+=String(l);}),r.stderr?.on("data",l=>{c+=String(l);}),r.once("error",l=>{i({status:null,stdout:o,stderr:c,error:l});}),r.once("close",l=>{i({status:l,stdout:o,stderr:c});});})}async function pt(e,t,n){return n.runCommandAsync?n.runCommandAsync(e,t):n.runCommand?n.runCommand(e,t):ft(e,t)}function mt(e){return new Promise(t=>{setTimeout(t,Math.max(0,e));})}function ht(){return new Promise(e=>{setImmediate(e);})}function A(e,t=process.kill){try{return t(e,0),"alive"}catch(n){return ce(n)==="ESRCH"?"not_found":ce(n)==="EPERM"?"alive":"unknown"}}function gt(e,t){let n=A(-e,t),r=A(e,t);return n==="alive"||r==="alive"?"alive":n==="unknown"||r==="unknown"?"unknown":"not_found"}async function de(e,t,n,r){let o=Math.max(0,n),c=Math.max(1,r.pollIntervalMs??lt),s=Date.now()+o,i,a=o===0,l=r.sleep?Promise.resolve().then(()=>r.sleep(o)).then(()=>{},()=>{}):new Promise(d=>{i=setTimeout(d,o);});l.then(()=>{a=true;});try{for(await ht();;){let d=gt(e,t);if(d==="not_found")return d;let f=s-Date.now();if(a||f<=0)return d;await Promise.race([l,mt(Math.min(c,f))]);}}finally{i!==void 0&&clearTimeout(i);}}async function le(e,t,n,r,o){let c=await de(e,t,o.hardConfirmMs??ut,{...o,sleep:void 0});return c==="not_found"?n?{status:"not_found",pid:e,method:r}:{status:"terminated",pid:e,method:r}:c==="alive"?{status:"failed",pid:e,method:r,error:"Process is still running after termination attempt"}:{status:"failed",pid:e,method:r,error:"Unable to verify process termination"}}async function fe(e,t={}){let n=t.platform??process.platform,r=n==="win32"?"taskkill":"process-group",o=u=>({status:"failed",pid:e,method:r,error:u});if(!dt(e))return o("Invalid process ID");let c=t.kill??process.kill,s=A(e,c);if(s==="not_found")return {status:"not_found",pid:e,method:r};if(s!=="alive")return o("Unable to determine whether the process is alive");if(n==="win32"){let u;try{u=await pt("taskkill",["/PID",String(e),"/T","/F"],t);}catch(h){u={status:null,stdout:"",stderr:"",error:ue(h)};}let P=A(e,c);return P==="not_found"?u.status===0&&!u.error?{status:"terminated",pid:e,method:r}:{status:"not_found",pid:e,method:r}:o(P==="alive"?"Process is still running after termination attempt":"Unable to verify process termination")}let i,a=t.signal??"SIGKILL";try{c(-e,a);}catch(u){i=u;}if(a==="SIGKILL")return le(e,c,i,r,t);if(await de(e,c,t.graceMs??ct,t)==="not_found")return i?{status:"not_found",pid:e,method:r}:{status:"terminated",pid:e,method:r};let d;try{c(-e,"SIGKILL");}catch(u){d=u;}let f=await le(e,c,d,r,t);return f.status==="terminated"?f:f.status==="not_found"?i?f:{status:"terminated",pid:e,method:r}:o(f.error??"Process termination failed")}var wt=["CREWX_ASSIGNED_TASK_ID","CREWX_DETACHED_RUNNER"];function Pt(e,t){let n={};for(let[r,o]of Object.entries(e))o!==void 0&&(t.includes(r)||(n[r]=o));return n}function pe(e){return Pt(e,wt)}var me=3e4;function he(e){if(typeof e.pid!="number"){try{e.kill();}catch{}return}fe(e.pid,{signal:"SIGKILL"}).then(t=>{if(t.status==="failed")try{e.kill("SIGKILL");}catch{}},()=>{try{e.kill("SIGKILL");}catch{}});}var ge=(e,t,n={})=>new Promise((r,o)=>{let c=pe(n.env??process.env),s=process.platform,i;try{let w=ee({command:e,platform:s,env:c,cwd:n.cwd,allowShellFallback:!1});i=te(w,t);}catch(w){o(w instanceof Error?w:new Error(String(w)));return}let a=child_process.spawn(i.command,i.argv,{cwd:n.cwd,env:c,shell:i.shell,windowsHide:i.windowsHide??true,detached:s!=="win32"}),l="",d="",f=false,u=new k({platform:s}),P=new k({platform:s}),h=Promise.resolve(),C=Promise.resolve(),g=setTimeout(()=>{f||(f=true,he(a),o(new Error(`Command timed out after ${n.timeoutMs??me}ms: ${e} ${t.join(" ")}`)));},n.timeoutMs??me);a.stdout?.on("data",w=>{h=h.then(async()=>{l+=await u.write(w);});}),a.stderr?.on("data",w=>{C=C.then(async()=>{d+=await P.write(w);});}),a.on("error",w=>{f||(f=true,clearTimeout(g),o(w));}),a.on("close",w=>{f||(async()=>{await Promise.all([h,C]);let[y,$e]=await Promise.all([u.end(),P.end()]);f||(l+=y,d+=$e,f=true,clearTimeout(g),r({code:w??0,stdout:l,stderr:d}));})().catch(y=>{f||(f=true,clearTimeout(g),o(y instanceof Error?y:new Error(String(y))));});});});function yt(){try{return (typeof B=="function"?B:module$1.createRequire(__filename)).resolve("@crewx/sdk/package.json")}catch{return null}}function vt(){let e=[yt(),p.join(__dirname,"../../package.json"),p.join(__dirname,"../../../package.json")].filter(t=>!!t);for(let t of e)try{let n=JSON.parse(fs.readFileSync(t,"utf8"));if(n.name==="@crewx/sdk"&&n.version)return n.version}catch{}return "0.0.0"}var Pe=vt();var E=p__namespace.win32;function V(e){return E.join(e,".crewx")}function Ee(e){return E.join(V(e),"shortcut.json")}function Ce(e){return E.join(V(e),"launcher.json")}function ye(e){return E.join(V(e),"bin","crewx-launcher.cmd")}function ve(e){return E.join(e,"CrewX.lnk")}function X(e,t){return E.normalize(e).toLowerCase()===E.normalize(t).toLowerCase()}var Rt="[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; [Environment]::GetFolderPath('DesktopDirectory')";async function Re(e){try{let n=await e.run("powershell",["-NoProfile","-NonInteractive","-Command",Rt],{env:e.env}),r=n.stdout.trim();if(n.code===0&&r)return {dir:r,source:"known-folder"}}catch{}let t=e.env.USERPROFILE||e.env.Userprofile||e.homedir();return t?{dir:E.join(t,"Desktop"),source:"fallback"}:null}function G(e,t){let n=E.resolve(t,"node_modules",".bin").toLowerCase();return e.split(";").filter(r=>r?E.resolve(r).toLowerCase()!==n:true).join(";")}function be(e){return e?/\\Program Files( \(x86\))?\\/i.test(e)&&/crewx/i.test(e):false}function bt(e,t){let n=a=>{let[l,...d]=a.split("-"),f=d.join("-")||void 0;return {parts:(l??"").split(".").map(P=>Number.parseInt(P,10)||0),pre:f}},r=n(e),o=n(t),c=Math.max(r.parts.length,o.parts.length);for(let a=0;a<c;a++){let l=r.parts[a]??0,d=o.parts[a]??0;if(l!==d)return l<d?-1:1}if(r.pre===o.pre)return 0;if(!r.pre&&o.pre)return 1;if(r.pre&&!o.pre)return -1;let s=Number.parseInt(r.pre.match(/(\d+)$/)?.[1]??"",10),i=Number.parseInt(o.pre.match(/(\d+)$/)?.[1]??"",10);return !Number.isNaN(s)&&!Number.isNaN(i)&&s!==i?s<i?-1:1:r.pre<o.pre?-1:r.pre>o.pre?1:0}function _(e,t){return bt(e,t)<0}var _e=p__namespace.win32,xe=1;function Ie(e,t){if(!e.existsSync(t))return null;try{let n=JSON.parse(e.readFileSync(t));return {schema:n.schema??xe,shortcutPath:n.shortcutPath,version:n.version,iconHash:typeof n.iconHash=="string"?n.iconHash:void 0,owned:!!n.owned,declined:!!n.declined,desktopSource:n.desktopSource,updatedAt:n.updatedAt}}catch{return null}}function W(e,t,n){let r={schema:xe,...n,updatedAt:new Date().toISOString()};e.mkdirSync(_e.dirname(t)),e.writeFileSync(t,JSON.stringify(r,null,2));}function M(e,t){if(!e.existsSync(t))return null;try{let n=JSON.parse(e.readFileSync(t));return {schema:n.schema??0,binPath:n.binPath,updatedAt:n.updatedAt}}catch{return null}}function Le(e,t,n){e.mkdirSync(_e.dirname(t)),e.writeFileSync(t,JSON.stringify(n,null,2));}var kt=p__namespace.win32,x=1;function _t(e){return e.replace(/%/g,"%%")}function xt(e){return ["@echo off","setlocal DisableDelayedExpansion","chcp 65001 >nul","",'set "CREWX_WORKDIR=%USERPROFILE%\\crewx"','if not exist "%CREWX_WORKDIR%" mkdir "%CREWX_WORKDIR%" >nul 2>nul','cd /d "%CREWX_WORKDIR%"',"",'set "CREWX_PORT_EFFECTIVE=%CREWX_PORT%"','if "%CREWX_PORT_EFFECTIVE%"=="" set "CREWX_PORT_EFFECTIVE=8150"','set "CREWX_HEALTH_URL=http://127.0.0.1:%CREWX_PORT_EFFECTIVE%/api/v1/health"','set "CREWX_ORIGIN_URL=http://127.0.0.1:%CREWX_PORT_EFFECTIVE%/"',"",e.bakedBinPath?`set "CREWX_FALLBACK_BIN=${_t(e.bakedBinPath)}"`:'set "CREWX_FALLBACK_BIN="','set "CREWX_RESOLVED_BIN=%CREWX_BIN%"','if "%CREWX_RESOLVED_BIN%"=="" set "CREWX_RESOLVED_BIN=%CREWX_FALLBACK_BIN%"','if "%CREWX_RESOLVED_BIN%"=="" (',` for /f "delims=" %%I in ('where crewx 2^>nul') do (`,' if not defined CREWX_RESOLVED_BIN set "CREWX_RESOLVED_BIN=%%I"'," )",")","",'powershell -NoProfile -NonInteractive -Command "try { $r = Invoke-WebRequest -Uri $env:CREWX_HEALTH_URL -TimeoutSec 1 -UseBasicParsing; if ($r.StatusCode -eq 200) { exit 0 } else { exit 1 } } catch { exit 1 }"',"if %ERRORLEVEL% EQU 0 (",' start "" "%CREWX_ORIGIN_URL%"'," exit /b 0",")","",'if "%CREWX_RESOLVED_BIN%"=="" ('," echo CrewX executable not found. Please reinstall the desktop shortcut."," pause"," exit /b 1",")","",'start "CrewX" /min "%CREWX_RESOLVED_BIN%"',""].join(`\r
2
+ `)}function Oe(e){let t=M(e.fs,e.launcherManifestPath),n=!!t&&t.schema>=x&&e.fs.existsSync(e.wrapperPath),r=n&&!t.binPath&&!!e.bakedBinPath;if(n&&!r)return {wrapperPath:e.wrapperPath,wrote:false,schema:t.schema};let c=xt({bakedBinPath:e.bakedBinPath});try{e.fs.mkdirSync(kt.dirname(e.wrapperPath)),e.fs.writeFileSync(e.wrapperPath,c),Le(e.fs,e.launcherManifestPath,{schema:x,binPath:e.bakedBinPath,updatedAt:new Date().toISOString()});}catch(s){throw s instanceof m?s:new m("WRITE_DENIED",`Could not write launcher wrapper: ${s instanceof Error?s.message:String(s)}`)}return {wrapperPath:e.wrapperPath,wrote:true,schema:x}}var It=["$ws = New-Object -ComObject WScript.Shell","$sc = $ws.CreateShortcut($env:CREWX_LNK_PATH)","$sc.TargetPath = $env:CREWX_LNK_TARGET","if ($env:CREWX_LNK_WORKDIR) { $sc.WorkingDirectory = $env:CREWX_LNK_WORKDIR }","$sc.WindowStyle = 7","if ($env:CREWX_LNK_ICON) { $sc.IconLocation = $env:CREWX_LNK_ICON }","$sc.Save()"].join("; "),Lt=["[Console]::OutputEncoding = [System.Text.Encoding]::UTF8","$ws = New-Object -ComObject WScript.Shell","$sc = $ws.CreateShortcut($env:CREWX_LNK_PATH)","[PSCustomObject]@{ TargetPath = $sc.TargetPath; WorkingDirectory = $sc.WorkingDirectory; IconLocation = $sc.IconLocation } | ConvertTo-Json -Compress"].join("; ");async function Te(e){let t={...e.env,CREWX_LNK_PATH:e.shortcutPath,CREWX_LNK_TARGET:e.targetPath,CREWX_LNK_WORKDIR:e.workingDirectory??"",CREWX_LNK_ICON:e.iconPath??""},n;try{n=await e.run("powershell",["-NoProfile","-NonInteractive","-Command",It],{env:t});}catch(r){throw new m("POWERSHELL_UNAVAILABLE",`Could not run PowerShell: ${r instanceof Error?r.message:String(r)}`)}if(n.code!==0)throw new m("POWERSHELL_UNAVAILABLE",`Failed to create desktop shortcut: ${n.stderr||n.stdout}`)}function De(e){let t=e.trim(),n=t.lastIndexOf(",");return n!==-1&&/^-?\d+$/.test(t.slice(n+1).trim())&&(t=t.slice(0,n).trim()),t.length>=2&&t.startsWith('"')&&t.endsWith('"')&&(t=t.slice(1,-1).trim()),t}async function Ae(e){try{let t={...e.env,CREWX_LNK_PATH:e.shortcutPath},n=await e.run("powershell",["-NoProfile","-NonInteractive","-Command",Lt],{env:t});if(n.code!==0||!n.stdout.trim())return null;let r=JSON.parse(n.stdout.trim());return {targetPath:r.TargetPath??"",workingDirectory:r.WorkingDirectory??"",iconLocation:r.IconLocation??""}}catch{return null}}var K=p__namespace.win32;async function I(e){let t=G(e.env.PATH??e.env.Path??"",e.cwd),n={...e.env,PATH:t,Path:t},r;try{r=await e.run("npm",["list","-g","crewx","--depth=0","--json"],{env:n});}catch{return {installed:false}}let o;try{o=JSON.parse(r.stdout||"{}");}catch{return {installed:false}}let c=o.dependencies?.crewx;if(!c?.version)return {installed:false};let s;try{let a=await e.run("npm",["prefix","-g"],{env:n});a.code===0&&(s=a.stdout.trim()||void 0);}catch{}let i=s?K.join(s,"crewx.cmd"):void 0;return {installed:true,version:c.version,binPath:i,prefix:s}}var Nt=/EACCES|EPERM|EROFS/,Ot=/ENOTFOUND|ETIMEDOUT|ECONNREFUSED|network|registry/i,Tt=/^\d+\.\d+\.\d+/;function Dt(e){return !!e&&e!=="0.0.0"&&Tt.test(e)}var J=10*6e4;async function Me(e){if(!Dt(e.targetVersion))throw new m("GLOBAL_INSTALL_FAILED",`RUNNING_VERSION_UNKNOWN: cannot reliably determine the running crewx version to install (got ${JSON.stringify(e.targetVersion)}); refusing to fall back to crewx@latest`);if(e.currentInfo?.installed&&e.currentInfo.version&&!_(e.currentInfo.version,e.targetVersion))return {info:e.currentInfo};let t=G(e.env.PATH??e.env.Path??"",e.cwd),n={...e.env,PATH:t,Path:t},r=`crewx@${e.targetVersion}`;e.onProgress?.({phase:"global-install",message:`Installing crewx globally (npm install -g ${r})`});let o;try{o=await e.run("npm",["install","-g",r,"--no-audit","--no-fund"],{env:n,timeoutMs:J});}catch(s){throw new m("NPM_UNAVAILABLE",`Could not run npm: ${s instanceof Error?s.message:String(s)}`)}if(o.code===0)return {info:await I({env:n,cwd:e.cwd,run:e.run})};let c=`${o.stdout}
3
+ ${o.stderr}`;if(Nt.test(c)){e.onProgress?.({phase:"global-install",message:"Permission denied \u2014 retrying with a user-scoped npm prefix"});let s=e.env.LOCALAPPDATA||K.join(e.env.USERPROFILE??"","AppData","Local"),i={...n,npm_config_prefix:K.join(s,"crewx","npm")},a;try{a=await e.run("npm",["install","-g",r,"--no-audit","--no-fund"],{env:i,timeoutMs:J});}catch(l){throw new m("NPM_PERMISSION_DENIED",`Retry with user-scoped prefix failed: ${l instanceof Error?l.message:String(l)}`)}if(a.code===0)return {info:await I({env:i,cwd:e.cwd,run:e.run})};throw new m("NPM_PERMISSION_DENIED",`npm install -g failed after user-scoped prefix retry: ${a.stderr||a.stdout}`)}if(Ot.test(c)){if(!e.installRoot)throw new m("OFFLINE_NO_SOURCE","The npm registry is unreachable and no local installRoot was provided for an offline install");e.onProgress?.({phase:"global-install",message:`Registry unreachable \u2014 installing offline from ${e.installRoot}`});let s;try{s=await e.run("npm",["install","-g",e.installRoot,"--offline","--no-audit","--no-fund"],{env:n,timeoutMs:J});}catch(i){throw new m("GLOBAL_INSTALL_FAILED",`Offline install failed: ${i instanceof Error?i.message:String(i)}`)}if(s.code===0)return {info:await I({env:n,cwd:e.cwd,run:e.run})};throw new m("GLOBAL_INSTALL_FAILED",`Offline install failed: ${s.stderr||s.stdout}`)}throw new m("GLOBAL_INSTALL_FAILED",c.trim()||`npm install -g ${r} failed`)}function Wt(e){return e.run??ge}function Mt(e){return e.fs??q}async function F(e){let t=e.platform??process.platform,n=e.env??process.env,r=e.homedir??Y,o=Wt(e),c=Mt(e),s=e.runningVersion??Pe,i=e.cwd??process.cwd(),a=r(),l=Ee(a),d=Ce(a),f=ye(a),u=null;t==="win32"&&(u=await Re({env:n,homedir:r,run:o}));let P=u?ve(u.dir):null;return {platform:t,env:n,homedir:r,run:o,fs:c,runningVersion:s,cwd:i,installRoot:e.installRoot,shortcutManifestPath:l,launcherManifestPath:d,wrapperPath:f,desktop:u,shortcutPath:P}}function Fe(e){return e?p__namespace.win32.normalize(e).toLowerCase().endsWith(`${p__namespace.win32.sep}bin${p__namespace.win32.sep}crewx.ico`):false}function j(e,t){let n=e.readBinaryFileSync;if(n)try{return crypto.createHash("sha256").update(n(t)).digest("hex")}catch{return}}async function Ft(e){try{await e.run("ie4uinit.exe",["-show"],{env:e.env});}catch{}}async function v(e){if(e.platform!=="win32")return {supported:false,state:"unsupported",globalCrewx:null,runningVersion:e.runningVersion,errors:[],manifest:null,iconStale:false};let t=[];e.desktop||t.push("NO_DESKTOP_DIR: could not resolve the Windows Desktop directory");let n=Ie(e.fs,e.shortcutManifestPath),r=M(e.fs,e.launcherManifestPath),o=await I({env:e.env,cwd:e.cwd,run:e.run}),c=e.shortcutPath?e.fs.existsSync(e.shortcutPath):false,s,i=false,a,l;if(!c)s=n?.declined?"declined":"not-installed";else {let d=!!n?.owned&&!!e.shortcutPath&&n.shortcutPath===e.shortcutPath,f=false,u=e.shortcutPath?await Ae({run:e.run,env:e.env,shortcutPath:e.shortcutPath}):null;if(d||(u&&X(u.targetPath,e.wrapperPath)?d=true:u&&be(u.targetPath)&&(f=true)),f)s="foreign",t.push("NSIS_PRESENT: an NSIS-installed CrewX shortcut was detected");else if(!d)s="foreign";else if(n?.version&&_(e.runningVersion,n.version))s="superseded",t.push(`SUPERSEDED: running version ${e.runningVersion} is older than the installed shortcut's version ${n.version}; refusing to modify it`);else {let P=!r||r.schema<x||!e.fs.existsSync(e.wrapperPath);if(u){let h=De(u.iconLocation);if(!(!!h&&e.fs.existsSync(h)))i=true;else {a=h;let g=Be(o,e.fs);g?X(h,g)?(l=j(e.fs,h),i=!l||n?.iconHash!==l):i=true:Fe(h)?(l=j(e.fs,h),i=!l||n?.iconHash!==l):i=true;}}s=P||i?"stale":"installed";}}return {supported:true,state:s,shortcutPath:e.shortcutPath??void 0,desktopDir:e.desktop?.dir,desktopSource:e.desktop?.source,wrapperPath:e.wrapperPath,wrapperSchema:r?.schema,globalCrewx:o.installed?o:{installed:false},runningVersion:e.runningVersion,errors:t,manifest:n,iconStale:i,iconPath:a,iconHash:l}}function Be(e,t){if(!e?.installed||!e.prefix)return;let n=p__namespace.win32.join(e.prefix,"node_modules","crewx","bin","crewx.ico");return t.existsSync(n)?n:void 0}function R(e){let{manifest:t,iconStale:n,iconPath:r,iconHash:o,...c}=e;return c}async function Bt(e={}){let t=await F(e),n=await v(t);return R(n)}async function $t(e={}){let t=await F(e);e.onProgress?.({phase:"detect",message:"Checking current shortcut status"});let n=await v(t),r=R(n);if(!r.supported)return {...r,changed:false,installedGlobal:false};if(r.state==="superseded")return {...r,changed:false,installedGlobal:false};if(r.state==="foreign"){if(n.errors.some(g=>g.startsWith("NSIS_PRESENT")))throw new m("NSIS_PRESENT",`An NSIS-installed CrewX shortcut was detected at ${r.shortcutPath}`);if(!e.force)throw new m("FOREIGN_SHORTCUT",`An existing shortcut at ${r.shortcutPath} is not managed by CrewX`)}if(!t.desktop||!t.shortcutPath)throw new m("NO_DESKTOP_DIR","Could not resolve the Windows Desktop directory");let o=false,c=false,s=r.globalCrewx,i=[],a=n.manifest?.iconHash,l=false;if(!!s?.installed&&!!s.version&&_(s.version,t.runningVersion)||!s?.installed&&r.state!=="installed"){let g=await Me({env:t.env,cwd:t.cwd,run:t.run,targetVersion:t.runningVersion,currentInfo:s??void 0,installRoot:t.installRoot,onProgress:e.onProgress});s=g.info,c=g.info.installed,o=true,c||i.push(`GLOBAL_INSTALL_UNCONFIRMED: npm install -g crewx@${t.runningVersion} exited successfully but a follow-up check could not confirm the global install`);}if(e.onProgress?.({phase:"wrapper",message:"Ensuring launcher wrapper"}),Oe({fs:t.fs,wrapperPath:t.wrapperPath,launcherManifestPath:t.launcherManifestPath,bakedBinPath:s?.binPath}).wrote&&(o=true),!((r.state==="installed"||r.state==="stale")&&!n.iconStale)){let g=Be(s,t.fs)??(n.iconPath&&Fe(n.iconPath)&&t.fs.existsSync(n.iconPath)?n.iconPath:void 0);if(n.iconStale&&!g)throw new m("ICON_UNAVAILABLE",`Could not locate the global CrewX icon (bin\\crewx.ico) to repair the desktop shortcut at ${t.shortcutPath}; the existing shortcut was left untouched`);e.onProgress?.({phase:"lnk",message:"Creating desktop shortcut"}),await Te({run:t.run,env:t.env,shortcutPath:t.shortcutPath,targetPath:t.wrapperPath,iconPath:g}),o=true,l=n.iconStale;let w=g?j(t.fs,g):void 0;w&&(a=w);}o&&W(t.fs,t.shortcutManifestPath,{shortcutPath:t.shortcutPath,version:t.runningVersion,owned:true,declined:false,desktopSource:t.desktop.source,iconHash:a}),l&&await Ft(t);let h=await v(t),C=R(h);return {...C,errors:[...C.errors,...i],changed:o,installedGlobal:c}}async function Ht(e={}){let t=await F(e),n=await v(t),r=R(n);if(!r.supported)return r;if((r.state==="installed"||r.state==="stale")&&t.shortcutPath)try{t.fs.unlinkSync(t.shortcutPath);}catch{}W(t.fs,t.shortcutManifestPath,{shortcutPath:void 0,version:n.manifest?.version,owned:false,declined:true,desktopSource:void 0,iconHash:void 0});let o=await v(t);return R(o)}async function Ut(e={}){let t=await F(e),n=await v(t),r=R(n);if(!r.supported)return r;W(t.fs,t.shortcutManifestPath,{shortcutPath:n.manifest?.shortcutPath,version:n.manifest?.version,owned:n.manifest?.owned??false,declined:true,desktopSource:n.manifest?.desktopSource,iconHash:n.manifest?.iconHash});let o=await v(t);return R(o)}exports.ShortcutError=m;exports.dismissShortcutNotice=Ut;exports.getShortcutStatus=Bt;exports.installShortcut=$t;exports.killProcessTree=he;exports.uninstallShortcut=Ht;
@@ -0,0 +1,5 @@
1
+ import { type InstallShortcutOptions, type ShortcutEnvOptions, type ShortcutInstallResult, type ShortcutStatus } from './types';
2
+ export declare function getShortcutStatus(options?: ShortcutEnvOptions): Promise<ShortcutStatus>;
3
+ export declare function installShortcut(options?: InstallShortcutOptions): Promise<ShortcutInstallResult>;
4
+ export declare function uninstallShortcut(options?: ShortcutEnvOptions): Promise<ShortcutStatus>;
5
+ export declare function dismissShortcutNotice(options?: ShortcutEnvOptions): Promise<ShortcutStatus>;
@@ -0,0 +1,22 @@
1
+ import type { CommandRunner } from './types';
2
+ export interface WriteLnkOptions {
3
+ run: CommandRunner;
4
+ env: NodeJS.ProcessEnv;
5
+ shortcutPath: string;
6
+ targetPath: string;
7
+ workingDirectory?: string;
8
+ iconPath?: string;
9
+ }
10
+ export declare function writeLnk(opts: WriteLnkOptions): Promise<void>;
11
+ export interface LnkInfo {
12
+ targetPath: string;
13
+ workingDirectory: string;
14
+ iconLocation: string;
15
+ }
16
+ export interface ReadLnkOptions {
17
+ run: CommandRunner;
18
+ env: NodeJS.ProcessEnv;
19
+ shortcutPath: string;
20
+ }
21
+ export declare function normalizeIconLocation(raw: string): string;
22
+ export declare function readLnkTarget(opts: ReadLnkOptions): Promise<LnkInfo | null>;
@@ -0,0 +1,21 @@
1
+ import type { DesktopSource, ShortcutFsLike } from './types';
2
+ export declare const MANIFEST_SCHEMA_VERSION = 1;
3
+ export interface ShortcutManifest {
4
+ schema: number;
5
+ shortcutPath?: string;
6
+ version?: string;
7
+ iconHash?: string;
8
+ owned: boolean;
9
+ declined: boolean;
10
+ desktopSource?: DesktopSource;
11
+ updatedAt?: string;
12
+ }
13
+ export interface LauncherManifest {
14
+ schema: number;
15
+ binPath?: string;
16
+ updatedAt?: string;
17
+ }
18
+ export declare function readShortcutManifest(fs: ShortcutFsLike, manifestPath: string): ShortcutManifest | null;
19
+ export declare function writeShortcutManifest(fs: ShortcutFsLike, manifestPath: string, data: Omit<ShortcutManifest, 'schema' | 'updatedAt'>): void;
20
+ export declare function readLauncherManifest(fs: ShortcutFsLike, manifestPath: string): LauncherManifest | null;
21
+ export declare function writeLauncherManifest(fs: ShortcutFsLike, manifestPath: string, data: LauncherManifest): void;
@@ -0,0 +1,67 @@
1
+ export type ShortcutState = 'unsupported' | 'not-installed' | 'installed' | 'stale' | 'foreign' | 'superseded' | 'declined';
2
+ export type DesktopSource = 'known-folder' | 'fallback';
3
+ export interface GlobalCrewxInfo {
4
+ installed: boolean;
5
+ version?: string;
6
+ binPath?: string;
7
+ prefix?: string;
8
+ }
9
+ export interface ShortcutStatus {
10
+ supported: boolean;
11
+ state: ShortcutState;
12
+ shortcutPath?: string;
13
+ desktopDir?: string;
14
+ desktopSource?: DesktopSource;
15
+ wrapperPath?: string;
16
+ wrapperSchema?: number;
17
+ globalCrewx: GlobalCrewxInfo | null;
18
+ runningVersion: string;
19
+ errors: string[];
20
+ }
21
+ export interface ShortcutInstallResult extends ShortcutStatus {
22
+ changed: boolean;
23
+ installedGlobal: boolean;
24
+ }
25
+ export type ShortcutProgressPhase = 'detect' | 'global-install' | 'wrapper' | 'lnk';
26
+ export interface ShortcutProgressEvent {
27
+ phase: ShortcutProgressPhase;
28
+ message: string;
29
+ }
30
+ export interface CommandResult {
31
+ code: number;
32
+ stdout: string;
33
+ stderr: string;
34
+ }
35
+ export interface CommandRunOptions {
36
+ env?: NodeJS.ProcessEnv;
37
+ cwd?: string;
38
+ timeoutMs?: number;
39
+ }
40
+ export type CommandRunner = (command: string, args: string[], opts?: CommandRunOptions) => Promise<CommandResult>;
41
+ export interface ShortcutFsLike {
42
+ existsSync(path: string): boolean;
43
+ readFileSync(path: string): string;
44
+ readBinaryFileSync?: (path: string) => Uint8Array;
45
+ writeFileSync(path: string, data: string): void;
46
+ mkdirSync(path: string): void;
47
+ unlinkSync(path: string): void;
48
+ }
49
+ export interface ShortcutEnvOptions {
50
+ platform?: NodeJS.Platform;
51
+ env?: NodeJS.ProcessEnv;
52
+ homedir?: () => string;
53
+ run?: CommandRunner;
54
+ fs?: ShortcutFsLike;
55
+ runningVersion?: string;
56
+ cwd?: string;
57
+ }
58
+ export interface InstallShortcutOptions extends ShortcutEnvOptions {
59
+ force?: boolean;
60
+ onProgress?: (event: ShortcutProgressEvent) => void;
61
+ installRoot?: string;
62
+ }
63
+ export type ShortcutErrorCode = 'NOT_WINDOWS' | 'NO_DESKTOP_DIR' | 'NPM_UNAVAILABLE' | 'NPM_PERMISSION_DENIED' | 'OFFLINE_NO_SOURCE' | 'GLOBAL_INSTALL_FAILED' | 'POWERSHELL_UNAVAILABLE' | 'WRITE_DENIED' | 'FOREIGN_SHORTCUT' | 'NSIS_PRESENT' | 'ICON_UNAVAILABLE';
64
+ export declare class ShortcutError extends Error {
65
+ readonly code: ShortcutErrorCode;
66
+ constructor(code: ShortcutErrorCode, message: string);
67
+ }
@@ -0,0 +1 @@
1
+ export declare const SDK_VERSION: string;
@@ -0,0 +1,21 @@
1
+ import type { CommandRunner, DesktopSource } from './types';
2
+ export declare function crewxHomeDir(homedir: string): string;
3
+ export declare function shortcutManifestPath(homedir: string): string;
4
+ export declare function launcherManifestPath(homedir: string): string;
5
+ export declare function wrapperPath(homedir: string): string;
6
+ export declare function shortcutLnkPath(desktopDir: string): string;
7
+ export declare function samePath(a: string, b: string): boolean;
8
+ export interface ResolveDesktopDirOptions {
9
+ env: NodeJS.ProcessEnv;
10
+ homedir: () => string;
11
+ run: CommandRunner;
12
+ }
13
+ export interface ResolvedDesktopDir {
14
+ dir: string;
15
+ source: DesktopSource;
16
+ }
17
+ export declare function resolveDesktopDir(opts: ResolveDesktopDirOptions): Promise<ResolvedDesktopDir | null>;
18
+ export declare function filterWorkspaceLocalBin(pathValue: string, cwd: string): string;
19
+ export declare function looksLikeNsisInstall(targetPath: string): boolean;
20
+ export declare function compareVersions(a: string, b: string): -1 | 0 | 1;
21
+ export declare function isOlderVersion(a: string, b: string): boolean;
@@ -0,0 +1,18 @@
1
+ import type { ShortcutFsLike } from './types';
2
+ export declare const WRAPPER_SCHEMA_VERSION = 1;
3
+ export interface BuildWrapperScriptOptions {
4
+ bakedBinPath?: string;
5
+ }
6
+ export declare function buildWrapperScript(opts: BuildWrapperScriptOptions): string;
7
+ export interface EnsureWrapperOptions {
8
+ fs: ShortcutFsLike;
9
+ wrapperPath: string;
10
+ launcherManifestPath: string;
11
+ bakedBinPath?: string;
12
+ }
13
+ export interface EnsureWrapperResult {
14
+ wrapperPath: string;
15
+ wrote: boolean;
16
+ schema: number;
17
+ }
18
+ export declare function ensureWrapper(opts: EnsureWrapperOptions): EnsureWrapperResult;
@@ -0,0 +1,2 @@
1
+ import {parse}from'dotenv';import*as Y from'fs';import {readFileSync,existsSync,mkdirSync,writeFileSync,chmodSync,renameSync,unlinkSync}from'fs';import*as C from'path';import {join,dirname}from'path';import*as z from'os';import {randomUUID}from'crypto';var s=class extends Error{code;kind;status;constructor(e,n,r,o){super(o??`Account authentication request failed (${e})`),this.name="AccountAuthError",this.code=e,this.kind=n,this.status=r;}};var l=class extends Error{code="LOGIN_REQUIRED";constructor(){super("Login required \u2014 please log in again"),this.name="LoginRequiredError";}},f=class extends Error{code;constructor(e,n){super(n),this.name="SessionManagerError",this.code=e;}},p=class extends Error{code;constructor(e,n="auth.json is invalid \u2014 please log in again"){super(n),this.name="AuthJsonValidationError",this.code=e;}},i=class extends s{constructor(e){let n=e.startsWith("ACCOUNT_BASE_URL")?"CREWX_ACCOUNT_BASE_URL":e.startsWith("ACCOUNT_ISSUER")?"CREWX_ACCOUNT_ISSUER":e==="ACCOUNT_TARGET_INVALID"?"CREWX_TARGET":e==="ACCOUNT_TARGET_MIXED"?"CREWX_ACCOUNT_BASE_URL/CREWX_MARKETPLACE_URL":e==="MARKETPLACE_DISABLED"?"CREWX_MARKETPLACE_DISABLED":"CREWX_MARKETPLACE_URL",r=e==="ACCOUNT_TARGET_MIXED"?`${n} must not mix loopback and public hosts \u2014 choose one account target`:e==="MARKETPLACE_DISABLED"?`${n} disables Marketplace access`:`${n} is missing or invalid \u2014 configure it and try again`;super(e,"configuration",void 0,r),this.name="AccountConfigurationError";}};var O="CREWX_ACCOUNT_BASE_URL",I="CREWX_ACCOUNT_ISSUER",x="CREWX_MARKETPLACE_URL",L="CREWX_TARGET",X="CREWX_MARKETPLACE_DISABLED",R=Object.freeze({accountBaseUrl:"https://app.sowonai.com",marketplaceUrl:"https://market.sowonai.com"}),k=Object.freeze({accountBaseUrl:"http://127.0.0.1:3030",marketplaceUrl:"http://127.0.0.1:4000"}),D=Object.freeze(["https://app.sowonai.com/auth/v1","https://auth.sowonai.com/auth/v1"]);function P(t,e,n=false){let r=t?.trim();if(!r)throw new i(e);try{let o=new URL(r);if(o.protocol!=="http:"&&o.protocol!=="https:"||o.username.length>0||o.password.length>0||o.hostname.length===0||o.search.length>0||o.hash.length>0||n&&o.pathname!=="/")throw new Error("invalid URL")}catch{throw new i(e)}return r.replace(/\/+$/,"")}function q(t){let e=t?.trim();if(!e)throw new i("ACCOUNT_ISSUER_INVALID");try{let n=new URL(e);if(n.protocol!=="http:"&&n.protocol!=="https:"||n.username.length>0||n.password.length>0||n.hostname.length===0||n.search.length>0||n.hash.length>0)throw new Error("invalid issuer")}catch{throw new i("ACCOUNT_ISSUER_INVALID")}return e}function b(t){let e=t[L];if(e===void 0)return "production";let n=e.trim();if(n==="local"||n==="production")return n;throw new i("ACCOUNT_TARGET_INVALID")}function F(t){let e=t[X]?.trim().toLowerCase();return e==="1"||e==="true"}function V(t){return t==="local"?k:R}function J(t=process.env){let e=b(t),n=t[O];return n!==void 0?P(n,"ACCOUNT_BASE_URL_INVALID",true):V(e).accountBaseUrl}function de(t=process.env){let e=b(t);if(F(t))throw new i("MARKETPLACE_DISABLED");let n=t[x];return n!==void 0?P(n,"MARKETPLACE_URL_INVALID"):V(e).marketplaceUrl}function U(t=process.env){let e=t[I];return e===void 0?D:[q(e)]}function Ae(t=process.env){return U(t)[0]}function W(t,e,n,r=false){if(t===void 0)return e;try{return P(t,n,r)}catch{return t.trim()}}function _e(t){let e=t[I];if(e===void 0)return D;try{return [q(e)]}catch{return [e.trim()]}}function j(t){if(t===null)return false;try{let e=new URL(t).hostname.toLowerCase();return e==="127.0.0.1"||e==="localhost"||e==="[::1]"||e==="::1"}catch{return false}}function ge(t,e){return e!==null&&t===R.accountBaseUrl&&e===R.marketplaceUrl?"production":e!==null&&t===k.accountBaseUrl&&e===k.marketplaceUrl?"local":"custom"}function $(t=process.env){let e,n=true;try{e=b(t);}catch{e="production",n=false;}let r=V(e),o=t[L]!==void 0&&n,c=t[O],T=t[x],u=F(t),d=W(c,r.accountBaseUrl,"ACCOUNT_BASE_URL_INVALID",true),y=u?null:W(T,r.marketplaceUrl,"MARKETPLACE_URL_INVALID");return {accountBaseUrl:d,marketplaceUrl:y,issuers:_e(t),profile:ge(d,y),sources:{accountBaseUrl:c===void 0?o?"profile":"default":"env",marketplaceUrl:u?"disabled":T===void 0?o?"profile":"default":"env",issuer:t[I]===void 0?"default":"env"},mixed:y!==null&&j(d)!==j(y),marketplaceDisabled:u}}function Ee(t=process.env){if($(t).mixed)throw new i("ACCOUNT_TARGET_MIXED")}function M(t,e){return `${t.replace(/\/+$/,"")}/${e.replace(/^\/+/,"")}`}function v(){if(process.env.CREWX_HOME){let t=C.resolve(process.env.CREWX_HOME);try{return Y.realpathSync(t)}catch(e){if(e instanceof Error&&"code"in e&&e.code==="ENOENT")return t;throw e}}return process.platform!=="win32"&&process.env.XDG_CONFIG_HOME?C.join(process.env.XDG_CONFIG_HOME,"crewx"):C.join(z.homedir(),".crewx")}var te="CREWX_TASK_TICKET_SECRET";function ne(t={}){let e=t.workspaceDir??process.env.CREWX_WORKSPACE??process.cwd(),n=t.homeDir??v();return {workspace:join(e,".env"),home:join(n,".env")}}function me(t){try{return new Set(Object.keys(parse(readFileSync(t))))}catch(e){if(e?.code==="ENOENT")return new Set;throw e}}function Te(t){try{return parse(readFileSync(t))}catch(e){if(e?.code==="ENOENT")return {};throw e}}function Ce(t={}){let e=ne(t);for(let n of [e.workspace,e.home]){let r=Te(n);for(let[o,c]of Object.entries(r))o===te||process.env[o]!==void 0||(process.env[o]=c);}}var ie="auth.json",H=2,se=["version","sub","email","access_token","refresh_token","expires_at","updated_at"];function h(t="auth.json is invalid \u2014 please log in again"){throw new p("AUTH_JSON_INVALID",t)}function ve(){throw new p("AUTH_JSON_LEGACY","auth.json uses an unsupported legacy format \u2014 please log in again")}function Ne(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Oe(t){try{return E(t),!0}catch{return false}}function E(t){if(!Ne(t))return h();if(t.version===1)return ve();if(t.version!==H)return h();let e=Object.keys(t);if(e.length!==se.length||e.some(r=>!se.includes(r))||typeof t.sub!="string"||t.sub.length===0||typeof t.email!="string"||t.email.length===0||typeof t.access_token!="string"||t.access_token.length===0||typeof t.refresh_token!="string"||t.refresh_token.length===0)return h();let n=t.expires_at;return typeof n!="number"||!Number.isSafeInteger(n)||n<0||typeof t.updated_at!="string"||t.updated_at.length===0||Number.isNaN(Date.parse(t.updated_at))?h():{version:H,sub:t.sub,email:t.email,access_token:t.access_token,refresh_token:t.refresh_token,expires_at:n,updated_at:t.updated_at}}function ce(t){let e;try{e=JSON.parse(t);}catch{return h()}return E(e)}function ae(t){return t??join(v(),ie)}var A=class{configuredPath;constructor(e={}){this.configuredPath=typeof e=="string"?e:e.filePath;}path(){return ae(this.configuredPath)}read(){let e=this.path();if(!existsSync(e))return null;try{return ce(readFileSync(e,"utf8"))}catch(n){throw n instanceof p?n:new p("AUTH_JSON_INVALID")}}write(e){let n=E(e),r=this.path(),o=dirname(r);mkdirSync(o,{recursive:true,mode:448});let c=`${r}.tmp.${process.pid}.${randomUUID()}`;try{writeFileSync(c,JSON.stringify(n,null,2),{encoding:"utf8",mode:384}),chmodSync(c,384),renameSync(c,r),chmodSync(r,384);}catch{try{existsSync(c)&&unlinkSync(c);}catch{}throw new Error("Could not persist auth.json securely")}}clear(){let e=this.path();try{existsSync(e)&&unlinkSync(e);}catch{throw new Error("Could not clear auth.json")}}};function xe(t){let e=new A({filePath:t}).read();if(!e)throw new l;return e}function Le(t,e){new A({filePath:e}).write(t);}function De(t){new A({filePath:t}).clear();}var pe="/auth/v1/oauth/device/code",he="/auth/v1/oauth/token",le="/auth/v1/oauth/revoke",N="crewx-cli",m="urn:ietf:params:oauth:grant-type:device_code";function a(t){return typeof t=="string"&&t.trim().length>0}function w(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:null}function Pe(t){let e=w(t),n=e?.error??e?.code;if(typeof n=="string")return n.toLowerCase();let r=w(n),o=r?.code??r?.error;return typeof o=="string"?o.toLowerCase():void 0}function be(t){let e=w(t);if(!e||!a(e.device_code)||!a(e.user_code)||!a(e.verification_uri))throw new s("AUTH_RESPONSE_INVALID","protocol");let n=e.expires_in,r=e.interval;if(typeof n!="number"||!Number.isSafeInteger(n)||n<=0)throw new s("AUTH_RESPONSE_INVALID","protocol");if(e.verification_uri_complete!==void 0&&!a(e.verification_uri_complete))throw new s("AUTH_RESPONSE_INVALID","protocol");if(r!==void 0&&(typeof r!="number"||!Number.isSafeInteger(r)||r<0))throw new s("AUTH_RESPONSE_INVALID","protocol");let o={device_code:e.device_code,user_code:e.user_code,verification_uri:e.verification_uri,expires_in:n};return e.verification_uri_complete!==void 0&&(o.verification_uri_complete=e.verification_uri_complete),r!==void 0&&(o.interval=r),o}function Ve(t){let e=w(t),n=w(e?.account),r=e?.expires_in;if(!e||!a(e.access_token)||!a(e.refresh_token)||typeof r!="number"||!Number.isSafeInteger(r)||r<=0||!n||!a(n.sub)||!a(n.email))throw new s("AUTH_RESPONSE_INVALID","protocol");let o={access_token:e.access_token,refresh_token:e.refresh_token,expires_in:r,account:{sub:n.sub,email:n.email}};return typeof e.token_type=="string"&&e.token_type.length>0&&(o.token_type=e.token_type),typeof e.scope=="string"&&e.scope.length>0&&(o.scope=e.scope),o}var S=class{configuredBaseUrl;fetchImpl;timeoutMs;constructor(e={}){let n=typeof e=="string"?{baseUrl:e}:e;this.configuredBaseUrl=n.baseUrl===void 0?void 0:Je(n.baseUrl),this.fetchImpl=n.fetch??n.fetchImpl,this.timeoutMs=n.timeoutMs??1e4;}baseUrl(){return this.configuredBaseUrl!==void 0?this.configuredBaseUrl:J()}signal(e){if(!(e<=0||typeof AbortSignal>"u"||typeof AbortSignal.timeout!="function"))return AbortSignal.timeout(e)}async request(e,n,r,o={}){let c=M(this.baseUrl(),e),T=this.fetchImpl??globalThis.fetch;if(typeof T!="function")throw new s("AUTH_NETWORK_ERROR","network");let u;try{u=await T(c,{...n,signal:n.signal??this.signal(o.timeoutMs??this.timeoutMs)});}catch{throw new s("AUTH_NETWORK_ERROR","network")}if(o.parseBody===false){if(!u.ok)throw ue(u.status,null,r);return}let d=null;try{d=await u.json();}catch{d=null;}if(!u.ok)throw ue(u.status,d,r);return d}async requestDeviceCode(){let e=new URLSearchParams;e.set("client_id",N);let n=await this.request(pe,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:e.toString()});return be(n)}async requestToken(e){Me(e);let n=new URLSearchParams;n.set("grant_type",e.grant_type),n.set("client_id",N),e.grant_type===m?n.set("device_code",e.device_code):n.set("refresh_token",e.refresh_token);let r=await this.request(he,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()},e);return Ve(r)}async exchangeDeviceCode(e){return this.requestToken({grant_type:m,device_code:e})}async refreshToken(e){return this.requestToken({grant_type:"refresh_token",refresh_token:e})}async deviceCode(){return this.requestDeviceCode()}async getDeviceCode(){return this.requestDeviceCode()}async token(e){return this.requestToken(e)}async getToken(e){return this.requestToken(e)}async refresh(e){return this.refreshToken(e)}async refreshAccessToken(e){return this.refreshToken(e)}async revokeToken(e){if(!a(e))throw new s("AUTH_INPUT_INVALID","protocol");let n=new URLSearchParams;n.set("token",e),n.set("token_type_hint","refresh_token"),n.set("client_id",N),await this.request(le,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:n.toString()},void 0,{parseBody:false,timeoutMs:3e3});}async revoke(e){return this.revokeToken(e)}};function Je(t){if(typeof t!="string"||!t.trim())throw new i("ACCOUNT_BASE_URL_INVALID");try{let e=new URL(t.trim());if(e.protocol!=="http:"&&e.protocol!=="https:"||e.username.length>0||e.password.length>0||e.hostname.length===0||e.pathname!=="/"||e.search.length>0||e.hash.length>0)throw new Error("invalid URL")}catch{throw new i("ACCOUNT_BASE_URL_INVALID")}return t.trim().replace(/\/+$/,"")}function Me(t){if(!t||t.grant_type!==m&&t.grant_type!=="refresh_token"||t.grant_type===m&&!a(t.device_code)||t.grant_type==="refresh_token"&&!a(t.refresh_token))throw new s("AUTH_INPUT_INVALID","protocol")}function ue(t,e,n){let r=Pe(e);if(t>=500)return new s("AUTH_SERVER_ERROR","server",t);if(n?.grant_type==="refresh_token"&&(r==="invalid_grant"||t===401))return new s("INVALID_REFRESH_TOKEN","invalid_refresh",t);if(n?.grant_type===m){if(r==="authorization_pending")return new s("AUTHORIZATION_PENDING","pending",t);if(r==="slow_down")return new s("SLOW_DOWN","pending",t);if(r==="access_denied")return new s("ACCESS_DENIED","denied",t);if(r==="expired_token")return new s("EXPIRED_TOKEN","expired",t)}return new s("AUTH_HTTP_ERROR","http",t)}var G=class{client;store;refreshSkewSeconds;now;nowSecondsOverride;refreshPromise=null;constructor(e={},n){let r=He(e)?e:void 0,o=r?{}:e;this.client=r??o.client??o.authClient??new S,this.store=o.store??o.storage??n??new A,this.refreshSkewSeconds=o.refreshSkewSeconds??60,this.now=o.now??(()=>Date.now()),this.nowSecondsOverride=o.nowSeconds;}getSession(){return this.readSession()}isLoggedIn(){return this.readSession()!==null}async getAccessToken(){let e=this.requireSession();return e.expires_at>this.epochSeconds()+this.refreshSkewSeconds?e.access_token:(await this.refreshSession(e)).access_token}async getValidAccessToken(){return this.getAccessToken()}async getToken(){return this.getAccessToken()}async refresh(){return this.refreshSession(this.requireSession())}async loginWithDeviceCode(e){let n=await this.client.exchangeDeviceCode(e);return this.persistTokenResponse(n)}async login(e){return this.loginWithDeviceCode(e)}async setSession(e){return this.persistTokenResponse(e)}clear(){this.store.clear();}async withAccessToken(e){return e(await this.getAccessToken())}readSession(){try{let e=this.store.read();if(e===null)return null;let n=E(e);return fe(n.access_token,n.sub),n}catch(e){throw e instanceof p?new l:e}}requireSession(){let e=this.readSession();if(!e)throw new l;return e}epochSeconds(){return this.nowSecondsOverride?.()??Math.floor(this.now()/1e3)}refreshSession(e){if(this.refreshPromise)return this.refreshPromise;let n;return n=this.performRefresh(e).finally(()=>{this.refreshPromise===n&&(this.refreshPromise=null);}),this.refreshPromise=n,n}async performRefresh(e){try{let n=await this.client.refreshToken(e.refresh_token);return this.persistTokenResponse(n,e.sub)}catch(n){throw Be(n)?(this.store.clear(),new l):n}}persistTokenResponse(e,n){let r=e?.account;if(!e||typeof e.access_token!="string"||e.access_token.length===0||typeof e.refresh_token!="string"||e.refresh_token.length===0||!Number.isSafeInteger(e.expires_in)||e.expires_in<=0||!r||typeof r.sub!="string"||r.sub.length===0||typeof r.email!="string"||r.email.length===0)throw new f("AUTH_RESPONSE_INVALID","Account token response is malformed");if(n!==void 0&&r.sub!==n)throw new f("ACCOUNT_SUB_MISMATCH","Account subject changed during token refresh \u2014 please log in again");fe(e.access_token,r.sub);let o=E({version:2,sub:r.sub,email:r.email,access_token:e.access_token,refresh_token:e.refresh_token,expires_at:this.epochSeconds()+e.expires_in,updated_at:new Date(this.now()).toISOString()});return this.store.write(o),o}};function Be(t){return t instanceof s?t.kind==="invalid_refresh":typeof t=="object"&&t!==null&&(t.kind==="invalid_refresh"||t.code==="INVALID_REFRESH_TOKEN")}function He(t){return typeof t.exchangeDeviceCode=="function"&&typeof t.refreshToken=="function"}function fe(t,e){let n=U(),r=Ke(t);if(!n.includes(r.iss))throw new f("ACCOUNT_ISSUER_MISMATCH","Access token issuer does not match the configured account issuer \u2014 please log in again");if(r.sub!==e)throw new f("ACCOUNT_SUB_MISMATCH","Access token subject does not match the account session \u2014 please log in again")}function Ke(t){if(typeof t!="string")throw K();let e=t.split(".");if(e.length!==3||e.some(n=>!/^[A-Za-z0-9_-]+$/.test(n)))throw K();try{let n=JSON.parse(Buffer.from(e[1],"base64url").toString("utf8"));if(typeof n!="object"||n===null||Array.isArray(n)||typeof n.iss!="string"||n.iss.length===0||typeof n.sub!="string"||n.sub.length===0)throw new Error("missing identity claims");return {iss:n.iss,sub:n.sub}}catch{throw K()}}function K(){return new f("ACCESS_TOKEN_INVALID","Access token identity could not be verified \u2014 please log in again")}
2
+ export{O as ACCOUNT_BASE_URL_ENV,I as ACCOUNT_ISSUER_ENV,L as ACCOUNT_TARGET_ENV,ie as AUTH_JSON_FILENAME,H as AUTH_JSON_VERSION,s as AccountAuthError,i as AccountConfigurationError,S as AuthClient,s as AuthClientError,s as AuthError,A as AuthJsonStore,p as AuthJsonValidationError,te as CREWX_TASK_TICKET_SECRET_ENV,D as DEFAULT_ACCEPTED_ISSUERS,m as DEVICE_CODE_GRANT_TYPE,pe as DEVICE_CODE_PATH,k as LOCAL_TARGET,l as LoginRequiredError,X as MARKETPLACE_DISABLED_ENV,x as MARKETPLACE_URL_ENV,N as OAUTH_CLIENT_ID,R as PRODUCTION_TARGET,le as REVOKE_PATH,G as SessionManager,f as SessionManagerError,he as TOKEN_PATH,M as appendEndpoint,Ee as assertAccountTargetNotMixed,ae as authJsonPath,De as clearAuthJson,Oe as isAuthJsonV2,Ce as loadCrewxEnvFiles,ce as parseAuthJson,xe as readAuthJson,me as readCrewxEnvFileKeys,U as resolveAcceptedAccountIssuers,J as resolveAccountBaseUrl,Ae as resolveAccountIssuer,$ as resolveAccountTarget,ne as resolveCrewxEnvFilePaths,de as resolveMarketplaceUrl,E as validateAuthJson,Le as writeAuthJson};
@@ -0,0 +1,10 @@
1
+ import {format,inspect}from'util';import {readSync}from'fs';import {createHash}from'crypto';import {Console}from'console';import {Writable}from'stream';var R=["text/plain","application/json"];var H=Symbol;H.metadata===void 0&&Object.defineProperty(Symbol,"metadata",{configurable:false,value:Symbol.for("Symbol.metadata")});var ce=H.metadata,x=Symbol.for("crewx.app.tool-metadata"),A=class extends Error{code;detail;outcome;constructor(t,n=null,o){super(t),this.name="AppError",this.code=t,this.detail=n,this.outcome=K(o?.outcome);}};function K(e){return e==="rejected"?"rejected":"failed"}var B=class{static devtools=process.env.CREWX_APP_DEV==="1"?Object.freeze({log:true}):void 0;currentState;stateWasSet=false;answerBody;answerRange;callContext;workspaceRoot;constructor(t={workspaceRoot:process.cwd()}){this.currentState=t.state??{},this.workspaceRoot=t.workspaceRoot,this.callContext=t.context===void 0?void 0:ye(t.context);}get context(){if(this.callContext===void 0)throw new TypeError("this.context is only set when the Host runs the action; pass options.context when you construct the App in a test");return this.callContext}get state(){return this.currentState}get didSetState(){return this.stateWasSet}setState(t){this.currentState=t,this.stateWasSet=true;}get didSetContent(){return this.answerBody!==void 0}get producedContent(){return this.answerBody===void 0?void 0:{body:this.answerBody,...this.answerRange===void 0?{}:{range:this.answerRange}}}setContent(t,n){if(typeof t!="string"&&!(t instanceof Uint8Array))throw new TypeError("setContent needs a string or a Uint8Array");if(n!==void 0&&!Te(n))throw new TypeError("setContent range must be { startLine, lineCount, totalLines }, three integers of at least 1");this.answerBody=typeof t=="string"?new TextEncoder().encode(t):new Uint8Array(t),this.answerRange=n===void 0?void 0:{startLine:n.startLine,lineCount:n.lineCount,totalLines:n.totalLines};}emptyState(){return {}}validate(t,n,o){}mapError(t){return {code:"EXECUTION_FAILED",detail:null}}errorState(t,n,o){return {...O(o.state)?o.state:{},error:{code:t,detail:n}}}};function le(e){return function(t,n){if(n.static||n.private||n.kind!=="method")throw new TypeError("@Tool can decorate public instance methods only");let o=n.metadata;if(!o)throw new TypeError("standard decorator metadata is unavailable");let i=Object.hasOwn(o,x)?o[x]:[];if(i.some(s=>s.methodName===String(n.name)))throw new TypeError(`@Tool is declared more than once for ${String(n.name)}`);let r=e.content===void 0?void 0:fe(e.name,e.content);o[x]=[...i,{methodName:String(n.name),options:Object.freeze({...e,...r===void 0?{}:{content:r}})}];}}function j(e){let t=e[ce],n=t&&Object.hasOwn(t,x)?t[x]:[],o=new Map(n.map(r=>[r.methodName,r])),i=Object.getOwnPropertyNames(e.prototype).map(r=>o.get(r)).filter(r=>r!==void 0);if(i.length!==n.length)throw new TypeError("a @Tool method is missing from the App prototype");return i}function G(e){let t=e.definition,n=j(e),o=new Set;return n.map(({options:i})=>{if(o.has(i.name))throw new TypeError(`duplicate @Tool name: ${i.name}`);return o.add(i.name),{actionId:i.name,...i.dataInputs===void 0?{}:{dataInputs:[...i.dataInputs]},confirmation:i.confirmation??"none",capability:i.capability??"app.read",mutation:i.mutation??true,inputSchema:i.inputSchema,...i.content===void 0?{}:{content:me(i.content)},resultProjection:i.resultProjection??{allow:[...t.stateProjection.allow]},_meta:{description:i.description}}})}function pe(e,t){if(t.length===0)throw new TypeError("backendCommand must name the skill command");let n=G(e).map(({_meta:o,...i})=>({...i,backend:{type:"skill",command:[...t]},_meta:o}));return {...e.definition,actions:n}}function fe(e,t){let n=r=>{throw new TypeError(`@Tool ${e}: content ${r}`)},o=(r,s,u)=>{if(!O(u))return n(`${r} must be an object`);for(let a of Object.keys(u))if(a==="mediaType"){if(!R.includes(u[a]))return n(`${r}.mediaType must be one of ${R.join(", ")}`)}else if(a===s){if(typeof u[a]!="boolean")return n(`${r}.${a} must be true or false`)}else return n(`${r} has the unknown key "${a}"`);return Object.hasOwn(u,"mediaType")?Object.freeze({...u}):n(`${r}.mediaType is required`)};if(!O(t))return n("must be an object");let i={};for(let r of Object.keys(t))if(r==="in")i[r]=o("in","required",t[r]);else if(r==="out")i[r]=o("out","range",t[r]);else return n(`has the unknown key "${r}"; use "in" and/or "out"`);return Object.keys(i).length===0?n('needs "in" and/or "out"'):Object.freeze(i)}function ye(e){return Object.freeze({instanceId:e.instanceId,threadId:e.threadId,actor:e.actor,requestId:e.requestId,nowMs:e.nowMs})}function me(e){let t={};for(let[n,o]of Object.entries(e))t[n]={...o};return t}function Te(e){return O(e)&&["startLine","lineCount","totalLines"].every(t=>Number.isSafeInteger(e[t])&&e[t]>=1)}function O(e){if(e===null||typeof e!="object"||Array.isArray(e))return false;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}var Ee=/^[A-Za-z0-9._:-]{1,128}$/u,ge=/[\u0000-\u001f\u007f\u2028\u2029]/u;function $(e=process.env){let t=Q(e.CREWX_APP_INSTANCE_ID),n=e.CREWX_APP_REQUEST_ID,o=e.CREWX_APP_ACTOR_KIND,i=e.CREWX_APP_NOW_MS;if(t===void 0||typeof n!="string"||!Ee.test(n)||o!=="user"&&o!=="agent"||typeof i!="string"||!/^\d{1,16}$/u.test(i))return;let r=Number(i);if(!Number.isSafeInteger(r))return;let s=e.CREWX_THREAD_ID===void 0?null:Q(e.CREWX_THREAD_ID);if(s!==void 0)return Object.freeze({instanceId:t,threadId:s,actor:o,requestId:n,nowMs:r})}function Q(e){if(!(typeof e!="string"||e.length===0||ge.test(e)))return new TextEncoder().encode(e).byteLength<=512?e:void 0}var Ae="dist/tools.json",Ce=1,Oe="dist/main.mjs";var Z=["CREWX_APP_INSTANCE_ID","CREWX_THREAD_ID"];function we(e){if(!Array.isArray(e)||e.length===0)return false;let t=new Set;for(let n of e){if(!Z.some(o=>o===n)||t.has(n))return false;t.add(n);}return true}var L=2,U=2097152;var N=2*1024*1024,F=2e4;function z(e){return createHash("sha256").update(e).digest("hex")}function P(e){if(e.byteLength===0)return 0;let t=0;for(let n of e)n===10&&(t+=1);return e[e.byteLength-1]!==10&&(t+=1),t}var Se=U+1+N,Ie=64*1024,he=10,M={kind:"invalid"};function Re(e,t){try{let n=[],o=0;for(;;){let s=new Uint8Array(Ie),u=readSync(e,s,0,s.length,null);if(u===0)break;if(o+=u,o>t)return;n.push(s.subarray(0,u));}let i=new Uint8Array(o),r=0;for(let s of n)i.set(s,r),r+=s.byteLength;return i}catch{return}}function v(e){return Ne(Re(e,Se))}function Ne(e){if(e===void 0)return M;let t=e.indexOf(he);if(e.byteLength<=U){let o=Ue(Buffer.from(e.buffer,e.byteOffset,e.byteLength).toString("utf8"));if(o.ok&&!(t>=0&&S(o.value)&&o.value.schemaVersion===L))return {kind:"v1",value:o.value}}if(t<=0||t>U)return M;let n;try{n=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(e.subarray(0,t)));}catch{return M}return !S(n)||n.schemaVersion!==L?M:{kind:"v2",header:n,body:e.subarray(t+1)}}var xe="actionId,content,input,schemaVersion,state",ke="bytes,lines,mediaType,sha256",De="mediaType,range",je=/^[a-f0-9]{64}$/u,Le=new TextDecoder("utf-8",{fatal:true,ignoreBOM:true});function ne(e,t){let n=a=>({code:a,outcome:"rejected"});if(k(e)!==xe||e.schemaVersion!==L||typeof e.actionId!="string"||!S(e.input)||!S(e.state)||!S(e.content)||k(e.content)!=="in,out")return {code:"INPUT_INVALID",outcome:"failed"};let o=e.content,i,r=o.in;if(r===null){if(t.byteLength!==0)return n(t.byteLength>N?"CONTENT_TOO_LARGE":"CONTENT_DIGEST_MISMATCH")}else {if(!S(r)||k(r)!==ke||!ee(r.mediaType)||!te(r.bytes,N)||!te(r.lines,F)||typeof r.sha256!="string"||!je.test(r.sha256)||t.byteLength!==r.bytes)return n(t.byteLength>N?"CONTENT_TOO_LARGE":"CONTENT_DIGEST_MISMATCH");if(z(t)!==r.sha256||P(t)!==r.lines)return n("CONTENT_DIGEST_MISMATCH");let a;try{a=Le.decode(t);}catch{return n("CONTENT_ENCODING_INVALID")}i={mediaType:r.mediaType,text:a};}let s,u=o.out;if(u!==null){if(!S(u)||k(u)!==De||!ee(u.mediaType))return n("CONTENT_SOURCE_UNSUPPORTED");let a=u.range;if(a!==null&&!Fe(a))return n("CONTENT_SOURCE_UNSUPPORTED");s={mediaType:u.mediaType,...a===null?{}:{range:{startLine:a.startLine,lineCount:a.lineCount}}};}return {actionId:e.actionId,input:e.input,state:e.state,content:{...i===void 0?{}:{in:i},...s===void 0?{}:{out:s}}}}function oe(e){return Object.hasOwn(e,"code")}function re(e,t){let n=o=>({code:o,outcome:"rejected"});if(e?.in===void 0){if(t.in!==void 0)return n("CONTENT_SOURCE_UNSUPPORTED")}else if(t.in===void 0){if(e.in.required===true)return n("CONTENT_REQUIRED")}else if(t.in.mediaType!==e.in.mediaType)return n("CONTENT_SOURCE_UNSUPPORTED");if(e?.out===void 0){if(t.out!==void 0)return n("CONTENT_SOURCE_UNSUPPORTED")}else {if(t.out===void 0)return n("CONTENT_REQUIRED");if(t.out.mediaType!==e.out.mediaType||t.out.range!==void 0&&e.out.range!==true)return n("CONTENT_SOURCE_UNSUPPORTED")}}function J(e,t){let{content:n,...o}=e,i=t===void 0?o:{...o,content:{bytes:t.body.byteLength,lines:P(t.body),sha256:z(t.body),...t.range===void 0?{}:{range:t.range}}},r=new TextEncoder().encode(`${JSON.stringify(i)}
2
+ `);if(t===void 0)return r;let s=new Uint8Array(r.byteLength+t.body.byteLength);return s.set(r,0),s.set(t.body,r.byteLength),s}function ie(e){if(e.body.byteLength>N||P(e.body)>F)return {code:"CONTENT_TOO_LARGE",outcome:"failed"}}function Ue(e){try{return {ok:!0,value:JSON.parse(e)}}catch{return {ok:false}}}function k(e){return Object.keys(e).sort().join(",")}function S(e){if(e===null||typeof e!="object"||Array.isArray(e))return false;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function ee(e){return typeof e=="string"&&R.includes(e)}function te(e,t){return Number.isSafeInteger(e)&&e>=0&&e<=t}function Fe(e){return S(e)&&k(e)==="lineCount,startLine"&&Number.isSafeInteger(e.startLine)&&e.startLine>=1&&Number.isSafeInteger(e.lineCount)&&e.lineCount>=1&&e.lineCount<=F}var Me=1;async function ve(e,t,n=process.env.CREWX_WORKSPACE_ROOT??process.cwd(),o){return (await de(e,t,n,void 0,true,void 0,o)).response}async function de(e,t,n,o,i=true,r,s){let u=r!==void 0,a=O(t)?t:void 0,m=a?.input,T=a?.state,d=new e({state:O(T)?T:{},workspaceRoot:n,...s===void 0?{}:{context:s}}),C=O(m)?m:{},E=O(T)?T:d.emptyState(),y={};try{let c;if(u){if(a===void 0)throw new A("INPUT_INVALID");let f=ne(a,r);if(oe(f))throw new A(f.code,null,{outcome:f.outcome});(({actionId:c,input:C,state:E}=f)),y=f.content;}else {if(!a||Object.keys(a).length!==4||!["schemaVersion","actionId","input","state"].every(f=>Object.hasOwn(a,f))||a.schemaVersion!==Me||typeof a.actionId!="string"||!O(m)||!O(T))throw new A("INPUT_INVALID");c=a.actionId,C=m,E=T;}d=new e({state:E,workspaceRoot:n,...s===void 0?{}:{context:s}}),await d.validate(c,C,E);let l=j(e).find(({options:f})=>f.name===c);if(!l)throw new A("INPUT_INVALID");let g=d[l.methodName];if(typeof g!="function")throw new A("EXECUTION_FAILED");let p=re(l.options.content,y);if(p)throw new A(p.code,null,{outcome:p.outcome});let D=Object.freeze({...y.in===void 0?{}:{in:Object.freeze({text:y.in.text})},...y.out===void 0?{}:{out:Object.freeze(y.out.range===void 0?{}:{range:Object.freeze({...y.out.range})})}}),h=()=>g.call(d,C,D),I=i?await Xe(h):await h();if(I!==void 0&&!O(I))throw new A("EXECUTION_FAILED");let b;if(y.out!==void 0){if(b=d.producedContent,b===void 0)throw new A("EXECUTION_FAILED","content.out was requested but setContent was never called");let f=ie(b);if(f)throw new A(f.code,null,{outcome:f.outcome})}else if(d.didSetContent)throw new A("EXECUTION_FAILED","setContent was called but the request asked for no content.out");return {response:{...d.didSetState?{state:d.state}:{},...I===void 0?{}:{result:I}},...b===void 0?{}:{answer:b}}}catch(c){let l,g=c,p=c instanceof A?c:void 0;if(p)l={code:p.code,detail:p.detail,outcome:p.outcome};else try{l=d.mapError(c);}catch(q){l={code:"EXECUTION_FAILED",detail:null},g=q;}let D=Be(l?.code),h=D?l.code:"EXECUTION_FAILED",I=typeof l?.detail=="string"?l.detail:null,b=D?K(l.outcome):"failed",f;try{f=d.errorState(h,I,{input:C,state:E});}catch(q){g=new AggregateError([g,q],"App error handling failed"),f=d.emptyState();}return o?.(h,g,{outcome:b,detail:I,expected:p!==void 0&&g===p}),{response:{outcome:b,errorCode:h,state:O(f)?f:d.emptyState()}}}}async function Je(e,t={}){let n=t.output??process.stdout,o,i;if(t.preloadedInput!==void 0)o=t.preloadedInput.value,i=t.preloadedInput.body;else {let d=v(t.inputFd??0);d.kind==="v1"?o=d.value:d.kind==="v2"&&(o=d.header,i=d.body);}let r=i!==void 0,s=t.context??$(),u=false,a=(d,C,E)=>{u=true,t.onFailure?.(d,C,E);},m;try{m=await de(e,o,process.env.CREWX_WORKSPACE_ROOT??process.cwd(),a,t.consoleManaged!==!0,i,s);}catch(d){a("EXECUTION_FAILED",d),m={response:ae(t.emptyState)};}qe(m.response)&&!u&&a(m.response.errorCode,void 0,{outcome:m.response.outcome,detail:null,expected:false});let T;try{let d=(t.sanitize??se)(m.response);T=r?J(d,m.answer):`${JSON.stringify(d)}
3
+ `;}catch(d){a("EXECUTION_FAILED",d);let C=ae(t.emptyState);try{let E=(t.sanitize??se)(C);T=r?J(E):`${JSON.stringify(E)}
4
+ `;}catch(E){a("EXECUTION_FAILED",E),T=r?J(C):`${JSON.stringify(C)}
5
+ `;}}n.write(T);}async function Xe(e){let t=["log","info","debug"],n=new Map;for(let o of t)n.set(o,console[o]),console[o]=(...i)=>process.stderr.write(`${format(...i)}
6
+ `);try{return await e()}finally{for(let o of t)console[o]=n.get(o);}}function ae(e={}){return {outcome:"failed",errorCode:"EXECUTION_FAILED",state:{...e,error:{code:"EXECUTION_FAILED",detail:null}}}}function qe(e){return (e.outcome==="failed"||e.outcome==="rejected")&&typeof e.errorCode=="string"}function Be(e){return typeof e=="string"&&/^[A-Z][A-Z0-9_]{0,127}$/u.test(e)}function se(e){return e}var V={depth:null,maxArrayLength:null,maxStringLength:null},Y=class extends Writable{#e="buffer";#t=[];_write(t,n,o){if(this.#e==="buffer"){this.#t.push(typeof t=="string"?t:Uint8Array.from(t)),o();return}if(this.#e==="discard"){o();return}process.stderr.write(t,o);}flushToStderr(){this.#e="stderr";for(let t of this.#t)process.stderr.write(t);this.#t=[];}discard(){this.#e="discard",this.#t=[];}};async function ze(e,t={}){let n=process.stdout,o=n.write.bind(n),i=new Y,r=new Console({stdout:i,stderr:i,inspectOptions:{...V}});globalThis.console=r;let s=false,u="-",a="-",m,T=false,d,C;try{let c=We(t.inputFd??0);u=Ye(c.value),a=X(process.env.CREWX_APP_REQUEST_ID),m=new Date().toISOString();try{d=await e();}catch(p){T=!0,C=p;}let l=d?.default;if(!T&&l?.devtools?.log===!0?(Object.assign(inspect.defaultOptions,V),E(m),i.flushToStderr()):i.discard(),T){y("EXECUTION_FAILED",C),W(o,t,y);return}try{if(typeof d?.runSkillApp!="function")throw new TypeError("App module does not export runSkillApp");let p={sanitize:t.sanitize,emptyState:t.emptyState??Ve(l),preloadedInput:c.body===void 0?{value:c.value}:{value:c.value,body:c.body},onFailure:y,consoleManaged:!0,output:{write:o}};await d.runSkillApp(l,p);}catch(p){y("EXECUTION_FAILED",p),W(o,t,y);}}catch(c){y("EXECUTION_FAILED",c),W(o,t,y);}finally{process.exitCode=0;}function E(c){s||(process.stderr.write(`[crewx-app] ${c??new Date().toISOString()} ${X(u)} req=${a}
7
+ `),s=true);}function y(c,l,g){E();let p=g?.expected===true&&g.detail?` ${X(g.detail)}`:"";process.stderr.write(`[crewx-app] ${g?.outcome??"failed"} ${X(c)}${p}
8
+ `),l!==void 0&&g?.expected!==true&&process.stderr.write(`${inspect(l,V)}
9
+ `);}}function Ve(e){if(typeof e=="function")try{let n=new e({workspaceRoot:process.cwd()}).emptyState();return n!==null&&typeof n=="object"&&!Array.isArray(n)?n:void 0}catch{return}}function We(e){let t=v(e);return t.kind==="v1"?{value:t.value}:t.kind==="v2"?{value:t.header,body:t.body}:{value:void 0}}function Ye(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&typeof e.actionId=="string"?e.actionId:"-"}function X(e){return typeof e!="string"||e.length===0?"-":e.replace(/[\u0000-\u001f\u007f\u2028\u2029]/gu,"_")}function W(e,t,n){let o={code:"EXECUTION_FAILED",detail:null},r={outcome:"failed",errorCode:"EXECUTION_FAILED",state:t.emptyState!==null&&typeof t.emptyState=="object"&&!Array.isArray(t.emptyState)?{...t.emptyState,error:o}:{error:o}},s=r;try{s=(t.sanitize??He)(r);}catch(u){n("EXECUTION_FAILED",u);}e(`${JSON.stringify(s)}
10
+ `);}function He(e){return e}export{Ae as APP_TOOLS_FILE,Ce as APP_TOOLS_SCHEMA_VERSION,Oe as APP_TOOL_ENTRY,A as AppError,B as CrewXApp,Z as SKILL_BACKEND_ENV_NAMES,le as Tool,ve as executeAppRequest,pe as generateManifest,G as generateToolDeclarations,j as getToolDeclarations,we as isSkillBackendEnv,$ as readAppContext,ze as runAppEntry,Je as runSkillApp};
@@ -0,0 +1,3 @@
1
+ import*as m from'path';import m__default,{join}from'path';import {fileURLToPath}from'url';import {createHash}from'crypto';import {readFileSync,unlinkSync,mkdirSync,writeFileSync,existsSync,statSync}from'fs';import {homedir}from'os';import {execFile,spawn}from'child_process';import {StringDecoder}from'string_decoder';import {createRequire}from'module';var $=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var q=()=>fileURLToPath(import.meta.url),Ge=()=>m__default.dirname(q()),P=Ge(),S=q();var p=class extends Error{code;constructor(t,n){super(`${t}: ${n}`),this.code=t,this.name="ShortcutError";}};var Q={existsSync:e=>existsSync(e),readFileSync:e=>readFileSync(e,"utf8"),readBinaryFileSync:e=>new Uint8Array(readFileSync(e)),writeFileSync:(e,t)=>writeFileSync(e,t,"utf8"),mkdirSync:e=>{mkdirSync(e,{recursive:true});},unlinkSync:e=>{unlinkSync(e);}},Z=homedir;function O(e){return typeof e!="string"?void 0:e.trim()||void 0}function T(e){return O(e)?.toLowerCase()??""}function k(e){try{return statSync(e).isFile()}catch{return false}}function Qe(e,t){if(e===t)return true;let n=m__default.relative(e,t);return n!==""&&!n.startsWith("..")&&!m__default.isAbsolute(n)}function Ze(e,t){if(m__default.basename(e)!==".bin")return false;let n=m__default.dirname(e);if(m__default.basename(n)!=="node_modules")return false;let r=m__default.dirname(n);return Qe(r,t)}function ee(e,t={}){if(e.includes("/")||e.includes("\\")||m__default.isAbsolute(e))return e;let n=t.platform??process.platform,r=t.env??process.env,o=m__default.resolve(t.cwd??process.cwd()),c=(t.resolution??"global_first")==="global_first",s=r.PATH??r.Path??process.env.PATH??process.env.Path??"",i=n==="win32"?";":":",a=s.split(i).map(u=>u.trim()).filter(Boolean),l=m__default.extname(e).length>0,d=r.PATHEXT??r.Pathext??process.env.PATHEXT??process.env.Pathext??".EXE;.CMD;.BAT;.COM",f=n==="win32"?l?[""]:d.split(";").map(u=>u.trim()).filter(Boolean).map(u=>u.startsWith(".")?u:`.${u}`):[""];for(let u of a){let E=m__default.resolve(o,u);if(!(c&&Ze(E,o)))for(let h of f){let y=T(h),g=h.toUpperCase();for(let w of [h,y,g]){let v=m__default.join(E,`${e}${w}`);if(k(v))return v}}}return e}function et(e){if(!k(e))return null;try{let t=readFileSync(e,"utf8"),n=m__default.dirname(e),r=[];for(let i of t.matchAll(/"([^"\r\n]*)"/g)){let d=(i[1]??"").match(/%~?dp0%?\s*[\\/]*(.*)$/i)?.[1]?.trim();if(!d)continue;let f=d.replace(/[\\/]+/g,m__default.sep).replace(/^[\\/]+/,""),u=m__default.resolve(n,f);k(u)&&r.push(u);}let o=[],c=new Map;for(let i of t.matchAll(/SET\s+"(\w+)=%~?dp0%?[\\/]?([^"]+)"/gi)){let a=i[1].toUpperCase(),l=i[2].trim().replace(/[\\/]+/g,m__default.sep).replace(/^[\\/]+/,"");c.set(a,m__default.resolve(n,l));}for(let i of t.split(/\r?\n/))if(i.includes("%*"))for(let a of i.matchAll(/"%(\w+)%"/g)){let l=c.get(a[1].toUpperCase());l&&k(l)&&o.push(l);}let s=i=>i.find(a=>{let l=T(m__default.basename(a));return l!=="node.exe"&&l!=="node"})??null;return s(o)??s(r)}catch{return null}}function tt(e,t){if(typeof t=="string")return O(t)||null;if(!t||typeof t!="object")return null;if(e){let n=t[e],r=typeof n=="string"?O(n):void 0;if(r)return r}for(let n of Object.values(t)){let r=typeof n=="string"?O(n):void 0;if(r)return r}return null}function nt(e,t){if(!t)return null;let n=m__default.dirname(e),r=[m__default.resolve(n,"..",t),m__default.resolve(n,"node_modules",t)];for(let o of r){let c=m__default.join(o,"package.json");if(k(c))try{let s=JSON.parse(readFileSync(c,"utf8")),i=tt(t,s.bin);if(!i)continue;let a=m__default.resolve(o,i);if(k(a))return a}catch{}}return null}function rt(e){let t=e.platform??process.platform,n=e.env??process.env,r=e.execPath??process.execPath,o=e.cwd,c=e.resolution;if(t!=="win32")return {command:ee(e.command,{cwd:o,env:n,platform:t,resolution:c}),leadingArgv:[],resolution:"direct"};let s=ee(e.command,{cwd:o,env:n,platform:t,resolution:c}),i=T(m__default.extname(s));if(i===".js"||i===".cjs"||i===".mjs")return {command:r,leadingArgv:[s],resolution:"node-entrypoint",windowsHide:true};if(i===".cmd"||i===".bat"){let a=et(s)??nt(s,e.packageName);return a?T(m__default.extname(a))===".exe"?{command:a,leadingArgv:[],resolution:"exe-entrypoint",windowsHide:true}:{command:r,leadingArgv:[a],resolution:"node-entrypoint",windowsHide:true}:{command:s,leadingArgv:[],resolution:"unresolved-wrapper"}}return {command:s,leadingArgv:[],resolution:"direct",windowsHide:true}}function ot(e){if(e.candidate.resolution!=="unresolved-wrapper")return {command:e.candidate.command,leadingArgv:e.candidate.leadingArgv,resolution:e.candidate.resolution,windowsHide:e.candidate.windowsHide};throw new Error(`${m__default.basename(e.candidate.command)} wrapper resolved, but no executable/Node entrypoint could be resolved without shell execution.`)}function ne(e){let t=rt(e);return ot({candidate:t})}function re(e,t){return {command:e.command,argv:[...e.leadingArgv,...t],resolution:e.resolution,shell:e.shell,windowsHide:e.windowsHide}}var A="\uFFFD",H=8,se=1e3,it=new Map([[437,"ibm437"],[720,"ibm720"],[737,"ibm737"],[775,"ibm775"],[850,"ibm850"],[852,"ibm852"],[855,"ibm855"],[857,"ibm857"],[858,"ibm858"],[862,"ibm862"],[864,"ibm864"],[932,"shift_jis"],[936,"gb18030"],[949,"euc-kr"],[950,"big5"],[866,"ibm866"],[869,"ibm869"],[1250,"windows-1250"],[1251,"windows-1251"],[1252,"windows-1252"],[1253,"windows-1253"],[1254,"windows-1254"],[1255,"windows-1255"],[1256,"windows-1256"],[1257,"windows-1257"],[1258,"windows-1258"]]),D;function V(e){let t=0;for(let n of e)n===A&&(t+=1);return t}function U(e,t){return V(t)<V(e)?t:e}function at(e){let t=e.match(/(?:^|[^0-9])([0-9]{1,5})(?![0-9])/);if(!t)return null;let n=Number(t[1]);return Number.isInteger(n)&&n>0&&n<=65535?n:null}function ct(e){if(e!==65001)return it.get(e)}function lt(e){let t=ct(e);if(!t)return null;try{return new TextDecoder(t)}catch{return null}}function ut(){return new Promise(e=>{let t=false,n,r=o=>{t||(t=true,n&&clearTimeout(n),e(o));};n=setTimeout(()=>r(null),se),n.unref();try{execFile("chcp.com",[],{encoding:"ascii",timeout:se,windowsHide:!0},(c,s)=>{if(c){r(null);return}r(at(String(s)));}).once("error",()=>r(null));}catch{r(null);}})}function ce(){return process.platform!=="win32"?Promise.resolve(null):(D||(D=ut(),D.then(e=>{},()=>{})),D)}function dt(){process.platform==="win32"&&ce();}function ae(e,t){if(t.length>=H)return t.subarray(t.length-H);let n=H-t.length,r=e.length>n?e.subarray(e.length-n):e;return Buffer.concat([r,t])}var _=class{platform;detectCodePage;utf8Decoder=new StringDecoder("utf8");codePage;fallbackDecoder;replayTail=Buffer.alloc(0);pendingUtf8="";pendingFallback="";pendingBytes=Buffer.alloc(0);queue=Promise.resolve();ended=false;constructor(t={}){this.platform=t.platform??process.platform,this.detectCodePage=t.detectCodePage??ce,this.codePage=t.codePage;}write(t){let n=Buffer.from(t);return this.enqueue(()=>this.decodeChunk(n))}end(){return this.enqueue(()=>this.finish())}enqueue(t){let n=this.queue.then(t);return this.queue=n.then(()=>{},()=>{}),n}clearPendingCandidate(){this.pendingUtf8="",this.pendingFallback="",this.pendingBytes=Buffer.alloc(0);}async resolveCodePage(){if(this.codePage!==void 0)return this.codePage;try{this.codePage=await this.detectCodePage();}catch{this.codePage=null;}return this.codePage}async getFallbackDecoder(){if(this.fallbackDecoder!==void 0)return this.fallbackDecoder;let t=await this.resolveCodePage();return this.fallbackDecoder=t===null?null:lt(t),this.fallbackDecoder}async decodeChunk(t){if(this.ended)return "";let n=this.utf8Decoder.write(t),r=n.includes(A);if(r&&(this.utf8Decoder=new StringDecoder("utf8")),this.platform!=="win32")return n;if(this.fallbackDecoder){let a=this.fallbackDecoder.decode(t,{stream:true}),l=ae(this.pendingBytes,t);if(r){let d=this.pendingUtf8+n,f=this.pendingFallback+a;return this.clearPendingCandidate(),U(d,f)}if(V(a)>0){let d=this.pendingUtf8+n;return this.clearPendingCandidate(),this.fallbackDecoder=void 0,this.replayTail=l,d}if(this.pendingUtf8||this.pendingFallback){if(this.pendingUtf8+=n,this.pendingFallback+=a,this.pendingBytes=l,n.length===0||a.length===0)return "";let d=this.pendingUtf8;return this.clearPendingCandidate(),d}return n.length===0&&a.length>0?(this.pendingUtf8=n,this.pendingFallback=a,this.pendingBytes=l,""):n}let o=this.replayTail;if(this.fallbackDecoder===void 0&&(this.replayTail=ae(this.replayTail,t)),!r)return n;let c=this.fallbackDecoder===void 0,s=await this.getFallbackDecoder();if(!s)return this.replayTail=Buffer.alloc(0),n;c&&o.length>0&&s.decode(o,{stream:true}),this.replayTail=Buffer.alloc(0);let i=s.decode(t,{stream:true});return U(n,i)}async finish(){if(this.ended)return "";this.ended=true;let t=this.utf8Decoder.end();if(this.platform!=="win32")return t;if(this.fallbackDecoder===void 0&&t.includes(A)){let c=await this.getFallbackDecoder();c&&this.replayTail.length>0&&(c.decode(this.replayTail,{stream:true}),this.replayTail=Buffer.alloc(0));}let n=this.pendingUtf8+t,r=this.fallbackDecoder?.decode()??"",o=this.pendingFallback+r;return this.clearPendingCandidate(),n.includes(A)?U(n,o):n}};dt();var le=3e3;var mt=2e3,pt=25,ht=100;function fe(e){return e instanceof Error?e:e===void 0?void 0:new Error(String(e))}function ue(e){return typeof e=="object"&&e!==null&&"code"in e?String(e.code):void 0}function gt(e){return Number.isSafeInteger(e)&&e>0}function wt(e,t){return new Promise(n=>{let r;try{r=spawn(e,t,{windowsHide:!0});}catch(l){n({status:null,stdout:"",stderr:"",error:fe(l)});return}let o="",c="",s=false,i,a=setTimeout(()=>{try{r.kill();}catch{}i({status:null,stdout:o,stderr:c,error:new Error(`Command timed out after ${le}ms`)});},le);i=l=>{s||(s=true,clearTimeout(a),n(l));},r.stdout?.setEncoding("utf8"),r.stderr?.setEncoding("utf8"),r.stdout?.on("data",l=>{o+=String(l);}),r.stderr?.on("data",l=>{c+=String(l);}),r.once("error",l=>{i({status:null,stdout:o,stderr:c,error:l});}),r.once("close",l=>{i({status:l,stdout:o,stderr:c});});})}async function Pt(e,t,n){return n.runCommandAsync?n.runCommandAsync(e,t):n.runCommand?n.runCommand(e,t):wt(e,t)}function St(e){return new Promise(t=>{setTimeout(t,Math.max(0,e));})}function Et(){return new Promise(e=>{setImmediate(e);})}function W(e,t=process.kill){try{return t(e,0),"alive"}catch(n){return ue(n)==="ESRCH"?"not_found":ue(n)==="EPERM"?"alive":"unknown"}}function Ct(e,t){let n=W(-e,t),r=W(e,t);return n==="alive"||r==="alive"?"alive":n==="unknown"||r==="unknown"?"unknown":"not_found"}async function me(e,t,n,r){let o=Math.max(0,n),c=Math.max(1,r.pollIntervalMs??pt),s=Date.now()+o,i,a=o===0,l=r.sleep?Promise.resolve().then(()=>r.sleep(o)).then(()=>{},()=>{}):new Promise(d=>{i=setTimeout(d,o);});l.then(()=>{a=true;});try{for(await Et();;){let d=Ct(e,t);if(d==="not_found")return d;let f=s-Date.now();if(a||f<=0)return d;await Promise.race([l,St(Math.min(c,f))]);}}finally{i!==void 0&&clearTimeout(i);}}async function de(e,t,n,r,o){let c=await me(e,t,o.hardConfirmMs??ht,{...o,sleep:void 0});return c==="not_found"?n?{status:"not_found",pid:e,method:r}:{status:"terminated",pid:e,method:r}:c==="alive"?{status:"failed",pid:e,method:r,error:"Process is still running after termination attempt"}:{status:"failed",pid:e,method:r,error:"Unable to verify process termination"}}async function pe(e,t={}){let n=t.platform??process.platform,r=n==="win32"?"taskkill":"process-group",o=u=>({status:"failed",pid:e,method:r,error:u});if(!gt(e))return o("Invalid process ID");let c=t.kill??process.kill,s=W(e,c);if(s==="not_found")return {status:"not_found",pid:e,method:r};if(s!=="alive")return o("Unable to determine whether the process is alive");if(n==="win32"){let u;try{u=await Pt("taskkill",["/PID",String(e),"/T","/F"],t);}catch(h){u={status:null,stdout:"",stderr:"",error:fe(h)};}let E=W(e,c);return E==="not_found"?u.status===0&&!u.error?{status:"terminated",pid:e,method:r}:{status:"not_found",pid:e,method:r}:o(E==="alive"?"Process is still running after termination attempt":"Unable to verify process termination")}let i,a=t.signal??"SIGKILL";try{c(-e,a);}catch(u){i=u;}if(a==="SIGKILL")return de(e,c,i,r,t);if(await me(e,c,t.graceMs??mt,t)==="not_found")return i?{status:"not_found",pid:e,method:r}:{status:"terminated",pid:e,method:r};let d;try{c(-e,"SIGKILL");}catch(u){d=u;}let f=await de(e,c,d,r,t);return f.status==="terminated"?f:f.status==="not_found"?i?f:{status:"terminated",pid:e,method:r}:o(f.error??"Process termination failed")}var yt=["CREWX_ASSIGNED_TASK_ID","CREWX_DETACHED_RUNNER"];function vt(e,t){let n={};for(let[r,o]of Object.entries(e))o!==void 0&&(t.includes(r)||(n[r]=o));return n}function he(e){return vt(e,yt)}var ge=3e4;function we(e){if(typeof e.pid!="number"){try{e.kill();}catch{}return}pe(e.pid,{signal:"SIGKILL"}).then(t=>{if(t.status==="failed")try{e.kill("SIGKILL");}catch{}},()=>{try{e.kill("SIGKILL");}catch{}});}var Pe=(e,t,n={})=>new Promise((r,o)=>{let c=he(n.env??process.env),s=process.platform,i;try{let w=ne({command:e,platform:s,env:c,cwd:n.cwd,allowShellFallback:!1});i=re(w,t);}catch(w){o(w instanceof Error?w:new Error(String(w)));return}let a=spawn(i.command,i.argv,{cwd:n.cwd,env:c,shell:i.shell,windowsHide:i.windowsHide??true,detached:s!=="win32"}),l="",d="",f=false,u=new _({platform:s}),E=new _({platform:s}),h=Promise.resolve(),y=Promise.resolve(),g=setTimeout(()=>{f||(f=true,we(a),o(new Error(`Command timed out after ${n.timeoutMs??ge}ms: ${e} ${t.join(" ")}`)));},n.timeoutMs??ge);a.stdout?.on("data",w=>{h=h.then(async()=>{l+=await u.write(w);});}),a.stderr?.on("data",w=>{y=y.then(async()=>{d+=await E.write(w);});}),a.on("error",w=>{f||(f=true,clearTimeout(g),o(w));}),a.on("close",w=>{f||(async()=>{await Promise.all([h,y]);let[v,Ue]=await Promise.all([u.end(),E.end()]);f||(l+=v,d+=Ue,f=true,clearTimeout(g),r({code:w??0,stdout:l,stderr:d}));})().catch(v=>{f||(f=true,clearTimeout(g),o(v instanceof Error?v:new Error(String(v))));});});});function _t(){try{return (typeof $=="function"?$:createRequire(S)).resolve("@crewx/sdk/package.json")}catch{return null}}function xt(){let e=[_t(),join(P,"../../package.json"),join(P,"../../../package.json")].filter(t=>!!t);for(let t of e)try{let n=JSON.parse(readFileSync(t,"utf8"));if(n.name==="@crewx/sdk"&&n.version)return n.version}catch{}return "0.0.0"}var Ee=xt();var C=m.win32;function X(e){return C.join(e,".crewx")}function ye(e){return C.join(X(e),"shortcut.json")}function ve(e){return C.join(X(e),"launcher.json")}function Re(e){return C.join(X(e),"bin","crewx-launcher.cmd")}function be(e){return C.join(e,"CrewX.lnk")}function G(e,t){return C.normalize(e).toLowerCase()===C.normalize(t).toLowerCase()}var It="[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; [Environment]::GetFolderPath('DesktopDirectory')";async function ke(e){try{let n=await e.run("powershell",["-NoProfile","-NonInteractive","-Command",It],{env:e.env}),r=n.stdout.trim();if(n.code===0&&r)return {dir:r,source:"known-folder"}}catch{}let t=e.env.USERPROFILE||e.env.Userprofile||e.homedir();return t?{dir:C.join(t,"Desktop"),source:"fallback"}:null}function J(e,t){let n=C.resolve(t,"node_modules",".bin").toLowerCase();return e.split(";").filter(r=>r?C.resolve(r).toLowerCase()!==n:true).join(";")}function _e(e){return e?/\\Program Files( \(x86\))?\\/i.test(e)&&/crewx/i.test(e):false}function Lt(e,t){let n=a=>{let[l,...d]=a.split("-"),f=d.join("-")||void 0;return {parts:(l??"").split(".").map(E=>Number.parseInt(E,10)||0),pre:f}},r=n(e),o=n(t),c=Math.max(r.parts.length,o.parts.length);for(let a=0;a<c;a++){let l=r.parts[a]??0,d=o.parts[a]??0;if(l!==d)return l<d?-1:1}if(r.pre===o.pre)return 0;if(!r.pre&&o.pre)return 1;if(r.pre&&!o.pre)return -1;let s=Number.parseInt(r.pre.match(/(\d+)$/)?.[1]??"",10),i=Number.parseInt(o.pre.match(/(\d+)$/)?.[1]??"",10);return !Number.isNaN(s)&&!Number.isNaN(i)&&s!==i?s<i?-1:1:r.pre<o.pre?-1:r.pre>o.pre?1:0}function x(e,t){return Lt(e,t)<0}var Ie=m.win32,Le=1;function Ne(e,t){if(!e.existsSync(t))return null;try{let n=JSON.parse(e.readFileSync(t));return {schema:n.schema??Le,shortcutPath:n.shortcutPath,version:n.version,iconHash:typeof n.iconHash=="string"?n.iconHash:void 0,owned:!!n.owned,declined:!!n.declined,desktopSource:n.desktopSource,updatedAt:n.updatedAt}}catch{return null}}function M(e,t,n){let r={schema:Le,...n,updatedAt:new Date().toISOString()};e.mkdirSync(Ie.dirname(t)),e.writeFileSync(t,JSON.stringify(r,null,2));}function F(e,t){if(!e.existsSync(t))return null;try{let n=JSON.parse(e.readFileSync(t));return {schema:n.schema??0,binPath:n.binPath,updatedAt:n.updatedAt}}catch{return null}}function Oe(e,t,n){e.mkdirSync(Ie.dirname(t)),e.writeFileSync(t,JSON.stringify(n,null,2));}var Nt=m.win32,I=1;function Ot(e){return e.replace(/%/g,"%%")}function Tt(e){return ["@echo off","setlocal DisableDelayedExpansion","chcp 65001 >nul","",'set "CREWX_WORKDIR=%USERPROFILE%\\crewx"','if not exist "%CREWX_WORKDIR%" mkdir "%CREWX_WORKDIR%" >nul 2>nul','cd /d "%CREWX_WORKDIR%"',"",'set "CREWX_PORT_EFFECTIVE=%CREWX_PORT%"','if "%CREWX_PORT_EFFECTIVE%"=="" set "CREWX_PORT_EFFECTIVE=8150"','set "CREWX_HEALTH_URL=http://127.0.0.1:%CREWX_PORT_EFFECTIVE%/api/v1/health"','set "CREWX_ORIGIN_URL=http://127.0.0.1:%CREWX_PORT_EFFECTIVE%/"',"",e.bakedBinPath?`set "CREWX_FALLBACK_BIN=${Ot(e.bakedBinPath)}"`:'set "CREWX_FALLBACK_BIN="','set "CREWX_RESOLVED_BIN=%CREWX_BIN%"','if "%CREWX_RESOLVED_BIN%"=="" set "CREWX_RESOLVED_BIN=%CREWX_FALLBACK_BIN%"','if "%CREWX_RESOLVED_BIN%"=="" (',` for /f "delims=" %%I in ('where crewx 2^>nul') do (`,' if not defined CREWX_RESOLVED_BIN set "CREWX_RESOLVED_BIN=%%I"'," )",")","",'powershell -NoProfile -NonInteractive -Command "try { $r = Invoke-WebRequest -Uri $env:CREWX_HEALTH_URL -TimeoutSec 1 -UseBasicParsing; if ($r.StatusCode -eq 200) { exit 0 } else { exit 1 } } catch { exit 1 }"',"if %ERRORLEVEL% EQU 0 (",' start "" "%CREWX_ORIGIN_URL%"'," exit /b 0",")","",'if "%CREWX_RESOLVED_BIN%"=="" ('," echo CrewX executable not found. Please reinstall the desktop shortcut."," pause"," exit /b 1",")","",'start "CrewX" /min "%CREWX_RESOLVED_BIN%"',""].join(`\r
2
+ `)}function De(e){let t=F(e.fs,e.launcherManifestPath),n=!!t&&t.schema>=I&&e.fs.existsSync(e.wrapperPath),r=n&&!t.binPath&&!!e.bakedBinPath;if(n&&!r)return {wrapperPath:e.wrapperPath,wrote:false,schema:t.schema};let c=Tt({bakedBinPath:e.bakedBinPath});try{e.fs.mkdirSync(Nt.dirname(e.wrapperPath)),e.fs.writeFileSync(e.wrapperPath,c),Oe(e.fs,e.launcherManifestPath,{schema:I,binPath:e.bakedBinPath,updatedAt:new Date().toISOString()});}catch(s){throw s instanceof p?s:new p("WRITE_DENIED",`Could not write launcher wrapper: ${s instanceof Error?s.message:String(s)}`)}return {wrapperPath:e.wrapperPath,wrote:true,schema:I}}var Dt=["$ws = New-Object -ComObject WScript.Shell","$sc = $ws.CreateShortcut($env:CREWX_LNK_PATH)","$sc.TargetPath = $env:CREWX_LNK_TARGET","if ($env:CREWX_LNK_WORKDIR) { $sc.WorkingDirectory = $env:CREWX_LNK_WORKDIR }","$sc.WindowStyle = 7","if ($env:CREWX_LNK_ICON) { $sc.IconLocation = $env:CREWX_LNK_ICON }","$sc.Save()"].join("; "),At=["[Console]::OutputEncoding = [System.Text.Encoding]::UTF8","$ws = New-Object -ComObject WScript.Shell","$sc = $ws.CreateShortcut($env:CREWX_LNK_PATH)","[PSCustomObject]@{ TargetPath = $sc.TargetPath; WorkingDirectory = $sc.WorkingDirectory; IconLocation = $sc.IconLocation } | ConvertTo-Json -Compress"].join("; ");async function Ae(e){let t={...e.env,CREWX_LNK_PATH:e.shortcutPath,CREWX_LNK_TARGET:e.targetPath,CREWX_LNK_WORKDIR:e.workingDirectory??"",CREWX_LNK_ICON:e.iconPath??""},n;try{n=await e.run("powershell",["-NoProfile","-NonInteractive","-Command",Dt],{env:t});}catch(r){throw new p("POWERSHELL_UNAVAILABLE",`Could not run PowerShell: ${r instanceof Error?r.message:String(r)}`)}if(n.code!==0)throw new p("POWERSHELL_UNAVAILABLE",`Failed to create desktop shortcut: ${n.stderr||n.stdout}`)}function We(e){let t=e.trim(),n=t.lastIndexOf(",");return n!==-1&&/^-?\d+$/.test(t.slice(n+1).trim())&&(t=t.slice(0,n).trim()),t.length>=2&&t.startsWith('"')&&t.endsWith('"')&&(t=t.slice(1,-1).trim()),t}async function Me(e){try{let t={...e.env,CREWX_LNK_PATH:e.shortcutPath},n=await e.run("powershell",["-NoProfile","-NonInteractive","-Command",At],{env:t});if(n.code!==0||!n.stdout.trim())return null;let r=JSON.parse(n.stdout.trim());return {targetPath:r.TargetPath??"",workingDirectory:r.WorkingDirectory??"",iconLocation:r.IconLocation??""}}catch{return null}}var j=m.win32;async function L(e){let t=J(e.env.PATH??e.env.Path??"",e.cwd),n={...e.env,PATH:t,Path:t},r;try{r=await e.run("npm",["list","-g","crewx","--depth=0","--json"],{env:n});}catch{return {installed:false}}let o;try{o=JSON.parse(r.stdout||"{}");}catch{return {installed:false}}let c=o.dependencies?.crewx;if(!c?.version)return {installed:false};let s;try{let a=await e.run("npm",["prefix","-g"],{env:n});a.code===0&&(s=a.stdout.trim()||void 0);}catch{}let i=s?j.join(s,"crewx.cmd"):void 0;return {installed:true,version:c.version,binPath:i,prefix:s}}var Wt=/EACCES|EPERM|EROFS/,Mt=/ENOTFOUND|ETIMEDOUT|ECONNREFUSED|network|registry/i,Ft=/^\d+\.\d+\.\d+/;function Bt(e){return !!e&&e!=="0.0.0"&&Ft.test(e)}var K=10*6e4;async function Be(e){if(!Bt(e.targetVersion))throw new p("GLOBAL_INSTALL_FAILED",`RUNNING_VERSION_UNKNOWN: cannot reliably determine the running crewx version to install (got ${JSON.stringify(e.targetVersion)}); refusing to fall back to crewx@latest`);if(e.currentInfo?.installed&&e.currentInfo.version&&!x(e.currentInfo.version,e.targetVersion))return {info:e.currentInfo};let t=J(e.env.PATH??e.env.Path??"",e.cwd),n={...e.env,PATH:t,Path:t},r=`crewx@${e.targetVersion}`;e.onProgress?.({phase:"global-install",message:`Installing crewx globally (npm install -g ${r})`});let o;try{o=await e.run("npm",["install","-g",r,"--no-audit","--no-fund"],{env:n,timeoutMs:K});}catch(s){throw new p("NPM_UNAVAILABLE",`Could not run npm: ${s instanceof Error?s.message:String(s)}`)}if(o.code===0)return {info:await L({env:n,cwd:e.cwd,run:e.run})};let c=`${o.stdout}
3
+ ${o.stderr}`;if(Wt.test(c)){e.onProgress?.({phase:"global-install",message:"Permission denied \u2014 retrying with a user-scoped npm prefix"});let s=e.env.LOCALAPPDATA||j.join(e.env.USERPROFILE??"","AppData","Local"),i={...n,npm_config_prefix:j.join(s,"crewx","npm")},a;try{a=await e.run("npm",["install","-g",r,"--no-audit","--no-fund"],{env:i,timeoutMs:K});}catch(l){throw new p("NPM_PERMISSION_DENIED",`Retry with user-scoped prefix failed: ${l instanceof Error?l.message:String(l)}`)}if(a.code===0)return {info:await L({env:i,cwd:e.cwd,run:e.run})};throw new p("NPM_PERMISSION_DENIED",`npm install -g failed after user-scoped prefix retry: ${a.stderr||a.stdout}`)}if(Mt.test(c)){if(!e.installRoot)throw new p("OFFLINE_NO_SOURCE","The npm registry is unreachable and no local installRoot was provided for an offline install");e.onProgress?.({phase:"global-install",message:`Registry unreachable \u2014 installing offline from ${e.installRoot}`});let s;try{s=await e.run("npm",["install","-g",e.installRoot,"--offline","--no-audit","--no-fund"],{env:n,timeoutMs:K});}catch(i){throw new p("GLOBAL_INSTALL_FAILED",`Offline install failed: ${i instanceof Error?i.message:String(i)}`)}if(s.code===0)return {info:await L({env:n,cwd:e.cwd,run:e.run})};throw new p("GLOBAL_INSTALL_FAILED",`Offline install failed: ${s.stderr||s.stdout}`)}throw new p("GLOBAL_INSTALL_FAILED",c.trim()||`npm install -g ${r} failed`)}function Ht(e){return e.run??Pe}function Ut(e){return e.fs??Q}async function B(e){let t=e.platform??process.platform,n=e.env??process.env,r=e.homedir??Z,o=Ht(e),c=Ut(e),s=e.runningVersion??Ee,i=e.cwd??process.cwd(),a=r(),l=ye(a),d=ve(a),f=Re(a),u=null;t==="win32"&&(u=await ke({env:n,homedir:r,run:o}));let E=u?be(u.dir):null;return {platform:t,env:n,homedir:r,run:o,fs:c,runningVersion:s,cwd:i,installRoot:e.installRoot,shortcutManifestPath:l,launcherManifestPath:d,wrapperPath:f,desktop:u,shortcutPath:E}}function $e(e){return e?m.win32.normalize(e).toLowerCase().endsWith(`${m.win32.sep}bin${m.win32.sep}crewx.ico`):false}function z(e,t){let n=e.readBinaryFileSync;if(n)try{return createHash("sha256").update(n(t)).digest("hex")}catch{return}}async function Vt(e){try{await e.run("ie4uinit.exe",["-show"],{env:e.env});}catch{}}async function R(e){if(e.platform!=="win32")return {supported:false,state:"unsupported",globalCrewx:null,runningVersion:e.runningVersion,errors:[],manifest:null,iconStale:false};let t=[];e.desktop||t.push("NO_DESKTOP_DIR: could not resolve the Windows Desktop directory");let n=Ne(e.fs,e.shortcutManifestPath),r=F(e.fs,e.launcherManifestPath),o=await L({env:e.env,cwd:e.cwd,run:e.run}),c=e.shortcutPath?e.fs.existsSync(e.shortcutPath):false,s,i=false,a,l;if(!c)s=n?.declined?"declined":"not-installed";else {let d=!!n?.owned&&!!e.shortcutPath&&n.shortcutPath===e.shortcutPath,f=false,u=e.shortcutPath?await Me({run:e.run,env:e.env,shortcutPath:e.shortcutPath}):null;if(d||(u&&G(u.targetPath,e.wrapperPath)?d=true:u&&_e(u.targetPath)&&(f=true)),f)s="foreign",t.push("NSIS_PRESENT: an NSIS-installed CrewX shortcut was detected");else if(!d)s="foreign";else if(n?.version&&x(e.runningVersion,n.version))s="superseded",t.push(`SUPERSEDED: running version ${e.runningVersion} is older than the installed shortcut's version ${n.version}; refusing to modify it`);else {let E=!r||r.schema<I||!e.fs.existsSync(e.wrapperPath);if(u){let h=We(u.iconLocation);if(!(!!h&&e.fs.existsSync(h)))i=true;else {a=h;let g=He(o,e.fs);g?G(h,g)?(l=z(e.fs,h),i=!l||n?.iconHash!==l):i=true:$e(h)?(l=z(e.fs,h),i=!l||n?.iconHash!==l):i=true;}}s=E||i?"stale":"installed";}}return {supported:true,state:s,shortcutPath:e.shortcutPath??void 0,desktopDir:e.desktop?.dir,desktopSource:e.desktop?.source,wrapperPath:e.wrapperPath,wrapperSchema:r?.schema,globalCrewx:o.installed?o:{installed:false},runningVersion:e.runningVersion,errors:t,manifest:n,iconStale:i,iconPath:a,iconHash:l}}function He(e,t){if(!e?.installed||!e.prefix)return;let n=m.win32.join(e.prefix,"node_modules","crewx","bin","crewx.ico");return t.existsSync(n)?n:void 0}function b(e){let{manifest:t,iconStale:n,iconPath:r,iconHash:o,...c}=e;return c}async function Xt(e={}){let t=await B(e),n=await R(t);return b(n)}async function Gt(e={}){let t=await B(e);e.onProgress?.({phase:"detect",message:"Checking current shortcut status"});let n=await R(t),r=b(n);if(!r.supported)return {...r,changed:false,installedGlobal:false};if(r.state==="superseded")return {...r,changed:false,installedGlobal:false};if(r.state==="foreign"){if(n.errors.some(g=>g.startsWith("NSIS_PRESENT")))throw new p("NSIS_PRESENT",`An NSIS-installed CrewX shortcut was detected at ${r.shortcutPath}`);if(!e.force)throw new p("FOREIGN_SHORTCUT",`An existing shortcut at ${r.shortcutPath} is not managed by CrewX`)}if(!t.desktop||!t.shortcutPath)throw new p("NO_DESKTOP_DIR","Could not resolve the Windows Desktop directory");let o=false,c=false,s=r.globalCrewx,i=[],a=n.manifest?.iconHash,l=false;if(!!s?.installed&&!!s.version&&x(s.version,t.runningVersion)||!s?.installed&&r.state!=="installed"){let g=await Be({env:t.env,cwd:t.cwd,run:t.run,targetVersion:t.runningVersion,currentInfo:s??void 0,installRoot:t.installRoot,onProgress:e.onProgress});s=g.info,c=g.info.installed,o=true,c||i.push(`GLOBAL_INSTALL_UNCONFIRMED: npm install -g crewx@${t.runningVersion} exited successfully but a follow-up check could not confirm the global install`);}if(e.onProgress?.({phase:"wrapper",message:"Ensuring launcher wrapper"}),De({fs:t.fs,wrapperPath:t.wrapperPath,launcherManifestPath:t.launcherManifestPath,bakedBinPath:s?.binPath}).wrote&&(o=true),!((r.state==="installed"||r.state==="stale")&&!n.iconStale)){let g=He(s,t.fs)??(n.iconPath&&$e(n.iconPath)&&t.fs.existsSync(n.iconPath)?n.iconPath:void 0);if(n.iconStale&&!g)throw new p("ICON_UNAVAILABLE",`Could not locate the global CrewX icon (bin\\crewx.ico) to repair the desktop shortcut at ${t.shortcutPath}; the existing shortcut was left untouched`);e.onProgress?.({phase:"lnk",message:"Creating desktop shortcut"}),await Ae({run:t.run,env:t.env,shortcutPath:t.shortcutPath,targetPath:t.wrapperPath,iconPath:g}),o=true,l=n.iconStale;let w=g?z(t.fs,g):void 0;w&&(a=w);}o&&M(t.fs,t.shortcutManifestPath,{shortcutPath:t.shortcutPath,version:t.runningVersion,owned:true,declined:false,desktopSource:t.desktop.source,iconHash:a}),l&&await Vt(t);let h=await R(t),y=b(h);return {...y,errors:[...y.errors,...i],changed:o,installedGlobal:c}}async function Jt(e={}){let t=await B(e),n=await R(t),r=b(n);if(!r.supported)return r;if((r.state==="installed"||r.state==="stale")&&t.shortcutPath)try{t.fs.unlinkSync(t.shortcutPath);}catch{}M(t.fs,t.shortcutManifestPath,{shortcutPath:void 0,version:n.manifest?.version,owned:false,declined:true,desktopSource:void 0,iconHash:void 0});let o=await R(t);return b(o)}async function Kt(e={}){let t=await B(e),n=await R(t),r=b(n);if(!r.supported)return r;M(t.fs,t.shortcutManifestPath,{shortcutPath:n.manifest?.shortcutPath,version:n.manifest?.version,owned:n.manifest?.owned??false,declined:true,desktopSource:n.manifest?.desktopSource,iconHash:n.manifest?.iconHash});let o=await R(t);return b(o)}export{p as ShortcutError,Kt as dismissShortcutNotice,Xt as getShortcutStatus,Gt as installShortcut,we as killProcessTree,Jt as uninstallShortcut};