@hizliemre/horse-code 0.3.0 → 0.4.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 (32) hide show
  1. package/dist/{app-5FXHE7GX.js → app-KR7TAHUD.js} +82 -40
  2. package/dist/{chunk-LNW557IO.js → chunk-372X5HHU.js} +2 -2
  3. package/dist/{chunk-XEGQT5EN.js → chunk-4M6LXNG2.js} +1 -1
  4. package/dist/{chunk-6OSEQOYY.js → chunk-6S4WWQMN.js} +2 -2
  5. package/dist/chunk-ACTVFJRW.js +989 -0
  6. package/dist/{chunk-LLL7QWXB.js → chunk-BFIZMM4G.js} +6 -6
  7. package/dist/chunk-CYLPQWIF.js +214 -0
  8. package/dist/{chunk-AE36LLL2.js → chunk-JLWQCA7B.js} +2 -209
  9. package/dist/{chunk-XYZVZPAY.js → chunk-KXBYRU4W.js} +66 -31
  10. package/dist/chunk-MZM24M5M.js +251 -0
  11. package/dist/chunk-NBTH2VVI.js +1945 -0
  12. package/dist/chunk-PIG54WFU.js +2873 -0
  13. package/dist/{run-P6ZYL5JL.js → chunk-QJYVZPLG.js} +133 -389
  14. package/dist/{chunk-YPZP7LYL.js → chunk-UANNVVIU.js} +1 -1
  15. package/dist/{chunk-UGESK765.js → chunk-UTHLEW5V.js} +1 -1
  16. package/dist/{chunk-KAGKX2YT.js → chunk-ZPJP2VH5.js} +10 -1
  17. package/dist/cli.js +262 -69
  18. package/dist/{fix-ONLA45HD.js → fix-SSDUVV4T.js} +11 -8
  19. package/dist/{ongoing-WHYXPW24.js → ongoing-6NUSPSCV.js} +3 -2
  20. package/dist/{project-graph-5HNPRFQG.js → project-graph-OGIM2B33.js} +1 -1
  21. package/dist/research-MHBNZ6SA.js +111 -0
  22. package/dist/run-V5ZLZ3LS.js +274 -0
  23. package/dist/{save-skills-ZW5GY6KV.js → save-skills-NPKTYNAF.js} +2 -2
  24. package/dist/{trace-X6TU3AG6.js → trace-UVMZZRA5.js} +1 -1
  25. package/dist/{trace-adopt-URECQWJV.js → trace-adopt-7HWELJFE.js} +1 -1
  26. package/dist/{trace-run-7U4WJZ3V.js → trace-run-OBOD552Q.js} +9 -4
  27. package/dist/{triage-FCYHD2AQ.js → triage-IFCVL5MA.js} +7 -6
  28. package/dist/{verify-LC57A6H2.js → verify-2DTBG6RG.js} +26 -20
  29. package/package.json +1 -1
  30. package/dist/chunk-MRZVA5JB.js +0 -163
  31. package/dist/chunk-UEWVVN5L.js +0 -5691
  32. package/dist/{chunk-EAF22QIG.js → chunk-JR2JLRE3.js} +3 -3
@@ -10,48 +10,56 @@ import {
10
10
  restoreTerminal,
11
11
  runJob,
12
12
  sttySane
13
- } from "./chunk-XYZVZPAY.js";
13
+ } from "./chunk-KXBYRU4W.js";
14
14
  import "./chunk-M2RKCIGV.js";
15
+ import "./chunk-UTHLEW5V.js";
16
+ import {
17
+ RoleFitness,
18
+ asChoice
19
+ } from "./chunk-PIG54WFU.js";
20
+ import {
21
+ describeUnfinished,
22
+ toSlug,
23
+ unfinishedSessions
24
+ } from "./chunk-NBTH2VVI.js";
25
+ import "./chunk-ZSQ24YDJ.js";
26
+ import "./chunk-QF4MP6BS.js";
27
+ import {
28
+ saveRoleSkills
29
+ } from "./chunk-JR2JLRE3.js";
30
+ import {
31
+ objectField,
32
+ patchConfig
33
+ } from "./chunk-H2FDGPVW.js";
15
34
  import {
16
35
  DURABLE_ROLES,
17
- REQUIRED_ROLES,
18
36
  ROLE_PROFILES,
19
- RoleFitness,
20
37
  adjustRoleModels,
21
- asChoice,
22
38
  capabilityScore,
23
39
  cliFor,
24
- describeUnfinished,
25
40
  effortFor,
26
41
  filterModelsForRole,
27
42
  isKnownModel,
43
+ isPeer,
28
44
  modelBand,
29
45
  mostCapable,
30
46
  newestPrimary,
31
47
  sourceOf,
32
- strongestPrimary,
33
- toSlug,
34
- unfinishedSessions
35
- } from "./chunk-UEWVVN5L.js";
36
- import "./chunk-QF4MP6BS.js";
37
- import "./chunk-UGESK765.js";
38
- import "./chunk-ZSQ24YDJ.js";
48
+ strongestPrimary
49
+ } from "./chunk-ACTVFJRW.js";
39
50
  import {
40
- saveRoleSkills
41
- } from "./chunk-EAF22QIG.js";
51
+ REQUIRED_ROLES
52
+ } from "./chunk-MZM24M5M.js";
42
53
  import "./chunk-G45RWL7S.js";
