@giamme/forge 0.8.0 → 0.10.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 (83) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +106 -1766
  3. package/SKILL.md +22 -3
  4. package/VERSION +1 -1
  5. package/docs/README.md +26 -0
  6. package/docs/add-ons.md +33 -0
  7. package/docs/artifacts.md +84 -0
  8. package/docs/commands.md +365 -0
  9. package/docs/dataset.md +29 -0
  10. package/docs/decomposed-runs.md +310 -0
  11. package/docs/development.md +95 -0
  12. package/docs/forge-ui.md +128 -0
  13. package/docs/fractal.md +181 -0
  14. package/docs/install.md +160 -0
  15. package/docs/memory.md +156 -0
  16. package/docs/models.md +118 -0
  17. package/docs/reviews.md +245 -0
  18. package/docs/safety.md +55 -0
  19. package/docs/troubleshooting.md +54 -0
  20. package/forge +20 -0
  21. package/package.json +3 -2
  22. package/references/dataset.md +18 -1
  23. package/references/decompose.md +20 -2
  24. package/references/fractal.md +1 -1
  25. package/references/harnesses.md +18 -6
  26. package/references/solo.md +1 -1
  27. package/references/ui.md +27 -5
  28. package/scripts/forge-config.py +347 -0
  29. package/scripts/forge-control.py +645 -0
  30. package/scripts/forge-dispatch.sh +7 -1
  31. package/scripts/forge-issues.py +806 -0
  32. package/scripts/forge-lib-task.sh +234 -35
  33. package/scripts/forge-parallel-options.sh +3 -1
  34. package/scripts/forge-parallel.sh +3 -2
  35. package/scripts/forge-route.py +184 -27
  36. package/scripts/forge-runs-rm.py +840 -0
  37. package/scripts/forge-runs.py +139 -0
  38. package/scripts/forge-runtime.py +59 -6
  39. package/scripts/forge-schedule.py +227 -11
  40. package/scripts/forge-ui.py +85 -19
  41. package/scripts/forge-version.py +54 -12
  42. package/scripts/forge_dataset/__init__.py +77 -6
  43. package/scripts/forge_dataset/capture.py +5 -2
  44. package/scripts/forge_dataset/harvest.py +23 -1
  45. package/scripts/forge_dataset/importer.py +420 -18
  46. package/scripts/forge_fractal/__init__.py +2 -1
  47. package/scripts/forge_registry.py +168 -16
  48. package/ui/README.md +116 -23
  49. package/ui/THIRD_PARTY_NOTICES.md +108 -0
  50. package/ui/docs/api.md +283 -23
  51. package/ui/forge_ui/__main__.py +10 -2
  52. package/ui/forge_ui/control.py +575 -0
  53. package/ui/forge_ui/export.py +33 -9
  54. package/ui/forge_ui/fractal.py +1 -2
  55. package/ui/forge_ui/reader.py +121 -8
  56. package/ui/forge_ui/server.py +135 -5
  57. package/ui/forge_ui/static/D-DINCondensed-Bold.woff2 +0 -0
  58. package/ui/forge_ui/static/app.js +358 -131
  59. package/ui/forge_ui/static/cloud3d.js +3 -2
  60. package/ui/forge_ui/static/cloudui.js +8 -5
  61. package/ui/forge_ui/static/controls.js +619 -0
  62. package/ui/forge_ui/static/convo.js +295 -0
  63. package/ui/forge_ui/static/datatable.js +232 -0
  64. package/ui/forge_ui/static/diffview.js +29 -10
  65. package/ui/forge_ui/static/findings3d.js +134 -0
  66. package/ui/forge_ui/static/findingsview.js +412 -0
  67. package/ui/forge_ui/static/graph.js +3 -3
  68. package/ui/forge_ui/static/icons.js +94 -0
  69. package/ui/forge_ui/static/index.html +31 -13
  70. package/ui/forge_ui/static/iso.js +70 -19
  71. package/ui/forge_ui/static/leaderboard.js +44 -48
  72. package/ui/forge_ui/static/panel.js +92 -36
  73. package/ui/forge_ui/static/rundelete.js +388 -0
  74. package/ui/forge_ui/static/runmodel.js +17 -1
  75. package/ui/forge_ui/static/scene3d.js +518 -43
  76. package/ui/forge_ui/static/search.js +2 -1
  77. package/ui/forge_ui/static/settings.js +399 -0
  78. package/ui/forge_ui/static/shell.js +137 -0
  79. package/ui/forge_ui/static/stagectl.js +150 -0
  80. package/ui/forge_ui/static/style.css +1099 -469
  81. package/ui/forge_ui/static/theme.js +25 -0
  82. package/ui/forge_ui/static/uikit.js +161 -0
  83. package/ui/forge_ui/transcripts.py +608 -0
