okstra 0.186.7 → 0.187.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 +104 -39
- 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 +37 -36
- 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 +25 -18
- 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/convergence.md +96 -87
- 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 +34 -4
- 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 +40 -22
- package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +14 -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} +12 -1
- 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 +215 -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 +408 -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 +260 -8
- 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 +16 -2
- package/runtime/python/okstra_ctl/contract_graph_cli.py +7 -0
- package/runtime/python/okstra_ctl/convergence.py +101 -15
- 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 +102 -25
- package/runtime/python/okstra_ctl/dispatch_state.py +268 -39
- 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 +21 -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/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 +90 -16
- 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 +25 -11
- 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 +3 -7
- 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 +206 -15
- 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 +90 -3
- package/runtime/python/okstra_ctl/report_projections.py +8 -2
- package/runtime/python/okstra_ctl/report_synthesis_packet.py +258 -1
- package/runtime/python/okstra_ctl/report_translation.py +2 -35
- 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/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 +16 -9
- 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/claude.py +9 -1
- package/runtime/python/okstra_token_usage/cli.py +3 -1
- package/runtime/python/okstra_token_usage/collect.py +71 -10
- 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 +19 -7
- 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 +1 -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 +1369 -2654
- 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,345 +0,0 @@
|
|
|
1
|
-
# shellcheck shell=bash
|
|
2
|
-
|
|
3
|
-
_okstra_ctl_rerun() {
|
|
4
|
-
local yes="false" dry_run="false" use_filter="false"
|
|
5
|
-
local project="all" task_group="all" status="all" since=""
|
|
6
|
-
local project_set="false" task_group_set="false"
|
|
7
|
-
local max_spawn="${OKSTRA_CTL_MAX_SPAWN:-10}"
|
|
8
|
-
local from_stdin="false" use_last="false"
|
|
9
|
-
local -a explicit=()
|
|
10
|
-
local ignore_brief_drift="false"
|
|
11
|
-
while [[ $# -gt 0 ]]; do
|
|
12
|
-
case "$1" in
|
|
13
|
-
--yes) yes="true"; shift ;;
|
|
14
|
-
--dry-run) dry_run="true"; shift ;;
|
|
15
|
-
--filter) use_filter="true"; shift ;;
|
|
16
|
-
--project) project="$2"; project_set="true"; shift 2 ;;
|
|
17
|
-
--task-group) task_group="$2"; task_group_set="true"; shift 2 ;;
|
|
18
|
-
--status) status="$2"; shift 2 ;;
|
|
19
|
-
--since) since="$2"; shift 2 ;;
|
|
20
|
-
--max-spawn) max_spawn="$2"; shift 2 ;;
|
|
21
|
-
--ignore-brief-drift) ignore_brief_drift="true"; shift ;;
|
|
22
|
-
last) use_last="true"; shift ;;
|
|
23
|
-
-) from_stdin="true"; shift ;;
|
|
24
|
-
*) explicit+=("$1"); shift ;;
|
|
25
|
-
esac
|
|
26
|
-
done
|
|
27
|
-
# tmux 부재 검사는 실제 spawn 이 일어나는 경우에만. --dry-run 은 CI/최소 환경에서도
|
|
28
|
-
# 안전 미리보기를 제공해야 하므로 우회한다.
|
|
29
|
-
if [[ "$dry_run" != "true" ]] && ! command -v tmux >/dev/null 2>&1; then
|
|
30
|
-
printf 'rerun: tmux is required but not found\n' >&2; exit 2
|
|
31
|
-
fi
|
|
32
|
-
# 'last' selector 는 부작용 있는 명령이므로 모호한 기본값을 거부한다.
|
|
33
|
-
# 사용자는 --project / --task-group 을 반드시 명시해야 한다 ('all' 와일드카드 허용).
|
|
34
|
-
if [[ "$use_last" == "true" ]]; then
|
|
35
|
-
if [[ "$project_set" != "true" || "$task_group_set" != "true" ]]; then
|
|
36
|
-
printf 'rerun last: --project 와 --task-group 을 반드시 지정해 주십시오 (all 와일드카드 명시 가능)\n' >&2
|
|
37
|
-
exit 2
|
|
38
|
-
fi
|
|
39
|
-
fi
|
|
40
|
-
|
|
41
|
-
# stdin selector('-') 사용 시 호출자의 파이프 데이터를 미리 읽어 env 로 전달.
|
|
42
|
-
# python3 - <<'PY' 는 stdin 을 heredoc 으로 사용하므로 자식 프로세스 안에서는
|
|
43
|
-
# sys.stdin 이 EOF 가 되어 caller 의 piped runId 들을 읽을 수 없다.
|
|
44
|
-
local stdin_payload=""
|
|
45
|
-
if [[ "$from_stdin" == "true" ]]; then
|
|
46
|
-
stdin_payload="$(cat)"
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
OKSTRA_HOME_RESOLVED="$(okstra_central_home)" \
|
|
50
|
-
OKSTRA_CTL_LIB_DIR="$SCRIPT_DIR" \
|
|
51
|
-
OKSTRA_SCRIPT="$SCRIPT_DIR/okstra.sh" \
|
|
52
|
-
OK_YES="$yes" OK_DRY="$dry_run" OK_FILTER="$use_filter" \
|
|
53
|
-
OK_PROJECT="$project" OK_TG="$task_group" OK_STATUS="$status" \
|
|
54
|
-
OK_SINCE="$since" OK_MAX="$max_spawn" OK_LAST="$use_last" \
|
|
55
|
-
OK_STDIN="$from_stdin" OK_STDIN_DATA="$stdin_payload" \
|
|
56
|
-
OK_IGNORE_BRIEF_DRIFT="$ignore_brief_drift" \
|
|
57
|
-
OK_EXPLICIT_JSON="$(printf '%s\n' "${explicit[@]:-}" | python3 -c 'import json,sys; print(json.dumps([l.strip() for l in sys.stdin if l.strip()]))')" \
|
|
58
|
-
python3 - <<'PY'
|
|
59
|
-
import fcntl, hashlib, json, os, subprocess, sys, time
|
|
60
|
-
sys.path.insert(0, os.environ["OKSTRA_CTL_LIB_DIR"])
|
|
61
|
-
from pathlib import Path
|
|
62
|
-
from okstra_ctl import (
|
|
63
|
-
expand_selectors, find_row_by_run_id, load_invocation,
|
|
64
|
-
predict_next_run_seq, build_run_id, build_tmux_command,
|
|
65
|
-
run_id_to_session_name, task_lock_filename, make_batch_id,
|
|
66
|
-
write_batch_meta, ResolveError, central_lock,
|
|
67
|
-
reserve_run_in_active, remove_reservation,
|
|
68
|
-
slugify_task_segment,
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
home = Path(os.environ["OKSTRA_HOME_RESOLVED"])
|
|
72
|
-
explicit = json.loads(os.environ["OK_EXPLICIT_JSON"])
|
|
73
|
-
use_filter = os.environ["OK_FILTER"] == "true"
|
|
74
|
-
use_last = os.environ["OK_LAST"] == "true"
|
|
75
|
-
from_stdin = os.environ["OK_STDIN"] == "true"
|
|
76
|
-
max_spawn = int(os.environ["OK_MAX"])
|
|
77
|
-
yes = os.environ["OK_YES"] == "true"
|
|
78
|
-
dry = os.environ["OK_DRY"] == "true"
|
|
79
|
-
|
|
80
|
-
try:
|
|
81
|
-
targets = expand_selectors(
|
|
82
|
-
home, explicit=explicit, use_filter=use_filter,
|
|
83
|
-
project=os.environ["OK_PROJECT"], task_group=os.environ["OK_TG"],
|
|
84
|
-
status=os.environ["OK_STATUS"], since=os.environ["OK_SINCE"],
|
|
85
|
-
last=use_last, from_stdin=from_stdin,
|
|
86
|
-
stdin_data=os.environ.get("OK_STDIN_DATA", ""),
|
|
87
|
-
)
|
|
88
|
-
except ResolveError as e:
|
|
89
|
-
print(f"rerun: {e}", file=sys.stderr); sys.exit(2)
|
|
90
|
-
|
|
91
|
-
if not targets:
|
|
92
|
-
print("rerun: no targets selected", file=sys.stderr); sys.exit(2)
|
|
93
|
-
if len(targets) > max_spawn:
|
|
94
|
-
print(f"매칭 결과 {len(targets)}건은 임계({max_spawn})를 초과합니다. "
|
|
95
|
-
f"--max-spawn {len(targets)} 로 재실행하거나 선택자를 좁혀 주십시오.",
|
|
96
|
-
file=sys.stderr); sys.exit(2)
|
|
97
|
-
if len(targets) > 1 and not yes and not dry:
|
|
98
|
-
print("rerun targets:")
|
|
99
|
-
for t in targets: print(f" - {t}")
|
|
100
|
-
print("재실행하려면 --yes 를 추가해 주십시오.", file=sys.stderr); sys.exit(2)
|
|
101
|
-
|
|
102
|
-
ignore_brief_drift = os.environ.get("OK_IGNORE_BRIEF_DRIFT") == "true"
|
|
103
|
-
|
|
104
|
-
# 현재 okstra-ctl 프로세스의 OKSTRA_HOME / 명시적 ctl-only override 만 base 에
|
|
105
|
-
# 둔다. 각 target 의 inv["envOverrides"](원본 run 시점에 캡처된 환경변수) 를
|
|
106
|
-
# 로드 시점에 layer 한다.
|
|
107
|
-
extra_env_base = {"OKSTRA_HOME": str(home)}
|
|
108
|
-
for key in ("OKSTRA_CTL_SKIP_RECONCILE", "OKSTRA_CTL_SKIP_BACKFILL"):
|
|
109
|
-
if os.environ.get(key):
|
|
110
|
-
extra_env_base[key] = os.environ[key]
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def _brief_sha256(brief_path):
|
|
114
|
-
try:
|
|
115
|
-
with open(brief_path, "rb") as f:
|
|
116
|
-
return hashlib.sha256(f.read()).hexdigest()
|
|
117
|
-
except OSError:
|
|
118
|
-
return None
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def _brief_path_from_argv(argv, cwd, project_root):
|
|
122
|
-
"""invocation argv 에서 --task-brief 값을 찾아 절대 경로화한다.
|
|
123
|
-
okstra.sh resolve_brief_path 의 lookup 순서(cwd-relative 우선,
|
|
124
|
-
PROJECT_ROOT fallback) 를 동일하게 mirror 한다 — 그렇지 않으면 사용자가
|
|
125
|
-
프로젝트 밖에서 project-relative --task-brief 로 실행한 run 의 drift
|
|
126
|
-
검사가 'brief missing' 으로 잘못 skip 된다.
|
|
127
|
-
"""
|
|
128
|
-
for i, tok in enumerate(argv):
|
|
129
|
-
if tok == "--task-brief" and i + 1 < len(argv):
|
|
130
|
-
raw = argv[i + 1]
|
|
131
|
-
p = Path(raw)
|
|
132
|
-
if p.is_absolute():
|
|
133
|
-
return p if p.is_file() else None
|
|
134
|
-
cwd_rel = Path(cwd) / p if cwd else None
|
|
135
|
-
if cwd_rel and cwd_rel.is_file():
|
|
136
|
-
return cwd_rel
|
|
137
|
-
root_rel = Path(project_root) / p if project_root else None
|
|
138
|
-
if root_rel and root_rel.is_file():
|
|
139
|
-
return root_rel
|
|
140
|
-
return None
|
|
141
|
-
return None
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
batch_id = make_batch_id()
|
|
145
|
-
items = []
|
|
146
|
-
spawned = skipped = rejected = 0
|
|
147
|
-
# 같은 (project, group, task_id, task_type) 에 속한 다중 rerun 이 같은 batch 내에서
|
|
148
|
-
# 같은 seq 를 받지 않도록 메모리상 reservation 추적. tmux spawn 후 detached okstra 가
|
|
149
|
-
# 디스크에 manifest/report 를 쓰기 전에 락이 풀리므로 filesystem-only 예측은 충돌한다.
|
|
150
|
-
batch_reserved = {}
|
|
151
|
-
for original in targets:
|
|
152
|
-
row = find_row_by_run_id(home, original)
|
|
153
|
-
# implementation 은 stage 격리 task-type 이다. 한 run = 런타임에 live
|
|
154
|
-
# registry/consumers 상태로 auto-resolve 되는 단일 stage(stage_targets.resolve_effective_stages)
|
|
155
|
-
# 이므로, cmd-rerun 은 spawn 전에 어느 stage-<N> 가 선택될지 알 수 없어
|
|
156
|
-
# runs/implementation/stage-<N> 경로도 per-stage run_seq 도 예측할 수 없다.
|
|
157
|
-
# OKSTRA_RUN_SEQ_OVERRIDE(run 전체에 단일 seq) 는 per-stage seq 카운터와
|
|
158
|
-
# 구조적으로 양립 불가하고, 원본 invocation 재생은 진짜 rerun 이 아니다
|
|
159
|
-
# (forced --stage N 은 이미 done 이라 거부되고, --stage auto 는 다른 ready
|
|
160
|
-
# stage 로 조용히 전진한다). 따라서 선예약/spawn 이전에 거부하고 신규
|
|
161
|
-
# implementation run 으로 안내한다.
|
|
162
|
-
if row and slugify_task_segment(row.get("taskType", "")) == "implementation":
|
|
163
|
-
items.append({"originalRunId": original, "newRunId": None,
|
|
164
|
-
"newRunSeq": None, "sessionName": None,
|
|
165
|
-
"status": "rejected", "spawnedAt": None,
|
|
166
|
-
"skipReason": "implementation 은 stage 격리되어 okstra-ctl rerun 으로 "
|
|
167
|
-
"재실행할 수 없습니다. 다음 ready stage 를 실행하려면 "
|
|
168
|
-
"새 implementation run 을 시작하십시오 "
|
|
169
|
-
"(okstra.sh --task-type implementation --stage auto)."})
|
|
170
|
-
rejected += 1
|
|
171
|
-
continue
|
|
172
|
-
inv = (load_invocation(home, row["projectId"], row["taskGroup"],
|
|
173
|
-
row["taskId"], row["taskType"], row["runSeq"])
|
|
174
|
-
if row else None)
|
|
175
|
-
if inv is None or inv.get("backfilled") or not Path(row["projectRoot"]).is_dir():
|
|
176
|
-
items.append({"originalRunId": original, "newRunId": None,
|
|
177
|
-
"newRunSeq": None, "sessionName": None,
|
|
178
|
-
"status": "skipped", "spawnedAt": None,
|
|
179
|
-
"skipReason": "no invocation / backfilled / project root missing"})
|
|
180
|
-
skipped += 1
|
|
181
|
-
continue
|
|
182
|
-
# brief drift 검사: 원래 run 시점에 캡처한 briefSha256 과 현재 brief 파일의
|
|
183
|
-
# 해시가 다르면, --ignore-brief-drift 가 없는 한 skip 하고 사유를 기록한다.
|
|
184
|
-
# 그렇지 않으면 batch/--yes 재실행이 다른 입력으로 silently 분석을 수행한다.
|
|
185
|
-
recorded_sha = inv.get("briefSha256") or ""
|
|
186
|
-
if recorded_sha and not ignore_brief_drift:
|
|
187
|
-
brief_abs = _brief_path_from_argv(inv.get("argv", []),
|
|
188
|
-
inv.get("cwd", ""),
|
|
189
|
-
row["projectRoot"])
|
|
190
|
-
current_sha = _brief_sha256(brief_abs) if brief_abs else None
|
|
191
|
-
if current_sha is None:
|
|
192
|
-
items.append({"originalRunId": original, "newRunId": None,
|
|
193
|
-
"newRunSeq": None, "sessionName": None,
|
|
194
|
-
"status": "skipped", "spawnedAt": None,
|
|
195
|
-
"skipReason": "brief missing for drift check"})
|
|
196
|
-
skipped += 1
|
|
197
|
-
continue
|
|
198
|
-
if current_sha != recorded_sha:
|
|
199
|
-
items.append({"originalRunId": original, "newRunId": None,
|
|
200
|
-
"newRunSeq": None, "sessionName": None,
|
|
201
|
-
"status": "skipped", "spawnedAt": None,
|
|
202
|
-
"skipReason": "brief drift (use --ignore-brief-drift to override)"})
|
|
203
|
-
skipped += 1
|
|
204
|
-
continue
|
|
205
|
-
lock = home / ".locks" / task_lock_filename(
|
|
206
|
-
row["projectId"], row["taskGroup"], row["taskId"], row["taskType"])
|
|
207
|
-
lock.parent.mkdir(parents=True, exist_ok=True); lock.touch()
|
|
208
|
-
with lock.open("r+") as lf:
|
|
209
|
-
fcntl.flock(lf.fileno(), fcntl.LOCK_EX)
|
|
210
|
-
rkey = (row["projectId"], row["taskGroup"], row["taskId"], row["taskType"])
|
|
211
|
-
used = batch_reserved.setdefault(rkey, set())
|
|
212
|
-
# 중앙 인덱스(active.jsonl) 와 manifest 디렉터리까지 함께 보고 다음 seq 를 계산.
|
|
213
|
-
# 다른 okstra-ctl 프로세스가 이미 예약했거나 in-flight 인 run 의 seq 도 회피된다.
|
|
214
|
-
with central_lock(home):
|
|
215
|
-
next_seq = predict_next_run_seq(
|
|
216
|
-
Path(row["projectRoot"]),
|
|
217
|
-
row["taskGroup"], row["taskId"], row["taskType"],
|
|
218
|
-
home=home, project_id=row["projectId"])
|
|
219
|
-
while next_seq in used:
|
|
220
|
-
next_seq += 1
|
|
221
|
-
used.add(next_seq)
|
|
222
|
-
new_run_id = build_run_id(row["projectId"], row["taskGroup"],
|
|
223
|
-
row["taskId"], row["taskType"], next_seq)
|
|
224
|
-
session = run_id_to_session_name(new_run_id)
|
|
225
|
-
# dry-run 이 아닌 경우 reservation 을 중앙 인덱스에 영속한다.
|
|
226
|
-
# 후속 okstra-ctl 호출이 즉시 이 seq 를 회피할 수 있게 된다.
|
|
227
|
-
if not dry:
|
|
228
|
-
# rerun 시 새 run 의 RUN_DIR 은 같은 task-type 디렉터리, FINAL_REPORT 는 새 seq.
|
|
229
|
-
# okstra.sh 는 디렉터리 segment 를 slugify_value 로 정규화하므로
|
|
230
|
-
# (공백/대문자/`/` 등이 포함된 raw taskGroup/taskId 그대로 쓰면
|
|
231
|
-
# 실제 디스크 경로와 어긋나 tail -F 가 영구 wait 하거나 startup
|
|
232
|
-
# 실패 시 row 가 잘못된 경로를 가리킨다) 같은 슬러그로 예측 경로를
|
|
233
|
-
# 만든다. 정상 spawn 시 record_start 가 RUN_DIR_RELATIVE_PATH 로
|
|
234
|
-
# 정확 값을 다시 update 한다.
|
|
235
|
-
slug_group = slugify_task_segment(row["taskGroup"])
|
|
236
|
-
slug_task = slugify_task_segment(row["taskId"])
|
|
237
|
-
slug_type = slugify_task_segment(row["taskType"])
|
|
238
|
-
base_run = (".okstra/tasks/"
|
|
239
|
-
f"{slug_group}/{slug_task}/runs/{slug_type}")
|
|
240
|
-
final_rel = (f"{base_run}/reports/"
|
|
241
|
-
f"final-report-{slug_type}-{next_seq:03d}.md")
|
|
242
|
-
# 예약 시점에 final status 경로도 best-effort 로 박아 둔다.
|
|
243
|
-
# RUN_STATUS_SEQ 는 RUN_MANIFESTS_SEQ 와 별개 카운터지만,
|
|
244
|
-
# 정상 run 에선 두 카운터가 함께 advance 한다(render-only/
|
|
245
|
-
# 실패 prep 만 manifest 만 advance). 추후 record_start 가
|
|
246
|
-
# 정확한 finalStatusRel 로 row 를 update 하므로 여기서 값을
|
|
247
|
-
# 비워 두면 spawn 직후 tail 이 status dir 부재로 race-fail
|
|
248
|
-
# 한다 — 기대 경로를 미리 채워 tail -F 가 등장 대기하게 한다.
|
|
249
|
-
final_status_rel = (f"{base_run}/status/"
|
|
250
|
-
f"final-{slug_type}-{next_seq:03d}.status")
|
|
251
|
-
reserve_run_in_active(
|
|
252
|
-
home, project_id=row["projectId"],
|
|
253
|
-
project_root=row["projectRoot"],
|
|
254
|
-
task_group=row["taskGroup"], task_id=row["taskId"],
|
|
255
|
-
task_type=row["taskType"], run_seq=next_seq,
|
|
256
|
-
when=time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
|
257
|
-
run_dir_rel=base_run, final_report_record_rel=final_rel,
|
|
258
|
-
final_status_rel=final_status_rel,
|
|
259
|
-
)
|
|
260
|
-
# 원본 invocation 시점에 캡처된 envOverrides 를 base 에 layer 한다.
|
|
261
|
-
# 신규 모델은 PROJECT_ROOT 를 project.json 에서 자기 해석하므로
|
|
262
|
-
# invocation-specific 환경변수 override 가 사실상 사라졌지만, 호환을
|
|
263
|
-
# 위해 envOverrides 가 dict 형태로 남아있을 수 있다. base(현재 ctl
|
|
264
|
-
# 환경) 키와 충돌하면 base 가 우선해 사용자의 OKSTRA_HOME 등이 보존된다.
|
|
265
|
-
target_env = {}
|
|
266
|
-
for k, v in (inv.get("envOverrides") or {}).items():
|
|
267
|
-
if isinstance(v, str):
|
|
268
|
-
target_env[k] = v
|
|
269
|
-
target_env.update(extra_env_base)
|
|
270
|
-
cmd = build_tmux_command(session_name=session, cwd=inv["cwd"],
|
|
271
|
-
run_seq=next_seq, argv=inv["argv"],
|
|
272
|
-
okstra_script=os.environ["OKSTRA_SCRIPT"],
|
|
273
|
-
extra_env=target_env)
|
|
274
|
-
if dry:
|
|
275
|
-
items.append({"originalRunId": original, "newRunId": new_run_id,
|
|
276
|
-
"newRunSeq": next_seq, "sessionName": session,
|
|
277
|
-
"status": "dry-run", "spawnedAt": None,
|
|
278
|
-
"skipReason": None})
|
|
279
|
-
continue
|
|
280
|
-
# 핵심 모델: tmux 세션을 detached 로 띄우고 즉시 다음 대상으로 넘어간다.
|
|
281
|
-
rc = subprocess.run(cmd, capture_output=True, text=True)
|
|
282
|
-
if rc.returncode != 0:
|
|
283
|
-
# spawn 실패 시 reservation 을 정리한다(중앙 인덱스 누수 방지).
|
|
284
|
-
with central_lock(home):
|
|
285
|
-
remove_reservation(
|
|
286
|
-
home, project_id=row["projectId"],
|
|
287
|
-
task_group=row["taskGroup"], task_id=row["taskId"],
|
|
288
|
-
task_type=row["taskType"], run_seq=next_seq,
|
|
289
|
-
)
|
|
290
|
-
items.append({"originalRunId": original, "newRunId": new_run_id,
|
|
291
|
-
"newRunSeq": next_seq, "sessionName": session,
|
|
292
|
-
"status": "skipped", "spawnedAt": None,
|
|
293
|
-
"skipReason": f"tmux: {rc.stderr.strip()}"})
|
|
294
|
-
skipped += 1
|
|
295
|
-
continue
|
|
296
|
-
items.append({"originalRunId": original, "newRunId": new_run_id,
|
|
297
|
-
"newRunSeq": next_seq, "sessionName": session,
|
|
298
|
-
"status": "spawned",
|
|
299
|
-
"spawnedAt": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
|
300
|
-
"skipReason": None})
|
|
301
|
-
spawned += 1
|
|
302
|
-
|
|
303
|
-
selector_raw = (
|
|
304
|
-
explicit
|
|
305
|
-
+ (["--filter", "--project", os.environ["OK_PROJECT"],
|
|
306
|
-
"--task-group", os.environ["OK_TG"],
|
|
307
|
-
"--status", os.environ["OK_STATUS"], "--since", os.environ["OK_SINCE"]]
|
|
308
|
-
if use_filter else [])
|
|
309
|
-
+ (["last"] if use_last else [])
|
|
310
|
-
+ (["-"] if from_stdin else [])
|
|
311
|
-
)
|
|
312
|
-
write_batch_meta(home, batch_id, {
|
|
313
|
-
"batchId": batch_id,
|
|
314
|
-
"createdAt": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
|
315
|
-
"selectorRaw": selector_raw, "maxSpawn": max_spawn,
|
|
316
|
-
"items": items,
|
|
317
|
-
"summary": {"total": len(targets), "spawned": spawned,
|
|
318
|
-
"skipped": skipped, "rejected": rejected},
|
|
319
|
-
})
|
|
320
|
-
|
|
321
|
-
dry_run_count = sum(1 for it in items if it["status"] == "dry-run")
|
|
322
|
-
if dry_run_count:
|
|
323
|
-
print(f"batch {batch_id} dry-run: {dry_run_count} skipped: {skipped} rejected: {rejected}")
|
|
324
|
-
else:
|
|
325
|
-
print(f"batch {batch_id} spawned: {spawned} skipped: {skipped} rejected: {rejected}")
|
|
326
|
-
print()
|
|
327
|
-
header = ("RUN-ID", "SESSION-NAME", "ATTACH")
|
|
328
|
-
rows = []
|
|
329
|
-
# dry-run 도 미리보기 대상이다 — preview 의 본래 목적이 spawn 없이 target/
|
|
330
|
-
# reservation 을 보여주는 것이므로 spawned 와 동일하게 row 에 포함한다.
|
|
331
|
-
for it in items:
|
|
332
|
-
if it["status"] in ("spawned", "dry-run"):
|
|
333
|
-
attach = (f"tmux attach -t {it['sessionName']}"
|
|
334
|
-
if it["status"] == "spawned" else "(dry-run)")
|
|
335
|
-
rows.append((it["newRunId"] or "-", it["sessionName"] or "-", attach))
|
|
336
|
-
if rows:
|
|
337
|
-
table = [header] + rows
|
|
338
|
-
widths = [max(len(t[i]) for t in table) for i in range(3)]
|
|
339
|
-
for t in table:
|
|
340
|
-
print(" ".join(c.ljust(widths[i]) for i, c in enumerate(t)))
|
|
341
|
-
print()
|
|
342
|
-
print(f"monitor batch : okstra-ctl batch status {batch_id}")
|
|
343
|
-
print( "list sessions : tmux ls | grep ^okstra-")
|
|
344
|
-
PY
|
|
345
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# shellcheck shell=bash
|
|
2
|
-
|
|
3
|
-
_okstra_ctl_show() {
|
|
4
|
-
if [[ $# -lt 1 ]]; then
|
|
5
|
-
printf 'show: missing <runId-or-prefix>\n' >&2; exit 2
|
|
6
|
-
fi
|
|
7
|
-
OKSTRA_HOME_RESOLVED="$(okstra_central_home)" \
|
|
8
|
-
OKSTRA_CTL_LIB_DIR="$SCRIPT_DIR" \
|
|
9
|
-
OK_QUERY="$1" \
|
|
10
|
-
python3 - <<'PY'
|
|
11
|
-
import os, sys
|
|
12
|
-
sys.path.insert(0, os.environ["OKSTRA_CTL_LIB_DIR"])
|
|
13
|
-
from pathlib import Path
|
|
14
|
-
from okstra_ctl import resolve_run_id, find_row_by_run_id, format_show, ResolveError
|
|
15
|
-
home = Path(os.environ["OKSTRA_HOME_RESOLVED"])
|
|
16
|
-
try:
|
|
17
|
-
rid = resolve_run_id(home, os.environ["OK_QUERY"])
|
|
18
|
-
except ResolveError as e:
|
|
19
|
-
print(f"show: {e}", file=sys.stderr)
|
|
20
|
-
for c in e.candidates: print(f" - {c}", file=sys.stderr)
|
|
21
|
-
sys.exit(2)
|
|
22
|
-
row = find_row_by_run_id(home, rid)
|
|
23
|
-
if row is None:
|
|
24
|
-
print(f"show: row not found for {rid}", file=sys.stderr); sys.exit(2)
|
|
25
|
-
print(format_show(row), end="")
|
|
26
|
-
PY
|
|
27
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
# shellcheck shell=bash
|
|
2
|
-
|
|
3
|
-
_okstra_ctl_tail() {
|
|
4
|
-
if [[ $# -lt 1 ]]; then
|
|
5
|
-
printf 'tail: missing <runId-or-prefix> | active\n' >&2; exit 2
|
|
6
|
-
fi
|
|
7
|
-
if [[ "$1" == "active" ]]; then
|
|
8
|
-
OKSTRA_HOME_RESOLVED="$(okstra_central_home)" \
|
|
9
|
-
OKSTRA_CTL_LIB_DIR="$SCRIPT_DIR" \
|
|
10
|
-
python3 - <<'PY'
|
|
11
|
-
import os, sys
|
|
12
|
-
sys.path.insert(0, os.environ["OKSTRA_CTL_LIB_DIR"])
|
|
13
|
-
from pathlib import Path
|
|
14
|
-
from okstra_ctl import read_run_index, format_runs_table
|
|
15
|
-
# tail active 는 active.jsonl 자체를 보여줘야 한다 — running 외에도
|
|
16
|
-
# in-progress(backfill), reserving(rerun 예약), 그리고 어떤 비-터미널
|
|
17
|
-
# 상태든 active 에 들어있는 것은 사용자가 모니터링해야 할 대상이다.
|
|
18
|
-
# 디스크 row 는 slim(파생 taskType 없음)이라 read_run_index 로 hydrate 해야
|
|
19
|
-
# format_runs_table 의 TASK-TYPE 열이 채워진다.
|
|
20
|
-
rows = sorted(read_run_index(Path(os.environ["OKSTRA_HOME_RESOLVED"]) / "active.jsonl"),
|
|
21
|
-
key=lambda r: r.get("startedAt", ""), reverse=True)
|
|
22
|
-
print(format_runs_table(rows), end="")
|
|
23
|
-
PY
|
|
24
|
-
return 0
|
|
25
|
-
fi
|
|
26
|
-
# 정확한 status 파일 경로는 row 의 finalStatusRel(RUN_STATUS_SEQ 기반,
|
|
27
|
-
# record_start 시점에 박힘) 에서 가져온다. RUN_STATUS_SEQ 와
|
|
28
|
-
# RUN_MANIFESTS_SEQ 는 별개 카운터이므로 row["runSeq"] 로 추정하면
|
|
29
|
-
# render-only 가 manifest seq 만 advance 한 직후의 실행에서 어긋난다.
|
|
30
|
-
# finalStatusRel 이 없을 때만 (구식 row) runDirRel/taskType/runSeq 로
|
|
31
|
-
# fallback 하고, 그래도 없으면 expected status 파일이 아직 만들어지지
|
|
32
|
-
# 않았어도 tail -F 로 wait 한다(`tail -F` 는 by-name 으로 파일 등장을
|
|
33
|
-
# 감지한다).
|
|
34
|
-
local resolved resolve_rc
|
|
35
|
-
resolved="$(OKSTRA_HOME_RESOLVED="$(okstra_central_home)" \
|
|
36
|
-
OKSTRA_CTL_LIB_DIR="$SCRIPT_DIR" \
|
|
37
|
-
OK_QUERY="$1" python3 -c '
|
|
38
|
-
import os, sys
|
|
39
|
-
sys.path.insert(0, os.environ["OKSTRA_CTL_LIB_DIR"])
|
|
40
|
-
from pathlib import Path
|
|
41
|
-
from okstra_ctl import resolve_run_id, find_row_by_run_id, ResolveError, resolve_under_root
|
|
42
|
-
home = Path(os.environ["OKSTRA_HOME_RESOLVED"])
|
|
43
|
-
try:
|
|
44
|
-
rid = resolve_run_id(home, os.environ["OK_QUERY"])
|
|
45
|
-
except ResolveError as e:
|
|
46
|
-
print(f"tail: {e}", file=sys.stderr)
|
|
47
|
-
for c in e.candidates: print(f" - {c}", file=sys.stderr)
|
|
48
|
-
sys.exit(2)
|
|
49
|
-
row = find_row_by_run_id(home, rid)
|
|
50
|
-
if row is None:
|
|
51
|
-
print(f"tail: row not found for {rid}", file=sys.stderr); sys.exit(2)
|
|
52
|
-
project_root = Path(row["projectRoot"])
|
|
53
|
-
run_dir = resolve_under_root(project_root, row.get("runDirRel"))
|
|
54
|
-
if run_dir is None:
|
|
55
|
-
print("tail: runDirRel escapes project root", file=sys.stderr); sys.exit(2)
|
|
56
|
-
status_rel = row.get("finalStatusRel") or ""
|
|
57
|
-
status_abs = str(project_root / status_rel) if status_rel else ""
|
|
58
|
-
print(run_dir)
|
|
59
|
-
print(row.get("taskType", ""))
|
|
60
|
-
print(int(row.get("runSeq", 0)))
|
|
61
|
-
print(status_abs)
|
|
62
|
-
')"
|
|
63
|
-
resolve_rc=$?
|
|
64
|
-
# resolve 단계가 ResolveError/누락 row 로 exit≠0 한 경우 stderr 의 깔끔한
|
|
65
|
-
# `tail: ...` 메시지를 살리고 fallback glob 으로 넘어가지 않는다.
|
|
66
|
-
if [[ $resolve_rc -ne 0 ]]; then exit "$resolve_rc"; fi
|
|
67
|
-
local rid task_type seq status_abs
|
|
68
|
-
rid="$(printf '%s\n' "$resolved" | sed -n '1p')"
|
|
69
|
-
task_type="$(printf '%s\n' "$resolved" | sed -n '2p')"
|
|
70
|
-
seq="$(printf '%s\n' "$resolved" | sed -n '3p')"
|
|
71
|
-
status_abs="$(printf '%s\n' "$resolved" | sed -n '4p')"
|
|
72
|
-
if [[ -n "$status_abs" ]]; then
|
|
73
|
-
# row 가 정식 경로를 알고 있으면 그것만 tail. 아직 파일이 없어도
|
|
74
|
-
# `tail -F` 가 등장을 기다리므로, active 진입 직후 호출도 정상.
|
|
75
|
-
exec tail -F "$status_abs"
|
|
76
|
-
fi
|
|
77
|
-
# 구식 row(이전 버전에서 작성되어 finalStatusRel 누락) — runSeq 로 glob.
|
|
78
|
-
if [[ ! -d "$rid/status" ]]; then
|
|
79
|
-
printf 'tail: status dir missing: %s/status\n' "$rid" >&2; exit 2
|
|
80
|
-
fi
|
|
81
|
-
local seq_pad
|
|
82
|
-
seq_pad="$(printf '%03d' "$seq")"
|
|
83
|
-
shopt -s nullglob
|
|
84
|
-
local matches=("$rid/status/"*"-${task_type}-${seq_pad}".*)
|
|
85
|
-
shopt -u nullglob
|
|
86
|
-
if [[ ${#matches[@]} -eq 0 ]]; then
|
|
87
|
-
# 매니페스트 카운터가 status 카운터를 앞섰을 수 있으므로 정확
|
|
88
|
-
# 매칭이 없어도 가장 그럴듯한 expected 경로로 wait 한다.
|
|
89
|
-
exec tail -F "$rid/status/final-${task_type}-${seq_pad}.status"
|
|
90
|
-
fi
|
|
91
|
-
exec tail -F "${matches[@]}"
|
|
92
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# shellcheck shell=bash
|
|
2
|
-
|
|
3
|
-
main() {
|
|
4
|
-
if [[ $# -eq 0 ]]; then
|
|
5
|
-
usage
|
|
6
|
-
exit 2
|
|
7
|
-
fi
|
|
8
|
-
case "$1" in
|
|
9
|
-
-h|--help)
|
|
10
|
-
cat <<'HELP'
|
|
11
|
-
okstra-ctl: okstra Control Center CLI.
|
|
12
|
-
|
|
13
|
-
Subcommands: projects, list, show, open, tail, rerun, batch, reconcile, reindex.
|
|
14
|
-
HELP
|
|
15
|
-
usage
|
|
16
|
-
exit 0
|
|
17
|
-
;;
|
|
18
|
-
projects|list|show|open|tail|rerun|batch|reconcile|reindex)
|
|
19
|
-
local sub="$1"; shift
|
|
20
|
-
# reindex 는 사용자가 명시적으로 지정한 --project 필터를 가지므로,
|
|
21
|
-
# 이 경로에서 자동(unqualified) backfill 을 추가로 돌리면 사용자
|
|
22
|
-
# scope 을 무시하고 모든 프로젝트를 스캔하게 된다. reindex 자체가
|
|
23
|
-
# backfill 을 수행하므로 prepare 의 자동 backfill 단계는 건너뛴다.
|
|
24
|
-
if [[ "$sub" == "reindex" ]]; then
|
|
25
|
-
OKSTRA_CTL_SKIP_BACKFILL=1 _okstra_ctl_prepare
|
|
26
|
-
elif [[ "$sub" == "reconcile" ]]; then
|
|
27
|
-
# 사용자 --project 필터를 보존하기 위해 prepare 의 unscoped
|
|
28
|
-
# reconcile 단계를 건너뛴다(서브커맨드 본체가 스코프 reconcile 수행).
|
|
29
|
-
OKSTRA_CTL_SKIP_RECONCILE=1 _okstra_ctl_prepare
|
|
30
|
-
else
|
|
31
|
-
_okstra_ctl_prepare
|
|
32
|
-
fi
|
|
33
|
-
"_okstra_ctl_${sub}" "$@"
|
|
34
|
-
;;
|
|
35
|
-
*)
|
|
36
|
-
printf 'unknown subcommand: %s\n' "$1" >&2
|
|
37
|
-
usage
|
|
38
|
-
exit 2
|
|
39
|
-
;;
|
|
40
|
-
esac
|
|
41
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# shellcheck shell=bash
|
|
2
|
-
|
|
3
|
-
_okstra_ctl_prepare() {
|
|
4
|
-
okstra_central_bootstrap
|
|
5
|
-
local home; home="$(okstra_central_home)"
|
|
6
|
-
if [[ "${OKSTRA_CTL_SKIP_BACKFILL:-0}" != "1" ]]; then
|
|
7
|
-
if ! OKSTRA_STATE_PATH="$home/state.json" python3 -c '
|
|
8
|
-
import json, os, sys
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
state = Path(os.environ["OKSTRA_STATE_PATH"])
|
|
11
|
-
data = json.loads(state.read_text()) if state.is_file() else {}
|
|
12
|
-
sys.exit(0 if data.get("backfilledAt") else 1)
|
|
13
|
-
'; then
|
|
14
|
-
_okstra_ctl_reindex >/dev/null 2>&1 || true
|
|
15
|
-
fi
|
|
16
|
-
fi
|
|
17
|
-
if [[ "${OKSTRA_CTL_SKIP_RECONCILE:-0}" == "1" ]]; then
|
|
18
|
-
return 0
|
|
19
|
-
fi
|
|
20
|
-
OKSTRA_HOME_RESOLVED="$home" \
|
|
21
|
-
OKSTRA_CTL_LIB_DIR="$SCRIPT_DIR" \
|
|
22
|
-
python3 - <<'PY'
|
|
23
|
-
import os, sys
|
|
24
|
-
sys.path.insert(0, os.environ["OKSTRA_CTL_LIB_DIR"])
|
|
25
|
-
from pathlib import Path
|
|
26
|
-
from okstra_ctl import reconcile_active, reconcile_recent
|
|
27
|
-
home = Path(os.environ["OKSTRA_HOME_RESOLVED"])
|
|
28
|
-
reconcile_active(home)
|
|
29
|
-
reconcile_recent(home)
|
|
30
|
-
PY
|
|
31
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# shellcheck shell=bash
|
|
2
|
-
|
|
3
|
-
usage() {
|
|
4
|
-
cat >&2 <<'USAGE'
|
|
5
|
-
usage:
|
|
6
|
-
okstra-ctl projects [--sort recent|name|count] [--active]
|
|
7
|
-
okstra-ctl list [--project <id|all>] [--task-group <name|all>]
|
|
8
|
-
[--status running|completed|failed|all]
|
|
9
|
-
[--since <duration|date>] [--limit N]
|
|
10
|
-
okstra-ctl show <taskId-or-prefix>
|
|
11
|
-
okstra-ctl open <taskId-or-prefix>
|
|
12
|
-
okstra-ctl tail <taskId-or-prefix> | active
|
|
13
|
-
okstra-ctl rerun <selector> [<selector> ...]
|
|
14
|
-
[--filter --project <id|all> --task-group <name|all>
|
|
15
|
-
--status ... --since ...]
|
|
16
|
-
[--max-spawn N] [--dry-run] [--yes]
|
|
17
|
-
okstra-ctl batch list
|
|
18
|
-
okstra-ctl batch status <batch-id>
|
|
19
|
-
okstra-ctl reconcile [--project <id|all>]
|
|
20
|
-
okstra-ctl reindex [--project <id|all>]
|
|
21
|
-
okstra-ctl --help
|
|
22
|
-
USAGE
|
|
23
|
-
}
|