@nanonets/graft 0.21.1 → 0.22.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.
- package/README.md +549 -315
- package/dist/app/review-process.d.ts.map +1 -1
- package/dist/app/review-process.js +6 -5
- package/dist/app/review-process.js.map +1 -1
- package/dist/app/sources.js +2 -2
- package/dist/app/sources.js.map +1 -1
- package/dist/ask/ask.d.ts +12 -6
- package/dist/ask/ask.d.ts.map +1 -1
- package/dist/ask/ask.js +28 -38
- package/dist/ask/ask.js.map +1 -1
- package/dist/bin/graft.d.ts +3 -0
- package/dist/bin/graft.d.ts.map +1 -0
- package/dist/bin/graft.js +8 -0
- package/dist/bin/graft.js.map +1 -0
- package/dist/bin/trail.d.ts +3 -0
- package/dist/bin/trail.d.ts.map +1 -0
- package/dist/bin/trail.js +6 -0
- package/dist/bin/trail.js.map +1 -0
- package/dist/blast/blast-cli.d.ts.map +1 -1
- package/dist/blast/blast-cli.js +2 -1
- package/dist/blast/blast-cli.js.map +1 -1
- package/dist/blast/render.d.ts.map +1 -1
- package/dist/blast/render.js +3 -2
- package/dist/blast/render.js.map +1 -1
- package/dist/brand.d.ts +97 -0
- package/dist/brand.d.ts.map +1 -0
- package/dist/brand.js +254 -0
- package/dist/brand.js.map +1 -0
- package/dist/check/local-check.d.ts +104 -0
- package/dist/check/local-check.d.ts.map +1 -0
- package/dist/check/local-check.js +830 -0
- package/dist/check/local-check.js.map +1 -0
- package/dist/check/types.d.ts +31 -0
- package/dist/check/types.d.ts.map +1 -0
- package/dist/check/types.js +2 -0
- package/dist/check/types.js.map +1 -0
- package/dist/claude/format.d.ts +44 -1
- package/dist/claude/format.d.ts.map +1 -1
- package/dist/claude/format.js +113 -19
- package/dist/claude/format.js.map +1 -1
- package/dist/claude/hook-layers.d.ts +8 -0
- package/dist/claude/hook-layers.d.ts.map +1 -0
- package/dist/claude/hook-layers.js +72 -0
- package/dist/claude/hook-layers.js.map +1 -0
- package/dist/claude/hooks.d.ts +34 -0
- package/dist/claude/hooks.d.ts.map +1 -1
- package/dist/claude/hooks.js +220 -12
- package/dist/claude/hooks.js.map +1 -1
- package/dist/claude/init.d.ts +12 -1
- package/dist/claude/init.d.ts.map +1 -1
- package/dist/claude/init.js +48 -19
- package/dist/claude/init.js.map +1 -1
- package/dist/claude/session-metrics.d.ts +1 -1
- package/dist/claude/session-metrics.d.ts.map +1 -1
- package/dist/claude/session-metrics.js +11 -8
- package/dist/claude/session-metrics.js.map +1 -1
- package/dist/claude/settings-merge.d.ts +1 -0
- package/dist/claude/settings-merge.d.ts.map +1 -1
- package/dist/claude/settings-merge.js +21 -18
- package/dist/claude/settings-merge.js.map +1 -1
- package/dist/claude/shim-template.d.ts +17 -2
- package/dist/claude/shim-template.d.ts.map +1 -1
- package/dist/claude/shim-template.js +116 -22
- package/dist/claude/shim-template.js.map +1 -1
- package/dist/claude/skill-template.d.ts +10 -1
- package/dist/claude/skill-template.d.ts.map +1 -1
- package/dist/claude/skill-template.js +132 -1
- package/dist/claude/skill-template.js.map +1 -1
- package/dist/claude/state.d.ts +8 -0
- package/dist/claude/state.d.ts.map +1 -1
- package/dist/claude/state.js.map +1 -1
- package/dist/claude/statusline.d.ts.map +1 -1
- package/dist/claude/statusline.js +4 -1
- package/dist/claude/statusline.js.map +1 -1
- package/dist/claude/tally.js +1 -1
- package/dist/claude/tally.js.map +1 -1
- package/dist/cli-epilogue.d.ts +0 -6
- package/dist/cli-epilogue.d.ts.map +1 -1
- package/dist/cli-epilogue.js +5 -4
- package/dist/cli-epilogue.js.map +1 -1
- package/dist/cli-meta.d.ts +8 -0
- package/dist/cli-meta.d.ts.map +1 -1
- package/dist/cli-meta.js +28 -8
- package/dist/cli-meta.js.map +1 -1
- package/dist/cli-picker.d.ts.map +1 -1
- package/dist/cli-picker.js +11 -7
- package/dist/cli-picker.js.map +1 -1
- package/dist/cli.d.ts +0 -5
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1039 -559
- package/dist/cli.js.map +1 -1
- package/dist/cloud/diff.d.ts +18 -0
- package/dist/cloud/diff.d.ts.map +1 -0
- package/dist/cloud/diff.js +58 -0
- package/dist/cloud/diff.js.map +1 -0
- package/dist/cloud/nudge.d.ts +66 -0
- package/dist/cloud/nudge.d.ts.map +1 -0
- package/dist/cloud/nudge.js +269 -0
- package/dist/cloud/nudge.js.map +1 -0
- package/dist/cloud/workspace-sync.d.ts +58 -0
- package/dist/cloud/workspace-sync.d.ts.map +1 -0
- package/dist/cloud/workspace-sync.js +268 -0
- package/dist/cloud/workspace-sync.js.map +1 -0
- package/dist/cloud/workspace.d.ts +159 -0
- package/dist/cloud/workspace.d.ts.map +1 -0
- package/dist/cloud/workspace.js +134 -0
- package/dist/cloud/workspace.js.map +1 -0
- package/dist/context/check.d.ts +1 -1
- package/dist/context/check.d.ts.map +1 -1
- package/dist/context/check.js +9 -8
- package/dist/context/check.js.map +1 -1
- package/dist/context/node-file.js +1 -1
- package/dist/context/node-file.js.map +1 -1
- package/dist/context/savings.d.ts.map +1 -1
- package/dist/context/savings.js +10 -7
- package/dist/context/savings.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +3 -1
- package/dist/engine.js.map +1 -1
- package/dist/graph/build.d.ts +30 -0
- package/dist/graph/build.d.ts.map +1 -1
- package/dist/graph/build.js +65 -19
- package/dist/graph/build.js.map +1 -1
- package/dist/graph/cards.d.ts.map +1 -1
- package/dist/graph/cards.js +4 -2
- package/dist/graph/cards.js.map +1 -1
- package/dist/graph/check.d.ts.map +1 -1
- package/dist/graph/check.js +17 -18
- package/dist/graph/check.js.map +1 -1
- package/dist/graph/container.d.ts.map +1 -1
- package/dist/graph/container.js +7 -2
- package/dist/graph/container.js.map +1 -1
- package/dist/graph/extract-cache.d.ts +4 -0
- package/dist/graph/extract-cache.d.ts.map +1 -1
- package/dist/graph/extract-cache.js.map +1 -1
- package/dist/graph/extract.d.ts +2 -0
- package/dist/graph/extract.d.ts.map +1 -1
- package/dist/graph/extract.js +5 -32
- package/dist/graph/extract.js.map +1 -1
- package/dist/graph/generic.d.ts +7 -1
- package/dist/graph/generic.d.ts.map +1 -1
- package/dist/graph/generic.js +48 -8
- package/dist/graph/generic.js.map +1 -1
- package/dist/graph/native.d.ts +38 -0
- package/dist/graph/native.d.ts.map +1 -0
- package/dist/graph/native.js +169 -0
- package/dist/graph/native.js.map +1 -0
- package/dist/graph/refresh.d.ts.map +1 -1
- package/dist/graph/refresh.js +3 -2
- package/dist/graph/refresh.js.map +1 -1
- package/dist/graph/traverse-cli.d.ts.map +1 -1
- package/dist/graph/traverse-cli.js +4 -3
- package/dist/graph/traverse-cli.js.map +1 -1
- package/dist/graph/workspace-cli.d.ts +2 -0
- package/dist/graph/workspace-cli.d.ts.map +1 -1
- package/dist/graph/workspace-cli.js +13 -1
- package/dist/graph/workspace-cli.js.map +1 -1
- package/dist/graph/workspace.d.ts.map +1 -1
- package/dist/graph/workspace.js +6 -5
- package/dist/graph/workspace.js.map +1 -1
- package/dist/hosts/antigravity.d.ts +10 -3
- package/dist/hosts/antigravity.d.ts.map +1 -1
- package/dist/hosts/antigravity.js +27 -10
- package/dist/hosts/antigravity.js.map +1 -1
- package/dist/hosts/claude-global.d.ts +27 -4
- package/dist/hosts/claude-global.d.ts.map +1 -1
- package/dist/hosts/claude-global.js +90 -9
- package/dist/hosts/claude-global.js.map +1 -1
- package/dist/hosts/codex-hooks.d.ts.map +1 -1
- package/dist/hosts/codex-hooks.js +1 -2
- package/dist/hosts/codex-hooks.js.map +1 -1
- package/dist/hosts/config-write.d.ts.map +1 -1
- package/dist/hosts/config-write.js +2 -1
- package/dist/hosts/config-write.js.map +1 -1
- package/dist/hosts/cursor-hooks.d.ts +5 -2
- package/dist/hosts/cursor-hooks.d.ts.map +1 -1
- package/dist/hosts/cursor-hooks.js +14 -9
- package/dist/hosts/cursor-hooks.js.map +1 -1
- package/dist/hosts/init.d.ts +3 -0
- package/dist/hosts/init.d.ts.map +1 -1
- package/dist/hosts/init.js +32 -10
- package/dist/hosts/init.js.map +1 -1
- package/dist/hosts/instructions.d.ts +9 -4
- package/dist/hosts/instructions.d.ts.map +1 -1
- package/dist/hosts/instructions.js +19 -16
- package/dist/hosts/instructions.js.map +1 -1
- package/dist/hosts/mcp-config.d.ts +19 -4
- package/dist/hosts/mcp-config.d.ts.map +1 -1
- package/dist/hosts/mcp-config.js +81 -30
- package/dist/hosts/mcp-config.js.map +1 -1
- package/dist/hosts/plan.d.ts.map +1 -1
- package/dist/hosts/plan.js +11 -9
- package/dist/hosts/plan.js.map +1 -1
- package/dist/hosts/registry.d.ts +25 -2
- package/dist/hosts/registry.d.ts.map +1 -1
- package/dist/hosts/registry.js +53 -0
- package/dist/hosts/registry.js.map +1 -1
- package/dist/hosts/retract.d.ts.map +1 -1
- package/dist/hosts/retract.js +73 -33
- package/dist/hosts/retract.js.map +1 -1
- package/dist/hosts/sections.d.ts +17 -1
- package/dist/hosts/sections.d.ts.map +1 -1
- package/dist/hosts/sections.js +52 -2
- package/dist/hosts/sections.js.map +1 -1
- package/dist/mcp/instructions.d.ts +1 -25
- package/dist/mcp/instructions.d.ts.map +1 -1
- package/dist/mcp/instructions.js +6 -4
- package/dist/mcp/instructions.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +7 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-names.d.ts +10 -3
- package/dist/mcp/tool-names.d.ts.map +1 -1
- package/dist/mcp/tool-names.js +13 -5
- package/dist/mcp/tool-names.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +6 -5
- package/dist/mcp/tools.js.map +1 -1
- package/dist/notes/ask-notes.d.ts +8 -0
- package/dist/notes/ask-notes.d.ts.map +1 -0
- package/dist/notes/ask-notes.js +18 -0
- package/dist/notes/ask-notes.js.map +1 -0
- package/dist/notes/branches.d.ts +85 -0
- package/dist/notes/branches.d.ts.map +1 -0
- package/dist/notes/branches.js +238 -0
- package/dist/notes/branches.js.map +1 -0
- package/dist/notes/cold-start.d.ts +127 -0
- package/dist/notes/cold-start.d.ts.map +1 -0
- package/dist/notes/cold-start.js +476 -0
- package/dist/notes/cold-start.js.map +1 -0
- package/dist/notes/git-facts.d.ts +17 -0
- package/dist/notes/git-facts.d.ts.map +1 -0
- package/dist/notes/git-facts.js +117 -0
- package/dist/notes/git-facts.js.map +1 -0
- package/dist/notes/home.d.ts +87 -0
- package/dist/notes/home.d.ts.map +1 -0
- package/dist/notes/home.js +423 -0
- package/dist/notes/home.js.map +1 -0
- package/dist/notes/notes.d.ts +178 -0
- package/dist/notes/notes.d.ts.map +1 -0
- package/dist/notes/notes.js +498 -0
- package/dist/notes/notes.js.map +1 -0
- package/dist/notes/repo-trail.d.ts +16 -0
- package/dist/notes/repo-trail.d.ts.map +1 -0
- package/dist/notes/repo-trail.js +74 -0
- package/dist/notes/repo-trail.js.map +1 -0
- package/dist/notes/session-cost.d.ts +21 -0
- package/dist/notes/session-cost.d.ts.map +1 -0
- package/dist/notes/session-cost.js +162 -0
- package/dist/notes/session-cost.js.map +1 -0
- package/dist/search/grep-cli.d.ts.map +1 -1
- package/dist/search/grep-cli.js +4 -3
- package/dist/search/grep-cli.js.map +1 -1
- package/dist/skills/skills.d.ts +118 -0
- package/dist/skills/skills.d.ts.map +1 -0
- package/dist/skills/skills.js +370 -0
- package/dist/skills/skills.js.map +1 -0
- package/dist/telemetry/contract.d.ts +2 -14
- package/dist/telemetry/contract.d.ts.map +1 -1
- package/dist/telemetry/contract.js +39 -24
- package/dist/telemetry/contract.js.map +1 -1
- package/dist/telemetry/gate.d.ts.map +1 -1
- package/dist/telemetry/gate.js +2 -1
- package/dist/telemetry/gate.js.map +1 -1
- package/dist/telemetry/notice.d.ts +1 -1
- package/dist/telemetry/notice.d.ts.map +1 -1
- package/dist/telemetry/notice.js +6 -5
- package/dist/telemetry/notice.js.map +1 -1
- package/dist/telemetry/track.d.ts.map +1 -1
- package/dist/telemetry/track.js +5 -0
- package/dist/telemetry/track.js.map +1 -1
- package/dist/upkeep-run.d.ts +7 -0
- package/dist/upkeep-run.d.ts.map +1 -1
- package/dist/upkeep-run.js +52 -12
- package/dist/upkeep-run.js.map +1 -1
- package/dist/upkeep.d.ts +9 -19
- package/dist/upkeep.d.ts.map +1 -1
- package/dist/upkeep.js +38 -59
- package/dist/upkeep.js.map +1 -1
- package/dist/util/browser.d.ts +3 -0
- package/dist/util/browser.d.ts.map +1 -0
- package/dist/util/browser.js +14 -0
- package/dist/util/browser.js.map +1 -0
- package/dist/util/front-matter.d.ts +19 -0
- package/dist/util/front-matter.d.ts.map +1 -0
- package/dist/util/front-matter.js +21 -0
- package/dist/util/front-matter.js.map +1 -0
- package/dist/util/state.d.ts +1 -18
- package/dist/util/state.d.ts.map +1 -1
- package/dist/util/state.js +4 -2
- package/dist/util/state.js.map +1 -1
- package/dist/viz/assemble.js +1 -1
- package/dist/viz/assemble.js.map +1 -1
- package/dist/viz/serve.d.ts.map +1 -1
- package/dist/viz/serve.js +4 -3
- package/dist/viz/serve.js.map +1 -1
- package/package.json +7 -7
- package/scripts/pack-trail.mjs +53 -0
- package/scripts/postinstall.mjs +17 -2
- package/scripts/run-tests.mjs +4 -1
- package/dist/brain/attach.d.ts +0 -44
- package/dist/brain/attach.d.ts.map +0 -1
- package/dist/brain/attach.js +0 -63
- package/dist/brain/attach.js.map +0 -1
- package/dist/brain/claude-md.d.ts +0 -61
- package/dist/brain/claude-md.d.ts.map +0 -1
- package/dist/brain/claude-md.js +0 -171
- package/dist/brain/claude-md.js.map +0 -1
- package/dist/brain/connect.d.ts +0 -59
- package/dist/brain/connect.d.ts.map +0 -1
- package/dist/brain/connect.js +0 -80
- package/dist/brain/connect.js.map +0 -1
- package/dist/brain/context-files.d.ts +0 -79
- package/dist/brain/context-files.d.ts.map +0 -1
- package/dist/brain/context-files.js +0 -245
- package/dist/brain/context-files.js.map +0 -1
- package/dist/brain/link.d.ts +0 -106
- package/dist/brain/link.d.ts.map +0 -1
- package/dist/brain/link.js +0 -167
- package/dist/brain/link.js.map +0 -1
- package/dist/brain/pull.d.ts +0 -48
- package/dist/brain/pull.d.ts.map +0 -1
- package/dist/brain/pull.js +0 -257
- package/dist/brain/pull.js.map +0 -1
- package/dist/brain/push.d.ts +0 -155
- package/dist/brain/push.d.ts.map +0 -1
- package/dist/brain/push.js +0 -304
- package/dist/brain/push.js.map +0 -1
- package/dist/brain/signup.d.ts +0 -117
- package/dist/brain/signup.d.ts.map +0 -1
- package/dist/brain/signup.js +0 -276
- package/dist/brain/signup.js.map +0 -1
- package/dist/brain/upload.d.ts +0 -61
- package/dist/brain/upload.d.ts.map +0 -1
- package/dist/brain/upload.js +0 -210
- package/dist/brain/upload.js.map +0 -1
- package/dist/brain/watch.d.ts +0 -209
- package/dist/brain/watch.d.ts.map +0 -1
- package/dist/brain/watch.js +0 -397
- package/dist/brain/watch.js.map +0 -1
- package/dist/brain/wire.d.ts +0 -38
- package/dist/brain/wire.d.ts.map +0 -1
- package/dist/brain/wire.js +0 -133
- package/dist/brain/wire.js.map +0 -1
- package/dist/legacy-args.d.ts +0 -12
- package/dist/legacy-args.d.ts.map +0 -1
- package/dist/legacy-args.js +0 -31
- package/dist/legacy-args.js.map +0 -1
|
@@ -22,15 +22,16 @@
|
|
|
22
22
|
* - `afterMCPExecution` → the graft MCP calls, savings parsed from `result_json`.
|
|
23
23
|
* - `sessionEnd` → roll the closed session up into `session_summary` as Cursor.
|
|
24
24
|
*/
|
|
25
|
-
import { writeFileSync } from 'node:fs';
|
|
25
|
+
import { rmSync, writeFileSync } from 'node:fs';
|
|
26
26
|
import { join } from 'node:path';
|
|
27
27
|
import { hooksShim } from '../claude/shim-template.js';
|
|
28
|
-
import { claudeDistDir } from '../claude/paths.js';
|
|
29
28
|
import { writeOwned, isGraftEntry, readJsonObject } from './config-write.js';
|
|
29
|
+
import { cursorHookShimRelPath } from './registry.js';
|
|
30
30
|
/** The Cursor hooks.json schema version graft writes. */
|
|
31
31
|
const CURSOR_HOOKS_VERSION = 1;
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
/** `.cursor/hooks/graft-hooks.cjs`, or `trail-hooks.cjs` in a repo that uses trail. */
|
|
33
|
+
export function shimPathFor(repo, name = 'graft') {
|
|
34
|
+
return join(repo, cursorHookShimRelPath(name));
|
|
34
35
|
}
|
|
35
36
|
function configPathFor(repo) {
|
|
36
37
|
return join(repo, '.cursor', 'hooks.json');
|
|
@@ -41,11 +42,11 @@ function configPathFor(repo) {
|
|
|
41
42
|
* the Cursor-only, no-global init). Always returns the pair: unlike Codex there
|
|
42
43
|
* is no "is the CLI installed" gate — the repo's own `.cursor/` is what we write.
|
|
43
44
|
*/
|
|
44
|
-
export function cursorHookTargets(repo) {
|
|
45
|
+
export function cursorHookTargets(repo, name = 'graft') {
|
|
45
46
|
return [
|
|
46
47
|
{
|
|
47
48
|
hostId: 'cursor', id: 'cursor-hook-shim',
|
|
48
|
-
path: shimPathFor(repo),
|
|
49
|
+
path: shimPathFor(repo, name),
|
|
49
50
|
scope: 'repo', kind: 'hook', what: 'session-scoring hook shim',
|
|
50
51
|
},
|
|
51
52
|
{
|
|
@@ -69,9 +70,13 @@ function desiredEntries() {
|
|
|
69
70
|
* clobbered. Foreign hook entries are preserved; a stale graft entry is replaced
|
|
70
71
|
* so an upgrade re-points to the current shim/sub-command instead of stacking.
|
|
71
72
|
*/
|
|
72
|
-
export function installCursorHooks(repo) {
|
|
73
|
-
const shimPath = shimPathFor(repo);
|
|
74
|
-
const shimWrite = writeOwned('cursor-hook-shim', shimPath, hooksShim(
|
|
73
|
+
export function installCursorHooks(repo, name = 'graft') {
|
|
74
|
+
const shimPath = shimPathFor(repo, name);
|
|
75
|
+
const shimWrite = writeOwned('cursor-hook-shim', shimPath, hooksShim(), 0o755);
|
|
76
|
+
// A repo moving to trail's names: graft's shim goes, and its entries are
|
|
77
|
+
// replaced below (`isGraftEntry` knows both names).
|
|
78
|
+
if (name === 'trail')
|
|
79
|
+
rmSync(shimPathFor(repo, 'graft'), { force: true });
|
|
75
80
|
const cfgPath = configPathFor(repo);
|
|
76
81
|
const skipped = { id: 'cursor-hooks', path: cfgPath, action: 'skipped-unparseable' };
|
|
77
82
|
const loaded = readJsonObject(cfgPath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor-hooks.js","sourceRoot":"","sources":["../../src/hosts/cursor-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"cursor-hooks.js","sourceRoot":"","sources":["../../src/hosts/cursor-hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/hosts/init.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Brand } from '../brand.js';
|
|
1
2
|
import { type McpWrite } from './mcp-config.js';
|
|
2
3
|
import type { ConfigWrite } from './config-write.js';
|
|
3
4
|
export interface HostsInitResult {
|
|
@@ -19,5 +20,7 @@ export declare function runHostsInit(repo: string, opts?: {
|
|
|
19
20
|
hooks?: boolean;
|
|
20
21
|
/** false → skip every write outside the repo (the ~/.codex/ targets). */
|
|
21
22
|
global?: boolean;
|
|
23
|
+
/** The name `init` runs under; trail's moves the repo to trail's names (see `hostWiringName`). */
|
|
24
|
+
brand?: Brand;
|
|
22
25
|
}): HostsInitResult;
|
|
23
26
|
//# sourceMappingURL=init.d.ts.map
|
package/dist/hosts/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/hosts/init.ts"],"names":[],"mappings":"AAUA,OAAO,EAAsB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/hosts/init.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAsB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACxD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,EAAE,QAAQ,EAAE,CAAC;IAChB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AA4BD,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IACJ,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yEAAyE;IACzE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kGAAkG;IAClG,KAAK,CAAC,EAAE,KAAK,CAAC;CACV,GACL,eAAe,CAqDjB"}
|
package/dist/hosts/init.js
CHANGED
|
@@ -3,15 +3,16 @@
|
|
|
3
3
|
* Selection = explicit ids > all > detected. Claude Code is handled
|
|
4
4
|
* separately by src/claude/init.ts (hooks + statusline + skill).
|
|
5
5
|
*/
|
|
6
|
-
import { statSync, writeFileSync, readFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
7
|
-
import { dirname, join } from 'node:path';
|
|
6
|
+
import { statSync, writeFileSync, readFileSync, mkdirSync, existsSync, rmSync, rmdirSync } from 'node:fs';
|
|
7
|
+
import { basename, dirname, join } from 'node:path';
|
|
8
8
|
import { homedir } from 'node:os';
|
|
9
|
-
import { HOSTS, detectHosts } from './registry.js';
|
|
10
|
-
import { upsertSection } from './sections.js';
|
|
9
|
+
import { HOSTS, detectHosts, hostRelPath, hostWiringName } from './registry.js';
|
|
10
|
+
import { GRAFT_MARKERS, markersFor, upsertSection } from './sections.js';
|
|
11
11
|
import { registerMcpConfigs } from './mcp-config.js';
|
|
12
12
|
import { installCodexHooks } from './codex-hooks.js';
|
|
13
13
|
import { installCursorHooks } from './cursor-hooks.js';
|
|
14
14
|
import { installAntigravitySkill } from './antigravity.js';
|
|
15
|
+
import { rememberInstall } from '../claude/shim-template.js';
|
|
15
16
|
function probeFor(home, repo) {
|
|
16
17
|
return {
|
|
17
18
|
home, repo,
|
|
@@ -31,9 +32,23 @@ function writeOwned(path, content) {
|
|
|
31
32
|
writeFileSync(path, content);
|
|
32
33
|
return existed ? 'replaced' : 'created';
|
|
33
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* A graft-named file a host owned, gone now that the repo uses trail's names,
|
|
37
|
+
* with its `graft/` folder when that was all the folder held.
|
|
38
|
+
*/
|
|
39
|
+
function removeGraftCopy(path) {
|
|
40
|
+
rmSync(path, { force: true });
|
|
41
|
+
if (basename(dirname(path)) === 'graft') {
|
|
42
|
+
try {
|
|
43
|
+
rmdirSync(dirname(path));
|
|
44
|
+
}
|
|
45
|
+
catch { /* not empty, or not there */ }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
34
48
|
export function runHostsInit(repo, opts = {}) {
|
|
35
49
|
const home = opts.home ?? homedir();
|
|
36
50
|
const probe = probeFor(home, repo);
|
|
51
|
+
const name = hostWiringName(repo, opts.brand);
|
|
37
52
|
let selected;
|
|
38
53
|
let unknown = [];
|
|
39
54
|
if (opts.agents !== undefined) {
|
|
@@ -49,16 +64,20 @@ export function runHostsInit(repo, opts = {}) {
|
|
|
49
64
|
}
|
|
50
65
|
const written = [];
|
|
51
66
|
for (const host of selected) {
|
|
52
|
-
const path = join(repo, host
|
|
67
|
+
const path = join(repo, hostRelPath(host, name));
|
|
68
|
+
// Under trail, graft's copy of an owned file goes and graft's fenced
|
|
69
|
+
// block becomes trail's, so the agent reads the instructions once.
|
|
53
70
|
const action = host.kind === 'owned'
|
|
54
|
-
? writeOwned(path, host.content())
|
|
55
|
-
: upsertSection(path, host.content()).action;
|
|
71
|
+
? writeOwned(path, host.content(name))
|
|
72
|
+
: upsertSection(path, host.content(name), markersFor(name), name === 'trail' ? [GRAFT_MARKERS] : []).action;
|
|
73
|
+
if (name === 'trail' && host.kind === 'owned')
|
|
74
|
+
removeGraftCopy(join(repo, host.relPath));
|
|
56
75
|
written.push({ id: host.id, path, action });
|
|
57
76
|
}
|
|
58
77
|
const skipped = HOSTS.filter((h) => !selected.includes(h)).map((h) => h.id);
|
|
59
78
|
const mcp = opts.mcp === false
|
|
60
79
|
? []
|
|
61
|
-
: registerMcpConfigs(repo, selected.map((h) => h.id), { home, global: opts.global });
|
|
80
|
+
: registerMcpConfigs(repo, selected.map((h) => h.id), { home, global: opts.global, name });
|
|
62
81
|
// The Codex hook targets are user-level (~/.codex), so --no-global suppresses them.
|
|
63
82
|
const hooks = opts.hooks === false || opts.global === false || !selected.some((h) => h.id === 'agents')
|
|
64
83
|
? []
|
|
@@ -67,11 +86,14 @@ export function runHostsInit(repo, opts = {}) {
|
|
|
67
86
|
// no-global posture — so --no-global does NOT suppress them; only --no-hooks does.
|
|
68
87
|
const cursorHooks = opts.hooks === false || !selected.some((h) => h.id === 'cursor')
|
|
69
88
|
? []
|
|
70
|
-
: installCursorHooks(repo);
|
|
89
|
+
: installCursorHooks(repo, name);
|
|
90
|
+
// Both write the hooks shim, which finds this install through the trail home.
|
|
91
|
+
if (hooks.length > 0 || cursorHooks.length > 0)
|
|
92
|
+
rememberInstall(home);
|
|
71
93
|
// Antigravity's skill is a global write too, so --no-global suppresses it as well.
|
|
72
94
|
const antigravitySkill = opts.global === false || !selected.some((h) => h.id === 'antigravity')
|
|
73
95
|
? []
|
|
74
|
-
: installAntigravitySkill(home);
|
|
96
|
+
: installAntigravitySkill(home, name);
|
|
75
97
|
return { written, skipped, unknown, mcp, hooks: [...hooks, ...cursorHooks, ...antigravitySkill] };
|
|
76
98
|
}
|
|
77
99
|
//# sourceMappingURL=init.js.map
|
package/dist/hosts/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/hosts/init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/hosts/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The one canonical Graft instruction block, rendered into each host's
|
|
3
3
|
* native format. Content changes happen HERE only; renderers just wrap it.
|
|
4
|
+
*
|
|
5
|
+
* `name` is the repo's name for the tool (see `hostWiringName`): a repo wired
|
|
6
|
+
* by trail gets the same text in trail's spelling, so an agent on a machine
|
|
7
|
+
* with only `trail` installed is never told to run `graft`.
|
|
4
8
|
*/
|
|
5
|
-
|
|
6
|
-
export declare function
|
|
7
|
-
export declare function
|
|
8
|
-
export declare function
|
|
9
|
+
import type { Brand } from '../brand.js';
|
|
10
|
+
export declare function instructionBody(name?: Brand): string;
|
|
11
|
+
export declare function cursorRule(name?: Brand): string;
|
|
12
|
+
export declare function kiroSteering(name?: Brand): string;
|
|
13
|
+
export declare function windsurfRule(name?: Brand): string;
|
|
9
14
|
//# sourceMappingURL=instructions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/hosts/instructions.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/hosts/instructions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAOzC,wBAAgB,eAAe,CAAC,IAAI,GAAE,KAAe,GAAG,MAAM,CAE7D;AA4CD,wBAAgB,UAAU,CAAC,IAAI,GAAE,KAAe,GAAG,MAAM,CAOxD;AAED,wBAAgB,YAAY,CAAC,IAAI,GAAE,KAAe,GAAG,MAAM,CAM1D;AAED,wBAAgB,YAAY,CAAC,IAAI,GAAE,KAAe,GAAG,MAAM,CAG1D"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export function instructionBody() {
|
|
1
|
+
import { trailSpelling } from '../claude/skill-template.js';
|
|
2
|
+
function inName(text, name) {
|
|
3
|
+
return name === 'trail' ? trailSpelling(text) : text;
|
|
4
|
+
}
|
|
5
|
+
export function instructionBody(name = 'graft') {
|
|
6
|
+
return inName(graftBody(), name);
|
|
7
|
+
}
|
|
8
|
+
function graftBody() {
|
|
6
9
|
return `## Graft — repo context graph
|
|
7
10
|
|
|
8
11
|
This repo is indexed in \`graft/\`: small linked markdown nodes that explain each
|
|
@@ -43,23 +46,23 @@ re-read whole files.
|
|
|
43
46
|
After big code changes, refresh the graph with \`graft build\` (deterministic,
|
|
44
47
|
no API key, $0).`;
|
|
45
48
|
}
|
|
46
|
-
export function cursorRule() {
|
|
47
|
-
return `---
|
|
49
|
+
export function cursorRule(name = 'graft') {
|
|
50
|
+
return inName(`---
|
|
48
51
|
description: Use the Graft context graph in graft/ before exploring source
|
|
49
52
|
alwaysApply: true
|
|
50
53
|
---
|
|
51
|
-
${
|
|
52
|
-
|
|
54
|
+
${graftBody()}
|
|
55
|
+
`, name);
|
|
53
56
|
}
|
|
54
|
-
export function kiroSteering() {
|
|
55
|
-
return `---
|
|
57
|
+
export function kiroSteering(name = 'graft') {
|
|
58
|
+
return inName(`---
|
|
56
59
|
inclusion: always
|
|
57
60
|
---
|
|
58
|
-
${
|
|
59
|
-
|
|
61
|
+
${graftBody()}
|
|
62
|
+
`, name);
|
|
60
63
|
}
|
|
61
|
-
export function windsurfRule() {
|
|
62
|
-
return `${
|
|
63
|
-
|
|
64
|
+
export function windsurfRule(name = 'graft') {
|
|
65
|
+
return inName(`${graftBody()}
|
|
66
|
+
`, name);
|
|
64
67
|
}
|
|
65
68
|
//# sourceMappingURL=instructions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instructions.js","sourceRoot":"","sources":["../../src/hosts/instructions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instructions.js","sourceRoot":"","sources":["../../src/hosts/instructions.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,SAAS,MAAM,CAAC,IAAY,EAAE,IAAW;IACvC,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAc,OAAO;IACnD,OAAO,MAAM,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,SAAS;IAChB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsCQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAc,OAAO;IAC9C,OAAO,MAAM,CAAC;;;;EAId,SAAS,EAAE;CACZ,EAAE,IAAI,CAAC,CAAC;AACT,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAc,OAAO;IAChD,OAAO,MAAM,CAAC;;;EAGd,SAAS,EAAE;CACZ,EAAE,IAAI,CAAC,CAAC;AACT,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAc,OAAO;IAChD,OAAO,MAAM,CAAC,GAAG,SAAS,EAAE;CAC7B,EAAE,IAAI,CAAC,CAAC;AACT,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PlannedWrite } from './plan.js';
|
|
2
2
|
import { type ConfigWrite } from './config-write.js';
|
|
3
|
+
import { type Brand } from '../brand.js';
|
|
3
4
|
/** MCP registration reports the same write-result record every installer does. */
|
|
4
5
|
export type McpWrite = ConfigWrite;
|
|
5
6
|
/** A planned MCP write, plus the detail needed to actually perform it. */
|
|
@@ -7,8 +8,10 @@ export interface McpTarget extends PlannedWrite {
|
|
|
7
8
|
format: 'json' | 'toml';
|
|
8
9
|
/** JSON only: the top-level key holding the server map. */
|
|
9
10
|
topKey?: string;
|
|
10
|
-
/** JSON only: the server entry to merge in under `
|
|
11
|
+
/** JSON only: the server entry to merge in under `key`. */
|
|
11
12
|
entry?: object;
|
|
13
|
+
/** The server's name in the file: `graft`, or `trail` in a repo that uses trail. */
|
|
14
|
+
key: Brand;
|
|
12
15
|
}
|
|
13
16
|
/**
|
|
14
17
|
* JSON hosts: `{ command, args }`.
|
|
@@ -20,20 +23,26 @@ export interface McpTarget extends PlannedWrite {
|
|
|
20
23
|
*/
|
|
21
24
|
export declare function serverEntry(opts?: {
|
|
22
25
|
onPath?: boolean;
|
|
26
|
+
brand?: 'graft' | 'trail';
|
|
23
27
|
}): {
|
|
24
28
|
command: string;
|
|
25
29
|
args: string[];
|
|
26
30
|
};
|
|
27
|
-
export declare function mergeJsonKey(id: string, path: string, topKey: string, entry: object): McpWrite;
|
|
28
31
|
/**
|
|
29
|
-
*
|
|
32
|
+
* `key` is the server's name in the file (`graft`, or `trail` in a repo that
|
|
33
|
+
* uses trail); `drop` names entries this write replaces, so a repo moving to
|
|
34
|
+
* trail doesn't start the same server twice.
|
|
35
|
+
*/
|
|
36
|
+
export declare function mergeJsonKey(id: string, path: string, topKey: string, entry: object, key?: string, drop?: string[]): McpWrite;
|
|
37
|
+
/**
|
|
38
|
+
* Remove the `[mcp_servers.graft]` table (or `name`'s) from a TOML config, returning the rest.
|
|
30
39
|
*
|
|
31
40
|
* Line-based on purpose: a real parse-and-reserialize would reformat the user's
|
|
32
41
|
* whole file. The table runs from its header to the next `[`-header or EOF, which
|
|
33
42
|
* is exactly the shape {@link upsertCodexToml} appends. Exported so the writer and
|
|
34
43
|
* `retract.ts` can never disagree about what "graft's section" means.
|
|
35
44
|
*/
|
|
36
|
-
export declare function stripTomlSection(text: string): {
|
|
45
|
+
export declare function stripTomlSection(text: string, name?: Brand): {
|
|
37
46
|
rest: string;
|
|
38
47
|
found: boolean;
|
|
39
48
|
};
|
|
@@ -41,12 +50,18 @@ export declare function stripTomlSection(text: string): {
|
|
|
41
50
|
* The MCP config files selecting these hosts would touch — pure, no writes.
|
|
42
51
|
* Codex's target is the user-level `~/.codex/config.toml`, so it is scoped
|
|
43
52
|
* 'global': registering there affects every project on the machine.
|
|
53
|
+
*
|
|
54
|
+
* `name` is the repo's name for the tool: under trail the server is `trail`,
|
|
55
|
+
* launched as `trail mcp` (or `npx -y @trailhq/trail-code mcp`). The files
|
|
56
|
+
* are the same either way.
|
|
44
57
|
*/
|
|
45
58
|
export declare function mcpTargets(repo: string, ids: string[], opts?: {
|
|
46
59
|
home?: string;
|
|
60
|
+
name?: Brand;
|
|
47
61
|
}): McpTarget[];
|
|
48
62
|
export declare function registerMcpConfigs(repo: string, ids: string[], opts?: {
|
|
49
63
|
home?: string;
|
|
50
64
|
global?: boolean;
|
|
65
|
+
name?: Brand;
|
|
51
66
|
}): McpWrite[];
|
|
52
67
|
//# sourceMappingURL=mcp-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-config.d.ts","sourceRoot":"","sources":["../../src/hosts/mcp-config.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-config.d.ts","sourceRoot":"","sources":["../../src/hosts/mcp-config.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAEtD,kFAAkF;AAClF,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC;AAEnC,0EAA0E;AAC1E,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,GAAG,EAAE,KAAK,CAAC;CACZ;AA+BD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;CAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAM3H;AAYD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAU,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,QAAQ,CAgBlI;AAOD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,KAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAYtG;AAiDD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EAAE,EACb,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAA;CAAO,GACzC,SAAS,EAAE,CAqDb;AAoBD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EAAE,EACb,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAA;CAAO,GAC3D,QAAQ,EAAE,CAUZ"}
|
package/dist/hosts/mcp-config.js
CHANGED
|
@@ -12,6 +12,7 @@ import { spawnSync } from 'node:child_process';
|
|
|
12
12
|
import { dirname, join } from 'node:path';
|
|
13
13
|
import { homedir } from 'node:os';
|
|
14
14
|
import { readJsonObject } from './config-write.js';
|
|
15
|
+
import { trailOnPath } from '../brand.js';
|
|
15
16
|
/**
|
|
16
17
|
* How to launch the MCP server, decided once at init time.
|
|
17
18
|
*
|
|
@@ -24,13 +25,17 @@ import { readJsonObject } from './config-write.js';
|
|
|
24
25
|
* cheap half of the fix, not the whole of it.)
|
|
25
26
|
*
|
|
26
27
|
* Deliberately a bare command name, never an absolute path: these files get
|
|
27
|
-
* committed and shared, and this repo
|
|
28
|
-
*
|
|
28
|
+
* committed and shared, and this repo carried the scar of the alternative — a
|
|
29
|
+
* checked-in hook shim with another machine's home directory baked into it. A
|
|
29
30
|
* bare `graft` works on any machine that has it installed; `npx` remains the
|
|
30
31
|
* fallback for machines that don't.
|
|
31
32
|
*/
|
|
32
33
|
const NPX_LAUNCH = { command: 'npx', args: ['-y', '@nanonets/graft', 'mcp'] };
|
|
33
34
|
const BIN_LAUNCH = { command: 'graft', args: ['mcp'] };
|
|
35
|
+
// The same server under trail's name, for a repo that uses trail: its tools are
|
|
36
|
+
// `trail_*` (and it still answers `graft_*`).
|
|
37
|
+
const TRAIL_NPX_LAUNCH = { command: 'npx', args: ['-y', '@trailhq/trail-code', 'mcp'] };
|
|
38
|
+
const TRAIL_BIN_LAUNCH = { command: 'trail', args: ['mcp'] };
|
|
34
39
|
function graftOnPath() {
|
|
35
40
|
const r = spawnSync('graft', ['--version'], { stdio: 'ignore', timeout: 5000 });
|
|
36
41
|
return r.status === 0;
|
|
@@ -44,13 +49,16 @@ function graftOnPath() {
|
|
|
44
49
|
* `opts.onPath` is the same override for direct unit tests of both branches.
|
|
45
50
|
*/
|
|
46
51
|
export function serverEntry(opts = {}) {
|
|
52
|
+
const trail = opts.brand === 'trail';
|
|
47
53
|
const forced = process.env.GRAFT_MCP_NPX;
|
|
48
54
|
if (forced !== undefined && forced !== '' && forced !== '0' && forced !== 'false')
|
|
49
|
-
return NPX_LAUNCH;
|
|
55
|
+
return trail ? TRAIL_NPX_LAUNCH : NPX_LAUNCH;
|
|
56
|
+
if (trail)
|
|
57
|
+
return (opts.onPath ?? trailOnPath()) ? TRAIL_BIN_LAUNCH : TRAIL_NPX_LAUNCH;
|
|
50
58
|
return (opts.onPath ?? graftOnPath()) ? BIN_LAUNCH : NPX_LAUNCH;
|
|
51
59
|
}
|
|
52
|
-
function opencodeEntry() {
|
|
53
|
-
const { command, args } = serverEntry();
|
|
60
|
+
function opencodeEntry(name = 'graft') {
|
|
61
|
+
const { command, args } = serverEntry({ brand: name });
|
|
54
62
|
return { type: 'local', command: [command, ...args], enabled: true };
|
|
55
63
|
}
|
|
56
64
|
function dirExists(p) {
|
|
@@ -61,7 +69,12 @@ function dirExists(p) {
|
|
|
61
69
|
return false;
|
|
62
70
|
}
|
|
63
71
|
}
|
|
64
|
-
|
|
72
|
+
/**
|
|
73
|
+
* `key` is the server's name in the file (`graft`, or `trail` in a repo that
|
|
74
|
+
* uses trail); `drop` names entries this write replaces, so a repo moving to
|
|
75
|
+
* trail doesn't start the same server twice.
|
|
76
|
+
*/
|
|
77
|
+
export function mergeJsonKey(id, path, topKey, entry, key = 'graft', drop = []) {
|
|
65
78
|
const loaded = readJsonObject(path);
|
|
66
79
|
if (loaded === 'unparseable')
|
|
67
80
|
return { id, path, action: 'skipped-unparseable' };
|
|
@@ -70,27 +83,33 @@ export function mergeJsonKey(id, path, topKey, entry) {
|
|
|
70
83
|
if (typeof bucket !== 'object' || bucket === null || Array.isArray(bucket)) {
|
|
71
84
|
return { id, path, action: 'skipped-unparseable' };
|
|
72
85
|
}
|
|
73
|
-
|
|
86
|
+
const dropping = drop.filter((k) => k in bucket);
|
|
87
|
+
if (JSON.stringify(bucket[key]) === JSON.stringify(entry) && dropping.length === 0)
|
|
74
88
|
return { id, path, action: 'unchanged' };
|
|
75
89
|
const action = existed ? 'updated' : 'created';
|
|
76
|
-
|
|
90
|
+
for (const k of dropping)
|
|
91
|
+
delete bucket[k];
|
|
92
|
+
bucket[key] = entry;
|
|
77
93
|
mkdirSync(dirname(path), { recursive: true });
|
|
78
94
|
writeFileSync(path, `${JSON.stringify(root, null, 2)}\n`);
|
|
79
95
|
return { id, path, action };
|
|
80
96
|
}
|
|
81
|
-
/** The `[mcp_servers.graft]` table header, as written and as matched. */
|
|
82
|
-
|
|
97
|
+
/** The `[mcp_servers.graft]` (or `.trail`) table header, as written and as matched. */
|
|
98
|
+
function tomlHeader(name) {
|
|
99
|
+
return `[mcp_servers.${name}]`;
|
|
100
|
+
}
|
|
83
101
|
/**
|
|
84
|
-
* Remove the `[mcp_servers.graft]` table from a TOML config, returning the rest.
|
|
102
|
+
* Remove the `[mcp_servers.graft]` table (or `name`'s) from a TOML config, returning the rest.
|
|
85
103
|
*
|
|
86
104
|
* Line-based on purpose: a real parse-and-reserialize would reformat the user's
|
|
87
105
|
* whole file. The table runs from its header to the next `[`-header or EOF, which
|
|
88
106
|
* is exactly the shape {@link upsertCodexToml} appends. Exported so the writer and
|
|
89
107
|
* `retract.ts` can never disagree about what "graft's section" means.
|
|
90
108
|
*/
|
|
91
|
-
export function stripTomlSection(text) {
|
|
109
|
+
export function stripTomlSection(text, name = 'graft') {
|
|
92
110
|
const lines = text.split('\n');
|
|
93
|
-
const
|
|
111
|
+
const header = tomlHeader(name);
|
|
112
|
+
const start = lines.findIndex((l) => l.trim() === header);
|
|
94
113
|
if (start === -1)
|
|
95
114
|
return { rest: text, found: false };
|
|
96
115
|
let end = start + 1;
|
|
@@ -111,13 +130,16 @@ export function stripTomlSection(text) {
|
|
|
111
130
|
* and re-append instead, so this converges like every other writer — foreign
|
|
112
131
|
* tables are untouched either way.
|
|
113
132
|
*/
|
|
114
|
-
function upsertCodexToml(id, path) {
|
|
133
|
+
function upsertCodexToml(id, path, name = 'graft') {
|
|
115
134
|
const existed = existsSync(path);
|
|
116
135
|
const text = existed ? readFileSync(path, 'utf8') : '';
|
|
117
|
-
const { command, args } = serverEntry();
|
|
136
|
+
const { command, args } = serverEntry({ brand: name });
|
|
118
137
|
const argList = args.map((a) => JSON.stringify(a)).join(", ");
|
|
119
|
-
const section = `${
|
|
120
|
-
const
|
|
138
|
+
const section = `${tomlHeader(name)}\ncommand = \"${command}\"\nargs = [${argList}]\n`;
|
|
139
|
+
const own = stripTomlSection(text, name);
|
|
140
|
+
// Under trail, graft's table goes: the same server, listed once.
|
|
141
|
+
const { rest, found: oldFound } = name === 'trail' ? stripTomlSection(own.rest, 'graft') : { rest: own.rest, found: false };
|
|
142
|
+
const found = own.found && !oldFound;
|
|
121
143
|
// Byte-identical already: don't rewrite the file just to reorder it.
|
|
122
144
|
if (found && text === appendSection(rest, section))
|
|
123
145
|
return { id, path, action: 'unchanged' };
|
|
@@ -132,42 +154,48 @@ function appendSection(text, section) {
|
|
|
132
154
|
const sep = text.endsWith('\n\n') ? '' : text.endsWith('\n') ? '\n' : '\n\n';
|
|
133
155
|
return `${text}${sep}${section}`;
|
|
134
156
|
}
|
|
135
|
-
function jsonTarget(hostId, id, path, topKey, entry, scope = 'repo') {
|
|
136
|
-
return { hostId, id, path, scope, kind: 'mcp', what: `${topKey}
|
|
157
|
+
function jsonTarget(hostId, id, path, topKey, entry, scope = 'repo', key = 'graft') {
|
|
158
|
+
return { hostId, id, path, scope, kind: 'mcp', what: `${topKey}.${key}`, format: 'json', topKey, entry, key };
|
|
137
159
|
}
|
|
138
160
|
/**
|
|
139
161
|
* The MCP config files selecting these hosts would touch — pure, no writes.
|
|
140
162
|
* Codex's target is the user-level `~/.codex/config.toml`, so it is scoped
|
|
141
163
|
* 'global': registering there affects every project on the machine.
|
|
164
|
+
*
|
|
165
|
+
* `name` is the repo's name for the tool: under trail the server is `trail`,
|
|
166
|
+
* launched as `trail mcp` (or `npx -y @trailhq/trail-code mcp`). The files
|
|
167
|
+
* are the same either way.
|
|
142
168
|
*/
|
|
143
169
|
export function mcpTargets(repo, ids, opts = {}) {
|
|
144
170
|
const home = opts.home ?? homedir();
|
|
145
|
-
const
|
|
171
|
+
const name = opts.name ?? 'graft';
|
|
172
|
+
const entry = serverEntry({ brand: name });
|
|
173
|
+
const json = (hostId, id, path, topKey, e, scope = 'repo') => jsonTarget(hostId, id, path, topKey, e, scope, name);
|
|
146
174
|
const out = [];
|
|
147
175
|
for (const id of ids) {
|
|
148
176
|
switch (id) {
|
|
149
177
|
case 'cursor':
|
|
150
|
-
out.push(
|
|
178
|
+
out.push(json(id, id, join(repo, '.cursor', 'mcp.json'), 'mcpServers', entry));
|
|
151
179
|
break;
|
|
152
180
|
case 'gemini':
|
|
153
|
-
out.push(
|
|
181
|
+
out.push(json(id, id, join(repo, '.gemini', 'settings.json'), 'mcpServers', entry));
|
|
154
182
|
break;
|
|
155
183
|
case 'antigravity':
|
|
156
184
|
// Antigravity reads MCP from its OWN registry, separate from Gemini CLI's
|
|
157
185
|
// `.gemini/settings.json` — a global `~/.gemini/config/mcp_config.json` (the
|
|
158
186
|
// gap #62 reported). Standard `{command,args}` under `mcpServers`. Global
|
|
159
187
|
// scope: it applies to every workspace opened in Antigravity.
|
|
160
|
-
out.push(
|
|
188
|
+
out.push(json(id, 'antigravity', join(home, '.gemini', 'config', 'mcp_config.json'), 'mcpServers', entry, 'global'));
|
|
161
189
|
break;
|
|
162
190
|
case 'kiro':
|
|
163
|
-
out.push(
|
|
191
|
+
out.push(json(id, id, join(repo, '.kiro', 'settings', 'mcp.json'), 'mcpServers', entry));
|
|
164
192
|
break;
|
|
165
193
|
case 'grok':
|
|
166
194
|
// Grok reads MCP from repo-level `.grok/config.toml` (`[mcp_servers.<name>]`),
|
|
167
195
|
// the same TOML shape Codex uses at ~/.codex/config.toml.
|
|
168
196
|
out.push({
|
|
169
197
|
hostId: id, id: 'grok', path: join(repo, '.grok', 'config.toml'),
|
|
170
|
-
scope: 'repo', kind: 'mcp', what:
|
|
198
|
+
scope: 'repo', kind: 'mcp', what: tomlHeader(name), format: 'toml', key: name,
|
|
171
199
|
});
|
|
172
200
|
break;
|
|
173
201
|
case 'agents':
|
|
@@ -176,11 +204,11 @@ export function mcpTargets(repo, ids, opts = {}) {
|
|
|
176
204
|
if (dirExists(join(home, '.codex'))) {
|
|
177
205
|
out.push({
|
|
178
206
|
hostId: id, id: 'codex', path: join(home, '.codex', 'config.toml'),
|
|
179
|
-
scope: 'global', kind: 'mcp', what:
|
|
207
|
+
scope: 'global', kind: 'mcp', what: tomlHeader(name), format: 'toml', key: name,
|
|
180
208
|
});
|
|
181
209
|
}
|
|
182
210
|
if (dirExists(join(home, '.config', 'opencode'))) {
|
|
183
|
-
out.push(
|
|
211
|
+
out.push(json(id, 'opencode', join(repo, 'opencode.json'), 'mcp', opencodeEntry(name)));
|
|
184
212
|
}
|
|
185
213
|
break;
|
|
186
214
|
default:
|
|
@@ -189,11 +217,34 @@ export function mcpTargets(repo, ids, opts = {}) {
|
|
|
189
217
|
}
|
|
190
218
|
return out;
|
|
191
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* Whether a machine-wide config already runs the server under trail's name.
|
|
222
|
+
* Every repo on the machine reads it, and `trail mcp` serves a repo still on
|
|
223
|
+
* graft too, so a graft repo leaves it alone rather than list the server twice.
|
|
224
|
+
*/
|
|
225
|
+
function trailServerIn(t) {
|
|
226
|
+
if (t.format === 'toml') {
|
|
227
|
+
try {
|
|
228
|
+
return stripTomlSection(readFileSync(t.path, 'utf8'), 'trail').found;
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const loaded = readJsonObject(t.path);
|
|
235
|
+
const bucket = loaded === 'unparseable' ? undefined : loaded.root[t.topKey];
|
|
236
|
+
return typeof bucket === 'object' && bucket !== null && !Array.isArray(bucket) && 'trail' in bucket;
|
|
237
|
+
}
|
|
192
238
|
export function registerMcpConfigs(repo, ids, opts = {}) {
|
|
239
|
+
const name = opts.name ?? 'graft';
|
|
193
240
|
return mcpTargets(repo, ids, opts)
|
|
194
241
|
.filter((t) => opts.global !== false || t.scope !== 'global')
|
|
195
|
-
.map((t) =>
|
|
196
|
-
|
|
197
|
-
|
|
242
|
+
.map((t) => {
|
|
243
|
+
if (name === 'graft' && t.scope === 'global' && trailServerIn(t))
|
|
244
|
+
return { id: t.id, path: t.path, action: 'unchanged' };
|
|
245
|
+
return t.format === 'toml'
|
|
246
|
+
? upsertCodexToml(t.id, t.path, name)
|
|
247
|
+
: mergeJsonKey(t.id, t.path, t.topKey, t.entry, name, name === 'trail' ? ['graft'] : []);
|
|
248
|
+
});
|
|
198
249
|
}
|
|
199
250
|
//# sourceMappingURL=mcp-config.js.map
|