gipity 1.0.347 → 1.0.356

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 (390) hide show
  1. package/README.md +1 -1
  2. package/dist/adopt-cwd.js +1 -0
  3. package/dist/commands/add.js +136 -9
  4. package/dist/commands/logs.js +79 -0
  5. package/dist/commands/page-eval.js +31 -0
  6. package/dist/commands/page-inspect.js +91 -62
  7. package/dist/commands/page-screenshot.js +1 -1
  8. package/dist/commands/page.js +18 -0
  9. package/dist/commands/project.js +1 -0
  10. package/dist/commands/workflow.js +63 -16
  11. package/dist/flag-aliases.js +41 -2
  12. package/dist/index.js +3 -4
  13. package/dist/knowledge.js +5 -4
  14. package/dist/project-setup.js +24 -0
  15. package/dist/setup.js +1 -1
  16. package/dist/template-vars.js +156 -0
  17. package/package.json +7 -6
  18. package/dist/__tests__/adopt-cwd.test.d.ts +0 -1
  19. package/dist/__tests__/adopt-cwd.test.js +0 -176
  20. package/dist/__tests__/adopt-cwd.test.js.map +0 -1
  21. package/dist/__tests__/capture-transcript.test.d.ts +0 -1
  22. package/dist/__tests__/capture-transcript.test.js +0 -92
  23. package/dist/__tests__/capture-transcript.test.js.map +0 -1
  24. package/dist/__tests__/claude-noninteractive.test.d.ts +0 -1
  25. package/dist/__tests__/claude-noninteractive.test.js +0 -92
  26. package/dist/__tests__/claude-noninteractive.test.js.map +0 -1
  27. package/dist/__tests__/claude-trust.test.d.ts +0 -1
  28. package/dist/__tests__/claude-trust.test.js +0 -71
  29. package/dist/__tests__/claude-trust.test.js.map +0 -1
  30. package/dist/__tests__/cli-cmd-add.test.d.ts +0 -1
  31. package/dist/__tests__/cli-cmd-add.test.js +0 -45
  32. package/dist/__tests__/cli-cmd-add.test.js.map +0 -1
  33. package/dist/__tests__/cli-cmd-agent.test.d.ts +0 -1
  34. package/dist/__tests__/cli-cmd-agent.test.js +0 -76
  35. package/dist/__tests__/cli-cmd-agent.test.js.map +0 -1
  36. package/dist/__tests__/cli-cmd-approval.test.d.ts +0 -1
  37. package/dist/__tests__/cli-cmd-approval.test.js +0 -47
  38. package/dist/__tests__/cli-cmd-approval.test.js.map +0 -1
  39. package/dist/__tests__/cli-cmd-audit.test.d.ts +0 -1
  40. package/dist/__tests__/cli-cmd-audit.test.js +0 -33
  41. package/dist/__tests__/cli-cmd-audit.test.js.map +0 -1
  42. package/dist/__tests__/cli-cmd-chat.test.d.ts +0 -1
  43. package/dist/__tests__/cli-cmd-chat.test.js +0 -94
  44. package/dist/__tests__/cli-cmd-chat.test.js.map +0 -1
  45. package/dist/__tests__/cli-cmd-credits.test.d.ts +0 -1
  46. package/dist/__tests__/cli-cmd-credits.test.js +0 -66
  47. package/dist/__tests__/cli-cmd-credits.test.js.map +0 -1
  48. package/dist/__tests__/cli-cmd-db.test.d.ts +0 -1
  49. package/dist/__tests__/cli-cmd-db.test.js +0 -95
  50. package/dist/__tests__/cli-cmd-db.test.js.map +0 -1
  51. package/dist/__tests__/cli-cmd-deploy.test.d.ts +0 -1
  52. package/dist/__tests__/cli-cmd-deploy.test.js +0 -53
  53. package/dist/__tests__/cli-cmd-deploy.test.js.map +0 -1
  54. package/dist/__tests__/cli-cmd-domain.test.d.ts +0 -1
  55. package/dist/__tests__/cli-cmd-domain.test.js +0 -73
  56. package/dist/__tests__/cli-cmd-domain.test.js.map +0 -1
  57. package/dist/__tests__/cli-cmd-email.test.d.ts +0 -1
  58. package/dist/__tests__/cli-cmd-email.test.js +0 -31
  59. package/dist/__tests__/cli-cmd-email.test.js.map +0 -1
  60. package/dist/__tests__/cli-cmd-file.test.d.ts +0 -1
  61. package/dist/__tests__/cli-cmd-file.test.js +0 -86
  62. package/dist/__tests__/cli-cmd-file.test.js.map +0 -1
  63. package/dist/__tests__/cli-cmd-fn.test.d.ts +0 -1
  64. package/dist/__tests__/cli-cmd-fn.test.js +0 -50
  65. package/dist/__tests__/cli-cmd-fn.test.js.map +0 -1
  66. package/dist/__tests__/cli-cmd-generate.test.d.ts +0 -1
  67. package/dist/__tests__/cli-cmd-generate.test.js +0 -46
  68. package/dist/__tests__/cli-cmd-generate.test.js.map +0 -1
  69. package/dist/__tests__/cli-cmd-gmail.test.d.ts +0 -1
  70. package/dist/__tests__/cli-cmd-gmail.test.js +0 -49
  71. package/dist/__tests__/cli-cmd-gmail.test.js.map +0 -1
  72. package/dist/__tests__/cli-cmd-info.test.d.ts +0 -1
  73. package/dist/__tests__/cli-cmd-info.test.js +0 -52
  74. package/dist/__tests__/cli-cmd-info.test.js.map +0 -1
  75. package/dist/__tests__/cli-cmd-init.test.d.ts +0 -1
  76. package/dist/__tests__/cli-cmd-init.test.js +0 -76
  77. package/dist/__tests__/cli-cmd-init.test.js.map +0 -1
  78. package/dist/__tests__/cli-cmd-job.test.d.ts +0 -1
  79. package/dist/__tests__/cli-cmd-job.test.js +0 -204
  80. package/dist/__tests__/cli-cmd-job.test.js.map +0 -1
  81. package/dist/__tests__/cli-cmd-location.test.d.ts +0 -1
  82. package/dist/__tests__/cli-cmd-location.test.js +0 -58
  83. package/dist/__tests__/cli-cmd-location.test.js.map +0 -1
  84. package/dist/__tests__/cli-cmd-login.test.d.ts +0 -1
  85. package/dist/__tests__/cli-cmd-login.test.js +0 -41
  86. package/dist/__tests__/cli-cmd-login.test.js.map +0 -1
  87. package/dist/__tests__/cli-cmd-logout.test.d.ts +0 -1
  88. package/dist/__tests__/cli-cmd-logout.test.js +0 -20
  89. package/dist/__tests__/cli-cmd-logout.test.js.map +0 -1
  90. package/dist/__tests__/cli-cmd-logs.test.d.ts +0 -1
  91. package/dist/__tests__/cli-cmd-logs.test.js +0 -40
  92. package/dist/__tests__/cli-cmd-logs.test.js.map +0 -1
  93. package/dist/__tests__/cli-cmd-memory.test.d.ts +0 -1
  94. package/dist/__tests__/cli-cmd-memory.test.js +0 -58
  95. package/dist/__tests__/cli-cmd-memory.test.js.map +0 -1
  96. package/dist/__tests__/cli-cmd-page-inspect.test.d.ts +0 -1
  97. package/dist/__tests__/cli-cmd-page-inspect.test.js +0 -47
  98. package/dist/__tests__/cli-cmd-page-inspect.test.js.map +0 -1
  99. package/dist/__tests__/cli-cmd-plan.test.d.ts +0 -1
  100. package/dist/__tests__/cli-cmd-plan.test.js +0 -81
  101. package/dist/__tests__/cli-cmd-plan.test.js.map +0 -1
  102. package/dist/__tests__/cli-cmd-project.test.d.ts +0 -1
  103. package/dist/__tests__/cli-cmd-project.test.js +0 -61
  104. package/dist/__tests__/cli-cmd-project.test.js.map +0 -1
  105. package/dist/__tests__/cli-cmd-rbac.test.d.ts +0 -1
  106. package/dist/__tests__/cli-cmd-rbac.test.js +0 -39
  107. package/dist/__tests__/cli-cmd-rbac.test.js.map +0 -1
  108. package/dist/__tests__/cli-cmd-realtime.test.d.ts +0 -1
  109. package/dist/__tests__/cli-cmd-realtime.test.js +0 -51
  110. package/dist/__tests__/cli-cmd-realtime.test.js.map +0 -1
  111. package/dist/__tests__/cli-cmd-records.test.d.ts +0 -1
  112. package/dist/__tests__/cli-cmd-records.test.js +0 -67
  113. package/dist/__tests__/cli-cmd-records.test.js.map +0 -1
  114. package/dist/__tests__/cli-cmd-relay.test.d.ts +0 -1
  115. package/dist/__tests__/cli-cmd-relay.test.js +0 -100
  116. package/dist/__tests__/cli-cmd-relay.test.js.map +0 -1
  117. package/dist/__tests__/cli-cmd-sandbox.test.d.ts +0 -1
  118. package/dist/__tests__/cli-cmd-sandbox.test.js +0 -46
  119. package/dist/__tests__/cli-cmd-sandbox.test.js.map +0 -1
  120. package/dist/__tests__/cli-cmd-scaffold.test.d.ts +0 -1
  121. package/dist/__tests__/cli-cmd-scaffold.test.js +0 -30
  122. package/dist/__tests__/cli-cmd-scaffold.test.js.map +0 -1
  123. package/dist/__tests__/cli-cmd-skill.test.d.ts +0 -1
  124. package/dist/__tests__/cli-cmd-skill.test.js +0 -40
  125. package/dist/__tests__/cli-cmd-skill.test.js.map +0 -1
  126. package/dist/__tests__/cli-cmd-test.test.d.ts +0 -1
  127. package/dist/__tests__/cli-cmd-test.test.js +0 -58
  128. package/dist/__tests__/cli-cmd-test.test.js.map +0 -1
  129. package/dist/__tests__/cli-cmd-workflow.test.d.ts +0 -1
  130. package/dist/__tests__/cli-cmd-workflow.test.js +0 -84
  131. package/dist/__tests__/cli-cmd-workflow.test.js.map +0 -1
  132. package/dist/__tests__/cli-e2e-live.test.d.ts +0 -1
  133. package/dist/__tests__/cli-e2e-live.test.js +0 -144
  134. package/dist/__tests__/cli-e2e-live.test.js.map +0 -1
  135. package/dist/__tests__/cli-smoke.test.d.ts +0 -1
  136. package/dist/__tests__/cli-smoke.test.js +0 -69
  137. package/dist/__tests__/cli-smoke.test.js.map +0 -1
  138. package/dist/__tests__/config.test.d.ts +0 -1
  139. package/dist/__tests__/config.test.js +0 -95
  140. package/dist/__tests__/config.test.js.map +0 -1
  141. package/dist/__tests__/flag-aliases.test.d.ts +0 -1
  142. package/dist/__tests__/flag-aliases.test.js +0 -33
  143. package/dist/__tests__/flag-aliases.test.js.map +0 -1
  144. package/dist/__tests__/helpers/mock-server.d.ts +0 -52
  145. package/dist/__tests__/helpers/mock-server.js +0 -86
  146. package/dist/__tests__/helpers/mock-server.js.map +0 -1
  147. package/dist/__tests__/helpers/spawn-cli.d.ts +0 -30
  148. package/dist/__tests__/helpers/spawn-cli.js +0 -72
  149. package/dist/__tests__/helpers/spawn-cli.js.map +0 -1
  150. package/dist/__tests__/helpers/test-home.d.ts +0 -22
  151. package/dist/__tests__/helpers/test-home.js +0 -35
  152. package/dist/__tests__/helpers/test-home.js.map +0 -1
  153. package/dist/__tests__/hook-capture.test.d.ts +0 -1
  154. package/dist/__tests__/hook-capture.test.js +0 -65
  155. package/dist/__tests__/hook-capture.test.js.map +0 -1
  156. package/dist/__tests__/prompts.test.d.ts +0 -1
  157. package/dist/__tests__/prompts.test.js +0 -129
  158. package/dist/__tests__/prompts.test.js.map +0 -1
  159. package/dist/__tests__/push-cas.test.d.ts +0 -1
  160. package/dist/__tests__/push-cas.test.js +0 -133
  161. package/dist/__tests__/push-cas.test.js.map +0 -1
  162. package/dist/__tests__/relay-bridge-abort.test.d.ts +0 -1
  163. package/dist/__tests__/relay-bridge-abort.test.js +0 -65
  164. package/dist/__tests__/relay-bridge-abort.test.js.map +0 -1
  165. package/dist/__tests__/relay-daemon.test.d.ts +0 -1
  166. package/dist/__tests__/relay-daemon.test.js +0 -232
  167. package/dist/__tests__/relay-daemon.test.js.map +0 -1
  168. package/dist/__tests__/relay-ingest-contract.test.d.ts +0 -1
  169. package/dist/__tests__/relay-ingest-contract.test.js +0 -76
  170. package/dist/__tests__/relay-ingest-contract.test.js.map +0 -1
  171. package/dist/__tests__/relay-installers.test.d.ts +0 -1
  172. package/dist/__tests__/relay-installers.test.js +0 -95
  173. package/dist/__tests__/relay-installers.test.js.map +0 -1
  174. package/dist/__tests__/relay-machine-id.test.d.ts +0 -1
  175. package/dist/__tests__/relay-machine-id.test.js +0 -41
  176. package/dist/__tests__/relay-machine-id.test.js.map +0 -1
  177. package/dist/__tests__/relay-pair.test.d.ts +0 -1
  178. package/dist/__tests__/relay-pair.test.js.map +0 -1
  179. package/dist/__tests__/relay-redact.test.d.ts +0 -1
  180. package/dist/__tests__/relay-redact.test.js +0 -78
  181. package/dist/__tests__/relay-redact.test.js.map +0 -1
  182. package/dist/__tests__/relay-state.test.d.ts +0 -1
  183. package/dist/__tests__/relay-state.test.js +0 -85
  184. package/dist/__tests__/relay-state.test.js.map +0 -1
  185. package/dist/__tests__/setup-skills-block.test.d.ts +0 -1
  186. package/dist/__tests__/setup-skills-block.test.js +0 -65
  187. package/dist/__tests__/setup-skills-block.test.js.map +0 -1
  188. package/dist/__tests__/stream-json.test.d.ts +0 -1
  189. package/dist/__tests__/stream-json.test.js +0 -186
  190. package/dist/__tests__/stream-json.test.js.map +0 -1
  191. package/dist/__tests__/sync-apply.test.d.ts +0 -1
  192. package/dist/__tests__/sync-apply.test.js +0 -457
  193. package/dist/__tests__/sync-apply.test.js.map +0 -1
  194. package/dist/__tests__/sync-lock.test.d.ts +0 -1
  195. package/dist/__tests__/sync-lock.test.js +0 -105
  196. package/dist/__tests__/sync-lock.test.js.map +0 -1
  197. package/dist/__tests__/sync.test.d.ts +0 -1
  198. package/dist/__tests__/sync.test.js +0 -160
  199. package/dist/__tests__/sync.test.js.map +0 -1
  200. package/dist/__tests__/updater.test.d.ts +0 -1
  201. package/dist/__tests__/updater.test.js +0 -95
  202. package/dist/__tests__/updater.test.js.map +0 -1
  203. package/dist/__tests__/upload.test.d.ts +0 -1
  204. package/dist/__tests__/upload.test.js +0 -92
  205. package/dist/__tests__/upload.test.js.map +0 -1
  206. package/dist/__tests__/utils.test.d.ts +0 -1
  207. package/dist/__tests__/utils.test.js +0 -69
  208. package/dist/__tests__/utils.test.js.map +0 -1
  209. package/dist/adopt-cwd.d.ts +0 -69
  210. package/dist/adopt-cwd.js.map +0 -1
  211. package/dist/api.d.ts +0 -41
  212. package/dist/api.js.map +0 -1
  213. package/dist/auth.d.ts +0 -17
  214. package/dist/auth.js.map +0 -1
  215. package/dist/banner.d.ts +0 -6
  216. package/dist/banner.js.map +0 -1
  217. package/dist/capture/sources/claude-code.d.ts +0 -78
  218. package/dist/capture/sources/claude-code.js.map +0 -1
  219. package/dist/coding-guidelines.d.ts +0 -9
  220. package/dist/coding-guidelines.js.map +0 -1
  221. package/dist/colors.d.ts +0 -22
  222. package/dist/colors.js.map +0 -1
  223. package/dist/commands/add.d.ts +0 -2
  224. package/dist/commands/add.js.map +0 -1
  225. package/dist/commands/agent.d.ts +0 -2
  226. package/dist/commands/agent.js.map +0 -1
  227. package/dist/commands/api.d.ts +0 -1
  228. package/dist/commands/api.js.map +0 -1
  229. package/dist/commands/approval.d.ts +0 -2
  230. package/dist/commands/approval.js.map +0 -1
  231. package/dist/commands/audit.d.ts +0 -2
  232. package/dist/commands/audit.js.map +0 -1
  233. package/dist/commands/browser.d.ts +0 -2
  234. package/dist/commands/browser.js.map +0 -1
  235. package/dist/commands/chat.d.ts +0 -2
  236. package/dist/commands/chat.js.map +0 -1
  237. package/dist/commands/checkpoint.d.ts +0 -2
  238. package/dist/commands/checkpoint.js.map +0 -1
  239. package/dist/commands/claude.d.ts +0 -16
  240. package/dist/commands/claude.js.map +0 -1
  241. package/dist/commands/credits.d.ts +0 -2
  242. package/dist/commands/credits.js.map +0 -1
  243. package/dist/commands/db.d.ts +0 -2
  244. package/dist/commands/db.js.map +0 -1
  245. package/dist/commands/deploy.d.ts +0 -2
  246. package/dist/commands/deploy.js.map +0 -1
  247. package/dist/commands/doctor.d.ts +0 -2
  248. package/dist/commands/doctor.js.map +0 -1
  249. package/dist/commands/domain.d.ts +0 -2
  250. package/dist/commands/domain.js.map +0 -1
  251. package/dist/commands/email.d.ts +0 -2
  252. package/dist/commands/email.js.map +0 -1
  253. package/dist/commands/file.d.ts +0 -2
  254. package/dist/commands/file.js.map +0 -1
  255. package/dist/commands/fn.d.ts +0 -2
  256. package/dist/commands/fn.js.map +0 -1
  257. package/dist/commands/generate.d.ts +0 -2
  258. package/dist/commands/generate.js.map +0 -1
  259. package/dist/commands/gmail.d.ts +0 -2
  260. package/dist/commands/gmail.js.map +0 -1
  261. package/dist/commands/hook-capture.d.ts +0 -15
  262. package/dist/commands/hook-capture.js.map +0 -1
  263. package/dist/commands/init.d.ts +0 -2
  264. package/dist/commands/init.js.map +0 -1
  265. package/dist/commands/job.d.ts +0 -2
  266. package/dist/commands/job.js.map +0 -1
  267. package/dist/commands/location.d.ts +0 -9
  268. package/dist/commands/location.js.map +0 -1
  269. package/dist/commands/login.d.ts +0 -2
  270. package/dist/commands/login.js.map +0 -1
  271. package/dist/commands/logout.d.ts +0 -2
  272. package/dist/commands/logout.js.map +0 -1
  273. package/dist/commands/logs.d.ts +0 -2
  274. package/dist/commands/logs.js.map +0 -1
  275. package/dist/commands/memory.d.ts +0 -2
  276. package/dist/commands/memory.js.map +0 -1
  277. package/dist/commands/page-inspect.d.ts +0 -2
  278. package/dist/commands/page-inspect.js.map +0 -1
  279. package/dist/commands/page-screenshot.d.ts +0 -2
  280. package/dist/commands/page-screenshot.js.map +0 -1
  281. package/dist/commands/plan.d.ts +0 -2
  282. package/dist/commands/plan.js.map +0 -1
  283. package/dist/commands/project.d.ts +0 -2
  284. package/dist/commands/project.js.map +0 -1
  285. package/dist/commands/push.d.ts +0 -2
  286. package/dist/commands/push.js.map +0 -1
  287. package/dist/commands/rbac.d.ts +0 -2
  288. package/dist/commands/rbac.js.map +0 -1
  289. package/dist/commands/realtime.d.ts +0 -2
  290. package/dist/commands/realtime.js.map +0 -1
  291. package/dist/commands/records.d.ts +0 -2
  292. package/dist/commands/records.js.map +0 -1
  293. package/dist/commands/relay-install.d.ts +0 -11
  294. package/dist/commands/relay-install.js.map +0 -1
  295. package/dist/commands/relay.d.ts +0 -9
  296. package/dist/commands/relay.js.map +0 -1
  297. package/dist/commands/sandbox.d.ts +0 -2
  298. package/dist/commands/sandbox.js.map +0 -1
  299. package/dist/commands/scaffold.d.ts +0 -2
  300. package/dist/commands/scaffold.js.map +0 -1
  301. package/dist/commands/skill.d.ts +0 -2
  302. package/dist/commands/skill.js.map +0 -1
  303. package/dist/commands/skills.d.ts +0 -2
  304. package/dist/commands/skills.js.map +0 -1
  305. package/dist/commands/start-cc.d.ts +0 -2
  306. package/dist/commands/start-cc.js.map +0 -1
  307. package/dist/commands/status.d.ts +0 -2
  308. package/dist/commands/status.js.map +0 -1
  309. package/dist/commands/sync.d.ts +0 -2
  310. package/dist/commands/sync.js.map +0 -1
  311. package/dist/commands/test.d.ts +0 -2
  312. package/dist/commands/test.js.map +0 -1
  313. package/dist/commands/uninstall.d.ts +0 -10
  314. package/dist/commands/uninstall.js.map +0 -1
  315. package/dist/commands/update.d.ts +0 -2
  316. package/dist/commands/update.js.map +0 -1
  317. package/dist/commands/upload.d.ts +0 -2
  318. package/dist/commands/upload.js.map +0 -1
  319. package/dist/commands/workflow.d.ts +0 -2
  320. package/dist/commands/workflow.js.map +0 -1
  321. package/dist/config.d.ts +0 -39
  322. package/dist/config.js.map +0 -1
  323. package/dist/flag-aliases.d.ts +0 -12
  324. package/dist/flag-aliases.js.map +0 -1
  325. package/dist/gip3dw-guide.d.ts +0 -7
  326. package/dist/gip3dw-guide.js.map +0 -1
  327. package/dist/gipcc.d.ts +0 -2
  328. package/dist/gipcc.js.map +0 -1
  329. package/dist/gipccd.d.ts +0 -2
  330. package/dist/gipccd.js.map +0 -1
  331. package/dist/help-skills.d.ts +0 -7
  332. package/dist/help-skills.js.map +0 -1
  333. package/dist/helpers/command.d.ts +0 -12
  334. package/dist/helpers/command.js.map +0 -1
  335. package/dist/helpers/index.d.ts +0 -6
  336. package/dist/helpers/index.js.map +0 -1
  337. package/dist/helpers/output.d.ts +0 -22
  338. package/dist/helpers/output.js.map +0 -1
  339. package/dist/helpers/sync.d.ts +0 -13
  340. package/dist/helpers/sync.js.map +0 -1
  341. package/dist/hooks/capture-runner.d.ts +0 -24
  342. package/dist/hooks/capture-runner.js.map +0 -1
  343. package/dist/index.d.ts +0 -2
  344. package/dist/index.js.map +0 -1
  345. package/dist/knowledge.d.ts +0 -11
  346. package/dist/knowledge.js.map +0 -1
  347. package/dist/platform-overview.d.ts +0 -9
  348. package/dist/platform-overview.js.map +0 -1
  349. package/dist/project-setup.d.ts +0 -26
  350. package/dist/project-setup.js.map +0 -1
  351. package/dist/prompts.d.ts +0 -80
  352. package/dist/prompts.js.map +0 -1
  353. package/dist/provider-docs.d.ts +0 -27
  354. package/dist/provider-docs.js.map +0 -1
  355. package/dist/relay/daemon.d.ts +0 -47
  356. package/dist/relay/daemon.js.map +0 -1
  357. package/dist/relay/device-http.d.ts +0 -9
  358. package/dist/relay/device-http.js.map +0 -1
  359. package/dist/relay/installers.d.ts +0 -24
  360. package/dist/relay/installers.js.map +0 -1
  361. package/dist/relay/machine-id.d.ts +0 -2
  362. package/dist/relay/machine-id.js.map +0 -1
  363. package/dist/relay/onboarding.d.ts +0 -8
  364. package/dist/relay/onboarding.js.map +0 -1
  365. package/dist/relay/paths.d.ts +0 -5
  366. package/dist/relay/paths.js.map +0 -1
  367. package/dist/relay/redact.d.ts +0 -34
  368. package/dist/relay/redact.js.map +0 -1
  369. package/dist/relay/state.d.ts +0 -39
  370. package/dist/relay/state.js.map +0 -1
  371. package/dist/relay/stream-json.d.ts +0 -105
  372. package/dist/relay/stream-json.js.map +0 -1
  373. package/dist/relay/transcripts.d.ts +0 -60
  374. package/dist/relay/transcripts.js.map +0 -1
  375. package/dist/setup.d.ts +0 -101
  376. package/dist/setup.js.map +0 -1
  377. package/dist/sync.d.ts +0 -74
  378. package/dist/sync.js.map +0 -1
  379. package/dist/updater/bootstrap.d.ts +0 -13
  380. package/dist/updater/bootstrap.js.map +0 -1
  381. package/dist/updater/check.d.ts +0 -12
  382. package/dist/updater/check.js.map +0 -1
  383. package/dist/updater/shim.d.ts +0 -2
  384. package/dist/updater/shim.js.map +0 -1
  385. package/dist/updater/state.d.ts +0 -24
  386. package/dist/updater/state.js.map +0 -1
  387. package/dist/upload.d.ts +0 -40
  388. package/dist/upload.js.map +0 -1
  389. package/dist/utils.d.ts +0 -39
  390. package/dist/utils.js.map +0 -1
