runwork 0.15.1 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (404) hide show
  1. package/bundled-types/task-delegation/task-delegation/types.d.ts +6 -0
  2. package/dist/index.js +20237 -116
  3. package/package.json +4 -4
  4. package/dist/__tests__/curl-parser.test.d.ts +0 -1
  5. package/dist/__tests__/curl-parser.test.js +0 -250
  6. package/dist/__tests__/install-scripts.test.d.ts +0 -1
  7. package/dist/__tests__/install-scripts.test.js +0 -280
  8. package/dist/__tests__/types-manager.test.d.ts +0 -1
  9. package/dist/__tests__/types-manager.test.js +0 -89
  10. package/dist/agents/__tests__/chatgpt-registry.test.d.ts +0 -1
  11. package/dist/agents/__tests__/chatgpt-registry.test.js +0 -61
  12. package/dist/agents/__tests__/claude-code-managed-block.test.d.ts +0 -1
  13. package/dist/agents/__tests__/claude-code-managed-block.test.js +0 -105
  14. package/dist/agents/__tests__/claude-code-plugin.test.d.ts +0 -1
  15. package/dist/agents/__tests__/claude-code-plugin.test.js +0 -47
  16. package/dist/agents/__tests__/claude-code-stats.test.d.ts +0 -1
  17. package/dist/agents/__tests__/claude-code-stats.test.js +0 -390
  18. package/dist/agents/__tests__/claude-desktop-memory.test.d.ts +0 -1
  19. package/dist/agents/__tests__/claude-desktop-memory.test.js +0 -154
  20. package/dist/agents/__tests__/claude-desktop-plugin-tree.test.d.ts +0 -1
  21. package/dist/agents/__tests__/claude-desktop-plugin-tree.test.js +0 -161
  22. package/dist/agents/__tests__/claude-desktop-plugin.test.d.ts +0 -1
  23. package/dist/agents/__tests__/claude-desktop-plugin.test.js +0 -117
  24. package/dist/agents/__tests__/claude-desktop-rpm.test.d.ts +0 -1
  25. package/dist/agents/__tests__/claude-desktop-rpm.test.js +0 -126
  26. package/dist/agents/__tests__/claude-desktop-stats.test.d.ts +0 -1
  27. package/dist/agents/__tests__/claude-desktop-stats.test.js +0 -280
  28. package/dist/agents/__tests__/codex-instructions.test.d.ts +0 -1
  29. package/dist/agents/__tests__/codex-instructions.test.js +0 -57
  30. package/dist/agents/__tests__/codex-minimum-permissions.test.d.ts +0 -1
  31. package/dist/agents/__tests__/codex-minimum-permissions.test.js +0 -82
  32. package/dist/agents/__tests__/codex-stats.test.d.ts +0 -1
  33. package/dist/agents/__tests__/codex-stats.test.js +0 -370
  34. package/dist/agents/__tests__/cursor-merge.test.d.ts +0 -1
  35. package/dist/agents/__tests__/cursor-merge.test.js +0 -66
  36. package/dist/agents/__tests__/cursor-stats.test.d.ts +0 -1
  37. package/dist/agents/__tests__/cursor-stats.test.js +0 -183
  38. package/dist/agents/__tests__/defaults-merge.test.d.ts +0 -1
  39. package/dist/agents/__tests__/defaults-merge.test.js +0 -268
  40. package/dist/agents/__tests__/detection.test.d.ts +0 -1
  41. package/dist/agents/__tests__/detection.test.js +0 -89
  42. package/dist/agents/__tests__/graceful-degradation.test.d.ts +0 -1
  43. package/dist/agents/__tests__/graceful-degradation.test.js +0 -129
  44. package/dist/agents/__tests__/instruction-hint.test.d.ts +0 -1
  45. package/dist/agents/__tests__/instruction-hint.test.js +0 -69
  46. package/dist/agents/__tests__/intro-skill.test.d.ts +0 -1
  47. package/dist/agents/__tests__/intro-skill.test.js +0 -193
  48. package/dist/agents/__tests__/schema-validation.test.d.ts +0 -1
  49. package/dist/agents/__tests__/schema-validation.test.js +0 -212
  50. package/dist/agents/__tests__/skill-slug.test.d.ts +0 -1
  51. package/dist/agents/__tests__/skill-slug.test.js +0 -77
  52. package/dist/agents/claude-code.d.ts +0 -59
  53. package/dist/agents/claude-code.js +0 -753
  54. package/dist/agents/claude-desktop-plugin-tree.d.ts +0 -59
  55. package/dist/agents/claude-desktop-plugin-tree.js +0 -143
  56. package/dist/agents/claude-desktop.d.ts +0 -47
  57. package/dist/agents/claude-desktop.js +0 -684
  58. package/dist/agents/cline.d.ts +0 -15
  59. package/dist/agents/cline.js +0 -130
  60. package/dist/agents/codex.d.ts +0 -44
  61. package/dist/agents/codex.js +0 -453
  62. package/dist/agents/conversation-skills.d.ts +0 -18
  63. package/dist/agents/conversation-skills.js +0 -229
  64. package/dist/agents/cursor.d.ts +0 -35
  65. package/dist/agents/cursor.js +0 -294
  66. package/dist/agents/default-config.d.ts +0 -30
  67. package/dist/agents/default-config.js +0 -67
  68. package/dist/agents/defaults-merge.d.ts +0 -87
  69. package/dist/agents/defaults-merge.js +0 -150
  70. package/dist/agents/detect.d.ts +0 -4
  71. package/dist/agents/detect.js +0 -67
  72. package/dist/agents/detection.d.ts +0 -18
  73. package/dist/agents/detection.js +0 -94
  74. package/dist/agents/gemini.d.ts +0 -15
  75. package/dist/agents/gemini.js +0 -122
  76. package/dist/agents/generic-adapter.d.ts +0 -25
  77. package/dist/agents/generic-adapter.js +0 -151
  78. package/dist/agents/intro-skill.d.ts +0 -45
  79. package/dist/agents/intro-skill.js +0 -447
  80. package/dist/agents/registry-data.d.ts +0 -192
  81. package/dist/agents/registry-data.js +0 -669
  82. package/dist/agents/registry.d.ts +0 -13
  83. package/dist/agents/registry.js +0 -36
  84. package/dist/agents/runtime-detection.d.ts +0 -82
  85. package/dist/agents/runtime-detection.js +0 -271
  86. package/dist/agents/session-start-hook.d.ts +0 -37
  87. package/dist/agents/session-start-hook.js +0 -159
  88. package/dist/agents/types.d.ts +0 -171
  89. package/dist/agents/types.js +0 -75
  90. package/dist/agents/utils/instruction-hint.d.ts +0 -21
  91. package/dist/agents/utils/instruction-hint.js +0 -108
  92. package/dist/agents/utils/json-config.d.ts +0 -19
  93. package/dist/agents/utils/json-config.js +0 -69
  94. package/dist/agents/utils/toml-config.d.ts +0 -8
  95. package/dist/agents/utils/toml-config.js +0 -27
  96. package/dist/agents/windsurf.d.ts +0 -14
  97. package/dist/agents/windsurf.js +0 -102
  98. package/dist/api/__tests__/client.test.d.ts +0 -1
  99. package/dist/api/__tests__/client.test.js +0 -272
  100. package/dist/api/client.d.ts +0 -326
  101. package/dist/api/client.js +0 -427
  102. package/dist/auth/__tests__/login-flow.test.d.ts +0 -1
  103. package/dist/auth/__tests__/login-flow.test.js +0 -101
  104. package/dist/auth/__tests__/store.test.d.ts +0 -1
  105. package/dist/auth/__tests__/store.test.js +0 -132
  106. package/dist/auth/login-flow.d.ts +0 -26
  107. package/dist/auth/login-flow.js +0 -137
  108. package/dist/auth/store.d.ts +0 -5
  109. package/dist/auth/store.js +0 -62
  110. package/dist/commands/__tests__/clone-args.test.d.ts +0 -1
  111. package/dist/commands/__tests__/clone-args.test.js +0 -51
  112. package/dist/commands/__tests__/clone-source-result.test.d.ts +0 -1
  113. package/dist/commands/__tests__/clone-source-result.test.js +0 -45
  114. package/dist/commands/__tests__/info-merge.test.d.ts +0 -1
  115. package/dist/commands/__tests__/info-merge.test.js +0 -55
  116. package/dist/commands/__tests__/mcp-entries.test.d.ts +0 -1
  117. package/dist/commands/__tests__/mcp-entries.test.js +0 -48
  118. package/dist/commands/__tests__/setup-persona.test.d.ts +0 -1
  119. package/dist/commands/__tests__/setup-persona.test.js +0 -31
  120. package/dist/commands/__tests__/setup.test.d.ts +0 -1
  121. package/dist/commands/__tests__/setup.test.js +0 -81
  122. package/dist/commands/__tests__/sync-redetect.test.d.ts +0 -1
  123. package/dist/commands/__tests__/sync-redetect.test.js +0 -96
  124. package/dist/commands/__tests__/sync-telemetry.test.d.ts +0 -1
  125. package/dist/commands/__tests__/sync-telemetry.test.js +0 -281
  126. package/dist/commands/__tests__/upgrade.test.d.ts +0 -1
  127. package/dist/commands/__tests__/upgrade.test.js +0 -157
  128. package/dist/commands/agents.d.ts +0 -2
  129. package/dist/commands/agents.js +0 -160
  130. package/dist/commands/api-keys.d.ts +0 -2
  131. package/dist/commands/api-keys.js +0 -95
  132. package/dist/commands/apps.d.ts +0 -2
  133. package/dist/commands/apps.js +0 -82
  134. package/dist/commands/build-plugin.d.ts +0 -2
  135. package/dist/commands/build-plugin.js +0 -135
  136. package/dist/commands/clone.d.ts +0 -60
  137. package/dist/commands/clone.js +0 -271
  138. package/dist/commands/components.d.ts +0 -2
  139. package/dist/commands/components.js +0 -43
  140. package/dist/commands/deploy.d.ts +0 -2
  141. package/dist/commands/deploy.js +0 -279
  142. package/dist/commands/dev.d.ts +0 -11
  143. package/dist/commands/dev.js +0 -1011
  144. package/dist/commands/doctor.d.ts +0 -2
  145. package/dist/commands/doctor.js +0 -230
  146. package/dist/commands/endpoints.d.ts +0 -2
  147. package/dist/commands/endpoints.js +0 -189
  148. package/dist/commands/entities.d.ts +0 -2
  149. package/dist/commands/entities.js +0 -198
  150. package/dist/commands/files.d.ts +0 -2
  151. package/dist/commands/files.js +0 -193
  152. package/dist/commands/inbox.d.ts +0 -11
  153. package/dist/commands/inbox.js +0 -60
  154. package/dist/commands/info.d.ts +0 -178
  155. package/dist/commands/info.js +0 -455
  156. package/dist/commands/init.d.ts +0 -21
  157. package/dist/commands/init.js +0 -185
  158. package/dist/commands/integrations.d.ts +0 -2
  159. package/dist/commands/integrations.js +0 -233
  160. package/dist/commands/login.d.ts +0 -2
  161. package/dist/commands/login.js +0 -44
  162. package/dist/commands/logout.d.ts +0 -2
  163. package/dist/commands/logout.js +0 -13
  164. package/dist/commands/logs.d.ts +0 -2
  165. package/dist/commands/logs.js +0 -232
  166. package/dist/commands/mcp-entries.d.ts +0 -13
  167. package/dist/commands/mcp-entries.js +0 -26
  168. package/dist/commands/mcp.d.ts +0 -2
  169. package/dist/commands/mcp.js +0 -245
  170. package/dist/commands/open.d.ts +0 -2
  171. package/dist/commands/open.js +0 -53
  172. package/dist/commands/resume.d.ts +0 -2
  173. package/dist/commands/resume.js +0 -289
  174. package/dist/commands/save-convo.d.ts +0 -8
  175. package/dist/commands/save-convo.js +0 -20
  176. package/dist/commands/schedules.d.ts +0 -2
  177. package/dist/commands/schedules.js +0 -221
  178. package/dist/commands/setup.d.ts +0 -27
  179. package/dist/commands/setup.js +0 -177
  180. package/dist/commands/share-convo.d.ts +0 -24
  181. package/dist/commands/share-convo.js +0 -167
  182. package/dist/commands/skills.d.ts +0 -2
  183. package/dist/commands/skills.js +0 -352
  184. package/dist/commands/sync-telemetry.d.ts +0 -33
  185. package/dist/commands/sync-telemetry.js +0 -186
  186. package/dist/commands/sync.d.ts +0 -37
  187. package/dist/commands/sync.js +0 -702
  188. package/dist/commands/uninstall.d.ts +0 -2
  189. package/dist/commands/uninstall.js +0 -145
  190. package/dist/commands/upgrade.d.ts +0 -14
  191. package/dist/commands/upgrade.js +0 -217
  192. package/dist/commands/validate.d.ts +0 -2
  193. package/dist/commands/validate.js +0 -89
  194. package/dist/commands/welcome.d.ts +0 -1
  195. package/dist/commands/welcome.js +0 -86
  196. package/dist/commands/workflows.d.ts +0 -2
  197. package/dist/commands/workflows.js +0 -187
  198. package/dist/deploy/__tests__/deploy-state.test.d.ts +0 -1
  199. package/dist/deploy/__tests__/deploy-state.test.js +0 -80
  200. package/dist/deploy/__tests__/deploy-status.test.d.ts +0 -1
  201. package/dist/deploy/__tests__/deploy-status.test.js +0 -41
  202. package/dist/deploy/__tests__/detach-args.test.d.ts +0 -1
  203. package/dist/deploy/__tests__/detach-args.test.js +0 -30
  204. package/dist/deploy/deploy-state.d.ts +0 -36
  205. package/dist/deploy/deploy-state.js +0 -63
  206. package/dist/deploy/deploy-status.d.ts +0 -21
  207. package/dist/deploy/deploy-status.js +0 -36
  208. package/dist/deploy/detach.d.ts +0 -32
  209. package/dist/deploy/detach.js +0 -71
  210. package/dist/dev/__tests__/attach.test.d.ts +0 -1
  211. package/dist/dev/__tests__/attach.test.js +0 -296
  212. package/dist/dev/__tests__/detach.test.d.ts +0 -1
  213. package/dist/dev/__tests__/detach.test.js +0 -404
  214. package/dist/dev/__tests__/preview-url-poller.test.d.ts +0 -1
  215. package/dist/dev/__tests__/preview-url-poller.test.js +0 -149
  216. package/dist/dev/__tests__/session.test.d.ts +0 -1
  217. package/dist/dev/__tests__/session.test.js +0 -446
  218. package/dist/dev/__tests__/startup-sync.test.d.ts +0 -1
  219. package/dist/dev/__tests__/startup-sync.test.js +0 -32
  220. package/dist/dev/__tests__/stop.test.d.ts +0 -1
  221. package/dist/dev/__tests__/stop.test.js +0 -172
  222. package/dist/dev/attach.d.ts +0 -120
  223. package/dist/dev/attach.js +0 -269
  224. package/dist/dev/detach.d.ts +0 -187
  225. package/dist/dev/detach.js +0 -292
  226. package/dist/dev/preview-url-poller.d.ts +0 -35
  227. package/dist/dev/preview-url-poller.js +0 -50
  228. package/dist/dev/session.d.ts +0 -175
  229. package/dist/dev/session.js +0 -258
  230. package/dist/dev/startup-sync.d.ts +0 -23
  231. package/dist/dev/startup-sync.js +0 -14
  232. package/dist/dev/stop.d.ts +0 -52
  233. package/dist/dev/stop.js +0 -101
  234. package/dist/devtools/registry-data.d.ts +0 -46
  235. package/dist/devtools/registry-data.js +0 -40
  236. package/dist/generated/bundled-types.d.ts +0 -1
  237. package/dist/generated/bundled-types.js +0 -46
  238. package/dist/generated/version.d.ts +0 -1
  239. package/dist/generated/version.js +0 -2
  240. package/dist/git/__tests__/auto-commit.test.d.ts +0 -1
  241. package/dist/git/__tests__/auto-commit.test.js +0 -431
  242. package/dist/git/__tests__/classify-sync-error.test.d.ts +0 -1
  243. package/dist/git/__tests__/classify-sync-error.test.js +0 -57
  244. package/dist/git/__tests__/credential-helper-e2e.test.d.ts +0 -21
  245. package/dist/git/__tests__/credential-helper-e2e.test.js +0 -195
  246. package/dist/git/__tests__/credentials.test.d.ts +0 -1
  247. package/dist/git/__tests__/credentials.test.js +0 -141
  248. package/dist/git/__tests__/deploy-guard.test.d.ts +0 -1
  249. package/dist/git/__tests__/deploy-guard.test.js +0 -61
  250. package/dist/git/__tests__/ensure-git-credential-helper.test.d.ts +0 -1
  251. package/dist/git/__tests__/ensure-git-credential-helper.test.js +0 -133
  252. package/dist/git/__tests__/ensure-runwork-remote.test.d.ts +0 -1
  253. package/dist/git/__tests__/ensure-runwork-remote.test.js +0 -109
  254. package/dist/git/__tests__/identity.test.d.ts +0 -1
  255. package/dist/git/__tests__/identity.test.js +0 -146
  256. package/dist/git/__tests__/manifest.test.d.ts +0 -1
  257. package/dist/git/__tests__/manifest.test.js +0 -446
  258. package/dist/git/__tests__/preflight-resolution.test.d.ts +0 -1
  259. package/dist/git/__tests__/preflight-resolution.test.js +0 -366
  260. package/dist/git/__tests__/preflight.test.d.ts +0 -1
  261. package/dist/git/__tests__/preflight.test.js +0 -36
  262. package/dist/git/__tests__/repo-config.test.d.ts +0 -1
  263. package/dist/git/__tests__/repo-config.test.js +0 -26
  264. package/dist/git/__tests__/sync.test.d.ts +0 -1
  265. package/dist/git/__tests__/sync.test.js +0 -405
  266. package/dist/git/auto-commit.d.ts +0 -35
  267. package/dist/git/auto-commit.js +0 -293
  268. package/dist/git/classify-sync-error.d.ts +0 -21
  269. package/dist/git/classify-sync-error.js +0 -111
  270. package/dist/git/credentials.d.ts +0 -75
  271. package/dist/git/credentials.js +0 -164
  272. package/dist/git/critical-files.d.ts +0 -20
  273. package/dist/git/critical-files.js +0 -68
  274. package/dist/git/deploy-guard.d.ts +0 -53
  275. package/dist/git/deploy-guard.js +0 -78
  276. package/dist/git/identity.d.ts +0 -44
  277. package/dist/git/identity.js +0 -133
  278. package/dist/git/preflight.d.ts +0 -57
  279. package/dist/git/preflight.js +0 -276
  280. package/dist/git/remote.d.ts +0 -37
  281. package/dist/git/remote.js +0 -75
  282. package/dist/git/repo-config.d.ts +0 -8
  283. package/dist/git/repo-config.js +0 -29
  284. package/dist/git/sync.d.ts +0 -15
  285. package/dist/git/sync.js +0 -159
  286. package/dist/health/__tests__/checks.test.d.ts +0 -1
  287. package/dist/health/__tests__/checks.test.js +0 -357
  288. package/dist/health/__tests__/cli-distribution-checks.test.d.ts +0 -1
  289. package/dist/health/__tests__/cli-distribution-checks.test.js +0 -196
  290. package/dist/health/__tests__/fix.test.d.ts +0 -1
  291. package/dist/health/__tests__/fix.test.js +0 -72
  292. package/dist/health/__tests__/runner-filter.test.d.ts +0 -1
  293. package/dist/health/__tests__/runner-filter.test.js +0 -61
  294. package/dist/health/checks.d.ts +0 -42
  295. package/dist/health/checks.js +0 -636
  296. package/dist/health/fix.d.ts +0 -22
  297. package/dist/health/fix.js +0 -62
  298. package/dist/health/runner.d.ts +0 -8
  299. package/dist/health/runner.js +0 -47
  300. package/dist/health/types.d.ts +0 -12
  301. package/dist/health/types.js +0 -1
  302. package/dist/index.d.ts +0 -1
  303. package/dist/logs/__tests__/tailer-format.test.d.ts +0 -1
  304. package/dist/logs/__tests__/tailer-format.test.js +0 -43
  305. package/dist/logs/tailer.d.ts +0 -17
  306. package/dist/logs/tailer.js +0 -217
  307. package/dist/sync/__tests__/change-detect.test.d.ts +0 -1
  308. package/dist/sync/__tests__/change-detect.test.js +0 -123
  309. package/dist/sync/__tests__/hash.test.d.ts +0 -1
  310. package/dist/sync/__tests__/hash.test.js +0 -18
  311. package/dist/sync/change-detect.d.ts +0 -19
  312. package/dist/sync/change-detect.js +0 -136
  313. package/dist/sync/conflict-ui.d.ts +0 -5
  314. package/dist/sync/conflict-ui.js +0 -78
  315. package/dist/sync/executor.d.ts +0 -23
  316. package/dist/sync/executor.js +0 -102
  317. package/dist/sync/hash.d.ts +0 -1
  318. package/dist/sync/hash.js +0 -4
  319. package/dist/sync/types.d.ts +0 -24
  320. package/dist/sync/types.js +0 -1
  321. package/dist/template/manifest.d.ts +0 -17
  322. package/dist/template/manifest.js +0 -145
  323. package/dist/tools/types.d.ts +0 -52
  324. package/dist/tools/types.js +0 -8
  325. package/dist/types-manager.d.ts +0 -1
  326. package/dist/types-manager.js +0 -35
  327. package/dist/types.d.ts +0 -349
  328. package/dist/types.js +0 -1
  329. package/dist/ui/__tests__/banner.test.d.ts +0 -1
  330. package/dist/ui/__tests__/banner.test.js +0 -98
  331. package/dist/ui/__tests__/colors.test.d.ts +0 -1
  332. package/dist/ui/__tests__/colors.test.js +0 -22
  333. package/dist/ui/__tests__/keyboard.test.d.ts +0 -1
  334. package/dist/ui/__tests__/keyboard.test.js +0 -34
  335. package/dist/ui/__tests__/status-line.test.d.ts +0 -1
  336. package/dist/ui/__tests__/status-line.test.js +0 -54
  337. package/dist/ui/banner.d.ts +0 -29
  338. package/dist/ui/banner.js +0 -153
  339. package/dist/ui/colors.d.ts +0 -4
  340. package/dist/ui/colors.js +0 -7
  341. package/dist/ui/keyboard.d.ts +0 -12
  342. package/dist/ui/keyboard.js +0 -61
  343. package/dist/ui/status-line.d.ts +0 -6
  344. package/dist/ui/status-line.js +0 -53
  345. package/dist/utils/__tests__/format-error.test.d.ts +0 -1
  346. package/dist/utils/__tests__/format-error.test.js +0 -43
  347. package/dist/utils/__tests__/help-json.test.d.ts +0 -1
  348. package/dist/utils/__tests__/help-json.test.js +0 -39
  349. package/dist/utils/__tests__/http.test.d.ts +0 -1
  350. package/dist/utils/__tests__/http.test.js +0 -381
  351. package/dist/utils/__tests__/ignore-matcher.test.d.ts +0 -1
  352. package/dist/utils/__tests__/ignore-matcher.test.js +0 -205
  353. package/dist/utils/__tests__/output.test.d.ts +0 -1
  354. package/dist/utils/__tests__/output.test.js +0 -38
  355. package/dist/utils/__tests__/prompt.test.d.ts +0 -1
  356. package/dist/utils/__tests__/prompt.test.js +0 -27
  357. package/dist/utils/__tests__/resolve.test.d.ts +0 -1
  358. package/dist/utils/__tests__/resolve.test.js +0 -95
  359. package/dist/utils/__tests__/sqlite.test.d.ts +0 -1
  360. package/dist/utils/__tests__/sqlite.test.js +0 -89
  361. package/dist/utils/agent-guidance.d.ts +0 -47
  362. package/dist/utils/agent-guidance.js +0 -128
  363. package/dist/utils/app-info.d.ts +0 -70
  364. package/dist/utils/app-info.js +0 -167
  365. package/dist/utils/curl-parser.d.ts +0 -12
  366. package/dist/utils/curl-parser.js +0 -162
  367. package/dist/utils/data-input.d.ts +0 -1
  368. package/dist/utils/data-input.js +0 -38
  369. package/dist/utils/format-error.d.ts +0 -10
  370. package/dist/utils/format-error.js +0 -38
  371. package/dist/utils/fs.d.ts +0 -5
  372. package/dist/utils/fs.js +0 -23
  373. package/dist/utils/help-json.d.ts +0 -70
  374. package/dist/utils/help-json.js +0 -88
  375. package/dist/utils/http.d.ts +0 -46
  376. package/dist/utils/http.js +0 -421
  377. package/dist/utils/ignore-matcher.d.ts +0 -47
  378. package/dist/utils/ignore-matcher.js +0 -132
  379. package/dist/utils/output.d.ts +0 -17
  380. package/dist/utils/output.js +0 -27
  381. package/dist/utils/prompt.d.ts +0 -5
  382. package/dist/utils/prompt.js +0 -42
  383. package/dist/utils/resolve.d.ts +0 -12
  384. package/dist/utils/resolve.js +0 -52
  385. package/dist/utils/setup-state.d.ts +0 -3
  386. package/dist/utils/setup-state.js +0 -19
  387. package/dist/utils/sqlite-adapter.d.ts +0 -48
  388. package/dist/utils/sqlite-adapter.js +0 -147
  389. package/dist/utils/sqlite.d.ts +0 -14
  390. package/dist/utils/sqlite.js +0 -14
  391. package/dist/utils/subprocess.d.ts +0 -19
  392. package/dist/utils/subprocess.js +0 -27
  393. package/dist/utils/which.d.ts +0 -14
  394. package/dist/utils/which.js +0 -47
  395. package/dist/utils/zip.d.ts +0 -7
  396. package/dist/utils/zip.js +0 -42
  397. package/dist/validate/__tests__/validate.test.d.ts +0 -1
  398. package/dist/validate/__tests__/validate.test.js +0 -42
  399. package/dist/validate/freshness.d.ts +0 -28
  400. package/dist/validate/freshness.js +0 -48
  401. package/dist/validate/preview.d.ts +0 -21
  402. package/dist/validate/preview.js +0 -39
  403. package/dist/workspace/resolve.d.ts +0 -19
  404. package/dist/workspace/resolve.js +0 -100
