@worca/app 1.2.0-rc.3 → 1.3.0-rc.2

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 (104) hide show
  1. package/README.md +42 -0
  2. package/agents/memoryDefragmenter.meta.json +24 -0
  3. package/agents/worca-cc-code-reviewer.md +6 -1
  4. package/agents/worca-cc-implementer.md +6 -1
  5. package/agents/worca-cc-memory-defragmenter.md +32 -0
  6. package/agents/worca-cc-planner.md +5 -1
  7. package/package.json +5 -2
  8. package/src/cli/render.mjs +36 -0
  9. package/src/cli/worca-cc.mjs +137 -8
  10. package/src/core/agent-registry.mjs +12 -34
  11. package/src/core/artifacts.mjs +132 -8
  12. package/src/core/ask/catalog.mjs +32 -7
  13. package/src/core/ask/comment-deps.mjs +5 -2
  14. package/src/core/ask/events.mjs +65 -2
  15. package/src/core/ask/limits.mjs +9 -0
  16. package/src/core/ask/mcp-stdio.mjs +10 -0
  17. package/src/core/ask/memory-deps.mjs +107 -0
  18. package/src/core/ask/metrics-deps.mjs +124 -0
  19. package/src/core/ask/metrics-proposal.mjs +175 -0
  20. package/src/core/ask/prompt.mjs +53 -10
  21. package/src/core/ask/proposal.mjs +49 -2
  22. package/src/core/ask/spawn.mjs +21 -4
  23. package/src/core/ask/store.mjs +14 -5
  24. package/src/core/ask/tool-deps.mjs +26 -2
  25. package/src/core/ask/tools.mjs +439 -6
  26. package/src/core/ask/turn.mjs +163 -4
  27. package/src/core/ask/workflow-deps.mjs +226 -0
  28. package/src/core/auto/classify.mjs +352 -0
  29. package/src/core/auto/fingerprint.mjs +141 -0
  30. package/src/core/auto/match.mjs +30 -0
  31. package/src/core/auto/model.mjs +23 -0
  32. package/src/core/auto/proposal.mjs +132 -0
  33. package/src/core/auto/recipes.mjs +75 -0
  34. package/src/core/auto/repo-look.mjs +46 -0
  35. package/src/core/claude-runner.mjs +132 -11
  36. package/src/core/config.mjs +120 -3
  37. package/src/core/db.mjs +44 -1
  38. package/src/core/diff-comments.mjs +55 -9
  39. package/src/core/frontmatter.mjs +75 -0
  40. package/src/core/git-info.mjs +233 -26
  41. package/src/core/graph/builtin-workflows.mjs +50 -0
  42. package/src/core/graph/executor.mjs +11 -3
  43. package/src/core/index-html.mjs +17 -0
  44. package/src/core/memory-store.mjs +441 -0
  45. package/src/core/memory-sync.mjs +300 -0
  46. package/src/core/metrics/ledger.mjs +47 -0
  47. package/src/core/metrics/lock.mjs +117 -0
  48. package/src/core/metrics/read.mjs +303 -0
  49. package/src/core/metrics/record.mjs +389 -0
  50. package/src/core/metrics/sync.mjs +1100 -0
  51. package/src/core/onboarding.mjs +99 -0
  52. package/src/core/orchestrator.mjs +394 -7
  53. package/src/core/phases.mjs +16 -3
  54. package/src/core/pipeline-delete.mjs +1 -1
  55. package/src/core/plugin-store.mjs +2 -10
  56. package/src/core/preflight.mjs +2 -3
  57. package/src/core/projects.mjs +16 -1
  58. package/src/core/run-harness.mjs +458 -32
  59. package/src/core/run-report.mjs +896 -0
  60. package/src/core/settings.mjs +162 -0
  61. package/src/core/sources.mjs +4 -1
  62. package/src/core/store.mjs +5 -0
  63. package/src/core/workflow-export.mjs +2 -0
  64. package/src/core/workflow-share.mjs +1 -0
  65. package/src/core/workflows.mjs +43 -23
  66. package/src/core/workspaces.mjs +37 -8
  67. package/src/shared/graph/agent-meta.mjs +5 -2
  68. package/src/shared/graph/assemble.mjs +455 -0
  69. package/src/shared/graph/flow-layout.mjs +249 -0
  70. package/src/shared/graph/geometry.mjs +48 -28
  71. package/src/shared/graph/isomorphic.mjs +101 -0
  72. package/src/shared/report-reasons.mjs +58 -0
  73. package/src/shared/team-metrics/aggregate.mjs +341 -0
  74. package/src/shared/team-metrics/workspace-match.mjs +13 -0
  75. package/ui/public/about-links.mjs +21 -0
  76. package/ui/public/app.js +3736 -479
  77. package/ui/public/artifact-view.mjs +135 -0
  78. package/ui/public/ask-model.mjs +18 -1
  79. package/ui/public/ask-panel.mjs +1589 -212
  80. package/ui/public/ask-run-card.mjs +209 -0
  81. package/ui/public/assets/worca-logo-mask.png +0 -0
  82. package/ui/public/assets/worca-mark-mask.png +0 -0
  83. package/ui/public/auto-build.mjs +95 -0
  84. package/ui/public/auto-proposal.mjs +174 -0
  85. package/ui/public/comment-thread.mjs +55 -0
  86. package/ui/public/getting-started.mjs +261 -0
  87. package/ui/public/graph/composer.mjs +41 -5
  88. package/ui/public/graph/inspector.mjs +3 -1
  89. package/ui/public/graph/model.mjs +1 -0
  90. package/ui/public/graph/run-hosts.mjs +73 -12
  91. package/ui/public/graph/view.mjs +218 -50
  92. package/ui/public/guide-spot.mjs +215 -0
  93. package/ui/public/index.html +447 -29
  94. package/ui/public/memory-view.mjs +192 -0
  95. package/ui/public/node-tunables.mjs +201 -0
  96. package/ui/public/report-run.mjs +75 -0
  97. package/ui/public/results-view.mjs +25 -0
  98. package/ui/public/source-pane.mjs +16 -2
  99. package/ui/public/stats-view.mjs +2 -2
  100. package/ui/public/style.css +1499 -303
  101. package/ui/public/team-metrics-surfaces.mjs +452 -0
  102. package/ui/public/team-metrics-view.mjs +533 -0
  103. package/ui/public/thinking-orb.mjs +46 -8
  104. package/ui/server.mjs +1304 -194
