openplanr 2.6.0 → 2.6.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 (50) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/CONTRIBUTING.md +2 -31
  3. package/dist/dashboard/.vite/manifest.json +1 -1
  4. package/dist/dashboard/assets/{index-BaARCc1f.js → index-AeydhSKa.js} +2 -2
  5. package/dist/dashboard/assets/{index-BaARCc1f.js.map → index-AeydhSKa.js.map} +1 -1
  6. package/dist/dashboard/dashboard-manifest.json +8 -8
  7. package/dist/dashboard/index.html +1 -1
  8. package/dist/services/codex-plugin-service.d.ts +2 -2
  9. package/dist/services/codex-plugin-service.d.ts.map +1 -1
  10. package/dist/services/codex-plugin-service.js +7 -7
  11. package/dist/services/codex-plugin-service.js.map +1 -1
  12. package/dist/services/diagram-artifact-service.d.ts +20 -0
  13. package/dist/services/diagram-artifact-service.d.ts.map +1 -1
  14. package/dist/services/diagram-artifact-service.js +10 -0
  15. package/dist/services/diagram-artifact-service.js.map +1 -1
  16. package/lib/host-packages/adapter-registry.json +5 -5
  17. package/lib/host-packages/capability-map.json +1 -1
  18. package/lib/host-packages/claude/.claude-plugin/marketplace.json +2 -2
  19. package/lib/host-packages/claude/openplanr/.claude-plugin/plugin.json +1 -1
  20. package/lib/host-packages/claude/openplanr/.openplanr-content.json +10 -10
  21. package/lib/host-packages/claude/openplanr/skills/design/scripts/design.mjs +66 -1
  22. package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/package.json +5 -1
  23. package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/design.mjs +66 -1
  24. package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/package.json +5 -1
  25. package/lib/host-packages/claude/openplanr/skills/design-review/scripts/design.mjs +66 -1
  26. package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/package.json +5 -1
  27. package/lib/host-packages/claude/openplanr/skills/plan/scripts/design.mjs +66 -1
  28. package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/package.json +5 -1
  29. package/lib/host-packages/cursor/openplanr/.openplanr-content.json +10 -10
  30. package/lib/host-packages/cursor/openplanr/manifest.json +1 -1
  31. package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/design.mjs +66 -1
  32. package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/package.json +5 -1
  33. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/design.mjs +66 -1
  34. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/package.json +5 -1
  35. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/design.mjs +66 -1
  36. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/package.json +5 -1
  37. package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/design.mjs +66 -1
  38. package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/package.json +5 -1
  39. package/lib/host-packages/openai/.claude-plugin/marketplace.json +2 -2
  40. package/lib/host-packages/openai/openplanr/.codex-plugin/plugin.json +1 -1
  41. package/lib/host-packages/openai/openplanr/.openplanr-content.json +10 -10
  42. package/lib/host-packages/openai/openplanr/skills/design/scripts/design.mjs +66 -1
  43. package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/package.json +5 -1
  44. package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/design.mjs +66 -1
  45. package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/package.json +5 -1
  46. package/lib/host-packages/openai/openplanr/skills/design-review/scripts/design.mjs +66 -1
  47. package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/package.json +5 -1
  48. package/lib/host-packages/openai/openplanr/skills/plan/scripts/design.mjs +66 -1
  49. package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/package.json +5 -1
  50. package/package.json +2 -2
