@zaip-ai/cli 3.3.0 → 3.5.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.
- package/dist/services/adapters.d.ts +1 -1
- package/dist/services/adapters.d.ts.map +1 -1
- package/dist/services/adapters.js +4 -3
- package/dist/services/adapters.js.map +1 -1
- package/dist/services/agent-catalog-upgrade.d.ts +3 -0
- package/dist/services/agent-catalog-upgrade.d.ts.map +1 -0
- package/dist/services/agent-catalog-upgrade.js +35 -0
- package/dist/services/agent-catalog-upgrade.js.map +1 -0
- package/dist/services/install-agents-template.d.ts.map +1 -1
- package/dist/services/install-agents-template.js +22 -22
- package/dist/services/install-agents-template.js.map +1 -1
- package/dist/services/install-template-policy.d.ts +3 -0
- package/dist/services/install-template-policy.d.ts.map +1 -0
- package/dist/services/install-template-policy.js +21 -0
- package/dist/services/install-template-policy.js.map +1 -0
- package/dist/services/logger.test.js +12 -2
- package/dist/services/logger.test.js.map +1 -1
- package/dist/services/sqlite-bootstrap.d.ts +1 -0
- package/dist/services/sqlite-bootstrap.d.ts.map +1 -1
- package/dist/services/sqlite-bootstrap.js +10 -1
- package/dist/services/sqlite-bootstrap.js.map +1 -1
- package/package.json +2 -2
- package/templates/.agents/config/agents/discovery.json +1 -1
- package/templates/.agents/dashboard/.zaip-managed.json +286 -126
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-BBFDrn64.js → CostCalculationGuidePage-C5NgEcVh.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-Cd-qo9w7.js → DashboardHelpDialog-CCMVnkkI.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-J7L5m8lk.js → PricingSettingsDialog-CGYcJ5EB.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-B9GWkEyN.css → ProjectSettingsPage-CQMhvzvJ.css} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-D46WWIKr.js +3 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-BzVtGLWS.js → TraceabilityWorkspace-BKBpJyLh.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{cost-monitor-PoJA2PI1.css → cost-monitor-BsMfGfQi.css} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-j3aUYH5G.js +68 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-CWzf_RiP.js → icons-vendor-x8xxL9yW.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Bas2TVju.js +2 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-CxrG_wRI.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-CtHdbZk3.js → react-vendor-CNOXIJHN.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-BKrDH2TR.js → traceability-CcpbpT1s.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +7 -7
- package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/App.tsx +12 -1
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsCard.tsx +5 -0
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsField.tsx +21 -0
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.dom.test.ts +12 -1
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +16 -28
- package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +25 -4
- package/templates/.agents/dashboard/apps/frontend/src/WorkspaceStatus.test.tsx +51 -0
- package/templates/.agents/dashboard/apps/frontend/src/WorkspaceStatus.tsx +39 -0
- package/templates/.agents/dashboard/apps/frontend/src/app-work-board-options.ts +41 -0
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-runtime-status.ts +25 -0
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-copy.ts +13 -4
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +25 -1
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-workspace.css +28 -0
- package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +39 -0
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +5 -1
- package/templates/.agents/dashboard/apps/frontend/src/use-app-work-board.test.ts +140 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-work-board.ts +28 -41
- package/templates/.agents/dashboard/apps/frontend/src/use-runtime-status.ts +38 -0
- package/templates/.agents/dashboard/apps/frontend/src/workspace-status.css +20 -0
- package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +25 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +17 -19
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.tsx +13 -167
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostGroupsTable.tsx +2 -9
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +8 -8
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +29 -52
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTableLoading.test.ts +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables-keeps-legacy-codex-identity-fields-blank.test.ts +2 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +4 -27
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.test.ts +2 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.tsx +4 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/agent-model-presentation.test.ts +26 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-embedded.css +7 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-loaders.ts +173 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-props.ts +47 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-selectors.ts +1 -7
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-page-range.ts +3 -9
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +44 -83
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +11 -111
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +47 -181
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +63 -91
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/cost-monitor-unavailable.test.ts +55 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/cost-summary-duration.test.ts +189 -0
- package/templates/.agents/dashboard/modules/operations/package.json +1 -1
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsEntityFilters.tsx +82 -0
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +22 -31
- package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.test.tsx +13 -1
- package/templates/.agents/dashboard/modules/operations/src/react/PagedWorkList.tsx +16 -3
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +11 -27
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +44 -193
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportColumns.ts +186 -0
- package/templates/.agents/dashboard/modules/operations/src/react/export/excel-agent-participations.test.ts +28 -0
- package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +2 -1
- package/templates/.agents/dashboard/modules/operations/src/react/operations-export-duration.ts +13 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-filter-panel.css +4 -0
- package/templates/.agents/dashboard/modules/operations/src/react/use-operation-filter-feedback.ts +18 -0
- package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +11 -0
- package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +10 -2
- package/templates/.agents/dashboard/modules/operations/src/work-board-model.ts +1 -1
- package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
- package/templates/.agents/dashboard/packages/branding/package.json +1 -1
- package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
- package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +395 -341
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +346 -294
- package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +2 -1
- package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +42 -8
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +395 -341
- package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.test.ts +95 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/active-codex-telemetry.ts +102 -12
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +2 -3
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +75 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/server-costs-routes.ts +10 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-lifecycle-diagnostics.ts +50 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-macro-population.test.ts +165 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-page-filters.ts +65 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.test.ts +111 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.ts +53 -63
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.ts +19 -5
- package/templates/.agents/dashboard/packages/local-runtime/src/server-period-macro-metric.ts +11 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/server-read-projections.ts +16 -9
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-refresh.test.ts +46 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.test.ts +10 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot-synchronization.ts +4 -3
- package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +43 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +46 -11
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-filter-matrix.test.ts +188 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-summary-details.test.ts +85 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-cost-summary-details.ts +147 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-first-fold-cache.ts +64 -54
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-macro-classification.test.ts +172 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-materialize-projections.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-projection.ts +2 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.test.ts +7 -7
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-operations-work-list.ts +2 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-period-averages.ts +10 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-pricing-provenance.test.ts +39 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-agent-dimension.ts +18 -82
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-cached-cost-page.ts +169 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-developer.ts +205 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-entity-group.ts +13 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-filtered-dimension.ts +22 -23
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-financial.ts +42 -209
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-model-dimension.ts +18 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-provider-dimension.ts +9 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-summary.ts +76 -83
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-query-view-page.ts +25 -161
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-canonical.ts +20 -47
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-counts-every-root-execution-day-returns.test.ts +2 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-filesystem.ts +16 -16
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-multi-provider.test.ts +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-rebuild.ts +47 -22
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model-schema.ts +3 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +11 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-rebuild-result.ts +15 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-base-views.ts +4 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-dashboard-views.ts +15 -56
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-macro-classification.ts +48 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-summary-cursor.ts +15 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-token-active-allocation.ts +46 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-work-stages.ts +60 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-history.mjs +5 -1
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-claims.test.mjs +7 -1
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-page.mjs +17 -2
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-ownership.mjs +65 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-ownership.test.mjs +72 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-processes.mjs +32 -9
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +39 -45
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +5 -2
- package/templates/.agents/dashboard/packages/ui/package.json +1 -1
- package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
- package/templates/.agents/dashboard/tests/e2e/specs/dashboard-performance-matrix.spec.ts +1 -18
- package/templates/.agents/dashboard/tests/e2e/specs/export-row-identity.spec.ts +20 -0
- package/templates/.agents/dashboard/tests/e2e/specs/export-row-identity.ts +20 -0
- package/templates/.agents/design/.zaip-managed.json +105 -69
- package/templates/.agents/design/apps/catalog/dist/assets/index-0W0Gj_Gs.css +1 -0
- package/templates/.agents/design/apps/catalog/dist/assets/index-32GZO95T.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/assets/{index-D_lfqoyx.js → index-BP8IxOxt.js} +3 -3
- package/templates/.agents/design/apps/catalog/dist/assets/index-D1JaPXfV.css +1 -0
- package/templates/.agents/design/apps/catalog/dist/assets/index-D2miO4-O.js +72 -0
- package/templates/.agents/design/apps/catalog/dist/assets/{index-BOjCcUaU.js → index-QJsgr9Ht.js} +3 -3
- package/templates/.agents/design/apps/catalog/dist/assets/{index-CqtYXZfV.js → index-mvD5mwcC.js} +3 -3
- package/templates/.agents/design/apps/catalog/dist/index.html +2 -2
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/CatalogShell-BJ8b4xZr.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{Color-6AOWCN3U-Cm-yJJz_.js → Color-6AOWCN3U-CQLHzznn.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-kxWwSKin.js +146 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/DashboardFilters.stories-Chm_dXV7.js +9 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/DashboardFiltersSpecimen-9CaCbGIZ.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/DesignSystem.stories-ED52wFjY.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{DocsRenderer-JROSPFPF-Belk4jRr.js → DocsRenderer-JROSPFPF-BcLgM80v.js} +4 -4
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/Primitives-DV6Bpudf.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{WithTooltip-7X4HQR7L-DoPvjkS1.js → WithTooltip-7X4HQR7L-BKNiAz_E.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/WorkspaceStatus.stories-BL19HGOo.js +17 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/WorkspaceStatusSpecimen-DQnSS6s9.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-DRQKCCAG-B1itKXEN.js → chunk-DRQKCCAG-DZBcXL-p.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{chunk-W22LQPXL-C-Eb5SPY.js → chunk-W22LQPXL-CF3y2mfo.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{components-DnyKLwhj.js → components-BVjxMRGq.js} +5 -5
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-Do9sjqiW.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/iframe-0W0Gj_Gs.css +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{iframe-DcXBsFPz.js → iframe-CTWGZcEe.js} +4 -4
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{react-18-CRM89QRf.js → react-18-B9_a4mHb.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-NrUxok8K.js +1 -0
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{syntaxhighlighter-YFXUGROL-B03jQGTF.js → syntaxhighlighter-YFXUGROL-F_p8E2xc.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/{theming-4ZyufAga.js → theming-fbSD9ZLF.js} +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/iframe.html +2 -2
- package/templates/.agents/design/apps/catalog/dist/storybook/index.json +1 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/sb-addons/a11y-2/manager-bundle.js +3 -3
- package/templates/.agents/design/apps/catalog/dist/storybook/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js +3 -3
- package/templates/.agents/design/apps/catalog/package.json +1 -1
- package/templates/.agents/design/apps/catalog/src/components/DashboardFiltersSpecimen.tsx +61 -0
- package/templates/.agents/design/apps/catalog/src/components/Primitives.tsx +24 -0
- package/templates/.agents/design/apps/catalog/src/components/StackVersionFieldSpecimen.tsx +70 -0
- package/templates/.agents/design/apps/catalog/src/components/WorkspaceStatusSpecimen.tsx +42 -0
- package/templates/.agents/design/apps/catalog/src/design-contract.test.ts +27 -13
- package/templates/.agents/design/apps/catalog/src/pages/ComponentsPage.tsx +52 -0
- package/templates/.agents/design/apps/catalog/src/pages/DesignSystemPage.tsx +15 -1
- package/templates/.agents/design/apps/catalog/src/stories/Components.stories.tsx +32 -0
- package/templates/.agents/design/apps/catalog/src/stories/DashboardFilters.stories.tsx +7 -0
- package/templates/.agents/design/apps/catalog/src/stories/WorkspaceStatus.stories.tsx +12 -0
- package/templates/.agents/design/apps/catalog/src/styles/components.css +84 -3
- package/templates/.agents/design/apps/catalog/src/styles/stack-version-field.css +17 -0
- package/templates/.agents/design/apps/catalog/src/styles.css +2 -0
- package/templates/.agents/design/packages/local-runtime/package.json +1 -1
- package/templates/.agents/design/tokens.json +32 -0
- package/templates/.agents/requirements/autonomous-assurance.md +1 -1
- package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
- package/templates/.agents/requirements/comparative-audit.md +1 -1
- package/templates/.agents/requirements/context-engine.md +1 -1
- package/templates/.agents/requirements/cost-observability.md +1 -1
- package/templates/.agents/requirements/dashboard-launch.md +1 -1
- package/templates/.agents/requirements/data-export.md +1 -1
- package/templates/.agents/requirements/design-system.md +1 -1
- package/templates/.agents/requirements/execution-engine.md +1 -1
- package/templates/.agents/requirements/kanban-dashboard.md +1 -1
- package/templates/.agents/requirements/model-orchestration.md +1 -1
- package/templates/.agents/requirements/public-distribution.md +9 -3
- package/templates/.agents/requirements/software-architecture.md +1 -1
- package/templates/.agents/requirements/strategic-improvements.md +1 -1
- package/templates/.agents/requirements/work-lifecycle.md +1 -1
- package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
- package/templates/.agents/rules/autonomy-decision.md +1 -0
- package/templates/.agents/rules/workflow.md +2 -2
- package/templates/.agents/runtime/VERSION +1 -1
- package/templates/.agents/runtime/bin/zaip.mjs +27 -26
- package/templates/.agents/runtime/checksums.sha256 +5 -5
- package/templates/.agents/runtime/manifest.json +1 -1
- package/templates/.agents/runtime/provenance.json +4 -4
- package/templates/.agents/runtime/sbom.cdx.json +1 -1
- package/templates/.agents/skills/zaip-skill-execution/SKILL.md +13 -0
- package/templates/.agents/skills/zaip-skill-execution/references/autonomous-continuation.md +17 -0
- package/templates/.agents/skills/zaip-skill-execution/references/correction-cycle.md +2 -2
- package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +9 -6
- package/templates/.agents/skills/zaip-skill-github-deploy/agents/openai.yaml +1 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/references/deployment-workflow.md +11 -9
- package/templates/.agents/skills/zaip-skill-github-deploy/references/release-identity.md +2 -2
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/consumer-release-preparation.mjs +1 -2
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/consumer-release-preparation.test.mjs +9 -1
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +23 -0
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/preflight.mjs +2 -6
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/preflight.test.mjs +15 -1
- package/templates/.agents/skills/zaip-skill-move-prd/SKILL.md +4 -0
- package/templates/.agents/skills/zaip-skill-move-spec/SKILL.md +4 -0
- package/templates/.agents/skills/zaip-skill-prd/SKILL.md +3 -3
- package/templates/.agents/skills/zaip-skill-release-qualification/SKILL.md +11 -8
- package/templates/.agents/skills/zaip-skill-release-qualification/references/local-preparation.md +13 -12
- package/templates/.agents/skills/zaip-skill-setup/SKILL.md +17 -2
- package/templates/.agents/skills/zaip-skill-setup/agents/openai.yaml +1 -1
- package/templates/.agents/skills/zaip-skill-spec/SKILL.md +2 -2
- package/templates/.agents/zaip-aios/VERSION +1 -1
- package/templates/template-manifest.json +445 -245
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-BpsAFy0g.js +0 -3
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor--iPcnZdx.js +0 -68
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-Cmlx8OYH.css +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DfdlGa7c.js +0 -2
- package/templates/.agents/design/apps/catalog/dist/assets/index-BEmIE7WE.css +0 -1
- package/templates/.agents/design/apps/catalog/dist/assets/index-BJV597iq.js +0 -72
- package/templates/.agents/design/apps/catalog/dist/assets/index-B_WhrCZe.js +0 -72
- package/templates/.agents/design/apps/catalog/dist/assets/index-CqqYWY2f.js +0 -9
- package/templates/.agents/design/apps/catalog/dist/assets/index-D9pj7Jlf.js +0 -9
- package/templates/.agents/design/apps/catalog/dist/assets/index-i_PO2k9R.js +0 -9
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/CatalogShell-Cstn1UwA.js +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/Components.stories-D1WopB2L.js +0 -137
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/DesignSystem.stories-DQ9PJ3N3.js +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/formatter-L2YTDE3Q-D0OSgxWz.js +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/iframe-BEmIE7WE.css +0 -1
- package/templates/.agents/design/apps/catalog/dist/storybook/assets/react-C3tkVMIp.js +0 -1
package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-dashboard-views.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { macroClassificationSql } from "./sqlite-schema-macro-classification.js";
|
|
2
|
+
|
|
1
3
|
export const dashboardViewSql = ` CREATE VIEW vw_operations_work_list AS SELECT * FROM vw_entities;
|
|
4
|
+
${macroClassificationSql}
|
|
2
5
|
-- Full work summary retains historical activity coverage for internal
|
|
3
6
|
-- entity summaries. It is not the Kanban population.
|
|
4
7
|
CREATE VIEW vw_operations_work_summary AS
|
|
@@ -49,30 +52,18 @@ export const dashboardViewSql = ` CREATE VIEW vw_operations_work_list AS
|
|
|
49
52
|
), durations AS (
|
|
50
53
|
SELECT entity_kind, entity_id, ROUND(SUM(duration_ms)) AS total_duration
|
|
51
54
|
FROM entity_activity GROUP BY entity_kind, entity_id
|
|
52
|
-
), macro_classification AS (
|
|
53
|
-
-- These are structural macro facts. The narrowed-period first
|
|
54
|
-
-- fold filters the selected macros by activity, then retains their
|
|
55
|
-
-- canonical Task/rework classification instead of treating the
|
|
56
|
-
-- compact work-list row as an empty delivery.
|
|
57
|
-
SELECT 'spec' AS entity_kind, spec_id AS entity_id,
|
|
58
|
-
COUNT(DISTINCT task_id) AS task_count,
|
|
59
|
-
SUM(CASE WHEN work_type='rework' AND run_role='root' THEN 1 ELSE 0 END) AS rework_run_count
|
|
60
|
-
FROM activities WHERE spec_id IS NOT NULL GROUP BY spec_id
|
|
61
|
-
UNION ALL
|
|
62
|
-
SELECT 'prd' AS entity_kind, prd_id AS entity_id,
|
|
63
|
-
COUNT(DISTINCT task_id) AS task_count,
|
|
64
|
-
SUM(CASE WHEN work_type='rework' AND run_role='root' THEN 1 ELSE 0 END) AS rework_run_count
|
|
65
|
-
FROM activities WHERE prd_id IS NOT NULL GROUP BY prd_id
|
|
66
55
|
)
|
|
67
56
|
SELECT w.entity_kind, w.id, w.title, w.status, w.risk, w.occurred_at, w.occurred_day_sp,
|
|
68
57
|
f.invocation_count, f.llm_call_count, d.total_duration,
|
|
69
58
|
f.total_tokens, f.total_cost_usd, f.total_cost_brl,
|
|
70
59
|
COALESCE(classification.task_count, 0) AS task_count,
|
|
71
|
-
COALESCE(classification.rework_run_count, 0) AS rework_run_count
|
|
60
|
+
COALESCE(classification.rework_run_count, 0) AS rework_run_count,
|
|
61
|
+
COALESCE(classification.task_ids_json, '[]') AS task_ids_json,
|
|
62
|
+
COALESCE(classification.completed_task_count, 0) AS completed_task_count
|
|
72
63
|
FROM work_items w
|
|
73
64
|
LEFT JOIN financial f ON f.entity_kind=w.entity_kind AND f.entity_id=w.id
|
|
74
65
|
LEFT JOIN durations d ON d.entity_kind=w.entity_kind AND d.entity_id=w.id
|
|
75
|
-
LEFT JOIN
|
|
66
|
+
LEFT JOIN vw_macro_classification classification
|
|
76
67
|
ON classification.entity_kind=w.entity_kind AND classification.entity_id=w.id;
|
|
77
68
|
-- Kanban is a lifecycle surface: it lists only canonical records.
|
|
78
69
|
-- Telemetry-only identifiers remain Cost Monitor facts but cannot
|
|
@@ -207,46 +198,16 @@ export const dashboardViewSql = ` CREATE VIEW vw_operations_work_list AS
|
|
|
207
198
|
overview.latest_task_created_at
|
|
208
199
|
FROM vw_first_fold_overview_all_time overview;
|
|
209
200
|
CREATE VIEW vw_first_fold_spec_status_all_time AS
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
WHEN status='failed' THEN 'failed'
|
|
214
|
-
WHEN status='blocked' THEN 'blocked'
|
|
215
|
-
WHEN status IN ('delivered','completed') THEN 'completed'
|
|
216
|
-
WHEN status='ready' THEN 'ready'
|
|
217
|
-
WHEN status='draft' THEN 'planning'
|
|
218
|
-
WHEN status='verifying' THEN 'verifying'
|
|
219
|
-
WHEN status IN ('active','executing') THEN 'executing'
|
|
220
|
-
ELSE 'planning'
|
|
221
|
-
END AS stage, COUNT(*) AS entity_count
|
|
222
|
-
FROM spec_summary GROUP BY stage
|
|
223
|
-
), total AS (SELECT SUM(entity_count) AS entity_count FROM counts)
|
|
224
|
-
SELECT counts.stage, counts.entity_count,
|
|
225
|
-
CASE WHEN total.entity_count=0 THEN 0.0 ELSE CAST(counts.entity_count AS REAL)/total.entity_count END AS entity_percentage
|
|
226
|
-
FROM counts CROSS JOIN total;
|
|
201
|
+
SELECT COALESCE(c.stage, 'planning') AS stage, COUNT(*) AS entity_count
|
|
202
|
+
FROM work_items w LEFT JOIN canonical_work_items c ON c.entity_kind=w.entity_kind AND c.id=w.id
|
|
203
|
+
WHERE w.entity_kind='spec' GROUP BY COALESCE(c.stage, 'planning');
|
|
227
204
|
CREATE VIEW vw_first_fold_prd_status_all_time AS
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
WHEN status='failed' THEN 'failed'
|
|
232
|
-
WHEN status='blocked' THEN 'blocked'
|
|
233
|
-
WHEN status IN ('delivered','completed') THEN 'completed'
|
|
234
|
-
WHEN status='ready' THEN 'ready'
|
|
235
|
-
WHEN status='draft' THEN 'definition'
|
|
236
|
-
WHEN status='verifying' THEN 'verifying'
|
|
237
|
-
WHEN status IN ('active','executing') THEN 'executing'
|
|
238
|
-
ELSE 'definition'
|
|
239
|
-
END AS stage, COUNT(*) AS entity_count
|
|
240
|
-
FROM prd_summary GROUP BY stage
|
|
241
|
-
), total AS (SELECT SUM(entity_count) AS entity_count FROM counts)
|
|
242
|
-
SELECT counts.stage, counts.entity_count,
|
|
243
|
-
CASE WHEN total.entity_count=0 THEN 0.0 ELSE CAST(counts.entity_count AS REAL)/total.entity_count END AS entity_percentage
|
|
244
|
-
FROM counts CROSS JOIN total;
|
|
205
|
+
SELECT COALESCE(c.stage, 'definition') AS stage, COUNT(*) AS entity_count
|
|
206
|
+
FROM work_items w LEFT JOIN canonical_work_items c ON c.entity_kind=w.entity_kind AND c.id=w.id
|
|
207
|
+
WHERE w.entity_kind='prd' GROUP BY COALESCE(c.stage, 'definition');
|
|
245
208
|
CREATE VIEW vw_first_fold_spec_classification_all_time AS
|
|
246
209
|
WITH rollup AS (
|
|
247
|
-
SELECT
|
|
248
|
-
SUM(CASE WHEN a.work_type='rework' AND a.run_role='root' THEN 1 ELSE 0 END) AS rework_run_count
|
|
249
|
-
FROM spec_summary s LEFT JOIN activities a ON a.spec_id=s.id GROUP BY s.id
|
|
210
|
+
SELECT task_count, rework_run_count FROM vw_macro_classification WHERE entity_kind='spec'
|
|
250
211
|
), counts AS (
|
|
251
212
|
SELECT CASE WHEN rework_run_count>0 THEN 'rework' WHEN task_count>0 THEN 'structured' ELSE 'empty' END AS classification,
|
|
252
213
|
COUNT(*) AS entity_count
|
|
@@ -257,9 +218,7 @@ export const dashboardViewSql = ` CREATE VIEW vw_operations_work_list AS
|
|
|
257
218
|
FROM counts CROSS JOIN total;
|
|
258
219
|
CREATE VIEW vw_first_fold_prd_classification_all_time AS
|
|
259
220
|
WITH rollup AS (
|
|
260
|
-
SELECT
|
|
261
|
-
SUM(CASE WHEN a.work_type='rework' AND a.run_role='root' THEN 1 ELSE 0 END) AS rework_run_count
|
|
262
|
-
FROM prd_summary p LEFT JOIN activities a ON a.prd_id=p.id GROUP BY p.id
|
|
221
|
+
SELECT task_count, rework_run_count FROM vw_macro_classification WHERE entity_kind='prd'
|
|
263
222
|
), counts AS (
|
|
264
223
|
SELECT CASE WHEN rework_run_count>0 THEN 'rework' WHEN task_count>0 THEN 'structured' ELSE 'empty' END AS classification,
|
|
265
224
|
COUNT(*) AS entity_count
|
package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-schema-macro-classification.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Structural membership exists before a Task has any Run.
|
|
2
|
+
// Keep drafts in known_tasks to suppress historical fallback, then filter
|
|
3
|
+
// structural links. Materialization avoids repeated JSON payload scans.
|
|
4
|
+
export const macroClassificationSql = `CREATE VIEW vw_macro_classification AS
|
|
5
|
+
WITH known_tasks AS MATERIALIZED (SELECT id, status, spec_id, change_id FROM canonical_work_items WHERE entity_kind='task'),
|
|
6
|
+
canonical_tasks AS (SELECT * FROM known_tasks WHERE status<>'draft'),
|
|
7
|
+
task_change_links AS MATERIALIZED (
|
|
8
|
+
SELECT t.id AS task_id, COALESCE(c.source_spec_id, CASE WHEN c.source_type='spec' THEN c.source_id END) AS spec_id,
|
|
9
|
+
COALESCE(c.source_prd_id, CASE WHEN c.source_type='prd' THEN c.source_id END) AS prd_id FROM canonical_tasks t JOIN canonical_changes c ON t.change_id=c.id
|
|
10
|
+
UNION
|
|
11
|
+
SELECT t.id, COALESCE(c.source_spec_id, CASE WHEN c.source_type='spec' THEN c.source_id END),
|
|
12
|
+
COALESCE(c.source_prd_id, CASE WHEN c.source_type='prd' THEN c.source_id END) FROM canonical_changes c CROSS JOIN json_each(c.task_ids_json) j JOIN canonical_tasks t ON t.id=j.value
|
|
13
|
+
), task_links AS (
|
|
14
|
+
SELECT 'spec' AS entity_kind, t.spec_id AS entity_id, t.id AS task_id FROM canonical_tasks t WHERE t.spec_id IS NOT NULL
|
|
15
|
+
UNION
|
|
16
|
+
SELECT 'spec', spec_id, task_id FROM task_change_links
|
|
17
|
+
UNION
|
|
18
|
+
SELECT 'prd', prd_id, task_id FROM task_change_links
|
|
19
|
+
UNION
|
|
20
|
+
SELECT 'prd', s.prd_id, t.id FROM canonical_tasks t
|
|
21
|
+
LEFT JOIN task_change_links l ON l.task_id=t.id
|
|
22
|
+
JOIN canonical_work_items s ON s.entity_kind='spec' AND s.id=COALESCE(t.spec_id,l.spec_id)
|
|
23
|
+
WHERE s.prd_id IS NOT NULL AND l.prd_id IS NULL
|
|
24
|
+
UNION
|
|
25
|
+
SELECT 'spec', spec_id, task_id FROM activities a WHERE spec_id IS NOT NULL AND task_id IS NOT NULL
|
|
26
|
+
AND NOT EXISTS (SELECT 1 FROM known_tasks t WHERE t.id=a.task_id)
|
|
27
|
+
UNION
|
|
28
|
+
SELECT 'prd', prd_id, task_id FROM activities a WHERE prd_id IS NOT NULL AND task_id IS NOT NULL
|
|
29
|
+
AND NOT EXISTS (SELECT 1 FROM known_tasks t WHERE t.id=a.task_id)
|
|
30
|
+
), tasks AS (
|
|
31
|
+
SELECT l.entity_kind, l.entity_id, COUNT(DISTINCT l.task_id) AS task_count,
|
|
32
|
+
json_group_array(DISTINCT l.task_id) AS task_ids_json,
|
|
33
|
+
COUNT(DISTINCT CASE WHEN t.status='completed' THEN l.task_id END) AS completed_task_count
|
|
34
|
+
FROM task_links l LEFT JOIN known_tasks t ON t.id=l.task_id
|
|
35
|
+
GROUP BY l.entity_kind, l.entity_id
|
|
36
|
+
), rework AS (
|
|
37
|
+
SELECT 'spec' AS entity_kind, spec_id AS entity_id, COUNT(*) AS rework_run_count
|
|
38
|
+
FROM activities WHERE spec_id IS NOT NULL AND work_type='rework' AND run_role='root' GROUP BY spec_id
|
|
39
|
+
UNION ALL
|
|
40
|
+
SELECT 'prd', prd_id, COUNT(*) FROM activities
|
|
41
|
+
WHERE prd_id IS NOT NULL AND work_type='rework' AND run_role='root' GROUP BY prd_id
|
|
42
|
+
)
|
|
43
|
+
SELECT w.entity_kind, w.id AS entity_id, COALESCE(t.task_count, 0) AS task_count,
|
|
44
|
+
COALESCE(r.rework_run_count, 0) AS rework_run_count,
|
|
45
|
+
COALESCE(t.task_ids_json, '[]') AS task_ids_json, COALESCE(t.completed_task_count, 0) AS completed_task_count
|
|
46
|
+
FROM work_items w LEFT JOIN tasks t ON t.entity_kind=w.entity_kind AND t.entity_id=w.id
|
|
47
|
+
LEFT JOIN rework r ON r.entity_kind=w.entity_kind AND r.entity_id=w.id
|
|
48
|
+
WHERE w.entity_kind IN ('spec','prd');`;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function encodeSummaryCursor(occurredAt: string, id: string): string {
|
|
2
|
+
return encodeURIComponent(JSON.stringify([occurredAt, id]));
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function parseSummaryCursor(cursor: string | null): [string, string] | null {
|
|
6
|
+
if (cursor === null) return null;
|
|
7
|
+
try {
|
|
8
|
+
const parsed = JSON.parse(decodeURIComponent(cursor));
|
|
9
|
+
return Array.isArray(parsed) && typeof parsed[0] === "string" && typeof parsed[1] === "string"
|
|
10
|
+
? [parsed[0], parsed[1]]
|
|
11
|
+
: null;
|
|
12
|
+
} catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-token-active-allocation.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { saoPauloDay } from "./sqlite-calendar.js";
|
|
2
|
+
|
|
3
|
+
export type TemporalInterval = { activityRowId: string; startMs: number; endMs: number };
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Splits every observed interval at every activity boundary and São Paulo day
|
|
7
|
+
* boundary. Each elementary segment is divided equally among the token-active
|
|
8
|
+
* activities covering it, making the materialized fact additive by activity,
|
|
9
|
+
* day, and every parent dimension.
|
|
10
|
+
*/
|
|
11
|
+
export function allocateAttributedTokenActiveMs(intervals: readonly TemporalInterval[]) {
|
|
12
|
+
const boundaries = new Set<number>();
|
|
13
|
+
for (const interval of intervals) {
|
|
14
|
+
boundaries.add(interval.startMs);
|
|
15
|
+
boundaries.add(interval.endMs);
|
|
16
|
+
for (let cursor = interval.startMs; cursor < interval.endMs; ) {
|
|
17
|
+
const nextDay =
|
|
18
|
+
Date.parse(`${saoPauloDay(new Date(cursor).toISOString())}T03:00:00.000Z`) + 86_400_000;
|
|
19
|
+
if (nextDay >= interval.endMs) break;
|
|
20
|
+
boundaries.add(nextDay);
|
|
21
|
+
cursor = nextDay;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const points = [...boundaries].sort((left, right) => left - right);
|
|
25
|
+
const allocated = new Map<string, { activityRowId: string; day: string; value: number }>();
|
|
26
|
+
for (let index = 0; index < points.length - 1; index += 1) {
|
|
27
|
+
const startMs = points[index]!;
|
|
28
|
+
const endMs = points[index + 1]!;
|
|
29
|
+
const active = intervals.filter(
|
|
30
|
+
(interval) => interval.startMs < endMs && interval.endMs > startMs,
|
|
31
|
+
);
|
|
32
|
+
if (active.length === 0 || endMs <= startMs) continue;
|
|
33
|
+
const share = (endMs - startMs) / active.length;
|
|
34
|
+
const day = saoPauloDay(new Date(startMs).toISOString());
|
|
35
|
+
for (const interval of active) {
|
|
36
|
+
const key = `${interval.activityRowId}:${day}`;
|
|
37
|
+
const previous = allocated.get(key);
|
|
38
|
+
allocated.set(key, {
|
|
39
|
+
activityRowId: interval.activityRowId,
|
|
40
|
+
day,
|
|
41
|
+
value: (previous?.value ?? 0) + share,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return [...allocated.values()];
|
|
46
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { CanonicalChange, CanonicalEntity } from "./sqlite-read-model-canonical.js";
|
|
2
|
+
|
|
3
|
+
/** Derive display stages from persisted lifecycle facts, never from live invocation guesses. */
|
|
4
|
+
export function deriveCanonicalWorkStages(
|
|
5
|
+
entities: Map<string, CanonicalEntity>,
|
|
6
|
+
changes: readonly CanonicalChange[],
|
|
7
|
+
): void {
|
|
8
|
+
const children = new Map<string, Set<string>>();
|
|
9
|
+
const changesById = new Map(changes.map((change) => [change.id, change]));
|
|
10
|
+
const changesByTask = new Map<string, CanonicalChange>();
|
|
11
|
+
for (const change of changes)
|
|
12
|
+
for (const taskId of change.taskIds) {
|
|
13
|
+
if (!changesByTask.has(taskId)) changesByTask.set(taskId, change);
|
|
14
|
+
}
|
|
15
|
+
const link = (kind: string, id: string | null, taskId: string) => {
|
|
16
|
+
if (id === null) return;
|
|
17
|
+
const key = `${kind}:${id}`;
|
|
18
|
+
const ids = children.get(key) ?? new Set<string>();
|
|
19
|
+
ids.add(taskId);
|
|
20
|
+
children.set(key, ids);
|
|
21
|
+
};
|
|
22
|
+
for (const task of entities.values()) {
|
|
23
|
+
if (task.kind !== "task" || task.status === "draft") continue;
|
|
24
|
+
const change = changesById.get(task.changeId ?? "") ?? changesByTask.get(task.id);
|
|
25
|
+
const specId =
|
|
26
|
+
task.specId ??
|
|
27
|
+
change?.sourceSpecId ??
|
|
28
|
+
(change?.sourceType === "spec" ? change.sourceId : null);
|
|
29
|
+
const prdId =
|
|
30
|
+
change?.sourcePrdId ??
|
|
31
|
+
(change?.sourceType === "prd" ? change.sourceId : null) ??
|
|
32
|
+
(specId ? (entities.get(`spec:${specId}`)?.prdId ?? null) : null);
|
|
33
|
+
link("spec", specId, task.id);
|
|
34
|
+
link("prd", prdId, task.id);
|
|
35
|
+
}
|
|
36
|
+
for (const entity of entities.values()) {
|
|
37
|
+
if (entity.kind !== "spec" && entity.kind !== "prd") continue;
|
|
38
|
+
const status = entity.status;
|
|
39
|
+
if (status === "delivered" || status === "completed") entity.stage = "completed";
|
|
40
|
+
else if (
|
|
41
|
+
status === "blocked" ||
|
|
42
|
+
status === "failed" ||
|
|
43
|
+
status === "cancelled" ||
|
|
44
|
+
status === "ready" ||
|
|
45
|
+
status === "verifying"
|
|
46
|
+
)
|
|
47
|
+
entity.stage = status;
|
|
48
|
+
else if (status === "draft") entity.stage = entity.kind === "prd" ? "definition" : "planning";
|
|
49
|
+
else if (status === "active" || status === "executing") {
|
|
50
|
+
const tasks = [...(children.get(`${entity.kind}:${entity.id}`) ?? [])].map((id) =>
|
|
51
|
+
entities.get(`task:${id}`),
|
|
52
|
+
);
|
|
53
|
+
entity.stage =
|
|
54
|
+
tasks.length > 0 &&
|
|
55
|
+
tasks.every((t) => t?.status === "verifying" || t?.status === "completed")
|
|
56
|
+
? "verifying"
|
|
57
|
+
: "executing";
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -2,6 +2,7 @@ export async function collectPreviousDashboardSessions({
|
|
|
2
2
|
candidateSessionPath,
|
|
3
3
|
candidateRegistryPath,
|
|
4
4
|
probe,
|
|
5
|
+
inspectOwnership,
|
|
5
6
|
readDashboardSession,
|
|
6
7
|
readPortRegistry,
|
|
7
8
|
workspaceRoot,
|
|
@@ -34,7 +35,10 @@ export async function collectPreviousDashboardSessions({
|
|
|
34
35
|
}
|
|
35
36
|
const reachable = await Promise.all(
|
|
36
37
|
[...latestByPort.values()].map(async (candidate) =>
|
|
37
|
-
(await probe(candidate.port))
|
|
38
|
+
(await probe(candidate.port)) &&
|
|
39
|
+
(await inspectOwnership(candidate, { workspaceRoot, workspaceKey }))
|
|
40
|
+
? candidate
|
|
41
|
+
: null,
|
|
38
42
|
),
|
|
39
43
|
);
|
|
40
44
|
return reachable.filter(Boolean);
|
package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-launch-claims.test.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
host,
|
|
8
8
|
requestBackgroundProjectionRefresh,
|
|
9
9
|
workspaceKey,
|
|
10
|
+
workspaceRoot,
|
|
10
11
|
} from "./start-dashboard.mjs";
|
|
11
12
|
|
|
12
13
|
const temporaryDirectories = [];
|
|
@@ -23,7 +24,12 @@ describe("dashboard launch claims", () => {
|
|
|
23
24
|
const path = join(directory, "dashboard-launch.json");
|
|
24
25
|
await writeFile(
|
|
25
26
|
path,
|
|
26
|
-
JSON.stringify({
|
|
27
|
+
JSON.stringify({
|
|
28
|
+
kind: "zaip-dashboard-sqlite-launch",
|
|
29
|
+
workspaceKey,
|
|
30
|
+
workspace: workspaceRoot,
|
|
31
|
+
launcherPid: 1234,
|
|
32
|
+
}),
|
|
27
33
|
);
|
|
28
34
|
const stops = [];
|
|
29
35
|
await expect(
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import { createServer as createHttpServer } from "node:http";
|
|
2
|
+
import { basename } from "node:path";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
const escapeHtml = (text) =>
|
|
5
|
+
String(text).replace(
|
|
6
|
+
/[&<>"']/g,
|
|
7
|
+
(character) =>
|
|
8
|
+
({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[character],
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
export async function createDashboardLaunchPage({
|
|
12
|
+
port,
|
|
13
|
+
host,
|
|
14
|
+
runtimeKind,
|
|
15
|
+
healthPath,
|
|
16
|
+
delay,
|
|
17
|
+
workspaceRoot = "",
|
|
18
|
+
}) {
|
|
4
19
|
let redirectUrl = null;
|
|
5
20
|
let failure = null;
|
|
6
21
|
let progress = {
|
|
@@ -81,7 +96,7 @@ export async function createDashboardLaunchPage({ port, host, runtimeKind, healt
|
|
|
81
96
|
</head>
|
|
82
97
|
<body>
|
|
83
98
|
<main class="launch-overlay" aria-label="Preparando dashboard" aria-busy="true">
|
|
84
|
-
<section class="progress" aria-live="polite" role="status"><strong id="phase">Iniciando o launcher local</strong><span id="detail">Abrindo a página de preparação.</span><span class="activity" id="activity" aria-hidden="true">Atividade em andamento.</span><div class="track" id="track" role="progressbar" aria-label="Preparação em andamento" aria-valuemin="0" aria-valuemax="100" aria-valuenow="4" aria-valuetext="Iniciando o launcher local"><div class="bar" id="bar"></div></div><ol class="steps" id="steps" aria-label="Etapas de preparação"><li data-state="active">Iniciando o launcher local</li></ol><span class="handoff" id="handoff">O dashboard está pronto. Abrindo a tela principal automaticamente…</span><span class="failure" id="failure" role="alert"></span></section>
|
|
99
|
+
<section class="progress" aria-live="polite" role="status"><div aria-label="Workspace" style="margin-bottom:20px;overflow-wrap:anywhere"><strong>${escapeHtml(basename(workspaceRoot))}</strong><span>${escapeHtml(workspaceRoot)}</span></div><strong id="phase">Iniciando o launcher local</strong><span id="detail">Abrindo a página de preparação.</span><span class="activity" id="activity" aria-hidden="true">Atividade em andamento.</span><div class="track" id="track" role="progressbar" aria-label="Preparação em andamento" aria-valuemin="0" aria-valuemax="100" aria-valuenow="4" aria-valuetext="Iniciando o launcher local"><div class="bar" id="bar"></div></div><ol class="steps" id="steps" aria-label="Etapas de preparação"><li data-state="active">Iniciando o launcher local</li></ol><span class="handoff" id="handoff">O dashboard está pronto. Abrindo a tela principal automaticamente…</span><span class="failure" id="failure" role="alert"></span></section>
|
|
85
100
|
</main>
|
|
86
101
|
<script>
|
|
87
102
|
let handoffTarget=null,progressRequestInFlight=false,terminalFailure=false,lastProgressPercent=4,compilationStartedAt=null,compilationDetail="",compilationTicker=null,activeStepKey="",activeStepStartedAt=Date.now();
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { listeningProcessId, processCommandLine } from "./start-dashboard-processes.mjs";
|
|
3
|
+
|
|
4
|
+
const normalized = (value) =>
|
|
5
|
+
process.platform === "win32" ? resolve(value).toLowerCase() : resolve(value);
|
|
6
|
+
|
|
7
|
+
export function dashboardCommandMatches(command, workspace) {
|
|
8
|
+
if (typeof command !== "string" || typeof workspace !== "string") return false;
|
|
9
|
+
const args = [...command.matchAll(/"([^"]*)"|'([^']*)'|([^\s\0]+)/g)].map(
|
|
10
|
+
(match) => match[1] ?? match[2] ?? match[3],
|
|
11
|
+
);
|
|
12
|
+
const root = resolve(workspace, ".agents/dashboard/packages/local-runtime");
|
|
13
|
+
const expected = ["server.mjs", "dist/server.cjs", "dist/server.js"].map((file) =>
|
|
14
|
+
normalized(resolve(root, file)),
|
|
15
|
+
);
|
|
16
|
+
// Our launcher spawns Node with exactly one script argument. A foreign
|
|
17
|
+
// script mentioning the runtime path later in its arguments is not owned.
|
|
18
|
+
return typeof args[1] === "string" && expected.includes(normalized(args[1]));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** A recorded PID is only a hint. Prove the listener, executable and HTTP identity together. */
|
|
22
|
+
export async function inspectDashboardOwnership(
|
|
23
|
+
session,
|
|
24
|
+
{
|
|
25
|
+
workspaceRoot,
|
|
26
|
+
workspaceKey,
|
|
27
|
+
host = "127.0.0.1",
|
|
28
|
+
fetchImpl = fetch,
|
|
29
|
+
listeningProcessIdImpl = listeningProcessId,
|
|
30
|
+
processCommandLineImpl = processCommandLine,
|
|
31
|
+
} = {},
|
|
32
|
+
) {
|
|
33
|
+
if (
|
|
34
|
+
session?.workspace !== workspaceRoot ||
|
|
35
|
+
session?.workspaceKey !== workspaceKey ||
|
|
36
|
+
!Number.isInteger(session?.serverPid) ||
|
|
37
|
+
session.serverPid <= 0 ||
|
|
38
|
+
!Number.isInteger(session?.port) ||
|
|
39
|
+
session.port <= 0 ||
|
|
40
|
+
session.port > 65535
|
|
41
|
+
)
|
|
42
|
+
return null;
|
|
43
|
+
const listener = await listeningProcessIdImpl(session.port, host);
|
|
44
|
+
if (
|
|
45
|
+
listener !== session.serverPid ||
|
|
46
|
+
!dashboardCommandMatches(await processCommandLineImpl(listener), workspaceRoot)
|
|
47
|
+
)
|
|
48
|
+
return null;
|
|
49
|
+
try {
|
|
50
|
+
const response = await fetchImpl(`http://${host}:${session.port}/api/v2/health`, {
|
|
51
|
+
signal: AbortSignal.timeout(1500),
|
|
52
|
+
});
|
|
53
|
+
const health = await response.json();
|
|
54
|
+
if (
|
|
55
|
+
health?.kind !== "zaip-dashboard-sqlite-runtime" ||
|
|
56
|
+
health.workspaceKey !== workspaceKey ||
|
|
57
|
+
health.workspace !== workspaceRoot ||
|
|
58
|
+
health.server_pid !== listener
|
|
59
|
+
)
|
|
60
|
+
return null;
|
|
61
|
+
return health;
|
|
62
|
+
} catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import {
|
|
4
|
+
dashboardCommandMatches,
|
|
5
|
+
inspectDashboardOwnership,
|
|
6
|
+
} from "./start-dashboard-ownership.mjs";
|
|
7
|
+
import { stopOwnedDashboardProcess } from "./start-dashboard-processes.mjs";
|
|
8
|
+
|
|
9
|
+
const workspace = resolve("fixture dashboard");
|
|
10
|
+
const command = `node "${resolve(workspace, ".agents/dashboard/packages/local-runtime/dist/server.cjs")}"`;
|
|
11
|
+
const session = { workspace, workspaceKey: "key", serverPid: 12345, rootPid: 111, port: 4417 };
|
|
12
|
+
const health = {
|
|
13
|
+
kind: "zaip-dashboard-sqlite-runtime",
|
|
14
|
+
workspace,
|
|
15
|
+
workspaceKey: "key",
|
|
16
|
+
server_pid: 12345,
|
|
17
|
+
};
|
|
18
|
+
const options = {
|
|
19
|
+
workspaceRoot: workspace,
|
|
20
|
+
workspaceKey: "key",
|
|
21
|
+
listeningProcessIdImpl: async () => 12345,
|
|
22
|
+
processCommandLineImpl: async () => command,
|
|
23
|
+
fetchImpl: async () => new Response(JSON.stringify(health)),
|
|
24
|
+
};
|
|
25
|
+
describe("dashboard ownership", () => {
|
|
26
|
+
it("requires an exact runtime argument including workspaces containing spaces", () => {
|
|
27
|
+
expect(dashboardCommandMatches(command, workspace)).toBe(true);
|
|
28
|
+
expect(
|
|
29
|
+
dashboardCommandMatches(
|
|
30
|
+
`node unrelated.js "${resolve(workspace, ".agents/dashboard/packages/local-runtime/dist/server.cjs")}"`,
|
|
31
|
+
workspace,
|
|
32
|
+
),
|
|
33
|
+
).toBe(false);
|
|
34
|
+
expect(dashboardCommandMatches(command + ".foreign", workspace + "-other")).toBe(false);
|
|
35
|
+
expect(dashboardCommandMatches(`node "${workspace}/unrelated.js"`, workspace)).toBe(false);
|
|
36
|
+
});
|
|
37
|
+
it("accepts a live owned server even while degraded", async () => {
|
|
38
|
+
expect(
|
|
39
|
+
await inspectDashboardOwnership(session, {
|
|
40
|
+
...options,
|
|
41
|
+
fetchImpl: async () =>
|
|
42
|
+
new Response(JSON.stringify({ ...health, status: "degraded" }), { status: 503 }),
|
|
43
|
+
}),
|
|
44
|
+
).toMatchObject(health);
|
|
45
|
+
});
|
|
46
|
+
it.each([
|
|
47
|
+
{ listeningProcessIdImpl: async () => 999 },
|
|
48
|
+
{ processCommandLineImpl: async () => "node unrelated.js" },
|
|
49
|
+
{
|
|
50
|
+
fetchImpl: async () =>
|
|
51
|
+
new Response(JSON.stringify({ ...health, workspace: workspace + "-other" })),
|
|
52
|
+
},
|
|
53
|
+
{ fetchImpl: async () => new Response(JSON.stringify({ ...health, server_pid: 999 })) },
|
|
54
|
+
{ fetchImpl: async () => new Response(JSON.stringify({ ...health, workspaceKey: "other" })) },
|
|
55
|
+
])("rejects mismatched evidence %#", async (override) => {
|
|
56
|
+
expect(await inspectDashboardOwnership(session, { ...options, ...override })).toBeNull();
|
|
57
|
+
});
|
|
58
|
+
it("does not kill a reused PID that now listens on the same port", async () => {
|
|
59
|
+
const killed = [];
|
|
60
|
+
const result = await stopOwnedDashboardProcess(session, {
|
|
61
|
+
...options,
|
|
62
|
+
host: "127.0.0.1",
|
|
63
|
+
packageRoot: resolve(workspace, ".agents/dashboard/packages/local-runtime"),
|
|
64
|
+
probeDashboardPort: async () => true,
|
|
65
|
+
delay: async () => {},
|
|
66
|
+
processCommandLineImpl: async () => "node foreign-server.js",
|
|
67
|
+
stopProcessTreeImpl: async (pid) => killed.push(pid),
|
|
68
|
+
});
|
|
69
|
+
expect(result).toBe("skipped_unowned");
|
|
70
|
+
expect(killed).toEqual([]);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { resolve } from "node:path";
|
|
3
4
|
import process from "node:process";
|
|
5
|
+
import { inspectDashboardOwnership } from "./start-dashboard-ownership.mjs";
|
|
4
6
|
|
|
5
7
|
export function teardownWarning(status) {
|
|
6
8
|
return status === "close_failed";
|
|
@@ -23,10 +25,12 @@ export async function stopOwnedDashboardProcess(
|
|
|
23
25
|
fetchImpl,
|
|
24
26
|
host,
|
|
25
27
|
packageRoot,
|
|
28
|
+
workspaceRoot = resolve(packageRoot, "../../../.."),
|
|
26
29
|
delay,
|
|
27
30
|
listeningProcessIdImpl = listeningProcessId,
|
|
28
31
|
isProcessAliveImpl = isProcessAlive,
|
|
29
32
|
stopProcessTreeImpl = stopProcessTree,
|
|
33
|
+
processCommandLineImpl = processCommandLine,
|
|
30
34
|
},
|
|
31
35
|
) {
|
|
32
36
|
const initiallyReachable = await probeDashboardPort(
|
|
@@ -41,6 +45,15 @@ export async function stopOwnedDashboardProcess(
|
|
|
41
45
|
// a transient runtime response) can never be persisted as closed.
|
|
42
46
|
if (!initiallyReachable && listenerPid === null) return "closed";
|
|
43
47
|
if (!registeredListenerMatches(session, listenerPid)) return "skipped_unowned";
|
|
48
|
+
const ownershipOptions = {
|
|
49
|
+
workspaceRoot,
|
|
50
|
+
workspaceKey,
|
|
51
|
+
host,
|
|
52
|
+
fetchImpl,
|
|
53
|
+
listeningProcessIdImpl,
|
|
54
|
+
processCommandLineImpl,
|
|
55
|
+
};
|
|
56
|
+
if (!(await inspectDashboardOwnership(session, ownershipOptions))) return "skipped_unowned";
|
|
44
57
|
// The server PID is the ownership boundary. Killing the recorded launcher
|
|
45
58
|
// root with taskkill /t can also terminate a newly handed-off generation on
|
|
46
59
|
// Windows when the old launcher process tree is still being reaped. The
|
|
@@ -64,7 +77,11 @@ export async function stopOwnedDashboardProcess(
|
|
|
64
77
|
// Windows can report taskkill complete before the listener disappears.
|
|
65
78
|
// Retry only while the original registered server PID is still listening;
|
|
66
79
|
// a reused or foreign PID remains protected by the ownership check above.
|
|
67
|
-
if (
|
|
80
|
+
if (
|
|
81
|
+
listenerStillMatches &&
|
|
82
|
+
Date.now() - lastTeardownAttemptAt >= 500 &&
|
|
83
|
+
(await inspectDashboardOwnership(session, ownershipOptions))
|
|
84
|
+
) {
|
|
68
85
|
await stopProcessTreeImpl(session.serverPid);
|
|
69
86
|
if (rootIsKnownLauncher) await stopProcessTreeImpl(session.rootPid);
|
|
70
87
|
lastTeardownAttemptAt = Date.now();
|
|
@@ -88,17 +105,23 @@ export async function listeningProcessId(port, host = "127.0.0.1") {
|
|
|
88
105
|
|
|
89
106
|
export async function isKnownDashboardLauncher(pid, packageRoot) {
|
|
90
107
|
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
91
|
-
const command =
|
|
92
|
-
process.platform === "win32"
|
|
93
|
-
? await commandOutput("powershell.exe", [
|
|
94
|
-
"-NoProfile",
|
|
95
|
-
"-Command",
|
|
96
|
-
`(Get-CimInstance Win32_Process -Filter 'ProcessId=${pid}' -ErrorAction SilentlyContinue).CommandLine`,
|
|
97
|
-
])
|
|
98
|
-
: await readFile(`/proc/${pid}/cmdline`, "utf8").catch(() => "");
|
|
108
|
+
const command = await processCommandLine(pid);
|
|
99
109
|
return command.includes("start-dashboard") && command.includes(packageRoot);
|
|
100
110
|
}
|
|
101
111
|
|
|
112
|
+
export async function processCommandLine(pid) {
|
|
113
|
+
if (!Number.isInteger(pid) || pid <= 0) return "";
|
|
114
|
+
return process.platform === "win32"
|
|
115
|
+
? await commandOutput("powershell.exe", [
|
|
116
|
+
"-NoProfile",
|
|
117
|
+
"-Command",
|
|
118
|
+
`(Get-CimInstance Win32_Process -Filter 'ProcessId=${pid}' -ErrorAction SilentlyContinue).CommandLine`,
|
|
119
|
+
])
|
|
120
|
+
: process.platform === "linux"
|
|
121
|
+
? await readFile(`/proc/${pid}/cmdline`, "utf8").catch(() => "")
|
|
122
|
+
: await commandOutput("ps", ["-p", String(pid), "-o", "command="]);
|
|
123
|
+
}
|
|
124
|
+
|
|
102
125
|
export async function isAncestorProcess(ancestorPid, descendantPid, parentOf = processParentId) {
|
|
103
126
|
if (!Number.isInteger(ancestorPid) || !Number.isInteger(descendantPid)) return false;
|
|
104
127
|
const visited = new Set();
|