package/README.md CHANGED
@@ -141,7 +141,7 @@ gipity sync down # Pull remote changes
141
141
  | `gipity add <template>` | Add a template (web-simple, 2d-game, 3d-world, web-fullstack, api) |
142
142
  | `gipity test` | Run project tests in sandboxed containers |
143
143
  | `gipity logs fn <name>` | View function execution logs |
144
- | `gipity page-inspect <url>` | Inspect a URL: console errors, performance, failed resources |
144
+ | `gipity page inspect <url>` | Inspect a URL: console errors, performance, failed resources |
145
145
  | `gipity records` | Query and manage Records API tables |
146
146
  | `gipity fn` | Manage and call serverless functions |
147
147
  | `gipity rbac` | Manage RBAC policies |
package/dist/adopt-cwd.js CHANGED
@@ -241,6 +241,7 @@ export async function adoptCurrentDir(opts) {
241
241
  dir: opts.cwd,
242
242
  projectGuid: project.short_guid,
243
243
  projectSlug: project.slug,
244
+ projectName: project.name,
244
245
  accountSlug: opts.accountSlug,
245
246
  agentGuid,
246
247
  sync: 'strict',
@@ -1,3 +1,6 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import os from 'os';
1
4
  import { Command } from 'commander';
2
5
  import { post } from '../api.js';
3
6
  import { requireConfig } from '../config.js';
@@ -27,12 +30,113 @@ function printCatalog() {
27
30
  for (const k of KITS)
28
31
  console.log(` ${k.key} ${muted('- ' + k.hint)}`);
29
32
  console.log('');
30
- console.log(muted('Usage: gipity add <name> [--title <t>] [--description <d>] [--force]'));
33
+ console.log(`${bold('Local path')} ${muted('- install from a directory on disk (template or kit)')}`);
34
+ console.log(` ${muted('gipity add ./path/to/template (or ~/path, /abs/path)')}`);
35
+ console.log(` ${muted('gipity add ./path/to/kit (auto-detected via package.json gipity.install)')}`);
31
36
  console.log('');
37
+ console.log(muted('Usage: gipity add <name|path> [--title <t>] [--description <d>] [--force]'));
38
+ console.log('');
39
+ }
40
+ // ─── Local-path payload mode ────────────────────────────────────────────────
41
+ //
42
+ // `gipity add ./path/to/template` walks a directory and ships the contents to
43
+ // the server as a JSON payload, instead of asking the server to look the name
44
+ // up in its bundled catalog. This is the dev loop for template authors: you
45
+ // can iterate on `registry/templates/<name>/` and push to a real app without
46
+ // having to redeploy the server.
47
+ //
48
+ // The server-side wire shape this builds matches addSchema.files in
49
+ // platform/server/src/routes/projects/add.ts (same field names, same encoding
50
+ // discriminator).
51
+ const TEXT_EXTENSIONS = new Set([
52
+ '.html', '.htm', '.css', '.js', '.mjs', '.ts', '.tsx', '.jsx',
53
+ '.json', '.yaml', '.yml', '.toml',
54
+ '.md', '.markdown', '.txt', '.csv', '.xml', '.svg',
55
+ '.py', '.sh', '.bash', '.sql',
56
+ '.env', '.gitignore', '.dockerignore',
57
+ ]);
58
+ // Anything not in TEXT_EXTENSIONS gets base64 - safer than guessing. The
59
+ // server-side BINARY_MIME table maps the extension back to a content-type.
60
+ const SKIP_DIR_NAMES = new Set([
61
+ 'node_modules', '.git', 'dist', 'build', '__pycache__', '.next', '.vite',
62
+ '.gipity', // local project state dir - never belongs in a template payload
63
+ ]);
64
+ const SKIP_FILE_NAMES = new Set(['.DS_Store', 'Thumbs.db']);
65
+ const MAX_PAYLOAD_BYTES = 25 * 1024 * 1024; // 25 MB (server caps body at 30 MB)
66
+ const MAX_FILES = 500;
67
+ function looksLikePath(name) {
68
+ // ./ or ../ or absolute / or ~/ - and any string that already contains a
69
+ // separator (cross-platform: forward or back slash). Bare catalog keys like
70
+ // "web-simple" or "karaoke-captions" hit the server lookup path; anything
71
+ // that walks a filesystem hits payload mode.
72
+ return /^[./~]/.test(name) || name.includes('/') || name.includes('\\');
73
+ }
74
+ function resolveLocalPath(input) {
75
+ if (input.startsWith('~'))
76
+ return path.resolve(os.homedir() + input.slice(1));
77
+ return path.resolve(input);
78
+ }
79
+ /** Sniff whether a local-path payload is a kit or a template, mirroring the
80
+ * server-side sniff in routes/projects/add.ts. Templates ship `gipity.yaml`
81
+ * at the root; kits ship `package.json` with a `gipity.install` block. The
82
+ * CLI sends the result as a `kind` hint so the server doesn't have to
83
+ * re-do the sniff on the encoded payload. */
84
+ function sniffPayloadKind(files) {
85
+ const pkg = files.find(f => f.path === 'package.json');
86
+ if (!pkg)
87
+ return 'template';
88
+ if (pkg.encoding !== 'utf8')
89
+ return 'template'; // base64'd package.json would be weird; default to template
90
+ try {
91
+ const manifest = JSON.parse(pkg.content);
92
+ if (manifest?.gipity?.install)
93
+ return 'kit';
94
+ }
95
+ catch { /* fall through */ }
96
+ return 'template';
97
+ }
98
+ function buildLocalPayload(rootDir) {
99
+ const stat = fs.statSync(rootDir);
100
+ if (!stat.isDirectory()) {
101
+ throw new Error(`Not a directory: ${rootDir}`);
102
+ }
103
+ const files = [];
104
+ let totalBytes = 0;
105
+ function walk(dir, prefix) {
106
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
107
+ if (entry.isDirectory()) {
108
+ if (SKIP_DIR_NAMES.has(entry.name))
109
+ continue;
110
+ walk(path.join(dir, entry.name), prefix ? `${prefix}/${entry.name}` : entry.name);
111
+ continue;
112
+ }
113
+ if (!entry.isFile())
114
+ continue; // skip symlinks, sockets, etc.
115
+ if (SKIP_FILE_NAMES.has(entry.name))
116
+ continue;
117
+ if (files.length >= MAX_FILES) {
118
+ throw new Error(`Too many files (>${MAX_FILES}). Trim the template or raise the server cap.`);
119
+ }
120
+ const fullPath = path.join(dir, entry.name);
121
+ const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
122
+ const ext = path.extname(entry.name).toLowerCase();
123
+ const buf = fs.readFileSync(fullPath);
124
+ const isText = TEXT_EXTENSIONS.has(ext);
125
+ const content = isText ? buf.toString('utf8') : buf.toString('base64');
126
+ const encoding = isText ? 'utf8' : 'base64';
127
+ totalBytes += content.length;
128
+ if (totalBytes > MAX_PAYLOAD_BYTES) {
129
+ throw new Error(`Payload exceeds ${Math.round(MAX_PAYLOAD_BYTES / 1024 / 1024)} MB cap.`);
130
+ }
131
+ files.push({ path: relPath, content, encoding });
132
+ }
133
+ }
134
+ walk(rootDir, '');
135
+ return { name: path.basename(rootDir), files };
32
136
  }
