crewly 1.5.8 → 1.5.10

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 (265) hide show
  1. package/config/skills/_common/lib.sh +47 -0
  2. package/config/skills/agent/browse-stealth/execute.sh +7 -7
  3. package/config/skills/agent/competitor-content-tracker/execute.sh +13 -13
  4. package/config/skills/agent/content-calendar/execute.sh +29 -29
  5. package/config/skills/agent/content-repurposer/execute.sh +8 -8
  6. package/config/skills/agent/content-writer/execute.sh +22 -22
  7. package/config/skills/agent/core/accept-task/execute.sh +6 -6
  8. package/config/skills/agent/core/block-task/execute.sh +5 -5
  9. package/config/skills/agent/core/check-quality-gates/execute.sh +5 -5
  10. package/config/skills/agent/core/complete-task/execute.sh +13 -13
  11. package/config/skills/agent/core/generate-pdf/execute.sh +4 -4
  12. package/config/skills/agent/core/get-my-context/execute.sh +5 -5
  13. package/config/skills/agent/core/get-my-tasks/execute.sh +4 -4
  14. package/config/skills/agent/core/get-sops/execute.sh +4 -4
  15. package/config/skills/agent/core/get-team-norms/execute.sh +4 -4
  16. package/config/skills/agent/core/handoff-task/execute.sh +8 -8
  17. package/config/skills/agent/core/manage-knowledge/execute.sh +14 -14
  18. package/config/skills/agent/core/marketplace-search/execute.sh +6 -6
  19. package/config/skills/agent/core/query-knowledge/execute.sh +5 -5
  20. package/config/skills/agent/core/read-task/execute.sh +2 -2
  21. package/config/skills/agent/core/recall/execute.sh +5 -5
  22. package/config/skills/agent/core/record-learning/execute.sh +7 -7
  23. package/config/skills/agent/core/register-self/execute.sh +6 -6
  24. package/config/skills/agent/core/remember/execute.sh +9 -9
  25. package/config/skills/agent/core/report-progress/execute.sh +5 -5
  26. package/config/skills/agent/core/report-status/execute.sh +14 -14
  27. package/config/skills/agent/core/save-working-state/execute.sh +5 -5
  28. package/config/skills/agent/core/schedule-check/execute.sh +9 -9
  29. package/config/skills/agent/core/send-chat-response/execute.sh +5 -5
  30. package/config/skills/agent/core/send-message/execute.sh +6 -5
  31. package/config/skills/agent/core/update-team-norm/execute.sh +9 -9
  32. package/config/skills/agent/core/update-user-profile/execute.sh +2 -2
  33. package/config/skills/agent/marketing/brand-onboarding/execute.sh +8 -8
  34. package/config/skills/agent/marketing/submit-for-approval/execute.sh +10 -10
  35. package/config/skills/agent/marketing/weekly-content-planning/execute.sh +8 -8
  36. package/config/skills/agent/marketing/weekly-marketing-report/execute.sh +5 -5
  37. package/config/skills/agent/trend-monitor/execute.sh +12 -12
  38. package/config/skills/auditor/score-task/execute.sh +4 -4
  39. package/config/skills/orchestrator/assign-task/execute.sh +1 -1
  40. package/config/skills/orchestrator/assign-team-to-project/execute.sh +2 -2
  41. package/config/skills/orchestrator/broadcast/execute.sh +2 -2
  42. package/config/skills/orchestrator/broadcast-to-org/execute.sh +3 -3
  43. package/config/skills/orchestrator/cancel-all-schedules/execute.sh +3 -3
  44. package/config/skills/orchestrator/cancel-cron/execute.sh +2 -2
  45. package/config/skills/orchestrator/cancel-schedule/execute.sh +2 -2
  46. package/config/skills/orchestrator/complete-task/execute.sh +1 -1
  47. package/config/skills/orchestrator/create-cron/execute.sh +6 -6
  48. package/config/skills/orchestrator/create-project/execute.sh +2 -2
  49. package/config/skills/orchestrator/create-team/execute.sh +2 -2
  50. package/config/skills/orchestrator/delegate-task/execute.sh +19 -19
  51. package/config/skills/orchestrator/get-agent-logs/execute.sh +3 -3
  52. package/config/skills/orchestrator/get-agent-status/execute.sh +2 -2
  53. package/config/skills/orchestrator/get-tasks/execute.sh +2 -2
  54. package/config/skills/orchestrator/handle-agent-failure/execute.sh +7 -7
  55. package/config/skills/orchestrator/list-cron/execute.sh +3 -3
  56. package/config/skills/orchestrator/list-schedules/execute.sh +2 -2
  57. package/config/skills/orchestrator/query-knowledge/execute.sh +5 -5
  58. package/config/skills/orchestrator/read-session-logs/execute.sh +3 -3
  59. package/config/skills/orchestrator/read-system-logs/execute.sh +3 -3
  60. package/config/skills/orchestrator/recall/execute.sh +2 -2
  61. package/config/skills/orchestrator/record-failure/execute.sh +2 -2
  62. package/config/skills/orchestrator/record-learning/execute.sh +2 -2
  63. package/config/skills/orchestrator/record-success/execute.sh +2 -2
  64. package/config/skills/orchestrator/register-self/execute.sh +4 -4
  65. package/config/skills/orchestrator/remember/execute.sh +3 -3
  66. package/config/skills/orchestrator/report-bug/execute.sh +5 -5
  67. package/config/skills/orchestrator/resume-session/execute.sh +2 -2
  68. package/config/skills/orchestrator/schedule-check/execute.sh +10 -10
  69. package/config/skills/orchestrator/send-key/execute.sh +6 -6
  70. package/config/skills/orchestrator/send-message/execute.sh +7 -6
  71. package/config/skills/orchestrator/set-goal/execute.sh +2 -2
  72. package/config/skills/orchestrator/start-agent/execute.sh +3 -3
  73. package/config/skills/orchestrator/start-team/execute.sh +2 -2
  74. package/config/skills/orchestrator/stop-agent/execute.sh +3 -3
  75. package/config/skills/orchestrator/stop-team/execute.sh +2 -2
  76. package/config/skills/orchestrator/subscribe-event/execute.sh +3 -3
  77. package/config/skills/orchestrator/terminate-agent/execute.sh +2 -2
  78. package/config/skills/orchestrator/unsubscribe-event/execute.sh +2 -2
  79. package/config/skills/orchestrator/update-cron/execute.sh +3 -3
  80. package/config/skills/orchestrator/update-focus/execute.sh +2 -2
  81. package/config/skills/orchestrator/update-team/execute.sh +3 -3
  82. package/config/skills/team-leader/aggregate-results/execute.sh +7 -7
  83. package/config/skills/team-leader/decompose-goal/execute.sh +5 -5
  84. package/config/skills/team-leader/delegate-task/execute.sh +13 -13
  85. package/config/skills/team-leader/handle-failure/execute.sh +10 -10
  86. package/config/skills/team-leader/schedule-check/execute.sh +9 -9
  87. package/config/skills/team-leader/start-agent/execute.sh +4 -4
  88. package/config/skills/team-leader/stop-agent/execute.sh +4 -4
  89. package/config/skills/team-leader/verify-output/execute.sh +8 -8
  90. package/config/templates/cloud-deploy.json +119 -0
  91. package/config/templates/dev-fullstack/template.json +64 -17
  92. package/config/templates/research-analysis/template.json +44 -15
  93. package/config/templates/social-media-ops/template.json +43 -15
  94. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.d.ts +31 -0
  95. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.d.ts.map +1 -0
  96. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js +94 -0
  97. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.controller.js.map +1 -0
  98. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.routes.d.ts +19 -0
  99. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.routes.d.ts.map +1 -0
  100. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.routes.js +25 -0
  101. package/dist/backend/backend/src/controllers/agent-stream/agent-stream.routes.js.map +1 -0
  102. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts +11 -3
  103. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
  104. package/dist/backend/backend/src/controllers/browser/browser.controller.js +56 -26
  105. package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
  106. package/dist/backend/backend/src/controllers/browser/browser.routes.d.ts.map +1 -1
  107. package/dist/backend/backend/src/controllers/browser/browser.routes.js +3 -1
  108. package/dist/backend/backend/src/controllers/browser/browser.routes.js.map +1 -1
  109. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts +16 -0
  110. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  111. package/dist/backend/backend/src/controllers/chat/chat.controller.js +39 -2
  112. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  113. package/dist/backend/backend/src/controllers/chat/chat.routes.d.ts.map +1 -1
  114. package/dist/backend/backend/src/controllers/chat/chat.routes.js +3 -1
  115. package/dist/backend/backend/src/controllers/chat/chat.routes.js.map +1 -1
  116. package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts +15 -0
  117. package/dist/backend/backend/src/controllers/cloud/cloud.controller.d.ts.map +1 -1
  118. package/dist/backend/backend/src/controllers/cloud/cloud.controller.js +45 -0
  119. package/dist/backend/backend/src/controllers/cloud/cloud.controller.js.map +1 -1
  120. package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts +1 -0
  121. package/dist/backend/backend/src/controllers/cloud/cloud.routes.d.ts.map +1 -1
  122. package/dist/backend/backend/src/controllers/cloud/cloud.routes.js +3 -1
  123. package/dist/backend/backend/src/controllers/cloud/cloud.routes.js.map +1 -1
  124. package/dist/backend/backend/src/controllers/index.d.ts.map +1 -1
  125. package/dist/backend/backend/src/controllers/index.js +2 -0
  126. package/dist/backend/backend/src/controllers/index.js.map +1 -1
  127. package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.d.ts +15 -0
  128. package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.d.ts.map +1 -1
  129. package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.js +35 -1
  130. package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.js.map +1 -1
  131. package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.d.ts.map +1 -1
  132. package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.js +2 -1
  133. package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.js.map +1 -1
  134. package/dist/backend/backend/src/controllers/monitoring/monitoring.routes.d.ts.map +1 -1
  135. package/dist/backend/backend/src/controllers/monitoring/monitoring.routes.js +7 -1
  136. package/dist/backend/backend/src/controllers/monitoring/monitoring.routes.js.map +1 -1
  137. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  138. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +29 -6
  139. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  140. package/dist/backend/backend/src/controllers/monitoring/token-usage.controller.d.ts +29 -0
  141. package/dist/backend/backend/src/controllers/monitoring/token-usage.controller.d.ts.map +1 -1
  142. package/dist/backend/backend/src/controllers/monitoring/token-usage.controller.js +76 -0
  143. package/dist/backend/backend/src/controllers/monitoring/token-usage.controller.js.map +1 -1
  144. package/dist/backend/backend/src/controllers/project/project.controller.d.ts +16 -0
  145. package/dist/backend/backend/src/controllers/project/project.controller.d.ts.map +1 -1
  146. package/dist/backend/backend/src/controllers/project/project.controller.js +47 -0
  147. package/dist/backend/backend/src/controllers/project/project.controller.js.map +1 -1
  148. package/dist/backend/backend/src/controllers/project/project.routes.d.ts.map +1 -1
  149. package/dist/backend/backend/src/controllers/project/project.routes.js +3 -1
  150. package/dist/backend/backend/src/controllers/project/project.routes.js.map +1 -1
  151. package/dist/backend/backend/src/controllers/system/scheduler.controller.d.ts.map +1 -1
  152. package/dist/backend/backend/src/controllers/system/scheduler.controller.js +10 -2
  153. package/dist/backend/backend/src/controllers/system/scheduler.controller.js.map +1 -1
  154. package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
  155. package/dist/backend/backend/src/controllers/team/team.controller.js +34 -3
  156. package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
  157. package/dist/backend/backend/src/index.d.ts.map +1 -1
  158. package/dist/backend/backend/src/index.js +18 -4
  159. package/dist/backend/backend/src/index.js.map +1 -1
  160. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  161. package/dist/backend/backend/src/services/agent/agent-registration.service.js +25 -0
  162. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  163. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts +2 -0
  164. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.d.ts.map +1 -1
  165. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js +19 -0
  166. package/dist/backend/backend/src/services/agent/crewly-agent/agent-runner.service.js.map +1 -1
  167. package/dist/backend/backend/src/services/agent/crewly-agent/agent-stream.service.d.ts +145 -0
  168. package/dist/backend/backend/src/services/agent/crewly-agent/agent-stream.service.d.ts.map +1 -0
  169. package/dist/backend/backend/src/services/agent/crewly-agent/agent-stream.service.js +133 -0
  170. package/dist/backend/backend/src/services/agent/crewly-agent/agent-stream.service.js.map +1 -0
  171. package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.d.ts +130 -0
  172. package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.d.ts.map +1 -0
  173. package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.js +263 -0
  174. package/dist/backend/backend/src/services/agent/crewly-agent/audit-log.service.js.map +1 -0
  175. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.d.ts.map +1 -1
  176. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js +8 -0
  177. package/dist/backend/backend/src/services/agent/crewly-agent/crewly-agent-runtime.service.js.map +1 -1
  178. package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.d.ts +79 -0
  179. package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.d.ts.map +1 -0
  180. package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.js +218 -0
  181. package/dist/backend/backend/src/services/agent/crewly-agent/env-isolation.service.js.map +1 -0
  182. package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.d.ts +91 -0
  183. package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.d.ts.map +1 -0
  184. package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.js +143 -0
  185. package/dist/backend/backend/src/services/agent/crewly-agent/output-filter.service.js.map +1 -0
  186. package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.d.ts +103 -0
  187. package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.d.ts.map +1 -0
  188. package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.js +256 -0
  189. package/dist/backend/backend/src/services/agent/crewly-agent/prompt-guard.service.js.map +1 -0
  190. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts +44 -0
  191. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.d.ts.map +1 -1
  192. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js +323 -1
  193. package/dist/backend/backend/src/services/agent/crewly-agent/tool-registry.js.map +1 -1
  194. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts +21 -0
  195. package/dist/backend/backend/src/services/agent/crewly-agent/types.d.ts.map +1 -1
  196. package/dist/backend/backend/src/services/agent/crewly-agent/types.js +7 -0
  197. package/dist/backend/backend/src/services/agent/crewly-agent/types.js.map +1 -1
  198. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts +4 -1
  199. package/dist/backend/backend/src/services/browser/browser-bridge.service.d.ts.map +1 -1
  200. package/dist/backend/backend/src/services/browser/browser-bridge.service.js +26 -11
  201. package/dist/backend/backend/src/services/browser/browser-bridge.service.js.map +1 -1
  202. package/dist/backend/backend/src/services/chat/chat-highlights.service.d.ts +100 -0
  203. package/dist/backend/backend/src/services/chat/chat-highlights.service.d.ts.map +1 -0
  204. package/dist/backend/backend/src/services/chat/chat-highlights.service.js +145 -0
  205. package/dist/backend/backend/src/services/chat/chat-highlights.service.js.map +1 -0
  206. package/dist/backend/backend/src/services/chat/chat-sanitizer.service.d.ts +76 -0
  207. package/dist/backend/backend/src/services/chat/chat-sanitizer.service.d.ts.map +1 -0
  208. package/dist/backend/backend/src/services/chat/chat-sanitizer.service.js +127 -0
  209. package/dist/backend/backend/src/services/chat/chat-sanitizer.service.js.map +1 -0
  210. package/dist/backend/backend/src/services/chat/chat.service.d.ts +8 -0
  211. package/dist/backend/backend/src/services/chat/chat.service.d.ts.map +1 -1
  212. package/dist/backend/backend/src/services/chat/chat.service.js +27 -1
  213. package/dist/backend/backend/src/services/chat/chat.service.js.map +1 -1
  214. package/dist/backend/backend/src/services/marketplace/index.d.ts +1 -1
  215. package/dist/backend/backend/src/services/marketplace/index.d.ts.map +1 -1
  216. package/dist/backend/backend/src/services/marketplace/index.js +1 -1
  217. package/dist/backend/backend/src/services/marketplace/index.js.map +1 -1
  218. package/dist/backend/backend/src/services/marketplace/marketplace.service.d.ts +11 -0
  219. package/dist/backend/backend/src/services/marketplace/marketplace.service.d.ts.map +1 -1
  220. package/dist/backend/backend/src/services/marketplace/marketplace.service.js +31 -0
  221. package/dist/backend/backend/src/services/marketplace/marketplace.service.js.map +1 -1
  222. package/dist/backend/backend/src/services/monitoring/token-estimator.service.d.ts +197 -0
  223. package/dist/backend/backend/src/services/monitoring/token-estimator.service.d.ts.map +1 -0
  224. package/dist/backend/backend/src/services/monitoring/token-estimator.service.js +408 -0
  225. package/dist/backend/backend/src/services/monitoring/token-estimator.service.js.map +1 -0
  226. package/dist/backend/backend/src/services/project/project-search.service.d.ts +62 -0
  227. package/dist/backend/backend/src/services/project/project-search.service.d.ts.map +1 -0
  228. package/dist/backend/backend/src/services/project/project-search.service.js +107 -0
  229. package/dist/backend/backend/src/services/project/project-search.service.js.map +1 -0
  230. package/dist/backend/backend/src/services/quality/quality-gate.service.d.ts +11 -0
  231. package/dist/backend/backend/src/services/quality/quality-gate.service.d.ts.map +1 -1
  232. package/dist/backend/backend/src/services/quality/quality-gate.service.js +93 -19
  233. package/dist/backend/backend/src/services/quality/quality-gate.service.js.map +1 -1
  234. package/dist/backend/backend/src/services/session/session-command-helper.d.ts.map +1 -1
  235. package/dist/backend/backend/src/services/session/session-command-helper.js +11 -5
  236. package/dist/backend/backend/src/services/session/session-command-helper.js.map +1 -1
  237. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts +8 -2
  238. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  239. package/dist/backend/backend/src/services/workflow/scheduler.service.js +30 -6
  240. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  241. package/dist/backend/backend/src/types/settings.types.d.ts +3 -0
  242. package/dist/backend/backend/src/types/settings.types.d.ts.map +1 -1
  243. package/dist/backend/backend/src/types/settings.types.js +1 -0
  244. package/dist/backend/backend/src/types/settings.types.js.map +1 -1
  245. package/dist/cli/backend/src/types/settings.types.d.ts +3 -0
  246. package/dist/cli/backend/src/types/settings.types.d.ts.map +1 -1
  247. package/dist/cli/backend/src/types/settings.types.js +1 -0
  248. package/dist/cli/backend/src/types/settings.types.js.map +1 -1
  249. package/dist/cli/cli/src/commands/stop.d.ts.map +1 -1
  250. package/dist/cli/cli/src/commands/stop.js +3 -0
  251. package/dist/cli/cli/src/commands/stop.js.map +1 -1
  252. package/dist/cli/cli/src/utils/license-check.d.ts +70 -0
  253. package/dist/cli/cli/src/utils/license-check.d.ts.map +1 -0
  254. package/dist/cli/cli/src/utils/license-check.js +124 -0
  255. package/dist/cli/cli/src/utils/license-check.js.map +1 -0
  256. package/dist/cli/cli/src/utils/process-cleanup.d.ts +9 -0
  257. package/dist/cli/cli/src/utils/process-cleanup.d.ts.map +1 -1
  258. package/dist/cli/cli/src/utils/process-cleanup.js +48 -0
  259. package/dist/cli/cli/src/utils/process-cleanup.js.map +1 -1
  260. package/frontend/dist/assets/index-76782e9e.js +5215 -0
  261. package/frontend/dist/assets/index-b19b2478.css +33 -0
  262. package/frontend/dist/index.html +2 -2
  263. package/package.json +1 -1
  264. package/frontend/dist/assets/index-512efc8e.js +0 -4921
  265. package/frontend/dist/assets/index-dc6ac165.css +0 -33
