@kage-core/kage-graph-mcp 1.1.15 → 1.1.17

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 CHANGED
@@ -9,15 +9,29 @@ This package exposes two surfaces:
9
9
 
10
10
  ## Latest Release
11
11
 
12
- `1.1.15` hardens the npm release path and memory-only review flow:
13
-
14
- - `npm run release:npm:dry-run` runs the guarded release checks without
15
- publishing.
16
- - `npm run release:npm` builds the release helper, requires a clean worktree,
17
- fetches the remote branch, verifies local `HEAD` contains `origin/<branch>`,
18
- runs tests and `npm pack --dry-run`, pushes the branch before publishing,
19
- publishes with `--access public`, verifies npm registry metadata, and performs
20
- a smoke install.
12
+ `1.1.17` publishes content-based graph freshness:
13
+
14
+ - `kage pr check` now uses graph input hashes, so push-only operations and
15
+ empty/same-tree commits do not force another refresh while real source,
16
+ approved-memory, or code-index changes still stale generated graph artifacts.
17
+
18
+ `1.1.16` fixes the guarded release helper's npm verification step:
19
+
20
+ - exact-version `npm view` checks now retry with backoff after publish so npm
21
+ registry propagation does not make a successful publish look failed.
22
+ - the release helper is maintainer-only repo tooling: public package metadata no
23
+ longer exposes npm release scripts, and `dist/release.js` is excluded from the
24
+ published tarball.
25
+
26
+ `1.1.15` hardened the npm release path and memory-only review flow:
27
+
28
+ - the source-repo maintainer helper can run the guarded release checks without
29
+ publishing, or push/publish/smoke-test when explicitly invoked from a built
30
+ checkout.
31
+ - it requires a clean worktree, fetches the remote branch, verifies local `HEAD`
32
+ contains `origin/<branch>`, runs tests and `npm pack --dry-run`, pushes the
33
+ branch before publishing, publishes with `--access public`, verifies npm
34
+ registry metadata, and performs a smoke install.
21
35
  - all git steps run with `GIT_EDITOR=true` so agent sessions cannot get stuck in
22
36
  an interactive commit or rebase editor.
23
37
  - `kage propose --from-diff` now includes repo memory packet-only changes from
@@ -54,20 +68,27 @@ This package exposes two surfaces:
54
68
  ```bash
55
69
  npm install
56
70
  npm run build
57
- npm run release:npm:dry-run
58
71
  ```
59
72
 
60
- Publishing from the repo should use the guarded release script after the release
61
- commit is ready:
73
+ Publishing from the source repo should use the guarded maintainer helper after
74
+ the release commit is ready. It is intentionally not exposed as a public npm
75
+ script or included in the published tarball:
62
76
 
63
77
  ```bash
64
- npm run release:npm
78
+ npm run build --prefix mcp
79
+ cd mcp
80
+ node dist/release.js --dry-run
81
+ node dist/release.js --publish --push --smoke
65
82
  ```
66
83
 
67
84
  The script fetches the current branch and blocks if the remote branch is not an
68
85
  ancestor of local `HEAD`, which prevents publishing an npm version from a branch
69
86
  that cannot be pushed cleanly.
70
87
 
88
+ Do not refresh again just because the branch was pushed. Graph freshness is
89
+ based on source, approved memory, and code-index inputs; empty/same-tree commits
90
+ are accepted by `kage pr check`.
91
+
71
92
  ## CLI
72
93
 