33
137
  export const addCommand = new Command('add')
34
- .description('Add a template (scaffold an app) or a kit (reusable building block) to the project')
35
- .argument('[name]', 'Template or kit key - omit to list the catalog')
138
+ .description('Add a template (scaffold an app) or a kit (reusable building block) to the project. Pass ./path/to/dir to install a local template directly.')
139
+ .argument('[name]', 'Template/kit key, OR a local directory path (./, ~/, or /abs). Omit to list the catalog.')
36
140
  .option('--title <title>', 'App title - templates only (defaults to project name)')
37
141
  .option('--description <desc>', 'App description for meta tags - templates only')
38
142
  .option('--force', 'Templates only: overwrite any colliding files')
@@ -43,12 +147,35 @@ export const addCommand = new Command('add')
43
147
  return;
44
148
  }
45
149
  const config = requireConfig();
46
- const res = await post(`/projects/${config.projectGuid}/add`, {
47
- name,
48
- title: opts.title,
49
- description: opts.description,
50
- force: opts.force,
51
- });
150
+ // Local-path payload mode kicks in when `name` looks like a path - bare
151
+ // names still go through the server's bundled catalog like before.
152
+ let body;
153
+ if (looksLikePath(name)) {
154
+ const resolved = resolveLocalPath(name);
155
+ if (!fs.existsSync(resolved)) {
156
+ throw new Error(`Local template/kit not found: ${resolved}`);
157
+ }
158
+ const { name: labelName, files } = buildLocalPayload(resolved);
159
+ const kind = sniffPayloadKind(files);
160
+ console.log(muted(`Uploading ${files.length} file(s) from ${resolved} (${kind}) ...`));
161
+ body = {
162
+ name: labelName,
163
+ title: opts.title,
164
+ description: opts.description,
165
+ force: opts.force,
166
+ files,
167
+ kind,
168
+ };
169
+ }
170
+ else {
171
+ body = {
172
+ name,
173
+ title: opts.title,
174
+ description: opts.description,
175
+ force: opts.force,
176
+ };
177
+ }
178
+ const res = await post(`/projects/${config.projectGuid}/add`, body);
52
179
  // Pull the created/installed files down to local.
