fanout-cli 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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unfinished.d.ts","sourceRoot":"","sources":["../src/unfinished.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,UAAU,EAAE,KAAK,WAAW,EAA+B,MAAM,aAAa,CAAC;AAc7G,oEAAoE;AACpE,MAAM,WAAW,OAAO;IACtB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,OAAO,EAAE,UAAU,GAAG,SAAS,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAuBjD;AAED,MAAM,WAAW,IAAI;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI,EAAE,CA8BnE;AAOD,kGAAkG;AAClG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,IAAI,EAAE,EAAE,GAAG,SAAK,GAAG,MAAM,CAcxE"}
@@ -0,0 +1,84 @@
1
+ import { mergeReadiness } from "fanout-core";
2
+ /**
3
+ * What to say about the lead's own changes.
4
+ *
5
+ * The runs a crew produced are the obvious thing to guard, and they are not where most of a session's code comes
6
+ * from: the lead writes it, and the lead is its only reader. A check nobody is reminded of is a check nobody runs,
7
+ * which is why this asks about the working tree and not only about the mission.
8
+ */
9
+ export function ownWorkOwed(work) {
10
+ if (work.files === 0)
11
+ return "";
12
+ const changed = `${String(work.files)} changed file${work.files === 1 ? "" : "s"}`;
13
+ if (work.checked === undefined) {
14
+ return ` ${changed}, and nobody but you has read them. Try: fanout check "<something you believe>"`;
15
+ }
16
+ if (work.checked.revision !== work.revision) {
17
+ // A check of older bytes is not a check of these ones, and saying "checked" here would be the lie.
18
+ return ` ${changed}, and they have moved since the last check. Run it again.`;
19
+ }
20
+ if (!work.checked.ran) {
21
+ return ` ${changed}, and the last check could not run at all.`;
22
+ }
23
+ const refuted = work.checked.claims.filter((claim) => claim.verdict === "refuted");
24
+ if (refuted.length > 0) {
25
+ return [
26
+ ` ${String(refuted.length)} of your own claims was refuted and is not fixed:`,
27
+ ...refuted.map((claim) => ` ✗ ${claim.claim}\n ${claim.evidence}`),
28
+ ].join("\n");
29
+ }
30
+ return "";
31
+ }
32
+ /**
33
+ * Every run that is waiting on the lead: finished agents nobody has reviewed, checks nobody has run, fixes with
34
+ * no proof, work reviewed at a revision that has since moved.
35
+ *
36
+ * Runs still working are deliberately not here. They are not owed by anyone; they are simply not done, and the
37
+ * mission view says so already.
38
+ */
39
+ export function whatIsOwed(missions) {
40
+ const owed = [];
41
+ for (const mission of missions) {
42
+ const lines = new Map((mission.plan?.lines ?? []).map((line) => [line.id, line]));
43
+ for (const runId of mission.runOrder) {
44
+ const run = mission.runs[runId];
45
+ if (run === undefined || !waitingOnTheLead(run))
46
+ continue;
47
+ const line = lines.get(run.lineId);
48
+ if (line === undefined) {
49
+ owed.push({ missionId: mission.missionId, runId, what: "finished, but its plan line is missing" });
50
+ continue;
51
+ }
52
+ /*
53
+ * The run's own recorded revision is the best we can do from the ledger alone: a hook must not go and read
54
+ * the worktree, because it runs on every turn and must stay fast. Asking readiness about the revision the
55
+ * review saw answers "is anything missing", which is the hook's question — "has the work moved since" is
56
+ * the merge tool's, and it recollects the diff to find out.
57
+ */
58
+ const judged = run.review?.revision ?? run.checks?.revision ?? run.approval?.revision ?? "";
59
+ const { blockers } = mergeReadiness(run, line, judged);
60
+ const first = blockers[0];
61
+ if (first !== undefined)
62
+ owed.push({ missionId: mission.missionId, runId, what: first.message });
63
+ }
64
+ }
65
+ return owed;
66
+ }
67
+ /** A run the agent has finished with, that has not yet been merged, dropped or run into a conflict. */
68
+ function waitingOnTheLead(run) {
69
+ return run.status === "done";
70
+ }
71
+ /** The hook's whole output. Empty string when nothing is owed, so a quiet session stays quiet. */
72
+ export function unfinishedReport(owed, own = "") {
73
+ const parts = [];
74
+ if (owed.length > 0) {
75
+ const lines = owed.map((item) => ` ${item.missionId} · ${item.runId}: ${item.what}`);
76
+ const count = `${String(owed.length)} run${owed.length === 1 ? "" : "s"}`;
77
+ parts.push(`${count} still waiting on you before anything can merge.\n${lines.join("\n")}\n` +
78
+ `Nothing has been merged. Review them, or drop them on purpose.`);
79
+ }
80
+ if (own !== "")
81
+ parts.push(`Your own changes:\n${own}`);
82
+ return parts.length === 0 ? "" : `Fanout: ${parts.join("\n\n")}\n`;
83
+ }
84
+ //# sourceMappingURL=unfinished.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unfinished.js","sourceRoot":"","sources":["../src/unfinished.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "fanout-cli",
3
+ "version": "0.7.0",
4
+ "description": "Let Claude Code lead the other coding-agent CLIs you already pay for.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "engines": {
8
+ "node": ">=22.18"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/elberacasa/fanout.git",
13
+ "directory": "packages/cli"
14
+ },
15
+ "homepage": "https://github.com/elberacasa/fanout#readme",
16
+ "bin": {
17
+ "fanout": "./dist/cli.js"
18
+ },
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/main.d.ts",
22
+ "default": "./dist/main.js"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "README.md",
28
+ "LICENSE"
29
+ ],
30
+ "dependencies": {
31
+ "@modelcontextprotocol/sdk": "1.30.0",
32
+ "fanout-adapter-claude": "0.7.0",
33
+ "fanout-adapter-codex": "0.7.0",
34
+ "fanout-core": "0.7.0",
35
+ "fanout-adapter-grok": "0.7.0",
36
+ "fanout-mcp": "0.7.0",
37
+ "fanout-adapter-fake": "0.7.0",
38
+ "fanout-daemon": "0.7.0"
39
+ },
40
+ "scripts": {
41
+ "typecheck": "tsc -p tsconfig.json",
42
+ "build": "tsc -p tsconfig.build.json"
43
+ }
44
+ }