43
- import {
44
- objectField,
45
- patchConfig
46
- } from "./chunk-H2FDGPVW.js";
47
- import "./chunk-MRZVA5JB.js";
48
54
  import "./chunk-LPQU436C.js";
49
55
  import {
50
56
  memoryNote,
51
57
  memoryState,
52
58
  walkFiles
53
- } from "./chunk-LLL7QWXB.js";
59
+ } from "./chunk-BFIZMM4G.js";
60
+ import "./chunk-CYLPQWIF.js";
54
61
  import "./chunk-63E73TGI.js";
62
+ import "./chunk-6S4WWQMN.js";
55
63
  import {
56
64
  estimateFreezeSeconds,
57
65
  fmtDuration,
@@ -61,15 +69,14 @@ import {
61
69
  stripThinking,
62
70
  telemetry,
63
71
  writeHeapSnapshot
64
- } from "./chunk-AE36LLL2.js";
65
- import "./chunk-6OSEQOYY.js";
72
+ } from "./chunk-JLWQCA7B.js";
66
73
  import {
67
74
  traceRootRel
68
- } from "./chunk-KAGKX2YT.js";
75
+ } from "./chunk-ZPJP2VH5.js";
69
76
  import {
70
77
  buildProjectGraph,
71
78
  graphStatus
72
- } from "./chunk-XEGQT5EN.js";
79
+ } from "./chunk-4M6LXNG2.js";
73
80
  import {
74
81
  writeAtomic
75
82
  } from "./chunk-6W4UH2BQ.js";
@@ -152,17 +159,26 @@ function validateChains(assignments, roles, models, heuristic) {
152
159
  chain.push(m);
153
160
  }
154
161
  };
162
+ const primaryOf = (byRole.get(role) ?? [])[0];
163
+ const admissible = (m) => {
164
+ const head = chain[0] ?? primaryOf;
165
+ if (!head || m === head) return true;
166
+ return sourceOf(m) !== sourceOf(head) && isPeer(head, m) && !chain.some((c) => sourceOf(c) === sourceOf(m));
167
+ };
168
+ const addIf = (m) => {
169
+ if (admissible(m)) add(m);
170
+ };
155
171
  for (const m of byRole.get(role) ?? []) {
156
172
  if (chain.length >= 3) break;
157
- add(m);
173
+ addIf(m);
158
174
  }
159
175
  for (const m of heuMap.get(role) ?? []) {
160
176
  if (chain.length >= 3) break;
161
- add(m);
177
+ addIf(m);
162
178
  }
163
179
  for (const m of models) {
164
180
  if (chain.length >= 3) break;
165
- add(m);
181
+ addIf(m);
166
182
  }
167
183
  const tuned = DURABLE_ROLES.includes(role) ? strongestPrimary(chain, models) : chain;
168
184
  return { role, models: newestPrimary(tuned, models) };
@@ -1739,6 +1755,7 @@ var COMMANDS = [
1739
1755
  { name: "/memories", desc: "List remembered facts (/forget N to remove)" },
1740
1756
  { name: "/forget", desc: "Forget a remembered fact (/forget N)" },
1741
1757
  { name: "/mcp", desc: "Connected MCP servers (/mcp add <url|command> installs one and verifies it)" },
1758
+ { name: "/init", desc: "Set this project up for horse-code \u2014 commit the knowledge, keep the derived files out" },
1742
1759
  { name: "/models", desc: "Models each connected subscription serves, and which ones a role is running" },
1743
1760
  { name: "/sources", desc: "Show your connected model sources (/sources refresh re-detects)" },
1744
1761
  { name: "/migrate", desc: "Bring a project from Claude Code / Codex / Cursor into horse-code (rules, memory, skills)" },
@@ -3169,7 +3186,7 @@ function ViewportLines({ lines, height }) {
3169
3186
  lines.map((line, i) => /* @__PURE__ */ jsx4(Text4, { children: line.length === 0 ? " " : line.map((s, j) => /* @__PURE__ */ jsx4(Text4, { color: s.color, backgroundColor: s.backgroundColor, bold: s.bold, italic: s.italic, dimColor: s.dim, children: s.text }, j)) }, i))
3170
3187
  ] });