@@ -169,7 +169,7 @@ export async function archivePipeline({ projectDir = null, key = null, workspace
169
169
  try {
170
170
  const branch = state?.branch?.feature;
171
171
  if (branch && state?.projectDir && await hasGh()) {
172
- const pr = await findPrForBranch({ projectDir: state.projectDir, head: branch });
172
+ const pr = await findPrForBranch({ projectDir: state.projectDir, head: branch, prUrl: row.pr_url || null });
173
173
  if (pr) persistPrState(row.id, pr);
174
174
  }
175
175
  } catch (e) {
@@ -28,6 +28,7 @@ import { loadAgentRegistry } from './agent-registry.mjs';
28
28
  import { pluginModelSecretStatus } from './plugin-models.mjs';
29
29
  import { referencedPluginModels } from './config.mjs';
30
30
  import { clearBindingsForPlugin } from './source-bindings.mjs';
31
+ import { parseFrontmatter } from './frontmatter.mjs';
31
32
 
32
33
  const execFileP = promisify(execFile);
33
34
  const defaultExec = (cmd, args, opts = {}) =>
@@ -55,15 +56,6 @@ function insideDir(dir, rel) {
55
56
  return resolve(root, rel).startsWith(root + sep);
56
57
  }
57
58
 
58
- /** Private copy of workflows.mjs:66-77 parseFrontmatterTools (module-private there). */
59
- function frontmatterTools(text) {
60
- const m = /^---\s*\n([\s\S]*?)\n---/.exec(text);
61
- if (!m) return [];
62
- const line = m[1].split(/\r?\n/).find((l) => /^tools\s*:/.test(l));
63
- if (!line) return [];
64
- return line.replace(/^tools\s*:/, '').split(',').map((s) => s.trim()).filter(Boolean);
65
- }
66
-
67
59
  /** The "Will install" consent inventory (spec §6.1, design §9.4): agents +
68
60
  * their frontmatter tools, sources + their secret fields, models with their
69
61
  * base-URL value VERBATIM (a model env can redirect all API traffic — the
@@ -89,7 +81,7 @@ export function buildInstallInventory(versionDir) {
89
81
  if (typeof af === 'string' && af.trim() && insideDir(aDir, af.trim())) mdFile = af.trim();
90
82
  } catch { /* unreadable sidecar: fall back to the sibling */ }
91
83
  let tools = [];
92
- try { tools = frontmatterTools(readFileSync(join(aDir, mdFile), 'utf8')); } catch { /* md missing */ }
84
+ try { tools = parseFrontmatter(readFileSync(join(aDir, mdFile), 'utf8'))?.tools ?? []; } catch { /* md missing */ }
93
85
  agents.push({ key, tools });
94
86
  }
95
87
  }
