okstra 0.86.0 → 0.87.1

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.
Files changed (103) hide show
  1. package/docs/kr/architecture.md +27 -27
  2. package/docs/kr/cli.md +21 -21
  3. package/docs/kr/performance-improvement-plan-v2.md +4 -4
  4. package/docs/kr/performance-improvement-plan.md +3 -3
  5. package/docs/project-structure-overview.md +6 -6
  6. package/docs/superpowers/plans/2026-06-17-okstra-error-report.md +724 -0
  7. package/docs/superpowers/specs/2026-06-17-okstra-error-report-design.md +123 -0
  8. package/docs/task-process/error-analysis.md +1 -1
  9. package/docs/task-process/final-verification.md +4 -4
  10. package/docs/task-process/implementation-planning.md +2 -2
  11. package/docs/task-process/implementation.md +3 -3
  12. package/docs/task-process/requirements-discovery.md +2 -2
  13. package/package.json +1 -1
  14. package/runtime/BUILD.json +2 -2
  15. package/runtime/agents/workers/{gemini-worker.md → antigravity-worker.md} +56 -56
  16. package/runtime/agents/workers/claude-worker.md +2 -2
  17. package/runtime/agents/workers/codex-worker.md +1 -1
  18. package/runtime/agents/workers/report-writer-worker.md +2 -2
  19. package/runtime/bin/lib/okstra/cli.sh +3 -3
  20. package/runtime/bin/lib/okstra/globals.sh +8 -8
  21. package/runtime/bin/lib/okstra/interactive.sh +1 -1
  22. package/runtime/bin/lib/okstra/usage.sh +7 -7
  23. package/runtime/bin/lib/okstra-ctl/cmd-reconcile.sh +5 -3
  24. package/runtime/bin/lib/okstra-ctl/prepare.sh +4 -2
  25. package/runtime/bin/{okstra-gemini-exec.sh → okstra-antigravity-exec.sh} +67 -60
  26. package/runtime/bin/okstra-error-log.py +2 -1
  27. package/runtime/bin/okstra-token-usage.py +3 -4
  28. package/runtime/bin/okstra-trace-cleanup.sh +4 -4
  29. package/runtime/bin/okstra-wrapper-status.py +3 -3
  30. package/runtime/bin/okstra.sh +1 -1
  31. package/runtime/prompts/launch.template.md +3 -3
  32. package/runtime/prompts/lead/context-loader.md +1 -1
  33. package/runtime/prompts/lead/convergence.md +8 -8
  34. package/runtime/prompts/lead/okstra-lead-contract.md +15 -15
  35. package/runtime/prompts/lead/report-writer.md +6 -6
  36. package/runtime/prompts/lead/team-contract.md +31 -31
  37. package/runtime/prompts/profiles/_coding-conventions-preflight.md +2 -2
  38. package/runtime/prompts/profiles/_common-contract.md +7 -7
  39. package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
  40. package/runtime/prompts/profiles/_implementation-executor.md +6 -6
  41. package/runtime/prompts/profiles/_implementation-verifier.md +4 -4
  42. package/runtime/prompts/profiles/_stage-discipline.md +1 -1
  43. package/runtime/prompts/profiles/error-analysis.md +1 -1
  44. package/runtime/prompts/profiles/final-verification.md +1 -1
  45. package/runtime/prompts/profiles/forbidden-actions.json +2 -2
  46. package/runtime/prompts/profiles/implementation-planning.md +1 -1
  47. package/runtime/prompts/profiles/implementation.md +3 -3
  48. package/runtime/prompts/profiles/improvement-discovery.md +3 -3
  49. package/runtime/prompts/profiles/requirements-discovery.md +1 -1
  50. package/runtime/prompts/wizard/prompts.ko.json +9 -5
  51. package/runtime/python/okstra_ctl/__init__.py +2 -0
  52. package/runtime/python/okstra_ctl/analysis_packet.py +1 -1
  53. package/runtime/python/okstra_ctl/clarification_items.py +17 -7
  54. package/runtime/python/okstra_ctl/codex_dispatch.py +2 -2
  55. package/runtime/python/okstra_ctl/context_cost.py +10 -44
  56. package/runtime/python/okstra_ctl/doctor.py +1 -1
  57. package/runtime/python/okstra_ctl/error_report.py +185 -0
  58. package/runtime/python/okstra_ctl/improvement_lenses.py +1 -1
  59. package/runtime/python/okstra_ctl/models.py +10 -10
  60. package/runtime/python/okstra_ctl/paths.py +9 -9
  61. package/runtime/python/okstra_ctl/reconcile.py +74 -11
  62. package/runtime/python/okstra_ctl/render.py +21 -21
  63. package/runtime/python/okstra_ctl/report_views.py +7 -13
  64. package/runtime/python/okstra_ctl/run.py +16 -16
  65. package/runtime/python/okstra_ctl/run_context.py +1 -1
  66. package/runtime/python/okstra_ctl/seeding.py +1 -1
  67. package/runtime/python/okstra_ctl/task_target.py +44 -0
  68. package/runtime/python/okstra_ctl/team.py +1 -1
  69. package/runtime/python/okstra_ctl/wizard.py +55 -30
  70. package/runtime/python/okstra_ctl/workers.py +3 -3
  71. package/runtime/python/okstra_ctl/workflow.py +1 -1
  72. package/runtime/python/okstra_ctl/worktree.py +1 -1
  73. package/runtime/python/okstra_token_usage/__init__.py +2 -3
  74. package/runtime/python/okstra_token_usage/antigravity.py +26 -0
  75. package/runtime/python/okstra_token_usage/blocks.py +4 -0
  76. package/runtime/python/okstra_token_usage/collect.py +20 -15
  77. package/runtime/python/okstra_token_usage/paths.py +0 -1
  78. package/runtime/python/okstra_token_usage/pricing.py +6 -3
  79. package/runtime/schemas/final-report-v1.0.schema.json +1 -1
  80. package/runtime/skills/okstra-brief/SKILL.md +1 -1
  81. package/runtime/skills/okstra-inspect/SKILL.md +85 -21
  82. package/runtime/skills/okstra-run/SKILL.md +3 -3
  83. package/runtime/skills/okstra-setup/SKILL.md +2 -2
  84. package/runtime/templates/prd/brief.template.md +2 -2
  85. package/runtime/templates/reports/i18n/en.json +1 -1
  86. package/runtime/templates/reports/i18n/ko.json +1 -1
  87. package/runtime/templates/reports/report.js +5 -11
  88. package/runtime/templates/reports/settings.template.json +2 -2
  89. package/runtime/templates/reports/task-brief.template.md +2 -2
  90. package/runtime/templates/worker-prompt-preamble.md +7 -7
  91. package/runtime/validators/forbidden_actions.py +1 -1
  92. package/runtime/validators/lib/fixtures.sh +3 -3
  93. package/runtime/validators/lib/validate-assets.sh +1 -1
  94. package/runtime/validators/validate-run.py +8 -8
  95. package/src/cli-registry.mjs +7 -0
  96. package/src/codex-dispatch.mjs +3 -3
  97. package/src/codex-run.mjs +2 -2
  98. package/src/doctor.mjs +1 -1
  99. package/src/error-report.mjs +27 -0
  100. package/src/install.mjs +1 -1
  101. package/src/render-bundle.mjs +1 -1
  102. package/src/uninstall.mjs +2 -2
  103. package/runtime/python/okstra_token_usage/gemini.py +0 -82
