@codazen/harmonica-mcp 0.25.2 → 0.25.4

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.
Files changed (2) hide show
  1. package/dist/index.js +26 -14
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -22602,6 +22602,7 @@ var LIFECYCLE_STATES = [
22602
22602
  "archived",
22603
22603
  "deprecated"
22604
22604
  ];
22605
+ var PR_LIFECYCLE_STATES = ["draft", "open"];
22605
22606
 
22606
22607
  // ../../libs/harmonica-services/src/mcp/tools/beat-version-tools.ts
22607
22608
  function registerBeatVersionTools(server, ctx, client) {
@@ -24811,7 +24812,7 @@ function registerProjectTools(server, ctx, client) {
24811
24812
  function registerRevisionLifecycleTools(server, ctx, client) {
24812
24813
  server.tool(
24813
24814
  "create_revision",
24814
- "Create a new revision on a Beat. Starts at planning status. Use this to add revisions alongside existing ones \u2014 no idempotency guard.",
24815
+ "Create a new revision on a Beat. Starts in `draft` state under the PR workflow (draft \u2192 open \u2192 merged) \u2014 NOT the standard Beat Version lifecycle. Transition to `open` when the PR is ready for review; transition to `merged` when the PR is merged. Environment progression (in_staging, ready_for_production, live) is tracked on the parent Beat Version, not the Revision. Use this to add revisions alongside existing ones \u2014 no idempotency guard.",
24815
24816
  {
24816
24817
  beatId: external_exports.string().describe("The beat ID to create the revision on"),
24817
24818
  title: external_exports.string().describe("Title for this revision"),
@@ -24937,7 +24938,7 @@ function registerRevisionLifecycleTools(server, ctx, client) {
24937
24938
  "Transition a revision to a new lifecycle state (e.g., concept \u2192 plan, build \u2192 deploy \u2192 support).",
24938
24939
  {
24939
24940
  revisionId: external_exports.string().describe("The revision ID (e.g., rev-abc123)"),
24940
- targetState: external_exports.enum(LIFECYCLE_STATES).describe("The target lifecycle state"),
24941
+ targetState: external_exports.enum([...LIFECYCLE_STATES, ...PR_LIFECYCLE_STATES]).describe("The target lifecycle state"),
24941
24942
  reason: external_exports.string().optional().describe("Why this transition is being made"),
24942
24943
  skipQualityCheck: external_exports.boolean().optional().describe("Skip the quality check guard (for reconciling already-shipped code)"),
24943
24944
  reconcile: external_exports.boolean().optional().describe("Walk through all intermediate forward states automatically. Use for already-shipped work that needs state machine catch-up.")
@@ -26451,6 +26452,9 @@ function createHttpClient(config2) {
26451
26452
  metadata: options.metadata
26452
26453
  }
26453
26454
  );
26455
+ if (raw === void 0) {
26456
+ return { success: false, error: { code: "REVISION_NOT_FOUND", message: "Revision not found" } };
26457
+ }
26454
26458
  return {
26455
26459
  success: true,
26456
26460
  previousState: raw.transition.previousState,
@@ -26458,8 +26462,7 @@ function createHttpClient(config2) {
26458
26462
  };
26459
26463
  } catch (err) {
26460
26464
  const message = err instanceof Error ? err.message : String(err);
26461
- const code = err instanceof ApiError && err.status === 404 ? "REVISION_NOT_FOUND" : "TRANSITION_FAILED";
26462
- return { success: false, error: { code, message } };
26465
+ return { success: false, error: { code: "TRANSITION_FAILED", message } };
26463
26466
  }
26464
26467
  },
26465
26468
  reconcileRevisionToState: async (revisionId, targetState, options) => {
@@ -26951,15 +26954,24 @@ function createHttpClient(config2) {
26951
26954
  return request("PATCH", `/api/beat-versions/${encodeURIComponent(beatVersionId)}`, updates);
26952
26955
  },
26953
26956
  transitionBeatVersionStatus: async (beatVersionId, targetState, options) => {
26954
- return request("PATCH", `/api/beat-versions/${encodeURIComponent(beatVersionId)}/status`, {
26955
- status: targetState,
26956
- reason: options.reason,
26957
- trigger: options.trigger,
26958
- actorType: options.actor.type,
26959
- actorId: options.actor.id,
26960
- actorName: options.actor.name,
26961
- metadata: options.metadata
26962
- });
26957
+ try {
26958
+ const res = await request("PATCH", `/api/beat-versions/${encodeURIComponent(beatVersionId)}/status`, {
26959
+ status: targetState,
26960
+ reason: options.reason,
26961
+ trigger: options.trigger,
26962
+ actorType: options.actor.type,
26963
+ actorId: options.actor.id,
26964
+ actorName: options.actor.name,
26965
+ metadata: options.metadata
26966
+ });
26967
+ if (res === void 0) {
26968
+ return { success: false, error: { code: "BEAT_VERSION_NOT_FOUND", message: "Beat version not found" } };
26969
+ }
26970
+ return { success: true };
26971
+ } catch (err) {
26972
+ const message = err instanceof Error ? err.message : String(err);
26973
+ return { success: false, error: { code: "TRANSITION_FAILED", message } };
26974
+ }
26963
26975
  },
26964
26976
  getBeatVersionAvailableTransitions: async (beatVersionId, actorType) => {
26965
26977
  const qs = actorType ? `?actorType=${encodeURIComponent(actorType)}` : "";
@@ -27056,7 +27068,7 @@ function loadConfig() {
27056
27068
  };
27057
27069
  }
27058
27070
  async function main() {
27059
- console.error(`[harmonica-mcp] v${"0.25.2"} starting\u2026`);
27071
+ console.error(`[harmonica-mcp] v${"0.25.4"} starting\u2026`);
27060
27072
  const config2 = loadConfig();
27061
27073
  const client = createHttpClient({
27062
27074
  apiBaseUrl: config2.apiBaseUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codazen/harmonica-mcp",
3
- "version": "0.25.2",
3
+ "version": "0.25.4",
4
4
  "description": "MCP server for Harmonica — connect Claude to your Harmonica projects",
5
5
  "license": "MIT",
6
6
  "bin": {