53
180
  const syncResult = await sync({ interactive: false });
54
181
  const data = res.data;
@@ -33,4 +33,83 @@ logsCommand
33
33
  console.log(` ${muted(time)} ${status} ${dur} ${trigger}${err}`);
34
34
  }
35
35
  }));
36
+ logsCommand
37
+ .command('app')
38
+ .description('Unified recent activity for this app — JS errors, failed function calls, failed services, network failures. Designed for agents debugging a deployed app.')
39
+ .option('--since <window>', "Window: 5m / 10m / 30m / 1h / 6h / 24h / 7d", '10m')
40
+ .option('--severity <level>', 'error | warn | network | all', 'all')
41
+ .option('--type <list>', "Comma-separated: errors,functions,services,traffic. Default excludes traffic (high volume).")
42
+ .option('--filter <pattern>', 'Substring match against message / fn name / path (case-insensitive)')
43
+ .option('--limit <n>', 'Max entries', '100')
44
+ .option('--json', 'Output as JSON (parseable by agents / pipes)')
45
+ .addHelpText('after', `
46
+ Examples:
47
+ $ gipity logs app Last 10 min of errors + fn failures
48
+ $ gipity logs app --since 1h Last hour
49
+ $ gipity logs app --severity network Only fetch/XHR failures
50
+ $ gipity logs app --filter song-create Anything mentioning song-create
51
+ $ gipity logs app --type errors Only JS errors
52
+ $ gipity logs app --json | jq .data.entries[0] Pipe-friendly
53
+ `)
54
+ .action((opts) => run('App logs', async () => {
55
+ const config = requireConfig();
56
+ const limit = parseInt(opts.limit, 10) || 100;
57
+ const qs = new URLSearchParams();
58
+ qs.set('since', String(opts.since));
59
+ qs.set('severity', String(opts.severity));
60
+ if (opts.type)
61
+ qs.set('type', String(opts.type));
62
+ if (opts.filter)
63
+ qs.set('filter', String(opts.filter));
64
+ qs.set('limit', String(limit));
65
+ const res = await get(`/projects/${config.projectGuid}/logs/app?${qs.toString()}`);
66
+ if (opts.json) {
67
+ console.log(JSON.stringify(res.data));
68
+ return;
69
+ }
70
+ const { entries, since, types, severity, truncated } = res.data;
71
+ if (entries.length === 0) {
72
+ console.log(`No activity in the last ${since} ${muted(`(severity=${severity} types=${types.join(',')})`)}.`);
73
+ return;
74
+ }
75
+ console.log(`${bold(`Recent activity`)} ${muted(`(last ${since}, ${entries.length}${truncated ? '+' : ''} entries, severity=${severity})`)}\n`);
76
+ for (const e of entries) {
77
+ const time = new Date(e.at).toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' });
78
+ const kindColor = e.kind === 'error' ? clrError : e.kind === 'function' ? warning : e.kind === 'service' ? warning : muted;
79
+ const kindTag = kindColor(`[${e.kind.padEnd(8)}]`);
80
+ console.log(`${muted(time)} ${kindTag} ${e.summary}`);
81
+ // Per-kind drilldown lines — what an agent most often needs without
82
+ // having to re-fetch the row.
83
+ const d = e.detail;
84
+ if (e.kind === 'error') {
85
+ const capturedBy = d.captured_by;
86
+ const url = d.network_url;
87
+ const status = d.network_status;
88
+ if (url)
89
+ console.log(` ${muted(`${capturedBy} → ${d.network_method || 'GET'} ${url} (${status ?? 'failed'})`)}`);
90
+ if (d.network_response_snippet)
91
+ console.log(` ${muted(`resp: ${String(d.network_response_snippet).slice(0, 160)}`)}`);
92
+ const corr = d.correlated_function_log;
93
+ if (corr) {
94
+ console.log(` ${muted(`└─ server fn ${corr.function_name} → ${corr.status}${corr.error_message ? ': ' + String(corr.error_message).slice(0, 100) : ''}`)}`);
95
+ }
96
+ const breadcrumbs = d.breadcrumbs;
97
+ if (breadcrumbs && breadcrumbs.length > 0) {
98
+ const lastFew = breadcrumbs.slice(-3).map(b => `${b.kind}${b.detail?.selector || b.detail?.url || b.detail?.path ? `:${b.detail.selector || b.detail.url || b.detail.path}` : ''}`).join(' → ');
99
+ console.log(` ${muted(`crumbs: ${lastFew}`)}`);
100
+ }
101
+ }
102
+ if (e.kind === 'function') {
103
+ const dur = d.duration_ms;
104
+ console.log(` ${muted(`${d.trigger_type} • ${dur ?? '?'}ms`)}${d.error_message ? muted(' • ') + clrError(String(d.error_message).slice(0, 200)) : ''}`);
105
+ }
106
+ if (e.kind === 'service') {
107
+ const dur = d.latency_ms;
108
+ console.log(` ${muted(`${d.service} (${d.provider ?? '?'}/${d.model ?? '?'}) • ${dur ?? '?'}ms`)}${d.error_message ? muted(' • ') + clrError(String(d.error_message).slice(0, 200)) : ''}`);
109
+ }
110
+ }
111
+ if (truncated) {
112
+ console.log(`\n${muted(`(truncated at ${limit} entries — bump --limit or narrow --filter)`)}`);
113
+ }
114
+ }));
36
115
  //# sourceMappingURL=logs.js.map