@@ -7,6 +7,53 @@
7
7
  # Base URL for the Crewly backend API
8
8
  CREWLY_API_URL="${CREWLY_API_URL:-http://localhost:8787}"
9
9
 
10
+ # -----------------------------------------------------------------------------
11
+ # read_json_input [arg]
12
+ #
13
+ # Reads JSON input from either:
14
+ # 1. The provided command-line argument ($1)
15
+ # 2. A file path prefixed with @ (e.g. @/tmp/input.json)
16
+ # 3. Standard input (stdin) — for piped or heredoc usage
17
+ #
18
+ # This solves Gemini CLI's run_shell_command escaping issues (#292, #293):
19
+ # special characters in JSON (parentheses, quotes, newlines) are mangled
20
+ # when passed as shell arguments. Piping via stdin bypasses shell parsing.
21
+ #
22
+ # Usage in skill scripts:
23
+ # INPUT=$(read_json_input "${1:-}")
24
+ # -----------------------------------------------------------------------------
25
+ read_json_input() {
26
+ local arg="${1:-}"
27
+
28
+ # Option 1: Direct argument provided (non-empty)
29
+ if [ -n "$arg" ]; then
30
+ # Support @filepath syntax: read JSON from file
31
+ if [[ "$arg" == @* ]]; then
32
+ local filepath="${arg:1}"
33
+ if [ -f "$filepath" ]; then
34
+ cat "$filepath"
35
+ else
36
+ echo '{}' >&2
37
+ echo "File not found: $filepath" >&2
38
+ return 1
39
+ fi
40
+ else
41
+ printf '%s' "$arg"
42
+ fi
43
+ return 0
44
+ fi
45
+
46
+ # Option 2: Read from stdin (pipe or heredoc)
47
+ if [ ! -t 0 ]; then
48
+ cat
49
+ return 0
50
+ fi
51
+
52
+ # Option 3: No input available
53
+ echo ''
54
+ return 0
55
+ }
56
+
10
57
  # -----------------------------------------------------------------------------