@@ -1,684 +0,0 @@
1
- import { existsSync, mkdtempSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync, mkdirSync } from 'fs';
2
- import { dirname, join } from 'path';
3
- import { homedir, platform, tmpdir } from 'os';
4
- import { mergeJsonMcpServers, readJsonConfig, writeJsonConfig, removeRunworkMcpServers } from './utils/json-config.js';
5
- import { writeHintToFile, writeTeamInstructionsToFile, removeHintFromFile, removeTeamInstructionsFromFile, } from './utils/instruction-hint.js';
6
- import { createZipFromDir } from '../utils/zip.js';
7
- import { writePluginMcpConfig, writePluginMetadata, writePluginSkills, writePluginTeamInstructions, writePluginTree, } from './claude-desktop-plugin-tree.js';
8
- const PLUGIN_NAME = 'runwork';
9
- const PLUGIN_VERSION = '1.0.0';
10
- const PLUGIN_DESCRIPTION = 'Skills and tools from your Runwork workspace';
11
- const PLUGIN_AUTHOR_NAME = 'Runwork';
12
- function getPluginMetadata() {
13
- return {
14
- pluginName: PLUGIN_NAME,
15
- pluginVersion: PLUGIN_VERSION,
16
- description: PLUGIN_DESCRIPTION,
17
- authorName: PLUGIN_AUTHOR_NAME,
18
- };
19
- }
20
- function getMcpConfigPath() {
21
- const os = platform();
22
- if (os === 'darwin') {
23
- return join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
24
- }
25
- if (os === 'win32') {
26
- return join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json');
27
- }
28
- return join(homedir(), '.config', 'Claude', 'claude_desktop_config.json');
29
- }
30
- function getCoworkBaseDir() {
31
- const os = platform();
32
- if (os === 'darwin') {
33
- return join(homedir(), 'Library', 'Application Support', 'Claude', 'local-agent-mode-sessions');
34
- }
35
- if (os === 'win32') {
36
- return join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), 'Claude', 'local-agent-mode-sessions');
37
- }
38
- return join(homedir(), '.config', 'Claude', 'local-agent-mode-sessions');
39
- }
40
- /**
41
- * Walk all `local-agent-mode-sessions/<session>/<org>/` directories and
42
- * invoke `visit` for each. Stops and returns the first non-null result.
43
- */
44
- function walkOrgDirs(visit) {
45
- const baseDir = getCoworkBaseDir();
46
- if (!existsSync(baseDir))
47
- return null;
48
- try {
49
- const sessionDirs = readdirSync(baseDir).filter(d => !d.startsWith('.') && d !== 'skills-plugin');
50
- for (const sessionId of sessionDirs) {
51
- const sessionPath = join(baseDir, sessionId);
52
- let orgDirs;
53
- try {
54
- orgDirs = readdirSync(sessionPath).filter(d => !d.startsWith('.'));
55
- }
56
- catch {
57
- continue;
58
- }
59
- for (const orgId of orgDirs) {
60
- const orgDir = join(sessionPath, orgId);
61
- const result = visit(orgDir);
62
- if (result !== null)
63
- return result;
64
- }
65
- }
66
- }
67
- catch {
68
- /* ignore */
69
- }
70
- return null;
71
- }
72
- /**
73
- * Collect every `<session>/<org>/memory/CLAUDE.md` path under the Cowork
74
- * base directory. Claude Desktop loads this file on every conversation in
75
- * the matching session/org — writing here gets Runwork instructions applied
76
- * foundationally, without relying on the agent invoking a skill. We target
77
- * every org we find because users may flip between sessions or orgs.
78
- */
79
- export function getCoworkMemoryClaudeMdPaths() {
80
- const paths = [];
81
- const baseDir = getCoworkBaseDir();
82
- if (!existsSync(baseDir))
83
- return paths;
84
- try {
85
- const sessionDirs = readdirSync(baseDir).filter(d => !d.startsWith('.') && d !== 'skills-plugin');
86
- for (const sessionId of sessionDirs) {
87
- const sessionPath = join(baseDir, sessionId);
88
- let orgDirs;
89
- try {
90
- orgDirs = readdirSync(sessionPath).filter(d => !d.startsWith('.'));
91
- }
92
- catch {
93
- continue;
94
- }
95
- for (const orgId of orgDirs) {
96
- paths.push(join(sessionPath, orgId, 'memory', 'CLAUDE.md'));
97
- }
98
- }
99
- }
100
- catch {
101
- /* ignore */
102
- }
103
- return paths;
104
- }
105
- /**
106
- * Find the cowork_plugins directory by discovering the session/org ID structure.
107
- * Path: local-agent-mode-sessions/<session-id>/<org-id>/cowork_plugins/
108
- */
109
- function findCoworkPluginsDir() {
110
- return walkOrgDirs((orgDir) => {
111
- const pluginsDir = join(orgDir, 'cowork_plugins');
112
- return existsSync(join(pluginsDir, 'installed_plugins.json')) ? pluginsDir : null;
113
- });
114
- }
115
- /**
116
- * Look for a plugin named `pluginName` in any `rpm/manifest.json`. These
117
- * entries are created by Claude Desktop when the user uploads a plugin zip
118
- * through Customize > Create plugin > Upload plugin. If found, sync should
119
- * update the plugin content files inside the rpm plugin directory instead
120
- * of writing to the legacy `cowork_plugins/` layout.
121
- *
122
- * We never modify `rpm/manifest.json` itself — Claude Desktop owns that
123
- * registry and assigns the plugin id we read from it here.
124
- */
125
- export function findRpmPluginByName(pluginName) {
126
- return walkOrgDirs((orgDir) => {
127
- const manifestPath = join(orgDir, 'rpm', 'manifest.json');
128
- if (!existsSync(manifestPath))
129
- return null;
130
- try {
131
- const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
132
- const entry = manifest.plugins?.find((p) => p.name === pluginName);
133
- if (!entry?.id)
134
- return null;
135
- return {
136
- pluginPath: join(orgDir, 'rpm', entry.id),
137
- orgDir,
138
- };
139
- }
140
- catch {
141
- return null;
142
- }
143
- });
144
- }
145
- function getMarketplaceJson() {
146
- return {
147
- name: 'runwork',
148
- owner: { name: PLUGIN_AUTHOR_NAME },
149
- plugins: [
150
- {
151
- name: PLUGIN_NAME,
152
- source: `./plugins/${PLUGIN_NAME}`,
153
- description: PLUGIN_DESCRIPTION,
154
- },
155
- ],
156
- };
157
- }
158
- function getCoworkSettingsPath(pluginsDir) {
159
- return join(dirname(pluginsDir), 'cowork_settings.json');
160
- }
161
- function setCoworkPluginEnabled(pluginsDir, enabled) {
162
- const settingsPath = getCoworkSettingsPath(pluginsDir);
163
- const settings = readJsonConfig(settingsPath);
164
- const enabledPlugins = (settings.enabledPlugins ?? {});
165
- enabledPlugins[`${PLUGIN_NAME}@runwork`] = enabled;
166
- settings.enabledPlugins = enabledPlugins;
167
- writeJsonConfig(settingsPath, settings);
168
- }
169
- export class ClaudeDesktopAdapter {
170
- name = 'Claude Desktop (Cowork)';
171
- slug = 'claude-desktop';
172
- async detect() {
173
- const os = platform();
174
- if (os === 'darwin')
175
- return existsSync('/Applications/Claude.app');
176
- return existsSync(getMcpConfigPath());
177
- }
178
- supportsMcpScope(scope) {
179
- return scope === 'user';
180
- }
181
- supportsSkills() {
182
- return true;
183
- }
184
- async writeMcpServers(servers, _scope) {
185
- // Claude Desktop has two MCP transport paths:
186
- // 1. claude_desktop_config.json with mcp-remote (stdio bridge): for chat mode
187
- // 2. .mcp.json inside the plugin directory (native HTTP): for cowork mode connectors
188
- //
189
- // For cowork connectors, embed the auth token in the URL query string.
190
- // This lets Claude Desktop connect without requiring the user to go through
191
- // an OAuth flow or manually click "Connect" in the Connectors UI.
192
- // Write to claude_desktop_config.json via mcp-remote (chat mode fallback).
193
- // Forward every auth header (Authorization, X-Api-Key, etc.) as a --header arg.
194
- const entries = {};
195
- for (const s of servers) {
196
- const args = ['mcp-remote', s.url];
197
- if (s.headers) {
198
- for (const [name, value] of Object.entries(s.headers)) {
199
- args.push('--header', `${name}:${value}`);
200
- }
201
- }
202
- entries[s.name] = {
203
- command: 'npx',
204
- args: ['-y', ...args],
205
- };
206
- }
207
- mergeJsonMcpServers(getMcpConfigPath(), entries, 'mcpServers');
208
- // Prefer rpm/plugin_<id>/ when the user has uploaded our zip through
209
- // Claude Desktop's Customize > Create plugin > Upload plugin flow.
210
- const rpm = findRpmPluginByName(PLUGIN_NAME);
211
- if (rpm) {
212
- writePluginMcpConfig(rpm.pluginPath, servers);
213
- return;
214
- }
215
- // Fall back to the legacy cowork_plugins layout (cache + marketplace).
216
- const pluginsDir = findCoworkPluginsDir();
217
- if (pluginsDir) {
218
- const cacheDir = join(pluginsDir, 'cache', 'runwork', PLUGIN_NAME, PLUGIN_VERSION);
219
- const marketDir = join(pluginsDir, 'marketplaces', 'runwork', 'plugins', PLUGIN_NAME);
220
- for (const dir of [cacheDir, marketDir]) {
221
- writePluginMcpConfig(dir, servers);
222
- }
223
- }
224
- }
225
- async writeSkills(skills, _scope) {
226
- // Prefer rpm/plugin_<id>/ when the user has uploaded our zip through
227
- // Claude Desktop's Customize > Create plugin > Upload plugin flow.
228
- // Claude Desktop owns rpm/manifest.json (registration, enablement),
229
- // so we only refresh the plugin content files.
230
- const rpm = findRpmPluginByName(PLUGIN_NAME);
231
- if (rpm) {
232
- writePluginMetadata(rpm.pluginPath, getPluginMetadata());
233
- writePluginSkills(rpm.pluginPath, skills);
234
- return;
235
- }
236
- const pluginsDir = findCoworkPluginsDir();
237
- if (!pluginsDir) {
238
- console.warn(' [Claude Desktop] Cowork plugins directory not found. Open Claude Desktop at least once first.');
239
- return;
240
- }
241
- // Fall back to legacy cowork_plugins layout: write to both cache
242
- // (installed copy) and marketplaces (source).
243
- const cacheDir = join(pluginsDir, 'cache', 'runwork', PLUGIN_NAME, PLUGIN_VERSION);
244
- const marketRoot = join(pluginsDir, 'marketplaces', 'runwork');
245
- const marketDir = join(marketRoot, 'plugins', PLUGIN_NAME);
246
- for (const dir of [cacheDir, marketDir]) {
247
- writePluginMetadata(dir, getPluginMetadata());
248
- writePluginSkills(dir, skills);
249
- }
250
- // Register in installed_plugins.json
251
- const installedPath = join(pluginsDir, 'installed_plugins.json');
252
- const installed = readJsonConfig(installedPath);
253
- if (!installed.version)
254
- installed.version = 2;
255
- if (!installed.plugins)
256
- installed.plugins = {};
257
- installed.plugins[`${PLUGIN_NAME}@runwork`] = [{
258
- scope: 'user',
259
- installPath: cacheDir,
260
- version: PLUGIN_VERSION,
261
- installedAt: new Date().toISOString(),
262
- lastUpdated: new Date().toISOString(),
263
- }];
264
- writeJsonConfig(installedPath, installed);
265
- // Write marketplace.json catalog
266
- const marketCatalogDir = join(marketRoot, '.claude-plugin');
267
- mkdirSync(marketCatalogDir, { recursive: true });
268
- writeFileSync(join(marketCatalogDir, 'marketplace.json'), JSON.stringify(getMarketplaceJson(), null, 2));
269
- // Register in known_marketplaces.json
270
- const marketplacesPath = join(pluginsDir, 'known_marketplaces.json');
271
- const marketplaces = readJsonConfig(marketplacesPath);
272
- marketplaces['runwork'] = {
273
- source: { source: 'directory', path: marketRoot },
274
- installLocation: marketRoot,
275
- lastUpdated: new Date().toISOString(),
276
- };
277
- writeJsonConfig(marketplacesPath, marketplaces);
278
- // Sync should recover a previously disabled plugin so it shows up in Customize.
279
- setCoworkPluginEnabled(pluginsDir, true);
280
- }
281
- async writeInstructionHint(hint, _scope) {
282
- // Cowork loads `<session>/<org>/memory/CLAUDE.md` on every conversation.
283
- // This is the same always-on memory surface Claude Code uses with
284
- // `~/.claude/CLAUDE.md`, so it's the right home for foundational hints.
285
- // Merge into marker blocks so any user-authored content above/below our
286
- // block is preserved.
287
- for (const path of getCoworkMemoryClaudeMdPaths()) {
288
- try {
289
- writeHintToFile(path, hint);
290
- }
291
- catch { /* best-effort per org */ }
292
- }
293
- }
294
- async buildPluginZip(skills, mcpServers, teamInstructions, outputPath) {
295
- // Materialise the plugin tree into a temp dir, zip it, then clean up.
296
- // Uses the same writePluginTree + writePluginTeamInstructions helpers
297
- // the sync path uses so the on-disk layout is byte-identical whether
298
- // the user installs via upload or sync.
299
- const stagingRoot = mkdtempSync(join(tmpdir(), 'runwork-plugin-'));
300
- const pluginStagingDir = join(stagingRoot, PLUGIN_NAME);
301
- try {
302
- writePluginTree(pluginStagingDir, {
303
- ...getPluginMetadata(),
304
- skills,
305
- mcpServers,
306
- });
307
- if (teamInstructions) {
308
- writePluginTeamInstructions(pluginStagingDir, teamInstructions);
309
- }
310
- createZipFromDir(pluginStagingDir, outputPath);
311
- }
312
- finally {
313
- try {
314
- rmSync(stagingRoot, { recursive: true, force: true });
315
- }
316
- catch {
317
- /* best-effort */
318
- }
319
- }
320
- }
321
- async writeTeamInstructions(instructions, _scope) {
322
- // Primary surface: `<org>/memory/CLAUDE.md`. Cowork auto-loads this on
323
- // every conversation, matching the Claude Code convention. Write through
324
- // the team-instructions marker block so user-authored content is safe.
325
- for (const path of getCoworkMemoryClaudeMdPaths()) {
326
- try {
327
- writeTeamInstructionsToFile(path, instructions);
328
- }
329
- catch { /* best-effort per org */ }
330
- }
331
- // Secondary surface: the plugin's `runwork-team-instructions` SKILL.md.
332
- // Kept for the build-plugin zip flow and as a slash-command fallback
333
- // when users inspect plugin skills. Prefer the rpm upload location when
334
- // present, otherwise fall back to the legacy cowork_plugins layout.
335
- const rpm = findRpmPluginByName(PLUGIN_NAME);
336
- if (rpm) {
337
- writePluginTeamInstructions(rpm.pluginPath, instructions);
338
- return;
339
- }
340
- const pluginsDir = findCoworkPluginsDir();
341
- if (!pluginsDir)
342
- return;
343
- writePluginTeamInstructions(join(pluginsDir, 'cache', 'runwork', PLUGIN_NAME, PLUGIN_VERSION), instructions);
344
- writePluginTeamInstructions(join(pluginsDir, 'marketplaces', 'runwork', 'plugins', PLUGIN_NAME), instructions);
345
- }
346
- // ── Agent config (limited to preferences) ──────────────────────────
347
- async writeAgentConfig(config, _scope) {
348
- const configPath = getMcpConfigPath();
349
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
350
- let desktopConfig = {};
351
- if (existsSync(configPath)) {
352
- try {
353
- desktopConfig = JSON.parse(readFileSync(configPath, 'utf-8'));
354
- }
355
- catch { /* start fresh */ }
356
- }
357
- if (!desktopConfig.preferences)
358
- desktopConfig.preferences = {};
359
- const prefs = desktopConfig.preferences;
360
- if (config.permissionRules) {
361
- if (config.permissionRules.allow?.includes('web_search')) {
362
- prefs.coworkWebSearchEnabled = true;
363
- }
364
- if (config.permissionRules.deny?.includes('web_search')) {
365
- prefs.coworkWebSearchEnabled = false;
366
- }
367
- if (config.permissionRules.allow?.includes('scheduled_tasks')) {
368
- prefs.coworkScheduledTasksEnabled = true;
369
- prefs.ccdScheduledTasksEnabled = true;
370
- }
371
- if (config.permissionRules.deny?.includes('scheduled_tasks')) {
372
- prefs.coworkScheduledTasksEnabled = false;
373
- prefs.ccdScheduledTasksEnabled = false;
374
- }
375
- }
376
- writeFileSync(configPath, JSON.stringify(desktopConfig, null, 2));
377
- }
378
- // ── Cleanup (uninstall) ────────────────────────────────────────────
379
- async cleanup(_scope, _manifest) {
380
- // 1. Remove MCP entries from claude_desktop_config.json
381
- removeRunworkMcpServers(getMcpConfigPath(), 'mcpServers');
382
- // Remove Runwork marker blocks from each org's memory/CLAUDE.md, leaving
383
- // any user-authored content in that file intact.
384
- for (const path of getCoworkMemoryClaudeMdPaths()) {
385
- try {
386
- removeHintFromFile(path);
387
- }
388
- catch { /* best-effort per org */ }
389
- try {
390
- removeTeamInstructionsFromFile(path);
391
- }
392
- catch { /* best-effort per org */ }
393
- }
394
- // 2. Remove the uploaded rpm plugin if the user installed via
395
- // Customize > Create plugin > Upload plugin. We delete both the
396
- // plugin directory and the manifest entry so Claude Desktop does
397
- // not show a stale Runwork plugin after uninstall.
398
- const rpm = findRpmPluginByName(PLUGIN_NAME);
399
- if (rpm) {
400
- if (existsSync(rpm.pluginPath)) {
401
- try {
402
- rmSync(rpm.pluginPath, { recursive: true, force: true });
403
- }
404
- catch { /* best-effort */ }
405
- }
406
- const manifestPath = join(rpm.orgDir, 'rpm', 'manifest.json');
407
- if (existsSync(manifestPath)) {
408
- try {
409
- const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
410
- if (Array.isArray(manifest.plugins)) {
411
- manifest.plugins = manifest.plugins.filter((p) => p.name !== PLUGIN_NAME);
412
- manifest.lastUpdated = Date.now();
413
- writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
414
- }
415
- }
416
- catch { /* best-effort */ }
417
- }
418
- }
419
- // 3. Remove Cowork plugin directories and registration
420
- const pluginsDir = findCoworkPluginsDir();
421
- if (pluginsDir) {
422
- // Remove cache/runwork and marketplaces/runwork directories
423
- const cacheRunwork = join(pluginsDir, 'cache', 'runwork');
424
- const marketRunwork = join(pluginsDir, 'marketplaces', 'runwork');
425
- for (const dir of [cacheRunwork, marketRunwork]) {
426
- if (existsSync(dir)) {
427
- try {
428
- rmSync(dir, { recursive: true, force: true });
429
- }
430
- catch { /* best-effort */ }
431
- }
432
- }
433
- // Remove from installed_plugins.json
434
- const installedPath = join(pluginsDir, 'installed_plugins.json');
435
- if (existsSync(installedPath)) {
436
- try {
437
- const installed = readJsonConfig(installedPath);
438
- if (installed.plugins) {
439
- delete installed.plugins[`${PLUGIN_NAME}@runwork`];
440
- writeJsonConfig(installedPath, installed);
441
- }
442
- }
443
- catch { /* best-effort */ }
444
- }
445
- // Remove from known_marketplaces.json
446
- const marketplacesPath = join(pluginsDir, 'known_marketplaces.json');
447
- if (existsSync(marketplacesPath)) {
448
- try {
449
- const marketplaces = readJsonConfig(marketplacesPath);
450
- delete marketplaces['runwork'];
451
- writeJsonConfig(marketplacesPath, marketplaces);
452
- }
453
- catch { /* best-effort */ }
454
- }
455
- // Remove the enable flag so cleanup fully unregisters the plugin.
456
- const coworkSettingsPath = getCoworkSettingsPath(pluginsDir);
457
- if (existsSync(coworkSettingsPath)) {
458
- try {
459
- const settings = readJsonConfig(coworkSettingsPath);
460
- const enabledPlugins = settings.enabledPlugins;
461
- if (enabledPlugins && typeof enabledPlugins === 'object' && !Array.isArray(enabledPlugins)) {
462
- delete enabledPlugins[`${PLUGIN_NAME}@runwork`];
463
- settings.enabledPlugins = enabledPlugins;
464
- writeJsonConfig(coworkSettingsPath, settings);
465
- }
466
- }
467
- catch { /* best-effort */ }
468
- }
469
- }
470
- }
471
- // ── Usage stats (passive, best-effort) ─────────────────────────────
472
- async readUsageStats(lastSyncAt) {
473
- try {
474
- const os = platform();
475
- let claudeAppDir;
476
- if (os === 'darwin') {
477
- claudeAppDir = join(homedir(), 'Library', 'Application Support', 'Claude');
478
- }
479
- else if (os === 'win32') {
480
- claudeAppDir = join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), 'Claude');
481
- }
482
- else {
483
- claudeAppDir = join(homedir(), '.config', 'Claude');
484
- }
485
- if (!existsSync(claudeAppDir))
486
- return null;
487
- const sinceMs = lastSyncAt ? new Date(lastSyncAt).getTime() : 0;
488
- let sessionCount = 0;
489
- let latestActivity = 0;
490
- const modelsUsed = new Set();
491
- let maxMcpTools = 0;
492
- // Read agent mode session JSON files
493
- // Path: local-agent-mode-sessions/{orgId}/{userId}/*.json
494
- const agentSessionsDir = join(claudeAppDir, 'local-agent-mode-sessions');
495
- if (existsSync(agentSessionsDir)) {
496
- this.walkSessionDirs(agentSessionsDir, sinceMs, (session) => {
497
- const sessionTime = session.lastActivityAt ?? session.createdAt ?? 0;
498
- if (sessionTime > sinceMs)
499
- sessionCount++;
500
- if (sessionTime > latestActivity)
501
- latestActivity = sessionTime;
502
- if (session.model)
503
- modelsUsed.add(session.model);
504
- if (session.enabledMcpTools && typeof session.enabledMcpTools === 'object') {
505
- const toolCount = Object.keys(session.enabledMcpTools).length;
506
- if (toolCount > maxMcpTools)
507
- maxMcpTools = toolCount;
508
- }
509
- });
510
- }
511
- // Also check code sessions launched from Desktop
512
- const codeSessionsDir = join(claudeAppDir, 'claude-code-sessions');
513
- if (existsSync(codeSessionsDir)) {
514
- this.walkSessionDirs(codeSessionsDir, sinceMs, (session) => {
515
- const sessionTime = session.lastActivityAt ?? session.createdAt ?? 0;
516
- if (sessionTime > sinceMs)
517
- sessionCount++;
518
- if (sessionTime > latestActivity)
519
- latestActivity = sessionTime;
520
- if (session.model)
521
- modelsUsed.add(session.model);
522
- });
523
- }
524
- // Check scheduled tasks
525
- let scheduledTaskRuns = 0;
526
- const scheduledTasksPath = join(claudeAppDir, 'scheduled-tasks.json');
527
- if (existsSync(scheduledTasksPath)) {
528
- try {
529
- const raw = readFileSync(scheduledTasksPath, 'utf-8');
530
- const parsed = JSON.parse(raw);
531
- const tasks = Array.isArray(parsed) ? parsed : Object.values(parsed);
532
- for (const task of tasks) {
533
- const t = task;
534
- if (t.lastRunAt && new Date(t.lastRunAt).getTime() > sinceMs) {
535
- scheduledTaskRuns++;
536
- }
537
- }
538
- }
539
- catch { /* best-effort */ }
540
- }
541
- if (sessionCount === 0 && latestActivity <= sinceMs && scheduledTaskRuns === 0)
542
- return null;
543
- return {
544
- hasNewActivity: sessionCount > 0 || scheduledTaskRuns > 0,
545
- sessionCount,
546
- messageCount: 0,
547
- toolCallCount: 0,
548
- tokensUsed: 0,
549
- aiLinesAdded: 0,
550
- aiLinesRemoved: 0,
551
- lastActiveAt: latestActivity > 0 ? new Date(latestActivity).toISOString() : null,
552
- modelsUsed: Array.from(modelsUsed),
553
- mcpToolCount: maxMcpTools > 0 ? maxMcpTools : undefined,
554
- extra: scheduledTaskRuns > 0 ? { scheduledTaskRuns } : undefined,
555
- };
556
- }
557
- catch {
558
- return null;
559
- }
560
- }
561
- async readVersion() {
562
- try {
563
- const os = platform();
564
- let claudeAppDir;
565
- if (os === 'darwin') {
566
- claudeAppDir = join(homedir(), 'Library', 'Application Support', 'Claude');
567
- }
568
- else if (os === 'win32') {
569
- claudeAppDir = join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), 'Claude');
570
- }
571
- else {
572
- claudeAppDir = join(homedir(), '.config', 'Claude');
573
- }
574
- const versionPath = join(claudeAppDir, 'claude-code', 'sdk-version');
575
- if (existsSync(versionPath)) {
576
- return readFileSync(versionPath, 'utf-8').trim();
577
- }
578
- return null;
579
- }
580
- catch {
581
- return null;
582
- }
583
- }
584
- async readSkillUsage(lastSyncAt) {
585
- // Cowork session JSON files contain enabledMcpTools, an object whose keys
586
- // are MCP tool names. Tools matching skill_* patterns indicate which skills
587
- // were loaded (reach, not invocation). This is the best we can get from
588
- // local data. For actual invocation data, OTEL or the Enterprise Analytics
589
- // API are needed.
590
- try {
591
- const baseDir = getCoworkBaseDir();
592
- if (!existsSync(baseDir))
593
- return null;
594
- const sinceMs = lastSyncAt ? new Date(lastSyncAt).getTime() : 0;
595
- const skillCounts = new Map();
596
- const agentSessionsDir = baseDir;
597
- this.walkSessionDirs(agentSessionsDir, sinceMs, (session) => {
598
- const sessionTime = session.lastActivityAt ?? session.createdAt ?? 0;
599
- if (sessionTime <= sinceMs)
600
- return;
601
- const mcpTools = session.enabledMcpTools;
602
- if (!mcpTools || typeof mcpTools !== 'object')
603
- return;
604
- for (const toolName of Object.keys(mcpTools)) {
605
- // Match patterns like "skill_Blog_Writing_Specialist" or
606
- // "mcp__Runwork__skill_Write_Cold_Email"
607
- const skillMatch = toolName.match(/skill_([A-Za-z0-9_]+)/);
608
- if (!skillMatch)
609
- continue;
610
- // Convert Tool_Name_Format to readable name
611
- const rawName = skillMatch[1].replace(/_/g, ' ').trim();
612
- if (!rawName)
613
- continue;
614
- const existing = skillCounts.get(rawName);
615
- if (existing) {
616
- existing.count++;
617
- if (sessionTime > existing.lastTs)
618
- existing.lastTs = sessionTime;
619
- }
620
- else {
621
- skillCounts.set(rawName, { count: 1, lastTs: sessionTime });
622
- }
623
- }
624
- });
625
- if (skillCounts.size === 0)
626
- return null;
627
- const results = [];
628
- for (const [skillName, { count, lastTs }] of skillCounts) {
629
- results.push({
630
- skillName,
631
- count,
632
- lastUsedAt: new Date(lastTs).toISOString(),
633
- });
634
- }
635
- return results;
636
- }
637
- catch {
638
- return null;
639
- }
640
- }
641
- /**
642
- * Walk the org/user/session directory tree and invoke callback for each session JSON.
643
- */
644
- walkSessionDirs(baseDir, _sinceMs, onSession) {
645
- try {
646
- for (const orgDir of readdirSync(baseDir)) {
647
- if (orgDir.startsWith('.') || orgDir === 'skills-plugin')
648
- continue;
649
- const orgPath = join(baseDir, orgDir);
650
- try {
651
- if (!statSync(orgPath).isDirectory())
652
- continue;
653
- }
654
- catch {
655
- continue;
656
- }
657
- for (const userDir of readdirSync(orgPath)) {
658
- if (userDir.startsWith('.'))
659
- continue;
660
- const userPath = join(orgPath, userDir);
661
- try {
662
- if (!statSync(userPath).isDirectory())
663
- continue;
664
- }
665
- catch {
666
- continue;
667
- }
668
- for (const file of readdirSync(userPath)) {
669
- if (!file.endsWith('.json'))
670
- continue;
671
- try {
672
- const session = JSON.parse(readFileSync(join(userPath, file), 'utf-8'));
673
- onSession(session);
674
- }
675
- catch {
676
- continue;
677
- }
678
- }
679
- }
680
- }
681
- }
682
- catch { /* best-effort */ }
683
- }
684
- }