@@ -0,0 +1,31 @@
1
+ import { Command } from 'commander';
2
+ import { post } from '../api.js';
3
+ import { brand, bold, muted } from '../colors.js';
4
+ import { run } from '../helpers/index.js';
5
+ // The long-tail escape hatch alongside `page inspect`'s fixed bundle: when the
6
+ // curated metrics don't cover what you need (computed styles, element rects,
7
+ // visibility, z-index stacks), eval an expression in page context and get the
8
+ // serialized result back. Runs in the same browser sandbox as inspect.
9
+ export const pageEvalCommand = new Command('eval')
10
+ .description('Evaluate a JS expression in a real browser on a page (DOM, computed styles, element rects)')
11
+ .argument('<url>', 'URL to load')
12
+ .argument('<expr>', 'JavaScript expression to evaluate in page context (result is JSON-serialized)')
13
+ .option('--wait <ms>', 'Sleep this many ms after DOMContentLoaded before evaluating (lets late async work settle)', '500')
14
+ .option('--json', 'Output as JSON')
15
+ .action((url, expr, opts) => run('Page eval', async () => {
16
+ const parsedWait = parseInt(opts.wait, 10);
17
+ const waitMs = Number.isFinite(parsedWait) && parsedWait >= 0 ? parsedWait : 500;
18
+ const res = await post('/tools/browser/eval', { url, expr, waitMs });
19
+ const d = res.data;
20
+ if (opts.json) {
21
+ console.log(JSON.stringify(d));
22
+ return;
23
+ }
24
+ console.log(`\n${brand('Eval')} ${bold(d.url || url)}`);
25
+ console.log(` ${muted('Expression:')} ${expr}`);
26
+ console.log(`\n${d.result || muted('(empty result)')}`);
27
+ if (d.truncated)
28
+ console.log(muted('\n(result truncated to fit context - narrow the expression for the full value)'));
29
+ console.log('');
30
+ }));
31
+ //# sourceMappingURL=page-eval.js.map
@@ -1,4 +1,4 @@
1
- import { Command } from 'commander';
1
+ import { Command, Option } from 'commander';
2
2
  import { post } from '../api.js';
