ecoportal-api-graphql 1.3.5 → 1.3.9

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 (499) hide show
  1. checksums.yaml +4 -4
  2. data/.ai-assistance/bridge/CLAUDE.md +338 -0
  3. data/.ai-assistance/bridge/archive/.gitkeep +0 -0
  4. data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.inbox.md +29 -0
  5. data/.ai-assistance/bridge/archive/oscar-a1b2c3d-gitlab-mcp-doc-update.outbox.md +18 -0
  6. data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.inbox.md +42 -0
  7. data/.ai-assistance/bridge/archive/oscar-c912c25-gemini-design-review.outbox.md +115 -0
  8. data/.ai-assistance/bridge/context/gemini-review-prompt.txt +48 -0
  9. data/.ai-assistance/bridge/context/gemini-review-response.md +104 -0
  10. data/.ai-assistance/bridge/context/project.md +42 -0
  11. data/.ai-assistance/bridge/inbox/.gitkeep +0 -0
  12. data/.ai-assistance/bridge/outbox/.gitkeep +0 -0
  13. data/.ai-assistance/bridge/outbox/request-for-standards-discovery.md +48 -0
  14. data/.ai-assistance/bridge/queue/.gitkeep +1 -0
  15. data/.ai-assistance/capabilities/CLAUDE.md +27 -0
  16. data/.ai-assistance/capabilities/assumptions-log.md +80 -0
  17. data/.ai-assistance/capabilities/code.md +47 -0
  18. data/.ai-assistance/capabilities/connectors.md +37 -0
  19. data/.ai-assistance/capabilities/cowork.md +55 -0
  20. data/.ai-assistance/code/OVERVIEW.md +155 -0
  21. data/.ai-assistance/code/data_fields.md +242 -0
  22. data/.ai-assistance/code/dependencies.md +151 -0
  23. data/.ai-assistance/code/diff_as_input.md +234 -0
  24. data/.ai-assistance/code/diff_service_deep_dive.md +192 -0
  25. data/.ai-assistance/code/ecoPortal_architecture/00_overview_and_index.md +55 -0
  26. data/.ai-assistance/code/ecoPortal_architecture/01_terminology_dictionary.md +181 -0
  27. data/.ai-assistance/code/ecoPortal_architecture/02_data_model.md +192 -0
  28. data/.ai-assistance/code/ecoPortal_architecture/03_api_layers.md +147 -0
  29. data/.ai-assistance/code/ecoPortal_architecture/04_graphql_queries_mutations.md +277 -0
  30. data/.ai-assistance/code/ecoPortal_architecture/05_page_workflows.md +200 -0
  31. data/.ai-assistance/code/ecoPortal_architecture/06_search_and_filters.md +228 -0
  32. data/.ai-assistance/code/ecoPortal_architecture/07_data_fields.md +197 -0
  33. data/.ai-assistance/code/ecoPortal_architecture/08_stages_sections.md +243 -0
  34. data/.ai-assistance/code/ecoPortal_architecture/09_people_contractors_locations.md +196 -0
  35. data/.ai-assistance/code/ecoPortal_architecture/10_forces_workflow_builder.md +132 -0
  36. data/.ai-assistance/code/ecoPortal_architecture/11_integration_gems.md +187 -0
  37. data/.ai-assistance/code/ecoPortal_architecture/12_ai_documentation_sources_gaps.md +236 -0
  38. data/.ai-assistance/code/ecoPortal_architecture/13_ai_infrastructure.md +183 -0
  39. data/.ai-assistance/code/ecoportal_schema_reference.md +240 -0
  40. data/.ai-assistance/code/graphql_domain_knowledge.md +230 -0
  41. data/.ai-assistance/code/refactoring/datafield-readwrite-shape-asymmetry.md +71 -0
  42. data/.ai-assistance/code/refactoring/opportunities.md +251 -0
  43. data/.ai-assistance/code/schema_analysis.md +321 -0
  44. data/.ai-assistance/code/search_filters.md +868 -0
  45. data/.ai-assistance/code/spec_coverage.md +73 -0
  46. data/.ai-assistance/code/workflow-command-guide.md +438 -0
  47. data/.ai-assistance/code/workflow-space.md +353 -0
  48. data/.ai-assistance/conventions/CLAUDE.md +30 -0
  49. data/.ai-assistance/conventions/code-working-tree-protocol.md +199 -0
  50. data/.ai-assistance/conventions/gitignore-rules.md +42 -0
  51. data/.ai-assistance/conventions/permission-guidance.md +120 -0
  52. data/.ai-assistance/integrations/README.md +70 -0
  53. data/.ai-assistance/integrations/gitkraken-mcp.md +107 -0
  54. data/.ai-assistance/integrations/gitlab-mcp.md +123 -0
  55. data/.ai-assistance/integrations/local-git.md +60 -0
  56. data/.ai-assistance/local_paths.example.md +17 -0
  57. data/.ai-assistance/projects/TODO.md +97 -0
  58. data/.ai-assistance/projects/api-v2-to-graphql-migration/DECISIONS.md +168 -0
  59. data/.ai-assistance/projects/api-v2-to-graphql-migration/INTENT.md +60 -0
  60. data/.ai-assistance/projects/api-v2-to-graphql-migration/TODO.md +267 -0
  61. data/.ai-assistance/projects/api-v2-to-graphql-migration/UPSTREAM.md +53 -0
  62. data/.ai-assistance/projects/api-v2-to-graphql-migration/notes/csv-template-pipeline-design.md +102 -0
  63. data/.ai-assistance/projects/api-v2-to-graphql-migration/notes/cutover-usecase-gap-audit.md +139 -0
  64. data/.ai-assistance/projects/dynamic-model-generation/INTENT.md +93 -0
  65. data/.ai-assistance/projects/eco-helpers-compat/INTENT.md +244 -0
  66. data/.ai-assistance/projects/eco-helpers-compat/MIGRATION_GUIDE.md +266 -0
  67. data/.ai-assistance/projects/eco-helpers-compat/TODO.md +86 -0
  68. data/.ai-assistance/projects/ecoportal-api-v2-doublemodel-review/INTENT.md +101 -0
  69. data/.ai-assistance/projects/graphql-agent/GAP_ANALYSIS.md +177 -0
  70. data/.ai-assistance/projects/ooze-graphql-native-migration/DECISIONS.md +161 -0
  71. data/.ai-assistance/projects/ooze-graphql-native-migration/INTENT.md +125 -0
  72. data/.ai-assistance/projects/ooze-graphql-native-migration/RISKS.md +126 -0
  73. data/.ai-assistance/projects/ooze-graphql-native-migration/TODO.md +256 -0
  74. data/.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-06-30-cutover-workflow-deep-review.md +122 -0
  75. data/.ai-assistance/projects/ooze-graphql-native-migration/analysis/2026-07-01-forces-via-workflow-commands-miss-rca.md +148 -0
  76. data/.ai-assistance/projects/page-model/DECISIONS.md +245 -0
  77. data/.ai-assistance/projects/page-model/TODO.md +190 -0
  78. data/.ai-assistance/projects/search-filter-builder/INTENT.md +107 -0
  79. data/.ai-assistance/projects/search-filter-builder/TODO.md +131 -0
  80. data/.ai-assistance/projects/template-maintenance/DESIGN.md +134 -0
  81. data/.ai-assistance/projects/workflow-space/TODO.md +213 -0
  82. data/.ai-assistance/reinstall-claude-desktop-windows.md +136 -0
  83. data/.ai-assistance/scripts/CLAUDE.md +150 -0
  84. data/.ai-assistance/scripts/bridge-init.sh +86 -0
  85. data/.ai-assistance/scripts/bridge-status.sh +44 -0
  86. data/.ai-assistance/scripts/capabilities-check.ts +104 -0
  87. data/.ai-assistance/scripts/check-outbox.sh +43 -0
  88. data/.ai-assistance/scripts/dep_graph.rb +91 -0
  89. data/.ai-assistance/scripts/lock-acquire.sh +103 -0
  90. data/.ai-assistance/scripts/lock-multi.sh +124 -0
  91. data/.ai-assistance/scripts/lock-queue.sh +94 -0
  92. data/.ai-assistance/scripts/setup-mcps.test.ts +188 -0
  93. data/.ai-assistance/scripts/setup-mcps.ts +234 -0
  94. data/.ai-assistance/scripts/task-complete.ts +74 -0
  95. data/.ai-assistance/scripts/task-create.ts +75 -0
  96. data/.ai-assistance/scripts/task-read.ts +125 -0
  97. data/.ai-assistance/scripts/token-logger.js +220 -0
  98. data/.ai-assistance/scripts/token-report.ts +158 -0
  99. data/.ai-assistance/scripts/token-session-start.js +66 -0
  100. data/.ai-assistance/skills/ai-instructions/SKILL.md +48 -0
  101. data/.ai-assistance/skills/code-specs/SKILL.md +69 -0
  102. data/.ai-assistance/skills/corporate-policies/SKILL.md +201 -0
  103. data/.ai-assistance/skills/dep-graph/SKILL.md +139 -0
  104. data/.ai-assistance/skills/ep-ai-manager/SKILL.md +417 -0
  105. data/.ai-assistance/skills/gemini-assist/SKILL.md +63 -0
  106. data/.ai-assistance/skills/gemini-assist/gemini-mcp-server.js +205 -0
  107. data/.ai-assistance/skills/gemini-assist/gemini_ask.py +1 -0
  108. data/.ai-assistance/skills/gemini-assist/gemini_ask.rb +240 -0
  109. data/.ai-assistance/skills/gemini-assist/prompts/cycle_end_review.txt +25 -0
  110. data/.ai-assistance/skills/graphql-schema-analysis/SKILL.md +261 -0
  111. data/.ai-assistance/skills/project-cycle/SKILL.md +177 -0
  112. data/.ai-assistance/skills/refactor/SKILL.md +62 -0
  113. data/.ai-assistance/skills/rubocop/SKILL.md +93 -0
  114. data/.ai-assistance/skills/ruby-scripting/SKILL.md +215 -0
  115. data/.ai-assistance/skills/spec-generation/SKILL.md +72 -0
  116. data/.ai-assistance/standards-version.json +21 -0
  117. data/.ai-assistance/token-budget.json +32 -0
  118. data/.ai-assistance/version.json +39 -0
  119. data/.claude/settings.json +146 -0
  120. data/.env.example +18 -0
  121. data/.gitattributes +15 -0
  122. data/.gitignore +13 -0
  123. data/.rubocop.yml +121 -97
  124. data/CHANGELOG.md +673 -477
  125. data/CLAUDE.md +232 -0
  126. data/Gemfile +30 -6
  127. data/Rakefile +90 -38
  128. data/docs/worklog.md +574 -0
  129. data/ecoportal-api-graphql.gemspec +40 -40
  130. data/lib/ecoportal/api/common/graphql/CLAUDE.md +36 -0
  131. data/lib/ecoportal/api/common/graphql/client.rb +1 -1
  132. data/lib/ecoportal/api/common/graphql/http_client.rb +35 -3
  133. data/lib/ecoportal/api/common/graphql/model/CLAUDE.md +28 -0
  134. data/lib/ecoportal/api/common/graphql/model/as_input.rb +8 -5
  135. data/lib/ecoportal/api/common/graphql/model/diffable/classic_diff_service.rb +3 -1
  136. data/lib/ecoportal/api/common/graphql/model/diffable/diff_service.rb +31 -23
  137. data/lib/ecoportal/api/common/graphql/model/diffable/hash_diff_nesting.rb +54 -1
  138. data/lib/ecoportal/api/graphql/CLAUDE.md +37 -0
  139. data/lib/ecoportal/api/graphql/base/CLAUDE.md +50 -0
  140. data/lib/ecoportal/api/graphql/base/ai_summary_version.rb +17 -0
  141. data/lib/ecoportal/api/graphql/base/delta_result.rb +16 -0
  142. data/lib/ecoportal/api/graphql/base/force/binding.rb +19 -0
  143. data/lib/ecoportal/api/graphql/base/force/binding_collection.rb +62 -0
  144. data/lib/ecoportal/api/graphql/base/force/collection.rb +47 -0
  145. data/lib/ecoportal/api/graphql/base/force.rb +65 -0
  146. data/lib/ecoportal/api/graphql/base/kickstand/job.rb +17 -0
  147. data/lib/ecoportal/api/graphql/base/kickstand/workflow.rb +18 -0
  148. data/lib/ecoportal/api/graphql/base/kickstand.rb +13 -0
  149. data/lib/ecoportal/api/graphql/base/page/basic.rb +38 -0
  150. data/lib/ecoportal/api/graphql/base/page/data_field/actions_list.rb +9 -0
  151. data/lib/ecoportal/api/graphql/base/page/data_field/ai_summary.rb +18 -0
  152. data/lib/ecoportal/api/graphql/base/page/data_field/checklist.rb +29 -0
  153. data/lib/ecoportal/api/graphql/base/page/data_field/collection.rb +112 -0
  154. data/lib/ecoportal/api/graphql/base/page/data_field/contractor_entities.rb +28 -0
  155. data/lib/ecoportal/api/graphql/base/page/data_field/cross_reference.rb +54 -0
  156. data/lib/ecoportal/api/graphql/base/page/data_field/date_field.rb +23 -0
  157. data/lib/ecoportal/api/graphql/base/page/data_field/file_field.rb +25 -0
  158. data/lib/ecoportal/api/graphql/base/page/data_field/gauge.rb +19 -0
  159. data/lib/ecoportal/api/graphql/base/page/data_field/geo.rb +24 -0
  160. data/lib/ecoportal/api/graphql/base/page/data_field/image_gallery.rb +24 -0
  161. data/lib/ecoportal/api/graphql/base/page/data_field/law.rb +8 -0
  162. data/lib/ecoportal/api/graphql/base/page/data_field/mailbox.rb +9 -0
  163. data/lib/ecoportal/api/graphql/base/page/data_field/number.rb +20 -0
  164. data/lib/ecoportal/api/graphql/base/page/data_field/people.rb +35 -0
  165. data/lib/ecoportal/api/graphql/base/page/data_field/plain_text.rb +17 -0
  166. data/lib/ecoportal/api/graphql/base/page/data_field/rich_text.rb +26 -0
  167. data/lib/ecoportal/api/graphql/base/page/data_field/select.rb +41 -0
  168. data/lib/ecoportal/api/graphql/base/page/data_field/signature.rb +9 -0
  169. data/lib/ecoportal/api/graphql/base/page/data_field/smart_fill.rb +17 -0
  170. data/lib/ecoportal/api/graphql/base/page/data_field/table.rb +9 -0
  171. data/lib/ecoportal/api/graphql/base/page/data_field/tag_field.rb +21 -0
  172. data/lib/ecoportal/api/graphql/base/page/data_field.rb +137 -12
  173. data/lib/ecoportal/api/graphql/base/page/phased/stage.rb +68 -14
  174. data/lib/ecoportal/api/graphql/base/page/phased.rb +1 -0
  175. data/lib/ecoportal/api/graphql/base/page/section.rb +36 -0
  176. data/lib/ecoportal/api/graphql/base/page/section_collection.rb +79 -0
  177. data/lib/ecoportal/api/graphql/base/page.rb +2 -0
  178. data/lib/ecoportal/api/graphql/base/pages_workflow/action_type_selection.rb +17 -0
  179. data/lib/ecoportal/api/graphql/base/pages_workflow/callback_type.rb +28 -0
  180. data/lib/ecoportal/api/graphql/base/pages_workflow/command_change.rb +17 -0
  181. data/lib/ecoportal/api/graphql/base/pages_workflow/command_change_message.rb +15 -0
  182. data/lib/ecoportal/api/graphql/base/pages_workflow/command_es_change.rb +17 -0
  183. data/lib/ecoportal/api/graphql/base/pages_workflow/command_interface.rb +36 -0
  184. data/lib/ecoportal/api/graphql/base/pages_workflow/email_config.rb +18 -0
  185. data/lib/ecoportal/api/graphql/base/pages_workflow/escalation_level.rb +19 -0
  186. data/lib/ecoportal/api/graphql/base/pages_workflow/in_system_config.rb +16 -0
  187. data/lib/ecoportal/api/graphql/base/pages_workflow/mailbox_field_selection.rb +17 -0
  188. data/lib/ecoportal/api/graphql/base/pages_workflow/operation_interface.rb +39 -0
  189. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/assign_to.rb +27 -0
  190. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/create_page.rb +21 -0
  191. data/lib/ecoportal/api/graphql/base/pages_workflow/operations/send_notification.rb +30 -0
  192. data/lib/ecoportal/api/graphql/base/pages_workflow/people_field_selection.rb +17 -0
  193. data/lib/ecoportal/api/graphql/base/pages_workflow/recipient_config.rb +34 -0
  194. data/lib/ecoportal/api/graphql/base/pages_workflow/register_field.rb +17 -0
  195. data/lib/ecoportal/api/graphql/base/pages_workflow/task_config_selection.rb +17 -0
  196. data/lib/ecoportal/api/graphql/base/pages_workflow/time_delay_config.rb +16 -0
  197. data/lib/ecoportal/api/graphql/base/pages_workflow/trigger_interface.rb +26 -0
  198. data/lib/ecoportal/api/graphql/base/pages_workflow/triggers/conditional_logic.rb +17 -0
  199. data/lib/ecoportal/api/graphql/base/pages_workflow/user_selection.rb +16 -0
  200. data/lib/ecoportal/api/graphql/base/pages_workflow.rb +35 -0
  201. data/lib/ecoportal/api/graphql/base/preset_view.rb +17 -0
  202. data/lib/ecoportal/api/graphql/base/preview_page.rb +23 -0
  203. data/lib/ecoportal/api/graphql/base/register.rb +18 -0
  204. data/lib/ecoportal/api/graphql/base.rb +11 -0
  205. data/lib/ecoportal/api/graphql/builder/CLAUDE.md +65 -0
  206. data/lib/ecoportal/api/graphql/builder/kickstand.rb +73 -0
  207. data/lib/ecoportal/api/graphql/builder/page.rb +210 -41
  208. data/lib/ecoportal/api/graphql/builder/register/preset_view.rb +84 -0
  209. data/lib/ecoportal/api/graphql/builder/register.rb +27 -19
  210. data/lib/ecoportal/api/graphql/builder/template.rb +80 -0
  211. data/lib/ecoportal/api/graphql/builder.rb +2 -0
  212. data/lib/ecoportal/api/graphql/compat/filter_translator.rb +107 -0
  213. data/lib/ecoportal/api/graphql/compat/page_reference.rb +23 -0
  214. data/lib/ecoportal/api/graphql/compat/pages.rb +212 -0
  215. data/lib/ecoportal/api/graphql/compat/registers.rb +84 -0
  216. data/lib/ecoportal/api/graphql/compat/response.rb +35 -0
  217. data/lib/ecoportal/api/graphql/compat/search_results.rb +33 -0
  218. data/lib/ecoportal/api/graphql/compat/stage_collection.rb +70 -0
  219. data/lib/ecoportal/api/graphql/compat/stage_view.rb +76 -0
  220. data/lib/ecoportal/api/graphql/compat.rb +17 -0
  221. data/lib/ecoportal/api/graphql/concerns/data_field_access.rb +71 -0
  222. data/lib/ecoportal/api/graphql/concerns/deprecation.rb +20 -0
  223. data/lib/ecoportal/api/graphql/concerns/fragment_definitions.rb +21 -28
  224. data/lib/ecoportal/api/graphql/concerns/page_compat.rb +51 -0
  225. data/lib/ecoportal/api/graphql/concerns/snake_camel_access.rb +60 -0
  226. data/lib/ecoportal/api/graphql/concerns.rb +4 -0
  227. data/lib/ecoportal/api/graphql/connection/page.rb +11 -0
  228. data/lib/ecoportal/api/graphql/connection/pages_workflow_command.rb +13 -0
  229. data/lib/ecoportal/api/graphql/connection/preset_view.rb +11 -0
  230. data/lib/ecoportal/api/graphql/connection/preview_page.rb +11 -0
  231. data/lib/ecoportal/api/graphql/connection.rb +4 -0
  232. data/lib/ecoportal/api/graphql/file_upload/client.rb +181 -0
  233. data/lib/ecoportal/api/graphql/file_upload.rb +10 -0
  234. data/lib/ecoportal/api/graphql/fragment/action.rb +1 -1
  235. data/lib/ecoportal/api/graphql/fragment/action_category.rb +1 -1
  236. data/lib/ecoportal/api/graphql/fragment/contractor_entity.rb +1 -1
  237. data/lib/ecoportal/api/graphql/fragment/force.rb +30 -0
  238. data/lib/ecoportal/api/graphql/fragment/location_draft.rb +2 -2
  239. data/lib/ecoportal/api/graphql/fragment/location_node.rb +1 -1
  240. data/lib/ecoportal/api/graphql/fragment/locations_error.rb +1 -1
  241. data/lib/ecoportal/api/graphql/fragment/page.rb +85 -0
  242. data/lib/ecoportal/api/graphql/fragment/pages/common_page_union.rb +395 -0
  243. data/lib/ecoportal/api/graphql/fragment/pages.rb +15 -0
  244. data/lib/ecoportal/api/graphql/fragment/pages_workflow.rb +172 -0
  245. data/lib/ecoportal/api/graphql/fragment/pagination.rb +1 -1
  246. data/lib/ecoportal/api/graphql/fragment.rb +37 -27
  247. data/lib/ecoportal/api/graphql/input/contractor_entity/update.rb +25 -0
  248. data/lib/ecoportal/api/graphql/input/delta_input.rb +16 -0
  249. data/lib/ecoportal/api/graphql/input/page/archive.rb +14 -0
  250. data/lib/ecoportal/api/graphql/input/page/build_from_template.rb +13 -0
  251. data/lib/ecoportal/api/graphql/input/page/create_draft.rb +13 -0
  252. data/lib/ecoportal/api/graphql/input/page/create_from_template.rb +18 -0
  253. data/lib/ecoportal/api/graphql/input/page/delete_draft.rb +13 -0
  254. data/lib/ecoportal/api/graphql/input/page/publish_draft.rb +13 -0
  255. data/lib/ecoportal/api/graphql/input/page/review_task.rb +14 -0
  256. data/lib/ecoportal/api/graphql/input/page/unarchive.rb +14 -0
  257. data/lib/ecoportal/api/graphql/input/page/update.rb +140 -0
  258. data/lib/ecoportal/api/graphql/input/page.rb +26 -0
  259. data/lib/ecoportal/api/graphql/input/preset_view/create.rb +18 -0
  260. data/lib/ecoportal/api/graphql/input/preset_view/permission.rb +16 -0
  261. data/lib/ecoportal/api/graphql/input/preset_view/update.rb +16 -0
  262. data/lib/ecoportal/api/graphql/input/preset_view.rb +14 -0
  263. data/lib/ecoportal/api/graphql/input/register/create.rb +18 -0
  264. data/lib/ecoportal/api/graphql/input/register/update.rb +15 -0
  265. data/lib/ecoportal/api/graphql/input/register.rb +13 -0
  266. data/lib/ecoportal/api/graphql/input/search_conf/ai_generator.rb +234 -0
  267. data/lib/ecoportal/api/graphql/input/search_conf.rb +367 -0
  268. data/lib/ecoportal/api/graphql/input/variable_binding.rb +20 -0
  269. data/lib/ecoportal/api/graphql/input/workflow_command/add_action_tag.rb +18 -0
  270. data/lib/ecoportal/api/graphql/input/workflow_command/add_binding.rb +18 -0
  271. data/lib/ecoportal/api/graphql/input/workflow_command/add_comment_tagging_user_group.rb +18 -0
  272. data/lib/ecoportal/api/graphql/input/workflow_command/add_default_direct_strategy_user.rb +18 -0
  273. data/lib/ecoportal/api/graphql/input/workflow_command/add_default_strategy.rb +18 -0
  274. data/lib/ecoportal/api/graphql/input/workflow_command/add_direct_strategy_user.rb +18 -0
  275. data/lib/ecoportal/api/graphql/input/workflow_command/add_field.rb +18 -0
  276. data/lib/ecoportal/api/graphql/input/workflow_command/add_force.rb +18 -0
  277. data/lib/ecoportal/api/graphql/input/workflow_command/add_gauge_field_stop.rb +19 -0
  278. data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_field_config.rb +23 -0
  279. data/lib/ecoportal/api/graphql/input/workflow_command/add_linked_helper.rb +18 -0
  280. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation.rb +18 -0
  281. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_direct_strategy_user.rb +18 -0
  282. data/lib/ecoportal/api/graphql/input/workflow_command/add_operation_strategy.rb +18 -0
  283. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_action_type.rb +18 -0
  284. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_filter.rb +18 -0
  285. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_people_field.rb +18 -0
  286. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_task_config.rb +18 -0
  287. data/lib/ecoportal/api/graphql/input/workflow_command/add_recipient_user.rb +18 -0
  288. data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback.rb +23 -0
  289. data/lib/ecoportal/api/graphql/input/workflow_command/add_scheduled_callback_action.rb +18 -0
  290. data/lib/ecoportal/api/graphql/input/workflow_command/add_section.rb +18 -0
  291. data/lib/ecoportal/api/graphql/input/workflow_command/add_select_field_option.rb +19 -0
  292. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage.rb +18 -0
  293. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_section.rb +18 -0
  294. data/lib/ecoportal/api/graphql/input/workflow_command/add_stage_tag.rb +18 -0
  295. data/lib/ecoportal/api/graphql/input/workflow_command/add_strategy.rb +18 -0
  296. data/lib/ecoportal/api/graphql/input/workflow_command/add_task.rb +18 -0
  297. data/lib/ecoportal/api/graphql/input/workflow_command/add_task_assignment_user_group.rb +18 -0
  298. data/lib/ecoportal/api/graphql/input/workflow_command/add_workflow_callback.rb +18 -0
  299. data/lib/ecoportal/api/graphql/input/workflow_command/collapse_section.rb +18 -0
  300. data/lib/ecoportal/api/graphql/input/workflow_command/edit_binding.rb +18 -0
  301. data/lib/ecoportal/api/graphql/input/workflow_command/edit_creator_permissions.rb +18 -0
  302. data/lib/ecoportal/api/graphql/input/workflow_command/edit_default_strategy.rb +18 -0
  303. data/lib/ecoportal/api/graphql/input/workflow_command/edit_field_configuration.rb +21 -0
  304. data/lib/ecoportal/api/graphql/input/workflow_command/edit_force.rb +18 -0
  305. data/lib/ecoportal/api/graphql/input/workflow_command/edit_gauge_field_stop.rb +19 -0
  306. data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_field_config.rb +19 -0
  307. data/lib/ecoportal/api/graphql/input/workflow_command/edit_linked_helper.rb +18 -0
  308. data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation.rb +18 -0
  309. data/lib/ecoportal/api/graphql/input/workflow_command/edit_operation_strategy.rb +18 -0
  310. data/lib/ecoportal/api/graphql/input/workflow_command/edit_page.rb +28 -0
  311. data/lib/ecoportal/api/graphql/input/workflow_command/edit_page_creator_permissions.rb +18 -0
  312. data/lib/ecoportal/api/graphql/input/workflow_command/edit_reminder.rb +18 -0
  313. data/lib/ecoportal/api/graphql/input/workflow_command/edit_required_sign_offs.rb +18 -0
  314. data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_comment_tagging.rb +18 -0
  315. data/lib/ecoportal/api/graphql/input/workflow_command/edit_restrict_task_assignment.rb +18 -0
  316. data/lib/ecoportal/api/graphql/input/workflow_command/edit_scheduled_callback.rb +22 -0
  317. data/lib/ecoportal/api/graphql/input/workflow_command/edit_section_header.rb +18 -0
  318. data/lib/ecoportal/api/graphql/input/workflow_command/edit_select_field_option.rb +19 -0
  319. data/lib/ecoportal/api/graphql/input/workflow_command/edit_stage.rb +18 -0
  320. data/lib/ecoportal/api/graphql/input/workflow_command/edit_strategy.rb +18 -0
  321. data/lib/ecoportal/api/graphql/input/workflow_command/edit_task_due.rb +18 -0
  322. data/lib/ecoportal/api/graphql/input/workflow_command/edit_trigger.rb +18 -0
  323. data/lib/ecoportal/api/graphql/input/workflow_command/expand_section.rb +18 -0
  324. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/contractor_entities.rb +24 -0
  325. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/cross_reference.rb +23 -0
  326. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/date.rb +20 -0
  327. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/gauge.rb +20 -0
  328. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/image_gallery.rb +20 -0
  329. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/location_field.rb +24 -0
  330. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/people.rb +24 -0
  331. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/plain_text.rb +20 -0
  332. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/rich_text.rb +20 -0
  333. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/select.rb +20 -0
  334. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/signature.rb +20 -0
  335. data/lib/ecoportal/api/graphql/input/workflow_command/field_config/table.rb +25 -0
  336. data/lib/ecoportal/api/graphql/input/workflow_command/move_field.rb +18 -0
  337. data/lib/ecoportal/api/graphql/input/workflow_command/move_stage.rb +18 -0
  338. data/lib/ecoportal/api/graphql/input/workflow_command/remove_action_tag.rb +18 -0
  339. data/lib/ecoportal/api/graphql/input/workflow_command/remove_binding.rb +18 -0
  340. data/lib/ecoportal/api/graphql/input/workflow_command/remove_callback.rb +18 -0
  341. data/lib/ecoportal/api/graphql/input/workflow_command/remove_comment_tagging_user_group.rb +18 -0
  342. data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_direct_strategy_user.rb +18 -0
  343. data/lib/ecoportal/api/graphql/input/workflow_command/remove_default_strategy.rb +18 -0
  344. data/lib/ecoportal/api/graphql/input/workflow_command/remove_direct_strategy_user.rb +18 -0
  345. data/lib/ecoportal/api/graphql/input/workflow_command/remove_field.rb +18 -0
  346. data/lib/ecoportal/api/graphql/input/workflow_command/remove_force.rb +18 -0
  347. data/lib/ecoportal/api/graphql/input/workflow_command/remove_gauge_field_stop.rb +17 -0
  348. data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_field_config.rb +17 -0
  349. data/lib/ecoportal/api/graphql/input/workflow_command/remove_linked_helper.rb +18 -0
  350. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation.rb +18 -0
  351. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_direct_strategy_user.rb +18 -0
  352. data/lib/ecoportal/api/graphql/input/workflow_command/remove_operation_strategy.rb +18 -0
  353. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_action_type.rb +18 -0
  354. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_filter.rb +18 -0
  355. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_people_field.rb +18 -0
  356. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_task_config.rb +18 -0
  357. data/lib/ecoportal/api/graphql/input/workflow_command/remove_recipient_user.rb +18 -0
  358. data/lib/ecoportal/api/graphql/input/workflow_command/remove_scheduled_callback.rb +18 -0
  359. data/lib/ecoportal/api/graphql/input/workflow_command/remove_section.rb +18 -0
  360. data/lib/ecoportal/api/graphql/input/workflow_command/remove_select_field_option.rb +17 -0
  361. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage.rb +18 -0
  362. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_section.rb +18 -0
  363. data/lib/ecoportal/api/graphql/input/workflow_command/remove_stage_tag.rb +18 -0
  364. data/lib/ecoportal/api/graphql/input/workflow_command/remove_strategy.rb +18 -0
  365. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task.rb +18 -0
  366. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_assignment_user_group.rb +18 -0
  367. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_due.rb +18 -0
  368. data/lib/ecoportal/api/graphql/input/workflow_command/remove_task_priority_level.rb +18 -0
  369. data/lib/ecoportal/api/graphql/input/workflow_command/reorder_forces.rb +18 -0
  370. data/lib/ecoportal/api/graphql/input/workflow_command/reorder_section.rb +18 -0
  371. data/lib/ecoportal/api/graphql/input/workflow_command.rb +251 -0
  372. data/lib/ecoportal/api/graphql/input.rb +8 -0
  373. data/lib/ecoportal/api/graphql/interface/base_page.rb +100 -58
  374. data/lib/ecoportal/api/graphql/interface/location_structure/nodes.rb +27 -28
  375. data/lib/ecoportal/api/graphql/logic/base_model.rb +2 -0
  376. data/lib/ecoportal/api/graphql/logic/base_query.rb +45 -2
  377. data/lib/ecoportal/api/graphql/logic/input.rb +15 -0
  378. data/lib/ecoportal/api/graphql/model/ai_summary_version.rb +10 -0
  379. data/lib/ecoportal/api/graphql/model/organization.rb +65 -55
  380. data/lib/ecoportal/api/graphql/model/page/basic.rb +14 -0
  381. data/lib/ecoportal/api/graphql/model/page/phased.rb +82 -20
  382. data/lib/ecoportal/api/graphql/model/page.rb +1 -0
  383. data/lib/ecoportal/api/graphql/model/page_union.rb +21 -0
  384. data/lib/ecoportal/api/graphql/model/pages_workflow.rb +20 -0
  385. data/lib/ecoportal/api/graphql/model/preset_view.rb +10 -0
  386. data/lib/ecoportal/api/graphql/model/preview_page.rb +10 -0
  387. data/lib/ecoportal/api/graphql/model/register.rb +10 -0
  388. data/lib/ecoportal/api/graphql/model.rb +8 -0
  389. data/lib/ecoportal/api/graphql/mutation/ai_summary/generate.rb +45 -0
  390. data/lib/ecoportal/api/graphql/mutation/ai_summary/submit_feedback.rb +40 -0
  391. data/lib/ecoportal/api/graphql/mutation/ai_summary.rb +13 -0
  392. data/lib/ecoportal/api/graphql/mutation/kickstand/bulk_update_jobs.rb +43 -0
  393. data/lib/ecoportal/api/graphql/mutation/kickstand/bulk_update_workflows.rb +43 -0
  394. data/lib/ecoportal/api/graphql/mutation/kickstand/fail_job.rb +39 -0
  395. data/lib/ecoportal/api/graphql/mutation/kickstand/fail_workflow.rb +39 -0
  396. data/lib/ecoportal/api/graphql/mutation/kickstand/start_job.rb +39 -0
  397. data/lib/ecoportal/api/graphql/mutation/kickstand/start_workflow.rb +39 -0
  398. data/lib/ecoportal/api/graphql/mutation/kickstand/stop_workflow.rb +39 -0
  399. data/lib/ecoportal/api/graphql/mutation/kickstand.rb +18 -0
  400. data/lib/ecoportal/api/graphql/mutation/location_structure/apply_commands.rb +3 -3
  401. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/add_commands.rb +2 -2
  402. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/create.rb +2 -2
  403. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/drop_bad_commands.rb +3 -3
  404. data/lib/ecoportal/api/graphql/mutation/location_structure/draft/publish.rb +3 -3
  405. data/lib/ecoportal/api/graphql/mutation/page/approve_review_task.rb +40 -0
  406. data/lib/ecoportal/api/graphql/mutation/page/archive.rb +40 -0
  407. data/lib/ecoportal/api/graphql/mutation/page/batch_update_review_task.rb +40 -0
  408. data/lib/ecoportal/api/graphql/mutation/page/build_from_template.rb +50 -0
  409. data/lib/ecoportal/api/graphql/mutation/page/create_draft.rb +40 -0
  410. data/lib/ecoportal/api/graphql/mutation/page/create_from_template.rb +43 -0
  411. data/lib/ecoportal/api/graphql/mutation/page/delete_draft.rb +40 -0
  412. data/lib/ecoportal/api/graphql/mutation/page/execute_force_commands.rb +69 -0
  413. data/lib/ecoportal/api/graphql/mutation/page/execute_workflow_commands.rb +51 -0
  414. data/lib/ecoportal/api/graphql/mutation/page/publish_draft.rb +40 -0
  415. data/lib/ecoportal/api/graphql/mutation/page/reject_review_task.rb +40 -0
  416. data/lib/ecoportal/api/graphql/mutation/page/restart_review_task.rb +40 -0
  417. data/lib/ecoportal/api/graphql/mutation/page/unarchive.rb +40 -0
  418. data/lib/ecoportal/api/graphql/mutation/page/undo_review_task.rb +40 -0
  419. data/lib/ecoportal/api/graphql/mutation/page/update.rb +40 -0
  420. data/lib/ecoportal/api/graphql/mutation/page/update_variable_bindings.rb +44 -0
  421. data/lib/ecoportal/api/graphql/mutation/page.rb +28 -0
  422. data/lib/ecoportal/api/graphql/mutation/preset_view/create.rb +35 -0
  423. data/lib/ecoportal/api/graphql/mutation/preset_view/destroy.rb +35 -0
  424. data/lib/ecoportal/api/graphql/mutation/preset_view/permission.rb +37 -0
  425. data/lib/ecoportal/api/graphql/mutation/preset_view/update.rb +35 -0
  426. data/lib/ecoportal/api/graphql/mutation/preset_view.rb +15 -0
  427. data/lib/ecoportal/api/graphql/mutation/register/create.rb +35 -0
  428. data/lib/ecoportal/api/graphql/mutation/register/destroy.rb +35 -0
  429. data/lib/ecoportal/api/graphql/mutation/register/update.rb +35 -0
  430. data/lib/ecoportal/api/graphql/mutation/register.rb +14 -0
  431. data/lib/ecoportal/api/graphql/mutation/smart_fill/generate.rb +36 -0
  432. data/lib/ecoportal/api/graphql/mutation/smart_fill/submit_feedback.rb +40 -0
  433. data/lib/ecoportal/api/graphql/mutation/smart_fill.rb +13 -0
  434. data/lib/ecoportal/api/graphql/mutation/template/create.rb +39 -0
  435. data/lib/ecoportal/api/graphql/mutation/template/create_related_page.rb +46 -0
  436. data/lib/ecoportal/api/graphql/mutation/template/destroy_related_page.rb +43 -0
  437. data/lib/ecoportal/api/graphql/mutation/template/publish.rb +39 -0
  438. data/lib/ecoportal/api/graphql/mutation/template/unpublish.rb +39 -0
  439. data/lib/ecoportal/api/graphql/mutation/template/update.rb +43 -0
  440. data/lib/ecoportal/api/graphql/mutation/template/update_information.rb +43 -0
  441. data/lib/ecoportal/api/graphql/mutation/template.rb +18 -0
  442. data/lib/ecoportal/api/graphql/mutation.rb +8 -0
  443. data/lib/ecoportal/api/graphql/payload/ai_summary_generate.rb +12 -0
  444. data/lib/ecoportal/api/graphql/payload/execute_workflow_commands.rb +36 -0
  445. data/lib/ecoportal/api/graphql/payload/force_commands.rb +31 -0
  446. data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_jobs.rb +36 -0
  447. data/lib/ecoportal/api/graphql/payload/kickstand/bulk_update_workflows.rb +36 -0
  448. data/lib/ecoportal/api/graphql/payload/kickstand/job.rb +13 -0
  449. data/lib/ecoportal/api/graphql/payload/kickstand/workflow.rb +13 -0
  450. data/lib/ecoportal/api/graphql/payload/kickstand.rb +15 -0
  451. data/lib/ecoportal/api/graphql/payload/location_structure/draft/create.rb +33 -34
  452. data/lib/ecoportal/api/graphql/payload/ok_payload.rb +21 -0
  453. data/lib/ecoportal/api/graphql/payload/page/archive.rb +13 -0
  454. data/lib/ecoportal/api/graphql/payload/page/build_from_template.rb +13 -0
  455. data/lib/ecoportal/api/graphql/payload/page/create_from_template.rb +13 -0
  456. data/lib/ecoportal/api/graphql/payload/page/draft.rb +13 -0
  457. data/lib/ecoportal/api/graphql/payload/page/review_task.rb +13 -0
  458. data/lib/ecoportal/api/graphql/payload/page/unarchive.rb +13 -0
  459. data/lib/ecoportal/api/graphql/payload/page/update.rb +13 -0
  460. data/lib/ecoportal/api/graphql/payload/page/update_variable_bindings.rb +13 -0
  461. data/lib/ecoportal/api/graphql/payload/page.rb +19 -0
  462. data/lib/ecoportal/api/graphql/payload/preset_view.rb +11 -0
  463. data/lib/ecoportal/api/graphql/payload/register.rb +11 -0
  464. data/lib/ecoportal/api/graphql/payload/template/create.rb +13 -0
  465. data/lib/ecoportal/api/graphql/payload/template/create_related_page.rb +13 -0
  466. data/lib/ecoportal/api/graphql/payload/template/destroy_related_page.rb +13 -0
  467. data/lib/ecoportal/api/graphql/payload/template/publish.rb +13 -0
  468. data/lib/ecoportal/api/graphql/payload/template/unpublish.rb +13 -0
  469. data/lib/ecoportal/api/graphql/payload/template/update.rb +13 -0
  470. data/lib/ecoportal/api/graphql/payload/template/update_information.rb +13 -0
  471. data/lib/ecoportal/api/graphql/payload/template.rb +18 -0
  472. data/lib/ecoportal/api/graphql/payload.rb +11 -0
  473. data/lib/ecoportal/api/graphql/query/action.rb +1 -1
  474. data/lib/ecoportal/api/graphql/query/action_categories.rb +1 -1
  475. data/lib/ecoportal/api/graphql/query/actions.rb +2 -2
  476. data/lib/ecoportal/api/graphql/query/contractor_entities.rb +1 -1
  477. data/lib/ecoportal/api/graphql/query/file_upload_signature.rb +76 -0
  478. data/lib/ecoportal/api/graphql/query/location_structure/draft.rb +2 -2
  479. data/lib/ecoportal/api/graphql/query/location_structure.rb +1 -1
  480. data/lib/ecoportal/api/graphql/query/location_structures.rb +1 -1
  481. data/lib/ecoportal/api/graphql/query/page.rb +45 -0
  482. data/lib/ecoportal/api/graphql/query/page_delta.rb +47 -0
  483. data/lib/ecoportal/api/graphql/query/page_with_forces.rb +43 -0
  484. data/lib/ecoportal/api/graphql/query/pages.rb +59 -0
  485. data/lib/ecoportal/api/graphql/query/pages_workflow_commands.rb +59 -0
  486. data/lib/ecoportal/api/graphql/query/register_preset_views.rb +78 -0
  487. data/lib/ecoportal/api/graphql/query/register_preview_pages.rb +83 -0
  488. data/lib/ecoportal/api/graphql/query/templates.rb +53 -0
  489. data/lib/ecoportal/api/graphql/query.rb +11 -0
  490. data/lib/ecoportal/api/graphql.rb +60 -2
  491. data/lib/ecoportal/api/graphql_version.rb +5 -5
  492. data/scripts/auto-worker-scheduler.sh +386 -0
  493. data/tests/contractor_entity_create.rb +19 -19
  494. data/tests/contractor_entity_udpate.rb +20 -20
  495. data/tests/dump_page_model.rb +74 -0
  496. data/tests/loc_structure_get.rb +1 -2
  497. data/tests/loc_structure_update.rb +51 -51
  498. data/tests/loc_structures_get.rb +15 -15
  499. metadata +436 -5