3171
3188
  }
3172
- function App({ controller, fullscreen = false, model, coachModel, refinerModel, listModels, setModel, setRoleModel, listRoles, adjustRoles, modelsPanel, listSessions, resumeSession, listPins, addPin, removePin, listMemories, addMemory, removeMemory, listMcp, sourcesInfo, refreshSources, listSkills, updateSkills, addSkill, graphStatus: graphStatus2, buildGraph, planTraces, runTraces, cleanWorktrees, migrate, continueFromClaude, addMcp, answerByTheWay, telemetryPath, parallel, setParallel, permMode, setPermMode, cancelJob, onExit }) {
3189
+ function App({ controller, fullscreen = false, model, coachModel, refinerModel, listModels, setModel, setRoleModel, listRoles, adjustRoles, modelsPanel, initProject, listSessions, resumeSession, listPins, addPin, removePin, listMemories, addMemory, removeMemory, listMcp, sourcesInfo, refreshSources, listSkills, updateSkills, addSkill, graphStatus: graphStatus2, buildGraph, planTraces, runTraces, cleanWorktrees, migrate, continueFromClaude, addMcp, answerByTheWay, telemetryPath, parallel, setParallel, permMode, setPermMode, cancelJob, onExit }) {
3173
3190
  const [state, setState] = useState3(controller.getState());
3174
3191
  useEffect3(() => controller.subscribe(() => setState(controller.getState())), [controller]);
3175
3192
  const { stdout } = useStdout();
@@ -3625,6 +3642,27 @@ ${rows.join("\n")}
3625
3642
 
3626
3643
  _\`/mcp add <url|command>\` to install another._`);
3627
3644
  };
3645
+ const doInit = async () => {
3646
+ if (!initProject) {
3647
+ controller.note("Project setup is not available.");
3648
+ return;
3649
+ }
3650
+ controller.note("Setting the project up\u2026");
3651
+ let report;
3652
+ try {
3653
+ report = await initProject();
3654
+ } catch (e) {
3655
+ controller.note(`init error: ${e instanceof Error ? e.message : String(e)}`);
3656
+ return;
3657
+ }
3658
+ controller.note(report.text);
3659
+ if (!report.canImport || !migrate) return;
3660
+ if (await controller.ask("Read these and import what they say?", { options: ["Import", "Skip"] }) !== "Import") {
3661
+ controller.note("Left alone. Run `/init` again, or `/migrate`, whenever you want them read.");
3662
+ return;
3663
+ }
3664
+ controller.note(await migrate(report.extra));
3665
+ };
3628
3666
  const doModels = () => {
3629
3667
  if (!modelsPanel) {
3630
3668
  controller.note("Models are not available.");
@@ -3909,6 +3947,7 @@ _\`/skills add <github-url>\` to install one \xB7 \`/skills update\` re-installs
3909
3947
  else if (c.name === "/remember") doRemember("");
3910
3948
  else if (c.name === "/forget") doForget("");
3911
3949
  else if (c.name === "/mcp") doMcp("");
3950
+ else if (c.name === "/init") void doInit();
3912
3951
  else if (c.name === "/models") doModels();
3913
3952
  else if (c.name === "/sources") doSources("");
3914
3953
  else if (c.name === "/skills") doSkills("");
@@ -5569,7 +5608,7 @@ Question: ${question}` }
5569
5608
  };
