@percepta/kaizen 0.5.1 → 0.7.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.
Files changed (140) hide show
  1. package/README.md +54 -126
  2. package/agent/claude-command.md +23 -0
  3. package/agent/evals.md +41 -0
  4. package/agent/overview.md +53 -0
  5. package/agent/variant-builder.md +22 -0
  6. package/agent/views.md +51 -0
  7. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/BUILD_ID +1 -1
  8. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/build-manifest.json +22 -22
  9. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/prerender-manifest.json +3 -3
  10. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/routes-manifest.json +42 -10
  11. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/chunks/27.js +1 -0
  12. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/chunks/516.js +8 -0
  13. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/chunks/913.js +1 -0
  14. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/middleware-build-manifest.js +1 -1
  15. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/404.html +1 -1
  16. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/500.html +1 -1
  17. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/benchmarks.html +1 -1
  18. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/benchmarks.js.nft.json +1 -1
  19. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/data/[[...path]].html +1 -0
  20. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/data/[[...path]].js.nft.json +1 -0
  21. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/eval.html +1 -1
  22. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/eval.js.nft.json +1 -1
  23. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/experiments/[[...path]].html +1 -0
  24. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/experiments/[[...path]].js.nft.json +1 -0
  25. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/ideas.html +1 -1
  26. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/ideas.js.nft.json +1 -1
  27. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-action.js +1 -0
  28. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-action.js.nft.json +1 -0
  29. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-dataset-item.js +1 -1
  30. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-dataset-item.js.nft.json +1 -1
  31. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-dataset-mutation.js +1 -0
  32. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-dataset-mutation.js.nft.json +1 -0
  33. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-dataset.js +1 -1
  34. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-dataset.js.nft.json +1 -1
  35. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-datasets.js +1 -1
  36. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-datasets.js.nft.json +1 -1
  37. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-trace.js +1 -1
  38. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-trace.js.nft.json +1 -1
  39. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-traces.js +1 -0
  40. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/langfuse-traces.js.nft.json +1 -0
  41. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/linear-ideas.js +2 -2
  42. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/linear-ideas.js.nft.json +1 -1
  43. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/run-events.js +1 -1
  44. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/run-events.js.nft.json +1 -1
  45. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/run-failures.js +1 -1
  46. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/run-failures.js.nft.json +1 -1
  47. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/run-traces.js +1 -0
  48. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/run-traces.js.nft.json +1 -0
  49. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/runs.js +2 -2
  50. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/runs.js.nft.json +1 -1
  51. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/systems.js +2 -2
  52. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/systems.js.nft.json +1 -1
  53. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/trace-renderer.js +1 -0
  54. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/api/trace-renderer.js.nft.json +1 -0
  55. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/index.html +1 -1
  56. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/index.js.nft.json +1 -1
  57. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages-manifest.json +7 -2
  58. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/SCF0o7YxElB9rzWaOohsA/_buildManifest.js +1 -0
  59. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/253-85c76c34f33c9604.js +8 -0
  60. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/pages/[system]/{benchmarks-ea3ad9fe4e28dd88.js → benchmarks-30a17b7659010b8c.js} +1 -1
  61. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/pages/[system]/data/[[...path]]-e5f4083fe9ffe429.js +1 -0
  62. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/pages/[system]/eval-160237a604b47416.js +1 -0
  63. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/pages/[system]/experiments/[[...path]]-91e47a4893093600.js +1 -0
  64. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/pages/[system]/ideas-96e58e4624952e26.js +1 -0
  65. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/pages/index-d3306bb6f5d7d235.js +1 -0
  66. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/css/cd3873236eb77caa.css +1 -0
  67. package/dashboard/.next/standalone/packages/kaizen/package.json +6 -3
  68. package/dashboard/.next/standalone/packages/kaizen/shared/workspace-paths.js +84 -0
  69. package/dist/commands/create-view.js +58 -0
  70. package/dist/commands/create-view.js.map +1 -0
  71. package/dist/commands/guide.js +66 -0
  72. package/dist/commands/guide.js.map +1 -0
  73. package/dist/commands/ideas.js +4 -8
  74. package/dist/commands/ideas.js.map +1 -1
  75. package/dist/commands/init-system.js +22 -20
  76. package/dist/commands/init-system.js.map +1 -1
  77. package/dist/commands/init.js +28 -64
  78. package/dist/commands/init.js.map +1 -1
  79. package/dist/commands/log.js +5 -11
  80. package/dist/commands/log.js.map +1 -1
  81. package/dist/commands/rebuild.js +7 -9
  82. package/dist/commands/rebuild.js.map +1 -1
  83. package/dist/commands/run.js +5 -9
  84. package/dist/commands/run.js.map +1 -1
  85. package/dist/commands/studio.js +3 -3
  86. package/dist/commands/studio.js.map +1 -1
  87. package/dist/index.js +17 -21
  88. package/dist/index.js.map +1 -1
  89. package/dist/lib/cli.js +20 -0
  90. package/dist/lib/cli.js.map +1 -0
  91. package/dist/lib/events.js.map +1 -1
  92. package/dist/lib/fs-utils.js +3 -27
  93. package/dist/lib/fs-utils.js.map +1 -1
  94. package/dist/lib/leaderboard.js +1 -1
  95. package/dist/lib/leaderboard.js.map +1 -1
  96. package/dist/lib/paths.js +3 -3
  97. package/dist/lib/paths.js.map +1 -1
  98. package/dist/lib/promotion.js.map +1 -1
  99. package/dist/lib/run-dir.js +1 -1
  100. package/dist/lib/run-dir.js.map +1 -1
  101. package/dist/lib/runner.js +6 -5
  102. package/dist/lib/runner.js.map +1 -1
  103. package/dist/lib/system.js +4 -2
  104. package/dist/lib/system.js.map +1 -1
  105. package/dist/package.js +6 -3
  106. package/dist/shared/view-types.d.ts +67 -0
  107. package/dist/shared/view-types.d.ts.map +1 -0
  108. package/dist/shared/workspace-paths.js +84 -0
  109. package/dist/shared/workspace-paths.js.map +1 -0
  110. package/dist/types.d.ts +3 -10
  111. package/dist/types.d.ts.map +1 -1
  112. package/package.json +6 -3
  113. package/shared/view-types.d.ts +69 -0
  114. package/shared/view-types.js +1 -0
  115. package/shared/workspace-paths.d.ts +19 -0
  116. package/shared/workspace-paths.js +84 -0
  117. package/templates/system/eval.py +13 -6
  118. package/templates/system/eval.ts +11 -5
  119. package/templates/system/rubric.md +1 -1
  120. package/templates/system/system.md +6 -5
  121. package/templates/view/dataset-item.tsx +63 -0
  122. package/templates/view/trace.tsx +10 -0
  123. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/chunks/424.js +0 -3
  124. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/data.html +0 -1
  125. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/data.js.nft.json +0 -1
  126. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/experiments.html +0 -1
  127. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/server/pages/[system]/experiments.js.nft.json +0 -1
  128. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/374-421036d63d323cc9.js +0 -3
  129. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/pages/[system]/data-57686b9546f2794a.js +0 -1
  130. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/pages/[system]/eval-d9b5f1b8db0f0f90.js +0 -1
  131. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/pages/[system]/experiments-4d2122d6ada9a04a.js +0 -1
  132. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/pages/[system]/ideas-6c1ff7f9e0da750b.js +0 -1
  133. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/chunks/pages/index-1556edd8356dd19f.js +0 -1
  134. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/css/e75cf1946c214544.css +0 -1
  135. package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/q7hDbHI4NR8DdLDV3kWYh/_buildManifest.js +0 -1
  136. package/dist/lib/env.js +0 -2
  137. package/dist/shared/env.js +0 -4
  138. package/templates/workspace/.claude/agents/variant-builder.md +0 -51
  139. package/templates/workspace/.claude/commands/kaizen.md +0 -65
  140. /package/dashboard/.next/standalone/packages/kaizen/dashboard/.next/static/{q7hDbHI4NR8DdLDV3kWYh → SCF0o7YxElB9rzWaOohsA}/_ssgManifest.js +0 -0