@@ -87,8 +87,9 @@ export function createCloud(E, host, cb = {}) {
87
87
  TMP.copy(col).lerp(E.accent, c.hot > .5 ? c.hot : 0);
88
88
  const lit = statusOf(el.f) === 'PENDING' ? 0 : .3;
89
89
  E.paint(el.M, c.vis, Math.min(1, lit + c.hot * .9), c.hov, 1, 1, TMP, 0);
90
- el.M.body.color.lerp(col, (E.theme === 'light' ? .1 : .12) * c.vis);
91
- setRoof(el, col, Math.round((E.theme === 'light' ? .14 : .2) * c.vis * 50) / 50);
90
+ const light = E.theme === 'light', plain = statusOf(el.f) === 'PENDING';
91
+ el.M.body.color.lerp(col, (light ? plain ? .06 : .34 : .12) * c.vis);
92
+ setRoof(el, col, Math.round((light ? plain ? .12 : .55 : .2) * c.vis * 50) / 50);
92
93
  el.haloMat.uniforms.color.value.copy(col);
93
94
  const glow = (el.f.state === 'live' ? .14 + .12 * pulse : 0) * c.vis + (c.hot > .5 ? .12 : 0);
94
95
  el.haloMat.uniforms.opacity.value = glow; el.halo.visible = glow > .002; // no draw for a halo that is off
@@ -99,7 +99,7 @@ window.ForgeCloudUI = (() => {
99
99
  else if (root.requestFullscreen) root.requestFullscreen().catch(() => say('Full screen is not available here.'));
100
100
  });
101
101
  document.addEventListener('fullscreenchange', () => { full.textContent = document.fullscreenElement === root ? 'Exit full screen' : 'Full screen'; });
102
- const title = el('h1', 'Run cloud');
102
+ const title = el('h1', 'Run cloud', 'module-title');
103
103
  const left = el('div', undefined, 'cloud-bar-left'); left.append(title, count);
104
104
  const tools = el('div', undefined, 'cloud-bar-tools'); tools.append(filtersBtn, layoutSeg, shapeSeg, resetView, posMenu, full);
105
105
  if (ctx.viewToggle) tools.append(ctx.viewToggle());
@@ -225,7 +225,7 @@ window.ForgeCloudUI = (() => {
225
225
  const f = prefs.filter, O = CM.options(S.facts), P = CM.projects(S.runs);
226
226
  panel.replaceChildren();
227
227
  const head = el('div', undefined, 'cloud-panel-head');
228
- head.append(el('h2', 'Filters'), button('Reset', 'linkish', () => { prefs.filter = CM.emptyFilter(); apply({ rebuild: true }); }, 'Show every run'));
228
+ head.append(el('h2', 'Filters', 'plate'), button('Reset', 'linkish', () => { prefs.filter = CM.emptyFilter(); apply({ rebuild: true }); }, 'Show every run'));
229
229
  panel.append(head);
230
230
  const text = el('input'); text.type = 'search'; text.value = f.text; text.placeholder = 'goal, repo, run or task id, title, model…'; text.dataset.key = 'text';
231
231
  text.setAttribute('aria-label', 'Search the runs');
@@ -285,16 +285,19 @@ window.ForgeCloudUI = (() => {
285
285
  const head = el('div', undefined, 'cloud-card-head');
286
286
  head.append(el('span', STATE[f.state] ? STATE[f.state].label : f.state, 'chip st-' + (STATE[f.state] || { st: 'unknown' }).st),
287
287
  el('span', `${proj ? proj.name : RM.basename(r.repo)} · ${r.kind || 'plan'}`, 'muted'));
288
- head.append(button('×', 'cloud-card-close', () => ctx.route({ sel: null, focus: S.focus }), 'Close (Esc)'));
288
+ const shut = button('', 'cloud-card-close', () => ctx.route({ sel: null, focus: S.focus }), 'Close (Esc)');
289
+ shut.setAttribute('aria-label', 'Close (Esc)'); if (window.ForgeIcons) shut.append(window.ForgeIcons.icon('close'));
290
+ head.append(shut);
289
291
  card.append(head, el('h2', String(r.goal || 'Untitled run').split('\n')[0]), el('p', r.run_id || '', 'mono muted'));
290
292
  const leds = el('span', undefined, 'leds');
291
293
  for (const t of list(r.task_statuses).slice(0, 120)) { const l = el('i', undefined, 'led st-' + String(t.status || 'pending').toLowerCase()); l.title = `${t.id}: ${t.status}${t.title ? ' · ' + t.title : ''}`; leds.append(l); }
292
294
  card.append(leds);
293
295
  const dl = el('dl', undefined, 'fields');
294
296
  const mix = ['high', 'medium', 'low', 'none'].filter(k => f.diff[k]).map(k => `${f.diff[k]} ${k === 'none' ? 'unset' : k}`).join(' · ');
295
- for (const [k, v, mono] of [['Tasks', `${f.n}${mix ? ' · ' + mix : ''}`], ['Implementers', [...f.dwarf].join(', ') || '—', true], ['Reviewers', [...f.qa].join(', ') || '—', true],
297
+ const plates = specs => { if (!specs.length || !window.ForgeIcons) return specs.join(', ') || '—'; const s = el('span', undefined, 'plates'); for (const x of specs) s.append(window.ForgeIcons.modelPlate(x)); return s; };
298
+ for (const [k, v, mono] of [['Tasks', `${f.n}${mix ? ' · ' + mix : ''}`], ['Implementers', plates([...f.dwarf])], ['Reviewers', plates([...f.qa])],
296
299
  ['Started', when(r.created)], ['Updated', when(r.updated)], ['Final review', r.final_review || '—'], ['Verification', r.verification_status || '—'], ['Decompose', r.decompose_level || 'off']]) {
297
- dl.append(el('dt', k), el('dd', v, mono ? 'mono' : ''));
300
+ const dd = el('dd', undefined, mono ? 'mono' : ''); dd.append(v instanceof Node ? v : document.createTextNode(String(v))); dl.append(el('dt', k), dd);
298
301
  }
299
302
  card.append(dl);
300
303
  if (!shown) card.append(el('p', 'Hidden by the current filters.', 'warn'));