@@ -5,14 +5,14 @@ const USAGE = `okstra codex-dispatch — dispatch CLI-backed workers for a prepa
5
5
 
6
6
  Usage:
7
7
  okstra codex-dispatch --project-root <dir> --run-manifest <path> \\
8
- [--workers codex[,gemini[,report-writer]]] [--dry-run] \\
8
+ [--workers codex[,antigravity[,report-writer]]] [--dry-run] \\
9
9
  [--idle-timeout-seconds <n>] \\
10
10
  [--enable-codex-report-writer --report-writer-codex-model <model>]
11
11
 
12
12
  This command reads an existing run manifest produced by 'okstra codex-run' and
13
13
  dispatches only Codex-side supported workers. When --workers is omitted, the
14
- command selects the supported subset of the run roster (codex/gemini, plus
15
- report-writer only when explicitly opted in). Codex and gemini use their
14
+ command selects the supported subset of the run roster (codex/antigravity, plus
15
+ report-writer only when explicitly opted in). Codex and antigravity use their
16
16
  existing wrappers. The report-writer role is available only through explicit
17
17
  Codex opt-in because the prepared manifest still records the Claude-side report
18
18
  writer model by default. Explicitly requesting unsupported workers such as
package/src/codex-run.mjs CHANGED
@@ -13,7 +13,7 @@ Usage:
13
13
  --task-group <tg> --task-id <tid> --task-type <type> \\
14
14
  --task-brief <path-or-rel> [--workers <list>] [--directive <text>] \\
15
15
  [--lead-model <m>] [--claude-model <m>] [--codex-model <m>] \\
16
- [--gemini-model <m>] [--report-writer-model <m>] \\
16
+ [--antigravity-model <m>] [--report-writer-model <m>] \\
17
17
  [--related-tasks <list>] [--base-ref <ref>] \\
18
18
  [--clarification-response <path>] [--work-category <cat>] \\
19
19
  [--stage <auto|N>] [--stages <csv>] [--pr-template-path <path>] \\
@@ -21,7 +21,7 @@ Usage:
21
21
 
22
22
  --render-only and --lead-runtime are owned by this command.
23
23
  Worker dispatch is intentionally disabled here; use 'okstra codex-dispatch'
24
- with the rendered run manifest for CLI-backed codex/gemini workers.
24
+ with the rendered run manifest for CLI-backed codex/antigravity workers.
25
25
  `;