11
58
  # api_call METHOD endpoint [json_body]
12
59
  #
@@ -14,15 +14,15 @@ CDP_PORT=9222
14
14
  VENV_DIR="${HOME}/.crewly/patchright-venv"
15
15
  PYTHON="${VENV_DIR}/bin/python3"
16
16
 
17
- INPUT="${1:-}"
17
+ INPUT=$(read_json_input "${1:-}")
18
18
  [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"url\":\"...\",\"action\":\"read|screenshot|interact\",\"selectors\":[...]}'"
19
19
 
20
- URL=$(echo "$INPUT" | jq -r '.url // empty')
21
- ACTION=$(echo "$INPUT" | jq -r '.action // "read"')
22
- SELECTORS_JSON=$(echo "$INPUT" | jq -c '.selectors // []')
23
- WAIT_FOR=$(echo "$INPUT" | jq -r '.waitFor // empty')
24
- WAIT_TIMEOUT=$(echo "$INPUT" | jq -r '.waitTimeout // empty')
25
- CDP_PORT_OVERRIDE=$(echo "$INPUT" | jq -r '.cdpPort // empty')
20
+ URL=$(printf '%s' "$INPUT" | jq -r '.url // empty')
21
+ ACTION=$(printf '%s' "$INPUT" | jq -r '.action // "read"')
22
+ SELECTORS_JSON=$(printf '%s' "$INPUT" | jq -c '.selectors // []')
23
+ WAIT_FOR=$(printf '%s' "$INPUT" | jq -r '.waitFor // empty')
24
+ WAIT_TIMEOUT=$(printf '%s' "$INPUT" | jq -r '.waitTimeout // empty')
25
+ CDP_PORT_OVERRIDE=$(printf '%s' "$INPUT" | jq -r '.cdpPort // empty')
26
26
 
27
27
  require_param "url" "$URL"
28
28
 
@@ -4,11 +4,11 @@ set -euo pipefail
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  source "${SCRIPT_DIR}/../_common/lib.sh"
6
6
 
7
- INPUT="${1:-}"
7
+ INPUT=$(read_json_input "${1:-}")
8
8
  [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"action\":\"save|list|compare|latest\",\"competitor\":\"crewai\",...}'"
9
9
 
10
- ACTION=$(echo "$INPUT" | jq -r '.action // empty')
11
- PROJECT_PATH=$(echo "$INPUT" | jq -r '.projectPath // empty')
10
+ ACTION=$(printf '%s' "$INPUT" | jq -r '.action // empty')
11
+ PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
12
12
 
13
13
  require_param "action" "$ACTION"
14
14
 
@@ -34,9 +34,9 @@ case "$ACTION" in
34
34
  # SAVE: Store content items from a competitor scan
35
35
  # ─────────────────────────────────────────────
36
36
  save)
37
- COMPETITOR=$(echo "$INPUT" | jq -r '.competitor // empty')
38
- SOURCE_TYPE=$(echo "$INPUT" | jq -r '.sourceType // empty')
39
- ITEMS=$(echo "$INPUT" | jq -r '.items // empty')
37
+ COMPETITOR=$(printf '%s' "$INPUT" | jq -r '.competitor // empty')
38
+ SOURCE_TYPE=$(printf '%s' "$INPUT" | jq -r '.sourceType // empty')
39
+ ITEMS=$(printf '%s' "$INPUT" | jq -r '.items // empty')
40
40
 
41
41
  require_param "competitor" "$COMPETITOR"
42
42
  require_param "sourceType" "$SOURCE_TYPE"
@@ -97,8 +97,8 @@ case "$ACTION" in
97
97
  # LIST: List tracked content by competitor
98
98
  # ─────────────────────────────────────────────
99
99
  list)