5570
5609
  const addMcp = async (input) => {
5571
5610
  const { parseCommand, parseConfigBlock, extractFromPage, verify } = await import("./install-O34KMWJB.js");
5572
- const { saveMcpServer } = await import("./save-skills-ZW5GY6KV.js");
5611
+ const { saveMcpServer } = await import("./save-skills-NPKTYNAF.js");
5573
5612
  let cand = parseCommand(input) ?? parseConfigBlock(input);
5574
5613
  if (!cand) {
5575
5614
  const url = input.trim();
@@ -5638,14 +5677,15 @@ _This project has no worktrees under \`.claude/worktrees\`._`}`);
5638
5677
  controller.note(`Could not continue from that worktree: ${e instanceof Error ? e.message : String(e)}`);
5639
5678
  }
5640
5679
  };
5641
- const migrate = async () => {
5680
+ const migrate = async (extra) => {
5642
5681
  if (!opts.memStore) return "Migration needs the memory store, which is not available in this session.";
5643
5682
  const progressLines = /* @__PURE__ */ new Map();
5644
- const { runMigration, describeResult } = await import("./run-P6ZYL5JL.js");
5683
+ const { runMigration, describeResult } = await import("./run-V5ZLZ3LS.js");
5645
5684
  const r = await runMigration({
5646
5685
  cwd: process.cwd(),
5647
5686
  home: homedir2(),
5648
5687
  provider: deps.provider,
5688
+ ...extra?.length ? { extra } : {},
5649
5689
  /**
5650
5690
  * The architect's whole CHAIN, not just its head.
5651
5691
  *
@@ -5720,12 +5760,13 @@ _Restart to pick them up in already-built prompts._` : `No role carries one perm
5720
5760
  };
5721
5761
  const refreshGraphIfStale = async () => {
5722
5762
  try {
5723
- const before = await graphStatus(process.cwd());
5763
+ const dir = await (opts.derivedDir?.() ?? Promise.resolve(process.cwd()));
5764
+ const before = await graphStatus(dir);
5724
5765
  if (before.built && !before.stale) return;
5725
5766
  const first = !before.built;
5726
5767
  controller.note(first ? `\u{1F9E0} Building the code graph for the first time \u2014 this reads the whole project, so it takes a few minutes. It runs once; after this, start-up only updates what changed.` : `\u{1F504} The code graph is out of date \u2014 updating it.`);
5727
5768
  controller.startBusy(first ? "building the code graph" : "updating the code graph");
5728
- const r = await buildProjectGraph(process.cwd());
5769
+ const r = await buildProjectGraph(dir);
5729
5770
  controller.endBusy();
5730
5771
  controller.note(r.ok ? `\u2705 Code graph ready \u2014 ${(r.nodes ?? 0).toLocaleString("en-US")} symbols, ${(r.edges ?? 0).toLocaleString("en-US")} relationships.` : `\u26A0\uFE0F The code graph could not be built: ${r.message}`);
5731
5772
  } catch {
@@ -5907,7 +5948,7 @@ _${saved ? `Saved to your config \u2014 future sessions start with these. ` : ""
5907
5948
  const cwd = process.cwd();
5908
5949
  const main = await recordedMainBranch(cwd) ?? await detectMainBranch(cwd, defaultGitRunner);
5909
5950
  if (!main) return;
5910
- const { ongoingWork, chooseOngoing } = await import("./ongoing-WHYXPW24.js");
5951
+ const { ongoingWork, chooseOngoing } = await import("./ongoing-6NUSPSCV.js");
5911
5952
  const open = await ongoingWork(defaultGitRunner, cwd, main);
5912
5953
  if (!open.length) return;
5913
5954
  const picked = await chooseOngoing(deps, read, open[0]?.language, open);
@@ -5926,11 +5967,11 @@ _${saved ? `Saved to your config \u2014 future sessions start with these. ` : ""
5926
5967
  })();
5927
5968
  void (async () => {
5928
5969
  try {
5929
- const { loadTraceIndex } = await import("./trace-X6TU3AG6.js");
5970
+ const { loadTraceIndex } = await import("./trace-UVMZZRA5.js");
5930
5971
  let index = await loadTraceIndex(process.cwd());
5931
5972
  startupExtra.traces = Object.keys(index.traces).length;
5932
5973
  paintSummary();
5933
- const { graphStatus: graphStatus2 } = await import("./project-graph-5HNPRFQG.js");
5974
+ const { graphStatus: graphStatus2 } = await import("./project-graph-OGIM2B33.js");
5934
5975
  const g = await graphStatus2(process.cwd());
5935
5976
  startupExtra.graph = { built: g.built, nodes: g.nodes, stale: g.stale };
5936
5977
  if (!g.built || g.stale) {
@@ -5939,11 +5980,11 @@ _${saved ? `Saved to your config \u2014 future sessions start with these. ` : ""
5939
5980
  const after = await graphStatus2(process.cwd());
5940
5981
  startupExtra.graph = { built: after.built, nodes: after.nodes, stale: after.stale };
5941
5982
  }
5942
- const g0 = await import("./project-graph-5HNPRFQG.js").then((m) => m.loadGraphSync(process.cwd()));
5983
+ const g0 = await import("./project-graph-OGIM2B33.js").then((m) => m.loadGraphSync(process.cwd()));
5943
5984
  if (g0) {
5944
5985
  const files = /* @__PURE__ */ new Set();
5945
5986
  for (const n of g0.nodes) if (n.source_file) files.add(n.source_file);
5946
- const { adoptDocs, indexAdoption, describeAdoption } = await import("./trace-adopt-URECQWJV.js");
5987
+ const { adoptDocs, indexAdoption, describeAdoption } = await import("./trace-adopt-7HWELJFE.js");
5947
5988
  const adoption = await adoptDocs(process.cwd(), files);
5948
5989
  const { readFile: readFile5 } = await import("fs/promises");
5949
5990
  const r = await indexAdoption(
@@ -5959,8 +6000,8 @@ _${saved ? `Saved to your config \u2014 future sessions start with these. ` : ""
5959
6000
  }
5960
6001
  startupExtra.traces = Object.keys(index.traces).length;
5961
6002
  paintSummary();
5962
- const { traceableFiles } = await import("./trace-run-7U4WJZ3V.js");
5963
- const { traceCoverage } = await import("./trace-X6TU3AG6.js");
6003
+ const { traceableFiles } = await import("./trace-run-OBOD552Q.js");
6004
+ const { traceCoverage } = await import("./trace-UVMZZRA5.js");
5964
6005
  startupExtra.coverage = await traceCoverage(process.cwd(), await traceableFiles(process.cwd()), index);
5965
6006
  paintSummary();
5966
6007
  } catch {
@@ -6077,6 +6118,7 @@ _${saved ? `Saved to your config \u2014 future sessions start with these. ` : ""
6077
6118
  listRoles,
6078
6119
  adjustRoles,
6079
6120
  modelsPanel: opts.modelsPanel,
6121
+ initProject: opts.initProject,
6080
6122
  listSkills: opts.listSkills,
6081
6123
  updateSkills: opts.updateSkills,
6082
6124
  addSkill: opts.addSkill,
@@ -5,11 +5,11 @@ import {
5
5
  memoryHints,
6
6
  readFileTool,
7
7
  reinforceUsed
8
- } from "./chunk-LLL7QWXB.js";
8
+ } from "./chunk-BFIZMM4G.js";
9
9
  import {
10
10
  ToolRegistry,
11
11
  runStructuredRole
12
- } from "./chunk-AE36LLL2.js";
12
+ } from "./chunk-CYLPQWIF.js";
13
13
 
14
14
  // src/engine/triage.ts
15
15
  import { z } from "zod";
@@ -300,7 +300,7 @@ function pruneTooling(doc, alsoDrop = /* @__PURE__ */ new Set()) {
300
300
  async function writtenTracePaths(cwd) {
301
301
  const out = /* @__PURE__ */ new Set();
302
302
  try {
303
- const { loadTraceIndex, traceRootRel } = await import("./trace-X6TU3AG6.js");
303
+ const { loadTraceIndex, traceRootRel } = await import("./trace-UVMZZRA5.js");
304
304
  const index = await loadTraceIndex(cwd);
305
305
  const root = traceRootRel().replace(/\\/g, "/");
306
306
  for (const [file, rec] of Object.entries(index.traces)) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  hashContent,
3
3
  traceDir
4
- } from "./chunk-KAGKX2YT.js";
4
+ } from "./chunk-ZPJP2VH5.js";
5
5
 
6
6
  // src/engine/project-brief.ts
7
7
  import { readFile, writeFile, mkdir } from "fs/promises";
@@ -70,7 +70,7 @@ async function gatherBriefInput(cwd, files) {
70
70
  async function ourOwnOutput(cwd) {
71
71
  const out = /* @__PURE__ */ new Set();
72
72
  try {
73
- const { loadTraceIndex, traceRootRel } = await import("./trace-X6TU3AG6.js");
73
+ const { loadTraceIndex, traceRootRel } = await import("./trace-UVMZZRA5.js");
74
74
  const root = traceRootRel().replace(/\\/g, "/");
75
75
  out.add(`${root}/PROJECT.md`);
76
76
  out.add(`${root}/PROJECT.json`);