@@ -14910,6 +14910,7 @@ function createArtifactReviewServer({
14910
14910
  throw artifactError(ARTIFACT_ERROR_CODES.LOOPBACK_STATE, "Artifact review instance id is invalid.");
14911
14911
  }
14912
14912
  const sessions = /* @__PURE__ */ new Map();
14913
+ const ownerSessions = /* @__PURE__ */ new Map();
14913
14914
  let port = null;
14914
14915
  let closePromise = null;
14915
14916
  let pendingRegistrations = 0;
@@ -14917,7 +14918,7 @@ function createArtifactReviewServer({
14917
14918
  let draining = false;
14918
14919
  let emptyTimer = null;
14919
14920
  const stageRuntime = () => readFileSync11(STAGE_RUNTIME_PATH, "utf8");
14920
- const idle = () => sessions.size === 0 && pendingRegistrations === 0 && activeRequests === 0;
14921
+ const idle = () => sessions.size === 0 && ownerSessions.size === 0 && pendingRegistrations === 0 && activeRequests === 0;
14921
14922
  const scheduleEmpty = () => {
14922
14923
  if (emptyTimer || draining || typeof onEmpty !== "function") return;
14923
14924
  emptyTimer = setTimeout(async () => {
@@ -15042,6 +15043,41 @@ function createArtifactReviewServer({
15042
15043
  notFound(res, { head });
15043
15044
  return;
15044
15045
  }
15046
+ if (segments[0] === "o") {
15047
+ const owner = safeSessionId(segments[1]) && ownerSessions.get(segments[1]);
15048
+ if (draining || !sessionMatches(owner, segments[2])) {
15049
+ notFound(res, { head });
15050
+ return;
15051
+ }
15052
+ const request2 = Promise.resolve().then(() => owner.handleRequest({
15053
+ req,
15054
+ segments: segments.slice(3),
15055
+ head,
15056
+ origin: `http://${LOOPBACK_HOST}:${port}`,
15057
+ recoveryScope: owner.recoveryScope
15058
+ }));
15059
+ owner.pending.add(request2);
15060
+ let response;
15061
+ try {
15062
+ response = await request2;
15063
+ } finally {
15064
+ owner.pending.delete(request2);
15065
+ }
15066
+ if (!response) {
15067
+ notFound(res, { head });
15068
+ return;
15069
+ }
15070
+ send(res, response.status, JSON.stringify(response.body), {
15071
+ // Rejections may precede body consumption (for example Content-Length
15072
+ // above the limit). Do not reuse a socket containing unread body bytes.
15073
+ ...response.status >= 400 ? { connection: "close" } : {},
15074
+ "content-type": "application/json; charset=utf-8",
15075
+ "cross-origin-resource-policy": "same-origin",
15076
+ "content-security-policy": "default-src 'none'; frame-ancestors 'none'",
15077
+ "x-frame-options": "DENY"
15078
+ }, { head });
15079
+ return;
15080
+ }
15045
15081
  if (segments.length < 3 || segments[0] !== "r" || !safeSessionId(segments[1])) {
15046
15082
  notFound(res, { head });
15047
15083
  return;
@@ -15200,6 +15236,32 @@ function createArtifactReviewServer({
15200
15236
  controlToken,
15201
15237
  instanceId,
15202
15238
  sessionCount: () => sessions.size,
15239
+ /** Trusted local authority only; this operation has no HTTP control route. */
15240
+ registerOwnerSession({ handleRequest } = {}) {
15241
+ if (draining || closePromise || typeof handleRequest !== "function") {
15242
+ throw artifactError(ARTIFACT_ERROR_CODES.LOOPBACK_STATE, "Local owner session cannot be registered.");
15243
+ }
15244
+ const id4 = mintCapabilityToken({ bytes: SESSION_ID_BYTES });
15245
+ const owner = {
15246
+ id: id4,
15247
+ capability: mintCapabilityToken({ bytes: SESSION_TOKEN_BYTES }),
15248
+ recoveryScope: `diagram-owner_${id4}`,
15249
+ handleRequest,
15250
+ pending: /* @__PURE__ */ new Set()
15251
+ };
15252
+ ownerSessions.set(id4, owner);
15253
+ return Object.freeze({
15254
+ sessionId: id4,
15255
+ capability: owner.capability,
15256
+ recoveryScope: owner.recoveryScope,
15257
+ path: `/o/${id4}/${owner.capability}/`,
15258
+ async close() {
15259
+ ownerSessions.delete(id4);
15260
+ await Promise.allSettled([...owner.pending]);
15261
+ if (idle()) scheduleEmpty();
15262
+ }
15263
+ });
15264
+ },
15203
15265
  isIdle: idle,
15204
15266
  accepting: () => !draining && !closePromise,
15205
15267
  beginCloseIfIdle() {
@@ -15224,6 +15286,9 @@ function createArtifactReviewServer({
15224
15286
  emptyTimer = null;
15225
15287
  closePromise = (async () => {
15226
15288
  sessions.clear();
15289
+ const pendingOwners = [...ownerSessions.values()].flatMap((owner) => [...owner.pending]);
15290
+ ownerSessions.clear();
15291
+ await Promise.allSettled(pendingOwners);
15227
15292
  await closeHttpServer(server);
15228
15293
  })();
15229
15294
  return closePromise;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openplanr/protocol",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "description": "Canonical OpenPlanr schemas, registries, typed errors, and portable contract validation",
6
6
  "license": "MIT",
@@ -83,6 +83,10 @@
83
83
  "./enterprise-contracts": {
84
84
  "types": "./src/enterprise-contracts.d.mts",
85
85
  "import": "./src/enterprise-contracts.mjs"
86
+ },
87
+ "./diagram-authoring-contracts": {
88
+ "types": "./src/diagram-authoring-contracts.d.mts",
89
+ "import": "./src/diagram-authoring-contracts.mjs"
86
90
  }
87
91
  },
88
92
  "files": [
@@ -14910,6 +14910,7 @@ function createArtifactReviewServer({
14910
14910
  throw artifactError(ARTIFACT_ERROR_CODES.LOOPBACK_STATE, "Artifact review instance id is invalid.");
14911
14911
  }
14912
14912
  const sessions = /* @__PURE__ */ new Map();
14913
+ const ownerSessions = /* @__PURE__ */ new Map();
14913
14914
  let port = null;
14914
14915
  let closePromise = null;
14915
14916
  let pendingRegistrations = 0;
@@ -14917,7 +14918,7 @@ function createArtifactReviewServer({
14917
14918
  let draining = false;
14918
14919
  let emptyTimer = null;
14919
14920
  const stageRuntime = () => readFileSync11(STAGE_RUNTIME_PATH, "utf8");
14920
- const idle = () => sessions.size === 0 && pendingRegistrations === 0 && activeRequests === 0;
14921
+ const idle = () => sessions.size === 0 && ownerSessions.size === 0 && pendingRegistrations === 0 && activeRequests === 0;
14921
14922
  const scheduleEmpty = () => {
14922
14923
  if (emptyTimer || draining || typeof onEmpty !== "function") return;
14923
14924
  emptyTimer = setTimeout(async () => {
@@ -15042,6 +15043,41 @@ function createArtifactReviewServer({
15042
15043
  notFound(res, { head });
15043
15044
  return;
15044
15045
  }
15046
+ if (segments[0] === "o") {
15047
+ const owner = safeSessionId(segments[1]) && ownerSessions.get(segments[1]);
15048
+ if (draining || !sessionMatches(owner, segments[2])) {
15049
+ notFound(res, { head });
15050
+ return;
15051
+ }
15052
+ const request2 = Promise.resolve().then(() => owner.handleRequest({
15053
+ req,
15054
+ segments: segments.slice(3),
15055
+ head,
15056
+ origin: `http://${LOOPBACK_HOST}:${port}`,
15057
+ recoveryScope: owner.recoveryScope
15058
+ }));
15059
+ owner.pending.add(request2);
15060
+ let response;
15061
+ try {
15062
+ response = await request2;
15063
+ } finally {
15064
+ owner.pending.delete(request2);
15065
+ }
15066
+ if (!response) {
15067
+ notFound(res, { head });
15068
+ return;
15069
+ }
15070
+ send(res, response.status, JSON.stringify(response.body), {
15071
+ // Rejections may precede body consumption (for example Content-Length
15072
+ // above the limit). Do not reuse a socket containing unread body bytes.
15073
+ ...response.status >= 400 ? { connection: "close" } : {},
15074
+ "content-type": "application/json; charset=utf-8",
15075
+ "cross-origin-resource-policy": "same-origin",
15076
+ "content-security-policy": "default-src 'none'; frame-ancestors 'none'",
15077
+ "x-frame-options": "DENY"
15078
+ }, { head });
15079
+ return;
15080
+ }
15045
15081
  if (segments.length < 3 || segments[0] !== "r" || !safeSessionId(segments[1])) {
15046
15082
  notFound(res, { head });
15047
15083
  return;
@@ -15200,6 +15236,32 @@ function createArtifactReviewServer({
15200
15236
  controlToken,
15201
15237
  instanceId,
15202
15238
  sessionCount: () => sessions.size,
15239
+ /** Trusted local authority only; this operation has no HTTP control route. */
15240
+ registerOwnerSession({ handleRequest } = {}) {
15241
+ if (draining || closePromise || typeof handleRequest !== "function") {
15242
+ throw artifactError(ARTIFACT_ERROR_CODES.LOOPBACK_STATE, "Local owner session cannot be registered.");
15243
+ }
15244
+ const id4 = mintCapabilityToken({ bytes: SESSION_ID_BYTES });
15245
+ const owner = {
15246
+ id: id4,
15247
+ capability: mintCapabilityToken({ bytes: SESSION_TOKEN_BYTES }),
15248
+ recoveryScope: `diagram-owner_${id4}`,
15249
+ handleRequest,
15250
+ pending: /* @__PURE__ */ new Set()
15251
+ };
15252
+ ownerSessions.set(id4, owner);
15253
+ return Object.freeze({
15254
+ sessionId: id4,
15255
+ capability: owner.capability,
15256
+ recoveryScope: owner.recoveryScope,
15257
+ path: `/o/${id4}/${owner.capability}/`,
15258
+ async close() {
15259
+ ownerSessions.delete(id4);
15260
+ await Promise.allSettled([...owner.pending]);
15261
+ if (idle()) scheduleEmpty();
15262
+ }
15263
+ });
15264
+ },
15203
15265
  isIdle: idle,
15204
15266
  accepting: () => !draining && !closePromise,
15205
15267
  beginCloseIfIdle() {
@@ -15224,6 +15286,9 @@ function createArtifactReviewServer({
15224
15286
  emptyTimer = null;
15225
15287
  closePromise = (async () => {
15226
15288
  sessions.clear();
15289
+ const pendingOwners = [...ownerSessions.values()].flatMap((owner) => [...owner.pending]);
15290
+ ownerSessions.clear();
15291
+ await Promise.allSettled(pendingOwners);
15227
15292
  await closeHttpServer(server);
15228
15293
  })();
15229
15294
  return closePromise;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openplanr/protocol",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "description": "Canonical OpenPlanr schemas, registries, typed errors, and portable contract validation",
6
6
  "license": "MIT",
@@ -83,6 +83,10 @@
83
83
  "./enterprise-contracts": {
84
84
  "types": "./src/enterprise-contracts.d.mts",
85
85
  "import": "./src/enterprise-contracts.mjs"
86
+ },
87
+ "./diagram-authoring-contracts": {
88
+ "types": "./src/diagram-authoring-contracts.d.mts",
89
+ "import": "./src/diagram-authoring-contracts.mjs"
86
90
  }
87
91
  },
88
92
  "files": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openplanr",
3
- "version": "2.6.0",
3
+ "version": "2.6.2",
4
4
  "description": "Deterministic OpenPlanr utilities for planning storage, validation, rendering, setup, diagnostics, and GitHub/Linear synchronization",
5
5
  "type": "module",
6
6
  "main": "./dist/cli/index.js",
@@ -115,7 +115,7 @@
115
115
  "zod": "^4.3.6"
116
116
  },
117
117
  "optionalDependencies": {
118
- "planr-pipeline": "0.49.0"
118
+ "planr-pipeline": "0.50.0"
119
119
  },
120
120
  "devDependencies": {
121
121
  "@biomejs/biome": "^2.4.9",