@codazen/harmonica-mcp 0.25.1 → 0.25.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.
- package/dist/index.js +26 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25154,11 +25154,14 @@ function registerSnapshotTools(server, ctx, client) {
|
|
|
25154
25154
|
"",
|
|
25155
25155
|
...versionNote,
|
|
25156
25156
|
` Beats: ${snapshot.beats.length}`,
|
|
25157
|
+
` Beat Versions: ${snapshot.beatVersions?.length ?? 0}`,
|
|
25157
25158
|
` Proposals: ${snapshot.proposals.length}`,
|
|
25158
25159
|
` Notes: ${snapshot.notes.length}`,
|
|
25159
25160
|
` Tasks: ${snapshot.tasks.length}`,
|
|
25160
25161
|
` Submissions: ${snapshot.submissions.length}`,
|
|
25161
25162
|
` PromptLogs: ${snapshot.promptLogs.length}`,
|
|
25163
|
+
` Drops: ${snapshot.drops?.length ?? 0}`,
|
|
25164
|
+
` Deliverables: ${snapshot.deliverables?.length ?? 0}`,
|
|
25162
25165
|
"",
|
|
25163
25166
|
"Use import_project_snapshot with this file path to import into another environment."
|
|
25164
25167
|
];
|
|
@@ -25169,9 +25172,12 @@ function registerSnapshotTools(server, ctx, client) {
|
|
|
25169
25172
|
"import_project_snapshot",
|
|
25170
25173
|
"Import a project snapshot into the current environment. Accepts an S3 presigned URL (https:// only), a file path, or inline JSON. Blocked in production by default.",
|
|
25171
25174
|
{
|
|
25172
|
-
snapshot: external_exports.string().describe("S3 presigned URL (https://...), file path, or inline JSON string")
|
|
25175
|
+
snapshot: external_exports.string().describe("S3 presigned URL (https://...), file path, or inline JSON string"),
|
|
25176
|
+
targetTeamspaceId: external_exports.string().min(1).optional().describe(
|
|
25177
|
+
"Remap all teamspace references (Drops, Deliverables, Project record) to this teamspace ID in the target environment. Required when the source and target environments use different teamspace UUIDs. When omitted and the snapshot contains Drops or Deliverables, a warning is included in the import summary."
|
|
25178
|
+
)
|
|
25173
25179
|
},
|
|
25174
|
-
async ({ snapshot: snapshotInput }) => {
|
|
25180
|
+
async ({ snapshot: snapshotInput, targetTeamspaceId }) => {
|
|
25175
25181
|
const isProduction = process.env.NODE_ENV === "production";
|
|
25176
25182
|
const importAllowed = process.env.ALLOW_PROJECT_IMPORT === "true";
|
|
25177
25183
|
if (isProduction && !importAllowed) {
|
|
@@ -25184,13 +25190,13 @@ function registerSnapshotTools(server, ctx, client) {
|
|
|
25184
25190
|
};
|
|
25185
25191
|
}
|
|
25186
25192
|
const trimmed = snapshotInput.trim();
|
|
25187
|
-
const importOptions = { targetOrgId: ctx.orgId, targetUserId: ctx.user.userId };
|
|
25193
|
+
const importOptions = { targetOrgId: ctx.orgId, targetUserId: ctx.user.userId, targetTeamspaceId };
|
|
25188
25194
|
if (trimmed.startsWith("https://")) {
|
|
25189
25195
|
if (isPrivateHost(trimmed)) {
|
|
25190
25196
|
throw new Error("Snapshot URL must point to a public host \u2014 private, link-local, and loopback addresses are not permitted.");
|
|
25191
25197
|
}
|
|
25192
25198
|
const result2 = await client.importProjectSnapshotFromUrl(trimmed, importOptions);
|
|
25193
|
-
return { content: [{ type: "text", text: formatImportSummary(result2) }] };
|
|
25199
|
+
return { content: [{ type: "text", text: formatImportSummary(result2, targetTeamspaceId) }] };
|
|
25194
25200
|
}
|
|
25195
25201
|
if (trimmed.startsWith("http://")) {
|
|
25196
25202
|
throw new Error("Snapshot URL must use https:// \u2014 http:// is not permitted.");
|
|
@@ -25205,7 +25211,7 @@ function registerSnapshotTools(server, ctx, client) {
|
|
|
25205
25211
|
assertSnapshotShape(parsed, "");
|
|
25206
25212
|
const normalized = normalizeSnapshot(parsed);
|
|
25207
25213
|
const result = await client.importProjectSnapshot(normalized, importOptions);
|
|
25208
|
-
return { content: [{ type: "text", text: formatImportSummary(result) }] };
|
|
25214
|
+
return { content: [{ type: "text", text: formatImportSummary(result, targetTeamspaceId) }] };
|
|
25209
25215
|
}
|
|
25210
25216
|
);
|
|
25211
25217
|
}
|
|
@@ -25248,7 +25254,7 @@ async function resolveSnapshotInput(input) {
|
|
|
25248
25254
|
}
|
|
25249
25255
|
return trimmed;
|
|
25250
25256
|
}
|
|
25251
|
-
function formatImportSummary(result) {
|
|
25257
|
+
function formatImportSummary(result, targetTeamspaceId) {
|
|
25252
25258
|
const lines = [
|
|
25253
25259
|
`Imported project: ${result.projectId}`,
|
|
25254
25260
|
` Beats: ${result.counts.beats}`,
|
|
@@ -25259,12 +25265,24 @@ function formatImportSummary(result) {
|
|
|
25259
25265
|
` Notes: ${result.counts.notes}`,
|
|
25260
25266
|
` Tasks: ${result.counts.tasks}`,
|
|
25261
25267
|
` Submissions: ${result.counts.submissions}`,
|
|
25262
|
-
` PromptLogs: ${result.counts.promptLogs}
|
|
25268
|
+
` PromptLogs: ${result.counts.promptLogs}`,
|
|
25269
|
+
` Beat Versions: ${result.counts.beatVersions ?? 0}`,
|
|
25270
|
+
` Drops: ${result.counts.drops ?? 0}`,
|
|
25271
|
+
` Deliverables: ${result.counts.deliverables ?? 0}`
|
|
25263
25272
|
];
|
|
25264
25273
|
if (result.errors.length > 0) {
|
|
25265
25274
|
lines.push("", `Errors (${result.errors.length}):`);
|
|
25266
25275
|
result.errors.forEach((e) => lines.push(` - ${e}`));
|
|
25267
25276
|
}
|
|
25277
|
+
const hasTeamspaceData = result.projectTeamspaceId !== void 0 || (result.counts.drops ?? 0) + (result.counts.deliverables ?? 0) > 0;
|
|
25278
|
+
if (!targetTeamspaceId && hasTeamspaceData) {
|
|
25279
|
+
lines.push(
|
|
25280
|
+
"",
|
|
25281
|
+
"Warning: snapshot contains teamspace-scoped data but targetTeamspaceId was not provided.",
|
|
25282
|
+
"The project record and any Drops or Deliverables were imported with their original teamspaceId and may not appear under the correct teamspace in this environment.",
|
|
25283
|
+
"Re-run with targetTeamspaceId set to the target teamspace UUID to remap them."
|
|
25284
|
+
);
|
|
25285
|
+
}
|
|
25268
25286
|
return lines.join("\n");
|
|
25269
25287
|
}
|
|
25270
25288
|
function isPrivateHost(url) {
|
|
@@ -27038,7 +27056,7 @@ function loadConfig() {
|
|
|
27038
27056
|
};
|
|
27039
27057
|
}
|
|
27040
27058
|
async function main() {
|
|
27041
|
-
console.error(`[harmonica-mcp] v${"0.25.
|
|
27059
|
+
console.error(`[harmonica-mcp] v${"0.25.2"} starting\u2026`);
|
|
27042
27060
|
const config2 = loadConfig();
|
|
27043
27061
|
const client = createHttpClient({
|
|
27044
27062
|
apiBaseUrl: config2.apiBaseUrl,
|