3
3
  import { formatSize } from '../utils.js';
4
4
  import { brand, bold, error as clrError, warning, muted, info } from '../colors.js';
@@ -19,78 +19,107 @@ function shortUrl(url, truncate = true, maxLen = 100) {
19
19
  const tailLen = Math.floor(keep / 2);
20
20
  return result.slice(0, headLen) + '…' + result.slice(-tailLen);
21
21
  }
22
- export const pageInspectCommand = new Command('page-inspect')
23
- .description('Inspect a web page')
22
+ export const pageInspectCommand = new Command('inspect')
23
+ .description('Inspect a web page (console, failed resources, timing, layout overflow)')
24
24
  .argument('<url>', 'URL to inspect')
25
25
  .option('--wait <ms>', 'Sleep this many ms after DOMContentLoaded before capturing (lets late async/LCP work settle)', '500')
26
26
  .option('--json', 'Output as JSON')
27
27
  .option('--no-truncate', 'Show full URLs instead of truncating long ones with middle-ellipsis')
28
- .option('--all', 'Include render-blocking, large resources, oversized images, and LCP detail')
29
- .action((url, opts) => run('Page inspect', async () => {
30
- const parsedWait = parseInt(opts.wait, 10);
31
- const waitMs = Number.isFinite(parsedWait) && parsedWait >= 0 ? parsedWait : 500;
32
- const truncate = opts.truncate !== false;
33
- const showAll = opts.all === true;
34
- const res = await post(`/tools/browser/inspect`, { url, waitMs });
35
- const b = res.data;
36
- if (opts.json) {
37
- console.log(JSON.stringify(b));
38
- return;
28
+ .option('--all', 'Include render-blocking, large resources, oversized images, overflow culprits, and LCP detail')
29
+ // Hidden redirect: agents reach for `page inspect --screenshot`. We don't take
30
+ // an image here (`page screenshot` is the single path for that) — just point there.
31
+ .addOption(new Option('--screenshot [path]', 'Capture a screenshot').hideHelp())
32
+ .action((url, opts) => {
33
+ if (opts.screenshot !== undefined) {
34
+ console.error(clrError('page inspect does not capture screenshots. Use page screenshot:'));
35
+ console.error(` gipity page screenshot ${url}${typeof opts.screenshot === 'string' ? ` -o ${opts.screenshot}` : ''}`);
36
+ process.exit(1);
39
37
  }
40
- const timing = b.timing || { ttfb: 0, domReady: 0, load: 0 };
41
- // ── Page Info ──
42
- console.log(`\n${brand('Inspecting')} ${bold(b.url || url)}`);
43
- console.log(` ${muted('Title:')} ${b.title || '(none)'}`);
44
- console.log(` ${muted('Elements:')} ${b.elementCount || 0}`);
45
- console.log(` ${muted('Page weight:')} ${info(formatSize(b.totalBytes || 0))}`);
46
- // ── Timing ──
47
- console.log(`\n ${bold('Timing:')}`);
48
- console.log(` ${muted('TTFB:')} ${timing.ttfb}ms`);
49
- console.log(` ${muted('DOM ready:')} ${timing.domReady}ms`);
50
- console.log(` ${muted('Load:')} ${timing.load}ms`);
51
- if (showAll && b.lcp) {
52
- console.log(` LCP: ${b.lcp.time}ms (${b.lcp.element}${b.lcp.url ? ' ' + shortUrl(b.lcp.url, truncate) : ''})`);
53
- }
54
- // ── Console ──
55
- if (b.console?.length > 0) {
56
- console.log(`\n ${bold('Console')} ${muted(`(${b.console.length})`)}:`);
57
- for (const line of b.console) {
58
- console.log(` ${warning(line)}`);
38
+ return run('Page inspect', async () => {
39
+ const parsedWait = parseInt(opts.wait, 10);
40
+ const waitMs = Number.isFinite(parsedWait) && parsedWait >= 0 ? parsedWait : 500;
41
+ const truncate = opts.truncate !== false;
42
+ const showAll = opts.all === true;
43
+ const res = await post(`/tools/browser/inspect`, { url, waitMs });
44
+ const b = res.data;
45
+ if (opts.json) {
46
+ console.log(JSON.stringify(b));
47
+ return;
59
48
  }
60
- }
61
- else {
62
- console.log(`\n ${bold('Console:')} ${muted('(clean)')}`);
63
- }
64
- // ── Failed Resources ──
65
- if (b.failedResources?.length > 0) {
66
- console.log(`\n ${clrError(`Failed resources (${b.failedResources.length}):`)}`);
67
- for (const r of b.failedResources) {
68
- console.log(` ${clrError(r)}`);
49
+ const timing = b.timing || { ttfb: 0, domReady: 0, load: 0 };
50
+ // ── Page Info ──
51
+ console.log(`\n${brand('Inspecting')} ${bold(b.url || url)}`);
52
+ console.log(` ${muted('Title:')} ${b.title || '(none)'}`);
53
+ console.log(` ${muted('Elements:')} ${b.elementCount || 0}`);
54
+ console.log(` ${muted('Page weight:')} ${info(formatSize(b.totalBytes || 0))}`);
55
+ // ── Timing ──
56
+ console.log(`\n ${bold('Timing:')}`);
57
+ console.log(` ${muted('TTFB:')} ${timing.ttfb}ms`);
58
+ console.log(` ${muted('DOM ready:')} ${timing.domReady}ms`);
59
+ console.log(` ${muted('Load:')} ${timing.load}ms`);
60
+ if (showAll && b.lcp) {
61
+ console.log(` LCP: ${b.lcp.time}ms (${b.lcp.element}${b.lcp.url ? ' ' + shortUrl(b.lcp.url, truncate) : ''})`);
69
62
  }
70
- }
71
- if (showAll) {
72
- // ── Render Blocking ──
73
- if (b.renderBlocking?.length > 0) {
74
- console.log(`\n ${warning(`Render-blocking (${b.renderBlocking.length}):`)}`);
75
- for (const r of b.renderBlocking) {
76
- console.log(` ${shortUrl(r, truncate)}`);
63
+ // ── Console ──
64
+ if (b.console?.length > 0) {
65
+ console.log(`\n ${bold('Console')} ${muted(`(${b.console.length})`)}:`);
66
+ for (const line of b.console) {
67
+ console.log(` ${warning(line)}`);
77
68
  }
78
69
  }
79
- // ── Large Resources ──
80
- if (b.largeResources?.length > 0) {
81
- console.log(`\n ${warning(`Large resources >100KB (${b.largeResources.length}):`)}`);
82
- for (const r of b.largeResources) {
83
- console.log(` ${info(formatSize(r.size).padEnd(10))} ${muted(r.type.padEnd(8))} ${shortUrl(r.url, truncate)}`);
70
+ else {
71
+ console.log(`\n ${bold('Console:')} ${muted('(clean)')}`);
72
+ }
73
+ // ── Failed Resources ──
74
+ if (b.failedResources?.length > 0) {
75
+ console.log(`\n ${clrError(`Failed resources (${b.failedResources.length}):`)}`);
76
+ for (const r of b.failedResources) {
77
+ console.log(` ${clrError(r)}`);
84
78
  }
85
79
  }
86
- // ── Oversized Images ──
87
- if (b.oversizedImages?.length > 0) {
88
- console.log(`\n ${warning(`Oversized images (${b.oversizedImages.length}):`)}`);
89
- for (const img of b.oversizedImages) {
90
- console.log(` ${img.natural} served, ${img.displayed} displayed - ${shortUrl(img.src, truncate)}`);
80
+ // ── Layout (horizontal overflow) ──
81
+ if (b.overflow) {
82
+ if (b.overflow.overflowX) {
83
+ console.log(`\n ${clrError(`Horizontal overflow: +${b.overflow.amount}px`)} ${muted(`(content ${b.overflow.scrollWidth}px vs viewport ${b.overflow.clientWidth}px)`)}`);
84
+ if (showAll && b.overflow.culprits.length > 0) {
85
+ console.log(` ${muted('Overflowing elements:')}`);
86
+ for (const c of b.overflow.culprits) {
87
+ const sel = c.cls ? `${c.tag}.${c.cls.split(/\s+/)[0]}` : c.tag;
88
+ console.log(` ${sel} ${muted(`(right ${c.right}px, width ${c.width}px)`)}`);
89
+ }
90
+ }
91
+ else if (b.overflow.culprits.length > 0) {
92
+ console.log(` ${muted(`${b.overflow.culprits.length} overflowing element(s) - use --all to list`)}`);
93
+ }
94
+ }
95
+ else {
96
+ console.log(`\n ${bold('Layout:')} ${muted('no horizontal overflow')}`);
91
97
  }
92
98
  }
93
- }
94
- console.log('');
95
- }));
99
+ if (showAll) {
100
+ // ── Render Blocking ──
101
+ if (b.renderBlocking?.length > 0) {
102
+ console.log(`\n ${warning(`Render-blocking (${b.renderBlocking.length}):`)}`);
103
+ for (const r of b.renderBlocking) {
104
+ console.log(` ${shortUrl(r, truncate)}`);
105
+ }
106
+ }
107
+ // ── Large Resources ──
108
+ if (b.largeResources?.length > 0) {
109
+ console.log(`\n ${warning(`Large resources >100KB (${b.largeResources.length}):`)}`);
110
+ for (const r of b.largeResources) {
111
+ console.log(` ${info(formatSize(r.size).padEnd(10))} ${muted(r.type.padEnd(8))} ${shortUrl(r.url, truncate)}`);
112
+ }
113
+ }
114
+ // ── Oversized Images ──
115
+ if (b.oversizedImages?.length > 0) {
116
+ console.log(`\n ${warning(`Oversized images (${b.oversizedImages.length}):`)}`);
117
+ for (const img of b.oversizedImages) {
118
+ console.log(` ${img.natural} served, ${img.displayed} displayed - ${shortUrl(img.src, truncate)}`);
119
+ }
120
+ }
121
+ }
122
+ console.log('');
123
+ });
124
+ });
96
125
  //# sourceMappingURL=page-inspect.js.map
@@ -91,7 +91,7 @@ function splitCsv(values) {
91
91
  function appendOption(value, previous = []) {
92
92
  return [...previous, value];
93
93
  }
94
- export const pageScreenshotCommand = new Command('page-screenshot')
94
+ export const pageScreenshotCommand = new Command('screenshot')
95
95
  .description('Screenshot a web page')
96
96
  .argument('<url>', 'URL to screenshot')
97
97
  .option('--post-load-delay <ms>', 'Delay after DOMContentLoaded before capture, in ms', '1000')
@@ -0,0 +1,18 @@
1
+ import { Command } from 'commander';
2
+ import { pageInspectCommand } from './page-inspect.js';
3
+ import { pageScreenshotCommand } from './page-screenshot.js';
4
+ import { pageEvalCommand } from './page-eval.js';
5
+ // Parent namespace grouping the page/browser diagnostics under one command:
6
+ // gipity page inspect | eval | screenshot
7
+ // Each subcommand is canonical for its capability; the namespace keeps the
8
+ // top-level surface lean and makes the siblings discoverable via `page --help`.
9
+ export const pageCommand = new Command('page')
10
+ .description('Inspect, evaluate, and screenshot web pages (page inspect | eval | screenshot)')
11
+ .addCommand(pageInspectCommand)
12
+ .addCommand(pageEvalCommand)
13
+ .addCommand(pageScreenshotCommand);
14
+ // No subcommand → show help instead of commander's terse error.
15
+ pageCommand.action(() => {
16
+ pageCommand.help();
17
+ });
18
+ //# sourceMappingURL=page.js.map
@@ -85,6 +85,7 @@ projectCommand
85
85
  dir,
86
86
  projectGuid: project.short_guid,
87
87
  projectSlug: project.slug,
88
+ projectName: project.name,
88
89
  accountSlug,
89
90
  agentGuid,
90
91
  sync: 'soft',
@@ -3,10 +3,7 @@ import { get, post, put, del } from '../api.js';
3
3
  import { requireConfig } from '../config.js';
4
4
  import { success, error as clrError, muted, bold } from '../colors.js';
5
5
  import { run, printList, printResult } from '../helpers/index.js';
6
- export const workflowCommand = new Command('workflow')
7
- .description('Manage workflows')
8
- .option('--json', 'Output as JSON')
9
- .action((opts) => run('Workflow', async () => {
6
+ async function listWorkflows(opts) {
10
7
  const res = await get('/workflows');
11
8
  if (opts.json) {
12
9
  console.log(JSON.stringify(res));
@@ -23,7 +20,16 @@ export const workflowCommand = new Command('workflow')
23
20
  const line = `${bold(w.name)} [${statusText}] ${muted(w.trigger_type)}${cron}${proj}`;
24
21
  return w.description ? `${line}\n ${muted(w.description)}` : line;
25
22
  });
26
- }));
23
+ }
24
+ export const workflowCommand = new Command('workflow')
25
+ .description('Manage workflows')
26
+ .option('--json', 'Output as JSON')
27
+ .action((opts) => run('Workflow', () => listWorkflows(opts)));
28
+ workflowCommand
29
+ .command('list')
30
+ .description('List workflows')
31
+ .option('--json', 'Output as JSON')
32
+ .action((opts) => run('List', () => listWorkflows(opts)));
27
33
  workflowCommand
28
34
  .command('info <name>')
29
35
  .description('Show workflow details')
@@ -71,7 +77,9 @@ workflowCommand
71
77
  ? `${((new Date(r.completed_at).getTime() - new Date(r.started_at).getTime()) / 1000).toFixed(1)}s`
72
78
  : 'running';
73
79
  const statusColor = r.status === 'completed' ? success : r.status === 'failed' ? clrError : muted;
74
- return `${muted(r.short_guid)} ${statusColor(r.status)} ${dur} ${r.total_tokens} tokens ${muted(new Date(r.started_at).toLocaleString())}`;
80
+ const line = `${muted(r.short_guid)} ${statusColor(r.status)} ${dur} ${r.total_tokens} tokens ${muted(new Date(r.started_at).toLocaleString())}`;
81
+ // Surface why a run failed inline so you don't have to hit the REST API.
82
+ return r.error_message ? `${line}\n ${clrError(r.error_message)}` : line;
75
83
  });
76
84
  }));
77
85
  workflowCommand
@@ -80,8 +88,12 @@ workflowCommand
80
88
  .option('--json', 'Output as JSON')
81
89
  .action((name, opts) => run('Enable', async () => {
82
90
  const wf = await resolveWorkflow(name);
83
- await put(`/workflows/${wf.short_guid}`, { is_active: true });
84
- printResult(`Enabled "${wf.name}".`, opts, { enabled: wf.name });
91
+ const res = await put(`/workflows/${wf.short_guid}`, { is_active: true });
92
+ if (!res.data?.is_active) {
93
+ console.error(clrError(`Workflow "${wf.name}" is still inactive after enable — not enabled.`));
94
+ process.exit(1);
95
+ }
96
+ printResult(`Enabled "${wf.name}".`, opts, { enabled: wf.name, is_active: true });
85
97
  }));
86
98
  workflowCommand
87
99
  .command('disable <name>')
@@ -89,8 +101,12 @@ workflowCommand
89
101
  .option('--json', 'Output as JSON')
90
102
  .action((name, opts) => run('Disable', async () => {
91
103
  const wf = await resolveWorkflow(name);
92
- await put(`/workflows/${wf.short_guid}`, { is_active: false });
93
- printResult(`Disabled "${wf.name}".`, opts, { disabled: wf.name });
104
+ const res = await put(`/workflows/${wf.short_guid}`, { is_active: false });
105
+ if (res.data?.is_active) {
106
+ console.error(clrError(`Workflow "${wf.name}" is still active after disable — not disabled.`));
107
+ process.exit(1);
108
+ }
109
+ printResult(`Disabled "${wf.name}".`, opts, { disabled: wf.name, is_active: false });
94
110
  }));
95
111
  workflowCommand
96
112
  .command('create')
@@ -132,15 +148,46 @@ workflowCommand
132
148
  .action((name, opts) => run('Delete', async () => {
133
149
  const wf = await resolveWorkflow(name);
134
150
  await del(`/workflows/${wf.short_guid}`);
135
- printResult(`Deleted "${wf.name}".`, opts, { deleted: wf.name });
151
+ // Delete is a soft-delete (is_active → 0). Verify the targeted record
152
+ // actually went inactive rather than trusting the request was accepted.
153
+ const after = await get(`/workflows/${wf.short_guid}`);
154
+ if (after.data?.is_active) {
155
+ console.error(clrError(`Workflow "${wf.name}" (${wf.short_guid}) is still active — delete had no effect.`));
156
+ process.exit(1);
157
+ }
158
+ printResult(`Deleted "${wf.name}".`, opts, { deleted: wf.name, short_guid: wf.short_guid });
136
159
  }));
160
+ // Resolve a workflow by name within the linked project (like `gipity fn`), or
161
+ // by short_guid anywhere. Names are unique per active project workflow (DB
162
+ // constraint), so a bare name in this project is unambiguous; the same name in
163
+ // another project is a different workflow and simply isn't matched here.
137
164
  async function resolveWorkflow(name) {
138
- const res = await get('/workflows');
139
- const match = res.data.find(w => w.name === name || w.short_guid === name);
140
- if (!match) {
141
- console.error(clrError(`Workflow "${name}" not found.`));
165
+ const { projectGuid } = requireConfig();
166
+ const res = await get(`/projects/${projectGuid}/workflows`);
167
+ const list = res.data ?? [];
168
+ // Exact short_guid match wins — unambiguous override.
169
+ const byGuid = list.find(w => w.short_guid === name);
170
+ if (byGuid)
171
+ return byGuid;
172
+ const byName = list.filter(w => w.name === name);
173
+ if (byName.length === 0) {
174
+ // Fall back to a global short_guid lookup (e.g. account-level workflows).
175
+ const all = await get('/workflows');
176
+ const global = (all.data ?? []).find(w => w.short_guid === name);
177
+ if (global)
178
+ return global;
179
+ console.error(clrError(`Workflow "${name}" not found in this project.`));
142
180
  process.exit(1);
143
181
  }
144
- return match;
182
+ if (byName.length === 1)
183
+ return byName[0];
184
+ // More than one (an active + soft-deleted carrying the same name): prefer the
185
+ // active one; refuse if still ambiguous.
186
+ const active = byName.filter(w => w.is_active);
187
+ if (active.length === 1)
188
+ return active[0];
189
+ console.error(clrError(`${byName.length} workflows named "${name}" in this project — pass a short_guid:\n` +
190
+ byName.map(w => ` ${w.short_guid}${w.is_active ? '' : ' (inactive)'}`).join('\n')));
191
+ process.exit(1);
145
192
  }
146
193
  //# sourceMappingURL=workflow.js.map