@flyingrobots/graft 0.3.5 → 0.5.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 (111) hide show
  1. package/ARCHITECTURE.md +386 -0
  2. package/CHANGELOG.md +69 -0
  3. package/CODE_OF_CONDUCT.md +65 -0
  4. package/README.md +153 -17
  5. package/bin/graft.js +4 -11
  6. package/docs/ADVANCED_GUIDE.md +49 -0
  7. package/docs/CLI.md +43 -0
  8. package/docs/GUIDE.md +321 -32
  9. package/docs/MCP.md +44 -0
  10. package/package.json +17 -4
  11. package/src/adapters/node-fs.ts +4 -0
  12. package/src/adapters/node-git.ts +47 -0
  13. package/src/adapters/node-process-runner.ts +27 -0
  14. package/src/cli/index-cmd.ts +86 -0
  15. package/src/cli/init.ts +808 -57
  16. package/src/cli/main.ts +437 -0
  17. package/src/contracts/capabilities.ts +341 -0
  18. package/src/contracts/causal-ontology.ts +622 -0
  19. package/src/contracts/causal-surface-next-action.ts +18 -0
  20. package/src/contracts/output-schemas.ts +1169 -0
  21. package/src/git/diff.ts +25 -21
  22. package/src/git/target-git-hook-bootstrap.ts +56 -0
  23. package/src/hooks/posttooluse-read.ts +21 -74
  24. package/src/hooks/pretooluse-read.ts +20 -56
  25. package/src/hooks/read-governor.ts +95 -0
  26. package/src/hooks/read-messages.ts +53 -0
  27. package/src/mcp/burden.ts +123 -0
  28. package/src/mcp/cache.ts +51 -0
  29. package/src/mcp/cached-file.ts +10 -8
  30. package/src/mcp/context.ts +67 -2
  31. package/src/mcp/daemon-control-plane.ts +554 -0
  32. package/src/mcp/daemon-job-scheduler.ts +279 -0
  33. package/src/mcp/daemon-repos.ts +216 -0
  34. package/src/mcp/daemon-server.ts +396 -0
  35. package/src/mcp/daemon-worker-pool.ts +310 -0
  36. package/src/mcp/daemon-worker-process.ts +52 -0
  37. package/src/mcp/metrics.ts +108 -1
  38. package/src/mcp/monitor-tick-job.ts +99 -0
  39. package/src/mcp/persisted-local-history.ts +1246 -0
  40. package/src/mcp/persistent-monitor-runtime.ts +549 -0
  41. package/src/mcp/policy.ts +84 -0
  42. package/src/mcp/receipt.ts +82 -12
  43. package/src/mcp/repo-concurrency.ts +318 -0
  44. package/src/mcp/repo-state.ts +777 -0
  45. package/src/mcp/repo-tool-job.ts +302 -0
  46. package/src/mcp/run-capture-config.ts +33 -0
  47. package/src/mcp/runtime-causal-context.ts +72 -0
  48. package/src/mcp/runtime-observability.ts +219 -0
  49. package/src/mcp/runtime-staged-target.ts +161 -0
  50. package/src/mcp/runtime-workspace-overlay.ts +255 -0
  51. package/src/mcp/semantic-transition-guidance.ts +60 -0
  52. package/src/mcp/semantic-transition-summary.ts +130 -0
  53. package/src/mcp/server.ts +704 -45
  54. package/src/mcp/stdio-server.ts +12 -0
  55. package/src/mcp/stdio.ts +2 -5
  56. package/src/mcp/tools/activity-view.ts +325 -0
  57. package/src/mcp/tools/causal-attach.ts +67 -0
  58. package/src/mcp/tools/causal-status.ts +58 -0
  59. package/src/mcp/tools/changed-since.ts +13 -11
  60. package/src/mcp/tools/code-find.ts +164 -0
  61. package/src/mcp/tools/code-refs.ts +466 -0
  62. package/src/mcp/tools/code-show.ts +252 -0
  63. package/src/mcp/tools/daemon-monitors.ts +14 -0
  64. package/src/mcp/tools/daemon-repos.ts +22 -0
  65. package/src/mcp/tools/daemon-sessions.ts +14 -0
  66. package/src/mcp/tools/daemon-status.ts +12 -0
  67. package/src/mcp/tools/doctor.ts +45 -2
  68. package/src/mcp/tools/explain.ts +4 -0
  69. package/src/mcp/tools/file-outline.ts +7 -3
  70. package/src/mcp/tools/git-files.ts +73 -0
  71. package/src/mcp/tools/graft-diff.ts +12 -4
  72. package/src/mcp/tools/map.ts +136 -0
  73. package/src/mcp/tools/monitor-pause.ts +18 -0
  74. package/src/mcp/tools/monitor-resume.ts +18 -0
  75. package/src/mcp/tools/monitor-start.ts +20 -0
  76. package/src/mcp/tools/monitor-stop.ts +18 -0
  77. package/src/mcp/tools/precision-match.ts +51 -0
  78. package/src/mcp/tools/precision-query.ts +127 -0
  79. package/src/mcp/tools/precision.ts +312 -0
  80. package/src/mcp/tools/run-capture.ts +126 -44
  81. package/src/mcp/tools/safe-read.ts +14 -12
  82. package/src/mcp/tools/since.ts +49 -0
  83. package/src/mcp/tools/state.ts +11 -3
  84. package/src/mcp/tools/stats.ts +5 -1
  85. package/src/mcp/tools/workspace-authorizations.ts +14 -0
  86. package/src/mcp/tools/workspace-authorize.ts +20 -0
  87. package/src/mcp/tools/workspace-bind.ts +25 -0
  88. package/src/mcp/tools/workspace-rebind.ts +25 -0
  89. package/src/mcp/tools/workspace-revoke.ts +18 -0
  90. package/src/mcp/tools/workspace-status.ts +12 -0
  91. package/src/mcp/warp-pool.ts +36 -0
  92. package/src/mcp/workspace-router.ts +984 -0
  93. package/src/operations/file-outline.ts +12 -2
  94. package/src/operations/graft-diff.ts +56 -10
  95. package/src/operations/safe-read.ts +27 -4
  96. package/src/operations/state.ts +6 -9
  97. package/src/parser/lang.ts +19 -3
  98. package/src/parser/outline.ts +191 -2
  99. package/src/parser/types.ts +9 -1
  100. package/src/policy/types.ts +4 -3
  101. package/src/ports/filesystem.ts +1 -0
  102. package/src/ports/git.ts +16 -0
  103. package/src/ports/process-runner.ts +22 -0
  104. package/src/release/security-gate.ts +102 -0
  105. package/src/session/tracker.ts +31 -0
  106. package/src/version.ts +3 -0
  107. package/src/warp/indexer.ts +513 -0
  108. package/src/warp/observers.ts +105 -0
  109. package/src/warp/open.ts +31 -0
  110. package/src/warp/plumbing.d.ts +15 -0
  111. package/src/warp/writer-id.ts +30 -0
