@zaip-ai/cli 2.2.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (420) hide show
  1. package/dist/services/adapters.d.ts +1 -1
  2. package/dist/services/adapters.d.ts.map +1 -1
  3. package/dist/services/adapters.js +23 -9
  4. package/dist/services/adapters.js.map +1 -1
  5. package/dist/services/agent-adapters.js +25 -9
  6. package/dist/services/agent-adapters.js.map +1 -1
  7. package/dist/services/agent-discovery.d.ts +27 -0
  8. package/dist/services/agent-discovery.d.ts.map +1 -0
  9. package/dist/services/agent-discovery.js +73 -0
  10. package/dist/services/agent-discovery.js.map +1 -0
  11. package/dist/services/codex-conversation-lifecycle-hook.d.ts.map +1 -1
  12. package/dist/services/codex-conversation-lifecycle-hook.js +153 -24
  13. package/dist/services/codex-conversation-lifecycle-hook.js.map +1 -1
  14. package/dist/services/codex-pre-tool-hook-template.d.ts.map +1 -1
  15. package/dist/services/codex-pre-tool-hook-template.js +146 -72
  16. package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
  17. package/dist/services/codex-rules.d.ts +1 -1
  18. package/dist/services/codex-rules.d.ts.map +1 -1
  19. package/dist/services/codex-rules.js +3 -3
  20. package/dist/services/codex-subagent-hook-template.d.ts +1 -1
  21. package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
  22. package/dist/services/codex-subagent-hook-template.js +117 -66
  23. package/dist/services/codex-subagent-hook-template.js.map +1 -1
  24. package/dist/services/install-agents-template.d.ts.map +1 -1
  25. package/dist/services/install-agents-template.js +56 -6
  26. package/dist/services/install-agents-template.js.map +1 -1
  27. package/dist/services/logger.js +1 -1
  28. package/dist/services/logger.js.map +1 -1
  29. package/dist/services/logger.test.js +22 -1
  30. package/dist/services/logger.test.js.map +1 -1
  31. package/dist/services/runtime-template.test.js +129 -0
  32. package/dist/services/runtime-template.test.js.map +1 -1
  33. package/package.json +1 -1
  34. package/templates/.agents/.env.example +9 -3
  35. package/templates/.agents/README-ENG.md +30 -5
  36. package/templates/.agents/README.md +30 -7
  37. package/templates/.agents/architecture/software-architecture.md +1 -59
  38. package/templates/.agents/branding/brandbook.md +3 -0
  39. package/templates/.agents/config/agents/catalog.yaml +22 -10
  40. package/templates/.agents/config/agents/discovery.json +319 -0
  41. package/templates/.agents/config/clients/codex/agents/zaip-agent-backend.toml +2 -2
  42. package/templates/.agents/config/clients/codex/agents/zaip-agent-builder.toml +2 -2
  43. package/templates/.agents/config/clients/codex/agents/zaip-agent-cloud-engineer.toml +11 -8
  44. package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +2 -2
  45. package/templates/.agents/config/clients/codex/agents/zaip-agent-frontend.toml +2 -2
  46. package/templates/.agents/config/clients/codex/agents/zaip-agent-task-executor.toml +2 -2
  47. package/templates/.agents/config/clients/codex/agents/zaip-agent-website-developer.toml +2 -2
  48. package/templates/.agents/config/pricing/models.json +9 -5
  49. package/templates/.agents/config/project.yaml +12 -1
  50. package/templates/.agents/dashboard/.zaip-managed.json +375 -95
  51. package/templates/.agents/dashboard/apps/frontend/dist/assets/CostCalculationGuidePage-CGxeQak4.js +1 -0
  52. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-DaSllaJp.js → DashboardHelpDialog-tzS7YxYB.js} +57 -33
  53. package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-DEbCi1gP.js +1 -0
  54. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-1L7Qw-Gq.js +3 -0
  55. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-EInWr641.css +1 -0
  56. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-t1Om0Abw.js +1 -0
  57. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-B6aZfo5f.js +68 -0
  58. package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-TPUT2IUt.js → icons-vendor-DiGC-dsJ.js} +1 -1
  59. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DgTmNHN5.js +2 -0
  60. package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-Ct48XHGL.js → react-vendor-kPO6yNed.js} +1 -1
  61. package/templates/.agents/dashboard/apps/frontend/dist/assets/rolldown-runtime-Bh1tDfsg.js +1 -0
  62. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-DQpKX9c1.js +1 -0
  63. package/templates/.agents/dashboard/apps/frontend/dist/index.html +6 -6
  64. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  65. package/templates/.agents/dashboard/apps/frontend/src/App.tsx +3 -1264
  66. package/templates/.agents/dashboard/apps/frontend/src/AppDashboardContent.tsx +363 -0
  67. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.dom.test.ts +99 -0
  68. package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +62 -6
  69. package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +3 -1
  70. package/templates/.agents/dashboard/apps/frontend/src/__tests__/app-composition-support.ts +7 -0
  71. package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +9 -7
  72. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api-settings.ts +151 -0
  73. package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +28 -153
  74. package/templates/.agents/dashboard/apps/frontend/src/dashboard-app-shell.tsx +33 -0
  75. package/templates/.agents/dashboard/apps/frontend/src/dashboard-cost-facts.ts +30 -0
  76. package/templates/.agents/dashboard/apps/frontend/src/dashboard-project-overview.ts +7 -1
  77. package/templates/.agents/dashboard/apps/frontend/src/dashboard-retry.ts +17 -0
  78. package/templates/.agents/dashboard/apps/frontend/src/dashboard-setup-route.ts +29 -0
  79. package/templates/.agents/dashboard/apps/frontend/src/dashboard-view-actions.ts +66 -0
  80. package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +3 -2
  81. package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +2 -2
  82. package/templates/.agents/dashboard/apps/frontend/src/project-installation-status.test.ts +48 -0
  83. package/templates/.agents/dashboard/apps/frontend/src/project-installation-status.ts +29 -0
  84. package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +68 -0
  85. package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +2 -2
  86. package/templates/.agents/dashboard/apps/frontend/src/sao-paulo-day-rollover.test.ts +36 -0
  87. package/templates/.agents/dashboard/apps/frontend/src/sao-paulo-day-rollover.ts +30 -0
  88. package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +2 -5
  89. package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +30 -19
  90. package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +9 -1
  91. package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-task-pagination.ts +77 -0
  92. package/templates/.agents/dashboard/apps/frontend/src/use-app-work-board.ts +397 -0
  93. package/templates/.agents/dashboard/apps/frontend/src/use-dashboard-app-model.tsx +782 -0
  94. package/templates/.agents/dashboard/apps/frontend/src/use-snapshot-notice.tsx +49 -0
  95. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  96. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostDeveloperPanelSlot.tsx +16 -0
  97. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostGroupsTable.tsx +459 -0
  98. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +27 -17
  99. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +62 -186
  100. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorRunDialog.tsx +20 -0
  101. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables-hides-calls-that-have-no-collected.test.ts +80 -0
  102. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables-keeps-legacy-codex-identity-fields-blank.test.ts +455 -0
  103. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +18 -525
  104. package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +32 -508
  105. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-export-sources.ts +74 -0
  106. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-actions.ts +19 -0
  107. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-selectors.ts +49 -0
  108. package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-table-formatters.ts +115 -0
  109. package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test-fixtures.ts +2 -0
  110. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  111. package/templates/.agents/dashboard/modules/operations/src/contracts.ts +4 -0
  112. package/templates/.agents/dashboard/modules/operations/src/react/EntityTableBadges.tsx +34 -0
  113. package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +8 -38
  114. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview-keeps-structure-classes-mutually-exclusive.test.ts +243 -0
  115. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +27 -275
  116. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +70 -247
  117. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewCharts.tsx +171 -0
  118. package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverviewPanels.tsx +64 -0
  119. package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +4 -3
  120. package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.test.tsx +2 -1
  121. package/templates/.agents/dashboard/modules/operations/src/react/manual-work-priority.test.ts +2 -1
  122. package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +6 -2
  123. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +6 -14
  124. package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.status-cards.test.ts +3 -1
  125. package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +2 -0
  126. package/templates/.agents/dashboard/modules/operations/src/react/overview-metric-format.ts +32 -0
  127. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  128. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  129. package/templates/.agents/dashboard/packages/branding/src/index.ts +1 -1
  130. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  131. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  132. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +1458 -1458
  133. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +1425 -1425
  134. package/templates/.agents/dashboard/packages/local-runtime/package.json +2 -1
  135. package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +7 -3
  136. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +1458 -1459
  137. package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.ts +25 -0
  138. package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.test.ts +1 -1
  139. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +53 -8
  140. package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +79 -24
  141. package/templates/.agents/dashboard/packages/local-runtime/src/projection-refresh-diagnostics.ts +35 -0
  142. package/templates/.agents/dashboard/packages/local-runtime/src/server-costs-routes.ts +168 -0
  143. package/templates/.agents/dashboard/packages/local-runtime/src/server-dual-reads-manifest-summaries-without-losing.test.ts +344 -0
  144. package/templates/.agents/dashboard/packages/local-runtime/src/server-http-contracts.ts +31 -0
  145. package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-routes.ts +345 -0
  146. package/templates/.agents/dashboard/packages/local-runtime/src/server-read-projections.ts +461 -0
  147. package/templates/.agents/dashboard/packages/local-runtime/src/server-reconciliation-refresh.test.ts +78 -0
  148. package/templates/.agents/dashboard/packages/local-runtime/src/server-route-context.ts +13 -0
  149. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.test.ts +18 -0
  150. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.ts +19 -3
  151. package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +22 -21
  152. package/templates/.agents/dashboard/packages/local-runtime/src/server-sqlite-view-allowlist.test.ts +25 -0
  153. package/templates/.agents/dashboard/packages/local-runtime/src/server-trace-routes.ts +64 -0
  154. package/templates/.agents/dashboard/packages/local-runtime/src/server-work-reconciliation.test.ts +2 -30
  155. package/templates/.agents/dashboard/packages/local-runtime/src/server-work-reconciliation.ts +6 -23
  156. package/templates/.agents/dashboard/packages/local-runtime/src/server.test-fixtures.ts +1 -1
  157. package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +2 -330
  158. package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +73 -1060
  159. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-materialize-first-fold.ts +78 -0
  160. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-materialize-projections.ts +561 -0
  161. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-materialize-runs.ts +600 -0
  162. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.test.ts +1 -1
  163. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-agent-dimension.ts +269 -0
  164. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-context.ts +32 -0
  165. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-entity-group.ts +244 -0
  166. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-filtered-dimension.ts +292 -0
  167. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-financial.ts +547 -0
  168. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-model-dimension.ts +360 -0
  169. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-provider-dimension.ts +169 -0
  170. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-summary.ts +475 -0
  171. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-temporal-dimension.ts +132 -0
  172. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-timing.ts +299 -0
  173. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-view-page.ts +692 -0
  174. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-counts-every-root-execution-day-returns.test.ts +739 -0
  175. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-does-not-convert-delayed-historical-finalizer.test.ts +706 -0
  176. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-filesystem.ts +748 -0
  177. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-first-fold-types.ts +1 -1
  178. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-keeps-orphan-telemetry-out-kanban-without.test.ts +710 -0
  179. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-marks-token-cost-telemetry-unavailable-when.test.ts +618 -0
  180. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-rebuild.ts +755 -0
  181. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-rebuilds-disposable-snapshot-serves-zaip-records.test.ts +276 -0
  182. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-schema.ts +193 -0
  183. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-types.ts +123 -0
  184. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +1 -2805
  185. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +17 -6930
  186. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-base-views.ts +385 -0
  187. package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-dashboard-views.ts +412 -0
  188. package/templates/.agents/dashboard/packages/local-runtime/src/work-priority-contract.test.ts +4 -3
  189. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-build.mjs +195 -0
  190. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-lifecycle.test.mjs +2 -7
  191. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-logging.mjs +35 -0
  192. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-navigation.mjs +114 -0
  193. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-paths.mjs +90 -0
  194. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +89 -418
  195. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +22 -12
  196. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  197. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  198. package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +4 -1
  199. package/templates/.agents/design/.zaip-managed.json +5 -5
  200. package/templates/.agents/design/DESIGN.md +2 -186
  201. package/templates/.agents/design/README.md +12 -2
  202. package/templates/.agents/design/apps/catalog/package.json +1 -1
  203. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  204. package/templates/.agents/growth/strategy.md +3 -0
  205. package/templates/.agents/marketing/strategy.md +3 -0
  206. package/templates/.agents/requirements/autonomous-assurance.md +2 -1
  207. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
  208. package/templates/.agents/requirements/comparative-audit.md +1 -1
  209. package/templates/.agents/requirements/context-engine.md +1 -1
  210. package/templates/.agents/requirements/cost-observability.md +1 -1
  211. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  212. package/templates/.agents/requirements/data-export.md +1 -1
  213. package/templates/.agents/requirements/design-system.md +13 -4
  214. package/templates/.agents/requirements/execution-engine.md +1 -1
  215. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  216. package/templates/.agents/requirements/model-orchestration.md +1 -1
  217. package/templates/.agents/requirements/public-distribution.md +4 -2
  218. package/templates/.agents/requirements/software-architecture.md +1 -1
  219. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  220. package/templates/.agents/requirements/work-lifecycle.md +3 -3
  221. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  222. package/templates/.agents/rules/architecture.md +2 -0
  223. package/templates/.agents/rules/astra-diagnostic.md +1 -1
  224. package/templates/.agents/rules/autonomy-decision.md +3 -1
  225. package/templates/.agents/rules/cloud-hostinger-autonomy.md +2 -0
  226. package/templates/.agents/rules/context.md +2 -1
  227. package/templates/.agents/rules/core.md +3 -3
  228. package/templates/.agents/rules/design-system-central-contract.md +17 -0
  229. package/templates/.agents/rules/evolution.md +3 -1
  230. package/templates/.agents/rules/frontend-lite.md +3 -1
  231. package/templates/.agents/rules/local-sqlite-storage.md +2 -2
  232. package/templates/.agents/rules/meta-mcp.md +3 -1
  233. package/templates/.agents/rules/model-orchestration.md +1 -1
  234. package/templates/.agents/rules/run-lifecycle-closure.md +6 -4
  235. package/templates/.agents/rules/security.md +3 -1
  236. package/templates/.agents/rules/specialist-routing.md +3 -1
  237. package/templates/.agents/rules/text-writing-utf8.md +1 -1
  238. package/templates/.agents/rules/workflow.md +7 -5
  239. package/templates/.agents/runtime/VERSION +1 -1
  240. package/templates/.agents/runtime/bin/zaip.mjs +519 -247
  241. package/templates/.agents/runtime/checksums.sha256 +6 -6
  242. package/templates/.agents/runtime/manifest.json +1 -1
  243. package/templates/.agents/runtime/pnpm-lock.sha256 +1 -1
  244. package/templates/.agents/runtime/provenance.json +5 -5
  245. package/templates/.agents/runtime/sbom.cdx.json +1 -1
  246. package/templates/.agents/sales/playbook.md +3 -0
  247. package/templates/.agents/skills/zaip-aios/SKILL.md +5 -3
  248. package/templates/.agents/skills/zaip-skill-adapt-stack/SKILL.md +1 -0
  249. package/templates/.agents/skills/zaip-skill-api-contracts/SKILL.md +14 -0
  250. package/templates/.agents/skills/zaip-skill-api-contracts/agents/openai.yaml +4 -0
  251. package/templates/.agents/skills/zaip-skill-application-observability/SKILL.md +15 -0
  252. package/templates/.agents/skills/zaip-skill-application-observability/agents/openai.yaml +4 -0
  253. package/templates/.agents/skills/zaip-skill-application-observability/references/signal-design.md +3 -0
  254. package/templates/.agents/skills/zaip-skill-application-readiness/SKILL.md +15 -0
  255. package/templates/.agents/skills/zaip-skill-application-readiness/agents/openai.yaml +4 -0
  256. package/templates/.agents/skills/zaip-skill-application-readiness/references/evidence-matrix.md +3 -0
  257. package/templates/.agents/skills/zaip-skill-architecture-design/SKILL.md +14 -0
  258. package/templates/.agents/skills/zaip-skill-architecture-design/agents/openai.yaml +4 -0
  259. package/templates/.agents/skills/zaip-skill-async-jobs/SKILL.md +14 -0
  260. package/templates/.agents/skills/zaip-skill-async-jobs/agents/openai.yaml +4 -0
  261. package/templates/.agents/skills/zaip-skill-auth-tenancy/SKILL.md +15 -0
  262. package/templates/.agents/skills/zaip-skill-auth-tenancy/agents/openai.yaml +4 -0
  263. package/templates/.agents/skills/zaip-skill-auth-tenancy/references/data-access-paths.md +9 -0
  264. package/templates/.agents/skills/zaip-skill-auth-tenancy/references/worker-scenario.md +5 -0
  265. package/templates/.agents/skills/zaip-skill-auth-tenancy/scripts/worker-contract.test.mjs +27 -0
  266. package/templates/.agents/skills/zaip-skill-author-skills/SKILL.md +2 -0
  267. package/templates/.agents/skills/zaip-skill-author-skills/references/engineering-skill-index.md +9 -0
  268. package/templates/.agents/skills/zaip-skill-author-skills/scripts/audit-skill-catalog.mjs +5 -3
  269. package/templates/.agents/skills/zaip-skill-author-skills/scripts/author-skill-scripts.test.mjs +27 -0
  270. package/templates/.agents/skills/zaip-skill-backend/SKILL.md +4 -0
  271. package/templates/.agents/skills/zaip-skill-backend/references/deployment-environments.md +75 -0
  272. package/templates/.agents/skills/zaip-skill-backend/references/supabase-migration-contract.md +23 -0
  273. package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +2 -0
  274. package/templates/.agents/skills/zaip-skill-cache-strategy/SKILL.md +14 -0
  275. package/templates/.agents/skills/zaip-skill-cache-strategy/agents/openai.yaml +4 -0
  276. package/templates/.agents/skills/zaip-skill-change/SKILL.md +1 -1
  277. package/templates/.agents/skills/zaip-skill-cloud-engineering/SKILL.md +7 -0
  278. package/templates/.agents/skills/zaip-skill-cloudflare-github-deploy/SKILL.md +37 -0
  279. package/templates/.agents/skills/zaip-skill-cloudflare-github-deploy/agents/openai.yaml +6 -0
  280. package/templates/.agents/skills/zaip-skill-cloudflare-github-deploy/references/workers-static-assets.md +26 -0
  281. package/templates/.agents/skills/zaip-skill-cloudflare-github-deploy/references/workflow-templates.md +71 -0
  282. package/templates/.agents/skills/zaip-skill-cloudflare-github-deploy/scripts/cloudflare-github-deploy-contract.test.mjs +77 -0
  283. package/templates/.agents/skills/zaip-skill-config/SKILL.md +21 -11
  284. package/templates/.agents/skills/zaip-skill-config/agents/openai.yaml +2 -2
  285. package/templates/.agents/skills/zaip-skill-container-runtime/SKILL.md +14 -0
  286. package/templates/.agents/skills/zaip-skill-container-runtime/agents/openai.yaml +4 -0
  287. package/templates/.agents/skills/zaip-skill-context/SKILL.md +6 -1
  288. package/templates/.agents/skills/zaip-skill-context/references/prd-spec-task-handoff.md +10 -0
  289. package/templates/.agents/skills/zaip-skill-context/references/rule-selection.md +20 -0
  290. package/templates/.agents/skills/zaip-skill-cqrs/SKILL.md +1 -0
  291. package/templates/.agents/skills/zaip-skill-cybersecurity/SKILL.md +18 -0
  292. package/templates/.agents/skills/zaip-skill-cybersecurity/agents/openai.yaml +4 -0
  293. package/templates/.agents/skills/zaip-skill-cybersecurity/references/audit-contract.md +94 -0
  294. package/templates/.agents/skills/zaip-skill-cybersecurity/scripts/score-audit.mjs +185 -0
  295. package/templates/.agents/skills/zaip-skill-cybersecurity/scripts/score-audit.test.mjs +101 -0
  296. package/templates/.agents/skills/zaip-skill-data-modeling/SKILL.md +14 -0
  297. package/templates/.agents/skills/zaip-skill-data-modeling/agents/openai.yaml +4 -0
  298. package/templates/.agents/skills/zaip-skill-database-migrations/SKILL.md +20 -0
  299. package/templates/.agents/skills/zaip-skill-database-migrations/agents/openai.yaml +4 -0
  300. package/templates/.agents/skills/zaip-skill-database-migrations/references/manual-mode.md +15 -0
  301. package/templates/.agents/skills/zaip-skill-database-migrations/references/promotion-example.md +5 -0
  302. package/templates/.agents/skills/zaip-skill-database-migrations/scripts/export-manual-sql.mjs +145 -0
  303. package/templates/.agents/skills/zaip-skill-database-migrations/scripts/export-manual-sql.test.mjs +178 -0
  304. package/templates/.agents/skills/zaip-skill-dependency-upgrade/SKILL.md +14 -0
  305. package/templates/.agents/skills/zaip-skill-dependency-upgrade/agents/openai.yaml +4 -0
  306. package/templates/.agents/skills/zaip-skill-deployment-pipeline/SKILL.md +15 -0
  307. package/templates/.agents/skills/zaip-skill-deployment-pipeline/agents/openai.yaml +4 -0
  308. package/templates/.agents/skills/zaip-skill-deployment-pipeline/references/runtime-shapes.md +3 -0
  309. package/templates/.agents/skills/zaip-skill-design-system/SKILL.md +20 -9
  310. package/templates/.agents/skills/zaip-skill-dev-environment/SKILL.md +14 -0
  311. package/templates/.agents/skills/zaip-skill-dev-environment/agents/openai.yaml +4 -0
  312. package/templates/.agents/skills/zaip-skill-dev-environment/references/inventory-contract.md +7 -0
  313. package/templates/.agents/skills/zaip-skill-dev-environment/scripts/inventory.mjs +77 -0
  314. package/templates/.agents/skills/zaip-skill-disaster-recovery/SKILL.md +15 -0
  315. package/templates/.agents/skills/zaip-skill-disaster-recovery/agents/openai.yaml +4 -0
  316. package/templates/.agents/skills/zaip-skill-disaster-recovery/references/recovery-scope.md +3 -0
  317. package/templates/.agents/skills/zaip-skill-execution/SKILL.md +3 -3
  318. package/templates/.agents/skills/zaip-skill-execution/references/correction-cycle.md +7 -0
  319. package/templates/.agents/skills/zaip-skill-execution/references/runtime-governance.md +1 -5
  320. package/templates/.agents/skills/zaip-skill-external-integrations/SKILL.md +14 -0
  321. package/templates/.agents/skills/zaip-skill-external-integrations/agents/openai.yaml +4 -0
  322. package/templates/.agents/skills/zaip-skill-frontend/SKILL.md +4 -0
  323. package/templates/.agents/skills/zaip-skill-frontend-componentization/SKILL.md +44 -0
  324. package/templates/.agents/skills/zaip-skill-frontend-componentization/agents/openai.yaml +4 -0
  325. package/templates/.agents/skills/zaip-skill-frontend-data-flows/SKILL.md +14 -0
  326. package/templates/.agents/skills/zaip-skill-frontend-data-flows/agents/openai.yaml +4 -0
  327. package/templates/.agents/skills/zaip-skill-general-operations/SKILL.md +2 -0
  328. package/templates/.agents/skills/zaip-skill-github-actions-setup/SKILL.md +36 -0
  329. package/templates/.agents/skills/zaip-skill-github-actions-setup/agents/openai.yaml +4 -0
  330. package/templates/.agents/skills/zaip-skill-github-actions-setup/references/cloudflare-pages.md +33 -0
  331. package/templates/.agents/skills/zaip-skill-github-actions-setup/references/github.md +63 -0
  332. package/templates/.agents/skills/zaip-skill-github-actions-setup/references/hostinger-vps.md +55 -0
  333. package/templates/.agents/skills/zaip-skill-github-actions-setup/references/npm.md +30 -0
  334. package/templates/.agents/skills/zaip-skill-github-actions-setup/scripts/check-skill.mjs +55 -0
  335. package/templates/.agents/skills/zaip-skill-github-actions-setup/scripts/verify-cloudflare.mjs +61 -0
  336. package/templates/.agents/skills/zaip-skill-github-actions-setup/scripts/verify-cloudflare.test.mjs +128 -0
  337. package/templates/.agents/skills/zaip-skill-github-actions-setup/scripts/verify-ssh.integration.test.mjs +106 -0
  338. package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +43 -76
  339. package/templates/.agents/skills/zaip-skill-github-deploy/references/deployment-workflow.md +131 -0
  340. package/templates/.agents/skills/zaip-skill-github-deploy/references/github-release-workflow-template.md +31 -0
  341. package/templates/.agents/skills/zaip-skill-github-deploy/references/release-gate-matrix.md +24 -0
  342. package/templates/.agents/skills/zaip-skill-github-deploy/references/release-identity.md +44 -0
  343. package/templates/.agents/skills/zaip-skill-github-deploy/references/release-notes.md +134 -0
  344. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/consumer-release-preparation.mjs +389 -0
  345. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/consumer-release-preparation.test.mjs +134 -0
  346. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +25 -2
  347. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-readiness-api.test.mjs +134 -0
  348. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-readiness.mjs +98 -0
  349. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-readiness.test.mjs +25 -0
  350. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/install-github-readiness-workflow.mjs +159 -0
  351. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/install-github-readiness-workflow.test.mjs +160 -0
  352. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/preflight.mjs +149 -12
  353. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/preflight.test.mjs +64 -5
  354. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/release-notes-coverage.test.mjs +126 -0
  355. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/resolve-release-identity.mjs +78 -0
  356. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/resolve-release-identity.test.mjs +51 -0
  357. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/validate-release-notes.mjs +184 -0
  358. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/validate-release-notes.test.mjs +109 -0
  359. package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +2 -0
  360. package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/SKILL.md +18 -10
  361. package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/agents/openai.yaml +3 -4
  362. package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/references/aws-cli-terraform.md +62 -0
  363. package/templates/.agents/skills/zaip-skill-hostinger-cloudflare-terraform/references/guia-iniciante-hostinger-vps.md +183 -0
  364. package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +2 -0
  365. package/templates/.agents/skills/zaip-skill-module-scaffold/SKILL.md +14 -0
  366. package/templates/.agents/skills/zaip-skill-module-scaffold/agents/openai.yaml +4 -0
  367. package/templates/.agents/skills/zaip-skill-module-scaffold/references/scaffold-contract.md +9 -0
  368. package/templates/.agents/skills/zaip-skill-module-scaffold/scripts/helpers.test.mjs +121 -0
  369. package/templates/.agents/skills/zaip-skill-module-scaffold/scripts/scaffold.mjs +169 -0
  370. package/templates/.agents/skills/zaip-skill-move-prd/SKILL.md +1 -1
  371. package/templates/.agents/skills/zaip-skill-move-spec/SKILL.md +1 -1
  372. package/templates/.agents/skills/zaip-skill-performance-engineering/SKILL.md +14 -0
  373. package/templates/.agents/skills/zaip-skill-performance-engineering/agents/openai.yaml +4 -0
  374. package/templates/.agents/skills/zaip-skill-prd/SKILL.md +1 -1
  375. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +1 -0
  376. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +26 -9
  377. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +39 -13
  378. package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +1 -0
  379. package/templates/.agents/skills/zaip-skill-refactor-landing-page/SKILL.md +66 -0
  380. package/templates/.agents/skills/zaip-skill-refactor-landing-page/agents/openai.yaml +4 -0
  381. package/templates/.agents/skills/zaip-skill-refactor-landing-page/references/behavioral-dry-run.md +23 -0
  382. package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +40 -1
  383. package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +98 -0
  384. package/templates/.agents/skills/zaip-skill-review/SKILL.md +1 -0
  385. package/templates/.agents/skills/zaip-skill-rules/SKILL.md +3 -3
  386. package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +2 -0
  387. package/templates/.agents/skills/zaip-skill-setup/SKILL.md +19 -21
  388. package/templates/.agents/skills/zaip-skill-setup/agents/openai.yaml +2 -2
  389. package/templates/.agents/skills/zaip-skill-spec/SKILL.md +3 -2
  390. package/templates/.agents/skills/zaip-skill-storage-uploads/SKILL.md +14 -0
  391. package/templates/.agents/skills/zaip-skill-storage-uploads/agents/openai.yaml +4 -0
  392. package/templates/.agents/skills/zaip-skill-systematic-debugging/SKILL.md +14 -0
  393. package/templates/.agents/skills/zaip-skill-systematic-debugging/agents/openai.yaml +4 -0
  394. package/templates/.agents/skills/zaip-skill-task/SKILL.md +16 -7
  395. package/templates/.agents/skills/zaip-skill-task/references/commit-policy.md +25 -0
  396. package/templates/.agents/skills/zaip-skill-test-data/SKILL.md +14 -0
  397. package/templates/.agents/skills/zaip-skill-test-data/agents/openai.yaml +4 -0
  398. package/templates/.agents/skills/zaip-skill-test-data/scripts/generate.mjs +72 -0
  399. package/templates/.agents/skills/zaip-skill-testing-strategy/SKILL.md +15 -0
  400. package/templates/.agents/skills/zaip-skill-testing-strategy/agents/openai.yaml +4 -0
  401. package/templates/.agents/skills/zaip-skill-testing-strategy/references/example-map.md +3 -0
  402. package/templates/.agents/skills/zaip-skill-website-readiness/SKILL.md +8 -0
  403. package/templates/.agents/zaip-aios/VERSION +1 -1
  404. package/templates/.agents/zaip-aios/guides/10-seguranca.md +2 -1
  405. package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +5 -3
  406. package/templates/scripts/validate-cloud-hostinger-contract.mjs +34 -0
  407. package/templates/template-manifest.json +955 -211
  408. package/templates/.agents/branding/.gitkeep +0 -0
  409. package/templates/.agents/dashboard/apps/frontend/dist/assets/CostCalculationGuidePage-snUCQYTC.js +0 -1
  410. package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-BPtVUGgs.js +0 -1
  411. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-3Awyaovx.js +0 -3
  412. package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-GgzpZ_PY.css +0 -1
  413. package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BCvZFMEf.js +0 -1
  414. package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-DbaLbU2q.js +0 -68
  415. package/templates/.agents/dashboard/apps/frontend/dist/assets/index-_MEktQNM.js +0 -2
  416. package/templates/.agents/dashboard/apps/frontend/dist/assets/rolldown-runtime-D9-fqq9M.js +0 -1
  417. package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-BDe4_Ubl.js +0 -1
  418. package/templates/.agents/growth/.gitkeep +0 -0
  419. package/templates/.agents/marketing/.gitkeep +0 -0
  420. package/templates/.agents/sales/.gitkeep +0 -0
