@johnfaleke/fathom 0.1.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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +285 -0
  3. package/dist/ai/provider.d.ts +20 -0
  4. package/dist/ai/provider.d.ts.map +1 -0
  5. package/dist/ai/provider.js +2 -0
  6. package/dist/ai/provider.js.map +1 -0
  7. package/dist/checks/dependencies.d.ts +3 -0
  8. package/dist/checks/dependencies.d.ts.map +1 -0
  9. package/dist/checks/dependencies.js +106 -0
  10. package/dist/checks/dependencies.js.map +1 -0
  11. package/dist/checks/env-vars.d.ts +3 -0
  12. package/dist/checks/env-vars.d.ts.map +1 -0
  13. package/dist/checks/env-vars.js +76 -0
  14. package/dist/checks/env-vars.js.map +1 -0
  15. package/dist/checks/index.d.ts +4 -0
  16. package/dist/checks/index.d.ts.map +1 -0
  17. package/dist/checks/index.js +5 -0
  18. package/dist/checks/index.js.map +1 -0
  19. package/dist/cli.d.ts +3 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +123 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/commands/check.d.ts +4 -0
  24. package/dist/commands/check.d.ts.map +1 -0
  25. package/dist/commands/check.js +32 -0
  26. package/dist/commands/check.js.map +1 -0
  27. package/dist/commands/diff.d.ts +4 -0
  28. package/dist/commands/diff.d.ts.map +1 -0
  29. package/dist/commands/diff.js +30 -0
  30. package/dist/commands/diff.js.map +1 -0
  31. package/dist/commands/init.d.ts +2 -0
  32. package/dist/commands/init.d.ts.map +1 -0
  33. package/dist/commands/init.js +16 -0
  34. package/dist/commands/init.js.map +1 -0
  35. package/dist/commands/status.d.ts +7 -0
  36. package/dist/commands/status.d.ts.map +1 -0
  37. package/dist/commands/status.js +74 -0
  38. package/dist/commands/status.js.map +1 -0
  39. package/dist/core/git.d.ts +4 -0
  40. package/dist/core/git.d.ts.map +1 -0
  41. package/dist/core/git.js +40 -0
  42. package/dist/core/git.js.map +1 -0
  43. package/dist/core/project.d.ts +3 -0
  44. package/dist/core/project.d.ts.map +1 -0
  45. package/dist/core/project.js +59 -0
  46. package/dist/core/project.js.map +1 -0
  47. package/dist/core/runner.d.ts +3 -0
  48. package/dist/core/runner.d.ts.map +1 -0
  49. package/dist/core/runner.js +8 -0
  50. package/dist/core/runner.js.map +1 -0
  51. package/dist/core/storage.d.ts +17 -0
  52. package/dist/core/storage.d.ts.map +1 -0
  53. package/dist/core/storage.js +84 -0
  54. package/dist/core/storage.js.map +1 -0
  55. package/dist/index.d.ts +7 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +5 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/render/terminal.d.ts +5 -0
  60. package/dist/render/terminal.d.ts.map +1 -0
  61. package/dist/render/terminal.js +120 -0
  62. package/dist/render/terminal.js.map +1 -0
  63. package/dist/types.d.ts +61 -0
  64. package/dist/types.d.ts.map +1 -0
  65. package/dist/types.js +3 -0
  66. package/dist/types.js.map +1 -0
  67. package/package.json +50 -0
