@codazen/harmonica-mcp 3.6.0 → 3.6.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.
Files changed (2) hide show
  1. package/dist/index.js +23 -19
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -22374,7 +22374,7 @@ function registerBeatConvergenceTools(server, ctx, client) {
22374
22374
  { beatId: external_exports.string().describe("The beat ID (e.g., TF-B-001)") },
22375
22375
  async ({ beatId }) => {
22376
22376
  const beat = await fetchBeatInOrg(client, beatId, ctx.orgId);
22377
- const report = await client.getBeatConvergence(beat.projectId, beatId);
22377
+ const report = await client.getBeatConvergence(beat.systemId ?? beat.projectId, beatId);
22378
22378
  if (!report) {
22379
22379
  return { content: [{ type: "text", text: `No convergence data for beat "${beatId}".` }], isError: true };
22380
22380
  }
@@ -22989,7 +22989,7 @@ function formatSessionDetail(session) {
22989
22989
  "",
22990
22990
  `**Type:** ${type}`,
22991
22991
  `**Status:** ${status}`,
22992
- `**Project:** ${session.projectId}`,
22992
+ `**Project:** ${session.systemId ?? session.projectId}`,
22993
22993
  `**Actor:** ${session.actor.agentPersona}${session.actor.agentRole ? ` (${session.actor.agentRole})` : ""}`
22994
22994
  ];
22995
22995
  if (session.actor.initiator) {
@@ -23143,7 +23143,7 @@ function registerBeatTools(server, ctx, client) {
23143
23143
  },
23144
23144
  async ({ beatId, projectId }) => {
23145
23145
  const beat = await fetchBeatInOrg(client, beatId, ctx.orgId);
23146
- const resolvedProjectId = projectId ?? beat.projectId;
23146
+ const resolvedProjectId = projectId ?? beat.systemId ?? beat.projectId;
23147
23147
  const timeline = await client.getUnifiedBeatTimeline(resolvedProjectId, beatId);
23148
23148
  if (timeline.length === 0) {
23149
23149
  return { content: [{ type: "text", text: `No history for beat "${beatId}".` }] };
@@ -23257,7 +23257,7 @@ ${formatBeatDetail(beat)}${similarityWarning}` }] };
23257
23257
  return { content: [{ type: "text", text: `Beat not found: "${beatId}"` }], isError: true };
23258
23258
  }
23259
23259
  await logBeatActivity(client, {
23260
- projectId: beat.projectId,
23260
+ projectId: beat.systemId ?? beat.projectId,
23261
23261
  action: "beat_updated",
23262
23262
  beatIds: [beatId],
23263
23263
  beatTitles: [updated.title],
@@ -23476,7 +23476,7 @@ function registerBeatVersionTools(server, ctx, client) {
23476
23476
  return { content: [{ type: "text", text: `Beat not found: "${beatId}"` }], isError: true };
23477
23477
  }
23478
23478
  await assertBeatInOrg(client, beatId, ctx.orgId);
23479
- const beatVersion = await client.createBeatVersion(beat.projectId, beatId, {
23479
+ const beatVersion = await client.createBeatVersion(beat.systemId ?? beat.projectId, beatId, {
23480
23480
  title,
23481
23481
  description,
23482
23482
  scope,
@@ -24447,7 +24447,7 @@ function registerDownbeatTools(server, ctx, client) {
24447
24447
  { beatId: external_exports.string().describe("The beat ID (e.g., TF-B-001)") },
24448
24448
  async ({ beatId }) => {
24449
24449
  const beat = await fetchBeatInOrg(client, beatId, ctx.orgId);
24450
- const downbeat = await client.setDownbeat(beat.projectId, beatId);
24450
+ const downbeat = await client.setDownbeat(beat.systemId ?? beat.projectId, beatId);
24451
24451
  if (!downbeat) {
24452
24452
  return { content: [{ type: "text", text: `Could not set a Downbeat for beat "${beatId}".` }], isError: true };
24453
24453
  }
@@ -24460,7 +24460,7 @@ function registerDownbeatTools(server, ctx, client) {
24460
24460
  { beatId: external_exports.string().describe("The beat ID (e.g., TF-B-001)") },
24461
24461
  async ({ beatId }) => {
24462
24462
  const beat = await fetchBeatInOrg(client, beatId, ctx.orgId);
24463
- const result = await client.listIncrementsSinceDownbeat(beat.projectId, beatId);
24463
+ const result = await client.listIncrementsSinceDownbeat(beat.systemId ?? beat.projectId, beatId);
24464
24464
  if (!result) {
24465
24465
  return { content: [{ type: "text", text: `No such beat "${beatId}".` }], isError: true };
24466
24466
  }
@@ -24473,7 +24473,7 @@ function registerDownbeatTools(server, ctx, client) {
24473
24473
  { beatId: external_exports.string().describe("The beat ID (e.g., TF-B-001)") },
24474
24474
  async ({ beatId }) => {
24475
24475
  const beat = await fetchBeatInOrg(client, beatId, ctx.orgId);
24476
- const report = await client.getCodaDrift(beat.projectId, beatId);
24476
+ const report = await client.getCodaDrift(beat.systemId ?? beat.projectId, beatId);
24477
24477
  if (!report) {
24478
24478
  return { content: [{ type: "text", text: `No such beat "${beatId}".` }], isError: true };
24479
24479
  }
@@ -24486,7 +24486,7 @@ function registerDownbeatTools(server, ctx, client) {
24486
24486
  { beatId: external_exports.string().describe("The beat ID (e.g., TF-B-001)") },
24487
24487
  async ({ beatId }) => {
24488
24488
  const beat = await fetchBeatInOrg(client, beatId, ctx.orgId);
24489
- const report = await client.getRelationalDrift(beat.projectId, beatId);
24489
+ const report = await client.getRelationalDrift(beat.systemId ?? beat.projectId, beatId);
24490
24490
  if (!report) {
24491
24491
  return { content: [{ type: "text", text: `No such beat "${beatId}".` }], isError: true };
24492
24492
  }
@@ -29328,11 +29328,11 @@ function registerRevisionLifecycleTools(server, ctx, client) {
29328
29328
  if (!parentBv) {
29329
29329
  return { content: [{ type: "text", text: `Beat Version not found: "${beatVersionId}"` }], isError: true };
29330
29330
  }
29331
- if (parentBv.beatId !== beatId || parentBv.projectId !== beat.projectId) {
29331
+ if (parentBv.beatId !== beatId || (parentBv.systemId ?? parentBv.projectId) !== (beat.systemId ?? beat.projectId)) {
29332
29332
  return { content: [{ type: "text", text: `Beat Version "${beatVersionId}" belongs to a different Beat.` }], isError: true };
29333
29333
  }
29334
29334
  }
29335
- const { revision, warnings } = await client.createRevision(beat.projectId, beatId, {
29335
+ const { revision, warnings } = await client.createRevision(beat.systemId ?? beat.projectId, beatId, {
29336
29336
  title,
29337
29337
  description,
29338
29338
  changeSummary,
@@ -29420,7 +29420,7 @@ function registerRevisionLifecycleTools(server, ctx, client) {
29420
29420
  if (!bv) {
29421
29421
  return { content: [{ type: "text", text: `Beat Version not found: "${beatVersionId}"` }], isError: true };
29422
29422
  }
29423
- if (bv.beatId !== revision.beatId || bv.projectId !== revision.projectId) {
29423
+ if (bv.beatId !== revision.beatId || (bv.systemId ?? bv.projectId) !== (revision.systemId ?? revision.projectId)) {
29424
29424
  return { content: [{ type: "text", text: `Beat Version "${beatVersionId}" belongs to a different Beat.` }], isError: true };
29425
29425
  }
29426
29426
  }
@@ -32253,7 +32253,7 @@ function createHttpClient(config2) {
32253
32253
  getBeat: async (beatId) => {
32254
32254
  const raw = await request("GET", `/api/beats/${encodeURIComponent(beatId)}`);
32255
32255
  if (!raw) return void 0;
32256
- return { ...raw, beatId: raw.beatId ?? raw.id, status: raw.status ?? "open", beatStatus: coerceBeatStatusLocal(raw.beatStatus) };
32256
+ return { ...raw, beatId: raw.beatId ?? raw.id, projectId: raw.projectId ?? raw.systemId, status: raw.status ?? "open", beatStatus: coerceBeatStatusLocal(raw.beatStatus) };
32257
32257
  },
32258
32258
  getBeatConvergence: async (projectId, beatId) => {
32259
32259
  const raw = await request(
@@ -32300,7 +32300,9 @@ function createHttpClient(config2) {
32300
32300
  }
32301
32301
  const beat = await request("GET", `/api/beats/${encodeURIComponent(beatId)}`);
32302
32302
  if (!beat) return void 0;
32303
- const result = await request("PUT", `/api/systems/${encodeURIComponent(beat.projectId)}/beats/${encodeURIComponent(beatId)}`, updates);
32303
+ const systemId = beat.systemId ?? beat.projectId;
32304
+ if (!systemId) return void 0;
32305
+ const result = await request("PUT", `/api/systems/${encodeURIComponent(systemId)}/beats/${encodeURIComponent(beatId)}`, updates);
32304
32306
  const raw = result?.beat ?? result;
32305
32307
  return { ...raw, beatStatus: coerceBeatStatusLocal(raw.beatStatus) };
32306
32308
  },
@@ -32434,6 +32436,8 @@ function createHttpClient(config2) {
32434
32436
  listBeatNotes: async (beatId, filters) => {
32435
32437
  const beat = await request("GET", `/api/beats/${encodeURIComponent(beatId)}`);
32436
32438
  if (!beat) return [];
32439
+ const systemId = beat.systemId ?? beat.projectId;
32440
+ if (!systemId) return [];
32437
32441
  const params = new URLSearchParams();
32438
32442
  if (filters?.noteType) {
32439
32443
  const types = Array.isArray(filters.noteType) ? filters.noteType : [filters.noteType];
@@ -32445,7 +32449,7 @@ function createHttpClient(config2) {
32445
32449
  if (filters?.excludeChildren) params.set("excludeChildren", "true");
32446
32450
  if (filters?.significance) params.set("significance", filters.significance);
32447
32451
  const qs = params.toString() ? `?${params.toString()}` : "";
32448
- const result = await request("GET", `/api/systems/${encodeURIComponent(beat.projectId)}/beats/${encodeURIComponent(beatId)}/notes${qs}`);
32452
+ const result = await request("GET", `/api/systems/${encodeURIComponent(systemId)}/beats/${encodeURIComponent(beatId)}/notes${qs}`);
32449
32453
  return result?.notes ?? [];
32450
32454
  },
32451
32455
  getNote: async (noteId) => {
@@ -32768,9 +32772,9 @@ function createHttpClient(config2) {
32768
32772
  // partitions, but the REST surface is unified per the project-level
32769
32773
  // "avoid nested/duplicate routes" guidance.
32770
32774
  getSession: (sessionId) => request("GET", `/api/sessions/${encodeURIComponent(sessionId)}`),
32771
- listSystemSessions: async (projectId, options) => {
32775
+ listSystemSessions: async (systemId, options) => {
32772
32776
  const params = new URLSearchParams();
32773
- params.set("projectId", projectId);
32777
+ params.set("systemId", systemId);
32774
32778
  if (options?.status) params.set("status", options.status);
32775
32779
  if (options?.includeTerminal) params.set("includeTerminal", "true");
32776
32780
  const result = await request("GET", `/api/sessions?${params.toString()}`);
@@ -33321,7 +33325,7 @@ function createHttpClient(config2) {
33321
33325
  },
33322
33326
  searchByText: async (scope, query, options) => {
33323
33327
  const params = new URLSearchParams({ q: query });
33324
- if ("projectId" in scope) params.set("projectId", scope.projectId);
33328
+ if ("projectId" in scope) params.set("systemId", scope.projectId);
33325
33329
  else if ("teamspaceId" in scope) params.set("teamspaceId", scope.teamspaceId);
33326
33330
  else params.set("orgId", scope.orgId);
33327
33331
  if (options?.limit) params.set("limit", String(options.limit));
@@ -34157,7 +34161,7 @@ function loadConfig() {
34157
34161
  };
34158
34162
  }
34159
34163
  async function main() {
34160
- console.error(`[harmonica-mcp] v${"3.6.0"} starting\u2026`);
34164
+ console.error(`[harmonica-mcp] v${"3.6.1"} starting\u2026`);
34161
34165
  const config2 = loadConfig();
34162
34166
  const client = createHttpClient({
34163
34167
  apiBaseUrl: config2.apiBaseUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codazen/harmonica-mcp",
3
- "version": "3.6.0",
3
+ "version": "3.6.1",
4
4
  "description": "MCP server for Harmonica — connect any MCP-compatible AI assistant to Harmonica",
5
5
  "license": "MIT",
6
6
  "bin": {