@@ -184,6 +184,21 @@
184
184
  line-height: 1.35;
185
185
  }
186
186
 
187
+ .project-settings-metric.installation-metric.is-complete strong,
188
+ .project-settings-metric.installation-metric.is-complete span {
189
+ color: #166534;
190
+ }
191
+
192
+ .project-settings-metric.installation-metric.is-incomplete {
193
+ border-color: rgba(220, 38, 38, 0.3);
194
+ background: linear-gradient(145deg, rgba(220, 38, 38, 0.08), #fff 72%);
195
+ }
196
+
197
+ .project-settings-metric.installation-metric.is-incomplete strong,
198
+ .project-settings-metric.installation-metric.is-incomplete span {
199
+ color: #b91c1c;
200
+ }
201
+
187
202
  .project-settings-feature p {
188
203
  margin-top: 5px;
189
204
  color: #526176;
@@ -600,6 +615,59 @@
600
615
  color: #b91c1c;
601
616
  }
602
617
 
618
+ .project-detected-versions {
619
+ margin-top: 18px;
620
+ }
621
+
622
+ .project-detected-versions .project-settings-fields {
623
+ padding: 20px 22px 22px;
624
+ }
625
+
626
+ .project-detected-versions .project-stack-versions {
627
+ margin: 0;
628
+ }
629
+
630
+ .project-installation-toast {
631
+ position: fixed;
632
+ z-index: 20;
633
+ right: clamp(16px, 4vw, 48px);
634
+ bottom: clamp(16px, 4vw, 48px);
635
+ display: flex;
636
+ align-items: center;
637
+ gap: 12px;
638
+ max-width: min(420px, calc(100vw - 32px));
639
+ padding: 14px 16px;
640
+ border: 1px solid rgba(220, 38, 38, 0.35);
641
+ border-radius: 16px;
642
+ background: #fef2f2;
643
+ color: #b91c1c;
644
+ box-shadow: 0 18px 48px rgba(15, 23, 42, 0.16);
645
+ font-weight: 700;
646
+ line-height: 1.45;
647
+ }
648
+
649
+ .project-installation-toast button {
650
+ display: grid;
651
+ flex: none;
652
+ width: 32px;
653
+ min-height: 32px;
654
+ padding: 0;
655
+ border: 1px solid currentColor;
656
+ border-radius: 999px;
657
+ place-items: center;
658
+ background: transparent;
659
+ color: inherit;
660
+ cursor: pointer;
661
+ font: inherit;
662
+ font-size: 1.25rem;
663
+ line-height: 1;
664
+ }
665
+
666
+ .project-installation-toast button:focus-visible {
667
+ outline: 3px solid rgba(0, 176, 240, 0.42);
668
+ outline-offset: 3px;
669
+ }
670
+
603
671
  .project-settings-footer {
604
672
  position: sticky;
605
673
  bottom: 0;
@@ -35,8 +35,8 @@ const config: ProjectConfigSettings = {
35
35
 
36
36
  describe("project settings form mapping", () => {
37
37
  it("renders a canonical framework SemVer as a short major.minor label", () => {
38
- expect(shortFrameworkVersion("2.2.0")).toBe("v2.0");
39
- expect(shortFrameworkVersion("v2.2.0")).toBe("v2.0");
38
+ expect(shortFrameworkVersion("2.5.0")).toBe("v2.5");
39
+ expect(shortFrameworkVersion("v2.5.0")).toBe("v2.5");
40
40
  expect(shortFrameworkVersion("1.0")).toBeNull();
41
41
  });
42
42
 
@@ -0,0 +1,36 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ millisecondsUntilNextSaoPauloDay,
4
+ rolloverOperationsPeriod,
5
+ } from "./sao-paulo-day-rollover.js";
6
+
7
+ describe("Sao Paulo day rollover", () => {
8
+ it("moves Today and Yesterday at the America/Sao_Paulo midnight boundary", () => {
9
+ const beforeMidnight = new Date("2026-09-08T02:59:59.000Z");
10
+ const afterMidnight = new Date("2026-09-08T03:00:01.000Z");
11
+ expect(
12
+ rolloverOperationsPeriod(
13
+ { preset: "today", range: { start: "x", end: "x" } },
14
+ beforeMidnight,
15
+ ),
16
+ ).toEqual({ preset: "today", range: { start: "2026-09-07", end: "2026-09-07" } });
17
+ expect(
18
+ rolloverOperationsPeriod(
19
+ { preset: "yesterday", range: { start: "x", end: "x" } },
20
+ afterMidnight,
21
+ ),
22
+ ).toEqual({ preset: "yesterday", range: { start: "2026-09-07", end: "2026-09-07" } });
23
+ expect(millisecondsUntilNextSaoPauloDay(beforeMidnight)).toBeGreaterThanOrEqual(1_000);
24
+ expect(millisecondsUntilNextSaoPauloDay(beforeMidnight)).toBeLessThan(1_100);
25
+ });
26
+
27
+ it("keeps custom bounds and renews the All Time display range", () => {
28
+ const now = new Date("2026-09-08T03:00:01.000Z");
29
+ const custom = { preset: "custom" as const, range: { start: "2026-08-01", end: "2026-08-02" } };
30
+ expect(rolloverOperationsPeriod(custom, now)).toBe(custom);
31
+ expect(rolloverOperationsPeriod({ preset: "all", range: custom.range }, now)).toEqual({
32
+ preset: "all",
33
+ range: { start: "2026-09-01", end: "2026-09-08" },
34
+ });
35
+ });
36
+ });
@@ -0,0 +1,30 @@
1
+ import { saoPauloPeriodKey } from "@zaip-ai/dashboard-operations/contracts";
2
+ import { dateRangeForPreset } from "@zaip-ai/dashboard-operations/react";
3
+ import type { OperationsPeriodState } from "./operations-period.js";
4
+
5
+ export function rolloverOperationsPeriod(
6
+ period: OperationsPeriodState,
7
+ now = new Date(),
8
+ ): OperationsPeriodState {
9
+ if (period.preset === "custom") return period;
10
+ if (period.preset === "all") {
11
+ return { ...period, range: dateRangeForPreset("this-month", now) };
12
+ }
13
+ return { ...period, range: dateRangeForPreset(period.preset, now) };
14
+ }
15
+
16
+ /** Schedule against the project calendar rather than the browser's local zone. */
17
+ export function millisecondsUntilNextSaoPauloDay(now = new Date()): number {
18
+ const day = saoPauloPeriodKey(now.toISOString(), "day");
19
+ if (day === null) throw new RangeError("Invalid Sao Paulo day anchor");
20
+ let low = now.getTime();
21
+ let high = low + 30 * 60 * 60 * 1_000;
22
+ while (saoPauloPeriodKey(new Date(high).toISOString(), "day") === day)
23
+ high += 6 * 60 * 60 * 1_000;
24
+ while (high - low > 1) {
25
+ const middle = Math.floor((low + high) / 2);
26
+ if (saoPauloPeriodKey(new Date(middle).toISOString(), "day") === day) low = middle;
27
+ else high = middle;
28
+ }
29
+ return Math.max(1, high - now.getTime() + 25);
30
+ }
@@ -42,14 +42,11 @@ describe("snapshot update banner semantics", () => {
42
42
  });
43
43
 
44
44
  it("presents a stale local snapshot as neutral status and reserves alert red for errors", () => {
45
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
45
+ const app = readFileSync(new URL("./AppDashboardContent.tsx", import.meta.url), "utf8");
46
46
  const boundary = readFileSync(new URL("./AppLoadingBoundary.tsx", import.meta.url), "utf8");
47
47
  const overlays = readFileSync(new URL("./AppOverlays.tsx", import.meta.url), "utf8");
48
48
  const styles = readFileSync(new URL("./styles.css", import.meta.url), "utf8");
49
- const snapshot = app.slice(
50
- app.indexOf("const initialDataPending"),
51
- app.indexOf("const renderedOperations"),
52
- );
49
+ const snapshot = readFileSync(new URL("./use-snapshot-notice.tsx", import.meta.url), "utf8");
53
50
  const compactSnapshot = snapshot.replace(/\s+/g, " ");
54
51
  const error = app.slice(app.indexOf("{error ?"), app.indexOf("{/* Cost Monitor boundary"));
55
52
 
@@ -1,5 +1,6 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { describe, expect, it } from "vitest";
3
+ import { readAppCompositionSource } from "./__tests__/app-composition-support.js";
3
4
  import { isCurrentDashboardRequest, mergeBoardPages, needsAtomicCostSnapshot } from "./App.js";
4
5
  import { loadAtomicCostSnapshot } from "./snapshot-coherence.js";
5
6
  import {
@@ -35,7 +36,7 @@ describe("atomic Cost snapshot loading", () => {
35
36
  });
36
37
 
37
38
  it("keeps Cost out of quick Operations and fetches its narrow summary on entry", () => {
38
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
39
+ const app = readAppCompositionSource();
39
40
  expect(app).not.toContain("api.snapshot(currency, period)");
40
41
  expect(app).toContain('api.costMonitor(currency, period, "summary", controller.signal)');
41
42
  expect(app).not.toContain("dailyCostSeed(currency, period)");
@@ -51,10 +52,9 @@ describe("atomic Cost snapshot loading", () => {
51
52
  });
52
53
 
53
54
  it("mounts Cost immediately and lets its Daily page own the only initial request", () => {
54
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
55
- const costSelection = app.slice(
56
- app.indexOf('if (nextView === "cost-monitor")'),
57
- app.indexOf('if (nextView === "traceability")'),
55
+ const costSelection = readFileSync(
56
+ new URL("./dashboard-view-actions.ts", import.meta.url),
57
+ "utf8",
58
58
  );
59
59
  expect(costSelection).toContain("loadCostSummary()");
60
60
  expect(costSelection).not.toContain("loadCostDetails");
@@ -62,10 +62,10 @@ describe("atomic Cost snapshot loading", () => {
62
62
  });
63
63
 
64
64
  it("never blocks the dashboard or starts a full snapshot for a paged Cost request", () => {
65
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
65
+ const app = readAppCompositionSource();
66
66
  const globalGate = app.slice(
67
- app.indexOf("const globalLoadingPending"),
68
- app.indexOf("const renderedOperations"),
67
+ app.indexOf("globalLoadingPending:"),
68
+ app.indexOf("snapshotNotice:"),
69
69
  );
70
70
  expect(app).toContain("const [, setCostSurfaceLoading] = useState(false);");
71
71
  expect(globalGate).not.toContain("costSurfaceLoading");
@@ -76,7 +76,7 @@ describe("atomic Cost snapshot loading", () => {
76
76
  });
77
77
 
78
78
  it("does not request Cost Monitor while the initial route is Operations", () => {
79
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
79
+ const app = readAppCompositionSource();
80
80
  const initialLoad = app.slice(
81
81
  app.indexOf("const refresh = useCallback"),
82
82
  app.indexOf("const loadOperationsDetails"),
@@ -88,15 +88,15 @@ describe("atomic Cost snapshot loading", () => {
88
88
  });
89
89
 
90
90
  it("retries a failed Cost snapshot through its summary request", () => {
91
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
92
- const retry = app.slice(app.indexOf("const retryLastLoad"), app.indexOf("const setupRoute"));
91
+ const app = readAppCompositionSource();
92
+ const retry = readFileSync(new URL("./dashboard-retry.ts", import.meta.url), "utf8");
93
93
 
94
94
  expect(retry).toContain('if (failedArea === "costs") void loadCostSummary();');
95
95
  expect(retry).not.toContain("loadCosts");
96
96
  });
97
97
 
98
98
  it("does not prefetch a newer Operations snapshot in the background", () => {
99
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
99
+ const app = readAppCompositionSource();
100
100
  const effects = readFileSync(new URL("./use-app-effects.ts", import.meta.url), "utf8");
101
101
  const costLoaders = readFileSync(new URL("./use-app-cost-loaders.ts", import.meta.url), "utf8");
102
102
  expect(app).not.toContain("const costPrefetch = useRef");
@@ -204,6 +204,7 @@ describe("atomic Cost snapshot loading", () => {
204
204
  "isCommittedSnapshotRevision(ready.snapshot_state, ready.snapshot_revision)",
205
205
  );
206
206
  expect(effects).toContain("settleSnapshotRevisionRefresh({");
207
+ expect(effects).toContain("if (succeeded) setSnapshotUpdating(false);");
207
208
  expect(effects).toContain(
208
209
  "snapshotRevisionPollDelay(document.visibilityState, consecutiveFailures)",
209
210
  );
@@ -212,13 +213,23 @@ describe("atomic Cost snapshot loading", () => {
212
213
  });
213
214
 
214
215
  it("does not reconcile open work automatically", () => {
215
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
216
+ const app = readAppCompositionSource();
216
217
  expect(app).not.toContain("startupReconciliation");
217
218
  expect(app).toContain("await refresh(false, reconcileOpenWork, !reconcileOpenWork)");
218
219
  });
219
220
 
221
+ it("uses only materialized positive-token telemetry for the Atualizado header", () => {
222
+ const app = readAppCompositionSource();
223
+ // A file rebuild or task lifecycle event is not token collection. The
224
+ // header remains absent until the committed snapshot carries positive-token
225
+ // effective usage, whether it arrives through a regular, reconciliation,
226
+ // or explicit projection refresh.
227
+ expect(app).toContain("projection.summary.latest_token_collected_at ?? null");
228
+ expect(app).toContain("snapshot.projection.latest_token_collected_at ?? null");
229
+ });
230
+
220
231
  it("removes the global Cost detail request and keeps stale request guards", () => {
221
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
232
+ const app = readAppCompositionSource();
222
233
  const costPage = readFileSync(
223
234
  new URL("../../../modules/cost-monitor/src/react/CostMonitorPage.tsx", import.meta.url),
224
235
  "utf8",
@@ -252,7 +263,7 @@ describe("atomic Cost snapshot loading", () => {
252
263
  });
253
264
  expect(afterPeriodChange).toEqual({ costs: null, activeExport: null });
254
265
 
255
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
266
+ const app = readAppCompositionSource();
256
267
  const periodChange = app.slice(
257
268
  app.indexOf("onDateChange={(preset, range) => {"),
258
269
  app.indexOf("settings={"),
@@ -274,7 +285,7 @@ describe("atomic Cost snapshot loading", () => {
274
285
  });
275
286
 
276
287
  it("owns the rendered Operations period in App and routes date changes back to its request state", () => {
277
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
288
+ const app = readAppCompositionSource();
278
289
  const operationsPage = app.slice(app.indexOf("<OperationsPage"), app.indexOf("<AppOverlays"));
279
290
 
280
291
  expect(operationsPage).toContain("datePreset={operationsPeriod.preset}");
@@ -284,7 +295,7 @@ describe("atomic Cost snapshot loading", () => {
284
295
  });
285
296
 
286
297
  it("keeps detail hydration stable when the quick Operations projection updates", () => {
287
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
298
+ const app = readAppCompositionSource();
288
299
  const detailsLoader = app.slice(
289
300
  app.indexOf("const loadOperationsDetails"),
290
301
  app.indexOf("const loadMoreBoard"),
@@ -296,7 +307,7 @@ describe("atomic Cost snapshot loading", () => {
296
307
  });
297
308
 
298
309
  it("loads the compact Operations projection before detail data", () => {
299
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
310
+ const app = readAppCompositionSource();
300
311
  const initialLoad = app.slice(
301
312
  app.indexOf("const refresh = useCallback"),
302
313
  app.indexOf("const loadOperationsDetails"),
@@ -313,7 +324,7 @@ describe("atomic Cost snapshot loading", () => {
313
324
  });
314
325
 
315
326
  it("defers bounded work-board hydration until after the quick first paint", () => {
316
- const app = readFileSync(new URL("./App.tsx", import.meta.url), "utf8");
327
+ const app = readAppCompositionSource();
317
328
  const boardHydration = app.slice(
318
329
  app.indexOf('if (dashboardView !== "operations" || operations === null) return;'),
319
330
  app.indexOf("const loadCostDetails"),
@@ -62,6 +62,7 @@ export function isCommittedSnapshotRevision(
62
62
  );
63
63
  }
64
64
 
65
+ /** A changed immutable revision is usable even while its successor is building. */
65
66
  export function settleSnapshotRevisionRefresh({
66
67
  observedRevision,
67
68
  pendingRevision,
@@ -248,6 +249,10 @@ export function useAppEffects({
248
249
  // lifecycle reconciliation from a tab that happened to stay open.
249
250
  void refresh(false, false, false, true)
250
251
  .then((succeeded) => {
252
+ // Do not settle an updating banner merely because `/ready` observed
253
+ // a new hash. Settle it only after the tab has loaded that committed
254
+ // immutable generation successfully.
255
+ if (succeeded) setSnapshotUpdating(false);
251
256
  const settled = settleSnapshotRevisionRefresh({
252
257
  observedRevision: observedSnapshotRevision.current,
253
258
  pendingRevision: pendingSnapshotRevisionRefresh.current,
@@ -281,6 +286,9 @@ export function useAppEffects({
281
286
  observedSnapshotRevision.current = ready.snapshot_revision;
282
287
  }
283
288
  if (shouldRefreshForSnapshotRevision(previousRevision, ready.snapshot_revision)) {
289
+ // `updating` can describe a later rebuild. The revision in this
290
+ // response is already immutable; `refreshChangedRevision` settles
291
+ // the banner after its GET has loaded that generation.
284
292
  pendingSnapshotRevisionRefresh.current = ready.snapshot_revision;
285
293
  refreshChangedRevision();
286
294
  }
@@ -301,7 +309,7 @@ export function useAppEffects({
301
309
  cancelled = true;
302
310
  if (timeout !== null) window.clearTimeout(timeout);
303
311
  };
304
- }, [api, refresh]);
312
+ }, [api, refresh, setSnapshotUpdating]);
305
313
 
306
314
  useEffect(() => {
307
315
  if (
@@ -0,0 +1,77 @@
1
+ import type { OperationsProjection } from "@zaip-ai/dashboard-operations/contracts";
2
+ import {
3
+ type Dispatch,
4
+ type SetStateAction,
5
+ useCallback,
6
+ useEffect,
7
+ useRef,
8
+ useState,
9
+ } from "react";
10
+ import { traceTaskSearchStages } from "./AppWorkBoard.js";
11
+ import type { DashboardApiClient } from "./dashboard-api.js";
12
+ import {
13
+ appendTraceabilityTaskPage,
14
+ traceabilityTaskPageSize,
15
+ } from "./traceability-task-pagination.js";
16
+ export function useAppTraceTaskPagination(
17
+ api: DashboardApiClient,
18
+ traceTasks: OperationsProjection["tasks"],
19
+ setTraceTasks: Dispatch<SetStateAction<OperationsProjection["tasks"]>>,
20
+ ) {
21
+ const traceTasksRef = useRef(traceTasks);
22
+ const traceTaskCursorRef = useRef({ offset: 0, stageIndex: 0 });
23
+ const traceTasksLoadingRef = useRef(false);
24
+ const [traceTasksHasMore, setTraceTasksHasMore] = useState(false);
25
+ const [traceTasksLoading, setTraceTasksLoading] = useState(false);
26
+ useEffect(() => {
27
+ traceTasksRef.current = traceTasks;
28
+ }, [traceTasks]);
29
+ const loadMoreTraceTasks = useCallback(
30
+ async (loadAll = false, reset = false): Promise<OperationsProjection["tasks"]> => {
31
+ if (traceTasksLoadingRef.current) return traceTasksRef.current;
32
+ if (reset) {
33
+ traceTaskCursorRef.current = { offset: 0, stageIndex: 0 };
34
+ traceTasksRef.current = [];
35
+ setTraceTasks([]);
36
+ setTraceTasksHasMore(true);
37
+ }
38
+ if (traceTaskCursorRef.current.stageIndex >= traceTaskSearchStages.length)
39
+ return traceTasksRef.current;
40
+
41
+ traceTasksLoadingRef.current = true;
42
+ setTraceTasksLoading(true);
43
+ try {
44
+ do {
45
+ const cursor = traceTaskCursorRef.current;
46
+ const stage = traceTaskSearchStages[cursor.stageIndex];
47
+ if (stage === undefined) break;
48
+ const page = await api.operationsBoard(
49
+ { from: null, to: null },
50
+ stage,
51
+ cursor.offset,
52
+ { kind: "all-tasks" },
53
+ undefined,
54
+ traceabilityTaskPageSize,
55
+ );
56
+ const updated = appendTraceabilityTaskPage({
57
+ cursor,
58
+ page,
59
+ tasks: traceTasksRef.current,
60
+ });
61
+ traceTasksRef.current = updated.tasks;
62
+ setTraceTasks(traceTasksRef.current);
63
+ traceTaskCursorRef.current = updated.cursor;
64
+ if (page.tasks.length > 0 && !loadAll) break;
65
+ } while (traceTaskCursorRef.current.stageIndex < traceTaskSearchStages.length);
66
+ setTraceTasksHasMore(traceTaskCursorRef.current.stageIndex < traceTaskSearchStages.length);
67
+ return traceTasksRef.current;
68
+ } finally {
69
+ traceTasksLoadingRef.current = false;
70
+ setTraceTasksLoading(false);
71
+ }
72
+ },
73
+ [api, setTraceTasks],
74
+ );
75
+
76
+ return { loadMoreTraceTasks, traceTasksHasMore, traceTasksLoading };
77
+ }