@@ -0,0 +1,134 @@
1
+ # Template-Maintenance Tooling — Design & Scoping
2
+
3
+ **Status:** DESIGN ONLY — not started. Implementation deferred until after the backwards-compat
4
+ cutover release. This doc scopes the work so the AI agent (integrations agent) can pick it up.
5
+ **Owner:** Oscar. **Drafted:** 2026-07-02.
6
+
7
+ ---
8
+
9
+ ## Why
10
+
11
+ A customer delivery needs **300+ templates** built/maintained programmatically (deadline ~Sept
12
+ 2026 for the CSV→templates pipeline). We need a GraphQL-native way to **build and update templates
13
+ (workflows)** — create stages/sections/fields/forces/strategies/etc., and later diff a desired
14
+ template against a live one and apply only the delta.
15
+
16
+ This is a **new, additive** capability. It has **no end-script dependencies** and does **not** touch
17
+ the maintained cutover integrations (toocs-coding, cans-upsert, supplier-documents, and Travis's
18
+ upcoming mitre10). **OozeRedirect stays for the APIv2-shaped cases.** Template editing needs **no
19
+ backwards compatibility** — we rewrite it cleanly, reusing the *ideas* (not the code) proven for
20
+ APIv2, and add specs (preventative — see "Testing philosophy").
21
+
22
+ Can ship in the **same release** as the cutover fixes as long as it **loads** and **passes the tests
23
+ we can gather** (no runtime coupling to existing scripts).
24
+
25
+ ---
26
+
27
+ ## What already exists (survey, 2026-07-01/02) — this is "extend a pattern", not "build new"
28
+
29
+ ### Gem (`ecoportal-api-graphql`) — the mutation surface is largely built
30
+ - **91** `input/workflow_command/*.rb` command inputs (stages, sections, fields, forces, bindings,
31
+ tasks, strategies, operations, recipients, callbacks, gauge stops, linked fields, select options…).
32
+ - `input/workflow_command.rb` — `WorkflowCommand::COMMAND_MAP` registry (`SCHEMA_VERSION`).
33
+ - `mutation/page/execute_workflow_commands.rb` — applies a command batch (`executeWorkflowCommands`).
34
+ - `query/pages_workflow_commands.rb` + `base/pages_workflow*` — the workflow READ model.
35
+ - `base/force.rb` — queues `editForce`/`addBinding` commands (forces ARE mutable via the command-bus;
36
+ see `.ai-assistance/code/ecoPortal_architecture/10_forces_workflow_builder.md`).
37
+
38
+ ### eco-helpers — the samples space + the diff→commands PRECEDENT
39
+ - `lib/eco/api/usecases/graphql/samples/pages/{page,org_page}/{base,dsl}.rb` + `pages/CLAUDE.md` —
40
+ the **established sample convention**: each sample is a `base.rb` + `dsl.rb` pair. A template
41
+ sample slots in as `samples/pages/template/{base,dsl}.rb`.
42
+ - `lib/eco/api/usecases/graphql/samples/location/command/{dsl,service,service/tree_update,results,
43
+ track_changed_ids}.rb` + `samples/location/service/tree_diff/convertible/*` — a **working
44
+ diff→apply-commands engine** for LOCATION STRUCTURE (which uses `location_structure/apply_commands`
45
+ in the gem). This is the architectural precedent to mirror for templates.
46
+ - **`track_changed_ids` is the hard part already solved:** newly created nodes get server-assigned
47
+ ids that *subsequent* commands must reference (a new stage's id feeds the addSection targeting it).
48
+ Template build has the identical id-threading problem — reuse this pattern, don't reinvent it.
49
+
50
+ ---
51
+
52
+ ## Design: template editing = the location diff→commands engine, retargeted to workflow commands
53
+
54
+ Mirror `samples/location/command` + `tree_diff`, but:
55
+ - **Target model:** template/workflow (stages → sections → fields → forces/strategies/…) instead of
56
+ the location tree.
57
+ - **Command vocabulary:** the 91 `WorkflowCommand` inputs instead of location `apply_commands`.
58
+ - **Apply mutation:** `executeWorkflowCommands` instead of `applyCommands`.
59
+ - **DSL home:** `samples/pages/template/{base,dsl}.rb`, following the existing `page`/`org_page` shape.
60
+
61
+ Two capabilities, in order of need:
62
+ 1. **Build from scratch** — declare a desired template via the DSL → emit an ordered command sequence
63
+ (addStage → addSection → addField → …) → `executeWorkflowCommands`, threading server-assigned ids
64
+ between commands (`track_changed_ids` pattern) → read back to verify.
65
+ 2. **Diff & update** — read the live template's workflow structure, diff against the desired DSL,
66
+ emit only the delta commands (the eventual UAT→PROD `template-diff-deploy` need). Build (1) first;
67
+ (2) reuses the same command emitter + the tree_diff approach.
68
+
69
+ ---
70
+
71
+ ## Reference target (the test/characterization anchor)
72
+
73
+ Reconstruct **template sample `6a3fa5b8f89e07c758df622b`** step by step. Capture it once as a pinned
74
+ fixture (a `dump_template` tool — extend `tests/dump_page_model.rb`'s approach to fetch the workflow
75
+ structure via the `pages_workflow_commands`/`PagesWorkflow` read). Each construction step reproduces
76
+ one piece of that sample; the fixture is the golden master to diff against.
77
+
78
+ ---
79
+
80
+ ## Testing philosophy (aligned with how our devs actually work)
81
+
82
+ NOT specs-first-as-design. Specs here are **preventative** (guard against future breakage), matching
83
+ the team's practice. Two layers:
84
+ 1. **Offline serialization specs (CI-pure, fast):** each `WorkflowCommand` input → correct GraphQL
85
+ payload; the command emitter produces the right ordered sequence + id-threading for a given DSL.
86
+ Added incrementally as each command type is wired — regression net, not design driver.
87
+ 2. **Live characterization harness (sandbox org, NOT CI):** replay the command sequence to reconstruct
88
+ sample `6a3fa5b8…622b`, fetch the result, assert structure-equivalence vs the pinned fixture.
89
+ `executeWorkflowCommands` mutates server state, so this runs against a sandbox/dev org by hand,
90
+ not in CI. Doubles as the regression net for the 300+ template delivery.
91
+
92
+ Specs go in **eco-helpers** (for the samples/pages layer) and in the gem (for command serialization).
93
+
94
+ ---
95
+
96
+ ## Phases
97
+
98
+ - **Phase 0 — Study & capture (read-only; no prod writes):** read the two precedents
99
+ (`samples/pages/{page,org_page}/{base,dsl}.rb` + `pages/CLAUDE.md`; `samples/location/command` +
100
+ `tree_diff`, esp. `track_changed_ids`); build `dump_template` + pin sample `6a3fa5b8…622b`; map which
101
+ of the 91 commands the sample needs.
102
+ - **Phase 1 — Gem read-back + ergonomic execute facade:** confirm the `PagesWorkflow` read returns a
103
+ diff-able structure; ensure `executeWorkflowCommands` has a clean builder facade. Offline command
104
+ specs (incremental).
105
+ - **Phase 2 — `samples/pages/template/{base,dsl}.rb` (build-from-scratch):** DSL → ordered command
106
+ emitter + id-threading → execute → read-back verify.
107
+ - **Phase 3 — Characterization suite:** the sandbox replay-the-sample suite (one assertion group per
108
+ construction step) vs the Phase 0 fixture.
109
+ - **Phase 4 — Diff & update:** read live template, diff vs desired, emit delta commands (reuses the
110
+ tree_diff approach). Feeds `template-diff-deploy` (UAT→PROD via changelog).
111
+ - **Phase 5 — Ship:** rides the same release; gated only on "loads + passes gathered tests"; no
112
+ end-script deps; OozeRedirect untouched.
113
+
114
+ ---
115
+
116
+ ## Constraints / guardrails
117
+ - No runtime coupling to the maintained integrations; OozeRedirect is for APIv2 cases only.
118
+ - `WorkflowCommandInput` API is **volatile** — design for change (thin, data-driven command mapping;
119
+ keep `SCHEMA_VERSION` in view).
120
+ - Prefer capturing verified platform facts in the **shared** knowledge base (not machine-local memory)
121
+ — the forces-RCA lesson.
122
+
123
+ ## Open questions (for the implementing agent / Oscar)
124
+ 1. Sandbox org for the live characterization harness — which org/creds?
125
+ 2. Is the `PagesWorkflow` read complete enough to diff a full template, or are there gaps (like the
126
+ forces READ query `Query::PageWithForces`, which is WIP)?
127
+ 3. Command ordering/dependency rules — is there a canonical order the backend expects, or does
128
+ `executeWorkflowCommands` resolve intra-batch references? (drives the id-threading design)
129
+ 4. Does `6a3fa5b8…622b` exercise forces? If so, coordinate with the `force_support?` read/write split.
130
+
131
+ ## Related
132
+ - `.ai-assistance/code/ecoPortal_architecture/10_forces_workflow_builder.md` (command-bus + forces)
133
+ - Memory: post-cutover-priorities, project-template-csv-pipeline, project-template-diff-deploy,
134
+ project-template-update-architecture, project-workflow-space.
@@ -0,0 +1,213 @@
1
+ # TODOs — Workflow Space Project
2
+
3
+ > Created 2026-06-11 from live schema introspection `20260605T101224_live_ep_graphql_schema.graphql.json`.
4
+ > Phases W1-W5 implemented on branch `pages`. All completed 2026-06-11.
5
+
6
+ ---
7
+
8
+ ## Phase W1 — Read Model (PagesWorkflow)
9
+
10
+ - [x] **W1.1** `Base::PagesWorkflow` — `autoPageCreationEnabled`, `stages` (passarray),
11
+ `fields` (embeds_many RegisterField), `commands` connection reference.
12
+ *Done 2026-06-11 — `lib/ecoportal/api/graphql/base/pages_workflow.rb`*
13
+
14
+ - [x] **W1.2** `Base::PagesWorkflow::RegisterField` — `key`, `name`, `type`, `total`,
15
+ `missing`, `enableCrossRegisterReporting`.
16
+ *Done 2026-06-11 — `base/pages_workflow/register_field.rb`*
17
+
18
+ - [x] **W1.3** `Base::PagesWorkflow::CallbackType` — `id`, `triggerCondition`, `operations`
19
+ (dispatched via OperationInterface), `triggers` (dispatched via TriggerInterface).
20
+ *Done 2026-06-11 — `base/pages_workflow/callback_type.rb`*
21
+
22
+ - [x] **W1.4** `Base::PagesWorkflow::OperationInterface` + three concrete classes:
23
+ `Operations::AssignTo` (targetTaskType, escalationLevels),
24
+ `Operations::CreatePage` (templateId, crossReferenceFieldId),
25
+ `Operations::SendNotification` (recurring, emailConfig, inSystemConfig, recipientConfig).
26
+ `from_doc` dispatches on `__typename`.
27
+ *Done 2026-06-11 — `base/pages_workflow/operation_interface.rb` + `operations/`*
28
+
29
+ - [x] **W1.5** `Base::PagesWorkflow::TriggerInterface` + concrete class:
30
+ `Triggers::ConditionalLogic` (filters: [StoredEsFilter!]).
31
+ `from_doc` dispatches on `__typename`.
32
+ *Done 2026-06-11 — `base/pages_workflow/trigger_interface.rb` + `triggers/`*
33
+
34
+ - [x] **W1.6** Supporting value objects: `TimeDelayConfig`, `EscalationLevel`,
35
+ `RecipientConfig`, `EmailConfig`, `InSystemConfig`, `UserSelection`,
36
+ `PeopleFieldSelection`, `TaskConfigSelection`, `ActionTypeSelection`, `MailboxFieldSelection`.
37
+ *Done 2026-06-11*
38
+
39
+ - [x] **W1.7** `Base::PagesWorkflow::CommandInterface` + three concrete classes:
40
+ `CommandChange` (changes: [Change!]), `CommandChangeMessage` (changeMessages: [String!]),
41
+ `CommandEsChange` (changes: [StoredEsFilterChange!]).
42
+ *Done 2026-06-11 — `base/pages_workflow/command_interface.rb`*
43
+
44
+ - [x] **W1.8** `Model::PagesWorkflow < Base::PagesWorkflow` — `class_resolver` wiring
45
+ for `command_connection_class`, `operation_class`, `trigger_class`.
46
+ *Done 2026-06-11 — `lib/ecoportal/api/graphql/model/pages_workflow.rb`*
47
+
48
+ - [x] **W1.9** `Connection::PagesWorkflowCommand` — paginated connection for command log.
49
+ *Done 2026-06-11 — `lib/ecoportal/api/graphql/connection/pages_workflow_command.rb`*
50
+
51
+ - [x] **W1.10** Three fragments in `fragment/pages_workflow.rb`:
52
+ `PagesWorkflowFields`, `PagesWorkflowCallbackFields`, `PagesWorkflowCommandFields`.
53
+ *Done 2026-06-11*
54
+
55
+ ---
56
+
57
+ ## Phase W2 — Mutation: ExecuteWorkflowCommands
58
+
59
+ - [x] **W2.1** `Mutation::Page::ExecuteWorkflowCommands` — `field_name :executeWorkflowCommands`,
60
+ `query(id:, patch_ver:, commands:)` method, `default_payload_block` (patchVer + item +
61
+ errors). `payload_class` → `Payload::ExecuteWorkflowCommands`.
62
+ *Done 2026-06-11 — `mutation/page/execute_workflow_commands.rb`*
63
+
64
+ - [x] **W2.2** `Payload::ExecuteWorkflowCommands` — `patchVer`, `item` (Model::PagesWorkflow),
65
+ `success?`, `error?`, `body`.
66
+ *Done 2026-06-11 — `payload/execute_workflow_commands.rb`*
67
+
68
+ ---
69
+
70
+ ## Phase W3 — Input: WorkflowCommand dispatcher
71
+
72
+ - [x] **W3.1** `Input::WorkflowCommand` — `SCHEMA_VERSION`, `COMMAND_MAP` (all 90 schema
73
+ keys mapped to Ruby module constant strings), `.build(key, **kwargs)`, `.valid_key?`,
74
+ `.build_commands`.
75
+ *Done 2026-06-11 — `lib/ecoportal/api/graphql/input/workflow_command.rb`*
76
+
77
+ ---
78
+
79
+ ## Phase W4 — Sub-input modules (~83 commands)
80
+
81
+ All sub-input modules follow the pattern:
82
+ `module CommandName; SCHEMA_VERSION; VALID_KEYS; def self.build(**kwargs); end`
83
+
84
+ - [x] **W4.1** Page-level: `EditPage`, `EditPageCreatorPermissions`.
85
+ *Done 2026-06-11*
86
+
87
+ - [x] **W4.2** Stage structural: `AddStage`, `RemoveStage`, `EditStage`, `MoveStage`.
88
+ *Done 2026-06-11*
89
+
90
+ - [x] **W4.3** Stage permissions: `EditCreatorPermissions`, `EditRestrictCommentTagging`,
91
+ `AddCommentTaggingUserGroup`, `RemoveCommentTaggingUserGroup`,
92
+ `EditRestrictTaskAssignment`, `AddTaskAssignmentUserGroup`,
93
+ `RemoveTaskAssignmentUserGroup`, `AddStageTag`, `RemoveStageTag`.
94
+ *Done 2026-06-11*
95
+
96
+ - [x] **W4.4** Section: `AddSection`, `RemoveSection`, `AddStageSection`,
97
+ `RemoveStageSection`, `EditSectionHeader`, `CollapseSection`, `ExpandSection`,
98
+ `ReorderSection`.
99
+ *Done 2026-06-11*
100
+
101
+ - [x] **W4.5** Task: `AddTask`, `RemoveTask`, `EditTaskDue`, `RemoveTaskDue`,
102
+ `RemoveTaskPriorityLevel`, `EditRequiredSignOffs`, `EditReminder`.
103
+ *Done 2026-06-11*
104
+
105
+ - [x] **W4.6** Strategy: `AddDefaultStrategy`, `EditDefaultStrategy`,
106
+ `RemoveDefaultStrategy`, `AddDefaultDirectStrategyUser`,
107
+ `RemoveDefaultDirectStrategyUser`, `AddStrategy`, `EditStrategy`,
108
+ `RemoveStrategy`, `AddDirectStrategyUser`, `RemoveDirectStrategyUser`,
109
+ `AddOperationStrategy`, `EditOperationStrategy`, `RemoveOperationStrategy`,
110
+ `AddOperationDirectStrategyUser`, `RemoveOperationDirectStrategyUser`.
111
+ *Done 2026-06-11*
112
+
113
+ - [x] **W4.7** Callback + Operation: `AddWorkflowCallback`, `RemoveCallback`,
114
+ `EditTrigger`, `AddOperation`, `EditOperation`, `RemoveOperation`.
115
+ *Done 2026-06-11*
116
+
117
+ - [x] **W4.8** Recipients (10 variants): `AddRecipientUser`, `RemoveRecipientUser`,
118
+ `AddRecipientPeopleField`, `RemoveRecipientPeopleField`, `AddRecipientTaskConfig`,
119
+ `RemoveRecipientTaskConfig`, `AddRecipientActionType`, `RemoveRecipientActionType`,
120
+ `AddRecipientFilter`, `RemoveRecipientFilter`.
121
+ *Done 2026-06-11*
122
+
123
+ - [x] **W4.9** Scheduled: `AddScheduledCallback`, `EditScheduledCallback`,
124
+ `RemoveScheduledCallback`, `AddScheduledCallbackAction`, `AddActionTag`,
125
+ `RemoveActionTag`.
126
+ *Done 2026-06-11*
127
+
128
+ - [x] **W4.10** Field structural: `AddField`, `MoveField`, `RemoveField`.
129
+ *Done 2026-06-11*
130
+
131
+ - [x] **W4.11** Field configuration: `EditFieldConfiguration` (base) + 12 byType
132
+ sub-modules in `field_config/`: `PlainText`, `RichText`, `Date`, `Gauge`, `Select`,
133
+ `People`, `CrossReference`, `ImageGallery`, `LocationField`, `ContractorEntities`,
134
+ `Signature`, `Table`.
135
+ *Done 2026-06-11*
136
+
137
+ - [x] **W4.12** Select options: `AddSelectFieldOption`, `EditSelectFieldOption`,
138
+ `RemoveSelectFieldOption`.
139
+ *Done 2026-06-11*
140
+
141
+ - [x] **W4.13** Gauge stops: `AddGaugeFieldStop`, `EditGaugeFieldStop`,
142
+ `RemoveGaugeFieldStop`.
143
+ *Done 2026-06-11*
144
+
145
+ - [x] **W4.14** Linked fields: `AddLinkedFieldConfig`, `EditLinkedFieldConfig`,
146
+ `RemoveLinkedFieldConfig`.
147
+ *Done 2026-06-11*
148
+
149
+ - [x] **W4.15** Forces / bindings: `AddForce`, `RemoveForce`, `EditForce`,
150
+ `ReorderForces`, `AddBinding`, `EditBinding`, `RemoveBinding`,
151
+ `AddLinkedHelper`, `EditLinkedHelper`, `RemoveLinkedHelper`.
152
+ *Done 2026-06-11*
153
+
154
+ ---
155
+
156
+ ## Phase W5 — Concerns and Cross-cutting
157
+
158
+ - [x] **W5.1** `Concerns::Deprecation` — `SCHEMA_VERSION`, `WARNED` (Set), `warn_once(key, msg)`.
159
+ Process-level warning deduplicator used across this area and others.
160
+ *Done 2026-06-11 — `lib/ecoportal/api/graphql/concerns/deprecation.rb`*
161
+
162
+ - [x] **W5.2** Code-spec docs:
163
+ - `.ai-assistance/code/workflow-space.md` — read model + command bus spec.
164
+ - `.ai-assistance/code/workflow-command-guide.md` — full command mapping + usage examples.
165
+ *Done 2026-06-11*
166
+
167
+ ---
168
+
169
+ ## Notes on Implementation Approach
170
+
171
+ ### SCHEMA_VERSION tracking
172
+
173
+ Every file in the workflow space carries `SCHEMA_VERSION = '20260605'.freeze`. This
174
+ matches the introspection snapshot date. When engineering changes the Workflow Builder
175
+ schema, re-run introspection, update the constant across all affected files, and diff
176
+ `WorkflowCommandInput` against the new schema to catch added or removed command keys.
177
+
178
+ ### Concerns::Deprecation
179
+
180
+ The `warn_once` pattern guards against repeated warnings from hot code paths (e.g.
181
+ schema version mismatches, deprecated method calls). It holds its warned-key `Set`
182
+ at the module level — process-global, not per-instance. This is intentional.
183
+
184
+ ---
185
+
186
+ ## Phase F — Deferred Items
187
+
188
+ These items were identified during W1-W5 but deferred due to complexity or low
189
+ immediate priority.
190
+
191
+ - [x] **F.1** Kickstand mutations — `startKickstandWorkflow`, `stopKickstandWorkflow`,
192
+ `failKickstandWorkflow`, `bulkUpdateKickstandWorkflows`.
193
+ `Base::Kickstand::Workflow`, `Payload::Kickstand::{Workflow,BulkUpdateWorkflows}`,
194
+ `Mutation::Kickstand::{Start,Stop,Fail}Workflow + BulkUpdateWorkflows`,
195
+ `Builder::Kickstand` wired as `api.kickstand`.
196
+ *Done 2026-06-12*
197
+
198
+ - [x] **F.2** `PagesWorkflow.commands` connection — `Query::PagesWorkflowCommands`
199
+ navigates `currentOrganization.page.workflow.commands`; uses `PagesWorkflowCommandFields`.
200
+ *Done 2026-06-12*
201
+
202
+ - [x] **F.3** Full Stage fragment with `workflowCallbacks` — `Fragment::StageWithCallbacksFields`
203
+ on `Stage` spreads `PagesWorkflowCallbackFields` into `workflowCallbacks`.
204
+ Stage model already had `workflow_callbacks` accessor; now it can be populated.
205
+ *Done 2026-06-12*
206
+
207
+ - [x] **F.4** `Builder::Page#execute_workflow_commands` — already shipped with W1-W5
208
+ (`builder/page.rb:68`).
209
+
210
+ - [x] **F.5** Rake task `schema_drift` — compares `WorkflowCommandInput` schema keys vs
211
+ `COMMAND_MAP`, and audits `SCHEMA_VERSION` currency across all workflow-space files.
212
+ Run: `bundle exec rake schema_drift`.
213
+ *Done 2026-06-12*
@@ -0,0 +1,136 @@
1
+ # Reinstall Claude Desktop App on Windows (MSIX → Standard)
2
+
3
+ **Why:** The default Claude Desktop installer uses MSIX packaging, which silently redirects
4
+ AppData writes into a sandboxed container. This breaks MCP config paths, plugin loading,
5
+ and adds an extra layer of isolation on top of CoWork's sandbox.
6
+ This guide switches to a standard (non-sandboxed) installation.
7
+
8
+ **Does this affect Claude Code CLI?** No. The CLI is an independent npm/winget package.
9
+ This procedure does not touch it.
10
+
11
+ ---
12
+
13
+ ## Before you start
14
+
15
+ ### 1. Back up your session data
16
+
17
+ Copy this entire folder somewhere safe (e.g. `C:\claude\backup\`):
18
+
19
+ ```
20
+ C:\Users\<username>\AppData\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\
21
+ ```
22
+
23
+ This contains your sessions, config, and plugins. Everything else (repos, projects) is
24
+ unaffected — it lives on your filesystem independently of the app.
25
+
26
+ ### 2. Note your MCP config location
27
+
28
+ Your current working config is at:
29
+ ```
30
+ C:\Users\<username>\AppData\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json
31
+ ```
32
+ Copy this file separately so you can reference it after reinstall.
33
+
34
+ ---
35
+
36
+ ## Step 1 — Kill Claude processes
37
+
38
+ Open **PowerShell as Administrator** and run:
39
+
40
+ ```powershell
41
+ Get-Process *claude*,*chrome-native-host*,*cowork* -ErrorAction SilentlyContinue | Stop-Process -Force
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Step 2 — Remove the MSIX package
47
+
48
+ In the same Admin PowerShell:
49
+
50
+ ```powershell
51
+ Get-AppxPackage -Name "Claude*" -AllUsers | Remove-AppxPackage -AllUsers -ErrorAction SilentlyContinue
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Step 3 — Delete the sandboxed package folder
57
+
58
+ In File Explorer, navigate to:
59
+ ```
60
+ %LOCALAPPDATA%\Packages\
61
+ ```
62
+ Delete the folder named `Claude_pzs8sxrjxfjjc` (or similar).
63
+
64
+ ---
65
+
66
+ ## Step 4 — Allow apps from any source (one-time Windows setting)
67
+
68
+ To prevent Windows from silently re-packaging the installer as MSIX:
69
+
70
+ `Settings → Apps → Advanced app settings → Choose where to get apps → set to Anywhere`
71
+
72
+ ---
73
+
74
+ ## Step 5 — Install via winget (standard path)
75
+
76
+ Open a **standard (non-admin) PowerShell** and run:
77
+
78
+ ```powershell
79
+ winget install Anthropic.Claude
80
+ ```
81
+
82
+ If winget doesn't find it, download the standalone `.exe` directly from
83
+ **https://claude.com/download** and run it. Do not use the Microsoft Store.
84
+
85
+ ---
86
+
87
+ ## Step 6 — Launch Claude and confirm paths
88
+
89
+ After first launch, verify the config now lives at the standard location:
90
+ ```
91
+ C:\Users\<username>\AppData\Roaming\Claude\claude_desktop_config.json
92
+ ```
93
+ If that file exists, the sandboxing is gone.
94
+
95
+ ---
96
+
97
+ ## Step 7 — Restore your session data
98
+
99
+ Copy your backup into the new location:
100
+ ```
101
+ From: C:\claude\backup\Claude\
102
+ To: C:\Users\<username>\AppData\Roaming\Claude\
103
+ ```
104
+
105
+ **Merge carefully** — if the reinstall already created files there, prioritise your backup
106
+ for `local-agent-mode-sessions\` and `claude_desktop_config.json`.
107
+ Do not blindly overwrite the whole folder.
108
+
109
+ ---
110
+
111
+ ## Step 8 — Restore MCP config
112
+
113
+ If your `claude_desktop_config.json` did not carry over from the backup, copy your saved
114
+ copy from Step 0 into `AppData\Roaming\Claude\claude_desktop_config.json`.
115
+
116
+ Restart Claude Desktop. Check Settings → Developer to confirm MCPs are loading.
117
+
118
+ ---
119
+
120
+ ## After reinstall
121
+
122
+ - CoWork sessions should resume from where you left off
123
+ - MCP "Edit Config" button will now open the correct file
124
+ - Plugin skills will load from the correct paths
125
+ - The CoWork sandbox will no longer be inside an MSIX container layer
126
+
127
+ ---
128
+
129
+ ## What is NOT affected by this reinstall
130
+
131
+ | Thing | Safe? | Notes |
132
+ |-------|-------|-------|
133
+ | Claude Code CLI | ✓ | Separate npm/winget install, untouched |
134
+ | Git repos (e.g. ecoportal-api-graphql) | ✓ | Live on filesystem, nothing to do with the app |
135
+ | `.claude/` folder in repos | ✓ | Part of the repo, git-tracked |
136
+ | `local_paths.md` | ✓ | Git-ignored but stays on your disk |
@@ -0,0 +1,150 @@
1
+ # Scripts
2
+
3
+ These scripts move token-expensive work (file scanning, UUID gen, archiving) to CPU.
4
+ Agents call scripts and read their output — they do not replicate this logic in prose.
5
+
6
+ ## Script index
7
+
8
+ | Script | Language | Called by | Purpose |
9
+ |--------|----------|-----------|---------|
10
+ | `setup-mcps.ts` | TypeScript | Human (once per machine) | Write GitKraken + GitLab MCP entries to Claude Desktop config |
11
+ | `setup-mcps.test.ts` | TypeScript | CI / on-demand | Unit tests for setup-mcps.ts logic |
12
+ | `bridge-init.sh` | Bash | Code (startup) | Detect env, scan inbox+stale tasks, return JSON summary |
13
+ | `lock-acquire.sh` | Bash | Either | Atomically acquire bridge LOCK; detects stale locks by mtime |
14
+ | `task-create.ts` | TypeScript | CoWork or Code | Create a new inbox task file |
15
+ | `task-read.ts` | TypeScript | Either | Parse a task file → structured JSON (reduces read token cost) |
16
+ | `task-complete.ts` | TypeScript | Code (after finishing) | Write outbox, archive pair |
17
+ | `check-outbox.sh` | Bash | CoWork | Check if Code has responded to a task |
18
+ | `bridge-status.sh` | Bash | Either | Quick dashboard: counts, last activity |
19
+ | `capabilities-check.ts` | TypeScript | Scheduled / on-demand | Verify capabilities, update assumptions-log |
20
+
21
+ ## Usage
22
+
23
+ ### setup-mcps.ts
24
+ Run once per machine when onboarding. Writes GitKraken + GitLab MCP entries into
25
+ Claude Desktop's global config. Safe to re-run — merges, never overwrites unrelated entries.
26
+ ```bash
27
+ npx ts-node .ai-assistance/scripts/setup-mcps.ts
28
+ # prompts for GitLab PAT (defaults from .env), then writes claude_desktop_config.json
29
+ # backs up existing config to claude_desktop_config.json.backup first
30
+ ```
31
+
32
+ ### setup-mcps.test.ts
33
+ ```bash
34
+ npx ts-node .ai-assistance/scripts/setup-mcps.test.ts
35
+ # runs unit tests for parseEnvFile, buildMcpEntries, mergeConfig, getConfigPath
36
+ # exits 0 on all pass, 1 if any fail
37
+ ```
38
+
39
+ ### bridge-init.sh
40
+ ```bash
41
+ bash .ai-assistance/scripts/bridge-init.sh
42
+ # outputs: {"env":"code","user":"oscar","pending":2,"tasks":[...],"stale":1,"stale_tasks":["oscar-abc-old-task.md"]}
43
+ # also writes output to .ai-assistance/bridge/STATUS (read by Code on startup)
44
+ # stale_tasks: IN_PROGRESS files older than 1 hour — likely crashed sessions
45
+ ```
46
+
47
+ ### lock-acquire.sh
48
+ ```bash
49
+ result=$(bash .ai-assistance/scripts/lock-acquire.sh \
50
+ --agent code \
51
+ --user oscar \
52
+ --intent "Implementing Phase D mutations" \
53
+ [--expiry-minutes 60] # default: 60
54
+ [--lock-file /custom/path] # default: .ai-assistance/bridge/LOCK
55
+ )
56
+ # success: {"acquired":true,"lock_file":"...","expires":"2026-06-08T12:00:00Z"}
57
+ # failure: {"acquired":false,"reason":"locked","held_by":"code/oscar","intent":"...","age_seconds":42}
58
+ # stale lock (expired by mtime): auto-detected and overwritten
59
+
60
+ # Release when done:
61
+ rm .ai-assistance/bridge/LOCK
62
+ ```
63
+
64
+ Uses temp-file + hard-link for atomicity (POSIX + NTFS). Falls back to bash `noclobber`
65
+ if hard links unavailable. Always check `"acquired":true` before proceeding.
66
+
67
+ **Hook notes (hard-won):**
68
+ - Correct Claude Code hook event name is `SessionStart` (not `PostSessionStart`)
69
+ - Use `bash script.sh` in hook commands — `source` is not available in hook context
70
+ - Hook stdout is NOT injected into Code's context — Code never sees it as a message
71
+ - Solution: write output to `bridge/STATUS`; Code reads that file when asked
72
+ - Code is passive and will not act on hook output unprompted — ask "any pending tasks?"
73
+ at session start; Code reads STATUS and reports immediately
74
+
75
+ ```bash
76
+ ```
77
+
78
+ ### task-create.ts
79
+ ```bash
80
+ npx ts-node .ai-assistance/scripts/task-create.ts \
81
+ --title "List open MRs" \
82
+ --request "Run: git branch --show-current in ecoportal-api-graphql, then list all open MRs via GitLab plugin" \
83
+ --expected "Current branch name + MR table (ID, title, source branch, author, date)" \
84
+ --from cowork \
85
+ --to code \
86
+ --user oscar
87
+ # outputs: created oscar-[uuid]-list-open-mrs.md
88
+ ```
89
+
90
+ ### task-read.ts
91
+ ```bash
92
+ # Read from inbox (default)
93
+ npx ts-node .ai-assistance/scripts/task-read.ts --task oscar-a3f2b1c-list-open-mrs.md
94
+
95
+ # Explicitly target outbox or archive
96
+ npx ts-node .ai-assistance/scripts/task-read.ts --task oscar-a3f2b1c-list-open-mrs.md --dir outbox
97
+
98
+ # Read by absolute path
99
+ npx ts-node .ai-assistance/scripts/task-read.ts --file /abs/path/to/task.md
100
+
101
+ # Output: structured JSON with title, status, created, from, to,
102
+ # context, request, expected, result, notes, raw_path
103
+ # Uses this instead of reading raw Markdown — saves ~200 tokens per task read.
104
+ ```
105
+
106
+ ### task-complete.ts
107
+ ```bash
108
+ npx ts-node .ai-assistance/scripts/task-complete.ts \
109
+ --task oscar-a3f2b1c-list-open-mrs.md \
110
+ --status done \
111
+ --result "Branch: feature/auth. MRs: ..." \
112
+ --notes "GitLab plugin authenticated successfully"
113
+ # outputs: wrote outbox file, archived pair
114
+ ```
115
+
116
+ ### check-outbox.sh
117
+ ```bash
118
+ bash .ai-assistance/scripts/check-outbox.sh oscar-a3f2b1c-list-open-mrs.md
119
+ # outputs: DONE | "Branch: feature/auth. Open MRs: 3"
120
+ # or: PENDING | no response yet
121
+ # or: FAILED | "GitLab credentials not configured"
122
+ ```
123
+
124
+ ### bridge-status.sh
125
+ ```bash
126
+ bash .ai-assistance/scripts/bridge-status.sh
127
+ # outputs: pending:2 done:5 failed:0 archived:12 last_activity:2026-06-03T14:32Z
128
+ ```
129
+
130
+ ### capabilities-check.ts
131
+ ```bash
132
+ npx ts-node .ai-assistance/scripts/capabilities-check.ts
133
+ # checks connector endpoints, flags stale assumptions, updates assumptions-log.md
134
+ # uses Haiku model for any inference (cheap, fast)
135
+ ```
136
+
137
+ ## Dependencies
138
+
139
+ ```bash
140
+ # TypeScript scripts require:
141
+ npm install -g ts-node typescript
142
+
143
+ # Node type definitions (required for ts-node to resolve assert, process, etc.):
144
+ npm install --save-dev @types/node
145
+
146
+ # tsconfig.json must include "types": ["node"] in compilerOptions
147
+
148
+ # capabilities-check.ts additionally requires:
149
+ npm install @anthropic-ai/sdk
150
+ ```