okstra 0.57.0 → 0.58.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okstra",
3
- "version": "0.57.0",
3
+ "version": "0.58.0",
4
4
  "description": "Multi-agent cross-verification orchestrator runtime + Claude Code skills.",
5
5
  "license": "MIT",
6
6
  "author": "devonshin",
@@ -1,5 +1,5 @@
1
1
  {
2
- "package": "0.57.0",
3
- "builtAt": "2026-06-08T17:08:29.657Z",
2
+ "package": "0.58.0",
3
+ "builtAt": "2026-06-08T17:51:22.479Z",
4
4
  "repoRoot": "/home/runner/work/okstra/okstra"
5
5
  }
@@ -236,14 +236,20 @@
236
236
  "label": "추가 critic 패스를 돌릴까요? (놓친 finding/blocker 를 캐는 검증 패스 — opt-in)",
237
237
  "echo_template": "critic: {value}",
238
238
  "options": {
239
- "off": "사용 안 함 (기본·추천)",
240
- "claude": "claude critic (추천)",
241
- "__free_input__": "직접 입력 (codex / gemini)"
239
+ "off": "사용 안 함 (기본·추천)"
240
+ },
241
+ "labels": {
242
+ "provider_recommended": "{provider} critic (추천)",
243
+ "provider": "{provider} critic"
242
244
  }
243
245
  },
244
246
  "critic_text": {
245
- "label": "critic provider 를 직접 입력하세요 (codex / gemini)",
246
- "echo_template": "critic: {value}"
247
+ "label": "critic provider 를 선택하세요",
248
+ "echo_template": "critic: {value}",
249
+ "labels": {
250
+ "provider_recommended": "{provider} critic (추천)",
251
+ "provider": "{provider} critic"
252
+ }
247
253
  },
248
254
  "defaults_or_custom": {
249
255
  "label": "역할별로 어떤 모델을 쓸지 정하는 단계입니다 (참여 워커 구성을 바꾸는 게 아닙니다).\n· 기본값으로 진행 — lead·실행자/워커·report-writer 를 모두 추천 모델로 두고 바로 진행합니다.\n· 커스터마이즈 — 역할별 모델을 직접 고르고, 추가 directive·관련 task 도 지정합니다.",
@@ -1572,17 +1572,29 @@ def _submit_pr_template_pick(state: WizardState, value: str) -> Optional[str]:
1572
1572
  return _submit_optional_cached_pick(state, value, _PR_TEMPLATE_PICK_SPEC)
1573
1573
 
1574
1574
 
1575
- CRITIC_CHOICES = ["off", "claude", "codex", "gemini"]
1575
+ def _critic_provider_choices() -> list[str]:
1576
+ return list(EXECUTORS)
1577
+
1578
+
1579
+ def _critic_choices() -> list[str]:
1580
+ return ["off", *_critic_provider_choices()]
1581
+
1582
+
1583
+ def _critic_provider_label(provider: str, t: dict) -> str:
1584
+ labels = t.get("labels", {})
1585
+ if provider == "claude":
1586
+ template = labels.get("provider_recommended", "{provider} critic (recommended)")
1587
+ else:
1588
+ template = labels.get("provider", "{provider} critic")
1589
+ return template.format(provider=provider)
1576
1590
 
1577
1591
 
1578
1592
  def _build_critic_pick(state: WizardState) -> Prompt:
1579
1593
  t = _p(state.workspace_root, "critic_pick")
1580
- options: list[Option] = []
1581
- for k, v in t["options"].items():
1582
- if not k.startswith("_"):
1583
- options.append(_opt(k, v))
1584
- custom_label = t["options"].get(PICK_TYPE_CUSTOM, PICK_TYPE_CUSTOM)
1585
- options.append(_opt(PICK_TYPE_CUSTOM, custom_label))
1594
+ off_label = t["options"].get("off", "off")
1595
+ options = [_opt("off", off_label)]
1596
+ for provider in _critic_provider_choices():
1597
+ options.append(_opt(provider, _critic_provider_label(provider, t)))
1586
1598
  return Prompt(
1587
1599
  step=S_CRITIC_PICK, kind="pick",
1588
1600
  label=t["label"],
@@ -1592,12 +1604,10 @@ def _build_critic_pick(state: WizardState) -> Prompt:
1592
1604
 
1593
1605
 
1594
1606
  def _submit_critic_pick(state: WizardState, value: str) -> Optional[str]:
1595
- if value == PICK_TYPE_CUSTOM:
1596
- state.critic_pending_text = True
1597
- return None
1598
1607
  choice = (value or "").strip().lower()
1599
- if choice not in CRITIC_CHOICES:
1600
- raise WizardError(f"critic must be one of {CRITIC_CHOICES}, got: {value!r}")
1608
+ choices = _critic_choices()
1609
+ if choice not in choices:
1610
+ raise WizardError(f"critic must be one of {choices}, got: {value!r}")
1601
1611
  state.critic = choice
1602
1612
  state.critic_pending_text = False
1603
1613
  return f"critic: {choice}"
@@ -1605,17 +1615,23 @@ def _submit_critic_pick(state: WizardState, value: str) -> Optional[str]:
1605
1615
 
1606
1616
  def _build_critic_text(state: WizardState) -> Prompt:
1607
1617
  t = _p(state.workspace_root, "critic_text")
1618
+ options = [
1619
+ _opt(provider, _critic_provider_label(provider, t))
1620
+ for provider in _critic_provider_choices()
1621
+ ]
1608
1622
  return Prompt(
1609
- step=S_CRITIC_TEXT, kind="text",
1623
+ step=S_CRITIC_TEXT, kind="pick",
1610
1624
  label=t["label"],
1625
+ options=options,
1611
1626
  echo_template=t["echo_template"],
1612
1627
  )
1613
1628
 
1614
1629
 
1615
1630
  def _submit_critic_text(state: WizardState, value: str) -> Optional[str]:
1616
1631
  choice = (value or "").strip().lower()
1617
- if choice not in CRITIC_CHOICES:
1618
- raise WizardError(f"critic must be one of {CRITIC_CHOICES}, got: {value!r}")
1632
+ providers = _critic_provider_choices()
1633
+ if choice not in providers:
1634
+ raise WizardError(f"critic must be one of {providers}, got: {value!r}")
1619
1635
  state.critic = choice
1620
1636
  state.critic_pending_text = False
1621
1637
  return f"critic: {choice}"