@codazen/harmonica-mcp 3.7.0 → 3.7.2

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 +195 -39
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -25905,6 +25905,126 @@ function formatTriageActions(actions) {
25905
25905
  // ../../libs/harmonica-services/src/mcp/tools/note-element-tools.ts
25906
25906
  var import_crypto3 = require("crypto");
25907
25907
 
25908
+ // ../../libs/harmonica-schemas/src/azure-marketplace.ts
25909
+ var AzureMarketplaceSubscriptionSchema = external_exports.object({
25910
+ id: external_exports.string(),
25911
+ publisherId: external_exports.string().optional(),
25912
+ offerId: external_exports.string().optional(),
25913
+ name: external_exports.string().optional(),
25914
+ saasSubscriptionStatus: external_exports.string().optional(),
25915
+ planId: external_exports.string().optional(),
25916
+ quantity: external_exports.number().optional(),
25917
+ beneficiary: external_exports.object({
25918
+ emailId: external_exports.string().optional(),
25919
+ objectId: external_exports.string().optional(),
25920
+ tenantId: external_exports.string().optional()
25921
+ }).optional(),
25922
+ purchaser: external_exports.object({
25923
+ emailId: external_exports.string().optional(),
25924
+ objectId: external_exports.string().optional(),
25925
+ tenantId: external_exports.string().optional()
25926
+ }).optional()
25927
+ });
25928
+ var AzureSubscribedSchema = external_exports.object({
25929
+ action: external_exports.literal("Subscribe"),
25930
+ // Non-blank, not merely non-empty. A bare z.string() accepts "", which would
25931
+ // derive the slug "az-" — 3 chars, trailing dash, invalid under the repository
25932
+ // slug invariant. And .min(1) alone still admits " ", which normalizes to
25933
+ // nothing and falls through to the hash fallback, quietly provisioning an org
25934
+ // under a hashed slug for input that is plainly garbage. Reject it at the
25935
+ // boundary instead.
25936
+ subscriptionId: external_exports.string().min(1).refine((v) => v.trim().length > 0, {
25937
+ message: "subscriptionId must not be blank"
25938
+ }),
25939
+ offerId: external_exports.string(),
25940
+ planId: external_exports.string(),
25941
+ quantity: external_exports.number().optional(),
25942
+ timeStamp: external_exports.string(),
25943
+ operationId: external_exports.string(),
25944
+ subscription: AzureMarketplaceSubscriptionSchema
25945
+ });
25946
+ var AzureUnsubscribedSchema = external_exports.object({
25947
+ action: external_exports.literal("Unsubscribe"),
25948
+ // Non-blank, not merely non-empty. A bare z.string() accepts "", which would
25949
+ // derive the slug "az-" — 3 chars, trailing dash, invalid under the repository
25950
+ // slug invariant. And .min(1) alone still admits " ", which normalizes to
25951
+ // nothing and falls through to the hash fallback, quietly provisioning an org
25952
+ // under a hashed slug for input that is plainly garbage. Reject it at the
25953
+ // boundary instead.
25954
+ subscriptionId: external_exports.string().min(1).refine((v) => v.trim().length > 0, {
25955
+ message: "subscriptionId must not be blank"
25956
+ }),
25957
+ offerId: external_exports.string(),
25958
+ planId: external_exports.string(),
25959
+ timeStamp: external_exports.string(),
25960
+ operationId: external_exports.string(),
25961
+ subscription: AzureMarketplaceSubscriptionSchema
25962
+ });
25963
+ var AzureChangePlanSchema = external_exports.object({
25964
+ action: external_exports.literal("ChangePlan"),
25965
+ // Non-blank, not merely non-empty. A bare z.string() accepts "", which would
25966
+ // derive the slug "az-" — 3 chars, trailing dash, invalid under the repository
25967
+ // slug invariant. And .min(1) alone still admits " ", which normalizes to
25968
+ // nothing and falls through to the hash fallback, quietly provisioning an org
25969
+ // under a hashed slug for input that is plainly garbage. Reject it at the
25970
+ // boundary instead.
25971
+ subscriptionId: external_exports.string().min(1).refine((v) => v.trim().length > 0, {
25972
+ message: "subscriptionId must not be blank"
25973
+ }),
25974
+ offerId: external_exports.string(),
25975
+ planId: external_exports.string(),
25976
+ timeStamp: external_exports.string(),
25977
+ operationId: external_exports.string(),
25978
+ subscription: AzureMarketplaceSubscriptionSchema
25979
+ });
25980
+ var AzureSuspendSchema = external_exports.object({
25981
+ action: external_exports.literal("Suspend"),
25982
+ // Non-blank, not merely non-empty. A bare z.string() accepts "", which would
25983
+ // derive the slug "az-" — 3 chars, trailing dash, invalid under the repository
25984
+ // slug invariant. And .min(1) alone still admits " ", which normalizes to
25985
+ // nothing and falls through to the hash fallback, quietly provisioning an org
25986
+ // under a hashed slug for input that is plainly garbage. Reject it at the
25987
+ // boundary instead.
25988
+ subscriptionId: external_exports.string().min(1).refine((v) => v.trim().length > 0, {
25989
+ message: "subscriptionId must not be blank"
25990
+ }),
25991
+ offerId: external_exports.string(),
25992
+ planId: external_exports.string(),
25993
+ timeStamp: external_exports.string(),
25994
+ operationId: external_exports.string(),
25995
+ subscription: AzureMarketplaceSubscriptionSchema
25996
+ });
25997
+ var AzureReinstateSchema = external_exports.object({
25998
+ action: external_exports.literal("Reinstate"),
25999
+ // Non-blank, not merely non-empty. A bare z.string() accepts "", which would
26000
+ // derive the slug "az-" — 3 chars, trailing dash, invalid under the repository
26001
+ // slug invariant. And .min(1) alone still admits " ", which normalizes to
26002
+ // nothing and falls through to the hash fallback, quietly provisioning an org
26003
+ // under a hashed slug for input that is plainly garbage. Reject it at the
26004
+ // boundary instead.
26005
+ subscriptionId: external_exports.string().min(1).refine((v) => v.trim().length > 0, {
26006
+ message: "subscriptionId must not be blank"
26007
+ }),
26008
+ offerId: external_exports.string(),
26009
+ planId: external_exports.string(),
26010
+ timeStamp: external_exports.string(),
26011
+ operationId: external_exports.string(),
26012
+ subscription: AzureMarketplaceSubscriptionSchema
26013
+ });
26014
+ var AzureMarketplaceWebhookEventSchema = external_exports.discriminatedUnion("action", [
26015
+ AzureSubscribedSchema,
26016
+ AzureUnsubscribedSchema,
26017
+ AzureChangePlanSchema,
26018
+ AzureSuspendSchema,
26019
+ AzureReinstateSchema
26020
+ ]);
26021
+ var AZURE_MARKETPLACE_WEBHOOK_ACTIONS = AzureMarketplaceWebhookEventSchema.options.map(
26022
+ (o) => o.shape.action.value
26023
+ );
26024
+ var AzureMarketplaceActivateBodySchema = external_exports.object({
26025
+ token: external_exports.string().min(1)
26026
+ });
26027
+
25908
26028
  // ../../libs/harmonica-schemas/src/compose-beat-versions.ts
25909
26029
  var BeatVersionDraftSchema = external_exports.object({
25910
26030
  title: external_exports.string().min(1).max(300),
@@ -26216,25 +26336,35 @@ var NoteStatusSchema = external_exports.enum([
26216
26336
  ]);
26217
26337
  var SystemStatusSchema = external_exports.enum(["active", "archived", "draft"]);
26218
26338
  var ChangeImportanceSchema = external_exports.enum(["minor", "moderate", "major"]);
26219
- var BeatApiSchema = external_exports.object({
26220
- beatId: external_exports.string(),
26221
- projectId: external_exports.string(),
26222
- /** Source project's title; attached by the flat /api/beats endpoint for
26223
- * multi-project (teamspace/org) responses. */
26224
- projectName: external_exports.string().nullish(),
26225
- title: external_exports.string(),
26226
- version: external_exports.number().nullish(),
26227
- description: external_exports.string().nullish(),
26228
- beatStatus: BeatStatusSchema.nullish(),
26229
- tags: external_exports.array(external_exports.string()).nullish(),
26230
- priority: external_exports.number().nullish(),
26231
- estimatedEffort: external_exports.string().nullish(),
26232
- humanAssignee: HumanAssigneeSchema.nullish(),
26233
- agentAssignee: AgentAssigneeSchema.nullish(),
26234
- revisionCount: external_exports.number().nullish(),
26235
- createdAt: external_exports.string(),
26236
- updatedAt: external_exports.string()
26237
- }).passthrough();
26339
+ var BeatApiSchema = external_exports.preprocess(
26340
+ (raw) => {
26341
+ if (typeof raw !== "object" || raw === null) return raw;
26342
+ const b = raw;
26343
+ const id = b["systemId"] ?? b["projectId"];
26344
+ if (!id) return raw;
26345
+ return { ...b, systemId: id, projectId: id };
26346
+ },
26347
+ external_exports.object({
26348
+ beatId: external_exports.string(),
26349
+ systemId: external_exports.string(),
26350
+ projectId: external_exports.string(),
26351
+ /** Source project's title; attached by the flat /api/beats endpoint for
26352
+ * multi-project (teamspace/org) responses. */
26353
+ projectName: external_exports.string().nullish(),
26354
+ title: external_exports.string(),
26355
+ version: external_exports.number().nullish(),
26356
+ description: external_exports.string().nullish(),
26357
+ beatStatus: BeatStatusSchema.nullish(),
26358
+ tags: external_exports.array(external_exports.string()).nullish(),
26359
+ priority: external_exports.number().nullish(),
26360
+ estimatedEffort: external_exports.string().nullish(),
26361
+ humanAssignee: HumanAssigneeSchema.nullish(),
26362
+ agentAssignee: AgentAssigneeSchema.nullish(),
26363
+ revisionCount: external_exports.number().nullish(),
26364
+ createdAt: external_exports.string(),
26365
+ updatedAt: external_exports.string()
26366
+ }).passthrough()
26367
+ );
26238
26368
  var RevisionScmSchema = external_exports.object({
26239
26369
  provider: external_exports.literal("github"),
26240
26370
  number: external_exports.string(),
@@ -26865,21 +26995,31 @@ var AccountSystemApiSchema = external_exports.object({
26865
26995
  var AccountSystemsResponseSchema = external_exports.object({ systems: external_exports.array(AccountSystemApiSchema) }).passthrough();
26866
26996
  var LAYER_STATUSES = ["active", "archived"];
26867
26997
  var LayerStatusApiSchema = external_exports.enum(LAYER_STATUSES);
26868
- var LayerApiSchema = external_exports.object({
26869
- layerId: external_exports.string(),
26870
- projectId: external_exports.string(),
26871
- layerKey: external_exports.string(),
26872
- name: external_exports.string(),
26873
- description: external_exports.string().nullish(),
26874
- parentLayerId: external_exports.string().nullish(),
26875
- repoPatterns: external_exports.array(external_exports.string()).nullish(),
26876
- status: LayerStatusApiSchema,
26877
- archivedAt: external_exports.string().nullish(),
26878
- createdBy: external_exports.string().nullish(),
26879
- version: external_exports.number().nullish(),
26880
- createdAt: external_exports.string(),
26881
- updatedAt: external_exports.string()
26882
- }).passthrough();
26998
+ var LayerApiSchema = external_exports.preprocess(
26999
+ (raw) => {
27000
+ if (typeof raw !== "object" || raw === null) return raw;
27001
+ const l = raw;
27002
+ const id = l["systemId"] ?? l["projectId"];
27003
+ if (!id) return raw;
27004
+ return { ...l, systemId: id, projectId: id };
27005
+ },
27006
+ external_exports.object({
27007
+ layerId: external_exports.string(),
27008
+ systemId: external_exports.string(),
27009
+ projectId: external_exports.string(),
27010
+ layerKey: external_exports.string(),
27011
+ name: external_exports.string(),
27012
+ description: external_exports.string().nullish(),
27013
+ parentLayerId: external_exports.string().nullish(),
27014
+ repoPatterns: external_exports.array(external_exports.string()).nullish(),
27015
+ status: LayerStatusApiSchema,
27016
+ archivedAt: external_exports.string().nullish(),
27017
+ createdBy: external_exports.string().nullish(),
27018
+ version: external_exports.number().nullish(),
27019
+ createdAt: external_exports.string(),
27020
+ updatedAt: external_exports.string()
27021
+ }).passthrough()
27022
+ );
26883
27023
  var LayersResponseSchema = external_exports.object({ layers: external_exports.array(LayerApiSchema) }).passthrough();
26884
27024
  var LAYER_RUBRIC_SCOPES_LIST = ["account", "teamspace", "movement"];
26885
27025
  var LayerRubricScopeApiSchema = external_exports.enum(LAYER_RUBRIC_SCOPES_LIST);
@@ -29322,17 +29462,25 @@ function registerRevisionLifecycleTools(server, ctx, client) {
29322
29462
  if (!beat) {
29323
29463
  return { content: [{ type: "text", text: `Beat not found: "${beatId}"` }], isError: true };
29324
29464
  }
29465
+ const beatSystemId = beat.systemId ?? beat.projectId;
29466
+ if (!beatSystemId) {
29467
+ return { content: [{ type: "text", text: `Beat "${beatId}" has no system identifier \u2014 record may be corrupt.` }], isError: true };
29468
+ }
29325
29469
  let parentBv;
29326
29470
  if (beatVersionId !== void 0) {
29327
29471
  parentBv = await client.getBeatVersion(beatVersionId);
29328
29472
  if (!parentBv) {
29329
29473
  return { content: [{ type: "text", text: `Beat Version not found: "${beatVersionId}"` }], isError: true };
29330
29474
  }
29331
- if (parentBv.beatId !== beatId || parentBv.systemId !== beat.systemId) {
29475
+ const bvSystemId = parentBv.systemId ?? parentBv.projectId;
29476
+ if (!bvSystemId) {
29477
+ return { content: [{ type: "text", text: `Beat Version "${beatVersionId}" has no system identifier \u2014 record may be corrupt.` }], isError: true };
29478
+ }
29479
+ if (parentBv.beatId !== beat.beatId || bvSystemId !== beatSystemId) {
29332
29480
  return { content: [{ type: "text", text: `Beat Version "${beatVersionId}" belongs to a different Beat.` }], isError: true };
29333
29481
  }
29334
29482
  }
29335
- const { revision, warnings } = await client.createRevision(beat.systemId, beatId, {
29483
+ const { revision, warnings } = await client.createRevision(beatSystemId, beat.beatId, {
29336
29484
  title,
29337
29485
  description,
29338
29486
  changeSummary,
@@ -29420,7 +29568,15 @@ function registerRevisionLifecycleTools(server, ctx, client) {
29420
29568
  if (!bv) {
29421
29569
  return { content: [{ type: "text", text: `Beat Version not found: "${beatVersionId}"` }], isError: true };
29422
29570
  }
29423
- if (bv.beatId !== revision.beatId || bv.systemId !== revision.systemId) {
29571
+ const bvSystemId = bv.systemId ?? bv.projectId;
29572
+ if (!bvSystemId) {
29573
+ return { content: [{ type: "text", text: `Beat Version "${beatVersionId}" has no system identifier \u2014 record may be corrupt.` }], isError: true };
29574
+ }
29575
+ const revSystemId = revision.systemId ?? revision.projectId;
29576
+ if (!revSystemId) {
29577
+ return { content: [{ type: "text", text: `Revision "${revisionId}" has no system identifier \u2014 record may be corrupt.` }], isError: true };
29578
+ }
29579
+ if (bv.beatId !== revision.beatId || bvSystemId !== revSystemId) {
29424
29580
  return { content: [{ type: "text", text: `Beat Version "${beatVersionId}" belongs to a different Beat.` }], isError: true };
29425
29581
  }
29426
29582
  }
@@ -33182,7 +33338,7 @@ function createHttpClient(config2) {
33182
33338
  const result = await request(
33183
33339
  "POST",
33184
33340
  `/api/sessions`,
33185
- { projectId, message, ...triggeredBy && { triggeredBy }, ...trimmedRevisionId && { revisionId: trimmedRevisionId } }
33341
+ { systemId: projectId, message, ...triggeredBy && { triggeredBy }, ...trimmedRevisionId && { revisionId: trimmedRevisionId } }
33186
33342
  );
33187
33343
  if (!result?.taskId) throw new Error("Start session enqueue failed: no taskId returned");
33188
33344
  return { taskId: result.taskId, taskType: "generic_session", status: result.status ?? "pending", systemId: projectId, createdAt: (/* @__PURE__ */ new Date()).toISOString() };
@@ -34161,7 +34317,7 @@ function loadConfig() {
34161
34317
  };
34162
34318
  }
34163
34319
  async function main() {
34164
- console.error(`[harmonica-mcp] v${"3.7.0"} starting\u2026`);
34320
+ console.error(`[harmonica-mcp] v${"3.7.2"} starting\u2026`);
34165
34321
  const config2 = loadConfig();
34166
34322
  const client = createHttpClient({
34167
34323
  apiBaseUrl: config2.apiBaseUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codazen/harmonica-mcp",
3
- "version": "3.7.0",
3
+ "version": "3.7.2",
4
4
  "description": "MCP server for Harmonica — connect any MCP-compatible AI assistant to Harmonica",
5
5
  "license": "MIT",
6
6
  "bin": {