@@ -0,0 +1 @@
1
+ .Studio_page__X6enu{min-height:100%;background:#0a0a0a;color:#fafafa;font-family:Geist,ui-sans-serif,system-ui,-apple-system,sans-serif}.Studio_topBar__OlLt6{display:grid;grid-template-columns:max-content max-content max-content minmax(0,1fr);align-items:center;gap:.9rem;padding:1rem 1.5rem}.Studio_logoLink__Hv20q{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;text-decoration:none}.Studio_topLogo__YEKp4{display:block;width:22px;height:22px;object-fit:contain}.Studio_systemSlot__5m3MM{min-width:0}.Studio_surfaceNav__RKZjS{display:flex;align-items:center;gap:.25rem;min-width:0}.Studio_surfaceLink__ivMXp{display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 .8rem;border-radius:0;color:var(--text-tertiary);text-decoration:none;font-size:.85rem;font-weight:500;white-space:nowrap;transition:background .15s,color .15s}.Studio_surfaceLink__ivMXp:hover{color:var(--text-secondary);background:rgba(255,255,255,.05)}.Studio_surfaceLinkActive__Der5b{color:#fafafa;background:rgba(255,255,255,.08)}.Studio_surfaceLinkDisabled__gfVYR{opacity:.45;pointer-events:none}.Studio_statusPill__m2ERk{display:inline-flex;align-items:center;min-height:22px;border-radius:0;padding:0 .45rem;color:var(--text-secondary);background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.08);font-size:.68rem;font-weight:600;white-space:nowrap}.Studio_content__LELHT{padding:0 1.5rem 2rem}.Studio_surface__lxZ_I{min-width:0}.Studio_surfaceBanner__UNvfB{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;width:100%;box-sizing:border-box;margin-bottom:1rem;border:1px solid rgba(255,255,255,.08);border-radius:0;background:rgba(255,255,255,.035);padding:.8rem .9rem}.Studio_surfaceBannerText__6jNss{min-width:0}.Studio_surfaceBannerTitle__vXJox{display:flex;align-items:center;gap:.45rem;color:#fafafa;font-size:.9rem;font-weight:650}.Studio_surfaceBannerCopy__Abpvv{margin-top:.2rem;color:var(--text-secondary);font-size:.78rem;line-height:1.45}.Studio_surfaceBannerCopy__Abpvv code{color:#fafafa;background:rgba(0,0,0,.24);border-radius:0;padding:.05rem .25rem}.Studio_sourceChip___xMTP{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border:1px solid rgba(255,255,255,.1);border-radius:0;background:rgba(255,255,255,.04);color:#fafafa;line-height:1;padding:0;vertical-align:middle}.Studio_sourceChip_code__DPzDj{color:#fafafa}.Studio_sourceChip_langfuse__h6LSy,.Studio_sourceChip_linear__9NNQ5{background:rgba(255,255,255,.06)}.Studio_sourceChip_local__3Ws2K{color:#fafafa}.Studio_sourceLogo__iWmOz{object-fit:contain}.Studio_sourceLogo__iWmOz,.Studio_sourceSvgIcon__dpcyH{display:block;width:15px;height:15px}.Studio_provenanceLine__a5uDd{display:flex;align-items:center;flex-wrap:wrap;gap:.4rem;margin-top:.45rem;color:var(--text-tertiary);font-size:.74rem}.Studio_provenanceLine__a5uDd code{color:#fafafa;background:rgba(0,0,0,.24);border-radius:0;padding:.08rem .28rem}.Studio_inlineSourceValue__WMOb9{display:inline-flex;align-items:center;gap:.35rem;vertical-align:middle;white-space:nowrap}.Studio_syncStatus__exlkz{display:flex;align-items:center;justify-content:flex-end;gap:.4rem;flex-shrink:0}.Studio_syncStatusLabel__C5cmS{color:var(--text-tertiary);font-size:.74rem;font-weight:500;white-space:nowrap}.Studio_iconButton__aVxFx{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px solid rgba(255,255,255,.09);border-radius:0;background:rgba(255,255,255,.04);color:#fafafa;cursor:pointer;font-family:inherit;font-size:1rem;line-height:1;padding:0;white-space:nowrap}.Studio_iconButton__aVxFx:hover:not(:disabled){background:rgba(255,255,255,.07);border-color:rgba(255,255,255,.15)}.Studio_iconButton__aVxFx:disabled{color:var(--text-tertiary);cursor:default}.Studio_dataLayout__RTqFZ{display:grid;grid-template-columns:9.5rem minmax(0,1fr);gap:0;align-items:start}.Studio_experimentsLayout__dJ9_W{display:flex;align-items:flex-start;min-width:0}.Studio_dataNav__Hhqcz{display:flex;flex-direction:column;gap:.25rem;align-self:stretch;box-sizing:border-box;min-height:calc(100vh - 8rem);padding:0 1rem 0 0;border-right:1px solid rgba(255,255,255,.08)}.Studio_experimentNav__pUm9S{min-width:220px;max-width:min(520px,45vw);overflow:auto;flex:0 0 auto;padding:0;border-right:none}.Studio_experimentNavItem__VrdaI{display:flex;width:100%;box-sizing:border-box}.Studio_sidebarResizeHandle__Bfcoi{position:relative;align-self:stretch;flex:0 0 16px;min-height:calc(100vh - 8rem);cursor:col-resize}.Studio_sidebarResizeHandle__Bfcoi:before{content:"";position:absolute;top:0;bottom:0;left:7px;width:1px;background:rgba(255,255,255,.08);transition:background .12s ease}.Studio_sidebarResizeHandle__Bfcoi:hover:before{background:rgba(255,255,255,.22)}.Studio_dataNavItem__rzaJQ{display:inline-flex;align-items:center;justify-content:flex-start;width:fit-content;min-height:32px;border:0;border-radius:0;background:transparent;color:var(--text-tertiary);cursor:pointer;font-family:inherit;font-size:.85rem;font-weight:500;padding:0 .8rem;text-align:left;text-decoration:none;transition:background .15s,color .15s}.Studio_dataNavGroupItem__0bfKJ{flex-direction:column;align-items:flex-start;gap:.12rem;width:100%;min-height:48px;padding:.4rem .65rem}.Studio_dataNavItemMeta__PEhqv,.Studio_dataNavItemText__nSadp{display:block;width:100%;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Studio_experimentNavItem__VrdaI .Studio_dataNavItemMeta__PEhqv,.Studio_experimentNavItem__VrdaI .Studio_dataNavItemText__nSadp{overflow:visible;text-overflow:clip;white-space:normal}.Studio_dataNavItemText__nSadp{color:inherit;line-height:1.2}.Studio_dataNavItemMeta__PEhqv{color:var(--text-tertiary);font-size:.7rem;line-height:1.2}.Studio_dataNavEmpty__sffpq{color:var(--text-tertiary);font-size:.78rem;padding:.5rem .65rem}.Studio_experimentNavEmpty__6O0bX{display:flex;flex-direction:column;gap:.25rem;width:100%;box-sizing:border-box;padding:.5rem .65rem}.Studio_dataNavEmptyTitle__VI2PP{color:var(--text-secondary);font-size:.82rem;font-weight:500;line-height:1.25}.Studio_dataNavEmptyCopy__dq6XK{color:var(--text-tertiary);font-size:.74rem;line-height:1.4}.Studio_dataNavItem__rzaJQ:hover{color:var(--text-secondary);background:rgba(255,255,255,.05)}.Studio_dataNavItem__rzaJQ:focus{outline:none}.Studio_dataNavItemActive__TANbd{color:#fafafa;background:rgba(255,255,255,.08)}.Studio_dataLayout__RTqFZ>.Studio_dataNav__Hhqcz{width:100%;padding:0}.Studio_dataLayout__RTqFZ>.Studio_dataNav__Hhqcz .Studio_dataNavItem__rzaJQ{display:flex;width:100%;box-sizing:border-box}.Studio_dataMain__rSYxU{min-width:0;flex:1 1 auto;padding:0 1.5rem 1.5rem}.Studio_surfaceToolbar__ayM6U{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:1rem}.Studio_tracesToolbarSearch__Y_MtI{display:flex;align-items:center;gap:.45rem;min-width:0;flex:1 1 auto}.Studio_textInput__9WjCF.Studio_traceSearchInput__5oRye{width:min(390px,44vw);height:28px;min-height:28px;font-size:.8rem;font-weight:500;line-height:1;padding:0 .6rem}.Studio_textInput__9WjCF.Studio_traceSearchInput__5oRye::placeholder{color:rgba(255,255,255,.42);font-weight:450}.Studio_secondaryButton__gEhyV.Studio_traceSearchButton__EmQvq{display:inline-flex;align-items:center;justify-content:center;flex:0 0 28px;width:28px;height:28px;padding:0}.Studio_searchIcon__siCkB{display:block;width:14px;height:14px;background:50%/14px 14px no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fafafa' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='6.5'/%3E%3Cpath d='m16 16 4.5 4.5'/%3E%3C/svg%3E")}.Studio_tracesToolbarRight__YpWj8{display:flex;align-items:center;justify-content:flex-end;gap:.65rem;min-width:max-content;margin-left:auto}.Studio_surfaceTitle__7SjZP{color:#fafafa;font-size:.95rem;font-weight:600}.Studio_surfaceSubtitle__i6YB6{margin-top:.15rem;color:var(--text-tertiary);font-size:.75rem}.Studio_inlineSelector__er_h_{display:inline-flex;align-items:center;gap:.45rem;min-width:0;width:max-content}.Studio_inlineSelectorLabel__T4g6q{color:var(--text-tertiary);font-size:.72rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;white-space:nowrap}.Studio_filterBar__I6G_F{display:flex;justify-content:flex-end;margin-bottom:1rem}.Studio_dangerButton__9Bclj,.Studio_primaryButton__t0Otf,.Studio_secondaryButton__gEhyV,.Studio_select__rbQ0i{height:32px;border-radius:0;border:1px solid rgba(255,255,255,.09);background:rgba(255,255,255,.04);color:#fafafa;font-family:inherit;font-size:.8rem}.Studio_select__rbQ0i{max-width:340px;appearance:none;background:linear-gradient(45deg,transparent 50%,rgba(255,255,255,.58) 0) calc(100% - 14px) 13px /5px 5px no-repeat,linear-gradient(135deg,rgba(255,255,255,.58) 50%,transparent 0) calc(100% - 9px) 13px /5px 5px no-repeat,rgba(255,255,255,.04);padding:0 1.8rem 0 .5rem}.Studio_select__rbQ0i:focus{outline:none;border-color:rgba(255,255,255,.22);background-color:rgba(255,255,255,.06)}.Studio_select__rbQ0i option{background:#111;color:#fafafa}.Studio_checkboxInput__E3h42{display:inline-grid;place-content:center;width:14px;height:14px;margin:0;appearance:none;cursor:pointer;border:1px solid rgba(255,255,255,.24);background:rgba(255,255,255,.04);vertical-align:middle}.Studio_checkboxInput__E3h42:before{width:7px;height:4px;border-bottom:1.8px solid #0a0a0a;border-left:1.8px solid #0a0a0a;content:"";opacity:0;transform:translateY(-1px) rotate(-45deg)}.Studio_checkboxInput__E3h42:checked{border-color:#fafafa;background:#fafafa}.Studio_checkboxInput__E3h42:checked:before{opacity:1}.Studio_checkboxInput__E3h42:indeterminate{border-color:#fafafa;background:#fafafa}.Studio_checkboxInput__E3h42:indeterminate:before{width:8px;height:0;border-bottom:1.8px solid #0a0a0a;border-left:0;opacity:1;transform:none}.Studio_checkboxInput__E3h42:focus{outline:none;border-color:rgba(255,255,255,.5)}.Studio_dropdown__Qu_kI{position:relative;width:100%;max-width:340px}.Studio_dropdownButton__xiN8C{display:inline-flex;align-items:center;justify-content:space-between;gap:.65rem;width:100%;height:32px;padding:0 .6rem;border:1px solid rgba(255,255,255,.09);background:rgba(255,255,255,.04);color:#fafafa;cursor:pointer;font-family:inherit;font-size:.8rem;text-align:left}.Studio_dropdownButton__xiN8C:hover:not(:disabled),.Studio_dropdownButton__xiN8C[aria-expanded=true]{border-color:rgba(255,255,255,.18);background:rgba(255,255,255,.06)}.Studio_dropdownButton__xiN8C:focus{outline:none;border-color:rgba(255,255,255,.22)}.Studio_dropdownButton__xiN8C:disabled{color:var(--text-tertiary);cursor:default}.Studio_dropdownValue__0_6qb{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Studio_dropdownChevron__eSQVR{width:7px;height:7px;flex:0 0 7px;border-right:1px solid rgba(255,255,255,.62);border-bottom:1px solid rgba(255,255,255,.62);transform:translateY(-2px) rotate(45deg)}.Studio_dropdownMenu__Z_P4L{position:absolute;top:calc(100% + .25rem);left:0;right:0;z-index:1100;max-height:220px;overflow:auto;border:1px solid rgba(255,255,255,.12);background:#111;box-shadow:0 10px 24px rgba(0,0,0,.52)}.Studio_dropdownOption__8vaW9{display:block;width:100%;min-height:32px;padding:.45rem .6rem;border:0;border-bottom:1px solid rgba(255,255,255,.06);background:transparent;color:var(--text-secondary);cursor:pointer;font-family:inherit;font-size:.8rem;text-align:left}.Studio_dropdownOption__8vaW9:last-child{border-bottom:0}.Studio_dropdownOptionSelected__Qv75j,.Studio_dropdownOption__8vaW9:focus,.Studio_dropdownOption__8vaW9:hover{background:rgba(255,255,255,.08);color:#fafafa}.Studio_dropdownOption__8vaW9:focus{outline:none}.Studio_primaryButton__t0Otf{padding:0 .85rem;cursor:pointer;color:#0a0a0a;background:#fafafa;border-color:#fafafa;font-weight:600}.Studio_dangerButton__9Bclj,.Studio_secondaryButton__gEhyV{padding:0 .75rem;cursor:pointer}.Studio_dangerButton__9Bclj{color:#ffb3a6;background:rgba(232,85,61,.08);border-color:rgba(232,85,61,.22)}.Studio_primaryButton__t0Otf:hover:not(:disabled){background:var(--text-secondary);border-color:var(--text-secondary)}.Studio_secondaryButton__gEhyV:hover:not(:disabled){background:rgba(255,255,255,.07);border-color:rgba(255,255,255,.15)}.Studio_dangerButton__9Bclj:hover:not(:disabled){background:rgba(232,85,61,.13);border-color:rgba(232,85,61,.34)}.Studio_dangerButton__9Bclj:disabled,.Studio_primaryButton__t0Otf:disabled,.Studio_secondaryButton__gEhyV:disabled{color:var(--text-tertiary);cursor:default}.Studio_primaryButton__t0Otf:disabled{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.09)}.Studio_splitSurface__v2lGr{display:grid;grid-template-columns:minmax(240px,340px) minmax(0,1fr);gap:1rem;min-height:560px}.Studio_detailPanel__upjwv,.Studio_emptyPanel__nqsJ1,.Studio_errorPanel__OFovk,.Studio_listPanelEmpty__Ofh2D,.Studio_listPanel__KQbqx,.Studio_loadingPanel__VwGMY{border:1px solid rgba(255,255,255,.08);border-radius:0;background:rgba(255,255,255,.03)}.Studio_listPanel__KQbqx{overflow:auto;max-height:calc(100vh - 280px)}.Studio_emptyPanel__nqsJ1,.Studio_listPanelEmpty__Ofh2D,.Studio_loadingPanel__VwGMY{display:flex;align-items:center;justify-content:center;min-height:260px;color:var(--text-tertiary);font-size:.86rem;text-align:center;padding:2rem}.Studio_listRow__NObDS{display:flex;flex-direction:column;align-items:stretch;gap:.2rem;width:100%;padding:.75rem;border:0;border-bottom:1px solid rgba(255,255,255,.05);background:transparent;color:inherit;font-family:inherit;text-align:left;white-space:normal;cursor:pointer}.Studio_listRow__NObDS:hover{background:rgba(255,255,255,.04)}.Studio_listRowSelected__v7gF6{background:rgba(91,141,239,.1);box-shadow:inset 2px 0 0 #5b8def}.Studio_listRowTitle__Dg_xF{display:block;min-width:0;color:#fafafa;font-size:.82rem;font-weight:500;line-height:1.28;overflow:visible;overflow-wrap:anywhere;text-overflow:clip;white-space:normal}.Studio_listRowMeta__fmtZx{color:var(--text-tertiary);font-size:.72rem}.Studio_listRowLinked__YG4yc,.Studio_listRowMeta__fmtZx{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Studio_listRowLinked__YG4yc{color:rgba(158,188,255,.86);font-size:.7rem}.Studio_detailPanel__upjwv{min-width:0;padding:1rem;overflow:auto;max-height:calc(100vh - 280px)}.Studio_detailHeader__an_N2{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;margin-bottom:1rem}.Studio_detailHeaderAction__VRlRY{align-self:flex-start}.Studio_detailTitle__H8HXN{margin:0;color:#fafafa;font-size:1rem;font-weight:600;line-height:1.35;overflow-wrap:anywhere}.Studio_detailMeta__F__Kq,.Studio_mutedText__gxlbZ{margin-top:.2rem;color:var(--text-tertiary);font-size:.74rem;overflow-wrap:anywhere}.Studio_detailLink__QdlV6{color:#5b8def;font-size:.78rem;text-decoration:none}.Studio_detailLink__QdlV6:hover{text-decoration:underline}.Studio_detailGrid__eKjPQ{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.75rem}.Studio_jsonBlock__V4yWY{min-width:0;margin-bottom:.75rem}.Studio_jsonTitle__4rJZO,.Studio_sectionTitle__AgJZy{margin-bottom:.35rem;color:var(--text-secondary);font-size:.72rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em}.Studio_jsonPre__NT0BZ{max-height:320px;overflow:auto;margin:0;padding:.75rem;border-radius:0;background:rgba(0,0,0,.28);color:var(--text-secondary);font-size:.75rem;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.Studio_traceSection__7pMTX{margin-top:1rem}.Studio_traceHeader__Ulrn7{display:flex;align-items:baseline;gap:.75rem;margin-bottom:.6rem}.Studio_traceName__YsChW{color:#fafafa;font-size:.9rem;font-weight:600;overflow-wrap:anywhere}.Studio_tagRow__Prgun{display:flex;flex-wrap:wrap;gap:.35rem;margin:.75rem 0}.Studio_tagPill__TRnnW{display:inline-flex;align-items:center;min-height:22px;padding:0 .45rem;border-radius:0;background:rgba(91,141,239,.12);color:#9ebcff;border:1px solid rgba(91,141,239,.22);font-size:.7rem;font-weight:500}.Studio_errorPanel__OFovk{margin-bottom:1rem;padding:.75rem;color:#ffb3a6;background:rgba(232,85,61,.1);border-color:rgba(232,85,61,.3);font-size:.82rem}.Studio_successPanel__03cvQ{margin-bottom:1rem;padding:.75rem;color:#b8f5df;background:rgba(0,212,170,.08);border:1px solid rgba(0,212,170,.22);border-radius:0;font-size:.82rem}.Studio_evalDefinitionGrid__YMID0{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem}.Studio_evalDefinitionCell__wS4ZE{min-width:0}.Studio_evalDefinitionCode___J0aO{display:block;width:fit-content;max-width:100%;margin-top:.2rem;background:rgba(0,0,0,.24);color:var(--text-tertiary);font-size:.72rem;padding:.1rem .28rem;overflow-wrap:anywhere}.Studio_evalHistorySection__e_91j{margin-top:1rem}.Studio_evalSectionHeader___IiLV{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;margin-bottom:.75rem}.Studio_evalSummaryTable__gZ5vh{border:1px solid rgba(255,255,255,.08);background:rgba(255,255,255,.03)}.Studio_evalSummaryHeader__ku_ov,.Studio_evalSummaryRow__KtPSR{display:grid;grid-template-columns:minmax(180px,1.35fr) minmax(180px,1.35fr) 80px 80px 160px;gap:.75rem;align-items:center}.Studio_evalSummaryHeader__ku_ov{padding:.55rem .75rem;border-bottom:1px solid rgba(255,255,255,.08);color:var(--text-tertiary);font-size:.7rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.Studio_evalSummaryRow__KtPSR{padding:.65rem .75rem;border-bottom:1px solid rgba(255,255,255,.05);color:var(--text-secondary);font-size:.78rem}.Studio_evalSummaryRow__KtPSR:last-child{border-bottom:0}.Studio_evalSummaryMeta__RgcSF,.Studio_evalSummaryPrimary__VAArE{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Studio_evalSummaryPrimary__VAArE{color:#fafafa;font-weight:500}.Studio_evalSummaryMeta__RgcSF{margin-top:.12rem;color:var(--text-tertiary);font-size:.7rem}.Studio_setupBanner__rn3R6{margin-bottom:1rem;border:1px solid rgba(245,166,35,.34);border-radius:0;background:rgba(245,166,35,.08);padding:.85rem}.Studio_setupTitle__rrPH_{color:#fafafa;font-size:.88rem;font-weight:600}.Studio_setupCopy__InFUm{margin-top:.2rem;color:var(--text-secondary);font-size:.8rem;line-height:1.5}.Studio_setupHeader__0z51Y{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem}.Studio_setupState__u13N3{display:inline-flex;align-items:center;min-height:22px;border-radius:0;padding:0 .45rem;color:#f5c77b;background:rgba(245,166,35,.1);border:1px solid rgba(245,166,35,.3);font-size:.68rem;font-weight:600;white-space:nowrap}.Studio_setupGrid__43Ac0{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.75rem;margin-top:.8rem}.Studio_setupBlock__pXdLU{min-width:0}.Studio_setupBlockTitle__HS_1S{display:block;margin-bottom:.35rem;color:var(--text-tertiary);font-size:.68rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em}.Studio_setupCode__3AADb{display:block;width:fit-content;max-width:100%;margin-top:.25rem;border-radius:0;background:rgba(0,0,0,.26);color:#fafafa;padding:.18rem .38rem;font-size:.72rem;overflow-wrap:anywhere}.Studio_setupDetail__BYnnc,.Studio_setupLookup__S7xvC{margin-top:.75rem;color:var(--text-tertiary);font-size:.75rem;line-height:1.5;overflow-wrap:anywhere}.Studio_setupLookupLabel__OOHGt{color:var(--text-secondary);font-weight:600;margin-right:.35rem}.Studio_ideaMetaGrid__QA5ZP{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem;margin-bottom:.75rem}.Studio_metaCell__lTOia{min-width:0}.Studio_metaLabel__orMyw{display:block;color:var(--text-tertiary);font-size:.7rem}.Studio_metaValue__wPOIw{display:block;margin-top:.1rem;color:var(--text-secondary);font-size:.78rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Studio_descriptionBlock__RgZHz{white-space:pre-wrap;overflow-wrap:anywhere;color:var(--text-secondary);font-size:.84rem;line-height:1.55}.Studio_linkedExperimentsSection__V6m61{margin-bottom:1rem}.Studio_linkedExperimentsList__m3Pel{display:grid;gap:.5rem}.Studio_linkedExperimentsEmpty__j9at4{color:var(--text-tertiary);font-size:.78rem}.Studio_linkedExperimentRow___NdVV,.Studio_linkedExperimentsEmpty__j9at4{border:1px solid rgba(255,255,255,.08);background:rgba(255,255,255,.025);padding:.65rem .75rem}.Studio_linkedExperimentRow___NdVV{display:grid;grid-template-columns:minmax(0,1fr) max-content;align-items:center;gap:.75rem}.Studio_linkedExperimentMain__P1a2y,.Studio_linkedExperimentStats__SKDtt{min-width:0}.Studio_linkedExperimentTitle__zxkFB{display:block;min-width:0;color:#fafafa;font-size:.8rem;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Studio_linkedExperimentStats__SKDtt{display:inline-flex;align-items:center;justify-content:flex-end;gap:.45rem}.Studio_linkedExperimentScore__aOXcH{color:#fafafa;font-size:.8rem;font-weight:600;white-space:nowrap}.Studio_linkedExperimentMeta__UQRzL{display:block;min-width:0;color:var(--text-tertiary);font-size:.7rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Studio_formRow__CkHSQ{display:flex;flex-direction:column;gap:.35rem;margin-bottom:.75rem}.Studio_formLabel__pObCQ{color:var(--text-tertiary);font-size:.72rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em}.Studio_textInput__9WjCF{min-height:34px;padding:0 .65rem}.Studio_textAreaLarge__20NQc,.Studio_textArea__yi_Lm,.Studio_textInput__9WjCF{border:1px solid rgba(255,255,255,.1);border-radius:0;background:rgba(0,0,0,.26);color:#fafafa;font-family:inherit;font-size:.84rem}.Studio_textAreaLarge__20NQc,.Studio_textArea__yi_Lm{min-height:96px;resize:vertical;line-height:1.45;padding:.6rem .65rem}.Studio_textAreaLarge__20NQc{min-height:180px;font-family:Geist Mono,ui-monospace,monospace;font-size:.78rem}.Studio_textAreaLarge__20NQc::placeholder,.Studio_textArea__yi_Lm::placeholder,.Studio_textInput__9WjCF::placeholder{color:var(--text-tertiary)}.Studio_actionRow__0pQf0{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:.5rem}.Studio_actionFooter__wFiYP{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin:1rem 0;padding-top:.75rem;border-top:1px solid rgba(255,255,255,.08)}.Studio_emptyState__dwICN{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:560px;gap:.9rem;text-align:center}.Studio_emptyLogo__ehso4{width:220px;height:auto;opacity:.85}.Studio_emptyTitle__ByiEP{margin:0;color:#fafafa;font-size:1.45rem;font-weight:600}.Studio_emptyCopy__NP7hT,.Studio_emptyMeta__Bsrtp,.Studio_emptyPanelCopy__EExQw{color:var(--text-tertiary);font-size:.86rem;line-height:1.5}.Studio_emptyPanel__nqsJ1{flex-direction:column;gap:.35rem}.Studio_experimentEmptyPanel__p0J2y{min-height:360px}.Studio_experimentEmptyPanel__p0J2y .Studio_emptyPanelCopy__EExQw{max-width:420px}.Studio_experimentDetailSurface__dwDGR{display:flex;flex-direction:column;min-width:0}.Studio_experimentDetailSummary__R5pum{margin-bottom:.8rem;padding:.85rem 1rem;background:rgba(255,255,255,.025);border:1px solid rgba(255,255,255,.08)}.Studio_experimentDetailTitleRow__dLxGu{display:flex;align-items:center;justify-content:space-between;gap:1rem}.Studio_experimentDetailTitleGroup__u0ltv{display:flex;align-items:center;flex:1 1 auto;min-width:0;gap:.45rem;flex-wrap:nowrap}.Studio_experimentDetailTitle__WVcLo{margin:0;color:#fafafa;font-size:1rem;font-weight:600;line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Studio_experimentDetailTimeRow__WBHOD{display:flex;justify-content:flex-end;gap:.45rem;color:var(--text-tertiary);font-size:.68rem;line-height:1.35;white-space:nowrap}.Studio_experimentDetailTimeSeparator__zVrpA{color:rgba(255,255,255,.22)}.Studio_experimentMetricStrip__nO66g{display:grid;grid-template-columns:repeat(auto-fit,minmax(118px,1fr));gap:0;margin-top:.75rem;padding-top:.75rem;border-top:1px solid rgba(255,255,255,.06)}.Studio_experimentMetricItem__9szWE{display:grid;grid-template-columns:minmax(0,auto) auto;align-items:baseline;column-gap:.45rem;row-gap:.15rem;min-width:0;padding-right:.75rem;border-right:1px solid rgba(255,255,255,.06)}.Studio_experimentMetricItem__9szWE:last-child{border-right:0}.Studio_experimentMetricItemPrimary__8nYrs .Studio_experimentMetricValue__g26s2{color:#00d4aa}.Studio_experimentMetricLabel__g8uYl{color:var(--text-tertiary);font-size:.72rem;font-weight:500}.Studio_experimentMetricValue__g26s2{color:#fafafa;font-size:.95rem;font-weight:600;font-feature-settings:"tnum";font-variant-numeric:tabular-nums}.Studio_emptyPanelTitle__g31eb{color:#fafafa;font-size:.95rem;font-weight:600}.Studio_runTracesPanel__nh_gK{display:flex;flex-direction:column;width:100%;min-width:0;background:transparent;border:0;overflow:visible}.Studio_runTracesPanelHeader__gJlWU{display:flex;align-items:flex-start;justify-content:space-between;padding:0 0 .75rem}.Studio_runTracesPanelTitle__gUr1M{font-size:1.1rem;font-weight:500;margin:0;color:#fff}.Studio_runTracesDetail__vStOu{flex:1 1;overflow-y:auto;padding:1rem 1.5rem}.Studio_runTracesTableWrap__V4tCd{flex:1 1;overflow-y:auto;padding:0 0 1rem;background:rgba(255,255,255,.025);border:1px solid rgba(255,255,255,.08)}.Studio_datasetsTableWrap__biwzy{overflow:visible;padding-bottom:1.25rem}.Studio_runTracesTable__FzXJs{width:100%;border-collapse:collapse;font-size:.8rem;font-family:Geist,ui-sans-serif,system-ui,sans-serif}.Studio_runTracesTable__FzXJs th{position:sticky;top:0;z-index:1;padding:.6rem .75rem;text-align:left;font-size:.72rem;font-weight:600;letter-spacing:0;color:rgba(255,255,255,.48);background:#101010;border-bottom:1px solid rgba(255,255,255,.08);-webkit-user-select:none;user-select:none}.Studio_runTracesSortButton__ej_zF{display:inline-flex;align-items:center;gap:.35rem;max-width:100%;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;font:inherit;text-align:left;transition:color .15s ease}.Studio_runTracesSortButton__ej_zF:hover{color:var(--text-secondary)}.Studio_runTracesSortButtonActive__Oy1me{color:rgba(255,255,255,.9)}.Studio_runTracesSortIcon__HEo3w{color:inherit;font-size:.62rem;line-height:1;opacity:.76}.Studio_runTracesTable__FzXJs td{padding:.55rem .75rem;color:rgba(255,255,255,.78);border-bottom:1px solid rgba(255,255,255,.04)}.Studio_runTracesTableRowClickable__sdAb4{cursor:pointer;transition:background-color .15s ease}.Studio_runTracesTableRowClickable__sdAb4:hover{background:rgba(255,255,255,.04)}.Studio_datasetRowMenuOpen__7ty_2{position:relative;z-index:20}.Studio_runTracesTableId__zVZBX{font-family:Geist Mono,ui-monospace,monospace;font-size:.75rem;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Studio_datasetActionsCell__xmMLt{position:relative;overflow:visible;width:40px}.Studio_datasetActionsCellOpen__JsSmA{z-index:30}.Studio_datasetMenuAnchor__D7NTr{position:relative;display:inline-flex;justify-content:flex-end;width:100%;z-index:1}.Studio_datasetActionsCellOpen__JsSmA .Studio_datasetMenuAnchor__D7NTr{z-index:40}.Studio_backButton__sPEo0{display:inline-flex;align-items:center;align-self:flex-start;gap:.25rem;margin-bottom:.65rem;padding:0;font-family:inherit;font-size:.72rem;font-weight:500;color:var(--text-tertiary);background:transparent;border:0;border-radius:0;cursor:pointer;line-height:1.2;transition:color .15s}.Studio_backButton__sPEo0:hover{color:var(--text-secondary)}.Studio_tagPillRemove__K4mw7{margin-left:.35rem;background:none;border:none;color:rgba(255,255,255,.5);cursor:pointer;padding:0;font-size:.75rem;line-height:1}.Studio_tagPillRemove__K4mw7:hover{color:#fff}.Studio_dataFieldLabel__nb_nM{font-size:.8rem;color:rgba(255,255,255,.5);margin-bottom:.35rem}.Studio_membershipPanel__EGstU{display:grid;grid-template-columns:minmax(170px,max-content) minmax(0,1fr);align-items:center;gap:.75rem;margin:0 0 .65rem;padding:.65rem .75rem;border:1px solid rgba(255,255,255,.08);background:rgba(255,255,255,.025)}.Studio_membershipPanelWithAction__efBwS{grid-template-columns:minmax(170px,max-content) minmax(0,1fr) max-content}.Studio_traceDatasetControls__IwM5z{display:grid;gap:.5rem;margin:0 0 .65rem}.Studio_traceDatasetControls__IwM5z .Studio_membershipPanel__EGstU{margin-bottom:0}.Studio_membershipHeader___UOhR{display:flex;align-items:center;justify-content:space-between;gap:.75rem;min-width:0}.Studio_membershipTitle__2LIen{color:#fafafa;font-size:.82rem;font-weight:600}.Studio_membershipMeta__TlU5c{margin-top:.12rem;color:var(--text-tertiary);font-size:.7rem}.Studio_membershipContent__jqHx_{min-width:0}.Studio_membershipList__KXw_7{display:flex;flex-wrap:wrap;gap:.4rem}.Studio_membershipAction__RTbv1,.Studio_membershipActions__BUxtX{display:flex;justify-content:flex-end}.Studio_membershipActions__BUxtX{flex-wrap:wrap;gap:.5rem}.Studio_membershipAction__RTbv1 .Studio_primaryButton__t0Otf,.Studio_membershipAction__RTbv1 .Studio_secondaryButton__gEhyV{display:inline-flex;align-items:center;height:28px;padding:0 .65rem;font-size:.74rem;text-decoration:none}.Studio_membershipPill__QjB0k{display:inline-flex;align-items:center;gap:.3rem;min-width:0;max-width:100%;min-height:24px;padding:0 .35rem;border:1px solid rgba(255,255,255,.1);background:rgba(255,255,255,.04);color:var(--text-secondary);font-size:.72rem;font-weight:600;transition:background .15s,border-color .15s,color .15s}.Studio_membershipPill__QjB0k:focus-within,.Studio_membershipPill__QjB0k:hover{border-color:rgba(255,255,255,.16);background:rgba(255,255,255,.07);color:#fafafa}.Studio_membershipPillLink__h9fV9,.Studio_membershipPillText__RwhCM{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Studio_membershipPillLink__h9fV9{display:inline-flex;align-items:center}.Studio_membershipPillLink__h9fV9,.Studio_membershipPillLink__h9fV9:hover{color:inherit;text-decoration:none}.Studio_membershipPillLink__h9fV9:focus{outline:none}.Studio_membershipRemoveButton__2K9Rp{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:0;background:transparent;color:rgba(255,255,255,.56);cursor:pointer;font-family:inherit;font-size:.9rem;line-height:1}.Studio_membershipRemoveButton__2K9Rp:hover:not(:disabled){color:#fafafa;background:rgba(255,255,255,.06)}.Studio_membershipRemoveButton__2K9Rp:disabled{cursor:default;opacity:.45}.Studio_membershipEmpty__Dt4SO{color:var(--text-tertiary);font-size:.76rem;white-space:nowrap}@media (max-width:760px){.Studio_membershipPanelWithAction__efBwS,.Studio_membershipPanel__EGstU{grid-template-columns:1fr}.Studio_membershipAction__RTbv1{justify-content:flex-start}.Studio_membershipEmpty__Dt4SO{white-space:normal}}.Studio_modalOverlay__x1Fj4{position:fixed;inset:0;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;z-index:1000}.Studio_modalContent__djAeV{background:#1a1a1a;border:1px solid rgba(255,255,255,.12);border-radius:0;padding:1.5rem;min-width:360px;max-width:480px;box-shadow:0 8px 32px rgba(0,0,0,.6)}.Studio_modalTitle__0QlJa{margin:0 0 1rem;font-size:1rem;font-weight:600}.Studio_modalMessage__XPzbe{color:rgba(255,255,255,.6);margin:0 0 1rem;font-size:.85rem;line-height:1.4}.Studio_modalActions__IU0lF{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1rem}.Studio_contextMenu__OGBEA{position:absolute;top:100%;right:0;z-index:1000;background:#1a1a1a;border:1px solid rgba(255,255,255,.12);border-radius:0;padding:.25rem 0;min-width:120px;box-shadow:0 4px 12px rgba(0,0,0,.4);pointer-events:auto}.Studio_contextMenuAbove__Hn1fV{top:auto;bottom:calc(100% + .25rem)}.Studio_contextMenuItem__V_cT5{display:block;width:100%;padding:.5rem .75rem;text-align:left;background:none;border:none;color:rgba(255,255,255,.85);cursor:pointer;font-size:.8rem}.Studio_contextMenuItem__V_cT5:hover{background:rgba(255,255,255,.06)}.Studio_contextMenuItemDanger__pyiHt{color:#ef4444}.Studio_paginationBar__rQxsq{display:flex;align-items:center;justify-content:center;gap:.35rem;padding:.5rem}.Studio_paginationBarToolbar__CkBjt{justify-content:flex-end;padding:0}.Studio_paginationIconButton__7_OgH{flex:0 0 28px;width:28px;height:28px;font-size:.78rem}.Studio_paginationLabel__geOOY{padding:.25rem .45rem;font-size:.74rem;color:rgba(255,255,255,.6);white-space:nowrap}@media (max-width:900px){.Studio_topBar__OlLt6{grid-template-columns:minmax(0,1fr);align-items:stretch}.Studio_surfaceNav__RKZjS{overflow-x:auto}.Studio_dataNav__Hhqcz{flex-direction:row;align-self:auto;width:100%;min-height:0;overflow-x:auto;padding:0 0 .75rem;border-right:0;border-bottom:1px solid rgba(255,255,255,.08)}.Studio_dataLayout__RTqFZ>.Studio_dataNav__Hhqcz .Studio_dataNavItem__rzaJQ{flex:0 0 auto;width:auto}.Studio_dataMain__rSYxU{padding:0}.Studio_experimentNav__pUm9S{width:100%!important;min-width:0;max-width:none}.Studio_experimentsLayout__dJ9_W{flex-direction:column}.Studio_experimentsMain__8IYj4{width:100%;margin-left:0}.Studio_sidebarResizeHandle__Bfcoi{display:none}.Studio_actionFooter__wFiYP,.Studio_detailHeader__an_N2,.Studio_setupHeader__0z51Y,.Studio_surfaceBanner__UNvfB,.Studio_surfaceToolbar__ayM6U,.Studio_traceHeader__Ulrn7{flex-direction:column;align-items:stretch}.Studio_tracesToolbarRight__YpWj8,.Studio_tracesToolbarSearch__Y_MtI{flex-wrap:wrap;justify-content:flex-start;min-width:0;margin-left:0}.Studio_textInput__9WjCF.Studio_traceSearchInput__5oRye{width:min(100%,240px)}.Studio_syncStatus__exlkz{justify-content:flex-start}.Studio_dataLayout__RTqFZ,.Studio_detailGrid__eKjPQ,.Studio_evalDefinitionGrid__YMID0,.Studio_evalSummaryHeader__ku_ov,.Studio_evalSummaryRow__KtPSR,.Studio_ideaMetaGrid__QA5ZP,.Studio_linkedExperimentRow___NdVV,.Studio_setupGrid__43Ac0,.Studio_splitSurface__v2lGr{grid-template-columns:1fr}.Studio_detailPanel__upjwv,.Studio_listPanel__KQbqx{max-height:none}.Studio_datasetsTableWrap__biwzy,.Studio_runTracesTableWrap__V4tCd{overflow-x:auto}}.SystemSelector_wrapper__ERtiP{display:inline-flex;align-items:center;gap:.45rem;min-width:0;width:max-content}.SystemSelector_label__4i0LZ{color:var(--text-tertiary,#666);font-size:.72rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;white-space:nowrap}.SystemSelector_dropdown__mshbO{width:clamp(144px,18vw,280px)}.Runs_layout__Ih4Cn{display:flex;flex:1 1;min-height:100%;background:#0a0a0a}.Runs_heroLogo__BAUu8{width:240px;height:auto;opacity:.85}.Runs_headerLogo__TgYiK{width:18px;height:18px;object-fit:contain;border-radius:0;flex-shrink:0}.Runs_container__0aqIq{flex:1 1;min-width:0;margin:0;padding:2rem;font-family:Geist,ui-sans-serif,system-ui,-apple-system,sans-serif;background:#0a0a0a;color:#fafafa;min-height:100%;box-sizing:border-box;overflow-x:hidden}.Runs_headerRow__abEUi{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.6rem 0;border-bottom:1px solid rgba(255,255,255,.06);margin-bottom:.5rem}.Runs_title__oroey{font-size:1rem;font-weight:500;margin:0;color:#fff;white-space:nowrap;flex-shrink:0}.Runs_connectedBadge__d1Ss1{border:1px solid rgba(0,212,170,.4);color:#00d4aa;background:rgba(0,212,170,.1)}.Runs_connectedBadge__d1Ss1,.Runs_disconnectedBadge__v3kiS{font-size:.65rem;font-weight:500;text-transform:uppercase;letter-spacing:1px;padding:.2rem .6rem}.Runs_disconnectedBadge__v3kiS{border:1px solid rgba(245,166,35,.4);color:#f5a623;background:rgba(245,166,35,.1)}.Runs_systemTabs__Gtuvz{display:flex;gap:.25rem;margin-bottom:.5rem;border-bottom:1px solid rgba(255,255,255,.06);padding-bottom:0;overflow-x:auto}.Runs_systemTab__XYpgy{display:flex;align-items:center;gap:.5rem;padding:.6rem 1rem;background:none;border:none;border-bottom:2px solid transparent;color:var(--text-tertiary);font-family:inherit;font-size:.85rem;font-weight:400;cursor:pointer;transition:color .15s,border-color .15s;white-space:nowrap}.Runs_systemTab__XYpgy:hover{color:var(--text-secondary)}.Runs_systemTabActive__10lyk{color:#fff;border-bottom-color:#00d4aa}.Runs_systemTabName__pER4w{font-weight:400}.Runs_systemTabStatus__YbTNa{font-size:.6rem;font-weight:500;text-transform:uppercase;letter-spacing:.5px;padding:.1rem .4rem}.Runs_systemStatus_in_progress__i_6lJ{color:#00d4aa;background:rgba(0,212,170,.1);border:1px solid rgba(0,212,170,.3)}.Runs_systemStatus_completed__pjTng{color:#5b8def;background:rgba(91,141,239,.1);border:1px solid rgba(91,141,239,.3)}.Runs_systemStatus_not_started__FqOI6{color:var(--text-tertiary);background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08)}.Runs_subtitle__ZfT5k{color:var(--text-tertiary);font-size:.75rem;font-weight:400;line-height:1.4;margin-top:.15rem}.Runs_targetBadge__XoNhG{font-size:.65rem;color:var(--text-tertiary);background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.08);border-radius:0;padding:.1rem .4rem;white-space:nowrap;flex-shrink:0}.Runs_grid__7DXl9{display:grid;grid-template-columns:repeat(3,1fr);gap:1.25rem;margin-bottom:3rem}.Runs_card__AxGEL{border:1px solid rgba(255,255,255,.08);padding:1.5rem;background:rgba(255,255,255,.03);transition:border-color .4s,box-shadow .4s;min-width:0;overflow:hidden}.Runs_card__AxGEL:hover{border-color:rgba(255,255,255,.15)}@keyframes Runs_cardGlow__mf3t7{0%{border-color:rgba(0,212,170,.8);box-shadow:0 0 20px rgba(0,212,170,.15),inset 0 0 20px rgba(0,212,170,.03)}to{border-color:rgba(255,255,255,.08);box-shadow:none}}@keyframes Runs_badgePop__PdKoP{0%{transform:scale(1.3);filter:brightness(1.8)}40%{transform:scale(.95)}to{transform:scale(1);filter:brightness(1)}}@keyframes Runs_textHighlight__9znCz{0%{color:#00d4aa}to{color:var(--text-secondary)}}@keyframes Runs_slideInFade__SsIak{0%{opacity:0;transform:translateY(-8px);background:rgba(0,212,170,.12)}40%{opacity:1;transform:translateY(0)}to{background:transparent}}@keyframes Runs_diagramPulse__yN0dx{0%{border-color:rgba(0,212,170,.5);background:rgba(0,212,170,.06)}to{border-color:rgba(255,255,255,.06);background:rgba(255,255,255,.04)}}.Runs_cardFlash__pXo7_{animation:Runs_cardGlow__mf3t7 1.2s ease-out forwards}.Runs_badgeFlash__Q0C8G{animation:Runs_badgePop__PdKoP .5s cubic-bezier(.34,1.56,.64,1) forwards}.Runs_textFlash__O_0mj{animation:Runs_textHighlight__9znCz 1.2s ease-out forwards}.Runs_rowSlideIn__rGZ9I{animation:Runs_slideInFade__SsIak .8s ease-out forwards}.Runs_diagramFlash__4ZTFP{animation:Runs_diagramPulse__yN0dx 1.2s ease-out forwards}.Runs_cardHeader__7EpGx{display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem}.Runs_cardTitle__l82f2{font-size:1.1rem;font-weight:300;letter-spacing:-.2px;margin:0;color:#fff}.Runs_bestAccuracyInline__0XYna{margin-left:auto;font-size:.9rem;font-weight:500;font-feature-settings:"tnum";font-variant-numeric:tabular-nums;color:#00d4aa}.Runs_linearIssueLink__aVa6L{display:inline-flex;align-items:center;gap:.3rem;max-width:100%;min-height:24px;padding:0 .35rem;border:1px solid rgba(255,255,255,.1);background:rgba(255,255,255,.04);color:var(--text-secondary);font-size:.72rem;font-weight:600;text-decoration:none;white-space:nowrap}.Runs_linearIssueLink__aVa6L span{min-width:0;overflow:hidden;text-overflow:ellipsis}.Runs_linearIssueLink__aVa6L:hover{background:rgba(255,255,255,.07);border-color:rgba(255,255,255,.16);color:#fafafa}.Runs_linearIssueLink__aVa6L img{display:block;width:14px;height:14px;object-fit:contain}.Runs_statusBadge__T4ifS{display:inline-block;padding:.2rem .6rem;font-size:.6rem;font-weight:500;text-transform:uppercase;letter-spacing:1px;flex-shrink:0}.Runs_detailTitleStack__a_E4h{display:flex;flex-direction:column;min-width:0;gap:.35rem}.Runs_runProgressBlock__Hg4fw{margin-bottom:1rem;padding:.75rem;border:1px solid rgba(255,255,255,.08);background:rgba(255,255,255,.03)}.Runs_runProgressHeader__e69Sy{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:.45rem;color:var(--text-secondary);font-size:.76rem;font-feature-settings:"tnum";font-variant-numeric:tabular-nums}.Runs_runProgressTrack__c_Wjv{height:8px;background:rgba(255,255,255,.08);overflow:hidden}.Runs_runProgressFill__JOLgM{height:100%;background:#00d4aa}.Runs_runMetaGrid__kiPS9{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.65rem;margin-bottom:1rem}.Runs_runMetaCell__lEV1l{min-width:0;padding:.6rem .65rem;border:1px solid rgba(255,255,255,.07);background:rgba(255,255,255,.025)}.Runs_runMetaLabel__DxMGL{display:block;color:var(--text-tertiary);font-size:.65rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.Runs_runMetaValue__gJoib{display:block;min-width:0;margin-top:.18rem;color:var(--text-secondary);font-size:.78rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Runs_detailEmpty__wy74V{padding:.75rem;border:1px solid rgba(255,255,255,.07);background:rgba(255,255,255,.025);color:var(--text-tertiary);font-size:.8rem}.Runs_metricsTable__C_A_z{font-size:.8rem;margin-bottom:1rem;table-layout:fixed}.Runs_metricsTable__C_A_z td,.Runs_metricsTable__C_A_z th{padding:.5rem;text-align:center;border-bottom:1px solid rgba(255,255,255,.06)}.Runs_metricsTable__C_A_z th{font-weight:500;font-size:.7rem;text-transform:uppercase;letter-spacing:.5px;color:var(--text-tertiary);background:transparent;cursor:help;-webkit-text-decoration:underline dotted rgba(250,250,250,.2);text-decoration:underline dotted rgba(250,250,250,.2);text-underline-offset:3px}.Runs_metricsTable__C_A_z td{color:var(--text-primary);font-feature-settings:"tnum";font-variant-numeric:tabular-nums}.Runs_iterRowClickable__g1tjc{cursor:pointer;transition:background .15s}.Runs_iterRowClickable__g1tjc:hover{background:rgba(255,255,255,.04)}.Runs_iterRowExpanded__Nbl8_{background:rgba(255,255,255,.03)}.Runs_iterRowExpanded__Nbl8_ td{border-bottom-color:transparent}.Runs_bestRow__A_kku{background:rgba(0,212,170,.06)}.Runs_bestRow__A_kku.Runs_iterRowClickable__g1tjc:hover{background:rgba(0,212,170,.1)}.Runs_bestRow__A_kku td{color:#00d4aa;font-weight:500}.Runs_iterDetailRow__y10KK td{padding:0;border-bottom:1px solid rgba(255,255,255,.06)}.Runs_cardFooter__o_f_i{display:flex;flex-wrap:wrap;justify-content:space-between;gap:.5rem .9rem;font-size:.7rem;color:var(--text-tertiary);letter-spacing:.2px;padding-top:.35rem}.Runs_footerUpdated__21L7o{margin-left:auto}.Runs_chartContainer__bTh0u{border:1px solid rgba(255,255,255,.08);padding:1.5rem;background:rgba(255,255,255,.03)}.Runs_chartTitle__OkYqw{font-size:1.25rem;font-weight:300;letter-spacing:-.3px;margin:0 0 1.25rem;color:#fff}.Runs_chart__XhGIf{display:flex;flex-direction:column;gap:.35rem}.Runs_chartRow__DbGz_{display:flex;align-items:center;gap:1rem;height:32px}.Runs_chartLabel__3FlRl{width:180px;font-size:.75rem;font-weight:400;text-align:right;flex-shrink:0;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Runs_chartBarContainer__zzYv4{flex:1 1;display:flex;align-items:center;gap:.5rem}.Runs_chartBarTrack__5ogbA{flex:1 1;height:24px;position:relative;background:transparent}.Runs_chartBar__64D55{height:100%;background:#00d4aa;transition:width .3s ease}.Runs_chartRowClickable__RxDfH{cursor:pointer;transition:background .15s}.Runs_chartRowClickable__RxDfH:hover{background:rgba(255,255,255,.04)}.Runs_chartValue__lmV61{font-size:.85rem;font-weight:500;white-space:nowrap;color:var(--text-primary);font-feature-settings:"tnum";font-variant-numeric:tabular-nums;width:52px;text-align:right;flex-shrink:0}.Runs_metricsTable__C_A_z{width:100%;border-collapse:collapse;font-size:.85rem}.Runs_metricsTableHeader__8d74Z{font-size:.7rem;font-weight:500;text-transform:uppercase;letter-spacing:.05em;color:var(--text-tertiary);padding:.4rem .75rem;border-bottom:1px solid rgba(255,255,255,.08);text-align:left}.Runs_metricsTableRow__FEGrk{border-bottom:1px solid rgba(255,255,255,.04)}.Runs_metricsTableRow__FEGrk:hover{background:rgba(255,255,255,.03)}.Runs_metricsTableLabel__K8De_{padding:.5rem .75rem;color:var(--text-secondary);font-weight:400;white-space:nowrap}.Runs_metricsTableValue__kaegJ{padding:.5rem .75rem;text-align:right;font-weight:600;font-feature-settings:"tnum";font-variant-numeric:tabular-nums;color:var(--text-primary);white-space:nowrap}.Runs_metricsTableBarCell__8h1wf{padding:.5rem .75rem}.Runs_metricsTableBarTrack__b_CnH{height:6px;border-radius:0;background:rgba(255,255,255,.06);overflow:hidden}.Runs_metricsTableBar__HScEe{height:100%;border-radius:0;background:#00d4aa;transition:width .3s ease}.Runs_chartItems__Quwyx{font-size:.65rem;color:var(--text-tertiary);width:32px;text-align:right;flex-shrink:0;font-feature-settings:"tnum";font-variant-numeric:tabular-nums}.Runs_noData__fi5_n{color:var(--text-tertiary);text-align:center;padding:3rem;font-size:.9rem}.Runs_runSection__Ggi_B{margin-bottom:.75rem}.Runs_runSection__Ggi_B:last-child{margin-bottom:0}.Runs_runLabel__uGajV{display:block;font-size:.65rem;font-weight:500;text-transform:uppercase;letter-spacing:.5px;color:var(--text-tertiary);margin-bottom:.3rem}.Runs_treeForest__6GBAM{overflow-x:auto;overflow-y:hidden;padding-bottom:2rem;margin-bottom:3rem}.Runs_treeSvg___AATo{display:block;flex-shrink:0}.Runs_treeNodeCard__Y5XEX{width:100%;height:100%;box-sizing:border-box;padding:.5rem .6rem;background:#0d0d0d;border:1px solid rgba(255,255,255,.08);cursor:pointer;text-align:left;font-family:Geist,ui-sans-serif,system-ui,-apple-system,sans-serif;color:#fafafa;transition:border-color .2s,box-shadow .2s,background .2s;display:flex;flex-direction:column;overflow:hidden}.Runs_treeNodeCard__Y5XEX:hover{border-color:rgba(255,255,255,.2);background:#131313}.Runs_treeNodeSelected__QaPg2{border-color:rgba(0,212,170,.5);box-shadow:0 0 12px rgba(0,212,170,.1);background:#0b1210}.Runs_treeNodeBest__U8FaL{box-shadow:0 0 0 1px rgba(0,212,170,.3),0 0 16px rgba(0,212,170,.08)}@keyframes Runs_nodeHighlight__Zuhi5{0%{border-color:rgba(91,141,239,1);box-shadow:0 0 24px rgba(91,141,239,.4),inset 0 0 12px rgba(91,141,239,.05)}70%{border-color:rgba(91,141,239,.6);box-shadow:0 0 16px rgba(91,141,239,.2)}to{border-color:rgba(255,255,255,.08);box-shadow:none}}.Runs_treeNodeHighlight__A7a9x{animation:Runs_nodeHighlight__Zuhi5 5s ease-out forwards}.Runs_treeNodeName__XtYDH{font-size:.65rem;font-weight:400;color:#fff;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.3;margin-bottom:.15rem}.Runs_treeNodeBadgeRow__ZwAvw{display:flex;align-items:center;gap:.3rem;margin-bottom:.15rem}.Runs_treeNodeBadge__jLVIw{display:inline-block;padding:.1rem .3rem;font-size:.5rem;font-weight:500;text-transform:uppercase;letter-spacing:.5px;flex-shrink:0}.Runs_treeNodeElapsed__vsyq2{font-size:.5rem;color:var(--text-tertiary);font-feature-settings:"tnum";font-variant-numeric:tabular-nums}.Runs_treeNodeScoreRow__BN81e{margin-bottom:.25rem;min-height:1.2rem;display:flex;align-items:center}.Runs_treeNodeIssueRow__7fXg_{min-width:0;margin-top:auto}.Runs_treeNodeIssueRow__7fXg_ .Runs_linearIssueLink__aVa6L{width:100%;min-height:22px;font-size:.58rem;padding:0 .28rem}.Runs_treeNodeIssueRow__7fXg_ .Runs_linearIssueLink__aVa6L img{width:12px;height:12px}.Runs_treeNodeAccuracy__ehSVZ{font-size:1rem;font-weight:600;font-feature-settings:"tnum";font-variant-numeric:tabular-nums;color:#00d4aa;letter-spacing:-.3px}.Runs_treeNodeItems__4SRsq{font-size:.6rem;color:var(--text-tertiary);font-feature-settings:"tnum";font-variant-numeric:tabular-nums;margin-left:.3rem}.Runs_treeNodeLoading__P7_CS{display:flex;align-items:center;gap:.4rem}@keyframes Runs_pulse__LMgDF{0%,to{opacity:.3}50%{opacity:1}}.Runs_treeNodePulse__nC6rt{width:6px;height:6px;border-radius:0;background:#f5a623;animation:Runs_pulse__LMgDF 1.5s ease-in-out infinite}.Runs_treeNodeLoadingText__C1_bJ{font-size:.7rem;color:var(--text-tertiary);font-weight:400}.Runs_detailPanelHeader__XMEDA{display:flex;align-items:center;gap:.5rem;margin-bottom:1.25rem}.Runs_detailPanelTitle__vAuOY{font-size:1.3rem;font-weight:300;letter-spacing:-.3px;margin:0;color:#fff}.Leaderboard_tableWrapper__6uunR{overflow-x:auto;margin:1rem 0 0;border-radius:0;border:1px solid rgba(255,255,255,.08);background:rgba(255,255,255,.025)}.Leaderboard_table__8gTqK{width:100%;border-collapse:collapse;font-size:.8rem;font-family:Geist,ui-sans-serif,system-ui,sans-serif}.Leaderboard_noData__aKd3L{color:rgba(255,255,255,.3);font-style:italic;text-align:center;padding:2rem 0}.Leaderboard_table__8gTqK thead{background:#101010;border-bottom:1px solid rgba(255,255,255,.1);position:sticky;top:0;z-index:1}.Leaderboard_table__8gTqK th{padding:.6rem .75rem;text-align:right;color:rgba(255,255,255,.48);font-weight:600;font-size:.72rem;letter-spacing:0;white-space:nowrap;-webkit-user-select:none;user-select:none}.Leaderboard_thRank__e16FK{width:2rem;text-align:center!important}.Leaderboard_thName__i_zQZ{text-align:left!important;min-width:180px}.Leaderboard_thStatus__F4ZyW{width:2.5rem;text-align:center!important}.Leaderboard_thMetric__ZMVo_{cursor:pointer;transition:color .15s ease;min-width:5rem}.Leaderboard_thMetric__ZMVo_:hover{color:rgba(255,255,255,.8)}.Leaderboard_thPrimary__SzN76{color:rgba(255,255,255,.62)}.Leaderboard_thPrimary__SzN76:hover{color:rgba(255,255,255,.86)}.Leaderboard_thSorted__13fmP{color:rgba(255,255,255,.9)!important}.Leaderboard_thPrimary__SzN76.Leaderboard_thSorted__13fmP{color:rgba(255,255,255,.92)!important}.Leaderboard_thLabel__2cqYD{margin-right:.3rem}.Leaderboard_sortArrow__3IJre{font-size:.62rem;vertical-align:middle;opacity:.76}.Leaderboard_thItems__3MS6a{width:3rem;text-align:right}.Leaderboard_thStarted__9zNIp{width:11rem;text-align:left!important}.Leaderboard_row__A9H8t{border-bottom:1px solid rgba(255,255,255,.04);cursor:pointer;transition:background-color .15s ease;will-change:transform}.Leaderboard_row__A9H8t:hover{background:rgba(255,255,255,.04)}.Leaderboard_rowBest__JCqYu{background:rgba(255,255,255,.045)}.Leaderboard_rowBest__JCqYu:hover{background:rgba(255,255,255,.075)}.Leaderboard_rowSelected__GFyz5{background:rgba(255,255,255,.075)!important;box-shadow:inset 2px 0 0 rgba(255,255,255,.42)}.Leaderboard_table__8gTqK td{padding:.55rem .75rem;text-align:right;color:rgba(255,255,255,.78);font-feature-settings:"tnum";font-variant-numeric:tabular-nums}.Leaderboard_tdRank__kZKT_{text-align:center!important;color:rgba(255,255,255,.3);font-size:.72rem}.Leaderboard_tdName__2ymmx{text-align:left!important;display:flex;align-items:center;gap:.5rem}.Leaderboard_expName__6rkrZ{color:rgba(255,255,255,.9);font-weight:450}.Leaderboard_bestBadge__33jMs{font-size:.55rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:rgba(255,255,255,.88);background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.16);padding:.1rem .35rem;border-radius:0;flex-shrink:0}.Leaderboard_tdStatus__zRhgm{text-align:center!important}.Leaderboard_statusDot__hEPYp{display:inline-block;width:7px;height:7px;border-radius:0}.Leaderboard_tdMetric__Ll0O_{font-family:Geist Mono,ui-monospace,monospace;font-size:.8rem}.Leaderboard_tdPrimary__SZr_5{color:rgba(255,255,255,.92);font-weight:500}.Leaderboard_metricEmpty__l1hwN{color:rgba(255,255,255,.15)}.Leaderboard_tdItems__4_5Q6{color:rgba(255,255,255,.3);font-size:.72rem}.Leaderboard_tdStarted__p97S3{color:rgba(255,255,255,.45);font-size:.72rem;text-align:left!important;white-space:nowrap}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percepta/kaizen",
3
- "version": "0.5.1",
3
+ "version": "0.7.0",
4
4
  "description": "Automated AI researcher that improves AI systems",
5
5
  "keywords": [
6
6
  "ai",
@@ -14,6 +14,7 @@
14
14
  "kaizen": "./bin/kaizen.js"
15
15
  },
16
16
  "files": [
17
+ "agent",
17
18
  "bin",
18
19
  "dashboard/.next/standalone",
19
20
  "dist",
@@ -46,11 +47,13 @@
46
47
  "typecheck:dashboard": "tsc -p dashboard --noEmit",
47
48
  "test": "vitest run",
48
49
  "dev": "tsx src/index.ts",
49
- "dev:studio": "KAIZEN_WORKSPACE=examples/legacy-workspace next dev dashboard --webpack --port 6789",
50
- "dev:next": "KAIZEN_WORKSPACE=examples/legacy-workspace next dev dashboard --webpack --port 6789",
50
+ "dev:studio": "KAIZEN_DEMO_MODE=1 KAIZEN_WORKSPACE=$PWD/examples/demo-workspace next dev dashboard --webpack --port 6789",
51
+ "dev:next": "KAIZEN_DEMO_MODE=1 KAIZEN_WORKSPACE=$PWD/examples/demo-workspace next dev dashboard --webpack --port 6789",
52
+ "seed:demo-data": "node scripts/seed-demo-traces.mjs --workspace $PWD/examples/demo-workspace",
51
53
  "kaizen": "tsx src/index.ts"
52
54
  },
53
55
  "dependencies": {
56
+ "esbuild": "^0.25.0",
54
57
  "tsx": "^4.21.0",
55
58
  "yaml": "^2.8.2"
56
59
  },
@@ -0,0 +1,84 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { realpathSync } from "node:fs";
3
+ import { join, resolve } from "node:path";
4
+
5
+ export const KAIZEN_DIR = "kaizen";
6
+ export const KAIZEN_CONFIG = "config.ts";
7
+ export const KAIZEN_STATE_DIR = ".kaizen";
8
+ export const KAIZEN_SYSTEMS_DIR = "systems";
9
+
10
+ export function kaizenDir(workspaceRoot) {
11
+ return join(workspaceRoot, KAIZEN_DIR);
12
+ }
13
+
14
+ export function kaizenConfigPath(workspaceRoot) {
15
+ return join(kaizenDir(workspaceRoot), KAIZEN_CONFIG);
16
+ }
17
+
18
+ export function kaizenSystemsDir(workspaceRoot) {
19
+ return join(kaizenDir(workspaceRoot), KAIZEN_SYSTEMS_DIR);
20
+ }
21
+
22
+ export function kaizenSystemDir(workspaceRoot, systemId) {
23
+ return join(kaizenSystemsDir(workspaceRoot), systemId);
24
+ }
25
+
26
+ export function kaizenSystemPath(workspaceRoot, systemId) {
27
+ return join(kaizenSystemDir(workspaceRoot, systemId), "system.md");
28
+ }
29
+
30
+ export function defaultKaizenStateDir(workspaceRoot) {
31
+ return join(primaryWorktreeRoot(workspaceRoot), KAIZEN_DIR, KAIZEN_STATE_DIR);
32
+ }
33
+
34
+ export function resolveKaizenStateDir(workspaceRoot) {
35
+ const raw = process.env.KAIZEN_STATE_DIR;
36
+ return raw
37
+ ? resolve(workspaceRoot, raw)
38
+ : defaultKaizenStateDir(workspaceRoot);
39
+ }
40
+
41
+ export function primaryWorktreeRoot(workspaceRoot) {
42
+ const normalizedWorkspace = canonicalPath(workspaceRoot);
43
+ const gitRoot = gitTopLevel(normalizedWorkspace);
44
+ if (!gitRoot || canonicalPath(gitRoot) !== normalizedWorkspace) {
45
+ return normalizedWorkspace;
46
+ }
47
+
48
+ try {
49
+ const out = execFileSync(
50
+ "git",
51
+ ["-C", normalizedWorkspace, "worktree", "list", "--porcelain"],
52
+ { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] },
53
+ );
54
+ const first = out.split("\n").find((line) => line.startsWith("worktree "));
55
+ return first
56
+ ? canonicalPath(first.slice("worktree ".length))
57
+ : normalizedWorkspace;
58
+ } catch {
59
+ return normalizedWorkspace;
60
+ }
61
+ }
62
+
63
+ function gitTopLevel(workspaceRoot) {
64
+ try {
65
+ return execFileSync(
66
+ "git",
67
+ ["-C", workspaceRoot, "rev-parse", "--show-toplevel"],
68
+ {
69
+ encoding: "utf-8",
70
+ stdio: ["ignore", "pipe", "ignore"],
71
+ },
72
+ ).trim();
73
+ } catch {
74
+ return null;
75
+ }
76
+ }
77
+
78
+ function canonicalPath(path) {
79
+ try {
80
+ return realpathSync(path);
81
+ } catch {
82
+ return resolve(path);
83
+ }
84
+ }
@@ -0,0 +1,58 @@
1
+ import { kaizenSystemDir, kaizenSystemPath } from "../shared/workspace-paths.js";
2
+ import { templatesDir, workspaceRoot } from "../lib/paths.js";
3
+ import { isSystemId, requireKaizenWorkspace } from "../lib/cli.js";
4
+ import { applyVars, ensureDir, writeFileSafely } from "../lib/fs-utils.js";
5
+ import { boolFlag, parseFlags, strFlag } from "../lib/parse-args.js";
6
+ import { existsSync, readFileSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ //#region src/commands/create-view.ts
9
+ const VIEW_TYPES = ["trace", "dataset-item"];
10
+ async function runCreateView(argv) {
11
+ const { positional, flags } = parseFlags(argv);
12
+ const root = workspaceRoot();
13
+ const force = boolFlag(flags, "force");
14
+ if (!requireKaizenWorkspace(root)) return 1;
15
+ const systemId = strFlag(flags, "system") ?? positional[0];
16
+ if (!systemId || !isSystemId(systemId)) {
17
+ process.stderr.write(`invalid system name: "${systemId ?? ""}". use kebab-case (e.g. cost-savings).\n`);
18
+ return 1;
19
+ }
20
+ if (!existsSync(kaizenSystemPath(root, systemId))) {
21
+ process.stderr.write(`system "${systemId}" not found at kaizen/systems/${systemId}/system.md.\nrun \`kaizen create system ${systemId}\` first.\n`);
22
+ return 1;
23
+ }
24
+ const typeFlag = strFlag(flags, "type");
25
+ if (!typeFlag) {
26
+ process.stderr.write(`kaizen create view: --type <${VIEW_TYPES.join("|")}> is required.\n`);
27
+ return 1;
28
+ }
29
+ const type = normalizeType(typeFlag);
30
+ if (!type) {
31
+ process.stderr.write(`invalid view type. use one of: ${VIEW_TYPES.join(", ")}.\n`);
32
+ return 1;
33
+ }
34
+ const dir = kaizenSystemDir(root, systemId);
35
+ const viewPath = join(dir, `${type}.tsx`);
36
+ if (existsSync(viewPath) && !force) {
37
+ process.stderr.write(`refusing to overwrite ${viewPath}. pass --force to replace.\n`);
38
+ return 1;
39
+ }
40
+ ensureDir(dir);
41
+ writeFileSafely(viewPath, applyVars(readFileSync(join(templatesDir(), "view", `${type}.tsx`), "utf-8"), { system_id: systemId }), { overwrite: force });
42
+ process.stdout.write(`scaffolded ${type} view for "${systemId}":\n`);
43
+ process.stdout.write(` kaizen/systems/${systemId}/${type}.tsx\n`);
44
+ process.stdout.write([
45
+ "",
46
+ "Kaizen Studio loads this file by convention beside system.md.",
47
+ "Refresh the browser or focus the Studio window after edits to reload the view.",
48
+ ""
49
+ ].join("\n"));
50
+ return 0;
51
+ }
52
+ function normalizeType(value) {
53
+ return VIEW_TYPES.includes(value) ? value : null;
54
+ }
55
+ //#endregion
56
+ export { runCreateView };
57
+
58
+ //# sourceMappingURL=create-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-view.js","names":[],"sources":["../../src/commands/create-view.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { isSystemId, requireKaizenWorkspace } from \"../lib/cli.js\";\nimport { applyVars, ensureDir, writeFileSafely } from \"../lib/fs-utils.js\";\nimport { boolFlag, parseFlags, strFlag } from \"../lib/parse-args.js\";\nimport {\n kaizenSystemDir,\n kaizenSystemPath,\n templatesDir,\n workspaceRoot,\n} from \"../lib/paths.js\";\n\nconst VIEW_TYPES = [\"trace\", \"dataset-item\"] as const;\ntype ViewType = (typeof VIEW_TYPES)[number];\n\nexport async function runCreateView(argv: string[]): Promise<number> {\n const { positional, flags } = parseFlags(argv);\n const root = workspaceRoot();\n const force = boolFlag(flags, \"force\");\n\n if (!requireKaizenWorkspace(root)) return 1;\n\n const systemId = strFlag(flags, \"system\") ?? positional[0];\n if (!systemId || !isSystemId(systemId)) {\n process.stderr.write(\n `invalid system name: \"${systemId ?? \"\"}\". use kebab-case (e.g. cost-savings).\\n`,\n );\n return 1;\n }\n\n const systemPath = kaizenSystemPath(root, systemId);\n if (!existsSync(systemPath)) {\n process.stderr.write(\n `system \"${systemId}\" not found at kaizen/systems/${systemId}/system.md.\\n` +\n `run \\`kaizen create system ${systemId}\\` first.\\n`,\n );\n return 1;\n }\n\n const typeFlag = strFlag(flags, \"type\");\n if (!typeFlag) {\n process.stderr.write(\n `kaizen create view: --type <${VIEW_TYPES.join(\"|\")}> is required.\\n`,\n );\n return 1;\n }\n const type = normalizeType(typeFlag);\n if (!type) {\n process.stderr.write(\n `invalid view type. use one of: ${VIEW_TYPES.join(\", \")}.\\n`,\n );\n return 1;\n }\n\n const dir = kaizenSystemDir(root, systemId);\n const viewPath = join(dir, `${type}.tsx`);\n if (existsSync(viewPath) && !force) {\n process.stderr.write(\n `refusing to overwrite ${viewPath}. pass --force to replace.\\n`,\n );\n return 1;\n }\n\n ensureDir(dir);\n const templatePath = join(templatesDir(), \"view\", `${type}.tsx`);\n const template = readFileSync(templatePath, \"utf-8\");\n writeFileSafely(viewPath, applyVars(template, { system_id: systemId }), {\n overwrite: force,\n });\n\n process.stdout.write(`scaffolded ${type} view for \"${systemId}\":\\n`);\n process.stdout.write(` kaizen/systems/${systemId}/${type}.tsx\\n`);\n process.stdout.write(\n [\n \"\",\n \"Kaizen Studio loads this file by convention beside system.md.\",\n \"Refresh the browser or focus the Studio window after edits to reload the view.\",\n \"\",\n ].join(\"\\n\"),\n );\n\n return 0;\n}\n\nfunction normalizeType(value: string): ViewType | null {\n return (VIEW_TYPES as readonly string[]).includes(value)\n ? (value as ViewType)\n : null;\n}\n"],"mappings":";;;;;;;;AAYA,MAAM,aAAa,CAAC,SAAS,eAAe;AAG5C,eAAsB,cAAc,MAAiC;CACnE,MAAM,EAAE,YAAY,UAAU,WAAW,KAAK;CAC9C,MAAM,OAAO,eAAe;CAC5B,MAAM,QAAQ,SAAS,OAAO,QAAQ;AAEtC,KAAI,CAAC,uBAAuB,KAAK,CAAE,QAAO;CAE1C,MAAM,WAAW,QAAQ,OAAO,SAAS,IAAI,WAAW;AACxD,KAAI,CAAC,YAAY,CAAC,WAAW,SAAS,EAAE;AACtC,UAAQ,OAAO,MACb,yBAAyB,YAAY,GAAG,0CACzC;AACD,SAAO;;AAIT,KAAI,CAAC,WADc,iBAAiB,MAAM,SAChB,CAAC,EAAE;AAC3B,UAAQ,OAAO,MACb,WAAW,SAAS,gCAAgC,SAAS,0CAC7B,SAAS,aAC1C;AACD,SAAO;;CAGT,MAAM,WAAW,QAAQ,OAAO,OAAO;AACvC,KAAI,CAAC,UAAU;AACb,UAAQ,OAAO,MACb,+BAA+B,WAAW,KAAK,IAAI,CAAC,kBACrD;AACD,SAAO;;CAET,MAAM,OAAO,cAAc,SAAS;AACpC,KAAI,CAAC,MAAM;AACT,UAAQ,OAAO,MACb,kCAAkC,WAAW,KAAK,KAAK,CAAC,KACzD;AACD,SAAO;;CAGT,MAAM,MAAM,gBAAgB,MAAM,SAAS;CAC3C,MAAM,WAAW,KAAK,KAAK,GAAG,KAAK,MAAM;AACzC,KAAI,WAAW,SAAS,IAAI,CAAC,OAAO;AAClC,UAAQ,OAAO,MACb,yBAAyB,SAAS,8BACnC;AACD,SAAO;;AAGT,WAAU,IAAI;AAGd,iBAAgB,UAAU,UADT,aADI,KAAK,cAAc,EAAE,QAAQ,GAAG,KAAK,MAChB,EAAE,QACA,EAAE,EAAE,WAAW,UAAU,CAAC,EAAE,EACtE,WAAW,OACZ,CAAC;AAEF,SAAQ,OAAO,MAAM,cAAc,KAAK,aAAa,SAAS,MAAM;AACpE,SAAQ,OAAO,MAAM,oBAAoB,SAAS,GAAG,KAAK,QAAQ;AAClE,SAAQ,OAAO,MACb;EACE;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK,CACb;AAED,QAAO;;AAGT,SAAS,cAAc,OAAgC;AACrD,QAAQ,WAAiC,SAAS,MAAM,GACnD,QACD"}
@@ -0,0 +1,66 @@
1
+ import { packageRoot } from "../lib/paths.js";
2
+ import { readFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ //#region src/commands/guide.ts
5
+ const TOPICS = {
6
+ overview: {
7
+ file: "overview.md",
8
+ description: "canonical agent workflow, commands, files, evals, and views"
9
+ },
10
+ evals: {
11
+ file: "evals.md",
12
+ description: "eval script invocation, NDJSON events, and baseline runs"
13
+ },
14
+ views: {
15
+ file: "views.md",
16
+ description: "custom trace and dataset item view paths, props, and actions"
17
+ },
18
+ "claude-command": {
19
+ file: "claude-command.md",
20
+ description: "Claude Code slash-command instructions"
21
+ },
22
+ "variant-builder": {
23
+ file: "variant-builder.md",
24
+ description: "single-variant worktree agent instructions"
25
+ }
26
+ };
27
+ function runGuide(argv) {
28
+ const [rawTopic] = argv.filter((arg) => !arg.startsWith("-"));
29
+ const topic = rawTopic ?? "overview";
30
+ if (topic === "topics" || topic === "list") {
31
+ process.stdout.write(renderTopicList());
32
+ return 0;
33
+ }
34
+ if (topic === "all") {
35
+ process.stdout.write(Object.keys(TOPICS).map((name) => readGuide(name)).join("\n\n---\n\n"));
36
+ process.stdout.write("\n");
37
+ return 0;
38
+ }
39
+ if (!isGuideTopic(topic)) {
40
+ process.stderr.write(`unknown guide topic: ${topic}\n\n${renderTopicList()}`);
41
+ return 1;
42
+ }
43
+ process.stdout.write(readGuide(topic));
44
+ process.stdout.write("\n");
45
+ return 0;
46
+ }
47
+ function readGuide(topic) {
48
+ const guide = TOPICS[topic];
49
+ return readFileSync(join(packageRoot(), "agent", guide.file), "utf-8");
50
+ }
51
+ function isGuideTopic(topic) {
52
+ return Object.prototype.hasOwnProperty.call(TOPICS, topic);
53
+ }
54
+ function renderTopicList() {
55
+ return [
56
+ "kaizen guide topics:",
57
+ "",
58
+ ...Object.entries(TOPICS).map(([name, guide]) => ` ${name.padEnd(15)} ${guide.description}`),
59
+ " all print every guide topic",
60
+ ""
61
+ ].join("\n");
62
+ }
63
+ //#endregion
64
+ export { runGuide };
65
+
66
+ //# sourceMappingURL=guide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guide.js","names":[],"sources":["../../src/commands/guide.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { packageRoot } from \"../lib/paths.js\";\n\ninterface GuideTopic {\n file: string;\n description: string;\n}\n\nconst TOPICS: Record<string, GuideTopic> = {\n overview: {\n file: \"overview.md\",\n description: \"canonical agent workflow, commands, files, evals, and views\",\n },\n evals: {\n file: \"evals.md\",\n description: \"eval script invocation, NDJSON events, and baseline runs\",\n },\n views: {\n file: \"views.md\",\n description: \"custom trace and dataset item view paths, props, and actions\",\n },\n \"claude-command\": {\n file: \"claude-command.md\",\n description: \"Claude Code slash-command instructions\",\n },\n \"variant-builder\": {\n file: \"variant-builder.md\",\n description: \"single-variant worktree agent instructions\",\n },\n};\n\nexport function runGuide(argv: string[]): number {\n const [rawTopic] = argv.filter((arg) => !arg.startsWith(\"-\"));\n const topic = rawTopic ?? \"overview\";\n\n if (topic === \"topics\" || topic === \"list\") {\n process.stdout.write(renderTopicList());\n return 0;\n }\n\n if (topic === \"all\") {\n process.stdout.write(\n Object.keys(TOPICS)\n .map((name) => readGuide(name))\n .join(\"\\n\\n---\\n\\n\"),\n );\n process.stdout.write(\"\\n\");\n return 0;\n }\n\n if (!isGuideTopic(topic)) {\n process.stderr.write(\n `unknown guide topic: ${topic}\\n\\n${renderTopicList()}`,\n );\n return 1;\n }\n\n process.stdout.write(readGuide(topic));\n process.stdout.write(\"\\n\");\n return 0;\n}\n\nfunction readGuide(topic: string): string {\n const guide = TOPICS[topic];\n return readFileSync(join(packageRoot(), \"agent\", guide.file), \"utf-8\");\n}\n\nfunction isGuideTopic(topic: string): boolean {\n return Object.prototype.hasOwnProperty.call(TOPICS, topic);\n}\n\nfunction renderTopicList(): string {\n return [\n \"kaizen guide topics:\",\n \"\",\n ...Object.entries(TOPICS).map(\n ([name, guide]) => ` ${name.padEnd(15)} ${guide.description}`,\n ),\n \" all print every guide topic\",\n \"\",\n ].join(\"\\n\");\n}\n"],"mappings":";;;;AASA,MAAM,SAAqC;CACzC,UAAU;EACR,MAAM;EACN,aAAa;EACd;CACD,OAAO;EACL,MAAM;EACN,aAAa;EACd;CACD,OAAO;EACL,MAAM;EACN,aAAa;EACd;CACD,kBAAkB;EAChB,MAAM;EACN,aAAa;EACd;CACD,mBAAmB;EACjB,MAAM;EACN,aAAa;EACd;CACF;AAED,SAAgB,SAAS,MAAwB;CAC/C,MAAM,CAAC,YAAY,KAAK,QAAQ,QAAQ,CAAC,IAAI,WAAW,IAAI,CAAC;CAC7D,MAAM,QAAQ,YAAY;AAE1B,KAAI,UAAU,YAAY,UAAU,QAAQ;AAC1C,UAAQ,OAAO,MAAM,iBAAiB,CAAC;AACvC,SAAO;;AAGT,KAAI,UAAU,OAAO;AACnB,UAAQ,OAAO,MACb,OAAO,KAAK,OAAO,CAChB,KAAK,SAAS,UAAU,KAAK,CAAC,CAC9B,KAAK,cAAc,CACvB;AACD,UAAQ,OAAO,MAAM,KAAK;AAC1B,SAAO;;AAGT,KAAI,CAAC,aAAa,MAAM,EAAE;AACxB,UAAQ,OAAO,MACb,wBAAwB,MAAM,MAAM,iBAAiB,GACtD;AACD,SAAO;;AAGT,SAAQ,OAAO,MAAM,UAAU,MAAM,CAAC;AACtC,SAAQ,OAAO,MAAM,KAAK;AAC1B,QAAO;;AAGT,SAAS,UAAU,OAAuB;CACxC,MAAM,QAAQ,OAAO;AACrB,QAAO,aAAa,KAAK,aAAa,EAAE,SAAS,MAAM,KAAK,EAAE,QAAQ;;AAGxE,SAAS,aAAa,OAAwB;AAC5C,QAAO,OAAO,UAAU,eAAe,KAAK,QAAQ,MAAM;;AAG5D,SAAS,kBAA0B;AACjC,QAAO;EACL;EACA;EACA,GAAG,OAAO,QAAQ,OAAO,CAAC,KACvB,CAAC,MAAM,WAAW,KAAK,KAAK,OAAO,GAAG,CAAC,GAAG,MAAM,cAClD;EACD;EACA;EACD,CAAC,KAAK,KAAK"}
@@ -1,8 +1,8 @@
1
- import { ISSUE_QUERY, KAIZEN_LINEAR_LABEL, buildIssueFilter, linearHttpMessage, linearProjectRefFromFields, parseLinearBody, resolveLinearEnv, resolveLinearProject } from "../shared/linear-ideas.js";
2
- import { readEnvFile } from "../shared/env-file.js";
3
- import "../lib/env.js";
4
- import { boolFlag, parseFlags, strFlag } from "../lib/parse-args.js";
5
1
  import { workspaceRoot } from "../lib/paths.js";
2
+ import { pad } from "../lib/cli.js";
3
+ import { boolFlag, parseFlags, strFlag } from "../lib/parse-args.js";
4
+ import { readEnvFile } from "../shared/env-file.js";
5
+ import { ISSUE_QUERY, KAIZEN_LINEAR_LABEL, buildIssueFilter, linearHttpMessage, linearProjectRefFromFields, parseLinearBody, resolveLinearEnv, resolveLinearProject } from "../shared/linear-ideas.js";
6
6
  import { loadSystem } from "../lib/system.js";
7
7
  import { join } from "node:path";
8
8
  //#region src/commands/ideas.ts
@@ -127,10 +127,6 @@ function formatDate(value) {
127
127
  if (Number.isNaN(date.getTime())) return value.slice(0, 10);
128
128
  return date.toISOString().slice(0, 10);
129
129
  }
130
- function pad(s, w) {
131
- if (s.length >= w) return s.slice(0, w - 1) + " ";
132
- return s + " ".repeat(w - s.length);
133
- }
134
130
  //#endregion
135
131
  export { runIdeas };
136
132
 
@@ -1 +1 @@
1
- {"version":3,"file":"ideas.js","names":[],"sources":["../../src/commands/ideas.ts"],"sourcesContent":["import { join } from \"node:path\";\nimport {\n buildIssueFilter,\n ISSUE_QUERY,\n KAIZEN_LINEAR_LABEL,\n linearProjectRefFromFields,\n linearHttpMessage,\n parseLinearBody,\n resolveLinearEnv,\n resolveLinearProject,\n type LinearIdea,\n type LinearProject,\n type LinearProjectRef,\n} from \"../../shared/linear-ideas.js\";\nimport { readEnvFile } from \"../lib/env.js\";\nimport { boolFlag, parseFlags, strFlag } from \"../lib/parse-args.js\";\nimport { workspaceRoot } from \"../lib/paths.js\";\nimport { loadSystem } from \"../lib/system.js\";\n\nexport async function runIdeas(argv: string[]): Promise<number> {\n const { flags } = parseFlags(argv);\n const root = workspaceRoot();\n const systemId = strFlag(flags, \"system\");\n const json = boolFlag(flags, \"json\");\n const limit = parseLimit(strFlag(flags, \"limit\") ?? strFlag(flags, \"n\"));\n\n if (!systemId) {\n process.stderr.write(\"kaizen ideas: --system <id> is required\\n\");\n return 1;\n }\n if (limit === null) {\n process.stderr.write(\"kaizen ideas: --limit must be a positive integer\\n\");\n return 1;\n }\n\n const system = loadSystem(root, systemId);\n const projectRef = linearProjectRefFromFields({\n project: stringFrontmatter(system.frontmatter.linear_project),\n projectId: stringFrontmatter(system.frontmatter.linear_project_id),\n projectUrl: stringFrontmatter(system.frontmatter.linear_project_url),\n });\n if (!projectRef) {\n process.stderr.write(\n `kaizen ideas: system \"${systemId}\" is missing linear_project in frontmatter.\\n` +\n \"Add the Linear project URL or project ID to scope ideas for this system.\\n\",\n );\n return 1;\n }\n\n const envPath = join(root, \".env.local\");\n const linearEnv = resolveLinearEnv(readEnvFile(envPath), {});\n const token = linearEnv.apiKey;\n if (!token) {\n process.stderr.write(\n `kaizen ideas: LINEAR_API_KEY is missing. Add it to ${envPath}.\\n`,\n );\n return 1;\n }\n\n const config = {\n system: systemId,\n projectRef,\n team:\n stringFrontmatter(system.frontmatter.linear_team) ?? linearEnv.teamKey,\n label: KAIZEN_LINEAR_LABEL,\n limit,\n };\n\n const { project, ideas } = await fetchLinearIdeas(token, config);\n const outputConfig = {\n ...config,\n project,\n };\n\n if (json) {\n process.stdout.write(\n JSON.stringify({ config: outputConfig, ideas }, null, 2) + \"\\n\",\n );\n return 0;\n }\n\n printIdeas(outputConfig, ideas);\n return 0;\n}\n\nfunction parseLimit(raw: string | undefined): number | null {\n if (!raw) return 50;\n const n = Number(raw);\n return Number.isInteger(n) && n > 0 ? n : null;\n}\n\nasync function fetchLinearIdeas(\n token: string,\n config: {\n projectRef: LinearProjectRef;\n team: string | null;\n label: string;\n limit: number;\n },\n): Promise<{ project: LinearProject; ideas: LinearIdea[] }> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n try {\n const project = await resolveLinearProject(\n token,\n config.projectRef,\n controller.signal,\n );\n if (!project) {\n throw new Error(\n `Linear project ${config.projectRef.value} was not found`,\n );\n }\n\n const res = await fetch(\"https://api.linear.app/graphql\", {\n method: \"POST\",\n headers: {\n Authorization: token,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n query: ISSUE_QUERY,\n variables: {\n first: config.limit,\n filter: buildIssueFilter({\n projectId: project.id,\n teamKey: config.team,\n label: config.label,\n }),\n },\n }),\n signal: controller.signal,\n });\n\n const text = await res.text();\n const body = parseLinearBody(text);\n if (!res.ok || body.errors?.length) {\n throw new Error(linearHttpMessage(res, body.errors));\n }\n return { project, ideas: body.data?.issues?.nodes ?? [] };\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction printIdeas(\n config: {\n system: string;\n project: LinearProject;\n team: string | null;\n label: string;\n },\n ideas: LinearIdea[],\n): void {\n process.stdout.write(\n `system: ${config.system} project: ${config.project.name} label: ${config.label}\\n`,\n );\n if (config.team) process.stdout.write(`team: ${config.team}\\n`);\n if (ideas.length === 0) {\n process.stdout.write(\"no ideas found.\\n\");\n return;\n }\n\n process.stdout.write(\"\\n\");\n process.stdout.write(\n pad(\"issue\", 12) +\n pad(\"priority\", 10) +\n pad(\"status\", 18) +\n pad(\"assignee\", 18) +\n pad(\"updated\", 13) +\n \"title\\n\",\n );\n for (const idea of ideas) {\n process.stdout.write(\n pad(idea.identifier, 12) +\n pad(priorityLabel(idea.priority), 10) +\n pad(idea.state?.name ?? \"No status\", 18) +\n pad(idea.assignee?.name ?? \"Unassigned\", 18) +\n pad(formatDate(idea.updatedAt), 13) +\n idea.title +\n \"\\n\",\n );\n }\n process.stdout.write(\n \"\\nUse `kaizen ideas --system \" +\n config.system +\n \" --json` for URLs and full issue details.\\n\",\n );\n}\n\nfunction stringFrontmatter(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() ? value.trim() : null;\n}\n\nfunction priorityLabel(priority: number): string {\n if (priority === 1) return \"Urgent\";\n if (priority === 2) return \"High\";\n if (priority === 3) return \"Normal\";\n if (priority === 4) return \"Low\";\n return \"None\";\n}\n\nfunction formatDate(value: string): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value.slice(0, 10);\n return date.toISOString().slice(0, 10);\n}\n\nfunction pad(s: string, w: number): string {\n if (s.length >= w) return s.slice(0, w - 1) + \" \";\n return s + \" \".repeat(w - s.length);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ideas.js","names":[],"sources":["../../src/commands/ideas.ts"],"sourcesContent":["import { join } from \"node:path\";\nimport { readEnvFile } from \"../../shared/env-file.js\";\nimport {\n buildIssueFilter,\n ISSUE_QUERY,\n KAIZEN_LINEAR_LABEL,\n linearProjectRefFromFields,\n linearHttpMessage,\n parseLinearBody,\n resolveLinearEnv,\n resolveLinearProject,\n type LinearIdea,\n type LinearProject,\n type LinearProjectRef,\n} from \"../../shared/linear-ideas.js\";\nimport { pad } from \"../lib/cli.js\";\nimport { boolFlag, parseFlags, strFlag } from \"../lib/parse-args.js\";\nimport { workspaceRoot } from \"../lib/paths.js\";\nimport { loadSystem } from \"../lib/system.js\";\n\nexport async function runIdeas(argv: string[]): Promise<number> {\n const { flags } = parseFlags(argv);\n const root = workspaceRoot();\n const systemId = strFlag(flags, \"system\");\n const json = boolFlag(flags, \"json\");\n const limit = parseLimit(strFlag(flags, \"limit\") ?? strFlag(flags, \"n\"));\n\n if (!systemId) {\n process.stderr.write(\"kaizen ideas: --system <id> is required\\n\");\n return 1;\n }\n if (limit === null) {\n process.stderr.write(\"kaizen ideas: --limit must be a positive integer\\n\");\n return 1;\n }\n\n const system = loadSystem(root, systemId);\n const projectRef = linearProjectRefFromFields({\n project: stringFrontmatter(system.frontmatter.linear_project),\n projectId: stringFrontmatter(system.frontmatter.linear_project_id),\n projectUrl: stringFrontmatter(system.frontmatter.linear_project_url),\n });\n if (!projectRef) {\n process.stderr.write(\n `kaizen ideas: system \"${systemId}\" is missing linear_project in frontmatter.\\n` +\n \"Add the Linear project URL or project ID to scope ideas for this system.\\n\",\n );\n return 1;\n }\n\n const envPath = join(root, \".env.local\");\n const linearEnv = resolveLinearEnv(readEnvFile(envPath), {});\n const token = linearEnv.apiKey;\n if (!token) {\n process.stderr.write(\n `kaizen ideas: LINEAR_API_KEY is missing. Add it to ${envPath}.\\n`,\n );\n return 1;\n }\n\n const config = {\n system: systemId,\n projectRef,\n team:\n stringFrontmatter(system.frontmatter.linear_team) ?? linearEnv.teamKey,\n label: KAIZEN_LINEAR_LABEL,\n limit,\n };\n\n const { project, ideas } = await fetchLinearIdeas(token, config);\n const outputConfig = {\n ...config,\n project,\n };\n\n if (json) {\n process.stdout.write(\n JSON.stringify({ config: outputConfig, ideas }, null, 2) + \"\\n\",\n );\n return 0;\n }\n\n printIdeas(outputConfig, ideas);\n return 0;\n}\n\nfunction parseLimit(raw: string | undefined): number | null {\n if (!raw) return 50;\n const n = Number(raw);\n return Number.isInteger(n) && n > 0 ? n : null;\n}\n\nasync function fetchLinearIdeas(\n token: string,\n config: {\n projectRef: LinearProjectRef;\n team: string | null;\n label: string;\n limit: number;\n },\n): Promise<{ project: LinearProject; ideas: LinearIdea[] }> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n try {\n const project = await resolveLinearProject(\n token,\n config.projectRef,\n controller.signal,\n );\n if (!project) {\n throw new Error(\n `Linear project ${config.projectRef.value} was not found`,\n );\n }\n\n const res = await fetch(\"https://api.linear.app/graphql\", {\n method: \"POST\",\n headers: {\n Authorization: token,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n query: ISSUE_QUERY,\n variables: {\n first: config.limit,\n filter: buildIssueFilter({\n projectId: project.id,\n teamKey: config.team,\n label: config.label,\n }),\n },\n }),\n signal: controller.signal,\n });\n\n const text = await res.text();\n const body = parseLinearBody(text);\n if (!res.ok || body.errors?.length) {\n throw new Error(linearHttpMessage(res, body.errors));\n }\n return { project, ideas: body.data?.issues?.nodes ?? [] };\n } finally {\n clearTimeout(timeout);\n }\n}\n\nfunction printIdeas(\n config: {\n system: string;\n project: LinearProject;\n team: string | null;\n label: string;\n },\n ideas: LinearIdea[],\n): void {\n process.stdout.write(\n `system: ${config.system} project: ${config.project.name} label: ${config.label}\\n`,\n );\n if (config.team) process.stdout.write(`team: ${config.team}\\n`);\n if (ideas.length === 0) {\n process.stdout.write(\"no ideas found.\\n\");\n return;\n }\n\n process.stdout.write(\"\\n\");\n process.stdout.write(\n pad(\"issue\", 12) +\n pad(\"priority\", 10) +\n pad(\"status\", 18) +\n pad(\"assignee\", 18) +\n pad(\"updated\", 13) +\n \"title\\n\",\n );\n for (const idea of ideas) {\n process.stdout.write(\n pad(idea.identifier, 12) +\n pad(priorityLabel(idea.priority), 10) +\n pad(idea.state?.name ?? \"No status\", 18) +\n pad(idea.assignee?.name ?? \"Unassigned\", 18) +\n pad(formatDate(idea.updatedAt), 13) +\n idea.title +\n \"\\n\",\n );\n }\n process.stdout.write(\n \"\\nUse `kaizen ideas --system \" +\n config.system +\n \" --json` for URLs and full issue details.\\n\",\n );\n}\n\nfunction stringFrontmatter(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() ? value.trim() : null;\n}\n\nfunction priorityLabel(priority: number): string {\n if (priority === 1) return \"Urgent\";\n if (priority === 2) return \"High\";\n if (priority === 3) return \"Normal\";\n if (priority === 4) return \"Low\";\n return \"None\";\n}\n\nfunction formatDate(value: string): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value.slice(0, 10);\n return date.toISOString().slice(0, 10);\n}\n"],"mappings":";;;;;;;;AAoBA,eAAsB,SAAS,MAAiC;CAC9D,MAAM,EAAE,UAAU,WAAW,KAAK;CAClC,MAAM,OAAO,eAAe;CAC5B,MAAM,WAAW,QAAQ,OAAO,SAAS;CACzC,MAAM,OAAO,SAAS,OAAO,OAAO;CACpC,MAAM,QAAQ,WAAW,QAAQ,OAAO,QAAQ,IAAI,QAAQ,OAAO,IAAI,CAAC;AAExE,KAAI,CAAC,UAAU;AACb,UAAQ,OAAO,MAAM,4CAA4C;AACjE,SAAO;;AAET,KAAI,UAAU,MAAM;AAClB,UAAQ,OAAO,MAAM,qDAAqD;AAC1E,SAAO;;CAGT,MAAM,SAAS,WAAW,MAAM,SAAS;CACzC,MAAM,aAAa,2BAA2B;EAC5C,SAAS,kBAAkB,OAAO,YAAY,eAAe;EAC7D,WAAW,kBAAkB,OAAO,YAAY,kBAAkB;EAClE,YAAY,kBAAkB,OAAO,YAAY,mBAAmB;EACrE,CAAC;AACF,KAAI,CAAC,YAAY;AACf,UAAQ,OAAO,MACb,yBAAyB,SAAS;EAEnC;AACD,SAAO;;CAGT,MAAM,UAAU,KAAK,MAAM,aAAa;CACxC,MAAM,YAAY,iBAAiB,YAAY,QAAQ,EAAE,EAAE,CAAC;CAC5D,MAAM,QAAQ,UAAU;AACxB,KAAI,CAAC,OAAO;AACV,UAAQ,OAAO,MACb,sDAAsD,QAAQ,KAC/D;AACD,SAAO;;CAGT,MAAM,SAAS;EACb,QAAQ;EACR;EACA,MACE,kBAAkB,OAAO,YAAY,YAAY,IAAI,UAAU;EACjE,OAAO;EACP;EACD;CAED,MAAM,EAAE,SAAS,UAAU,MAAM,iBAAiB,OAAO,OAAO;CAChE,MAAM,eAAe;EACnB,GAAG;EACH;EACD;AAED,KAAI,MAAM;AACR,UAAQ,OAAO,MACb,KAAK,UAAU;GAAE,QAAQ;GAAc;GAAO,EAAE,MAAM,EAAE,GAAG,KAC5D;AACD,SAAO;;AAGT,YAAW,cAAc,MAAM;AAC/B,QAAO;;AAGT,SAAS,WAAW,KAAwC;AAC1D,KAAI,CAAC,IAAK,QAAO;CACjB,MAAM,IAAI,OAAO,IAAI;AACrB,QAAO,OAAO,UAAU,EAAE,IAAI,IAAI,IAAI,IAAI;;AAG5C,eAAe,iBACb,OACA,QAM0D;CAC1D,MAAM,aAAa,IAAI,iBAAiB;CACxC,MAAM,UAAU,iBAAiB,WAAW,OAAO,EAAE,IAAO;AAC5D,KAAI;EACF,MAAM,UAAU,MAAM,qBACpB,OACA,OAAO,YACP,WAAW,OACZ;AACD,MAAI,CAAC,QACH,OAAM,IAAI,MACR,kBAAkB,OAAO,WAAW,MAAM,gBAC3C;EAGH,MAAM,MAAM,MAAM,MAAM,kCAAkC;GACxD,QAAQ;GACR,SAAS;IACP,eAAe;IACf,gBAAgB;IACjB;GACD,MAAM,KAAK,UAAU;IACnB,OAAO;IACP,WAAW;KACT,OAAO,OAAO;KACd,QAAQ,iBAAiB;MACvB,WAAW,QAAQ;MACnB,SAAS,OAAO;MAChB,OAAO,OAAO;MACf,CAAC;KACH;IACF,CAAC;GACF,QAAQ,WAAW;GACpB,CAAC;EAGF,MAAM,OAAO,gBAAgB,MADV,IAAI,MAAM,CACK;AAClC,MAAI,CAAC,IAAI,MAAM,KAAK,QAAQ,OAC1B,OAAM,IAAI,MAAM,kBAAkB,KAAK,KAAK,OAAO,CAAC;AAEtD,SAAO;GAAE;GAAS,OAAO,KAAK,MAAM,QAAQ,SAAS,EAAE;GAAE;WACjD;AACR,eAAa,QAAQ;;;AAIzB,SAAS,WACP,QAMA,OACM;AACN,SAAQ,OAAO,MACb,WAAW,OAAO,OAAO,cAAc,OAAO,QAAQ,KAAK,YAAY,OAAO,MAAM,IACrF;AACD,KAAI,OAAO,KAAM,SAAQ,OAAO,MAAM,SAAS,OAAO,KAAK,IAAI;AAC/D,KAAI,MAAM,WAAW,GAAG;AACtB,UAAQ,OAAO,MAAM,oBAAoB;AACzC;;AAGF,SAAQ,OAAO,MAAM,KAAK;AAC1B,SAAQ,OAAO,MACb,IAAI,SAAS,GAAG,GACd,IAAI,YAAY,GAAG,GACnB,IAAI,UAAU,GAAG,GACjB,IAAI,YAAY,GAAG,GACnB,IAAI,WAAW,GAAG,GAClB,UACH;AACD,MAAK,MAAM,QAAQ,MACjB,SAAQ,OAAO,MACb,IAAI,KAAK,YAAY,GAAG,GACtB,IAAI,cAAc,KAAK,SAAS,EAAE,GAAG,GACrC,IAAI,KAAK,OAAO,QAAQ,aAAa,GAAG,GACxC,IAAI,KAAK,UAAU,QAAQ,cAAc,GAAG,GAC5C,IAAI,WAAW,KAAK,UAAU,EAAE,GAAG,GACnC,KAAK,QACL,KACH;AAEH,SAAQ,OAAO,MACb,kCACE,OAAO,SACP,8CACH;;AAGH,SAAS,kBAAkB,OAA+B;AACxD,QAAO,OAAO,UAAU,YAAY,MAAM,MAAM,GAAG,MAAM,MAAM,GAAG;;AAGpE,SAAS,cAAc,UAA0B;AAC/C,KAAI,aAAa,EAAG,QAAO;AAC3B,KAAI,aAAa,EAAG,QAAO;AAC3B,KAAI,aAAa,EAAG,QAAO;AAC3B,KAAI,aAAa,EAAG,QAAO;AAC3B,QAAO;;AAGT,SAAS,WAAW,OAAuB;CACzC,MAAM,OAAO,IAAI,KAAK,MAAM;AAC5B,KAAI,OAAO,MAAM,KAAK,SAAS,CAAC,CAAE,QAAO,MAAM,MAAM,GAAG,GAAG;AAC3D,QAAO,KAAK,aAAa,CAAC,MAAM,GAAG,GAAG"}
@@ -1,9 +1,11 @@
1
- import { boolFlag, parseFlags, strFlag } from "../lib/parse-args.js";
1
+ import { kaizenSystemDir } from "../shared/workspace-paths.js";
2
2
  import { templatesDir, workspaceRoot } from "../lib/paths.js";
3
+ import { isSystemId, requireKaizenWorkspace } from "../lib/cli.js";
3
4
  import { applyVars, ensureDir, writeFileSafely } from "../lib/fs-utils.js";
5
+ import { boolFlag, parseFlags, strFlag } from "../lib/parse-args.js";
4
6
  import { prompt, promptChoice } from "../lib/prompt.js";
5
- import { join } from "node:path";
6
7
  import { existsSync, readFileSync } from "node:fs";
8
+ import { join } from "node:path";
7
9
  //#region src/commands/init-system.ts
8
10
  const EVAL_STYLES = [
9
11
  "ground-truth",
@@ -15,12 +17,9 @@ async function runInitSystem(argv) {
15
17
  const { positional, flags } = parseFlags(argv);
16
18
  const root = workspaceRoot();
17
19
  const force = boolFlag(flags, "force");
18
- if (!existsSync(join(root, "kaizen.config.ts"))) {
19
- process.stderr.write(`no kaizen.config.ts in ${root}.\nrun \`kaizen init\` first.\n`);
20
- return 1;
21
- }
20
+ if (!requireKaizenWorkspace(root)) return 1;
22
21
  const name = strFlag(flags, "name") ?? positional[0] ?? await prompt("system name (kebab-case)");
23
- if (!name || !/^[a-z][a-z0-9-]*$/.test(name)) {
22
+ if (!name || !isSystemId(name)) {
24
23
  process.stderr.write(`invalid system name: "${name}". use kebab-case (e.g. cost-savings).\n`);
25
24
  return 1;
26
25
  }
@@ -38,30 +37,33 @@ async function runInitSystem(argv) {
38
37
  primary_metric: strFlag(flags, "metric") ?? await prompt("primary metric name", evalStyle === "ground-truth" ? "accuracy" : "score"),
39
38
  target: strFlag(flags, "target") ?? await prompt("target score (0-1)", "0.90"),
40
39
  eval_ext: evalLanguage === "typescript" ? "ts" : "py",
40
+ eval_file: `eval.${evalLanguage === "typescript" ? "ts" : "py"}`,
41
+ rubric_frontmatter: evalStyle === "ground-truth" ? "" : `rubric: kaizen/systems/${name}/rubric.md\n`,
41
42
  iso_now: (/* @__PURE__ */ new Date()).toISOString()
42
43
  };
43
- const systemPath = join(root, "systems", `${name}.md`);
44
- const evalPath = join(root, "eval", `${name}.${vars.eval_ext}`);
45
- const rubricPath = join(root, "rubrics", `${name}.md`);
44
+ const systemDir = kaizenSystemDir(root, name);
45
+ const systemPath = join(systemDir, "system.md");
46
+ const evalPath = join(systemDir, vars.eval_file);
47
+ const rubricPath = join(systemDir, "rubric.md");
46
48
  if (!force) {
47
- for (const p of [systemPath, evalPath]) if (existsSync(p)) {
49
+ for (const p of [
50
+ systemPath,
51
+ evalPath,
52
+ ...evalStyle !== "ground-truth" ? [rubricPath] : []
53
+ ]) if (existsSync(p)) {
48
54
  process.stderr.write(`refusing to overwrite ${p}. pass --force to replace.\n`);
49
55
  return 1;
50
56
  }
51
57
  }
52
- ensureDir(join(root, "systems"));
53
- ensureDir(join(root, "eval"));
58
+ ensureDir(systemDir);
54
59
  const tpl = templatesDir();
55
60
  writeFileSafely(systemPath, applyVars(readFileSync(join(tpl, "system", "system.md"), "utf-8"), vars), { overwrite: force });
56
61
  writeFileSafely(evalPath, applyVars(readFileSync(join(tpl, "system", evalLanguage === "typescript" ? "eval.ts" : "eval.py"), "utf-8"), vars), { overwrite: force });
57
- if (evalStyle !== "ground-truth") {
58
- ensureDir(join(root, "rubrics"));
59
- writeFileSafely(rubricPath, applyVars(readFileSync(join(tpl, "system", "rubric.md"), "utf-8"), vars), { overwrite: force });
60
- }
62
+ if (evalStyle !== "ground-truth") writeFileSafely(rubricPath, applyVars(readFileSync(join(tpl, "system", "rubric.md"), "utf-8"), vars), { overwrite: force });
61
63
  process.stdout.write(`scaffolded system "${name}":\n`);
62
- process.stdout.write(` systems/${name}.md\n`);
63
- process.stdout.write(` eval/${name}.${vars.eval_ext}\n`);
64
- if (evalStyle !== "ground-truth") process.stdout.write(` rubrics/${name}.md\n`);
64
+ process.stdout.write(` kaizen/systems/${name}/system.md\n`);
65
+ process.stdout.write(` kaizen/systems/${name}/${vars.eval_file}\n`);
66
+ if (evalStyle !== "ground-truth") process.stdout.write(` kaizen/systems/${name}/rubric.md\n`);
65
67
  process.stdout.write([
66
68
  "",
67
69
  "the starter eval emits a working NDJSON event stream against 3 dummy items.",
@@ -1 +1 @@
1
- {"version":3,"file":"init-system.js","names":[],"sources":["../../src/commands/init-system.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { applyVars, ensureDir, writeFileSafely } from \"../lib/fs-utils.js\";\nimport { boolFlag, parseFlags, strFlag } from \"../lib/parse-args.js\";\nimport { templatesDir, workspaceRoot } from \"../lib/paths.js\";\nimport { prompt, promptChoice } from \"../lib/prompt.js\";\n\nconst EVAL_STYLES = [\"ground-truth\", \"llm-as-judge\", \"hybrid\"] as const;\ntype EvalStyle = (typeof EVAL_STYLES)[number];\nconst EVAL_LANGUAGES = [\"python\", \"typescript\"] as const;\ntype EvalLanguage = (typeof EVAL_LANGUAGES)[number];\n\nexport async function runInitSystem(argv: string[]): Promise<number> {\n const { positional, flags } = parseFlags(argv);\n const root = workspaceRoot();\n const force = boolFlag(flags, \"force\");\n\n if (!existsSync(join(root, \"kaizen.config.ts\"))) {\n process.stderr.write(\n `no kaizen.config.ts in ${root}.\\nrun \\`kaizen init\\` first.\\n`,\n );\n return 1;\n }\n\n const name =\n strFlag(flags, \"name\") ??\n positional[0] ??\n (await prompt(\"system name (kebab-case)\"));\n if (!name || !/^[a-z][a-z0-9-]*$/.test(name)) {\n process.stderr.write(\n `invalid system name: \"${name}\". use kebab-case (e.g. cost-savings).\\n`,\n );\n return 1;\n }\n\n const description =\n strFlag(flags, \"description\") ??\n (await prompt(\"one-line description\", `${name} system`));\n\n const evalStyle = (strFlag(flags, \"eval-style\") ??\n (await promptChoice(\n \"eval style\",\n [...EVAL_STYLES],\n \"ground-truth\",\n ))) as EvalStyle;\n\n const evalLanguage = normalizeEvalLanguage(\n strFlag(flags, \"eval-language\") ?? strFlag(flags, \"language\") ?? \"python\",\n );\n if (!evalLanguage) {\n process.stderr.write(\n `invalid eval language. use one of: ${EVAL_LANGUAGES.join(\", \")}, py, ts.\\n`,\n );\n return 1;\n }\n\n const primaryMetric =\n strFlag(flags, \"metric\") ??\n (await prompt(\n \"primary metric name\",\n evalStyle === \"ground-truth\" ? \"accuracy\" : \"score\",\n ));\n\n const target =\n strFlag(flags, \"target\") ?? (await prompt(\"target score (0-1)\", \"0.90\"));\n\n const vars: Record<string, string> = {\n name,\n description,\n eval_style: evalStyle,\n primary_metric: primaryMetric,\n target,\n eval_ext: evalLanguage === \"typescript\" ? \"ts\" : \"py\",\n iso_now: new Date().toISOString(),\n };\n\n const systemPath = join(root, \"systems\", `${name}.md`);\n const evalPath = join(root, \"eval\", `${name}.${vars.eval_ext}`);\n const rubricPath = join(root, \"rubrics\", `${name}.md`);\n\n if (!force) {\n for (const p of [systemPath, evalPath]) {\n if (existsSync(p)) {\n process.stderr.write(\n `refusing to overwrite ${p}. pass --force to replace.\\n`,\n );\n return 1;\n }\n }\n }\n\n ensureDir(join(root, \"systems\"));\n ensureDir(join(root, \"eval\"));\n\n const tpl = templatesDir();\n writeFileSafely(\n systemPath,\n applyVars(readFileSync(join(tpl, \"system\", \"system.md\"), \"utf-8\"), vars),\n { overwrite: force },\n );\n writeFileSafely(\n evalPath,\n applyVars(\n readFileSync(\n join(\n tpl,\n \"system\",\n evalLanguage === \"typescript\" ? \"eval.ts\" : \"eval.py\",\n ),\n \"utf-8\",\n ),\n vars,\n ),\n { overwrite: force },\n );\n\n if (evalStyle !== \"ground-truth\") {\n ensureDir(join(root, \"rubrics\"));\n writeFileSafely(\n rubricPath,\n applyVars(readFileSync(join(tpl, \"system\", \"rubric.md\"), \"utf-8\"), vars),\n { overwrite: force },\n );\n }\n\n process.stdout.write(`scaffolded system \"${name}\":\\n`);\n process.stdout.write(` systems/${name}.md\\n`);\n process.stdout.write(` eval/${name}.${vars.eval_ext}\\n`);\n if (evalStyle !== \"ground-truth\")\n process.stdout.write(` rubrics/${name}.md\\n`);\n process.stdout.write(\n [\n \"\",\n \"the starter eval emits a working NDJSON event stream against 3 dummy items.\",\n \"edit it to load your dataset and produce real scores, then:\",\n \"\",\n ` kaizen run --system ${name} --variant baseline --hypothesis \"starting baseline\"`,\n \"\",\n ].join(\"\\n\"),\n );\n\n return 0;\n}\n\nfunction normalizeEvalLanguage(raw: string): EvalLanguage | null {\n const normalized = raw.toLowerCase();\n if (normalized === \"python\" || normalized === \"py\") return \"python\";\n if (normalized === \"typescript\" || normalized === \"ts\") return \"typescript\";\n return null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"init-system.js","names":[],"sources":["../../src/commands/init-system.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { isSystemId, requireKaizenWorkspace } from \"../lib/cli.js\";\nimport { applyVars, ensureDir, writeFileSafely } from \"../lib/fs-utils.js\";\nimport { boolFlag, parseFlags, strFlag } from \"../lib/parse-args.js\";\nimport { kaizenSystemDir, templatesDir, workspaceRoot } from \"../lib/paths.js\";\nimport { prompt, promptChoice } from \"../lib/prompt.js\";\n\nconst EVAL_STYLES = [\"ground-truth\", \"llm-as-judge\", \"hybrid\"] as const;\ntype EvalStyle = (typeof EVAL_STYLES)[number];\nconst EVAL_LANGUAGES = [\"python\", \"typescript\"] as const;\ntype EvalLanguage = (typeof EVAL_LANGUAGES)[number];\n\nexport async function runInitSystem(argv: string[]): Promise<number> {\n const { positional, flags } = parseFlags(argv);\n const root = workspaceRoot();\n const force = boolFlag(flags, \"force\");\n\n if (!requireKaizenWorkspace(root)) return 1;\n\n const name =\n strFlag(flags, \"name\") ??\n positional[0] ??\n (await prompt(\"system name (kebab-case)\"));\n if (!name || !isSystemId(name)) {\n process.stderr.write(\n `invalid system name: \"${name}\". use kebab-case (e.g. cost-savings).\\n`,\n );\n return 1;\n }\n\n const description =\n strFlag(flags, \"description\") ??\n (await prompt(\"one-line description\", `${name} system`));\n\n const evalStyle = (strFlag(flags, \"eval-style\") ??\n (await promptChoice(\n \"eval style\",\n [...EVAL_STYLES],\n \"ground-truth\",\n ))) as EvalStyle;\n\n const evalLanguage = normalizeEvalLanguage(\n strFlag(flags, \"eval-language\") ?? strFlag(flags, \"language\") ?? \"python\",\n );\n if (!evalLanguage) {\n process.stderr.write(\n `invalid eval language. use one of: ${EVAL_LANGUAGES.join(\", \")}, py, ts.\\n`,\n );\n return 1;\n }\n\n const primaryMetric =\n strFlag(flags, \"metric\") ??\n (await prompt(\n \"primary metric name\",\n evalStyle === \"ground-truth\" ? \"accuracy\" : \"score\",\n ));\n\n const target =\n strFlag(flags, \"target\") ?? (await prompt(\"target score (0-1)\", \"0.90\"));\n\n const vars: Record<string, string> = {\n name,\n description,\n eval_style: evalStyle,\n primary_metric: primaryMetric,\n target,\n eval_ext: evalLanguage === \"typescript\" ? \"ts\" : \"py\",\n eval_file: `eval.${evalLanguage === \"typescript\" ? \"ts\" : \"py\"}`,\n rubric_frontmatter:\n evalStyle === \"ground-truth\"\n ? \"\"\n : `rubric: kaizen/systems/${name}/rubric.md\\n`,\n iso_now: new Date().toISOString(),\n };\n\n const systemDir = kaizenSystemDir(root, name);\n const systemPath = join(systemDir, \"system.md\");\n const evalPath = join(systemDir, vars.eval_file);\n const rubricPath = join(systemDir, \"rubric.md\");\n\n if (!force) {\n for (const p of [\n systemPath,\n evalPath,\n ...(evalStyle !== \"ground-truth\" ? [rubricPath] : []),\n ]) {\n if (existsSync(p)) {\n process.stderr.write(\n `refusing to overwrite ${p}. pass --force to replace.\\n`,\n );\n return 1;\n }\n }\n }\n\n ensureDir(systemDir);\n\n const tpl = templatesDir();\n writeFileSafely(\n systemPath,\n applyVars(readFileSync(join(tpl, \"system\", \"system.md\"), \"utf-8\"), vars),\n { overwrite: force },\n );\n writeFileSafely(\n evalPath,\n applyVars(\n readFileSync(\n join(\n tpl,\n \"system\",\n evalLanguage === \"typescript\" ? \"eval.ts\" : \"eval.py\",\n ),\n \"utf-8\",\n ),\n vars,\n ),\n { overwrite: force },\n );\n\n if (evalStyle !== \"ground-truth\") {\n writeFileSafely(\n rubricPath,\n applyVars(readFileSync(join(tpl, \"system\", \"rubric.md\"), \"utf-8\"), vars),\n { overwrite: force },\n );\n }\n\n process.stdout.write(`scaffolded system \"${name}\":\\n`);\n process.stdout.write(` kaizen/systems/${name}/system.md\\n`);\n process.stdout.write(` kaizen/systems/${name}/${vars.eval_file}\\n`);\n if (evalStyle !== \"ground-truth\")\n process.stdout.write(` kaizen/systems/${name}/rubric.md\\n`);\n process.stdout.write(\n [\n \"\",\n \"the starter eval emits a working NDJSON event stream against 3 dummy items.\",\n \"edit it to load your dataset and produce real scores, then:\",\n \"\",\n ` kaizen run --system ${name} --variant baseline --hypothesis \"starting baseline\"`,\n \"\",\n ].join(\"\\n\"),\n );\n\n return 0;\n}\n\nfunction normalizeEvalLanguage(raw: string): EvalLanguage | null {\n const normalized = raw.toLowerCase();\n if (normalized === \"python\" || normalized === \"py\") return \"python\";\n if (normalized === \"typescript\" || normalized === \"ts\") return \"typescript\";\n return null;\n}\n"],"mappings":"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"}