100
- FILTER_COMP=$(echo "$INPUT" | jq -r '.competitor // empty')
101
- LIMIT=$(echo "$INPUT" | jq -r '.limit // "20"')
100
+ FILTER_COMP=$(printf '%s' "$INPUT" | jq -r '.competitor // empty')
101
+ LIMIT=$(printf '%s' "$INPUT" | jq -r '.limit // "20"')
102
102
 
103
103
  RESULTS="[]"
104
104
 
@@ -137,9 +137,9 @@ case "$ACTION" in
137
137
  # LATEST: Get latest content from a competitor
138
138
  # ─────────────────────────────────────────────
139
139
  latest)
140
- FILTER_COMP=$(echo "$INPUT" | jq -r '.competitor // empty')
141
- FILTER_TYPE=$(echo "$INPUT" | jq -r '.sourceType // empty')
142
- LIMIT=$(echo "$INPUT" | jq -r '.limit // "15"')
140
+ FILTER_COMP=$(printf '%s' "$INPUT" | jq -r '.competitor // empty')
141
+ FILTER_TYPE=$(printf '%s' "$INPUT" | jq -r '.sourceType // empty')
142
+ LIMIT=$(printf '%s' "$INPUT" | jq -r '.limit // "15"')
143
143
 
144
144
  require_param "competitor" "$FILTER_COMP"
145
145
  validate_competitor "$FILTER_COMP"
@@ -170,8 +170,8 @@ case "$ACTION" in
170
170
  # COMPARE: Compare content activity across competitors
171
171
  # ─────────────────────────────────────────────
172
172
  compare)
173
- COMPETITORS_INPUT=$(echo "$INPUT" | jq -r '.competitors // "crewai,n8n,relevance-ai"')
174
- DAYS=$(echo "$INPUT" | jq -r '.days // "7"')
173
+ COMPETITORS_INPUT=$(printf '%s' "$INPUT" | jq -r '.competitors // "crewai,n8n,relevance-ai"')
174
+ DAYS=$(printf '%s' "$INPUT" | jq -r '.days // "7"')
175
175
 
176
176
  IFS=',' read -ra COMP_ARRAY <<< "$COMPETITORS_INPUT"
177
177
 
@@ -4,19 +4,19 @@ set -euo pipefail
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  source "${SCRIPT_DIR}/../_common/lib.sh"
6
6
 
7
- INPUT="${1:-}"
7
+ INPUT=$(read_json_input "${1:-}")
8
8
  [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"action\":\"add|list|update|next|stats\",\"calendarPath\":\"/path/to/calendar.json\",...}'"
9
9
 
10
10
  # Parse common parameters
11
- ACTION=$(echo "$INPUT" | jq -r '.action // empty')
12
- CALENDAR_PATH=$(echo "$INPUT" | jq -r '.calendarPath // empty')
11
+ ACTION=$(printf '%s' "$INPUT" | jq -r '.action // empty')
12
+ CALENDAR_PATH=$(printf '%s' "$INPUT" | jq -r '.calendarPath // empty')
13
13
 
14
14
  require_param "action" "$ACTION"
15
15
 
16
16
  # Default calendar path
17
17
  if [ -z "$CALENDAR_PATH" ]; then
18
18
  # Try to find project .crewly directory
19
- PROJECT_PATH=$(echo "$INPUT" | jq -r '.projectPath // empty')
19
+ PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
20
20
  if [ -n "$PROJECT_PATH" ]; then
21
21
  CALENDAR_PATH="${PROJECT_PATH}/.crewly/content/calendar.json"
22
22
  else
@@ -42,16 +42,16 @@ case "$ACTION" in
42
42
  # ADD: Add a new content entry
43
43
  # ─────────────────────────────────────────────
44
44
  add)
