@polterware/polter 0.1.0 → 0.2.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/dist/mcp.js CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  __export,
5
5
  allCommands,
6
6
  applyActions,
7
+ deletePipeline,
7
8
  executePipeline,
8
9
  findPipelineByName,
9
10
  getAllPipelines,
@@ -14,8 +15,9 @@ import {
14
15
  parsePolterYaml,
15
16
  planChanges,
16
17
  resolveToolCommand,
17
- runCommand
18
- } from "./chunk-TWWRDI3Q.js";
18
+ runCommand,
19
+ savePipeline
20
+ } from "./chunk-2OZZNSKW.js";
19
21
 
20
22
  // src/mcp.ts
21
23
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -13790,15 +13792,16 @@ function date4(params) {
13790
13792
  config(en_default());
13791
13793
 
13792
13794
  // src/mcp.ts
13793
- var TOOL_IDS = ["supabase", "gh", "vercel", "pulumi"];
13795
+ import crypto from "crypto";
13796
+ var TOOL_IDS = ["supabase", "gh", "vercel", "git"];
13794
13797
  var server = new McpServer({
13795
13798
  name: "polter",
13796
13799
  version: "0.1.0"
13797
13800
  });
13798
13801
  server.tool(
13799
13802
  "polter_list_commands",
13800
- "List available CLI commands across Supabase, GitHub, Vercel, and Pulumi. Optionally filter by tool.",
13801
- { tool: external_exports.enum(["supabase", "gh", "vercel", "pulumi"]).optional() },
13803
+ "List available CLI commands across Supabase, GitHub, Vercel, and Git. Optionally filter by tool.",
13804
+ { tool: external_exports.enum(["supabase", "gh", "vercel", "git"]).optional() },
13802
13805
  async ({ tool }) => {
13803
13806
  const commands = tool ? getCommandsByTool(tool) : allCommands;
13804
13807
  const result = commands.map((cmd) => ({
@@ -13818,7 +13821,7 @@ server.tool(
13818
13821
  );
13819
13822
  server.tool(
13820
13823
  "polter_run_command",
13821
- "Execute a CLI command by its Polter ID (e.g. 'gh:pr:create', 'vercel:deploy'). Use polter_list_commands to discover available IDs.",
13824
+ "Execute a CLI command by its Polter ID (e.g. 'gh:pr:create', 'vercel:deploy', 'git:commit'). Use polter_list_commands to discover available IDs.",
13822
13825
  {
13823
13826
  commandId: external_exports.string(),
13824
13827
  args: external_exports.array(external_exports.string()).optional(),
@@ -13907,6 +13910,126 @@ server.tool(
13907
13910
  };
13908
13911
  }
13909
13912
  );
13913
+ server.tool(
13914
+ "polter_create_pipeline",
13915
+ "Create a new pipeline (multi-step command sequence). Use polter_list_commands to discover valid command IDs for steps.",
13916
+ {
13917
+ name: external_exports.string().describe("Pipeline name"),
13918
+ description: external_exports.string().optional().describe("Pipeline description"),
13919
+ source: external_exports.enum(["project", "global"]).default("project").describe("Where to save the pipeline"),
13920
+ steps: external_exports.array(external_exports.object({
13921
+ commandId: external_exports.string().describe("Command ID (e.g. 'git:commit', 'vercel:deploy:prod')"),
13922
+ args: external_exports.array(external_exports.string()).default([]).describe("Command arguments"),
13923
+ flags: external_exports.array(external_exports.string()).default([]).describe("Command flags"),
13924
+ continueOnError: external_exports.boolean().default(false).describe("Continue pipeline if this step fails"),
13925
+ label: external_exports.string().optional().describe("Human-readable step label")
13926
+ })).min(1).describe("Pipeline steps")
13927
+ },
13928
+ async ({ name, description, source, steps }) => {
13929
+ const existing = findPipelineByName(name);
13930
+ if (existing) {
13931
+ return {
13932
+ content: [{ type: "text", text: JSON.stringify({ error: `Pipeline already exists: ${name}. Use polter_update_pipeline to modify it.` }) }],
13933
+ isError: true
13934
+ };
13935
+ }
13936
+ const invalidIds = steps.filter((s) => !getCommandById(s.commandId)).map((s) => s.commandId);
13937
+ if (invalidIds.length > 0) {
13938
+ return {
13939
+ content: [{ type: "text", text: JSON.stringify({ error: `Unknown command IDs: ${invalidIds.join(", ")}` }) }],
13940
+ isError: true
13941
+ };
13942
+ }
13943
+ const now = (/* @__PURE__ */ new Date()).toISOString();
13944
+ const pipeline = {
13945
+ id: crypto.randomUUID(),
13946
+ name,
13947
+ description,
13948
+ steps: steps.map((s) => ({
13949
+ id: crypto.randomUUID(),
13950
+ commandId: s.commandId,
13951
+ args: s.args,
13952
+ flags: s.flags,
13953
+ continueOnError: s.continueOnError,
13954
+ label: s.label
13955
+ })),
13956
+ createdAt: now,
13957
+ updatedAt: now
13958
+ };
13959
+ savePipeline(pipeline, source);
13960
+ return {
13961
+ content: [{ type: "text", text: JSON.stringify({ success: true, pipeline }, null, 2) }]
13962
+ };
13963
+ }
13964
+ );
13965
+ server.tool(
13966
+ "polter_update_pipeline",
13967
+ "Update an existing pipeline by name. You can change its description and/or steps.",
13968
+ {
13969
+ name: external_exports.string().describe("Pipeline name to update"),
13970
+ description: external_exports.string().optional().describe("New description"),
13971
+ steps: external_exports.array(external_exports.object({
13972
+ commandId: external_exports.string(),
13973
+ args: external_exports.array(external_exports.string()).default([]),
13974
+ flags: external_exports.array(external_exports.string()).default([]),
13975
+ continueOnError: external_exports.boolean().default(false),
13976
+ label: external_exports.string().optional()
13977
+ })).optional().describe("New steps (replaces all existing steps)")
13978
+ },
13979
+ async ({ name, description, steps }) => {
13980
+ const existing = findPipelineByName(name);
13981
+ if (!existing) {
13982
+ return {
13983
+ content: [{ type: "text", text: JSON.stringify({ error: `Pipeline not found: ${name}` }) }],
13984
+ isError: true
13985
+ };
13986
+ }
13987
+ if (steps) {
13988
+ const invalidIds = steps.filter((s) => !getCommandById(s.commandId)).map((s) => s.commandId);
13989
+ if (invalidIds.length > 0) {
13990
+ return {
13991
+ content: [{ type: "text", text: JSON.stringify({ error: `Unknown command IDs: ${invalidIds.join(", ")}` }) }],
13992
+ isError: true
13993
+ };
13994
+ }
13995
+ }
13996
+ const updated = {
13997
+ ...existing,
13998
+ description: description ?? existing.description,
13999
+ steps: steps ? steps.map((s) => ({
14000
+ id: crypto.randomUUID(),
14001
+ commandId: s.commandId,
14002
+ args: s.args,
14003
+ flags: s.flags,
14004
+ continueOnError: s.continueOnError,
14005
+ label: s.label
14006
+ })) : existing.steps,
14007
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
14008
+ };
14009
+ savePipeline(updated, existing.source);
14010
+ return {
14011
+ content: [{ type: "text", text: JSON.stringify({ success: true, pipeline: updated }, null, 2) }]
14012
+ };
14013
+ }
14014
+ );
14015
+ server.tool(
14016
+ "polter_delete_pipeline",
14017
+ "Delete a saved pipeline by name.",
14018
+ { name: external_exports.string().describe("Pipeline name to delete") },
14019
+ async ({ name }) => {
14020
+ const existing = findPipelineByName(name);
14021
+ if (!existing) {
14022
+ return {
14023
+ content: [{ type: "text", text: JSON.stringify({ error: `Pipeline not found: ${name}` }) }],
14024
+ isError: true
14025
+ };
14026
+ }
14027
+ deletePipeline(existing.id, existing.source);
14028
+ return {
14029
+ content: [{ type: "text", text: JSON.stringify({ success: true, deleted: name }) }]
14030
+ };
14031
+ }
14032
+ );
13910
14033
  server.tool(
13911
14034
  "polter_plan",
13912
14035
  "Parse polter.yaml and compute the diff between desired state and current state. Shows what actions would be taken without executing them.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polterware/polter",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "An interactive CLI for managing Supabase CLI workflows.",
5
5
  "type": "module",
6
6
  "bin": {