26
26
 
27
27
  const OWNED_FLAGS = new Set(["--workspace-root", "--render-only", "--lead-runtime"]);
package/src/doctor.mjs CHANGED
@@ -211,7 +211,7 @@ export async function run(args) {
211
211
  ),
212
212
  await check("bin: okstra.sh", () => checkBashEntry(paths.bin, "okstra.sh")),
213
213
  await check("bin: okstra-codex-exec.sh", () => checkBashEntry(paths.bin, "okstra-codex-exec.sh")),
214
- await check("bin: okstra-gemini-exec.sh", () => checkBashEntry(paths.bin, "okstra-gemini-exec.sh")),
214
+ await check("bin: okstra-antigravity-exec.sh", () => checkBashEntry(paths.bin, "okstra-antigravity-exec.sh")),
215
215
  await check("bin: okstra-central.sh", () => checkBashEntry(paths.bin, "okstra-central.sh")),
216
216
  ...(await Promise.all(
217
217
  requiredSkillNamesForRuntime(resolvedRuntime).map((name) =>
@@ -0,0 +1,27 @@
1
+ import { runPythonModule } from "./_python-helper.mjs";
2
+
3
+ const USAGE = `okstra error-report — aggregate okstra-run error logs into a task report
4
+
5
+ Usage:
6
+ okstra error-report <task-root>
7
+ okstra error-report <task-key> --project-root <dir>
8
+ okstra error-report <task-key> --cwd <dir>
9
+
10
+ Writes a timestamped markdown report under <task-root>/error-reports/ and
11
+ prints a JSON summary (counts by errorType / source / phase / agent) to stdout.
12
+ This is read-only against task state; it never mutates task artifacts.
13
+ `;
14
+
15
+ export async function run(args) {
16
+ if (args.includes("--help") || args.includes("-h")) {
17
+ process.stdout.write(USAGE);
18
+ return 0;
19
+ }
20
+
21
+ const result = await runPythonModule({
22
+ module: "okstra_ctl.error_report",
23
+ args,
24
+ stdio: "inherit-stdout",
25
+ });
26
+ return result.code ?? 0;
27
+ }
package/src/install.mjs CHANGED
@@ -30,7 +30,7 @@ const BIN_ENTRYPOINTS = [
30
30
  "okstra.sh",
31
31
  "okstra-codex-exec.sh",
32
32
  "okstra-claude-exec.sh",
33
- "okstra-gemini-exec.sh",
33
+ "okstra-antigravity-exec.sh",
34
34
  "okstra-trace-cleanup.sh",
35
35
  "okstra-team-reconcile.sh",
36
36
  "okstra-central.sh",
@@ -16,7 +16,7 @@ Usage:
16
16
  --task-brief <path-or-rel> [--executor <name>] \\
17
17
  [--approved-plan <path>] [--workers <list>] [--directive <text>] \\
18
18
  [--lead-model <m>] [--claude-model <m>] [--codex-model <m>] \\
19
- [--gemini-model <m>] [--report-writer-model <m>] \\
19
+ [--antigravity-model <m>] [--report-writer-model <m>] \\
20
20
  [--lead-runtime claude-code|codex] \\
21
21
  [--related-tasks <list>] [--base-ref <ref>] \\
22
22
  [--clarification-response <path>] [--work-category <cat>] \\
package/src/uninstall.mjs CHANGED
@@ -11,7 +11,7 @@ const BIN_ENTRYPOINTS = [
11
11
  "okstra.sh",
12
12
  "okstra-codex-exec.sh",
13
13
  "okstra-claude-exec.sh",
14
- "okstra-gemini-exec.sh",
14
+ "okstra-antigravity-exec.sh",
15
15
  "okstra-trace-cleanup.sh",
16
16
  "okstra-team-reconcile.sh",
17
17
  "okstra-central.sh",
@@ -47,7 +47,7 @@ const FALLBACK_SKILL_NAMES = [
47
47
  const FALLBACK_AGENT_NAMES = [
48
48
  "claude-worker.md",
49
49
  "codex-worker.md",
50
- "gemini-worker.md",
50
+ "antigravity-worker.md",
51
51
  "report-writer-worker.md",
52
52
  ];
53
53
 
@@ -1,82 +0,0 @@
1
- """Gemini CLI session collectors."""
2
- from __future__ import annotations
3
-
4
- import json
5
- from pathlib import Path
6
- from .paths import GEMINI_TMP, ts_in_window
7
-
8
-
9
- def gemini_session_total(json_path: Path) -> dict:
10
- try:
11
- data = json.loads(json_path.read_text())
12
- except (OSError, json.JSONDecodeError):
13
- return {"totalTokens": 0, "available": False}
14
- msgs = data.get("messages") or []
15
- total = 0
16
- inp = out = cached = thoughts = tool = 0
17
- model = None
18
- for m in msgs:
19
- tok = m.get("tokens") or {}
20
- total += tok.get("total", 0) or 0
21
- inp += tok.get("input", 0) or 0
22
- out += tok.get("output", 0) or 0
23
- cached += tok.get("cached", 0) or 0
24
- thoughts += tok.get("thoughts", 0) or 0
25
- tool += tok.get("tool", 0) or 0
26
- if model is None and m.get("model"):
27
- model = m["model"]
28
- return {
29
- "totalTokens": total,
30
- "inputTokens": inp,
31
- "outputTokens": out,
32
- "cachedTokens": cached,
33
- "thoughtsTokens": thoughts,
34
- "toolTokens": tool,
35
- "model": model,
36
- "startedAt": data.get("startTime"),
37
- "endedAt": data.get("lastUpdated"),
38
- "available": True,
39
- }
40
-
41
-
42
- def find_gemini_session(project_root: Path, started_at: str, ended_at: str) -> Path | None:
43
- """Find the latest gemini chat session in the requested window."""
44
- sessions = find_gemini_sessions(project_root, started_at, ended_at)
45
- return sessions[-1] if sessions else None
46
-
47
-
48
- def find_gemini_sessions(project_root: Path, started_at: str, ended_at: str) -> list[Path]:
49
- """Find gemini chat sessions whose first user message references the project."""
50
- if not GEMINI_TMP.is_dir() or not started_at or not ended_at:
51
- return []
52
- project_str = str(project_root)
53
- candidates: list[tuple[str, Path]] = []
54
- for p in GEMINI_TMP.glob("*/chats/session-*.json"):
55
- try:
56
- data = json.loads(p.read_text())
57
- except (OSError, json.JSONDecodeError):
58
- continue
59
- start = data.get("startTime") or ""
60
- if not ts_in_window(start, started_at, ended_at):
61
- continue
62
- # Match by content: first user message should mention project root or task path.
63
- msgs = data.get("messages") or []
64
- for m in msgs:
65
- if m.get("type") != "user":
66
- continue
67
- content = m.get("content") or []
68
- text = ""
69
- if isinstance(content, list):
70
- for block in content:
71
- if isinstance(block, dict) and block.get("text"):
72
- text = block["text"]
73
- break
74
- elif isinstance(content, str):
75
- text = content
76
- if project_str in text:
77
- candidates.append((start, p))
78
- break
79
- if not candidates:
80
- return []
81
- candidates.sort()
82
- return [path for _start, path in candidates]