45
- TITLE=$(echo "$INPUT" | jq -r '.title // empty')
46
- PLATFORM=$(echo "$INPUT" | jq -r '.platform // empty')
47
- CONTENT_TYPE=$(echo "$INPUT" | jq -r '.type // "post"')
48
- SCHEDULED_DATE=$(echo "$INPUT" | jq -r '.scheduledDate // empty')
49
- STATUS=$(echo "$INPUT" | jq -r '.status // "draft"')
50
- CONTENT_PATH=$(echo "$INPUT" | jq -r '.contentPath // empty')
51
- LINE=$(echo "$INPUT" | jq -r '.line // "crewly"')
52
- TOPIC=$(echo "$INPUT" | jq -r '.topic // empty')
53
- NOTES=$(echo "$INPUT" | jq -r '.notes // empty')
54
- TAGS=$(echo "$INPUT" | jq -r '.tags // "[]"')
45
+ TITLE=$(printf '%s' "$INPUT" | jq -r '.title // empty')
46
+ PLATFORM=$(printf '%s' "$INPUT" | jq -r '.platform // empty')
47
+ CONTENT_TYPE=$(printf '%s' "$INPUT" | jq -r '.type // "post"')
48
+ SCHEDULED_DATE=$(printf '%s' "$INPUT" | jq -r '.scheduledDate // empty')
49
+ STATUS=$(printf '%s' "$INPUT" | jq -r '.status // "draft"')
50
+ CONTENT_PATH=$(printf '%s' "$INPUT" | jq -r '.contentPath // empty')
51
+ LINE=$(printf '%s' "$INPUT" | jq -r '.line // "crewly"')
52
+ TOPIC=$(printf '%s' "$INPUT" | jq -r '.topic // empty')
53
+ NOTES=$(printf '%s' "$INPUT" | jq -r '.notes // empty')
54
+ TAGS=$(printf '%s' "$INPUT" | jq -r '.tags // "[]"')
55
55
 
56
56
  require_param "title" "$TITLE"
57
57
  require_param "platform" "$PLATFORM"
@@ -126,13 +126,13 @@ case "$ACTION" in
126
126
  # LIST: List calendar entries with filters
127
127
  # ─────────────────────────────────────────────
128
128
  list)
129
- FILTER_PLATFORM=$(echo "$INPUT" | jq -r '.platform // empty')
130
- FILTER_STATUS=$(echo "$INPUT" | jq -r '.status // empty')
131
- FILTER_DATE=$(echo "$INPUT" | jq -r '.date // empty')
132
- FILTER_DATE_FROM=$(echo "$INPUT" | jq -r '.dateFrom // empty')
133
- FILTER_DATE_TO=$(echo "$INPUT" | jq -r '.dateTo // empty')
134
- FILTER_LINE=$(echo "$INPUT" | jq -r '.line // empty')
135
- LIMIT=$(echo "$INPUT" | jq -r '.limit // "50"')
129
+ FILTER_PLATFORM=$(printf '%s' "$INPUT" | jq -r '.platform // empty')
130
+ FILTER_STATUS=$(printf '%s' "$INPUT" | jq -r '.status // empty')
131
+ FILTER_DATE=$(printf '%s' "$INPUT" | jq -r '.date // empty')
132
+ FILTER_DATE_FROM=$(printf '%s' "$INPUT" | jq -r '.dateFrom // empty')
133
+ FILTER_DATE_TO=$(printf '%s' "$INPUT" | jq -r '.dateTo // empty')
134
+ FILTER_LINE=$(printf '%s' "$INPUT" | jq -r '.line // empty')
135
+ LIMIT=$(printf '%s' "$INPUT" | jq -r '.limit // "50"')
136
136
 
137
137
  # Build jq filter
138
138
  JQ_FILTER=".entries"
@@ -173,7 +173,7 @@ case "$ACTION" in
173
173
  # UPDATE: Update an existing entry
174
174
  # ─────────────────────────────────────────────
175
175
  update)
176
- ENTRY_ID=$(echo "$INPUT" | jq -r '.id // empty')
176
+ ENTRY_ID=$(printf '%s' "$INPUT" | jq -r '.id // empty')
177
177
  require_param "id" "$ENTRY_ID"
178
178
 
179
179
  # Check if entry exists
@@ -187,12 +187,12 @@ case "$ACTION" in
187
187
  # Build update fields dynamically
188
188
  UPDATE_FIELDS=".updatedAt = \"${NOW}\""
189
189
 
190
- NEW_STATUS=$(echo "$INPUT" | jq -r '.status // empty')
191
- NEW_TITLE=$(echo "$INPUT" | jq -r '.title // empty')
192
- NEW_DATE=$(echo "$INPUT" | jq -r '.scheduledDate // empty')
193
- NEW_CONTENT_PATH=$(echo "$INPUT" | jq -r '.contentPath // empty')
194
- NEW_NOTES=$(echo "$INPUT" | jq -r '.notes // empty')
195
- NEW_TOPIC=$(echo "$INPUT" | jq -r '.topic // empty')
190
+ NEW_STATUS=$(printf '%s' "$INPUT" | jq -r '.status // empty')
191
+ NEW_TITLE=$(printf '%s' "$INPUT" | jq -r '.title // empty')
192
+ NEW_DATE=$(printf '%s' "$INPUT" | jq -r '.scheduledDate // empty')
193
+ NEW_CONTENT_PATH=$(printf '%s' "$INPUT" | jq -r '.contentPath // empty')
194
+ NEW_NOTES=$(printf '%s' "$INPUT" | jq -r '.notes // empty')
195
+ NEW_TOPIC=$(printf '%s' "$INPUT" | jq -r '.topic // empty')
196
196
 
197
197
  [ -n "$NEW_STATUS" ] && UPDATE_FIELDS="${UPDATE_FIELDS} | .status = \"${NEW_STATUS}\""
198
198
  [ -n "$NEW_TITLE" ] && UPDATE_FIELDS="${UPDATE_FIELDS} | .title = \"${NEW_TITLE}\""
@@ -221,7 +221,7 @@ case "$ACTION" in
221
221
  # NEXT: Get the next content to publish
222
222
  # ─────────────────────────────────────────────
223
223
  next)
224
- FILTER_PLATFORM=$(echo "$INPUT" | jq -r '.platform // empty')
224
+ FILTER_PLATFORM=$(printf '%s' "$INPUT" | jq -r '.platform // empty')
225
225
  TODAY=$(date -u +%Y-%m-%d)
226
226
 
227
227
  # Find entries that are ready/approved and scheduled for today or earlier
@@ -4,17 +4,17 @@ set -euo pipefail
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  source "${SCRIPT_DIR}/../_common/lib.sh"
6
6
 