@@ -0,0 +1,47 @@
1
+ // ---------------------------------------------------------------------------
2
+ // NodeGitClient — implements the GitClient port via GitPlumbing
3
+ // ---------------------------------------------------------------------------
4
+
5
+ import GitPlumbing from "@git-stunts/plumbing";
6
+ import type { GitClient, GitRunRequest } from "../ports/git.js";
7
+
8
+ class NodeGitClient implements GitClient {
9
+ private readonly clients = new Map<string, GitPlumbing>();
10
+
11
+ private resolveClient(cwd: string): GitPlumbing {
12
+ const cached = this.clients.get(cwd);
13
+ if (cached !== undefined) return cached;
14
+ const created = GitPlumbing.createDefault({ cwd });
15
+ this.clients.set(cwd, created);
16
+ return created;
17
+ }
18
+
19
+ async run(request: GitRunRequest) {
20
+ try {
21
+ const plumbing = this.resolveClient(request.cwd);
22
+ const stream = await plumbing.executeStream({ args: [...request.args] });
23
+ const stdout = await stream.collect({
24
+ asString: true,
25
+ ...(request.maxBufferBytes !== undefined ? { maxBytes: request.maxBufferBytes } : {}),
26
+ });
27
+ const finished = await stream.finished;
28
+ const error = "error" in finished && finished.error instanceof Error ? finished.error : undefined;
29
+ return {
30
+ status: finished.code,
31
+ stdout: typeof stdout === "string" ? stdout : new TextDecoder().decode(stdout),
32
+ stderr: finished.stderr,
33
+ ...(error !== undefined ? { error } : {}),
34
+ };
35
+ } catch (error: unknown) {
36
+ const normalized = error instanceof Error ? error : new Error(String(error));
37
+ return {
38
+ status: 1,
39
+ stdout: "",
40
+ stderr: normalized.message,
41
+ error: normalized,
42
+ };
43
+ }
44
+ }
45
+ }
46
+
47
+ export const nodeGit: GitClient = new NodeGitClient();
@@ -0,0 +1,27 @@
1
+ // ---------------------------------------------------------------------------
2
+ // NodeProcessRunner — implements the ProcessRunner port
3
+ // ---------------------------------------------------------------------------
4
+
5
+ import { spawnSync } from "node:child_process";
6
+ import type { ProcessRunRequest, ProcessRunResult, ProcessRunner } from "../ports/process-runner.js";
7
+
8
+ class NodeProcessRunner implements ProcessRunner {
9
+ run(request: ProcessRunRequest): ProcessRunResult {
10
+ const result = spawnSync(request.command, [...request.args], {
11
+ cwd: request.cwd,
12
+ encoding: "utf-8",
13
+ stdio: ["pipe", "pipe", "pipe"],
14
+ ...(request.timeoutMs !== undefined ? { timeout: request.timeoutMs } : {}),
15
+ ...(request.maxBufferBytes !== undefined ? { maxBuffer: request.maxBufferBytes } : {}),
16
+ });
17
+
18
+ return {
19
+ status: result.status,
20
+ stdout: typeof result.stdout === "string" ? result.stdout : "",
21
+ stderr: typeof result.stderr === "string" ? result.stderr : "",
22
+ ...(result.error !== undefined ? { error: result.error } : {}),
23
+ };
24
+ }
25
+ }
26
+
27
+ export const nodeProcessRunner: ProcessRunner = new NodeProcessRunner();
@@ -0,0 +1,86 @@
1
+ import { CanonicalJsonCodec } from "../adapters/canonical-json.js";
2
+ import { nodeGit } from "../adapters/node-git.js";
3
+ import { attachCliSchemaMeta, validateCliOutput } from "../contracts/output-schemas.js";
4
+ import { indexCommits } from "../warp/indexer.js";
5
+ import { openWarp } from "../warp/open.js";
6
+
7
+ const codec = new CanonicalJsonCodec();
8
+
9
+ interface Writer {
10
+ write(chunk: string): unknown;
11
+ }
12
+
13
+ export interface RunIndexOptions {
14
+ cwd?: string | undefined;
15
+ args?: readonly string[] | undefined;
16
+ stdout?: Writer | undefined;
17
+ stderr?: Writer | undefined;
18
+ }
19
+
20
+ function parseIndexArgs(args: readonly string[]): { json: boolean; from: string | null } {
21
+ let json = false;
22
+ let from: string | null = null;
23
+
24
+ for (const arg of args) {
25
+ if (arg === "--json") {
26
+ json = true;
27
+ continue;
28
+ }
29
+ from ??= arg;
30
+ }
31
+
32
+ return { json, from };
33
+ }
34
+
35
+ function writeLine(writer: Writer, line = ""): void {
36
+ writer.write(`${line}\n`);
37
+ }
38
+
39
+ function emitIndexJson(result: Record<string, unknown>, writer: Writer): void {
40
+ writer.write(`${codec.encode(validateCliOutput("index", attachCliSchemaMeta("index", result)))}\n`);
41
+ }
42
+
43
+ export async function runIndex(options: RunIndexOptions = {}): Promise<void> {
44
+ const cwd = options.cwd ?? process.cwd();
45
+ const args = options.args ?? process.argv.slice(3);
46
+ const stdout = options.stdout ?? process.stdout;
47
+ const stderr = options.stderr ?? process.stderr;
48
+ const { json, from } = parseIndexArgs(args);
49
+
50
+ try {
51
+ const warp = await openWarp({ cwd });
52
+ const result = await indexCommits(warp, {
53
+ cwd,
54
+ git: nodeGit,
55
+ ...(from !== null ? { from } : {}),
56
+ });
57
+
58
+ if (json) {
59
+ emitIndexJson({
60
+ ok: true,
61
+ cwd,
62
+ from,
63
+ commitsIndexed: result.commitsIndexed,
64
+ patchesWritten: result.patchesWritten,
65
+ }, stdout);
66
+ return;
67
+ }
68
+
69
+ writeLine(stdout);
70
+ writeLine(stdout, `Indexing structural history in ${cwd}`);
71
+ writeLine(stdout);
72
+ writeLine(stdout, ` commits indexed: ${String(result.commitsIndexed)}`);
73
+ writeLine(stdout, ` patches written: ${String(result.patchesWritten)}`);
74
+ writeLine(stdout);
75
+ writeLine(stdout, "Done.");
76
+ writeLine(stdout);
77
+ } catch (err: unknown) {
78
+ const message = err instanceof Error ? err.message : String(err);
79
+ process.exitCode = 1;
80
+ if (json) {
81
+ emitIndexJson({ ok: false, cwd, from, error: message }, stdout);
82
+ return;
83
+ }
84
+ writeLine(stderr, `Error: ${message}`);
85
+ }
86
+ }