@polterware/polter 0.3.1 → 0.4.1

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/dist/api.js CHANGED
@@ -1,12 +1,17 @@
1
- import "./chunk-AGVTFYXU.js";
1
+ import {
2
+ createIpcClient
3
+ } from "./chunk-VYHW3UNY.js";
2
4
  import {
3
5
  allCommands,
4
6
  applyActions,
7
+ createIpcServer,
5
8
  deletePipeline,
6
9
  detectPkgManager,
7
10
  executePipeline,
8
11
  features,
9
12
  findPipelineByName,
13
+ findProcessesByCwd,
14
+ findRunningByCommand,
10
15
  generateProcessId,
11
16
  getAllPipelines,
12
17
  getCommandById,
@@ -17,6 +22,8 @@ import {
17
22
  getFlagsForTool,
18
23
  getMcpStatusInfo,
19
24
  getProcessOutput,
25
+ getSocketPath,
26
+ getToolDisplayName,
20
27
  getToolInfo,
21
28
  installMcpServerSilent,
22
29
  isProcessRunning,
@@ -33,15 +40,19 @@ import {
33
40
  stopProcess,
34
41
  toolFlags,
35
42
  translateCommand
36
- } from "./chunk-7MIUDIAI.js";
43
+ } from "./chunk-ZHVOYB5M.js";
37
44
  export {
38
45
  allCommands,
39
46
  applyActions,
47
+ createIpcClient,
48
+ createIpcServer,
40
49
  deletePipeline,
41
50
  detectPkgManager,
42
51
  executePipeline,
43
52
  features,
44
53
  findPipelineByName,
54
+ findProcessesByCwd,
55
+ findRunningByCommand,
45
56
  generateProcessId,
46
57
  getAllPipelines,
47
58
  getCommandById,
@@ -52,6 +63,8 @@ export {
52
63
  getFlagsForTool,
53
64
  getMcpStatusInfo,
54
65
  getProcessOutput,
66
+ getSocketPath,
67
+ getToolDisplayName,
55
68
  getToolInfo,
56
69
  installMcpServerSilent,
57
70
  isProcessRunning,
@@ -0,0 +1,108 @@
1
+ import {
2
+ parseMessages,
3
+ serializeMessage
4
+ } from "./chunk-ZHVOYB5M.js";
5
+
6
+ // src/lib/ipcClient.ts
7
+ import net from "net";
8
+ var DEFAULT_TIMEOUT = 5e3;
9
+ function createIpcClient(socketPath) {
10
+ let socket = null;
11
+ let connected = false;
12
+ let nextId = 1;
13
+ let buffer = "";
14
+ const pending = /* @__PURE__ */ new Map();
15
+ function handleData(data) {
16
+ buffer += data.toString();
17
+ const { messages, remainder } = parseMessages(buffer);
18
+ buffer = remainder;
19
+ for (const msg of messages) {
20
+ if ("id" in msg && !("method" in msg)) {
21
+ const resp = msg;
22
+ const entry = pending.get(resp.id);
23
+ if (entry) {
24
+ pending.delete(resp.id);
25
+ if (resp.error) {
26
+ entry.reject(new Error(resp.error.message));
27
+ } else {
28
+ entry.resolve(resp.result);
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+ return {
35
+ connect() {
36
+ return new Promise((resolve, reject) => {
37
+ socket = net.createConnection(socketPath);
38
+ socket.on("connect", () => {
39
+ connected = true;
40
+ resolve();
41
+ });
42
+ socket.on("data", handleData);
43
+ socket.on("close", () => {
44
+ connected = false;
45
+ for (const entry of pending.values()) {
46
+ entry.reject(new Error("Connection closed"));
47
+ }
48
+ pending.clear();
49
+ });
50
+ socket.on("error", (err) => {
51
+ connected = false;
52
+ if (!connected) {
53
+ reject(err);
54
+ }
55
+ });
56
+ });
57
+ },
58
+ disconnect() {
59
+ if (socket) {
60
+ socket.destroy();
61
+ socket = null;
62
+ connected = false;
63
+ }
64
+ },
65
+ isConnected() {
66
+ return connected;
67
+ },
68
+ call(method, params) {
69
+ if (!socket || !connected) {
70
+ return Promise.reject(new Error("Not connected"));
71
+ }
72
+ const id = nextId++;
73
+ const request = {
74
+ jsonrpc: "2.0",
75
+ id,
76
+ method,
77
+ ...params !== void 0 ? { params } : {}
78
+ };
79
+ return new Promise((resolve, reject) => {
80
+ const timer = setTimeout(() => {
81
+ pending.delete(id);
82
+ reject(new Error(`RPC call "${method}" timed out after ${DEFAULT_TIMEOUT}ms`));
83
+ }, DEFAULT_TIMEOUT);
84
+ pending.set(id, {
85
+ resolve: (v) => {
86
+ clearTimeout(timer);
87
+ resolve(v);
88
+ },
89
+ reject: (e) => {
90
+ clearTimeout(timer);
91
+ reject(e);
92
+ }
93
+ });
94
+ try {
95
+ socket.write(serializeMessage(request));
96
+ } catch (err) {
97
+ clearTimeout(timer);
98
+ pending.delete(id);
99
+ reject(err);
100
+ }
101
+ });
102
+ }
103
+ };
104
+ }
105
+
106
+ export {
107
+ createIpcClient
108
+ };
@@ -675,8 +675,7 @@ var gitCommands = [
675
675
 
676
676
  // src/data/commands/pkg.ts
677
677
  var pkgCommands = [
678
- // Build & Publish
679
- { id: "pkg:build", tool: "pkg", base: ["run", "build"], label: "build", hint: "Run build script" },
678
+ // Publish & Version
680
679
  { id: "pkg:publish", tool: "pkg", base: ["publish"], label: "publish", hint: "Publish package to registry" },
681
680
  { id: "pkg:pack", tool: "pkg", base: ["pack"], label: "pack", hint: "Create tarball from package" },
682
681
  { id: "pkg:version:patch", tool: "pkg", base: ["version", "patch"], label: "version patch", hint: "Bump patch version" },
@@ -695,8 +694,7 @@ var pkgCommands = [
695
694
  // Registry & Config
696
695
  { id: "pkg:config:list", tool: "pkg", base: ["config", "list"], label: "config list", hint: "Show config" },
697
696
  { id: "pkg:whoami", tool: "pkg", base: ["whoami"], label: "whoami", hint: "Show logged-in user" },
698
- // Scripts & Info
699
- { id: "pkg:run", tool: "pkg", base: ["run"], label: "run", hint: "Run a package script" },
697
+ // Info & Registry
700
698
  { id: "pkg:info", tool: "pkg", base: ["info"], label: "info", hint: "Show package info" },
701
699
  { id: "pkg:search", tool: "pkg", base: ["search"], label: "search", hint: "Search packages in registry" },
702
700
  { id: "pkg:init", tool: "pkg", base: ["init"], label: "init", hint: "Initialize a new package.json" }
@@ -863,8 +861,6 @@ var features = [
863
861
  "pkg:outdated",
864
862
  "pkg:audit",
865
863
  "pkg:ls",
866
- "pkg:build",
867
- "pkg:run",
868
864
  "pkg:publish",
869
865
  "pkg:pack",
870
866
  "pkg:version:patch",
@@ -993,6 +989,7 @@ function runCommand(execution, args, cwd = process.cwd(), options) {
993
989
  cwd,
994
990
  env: resolvedExecution.env,
995
991
  shell: true,
992
+ detached: true,
996
993
  stdio: [options?.quiet ? "pipe" : "inherit", "pipe", "pipe"]
997
994
  });
998
995
  if (options?.quiet) {
@@ -1003,11 +1000,13 @@ function runCommand(execution, args, cwd = process.cwd(), options) {
1003
1000
  const text = data.toString();
1004
1001
  stdout += text;
1005
1002
  if (!options?.quiet) process.stdout.write(text);
1003
+ options?.onData?.(stdout, stderr);
1006
1004
  });
1007
1005
  child.stderr?.on("data", (data) => {
1008
1006
  const text = data.toString();
1009
1007
  stderr += text;
1010
1008
  if (!options?.quiet) process.stderr.write(text);
1009
+ options?.onData?.(stdout, stderr);
1011
1010
  });
1012
1011
  child.on("error", (err) => {
1013
1012
  resolve3({
@@ -1024,7 +1023,14 @@ function runCommand(execution, args, cwd = process.cwd(), options) {
1024
1023
  });
1025
1024
  return {
1026
1025
  promise,
1027
- abort: () => child.kill("SIGTERM")
1026
+ abort: () => {
1027
+ if (child.pid) {
1028
+ try {
1029
+ process.kill(-child.pid, "SIGTERM");
1030
+ } catch {
1031
+ }
1032
+ }
1033
+ }
1028
1034
  };
1029
1035
  }
1030
1036
  function runInteractiveCommand(execution, args, cwd = process.cwd()) {
@@ -1183,6 +1189,20 @@ function execCapture(command) {
1183
1189
  }
1184
1190
 
1185
1191
  // src/lib/toolResolver.ts
1192
+ function getToolDisplayName(toolId, cwd = process.cwd()) {
1193
+ if (toolId === "pkg") {
1194
+ const mgr = detectPkgManager(cwd);
1195
+ return mgr.id;
1196
+ }
1197
+ const names = {
1198
+ supabase: "supabase",
1199
+ gh: "github",
1200
+ vercel: "vercel",
1201
+ git: "git",
1202
+ pkg: "npm"
1203
+ };
1204
+ return names[toolId];
1205
+ }
1186
1206
  function resolveToolCommand(toolId, cwd = process.cwd()) {
1187
1207
  if (toolId === "supabase") {
1188
1208
  const resolved = resolveSupabaseCommand(cwd);
@@ -1325,6 +1345,31 @@ function getToolLinkInfo(toolId, cwd = process.cwd()) {
1325
1345
 
1326
1346
  // src/lib/processManager.ts
1327
1347
  import { spawn as spawn2 } from "child_process";
1348
+ import { join as join5 } from "path";
1349
+
1350
+ // src/lib/packageRoot.ts
1351
+ import { existsSync as existsSync4 } from "fs";
1352
+ import { dirname as dirname3, join as join4, resolve as resolve2 } from "path";
1353
+ var rootCache = /* @__PURE__ */ new Map();
1354
+ function findNearestPackageRoot(startDir = process.cwd()) {
1355
+ const resolvedStart = resolve2(startDir);
1356
+ if (rootCache.has(resolvedStart)) return rootCache.get(resolvedStart);
1357
+ let currentDir = resolvedStart;
1358
+ while (true) {
1359
+ if (existsSync4(join4(currentDir, "package.json"))) {
1360
+ rootCache.set(resolvedStart, currentDir);
1361
+ return currentDir;
1362
+ }
1363
+ const parentDir = dirname3(currentDir);
1364
+ if (parentDir === currentDir) {
1365
+ rootCache.set(resolvedStart, void 0);
1366
+ return void 0;
1367
+ }
1368
+ currentDir = parentDir;
1369
+ }
1370
+ }
1371
+
1372
+ // src/lib/processManager.ts
1328
1373
  var DEFAULT_BUFFER_CAP = 1e3;
1329
1374
  function createRingBuffer(cap = DEFAULT_BUFFER_CAP) {
1330
1375
  return { lines: [], cap, totalLines: 0 };
@@ -1492,6 +1537,20 @@ function removeProcess(id) {
1492
1537
  }
1493
1538
  registry.delete(id);
1494
1539
  }
1540
+ function findProcessesByCwd(cwd) {
1541
+ const normalized = cwd.replace(/\/+$/, "");
1542
+ return Array.from(registry.values()).filter((proc) => proc.cwd.replace(/\/+$/, "") === normalized).map(toProcessInfo);
1543
+ }
1544
+ function findRunningByCommand(cwd, command, args) {
1545
+ const normalized = cwd.replace(/\/+$/, "");
1546
+ const argsStr = args.join(" ");
1547
+ for (const proc of registry.values()) {
1548
+ if (proc.cwd.replace(/\/+$/, "") === normalized && proc.status === "running" && proc.command === command && proc.args.join(" ") === argsStr) {
1549
+ return toProcessInfo(proc);
1550
+ }
1551
+ }
1552
+ return void 0;
1553
+ }
1495
1554
  function toProcessInfo(proc) {
1496
1555
  const now = Date.now();
1497
1556
  const start = proc.startedAt.getTime();
@@ -1510,6 +1569,188 @@ function toProcessInfo(proc) {
1510
1569
  uptime: end - start
1511
1570
  };
1512
1571
  }
1572
+ function getSocketPath(cwd) {
1573
+ const root = findNearestPackageRoot(cwd);
1574
+ if (!root) return void 0;
1575
+ return join5(root, ".polter", "polter.sock");
1576
+ }
1577
+
1578
+ // src/lib/ipcServer.ts
1579
+ import net from "net";
1580
+ import { mkdirSync, unlinkSync, existsSync as existsSync5 } from "fs";
1581
+ import { dirname as dirname4 } from "path";
1582
+
1583
+ // src/lib/ipcProtocol.ts
1584
+ var DELIMITER = "\n";
1585
+ function serializeMessage(msg) {
1586
+ return JSON.stringify(msg) + DELIMITER;
1587
+ }
1588
+ function parseMessages(buffer) {
1589
+ const messages = [];
1590
+ let remainder = buffer;
1591
+ let idx;
1592
+ while ((idx = remainder.indexOf(DELIMITER)) !== -1) {
1593
+ const line = remainder.slice(0, idx);
1594
+ remainder = remainder.slice(idx + 1);
1595
+ if (line.length === 0) continue;
1596
+ try {
1597
+ messages.push(JSON.parse(line));
1598
+ } catch {
1599
+ }
1600
+ }
1601
+ return { messages, remainder };
1602
+ }
1603
+
1604
+ // src/lib/ipcServer.ts
1605
+ var handlers = {
1606
+ "ps.list": () => listProcesses(),
1607
+ "ps.start": (params) => {
1608
+ const { command, args, cwd, id } = params;
1609
+ const processArgs = args ?? [];
1610
+ const processId = id ?? generateProcessId(command, processArgs);
1611
+ const processCwd = cwd ?? process.cwd();
1612
+ return startProcess(processId, command, processArgs, processCwd);
1613
+ },
1614
+ "ps.stop": async (params) => {
1615
+ const { id } = params;
1616
+ return stopProcess(id);
1617
+ },
1618
+ "ps.logs": (params) => {
1619
+ const { id, tail, stream } = params;
1620
+ return getProcessOutput(id, tail, stream);
1621
+ },
1622
+ "ps.remove": (params) => {
1623
+ const { id } = params;
1624
+ removeProcess(id);
1625
+ return null;
1626
+ },
1627
+ "ps.find_by_cwd": (params) => {
1628
+ const { cwd, filter } = params;
1629
+ let processes = findProcessesByCwd(cwd);
1630
+ if (filter) {
1631
+ const f = filter.toLowerCase();
1632
+ processes = processes.filter(
1633
+ (p) => (p.command + " " + p.args.join(" ")).toLowerCase().includes(f)
1634
+ );
1635
+ }
1636
+ return processes;
1637
+ },
1638
+ "ps.find_running": (params) => {
1639
+ const { cwd, command, args } = params;
1640
+ return findRunningByCommand(cwd, command, args) ?? null;
1641
+ },
1642
+ "ps.generate_id": (params) => {
1643
+ const { command, args } = params;
1644
+ return generateProcessId(command, args);
1645
+ },
1646
+ status: () => ({ tui: true, pid: process.pid })
1647
+ };
1648
+ async function handleRequest(req) {
1649
+ const handler = handlers[req.method];
1650
+ if (!handler) {
1651
+ return {
1652
+ jsonrpc: "2.0",
1653
+ id: req.id,
1654
+ error: { code: -32601, message: `Method not found: ${req.method}` }
1655
+ };
1656
+ }
1657
+ try {
1658
+ const result = await handler(req.params ?? {});
1659
+ return { jsonrpc: "2.0", id: req.id, result };
1660
+ } catch (err) {
1661
+ return {
1662
+ jsonrpc: "2.0",
1663
+ id: req.id,
1664
+ error: { code: -32e3, message: err.message }
1665
+ };
1666
+ }
1667
+ }
1668
+ function createIpcServer(socketPath) {
1669
+ let server = null;
1670
+ const connections = /* @__PURE__ */ new Set();
1671
+ function handleConnection(socket) {
1672
+ connections.add(socket);
1673
+ let buffer = "";
1674
+ socket.on("data", async (data) => {
1675
+ buffer += data.toString();
1676
+ const { messages, remainder } = parseMessages(buffer);
1677
+ buffer = remainder;
1678
+ for (const msg of messages) {
1679
+ if ("method" in msg) {
1680
+ const response = await handleRequest(msg);
1681
+ try {
1682
+ socket.write(serializeMessage(response));
1683
+ } catch {
1684
+ }
1685
+ }
1686
+ }
1687
+ });
1688
+ socket.on("close", () => {
1689
+ connections.delete(socket);
1690
+ });
1691
+ socket.on("error", () => {
1692
+ connections.delete(socket);
1693
+ });
1694
+ }
1695
+ async function cleanStaleSocket() {
1696
+ if (!existsSync5(socketPath)) return;
1697
+ return new Promise((resolve3) => {
1698
+ const probe = net.createConnection(socketPath);
1699
+ probe.on("connect", () => {
1700
+ probe.destroy();
1701
+ resolve3();
1702
+ });
1703
+ probe.on("error", () => {
1704
+ try {
1705
+ unlinkSync(socketPath);
1706
+ } catch {
1707
+ }
1708
+ resolve3();
1709
+ });
1710
+ });
1711
+ }
1712
+ return {
1713
+ async start() {
1714
+ mkdirSync(dirname4(socketPath), { recursive: true });
1715
+ await cleanStaleSocket();
1716
+ return new Promise((resolve3, reject) => {
1717
+ server = net.createServer(handleConnection);
1718
+ server.on("error", (err) => {
1719
+ if (err.code === "EADDRINUSE") {
1720
+ try {
1721
+ unlinkSync(socketPath);
1722
+ } catch {
1723
+ }
1724
+ server.listen(socketPath, () => resolve3());
1725
+ } else {
1726
+ reject(err);
1727
+ }
1728
+ });
1729
+ server.listen(socketPath, () => resolve3());
1730
+ });
1731
+ },
1732
+ async stop() {
1733
+ for (const conn of connections) {
1734
+ conn.destroy();
1735
+ }
1736
+ connections.clear();
1737
+ return new Promise((resolve3) => {
1738
+ if (!server) {
1739
+ resolve3();
1740
+ return;
1741
+ }
1742
+ server.close(() => {
1743
+ try {
1744
+ unlinkSync(socketPath);
1745
+ } catch {
1746
+ }
1747
+ server = null;
1748
+ resolve3();
1749
+ });
1750
+ });
1751
+ }
1752
+ };
1753
+ }
1513
1754
 
1514
1755
  // src/pipeline/engine.ts
1515
1756
  async function executePipeline(pipeline, onProgress, cwd = process.cwd()) {
@@ -1564,32 +1805,8 @@ async function executePipeline(pipeline, onProgress, cwd = process.cwd()) {
1564
1805
  }
1565
1806
 
1566
1807
  // src/config/projectConfig.ts
1567
- import { existsSync as existsSync5, readFileSync as readFileSync2, writeFileSync, mkdirSync } from "fs";
1568
- import { join as join5 } from "path";
1569
-
1570
- // src/lib/packageRoot.ts
1571
- import { existsSync as existsSync4 } from "fs";
1572
- import { dirname as dirname3, join as join4, resolve as resolve2 } from "path";
1573
- var rootCache = /* @__PURE__ */ new Map();
1574
- function findNearestPackageRoot(startDir = process.cwd()) {
1575
- const resolvedStart = resolve2(startDir);
1576
- if (rootCache.has(resolvedStart)) return rootCache.get(resolvedStart);
1577
- let currentDir = resolvedStart;
1578
- while (true) {
1579
- if (existsSync4(join4(currentDir, "package.json"))) {
1580
- rootCache.set(resolvedStart, currentDir);
1581
- return currentDir;
1582
- }
1583
- const parentDir = dirname3(currentDir);
1584
- if (parentDir === currentDir) {
1585
- rootCache.set(resolvedStart, void 0);
1586
- return void 0;
1587
- }
1588
- currentDir = parentDir;
1589
- }
1590
- }
1591
-
1592
- // src/config/projectConfig.ts
1808
+ import { existsSync as existsSync6, readFileSync as readFileSync2, writeFileSync, mkdirSync as mkdirSync2 } from "fs";
1809
+ import { join as join6 } from "path";
1593
1810
  var CONFIG_DIR = ".polter";
1594
1811
  var CONFIG_FILE = "config.json";
1595
1812
  function defaultConfig() {
@@ -1602,13 +1819,13 @@ function defaultConfig() {
1602
1819
  function getProjectConfigPath(startDir) {
1603
1820
  const root = findNearestPackageRoot(startDir);
1604
1821
  if (!root) return void 0;
1605
- const dir = join5(root, CONFIG_DIR);
1606
- return { dir, file: join5(dir, CONFIG_FILE) };
1822
+ const dir = join6(root, CONFIG_DIR);
1823
+ return { dir, file: join6(dir, CONFIG_FILE) };
1607
1824
  }
1608
1825
  function readProjectConfig(startDir) {
1609
1826
  const paths = getProjectConfigPath(startDir);
1610
1827
  if (!paths) return void 0;
1611
- if (!existsSync5(paths.file)) return void 0;
1828
+ if (!existsSync6(paths.file)) return void 0;
1612
1829
  try {
1613
1830
  const raw = readFileSync2(paths.file, "utf-8");
1614
1831
  return JSON.parse(raw);
@@ -1619,7 +1836,7 @@ function readProjectConfig(startDir) {
1619
1836
  function writeProjectConfig(config2, startDir) {
1620
1837
  const paths = getProjectConfigPath(startDir);
1621
1838
  if (!paths) return false;
1622
- mkdirSync(paths.dir, { recursive: true });
1839
+ mkdirSync2(paths.dir, { recursive: true });
1623
1840
  writeFileSync(paths.file, JSON.stringify(config2, null, 2) + "\n", "utf-8");
1624
1841
  return true;
1625
1842
  }
@@ -1709,8 +1926,8 @@ function findPipelineByName(name, startDir) {
1709
1926
  }
1710
1927
 
1711
1928
  // src/declarative/parser.ts
1712
- import { existsSync as existsSync6, readFileSync as readFileSync3 } from "fs";
1713
- import { join as join6 } from "path";
1929
+ import { existsSync as existsSync7, readFileSync as readFileSync3 } from "fs";
1930
+ import { join as join7 } from "path";
1714
1931
  var YAML_FILE = "polter.yaml";
1715
1932
  function parseSimpleYaml(content) {
1716
1933
  const lines = content.split("\n");
@@ -1782,8 +1999,8 @@ function parseValue(raw) {
1782
1999
  return raw;
1783
2000
  }
1784
2001
  function findPolterYaml(startDir = process.cwd()) {
1785
- const filePath = join6(startDir, YAML_FILE);
1786
- return existsSync6(filePath) ? filePath : void 0;
2002
+ const filePath = join7(startDir, YAML_FILE);
2003
+ return existsSync7(filePath) ? filePath : void 0;
1787
2004
  }
1788
2005
  function parsePolterYaml(startDir = process.cwd()) {
1789
2006
  const filePath = findPolterYaml(startDir);
@@ -1929,16 +2146,16 @@ async function applyActions(actions, cwd = process.cwd(), onProgress) {
1929
2146
 
1930
2147
  // src/lib/mcpInstaller.ts
1931
2148
  import { spawnSync as spawnSync2 } from "child_process";
1932
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync7 } from "fs";
1933
- import { join as join7, dirname as dirname4 } from "path";
2149
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, existsSync as existsSync8 } from "fs";
2150
+ import { join as join8, dirname as dirname5 } from "path";
1934
2151
  import { fileURLToPath } from "url";
1935
2152
  import { homedir } from "os";
1936
2153
  import pc from "picocolors";
1937
- var __dirname = dirname4(fileURLToPath(import.meta.url));
2154
+ var __dirname = dirname5(fileURLToPath(import.meta.url));
1938
2155
  function readPkgVersion() {
1939
2156
  for (const rel of ["../../package.json", "../package.json"]) {
1940
- const p = join7(__dirname, rel);
1941
- if (existsSync7(p)) {
2157
+ const p = join8(__dirname, rel);
2158
+ if (existsSync8(p)) {
1942
2159
  const pkg = JSON.parse(readFileSync4(p, "utf-8"));
1943
2160
  return pkg.version;
1944
2161
  }
@@ -1961,15 +2178,15 @@ function tryClaudeCli(scope) {
1961
2178
  }
1962
2179
  function getSettingsPath(scope) {
1963
2180
  if (scope === "project") {
1964
- return join7(process.cwd(), ".mcp.json");
2181
+ return join8(process.cwd(), ".mcp.json");
1965
2182
  }
1966
- return join7(homedir(), ".claude", "settings.json");
2183
+ return join8(homedir(), ".claude", "settings.json");
1967
2184
  }
1968
2185
  function tryManualInstall(scope) {
1969
2186
  const settingsPath = getSettingsPath(scope);
1970
- const dir = join7(settingsPath, "..");
2187
+ const dir = join8(settingsPath, "..");
1971
2188
  let settings = {};
1972
- if (existsSync7(settingsPath)) {
2189
+ if (existsSync8(settingsPath)) {
1973
2190
  try {
1974
2191
  settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
1975
2192
  } catch {
@@ -1978,7 +2195,7 @@ function tryManualInstall(scope) {
1978
2195
  return false;
1979
2196
  }
1980
2197
  } else {
1981
- mkdirSync2(dir, { recursive: true });
2198
+ mkdirSync3(dir, { recursive: true });
1982
2199
  }
1983
2200
  const mcpServers = settings.mcpServers ?? {};
1984
2201
  mcpServers.polter = {
@@ -2030,7 +2247,7 @@ async function removeMcpServer(scope) {
2030
2247
  process.stdout.write(pc.yellow(" 'claude mcp remove' failed, falling back to manual removal...\n\n"));
2031
2248
  }
2032
2249
  const settingsPath = getSettingsPath(scope);
2033
- if (!existsSync7(settingsPath)) {
2250
+ if (!existsSync8(settingsPath)) {
2034
2251
  process.stdout.write(pc.yellow(" No settings file found. Nothing to remove.\n"));
2035
2252
  return;
2036
2253
  }
@@ -2056,11 +2273,11 @@ async function removeMcpServer(scope) {
2056
2273
  function getMcpStatusInfo() {
2057
2274
  const version = readPkgVersion();
2058
2275
  const scopeDefs = [
2059
- { label: "Project (.mcp.json)", path: join7(process.cwd(), ".mcp.json"), scope: "project" },
2060
- { label: "User (~/.claude/settings.json)", path: join7(homedir(), ".claude", "settings.json"), scope: "user" }
2276
+ { label: "Project (.mcp.json)", path: join8(process.cwd(), ".mcp.json"), scope: "project" },
2277
+ { label: "User (~/.claude/settings.json)", path: join8(homedir(), ".claude", "settings.json"), scope: "user" }
2061
2278
  ];
2062
2279
  const scopes = scopeDefs.map((s) => {
2063
- if (!existsSync7(s.path)) {
2280
+ if (!existsSync8(s.path)) {
2064
2281
  return { label: s.label, scope: s.scope, registered: false };
2065
2282
  }
2066
2283
  try {
@@ -2107,7 +2324,7 @@ async function removeMcpServerSilent(scope) {
2107
2324
  messages.push("'claude mcp remove' failed, falling back to manual removal...");
2108
2325
  }
2109
2326
  const settingsPath = getSettingsPath(scope);
2110
- if (!existsSync7(settingsPath)) {
2327
+ if (!existsSync8(settingsPath)) {
2111
2328
  messages.push("No settings file found. Nothing to remove.");
2112
2329
  return { success: true, message: messages.join("\n") };
2113
2330
  }
@@ -2146,11 +2363,11 @@ async function mcpStatus() {
2146
2363
  }
2147
2364
  process.stdout.write("\n");
2148
2365
  const scopes = [
2149
- { label: "Project (.mcp.json)", path: join7(process.cwd(), ".mcp.json"), key: "project" },
2150
- { label: "User (~/.claude/settings.json)", path: join7(homedir(), ".claude", "settings.json"), key: "user" }
2366
+ { label: "Project (.mcp.json)", path: join8(process.cwd(), ".mcp.json"), key: "project" },
2367
+ { label: "User (~/.claude/settings.json)", path: join8(homedir(), ".claude", "settings.json"), key: "user" }
2151
2368
  ];
2152
2369
  for (const scope of scopes) {
2153
- if (!existsSync7(scope.path)) {
2370
+ if (!existsSync8(scope.path)) {
2154
2371
  process.stdout.write(` ${scope.label}: ${pc.dim("not found")}
2155
2372
  `);
2156
2373
  continue;
@@ -2190,9 +2407,11 @@ export {
2190
2407
  detectPkgManager,
2191
2408
  translateCommand,
2192
2409
  resolvePkgArgs,
2410
+ getToolDisplayName,
2193
2411
  resolveToolCommand,
2194
2412
  getToolInfo,
2195
2413
  getToolLinkInfo,
2414
+ findNearestPackageRoot,
2196
2415
  generateProcessId,
2197
2416
  startProcess,
2198
2417
  stopProcess,
@@ -2200,8 +2419,13 @@ export {
2200
2419
  getProcessOutput,
2201
2420
  isProcessRunning,
2202
2421
  removeProcess,
2422
+ findProcessesByCwd,
2423
+ findRunningByCommand,
2424
+ getSocketPath,
2425
+ serializeMessage,
2426
+ parseMessages,
2427
+ createIpcServer,
2203
2428
  executePipeline,
2204
- findNearestPackageRoot,
2205
2429
  getProjectConfigPath,
2206
2430
  writeProjectConfig,
2207
2431
  getOrCreateProjectConfig,