7
- INPUT="${1:-}"
7
+ INPUT=$(read_json_input "${1:-}")
8
8
  [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"source\":\"content text\",\"platforms\":\"x-thread,linkedin,xiaohongshu\",\"tone\":\"professional\",\"brand\":\"personal\",\"outputDir\":\"/path/to/output\"}'"
9
9
 
10
10
  # Parse parameters
11
- SOURCE=$(echo "$INPUT" | jq -r '.source // empty')
12
- SOURCE_FILE=$(echo "$INPUT" | jq -r '.sourceFile // empty')
13
- PLATFORMS=$(echo "$INPUT" | jq -r '.platforms // "x-thread,linkedin"')
14
- TONE=$(echo "$INPUT" | jq -r '.tone // "professional"')
15
- OUTPUT_DIR=$(echo "$INPUT" | jq -r '.outputDir // empty')
16
- BRAND=$(echo "$INPUT" | jq -r '.brand // "personal"')
17
- LANGUAGE=$(echo "$INPUT" | jq -r '.language // "auto"')
11
+ SOURCE=$(printf '%s' "$INPUT" | jq -r '.source // empty')
12
+ SOURCE_FILE=$(printf '%s' "$INPUT" | jq -r '.sourceFile // empty')
13
+ PLATFORMS=$(printf '%s' "$INPUT" | jq -r '.platforms // "x-thread,linkedin"')
14
+ TONE=$(printf '%s' "$INPUT" | jq -r '.tone // "professional"')
15
+ OUTPUT_DIR=$(printf '%s' "$INPUT" | jq -r '.outputDir // empty')
16
+ BRAND=$(printf '%s' "$INPUT" | jq -r '.brand // "personal"')
17
+ LANGUAGE=$(printf '%s' "$INPUT" | jq -r '.language // "auto"')
18
18
 
19
19
  # Load source content from file if sourceFile is provided
20
20
  if [ -n "$SOURCE_FILE" ]; then
@@ -4,11 +4,11 @@ set -euo pipefail
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  source "${SCRIPT_DIR}/../_common/lib.sh"
6
6
 
7
- INPUT="${1:-}"
7
+ INPUT=$(read_json_input "${1:-}")
8
8
  [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"action\":\"draft|save|get|list\",\"topic\":\"...\",\"platform\":\"x-thread\",...}'"
9
9
 
10
- ACTION=$(echo "$INPUT" | jq -r '.action // "draft"')
11
- PROJECT_PATH=$(echo "$INPUT" | jq -r '.projectPath // empty')
10
+ ACTION=$(printf '%s' "$INPUT" | jq -r '.action // "draft"')
11
+ PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
12
12
 
13
13
  # Resolve content directory
14
14
  if [ -n "$PROJECT_PATH" ]; then
@@ -24,15 +24,15 @@ case "$ACTION" in
24
24
  # DRAFT: Generate a writing brief / prompt for a content piece
25
25
  # ─────────────────────────────────────────────
26
26
  draft)
27
- TOPIC=$(echo "$INPUT" | jq -r '.topic // empty')
28
- PLATFORM=$(echo "$INPUT" | jq -r '.platform // empty')
29
- LINE=$(echo "$INPUT" | jq -r '.line // "crewly"')
30
- TONE=$(echo "$INPUT" | jq -r '.tone // "professional"')
31
- LENGTH=$(echo "$INPUT" | jq -r '.length // "medium"')
32
- AUDIENCE=$(echo "$INPUT" | jq -r '.audience // empty')
33
- CONTEXT=$(echo "$INPUT" | jq -r '.context // empty')
34
- REFERENCES=$(echo "$INPUT" | jq -r '.references // empty')
35
- CTA=$(echo "$INPUT" | jq -r '.cta // empty')
27
+ TOPIC=$(printf '%s' "$INPUT" | jq -r '.topic // empty')
28
+ PLATFORM=$(printf '%s' "$INPUT" | jq -r '.platform // empty')
29
+ LINE=$(printf '%s' "$INPUT" | jq -r '.line // "crewly"')
30
+ TONE=$(printf '%s' "$INPUT" | jq -r '.tone // "professional"')
31
+ LENGTH=$(printf '%s' "$INPUT" | jq -r '.length // "medium"')
32
+ AUDIENCE=$(printf '%s' "$INPUT" | jq -r '.audience // empty')
33
+ CONTEXT=$(printf '%s' "$INPUT" | jq -r '.context // empty')
34
+ REFERENCES=$(printf '%s' "$INPUT" | jq -r '.references // empty')
35
+ CTA=$(printf '%s' "$INPUT" | jq -r '.cta // empty')
36
36
 
37
37
  require_param "topic" "$TOPIC"
38
38
  require_param "platform" "$PLATFORM"
@@ -175,12 +175,12 @@ case "$ACTION" in
175
175
  # SAVE: Save a completed content draft to disk
176
176
  # ─────────────────────────────────────────────
177
177
  save)
178
- DRAFT_ID=$(echo "$INPUT" | jq -r '.draftId // empty')
179
- TITLE=$(echo "$INPUT" | jq -r '.title // empty')
180
- PLATFORM=$(echo "$INPUT" | jq -r '.platform // empty')
181
- LINE=$(echo "$INPUT" | jq -r '.line // "crewly"')
182
- CONTENT=$(echo "$INPUT" | jq -r '.content // empty')
183
- CALENDAR_ID=$(echo "$INPUT" | jq -r '.calendarId // empty')
178
+ DRAFT_ID=$(printf '%s' "$INPUT" | jq -r '.draftId // empty')
179
+ TITLE=$(printf '%s' "$INPUT" | jq -r '.title // empty')
180
+ PLATFORM=$(printf '%s' "$INPUT" | jq -r '.platform // empty')
181
+ LINE=$(printf '%s' "$INPUT" | jq -r '.line // "crewly"')
182
+ CONTENT=$(printf '%s' "$INPUT" | jq -r '.content // empty')
183
+ CALENDAR_ID=$(printf '%s' "$INPUT" | jq -r '.calendarId // empty')
184
184
 
185
185
  require_param "title" "$TITLE"
186
186
  require_param "platform" "$PLATFORM"
@@ -234,8 +234,8 @@ DRAFT_EOF
234
234
  # GET: Read a saved draft
235
235
  # ─────────────────────────────────────────────
236
236
  get)
237
- FILE_PATH=$(echo "$INPUT" | jq -r '.filePath // empty')
238
- DRAFT_ID=$(echo "$INPUT" | jq -r '.draftId // empty')
237
+ FILE_PATH=$(printf '%s' "$INPUT" | jq -r '.filePath // empty')
238
+ DRAFT_ID=$(printf '%s' "$INPUT" | jq -r '.draftId // empty')
239
239
 
240
240
  if [ -n "$FILE_PATH" ] && [ -f "$FILE_PATH" ]; then
241
241
  CONTENT=$(cat "$FILE_PATH")
@@ -267,8 +267,8 @@ DRAFT_EOF
267
267
  # LIST: List saved drafts
268
268
  # ─────────────────────────────────────────────
269
269
  list)
270
- FILTER_PLATFORM=$(echo "$INPUT" | jq -r '.platform // empty')
271
- LIMIT=$(echo "$INPUT" | jq -r '.limit // "20"')
270
+ FILTER_PLATFORM=$(printf '%s' "$INPUT" | jq -r '.platform // empty')
271
+ LIMIT=$(printf '%s' "$INPUT" | jq -r '.limit // "20"')
272
272
 
273
273
  DRAFTS="[]"
274
274
 
@@ -4,15 +4,15 @@ set -euo pipefail
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  source "${SCRIPT_DIR}/../../_common/lib.sh"
6
6
 