73
94
  ```bash
@@ -221,9 +242,10 @@ hashes, git state, audit trust, inbox counts, and metrics readiness. CI, PR, and
221
242
  sync workflows build it after refresh.
222
243
 
223
244
  Use `kage refresh --project <repo>` or the `kage_refresh` MCP tool after
224
- meaningful file changes. Refresh rebuilds indexes, code graph, memory graph,
225
- metrics, and stale-memory metadata. Memory is marked stale when status or
226
- feedback says it is stale, its TTL expires, or grounded paths disappear.
245
+ meaningful file/content changes. Refresh rebuilds indexes, code graph, memory
246
+ graph, metrics, and stale-memory metadata. Memory is marked stale when status or
247
+ feedback says it is stale, its TTL expires, or grounded paths disappear. Pushes
248
+ and empty/same-tree commits do not need another refresh.
227
249
 
228
250
  Use `kage gc --project <repo> --dry-run` to preview stale packet cleanup.
229
251
  `kage gc --project <repo>` marks stale repo packets deprecated, rebuilds
@@ -396,7 +418,7 @@ Minimum policy:
396
418
  Before code changes or repo-specific answers:
397
419
  1. Call `kage_context` with `project_dir` and the user task as `query`.
398
420
  2. Capture reusable learnings with `kage_learn` or `kage_capture`.
399
- 3. After meaningful file changes, call `kage_refresh`.
421
+ 3. After meaningful file/content changes, call `kage_refresh`; skip it for push-only or same-tree commits.
400
422
  4. Before finishing changed-file tasks, call `kage_propose_from_diff` or `kage_pr_summarize`.
401
423
  5. Before merge, call `kage_pr_check`.
402
424
  6. Never publish or promote org/global memory automatically.
package/dist/index.js CHANGED
@@ -217,7 +217,7 @@ function listTools() {
217
217
  },
218
218
  {
219
219
  name: "kage_refresh",
220
- description: "Rebuild repo indexes, code graph, memory graph, metrics, and stale-memory metadata. Agents should run this after meaningful file changes and before PR checks.",
220
+ description: "Rebuild repo indexes, code graph, memory graph, metrics, and stale-memory metadata. Agents should run this after meaningful file/content changes before PR checks; push-only or same-tree commits do not need another refresh.",
221
221
  inputSchema: {
222
222
  type: "object",
223
223
  properties: {
package/dist/kernel.js CHANGED
@@ -193,8 +193,10 @@ decisions, debugging, explanation, or action. Do not store raw transcripts.
193
193
 
194
194
  ## End-Of-Task Proposal
195
195
 
196
- After meaningful file changes, call \`kage_refresh\` so indexes, code graph,
197
- memory graph, metrics, and stale-memory checks are current.
196
+ After meaningful file/content changes, call \`kage_refresh\` so indexes, code
197
+ graph, memory graph, metrics, and stale-memory checks are current. Do not
198
+ refresh solely because a branch was pushed, an empty commit was created, or the
199
+ git commit changed without graph inputs changing.
198
200
 
199
201
  Before finishing a task that changed files, call \`kage_pr_summarize\` or
200
202
  \`kage_propose_from_diff\`, then call \`kage_pr_check\`.
@@ -232,7 +234,7 @@ For normal coding tasks:
232
234
  1. \`kage_context\` — validate + recall + code graph + knowledge graph in one call
233
235
  2. Work on the task
234
236
  3. \`kage_learn\` for concrete learnings
235
- 4. \`kage_refresh\` after meaningful file changes
237
+ 4. \`kage_refresh\` after meaningful file/content changes, not after push-only or same-tree commits
236
238
  5. \`kage_propose_from_diff\` before the final response to create repo-local change memory
237
239
 
238
240
  For quick factual questions, \`kage_context\` alone is enough. For status or demo requests, call \`kage_metrics\`.
@@ -882,6 +884,9 @@ function gitBranch(projectDir) {
882
884
  function gitHead(projectDir) {
883
885
  return readGit(projectDir, ["rev-parse", "HEAD"]);
884
886
  }
887
+ function gitTree(projectDir) {
888
+ return readGit(projectDir, ["rev-parse", "HEAD^{tree}"]);
889
+ }
885
890
  function gitMergeBase(projectDir) {
886
891
  return readGit(projectDir, ["merge-base", "HEAD", "origin/main"])
887
892
  || readGit(projectDir, ["merge-base", "HEAD", "origin/master"]);
@@ -1863,6 +1868,49 @@ function externalIndexFiles(projectDir) {
1863
1868
  { path: (0, node_path_1.join)(projectDir, "dump.lsif"), parser: "lsif", format: "lsif" },
1864
1869
  ];
1865
1870
  }
1871
+ function sha256Hex(content) {
1872
+ return (0, node_crypto_1.createHash)("sha256").update(content).digest("hex");
1873
+ }
1874
+ function projectRelative(projectDir, path) {
1875
+ return (0, node_path_1.relative)(projectDir, path).replace(/\\/g, "/");
1876
+ }
1877
+ function graphInputHash(entries) {
1878
+ const hash = (0, node_crypto_1.createHash)("sha256");
1879
+ const sorted = entries.slice().sort((a, b) => a.kind.localeCompare(b.kind) || a.path.localeCompare(b.path));
1880
+ for (const entry of sorted) {
1881
+ hash.update(entry.kind);
1882
+ hash.update("\0");
1883
+ hash.update(entry.path);
1884
+ hash.update("\0");
1885
+ hash.update(entry.sha256);
1886
+ hash.update("\0");
1887
+ }
1888
+ return hash.digest("hex");
1889
+ }
1890
+ function fileInputEntries(projectDir, paths, kind) {
1891
+ return paths
1892
+ .filter((path) => (0, node_fs_1.existsSync)(path))
1893
+ .map((path) => ({
1894
+ kind,
1895
+ path: projectRelative(projectDir, path),
1896
+ sha256: sha256Hex((0, node_fs_1.readFileSync)(path)),
1897
+ }));
1898
+ }
1899
+ function codeGraphInputHash(projectDir) {
1900
+ return graphInputHash([
1901
+ ...fileInputEntries(projectDir, listCodeFiles(projectDir), "code_file"),
1902
+ ...fileInputEntries(projectDir, externalIndexFiles(projectDir).map((index) => index.path), "external_code_index"),
1903
+ ]);
1904
+ }
1905
+ function knowledgeGraphInputHash(projectDir, codeInputHash = codeGraphInputHash(projectDir)) {
1906
+ const packetEntries = loadPacketEntriesFromDir(packetsDir(projectDir))
1907
+ .filter((entry) => entry.packet.status === "approved")
1908
+ .map((entry) => entry.path);
1909
+ return graphInputHash([
1910
+ { kind: "code_graph_input", path: ".agent_memory/code_graph/input", sha256: codeInputHash },
1911
+ ...fileInputEntries(projectDir, packetEntries, "approved_packet"),
1912
+ ]);
1913
+ }
1866
1914
  function normalizeExternalKind(value) {
1867
1915
  const kind = String(value ?? "").toLowerCase();
1868
1916
  if (["function", "method", "class", "constant", "route", "test"].includes(kind))
@@ -2103,7 +2151,9 @@ function buildCodeGraph(projectDir) {
2103
2151
  ensureMemoryDirs(projectDir);
2104
2152
  const branch = gitBranch(projectDir);
2105
2153
  const head = gitHead(projectDir);
2154
+ const tree = gitTree(projectDir);
2106
2155
  const mergeBase = gitMergeBase(projectDir);
2156
+ const inputHash = codeGraphInputHash(projectDir);
2107
2157
  const absoluteFiles = listCodeFiles(projectDir);
2108
2158
  const knownFiles = new Set(absoluteFiles.map((path) => (0, node_path_1.relative)(projectDir, path).replace(/\\/g, "/")));
2109
2159
  const files = [];
@@ -2188,7 +2238,7 @@ function buildCodeGraph(projectDir) {
2188
2238
  project_dir: projectDir,
2189
2239
  repo_key: repoKey(projectDir),
2190
2240
  generated_at: nowIso(),
2191
- repo_state: { branch, head, merge_base: mergeBase },
2241
+ repo_state: { branch, head, merge_base: mergeBase, tree, input_hash: inputHash },
2192
2242
  files: files.sort((a, b) => a.path.localeCompare(b.path)),
2193
2243
  symbols: symbols.sort((a, b) => a.path.localeCompare(b.path) || a.line - b.line || a.name.localeCompare(b.name)),
2194
2244
  imports: imports.sort((a, b) => a.from_path.localeCompare(b.from_path) || a.line - b.line || a.specifier.localeCompare(b.specifier)),
@@ -2212,6 +2262,7 @@ function buildKnowledgeGraph(projectDir) {
2212
2262
  const packets = loadApprovedPackets(projectDir).sort((a, b) => a.id.localeCompare(b.id));
2213
2263
  const branch = gitBranch(projectDir);
2214
2264
  const head = gitHead(projectDir);
2265
+ const tree = gitTree(projectDir);
2215
2266
  const mergeBase = gitMergeBase(projectDir);
2216
2267
  const entities = new Map();
2217
2268
  const edges = new Map();
@@ -2219,6 +2270,7 @@ function buildKnowledgeGraph(projectDir) {
2219
2270
  const repoEntityId = graphEntityId("repo", repoKey(projectDir));
2220
2271
  const generatedFrom = packets.map((packet) => packet.updated_at).sort().at(-1) ?? null;
2221
2272
  const codeGraph = buildCodeGraph(projectDir);
2273
+ const inputHash = knowledgeGraphInputHash(projectDir, codeGraph.repo_state.input_hash ?? codeGraphInputHash(projectDir));
2222
2274
  addEntity(entities, {
2223
2275
  id: repoEntityId,
2224
2276
  type: "repo",
@@ -2540,7 +2592,7 @@ function buildKnowledgeGraph(projectDir) {
2540
2592
  project_dir: projectDir,
2541
2593
  repo_key: repoKey(projectDir),
2542
2594
  generated_from_updated_at: generatedFrom,
2543
- repo_state: { branch, head, merge_base: mergeBase },
2595
+ repo_state: { branch, head, merge_base: mergeBase, tree, input_hash: inputHash },
2544
2596
  episodes: episodes.sort((a, b) => a.id.localeCompare(b.id)),
2545
2597
  entities: [...entities.values()].sort((a, b) => a.id.localeCompare(b.id)),
2546
2598
  edges: [...edges.values()].sort((a, b) => a.id.localeCompare(b.id)),
@@ -4239,7 +4291,7 @@ Before making code changes or answering implementation questions:
4239
4291
  1. Call kage_context with project_dir and the user task as query.
4240
4292
  2. Use returned memory only when it is relevant, source-backed, and not stale.
4241
4293
  When you learn something reusable: kage_learn.
4242
- After meaningful file changes: kage_refresh.
4294
+ After meaningful file/content changes: kage_refresh. Push-only or same-tree commits do not need another refresh.
4243
4295
  Before finishing a task that changed files: kage_pr_summarize or kage_propose_from_diff, then kage_pr_check.
4244
4296
  If recalled memory helped: kage_feedback helpful. If wrong or stale: kage_feedback wrong or stale."
4245
4297
  fi
@@ -4963,15 +5015,22 @@ function createReviewArtifact(projectDir) {
4963
5015
  (0, node_fs_1.writeFileSync)(path, `${lines.join("\n").trim()}\n`, "utf8");
4964
5016
  return { path, pending: pending.length };
4965
5017
  }
4966
- function graphIsCurrent(projectDir, relativePath, head) {
5018
+ function graphIsCurrent(projectDir, relativePath, expected) {
4967
5019
  const path = (0, node_path_1.join)(projectDir, relativePath);
4968
5020
  if (!(0, node_fs_1.existsSync)(path))
4969
5021
  return false;
4970
- if (!head)
4971
- return true;
4972
5022
  try {
4973
5023
  const graph = readJson(path);
4974
- return graph.repo_state?.head === head;
5024
+ const repoState = graph.repo_state;
5025
+ if (!repoState)
5026
+ return false;
5027
+ if (expected.inputHash && repoState.input_hash)
5028
+ return repoState.input_hash === expected.inputHash;
5029
+ if (expected.tree && repoState.tree)
5030
+ return repoState.tree === expected.tree;
5031
+ if (!expected.head)
5032
+ return true;
5033
+ return repoState.head === expected.head;
4975
5034
  }
4976
5035
  catch {
4977
5036
  return false;
@@ -5005,6 +5064,9 @@ function prCheck(projectDir) {
5005
5064
  const overlay = buildBranchOverlay(projectDir);
5006
5065
  const rawStatus = readGit(projectDir, ["status", "--porcelain", "-uall"]) ?? "";
5007
5066
  const validation = validateProject(projectDir);
5067
+ const tree = gitTree(projectDir);
5068
+ const codeInputHash = codeGraphInputHash(projectDir);
5069
+ const memoryInputHash = knowledgeGraphInputHash(projectDir, codeInputHash);
5008
5070
  const stalePackets = loadPacketsFromDir(packetsDir(projectDir))
5009
5071
  .map((packet) => ({ packet, reasons: staleMemoryReasons(projectDir, packet) }))
5010
5072
  .filter((entry) => entry.reasons.length)
@@ -5014,8 +5076,8 @@ function prCheck(projectDir) {
5014
5076
  .map(parsePorcelainPath)
5015
5077
  .map((path) => path.replace(/^.* -> /, ""))
5016
5078
  .filter((path) => path.startsWith(".agent_memory/packets/") && path.endsWith(".json"))).sort();
5017
- const codeGraphCurrent = graphIsCurrent(projectDir, ".agent_memory/code_graph/graph.json", overlay.head);
5018
- const memoryGraphCurrent = graphIsCurrent(projectDir, ".agent_memory/graph/graph.json", overlay.head);
5079
+ const codeGraphCurrent = graphIsCurrent(projectDir, ".agent_memory/code_graph/graph.json", { head: overlay.head, tree, inputHash: codeInputHash });
5080
+ const memoryGraphCurrent = graphIsCurrent(projectDir, ".agent_memory/graph/graph.json", { head: overlay.head, tree, inputHash: memoryInputHash });
5019
5081
  const errors = [...validation.errors];
5020
5082
  const warnings = [...validation.warnings];
5021
5083
  const requiredActions = [];
@@ -5024,7 +5086,7 @@ function prCheck(projectDir) {
5024
5086
  requiredActions.push("Run kage refresh, then update or supersede stale packets.");
5025
5087
  }
5026
5088
  if (!codeGraphCurrent || !memoryGraphCurrent) {
5027
- errors.push("Generated graph artifacts are missing or not current for this branch head.");
5089
+ errors.push("Generated graph artifacts are missing or not current for this working tree content.");
5028
5090
  requiredActions.push("Run kage refresh --project <dir> before merge.");
5029
5091
  }
5030
5092
  if (!memoryPacketChanges.length && overlay.changed_files.some((path) => !path.startsWith(".agent_memory/"))) {
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@kage-core/kage-graph-mcp",
3
- "version": "1.1.15",
3
+ "version": "1.1.17",
4
4
  "description": "Local-first repo memory, code graph, and recall MCP server for coding agents",
5
5
  "main": "dist/index.js",
6
6
  "files": [
7
7
  "dist/**/*.js",
8
8
  "!dist/**/*.test.js",
9
+ "!dist/release.js",
9
10
  "viewer/**/*",
10
11
  "!viewer/graphs/*.json",
11
12
  "README.md"
@@ -21,9 +22,7 @@
21
22
  "build": "tsc",
22
23
  "start": "node dist/index.js",
23
24
  "dev": "ts-node index.ts",
24
- "test": "npm run build && node --test dist/**/*.test.js",
25
- "release:npm:dry-run": "npm run build && node dist/release.js --dry-run",
26
- "release:npm": "npm run build && node dist/release.js --publish --push --smoke"
25
+ "test": "npm run build && node --test dist/**/*.test.js"
27
26
  },
28
27
  "keywords": [
29
28
  "mcp",
package/dist/release.js DELETED
@@ -1,121 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseReleaseArgs = parseReleaseArgs;
4
- exports.buildNpmReleasePlan = buildNpmReleasePlan;
5
- exports.runNpmRelease = runNpmRelease;
6
- const node_child_process_1 = require("node:child_process");
7
- const node_fs_1 = require("node:fs");
8
- const node_os_1 = require("node:os");
9
- const node_path_1 = require("node:path");
10
- const DEFAULT_CACHE = "/private/tmp/kage-npm-cache";
11
- function parseReleaseArgs(argv) {
12
- const options = {
13
- publish: false,
14
- push: false,
15
- smoke: false,
16
- cache: DEFAULT_CACHE,
17
- };
18
- for (let index = 0; index < argv.length; index += 1) {
19
- const arg = argv[index];
20
- if (arg === "--publish")
21
- options.publish = true;
22
- else if (arg === "--dry-run")
23
- options.publish = false;
24
- else if (arg === "--push")
25
- options.push = true;
26
- else if (arg === "--smoke")
27
- options.smoke = true;
28
- else if (arg === "--cache") {
29
- const value = argv[index + 1];
30
- if (!value)
31
- throw new Error("--cache requires a path");
32
- options.cache = value;
33
- index += 1;
34
- }
35
- else {
36
- throw new Error(`Unknown release option: ${arg}`);
37
- }
38
- }
39
- return options;
40
- }
41
- function buildNpmReleasePlan(context) {
42
- const gitEnv = { GIT_EDITOR: "true" };
43
- const steps = [
44
- { name: "ensure clean worktree", command: "git", args: ["status", "--porcelain", "-uall"], env: gitEnv, expectEmptyStdout: true },
45
- { name: "fetch remote branch", command: "git", args: ["fetch", "origin", context.branch], env: gitEnv },
46
- { name: "ensure branch contains remote", command: "git", args: ["merge-base", "--is-ancestor", `origin/${context.branch}`, "HEAD"], env: gitEnv },
47
- { name: "run package tests", command: "npm", args: ["test"] },
48
- { name: "pack dry run", command: "npm", args: ["--cache", context.cache, "pack", "--dry-run"] },
49
- ];
50
- if (context.push) {
51
- steps.push({ name: "push branch", command: "git", args: ["push", "origin", context.branch], env: gitEnv });
52
- }
53
- if (context.publish) {
54
- steps.push({ name: "publish package", command: "npm", args: ["--cache", context.cache, "publish", "--access", "public"] }, { name: "verify npm version", command: "npm", args: ["view", `${context.packageName}@${context.version}`, "version"] });
55
- if (context.smoke) {
56
- steps.push({
57
- name: "smoke install published package",
58
- command: "npm",
59
- args: ["--cache", context.cache, "install", "--prefix", smokeInstallDir(context.version), `${context.packageName}@${context.version}`],
60
- });
61
- }
62
- }
63
- return steps;
64
- }
65
- function smokeInstallDir(version) {
66
- return (0, node_path_1.join)((0, node_os_1.tmpdir)(), `kage-npm-smoke-${version}`);
67
- }
68
- function stdout(command, args, cwd) {
69
- return (0, node_child_process_1.execFileSync)(command, args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
70
- }
71
- function packageMetadata(packageDir) {
72
- const pkg = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(packageDir, "package.json"), "utf8"));
73
- if (typeof pkg.name !== "string" || typeof pkg.version !== "string") {
74
- throw new Error("package.json must contain string name and version");
75
- }
76
- return { name: pkg.name, version: pkg.version };
77
- }
78
- function runStep(step, cwd) {
79
- console.log(`release:npm: ${step.name}`);
80
- if (step.expectEmptyStdout) {
81
- const output = (0, node_child_process_1.execFileSync)(step.command, step.args, {
82
- cwd,
83
- encoding: "utf8",
84
- stdio: ["ignore", "pipe", "inherit"],
85
- env: { ...process.env, ...step.env },
86
- }).trim();
87
- if (output)
88
- throw new Error(`release:npm: ${step.name} failed because output was not empty:\n${output}`);
89
- return;
90
- }
91
- (0, node_child_process_1.execFileSync)(step.command, step.args, {
92
- cwd,
93
- stdio: "inherit",
94
- env: { ...process.env, ...step.env },
95
- });
96
- }
97
- function runNpmRelease(argv = process.argv.slice(2), packageDir = process.cwd()) {
98
- const options = parseReleaseArgs(argv);
99
- const repoRoot = stdout("git", ["rev-parse", "--show-toplevel"], packageDir);
100
- const branch = stdout("git", ["branch", "--show-current"], repoRoot);
101
- if (!branch)
102
- throw new Error("npm release requires a named git branch");
103
- (0, node_fs_1.mkdirSync)(options.cache, { recursive: true });
104
- if (options.smoke)
105
- (0, node_fs_1.mkdirSync)(smokeInstallDir(packageMetadata(packageDir).version), { recursive: true });
106
- const metadata = packageMetadata(packageDir);
107
- const plan = buildNpmReleasePlan({ ...options, branch, packageName: metadata.name, version: metadata.version });
108
- console.log(`release:npm: package ${metadata.name}@${metadata.version}`);
109
- console.log(`release:npm: mode ${options.publish ? "publish" : "dry-run"}`);
110
- for (const step of plan)
111
- runStep(step, repoRoot === (0, node_path_1.resolve)(packageDir, "..") ? packageDir : repoRoot);
112
- }
113
- if (process.argv[1] && process.argv[1].endsWith("release.js")) {
114
- try {
115
- runNpmRelease();
116
- }
117
- catch (error) {
118
- console.error(error instanceof Error ? error.message : String(error));
119
- process.exit(2);
120
- }
121
- }