package/dist/cli.js ADDED
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env node
2
+ import { cmdInit } from "./commands/init.js";
3
+ import { cmdCheck } from "./commands/check.js";
4
+ import { cmdStatus } from "./commands/status.js";
5
+ import { cmdDiff } from "./commands/diff.js";
6
+ const VERSION = "0.1.0";
7
+ function printHelp() {
8
+ console.log(`fathom ${VERSION}
9
+
10
+ Understand the work — local-first Work State with evidence.
11
+
12
+ Usage:
13
+ fathom <command> [options]
14
+
15
+ Commands:
16
+ init Initialize Fathom in the current project
17
+ set [--current <text>] [--complete <item>] [--incomplete <item>]
18
+ Update the active work state
19
+ status [--json] Where does the project actually stand?
20
+ diff [--json] What meaningfully changed (git-backed in v0.1)
21
+ check [--json] Find inconsistencies and forgotten wiring
22
+
23
+ Options:
24
+ -h, --help Show help
25
+ -v, --version Show version
26
+ `);
27
+ }
28
+ async function main() {
29
+ const args = process.argv.slice(2);
30
+ const command = args[0];
31
+ const statusOptions = parseStatusOptions(args.slice(1));
32
+ const json = statusOptions.json || args.includes("--json");
33
+ if (!command || command === "-h" || command === "--help") {
34
+ printHelp();
35
+ return;
36
+ }
37
+ if (command === "-v" || command === "--version") {
38
+ console.log(VERSION);
39
+ return;
40
+ }
41
+ switch (command) {
42
+ case "init":
43
+ process.exitCode = await cmdInit(process.cwd());
44
+ break;
45
+ case "set":
46
+ process.exitCode = await cmdStatus(process.cwd(), {
47
+ json,
48
+ current: statusOptions.current,
49
+ completed: statusOptions.completed,
50
+ incomplete: statusOptions.incomplete,
51
+ });
52
+ break;
53
+ case "status":
54
+ process.exitCode = await cmdStatus(process.cwd(), {
55
+ json,
56
+ current: statusOptions.current,
57
+ completed: statusOptions.completed,
58
+ incomplete: statusOptions.incomplete,
59
+ });
60
+ break;
61
+ case "diff":
62
+ process.exitCode = await cmdDiff(process.cwd(), { json });
63
+ break;
64
+ case "check":
65
+ process.exitCode = await cmdCheck(process.cwd(), { json });
66
+ break;
67
+ default:
68
+ console.error(`Unknown command: ${command}`);
69
+ printHelp();
70
+ process.exitCode = 1;
71
+ }
72
+ }
73
+ function parseStatusOptions(args) {
74
+ const result = {
75
+ json: false,
76
+ current: undefined,
77
+ completed: undefined,
78
+ incomplete: undefined,
79
+ };
80
+ for (let i = 0; i < args.length; i += 1) {
81
+ const arg = args[i];
82
+ if (arg === "--json") {
83
+ result.json = true;
84
+ continue;
85
+ }
86
+ if (arg === "--current") {
87
+ const value = args[i + 1];
88
+ if (value && !value.startsWith("--")) {
89
+ result.current = value;
90
+ i += 1;
91
+ }
92
+ continue;
93
+ }
94
+ if (arg === "--complete") {
95
+ const value = args[i + 1];
96
+ if (value && !value.startsWith("--")) {
97
+ result.completed = splitList(value);
98
+ i += 1;
99
+ }
100
+ continue;
101
+ }
102
+ if (arg === "--incomplete") {
103
+ const value = args[i + 1];
104
+ if (value && !value.startsWith("--")) {
105
+ result.incomplete = splitList(value);
106
+ i += 1;
107
+ }
108
+ continue;
109
+ }
110
+ }
111
+ return result;
112
+ }
113
+ function splitList(value) {
114
+ return value
115
+ .split(",")
116
+ .map((item) => item.trim())
117
+ .filter(Boolean);
118
+ }
119
+ main().catch((err) => {
120
+ console.error(err);
121
+ process.exitCode = 1;
122
+ });
123
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO;;;;;;;;;;;;;;;;;;CAkB9B,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAExB,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAE3D,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzD,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IACD,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,CAAC,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YAChD,MAAM;QACR,KAAK,KAAK;YACR,OAAO,CAAC,QAAQ,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE;gBAChD,IAAI;gBACJ,OAAO,EAAE,aAAa,CAAC,OAAO;gBAC9B,SAAS,EAAE,aAAa,CAAC,SAAS;gBAClC,UAAU,EAAE,aAAa,CAAC,UAAU;aACrC,CAAC,CAAC;YACH,MAAM;QACR,KAAK,QAAQ;YACX,OAAO,CAAC,QAAQ,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE;gBAChD,IAAI;gBACJ,OAAO,EAAE,aAAa,CAAC,OAAO;gBAC9B,SAAS,EAAE,aAAa,CAAC,SAAS;gBAClC,UAAU,EAAE,aAAa,CAAC,UAAU;aACrC,CAAC,CAAC;YACH,MAAM;QACR,KAAK,MAAM;YACT,OAAO,CAAC,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,MAAM;QACR,KAAK,OAAO;YACV,OAAO,CAAC,QAAQ,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,MAAM;QACR;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;YAC7C,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAc;IAMxC,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,SAAsC;QAC/C,SAAS,EAAE,SAAiC;QAC5C,UAAU,EAAE,SAAiC;KAC9C,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;YACnB,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1B,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;gBACvB,CAAC,IAAI,CAAC,CAAC;YACT,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1B,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrC,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;gBACpC,CAAC,IAAI,CAAC,CAAC;YACT,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,cAAc,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1B,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrC,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;gBACrC,CAAC,IAAI,CAAC,CAAC;YACT,CAAC;YACD,SAAS;QACX,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function cmdCheck(cwd: string, opts?: {
2
+ json?: boolean;
3
+ }): Promise<number>;
4
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAcA,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5B,OAAO,CAAC,MAAM,CAAC,CA4BjB"}
@@ -0,0 +1,32 @@
1
+ import path from "node:path";
2
+ import { builtinChecks } from "../checks/index.js";
3
+ import { createProjectContext } from "../core/project.js";
4
+ import { runChecks } from "../core/runner.js";
5
+ import { appendEvent, applyFindings, isInitialized, loadConfig, loadState, saveState, } from "../core/storage.js";
6
+ import { renderFindings } from "../render/terminal.js";
7
+ export async function cmdCheck(cwd, opts = {}) {
8
+ const root = path.resolve(cwd);
9
+ if (!(await isInitialized(root))) {
10
+ console.error("Fathom is not initialized. Run `fathom init` first.");
11
+ return 1;
12
+ }
13
+ const config = await loadConfig(root);
14
+ const ctx = await createProjectContext(root, config);
15
+ const findings = await runChecks(ctx, builtinChecks);
16
+ let state = await loadState(root);
17
+ state = applyFindings(state, findings);
18
+ await saveState(root, state);
19
+ await appendEvent(root, {
20
+ type: "check",
21
+ at: new Date().toISOString(),
22
+ findingCount: findings.length,
23
+ });
24
+ if (opts.json) {
25
+ console.log(JSON.stringify({ findings, attention: state.attention }, null, 2));
26
+ }
27
+ else {
28
+ process.stdout.write(renderFindings(findings));
29
+ }
30
+ return findings.some((f) => f.severity === "warning") ? 2 : 0;
31
+ }
32
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EACL,WAAW,EACX,aAAa,EACb,aAAa,EACb,UAAU,EACV,SAAS,EACT,SAAS,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,GAAW,EACX,OAA2B,EAAE;IAE7B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAE/B,IAAI,CAAC,CAAC,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACrE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAErD,IAAI,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,GAAG,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACvC,MAAM,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC7B,MAAM,WAAW,CAAC,IAAI,EAAE;QACtB,IAAI,EAAE,OAAO;QACb,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,YAAY,EAAE,QAAQ,CAAC,MAAM;KAC9B,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACjF,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function cmdDiff(cwd: string, opts?: {
2
+ json?: boolean;
3
+ }): Promise<number>;
4
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAKA,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5B,OAAO,CAAC,MAAM,CAAC,CA6BjB"}
@@ -0,0 +1,30 @@
1
+ import path from "node:path";
2
+ import { gitChangedFiles, gitDiffStat, gitIsRepo } from "../core/git.js";
3
+ import { appendEvent, isInitialized } from "../core/storage.js";
4
+ import { renderDiff } from "../render/terminal.js";
5
+ export async function cmdDiff(cwd, opts = {}) {
6
+ const root = path.resolve(cwd);
7
+ if (!(await isInitialized(root))) {
8
+ console.error("Fathom is not initialized. Run `fathom init` first.");
9
+ return 1;
10
+ }
11
+ if (!(await gitIsRepo(root))) {
12
+ console.error("Not a git repository — semantic diff needs git for v0.1.");
13
+ return 1;
14
+ }
15
+ const files = await gitChangedFiles(root);
16
+ const summary = await gitDiffStat(root);
17
+ await appendEvent(root, {
18
+ type: "diff",
19
+ at: new Date().toISOString(),
20
+ filesChanged: files.length,
21
+ });
22
+ if (opts.json) {
23
+ console.log(JSON.stringify({ files, summary }, null, 2));
24
+ }
25
+ else {
26
+ process.stdout.write(renderDiff(summary, files));
27
+ }
28
+ return 0;
29
+ }
30
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAW,EACX,OAA2B,EAAE;IAE7B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAE/B,IAAI,CAAC,CAAC,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACrE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC1E,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;IAExC,MAAM,WAAW,CAAC,IAAI,EAAE;QACtB,IAAI,EAAE,MAAM;QACZ,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,YAAY,EAAE,KAAK,CAAC,MAAM;KAC3B,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function cmdInit(cwd: string): Promise<number>;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAOA,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAc1D"}
@@ -0,0 +1,16 @@
1
+ import path from "node:path";
2
+ import { initFathom, isInitialized, fathomPaths, } from "../core/storage.js";
3
+ export async function cmdInit(cwd) {
4
+ const root = path.resolve(cwd);
5
+ if (await isInitialized(root)) {
6
+ console.log(`Fathom already initialized at ${fathomPaths(root).dir}`);
7
+ return 0;
8
+ }
9
+ await initFathom(root);
10
+ console.log(`Initialized Fathom in ${fathomPaths(root).dir}`);
11
+ console.log(` state.json — current Work State`);
12
+ console.log(` events.jsonl — append-only observations`);
13
+ console.log(` config.json — local configuration`);
14
+ return 0;
15
+ }
16
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,UAAU,EACV,aAAa,EACb,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAE5B,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAE/B,IAAI,MAAM,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,iCAAiC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QACtE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,yBAAyB,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IACpD,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare function cmdStatus(cwd: string, opts?: {
2
+ json?: boolean;
3
+ current?: string | null;
4
+ completed?: string[];
5
+ incomplete?: string[];
6
+ }): Promise<number>;
7
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAgBA,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IACJ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB,GACL,OAAO,CAAC,MAAM,CAAC,CA6CjB"}
@@ -0,0 +1,74 @@
1
+ import path from "node:path";
2
+ import { builtinChecks } from "../checks/index.js";
3
+ import { gitChangedFiles } from "../core/git.js";
4
+ import { createProjectContext } from "../core/project.js";
5
+ import { runChecks } from "../core/runner.js";
6
+ import { appendEvent, applyFindings, isInitialized, loadConfig, loadState, saveState, } from "../core/storage.js";
7
+ import { renderStatus } from "../render/terminal.js";
8
+ export async function cmdStatus(cwd, opts = {}) {
9
+ const root = path.resolve(cwd);
10
+ if (!(await isInitialized(root))) {
11
+ console.error("Fathom is not initialized. Run `fathom init` first.");
12
+ return 1;
13
+ }
14
+ const config = await loadConfig(root);
15
+ const ctx = await createProjectContext(root, config);
16
+ const findings = await runChecks(ctx, builtinChecks);
17
+ const changed = await gitChangedFiles(root);
18
+ let state = await loadState(root);
19
+ state = applyFindings(state, findings);
20
+ if (opts.current !== undefined) {
21
+ state.currentWork = opts.current || null;
22
+ }
23
+ if (opts.completed !== undefined) {
24
+ state.completed = mergeWorkItems(state.completed, opts.completed, "completed");
25
+ }
26
+ if (opts.incomplete !== undefined) {
27
+ state.incomplete = mergeWorkItems(state.incomplete, opts.incomplete, "incomplete");
28
+ }
29
+ state.changes = {
30
+ filesChanged: changed.length,
31
+ summary: changed.slice(0, 20).map((f) => `~ ${f}`),
32
+ };
33
+ await saveState(root, state);
34
+ await appendEvent(root, {
35
+ type: "status",
36
+ at: new Date().toISOString(),
37
+ findingCount: findings.length,
38
+ filesChanged: changed.length,
39
+ });
40
+ if (opts.json) {
41
+ console.log(JSON.stringify(state, null, 2));
42
+ }
43
+ else {
44
+ process.stdout.write(renderStatus(state));
45
+ }
46
+ return 0;
47
+ }
48
+ function mergeWorkItems(current, nextTitles, status) {
49
+ const clean = nextTitles
50
+ .map((title) => title.trim())
51
+ .filter(Boolean);
52
+ const seen = new Set();
53
+ const merged = [];
54
+ for (const item of current) {
55
+ const key = item.title.trim().toLowerCase();
56
+ if (!seen.has(key) && item.status === status) {
57
+ seen.add(key);
58
+ merged.push(item);
59
+ }
60
+ }
61
+ for (const title of clean) {
62
+ const key = title.toLowerCase();
63
+ if (seen.has(key))
64
+ continue;
65
+ seen.add(key);
66
+ merged.push({
67
+ id: `${status}-${title.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`,
68
+ title,
69
+ status,
70
+ });
71
+ }
72
+ return merged;
73
+ }
74
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EACL,WAAW,EACX,aAAa,EACb,aAAa,EACb,UAAU,EACV,SAAS,EACT,SAAS,GACV,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAW,EACX,OAKI,EAAE;IAEN,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAE/B,IAAI,CAAC,CAAC,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACrE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAE5C,IAAI,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,GAAG,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAEvC,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;IAC3C,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACjC,KAAK,CAAC,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAClC,KAAK,CAAC,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACrF,CAAC;IAED,KAAK,CAAC,OAAO,GAAG;QACd,YAAY,EAAE,OAAO,CAAC,MAAM;QAC5B,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;KACnD,CAAC;IACF,MAAM,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC7B,MAAM,WAAW,CAAC,IAAI,EAAE;QACtB,IAAI,EAAE,QAAQ;QACd,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,YAAY,EAAE,QAAQ,CAAC,MAAM;QAC7B,YAAY,EAAE,OAAO,CAAC,MAAM;KAC7B,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,cAAc,CACrB,OAAmB,EACnB,UAAoB,EACpB,MAAkC;IAElC,MAAM,KAAK,GAAG,UAAU;SACrB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAe,EAAE,CAAC;IAE9B,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,MAAM,CAAC,IAAI,CAAC;YACV,EAAE,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,EAAE;YAClE,KAAK;YACL,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function gitChangedFiles(root: string): Promise<string[]>;
2
+ export declare function gitDiffStat(root: string): Promise<string[]>;
3
+ export declare function gitIsRepo(root: string): Promise<boolean>;
4
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/core/git.ts"],"names":[],"mappings":"AAKA,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAerE;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAcjE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAS9D"}
@@ -0,0 +1,40 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ const execFileAsync = promisify(execFile);
4
+ export async function gitChangedFiles(root) {
5
+ try {
6
+ const { stdout } = await execFileAsync("git", ["status", "--porcelain"], { cwd: root });
7
+ return stdout
8
+ .split(/\r?\n/)
9
+ .map((line) => line.trim())
10
+ .filter(Boolean)
11
+ .map((line) => line.replace(/^[MADRCU?!\s]{1,2}\s+/, "").replace(/^.* -> /, ""));
12
+ }
13
+ catch {
14
+ return [];
15
+ }
16
+ }
17
+ export async function gitDiffStat(root) {
18
+ try {
19
+ const { stdout } = await execFileAsync("git", ["diff", "--stat", "HEAD"], { cwd: root });
20
+ return stdout
21
+ .split(/\r?\n/)
22
+ .map((l) => l.trim())
23
+ .filter(Boolean);
24
+ }
25
+ catch {
26
+ return [];
27
+ }
28
+ }
29
+ export async function gitIsRepo(root) {
30
+ try {
31
+ await execFileAsync("git", ["rev-parse", "--is-inside-work-tree"], {
32
+ cwd: root,
33
+ });
34
+ return true;
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ }
40
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/core/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY;IAChD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CACpC,KAAK,EACL,CAAC,QAAQ,EAAE,aAAa,CAAC,EACzB,EAAE,GAAG,EAAE,IAAI,EAAE,CACd,CAAC;QACF,OAAO,MAAM;aACV,KAAK,CAAC,OAAO,CAAC;aACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aAC1B,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;IACrF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CACpC,KAAK,EACL,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,EAC1B,EAAE,GAAG,EAAE,IAAI,EAAE,CACd,CAAC;QACF,OAAO,MAAM;aACV,KAAK,CAAC,OAAO,CAAC;aACd,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY;IAC1C,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,EAAE;YACjE,GAAG,EAAE,IAAI;SACV,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { FathomConfig, ProjectContext } from "../types.js";
2
+ export declare function createProjectContext(root: string, config?: FathomConfig): Promise<ProjectContext>;
3
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/core/project.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAehE,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,cAAc,CAAC,CAwBzB"}
@@ -0,0 +1,59 @@
1
+ import { readdir, readFile, access } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { FATHOM_DIR } from "./storage.js";
4
+ const DEFAULT_IGNORE = [
5
+ "node_modules",
6
+ "dist",
7
+ ".git",
8
+ FATHOM_DIR,
9
+ "coverage",
10
+ ".next",
11
+ "build",
12
+ ".turbo",
13
+ ".cache",
14
+ ];
15
+ export async function createProjectContext(root, config) {
16
+ const ignore = new Set([...(config?.ignore ?? DEFAULT_IGNORE)]);
17
+ const files = await walkFiles(root, root, ignore);
18
+ return {
19
+ root,
20
+ fathomDir: path.join(root, FATHOM_DIR),
21
+ files,
22
+ async readText(relPath) {
23
+ try {
24
+ return await readFile(path.join(root, relPath), "utf8");
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ },
30
+ async exists(relPath) {
31
+ try {
32
+ await access(path.join(root, relPath));
33
+ return true;
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ },
39
+ };
40
+ }
41
+ async function walkFiles(root, dir, ignore) {
42
+ const entries = await readdir(dir, { withFileTypes: true });
43
+ const out = [];
44
+ for (const entry of entries) {
45
+ if (ignore.has(entry.name))
46
+ continue;
47
+ if (entry.name.startsWith(".") && entry.name !== ".env.example")
48
+ continue;
49
+ const abs = path.join(dir, entry.name);
50
+ if (entry.isDirectory()) {
51
+ out.push(...(await walkFiles(root, abs, ignore)));
52
+ }
53
+ else if (entry.isFile()) {
54
+ out.push(path.relative(root, abs).split(path.sep).join("/"));
55
+ }
56
+ }
57
+ return out;
58
+ }
59
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/core/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,cAAc,GAAG;IACrB,cAAc;IACd,MAAM;IACN,MAAM;IACN,UAAU;IACV,UAAU;IACV,OAAO;IACP,OAAO;IACP,QAAQ;IACR,QAAQ;CACT,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAY,EACZ,MAAqB;IAErB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAElD,OAAO;QACL,IAAI;QACJ,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC;QACtC,KAAK;QACL,KAAK,CAAC,QAAQ,CAAC,OAAe;YAC5B,IAAI,CAAC;gBACH,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;YAC1D,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,OAAe;YAC1B,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;gBACvC,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,SAAS,CACtB,IAAY,EACZ,GAAW,EACX,MAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAa,EAAE,CAAC;IAEzB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QACrC,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;YAAE,SAAS;QAE1E,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QACpD,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Check, Finding, ProjectContext } from "../types.js";
2
+ export declare function runChecks(ctx: ProjectContext, checks: Check[]): Promise<Finding[]>;
3
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/core/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElE,wBAAsB,SAAS,CAC7B,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,KAAK,EAAE,GACd,OAAO,CAAC,OAAO,EAAE,CAAC,CAMpB"}
@@ -0,0 +1,8 @@
1
+ export async function runChecks(ctx, checks) {
2
+ const findings = [];
3
+ for (const check of checks) {
4
+ findings.push(...(await check.run(ctx)));
5
+ }
6
+ return findings;
7
+ }
8
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/core/runner.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAmB,EACnB,MAAe;IAEf,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { FathomConfig, Finding, WorkState } from "../types.js";
2
+ export declare const FATHOM_DIR = ".fathom";
3
+ export declare function fathomPaths(root: string): {
4
+ dir: string;
5
+ state: string;
6
+ events: string;
7
+ config: string;
8
+ };
9
+ export declare function isInitialized(root: string): Promise<boolean>;
10
+ export declare function initFathom(root: string): Promise<void>;
11
+ export declare function emptyWorkState(root: string): WorkState;
12
+ export declare function loadConfig(root: string): Promise<FathomConfig>;
13
+ export declare function loadState(root: string): Promise<WorkState>;
14
+ export declare function saveState(root: string, state: WorkState): Promise<void>;
15
+ export declare function appendEvent(root: string, event: Record<string, unknown>): Promise<void>;
16
+ export declare function applyFindings(state: WorkState, findings: Finding[]): WorkState;
17
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/core/storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGpE,eAAO,MAAM,UAAU,YAAY,CAAC;AAEpC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM;;;;;EAQvC;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOlE;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC5D;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAYtD;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAGpE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAGhE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAO7E;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,SAAS,CAM9E"}
@@ -0,0 +1,84 @@
1
+ import { mkdir, readFile, writeFile, appendFile, access } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { WORK_STATE_VERSION } from "../types.js";
4
+ export const FATHOM_DIR = ".fathom";
5
+ export function fathomPaths(root) {
6
+ const dir = path.join(root, FATHOM_DIR);
7
+ return {
8
+ dir,
9
+ state: path.join(dir, "state.json"),
10
+ events: path.join(dir, "events.jsonl"),
11
+ config: path.join(dir, "config.json"),
12
+ };
13
+ }
14
+ export async function isInitialized(root) {
15
+ try {
16
+ await access(fathomPaths(root).dir);
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ export async function initFathom(root) {
24
+ const paths = fathomPaths(root);
25
+ await mkdir(paths.dir, { recursive: true });
26
+ const config = {
27
+ version: 1,
28
+ ignore: ["node_modules", "dist", ".git", ".fathom", "coverage", ".next"],
29
+ };
30
+ const state = emptyWorkState(root);
31
+ const envExamplePath = path.join(root, ".env.example");
32
+ await writeFile(paths.config, JSON.stringify(config, null, 2) + "\n", "utf8");
33
+ await writeFile(paths.state, JSON.stringify(state, null, 2) + "\n", "utf8");
34
+ await writeFile(paths.events, "", "utf8");
35
+ await writeFile(envExamplePath, [
36
+ "# Copy this file to .env and replace placeholders with real values.",
37
+ "# Fathom uses this file as the canonical environment reference.",
38
+ "",
39
+ "# Example variables",
40
+ "PORT=3000",
41
+ "NODE_ENV=development",
42
+ "",
43
+ ].join("\n") + "\n", "utf8");
44
+ await appendEvent(root, {
45
+ type: "init",
46
+ at: new Date().toISOString(),
47
+ });
48
+ }
49
+ export function emptyWorkState(root) {
50
+ return {
51
+ version: WORK_STATE_VERSION,
52
+ updatedAt: new Date().toISOString(),
53
+ root,
54
+ currentWork: null,
55
+ completed: [],
56
+ incomplete: [],
57
+ findings: [],
58
+ changes: { filesChanged: 0, summary: [] },
59
+ attention: 0,
60
+ };
61
+ }
62
+ export async function loadConfig(root) {
63
+ const raw = await readFile(fathomPaths(root).config, "utf8");
64
+ return JSON.parse(raw);
65
+ }
66
+ export async function loadState(root) {
67
+ const raw = await readFile(fathomPaths(root).state, "utf8");
68
+ return JSON.parse(raw);
69
+ }
70
+ export async function saveState(root, state) {
71
+ state.updatedAt = new Date().toISOString();
72
+ await writeFile(fathomPaths(root).state, JSON.stringify(state, null, 2) + "\n", "utf8");
73
+ }
74
+ export async function appendEvent(root, event) {
75
+ await appendFile(fathomPaths(root).events, JSON.stringify(event) + "\n", "utf8");
76
+ }
77
+ export function applyFindings(state, findings) {
78
+ return {
79
+ ...state,
80
+ findings,
81
+ attention: findings.filter((f) => f.severity !== "info").length,
82
+ };
83
+ }
84
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/core/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export type { Check, Evidence, Finding, FathomConfig, ProjectContext, Severity, WorkItem, WorkState, WorkStateSnapshot, WorkStateSummary, } from "./types.js";
2
+ export { WORK_STATE_VERSION } from "./types.js";
3
+ export { builtinChecks } from "./checks/index.js";
4
+ export { runChecks } from "./core/runner.js";
5
+ export { createProjectContext } from "./core/project.js";
6
+ export type { AIInterpretationRequest, AIInterpretationResult, AIProvider, ProviderType, } from "./ai/provider.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,KAAK,EACL,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,YAAY,EACV,uBAAuB,EACvB,sBAAsB,EACtB,UAAU,EACV,YAAY,GACb,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { WORK_STATE_VERSION } from "./types.js";
2
+ export { builtinChecks } from "./checks/index.js";
3
+ export { runChecks } from "./core/runner.js";
4
+ export { createProjectContext } from "./core/project.js";
5
+ //# sourceMappingURL=index.js.map