7
- INPUT="${1:-}"
8
- [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"sessionName\":\"dev-1\"}'"
7
+ INPUT=$(read_json_input "${1:-}")
8
+ [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"sessionName\":\"dev-1\"}' or echo '{...}' | execute.sh"
9
9
 
10
- SESSION_NAME=$(echo "$INPUT" | jq -r '.sessionName // empty')
10
+ SESSION_NAME=$(printf '%s' "$INPUT" | jq -r '.sessionName // empty')
11
11
  require_param "sessionName" "$SESSION_NAME"
12
12
 
13
- TEAM_MEMBER_ID=$(echo "$INPUT" | jq -r '.teamMemberId // empty')
14
- PROJECT_PATH=$(echo "$INPUT" | jq -r '.projectPath // empty')
15
- TASK_GROUP=$(echo "$INPUT" | jq -r '.taskGroup // empty')
13
+ TEAM_MEMBER_ID=$(printf '%s' "$INPUT" | jq -r '.teamMemberId // empty')
14
+ PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
15
+ TASK_GROUP=$(printf '%s' "$INPUT" | jq -r '.taskGroup // empty')
16
16
 
17
17
  BODY=$(jq -n \
18
18
  --arg sessionName "$SESSION_NAME" \
@@ -4,13 +4,13 @@ set -euo pipefail
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  source "${SCRIPT_DIR}/../../_common/lib.sh"
6
6
 
7
- INPUT="${1:-}"
7
+ INPUT=$(read_json_input "${1:-}")
8
8
  [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"absoluteTaskPath\":\"/path/to/task\",\"reason\":\"Missing API credentials\"}'"
9
9
 
10
- ABSOLUTE_TASK_PATH=$(echo "$INPUT" | jq -r '.absoluteTaskPath // empty')
11
- REASON=$(echo "$INPUT" | jq -r '.reason // empty')
12
- QUESTIONS=$(echo "$INPUT" | jq -r '.questions // empty')
13
- URGENCY=$(echo "$INPUT" | jq -r '.urgency // empty')
10
+ ABSOLUTE_TASK_PATH=$(printf '%s' "$INPUT" | jq -r '.absoluteTaskPath // empty')
11
+ REASON=$(printf '%s' "$INPUT" | jq -r '.reason // empty')
12
+ QUESTIONS=$(printf '%s' "$INPUT" | jq -r '.questions // empty')
13
+ URGENCY=$(printf '%s' "$INPUT" | jq -r '.urgency // empty')
14
14
  require_param "absoluteTaskPath" "$ABSOLUTE_TASK_PATH"
15
15
  require_param "reason" "$REASON"
16
16
 
@@ -4,15 +4,15 @@ set -euo pipefail
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  source "${SCRIPT_DIR}/../../_common/lib.sh"
6
6
 
7
- INPUT="${1:-}"
7
+ INPUT=$(read_json_input "${1:-}")
8
8
  [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"projectPath\":\"/path/to/project\"}'"
9
9
 
10
- PROJECT_PATH=$(echo "$INPUT" | jq -r '.projectPath // empty')
11
- GATES=$(echo "$INPUT" | jq -r '.gates // empty')
12
- SKIP_OPTIONAL=$(echo "$INPUT" | jq -r '.skipOptional // empty')
10
+ PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
11
+ GATES=$(printf '%s' "$INPUT" | jq -r '.gates // empty')
12
+ SKIP_OPTIONAL=$(printf '%s' "$INPUT" | jq -r '.skipOptional // empty')
13
13
 
14
14
  # Build body with optional fields
15
- BODY=$(echo "$INPUT" | jq '{} +
15
+ BODY=$(printf '%s' "$INPUT" | jq '{} +
16
16
  (if .projectPath then {projectPath: .projectPath} else {} end) +
17
17
  (if .gates then {gates: .gates} else {} end) +
18
18
  (if .skipOptional == true then {skipOptional: true} else {} end)')
@@ -4,23 +4,23 @@ set -euo pipefail
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  source "${SCRIPT_DIR}/../../_common/lib.sh"
6
6
 
7
- INPUT="${1:-}"
7
+ INPUT=$(read_json_input "${1:-}")
8
8
  [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"absoluteTaskPath\":\"/path/to/task\",\"sessionName\":\"dev-1\",\"summary\":\"Implemented feature X\",\"output\":{\"key\":\"value\"}}'"
9
9
 
10
- ABSOLUTE_TASK_PATH=$(echo "$INPUT" | jq -r '.absoluteTaskPath // empty')
11
- SESSION_NAME=$(echo "$INPUT" | jq -r '.sessionName // empty')
12
- SUMMARY=$(echo "$INPUT" | jq -r '.summary // empty')
13
- SKIP_GATES=$(echo "$INPUT" | jq -r '.skipGates // empty')
14
- OUTPUT_JSON=$(echo "$INPUT" | jq -c '.output // empty')
10
+ ABSOLUTE_TASK_PATH=$(printf '%s' "$INPUT" | jq -r '.absoluteTaskPath // empty')
11
+ SESSION_NAME=$(printf '%s' "$INPUT" | jq -r '.sessionName // empty')
12
+ SUMMARY=$(printf '%s' "$INPUT" | jq -r '.summary // empty')
13
+ SKIP_GATES=$(printf '%s' "$INPUT" | jq -r '.skipGates // empty')
14
+ OUTPUT_JSON=$(printf '%s' "$INPUT" | jq -c '.output // empty')
15
15
  require_param "absoluteTaskPath" "$ABSOLUTE_TASK_PATH"
16
16
  require_param "sessionName" "$SESSION_NAME"
17
17
  require_param "summary" "$SUMMARY"
18
18
 
19
19
  # Optional structured VerificationRequest fields (for hierarchical workflows)
20
- TASK_ID=$(echo "$INPUT" | jq -r '.taskId // empty')
21
- ARTIFACTS=$(echo "$INPUT" | jq -c '.artifacts // empty')
22
- TEST_RESULTS=$(echo "$INPUT" | jq -r '.testResults // empty')
23
- USE_STRUCTURED=$(echo "$INPUT" | jq -r '.structured // "false"')
20
+ TASK_ID=$(printf '%s' "$INPUT" | jq -r '.taskId // empty')
21
+ ARTIFACTS=$(printf '%s' "$INPUT" | jq -c '.artifacts // empty')
22
+ TEST_RESULTS=$(printf '%s' "$INPUT" | jq -r '.testResults // empty')
23
+ USE_STRUCTURED=$(printf '%s' "$INPUT" | jq -r '.structured // "false"')
24
24
 
25
25
  # If structured mode is enabled and taskId is provided, send a [VERIFICATION REQUEST]
26
26
  # to the orchestrator/team-leader before completing the task file.
@@ -29,7 +29,7 @@ if [ "$USE_STRUCTURED" = "true" ] && [ -n "$TASK_ID" ]; then
29
29
 
30
30
  # Add artifacts if provided
31
31
  if [ -n "$ARTIFACTS" ] && [ "$ARTIFACTS" != "" ]; then
32
- ARTIFACT_LINES=$(echo "$ARTIFACTS" | jq -r '.[]? | "- **\(.name)** (\(.type)): \(.content)"' 2>/dev/null || true)
32
+ ARTIFACT_LINES=$(printf '%s' "$ARTIFACTS" | jq -r '.[]? | "- **\(.name)** (\(.type)): \(.content)"' 2>/dev/null || true)
33
33
  if [ -n "$ARTIFACT_LINES" ]; then
34
34
  VER_MESSAGE="${VER_MESSAGE}\n\n## Artifacts\n${ARTIFACT_LINES}"
35
35
  fi
@@ -54,7 +54,7 @@ if echo "$ABSOLUTE_TASK_PATH" | grep -q '/in_progress/'; then
54
54
  echo '{"success":true,"message":"Task already completed (moved to done by report-status)"}'
55
55
  # Still persist knowledge below, then exit
56
56
  if [ -n "$SUMMARY" ]; then
57
- PROJECT_PATH=$(echo "$INPUT" | jq -r '.projectPath // empty')
57
+ PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
58
58
  auto_remember "$SESSION_NAME" "Task completed by ${SESSION_NAME}: ${SUMMARY}" "pattern" "project" "$PROJECT_PATH"
59
59
  fi
60
60
  exit 0
@@ -78,6 +78,6 @@ api_call POST "/task-management/complete" "$BODY"
78
78
  # Use [COMPLETED] prefix so recall can distinguish completed tasks from other patterns.
79
79
  # This prevents PM from re-delegating tasks that were already done.
80
80
  if [ -n "$SUMMARY" ]; then
81
- PROJECT_PATH=$(echo "$INPUT" | jq -r '.projectPath // empty')
81
+ PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
82
82
  auto_remember "$SESSION_NAME" "[COMPLETED] Task completed by ${SESSION_NAME}: ${SUMMARY}" "decision" "project" "$PROJECT_PATH"
83
83
  fi
@@ -5,12 +5,12 @@ set -euo pipefail
5
5
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
6
  source "${SCRIPT_DIR}/../../_common/lib.sh"
7
7
 
8
- INPUT="${1:-}"
8
+ INPUT=$(read_json_input "${1:-}")
9
9
  [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"input\":\"/tmp/report.md\",\"output\":\"/tmp/report.pdf\",\"title\":\"My Report\"}'"
10
10
 
11
- MD_PATH=$(echo "$INPUT" | jq -r '.input // empty')
12
- PDF_PATH=$(echo "$INPUT" | jq -r '.output // empty')
13
- TITLE=$(echo "$INPUT" | jq -r '.title // empty')
11
+ MD_PATH=$(printf '%s' "$INPUT" | jq -r '.input // empty')
12
+ PDF_PATH=$(printf '%s' "$INPUT" | jq -r '.output // empty')
13
+ TITLE=$(printf '%s' "$INPUT" | jq -r '.title // empty')
14
14
 
15
15
  require_param "input" "$MD_PATH"
16
16
 
@@ -4,12 +4,12 @@ set -euo pipefail
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  source "${SCRIPT_DIR}/../../_common/lib.sh"
6
6
 
7
- INPUT="${1:-}"
8
- [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"agentId\":\"dev-1\",\"agentRole\":\"developer\",\"projectPath\":\"/projects/app\"}'"
7
+ INPUT=$(read_json_input "${1:-}")
8
+ [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"agentId\":\"dev-1\",\"agentRole\":\"developer\",\"projectPath\":\"...\"}' or echo '{...}' | execute.sh"
9
9
 
10
- AGENT_ID=$(echo "$INPUT" | jq -r '.agentId // empty')
11
- AGENT_ROLE=$(echo "$INPUT" | jq -r '.agentRole // empty')
12
- PROJECT_PATH=$(echo "$INPUT" | jq -r '.projectPath // empty')
10
+ AGENT_ID=$(printf '%s' "$INPUT" | jq -r '.agentId // empty')
11
+ AGENT_ROLE=$(printf '%s' "$INPUT" | jq -r '.agentRole // empty')
12
+ PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
13
13
  require_param "agentId" "$AGENT_ID"
14
14
  require_param "agentRole" "$AGENT_ROLE"
15
15
  require_param "projectPath" "$PROJECT_PATH"
@@ -4,11 +4,11 @@ set -euo pipefail
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  source "${SCRIPT_DIR}/../../_common/lib.sh"
6
6
 
7
- INPUT="${1:-}"
8
- [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"sessionName\":\"crewly-product-sam-xxxx\"}'"
7
+ INPUT=$(read_json_input "${1:-}")
8
+ [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"sessionName\":\"...\",\"projectPath\":\"...\"}' or echo '{...}' | execute.sh"
9
9
 
10
- SESSION_NAME=$(echo "$INPUT" | jq -r '.sessionName // empty')
11
- PROJECT_PATH=$(echo "$INPUT" | jq -r '.projectPath // empty')
10
+ SESSION_NAME=$(printf '%s' "$INPUT" | jq -r '.sessionName // empty')
11
+ PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
12
12
  require_param "sessionName" "$SESSION_NAME"
13
13
  require_param "projectPath" "$PROJECT_PATH"
14
14
 
@@ -4,14 +4,14 @@ set -euo pipefail
4
4
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
5
  source "${SCRIPT_DIR}/../../_common/lib.sh"
6
6
 
7
- INPUT="${1:-}"
7
+ INPUT=$(read_json_input "${1:-}")
8
8
  [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"context\":\"deploying to production\"}'"
9
9
 
10
- CONTEXT=$(echo "$INPUT" | jq -r '.context // empty')
10
+ CONTEXT=$(printf '%s' "$INPUT" | jq -r '.context // empty')
11
11
  require_param "context" "$CONTEXT"
12
12
 
13
- CATEGORY=$(echo "$INPUT" | jq -r '.category // empty')
14
- ROLE=$(echo "$INPUT" | jq -r '.role // empty')
13
+ CATEGORY=$(printf '%s' "$INPUT" | jq -r '.category // empty')
14
+ ROLE=$(printf '%s' "$INPUT" | jq -r '.role // empty')
15
15
 
16
16
  BODY=$(jq -n \
17
17
  --arg context "$CONTEXT" \
@@ -7,12 +7,12 @@ source "${SCRIPT_DIR}/../../_common/lib.sh"
7
7
 
8
8
  CREWLY_HOME="${HOME}/.crewly"
9
9
 
10
- INPUT="${1:-}"
10
+ INPUT=$(read_json_input "${1:-}")
11
11
  [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"trigger\":\"before_commit\",\"teamId\":\"...\"}'"
12
12
 
13
- TRIGGER=$(echo "$INPUT" | jq -r '.trigger // empty')
14
- TEAM_ID=$(echo "$INPUT" | jq -r '.teamId // empty')
15
- SESSION_NAME=$(echo "$INPUT" | jq -r '.sessionName // empty')
13
+ TRIGGER=$(printf '%s' "$INPUT" | jq -r '.trigger // empty')
14
+ TEAM_ID=$(printf '%s' "$INPUT" | jq -r '.teamId // empty')
15
+ SESSION_NAME=$(printf '%s' "$INPUT" | jq -r '.sessionName // empty')
16
16
 
17
17
  # Resolve teamId: explicit param > lookup by sessionName > CREWLY_SESSION_NAME env
18
18
  resolve_team_id() {
@@ -24,16 +24,16 @@ set -euo pipefail
24
24
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
25
25
  source "${SCRIPT_DIR}/../../_common/lib.sh"
26
26
 
27
- INPUT="${1:-}"
27
+ INPUT=$(read_json_input "${1:-}")
28
28
  [ -z "$INPUT" ] && error_exit "Usage: execute.sh '{\"to\":\"target-session\",\"taskPath\":\"/path/to/task.md\",\"reason\":\"...\",\"progress\":\"...\"}'"
29
29
 
30
- TO=$(echo "$INPUT" | jq -r '.to // empty')
31
- TASK_PATH=$(echo "$INPUT" | jq -r '.taskPath // empty')
32
- REASON=$(echo "$INPUT" | jq -r '.reason // "Task handoff"')
33
- PROGRESS=$(echo "$INPUT" | jq -r '.progress // empty')
34
- FINDINGS=$(echo "$INPUT" | jq -r '.findings // empty')
35
- BLOCKERS=$(echo "$INPUT" | jq -r '.blockers // empty')
36
- PROJECT_PATH=$(echo "$INPUT" | jq -r '.projectPath // empty')
30
+ TO=$(printf '%s' "$INPUT" | jq -r '.to // empty')
31
+ TASK_PATH=$(printf '%s' "$INPUT" | jq -r '.taskPath // empty')
32
+ REASON=$(printf '%s' "$INPUT" | jq -r '.reason // "Task handoff"')
33
+ PROGRESS=$(printf '%s' "$INPUT" | jq -r '.progress // empty')
34
+ FINDINGS=$(printf '%s' "$INPUT" | jq -r '.findings // empty')
35
+ BLOCKERS=$(printf '%s' "$INPUT" | jq -r '.blockers // empty')
36
+ PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
37
37
  FROM_SESSION="${CREWLY_SESSION_NAME:-unknown}"
38
38
 
39
39
  require_param "to" "$TO"