@zaip-ai/cli 1.0.7 → 1.0.8
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/README.md +6 -4
- package/dist/services/adapters.d.ts +1 -1
- package/dist/services/adapters.d.ts.map +1 -1
- package/dist/services/adapters.js +15 -5
- package/dist/services/adapters.js.map +1 -1
- package/dist/services/adapters.test.js +1 -1
- package/dist/services/agent-adapters.d.ts +9 -0
- package/dist/services/agent-adapters.d.ts.map +1 -1
- package/dist/services/agent-adapters.js +38 -3
- package/dist/services/agent-adapters.js.map +1 -1
- package/dist/services/agent-adapters.test.js +8 -1
- package/dist/services/agent-adapters.test.js.map +1 -1
- package/dist/services/codex-config-template.d.ts +2 -1
- package/dist/services/codex-config-template.d.ts.map +1 -1
- package/dist/services/codex-config-template.js +13 -2
- package/dist/services/codex-config-template.js.map +1 -1
- package/dist/services/codex-rules.d.ts +1 -1
- package/dist/services/codex-rules.d.ts.map +1 -1
- package/dist/services/codex-rules.js +31 -7
- package/dist/services/codex-rules.js.map +1 -1
- package/dist/services/codex-subagent-hook-template.d.ts +1 -1
- package/dist/services/codex-subagent-hook-template.d.ts.map +1 -1
- package/dist/services/codex-subagent-hook-template.js +4 -1
- package/dist/services/codex-subagent-hook-template.js.map +1 -1
- package/dist/services/doctor.d.ts.map +1 -1
- package/dist/services/doctor.js +3 -1
- package/dist/services/doctor.js.map +1 -1
- package/dist/services/global-codex-config.d.ts +6 -3
- package/dist/services/global-codex-config.d.ts.map +1 -1
- package/dist/services/global-codex-config.js +82 -13
- package/dist/services/global-codex-config.js.map +1 -1
- package/dist/services/global-codex-config.test.js +57 -10
- package/dist/services/global-codex-config.test.js.map +1 -1
- package/dist/services/install-agents-template.d.ts.map +1 -1
- package/dist/services/install-agents-template.js +15 -2
- package/dist/services/install-agents-template.js.map +1 -1
- package/dist/services/logger.js +1 -1
- package/dist/services/logger.js.map +1 -1
- package/dist/services/logger.test.js +3 -3
- package/dist/services/logger.test.js.map +1 -1
- package/dist/services/runtime-template.test.js +21 -5
- package/dist/services/runtime-template.test.js.map +1 -1
- package/dist/services/template-manifest.d.ts.map +1 -1
- package/dist/services/template-manifest.js +2 -0
- package/dist/services/template-manifest.js.map +1 -1
- package/package.json +1 -1
- package/templates/.agents/config/agents/catalog.yaml +310 -10
- package/templates/.agents/config/clients/codex/agents/zaip-agent-brand-strategist.toml +30 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-designer.toml +5 -5
- package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-general-operations.toml +30 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-governance-compliance.toml +30 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-growth-strategist.toml +30 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-marketing-analyst.toml +8 -8
- package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +5 -3
- package/templates/.agents/config/clients/codex/agents/zaip-agent-sales-specialist.toml +30 -0
- package/templates/.agents/config/project.yaml +1 -1
- package/templates/.agents/dashboard/.zaip-managed.json +659 -163
- package/templates/.agents/dashboard/DATA-DICTIONARY.md +2227 -0
- package/templates/.agents/dashboard/README.md +48 -97
- package/templates/.agents/dashboard/apps/frontend/dist/assets/CostCalculationGuidePage-Z60df2r-.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-Cv-JcoxP.js → DashboardHelpDialog-Cs6dzDmW.js} +294 -109
- package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-Coc6pA-1.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-QE1k9yZB.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-_Pf5DA_A.js +3 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BVlz3DLZ.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-CaKwQP43.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-BZ5WdaMN.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Cf9ctPVt.js +68 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-C98LGC-Q.js → dashboard-localization-CLJ0lT9v.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/icons-vendor-DFBuc_qp.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8A4DcNXM.js +2 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DK_enB5Z.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/react-vendor-CCQOHdVI.js +9 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/rolldown-runtime-D9-fqq9M.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-DFY7ZDlu.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/traceability-pC2_0J8x.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +9 -2
- package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/App.tsx +952 -595
- package/templates/.agents/dashboard/apps/frontend/src/AppLoadingBoundary.tsx +48 -0
- package/templates/.agents/dashboard/apps/frontend/src/AppLoadingPanels.tsx +2 -0
- package/templates/.agents/dashboard/apps/frontend/src/AppOverlays.tsx +247 -0
- package/templates/.agents/dashboard/apps/frontend/src/AppRequestGuards.tsx +95 -0
- package/templates/.agents/dashboard/apps/frontend/src/AppSetupRoutes.tsx +87 -0
- package/templates/.agents/dashboard/apps/frontend/src/CostCalculationGuidePage.tsx +641 -0
- package/templates/.agents/dashboard/apps/frontend/src/DashboardAlternateContent.tsx +159 -0
- package/templates/.agents/dashboard/apps/frontend/src/DashboardCapabilityNav.tsx +13 -13
- package/templates/.agents/dashboard/apps/frontend/src/DashboardGlobalSettings.tsx +56 -0
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +257 -313
- package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +149 -0
- package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.test.ts +35 -0
- package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.tsx +111 -12
- package/templates/.agents/dashboard/apps/frontend/src/app-preferences.ts +15 -0
- package/templates/.agents/dashboard/apps/frontend/src/app-session-token.ts +20 -0
- package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.css +267 -0
- package/templates/.agents/dashboard/apps/frontend/src/cost-calculation-guide.test.ts +69 -0
- package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +70 -0
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +111 -0
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +432 -13
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-localization.ts +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/main.tsx +1 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-detail-hydration.test.ts +55 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-detail-hydration.ts +36 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.test.ts +126 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-entity-page-projection.ts +181 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-period-contract.test.ts +138 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-period-render.test.ts +105 -0
- package/templates/.agents/dashboard/apps/frontend/src/operations-period.test.ts +6 -3
- package/templates/.agents/dashboard/apps/frontend/src/operations-period.ts +9 -5
- package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +24 -0
- package/templates/.agents/dashboard/apps/frontend/src/period-transition-overlay.css +44 -0
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-model.ts +121 -62
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +471 -2
- package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +84 -17
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +44 -0
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +196 -39
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-notice.ts +15 -0
- package/templates/.agents/dashboard/apps/frontend/src/sqlite-cost-adapters.ts +26 -0
- package/templates/.agents/dashboard/apps/frontend/src/styles.css +14 -2
- package/templates/.agents/dashboard/apps/frontend/src/traceability-workspace.css +38 -2
- package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +187 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +190 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +121 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-operations-pages.ts +398 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-app-trace-documents.ts +141 -0
- package/templates/.agents/dashboard/apps/frontend/src/use-idle-cost-prefetch.ts +45 -0
- package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.test.ts +46 -0
- package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.ts +37 -0
- package/templates/.agents/dashboard/apps/frontend/vite.config.ts +55 -5
- package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/contracts.ts +47 -6
- package/templates/.agents/dashboard/modules/cost-monitor/src/duration-estimate.ts +13 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +64 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +275 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.test.ts +100 -15
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.tsx +131 -40
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostFilters.tsx +137 -19
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.test.ts +2 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.tsx +13 -10
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +303 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +226 -6
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +479 -402
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostSummary.tsx +5 -13
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +312 -72
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +373 -321
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.test.ts +17 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/MacroCostTable.tsx +25 -6
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-copy.ts +0 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-page-helpers.ts +17 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-responsive.css +6 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-row-filters.ts +123 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-summary.ts +8 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor-views.ts +32 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor.css +52 -14
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-table-presentation.ts +121 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/index.ts +3 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.test.ts +68 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +32 -5
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +108 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.test.ts +12 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +60 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +106 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.test.ts +2 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/aggregate.ts +5 -3
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-pricing-fallback.test.ts +53 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.basics.test.ts +34 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +168 -137
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.ts +188 -29
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +956 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +775 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-terminal-day.test.ts +95 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/index.ts +1 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/refactor-map-xr9l.json +61 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/task-cost-groups.test.ts +41 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/task-cost-groups.ts +55 -11
- package/templates/.agents/dashboard/modules/operations/package.json +2 -1
- package/templates/.agents/dashboard/modules/operations/src/contracts.ts +182 -0
- package/templates/.agents/dashboard/modules/operations/src/duration-population.test.ts +63 -1
- package/templates/.agents/dashboard/modules/operations/src/duration-population.ts +60 -5
- package/templates/.agents/dashboard/modules/operations/src/react/EntityDetailsDialog.tsx +14 -3
- package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.test.ts +44 -1
- package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +325 -18
- package/templates/.agents/dashboard/modules/operations/src/react/MacroPlanningDialog.tsx +1 -0
- package/templates/.agents/dashboard/modules/operations/src/react/OperationDateFilters.test.ts +9 -5
- package/templates/.agents/dashboard/modules/operations/src/react/OperationDateFilters.tsx +2 -2
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsMainContent.tsx +168 -0
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.helpers.tsx +95 -6
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +365 -14
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +532 -131
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +314 -358
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageNavigation.tsx +68 -0
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageOverview.tsx +169 -0
- package/templates/.agents/dashboard/modules/operations/src/react/PeriodSummaryTable.tsx +51 -8
- package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.test.tsx +32 -0
- package/templates/.agents/dashboard/modules/operations/src/react/PrdDocumentDialog.tsx +62 -6
- package/templates/.agents/dashboard/modules/operations/src/react/TaskBoard.test.ts +55 -0
- package/templates/.agents/dashboard/modules/operations/src/react/TaskBoard.tsx +27 -19
- package/templates/.agents/dashboard/modules/operations/src/react/TaskDetailsDialog.tsx +99 -42
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.priority.test.ts +19 -0
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.tsx +255 -34
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +163 -8
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +101 -68
- package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.test.ts +72 -1
- package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.ts +78 -16
- package/templates/.agents/dashboard/modules/operations/src/react/execution-metrics.ts +6 -4
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +50 -1
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +143 -9
- package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +29 -4
- package/templates/.agents/dashboard/modules/operations/src/react/macro-planning-dialog-content.css +49 -0
- package/templates/.agents/dashboard/modules/operations/src/react/macro-planning-dialog.css +93 -50
- package/templates/.agents/dashboard/modules/operations/src/react/manual-work-priority.test.ts +82 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.test.ts +29 -2
- package/templates/.agents/dashboard/modules/operations/src/react/operation-date-range.ts +22 -1
- package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.test.ts +77 -4
- package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.ts +65 -5
- package/templates/.agents/dashboard/modules/operations/src/react/operations-coverage-toast.test.ts +54 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-global-filters.test.ts +19 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +149 -12
- package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.status-cards.test.ts +27 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +136 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-period-scope.test.ts +160 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-period-scope.ts +47 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-query.ts +10 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-responsive.css +3 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-view-labels.ts +28 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operations-view-order.test.ts +24 -7
- package/templates/.agents/dashboard/modules/operations/src/react/operations.css +42 -0
- package/templates/.agents/dashboard/modules/operations/src/react/period-summary-population.test.ts +54 -0
- package/templates/.agents/dashboard/modules/operations/src/react/period-summary-population.ts +32 -0
- package/templates/.agents/dashboard/modules/operations/src/react/period-summary.test.ts +165 -6
- package/templates/.agents/dashboard/modules/operations/src/react/period-summary.ts +148 -6
- package/templates/.agents/dashboard/modules/operations/src/react/popup-localization.test.ts +1 -1
- package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.css +132 -0
- package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.css.test.ts +13 -0
- package/templates/.agents/dashboard/modules/operations/src/react/unified-work-board.header.test.ts +16 -0
- package/templates/.agents/dashboard/modules/operations/src/react/use-infinite-column.ts +11 -5
- package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +5 -3
- package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +4 -83
- package/templates/.agents/dashboard/modules/operations/src/server/build-operations-projection.test.ts +291 -15
- package/templates/.agents/dashboard/modules/operations/src/server/build-operations-projection.ts +182 -472
- package/templates/.agents/dashboard/modules/operations/src/server/canonical-compat.test.ts +40 -0
- package/templates/.agents/dashboard/modules/operations/src/server/canonical-compat.ts +19 -6
- package/templates/.agents/dashboard/modules/operations/src/server/canonical-run-projection.ts +31 -6
- package/templates/.agents/dashboard/modules/operations/src/server/daily-duration-projection.ts +220 -0
- package/templates/.agents/dashboard/modules/operations/src/server/execution-duration-projection.ts +28 -0
- package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.test.ts +27 -2
- package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.ts +22 -13
- package/templates/.agents/dashboard/modules/operations/src/server/filter.test.ts +3 -3
- package/templates/.agents/dashboard/modules/operations/src/server/filter.ts +7 -2
- package/templates/.agents/dashboard/modules/operations/src/server/index.ts +3 -0
- package/templates/.agents/dashboard/modules/operations/src/server/macro.ts +3 -12
- package/templates/.agents/dashboard/modules/operations/src/server/manifest-usage.ts +65 -0
- package/templates/.agents/dashboard/modules/operations/src/server/operations-projection-aggregates.ts +297 -0
- package/templates/.agents/dashboard/modules/operations/src/server/quick-daily-operations-projection.ts +324 -0
- package/templates/.agents/dashboard/modules/operations/src/server/quick-operations-projection.test.ts +505 -0
- package/templates/.agents/dashboard/modules/operations/src/server/quick-operations-projection.ts +609 -0
- package/templates/.agents/dashboard/modules/operations/src/server/runs.ts +18 -19
- package/templates/.agents/dashboard/modules/operations/src/work-board-model.ts +76 -0
- package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
- package/templates/.agents/dashboard/modules/traceability/src/server/build-task-trace.ts +3 -1
- package/templates/.agents/dashboard/packages/branding/package.json +1 -1
- package/templates/.agents/dashboard/packages/branding/src/index.ts +1 -1
- package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
- package/templates/.agents/dashboard/packages/contracts/src/index.ts +1 -0
- package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +1756 -0
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +1608 -0
- package/templates/.agents/dashboard/packages/local-runtime/package.json +8 -3
- package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-dashboard.mjs +12 -0
- package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +83 -0
- package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +28 -0
- package/templates/.agents/dashboard/packages/local-runtime/scripts/test-sqlite-read-model.mjs +262 -0
- package/templates/.agents/dashboard/packages/local-runtime/scripts/test-unix-launchers.mjs +41 -0
- package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +105 -0
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +1643 -107
- package/templates/.agents/dashboard/packages/local-runtime/src/agent-adapter-sync.ts +30 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.test.ts +3 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/agent-catalog-settings.ts +5 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/manifest-runs.ts +72 -33
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +335 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +392 -1
- package/templates/.agents/dashboard/packages/local-runtime/src/runtime.mjs +5 -5
- package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +71 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-board.ts +179 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-cross-layer-parity.test.ts +245 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models-route.ts +64 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models.test.ts +204 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-daily-read-models.ts +194 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.test.ts +163 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-pages.ts +354 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.test.ts +74 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-operations-runs-route.ts +113 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-overview.test.ts +68 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-period.ts +47 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-projections.ts +483 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server-settings.test.ts +5 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +163 -84
- package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +145 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +551 -266
- package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +1145 -308
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.test.ts +53 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.ts +708 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +2232 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +6151 -0
- package/templates/.agents/dashboard/packages/local-runtime/src/work-priority-contract.test.ts +33 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-history.mjs +41 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard-processes.mjs +210 -0
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +437 -190
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +299 -24
- package/templates/.agents/dashboard/packages/ui/package.json +1 -1
- package/templates/.agents/dashboard/packages/windows-launcher/LauncherVerificationBehaviorTests.cs +206 -0
- package/templates/.agents/dashboard/packages/windows-launcher/Program.cs +95 -8
- package/templates/.agents/dashboard/packages/windows-launcher/build-dashboard-launcher.ps1 +2 -2
- package/templates/.agents/dashboard/packages/windows-launcher/run-launcher-verification-tests.ps1 +22 -0
- package/templates/.agents/dashboard/read-model.dbml +2201 -0
- package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
- package/templates/.agents/dashboard/tests/e2e/playwright.config.ts +1 -1
- package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +214 -41
- package/templates/.agents/dashboard/work-priority.json +34 -0
- package/templates/.agents/dashboard/zaip-dashboard-linux.sh +45 -0
- package/templates/.agents/dashboard/zaip-dashboard-mac.command +3 -0
- package/templates/.agents/dashboard/zaip-dashboard-windows.exe +0 -0
- package/templates/.agents/design/.zaip-managed.json +3 -3
- package/templates/.agents/design/apps/catalog/package.json +1 -1
- package/templates/.agents/design/packages/local-runtime/package.json +1 -1
- package/templates/.agents/requirements/autonomous-assurance.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 +24 -0
- 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 +4 -3
- package/templates/.agents/requirements/model-orchestration.md +1 -1
- package/templates/.agents/requirements/public-distribution.md +9 -6
- 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 +9 -3
- package/templates/.agents/requirements/zaip-strategic-95.md +4 -4
- package/templates/.agents/rules/autonomy-decision.md +15 -0
- package/templates/.agents/rules/core.md +1 -1
- package/templates/.agents/rules/run-lifecycle-closure.md +1 -1
- package/templates/.agents/rules/specialist-routing.md +19 -0
- package/templates/.agents/rules/workflow.md +1 -1
- package/templates/.agents/runtime/VERSION +1 -1
- package/templates/.agents/runtime/bin/zaip.mjs +114 -64
- package/templates/.agents/runtime/checksums.sha256 +6 -4
- package/templates/.agents/runtime/manifest.json +3 -1
- package/templates/.agents/runtime/pnpm-lock.sha256 +1 -0
- package/templates/.agents/runtime/provenance.json +11 -0
- package/templates/.agents/runtime/sbom.cdx.json +1929 -39
- package/templates/.agents/skills/zaip-aios/SKILL.md +1 -1
- package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +15 -0
- package/templates/.agents/skills/zaip-skill-brand-governance/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-standards.md +30 -0
- package/templates/.agents/skills/zaip-skill-dashboard-sqlite/SKILL.md +25 -0
- package/templates/.agents/skills/zaip-skill-dashboard-sqlite/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/SKILL.md +18 -0
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/agents/openai.yaml +6 -0
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.mjs +71 -0
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/ready-queue-fence.test.mjs +60 -0
- package/templates/.agents/skills/zaip-skill-executar-fila-pronta/scripts/scheduled-ready-queue-contract.test.mjs +111 -0
- package/templates/.agents/skills/zaip-skill-execution/SKILL.md +2 -2
- package/templates/.agents/skills/zaip-skill-frontend-launcher/references/launcher-contract.md +3 -1
- package/templates/.agents/skills/zaip-skill-general-operations/SKILL.md +12 -0
- package/templates/.agents/skills/zaip-skill-general-operations/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-github-deploy/SKILL.md +9 -7
- package/templates/.agents/skills/zaip-skill-github-deploy/agents/openai.yaml +2 -2
- package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +11 -38
- package/templates/.agents/skills/zaip-skill-governance-compliance/SKILL.md +12 -0
- package/templates/.agents/skills/zaip-skill-governance-compliance/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +15 -0
- package/templates/.agents/skills/zaip-skill-growth-strategy-revops/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-growth-strategy-revops/references/growth-revops-framework.md +25 -0
- package/templates/.agents/skills/zaip-skill-instalar-agendamento/SKILL.md +17 -0
- package/templates/.agents/skills/zaip-skill-instalar-agendamento/agents/openai.yaml +6 -0
- package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +3 -3
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +76 -27
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +128 -24
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +122 -4
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +66 -19
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +193 -7
- package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +14 -0
- package/templates/.agents/skills/zaip-skill-sales-methodology/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-sales-methodology/references/sales-process-framework.md +77 -0
- package/templates/.agents/skills/zaip-skill-setup/SKILL.md +5 -0
- package/templates/.agents/skills/zaip-skill-sqlite-read-model/SKILL.md +96 -0
- package/templates/.agents/skills/zaip-skill-sqlite-read-model/agents/openai.yaml +4 -0
- package/templates/.agents/skills/zaip-skill-sqlite-read-model/scripts/ensure-node.mjs +18 -0
- package/templates/.agents/zaip-aios/INDEX.md +1 -0
- package/templates/.agents/zaip-aios/README.md +37 -8
- package/templates/.agents/zaip-aios/VERSION +1 -1
- package/templates/.agents/zaip-aios/guides/09-agentes-e-squads.md +43 -6
- package/templates/.agents/zaip-aios/guides/10-seguranca.md +21 -7
- package/templates/.agents/zaip-aios/guides/17-como-o-custo-e-calculado.md +32 -0
- package/templates/template-manifest.json +945 -214
- package/templates/.agents/dashboard/apps/frontend/dist/assets/AgentCatalogSettingsPage-CLYIi7Vo.js +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/AgentCatalogSettingsPage-DTDNVQGX.css +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/PricingSettingsDialog-CzEggcRb.js +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-05YKn6Z4.js +0 -3
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-YO3yqtgV.css +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8AzCnl3a.js +0 -77
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-DdBYQ_8D.css +0 -1
- package/templates/.agents/dashboard/apps/frontend/src/AgentCatalogSettingsPage.tsx +0 -617
- package/templates/.agents/dashboard/apps/frontend/src/agent-catalog-settings-page.css +0 -660
- package/templates/.agents/dashboard/apps/frontend/src/agent-catalog-settings.test.ts +0 -249
- package/templates/.agents/dashboard/dashboard.config.json +0 -4
- package/templates/.agents/dashboard/zaip-dashboard.exe +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Framework de Growth e RevOps
|
|
2
|
+
|
|
3
|
+
Use o framework para orientar decisões, não para substituir evidência por estimativas.
|
|
4
|
+
|
|
5
|
+
## Diagnóstico
|
|
6
|
+
|
|
7
|
+
Defina uma árvore de métricas: objetivo de negócio, métricas de resultado, drivers, guardrails, definição, origem, proprietário e período. Defina a unidade de análise, janela temporal, população, funil, métricas e fontes. Verifique cobertura, duplicidade, atrasos de atribuição, mudanças de definição e viés de seleção antes de comparar períodos ou segmentos.
|
|
8
|
+
|
|
9
|
+
Para RevOps, registre estágios, critérios de entrada e saída, handoffs, SLA, responsável e system of record de marketing, vendas, onboarding, suporte, retenção e expansão. Uma lacuna de source of truth deve aparecer como risco operacional, não ser conciliada por suposição.
|
|
10
|
+
|
|
11
|
+
## Experimentos
|
|
12
|
+
|
|
13
|
+
Mantenha um portfólio de experimentos com hipótese, alavanca, população elegível, controle ou comparação, métrica primária, guardrails, duração, critério de parada, decisão esperada, risco, dependências, proprietário e status. Um resultado indisponível ou inconclusivo deve permanecer inconclusivo.
|
|
14
|
+
|
|
15
|
+
## Caso financeiro
|
|
16
|
+
|
|
17
|
+
Mostre cenários base, conservador e agressivo, com premissas, fórmula, intervalo e sensibilidade para receita incremental, custo evitado, margem, capacidade ou payback. Diferencie potencial, cenário e resultado observado; somente resultado observado pode ser declarado como realizado.
|
|
18
|
+
|
|
19
|
+
## Aprendizado histórico
|
|
20
|
+
|
|
21
|
+
Registre hipótese, execução, resultado, decisão, contexto, limitação e reutilização recomendada. Use resultados anteriores comprovados como evidência condicionada ao contexto; não transforme um aprendizado histórico em regra universal.
|
|
22
|
+
|
|
23
|
+
## Fronteiras
|
|
24
|
+
|
|
25
|
+
Robert orienta a priorização estratégica de crescimento e RevOps. Gabi valida dados e métodos quantitativos. Sarah governa marca e posicionamento. Lúcia executa estratégia e ativos de marketing. Nenhuma dessas atividades autoriza abordagem comercial, mudança de preço, campanha, contratação ou publicação externa.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zaip-skill-instalar-agendamento
|
|
3
|
+
description: Install or update the native Codex hourly scheduler for the ready-work queue.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Instalar agendamento da fila pronta
|
|
7
|
+
|
|
8
|
+
Use esta skill somente quando a pessoa solicitar instalar, atualizar ou verificar o agendamento local da fila pronta. Ela configura o relógio; não inicia uma execução por conta própria.
|
|
9
|
+
|
|
10
|
+
1. Confirme que o repositório é ZAIP habilitado e que a automação nativa de tarefas agendadas do Codex Desktop está chamável, com capacidade `automation_update`. Pare com `blocked` se ela não estiver disponível. Nunca use o Agendador do Windows, um arquivo, Git ou uma promessa de execução futura como substituto.
|
|
11
|
+
2. Use `codex_app list_projects` para resolver o projeto Codex atual e seu checkout local real; não invente identificador, diretório ou contexto. Crie ou atualize, sem duplicar, a tarefa standalone de nome estável `ZAIP-AIOS - Fila Pronta Horária`: a cada hora, no minuto 0, em nova conversa no projeto resolvido. Ela abre uma única invocação com o prompt explícito `Ignore Automation memory and $CODEX_HOME. Start immediately by validating the repository and ready queue. First call codex_app set_thread_title without threadId, using America/Sao_Paulo local time in the exact format [YYYY-MM-DD-T-HH-mm] Tarefa Agendada; record a rename failure but continue the queue. Use $zaip-skill-executar-fila-pronta; this user-installed schedule authorizes only canonically ready/eligible items, never promotes draft or resumes blocked or failed work; respect the persisted manual order in .agents/dashboard/work-priority.json.`
|
|
12
|
+
3. Antes de gravar, valide o checkout: raiz Git existente, `.agents/config/project.yaml` com `zaip.enabled: true`, runtime ZAIP disponível e caminho absoluto sem credenciais. Falhe fechado se algum requisito faltar; não registre uma tarefa parcial.
|
|
13
|
+
4. Consulte `$CODEX_HOME/automations/*/automation.toml` somente em leitura, exclusivamente pelo nome estável para resolver identidade e deduplicação. É proibido criar, editar ou apagar TOML, ou usá-lo como fallback. Todas as visualizações e mutações da automação são exclusivamente por `codex_app automation_update`. Se houver mais de uma tarefa com esse nome, pare e reporte o conflito sem apagar nada. Se houver uma, inspecione seu ID, ação, agenda horária, nova conversa e diretório de trabalho e atualize-a; se não houver, crie uma. Preserve tarefas agendadas fora desse nome.
|
|
14
|
+
5. Verifique após criar/atualizar que existe exatamente uma tarefa com o nome, agenda a cada hora no minuto 0, nova conversa, checkout esperado e prompt da skill executora que respeita `.agents/dashboard/work-priority.json`. Registre somente a evidência observada; não afirme que uma hora futura será executada.
|
|
15
|
+
6. Explique que o agendamento pertence à máquina e ao usuário que o instalou. O repositório versiona a skill e o contrato, mas não cria um relógio em clones, nem funciona com a máquina desligada, o Codex Desktop fechado ou sem a automação nativa.
|
|
16
|
+
|
|
17
|
+
Não use esta skill para selecionar itens, burlar bloqueios, executar todos os itens `planned`, alterar prioridades do Kanban ou fazer deploy/push.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "ZAIP Instalar Agendamento"
|
|
3
|
+
short_description: "Instale ou atualize o agendamento horário nativo do Codex."
|
|
4
|
+
default_prompt: "Use $zaip-skill-instalar-agendamento para instalar ou atualizar com segurança o agendamento horário nativo do Codex Desktop, com validação imediata da fila e sua ordem manual persistida."
|
|
5
|
+
policy:
|
|
6
|
+
allow_implicit_invocation: false
|
|
@@ -5,6 +5,6 @@ description: Plan evidence-grounded marketing strategy, copy, campaigns, assets,
|
|
|
5
5
|
|
|
6
6
|
# Planejar marketing
|
|
7
7
|
|
|
8
|
-
1. Delimitar público, objetivo, canal, mensagem, evidência disponível e métrica de sucesso.
|
|
9
|
-
2. Produzir estratégia, copy, campanha,
|
|
10
|
-
3. Encaminhar website para Jonny, frontend de produto para Doug e regra visual central para Manu
|
|
8
|
+
1. Delimitar público, objetivo, canal, mensagem, Brandbook aprovado como input somente-leitura, evidência disponível e métrica de sucesso.
|
|
9
|
+
2. Produzir estratégia, copy, campanha, conteúdo, aplicação de marca ou ativo proporcionais ao objetivo; distinguir fatos fornecidos de hipóteses. Copy de marketing ambígua permanece com Lúcia.
|
|
10
|
+
3. Escalar Sarah somente se uma decisão de marca estiver ausente, contraditória ou precisar ser criada; um Brandbook aprovado não redireciona a entrega para Branding. Encaminhar script voltado a vendas para Aaron, estratégia empresarial/RevOps para Robert, website para Jonny, frontend de produto para Doug e regra visual central para Manu.
|
|
@@ -3,9 +3,11 @@ import { join, resolve } from "node:path";
|
|
|
3
3
|
import {
|
|
4
4
|
aggregate,
|
|
5
5
|
duplicateUsageAssignments,
|
|
6
|
+
duplicateUsageImpact,
|
|
6
7
|
exactCompletedSegment,
|
|
7
8
|
filesUnder,
|
|
8
9
|
jsonLines,
|
|
10
|
+
isExactDuplicateUsageGroup,
|
|
9
11
|
loadSegments,
|
|
10
12
|
pricingFor,
|
|
11
13
|
recordOccurredAt,
|
|
@@ -14,9 +16,13 @@ import {
|
|
|
14
16
|
sameCost,
|
|
15
17
|
usageStatus,
|
|
16
18
|
usageView,
|
|
19
|
+
supersedableUsageBeforeTerminal,
|
|
17
20
|
withSequence,
|
|
18
21
|
} from "./reconcile-telemetry-lib.mjs";
|
|
19
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
remeasureSelectedRuns,
|
|
24
|
+
timingEnrichmentRunIds,
|
|
25
|
+
} from "./reconcile-telemetry-remeasurement.mjs";
|
|
20
26
|
|
|
21
27
|
const workspace = resolve(process.cwd());
|
|
22
28
|
const apply = process.argv.includes("--apply");
|
|
@@ -39,9 +45,21 @@ const selectedRunIds = new Set(
|
|
|
39
45
|
: [],
|
|
40
46
|
),
|
|
41
47
|
);
|
|
48
|
+
const selectedSessionFiles = process.argv
|
|
49
|
+
.flatMap((argument, index, values) =>
|
|
50
|
+
argument === "--session-file"
|
|
51
|
+
? [String(values[index + 1] ?? "")]
|
|
52
|
+
: argument.startsWith("--session-file=")
|
|
53
|
+
? [argument.slice("--session-file=".length)]
|
|
54
|
+
: [],
|
|
55
|
+
)
|
|
56
|
+
.filter(Boolean);
|
|
42
57
|
if (remeasure && selectedRunIds.size === 0) {
|
|
43
58
|
throw new Error("--remeasure requires at least one explicit --run <RUN-ID>");
|
|
44
59
|
}
|
|
60
|
+
if (apply && deduplicate && selectedRunIds.size === 0) {
|
|
61
|
+
throw new Error("--apply --deduplicate requires at least one explicit --run <RUN-ID>");
|
|
62
|
+
}
|
|
45
63
|
const applyBackfill = apply && !deduplicate && !remeasure;
|
|
46
64
|
|
|
47
65
|
const runFiles = await filesUnder(join(workspace, ".agents", "records", "runs"), ".jsonl");
|
|
@@ -166,20 +184,35 @@ for (const file of runFiles) {
|
|
|
166
184
|
if (event.source_segment_key && event.tokens?.total !== null)
|
|
167
185
|
usedKeys.add(event.source_segment_key);
|
|
168
186
|
const { measured, deduplicated } = usageStatus(usage);
|
|
169
|
-
if (started) runs.push({ file, records, started, usage, measured, deduplicated });
|
|
187
|
+
if (started) runs.push({ file, records, started, usage, measured, deduplicated, nativeMeasured });
|
|
170
188
|
}
|
|
171
189
|
|
|
172
|
-
const allSegments = await loadSegments(
|
|
173
|
-
|
|
174
|
-
?
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
190
|
+
const allSegments = await loadSegments(
|
|
191
|
+
workspace,
|
|
192
|
+
selectedSessionFiles.length === 0 ? null : selectedSessionFiles,
|
|
193
|
+
);
|
|
194
|
+
// Native usage can be captured before the Codex session emits task_complete.
|
|
195
|
+
// A normal backfill must not replace those observed tokens or costs, but it can
|
|
196
|
+
// append an exact, timing-only correction once that terminal boundary appears.
|
|
197
|
+
const timingRunIds = timingEnrichmentRunIds({
|
|
198
|
+
remeasure,
|
|
199
|
+
applyBackfill,
|
|
200
|
+
selectedRunIds,
|
|
201
|
+
runs,
|
|
202
|
+
});
|
|
203
|
+
const remeasurement =
|
|
204
|
+
remeasure || (applyBackfill && timingRunIds.size > 0)
|
|
205
|
+
? await remeasureSelectedRuns({
|
|
206
|
+
apply,
|
|
207
|
+
allSegments,
|
|
208
|
+
runs,
|
|
209
|
+
selectedRunIds: timingRunIds,
|
|
210
|
+
// Automatic backfill is intentionally timing-only. Explicit remeasurement
|
|
211
|
+
// retains its existing token/cost correction behavior unless requested.
|
|
212
|
+
timingOnly: remeasure ? timingOnly : true,
|
|
213
|
+
workspace,
|
|
214
|
+
})
|
|
215
|
+
: [];
|
|
183
216
|
const unfinished = runs.filter(
|
|
184
217
|
(run) => !run.records.some((record) => recordType(record) === "run.finished"),
|
|
185
218
|
);
|
|
@@ -351,7 +384,21 @@ for (const run of runs) {
|
|
|
351
384
|
}
|
|
352
385
|
|
|
353
386
|
const duplicateGroups = duplicateUsageAssignments(runs);
|
|
354
|
-
const
|
|
387
|
+
const exactDuplicateGroups = duplicateGroups.filter(isExactDuplicateUsageGroup);
|
|
388
|
+
const aliasReviewGroups = duplicateGroups.filter((group) => !isExactDuplicateUsageGroup(group));
|
|
389
|
+
const selectedDuplicateGroups = selectedRunIds.size === 0
|
|
390
|
+
? exactDuplicateGroups
|
|
391
|
+
: exactDuplicateGroups.filter((group) =>
|
|
392
|
+
group.some(({ run }) => selectedRunIds.has(run.started.run_id)),
|
|
393
|
+
);
|
|
394
|
+
const selectedAliasReviewGroups = selectedRunIds.size === 0
|
|
395
|
+
? aliasReviewGroups
|
|
396
|
+
: aliasReviewGroups.filter((group) =>
|
|
397
|
+
group.some(({ run }) => selectedRunIds.has(run.started.run_id)),
|
|
398
|
+
);
|
|
399
|
+
const duplicateAssignments = selectedDuplicateGroups.flatMap((group) =>
|
|
400
|
+
group.slice(1).filter(({ run }) => selectedRunIds.size === 0 || selectedRunIds.has(run.started.run_id)),
|
|
401
|
+
);
|
|
355
402
|
let deduplicatedEvents = 0;
|
|
356
403
|
if (apply && deduplicate) {
|
|
357
404
|
for (const { run, usage } of duplicateAssignments) {
|
|
@@ -600,26 +647,25 @@ const eligible = candidates.filter(
|
|
|
600
647
|
|
|
601
648
|
if (applyBackfill) {
|
|
602
649
|
for (const { run, segment, confidence } of eligible) {
|
|
650
|
+
// Re-read each Run under the serial apply loop: a preceding timing repair may
|
|
651
|
+
// have reordered or appended a correction after the initial scan.
|
|
652
|
+
const persistedRecords = jsonLines(await readFile(run.file, "utf8"));
|
|
653
|
+
const finishIndex = persistedRecords.findIndex((record) => recordType(record) === "run.finished");
|
|
654
|
+
const insertAt = finishIndex < 0 ? persistedRecords.length : finishIndex;
|
|
603
655
|
const tokens = aggregate(segment);
|
|
604
656
|
const model = segment.model ?? run.started.model ?? null;
|
|
605
657
|
const cost = await pricingFor(workspace, model, tokens);
|
|
606
|
-
const superseded =
|
|
607
|
-
|
|
608
|
-
.find(
|
|
609
|
-
(event) =>
|
|
610
|
-
event.tokens?.total === null &&
|
|
611
|
-
!run.usage.some((other) => other.supersedes_event_id === event.event_id),
|
|
612
|
-
);
|
|
613
|
-
const sequence = Math.max(...run.records.map((record) => recordSequence(record) ?? 0)) + 1;
|
|
658
|
+
const superseded = supersedableUsageBeforeTerminal(persistedRecords);
|
|
659
|
+
const sequence = Math.max(...persistedRecords.map((record) => recordSequence(record) ?? 0)) + 1;
|
|
614
660
|
const event = {
|
|
615
661
|
schema_version: 2,
|
|
616
662
|
event_id: `${run.started.run_id}:reconcile:${String(sequence).padStart(6, "0")}`,
|
|
617
663
|
run_id: run.started.run_id,
|
|
618
664
|
sequence,
|
|
619
|
-
occurred_at:
|
|
665
|
+
occurred_at: persistedRecords.find((record) => recordType(record) === "run.finished")
|
|
620
666
|
? new Date(
|
|
621
667
|
Date.parse(
|
|
622
|
-
recordOccurredAt(
|
|
668
|
+
recordOccurredAt(persistedRecords.find((record) => recordType(record) === "run.finished")),
|
|
623
669
|
) - 1,
|
|
624
670
|
).toISOString()
|
|
625
671
|
: new Date().toISOString(),
|
|
@@ -640,9 +686,7 @@ if (applyBackfill) {
|
|
|
640
686
|
...(segment.finished_at ? { source_finished_at: segment.finished_at } : {}),
|
|
641
687
|
runtime: { reasoning_effort: segment.effort, service_tier: segment.service_tier },
|
|
642
688
|
};
|
|
643
|
-
const
|
|
644
|
-
const insertAt = finishIndex < 0 ? run.records.length : finishIndex;
|
|
645
|
-
const updated = [...run.records.slice(0, insertAt), event, ...run.records.slice(insertAt)].map(
|
|
689
|
+
const updated = [...persistedRecords.slice(0, insertAt), event, ...persistedRecords.slice(insertAt)].map(
|
|
646
690
|
(record, index) => withSequence(record, index + 1),
|
|
647
691
|
);
|
|
648
692
|
const temporary = `${run.file}.reconcile.tmp`;
|
|
@@ -722,6 +766,11 @@ console.log(
|
|
|
722
766
|
).length,
|
|
723
767
|
duplicated_correction_segments: correctionKeys.length - new Set(correctionKeys).size,
|
|
724
768
|
duplicate_segment_groups: duplicateGroups.length,
|
|
769
|
+
exact_source_key_groups: exactDuplicateGroups.length,
|
|
770
|
+
canonical_alias_review_groups: aliasReviewGroups.length,
|
|
771
|
+
selected_duplicate_segment_groups: selectedDuplicateGroups.length,
|
|
772
|
+
selected_canonical_alias_review_groups: selectedAliasReviewGroups.length,
|
|
773
|
+
selected_duplicate_segment_impact: duplicateUsageImpact(duplicateAssignments),
|
|
725
774
|
duplicate_segment_assignments: duplicateAssignments.length,
|
|
726
775
|
duplicate_segment_run_ids: duplicateGroups.map((group) =>
|
|
727
776
|
group.map(({ run }) => run.started.run_id),
|
package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs
CHANGED
|
@@ -112,6 +112,18 @@ export function usageView(record) {
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
export function supersedableUsageBeforeTerminal(records) {
|
|
116
|
+
const finishIndex = records.findIndex((record) => recordType(record) === "run.finished");
|
|
117
|
+
const beforeTerminal = records.slice(0, finishIndex < 0 ? records.length : finishIndex);
|
|
118
|
+
const usage = beforeTerminal.map(usageView).filter(Boolean);
|
|
119
|
+
return [...usage]
|
|
120
|
+
.reverse()
|
|
121
|
+
.find(
|
|
122
|
+
(event) =>
|
|
123
|
+
event.tokens?.total === null && !usage.some((other) => other.supersedes_event_id === event.event_id),
|
|
124
|
+
) ?? null;
|
|
125
|
+
}
|
|
126
|
+
|
|
115
127
|
export function withSequence(record, sequence) {
|
|
116
128
|
if (!Array.isArray(record)) return { ...record, sequence };
|
|
117
129
|
const copy = [...record];
|
|
@@ -127,6 +139,10 @@ export function canonicalSegmentKey(sourceSegmentKey) {
|
|
|
127
139
|
return (sessionsMarker < 0 ? normalized : normalized.slice(sessionsMarker + 1)).toLowerCase();
|
|
128
140
|
}
|
|
129
141
|
|
|
142
|
+
function normalizedRawSegmentKey(sourceSegmentKey) {
|
|
143
|
+
return String(sourceSegmentKey).replaceAll("\\", "/").toLowerCase();
|
|
144
|
+
}
|
|
145
|
+
|
|
130
146
|
export function usageStatus(usage) {
|
|
131
147
|
const superseded = new Set(usage.map((event) => event.supersedes_event_id).filter(Boolean));
|
|
132
148
|
const effective = usage.filter((event) => !superseded.has(event.event_id));
|
|
@@ -153,26 +169,22 @@ export function duplicateUsageAssignments(runs) {
|
|
|
153
169
|
continue;
|
|
154
170
|
}
|
|
155
171
|
const baseSegmentKey = canonicalSegmentKey(usage.source_segment_key);
|
|
156
|
-
|
|
157
|
-
baseSegmentKey,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
]);
|
|
165
|
-
groups.set(signature, [
|
|
166
|
-
...(groups.get(signature) ?? []),
|
|
167
|
-
{ run, usage, base_segment_key: baseSegmentKey },
|
|
172
|
+
groups.set(baseSegmentKey, [
|
|
173
|
+
...(groups.get(baseSegmentKey) ?? []),
|
|
174
|
+
{
|
|
175
|
+
run,
|
|
176
|
+
usage,
|
|
177
|
+
base_segment_key: baseSegmentKey,
|
|
178
|
+
raw_segment_key: normalizedRawSegmentKey(usage.source_segment_key),
|
|
179
|
+
},
|
|
168
180
|
]);
|
|
169
181
|
}
|
|
170
182
|
}
|
|
171
183
|
return [...groups.values()]
|
|
172
184
|
.filter((group) => new Set(group.map(({ run }) => run.started.run_id)).size > 1)
|
|
173
185
|
.map((group) =>
|
|
174
|
-
[...group].sort(
|
|
175
|
-
|
|
186
|
+
[...group].sort((left, right) =>
|
|
187
|
+
provenanceRank(left.usage) - provenanceRank(right.usage) ||
|
|
176
188
|
String(left.run.started.occurred_at).localeCompare(
|
|
177
189
|
String(right.run.started.occurred_at),
|
|
178
190
|
) || left.run.started.run_id.localeCompare(right.run.started.run_id),
|
|
@@ -180,6 +192,48 @@ export function duplicateUsageAssignments(runs) {
|
|
|
180
192
|
);
|
|
181
193
|
}
|
|
182
194
|
|
|
195
|
+
export function isExactDuplicateUsageGroup(group) {
|
|
196
|
+
return new Set(group.map(({ raw_segment_key }) => raw_segment_key)).size === 1;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function duplicateUsageImpact(assignments) {
|
|
200
|
+
const impact = {
|
|
201
|
+
assignments: assignments.length,
|
|
202
|
+
input_tokens: 0,
|
|
203
|
+
output_tokens: 0,
|
|
204
|
+
total_tokens: 0,
|
|
205
|
+
cost_usd: 0,
|
|
206
|
+
cost_brl: 0,
|
|
207
|
+
duration_ms: 0,
|
|
208
|
+
duration_assignments: 0,
|
|
209
|
+
};
|
|
210
|
+
for (const { usage } of assignments) {
|
|
211
|
+
for (const [key, value] of [
|
|
212
|
+
["input_tokens", usage.tokens?.input],
|
|
213
|
+
["output_tokens", usage.tokens?.output],
|
|
214
|
+
["total_tokens", usage.tokens?.total],
|
|
215
|
+
["cost_usd", usage.cost?.usd],
|
|
216
|
+
["cost_brl", usage.cost?.brl],
|
|
217
|
+
]) {
|
|
218
|
+
if (Number.isFinite(value)) impact[key] += value;
|
|
219
|
+
}
|
|
220
|
+
const start = Date.parse(usage.source_started_at ?? "");
|
|
221
|
+
const finish = Date.parse(usage.source_finished_at ?? "");
|
|
222
|
+
if (Number.isFinite(start) && Number.isFinite(finish) && finish >= start) {
|
|
223
|
+
impact.duration_ms += finish - start;
|
|
224
|
+
impact.duration_assignments += 1;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return impact;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function provenanceRank(usage) {
|
|
231
|
+
const source = usage.classification_source ?? "";
|
|
232
|
+
if (source === "current_context" || source.startsWith("exact_")) return 0;
|
|
233
|
+
if (usage.activity_kind !== "retrospective_local_reconciliation") return 1;
|
|
234
|
+
return source === "legacy_inferred" ? 2 : 1;
|
|
235
|
+
}
|
|
236
|
+
|
|
183
237
|
export function exactCompletedSegment(started, segments) {
|
|
184
238
|
if (!started?.client_turn_id) return { segment: null, ambiguous: false };
|
|
185
239
|
const runStartedAt = Date.parse(started.occurred_at ?? "");
|
|
@@ -198,7 +252,13 @@ export function exactCompletedSegment(started, segments) {
|
|
|
198
252
|
};
|
|
199
253
|
}
|
|
200
254
|
|
|
201
|
-
export function exactRemeasurementSegment(
|
|
255
|
+
export function exactRemeasurementSegment(
|
|
256
|
+
started,
|
|
257
|
+
sourceSegmentKey,
|
|
258
|
+
segments,
|
|
259
|
+
sourceOccurredAt = null,
|
|
260
|
+
sourceTokens = null,
|
|
261
|
+
) {
|
|
202
262
|
const turnMatch = exactCompletedSegment(started, segments);
|
|
203
263
|
if (turnMatch.segment !== null || turnMatch.ambiguous) return turnMatch;
|
|
204
264
|
if (typeof sourceSegmentKey !== "string") return turnMatch;
|
|
@@ -207,9 +267,50 @@ export function exactRemeasurementSegment(started, sourceSegmentKey, segments) {
|
|
|
207
267
|
segment.finished_at !== null &&
|
|
208
268
|
canonicalSegmentKey(segment.key) === canonicalSegmentKey(sourceSegmentKey),
|
|
209
269
|
);
|
|
270
|
+
if (matches.length === 1) return { segment: matches[0], ambiguous: false };
|
|
271
|
+
|
|
272
|
+
const sourceFinishedAt = Date.parse(sourceOccurredAt ?? "");
|
|
273
|
+
const sourceFile = canonicalSegmentKey(sourceSegmentKey).replace(/#\d+$/, "");
|
|
274
|
+
const timeMatches = Number.isFinite(sourceFinishedAt)
|
|
275
|
+
? segments.filter(
|
|
276
|
+
(segment) =>
|
|
277
|
+
segment.finished_at !== null &&
|
|
278
|
+
Date.parse(segment.finished_at) === sourceFinishedAt &&
|
|
279
|
+
canonicalSegmentKey(segment.key).replace(/#\d+$/, "") === sourceFile,
|
|
280
|
+
)
|
|
281
|
+
: [];
|
|
282
|
+
if (timeMatches.length === 1) return { segment: timeMatches[0], ambiguous: false };
|
|
283
|
+
|
|
284
|
+
const tokenMatches =
|
|
285
|
+
sourceTokens !== null
|
|
286
|
+
? segments.filter((segment) => {
|
|
287
|
+
if (canonicalSegmentKey(segment.key).replace(/#\d+$/, "") !== sourceFile) return false;
|
|
288
|
+
if (segment.finished_at === null || !Array.isArray(segment.usage)) return false;
|
|
289
|
+
const tokens = aggregate(segment);
|
|
290
|
+
const last = segment.usage.at(-1);
|
|
291
|
+
const lastTokens = last
|
|
292
|
+
? {
|
|
293
|
+
input: last.input_tokens,
|
|
294
|
+
cached_input: last.cached_input_tokens,
|
|
295
|
+
output: last.output_tokens,
|
|
296
|
+
reasoning: last.reasoning_output_tokens,
|
|
297
|
+
total: last.total_tokens,
|
|
298
|
+
}
|
|
299
|
+
: null;
|
|
300
|
+
const same = (candidate) =>
|
|
301
|
+
candidate !== null &&
|
|
302
|
+
["input", "cached_input", "output", "reasoning", "total"].every(
|
|
303
|
+
(key) => candidate[key] === sourceTokens[key],
|
|
304
|
+
);
|
|
305
|
+
return same(tokens) || same(lastTokens);
|
|
306
|
+
})
|
|
307
|
+
: [];
|
|
210
308
|
return {
|
|
211
|
-
segment:
|
|
212
|
-
ambiguous:
|
|
309
|
+
segment: tokenMatches.length === 1 ? tokenMatches[0] : null,
|
|
310
|
+
ambiguous:
|
|
311
|
+
timeMatches.length > 1 ||
|
|
312
|
+
tokenMatches.length > 1 ||
|
|
313
|
+
(timeMatches.length === 0 && tokenMatches.length === 0 && matches.length > 1),
|
|
213
314
|
};
|
|
214
315
|
}
|
|
215
316
|
|
|
@@ -217,11 +318,10 @@ function normalized(path) {
|
|
|
217
318
|
return resolve(path).replaceAll("\\", "/").toLowerCase();
|
|
218
319
|
}
|
|
219
320
|
|
|
220
|
-
export async function loadSegments(workspace) {
|
|
221
|
-
const
|
|
321
|
+
export async function loadSegments(workspace, sessionFiles = null) {
|
|
322
|
+
const files = sessionFiles ?? (await filesUnder(join(homedir(), ".codex", "sessions"), ".jsonl"));
|
|
222
323
|
const segments = [];
|
|
223
|
-
for (const file of
|
|
224
|
-
const fileSegmentStart = segments.length;
|
|
324
|
+
for (const file of files) {
|
|
225
325
|
let canonicalSessionMetaSeen = false;
|
|
226
326
|
let workspaceMatches = false;
|
|
227
327
|
let sessionId = null;
|
|
@@ -245,17 +345,21 @@ export async function loadSegments(workspace) {
|
|
|
245
345
|
}
|
|
246
346
|
const payload = record?.payload && typeof record.payload === "object" ? record.payload : null;
|
|
247
347
|
if (record.type === "session_meta" && typeof payload?.cwd === "string") {
|
|
348
|
+
const nextSessionId = canonicalSessionId(payload);
|
|
349
|
+
const sameSession = canonicalSessionMetaSeen && nextSessionId === sessionId;
|
|
350
|
+
if (sameSession) {
|
|
351
|
+
workspaceMatches = normalized(payload.cwd) === normalized(workspace);
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
248
354
|
if (canonicalSessionMetaSeen) {
|
|
249
|
-
segments.splice(fileSegmentStart);
|
|
250
355
|
current = null;
|
|
251
356
|
index = 0;
|
|
252
357
|
latestCumulativeUsage = null;
|
|
253
358
|
latestIncrementalUsage = null;
|
|
254
|
-
continue;
|
|
255
359
|
}
|
|
256
360
|
canonicalSessionMetaSeen = true;
|
|
257
361
|
workspaceMatches = normalized(payload.cwd) === normalized(workspace);
|
|
258
|
-
sessionId =
|
|
362
|
+
sessionId = nextSessionId;
|
|
259
363
|
}
|
|
260
364
|
if (!workspaceMatches) continue;
|
|
261
365
|
const settings = payload?.type === "thread_settings_applied" ? payload.thread_settings : null;
|
|
@@ -8,13 +8,16 @@ import {
|
|
|
8
8
|
canonicalSessionId,
|
|
9
9
|
cumulativeSnapshotDelta,
|
|
10
10
|
duplicateUsageAssignments,
|
|
11
|
+
duplicateUsageImpact,
|
|
11
12
|
exactCompletedSegment,
|
|
12
13
|
exactRemeasurementSegment,
|
|
13
14
|
jsonLines,
|
|
15
|
+
isExactDuplicateUsageGroup,
|
|
14
16
|
pricingFor,
|
|
15
17
|
recordSequence,
|
|
16
18
|
recordType,
|
|
17
19
|
sameTokenSnapshot,
|
|
20
|
+
supersedableUsageBeforeTerminal,
|
|
18
21
|
usageStatus,
|
|
19
22
|
usageView,
|
|
20
23
|
withSequence,
|
|
@@ -23,6 +26,20 @@ import {
|
|
|
23
26
|
const roots = [];
|
|
24
27
|
after(async () => Promise.all(roots.map((root) => rm(root, { recursive: true, force: true }))));
|
|
25
28
|
|
|
29
|
+
test("sums duplicate assignment impact without inventing duration", () => {
|
|
30
|
+
assert.deepEqual(duplicateUsageImpact([{ usage: { tokens: { input: 2, output: 3, total: 5 }, cost: { usd: 1, brl: 5 }, source_started_at: "2026-01-01T00:00:00Z", source_finished_at: "2026-01-01T00:00:01Z" } }]), { assignments: 1, input_tokens: 2, output_tokens: 3, total_tokens: 5, cost_usd: 1, cost_brl: 5, duration_ms: 1000, duration_assignments: 1 });
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("never supersedes usage recorded after run.finished", () => {
|
|
34
|
+
const records = [
|
|
35
|
+
{ type: "run.started", sequence: 1 },
|
|
36
|
+
{ type: "usage.recorded", sequence: 2, event_id: "before", tokens: { total: null } },
|
|
37
|
+
{ type: "run.finished", sequence: 3 },
|
|
38
|
+
{ type: "usage.recorded", sequence: 4, event_id: "after", tokens: { total: null } },
|
|
39
|
+
];
|
|
40
|
+
assert.equal(supersedableUsageBeforeTerminal(records)?.event_id, "before");
|
|
41
|
+
});
|
|
42
|
+
|
|
26
43
|
test("normalizes compact and object Run records without changing usage totals", () => {
|
|
27
44
|
const compact = [
|
|
28
45
|
2,
|
|
@@ -193,6 +210,70 @@ test("remeasurement falls back only to the exact persisted source segment key",
|
|
|
193
210
|
),
|
|
194
211
|
{ segment: null, ambiguous: true },
|
|
195
212
|
);
|
|
213
|
+
|
|
214
|
+
const resumedTarget = {
|
|
215
|
+
...target,
|
|
216
|
+
key: "c:/users/test/.codex/sessions/2026/07/25/child.jsonl#18",
|
|
217
|
+
finished_at: "2026-07-25T04:15:30.000Z",
|
|
218
|
+
};
|
|
219
|
+
assert.deepEqual(
|
|
220
|
+
exactRemeasurementSegment(
|
|
221
|
+
{ client_turn_id: null, occurred_at: "2026-07-25T04:00:00.000Z" },
|
|
222
|
+
"sessions/2026/07/25/child.jsonl#2",
|
|
223
|
+
[target, resumedTarget],
|
|
224
|
+
"2026-07-25T04:15:30.000Z",
|
|
225
|
+
),
|
|
226
|
+
{ segment: resumedTarget, ambiguous: false },
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
const tokenTarget = {
|
|
230
|
+
...resumedTarget,
|
|
231
|
+
finished_at: "2026-07-25T04:16:00.000Z",
|
|
232
|
+
usage: [
|
|
233
|
+
{
|
|
234
|
+
input_tokens: 90,
|
|
235
|
+
cached_input_tokens: 80,
|
|
236
|
+
output_tokens: 10,
|
|
237
|
+
reasoning_output_tokens: 2,
|
|
238
|
+
total_tokens: 100,
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
};
|
|
242
|
+
assert.deepEqual(
|
|
243
|
+
exactRemeasurementSegment(
|
|
244
|
+
{ client_turn_id: null, occurred_at: "2026-07-25T04:00:00.000Z" },
|
|
245
|
+
"sessions/2026/07/25/child.jsonl#2",
|
|
246
|
+
[target, tokenTarget],
|
|
247
|
+
"2026-07-25T04:15:59.000Z",
|
|
248
|
+
{ input: 90, cached_input: 80, output: 10, reasoning: 2, total: 100 },
|
|
249
|
+
),
|
|
250
|
+
{ segment: tokenTarget, ambiguous: false },
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
const cumulativeSnapshotTarget = {
|
|
254
|
+
...tokenTarget,
|
|
255
|
+
key: "c:/users/test/.codex/sessions/2026/07/25/child.jsonl#19",
|
|
256
|
+
usage: [
|
|
257
|
+
tokenTarget.usage[0],
|
|
258
|
+
{
|
|
259
|
+
input_tokens: 40,
|
|
260
|
+
cached_input_tokens: 30,
|
|
261
|
+
output_tokens: 4,
|
|
262
|
+
reasoning_output_tokens: 1,
|
|
263
|
+
total_tokens: 44,
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
};
|
|
267
|
+
assert.deepEqual(
|
|
268
|
+
exactRemeasurementSegment(
|
|
269
|
+
{ client_turn_id: null, occurred_at: "2026-07-25T04:00:00.000Z" },
|
|
270
|
+
"sessions/2026/07/25/child.jsonl#2",
|
|
271
|
+
[target, cumulativeSnapshotTarget],
|
|
272
|
+
null,
|
|
273
|
+
{ input: 40, cached_input: 30, output: 4, reasoning: 1, total: 44 },
|
|
274
|
+
),
|
|
275
|
+
{ segment: cumulativeSnapshotTarget, ambiguous: false },
|
|
276
|
+
);
|
|
196
277
|
});
|
|
197
278
|
|
|
198
279
|
test("detects only exact duplicate segment assignments across Runs", () => {
|
|
@@ -237,10 +318,11 @@ test("detects only exact duplicate segment assignments across Runs", () => {
|
|
|
237
318
|
const groups = duplicateUsageAssignments([duplicate, legitimateDelta, first]);
|
|
238
319
|
|
|
239
320
|
assert.equal(groups.length, 1);
|
|
240
|
-
assert.deepEqual(
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
321
|
+
assert.deepEqual(groups[0].map(({ run: item }) => item.started.run_id), [
|
|
322
|
+
"RUN-FIRST",
|
|
323
|
+
"RUN-DUPLICATE",
|
|
324
|
+
"RUN-DELTA",
|
|
325
|
+
]);
|
|
244
326
|
assert.equal(groups[0][0].base_segment_key, "sessions/2026/07/17/session.jsonl#1");
|
|
245
327
|
});
|
|
246
328
|
|
|
@@ -264,3 +346,39 @@ test("keeps duplicate reconciliation unavailable and protected from backfill", (
|
|
|
264
346
|
assert.equal(status.deduplicated, true);
|
|
265
347
|
assert.deepEqual(status.effective, [correction]);
|
|
266
348
|
});
|
|
349
|
+
|
|
350
|
+
test("prefers later current-context assignment over earlier legacy assignment", () => {
|
|
351
|
+
const run = (id, occurred_at, client_turn_id, classification_source, total) => ({
|
|
352
|
+
started: { run_id: id, occurred_at, client_turn_id },
|
|
353
|
+
usage: [{ event_id: `${id}:usage`, source_segment_key: "sessions/x.jsonl#1", supersedes_event_id: null, classification_source, tokens: { input: total - 1, output: 1, total } }],
|
|
354
|
+
});
|
|
355
|
+
const [group] = duplicateUsageAssignments([
|
|
356
|
+
run("XCHW", "2026-07-01T00:00:00.000Z", "legacy-turn", "legacy_inferred", 9_278_701),
|
|
357
|
+
run("HF77", "2026-07-01T00:01:00.000Z", "exact-turn", "current_context", 577),
|
|
358
|
+
]);
|
|
359
|
+
assert.equal(group[0].run.started.run_id, "HF77");
|
|
360
|
+
assert.equal(group[1].run.started.run_id, "XCHW");
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
test("keeps canonical aliases in review instead of making them apply candidates", () => {
|
|
364
|
+
const run = (id, source_segment_key) => ({
|
|
365
|
+
started: { run_id: id, occurred_at: "2026-07-01T00:00:00.000Z" },
|
|
366
|
+
usage: [{
|
|
367
|
+
event_id: `${id}:usage`,
|
|
368
|
+
source_segment_key,
|
|
369
|
+
supersedes_event_id: null,
|
|
370
|
+
tokens: { input: 1, output: 1, total: 2 },
|
|
371
|
+
}],
|
|
372
|
+
});
|
|
373
|
+
const [aliasGroup] = duplicateUsageAssignments([
|
|
374
|
+
run("RUN-A", "sessions/x.jsonl#1@RUN-A"),
|
|
375
|
+
run("RUN-B", "sessions/x.jsonl#1@RUN-B"),
|
|
376
|
+
]);
|
|
377
|
+
const [exactGroup] = duplicateUsageAssignments([
|
|
378
|
+
run("RUN-C", "sessions/x.jsonl#2"),
|
|
379
|
+
run("RUN-D", "SESSIONS\\x.jsonl#2"),
|
|
380
|
+
]);
|
|
381
|
+
|
|
382
|
+
assert.equal(isExactDuplicateUsageGroup(aliasGroup), false);
|
|
383
|
+
assert.equal(isExactDuplicateUsageGroup(exactGroup), true);
|
|
384
|
+
});
|