@polterware/polter 0.2.4 → 0.3.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,23 +1,30 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-EB76TTZL.js";
2
+ import "./chunk-AGVTFYXU.js";
3
3
  import {
4
4
  __export,
5
5
  allCommands,
6
6
  applyActions,
7
7
  deletePipeline,
8
+ detectPkgManager,
8
9
  executePipeline,
9
10
  findPipelineByName,
11
+ generateProcessId,
10
12
  getAllPipelines,
11
13
  getCommandById,
12
14
  getCommandsByTool,
13
15
  getCurrentStatus,
16
+ getProcessOutput,
14
17
  getToolInfo,
18
+ listProcesses,
15
19
  parsePolterYaml,
16
20
  planChanges,
21
+ resolvePkgArgs,
17
22
  resolveToolCommand,
18
23
  runCommand,
19
- savePipeline
20
- } from "./chunk-2B2UWOVQ.js";
24
+ savePipeline,
25
+ startProcess,
26
+ stopProcess
27
+ } from "./chunk-7MIUDIAI.js";
21
28
 
22
29
  // src/mcp.ts
23
30
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -13793,7 +13800,9 @@ config(en_default());
13793
13800
 
13794
13801
  // src/mcp.ts
13795
13802
  import crypto from "crypto";
13796
- var TOOL_IDS = ["supabase", "gh", "vercel", "git"];
13803
+ import { readFileSync, existsSync } from "fs";
13804
+ import { join } from "path";
13805
+ var TOOL_IDS = ["supabase", "gh", "vercel", "git", "pkg"];
13797
13806
  var server = new McpServer({
13798
13807
  name: "polter",
13799
13808
  version: "0.1.0"
@@ -13801,7 +13810,7 @@ var server = new McpServer({
13801
13810
  server.tool(
13802
13811
  "polter_list_commands",
13803
13812
  "List available CLI commands across Supabase, GitHub, Vercel, and Git. Optionally filter by tool.",
13804
- { tool: external_exports.enum(["supabase", "gh", "vercel", "git"]).optional() },
13813
+ { tool: external_exports.enum(["supabase", "gh", "vercel", "git", "pkg"]).optional() },
13805
13814
  async ({ tool }) => {
13806
13815
  const commands = tool ? getCommandsByTool(tool) : allCommands;
13807
13816
  const result = commands.map((cmd) => ({
@@ -13835,14 +13844,29 @@ server.tool(
13835
13844
  isError: true
13836
13845
  };
13837
13846
  }
13838
- const resolved = resolveToolCommand(cmdDef.tool);
13839
- const allArgs = [...cmdDef.base, ...args ?? [], ...flags ?? []];
13847
+ const cwd = process.cwd();
13848
+ const resolved = resolveToolCommand(cmdDef.tool, cwd);
13849
+ let baseArgs;
13850
+ if (cmdDef.tool === "pkg") {
13851
+ try {
13852
+ const translated = resolvePkgArgs(cmdDef.base, cwd);
13853
+ baseArgs = translated.args;
13854
+ } catch (err) {
13855
+ return {
13856
+ content: [{ type: "text", text: JSON.stringify({ error: err.message }) }],
13857
+ isError: true
13858
+ };
13859
+ }
13860
+ } else {
13861
+ baseArgs = cmdDef.base;
13862
+ }
13863
+ const allArgs = [...baseArgs, ...args ?? [], ...flags ?? []];
13840
13864
  const result = await runCommand(
13841
13865
  { command: resolved.command, env: resolved.env },
13842
13866
  allArgs,
13843
- process.cwd(),
13867
+ cwd,
13844
13868
  { quiet: true }
13845
- );
13869
+ ).promise;
13846
13870
  return {
13847
13871
  content: [{
13848
13872
  type: "text",
@@ -14084,5 +14108,366 @@ server.tool(
14084
14108
  };
14085
14109
  }
14086
14110
  );
14111
+ function pkgRunHelper(base, extraArgs = []) {
14112
+ const cwd = process.cwd();
14113
+ const translated = resolvePkgArgs(base, cwd);
14114
+ const resolved = resolveToolCommand("pkg", cwd);
14115
+ return runCommand(
14116
+ { command: resolved.command, env: resolved.env },
14117
+ [...translated.args, ...extraArgs],
14118
+ cwd,
14119
+ { quiet: true }
14120
+ ).promise;
14121
+ }
14122
+ server.tool(
14123
+ "polter_pkg_build",
14124
+ "Run the build script from package.json using the detected package manager.",
14125
+ {},
14126
+ async () => {
14127
+ const result = await pkgRunHelper(["run", "build"]);
14128
+ return {
14129
+ content: [{ type: "text", text: JSON.stringify({ success: result.exitCode === 0, stdout: result.stdout, stderr: result.stderr }, null, 2) }]
14130
+ };
14131
+ }
14132
+ );
14133
+ server.tool(
14134
+ "polter_pkg_publish",
14135
+ "Publish the package to the npm registry.",
14136
+ {
14137
+ tag: external_exports.string().optional().describe("Dist-tag (e.g. 'next', 'beta')"),
14138
+ dryRun: external_exports.boolean().optional().describe("Simulate publish without uploading")
14139
+ },
14140
+ async ({ tag, dryRun }) => {
14141
+ const extra = [];
14142
+ if (tag) extra.push("--tag", tag);
14143
+ if (dryRun) extra.push("--dry-run");
14144
+ try {
14145
+ const result = await pkgRunHelper(["publish"], extra);
14146
+ return {
14147
+ content: [{ type: "text", text: JSON.stringify({ success: result.exitCode === 0, stdout: result.stdout, stderr: result.stderr }, null, 2) }]
14148
+ };
14149
+ } catch (err) {
14150
+ return {
14151
+ content: [{ type: "text", text: JSON.stringify({ error: err.message }) }],
14152
+ isError: true
14153
+ };
14154
+ }
14155
+ }
14156
+ );
14157
+ server.tool(
14158
+ "polter_pkg_install",
14159
+ "Install dependencies. Optionally install specific packages.",
14160
+ {
14161
+ packages: external_exports.array(external_exports.string()).optional().describe("Specific packages to install"),
14162
+ dev: external_exports.boolean().optional().describe("Install as dev dependency")
14163
+ },
14164
+ async ({ packages, dev }) => {
14165
+ const base = packages && packages.length > 0 ? ["add"] : ["install"];
14166
+ const extra = [...packages ?? []];
14167
+ if (dev) extra.push("--save-dev");
14168
+ const result = await pkgRunHelper(base, extra);
14169
+ return {
14170
+ content: [{ type: "text", text: JSON.stringify({ success: result.exitCode === 0, stdout: result.stdout, stderr: result.stderr }, null, 2) }]
14171
+ };
14172
+ }
14173
+ );
14174
+ server.tool(
14175
+ "polter_pkg_run_script",
14176
+ "Run a script defined in package.json.",
14177
+ {
14178
+ script: external_exports.string().describe("Script name to run"),
14179
+ args: external_exports.array(external_exports.string()).optional().describe("Extra arguments")
14180
+ },
14181
+ async ({ script, args }) => {
14182
+ const result = await pkgRunHelper(["run", script], args ?? []);
14183
+ return {
14184
+ content: [{ type: "text", text: JSON.stringify({ success: result.exitCode === 0, stdout: result.stdout, stderr: result.stderr }, null, 2) }]
14185
+ };
14186
+ }
14187
+ );
14188
+ server.tool(
14189
+ "polter_pkg_version_bump",
14190
+ "Bump the package version (semver).",
14191
+ {
14192
+ type: external_exports.enum(["patch", "minor", "major"]).describe("Version bump type")
14193
+ },
14194
+ async ({ type }) => {
14195
+ const result = await pkgRunHelper(["version", type]);
14196
+ return {
14197
+ content: [{ type: "text", text: JSON.stringify({ success: result.exitCode === 0, stdout: result.stdout, stderr: result.stderr }, null, 2) }]
14198
+ };
14199
+ }
14200
+ );
14201
+ server.tool(
14202
+ "polter_pkg_audit",
14203
+ "Run a security audit on dependencies.",
14204
+ {
14205
+ fix: external_exports.boolean().optional().describe("Attempt to fix vulnerabilities")
14206
+ },
14207
+ async ({ fix }) => {
14208
+ try {
14209
+ const extra = fix ? ["--fix"] : [];
14210
+ const result = await pkgRunHelper(["audit"], extra);
14211
+ return {
14212
+ content: [{ type: "text", text: JSON.stringify({ success: result.exitCode === 0, stdout: result.stdout, stderr: result.stderr }, null, 2) }]
14213
+ };
14214
+ } catch (err) {
14215
+ return {
14216
+ content: [{ type: "text", text: JSON.stringify({ error: err.message }) }],
14217
+ isError: true
14218
+ };
14219
+ }
14220
+ }
14221
+ );
14222
+ server.tool(
14223
+ "polter_pkg_info",
14224
+ "Get information about a package from the registry.",
14225
+ {
14226
+ package: external_exports.string().describe("Package name to look up")
14227
+ },
14228
+ async ({ package: pkg }) => {
14229
+ try {
14230
+ const result = await pkgRunHelper(["info", pkg]);
14231
+ return {
14232
+ content: [{ type: "text", text: JSON.stringify({ success: result.exitCode === 0, stdout: result.stdout, stderr: result.stderr }, null, 2) }]
14233
+ };
14234
+ } catch (err) {
14235
+ return {
14236
+ content: [{ type: "text", text: JSON.stringify({ error: err.message }) }],
14237
+ isError: true
14238
+ };
14239
+ }
14240
+ }
14241
+ );
14242
+ server.tool(
14243
+ "polter_ps",
14244
+ "List all tracked background processes with their status, PID, uptime, and exit info.",
14245
+ {},
14246
+ async () => {
14247
+ const processes = listProcesses();
14248
+ return {
14249
+ content: [{ type: "text", text: JSON.stringify(processes, null, 2) }]
14250
+ };
14251
+ }
14252
+ );
14253
+ server.tool(
14254
+ "polter_start",
14255
+ "Start a command as a tracked background process. Useful for long-running tasks like dev servers. Output is captured and can be read with polter_logs.",
14256
+ {
14257
+ command: external_exports.string().describe("Command to run (e.g. 'npm')"),
14258
+ args: external_exports.array(external_exports.string()).optional().describe("Command arguments (e.g. ['run', 'dev'])"),
14259
+ id: external_exports.string().optional().describe("Human-readable process ID. Auto-generated if omitted."),
14260
+ cwd: external_exports.string().optional().describe("Working directory. Defaults to current directory.")
14261
+ },
14262
+ async ({ command, args, id, cwd }) => {
14263
+ const processArgs = args ?? [];
14264
+ const processId = id ?? generateProcessId(command, processArgs);
14265
+ const processCwd = cwd ?? process.cwd();
14266
+ try {
14267
+ const info = startProcess(processId, command, processArgs, processCwd);
14268
+ return {
14269
+ content: [{ type: "text", text: JSON.stringify({ success: true, process: info }, null, 2) }]
14270
+ };
14271
+ } catch (err) {
14272
+ return {
14273
+ content: [{ type: "text", text: JSON.stringify({ error: err.message }) }],
14274
+ isError: true
14275
+ };
14276
+ }
14277
+ }
14278
+ );
14279
+ server.tool(
14280
+ "polter_logs",
14281
+ "Read captured stdout/stderr from a tracked background process.",
14282
+ {
14283
+ id: external_exports.string().describe("Process ID"),
14284
+ tail: external_exports.number().optional().describe("Number of lines to return from the end (default: all)"),
14285
+ stream: external_exports.enum(["stdout", "stderr", "both"]).optional().describe("Which output stream to read (default: both)")
14286
+ },
14287
+ async ({ id, tail, stream }) => {
14288
+ try {
14289
+ const output = getProcessOutput(id, tail, stream);
14290
+ return {
14291
+ content: [{ type: "text", text: JSON.stringify(output, null, 2) }]
14292
+ };
14293
+ } catch (err) {
14294
+ return {
14295
+ content: [{ type: "text", text: JSON.stringify({ error: err.message }) }],
14296
+ isError: true
14297
+ };
14298
+ }
14299
+ }
14300
+ );
14301
+ server.tool(
14302
+ "polter_stop",
14303
+ "Stop a tracked background process. Sends SIGTERM, escalates to SIGKILL after 5 seconds.",
14304
+ {
14305
+ id: external_exports.string().describe("Process ID to stop")
14306
+ },
14307
+ async ({ id }) => {
14308
+ try {
14309
+ const info = await stopProcess(id);
14310
+ return {
14311
+ content: [{ type: "text", text: JSON.stringify({ success: true, process: info }, null, 2) }]
14312
+ };
14313
+ } catch (err) {
14314
+ return {
14315
+ content: [{ type: "text", text: JSON.stringify({ error: err.message }) }],
14316
+ isError: true
14317
+ };
14318
+ }
14319
+ }
14320
+ );
14321
+ server.resource(
14322
+ "package-json",
14323
+ "polter://package-json",
14324
+ { description: "Parsed package.json (name, version, dependencies, scripts)" },
14325
+ async () => {
14326
+ const cwd = process.cwd();
14327
+ const pkgPath = join(cwd, "package.json");
14328
+ if (!existsSync(pkgPath)) {
14329
+ return { contents: [{ uri: "polter://package-json", text: JSON.stringify({ error: "No package.json found" }) }] };
14330
+ }
14331
+ const raw = JSON.parse(readFileSync(pkgPath, "utf-8"));
14332
+ const summary = {
14333
+ name: raw.name,
14334
+ version: raw.version,
14335
+ description: raw.description,
14336
+ dependencies: raw.dependencies,
14337
+ devDependencies: raw.devDependencies,
14338
+ scripts: raw.scripts
14339
+ };
14340
+ return { contents: [{ uri: "polter://package-json", text: JSON.stringify(summary, null, 2) }] };
14341
+ }
14342
+ );
14343
+ server.resource(
14344
+ "dependency-tree",
14345
+ "polter://dependency-tree",
14346
+ { description: "Installed dependency tree (npm ls --json or equivalent)" },
14347
+ async () => {
14348
+ const cwd = process.cwd();
14349
+ try {
14350
+ const result = await pkgRunHelper(["ls", "--json"]);
14351
+ return { contents: [{ uri: "polter://dependency-tree", text: result.stdout }] };
14352
+ } catch {
14353
+ return { contents: [{ uri: "polter://dependency-tree", text: JSON.stringify({ error: "Could not list dependencies" }) }] };
14354
+ }
14355
+ }
14356
+ );
14357
+ server.resource(
14358
+ "scripts",
14359
+ "polter://scripts",
14360
+ { description: "Scripts defined in package.json" },
14361
+ async () => {
14362
+ const cwd = process.cwd();
14363
+ const pkgPath = join(cwd, "package.json");
14364
+ if (!existsSync(pkgPath)) {
14365
+ return { contents: [{ uri: "polter://scripts", text: JSON.stringify({ error: "No package.json found" }) }] };
14366
+ }
14367
+ const raw = JSON.parse(readFileSync(pkgPath, "utf-8"));
14368
+ return { contents: [{ uri: "polter://scripts", text: JSON.stringify(raw.scripts ?? {}, null, 2) }] };
14369
+ }
14370
+ );
14371
+ server.resource(
14372
+ "pkg-manager",
14373
+ "polter://pkg-manager",
14374
+ { description: "Detected package manager info (id, version, lockFile)" },
14375
+ async () => {
14376
+ const cwd = process.cwd();
14377
+ const mgr = detectPkgManager(cwd);
14378
+ const resolved = resolveToolCommand("pkg", cwd);
14379
+ let version2;
14380
+ if (resolved.source !== "not-found") {
14381
+ try {
14382
+ const result = await runCommand(
14383
+ { command: resolved.command, env: resolved.env },
14384
+ ["--version"],
14385
+ cwd,
14386
+ { quiet: true }
14387
+ ).promise;
14388
+ version2 = result.stdout.trim().split("\n")[0];
14389
+ } catch {
14390
+ }
14391
+ }
14392
+ return {
14393
+ contents: [{
14394
+ uri: "polter://pkg-manager",
14395
+ text: JSON.stringify({ id: mgr.id, command: mgr.command, lockFile: mgr.lockFile, version: version2 }, null, 2)
14396
+ }]
14397
+ };
14398
+ }
14399
+ );
14400
+ server.prompt(
14401
+ "polter_publish_workflow",
14402
+ "Step-by-step guide for publishing a package: version bump, build, test, publish, git tag.",
14403
+ {},
14404
+ async () => ({
14405
+ messages: [{
14406
+ role: "user",
14407
+ content: {
14408
+ type: "text",
14409
+ text: `Guide me through a complete publish workflow for this project:
14410
+
14411
+ 1. **Version bump** - Choose patch/minor/major based on changes since last release
14412
+ 2. **Build** - Run the build script to ensure dist is up to date
14413
+ 3. **Test** - Run the test suite to verify everything passes
14414
+ 4. **Publish** - Publish to npm registry (consider --dry-run first)
14415
+ 5. **Git tag** - Create and push a git tag for the release
14416
+
14417
+ Use polter tools to execute each step. Check package.json for current version and scripts first.`
14418
+ }
14419
+ }]
14420
+ })
14421
+ );
14422
+ server.prompt(
14423
+ "polter_version_strategy",
14424
+ "Suggest a semver versioning strategy based on current version and change type.",
14425
+ {
14426
+ currentVersion: external_exports.string().describe("Current package version"),
14427
+ changeType: external_exports.string().describe("Type of change: feature, fix, breaking, docs, etc.")
14428
+ },
14429
+ async ({ currentVersion, changeType }) => ({
14430
+ messages: [{
14431
+ role: "user",
14432
+ content: {
14433
+ type: "text",
14434
+ text: `Current version: ${currentVersion}
14435
+ Change type: ${changeType}
14436
+
14437
+ Based on semver rules:
14438
+ - PATCH (x.y.Z): backwards-compatible bug fixes
14439
+ - MINOR (x.Y.z): backwards-compatible new features
14440
+ - MAJOR (X.y.z): breaking changes
14441
+
14442
+ Recommend the appropriate version bump and explain the reasoning. If pre-1.0, note that minor can include breaking changes by convention.`
14443
+ }
14444
+ }]
14445
+ })
14446
+ );
14447
+ server.prompt(
14448
+ "polter_audit_resolution",
14449
+ "Guide for analyzing and resolving npm audit findings.",
14450
+ {},
14451
+ async () => ({
14452
+ messages: [{
14453
+ role: "user",
14454
+ content: {
14455
+ type: "text",
14456
+ text: `Run a security audit on this project and help me resolve any findings:
14457
+
14458
+ 1. **Run audit** - Use polter_pkg_audit to check for vulnerabilities
14459
+ 2. **Analyze results** - Categorize by severity (critical, high, moderate, low)
14460
+ 3. **Resolution strategy** for each finding:
14461
+ - Direct dependency: update to patched version
14462
+ - Transitive dependency: check if parent has update
14463
+ - No fix available: evaluate risk and consider alternatives
14464
+ 4. **Apply fixes** - Use polter_pkg_install to update packages
14465
+ 5. **Verify** - Re-run audit to confirm fixes
14466
+
14467
+ Start by running the audit.`
14468
+ }
14469
+ }]
14470
+ })
14471
+ );
14087
14472
  var transport = new StdioServerTransport();
14088
14473
  await server.connect(transport);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polterware/polter",
3
- "version": "0.2.4",
3
+ "version": "0.3.1",
4
4
  "description": "An interactive CLI for managing Supabase CLI workflows.",
5
5
  "type": "module",
6
6
  "bin": {
File without changes