okstra 0.202.0 → 0.205.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 +7 -6
- package/dist/cli-registry.mjs +7 -7
- package/dist/cli-registry.mjs.map +1 -1
- package/dist/commands/lifecycle/install.mjs +50 -124
- package/dist/commands/lifecycle/install.mjs.map +1 -1
- package/dist/commands/memory/memory.mjs +41 -8
- package/dist/commands/memory/memory.mjs.map +1 -1
- package/dist/lib/install-assets.mjs +3 -0
- package/dist/lib/install-assets.mjs.map +1 -1
- package/dist/lib/runtime-manifest.mjs +2 -1
- package/dist/lib/runtime-manifest.mjs.map +1 -1
- package/dist/lib/types.d.mts +2 -1
- package/docs/architecture/storage-model.md +14 -11
- package/docs/architecture.md +26 -20
- package/docs/cli.md +15 -12
- package/docs/contributor-change-matrix.md +3 -2
- package/docs/performance-improvement-plan-v2.md +3 -9
- package/docs/project-structure-overview.md +39 -11
- package/docs/task-process/README.md +1 -1
- package/docs/task-process/common-flow.md +1 -1
- package/docs/task-process/final-verification.md +3 -1
- package/docs/task-process/implementation-option-selection.md +1 -1
- package/docs/task-process/implementation.md +1 -1
- package/docs/task-process/release-handoff.md +36 -39
- package/package.json +1 -2
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/common.json +28 -0
- package/runtime/agents/operations/code-review.json +6 -0
- package/runtime/agents/operations/report-translation.json +6 -0
- package/runtime/agents/operations/schedule-verification.json +6 -0
- package/runtime/agents/roles/analyser.json +18 -0
- package/runtime/agents/roles/critic.json +18 -0
- package/runtime/agents/roles/designer.json +18 -0
- package/runtime/agents/roles/implementer.json +20 -0
- package/runtime/agents/roles/leader.json +20 -0
- package/runtime/agents/roles/planner.json +18 -0
- package/runtime/agents/roles/report-writer.json +19 -0
- package/runtime/agents/roles/translator.json +19 -0
- package/runtime/agents/roles/verifier.json +18 -0
- package/runtime/bin/lib/okstra/usage.sh +5 -5
- package/runtime/prompts/duties/acceptance-critic.json +32 -0
- package/runtime/prompts/duties/acceptance-verifier.json +32 -0
- package/runtime/prompts/duties/analysis-worker.json +32 -0
- package/runtime/prompts/duties/code-reviewer.json +32 -0
- package/runtime/prompts/duties/diagnosis-worker.json +32 -0
- package/runtime/prompts/duties/direction-selection-worker.json +32 -0
- package/runtime/prompts/duties/discovery-worker.json +32 -0
- package/runtime/prompts/duties/implementation-executor.json +32 -0
- package/runtime/prompts/duties/implementation-verifier.json +32 -0
- package/runtime/prompts/duties/lead.json +32 -0
- package/runtime/prompts/duties/planning-worker.json +36 -0
- package/runtime/prompts/duties/report-writer.json +32 -0
- package/runtime/prompts/duties/reverification-worker.json +32 -0
- package/runtime/prompts/duties/schedule-verifier.json +32 -0
- package/runtime/prompts/duties/scope-critic.json +32 -0
- package/runtime/prompts/duties/technical-verification-worker.json +32 -0
- package/runtime/prompts/duties/translator.json +32 -0
- package/runtime/prompts/launch.template.md +2 -1
- package/runtime/prompts/lead/adapters/cmux.md +1 -1
- package/runtime/prompts/lead/convergence.md +4 -4
- package/runtime/prompts/lead/okstra-lead-contract.md +115 -6
- package/runtime/prompts/lead/plan-body-verification.md +6 -6
- package/runtime/prompts/lead/report-writer.md +3 -3
- package/runtime/prompts/profiles/_common-contract.md +2 -2
- package/runtime/prompts/profiles/_implementation-diff-review.md +1 -1
- package/runtime/prompts/profiles/_implementation-executor.md +4 -1
- package/runtime/prompts/profiles/_implementation-self-check.md +1 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +2 -2
- package/runtime/prompts/profiles/change-impact-analysis.json +31 -0
- package/runtime/prompts/profiles/change-impact-analysis.md +0 -20
- package/runtime/prompts/profiles/error-analysis.json +39 -0
- package/runtime/prompts/profiles/error-analysis.md +0 -25
- package/runtime/prompts/profiles/feature-analysis.json +31 -0
- package/runtime/prompts/profiles/feature-analysis.md +0 -20
- package/runtime/prompts/profiles/final-verification.json +30 -0
- package/runtime/prompts/profiles/final-verification.md +4 -23
- package/runtime/prompts/profiles/forbidden-actions.json +4 -3
- package/runtime/prompts/profiles/implementation-option-selection.json +31 -0
- package/runtime/prompts/profiles/implementation-option-selection.md +0 -20
- package/runtime/prompts/profiles/implementation-planning.json +40 -0
- package/runtime/prompts/profiles/implementation-planning.md +4 -29
- package/runtime/prompts/profiles/implementation.json +30 -0
- package/runtime/prompts/profiles/implementation.md +1 -20
- package/runtime/prompts/profiles/improvement-discovery.json +31 -0
- package/runtime/prompts/profiles/improvement-discovery.md +0 -20
- package/runtime/prompts/profiles/project-analysis.json +31 -0
- package/runtime/prompts/profiles/project-analysis.md +0 -20
- package/runtime/prompts/profiles/release-handoff.json +5 -0
- package/runtime/prompts/profiles/release-handoff.md +74 -74
- package/runtime/prompts/profiles/requirements-discovery.json +39 -0
- package/runtime/prompts/profiles/requirements-discovery.md +0 -25
- package/runtime/prompts/profiles/technical-verification.json +39 -0
- package/runtime/prompts/profiles/technical-verification.md +0 -25
- package/runtime/prompts/wizard/prompts.ko.json +14 -18
- package/runtime/python/okstra_ctl/adapters/hosts/antigravity/relay.md +1 -0
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/adapter.py +3 -0
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/manifest.json +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +4 -3
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/worker-session.md +108 -0
- package/runtime/python/okstra_ctl/adapters/hosts/codex/relay.md +1 -0
- package/runtime/python/okstra_ctl/adapters/hosts/grok/relay.md +2 -0
- package/runtime/python/okstra_ctl/adapters/hosts/kimi/relay.md +2 -0
- package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +8 -1
- package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +8 -0
- package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +23 -6
- package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +6 -2
- package/runtime/python/okstra_ctl/agent/invocation.py +168 -113
- package/runtime/python/okstra_ctl/agent/prompt_cli/cli.py +120 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/materialize.py +107 -2
- package/runtime/python/okstra_ctl/agent/prompt_cli/run_identity.py +0 -49
- package/runtime/python/okstra_ctl/analysis_packet.py +4 -1
- package/runtime/python/okstra_ctl/application/open_worker.py +6 -1
- package/runtime/python/okstra_ctl/assignment_resolver.py +16 -5
- package/runtime/python/okstra_ctl/cmux.py +69 -20
- package/runtime/python/okstra_ctl/code_review_target.py +16 -8
- package/runtime/python/okstra_ctl/conformance.py +43 -0
- package/runtime/python/okstra_ctl/consumers.py +23 -8
- package/runtime/python/okstra_ctl/container.py +31 -8
- package/runtime/python/okstra_ctl/context_cost.py +11 -15
- package/runtime/python/okstra_ctl/contract_refreeze.py +156 -0
- package/runtime/python/okstra_ctl/convergence_engine.py +38 -0
- package/runtime/python/okstra_ctl/convergence_provenance.py +7 -1
- package/runtime/python/okstra_ctl/design_prep.py +34 -1
- package/runtime/python/okstra_ctl/dispatch_core.py +53 -27
- package/runtime/python/okstra_ctl/domain/host.py +5 -0
- package/runtime/python/okstra_ctl/domain/worker_runtime.py +10 -0
- package/runtime/python/okstra_ctl/error_report.py +4 -3
- package/runtime/python/okstra_ctl/execution_manifest.py +71 -18
- package/runtime/python/okstra_ctl/handoff.py +384 -286
- package/runtime/python/okstra_ctl/handoff_verification.py +25 -6
- package/runtime/python/okstra_ctl/implementation_stage.py +9 -0
- package/runtime/python/okstra_ctl/initial_prompt_materialization.py +113 -0
- package/runtime/python/okstra_ctl/lead_progress.py +1 -1
- package/runtime/python/okstra_ctl/legacy_model_selection.py +2 -2
- package/runtime/python/okstra_ctl/manager_cli.py +92 -4
- package/runtime/python/okstra_ctl/manager_launch.py +1 -1
- package/runtime/python/okstra_ctl/manager_paths.py +14 -3
- package/runtime/python/okstra_ctl/manager_store.py +210 -3
- package/runtime/python/okstra_ctl/manager_sync.py +4 -1
- package/runtime/python/okstra_ctl/manager_view.py +2 -1
- package/runtime/python/okstra_ctl/model_discovery.py +30 -0
- package/runtime/python/okstra_ctl/model_io/lines.py +14 -1
- package/runtime/python/okstra_ctl/model_io/renderers.py +4 -3
- package/runtime/python/okstra_ctl/models.py +1 -1
- package/runtime/python/okstra_ctl/next_phase.py +16 -6
- package/runtime/python/okstra_ctl/operation_invocation.py +86 -0
- package/runtime/python/okstra_ctl/option_comparison.py +168 -0
- package/runtime/python/okstra_ctl/path_hints.py +9 -0
- package/runtime/python/okstra_ctl/paths.py +3 -0
- package/runtime/python/okstra_ctl/profile_show.py +42 -1
- package/runtime/python/okstra_ctl/registry/host_discovery.py +20 -12
- package/runtime/python/okstra_ctl/registry/host_registry.py +11 -0
- package/runtime/python/okstra_ctl/render.py +79 -0
- package/runtime/python/okstra_ctl/report_contract.py +1 -1
- package/runtime/python/okstra_ctl/report_html/view_models/release_handoff.py +21 -3
- package/runtime/python/okstra_ctl/report_synthesis_packet.py +177 -17
- package/runtime/python/okstra_ctl/report_translation.py +2 -1
- package/runtime/python/okstra_ctl/report_translation_dispatch.py +69 -9
- package/runtime/python/okstra_ctl/role_requirements.py +142 -129
- package/runtime/python/okstra_ctl/rollup.py +3 -1
- package/runtime/python/okstra_ctl/run.py +76 -29
- package/runtime/python/okstra_ctl/schedule_semantics.py +17 -6
- package/runtime/python/okstra_ctl/stage_fix_carry.py +23 -4
- package/runtime/python/okstra_ctl/stage_integrate.py +178 -18
- package/runtime/python/okstra_ctl/stage_map.py +16 -2
- package/runtime/python/okstra_ctl/stage_targets.py +209 -43
- package/runtime/python/okstra_ctl/team.py +22 -13
- package/runtime/python/okstra_ctl/time_report.py +2 -1
- package/runtime/python/okstra_ctl/usage_report.py +3 -1
- package/runtime/python/okstra_ctl/wizard/confirmation.py +3 -9
- package/runtime/python/okstra_ctl/wizard/ids.py +1 -1
- package/runtime/python/okstra_ctl/wizard/registry.py +1 -1
- package/runtime/python/okstra_ctl/wizard/state.py +3 -5
- package/runtime/python/okstra_ctl/wizard/steps_plan.py +12 -21
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +5 -1
- package/runtime/python/okstra_ctl/worker_prompt_headers.py +35 -7
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +66 -48
- package/runtime/python/okstra_ctl/workflow.py +1 -1
- package/runtime/python/okstra_ctl/worktree/__init__.py +3 -1
- package/runtime/python/okstra_ctl/worktree/naming.py +9 -0
- package/runtime/python/okstra_ctl/worktree_registry.py +38 -9
- package/runtime/python/okstra_token_usage/pricing.py +6 -4
- package/runtime/schemas/agent-common-v1.schema.json +34 -0
- package/runtime/schemas/agent-duty-v1.schema.json +38 -0
- package/runtime/schemas/agent-operation-v1.schema.json +11 -0
- package/runtime/schemas/agent-profile-v1.schema.json +46 -0
- package/runtime/schemas/agent-role-v1.schema.json +29 -0
- package/runtime/schemas/final-report-v2.0.schema.json +118 -97
- package/runtime/schemas/final-report-v3.0.schema.json +118 -97
- package/runtime/skills/okstra-brief-gen/SKILL.md +84 -4
- package/runtime/skills/okstra-chat/SKILL.md +2 -2
- package/runtime/skills/okstra-code-review/SKILL.md +23 -9
- package/runtime/skills/okstra-container-build/SKILL.md +10 -10
- package/runtime/skills/okstra-inspect/SKILL.md +1 -1
- package/runtime/skills/okstra-inspect/facets/cost.md +1 -1
- package/runtime/skills/okstra-inspect/facets/error-zip.md +9 -9
- package/runtime/skills/okstra-inspect/facets/errors.md +16 -16
- package/runtime/skills/okstra-inspect/facets/logs.md +7 -7
- package/runtime/skills/okstra-inspect/facets/recap.md +2 -2
- package/runtime/skills/okstra-inspect/facets/report.md +1 -1
- package/runtime/skills/okstra-inspect/facets/status.md +4 -3
- package/runtime/skills/okstra-inspect/facets/time.md +11 -10
- package/runtime/skills/okstra-manager/SKILL.md +18 -2
- package/runtime/skills/okstra-pr-gen/SKILL.md +6 -5
- package/runtime/skills/okstra-rollup/SKILL.md +5 -5
- package/runtime/skills/okstra-run/SKILL.md +31 -12
- package/runtime/skills/okstra-schedule-gen/SKILL.md +19 -14
- package/runtime/skills/okstra-setup/SKILL.md +12 -10
- package/runtime/skills/okstra-setup/references/project-config.md +7 -6
- package/runtime/skills/okstra-usage/SKILL.md +1 -1
- package/runtime/skills/okstra-user-response/SKILL.md +1 -1
- package/runtime/templates/manager/view.template.html +1 -0
- package/runtime/templates/report-writer-prompt-preamble.md +8 -0
- package/runtime/templates/reports/brief.template.md +14 -4
- package/runtime/templates/reports/html/i18n/en.json +5 -4
- package/runtime/templates/reports/html/i18n/ko.json +5 -4
- package/runtime/templates/reports/html/tasks/release-handoff.template.html +8 -5
- package/runtime/templates/reports/i18n/en.json +1 -1
- package/runtime/templates/reports/md/tasks/release-handoff.template.md +1 -1
- package/runtime/templates/reports/release-handoff-input.template.md +6 -4
- package/runtime/templates/translator-prompt-preamble.md +36 -0
- package/runtime/validators/checks/validate-assets-01.py +7 -8
- package/runtime/validators/validate-brief.py +70 -0
- package/runtime/validators/validate-implementation-plan-stages.py +2 -1
- package/runtime/validators/validate-run.py +72 -15
- package/runtime/validators/validate-schedule.py +9 -0
- package/docs/for-ai/README.md +0 -68
- package/docs/for-ai/skills/okstra-brief-gen.md +0 -262
- package/docs/for-ai/skills/okstra-chat.md +0 -34
- package/docs/for-ai/skills/okstra-code-review.md +0 -57
- package/docs/for-ai/skills/okstra-container-build.md +0 -129
- package/docs/for-ai/skills/okstra-inspect.md +0 -262
- package/docs/for-ai/skills/okstra-manager.md +0 -86
- package/docs/for-ai/skills/okstra-memory.md +0 -126
- package/docs/for-ai/skills/okstra-pr-gen.md +0 -49
- package/docs/for-ai/skills/okstra-rollup.md +0 -114
- package/docs/for-ai/skills/okstra-run.md +0 -250
- package/docs/for-ai/skills/okstra-schedule-gen.md +0 -240
- package/docs/for-ai/skills/okstra-setup.md +0 -167
- package/docs/for-ai/skills/okstra-usage.md +0 -29
- package/docs/for-ai/skills/okstra-user-response.md +0 -72
- package/runtime/agents/workers/claude-worker.md +0 -128
- package/runtime/agents/workers/report-writer-worker.md +0 -37
- package/runtime/agents/workers/translator-worker.md +0 -63
- package/runtime/prompts/duties/acceptance-critic.md +0 -44
- package/runtime/prompts/duties/acceptance-verifier.md +0 -44
- package/runtime/prompts/duties/analysis-worker.md +0 -44
- package/runtime/prompts/duties/code-reviewer.md +0 -44
- package/runtime/prompts/duties/common.md +0 -39
- package/runtime/prompts/duties/diagnosis-worker.md +0 -44
- package/runtime/prompts/duties/direction-selection-worker.md +0 -44
- package/runtime/prompts/duties/discovery-worker.md +0 -44
- package/runtime/prompts/duties/implementation-executor.md +0 -44
- package/runtime/prompts/duties/implementation-verifier.md +0 -44
- package/runtime/prompts/duties/lead.md +0 -44
- package/runtime/prompts/duties/planning-worker.md +0 -52
- package/runtime/prompts/duties/report-writer.md +0 -44
- package/runtime/prompts/duties/reverification-worker.md +0 -44
- package/runtime/prompts/duties/schedule-verifier.md +0 -44
- package/runtime/prompts/duties/scope-critic.md +0 -44
- package/runtime/prompts/duties/technical-verification-worker.md +0 -44
- package/runtime/prompts/duties/translator.md +0 -44
- package/runtime/python/okstra_ctl/pane_title.py +0 -154
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Translator Prompt Preamble (canonical)
|
|
2
|
+
|
|
3
|
+
This file is the audience-specific contract for `translator`. Read it and the shared Worker Error Contract end-to-end. The task instructions in this prompt own this run's commands, paths, and target language; this file owns how you translate and what you may write.
|
|
4
|
+
|
|
5
|
+
## Output ownership
|
|
6
|
+
|
|
7
|
+
Write only the translations file at `**Result Path:**`, the completion pointer at `**Worker Result Path:**`, and the reading audit at `**Audit sidecar path:**`. The publish command named in the task instructions owns the sidecar the renderer overlays; do not write that file yourself.
|
|
8
|
+
|
|
9
|
+
Never edit the report record, the narrative Markdown, the rendered HTML, or any project source file.
|
|
10
|
+
|
|
11
|
+
Never add, remove, or re-order the `T-NNN` items relative to the work list you were given. Never translate a value the work list did not offer you: its absence is deliberate, because the renderer reads those values as machinery and a translated copy breaks the page silently.
|
|
12
|
+
|
|
13
|
+
Never return the translated text inline. The file on disk is the artifact; your return message names the paths and the verification result.
|
|
14
|
+
|
|
15
|
+
## Required reading
|
|
16
|
+
|
|
17
|
+
Read the complete work list before translating any item, continuing in chunks when it is long. A partial read produces a partial sidecar, and the items you never saw render in the source language with no error raised.
|
|
18
|
+
|
|
19
|
+
## How to translate
|
|
20
|
+
|
|
21
|
+
Judge every term on whether the translation or the original carries the meaning faster to a working developer in the target language, and pick that one. The goal is a reader who understands the report sooner, not a document with no English left in it.
|
|
22
|
+
|
|
23
|
+
- **Never touch**: code identifiers, file paths, CLI commands and flags, model names, commit SHAs, URLs, and anything already inside backticks. Reproduce them character for character.
|
|
24
|
+
- **Keep the English word** when that is what developers in the target language actually say. Forcing a native coinage onto `commit`, `worktree`, `merge`, `lint`, `diff`, `stage`, `rollback` or `PR` makes the sentence *slower* to read, not more local.
|
|
25
|
+
- **Translate the explanation.** Connective prose — why something matters, what a reader should do, what a finding means — is where the translation earns its place. Carry the meaning, not the word order.
|
|
26
|
+
- **Do not translate literally.** A word-for-word rendering that is technically correct and unreadable has failed. Say what the sentence means the way a developer would say it.
|
|
27
|
+
- **Gloss on first use, once.** When a technical term does need translating, write it as `<translation>(<English>)` the first time it appears in the document, then use the translation alone. Never gloss the same term twice.
|
|
28
|
+
- **One claim per sentence.** Where the English stacks four clauses behind em-dashes, split it. The reader gains nothing from the original's punctuation.
|
|
29
|
+
- **Match the register.** A verdict line is terse; a rationale paragraph is explanatory. Do not inflate a three-word cell into a sentence, or compress a paragraph into a fragment.
|
|
30
|
+
- **Leave it out when you cannot do it justice.** An omitted item renders in the source language, which is a correct fallback. A confident mistranslation is not.
|
|
31
|
+
|
|
32
|
+
## Failure handling
|
|
33
|
+
|
|
34
|
+
A failing verification check means a pointer resolves nowhere — you altered or invented one. Fix the translation and run the check again; do not return while it fails.
|
|
35
|
+
|
|
36
|
+
Record your own tool failures through the file named by `**Worker Error Contract Path:**`.
|
|
@@ -22,15 +22,14 @@ def check(source_path: Path, target_path: Path) -> None:
|
|
|
22
22
|
errors.append(f"build-output asset does not match source: {target_path}")
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
# 1.
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if not workers_source.is_dir():
|
|
30
|
-
errors.append(f"missing agents/workers source directory: {workers_source}")
|
|
25
|
+
# 1. Agent contracts: agents/common.json + agents/roles/* + agents/operations/*
|
|
26
|
+
# -> runtime/agents/*. 호스트 전역 에이전트 정의는 더 이상 없다(ADR-0017).
|
|
27
|
+
if not agents_source_root.is_dir():
|
|
28
|
+
errors.append(f"missing agents source directory: {agents_source_root}")
|
|
31
29
|
else:
|
|
32
|
-
for source_path in sorted(
|
|
33
|
-
|
|
30
|
+
for source_path in sorted(agents_source_root.rglob("*.json")):
|
|
31
|
+
relative = source_path.relative_to(agents_source_root)
|
|
32
|
+
check(source_path, runtime_root / "agents" / relative)
|
|
34
33
|
|
|
35
34
|
# 2. Lead contract + internal lead resources: prompts/lead/* + prompts/coding-preflight/*
|
|
36
35
|
# -> runtime/prompts/*. These ship as runtime resources (okstra install copies
|
|
@@ -47,6 +47,10 @@ Checks performed per brief file:
|
|
|
47
47
|
it is checked by `okstra_ctl.group_context.validate_group_context` (four
|
|
48
48
|
required sections, no template placeholder left, directory slug matches
|
|
49
49
|
the frontmatter `task-group`). Any other `type` is a failure.
|
|
50
|
+
16. No required section except `## Source Material` still carries the
|
|
51
|
+
template's `<...>` scaffolding — a paragraph wrapped in angle brackets,
|
|
52
|
+
a `- <...>` bullet, or a `> augmented: <label>` line. Source Material is
|
|
53
|
+
exempt because it holds the reporter's words verbatim.
|
|
50
54
|
|
|
51
55
|
Exit code 0 on PASS, 1 on FAIL.
|
|
52
56
|
"""
|
|
@@ -656,6 +660,71 @@ def check_variant_required_sections(
|
|
|
656
660
|
)
|
|
657
661
|
|
|
658
662
|
|
|
663
|
+
# 템플릿의 `<...>` 문구는 작성자가 바꿔 쓸 자리다. 그대로 남으면 다음 phase 가
|
|
664
|
+
# 그 문구를 제보 내용으로 읽는다. 문구는 여러 줄에 걸친 한 문단이라 줄 단위
|
|
665
|
+
# `is_template_example` 만으로는 잡히지 않는다 — 문단을 합쳐서 본다.
|
|
666
|
+
_AUGMENTED_LABEL_SCAFFOLD_RE = re.compile(r"^>\s*augmented:\s*<label>")
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
def _paragraphs_outside_fences(body: str) -> Iterable[list[str]]:
|
|
670
|
+
paragraph: list[str] = []
|
|
671
|
+
in_fence = False
|
|
672
|
+
for line in body.splitlines():
|
|
673
|
+
stripped = line.strip()
|
|
674
|
+
if stripped.startswith("```"):
|
|
675
|
+
in_fence = not in_fence
|
|
676
|
+
if in_fence or stripped.startswith("```") or not stripped:
|
|
677
|
+
if paragraph:
|
|
678
|
+
yield paragraph
|
|
679
|
+
paragraph = []
|
|
680
|
+
continue
|
|
681
|
+
paragraph.append(stripped)
|
|
682
|
+
if paragraph:
|
|
683
|
+
yield paragraph
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
def template_scaffold(body: str) -> list[str]:
|
|
687
|
+
"""Template scaffolding left in a section body, one entry per leftover."""
|
|
688
|
+
found: list[str] = []
|
|
689
|
+
for paragraph in _paragraphs_outside_fences(body):
|
|
690
|
+
joined = " ".join(paragraph)
|
|
691
|
+
if joined.startswith("<") and joined.endswith(">"):
|
|
692
|
+
found.append(joined)
|
|
693
|
+
continue
|
|
694
|
+
found.extend(
|
|
695
|
+
line
|
|
696
|
+
for line in paragraph
|
|
697
|
+
if is_template_example(line) or _AUGMENTED_LABEL_SCAFFOLD_RE.match(line)
|
|
698
|
+
)
|
|
699
|
+
return found
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
def check_template_scaffold(text: str, scope: str, errors: list[str]) -> None:
|
|
703
|
+
"""Required sections must not keep the template's `<...>` scaffolding.
|
|
704
|
+
|
|
705
|
+
`## Source Material` is exempt: it holds the reporter's words verbatim,
|
|
706
|
+
and those can legitimately contain angle-bracketed text.
|
|
707
|
+
"""
|
|
708
|
+
headings = [
|
|
709
|
+
REQUIREMENT_SECTION,
|
|
710
|
+
*ALWAYS_REQUIRED_SECTIONS,
|
|
711
|
+
_GATE_SECTION,
|
|
712
|
+
*(heading for heading, _prefix in _END_STATE_SECTIONS),
|
|
713
|
+
]
|
|
714
|
+
if scope == "codebase":
|
|
715
|
+
headings += ["Scan Scope", "Priority Lenses"]
|
|
716
|
+
else:
|
|
717
|
+
headings.append("Problem / Symptom")
|
|
718
|
+
for heading in headings:
|
|
719
|
+
leftover = template_scaffold(section_body(text, heading))
|
|
720
|
+
if leftover:
|
|
721
|
+
errors.append(
|
|
722
|
+
f"'## {heading}' still carries template text {leftover[0][:60]!r} — "
|
|
723
|
+
"replace it with the brief's content, or _(none)_ when the section "
|
|
724
|
+
"is deliberately empty. Downstream phases read this section as written"
|
|
725
|
+
)
|
|
726
|
+
|
|
727
|
+
|
|
659
728
|
def check_reporter_confirmations(
|
|
660
729
|
rc_status: str | None, reporter_rows: list[str], errors: list[str]
|
|
661
730
|
) -> None:
|
|
@@ -724,6 +793,7 @@ def validate_brief(path: Path, briefs_root: Path) -> list[str]:
|
|
|
724
793
|
check_requirement_section(text, errors)
|
|
725
794
|
check_end_state_sections(text, scope, errors)
|
|
726
795
|
check_variant_required_sections(text, scope, errors)
|
|
796
|
+
check_template_scaffold(text, scope, errors)
|
|
727
797
|
|
|
728
798
|
# 2. brief-id matches filename stem
|
|
729
799
|
stem = path.stem
|
|
@@ -34,6 +34,7 @@ from okstra_ctl.stage_map import ( # noqa: E402
|
|
|
34
34
|
parse_stage_dependencies,
|
|
35
35
|
parse_stage_map_text,
|
|
36
36
|
schema_v2_report,
|
|
37
|
+
stage_number_gap_message,
|
|
37
38
|
)
|
|
38
39
|
|
|
39
40
|
HARD_STEP_CAP = 8
|
|
@@ -86,7 +87,7 @@ def _stage_numbers_monotonic(
|
|
|
86
87
|
) -> List[ValidationError]:
|
|
87
88
|
return [
|
|
88
89
|
ValidationError("S2", r.stage_number,
|
|
89
|
-
|
|
90
|
+
stage_number_gap_message(r.stage_number, i))
|
|
90
91
|
for i, r in enumerate(stages, start=1)
|
|
91
92
|
if r.stage_number != i
|
|
92
93
|
]
|
|
@@ -43,6 +43,7 @@ from okstra_project.resolver import resolve_architecture # noqa: E402
|
|
|
43
43
|
from okstra_ctl.conformance import ( # noqa: E402
|
|
44
44
|
conformance_result_file,
|
|
45
45
|
detect_surfaces,
|
|
46
|
+
declared_stage_surface_gaps,
|
|
46
47
|
exempt_stage_surface_conflicts,
|
|
47
48
|
evaluate_conformance,
|
|
48
49
|
manifest_required_surfaces,
|
|
@@ -2120,7 +2121,13 @@ def _declared_conformance_errors(
|
|
|
2120
2121
|
and all(isinstance(value, str) for value in actual_requires)
|
|
2121
2122
|
else None
|
|
2122
2123
|
)
|
|
2123
|
-
|
|
2124
|
+
# 넓히는 것만 허용한다 — 선언보다 많은 capability 는 더 엄격한 검증이다.
|
|
2125
|
+
# 승인된 계획이 `requires` 를 좁게 적고 그 stage 의 diff 가 다른 표면을
|
|
2126
|
+
# 건드리면, diff-surface 대조는 넓힐 것을 요구하는데 정확 일치는 그것을
|
|
2127
|
+
# 거절해 같은 계획으로는 통과할 입력이 없었다(2026-09-22 dev-10860
|
|
2128
|
+
# Stage 1). 좁히는 것은 선언한 검증을 빼는 것이므로 여전히 불일치다.
|
|
2129
|
+
declared_capabilities = frozenset(declaration.get("requires") or [])
|
|
2130
|
+
if actual_capabilities is None or not actual_capabilities >= declared_capabilities:
|
|
2124
2131
|
errors.append(f"stage {stage_number} requires mismatch")
|
|
2125
2132
|
# 계획이 면제한 stage 에 구현이 실제 Tier 3 항목을 붙이는 것은 허용한다 —
|
|
2126
2133
|
# 면제 stage 의 diff 가 db/io/http/external 표면을 건드려 diff-surface 대조에
|
|
@@ -2183,6 +2190,24 @@ def _project_surface_patterns(project_root: Path) -> object:
|
|
|
2183
2190
|
return None
|
|
2184
2191
|
|
|
2185
2192
|
|
|
2193
|
+
def _implemented_stages(data_path: Path) -> frozenset[int]:
|
|
2194
|
+
"""이 태스크에서 구현이 끝난 stage. 원장을 못 읽으면 빈 집합이다."""
|
|
2195
|
+
from okstra_ctl.consumers import read_stage_consumer_state
|
|
2196
|
+
|
|
2197
|
+
try:
|
|
2198
|
+
state = read_stage_consumer_state(data_path.parent.parent)
|
|
2199
|
+
except (OSError, UnicodeError, ValueError):
|
|
2200
|
+
return frozenset()
|
|
2201
|
+
return frozenset(state.done_stages)
|
|
2202
|
+
|
|
2203
|
+
|
|
2204
|
+
def _is_implemented_stage(stage: object, implemented: frozenset[int]) -> bool:
|
|
2205
|
+
number = stage.get("stage") if isinstance(stage, dict) else None
|
|
2206
|
+
return isinstance(number, int) and not isinstance(number, bool) and (
|
|
2207
|
+
number in implemented
|
|
2208
|
+
)
|
|
2209
|
+
|
|
2210
|
+
|
|
2186
2211
|
def _validate_planning_conformance_declared(
|
|
2187
2212
|
report_path: Path,
|
|
2188
2213
|
failures: list[str],
|
|
@@ -2209,7 +2234,17 @@ def _validate_planning_conformance_declared(
|
|
|
2209
2234
|
ip = data.get("implementationPlanning")
|
|
2210
2235
|
if not isinstance(ip, dict):
|
|
2211
2236
|
return
|
|
2212
|
-
|
|
2237
|
+
# 구현이 끝난 stage 는 이 게이트의 대상이 아니다. 그 본문은 다음 계획 run 에
|
|
2238
|
+
# 그대로 이월되고(ADR-0015), 이월된 본문은 고칠 수 없다 — 규칙이 그 사이에
|
|
2239
|
+
# 넓어졌다면 통과 가능한 값이 없는 요구가 된다(2026-09-24, dev-10860: 이월된
|
|
2240
|
+
# stage 2·3·5 가 오늘의 표면 패턴으로 `requires` 누락 판정).
|
|
2241
|
+
implemented = _implemented_stages(data_path)
|
|
2242
|
+
stages = [
|
|
2243
|
+
stage
|
|
2244
|
+
for stage in ip.get("stages") or ()
|
|
2245
|
+
if not _is_implemented_stage(stage, implemented)
|
|
2246
|
+
]
|
|
2247
|
+
_planning_conformance_declarations(stages, failures)
|
|
2213
2248
|
if ip.get("planningContract") != "selected-direction":
|
|
2214
2249
|
from okstra_ctl.implementation_direction import (
|
|
2215
2250
|
stage_validation_executability_errors,
|
|
@@ -2217,6 +2252,8 @@ def _validate_planning_conformance_declared(
|
|
|
2217
2252
|
|
|
2218
2253
|
failures.extend(stage_validation_executability_errors(ip))
|
|
2219
2254
|
for conflict in exempt_stage_surface_conflicts(data, surface_patterns):
|
|
2255
|
+
if conflict["stage"] in implemented:
|
|
2256
|
+
continue
|
|
2220
2257
|
failures.append(
|
|
2221
2258
|
"conformance gate BLOCKING: stage "
|
|
2222
2259
|
f"{conflict['stage']} declares `Conformance exemption:` but its "
|
|
@@ -2229,6 +2266,19 @@ def _validate_planning_conformance_declared(
|
|
|
2229
2266
|
"blocks the same stage after the work is done, where the approved "
|
|
2230
2267
|
"plan can no longer be corrected."
|
|
2231
2268
|
)
|
|
2269
|
+
for gap in declared_stage_surface_gaps(data, surface_patterns):
|
|
2270
|
+
if gap["stage"] in implemented:
|
|
2271
|
+
continue
|
|
2272
|
+
failures.append(
|
|
2273
|
+
"conformance gate BLOCKING: stage "
|
|
2274
|
+
f"{gap['stage']} declares `Conformance tests:` with "
|
|
2275
|
+
f"requires={gap['requires']} but its planned paths touch surface(s) "
|
|
2276
|
+
f"{gap['surfaces']}: {', '.join(gap['paths'])} — add "
|
|
2277
|
+
f"{gap['surfaces']} to that stage's `requires`, or move those paths "
|
|
2278
|
+
"out of it. The implementation run's diff-surface check demands "
|
|
2279
|
+
"the wider set after the work is done, where the approved plan can "
|
|
2280
|
+
"no longer be corrected."
|
|
2281
|
+
)
|
|
2232
2282
|
|
|
2233
2283
|
|
|
2234
2284
|
def _validate_conformance_surfaces(
|
|
@@ -5728,7 +5778,7 @@ def _validate_verified_row_recorded(
|
|
|
5728
5778
|
report_path: Path,
|
|
5729
5779
|
failures: list[str],
|
|
5730
5780
|
) -> None:
|
|
5731
|
-
"""A release-ready
|
|
5781
|
+
"""A release-ready verification must leave a `verified` row per cleared stage.
|
|
5732
5782
|
|
|
5733
5783
|
`okstra handoff record-verified` validates its own inputs, but nothing
|
|
5734
5784
|
checked that it ever ran. Skipping it leaves the report saying `accepted`
|
|
@@ -5737,7 +5787,8 @@ def _validate_verified_row_recorded(
|
|
|
5737
5787
|
the only recoveries are re-running an expensive phase or hand-editing the
|
|
5738
5788
|
registry.
|
|
5739
5789
|
"""
|
|
5740
|
-
|
|
5790
|
+
scope = str(data.get("verificationScope") or "")
|
|
5791
|
+
if scope not in ("single-stage", "whole-task"):
|
|
5741
5792
|
return
|
|
5742
5793
|
if not release_handoff_allowed(data):
|
|
5743
5794
|
return
|
|
@@ -5752,11 +5803,17 @@ def _validate_verified_row_recorded(
|
|
|
5752
5803
|
if rows is None:
|
|
5753
5804
|
return
|
|
5754
5805
|
head = ((data.get("finalVerification") or {}).get("sourceImplementationReport") or {}).get("capturedHeadSha")
|
|
5806
|
+
# 전체 task 행의 `head_commit` 은 그 stage 자신의 완료 커밋이다. 검증된 head
|
|
5807
|
+
# 는 `verified_head_commit` 에 있으므로, 그 행을 stage 커밋으로 찾으면 모든
|
|
5808
|
+
# stage 가 누락으로 읽힌다.
|
|
5809
|
+
head_field = (
|
|
5810
|
+
"verified_head_commit" if scope == "whole-task" else "head_commit"
|
|
5811
|
+
)
|
|
5755
5812
|
verified = {
|
|
5756
5813
|
row.get("stage")
|
|
5757
5814
|
for row in rows
|
|
5758
5815
|
if isinstance(row, dict) and row.get("status") == "verified"
|
|
5759
|
-
and head and row.get(
|
|
5816
|
+
and head and row.get(head_field) == head
|
|
5760
5817
|
and row.get("final_verdict") == data.get("finalVerdict")
|
|
5761
5818
|
and _data_path_for(Path(str(row.get("report_path") or ""))).resolve() == _data_path_for(report_path).resolve()
|
|
5762
5819
|
}
|
|
@@ -5766,9 +5823,9 @@ def _validate_verified_row_recorded(
|
|
|
5766
5823
|
f"final-verification cleared stage(s) {missing} for release but "
|
|
5767
5824
|
"`runs/implementation-planning/consumers.jsonl` carries no "
|
|
5768
5825
|
"`verified` row matching this report and captured commit. Run `okstra handoff record-verified` "
|
|
5769
|
-
"before finishing — without that row the
|
|
5770
|
-
"while the registry says unverified, and the
|
|
5771
|
-
"offered for a
|
|
5826
|
+
"before finishing — once per cleared stage — without that row the "
|
|
5827
|
+
"report says accepted while the registry says unverified, and the "
|
|
5828
|
+
"stage is never offered for a pull request "
|
|
5772
5829
|
'(final-verification.md §"Verified-row recording").'
|
|
5773
5830
|
)
|
|
5774
5831
|
|
|
@@ -8065,19 +8122,19 @@ def _validate_final_verification_consistency(data: dict, failures: list[str]) ->
|
|
|
8065
8122
|
"`blocksReleaseHandoff: false`."
|
|
8066
8123
|
)
|
|
8067
8124
|
|
|
8125
|
+
if routing_token == "final-verification" and token == "accepted":
|
|
8126
|
+
failures.append(
|
|
8127
|
+
"final-verification: routingRecommendation cites `final-verification` "
|
|
8128
|
+
"but the verdict is `accepted` — an accepted verdict carries no blocker "
|
|
8129
|
+
"to re-verify. Route to release-handoff or done."
|
|
8130
|
+
)
|
|
8131
|
+
|
|
8068
8132
|
scope = data.get("verificationScope", "whole-task")
|
|
8069
8133
|
if scope not in ("whole-task", "single-stage"):
|
|
8070
8134
|
failures.append(
|
|
8071
8135
|
f"final-verification: verificationScope must be `whole-task` or "
|
|
8072
8136
|
f"`single-stage`, got {scope!r}."
|
|
8073
8137
|
)
|
|
8074
|
-
if scope == "single-stage" and routing_token == "release-handoff":
|
|
8075
|
-
failures.append(
|
|
8076
|
-
"final-verification: verificationScope `single-stage` cannot recommend "
|
|
8077
|
-
"plain release-handoff routing — a single-stage accepted verdict may "
|
|
8078
|
-
"only route to `release-handoff(stage-group)` (partial-PR mode); "
|
|
8079
|
-
"whole-task release-handoff requires whole-task verification."
|
|
8080
|
-
)
|
|
8081
8138
|
|
|
8082
8139
|
|
|
8083
8140
|
def validate_report_views(report_path: Path, failures: list[str]) -> None:
|
|
@@ -441,6 +441,15 @@ def _validate_format(path: Path) -> list[str]:
|
|
|
441
441
|
f"{why}; a stage block is Steps plus Exit criteria"
|
|
442
442
|
)
|
|
443
443
|
|
|
444
|
+
# 9b. The At a Glance work column is titled in the schedule's language.
|
|
445
|
+
glance_header = (
|
|
446
|
+
f"| # | {labels['glance_work_column']} | Category | Priority | Effort | Days | Risk |"
|
|
447
|
+
)
|
|
448
|
+
if "## At a Glance" in section_positions and glance_header not in text:
|
|
449
|
+
violations.append(
|
|
450
|
+
f"`## At a Glance` requires the header literal {glance_header!r}"
|
|
451
|
+
)
|
|
452
|
+
|
|
444
453
|
# 10. Days total format inside At a Glance: `**N tasks total / estimated effort: X.X ~ Y.Y days (Effort sum)**`
|
|
445
454
|
if "## At a Glance" in section_positions:
|
|
446
455
|
start = section_positions["## At a Glance"]
|
package/docs/for-ai/README.md
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# Okstra Skills AI Manuals
|
|
2
|
-
|
|
3
|
-
This directory is a compressed manual for an AI to quickly select and precisely run okstra public skills. The authoritative contract is `skills/*/SKILL.md`; this document is the operational guide for the AI. When the source skills, templates, validators, or CLI registry conflict, prefer the source skills and the actual validator/CLI implementation.
|
|
4
|
-
|
|
5
|
-
## Verified Sources
|
|
6
|
-
|
|
7
|
-
- Public skill list: [`src/lib/skill-catalog.mjs`](../../src/lib/skill-catalog.mjs)
|
|
8
|
-
- Skill sources: [`skills/`](../../skills/)
|
|
9
|
-
- CLI command surface: [`src/cli-registry.mjs`](../../src/cli-registry.mjs)
|
|
10
|
-
- brief template: [`templates/reports/brief.template.md`](../../templates/reports/brief.template.md)
|
|
11
|
-
- schedule template: [`templates/reports/schedule.template.md`](../../templates/reports/schedule.template.md)
|
|
12
|
-
- brief validator: [`validators/validate-brief.py`](../../validators/validate-brief.py)
|
|
13
|
-
- schedule validator: [`validators/validate-schedule.py`](../../validators/validate-schedule.py)
|
|
14
|
-
|
|
15
|
-
## Skill Routing
|
|
16
|
-
|
|
17
|
-
| User intent | Skill to use | Manual |
|
|
18
|
-
|---|---|---|
|
|
19
|
-
| Install/initialize okstra on a new project or a new machine | `okstra-setup` | [`skills/okstra-setup.md`](skills/okstra-setup.md) |
|
|
20
|
-
| Turn requirements, tickets, links, a codebase scan, or an error-zip into an okstra input brief | `okstra-brief-gen` | [`skills/okstra-brief-gen.md`](skills/okstra-brief-gen.md) |
|
|
21
|
-
| Start an okstra run or execute the next phase in the current Claude Code session | `okstra-run` | [`skills/okstra-run.md`](skills/okstra-run.md) |
|
|
22
|
-
| Manage okstra tasks across multiple projects — bundling, assignment, sync snapshots, child launch packets | `okstra-manager` | [`skills/okstra-manager.md`](skills/okstra-manager.md) |
|
|
23
|
-
| Check status, history, report, time, logs, cost, errors, error-zip, run-audit, recap | `okstra-inspect` | [`skills/okstra-inspect.md`](skills/okstra-inspect.md) |
|
|
24
|
-
| Collect and aggregate the results of multiple task runs across a task-group (or the whole project) into a synthesized summary | `okstra-rollup` | [`skills/okstra-rollup.md`](skills/okstra-rollup.md) |
|
|
25
|
-
| Project-wide recent run coverage, tokens, known cost, CPU, and wall-clock usage by task type | `okstra-usage` | [`skills/okstra-usage.md`](skills/okstra-usage.md) |
|
|
26
|
-
| Generate a client-facing work schedule for a whole task-group | `okstra-schedule-gen` | [`skills/okstra-schedule-gen.md`](skills/okstra-schedule-gen.md) |
|
|
27
|
-
| Store or search conversations/decisions/preferences/requirements in the global Memory Book | `okstra-memory` | [`skills/okstra-memory.md`](skills/okstra-memory.md) |
|
|
28
|
-
| Create or join a global room and send or read addressed messages across host sessions | `okstra-chat` | [`skills/okstra-chat.md`](skills/okstra-chat.md) |
|
|
29
|
-
| Manage the implementation-task worktree-based docker compose user-test environment | `okstra-container-build` | [`skills/okstra-container-build.md`](skills/okstra-container-build.md) |
|
|
30
|
-
| Answer the unresolved clarification questions an okstra run left behind in-session and record the approval gate | `okstra-user-response` | [`skills/okstra-user-response.md`](skills/okstra-user-response.md) |
|
|
31
|
-
| Register a PR body template or generate a PR description from a branch diff (global, git repository) | `okstra-pr-gen` | [`skills/okstra-pr-gen.md`](skills/okstra-pr-gen.md) |
|
|
32
|
-
| Review the changed code of one okstra `implementation` stage or of any branch against the coding-preflight rules, and write the result to a file | `okstra-code-review` | [`skills/okstra-code-review.md`](skills/okstra-code-review.md) |
|
|
33
|
-
|
|
34
|
-
## Shared Execution Rules
|
|
35
|
-
|
|
36
|
-
1. Run commands as separate Bash calls whenever the source skill requires it. In particular, do not wrap `okstra preflight --runtime claude-code`, `okstra wizard ...`, or `okstra container ...` calls in `&&`, `||`, `$(...)`, a leading variable assignment, `eval`, or `export`.
|
|
37
|
-
2. An `okstra <subcmd>` call bootstraps its own Python path. Unless a skill states otherwise, do not build `okstra paths --shell` or `export PYTHONPATH=...`.
|
|
38
|
-
3. Most skills except `okstra-setup` do not use an `npx` fallback. If the runtime is missing, tell the user to run `/okstra-setup` and stop. But if it fails with `unknown command: <cmd>`, the `okstra` binary on PATH is older than the skill — point the user to `npm i -g okstra@latest` rather than `/okstra-setup`, and stop.
|
|
39
|
-
4. Project artifacts go under `<PROJECT_ROOT>/.okstra/` by default. The exceptions are `okstra-memory` (`~/.okstra/memory-book/`) and `okstra-chat` (`~/.okstra/chat/`).
|
|
40
|
-
5. `runtime/` is build output. When fixing a source skill or template, edit the source under `skills/`, `templates/`, `validators/`, `scripts/`, `src/` and apply it via a build.
|
|
41
|
-
6. Do not guess the contents of a tracker, URL, file, report, log, zip, template, or validator. Use only what you have confirmed by reading or running with a tool.
|
|
42
|
-
7. Read-side skills also produce some artifacts. `okstra-inspect errors` produces an error report Markdown and `okstra-inspect error-zip` produces an anonymized zip. Even in these cases, keep the purpose-specific fixed CLI fields as the source of truth.
|
|
43
|
-
|
|
44
|
-
## The Order the AI Reads In
|
|
45
|
-
|
|
46
|
-
1. Pick a skill in this file.
|
|
47
|
-
2. Read only the matching `docs/for-ai/skills/<skill>.md`.
|
|
48
|
-
3. If the skill requires actual execution, confirm the relevant step in the source [`skills/<skill>/SKILL.md`](../../skills/).
|
|
49
|
-
4. When writing a brief or schedule, also confirm the template and the validator.
|
|
50
|
-
|
|
51
|
-
## Public Skill List
|
|
52
|
-
|
|
53
|
-
The public skills listed in this AI manual are the following 14:
|
|
54
|
-
|
|
55
|
-
- `okstra-setup`
|
|
56
|
-
- `okstra-brief-gen`
|
|
57
|
-
- `okstra-run`
|
|
58
|
-
- `okstra-manager`
|
|
59
|
-
- `okstra-memory`
|
|
60
|
-
- `okstra-chat`
|
|
61
|
-
- `okstra-inspect`
|
|
62
|
-
- `okstra-rollup`
|
|
63
|
-
- `okstra-usage`
|
|
64
|
-
- `okstra-schedule-gen`
|
|
65
|
-
- `okstra-container-build`
|
|
66
|
-
- `okstra-user-response`
|
|
67
|
-
- `okstra-pr-gen`
|
|
68
|
-
- `okstra-code-review`
|