@@ -322,9 +322,8 @@ export async function detectToolsPerProject(projectDirs) {
322
322
  * required version >= 2.1.220) rather than failing the run: R1(a)/(c) still hold via
323
323
  * the cwd and ancestor mechanisms, and R1(b) is reported as DEGRADED.
324
324
  *
325
- * Deliberately NO `addDir` field: `--add-dir` is not probed because no shipped
326
- * feature uses it (§5.3 — it needs `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1`
327
- * to carry memory at all, E2), and a probe field no consumer reads is dead weight.
325
+ * No `addDir` preflight probe: Ask Worca's memory mount passes `--add-dir`
326
+ * (claude-runner `addDirs`), verified by the 2026-09-13 rules probe, not by preflight.
328
327
  *
329
328
  * Never throws: a missing binary / hung process resolves to
330
329
  * `{ mcpConfig: false, version: null }`, which the caller treats the same as an old
@@ -144,16 +144,31 @@ export async function addProject(input) {
144
144
  }
145
145
 
146
146
  /**
147
- * Remove a project by name (case-insensitive). Absent name is a no-op.
147
+ * Remove a project by name (case-insensitive). Absent name is a no-op. Also prunes any metrics
148
+ * worktree that belonged to this project's repository, waiting up to ~10s for it: the wait is
149
+ * best-effort — a worktree still held by a running flush is skipped and swept on the next start.
148
150
  * @param {string} name
149
151
  * @returns {Promise<Array<{key:string, name:string, path:string, exists:boolean}>>}
150
152
  */
151
153
  export async function removeProject(name) {
152
154
  const key = (typeof name === 'string' ? name : '').trim();
155
+ let removedPath = null;
153
156
  if (key) {
154
157
  tx(() => {
158
+ const row = prepare('SELECT path FROM projects WHERE name = ? COLLATE NOCASE').get(key);
159
+ removedPath = row ? row.path : null;
155
160
  prepare('DELETE FROM projects WHERE name = ? COLLATE NOCASE').run(key);
156
161
  });
157
162
  }
163
+ if (removedPath) {
164
+ // Dynamic import: metrics/sync.mjs imports this module (worcaHome, listProjects).
165
+ try {
166
+ const { pruneMetricsWorktreesFor } = await import('./metrics/sync.mjs');
167
+ // Bounded: each removal waits for the slug lock, and a running flush can hold it for minutes.
168
+ // The DELETE request must not hang on that; the prune finishes in the background.
169
+ const prune = pruneMetricsWorktreesFor(removedPath).catch(() => []);
170
+ await Promise.race([prune, new Promise((r) => setTimeout(r, 10_000).unref?.())]);
171
+ } catch { /* best-effort: a leftover worktree is harmless and re-pruned by git */ }
172
+ }
158
173
  return listProjects();
159
174
  }