okstra 0.186.7 → 0.188.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 +1 -1
- package/dist/cli-registry.d.mts +88 -1
- package/dist/cli-registry.mjs +68 -111
- package/dist/cli-registry.mjs.map +1 -1
- package/dist/commands/execute/render-bundle.mjs +0 -1
- package/dist/commands/execute/render-bundle.mjs.map +1 -1
- package/dist/commands/execute/run.mjs +8 -3
- package/dist/commands/execute/run.mjs.map +1 -1
- package/dist/commands/lifecycle/check-project.mjs +1 -14
- package/dist/commands/lifecycle/check-project.mjs.map +1 -1
- package/dist/commands/lifecycle/config.mjs +38 -40
- package/dist/commands/lifecycle/config.mjs.map +1 -1
- package/dist/commands/lifecycle/doctor.d.mts +22 -7
- package/dist/commands/lifecycle/doctor.mjs +77 -49
- package/dist/commands/lifecycle/doctor.mjs.map +1 -1
- package/dist/commands/lifecycle/install.d.mts +12 -10
- package/dist/commands/lifecycle/install.mjs +107 -40
- package/dist/commands/lifecycle/install.mjs.map +1 -1
- package/dist/commands/lifecycle/paths.mjs +8 -3
- package/dist/commands/lifecycle/paths.mjs.map +1 -1
- package/dist/commands/lifecycle/preflight.mjs +2 -1
- package/dist/commands/lifecycle/preflight.mjs.map +1 -1
- package/dist/commands/lifecycle/setup.mjs +22 -36
- package/dist/commands/lifecycle/setup.mjs.map +1 -1
- package/dist/commands/lifecycle/uninstall.d.mts +4 -2
- package/dist/commands/lifecycle/uninstall.mjs +59 -15
- package/dist/commands/lifecycle/uninstall.mjs.map +1 -1
- package/dist/commands/memory/memory.mjs +7 -1
- package/dist/commands/memory/memory.mjs.map +1 -1
- package/dist/lib/helper-scripts.d.mts +1 -1
- package/dist/lib/helper-scripts.mjs +10 -18
- package/dist/lib/helper-scripts.mjs.map +1 -1
- package/dist/lib/host-config.d.mts +72 -0
- package/dist/lib/host-config.mjs +404 -0
- package/dist/lib/host-config.mjs.map +1 -0
- package/dist/lib/host-registry-client.d.mts +2 -2
- package/dist/lib/host-registry-client.mjs +0 -3
- package/dist/lib/host-registry-client.mjs.map +1 -1
- package/dist/lib/install-assets.d.mts +1 -0
- package/dist/lib/install-assets.mjs +4 -0
- package/dist/lib/install-assets.mjs.map +1 -1
- package/dist/lib/proc.d.mts +2 -0
- package/dist/lib/proc.mjs +12 -0
- package/dist/lib/proc.mjs.map +1 -1
- package/dist/lib/python-command.d.mts +2 -0
- package/dist/lib/python-command.mjs +52 -0
- package/dist/lib/python-command.mjs.map +1 -0
- package/dist/lib/python-helper.d.mts +2 -5
- package/dist/lib/python-helper.mjs +3 -52
- package/dist/lib/python-helper.mjs.map +1 -1
- package/dist/lib/runtime-payload.d.mts +23 -0
- package/dist/lib/runtime-payload.mjs +57 -0
- package/dist/lib/runtime-payload.mjs.map +1 -0
- package/dist/lib/types.d.mts +24 -13
- package/docs/architecture/storage-model.md +21 -5
- package/docs/architecture.md +39 -38
- package/docs/cli.md +55 -76
- package/docs/coding-rules.md +295 -0
- package/docs/container.md +10 -36
- package/docs/contributor-change-matrix.md +1 -1
- package/docs/for-ai/skills/okstra-code-review.md +0 -1
- package/docs/for-ai/skills/okstra-container-build.md +8 -41
- package/docs/for-ai/skills/okstra-inspect.md +4 -4
- package/docs/for-ai/skills/okstra-manager.md +2 -2
- package/docs/for-ai/skills/okstra-rollup.md +0 -1
- package/docs/for-ai/skills/okstra-run.md +3 -3
- package/docs/for-ai/skills/okstra-user-response.md +0 -1
- package/docs/performance-improvement-plan-v2.md +1 -1
- package/docs/project-structure-overview.md +62 -62
- package/docs/task-process/README.md +3 -3
- package/docs/task-process/common-flow.md +1 -1
- package/docs/task-process/error-analysis.md +3 -3
- package/docs/task-process/implementation-planning.md +3 -1
- package/docs/task-process/release-handoff.md +1 -1
- package/package.json +3 -2
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/claude-worker.md +6 -11
- package/runtime/agents/workers/report-writer-worker.md +1 -1
- package/runtime/bin/lib/okstra/cli.sh +4 -0
- package/runtime/bin/lib/okstra/globals.sh +2 -0
- package/runtime/bin/lib/okstra/interactive.sh +26 -173
- package/runtime/bin/lib/okstra/project-resolver.sh +23 -61
- package/runtime/bin/lib/okstra/usage.sh +3 -3
- package/runtime/bin/okstra-compact-reminder.sh +1 -5
- package/runtime/bin/okstra-error-log.py +19 -2
- package/runtime/bin/okstra-import-check.py +26 -0
- package/runtime/bin/okstra-inject-report-index.py +5 -4
- package/runtime/bin/okstra-provider-exec.py +22 -17
- package/runtime/bin/okstra-render-final-report.py +16 -6
- package/runtime/bin/okstra-render-report-views.py +47 -22
- package/runtime/bin/okstra-report-translate.py +30 -18
- package/runtime/bin/okstra-spawn-followups.py +4 -0
- package/runtime/bin/okstra-token-usage.py +3 -0
- package/runtime/bin/okstra.sh +4 -2
- package/runtime/bin/okstra_bootstrap.py +58 -0
- package/runtime/prompts/coding-preflight/overview.md +1 -1
- package/runtime/prompts/duties/planning-worker.md +1 -1
- package/runtime/prompts/launch.template.md +35 -9
- package/runtime/prompts/lead/adapters/cmux.md +3 -3
- package/runtime/prompts/lead/convergence.md +99 -88
- package/runtime/prompts/lead/okstra-lead-contract.md +63 -12
- package/runtime/prompts/lead/plan-body-verification.md +65 -46
- package/runtime/prompts/lead/report-writer.md +35 -5
- package/runtime/prompts/lead/team-contract.md +4 -1
- package/runtime/prompts/profiles/_clarification-recommendation.md +2 -1
- package/runtime/prompts/profiles/_coding-conventions-preflight.md +1 -1
- package/runtime/prompts/profiles/_common-contract.md +3 -3
- package/runtime/prompts/profiles/_coverage-critic.md +1 -1
- package/runtime/prompts/profiles/_implementation-deliverable.md +2 -2
- package/runtime/prompts/profiles/_implementation-executor.md +3 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +16 -2
- package/runtime/prompts/profiles/error-analysis.md +4 -3
- package/runtime/prompts/profiles/final-verification.md +2 -2
- package/runtime/prompts/profiles/implementation-planning.md +22 -17
- package/runtime/prompts/profiles/implementation.md +3 -2
- package/runtime/prompts/profiles/requirements-discovery.md +2 -1
- package/runtime/prompts/wizard/prompts.ko.json +29 -8
- package/runtime/python/okstra_ctl/__init__.py +6 -27
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +4 -5
- package/runtime/python/okstra_ctl/adapters/hosts/codex/adapter.py +21 -2
- package/runtime/python/okstra_ctl/adapters/hosts/external/adapter.py +3 -12
- package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +63 -22
- package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +20 -21
- package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +37 -20
- package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +86 -14
- package/runtime/python/okstra_ctl/adapters/providers/kimi/adapter.py +12 -12
- package/runtime/python/okstra_ctl/adapters/runtime/cmux.py +4 -7
- package/runtime/python/okstra_ctl/agent/__init__.py +1 -0
- package/runtime/python/okstra_ctl/{agent_activity.py → agent/activity.py} +16 -2
- package/runtime/python/okstra_ctl/{agent_invocation.py → agent/invocation.py} +34 -5
- package/runtime/python/okstra_ctl/agent/prompt_cli/__init__.py +19 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/__main__.py +11 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/cli.py +228 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/dynamic_verifier.py +155 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/emit.py +66 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/inputs.py +138 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/materialize.py +605 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/results.py +197 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/run_identity.py +107 -0
- package/runtime/python/okstra_ctl/analysis_packet.py +47 -4
- package/runtime/python/okstra_ctl/approval_decisions.py +287 -10
- package/runtime/python/okstra_ctl/assignment_resolver.py +0 -12
- package/runtime/python/okstra_ctl/attempt_evidence.py +12 -24
- package/runtime/python/okstra_ctl/blocking_checks.py +251 -0
- package/runtime/python/okstra_ctl/brief_frontmatter.py +0 -7
- package/runtime/python/okstra_ctl/clarification_items/__init__.py +102 -0
- package/runtime/python/okstra_ctl/clarification_items/carry.py +224 -0
- package/runtime/python/okstra_ctl/clarification_items/dispositions.py +135 -0
- package/runtime/python/okstra_ctl/clarification_items/parsing.py +253 -0
- package/runtime/python/okstra_ctl/clarification_items/rows.py +115 -0
- package/runtime/python/okstra_ctl/clarification_items/scan.py +215 -0
- package/runtime/python/okstra_ctl/clarification_items/sidecars.py +211 -0
- package/runtime/python/okstra_ctl/cmux.py +38 -31
- package/runtime/python/okstra_ctl/code_review_target.py +163 -1
- package/runtime/python/okstra_ctl/conformance.py +23 -0
- package/runtime/python/okstra_ctl/container.py +38 -421
- package/runtime/python/okstra_ctl/context_cost.py +32 -4
- package/runtime/python/okstra_ctl/contract_graph_cli.py +7 -0
- package/runtime/python/okstra_ctl/convergence.py +107 -16
- package/runtime/python/okstra_ctl/convergence_critic_prompt.py +345 -0
- package/runtime/python/okstra_ctl/convergence_engine.py +382 -70
- package/runtime/python/okstra_ctl/convergence_store.py +5 -29
- package/runtime/python/okstra_ctl/design_prep.py +108 -12
- package/runtime/python/okstra_ctl/design_snapshot.py +11 -1
- package/runtime/python/okstra_ctl/design_surfaces.py +29 -2
- package/runtime/python/okstra_ctl/dispatch_core.py +236 -49
- package/runtime/python/okstra_ctl/dispatch_state.py +417 -41
- package/runtime/python/okstra_ctl/doctor_cli.py +48 -0
- package/runtime/python/okstra_ctl/domain/worker_exec.py +10 -5
- package/runtime/python/okstra_ctl/domain/worker_presentation.py +28 -1
- package/runtime/python/okstra_ctl/domain/worker_stream.py +52 -21
- package/runtime/python/okstra_ctl/domain/write_policy.py +219 -0
- package/runtime/python/okstra_ctl/entrypoints/hosts.py +9 -2
- package/runtime/python/okstra_ctl/error_log_core.py +1 -1
- package/runtime/python/okstra_ctl/error_report.py +14 -0
- package/runtime/python/okstra_ctl/error_zip.py +18 -2
- package/runtime/python/okstra_ctl/exact_coverage.py +5 -0
- package/runtime/python/okstra_ctl/execution_identity.py +100 -7
- package/runtime/python/okstra_ctl/execution_manifest.py +67 -20
- package/runtime/python/okstra_ctl/execution_mutation_audit.py +90 -8
- package/runtime/python/okstra_ctl/final_report_paths.py +17 -0
- package/runtime/python/okstra_ctl/final_report_schema.py +319 -17
- package/runtime/python/okstra_ctl/git_reconcile.py +22 -2
- package/runtime/python/okstra_ctl/handoff.py +24 -1
- package/runtime/python/okstra_ctl/ids.py +6 -16
- package/runtime/python/okstra_ctl/implementation_direction.py +142 -33
- package/runtime/python/okstra_ctl/implementation_options.py +32 -13
- package/runtime/python/okstra_ctl/implementation_outcome.py +5 -2
- package/runtime/python/okstra_ctl/improvement_lenses.py +0 -14
- package/runtime/python/okstra_ctl/incremental_carry.py +69 -8
- package/runtime/python/okstra_ctl/incremental_scope.py +173 -12
- package/runtime/python/okstra_ctl/index.py +2 -2
- package/runtime/python/okstra_ctl/initial_prompt_materialization.py +48 -8
- package/runtime/python/okstra_ctl/interactive_cli.py +223 -0
- package/runtime/python/okstra_ctl/json_boundary.py +10 -0
- package/runtime/python/okstra_ctl/listing.py +0 -91
- package/runtime/python/okstra_ctl/locks.py +5 -19
- package/runtime/python/okstra_ctl/log_report.py +14 -0
- package/runtime/python/okstra_ctl/manager_cli.py +22 -3
- package/runtime/python/okstra_ctl/manager_launch.py +4 -8
- package/runtime/python/okstra_ctl/material.py +2 -2
- package/runtime/python/okstra_ctl/migrate.py +23 -1
- package/runtime/python/okstra_ctl/model_cli.py +19 -5
- package/runtime/python/okstra_ctl/model_discovery.py +46 -47
- package/runtime/python/okstra_ctl/model_io/__init__.py +1 -0
- package/runtime/python/okstra_ctl/model_io/lines.py +163 -0
- package/runtime/python/okstra_ctl/model_io/references.py +370 -0
- package/runtime/python/okstra_ctl/model_io/renderers.py +498 -0
- package/runtime/python/okstra_ctl/model_io_cli.py +30 -945
- package/runtime/python/okstra_ctl/model_pool.py +10 -6
- package/runtime/python/okstra_ctl/models.py +8 -8
- package/runtime/python/okstra_ctl/mutation_recovery.py +5 -63
- package/runtime/python/okstra_ctl/next_phase.py +121 -69
- package/runtime/python/okstra_ctl/pane_reclaim.py +23 -0
- package/runtime/python/okstra_ctl/pane_title.py +11 -8
- package/runtime/python/okstra_ctl/path_hints.py +36 -11
- package/runtime/python/okstra_ctl/paths.py +76 -8
- package/runtime/python/okstra_ctl/plan_items.py +132 -16
- package/runtime/python/okstra_ctl/plan_items_cli.py +486 -36
- package/runtime/python/okstra_ctl/plan_run_root.py +1 -1
- package/runtime/python/okstra_ctl/plan_validate_cli.py +51 -0
- package/runtime/python/okstra_ctl/plan_verify_cli.py +80 -0
- package/runtime/python/okstra_ctl/prepare_error.py +20 -0
- package/runtime/python/okstra_ctl/prior_planning.py +157 -0
- package/runtime/python/okstra_ctl/profile_show.py +18 -1
- package/runtime/python/okstra_ctl/project_setup_cli.py +140 -0
- package/runtime/python/okstra_ctl/recap.py +22 -1
- package/runtime/python/okstra_ctl/reconcile.py +84 -0
- package/runtime/python/okstra_ctl/registry/host_registry.py +18 -1
- package/runtime/python/okstra_ctl/render.py +98 -32
- package/runtime/python/okstra_ctl/render_final_report.py +4 -8
- package/runtime/python/okstra_ctl/report_assembly.py +297 -7
- package/runtime/python/okstra_ctl/report_contract.py +30 -7
- package/runtime/python/okstra_ctl/report_finalize.py +213 -16
- package/runtime/python/okstra_ctl/report_html/common.py +2 -2
- package/runtime/python/okstra_ctl/report_html/render.py +8 -12
- package/runtime/python/okstra_ctl/report_language.py +8 -4
- package/runtime/python/okstra_ctl/report_narrative.py +220 -34
- package/runtime/python/okstra_ctl/report_projections.py +8 -2
- package/runtime/python/okstra_ctl/report_synthesis_packet.py +393 -1
- package/runtime/python/okstra_ctl/report_translation.py +2 -35
- package/runtime/python/okstra_ctl/report_view_artifacts.py +42 -2
- package/runtime/python/okstra_ctl/report_views.py +4 -22
- package/runtime/python/okstra_ctl/resolve_task_key.py +13 -0
- package/runtime/python/okstra_ctl/rollup.py +13 -0
- package/runtime/python/okstra_ctl/run.py +639 -138
- package/runtime/python/okstra_ctl/run_audit.py +13 -0
- package/runtime/python/okstra_ctl/run_index_row.py +0 -12
- package/runtime/python/okstra_ctl/seeding.py +21 -11
- package/runtime/python/okstra_ctl/sequence.py +1 -1
- package/runtime/python/okstra_ctl/session.py +64 -14
- package/runtime/python/okstra_ctl/set_work_status.py +18 -0
- package/runtime/python/okstra_ctl/stage_integrate.py +15 -1
- package/runtime/python/okstra_ctl/stage_ledger.py +1 -1
- package/runtime/python/okstra_ctl/stage_map.py +57 -11
- package/runtime/python/okstra_ctl/stage_map_cli.py +83 -0
- package/runtime/python/okstra_ctl/stage_map_view.py +65 -0
- package/runtime/python/okstra_ctl/stage_targets.py +3 -12
- package/runtime/python/okstra_ctl/task_list_cli.py +138 -0
- package/runtime/python/okstra_ctl/task_show_cli.py +66 -0
- package/runtime/python/okstra_ctl/task_target.py +4 -16
- package/runtime/python/okstra_ctl/team.py +49 -2
- package/runtime/python/okstra_ctl/time_report.py +17 -2
- package/runtime/python/okstra_ctl/usage_report.py +11 -0
- package/runtime/python/okstra_ctl/user_response.py +55 -218
- package/runtime/python/okstra_ctl/user_response_values.py +242 -0
- package/runtime/python/okstra_ctl/validation_contract.py +3 -0
- package/runtime/python/okstra_ctl/verdict_blocks.py +28 -8
- package/runtime/python/okstra_ctl/verification_target.py +68 -0
- package/runtime/python/okstra_ctl/wizard.py +457 -92
- package/runtime/python/okstra_ctl/worker_artifacts.py +75 -16
- package/runtime/python/okstra_ctl/worker_audit_check.py +22 -0
- package/runtime/python/okstra_ctl/worker_dispatch.py +21 -0
- package/runtime/python/okstra_ctl/worker_liveness.py +33 -0
- package/runtime/python/okstra_ctl/worker_prompt_body.py +15 -2
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +98 -7
- package/runtime/python/okstra_ctl/worker_prompt_headers.py +24 -2
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +18 -3
- package/runtime/python/okstra_ctl/worker_request.py +2 -1
- package/runtime/python/okstra_ctl/worker_runner.py +58 -17
- package/runtime/python/okstra_ctl/worker_state.py +16 -1
- package/runtime/python/okstra_ctl/workflow.py +18 -1
- package/runtime/python/okstra_ctl/worktree/__init__.py +92 -0
- package/runtime/python/okstra_ctl/worktree/cleanliness.py +89 -0
- package/runtime/python/okstra_ctl/worktree/decisions.py +127 -0
- package/runtime/python/okstra_ctl/worktree/git_ops.py +165 -0
- package/runtime/python/okstra_ctl/worktree/linking.py +249 -0
- package/runtime/python/okstra_ctl/worktree/naming.py +91 -0
- package/runtime/python/okstra_ctl/worktree/provision.py +385 -0
- package/runtime/python/okstra_ctl/worktree/sync_config.py +181 -0
- package/runtime/python/okstra_ctl/worktree_cli.py +75 -0
- package/runtime/python/okstra_ctl/worktree_lookup_cli.py +39 -0
- package/runtime/python/okstra_ctl/worktree_registry.py +7 -0
- package/runtime/python/okstra_ctl/worktree_status_cli.py +53 -0
- package/runtime/python/okstra_ctl/write_policy.py +90 -213
- package/runtime/python/okstra_project/__init__.py +0 -4
- package/runtime/python/okstra_project/dirs.py +2 -2
- package/runtime/python/okstra_project/phase_pointer.py +84 -0
- package/runtime/python/okstra_project/slug.py +24 -0
- package/runtime/python/okstra_project/state.py +22 -230
- package/runtime/python/okstra_token_usage/antigravity.py +50 -12
- package/runtime/python/okstra_token_usage/claude.py +9 -1
- package/runtime/python/okstra_token_usage/cli.py +3 -1
- package/runtime/python/okstra_token_usage/collect.py +171 -36
- package/runtime/python/okstra_token_usage/cursor.py +2 -0
- package/runtime/python/okstra_token_usage/grok.py +1 -5
- package/runtime/python/okstra_token_usage/paths.py +26 -0
- package/runtime/python/okstra_token_usage/pricing.py +23 -8
- package/runtime/schemas/convergence-critic-results-v1.0.schema.json +5 -0
- package/runtime/schemas/execution-manifest-v2.schema.json +10 -10
- package/runtime/schemas/final-report-v2.0.schema.json +9 -26
- package/runtime/schemas/final-report-v3.0.schema.json +173 -41
- package/runtime/schemas/report-narrative-v3.0.schema.json +3 -2
- package/runtime/skills/okstra-brief-gen/SKILL.md +35 -2
- package/runtime/skills/okstra-container-build/SKILL.md +16 -47
- package/runtime/skills/okstra-inspect/facets/history.md +1 -1
- package/runtime/skills/okstra-inspect/facets/status.md +7 -6
- package/runtime/skills/okstra-pr-gen/SKILL.md +1 -1
- package/runtime/skills/okstra-run/SKILL.md +7 -5
- package/runtime/templates/report-writer-prompt-preamble.md +3 -1
- package/runtime/templates/reports/brief.template.md +6 -2
- package/runtime/templates/reports/error-analysis-input.template.md +2 -0
- package/runtime/templates/reports/final-verification-input.template.md +2 -0
- package/runtime/templates/reports/implementation-input.template.md +7 -1
- package/runtime/templates/reports/implementation-planning-input.template.md +4 -0
- package/runtime/templates/reports/quick-input.template.md +2 -0
- package/runtime/templates/reports/release-handoff-input.template.md +6 -1
- package/runtime/templates/reports/report.js +20 -3
- package/runtime/templates/reports/schedule.template.md +2 -0
- package/runtime/templates/reports/settings.template.json +0 -10
- package/runtime/templates/reports/task-brief.template.md +3 -0
- package/runtime/templates/reports/user-response.template.md +7 -3
- package/runtime/validators/checks/fixtures-01.py +57 -0
- package/runtime/validators/checks/fixtures-02.py +565 -0
- package/runtime/validators/checks/runners-01.py +108 -0
- package/runtime/validators/checks/validate-assets-01.py +60 -0
- package/runtime/validators/checks/validate-prompt-metadata-01.py +261 -0
- package/runtime/validators/checks/validate-tasks-01.py +46 -0
- package/runtime/validators/checks/validate-tasks-02.py +85 -0
- package/runtime/validators/checks/validate-tasks-03.py +61 -0
- package/runtime/validators/checks/validate-tasks-04.py +118 -0
- package/runtime/validators/forbidden_actions.py +73 -3
- package/runtime/validators/lib/common.sh +5 -0
- package/runtime/validators/lib/fixtures.sh +7 -591
- package/runtime/validators/lib/paths.sh +13 -0
- package/runtime/validators/lib/runners.sh +6 -104
- package/runtime/validators/lib/summary.sh +1 -1
- package/runtime/validators/lib/validate-assets.sh +6 -56
- package/runtime/validators/lib/validate-prompt-metadata.sh +6 -257
- package/runtime/validators/lib/validate-tasks.sh +9 -294
- package/runtime/validators/validate-implementation-plan-stages.py +4 -4
- package/runtime/validators/validate-run.py +1363 -2643
- package/runtime/validators/validate-workflow.sh +56 -16
- package/runtime/validators/validate_improvement_report.py +2 -1
- package/runtime/validators/validate_session_conformance.py +295 -49
- package/dist/commands/execute/agent-prompt.d.mts +0 -1
- package/dist/commands/execute/agent-prompt.mjs +0 -24
- package/dist/commands/execute/agent-prompt.mjs.map +0 -1
- package/dist/commands/execute/codex-dispatch.d.mts +0 -3
- package/dist/commands/execute/codex-dispatch.mjs +0 -6
- package/dist/commands/execute/codex-dispatch.mjs.map +0 -1
- package/dist/commands/execute/codex-run.d.mts +0 -3
- package/dist/commands/execute/codex-run.mjs +0 -62
- package/dist/commands/execute/codex-run.mjs.map +0 -1
- package/dist/commands/execute/convergence.d.mts +0 -1
- package/dist/commands/execute/convergence.mjs +0 -38
- package/dist/commands/execute/convergence.mjs.map +0 -1
- package/dist/commands/execute/error-log.d.mts +0 -1
- package/dist/commands/execute/error-log.mjs +0 -18
- package/dist/commands/execute/error-log.mjs.map +0 -1
- package/dist/commands/execute/git-reconcile.d.mts +0 -1
- package/dist/commands/execute/git-reconcile.mjs +0 -30
- package/dist/commands/execute/git-reconcile.mjs.map +0 -1
- package/dist/commands/execute/handoff.d.mts +0 -1
- package/dist/commands/execute/handoff.mjs +0 -31
- package/dist/commands/execute/handoff.mjs.map +0 -1
- package/dist/commands/execute/incremental-carry.d.mts +0 -1
- package/dist/commands/execute/incremental-carry.mjs +0 -20
- package/dist/commands/execute/incremental-carry.mjs.map +0 -1
- package/dist/commands/execute/incremental-scope.d.mts +0 -1
- package/dist/commands/execute/incremental-scope.mjs +0 -29
- package/dist/commands/execute/incremental-scope.mjs.map +0 -1
- package/dist/commands/execute/integrate-stages.d.mts +0 -1
- package/dist/commands/execute/integrate-stages.mjs +0 -24
- package/dist/commands/execute/integrate-stages.mjs.map +0 -1
- package/dist/commands/execute/pane-title.d.mts +0 -1
- package/dist/commands/execute/pane-title.mjs +0 -20
- package/dist/commands/execute/pane-title.mjs.map +0 -1
- package/dist/commands/execute/plan-items.d.mts +0 -1
- package/dist/commands/execute/plan-items.mjs +0 -9
- package/dist/commands/execute/plan-items.mjs.map +0 -1
- package/dist/commands/execute/plan-validate.d.mts +0 -1
- package/dist/commands/execute/plan-validate.mjs +0 -68
- package/dist/commands/execute/plan-validate.mjs.map +0 -1
- package/dist/commands/execute/plan-verify.d.mts +0 -1
- package/dist/commands/execute/plan-verify.mjs +0 -43
- package/dist/commands/execute/plan-verify.mjs.map +0 -1
- package/dist/commands/execute/spawn-followups.d.mts +0 -1
- package/dist/commands/execute/spawn-followups.mjs +0 -22
- package/dist/commands/execute/spawn-followups.mjs.map +0 -1
- package/dist/commands/execute/team.d.mts +0 -3
- package/dist/commands/execute/team.mjs +0 -66
- package/dist/commands/execute/team.mjs.map +0 -1
- package/dist/commands/execute/token-usage.d.mts +0 -1
- package/dist/commands/execute/token-usage.mjs +0 -19
- package/dist/commands/execute/token-usage.mjs.map +0 -1
- package/dist/commands/execute/worker-audit-check.d.mts +0 -1
- package/dist/commands/execute/worker-audit-check.mjs +0 -34
- package/dist/commands/execute/worker-audit-check.mjs.map +0 -1
- package/dist/commands/execute/worker-dispatch.d.mts +0 -7
- package/dist/commands/execute/worker-dispatch.mjs +0 -64
- package/dist/commands/execute/worker-dispatch.mjs.map +0 -1
- package/dist/commands/execute/worker-state.d.mts +0 -1
- package/dist/commands/execute/worker-state.mjs +0 -28
- package/dist/commands/execute/worker-state.mjs.map +0 -1
- package/dist/commands/execute/worktree-lookup.d.mts +0 -1
- package/dist/commands/execute/worktree-lookup.mjs +0 -92
- package/dist/commands/execute/worktree-lookup.mjs.map +0 -1
- package/dist/commands/execute/worktree-status.d.mts +0 -1
- package/dist/commands/execute/worktree-status.mjs +0 -121
- package/dist/commands/execute/worktree-status.mjs.map +0 -1
- package/dist/commands/inspect/code-review.d.mts +0 -1
- package/dist/commands/inspect/code-review.mjs +0 -32
- package/dist/commands/inspect/code-review.mjs.map +0 -1
- package/dist/commands/inspect/container.d.mts +0 -1
- package/dist/commands/inspect/container.mjs +0 -25
- package/dist/commands/inspect/container.mjs.map +0 -1
- package/dist/commands/inspect/context-cost.d.mts +0 -1
- package/dist/commands/inspect/context-cost.mjs +0 -25
- package/dist/commands/inspect/context-cost.mjs.map +0 -1
- package/dist/commands/inspect/design-prep.d.mts +0 -1
- package/dist/commands/inspect/design-prep.mjs +0 -22
- package/dist/commands/inspect/design-prep.mjs.map +0 -1
- package/dist/commands/inspect/error-report.d.mts +0 -1
- package/dist/commands/inspect/error-report.mjs +0 -25
- package/dist/commands/inspect/error-report.mjs.map +0 -1
- package/dist/commands/inspect/error-zip.d.mts +0 -1
- package/dist/commands/inspect/error-zip.mjs +0 -24
- package/dist/commands/inspect/error-zip.mjs.map +0 -1
- package/dist/commands/inspect/log-report.d.mts +0 -1
- package/dist/commands/inspect/log-report.mjs +0 -26
- package/dist/commands/inspect/log-report.mjs.map +0 -1
- package/dist/commands/inspect/model-io.d.mts +0 -1
- package/dist/commands/inspect/model-io.mjs +0 -25
- package/dist/commands/inspect/model-io.mjs.map +0 -1
- package/dist/commands/inspect/profile-show.d.mts +0 -1
- package/dist/commands/inspect/profile-show.mjs +0 -28
- package/dist/commands/inspect/profile-show.mjs.map +0 -1
- package/dist/commands/inspect/recap.d.mts +0 -1
- package/dist/commands/inspect/recap.mjs +0 -30
- package/dist/commands/inspect/recap.mjs.map +0 -1
- package/dist/commands/inspect/resolve-task-key.d.mts +0 -1
- package/dist/commands/inspect/resolve-task-key.mjs +0 -24
- package/dist/commands/inspect/resolve-task-key.mjs.map +0 -1
- package/dist/commands/inspect/rollup.d.mts +0 -1
- package/dist/commands/inspect/rollup.mjs +0 -25
- package/dist/commands/inspect/rollup.mjs.map +0 -1
- package/dist/commands/inspect/run-audit.d.mts +0 -1
- package/dist/commands/inspect/run-audit.mjs +0 -25
- package/dist/commands/inspect/run-audit.mjs.map +0 -1
- package/dist/commands/inspect/set-work-status.d.mts +0 -1
- package/dist/commands/inspect/set-work-status.mjs +0 -29
- package/dist/commands/inspect/set-work-status.mjs.map +0 -1
- package/dist/commands/inspect/stage-map.d.mts +0 -1
- package/dist/commands/inspect/stage-map.mjs +0 -131
- package/dist/commands/inspect/stage-map.mjs.map +0 -1
- package/dist/commands/inspect/task-list.d.mts +0 -1
- package/dist/commands/inspect/task-list.mjs +0 -149
- package/dist/commands/inspect/task-list.mjs.map +0 -1
- package/dist/commands/inspect/task-show.d.mts +0 -1
- package/dist/commands/inspect/task-show.mjs +0 -108
- package/dist/commands/inspect/task-show.mjs.map +0 -1
- package/dist/commands/inspect/time-report.d.mts +0 -1
- package/dist/commands/inspect/time-report.mjs +0 -24
- package/dist/commands/inspect/time-report.mjs.map +0 -1
- package/dist/commands/inspect/usage-report.d.mts +0 -1
- package/dist/commands/inspect/usage-report.mjs +0 -23
- package/dist/commands/inspect/usage-report.mjs.map +0 -1
- package/dist/commands/inspect/user-response.d.mts +0 -1
- package/dist/commands/inspect/user-response.mjs +0 -35
- package/dist/commands/inspect/user-response.mjs.map +0 -1
- package/dist/commands/inspect/worker-liveness.d.mts +0 -1
- package/dist/commands/inspect/worker-liveness.mjs +0 -45
- package/dist/commands/inspect/worker-liveness.mjs.map +0 -1
- package/dist/commands/lifecycle/contract-check.d.mts +0 -1
- package/dist/commands/lifecycle/contract-check.mjs +0 -18
- package/dist/commands/lifecycle/contract-check.mjs.map +0 -1
- package/dist/commands/lifecycle/migrate.d.mts +0 -1
- package/dist/commands/lifecycle/migrate.mjs +0 -30
- package/dist/commands/lifecycle/migrate.mjs.map +0 -1
- package/dist/commands/lifecycle/model.d.mts +0 -1
- package/dist/commands/lifecycle/model.mjs +0 -22
- package/dist/commands/lifecycle/model.mjs.map +0 -1
- package/dist/commands/manager.d.mts +0 -3
- package/dist/commands/manager.mjs +0 -50
- package/dist/commands/manager.mjs.map +0 -1
- package/dist/commands/report/agent-activity.d.mts +0 -1
- package/dist/commands/report/agent-activity.mjs +0 -20
- package/dist/commands/report/agent-activity.mjs.map +0 -1
- package/dist/commands/report/approval-decision.d.mts +0 -1
- package/dist/commands/report/approval-decision.mjs +0 -21
- package/dist/commands/report/approval-decision.mjs.map +0 -1
- package/dist/commands/report/design-snapshot.d.mts +0 -1
- package/dist/commands/report/design-snapshot.mjs +0 -19
- package/dist/commands/report/design-snapshot.mjs.map +0 -1
- package/dist/commands/report/finalize.d.mts +0 -4
- package/dist/commands/report/finalize.mjs +0 -64
- package/dist/commands/report/finalize.mjs.map +0 -1
- package/dist/commands/report/inject-report-index.d.mts +0 -1
- package/dist/commands/report/inject-report-index.mjs +0 -21
- package/dist/commands/report/inject-report-index.mjs.map +0 -1
- package/dist/commands/report/render-final-report.d.mts +0 -1
- package/dist/commands/report/render-final-report.mjs +0 -23
- package/dist/commands/report/render-final-report.mjs.map +0 -1
- package/dist/commands/report/render-views.d.mts +0 -1
- package/dist/commands/report/render-views.mjs +0 -27
- package/dist/commands/report/render-views.mjs.map +0 -1
- package/dist/commands/report/translate.d.mts +0 -1
- package/dist/commands/report/translate.mjs +0 -33
- package/dist/commands/report/translate.mjs.map +0 -1
- package/runtime/bin/lib/okstra/tmux-pane.sh +0 -40
- package/runtime/bin/lib/okstra-ctl/cmd-batch.sh +0 -59
- package/runtime/bin/lib/okstra-ctl/cmd-list.sh +0 -35
- package/runtime/bin/lib/okstra-ctl/cmd-open.sh +0 -36
- package/runtime/bin/lib/okstra-ctl/cmd-projects.sh +0 -26
- package/runtime/bin/lib/okstra-ctl/cmd-reconcile.sh +0 -29
- package/runtime/bin/lib/okstra-ctl/cmd-reindex.sh +0 -38
- package/runtime/bin/lib/okstra-ctl/cmd-rerun.sh +0 -345
- package/runtime/bin/lib/okstra-ctl/cmd-show.sh +0 -27
- package/runtime/bin/lib/okstra-ctl/cmd-tail.sh +0 -92
- package/runtime/bin/lib/okstra-ctl/main.sh +0 -41
- package/runtime/bin/lib/okstra-ctl/prepare.sh +0 -31
- package/runtime/bin/lib/okstra-ctl/usage.sh +0 -23
- package/runtime/bin/okstra-central.sh +0 -152
- package/runtime/bin/okstra-incremental-carry.py +0 -10
- package/runtime/bin/okstra-incremental-scope.py +0 -10
- package/runtime/bin/okstra-team-reconcile.sh +0 -36
- package/runtime/python/okstra_ctl/agent_prompt_cli.py +0 -1156
- package/runtime/python/okstra_ctl/batch.py +0 -60
- package/runtime/python/okstra_ctl/clarification_items.py +0 -1050
- package/runtime/python/okstra_ctl/container_registry.py +0 -72
- package/runtime/python/okstra_ctl/improvement_assignment.py +0 -61
- package/runtime/python/okstra_ctl/resolver.py +0 -54
- package/runtime/python/okstra_ctl/team_reconcile.py +0 -275
- package/runtime/python/okstra_ctl/tmux.py +0 -134
- package/runtime/python/okstra_ctl/worktree.py +0 -1099
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Read-side state accessors over okstra's on-disk authority files.
|
|
2
2
|
|
|
3
|
-
Skills
|
|
3
|
+
Skills and okstra.sh read the same files through this module
|
|
4
4
|
so identity / discovery values are derived from disk on every call instead of
|
|
5
5
|
being passed via process environment. This keeps concurrent claude-code skill
|
|
6
6
|
invocations isolated — each call reads the authoritative state at the moment
|
|
@@ -34,6 +34,13 @@ from .dirs import (
|
|
|
34
34
|
TASK_MANIFEST_FILENAME,
|
|
35
35
|
TASKS_RELATIVE,
|
|
36
36
|
)
|
|
37
|
+
# 포인터 승격은 순수 값 연산이라 하위 계층이 소유한다. 예전에는 함수 본문에서
|
|
38
|
+
# okstra_ctl.next_phase 를 지연 import 했다 — okstra_ctl 패키지 __init__ 이
|
|
39
|
+
# 이 모듈의 slugify 를 도로 끌어와 순환이 됐기 때문이다.
|
|
40
|
+
from .phase_pointer import promote as promote_phase_pointer
|
|
41
|
+
# slug 규칙은 leaf 가 소유한다 — okstra_ctl 이 이 모듈을 거치지 않고 규칙만
|
|
42
|
+
# 가져갈 수 있어야 패키지 __init__ 을 통한 순환이 생기지 않는다.
|
|
43
|
+
from .slug import slugify # noqa: F401 — 재노출: 기존 호출부가 state 에서 끌어온다
|
|
37
44
|
|
|
38
45
|
|
|
39
46
|
class StateError(Exception):
|
|
@@ -53,31 +60,6 @@ def _load_json(path: Path) -> Optional[dict]:
|
|
|
53
60
|
raise StateError(f"failed to parse {path}: {exc}") from exc
|
|
54
61
|
|
|
55
62
|
|
|
56
|
-
def _next_phase():
|
|
57
|
-
"""`okstra_ctl.next_phase` 를 호출 시점에 가져온다.
|
|
58
|
-
|
|
59
|
-
모듈 최상단에서 import 하면 순환이 된다 — `okstra_ctl/__init__.py` 가
|
|
60
|
-
`.ids` 를 거쳐 이 모듈의 `slugify` 를 도로 import 하기 때문에, 여기서
|
|
61
|
-
okstra_ctl 을 먼저 끌어오면 아직 정의되지 않은 이름을 찾다가 ImportError 로
|
|
62
|
-
죽는다. 같은 파일의 `_reconcile_task_root_best_effort` 도 같은 이유로 지연
|
|
63
|
-
import 를 쓴다.
|
|
64
|
-
"""
|
|
65
|
-
from okstra_ctl import next_phase
|
|
66
|
-
|
|
67
|
-
return next_phase
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def slugify(value: str) -> str:
|
|
71
|
-
"""task-group / task-id segment 를 디스크 경로용 slug 로 정규화한다.
|
|
72
|
-
|
|
73
|
-
소문자화 + 알파넘 외 문자 → '-' 로 collapse.
|
|
74
|
-
okstra.sh 의 path-resolve.sh slug 규칙과 일치해야 한다.
|
|
75
|
-
"""
|
|
76
|
-
value = (value or "").lower()
|
|
77
|
-
value = re.sub(r"[^a-z0-9]+", "-", value).strip("-")
|
|
78
|
-
return value
|
|
79
|
-
|
|
80
|
-
|
|
81
63
|
def read_task_catalog(project_root: Path) -> list[dict]:
|
|
82
64
|
"""project-level task-catalog.json 을 list[dict] 로 돌려준다.
|
|
83
65
|
|
|
@@ -117,7 +99,7 @@ def read_task_manifest(task_root: Path) -> Optional[dict]:
|
|
|
117
99
|
workflow = manifest.get("workflow")
|
|
118
100
|
if not isinstance(workflow, dict):
|
|
119
101
|
return manifest
|
|
120
|
-
workflow["nextRecommendedPhase"] =
|
|
102
|
+
workflow["nextRecommendedPhase"] = promote_phase_pointer(
|
|
121
103
|
workflow.get("nextRecommendedPhase")
|
|
122
104
|
)
|
|
123
105
|
# routingStatus 는 포인터 status 로 흡수됐다 — 승격과 같은 자리에서 지운다.
|
|
@@ -143,11 +125,20 @@ def read_task_key(task_root: Path) -> str:
|
|
|
143
125
|
|
|
144
126
|
|
|
145
127
|
def _reconcile_task_root_best_effort(project_root: Path, task_root: Path) -> None:
|
|
128
|
+
"""카탈로그가 가리키는 task-root 를 정본 산출물로 치유한다(best-effort).
|
|
129
|
+
|
|
130
|
+
import 를 함수 본문에 두는 이유는 순환이 아니다 — 순환은 없다. 하위 계층인
|
|
131
|
+
okstra_project 가 상위 계층 okstra_ctl 을 import 시점에 끌어오지 않게 하려는
|
|
132
|
+
것이다. 이 치유는 읽기측 해석의 부가 동작이므로, 실패해도 해석 자체는
|
|
133
|
+
계속돼야 한다.
|
|
134
|
+
"""
|
|
146
135
|
try:
|
|
147
136
|
from okstra_ctl.implementation_outcome import reconcile_implementation_outcome
|
|
148
137
|
|
|
149
138
|
reconcile_implementation_outcome(project_root, task_root)
|
|
150
139
|
except Exception:
|
|
140
|
+
# expected-miss: 치유는 부가 동작이다. 여기서 던지면 단순 조회가
|
|
141
|
+
# 실패한다. 무엇이 치유되지 않았는지는 다음 run 의 정합성 검사가 잡는다.
|
|
151
142
|
return
|
|
152
143
|
|
|
153
144
|
|
|
@@ -195,7 +186,7 @@ def _entry_with_manifest_state(entry: dict, task_root: Path) -> dict:
|
|
|
195
186
|
raw = workflow.get("nextRecommendedPhase")
|
|
196
187
|
if raw is None:
|
|
197
188
|
raw = entry.get("nextRecommendedPhase")
|
|
198
|
-
out["nextRecommendedPhase"] =
|
|
189
|
+
out["nextRecommendedPhase"] = promote_phase_pointer(raw)
|
|
199
190
|
out.update(derived_task_status(manifest))
|
|
200
191
|
return out
|
|
201
192
|
|
|
@@ -350,7 +341,7 @@ def list_project_tasks(
|
|
|
350
341
|
def resolve_task_identity(project_root: Path, task_key: str) -> dict:
|
|
351
342
|
"""task-key 한 줄로 manifest + 경로를 한 번에 반환.
|
|
352
343
|
|
|
353
|
-
skill
|
|
344
|
+
skill 과 okstra.sh 모두가 이 함수를 호출해 같은 dict 를 받는다.
|
|
354
345
|
StateError: task root 또는 manifest 없음.
|
|
355
346
|
"""
|
|
356
347
|
task_root = find_task_root(project_root, task_key)
|
|
@@ -379,7 +370,7 @@ def resolve_task_identity(project_root: Path, task_key: str) -> dict:
|
|
|
379
370
|
"taskType": manifest.get("taskType") or "",
|
|
380
371
|
"currentPhase": workflow.get("currentPhase") or "",
|
|
381
372
|
"currentPhaseState": workflow.get("currentPhaseState") or "",
|
|
382
|
-
"nextRecommendedPhase":
|
|
373
|
+
"nextRecommendedPhase": promote_phase_pointer(
|
|
383
374
|
workflow.get("nextRecommendedPhase")
|
|
384
375
|
),
|
|
385
376
|
"lastCompletedPhase": workflow.get("lastCompletedPhase") or "",
|
|
@@ -410,7 +401,7 @@ def task_read_side_snapshot(project_root: Path, task_key: str) -> dict:
|
|
|
410
401
|
"currentPhase": workflow.get("currentPhase"),
|
|
411
402
|
"currentPhaseState": workflow.get("currentPhaseState"),
|
|
412
403
|
"lastCompletedPhase": workflow.get("lastCompletedPhase"),
|
|
413
|
-
"nextRecommendedPhase":
|
|
404
|
+
"nextRecommendedPhase": promote_phase_pointer(
|
|
414
405
|
workflow.get("nextRecommendedPhase")
|
|
415
406
|
),
|
|
416
407
|
"phaseStates": workflow.get("phaseStates"),
|
|
@@ -421,202 +412,3 @@ def task_read_side_snapshot(project_root: Path, task_key: str) -> dict:
|
|
|
421
412
|
"modelAssignments": manifest.get("modelAssignments"),
|
|
422
413
|
"latestRunPath": manifest.get("latestRunPath"),
|
|
423
414
|
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
def stage_map_read_side_snapshot(project_root: Path, task_key: str) -> dict:
|
|
427
|
-
"""stage-map inspect 용 read-side view: Stage Map + done 처리된 stage 번호.
|
|
428
|
-
|
|
429
|
-
Stage Map 파싱과 planning run-root 위치를 caller 에게 노출하지 않는다 —
|
|
430
|
-
Node inspect 가 okstra_ctl 의 private 심볼을 import 하거나 `runs/` 경로를
|
|
431
|
-
직접 조립하지 않도록 하는 어댑터다.
|
|
432
|
-
"""
|
|
433
|
-
from okstra_ctl.consumers import read_stage_consumer_state
|
|
434
|
-
from okstra_ctl.paths import RunRef
|
|
435
|
-
from okstra_ctl.stage_map import (
|
|
436
|
-
PlanningDetail,
|
|
437
|
-
StageMapError,
|
|
438
|
-
load_planning_detail,
|
|
439
|
-
load_task_stage_map,
|
|
440
|
-
merge_planning_detail,
|
|
441
|
-
)
|
|
442
|
-
|
|
443
|
-
identity = resolve_task_identity(project_root, task_key)
|
|
444
|
-
task_root = Path(identity["taskRoot"])
|
|
445
|
-
try:
|
|
446
|
-
stage_snapshot = load_task_stage_map(task_root, identity["manifest"])
|
|
447
|
-
detail = (
|
|
448
|
-
load_planning_detail(Path(stage_snapshot.source_plan_path))
|
|
449
|
-
if stage_snapshot.source_plan_path
|
|
450
|
-
else PlanningDetail({}, {})
|
|
451
|
-
)
|
|
452
|
-
except StageMapError as exc:
|
|
453
|
-
raise StateError(str(exc), stage=exc.code) from exc
|
|
454
|
-
plan_run_root = RunRef.from_task_root(
|
|
455
|
-
task_root, "implementation-planning"
|
|
456
|
-
).run_dir
|
|
457
|
-
done: list[int] = []
|
|
458
|
-
if plan_run_root.is_dir():
|
|
459
|
-
done = sorted(
|
|
460
|
-
read_stage_consumer_state(
|
|
461
|
-
plan_run_root, recover_from_carry=True
|
|
462
|
-
).done_stages
|
|
463
|
-
)
|
|
464
|
-
return {
|
|
465
|
-
"taskKey": identity["taskKey"],
|
|
466
|
-
"taskRoot": identity["taskRoot"],
|
|
467
|
-
"state": stage_snapshot.state,
|
|
468
|
-
"sourcePlanPath": stage_snapshot.source_plan_path,
|
|
469
|
-
"stages": merge_planning_detail(stage_snapshot.stages, detail),
|
|
470
|
-
"doneStages": done,
|
|
471
|
-
"planning": detail.task_narratives,
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
def code_review_target_snapshot(
|
|
476
|
-
project_root: Path, task_key: str, stage: int
|
|
477
|
-
) -> dict:
|
|
478
|
-
"""stage 코드 리뷰가 무엇을 읽고 결과를 어디에 쓰는지 해소한다.
|
|
479
|
-
|
|
480
|
-
stage_map_read_side_snapshot 과 같은 결: caller 는 registry 행도, run-root
|
|
481
|
-
레이아웃도, stage base 규칙도 보지 않는다. stage_targets 의
|
|
482
|
-
StageTargetError 도 StateError 로 바꿔 던진다 — caller 가 그 예외를 잡으려고
|
|
483
|
-
okstra_ctl 을 import 하지 않도록.
|
|
484
|
-
|
|
485
|
-
base 는 stage worktree 를 만들 때 registry 행에 적힌 `base_ref` 다 — 그
|
|
486
|
-
stage 가 실제로 갈라져 나온 커밋. 리뷰 시점에 규칙으로 다시 계산하면
|
|
487
|
-
표류한다: 다중의존 stage 는 오늘의 task-key worktree HEAD 를 받게 되어
|
|
488
|
-
whole-task final-verification 이 stage 들을 병합한 뒤에는 base..head 구간이
|
|
489
|
-
비거나 뒤집히고, 단일의존 stage 는 선행 stage 가 재실행되면 어긋난다.
|
|
490
|
-
"""
|
|
491
|
-
from okstra_ctl import code_review_paths, worktree_registry
|
|
492
|
-
from okstra_ctl.stage_map import StageMapError, load_task_stage_map
|
|
493
|
-
|
|
494
|
-
identity = resolve_task_identity(project_root, task_key)
|
|
495
|
-
task_root = Path(identity["taskRoot"])
|
|
496
|
-
try:
|
|
497
|
-
stage_snapshot = load_task_stage_map(task_root, identity["manifest"])
|
|
498
|
-
except StageMapError as exc:
|
|
499
|
-
raise StateError(str(exc), stage=exc.code) from exc
|
|
500
|
-
if stage_snapshot.state != "ready":
|
|
501
|
-
raise StateError(
|
|
502
|
-
"implementation-planning Stage Map is missing",
|
|
503
|
-
stage="missing",
|
|
504
|
-
)
|
|
505
|
-
stages = stage_snapshot.stages
|
|
506
|
-
selected = next((s for s in stages if s["stage_number"] == stage), None)
|
|
507
|
-
if selected is None:
|
|
508
|
-
raise StateError(
|
|
509
|
-
f"stage {stage} is not in the Stage Map for {task_key}",
|
|
510
|
-
stage="stage_missing",
|
|
511
|
-
)
|
|
512
|
-
|
|
513
|
-
coords = (identity["projectId"], identity["taskGroup"], identity["taskId"])
|
|
514
|
-
stage_row = worktree_registry.get_stage_row(*coords, stage) or {}
|
|
515
|
-
worktree_view = _stage_worktree_view(project_root, stage_row, stage)
|
|
516
|
-
base_commit = stage_row.get("base_ref") or _legacy_stage_base_commit(
|
|
517
|
-
identity, stages, selected
|
|
518
|
-
)
|
|
519
|
-
review_path, round_no = code_review_paths.next_stage_review(
|
|
520
|
-
code_review_paths.stage_review_dir(
|
|
521
|
-
project_root, identity["taskGroup"], identity["taskId"]
|
|
522
|
-
),
|
|
523
|
-
stage,
|
|
524
|
-
)
|
|
525
|
-
return {
|
|
526
|
-
"mode": "stage",
|
|
527
|
-
"taskKey": identity["taskKey"],
|
|
528
|
-
"taskRoot": identity["taskRoot"],
|
|
529
|
-
"stage": stage,
|
|
530
|
-
**worktree_view,
|
|
531
|
-
"baseCommit": base_commit,
|
|
532
|
-
"reviewPath": str(review_path),
|
|
533
|
-
"round": round_no,
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
def _legacy_stage_base_commit(
|
|
538
|
-
identity: dict, stages: list[dict], selected: dict
|
|
539
|
-
) -> str:
|
|
540
|
-
"""`base_ref` 를 남기지 않은 옛 registry 행의 base 를 규칙에서 되살린다.
|
|
541
|
-
|
|
542
|
-
provision 이 base_ref 를 기록하기 전에 만들어진 stage 행에만 쓰인다. 규칙
|
|
543
|
-
자체는 stage_targets 가 소유하며 여기서 다시 유도하지 않는다.
|
|
544
|
-
"""
|
|
545
|
-
from okstra_ctl import stage_targets, worktree_registry
|
|
546
|
-
from okstra_ctl.paths import RunRef
|
|
547
|
-
|
|
548
|
-
coords = (identity["projectId"], identity["taskGroup"], identity["taskId"])
|
|
549
|
-
plan_run_root = RunRef.from_task_root(
|
|
550
|
-
Path(identity["taskRoot"]), "implementation-planning"
|
|
551
|
-
).run_dir
|
|
552
|
-
lifecycle = stage_targets.read_stage_lifecycle_snapshot(
|
|
553
|
-
stages, plan_run_root, recover_from_carry=True
|
|
554
|
-
)
|
|
555
|
-
# The anchor and the multi-dep candidate base must come from the task-key
|
|
556
|
-
# worktree HEAD, where stage work accumulates — not from the invocation
|
|
557
|
-
# cwd, which may sit on an older or unrelated commit.
|
|
558
|
-
task_entry = worktree_registry.lookup(*coords)
|
|
559
|
-
task_worktree = Path(
|
|
560
|
-
(task_entry.worktree_path if task_entry else "") or identity["projectRoot"]
|
|
561
|
-
)
|
|
562
|
-
anchor = worktree_registry.get_implementation_base(*coords) or ""
|
|
563
|
-
try:
|
|
564
|
-
return stage_targets.resolve_stage_base_commit(
|
|
565
|
-
selected,
|
|
566
|
-
lifecycle.done_rows,
|
|
567
|
-
anchor_base_commit=anchor,
|
|
568
|
-
candidate_base=_git_out(task_worktree, "rev-parse", "HEAD"),
|
|
569
|
-
project_root=task_worktree,
|
|
570
|
-
plan_run_root=plan_run_root,
|
|
571
|
-
)
|
|
572
|
-
except stage_targets.StageTargetError as exc:
|
|
573
|
-
raise StateError(
|
|
574
|
-
f"stage {selected['stage_number']} has no recorded base_ref and its "
|
|
575
|
-
f"base could not be derived: {exc}",
|
|
576
|
-
stage="stage_base_unresolved",
|
|
577
|
-
) from exc
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
def _stage_worktree_view(project_root: Path, stage_row: dict, stage: int) -> dict:
|
|
581
|
-
"""한 stage 의 worktree 경로 / 브랜치 / head 커밋.
|
|
582
|
-
|
|
583
|
-
철거된 stage worktree 는 오류가 아니다: whole-task final-verification 이
|
|
584
|
-
디렉터리를 지워도 브랜치는 남고, 리뷰가 필요한 커밋은 그 브랜치에 그대로
|
|
585
|
-
있다.
|
|
586
|
-
"""
|
|
587
|
-
branch = stage_row.get("branch") or ""
|
|
588
|
-
if not branch:
|
|
589
|
-
raise StateError(
|
|
590
|
-
f"stage {stage} has no registry branch — review it in branch mode",
|
|
591
|
-
stage="stage_branch_missing",
|
|
592
|
-
)
|
|
593
|
-
worktree_path = ""
|
|
594
|
-
if stage_row.get("status") == "active" and stage_row.get("worktree_path"):
|
|
595
|
-
candidate = Path(stage_row["worktree_path"])
|
|
596
|
-
if candidate.is_dir():
|
|
597
|
-
worktree_path = str(candidate)
|
|
598
|
-
head_source = Path(worktree_path) if worktree_path else Path(project_root)
|
|
599
|
-
head_ref = "HEAD" if worktree_path else branch
|
|
600
|
-
head_commit = _git_out(head_source, "rev-parse", head_ref)
|
|
601
|
-
if not head_commit:
|
|
602
|
-
raise StateError(
|
|
603
|
-
f"stage {stage} head could not be resolved: branch {branch!r} is "
|
|
604
|
-
f"not readable from {head_source}",
|
|
605
|
-
stage="stage_head_unresolved",
|
|
606
|
-
)
|
|
607
|
-
return {
|
|
608
|
-
"worktreePath": worktree_path,
|
|
609
|
-
"branch": branch,
|
|
610
|
-
"headCommit": head_commit,
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
def _git_out(repo: Path, *args: str) -> str:
|
|
615
|
-
"""git 호출의 stdout. 실패는 빈 문자열 — 호출자가 부재를 판단한다."""
|
|
616
|
-
result = subprocess.run(
|
|
617
|
-
["git", "-C", str(repo), *args],
|
|
618
|
-
capture_output=True,
|
|
619
|
-
text=True,
|
|
620
|
-
check=False,
|
|
621
|
-
)
|
|
622
|
-
return result.stdout.strip() if result.returncode == 0 else ""
|
|
@@ -1,18 +1,64 @@
|
|
|
1
1
|
"""Antigravity (`agy`) CLI usage collector.
|
|
2
2
|
|
|
3
3
|
공식 headless 문서는 ``--output-format json`` / ``stream-json`` 의 최종
|
|
4
|
-
``usage`` 객체에 토큰을 둔다. okstra 는
|
|
5
|
-
|
|
4
|
+
``usage`` 객체에 토큰을 둔다. okstra 는 ``stream-json`` 으로 호출하고, 러너가
|
|
5
|
+
스트림의 마지막 ``usage`` 스냅샷을 래퍼 status 사이드카의 ``usage`` 에 적는다
|
|
6
|
+
(`worker_runner`) — 그것이 정본이다. 워커 로그는 러너가 사람이 읽는 줄로 옮겨
|
|
7
|
+
적은 것이라 stream-json 이 아니다. raw stream-json 로그를 읽는 경로는 러너
|
|
8
|
+
이전의 로그를 위해 남긴다.
|
|
6
9
|
"""
|
|
7
10
|
from __future__ import annotations
|
|
8
11
|
|
|
12
|
+
import json
|
|
9
13
|
from pathlib import Path
|
|
14
|
+
from typing import Any, Mapping
|
|
10
15
|
|
|
11
16
|
from .jsonl_io import iter_jsonl
|
|
12
17
|
|
|
13
18
|
|
|
19
|
+
def _usage_total(usage: Mapping[str, Any], model: str | None) -> dict:
|
|
20
|
+
return {
|
|
21
|
+
"totalTokens": usage.get("total_tokens", 0) or 0,
|
|
22
|
+
"inputTokens": usage.get("input_tokens", 0) or 0,
|
|
23
|
+
"outputTokens": usage.get("output_tokens", 0) or 0,
|
|
24
|
+
"thoughtsTokens": usage.get("thinking_tokens", 0) or 0,
|
|
25
|
+
"cacheReadTokens": usage.get("cache_read_tokens", 0) or 0,
|
|
26
|
+
"model": model,
|
|
27
|
+
"available": True,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _read_status(status_path: Path) -> dict | None:
|
|
32
|
+
try:
|
|
33
|
+
data = json.loads(status_path.read_text(encoding="utf-8"))
|
|
34
|
+
except (OSError, ValueError):
|
|
35
|
+
return None
|
|
36
|
+
return data if isinstance(data, dict) else None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def status_carries_usage(path: Path) -> bool:
|
|
40
|
+
"""이 경로가 ``usage`` 스냅샷을 실은 래퍼 status 사이드카인가."""
|
|
41
|
+
if not path.name.endswith(".status.json"):
|
|
42
|
+
return False
|
|
43
|
+
status = _read_status(path)
|
|
44
|
+
return isinstance((status or {}).get("usage"), dict) and bool(status["usage"])
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def antigravity_status_total(status_path: Path) -> dict:
|
|
48
|
+
"""래퍼 status 사이드카의 ``usage`` 스냅샷. 모델은 served-model 관측값이다."""
|
|
49
|
+
status = _read_status(status_path) or {}
|
|
50
|
+
usage = status.get("usage")
|
|
51
|
+
if not isinstance(usage, dict) or not usage:
|
|
52
|
+
return {"totalTokens": 0, "available": False}
|
|
53
|
+
attestation = status.get("servedModelAttestation")
|
|
54
|
+
model = (
|
|
55
|
+
attestation.get("observedModel") if isinstance(attestation, dict) else None
|
|
56
|
+
)
|
|
57
|
+
return _usage_total(usage, model if isinstance(model, str) and model else None)
|
|
58
|
+
|
|
59
|
+
|
|
14
60
|
def antigravity_session_total(json_path: Path) -> dict:
|
|
15
|
-
"""stream-json 로그에서 마지막 result.usage 를 읽는다."""
|
|
61
|
+
"""raw stream-json 로그에서 마지막 result.usage 를 읽는다."""
|
|
16
62
|
result_usage: dict | None = None
|
|
17
63
|
step_usage: dict | None = None
|
|
18
64
|
model: str | None = None
|
|
@@ -35,15 +81,7 @@ def antigravity_session_total(json_path: Path) -> dict:
|
|
|
35
81
|
usage = result_usage or step_usage
|
|
36
82
|
if usage is None:
|
|
37
83
|
return {"totalTokens": 0, "available": False}
|
|
38
|
-
return
|
|
39
|
-
"totalTokens": usage.get("total_tokens", 0) or 0,
|
|
40
|
-
"inputTokens": usage.get("input_tokens", 0) or 0,
|
|
41
|
-
"outputTokens": usage.get("output_tokens", 0) or 0,
|
|
42
|
-
"thoughtsTokens": usage.get("thinking_tokens", 0) or 0,
|
|
43
|
-
"cacheReadTokens": usage.get("cache_read_tokens", 0) or 0,
|
|
44
|
-
"model": model,
|
|
45
|
-
"available": True,
|
|
46
|
-
}
|
|
84
|
+
return _usage_total(usage, model)
|
|
47
85
|
|
|
48
86
|
|
|
49
87
|
def find_antigravity_session(project_root: Path, started_at: str, ended_at: str) -> Path | None:
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
import json
|
|
5
|
+
import sys
|
|
5
6
|
import re
|
|
6
7
|
from datetime import datetime
|
|
7
8
|
from pathlib import Path
|
|
@@ -158,8 +159,15 @@ def _advance_usage_scan(jsonl_path: Path, usage_state: dict) -> dict:
|
|
|
158
159
|
if ev:
|
|
159
160
|
tail_events.append(ev)
|
|
160
161
|
break
|
|
161
|
-
except
|
|
162
|
+
except FileNotFoundError:
|
|
163
|
+
# expected-miss: 세션 jsonl 은 열거된 뒤 사라질 수 있고(정리·회전), 아직
|
|
164
|
+
# 한 줄도 안 쓴 세션은 파일 자체가 없다. 읽을 것이 없는 것이 정상이다.
|
|
162
165
|
pass
|
|
166
|
+
except OSError as exc:
|
|
167
|
+
# 파일은 있는데 못 읽은 것은 다르다. 읽다 만 상태로 반환하면 토큰 집계가
|
|
168
|
+
# 실제보다 적게 나오는데 리포트에는 정상 수치처럼 찍힌다.
|
|
169
|
+
print(f"token-usage: partial read of {jsonl_path} ({exc})",
|
|
170
|
+
file=sys.stderr)
|
|
163
171
|
usage_state.update(offset=offset, events=events,
|
|
164
172
|
agentName=agent_name, model=model)
|
|
165
173
|
return {"events": events + tail_events,
|