@schoolai/shipyard-mcp 0.1.0-next.435 → 0.1.0-next.437

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.
@@ -899,15 +899,17 @@ async function waitForApprovalHandler(planId, _reviewRequestIdParam, ctx) {
899
899
  throw err;
900
900
  }
901
901
  const metadata = ydoc.getMap(YDOC_KEYS.METADATA);
902
- const reviewRequestId = nanoid2();
903
902
  const planMetadata = getPlanMetadata(ydoc);
904
903
  const ownerId = planMetadata?.ownerId ?? "unknown";
905
- if (planMetadata?.status === "pending_review") {
906
- ctx.logger.warn(
907
- { planId, currentStatus: planMetadata.status },
908
- "Status already pending_review, another hook may be waiting. Skipping reviewRequestId update."
904
+ let reviewRequestId;
905
+ if (planMetadata?.status === "pending_review" && planMetadata.reviewRequestId) {
906
+ reviewRequestId = planMetadata.reviewRequestId;
907
+ ctx.logger.info(
908
+ { planId, currentStatus: planMetadata.status, reviewRequestId },
909
+ "Status already pending_review, reusing existing reviewRequestId for observer"
909
910
  );
910
911
  } else {
912
+ reviewRequestId = nanoid2();
911
913
  const result = transitionPlanStatus(
912
914
  ydoc,
913
915
  {
@@ -1174,11 +1176,15 @@ function extractFeedbackFromYDoc(ydoc, ctx) {
1174
1176
  return "Changes requested. Check the plan for reviewer comments.";
1175
1177
  }
1176
1178
  const contentFragment = ydoc.getXmlFragment(YDOC_KEYS.DOCUMENT_FRAGMENT);
1177
- const blocks = contentFragment.toJSON();
1178
- const planText = blocks.map((block) => {
1179
- if (!block.content || !Array.isArray(block.content)) return "";
1180
- return block.content.map((item) => typeof item === "object" && item && "text" in item ? item.text : "").join("");
1181
- }).filter(Boolean).join("\n");
1179
+ const fragmentJson = contentFragment.toJSON();
1180
+ let planText = "";
1181
+ if (Array.isArray(fragmentJson)) {
1182
+ const blocks = fragmentJson;
1183
+ planText = blocks.map((block) => {
1184
+ if (!block.content || !Array.isArray(block.content)) return "";
1185
+ return block.content.map((item) => typeof item === "object" && item && "text" in item ? item.text : "").join("");
1186
+ }).filter(Boolean).join("\n");
1187
+ }
1182
1188
  const resolveUser = createUserResolver(ydoc);
1183
1189
  const feedbackText = formatThreadsForLLM(threads, {
1184
1190
  includeResolved: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schoolai/shipyard-mcp",
3
- "version": "0.1.0-next.435",
3
+ "version": "0.1.0-next.437",
4
4
  "description": "Shipyard MCP server and CLI tools for distributed planning with CRDTs",
5
5
  "type": "module",
6
6
  "bin": {