@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/mcp.js CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-AGVTFYXU.js";
2
+ import {
3
+ createIpcClient
4
+ } from "./chunk-VYHW3UNY.js";
3
5
  import {
4
6
  __export,
5
7
  allCommands,
@@ -8,12 +10,15 @@ import {
8
10
  detectPkgManager,
9
11
  executePipeline,
10
12
  findPipelineByName,
13
+ findProcessesByCwd,
14
+ findRunningByCommand,
11
15
  generateProcessId,
12
16
  getAllPipelines,
13
17
  getCommandById,
14
18
  getCommandsByTool,
15
19
  getCurrentStatus,
16
20
  getProcessOutput,
21
+ getSocketPath,
17
22
  getToolInfo,
18
23
  listProcesses,
19
24
  parsePolterYaml,
@@ -23,8 +28,9 @@ import {
23
28
  runCommand,
24
29
  savePipeline,
25
30
  startProcess,
26
- stopProcess
27
- } from "./chunk-7MIUDIAI.js";
31
+ stopProcess,
32
+ translateCommand
33
+ } from "./chunk-ZHVOYB5M.js";
28
34
 
29
35
  // src/mcp.ts
30
36
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -13803,6 +13809,19 @@ import crypto from "crypto";
13803
13809
  import { readFileSync, existsSync } from "fs";
13804
13810
  import { join } from "path";
13805
13811
  var TOOL_IDS = ["supabase", "gh", "vercel", "git", "pkg"];
13812
+ async function withTuiConnection(method, params, fallback) {
13813
+ const socketPath = getSocketPath();
13814
+ if (!socketPath) return fallback();
13815
+ try {
13816
+ const client = createIpcClient(socketPath);
13817
+ await client.connect();
13818
+ const result = await client.call(method, params);
13819
+ client.disconnect();
13820
+ return result;
13821
+ } catch {
13822
+ return fallback();
13823
+ }
13824
+ }
13806
13825
  var server = new McpServer({
13807
13826
  name: "polter",
13808
13827
  version: "0.1.0"
@@ -14119,9 +14138,90 @@ function pkgRunHelper(base, extraArgs = []) {
14119
14138
  { quiet: true }
14120
14139
  ).promise;
14121
14140
  }
14141
+ server.tool(
14142
+ "polter_run_script_bg",
14143
+ "Start a package.json script as a tracked background process using the detected package manager (npm/pnpm/yarn/bun). The process output is captured and can be read with polter_logs. Use polter_ps to check status.",
14144
+ {
14145
+ script: external_exports.string().describe("Script name from package.json (e.g. 'dev', 'build', 'test')"),
14146
+ args: external_exports.array(external_exports.string()).optional().describe("Extra arguments to pass to the script"),
14147
+ cwd: external_exports.string().optional().describe("Working directory. Defaults to current directory.")
14148
+ },
14149
+ async ({ script, args: extraArgs, cwd: cwdArg }) => {
14150
+ const cwd = cwdArg ?? process.cwd();
14151
+ const pkgPath = join(cwd, "package.json");
14152
+ if (!existsSync(pkgPath)) {
14153
+ return {
14154
+ content: [{ type: "text", text: JSON.stringify({ error: "No package.json found in " + cwd }) }],
14155
+ isError: true
14156
+ };
14157
+ }
14158
+ const raw = JSON.parse(readFileSync(pkgPath, "utf-8"));
14159
+ const scripts = raw.scripts ?? {};
14160
+ if (!scripts[script]) {
14161
+ return {
14162
+ content: [{ type: "text", text: JSON.stringify({ error: `Script "${script}" not found. Available: ${Object.keys(scripts).join(", ")}` }) }],
14163
+ isError: true
14164
+ };
14165
+ }
14166
+ const mgr = detectPkgManager(cwd);
14167
+ try {
14168
+ const translated = translateCommand(["run", script, ...extraArgs ?? []], mgr.id);
14169
+ const existing = await withTuiConnection(
14170
+ "ps.find_running",
14171
+ { cwd, command: mgr.command, args: translated.args },
14172
+ () => findRunningByCommand(cwd, mgr.command, translated.args)
14173
+ );
14174
+ if (existing) {
14175
+ const output2 = await withTuiConnection(
14176
+ "ps.logs",
14177
+ { id: existing.id, tail: 20 },
14178
+ () => getProcessOutput(existing.id, 20)
14179
+ );
14180
+ return {
14181
+ content: [{
14182
+ type: "text",
14183
+ text: JSON.stringify({
14184
+ alreadyRunning: true,
14185
+ process: existing,
14186
+ output: output2
14187
+ }, null, 2)
14188
+ }]
14189
+ };
14190
+ }
14191
+ const id = generateProcessId(mgr.command, translated.args);
14192
+ const info = await withTuiConnection(
14193
+ "ps.start",
14194
+ { command: mgr.command, args: translated.args, cwd, id },
14195
+ () => startProcess(id, mgr.command, translated.args, cwd)
14196
+ );
14197
+ await new Promise((r) => setTimeout(r, 500));
14198
+ const output = await withTuiConnection(
14199
+ "ps.logs",
14200
+ { id, tail: 20 },
14201
+ () => getProcessOutput(id, 20)
14202
+ );
14203
+ return {
14204
+ content: [{
14205
+ type: "text",
14206
+ text: JSON.stringify({
14207
+ success: true,
14208
+ process: info,
14209
+ output,
14210
+ packageManager: mgr.id
14211
+ }, null, 2)
14212
+ }]
14213
+ };
14214
+ } catch (err) {
14215
+ return {
14216
+ content: [{ type: "text", text: JSON.stringify({ error: err.message }) }],
14217
+ isError: true
14218
+ };
14219
+ }
14220
+ }
14221
+ );
14122
14222
  server.tool(
14123
14223
  "polter_pkg_build",
14124
- "Run the build script from package.json using the detected package manager.",
14224
+ "Run the build script from package.json using the detected package manager (npm/pnpm/yarn/bun).",
14125
14225
  {},
14126
14226
  async () => {
14127
14227
  const result = await pkgRunHelper(["run", "build"]);
@@ -14132,7 +14232,7 @@ server.tool(
14132
14232
  );
14133
14233
  server.tool(
14134
14234
  "polter_pkg_publish",
14135
- "Publish the package to the npm registry.",
14235
+ "Publish the package to the registry using the detected package manager (npm/pnpm/yarn/bun).",
14136
14236
  {
14137
14237
  tag: external_exports.string().optional().describe("Dist-tag (e.g. 'next', 'beta')"),
14138
14238
  dryRun: external_exports.boolean().optional().describe("Simulate publish without uploading")
@@ -14156,7 +14256,7 @@ server.tool(
14156
14256
  );
14157
14257
  server.tool(
14158
14258
  "polter_pkg_install",
14159
- "Install dependencies. Optionally install specific packages.",
14259
+ "Install dependencies using the detected package manager (npm/pnpm/yarn/bun). Optionally install specific packages.",
14160
14260
  {
14161
14261
  packages: external_exports.array(external_exports.string()).optional().describe("Specific packages to install"),
14162
14262
  dev: external_exports.boolean().optional().describe("Install as dev dependency")
@@ -14173,7 +14273,7 @@ server.tool(
14173
14273
  );
14174
14274
  server.tool(
14175
14275
  "polter_pkg_run_script",
14176
- "Run a script defined in package.json.",
14276
+ "Run a script defined in package.json using the detected package manager (npm/pnpm/yarn/bun).",
14177
14277
  {
14178
14278
  script: external_exports.string().describe("Script name to run"),
14179
14279
  args: external_exports.array(external_exports.string()).optional().describe("Extra arguments")
@@ -14187,7 +14287,7 @@ server.tool(
14187
14287
  );
14188
14288
  server.tool(
14189
14289
  "polter_pkg_version_bump",
14190
- "Bump the package version (semver).",
14290
+ "Bump the package version (semver) using the detected package manager (npm/pnpm/yarn/bun).",
14191
14291
  {
14192
14292
  type: external_exports.enum(["patch", "minor", "major"]).describe("Version bump type")
14193
14293
  },
@@ -14200,7 +14300,7 @@ server.tool(
14200
14300
  );
14201
14301
  server.tool(
14202
14302
  "polter_pkg_audit",
14203
- "Run a security audit on dependencies.",
14303
+ "Run a security audit on dependencies using the detected package manager (npm/pnpm/yarn/bun).",
14204
14304
  {
14205
14305
  fix: external_exports.boolean().optional().describe("Attempt to fix vulnerabilities")
14206
14306
  },
@@ -14221,7 +14321,7 @@ server.tool(
14221
14321
  );
14222
14322
  server.tool(
14223
14323
  "polter_pkg_info",
14224
- "Get information about a package from the registry.",
14324
+ "Get information about a package from the registry using the detected package manager (npm/pnpm/yarn/bun).",
14225
14325
  {
14226
14326
  package: external_exports.string().describe("Package name to look up")
14227
14327
  },
@@ -14244,7 +14344,7 @@ server.tool(
14244
14344
  "List all tracked background processes with their status, PID, uptime, and exit info.",
14245
14345
  {},
14246
14346
  async () => {
14247
- const processes = listProcesses();
14347
+ const processes = await withTuiConnection("ps.list", {}, () => listProcesses());
14248
14348
  return {
14249
14349
  content: [{ type: "text", text: JSON.stringify(processes, null, 2) }]
14250
14350
  };
@@ -14264,7 +14364,11 @@ server.tool(
14264
14364
  const processId = id ?? generateProcessId(command, processArgs);
14265
14365
  const processCwd = cwd ?? process.cwd();
14266
14366
  try {
14267
- const info = startProcess(processId, command, processArgs, processCwd);
14367
+ const info = await withTuiConnection(
14368
+ "ps.start",
14369
+ { command, args: processArgs, cwd: processCwd, id: processId },
14370
+ () => startProcess(processId, command, processArgs, processCwd)
14371
+ );
14268
14372
  return {
14269
14373
  content: [{ type: "text", text: JSON.stringify({ success: true, process: info }, null, 2) }]
14270
14374
  };
@@ -14286,7 +14390,11 @@ server.tool(
14286
14390
  },
14287
14391
  async ({ id, tail, stream }) => {
14288
14392
  try {
14289
- const output = getProcessOutput(id, tail, stream);
14393
+ const output = await withTuiConnection(
14394
+ "ps.logs",
14395
+ { id, ...tail !== void 0 ? { tail } : {}, ...stream !== void 0 ? { stream } : {} },
14396
+ () => getProcessOutput(id, tail, stream)
14397
+ );
14290
14398
  return {
14291
14399
  content: [{ type: "text", text: JSON.stringify(output, null, 2) }]
14292
14400
  };
@@ -14306,7 +14414,11 @@ server.tool(
14306
14414
  },
14307
14415
  async ({ id }) => {
14308
14416
  try {
14309
- const info = await stopProcess(id);
14417
+ const info = await withTuiConnection(
14418
+ "ps.stop",
14419
+ { id },
14420
+ () => stopProcess(id)
14421
+ );
14310
14422
  return {
14311
14423
  content: [{ type: "text", text: JSON.stringify({ success: true, process: info }, null, 2) }]
14312
14424
  };
@@ -14318,6 +14430,130 @@ server.tool(
14318
14430
  }
14319
14431
  }
14320
14432
  );
14433
+ server.tool(
14434
+ "polter_smart_start",
14435
+ "Smart process starter: reads package.json, auto-detects package manager, starts a script as a background process. If script is omitted, lists available scripts. If already running, returns current info and recent logs instead of duplicating.",
14436
+ {
14437
+ script: external_exports.string().optional().describe("Script name from package.json (e.g. 'dev', 'build')"),
14438
+ cwd: external_exports.string().optional().describe("Repository directory. Defaults to current directory."),
14439
+ tail: external_exports.number().optional().default(20).describe("Number of initial log lines to return")
14440
+ },
14441
+ async ({ script, cwd: cwdArg, tail }) => {
14442
+ const cwd = cwdArg ?? process.cwd();
14443
+ const pkgPath = join(cwd, "package.json");
14444
+ if (!existsSync(pkgPath)) {
14445
+ return {
14446
+ content: [{ type: "text", text: JSON.stringify({ error: "No package.json found in " + cwd }) }],
14447
+ isError: true
14448
+ };
14449
+ }
14450
+ const raw = JSON.parse(readFileSync(pkgPath, "utf-8"));
14451
+ const scripts = raw.scripts ?? {};
14452
+ if (!script) {
14453
+ return {
14454
+ content: [{ type: "text", text: JSON.stringify({ scripts: Object.keys(scripts) }, null, 2) }]
14455
+ };
14456
+ }
14457
+ if (!scripts[script]) {
14458
+ return {
14459
+ content: [{ type: "text", text: JSON.stringify({ error: `Script "${script}" not found. Available: ${Object.keys(scripts).join(", ")}` }) }],
14460
+ isError: true
14461
+ };
14462
+ }
14463
+ const mgr = detectPkgManager(cwd);
14464
+ const runArgs = ["run", script];
14465
+ const existing = await withTuiConnection(
14466
+ "ps.find_running",
14467
+ { cwd, command: mgr.command, args: runArgs },
14468
+ () => findRunningByCommand(cwd, mgr.command, runArgs)
14469
+ );
14470
+ if (existing) {
14471
+ const output = await withTuiConnection(
14472
+ "ps.logs",
14473
+ { id: existing.id, tail },
14474
+ () => getProcessOutput(existing.id, tail)
14475
+ );
14476
+ return {
14477
+ content: [{
14478
+ type: "text",
14479
+ text: JSON.stringify({
14480
+ alreadyRunning: true,
14481
+ process: existing,
14482
+ output
14483
+ }, null, 2)
14484
+ }]
14485
+ };
14486
+ }
14487
+ try {
14488
+ const id = generateProcessId(mgr.command, runArgs);
14489
+ const info = await withTuiConnection(
14490
+ "ps.start",
14491
+ { command: mgr.command, args: runArgs, cwd, id },
14492
+ () => startProcess(id, mgr.command, runArgs, cwd)
14493
+ );
14494
+ await new Promise((r) => setTimeout(r, 500));
14495
+ const output = await withTuiConnection(
14496
+ "ps.logs",
14497
+ { id, tail },
14498
+ () => getProcessOutput(id, tail)
14499
+ );
14500
+ return {
14501
+ content: [{
14502
+ type: "text",
14503
+ text: JSON.stringify({
14504
+ alreadyRunning: false,
14505
+ process: info,
14506
+ output,
14507
+ packageManager: mgr.id
14508
+ }, null, 2)
14509
+ }]
14510
+ };
14511
+ } catch (err) {
14512
+ return {
14513
+ content: [{ type: "text", text: JSON.stringify({ error: err.message }) }],
14514
+ isError: true
14515
+ };
14516
+ }
14517
+ }
14518
+ );
14519
+ server.tool(
14520
+ "polter_find_process",
14521
+ "Find all tracked processes for a repository directory. Returns process info with recent logs embedded. No need to know process IDs \u2014 just point to the repo.",
14522
+ {
14523
+ cwd: external_exports.string().optional().describe("Repository directory. Defaults to current directory."),
14524
+ filter: external_exports.string().optional().describe("Filter by substring in command+args"),
14525
+ tail: external_exports.number().optional().default(20).describe("Number of log lines per process")
14526
+ },
14527
+ async ({ cwd: cwdArg, filter, tail }) => {
14528
+ const cwd = cwdArg ?? process.cwd();
14529
+ const processes = await withTuiConnection(
14530
+ "ps.find_by_cwd",
14531
+ { cwd, ...filter ? { filter } : {} },
14532
+ () => {
14533
+ let procs = findProcessesByCwd(cwd);
14534
+ if (filter) {
14535
+ const f = filter.toLowerCase();
14536
+ procs = procs.filter(
14537
+ (proc) => (proc.command + " " + proc.args.join(" ")).toLowerCase().includes(f)
14538
+ );
14539
+ }
14540
+ return procs;
14541
+ }
14542
+ );
14543
+ const results = [];
14544
+ for (const proc of processes) {
14545
+ const output = await withTuiConnection(
14546
+ "ps.logs",
14547
+ { id: proc.id, tail },
14548
+ () => getProcessOutput(proc.id, tail)
14549
+ );
14550
+ results.push({ process: proc, output });
14551
+ }
14552
+ return {
14553
+ content: [{ type: "text", text: JSON.stringify(results, null, 2) }]
14554
+ };
14555
+ }
14556
+ );
14321
14557
  server.resource(
14322
14558
  "package-json",
14323
14559
  "polter://package-json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polterware/polter",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "An interactive CLI for managing Supabase CLI workflows.",
5
5
  "type": "module",
6
6
  "bin": {
File without changes