@matteeh/osq 0.1.0 → 0.2.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/README.md +415 -72
- package/dist/cli/approve.d.ts +13 -3
- package/dist/cli/approve.d.ts.map +1 -1
- package/dist/cli/approve.js +59 -4
- package/dist/cli/approve.js.map +1 -1
- package/dist/cli/bin.js +0 -0
- package/dist/cli/confirm.d.ts +21 -0
- package/dist/cli/confirm.d.ts.map +1 -0
- package/dist/cli/confirm.js +28 -0
- package/dist/cli/confirm.js.map +1 -0
- package/dist/cli/doctor.d.ts +13 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +23 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/done.d.ts +12 -0
- package/dist/cli/done.d.ts.map +1 -0
- package/dist/cli/done.js +26 -0
- package/dist/cli/done.js.map +1 -0
- package/dist/cli/inbox.d.ts +22 -0
- package/dist/cli/inbox.d.ts.map +1 -0
- package/dist/cli/inbox.js +41 -0
- package/dist/cli/inbox.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +127 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts +1 -0
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +9 -3
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/lint.d.ts +26 -0
- package/dist/cli/lint.d.ts.map +1 -0
- package/dist/cli/lint.js +60 -0
- package/dist/cli/lint.js.map +1 -0
- package/dist/cli/migrate.d.ts +18 -0
- package/dist/cli/migrate.d.ts.map +1 -0
- package/dist/cli/migrate.js +42 -0
- package/dist/cli/migrate.js.map +1 -0
- package/dist/cli/new.js +1 -1
- package/dist/cli/new.js.map +1 -1
- package/dist/cli/plan-queue.d.ts +50 -0
- package/dist/cli/plan-queue.d.ts.map +1 -0
- package/dist/cli/plan-queue.js +167 -0
- package/dist/cli/plan-queue.js.map +1 -0
- package/dist/cli/plan.d.ts +35 -0
- package/dist/cli/plan.d.ts.map +1 -0
- package/dist/cli/plan.js +153 -0
- package/dist/cli/plan.js.map +1 -0
- package/dist/cli/queue.d.ts +9 -0
- package/dist/cli/queue.d.ts.map +1 -0
- package/dist/cli/queue.js +24 -0
- package/dist/cli/queue.js.map +1 -0
- package/dist/cli/reject.d.ts +8 -0
- package/dist/cli/reject.d.ts.map +1 -0
- package/dist/cli/reject.js +18 -0
- package/dist/cli/reject.js.map +1 -0
- package/dist/cli/report.d.ts +1 -1
- package/dist/cli/report.d.ts.map +1 -1
- package/dist/cli/report.js +141 -14
- package/dist/cli/report.js.map +1 -1
- package/dist/cli/retry.d.ts +7 -0
- package/dist/cli/retry.d.ts.map +1 -0
- package/dist/cli/retry.js +29 -0
- package/dist/cli/retry.js.map +1 -0
- package/dist/cli/serve.d.ts +30 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +136 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +7 -1
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/show.d.ts +2 -1
- package/dist/cli/show.d.ts.map +1 -1
- package/dist/cli/show.js +20 -3
- package/dist/cli/show.js.map +1 -1
- package/dist/cli/status.d.ts +1 -1
- package/dist/cli/status.d.ts.map +1 -1
- package/dist/cli/status.js +2 -2
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/watch.d.ts +9 -6
- package/dist/cli/watch.d.ts.map +1 -1
- package/dist/cli/watch.js +15 -2
- package/dist/cli/watch.js.map +1 -1
- package/dist/core/foundation/config-codex.d.ts +22 -0
- package/dist/core/foundation/config-codex.d.ts.map +1 -0
- package/dist/core/foundation/config-codex.js +58 -0
- package/dist/core/foundation/config-codex.js.map +1 -0
- package/dist/core/foundation/config-doctor.d.ts +14 -0
- package/dist/core/foundation/config-doctor.d.ts.map +1 -0
- package/dist/core/foundation/config-doctor.js +29 -0
- package/dist/core/foundation/config-doctor.js.map +1 -0
- package/dist/core/foundation/config-env.d.ts +3 -0
- package/dist/core/foundation/config-env.d.ts.map +1 -0
- package/dist/core/foundation/config-env.js +22 -0
- package/dist/core/foundation/config-env.js.map +1 -0
- package/dist/core/foundation/config-gates.d.ts +22 -0
- package/dist/core/foundation/config-gates.d.ts.map +1 -0
- package/dist/core/foundation/config-gates.js +43 -0
- package/dist/core/foundation/config-gates.js.map +1 -0
- package/dist/core/foundation/config-pi.d.ts +64 -0
- package/dist/core/foundation/config-pi.d.ts.map +1 -0
- package/dist/core/foundation/config-pi.js +131 -0
- package/dist/core/foundation/config-pi.js.map +1 -0
- package/dist/core/foundation/config-planning.d.ts +24 -0
- package/dist/core/foundation/config-planning.d.ts.map +1 -0
- package/dist/core/foundation/config-planning.js +60 -0
- package/dist/core/foundation/config-planning.js.map +1 -0
- package/dist/core/foundation/config-queue.d.ts +15 -0
- package/dist/core/foundation/config-queue.d.ts.map +1 -0
- package/dist/core/foundation/config-queue.js +24 -0
- package/dist/core/foundation/config-queue.js.map +1 -0
- package/dist/core/foundation/config-serve.d.ts +20 -0
- package/dist/core/foundation/config-serve.d.ts.map +1 -0
- package/dist/core/foundation/config-serve.js +35 -0
- package/dist/core/foundation/config-serve.js.map +1 -0
- package/dist/core/{config.d.ts → foundation/config.d.ts} +34 -3
- package/dist/core/foundation/config.d.ts.map +1 -0
- package/dist/core/{config.js → foundation/config.js} +35 -18
- package/dist/core/foundation/config.js.map +1 -0
- package/dist/core/foundation/doctor-managed.d.ts +13 -0
- package/dist/core/foundation/doctor-managed.d.ts.map +1 -0
- package/dist/core/foundation/doctor-managed.js +77 -0
- package/dist/core/foundation/doctor-managed.js.map +1 -0
- package/dist/core/foundation/doctor.d.ts +19 -0
- package/dist/core/foundation/doctor.d.ts.map +1 -0
- package/dist/core/foundation/doctor.js +187 -0
- package/dist/core/foundation/doctor.js.map +1 -0
- package/dist/core/foundation/harness-catalog.d.ts +96 -0
- package/dist/core/foundation/harness-catalog.d.ts.map +1 -0
- package/dist/core/foundation/harness-catalog.js +182 -0
- package/dist/core/foundation/harness-catalog.js.map +1 -0
- package/dist/core/foundation/init-blocks.d.ts +33 -0
- package/dist/core/foundation/init-blocks.d.ts.map +1 -0
- package/dist/core/foundation/init-blocks.js +165 -0
- package/dist/core/foundation/init-blocks.js.map +1 -0
- package/dist/core/foundation/init-managed.d.ts +10 -0
- package/dist/core/foundation/init-managed.d.ts.map +1 -0
- package/dist/core/foundation/init-managed.js +115 -0
- package/dist/core/foundation/init-managed.js.map +1 -0
- package/dist/core/foundation/init.d.ts +18 -0
- package/dist/core/foundation/init.d.ts.map +1 -0
- package/dist/core/foundation/init.js +113 -0
- package/dist/core/foundation/init.js.map +1 -0
- package/dist/core/{logger.d.ts → foundation/logger.d.ts} +1 -0
- package/dist/core/foundation/logger.d.ts.map +1 -0
- package/dist/core/{logger.js → foundation/logger.js} +18 -2
- package/dist/core/foundation/logger.js.map +1 -0
- package/dist/core/{new.d.ts → foundation/new.d.ts} +3 -0
- package/dist/core/foundation/new.d.ts.map +1 -0
- package/dist/core/foundation/new.js +206 -0
- package/dist/core/foundation/new.js.map +1 -0
- package/dist/core/foundation/package-root.d.ts +9 -0
- package/dist/core/foundation/package-root.d.ts.map +1 -0
- package/dist/core/foundation/package-root.js +11 -0
- package/dist/core/foundation/package-root.js.map +1 -0
- package/dist/core/lifecycle/done.d.ts +17 -0
- package/dist/core/lifecycle/done.d.ts.map +1 -0
- package/dist/core/lifecycle/done.js +97 -0
- package/dist/core/lifecycle/done.js.map +1 -0
- package/dist/core/lifecycle/reject.d.ts +26 -0
- package/dist/core/lifecycle/reject.d.ts.map +1 -0
- package/dist/core/lifecycle/reject.js +83 -0
- package/dist/core/lifecycle/reject.js.map +1 -0
- package/dist/core/lifecycle/retry-transition.d.ts +23 -0
- package/dist/core/lifecycle/retry-transition.d.ts.map +1 -0
- package/dist/core/lifecycle/retry-transition.js +41 -0
- package/dist/core/lifecycle/retry-transition.js.map +1 -0
- package/dist/core/lifecycle/retry.d.ts +18 -0
- package/dist/core/lifecycle/retry.d.ts.map +1 -0
- package/dist/core/lifecycle/retry.js +179 -0
- package/dist/core/lifecycle/retry.js.map +1 -0
- package/dist/core/report/approval-flags.d.ts +29 -0
- package/dist/core/report/approval-flags.d.ts.map +1 -0
- package/dist/core/report/approval-flags.js +138 -0
- package/dist/core/report/approval-flags.js.map +1 -0
- package/dist/core/report/planning-economics.d.ts +39 -0
- package/dist/core/report/planning-economics.d.ts.map +1 -0
- package/dist/core/report/planning-economics.js +168 -0
- package/dist/core/report/planning-economics.js.map +1 -0
- package/dist/core/report/planning-observed.d.ts +59 -0
- package/dist/core/report/planning-observed.d.ts.map +1 -0
- package/dist/core/report/planning-observed.js +135 -0
- package/dist/core/report/planning-observed.js.map +1 -0
- package/dist/core/report/planning-records.d.ts +69 -0
- package/dist/core/report/planning-records.d.ts.map +1 -0
- package/dist/core/report/planning-records.js +149 -0
- package/dist/core/report/planning-records.js.map +1 -0
- package/dist/core/report/planning-slice-lookup.d.ts +13 -0
- package/dist/core/report/planning-slice-lookup.d.ts.map +1 -0
- package/dist/core/report/planning-slice-lookup.js +146 -0
- package/dist/core/report/planning-slice-lookup.js.map +1 -0
- package/dist/core/report/planning-slice-measures.d.ts +17 -0
- package/dist/core/report/planning-slice-measures.d.ts.map +1 -0
- package/dist/core/report/planning-slice-measures.js +85 -0
- package/dist/core/report/planning-slice-measures.js.map +1 -0
- package/dist/core/report/planning-slice-record.d.ts +4 -0
- package/dist/core/report/planning-slice-record.d.ts.map +1 -0
- package/dist/core/report/planning-slice-record.js +66 -0
- package/dist/core/report/planning-slice-record.js.map +1 -0
- package/dist/core/report/planning-slice-turns.d.ts +13 -0
- package/dist/core/report/planning-slice-turns.d.ts.map +1 -0
- package/dist/core/report/planning-slice-turns.js +41 -0
- package/dist/core/report/planning-slice-turns.js.map +1 -0
- package/dist/core/report/planning-slice.d.ts +70 -0
- package/dist/core/report/planning-slice.d.ts.map +1 -0
- package/dist/core/report/planning-slice.js +147 -0
- package/dist/core/report/planning-slice.js.map +1 -0
- package/dist/core/report/planning.d.ts +31 -0
- package/dist/core/report/planning.d.ts.map +1 -0
- package/dist/core/report/planning.js +75 -0
- package/dist/core/report/planning.js.map +1 -0
- package/dist/core/report/report-events.d.ts +52 -0
- package/dist/core/report/report-events.d.ts.map +1 -0
- package/dist/core/report/report-events.js +198 -0
- package/dist/core/report/report-events.js.map +1 -0
- package/dist/core/report/report-pre-spawn.d.ts +25 -0
- package/dist/core/report/report-pre-spawn.d.ts.map +1 -0
- package/dist/core/report/report-pre-spawn.js +40 -0
- package/dist/core/report/report-pre-spawn.js.map +1 -0
- package/dist/core/report/report-retries.d.ts +30 -0
- package/dist/core/report/report-retries.d.ts.map +1 -0
- package/dist/core/report/report-retries.js +100 -0
- package/dist/core/report/report-retries.js.map +1 -0
- package/dist/core/report/report.d.ts +276 -0
- package/dist/core/report/report.d.ts.map +1 -0
- package/dist/core/report/report.js +1421 -0
- package/dist/core/report/report.js.map +1 -0
- package/dist/core/{lock.d.ts → run/lock.d.ts} +6 -0
- package/dist/core/run/lock.d.ts.map +1 -0
- package/dist/core/{lock.js → run/lock.js} +7 -15
- package/dist/core/run/lock.js.map +1 -0
- package/dist/core/run/manifest.d.ts +39 -0
- package/dist/core/run/manifest.d.ts.map +1 -0
- package/dist/core/run/manifest.js +137 -0
- package/dist/core/run/manifest.js.map +1 -0
- package/dist/core/run/scope-hash.d.ts +71 -0
- package/dist/core/run/scope-hash.d.ts.map +1 -0
- package/dist/core/run/scope-hash.js +177 -0
- package/dist/core/run/scope-hash.js.map +1 -0
- package/dist/core/run/scope.d.ts +30 -0
- package/dist/core/run/scope.d.ts.map +1 -0
- package/dist/core/run/scope.js +193 -0
- package/dist/core/run/scope.js.map +1 -0
- package/dist/core/run/summary.d.ts +8 -0
- package/dist/core/run/summary.d.ts.map +1 -0
- package/dist/core/run/summary.js +25 -0
- package/dist/core/run/summary.js.map +1 -0
- package/dist/core/run/verification.d.ts +23 -0
- package/dist/core/run/verification.d.ts.map +1 -0
- package/dist/core/run/verification.js +78 -0
- package/dist/core/run/verification.js.map +1 -0
- package/dist/core/spec/approve.d.ts +31 -0
- package/dist/core/spec/approve.d.ts.map +1 -0
- package/dist/core/spec/approve.js +111 -0
- package/dist/core/spec/approve.js.map +1 -0
- package/dist/core/spec/delta.d.ts +77 -0
- package/dist/core/spec/delta.d.ts.map +1 -0
- package/dist/core/spec/delta.js +581 -0
- package/dist/core/spec/delta.js.map +1 -0
- package/dist/core/spec/digest-flags.d.ts +21 -0
- package/dist/core/spec/digest-flags.d.ts.map +1 -0
- package/dist/core/spec/digest-flags.js +194 -0
- package/dist/core/spec/digest-flags.js.map +1 -0
- package/dist/core/spec/digest-verify-starts.d.ts +5 -0
- package/dist/core/spec/digest-verify-starts.d.ts.map +1 -0
- package/dist/core/spec/digest-verify-starts.js +31 -0
- package/dist/core/spec/digest-verify-starts.js.map +1 -0
- package/dist/core/spec/digest.d.ts +42 -0
- package/dist/core/spec/digest.d.ts.map +1 -0
- package/dist/core/spec/digest.js +170 -0
- package/dist/core/spec/digest.js.map +1 -0
- package/dist/core/spec/hasher.d.ts +11 -0
- package/dist/core/spec/hasher.d.ts.map +1 -0
- package/dist/core/{hasher.js → spec/hasher.js} +27 -3
- package/dist/core/spec/hasher.js.map +1 -0
- package/dist/core/spec/linter.d.ts +79 -0
- package/dist/core/spec/linter.d.ts.map +1 -0
- package/dist/core/spec/linter.js +826 -0
- package/dist/core/spec/linter.js.map +1 -0
- package/dist/core/spec/migrate.d.ts +54 -0
- package/dist/core/spec/migrate.d.ts.map +1 -0
- package/dist/core/spec/migrate.js +297 -0
- package/dist/core/spec/migrate.js.map +1 -0
- package/dist/core/spec/openspec-version.d.ts +30 -0
- package/dist/core/spec/openspec-version.d.ts.map +1 -0
- package/dist/core/spec/openspec-version.js +118 -0
- package/dist/core/spec/openspec-version.js.map +1 -0
- package/dist/core/spec/parser.d.ts +82 -0
- package/dist/core/spec/parser.d.ts.map +1 -0
- package/dist/core/spec/parser.js +221 -0
- package/dist/core/spec/parser.js.map +1 -0
- package/dist/core/spec/verify-paths.d.ts +18 -0
- package/dist/core/spec/verify-paths.d.ts.map +1 -0
- package/dist/core/spec/verify-paths.js +139 -0
- package/dist/core/spec/verify-paths.js.map +1 -0
- package/dist/core/spec/verify-starts.d.ts +45 -0
- package/dist/core/spec/verify-starts.d.ts.map +1 -0
- package/dist/core/spec/verify-starts.js +61 -0
- package/dist/core/spec/verify-starts.js.map +1 -0
- package/dist/core/status/inbox-cursor.d.ts +10 -0
- package/dist/core/status/inbox-cursor.d.ts.map +1 -0
- package/dist/core/status/inbox-cursor.js +33 -0
- package/dist/core/status/inbox-cursor.js.map +1 -0
- package/dist/core/status/inbox-projection.d.ts +15 -0
- package/dist/core/status/inbox-projection.d.ts.map +1 -0
- package/dist/core/status/inbox-projection.js +20 -0
- package/dist/core/status/inbox-projection.js.map +1 -0
- package/dist/core/status/inbox-text.d.ts +4 -0
- package/dist/core/status/inbox-text.d.ts.map +1 -0
- package/dist/core/status/inbox-text.js +48 -0
- package/dist/core/status/inbox-text.js.map +1 -0
- package/dist/core/status/inbox.d.ts +53 -0
- package/dist/core/status/inbox.d.ts.map +1 -0
- package/dist/core/status/inbox.js +167 -0
- package/dist/core/status/inbox.js.map +1 -0
- package/dist/core/status/layout.d.ts +29 -0
- package/dist/core/status/layout.d.ts.map +1 -0
- package/dist/core/status/layout.js +77 -0
- package/dist/core/status/layout.js.map +1 -0
- package/dist/core/status/queue-parser.d.ts +13 -0
- package/dist/core/status/queue-parser.d.ts.map +1 -0
- package/dist/core/status/queue-parser.js +88 -0
- package/dist/core/status/queue-parser.js.map +1 -0
- package/dist/core/status/queue-planning.d.ts +62 -0
- package/dist/core/status/queue-planning.d.ts.map +1 -0
- package/dist/core/status/queue-planning.js +158 -0
- package/dist/core/status/queue-planning.js.map +1 -0
- package/dist/core/status/queue-report-detail.d.ts +50 -0
- package/dist/core/status/queue-report-detail.d.ts.map +1 -0
- package/dist/core/status/queue-report-detail.js +140 -0
- package/dist/core/status/queue-report-detail.js.map +1 -0
- package/dist/core/status/queue-report.d.ts +14 -0
- package/dist/core/status/queue-report.d.ts.map +1 -0
- package/dist/core/status/queue-report.js +41 -0
- package/dist/core/status/queue-report.js.map +1 -0
- package/dist/core/status/queue-state.d.ts +53 -0
- package/dist/core/status/queue-state.d.ts.map +1 -0
- package/dist/core/status/queue-state.js +167 -0
- package/dist/core/status/queue-state.js.map +1 -0
- package/dist/core/status/queue.d.ts +7 -0
- package/dist/core/status/queue.d.ts.map +1 -0
- package/dist/core/status/queue.js +4 -0
- package/dist/core/status/queue.js.map +1 -0
- package/dist/core/status/show.d.ts +102 -0
- package/dist/core/status/show.d.ts.map +1 -0
- package/dist/core/status/show.js +704 -0
- package/dist/core/status/show.js.map +1 -0
- package/dist/core/status/state.d.ts +56 -0
- package/dist/core/status/state.d.ts.map +1 -0
- package/dist/core/status/state.js +187 -0
- package/dist/core/status/state.js.map +1 -0
- package/dist/core/status/status.d.ts +23 -0
- package/dist/core/status/status.d.ts.map +1 -0
- package/dist/core/status/status.js +173 -0
- package/dist/core/status/status.js.map +1 -0
- package/dist/core/web/web-data-change.d.ts +10 -0
- package/dist/core/web/web-data-change.d.ts.map +1 -0
- package/dist/core/web/web-data-change.js +106 -0
- package/dist/core/web/web-data-change.js.map +1 -0
- package/dist/core/web/web-data-folders.d.ts +39 -0
- package/dist/core/web/web-data-folders.d.ts.map +1 -0
- package/dist/core/web/web-data-folders.js +125 -0
- package/dist/core/web/web-data-folders.js.map +1 -0
- package/dist/core/web/web-data-graph.d.ts +8 -0
- package/dist/core/web/web-data-graph.d.ts.map +1 -0
- package/dist/core/web/web-data-graph.js +113 -0
- package/dist/core/web/web-data-graph.js.map +1 -0
- package/dist/core/web/web-data-lifecycle.d.ts +43 -0
- package/dist/core/web/web-data-lifecycle.d.ts.map +1 -0
- package/dist/core/web/web-data-lifecycle.js +141 -0
- package/dist/core/web/web-data-lifecycle.js.map +1 -0
- package/dist/core/web/web-data-observations.d.ts +30 -0
- package/dist/core/web/web-data-observations.d.ts.map +1 -0
- package/dist/core/web/web-data-observations.js +181 -0
- package/dist/core/web/web-data-observations.js.map +1 -0
- package/dist/core/web/web-data-tokens.d.ts +29 -0
- package/dist/core/web/web-data-tokens.d.ts.map +1 -0
- package/dist/core/web/web-data-tokens.js +62 -0
- package/dist/core/web/web-data-tokens.js.map +1 -0
- package/dist/core/web/web-data-types.d.ts +156 -0
- package/dist/core/web/web-data-types.d.ts.map +1 -0
- package/dist/core/web/web-data-types.js +15 -0
- package/dist/core/web/web-data-types.js.map +1 -0
- package/dist/core/web/web-data.d.ts +10 -0
- package/dist/core/web/web-data.d.ts.map +1 -0
- package/dist/core/web/web-data.js +8 -0
- package/dist/core/web/web-data.js.map +1 -0
- package/dist/core/web/web-events.d.ts +54 -0
- package/dist/core/web/web-events.d.ts.map +1 -0
- package/dist/core/web/web-events.js +162 -0
- package/dist/core/web/web-events.js.map +1 -0
- package/dist/core/web/web-export.d.ts +18 -0
- package/dist/core/web/web-export.d.ts.map +1 -0
- package/dist/core/web/web-export.js +112 -0
- package/dist/core/web/web-export.js.map +1 -0
- package/dist/core/web/web-server.d.ts +34 -0
- package/dist/core/web/web-server.d.ts.map +1 -0
- package/dist/core/web/web-server.js +182 -0
- package/dist/core/web/web-server.js.map +1 -0
- package/dist/core/web/web-static.d.ts +20 -0
- package/dist/core/web/web-static.d.ts.map +1 -0
- package/dist/core/web/web-static.js +104 -0
- package/dist/core/web/web-static.js.map +1 -0
- package/dist/harness/{agy.d.ts → agy/agy.d.ts} +8 -6
- package/dist/harness/agy/agy.d.ts.map +1 -0
- package/dist/harness/{agy.js → agy/agy.js} +49 -34
- package/dist/harness/agy/agy.js.map +1 -0
- package/dist/harness/claude/claude-turns.d.ts +29 -0
- package/dist/harness/claude/claude-turns.d.ts.map +1 -0
- package/dist/harness/claude/claude-turns.js +162 -0
- package/dist/harness/claude/claude-turns.js.map +1 -0
- package/dist/harness/claude/claude-usage.d.ts +12 -0
- package/dist/harness/claude/claude-usage.d.ts.map +1 -0
- package/dist/harness/claude/claude-usage.js +144 -0
- package/dist/harness/claude/claude-usage.js.map +1 -0
- package/dist/harness/codex/codex-observe-usage.d.ts +6 -0
- package/dist/harness/codex/codex-observe-usage.d.ts.map +1 -0
- package/dist/harness/codex/codex-observe-usage.js +215 -0
- package/dist/harness/codex/codex-observe-usage.js.map +1 -0
- package/dist/harness/codex/codex-prompt.d.ts +17 -0
- package/dist/harness/codex/codex-prompt.d.ts.map +1 -0
- package/dist/harness/codex/codex-prompt.js +43 -0
- package/dist/harness/codex/codex-prompt.js.map +1 -0
- package/dist/harness/codex/codex-stream.d.ts +23 -0
- package/dist/harness/codex/codex-stream.d.ts.map +1 -0
- package/dist/harness/codex/codex-stream.js +182 -0
- package/dist/harness/codex/codex-stream.js.map +1 -0
- package/dist/harness/codex/codex-usage.d.ts +26 -0
- package/dist/harness/codex/codex-usage.d.ts.map +1 -0
- package/dist/harness/codex/codex-usage.js +122 -0
- package/dist/harness/codex/codex-usage.js.map +1 -0
- package/dist/harness/codex/codex.d.ts +16 -0
- package/dist/harness/codex/codex.d.ts.map +1 -0
- package/dist/harness/codex/codex.js +92 -0
- package/dist/harness/codex/codex.js.map +1 -0
- package/dist/harness/index.d.ts +11 -2
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +24 -9
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/mock.d.ts +5 -2
- package/dist/harness/mock.d.ts.map +1 -1
- package/dist/harness/mock.js +10 -11
- package/dist/harness/mock.js.map +1 -1
- package/dist/harness/opencode/opencode-observe-usage.d.ts +4 -0
- package/dist/harness/opencode/opencode-observe-usage.d.ts.map +1 -0
- package/dist/harness/opencode/opencode-observe-usage.js +100 -0
- package/dist/harness/opencode/opencode-observe-usage.js.map +1 -0
- package/dist/harness/opencode/opencode-usage.d.ts +24 -0
- package/dist/harness/opencode/opencode-usage.d.ts.map +1 -0
- package/dist/harness/opencode/opencode-usage.js +181 -0
- package/dist/harness/opencode/opencode-usage.js.map +1 -0
- package/dist/harness/{opencode.d.ts → opencode/opencode.d.ts} +10 -7
- package/dist/harness/opencode/opencode.d.ts.map +1 -0
- package/dist/harness/{opencode.js → opencode/opencode.js} +159 -70
- package/dist/harness/opencode/opencode.js.map +1 -0
- package/dist/harness/pi/pi-args.d.ts +9 -0
- package/dist/harness/pi/pi-args.d.ts.map +1 -0
- package/dist/harness/pi/pi-args.js +33 -0
- package/dist/harness/pi/pi-args.js.map +1 -0
- package/dist/harness/pi/pi-stream.d.ts +27 -0
- package/dist/harness/pi/pi-stream.d.ts.map +1 -0
- package/dist/harness/pi/pi-stream.js +176 -0
- package/dist/harness/pi/pi-stream.js.map +1 -0
- package/dist/harness/pi/pi-tools.d.ts +5 -0
- package/dist/harness/pi/pi-tools.d.ts.map +1 -0
- package/dist/harness/pi/pi-tools.js +31 -0
- package/dist/harness/pi/pi-tools.js.map +1 -0
- package/dist/harness/pi/pi.d.ts +11 -0
- package/dist/harness/pi/pi.d.ts.map +1 -0
- package/dist/harness/pi/pi.js +109 -0
- package/dist/harness/pi/pi.js.map +1 -0
- package/dist/harness/prompt.d.ts +11 -0
- package/dist/harness/prompt.d.ts.map +1 -0
- package/dist/harness/prompt.js +105 -0
- package/dist/harness/prompt.js.map +1 -0
- package/dist/harness/types.d.ts +287 -8
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js +125 -0
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/watcher/archive-verify.d.ts +9 -0
- package/dist/watcher/archive-verify.d.ts.map +1 -0
- package/dist/watcher/archive-verify.js +80 -0
- package/dist/watcher/archive-verify.js.map +1 -0
- package/dist/watcher/archiver.d.ts +14 -2
- package/dist/watcher/archiver.d.ts.map +1 -1
- package/dist/watcher/archiver.js +112 -33
- package/dist/watcher/archiver.js.map +1 -1
- package/dist/watcher/attempt.d.ts +19 -0
- package/dist/watcher/attempt.d.ts.map +1 -0
- package/dist/watcher/attempt.js +94 -0
- package/dist/watcher/attempt.js.map +1 -0
- package/dist/watcher/auto-retry.d.ts +11 -0
- package/dist/watcher/auto-retry.d.ts.map +1 -0
- package/dist/watcher/auto-retry.js +180 -0
- package/dist/watcher/auto-retry.js.map +1 -0
- package/dist/watcher/build.d.ts +24 -0
- package/dist/watcher/build.d.ts.map +1 -0
- package/dist/watcher/build.js +169 -0
- package/dist/watcher/build.js.map +1 -0
- package/dist/watcher/change-verify.d.ts +25 -0
- package/dist/watcher/change-verify.d.ts.map +1 -0
- package/dist/watcher/change-verify.js +57 -0
- package/dist/watcher/change-verify.js.map +1 -0
- package/dist/watcher/dev.d.ts +51 -0
- package/dist/watcher/dev.d.ts.map +1 -0
- package/dist/watcher/dev.js +124 -0
- package/dist/watcher/dev.js.map +1 -0
- package/dist/watcher/failure-reason.d.ts +7 -0
- package/dist/watcher/failure-reason.d.ts.map +1 -0
- package/dist/watcher/failure-reason.js +2 -0
- package/dist/watcher/failure-reason.js.map +1 -0
- package/dist/watcher/fingerprint.d.ts +19 -0
- package/dist/watcher/fingerprint.d.ts.map +1 -0
- package/dist/watcher/fingerprint.js +53 -0
- package/dist/watcher/fingerprint.js.map +1 -0
- package/dist/watcher/heartbeat.d.ts +33 -0
- package/dist/watcher/heartbeat.d.ts.map +1 -0
- package/dist/watcher/heartbeat.js +135 -0
- package/dist/watcher/heartbeat.js.map +1 -0
- package/dist/watcher/lock.d.ts +10 -0
- package/dist/watcher/lock.d.ts.map +1 -0
- package/dist/watcher/lock.js +14 -0
- package/dist/watcher/lock.js.map +1 -0
- package/dist/watcher/loop.d.ts +26 -6
- package/dist/watcher/loop.d.ts.map +1 -1
- package/dist/watcher/loop.js +154 -37
- package/dist/watcher/loop.js.map +1 -1
- package/dist/watcher/measures.d.ts +46 -0
- package/dist/watcher/measures.d.ts.map +1 -0
- package/dist/watcher/measures.js +203 -0
- package/dist/watcher/measures.js.map +1 -0
- package/dist/watcher/outcome.d.ts +32 -0
- package/dist/watcher/outcome.d.ts.map +1 -0
- package/dist/watcher/outcome.js +127 -0
- package/dist/watcher/outcome.js.map +1 -0
- package/dist/watcher/regression.d.ts +43 -0
- package/dist/watcher/regression.d.ts.map +1 -0
- package/dist/watcher/regression.js +175 -0
- package/dist/watcher/regression.js.map +1 -0
- package/dist/watcher/runner.d.ts +6 -68
- package/dist/watcher/runner.d.ts.map +1 -1
- package/dist/watcher/runner.js +74 -523
- package/dist/watcher/runner.js.map +1 -1
- package/dist/watcher/spawn.d.ts +48 -0
- package/dist/watcher/spawn.d.ts.map +1 -0
- package/dist/watcher/spawn.js +130 -0
- package/dist/watcher/spawn.js.map +1 -0
- package/dist/watcher/task-verify.d.ts +59 -0
- package/dist/watcher/task-verify.d.ts.map +1 -0
- package/dist/watcher/task-verify.js +108 -0
- package/dist/watcher/task-verify.js.map +1 -0
- package/dist/watcher/verify.d.ts +44 -0
- package/dist/watcher/verify.d.ts.map +1 -0
- package/dist/watcher/verify.js +156 -0
- package/dist/watcher/verify.js.map +1 -0
- package/package.json +21 -9
- package/templates/PLANNER.md +77 -0
- package/templates/openspec/config.yaml +24 -0
- package/templates/openspec/schemas/osq/README.md +30 -0
- package/templates/openspec/schemas/osq/schema.yaml +133 -0
- package/templates/openspec/schemas/osq/templates/proposal.md +66 -0
- package/templates/openspec/schemas/osq/templates/spec.md +13 -0
- package/templates/openspec/schemas/osq/templates/tasks.md +11 -0
- package/templates/proposal.md +66 -0
- package/templates/tasks.md +5 -0
- package/ui/dist/assets/index-CZYeQ8la.js +9 -0
- package/ui/dist/assets/index-D6zVSjO7.css +1 -0
- package/ui/dist/index.html +14 -0
- package/dist/core/approve.d.ts +0 -11
- package/dist/core/approve.d.ts.map +0 -1
- package/dist/core/approve.js +0 -52
- package/dist/core/approve.js.map +0 -1
- package/dist/core/config.d.ts.map +0 -1
- package/dist/core/config.js.map +0 -1
- package/dist/core/hasher.d.ts +0 -4
- package/dist/core/hasher.d.ts.map +0 -1
- package/dist/core/hasher.js.map +0 -1
- package/dist/core/init.d.ts +0 -12
- package/dist/core/init.d.ts.map +0 -1
- package/dist/core/init.js +0 -151
- package/dist/core/init.js.map +0 -1
- package/dist/core/linter.d.ts +0 -8
- package/dist/core/linter.d.ts.map +0 -1
- package/dist/core/linter.js +0 -100
- package/dist/core/linter.js.map +0 -1
- package/dist/core/lock.d.ts.map +0 -1
- package/dist/core/lock.js.map +0 -1
- package/dist/core/logger.d.ts.map +0 -1
- package/dist/core/logger.js.map +0 -1
- package/dist/core/new.d.ts.map +0 -1
- package/dist/core/new.js +0 -79
- package/dist/core/new.js.map +0 -1
- package/dist/core/parser.d.ts +0 -32
- package/dist/core/parser.d.ts.map +0 -1
- package/dist/core/parser.js +0 -87
- package/dist/core/parser.js.map +0 -1
- package/dist/core/report.d.ts +0 -54
- package/dist/core/report.d.ts.map +0 -1
- package/dist/core/report.js +0 -475
- package/dist/core/report.js.map +0 -1
- package/dist/core/show.d.ts +0 -50
- package/dist/core/show.d.ts.map +0 -1
- package/dist/core/show.js +0 -374
- package/dist/core/show.js.map +0 -1
- package/dist/core/state.d.ts +0 -25
- package/dist/core/state.d.ts.map +0 -1
- package/dist/core/state.js +0 -180
- package/dist/core/state.js.map +0 -1
- package/dist/core/status.d.ts +0 -10
- package/dist/core/status.d.ts.map +0 -1
- package/dist/core/status.js +0 -106
- package/dist/core/status.js.map +0 -1
- package/dist/harness/agy.d.ts.map +0 -1
- package/dist/harness/agy.js.map +0 -1
- package/dist/harness/opencode.d.ts.map +0 -1
- package/dist/harness/opencode.js.map +0 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { resolveSymbol } from '../core/foundation/logger.js';
|
|
4
|
+
import { parseFrontmatter } from '../core/spec/parser.js';
|
|
5
|
+
import { asRecord } from '../harness/stream.js';
|
|
6
|
+
import { stripAnsi } from './fingerprint.js';
|
|
7
|
+
const ELLIPSIS = '…';
|
|
8
|
+
function truncateToWidth(text, width) {
|
|
9
|
+
if (width <= 0)
|
|
10
|
+
return '';
|
|
11
|
+
if (text.length <= width)
|
|
12
|
+
return text;
|
|
13
|
+
if (width === 1)
|
|
14
|
+
return ELLIPSIS;
|
|
15
|
+
return `${text.slice(0, width - 1)}${ELLIPSIS}`;
|
|
16
|
+
}
|
|
17
|
+
/** Curated task-started line: prefix plus the title truncated to terminal width. */
|
|
18
|
+
export function formatTaskStartedLine(taskNumber, title, pid, timeoutSeconds, symbols, terminalWidth = process.stderr.columns ?? 80) {
|
|
19
|
+
const symbol = resolveSymbol('▶', '[task]', symbols);
|
|
20
|
+
const prefix = `${symbol} task ${taskNumber} started (pid: ${pid ?? 'unknown'}, timeout: ${timeoutSeconds}s): `;
|
|
21
|
+
return `${prefix}${truncateToWidth(title, Math.max(0, terminalWidth - prefix.length))}`;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Body after the frontmatter of the dead marker a retry retained, with ANSI
|
|
25
|
+
* codes stripped. The retained attempt ordinal is one less than the following
|
|
26
|
+
* execution attempt. A missing marker, as after retrying a regression, yields no
|
|
27
|
+
* output.
|
|
28
|
+
*/
|
|
29
|
+
async function readRetainedMarkerBody(specFolderPath, taskNumber, attempt) {
|
|
30
|
+
const markerPath = path.join(specFolderPath, '.run', 'dead', `${taskNumber}.${attempt - 1}.md`);
|
|
31
|
+
const content = await fs.readFile(markerPath, 'utf8').catch(() => undefined);
|
|
32
|
+
if (content === undefined)
|
|
33
|
+
return undefined;
|
|
34
|
+
return stripAnsi(parseFrontmatter(content).body);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Reconstruct the target-wide execution attempt, prior failure reason, and
|
|
38
|
+
* failure output from the append-only event stream. The latest `retry`
|
|
39
|
+
* transition or requeued `recertification` wins, so a watcher restart loses
|
|
40
|
+
* neither the attempt nor the failure context. A retry's output is the body of
|
|
41
|
+
* the dead marker it retained; a requeued recertification keeps its captured
|
|
42
|
+
* verification output. A passed recertification is not a transition and never
|
|
43
|
+
* advances attempts. Without either event the target starts at attempt 1.
|
|
44
|
+
*/
|
|
45
|
+
export async function readRetryContext(specFolderPath, taskNumber) {
|
|
46
|
+
const eventPath = path.join(specFolderPath, '.run', 'events', `${taskNumber}.jsonl`);
|
|
47
|
+
const content = await fs.readFile(eventPath, 'utf8').catch(() => '');
|
|
48
|
+
let attempt = 1;
|
|
49
|
+
let reason;
|
|
50
|
+
let output;
|
|
51
|
+
for (const line of content.split('\n')) {
|
|
52
|
+
if (!line.trim())
|
|
53
|
+
continue;
|
|
54
|
+
let parsed;
|
|
55
|
+
try {
|
|
56
|
+
parsed = JSON.parse(line);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const event = asRecord(parsed);
|
|
62
|
+
if (event?.type === 'retry') {
|
|
63
|
+
const data = asRecord(event.data);
|
|
64
|
+
if (typeof data?.attempt === 'number' && Number.isInteger(data.attempt)) {
|
|
65
|
+
attempt = data.attempt;
|
|
66
|
+
}
|
|
67
|
+
if (typeof data?.reason === 'string' && data.reason) {
|
|
68
|
+
reason = data.reason;
|
|
69
|
+
}
|
|
70
|
+
output = await readRetainedMarkerBody(specFolderPath, taskNumber, attempt);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (event?.type !== 'recertification')
|
|
74
|
+
continue;
|
|
75
|
+
const data = asRecord(event.data);
|
|
76
|
+
if (data?.outcome !== 'requeued')
|
|
77
|
+
continue;
|
|
78
|
+
if (typeof data.attempt === 'number' && Number.isInteger(data.attempt)) {
|
|
79
|
+
attempt = data.attempt;
|
|
80
|
+
}
|
|
81
|
+
if (typeof data.reason === 'string' && data.reason) {
|
|
82
|
+
reason = data.reason;
|
|
83
|
+
}
|
|
84
|
+
if (typeof data.output === 'string') {
|
|
85
|
+
output = data.output;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
attempt,
|
|
90
|
+
...(reason ? { reason } : {}),
|
|
91
|
+
...(output ? { output } : {}),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=attempt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attempt.js","sourceRoot":"","sources":["../../src/watcher/attempt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { OsqConfig } from '../core/foundation/config.js';
|
|
2
|
+
import { type Logger } from '../core/foundation/logger.js';
|
|
3
|
+
export declare const ELIGIBLE_AUTO_RETRY_REASONS: readonly ["verify_red", "change_verify_red", "undeclared_test_change", "verify_path_missing", "no_result", "crashed", "timeout"];
|
|
4
|
+
export type EligibleAutoRetryReason = (typeof ELIGIBLE_AUTO_RETRY_REASONS)[number];
|
|
5
|
+
/**
|
|
6
|
+
* Decide, per active dead task in an approved change, whether to retry it. Runs
|
|
7
|
+
* from disk every cycle so a watcher restart between a death and its retry
|
|
8
|
+
* neither loses nor repeats the action. Returns the number of retries made.
|
|
9
|
+
*/
|
|
10
|
+
export declare function runAutomaticRetries(projectRoot: string, folderPath: string, config: OsqConfig, logger?: Logger): Promise<number>;
|
|
11
|
+
//# sourceMappingURL=auto-retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-retry.d.ts","sourceRoot":"","sources":["../../src/watcher/auto-retry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,8BAA8B,CAAC;AAU1E,eAAO,MAAM,2BAA2B,kIAQ9B,CAAC;AAEX,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AA6KnF;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAwBjB"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import YAML from 'yaml';
|
|
4
|
+
import { resolveSymbol } from '../core/foundation/logger.js';
|
|
5
|
+
import { retrySpec } from '../core/lifecycle/retry.js';
|
|
6
|
+
import { parseFrontmatter } from '../core/spec/parser.js';
|
|
7
|
+
import { appendHarnessEvent } from '../harness/types.js';
|
|
8
|
+
import { markerFingerprint } from './fingerprint.js';
|
|
9
|
+
// Automatic retry spends one agent attempt on a dead task when a fresh run
|
|
10
|
+
// could plausibly fix it. The decision is re-derived from disk every cycle; the
|
|
11
|
+
// retry transition itself (renaming the active marker) is the commit point.
|
|
12
|
+
export const ELIGIBLE_AUTO_RETRY_REASONS = [
|
|
13
|
+
'verify_red',
|
|
14
|
+
'change_verify_red',
|
|
15
|
+
'undeclared_test_change',
|
|
16
|
+
'verify_path_missing',
|
|
17
|
+
'no_result',
|
|
18
|
+
'crashed',
|
|
19
|
+
'timeout',
|
|
20
|
+
];
|
|
21
|
+
const ELIGIBLE = new Set(ELIGIBLE_AUTO_RETRY_REASONS);
|
|
22
|
+
const ACTIVE_DEAD = /^\d+\.md$/;
|
|
23
|
+
const RETAINED_DEAD = /^(\d+)\.(\d+)\.md$/;
|
|
24
|
+
async function readStream(folderPath, taskNumber) {
|
|
25
|
+
const raw = await fs
|
|
26
|
+
.readFile(path.join(folderPath, '.run', 'events', `${taskNumber}.jsonl`), 'utf8')
|
|
27
|
+
.catch(() => '');
|
|
28
|
+
const events = [];
|
|
29
|
+
for (const line of raw.split('\n')) {
|
|
30
|
+
if (!line.trim())
|
|
31
|
+
continue;
|
|
32
|
+
try {
|
|
33
|
+
events.push(JSON.parse(line));
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// A malformed line never blocks the decision.
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return events;
|
|
40
|
+
}
|
|
41
|
+
function dataOf(event) {
|
|
42
|
+
return event.data !== null && typeof event.data === 'object'
|
|
43
|
+
? event.data
|
|
44
|
+
: {};
|
|
45
|
+
}
|
|
46
|
+
function laterOf(a, b) {
|
|
47
|
+
if (a === undefined)
|
|
48
|
+
return b;
|
|
49
|
+
if (b === undefined)
|
|
50
|
+
return a;
|
|
51
|
+
return a > b ? a : b;
|
|
52
|
+
}
|
|
53
|
+
function lastManualRetryAt(events) {
|
|
54
|
+
let latest;
|
|
55
|
+
for (const event of events) {
|
|
56
|
+
if (event.type !== 'retry' || dataOf(event).automatic === true)
|
|
57
|
+
continue;
|
|
58
|
+
if (typeof event.timestamp !== 'string')
|
|
59
|
+
continue;
|
|
60
|
+
latest = laterOf(latest, event.timestamp);
|
|
61
|
+
}
|
|
62
|
+
return latest;
|
|
63
|
+
}
|
|
64
|
+
function automaticRetriesSince(events, cutoff) {
|
|
65
|
+
let count = 0;
|
|
66
|
+
for (const event of events) {
|
|
67
|
+
if (event.type !== 'retry' || dataOf(event).automatic !== true)
|
|
68
|
+
continue;
|
|
69
|
+
if (cutoff !== undefined && typeof event.timestamp === 'string' && event.timestamp < cutoff) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
count += 1;
|
|
73
|
+
}
|
|
74
|
+
return count;
|
|
75
|
+
}
|
|
76
|
+
async function readApprovedAt(runDir) {
|
|
77
|
+
const raw = await fs.readFile(path.join(runDir, 'manifest.json'), 'utf8').catch(() => '');
|
|
78
|
+
try {
|
|
79
|
+
const parsed = JSON.parse(raw);
|
|
80
|
+
return typeof parsed.approvedAt === 'string' ? parsed.approvedAt : undefined;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** Stored fingerprint, falling back to a content-derived one for legacy markers. */
|
|
87
|
+
function fingerprintOf(content, projectRoot) {
|
|
88
|
+
const stored = parseFrontmatter(content).data.fingerprint;
|
|
89
|
+
return typeof stored === 'string' && stored ? stored : markerFingerprint(content, projectRoot);
|
|
90
|
+
}
|
|
91
|
+
async function highestRetained(deadDir, taskNumber, projectRoot) {
|
|
92
|
+
const entries = await fs.readdir(deadDir).catch(() => []);
|
|
93
|
+
let bestOrdinal = -1;
|
|
94
|
+
let best;
|
|
95
|
+
for (const entry of entries) {
|
|
96
|
+
const match = entry.match(RETAINED_DEAD);
|
|
97
|
+
if (!match || match[1] !== taskNumber)
|
|
98
|
+
continue;
|
|
99
|
+
const ordinal = Number.parseInt(match[2], 10);
|
|
100
|
+
if (ordinal > bestOrdinal) {
|
|
101
|
+
bestOrdinal = ordinal;
|
|
102
|
+
best = entry;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (best === undefined)
|
|
106
|
+
return undefined;
|
|
107
|
+
const content = await fs.readFile(path.join(deadDir, best), 'utf8').catch(() => '');
|
|
108
|
+
return fingerprintOf(content, projectRoot);
|
|
109
|
+
}
|
|
110
|
+
function shortFingerprint(fingerprint) {
|
|
111
|
+
const hex = fingerprint.startsWith('sha256:') ? fingerprint.slice(7) : fingerprint;
|
|
112
|
+
return hex.slice(0, 12);
|
|
113
|
+
}
|
|
114
|
+
function errorMessage(err) {
|
|
115
|
+
return err instanceof Error ? err.message : String(err);
|
|
116
|
+
}
|
|
117
|
+
/** Mark the active marker stuck once, preserving the body after its frontmatter. */
|
|
118
|
+
async function markStuck(folderPath, specId, taskNumber, deadPath, fingerprint, logger) {
|
|
119
|
+
const content = await fs.readFile(deadPath, 'utf8');
|
|
120
|
+
const { data, body } = parseFrontmatter(content);
|
|
121
|
+
if (data.stuck === true)
|
|
122
|
+
return;
|
|
123
|
+
await fs.writeFile(deadPath, `---\n${YAML.stringify({ ...data, stuck: true })}---\n${body}`, 'utf8');
|
|
124
|
+
await appendHarnessEvent(folderPath, taskNumber, {
|
|
125
|
+
type: 'stuck',
|
|
126
|
+
timestamp: new Date().toISOString(),
|
|
127
|
+
data: { task: taskNumber, fingerprint },
|
|
128
|
+
});
|
|
129
|
+
logger?.info(`${resolveSymbol('■', '[stuck]', logger?.symbols === true)} task ${taskNumber} of ${specId} stuck: same failure twice (${shortFingerprint(fingerprint)})`);
|
|
130
|
+
}
|
|
131
|
+
async function decideDeadTask(projectRoot, folderPath, specId, taskNumber, deadPath, config, limit, logger) {
|
|
132
|
+
const content = await fs.readFile(deadPath, 'utf8').catch(() => '');
|
|
133
|
+
const reason = parseFrontmatter(content).data.reason;
|
|
134
|
+
if (typeof reason !== 'string' || !ELIGIBLE.has(reason))
|
|
135
|
+
return 'none';
|
|
136
|
+
const runDir = path.join(folderPath, '.run');
|
|
137
|
+
const events = await readStream(folderPath, taskNumber);
|
|
138
|
+
const fingerprint = fingerprintOf(content, projectRoot);
|
|
139
|
+
const previous = await highestRetained(path.join(runDir, 'dead'), taskNumber, projectRoot);
|
|
140
|
+
if (previous !== undefined && previous === fingerprint) {
|
|
141
|
+
await markStuck(folderPath, specId, taskNumber, deadPath, fingerprint, logger);
|
|
142
|
+
return 'stuck';
|
|
143
|
+
}
|
|
144
|
+
const cutoff = laterOf(await readApprovedAt(runDir), lastManualRetryAt(events));
|
|
145
|
+
if (automaticRetriesSince(events, cutoff) >= limit)
|
|
146
|
+
return 'none';
|
|
147
|
+
try {
|
|
148
|
+
const result = await retrySpec(projectRoot, specId, taskNumber, config, { automatic: true });
|
|
149
|
+
logger?.info(`${resolveSymbol('↻', '[retry]', logger?.symbols === true)} task ${taskNumber} of ${specId} retried automatically after ${result.reason} (attempt ${result.attempt})`);
|
|
150
|
+
return 'retried';
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
logger?.warn(`task ${taskNumber} of ${specId} automatic retry failed: ${errorMessage(err)}`);
|
|
154
|
+
return 'none';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Decide, per active dead task in an approved change, whether to retry it. Runs
|
|
159
|
+
* from disk every cycle so a watcher restart between a death and its retry
|
|
160
|
+
* neither loses nor repeats the action. Returns the number of retries made.
|
|
161
|
+
*/
|
|
162
|
+
export async function runAutomaticRetries(projectRoot, folderPath, config, logger) {
|
|
163
|
+
const limit = config.gates?.autoRetries ?? 1;
|
|
164
|
+
if (limit <= 0)
|
|
165
|
+
return 0;
|
|
166
|
+
const folderName = path.basename(folderPath);
|
|
167
|
+
const specId = folderName.match(/^(\d+)/)?.[1] ?? folderName;
|
|
168
|
+
const deadDir = path.join(folderPath, '.run', 'dead');
|
|
169
|
+
const entries = (await fs.readdir(deadDir).catch(() => []))
|
|
170
|
+
.filter((entry) => ACTIVE_DEAD.test(entry))
|
|
171
|
+
.sort();
|
|
172
|
+
let retried = 0;
|
|
173
|
+
for (const entry of entries) {
|
|
174
|
+
const decision = await decideDeadTask(projectRoot, folderPath, specId, entry.replace(/\.md$/, ''), path.join(deadDir, entry), config, limit, logger);
|
|
175
|
+
if (decision === 'retried')
|
|
176
|
+
retried += 1;
|
|
177
|
+
}
|
|
178
|
+
return retried;
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=auto-retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-retry.js","sourceRoot":"","sources":["../../src/watcher/auto-retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Identity of the osq build currently executing: package version plus commit. */
|
|
2
|
+
export interface BuildInfo {
|
|
3
|
+
version: string;
|
|
4
|
+
commit: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the active osq build identity. Version comes from `package.json`;
|
|
8
|
+
* the commit is the short git SHA when available, otherwise a hash of `dist/`,
|
|
9
|
+
* otherwise `unknown`. The result is cached per resolved root so the watcher
|
|
10
|
+
* pays the git spawn at most once.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveBuildInfo(projectRoot?: string): Promise<BuildInfo>;
|
|
13
|
+
export interface CheckStaleBuildOptions {
|
|
14
|
+
allowStale?: boolean;
|
|
15
|
+
packageRoot?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Refuse to run a compiled osq build whose `dist/` is older than `src/` when
|
|
19
|
+
* started from a repository checkout. An installed package carries no `src/`
|
|
20
|
+
* and is never considered stale. Prints exactly one error line and exits with
|
|
21
|
+
* code 1 when stale, so a developer rebuilds instead of debugging a phantom.
|
|
22
|
+
*/
|
|
23
|
+
export declare function checkStaleBuild(options?: CheckStaleBuildOptions): Promise<void>;
|
|
24
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/watcher/build.ts"],"names":[],"mappings":"AAOA,kFAAkF;AAClF,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAyGD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAY/E;AA0BD,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BzF"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
const UNKNOWN = 'unknown';
|
|
7
|
+
/**
|
|
8
|
+
* Package root of the running osq build: `src/watcher/` when executed through
|
|
9
|
+
* `tsx`, `dist/watcher/` once compiled. Both resolve two levels up.
|
|
10
|
+
*/
|
|
11
|
+
const PACKAGE_ROOT = path.resolve(fileURLToPath(new URL('../../', import.meta.url)));
|
|
12
|
+
/**
|
|
13
|
+
* Whether this module is being executed from TypeScript source (via `tsx`)
|
|
14
|
+
* rather than from compiled output. Source execution always reflects the
|
|
15
|
+
* latest code, so there is no compiled build that could be stale.
|
|
16
|
+
*/
|
|
17
|
+
const RUNNING_FROM_SOURCE = fileURLToPath(import.meta.url).endsWith('.ts');
|
|
18
|
+
const buildInfoCache = new Map();
|
|
19
|
+
/**
|
|
20
|
+
* Read the `version` field from `package.json`. Prefers the project root the
|
|
21
|
+
* watcher is running against and falls back to the osq package itself, so an
|
|
22
|
+
* installed consumer that carries no `package.json` still reports a version.
|
|
23
|
+
*/
|
|
24
|
+
async function readVersion(projectRoot) {
|
|
25
|
+
const candidates = [
|
|
26
|
+
path.join(projectRoot, 'package.json'),
|
|
27
|
+
path.join(PACKAGE_ROOT, 'package.json'),
|
|
28
|
+
];
|
|
29
|
+
for (const candidate of candidates) {
|
|
30
|
+
try {
|
|
31
|
+
const raw = await fs.readFile(candidate, 'utf8');
|
|
32
|
+
const parsed = JSON.parse(raw);
|
|
33
|
+
if (typeof parsed.version === 'string' && parsed.version.trim().length > 0) {
|
|
34
|
+
return parsed.version.trim();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Missing or malformed file: try the next candidate.
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return UNKNOWN;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* SHA-256 over every file under `dist/`, first 8 hex characters. Paths are
|
|
45
|
+
* sorted so the hash is stable across filesystems; the relative path is folded
|
|
46
|
+
* in so a rename changes the hash even when contents do not. Returns `unknown`
|
|
47
|
+
* when `dist/` is absent or empty.
|
|
48
|
+
*/
|
|
49
|
+
async function hashDist(projectRoot) {
|
|
50
|
+
const distDir = path.join(projectRoot, 'dist');
|
|
51
|
+
const files = [];
|
|
52
|
+
const walk = async (dir) => {
|
|
53
|
+
let entries;
|
|
54
|
+
try {
|
|
55
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
for (const entry of entries) {
|
|
61
|
+
const full = path.join(dir, entry.name);
|
|
62
|
+
if (entry.isDirectory()) {
|
|
63
|
+
await walk(full);
|
|
64
|
+
}
|
|
65
|
+
else if (entry.isFile()) {
|
|
66
|
+
files.push(full);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
await walk(distDir);
|
|
71
|
+
if (files.length === 0) {
|
|
72
|
+
return UNKNOWN;
|
|
73
|
+
}
|
|
74
|
+
files.sort();
|
|
75
|
+
const hash = createHash('sha256');
|
|
76
|
+
for (const file of files) {
|
|
77
|
+
const relative = path.relative(distDir, file).split(path.sep).join('/');
|
|
78
|
+
hash.update(relative);
|
|
79
|
+
hash.update('\0');
|
|
80
|
+
hash.update(await fs.readFile(file));
|
|
81
|
+
hash.update('\0');
|
|
82
|
+
}
|
|
83
|
+
return hash.digest('hex').slice(0, 8);
|
|
84
|
+
}
|
|
85
|
+
/** Short git commit for `cwd`, or `null` when git is missing / not a repo. */
|
|
86
|
+
function readGitCommit(cwd) {
|
|
87
|
+
return new Promise((resolve) => {
|
|
88
|
+
execFile('git', ['rev-parse', '--short', 'HEAD'], { cwd }, (error, stdout) => {
|
|
89
|
+
if (error) {
|
|
90
|
+
resolve(null);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const commit = String(stdout).trim();
|
|
94
|
+
resolve(commit.length > 0 ? commit : null);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolve the active osq build identity. Version comes from `package.json`;
|
|
100
|
+
* the commit is the short git SHA when available, otherwise a hash of `dist/`,
|
|
101
|
+
* otherwise `unknown`. The result is cached per resolved root so the watcher
|
|
102
|
+
* pays the git spawn at most once.
|
|
103
|
+
*/
|
|
104
|
+
export async function resolveBuildInfo(projectRoot) {
|
|
105
|
+
const root = path.resolve(projectRoot ?? PACKAGE_ROOT);
|
|
106
|
+
const cached = buildInfoCache.get(root);
|
|
107
|
+
if (cached) {
|
|
108
|
+
return cached;
|
|
109
|
+
}
|
|
110
|
+
const [version, gitCommit] = await Promise.all([readVersion(root), readGitCommit(root)]);
|
|
111
|
+
const commit = gitCommit ?? (await hashDist(root));
|
|
112
|
+
const info = { version, commit };
|
|
113
|
+
buildInfoCache.set(root, info);
|
|
114
|
+
return info;
|
|
115
|
+
}
|
|
116
|
+
/** Newest `mtimeMs` among every file below `dir`, or 0 when none exist. */
|
|
117
|
+
async function newestMtimeMs(dir) {
|
|
118
|
+
let entries;
|
|
119
|
+
try {
|
|
120
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return 0;
|
|
124
|
+
}
|
|
125
|
+
let newest = 0;
|
|
126
|
+
for (const entry of entries) {
|
|
127
|
+
const full = path.join(dir, entry.name);
|
|
128
|
+
if (entry.isDirectory()) {
|
|
129
|
+
newest = Math.max(newest, await newestMtimeMs(full));
|
|
130
|
+
}
|
|
131
|
+
else if (entry.isFile()) {
|
|
132
|
+
const stat = await fs.stat(full).catch(() => null);
|
|
133
|
+
if (stat) {
|
|
134
|
+
newest = Math.max(newest, stat.mtimeMs);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return newest;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Refuse to run a compiled osq build whose `dist/` is older than `src/` when
|
|
142
|
+
* started from a repository checkout. An installed package carries no `src/`
|
|
143
|
+
* and is never considered stale. Prints exactly one error line and exits with
|
|
144
|
+
* code 1 when stale, so a developer rebuilds instead of debugging a phantom.
|
|
145
|
+
*/
|
|
146
|
+
export async function checkStaleBuild(options = {}) {
|
|
147
|
+
if (options.allowStale === true) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
// Executing from TypeScript source means the running code *is* the latest
|
|
151
|
+
// source, so there is no compiled output that can be stale. An explicit
|
|
152
|
+
// `packageRoot` (tests, diagnostics) always performs the comparison.
|
|
153
|
+
if (options.packageRoot === undefined && RUNNING_FROM_SOURCE) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const packageRoot = options.packageRoot ? path.resolve(options.packageRoot) : PACKAGE_ROOT;
|
|
157
|
+
const srcDir = path.join(packageRoot, 'src');
|
|
158
|
+
const srcStat = await fs.stat(srcDir).catch(() => null);
|
|
159
|
+
if (!srcStat?.isDirectory()) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const srcNewest = await newestMtimeMs(srcDir);
|
|
163
|
+
const distNewest = await newestMtimeMs(path.join(packageRoot, 'dist'));
|
|
164
|
+
if (srcNewest > distNewest) {
|
|
165
|
+
console.error("osq build is stale: src/ is newer than dist/. Run 'npm run build' or pass --allow-stale.");
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/watcher/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { OsqConfig } from '../core/foundation/config.js';
|
|
2
|
+
import { type VerificationGateResult } from './verify.js';
|
|
3
|
+
/** Failure evidence for a red change gate; the runner writes it through `fail`. */
|
|
4
|
+
export interface ChangeVerifyFailure {
|
|
5
|
+
marker: string;
|
|
6
|
+
error: string;
|
|
7
|
+
extra?: string;
|
|
8
|
+
}
|
|
9
|
+
export type ChangeVerifyOutcome = {
|
|
10
|
+
ok: true;
|
|
11
|
+
} | ({
|
|
12
|
+
ok: false;
|
|
13
|
+
} & ChangeVerifyFailure);
|
|
14
|
+
/** Deterministic marker with reason, command, numeric exit code, timeout, output. */
|
|
15
|
+
export declare function formatChangeVerifyMarker(command: string, result: VerificationGateResult): string;
|
|
16
|
+
/** Marker used when an approved proposal exposes no change-level verify command. */
|
|
17
|
+
export declare function formatMissingChangeVerifyMarker(): string;
|
|
18
|
+
/**
|
|
19
|
+
* Run the proposal's change-level verify after a passing task verify. Returns a
|
|
20
|
+
* passing outcome when the gate is disabled or green, otherwise failure
|
|
21
|
+
* evidence for the runner's single `fail` path. The shared gate entrypoint owns
|
|
22
|
+
* the single `verify_ran` event, attributed to the established `change` target.
|
|
23
|
+
*/
|
|
24
|
+
export declare function runChangeVerifyGate(projectRoot: string, specFolderPath: string, config: OsqConfig): Promise<ChangeVerifyOutcome>;
|
|
25
|
+
//# sourceMappingURL=change-verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-verify.d.ts","sourceRoot":"","sources":["../../src/watcher/change-verify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,EAAE,KAAK,sBAAsB,EAA6B,MAAM,aAAa,CAAC;AAErF,mFAAmF;AACnF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,mBAAmB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,CAAC;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,GAAG,mBAAmB,CAAC,CAAC;AAEvF,qFAAqF;AACrF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAahG;AAED,oFAAoF;AACpF,wBAAgB,+BAA+B,IAAI,MAAM,CAQxD;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,mBAAmB,CAAC,CA4B9B"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { parseSpecMdFromFolder } from '../core/spec/parser.js';
|
|
2
|
+
import { runVerificationGateResult } from './verify.js';
|
|
3
|
+
/** Deterministic marker with reason, command, numeric exit code, timeout, output. */
|
|
4
|
+
export function formatChangeVerifyMarker(command, result) {
|
|
5
|
+
const output = result.output.trim() || '(no output)';
|
|
6
|
+
return [
|
|
7
|
+
'---',
|
|
8
|
+
'reason: change_verify_red',
|
|
9
|
+
...(result.timedOut ? ['timed_out: true'] : []),
|
|
10
|
+
`command: ${JSON.stringify(command)}`,
|
|
11
|
+
`exit_code: ${result.exitCode}`,
|
|
12
|
+
'---',
|
|
13
|
+
`Change-level verification ${result.timedOut ? 'timed out' : 'failed'} after task verification passed.`,
|
|
14
|
+
output,
|
|
15
|
+
'',
|
|
16
|
+
].join('\n');
|
|
17
|
+
}
|
|
18
|
+
/** Marker used when an approved proposal exposes no change-level verify command. */
|
|
19
|
+
export function formatMissingChangeVerifyMarker() {
|
|
20
|
+
return [
|
|
21
|
+
'---',
|
|
22
|
+
'reason: change_verify_red',
|
|
23
|
+
'---',
|
|
24
|
+
'Proposal change-level verify is missing or unreadable; cannot gate task completion.',
|
|
25
|
+
'',
|
|
26
|
+
].join('\n');
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Run the proposal's change-level verify after a passing task verify. Returns a
|
|
30
|
+
* passing outcome when the gate is disabled or green, otherwise failure
|
|
31
|
+
* evidence for the runner's single `fail` path. The shared gate entrypoint owns
|
|
32
|
+
* the single `verify_ran` event, attributed to the established `change` target.
|
|
33
|
+
*/
|
|
34
|
+
export async function runChangeVerifyGate(projectRoot, specFolderPath, config) {
|
|
35
|
+
if (config.gates?.changeVerifyAfterTask === false)
|
|
36
|
+
return { ok: true };
|
|
37
|
+
const specData = await parseSpecMdFromFolder(specFolderPath);
|
|
38
|
+
const command = specData?.verify ?? '';
|
|
39
|
+
if (!command) {
|
|
40
|
+
return {
|
|
41
|
+
ok: false,
|
|
42
|
+
marker: formatMissingChangeVerifyMarker(),
|
|
43
|
+
error: 'Change-level verify command is missing',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const result = await runVerificationGateResult(projectRoot, command, config.timeouts.verifyTimeoutSeconds ?? 600, { specFolderPath, taskNumber: 'change' });
|
|
47
|
+
if (result.passed)
|
|
48
|
+
return { ok: true };
|
|
49
|
+
const output = result.output.trim() || '(no output)';
|
|
50
|
+
return {
|
|
51
|
+
ok: false,
|
|
52
|
+
marker: formatChangeVerifyMarker(command, result),
|
|
53
|
+
error: result.error ?? `Change verify failed: ${output}`,
|
|
54
|
+
...(result.timedOut ? { extra: 'timed_out: true' } : {}),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=change-verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-verify.js","sourceRoot":"","sources":["../../src/watcher/change-verify.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAA+B,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAWrF,qFAAqF;AACrF,MAAM,UAAU,wBAAwB,CAAC,OAAe,EAAE,MAA8B;IACtF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,aAAa,CAAC;IACrD,OAAO;QACL,KAAK;QACL,2BAA2B;QAC3B,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,YAAY,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;QACrC,cAAc,MAAM,CAAC,QAAQ,EAAE;QAC/B,KAAK;QACL,6BAA6B,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,kCAAkC;QACvG,MAAM;QACN,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,+BAA+B;IAC7C,OAAO;QACL,KAAK;QACL,2BAA2B;QAC3B,KAAK;QACL,qFAAqF;QACrF,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,WAAmB,EACnB,cAAsB,EACtB,MAAiB;IAEjB,IAAI,MAAM,CAAC,KAAK,EAAE,qBAAqB,KAAK,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAEvE,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,cAAc,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,QAAQ,EAAE,MAAM,IAAI,EAAE,CAAC;IACvC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,+BAA+B,EAAE;YACzC,KAAK,EAAE,wCAAwC;SAChD,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAC5C,WAAW,EACX,OAAO,EACP,MAAM,CAAC,QAAQ,CAAC,oBAAoB,IAAI,GAAG,EAC3C,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,CACzC,CAAC;IACF,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAEvC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,aAAa,CAAC;IACrD,OAAO;QACL,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,wBAAwB,CAAC,OAAO,EAAE,MAAM,CAAC;QACjD,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,yBAAyB,MAAM,EAAE;QACxD,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzD,CAAC;AACJ,CAAC"}
|