openplanr 2.6.1 → 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.
- package/CHANGELOG.md +15 -0
- package/dist/dashboard/.vite/manifest.json +1 -1
- package/dist/dashboard/assets/{index-BaARCc1f.js → index-AeydhSKa.js} +2 -2
- package/dist/dashboard/assets/{index-BaARCc1f.js.map → index-AeydhSKa.js.map} +1 -1
- package/dist/dashboard/dashboard-manifest.json +8 -8
- package/dist/dashboard/index.html +1 -1
- package/dist/services/diagram-artifact-service.d.ts +20 -0
- package/dist/services/diagram-artifact-service.d.ts.map +1 -1
- package/dist/services/diagram-artifact-service.js +10 -0
- package/dist/services/diagram-artifact-service.js.map +1 -1
- package/lib/host-packages/adapter-registry.json +5 -5
- package/lib/host-packages/capability-map.json +1 -1
- package/lib/host-packages/claude/.claude-plugin/marketplace.json +2 -2
- package/lib/host-packages/claude/openplanr/.claude-plugin/plugin.json +1 -1
- package/lib/host-packages/claude/openplanr/.openplanr-content.json +10 -10
- package/lib/host-packages/claude/openplanr/skills/design/scripts/design.mjs +66 -1
- package/lib/host-packages/claude/openplanr/skills/design/scripts/runtime/packages/protocol/package.json +5 -1
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/design.mjs +66 -1
- package/lib/host-packages/claude/openplanr/skills/design-loop/scripts/runtime/packages/protocol/package.json +5 -1
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/design.mjs +66 -1
- package/lib/host-packages/claude/openplanr/skills/design-review/scripts/runtime/packages/protocol/package.json +5 -1
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/design.mjs +66 -1
- package/lib/host-packages/claude/openplanr/skills/plan/scripts/runtime/packages/protocol/package.json +5 -1
- package/lib/host-packages/cursor/openplanr/.openplanr-content.json +10 -10
- package/lib/host-packages/cursor/openplanr/manifest.json +1 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/design.mjs +66 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design/scripts/runtime/packages/protocol/package.json +5 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/design.mjs +66 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/scripts/runtime/packages/protocol/package.json +5 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/design.mjs +66 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/scripts/runtime/packages/protocol/package.json +5 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/design.mjs +66 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/scripts/runtime/packages/protocol/package.json +5 -1
- package/lib/host-packages/openai/.claude-plugin/marketplace.json +2 -2
- package/lib/host-packages/openai/openplanr/.codex-plugin/plugin.json +1 -1
- package/lib/host-packages/openai/openplanr/.openplanr-content.json +10 -10
- package/lib/host-packages/openai/openplanr/skills/design/scripts/design.mjs +66 -1
- package/lib/host-packages/openai/openplanr/skills/design/scripts/runtime/packages/protocol/package.json +5 -1
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/design.mjs +66 -1
- package/lib/host-packages/openai/openplanr/skills/design-loop/scripts/runtime/packages/protocol/package.json +5 -1
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/design.mjs +66 -1
- package/lib/host-packages/openai/openplanr/skills/design-review/scripts/runtime/packages/protocol/package.json +5 -1
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/design.mjs +66 -1
- package/lib/host-packages/openai/openplanr/skills/plan/scripts/runtime/packages/protocol/package.json +5 -1
- 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.
|
|
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": [
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"files": [
|
|
9
9
|
{
|
|
10
10
|
"path": "manifest.json",
|
|
11
|
-
"digest": "sha256:
|
|
11
|
+
"digest": "sha256:f7632851e45e3b63d23d3a132d6f679209c570dcba4908c8feb462a226b94f5b"
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
14
|
"path": "rules/planr-artifact.mdc",
|
|
@@ -244,7 +244,7 @@
|
|
|
244
244
|
},
|
|
245
245
|
{
|
|
246
246
|
"path": "rules/planr-design-loop/scripts/design.mjs",
|
|
247
|
-
"digest": "sha256:
|
|
247
|
+
"digest": "sha256:e368470cc9863cd20f5d5815c1d1df30a0f8432cbc09160f5b445fdb5420d4be"
|
|
248
248
|
},
|
|
249
249
|
{
|
|
250
250
|
"path": "rules/planr-design-loop/scripts/runtime/notices/entities.txt",
|
|
@@ -292,7 +292,7 @@
|
|
|
292
292
|
},
|
|
293
293
|
{
|
|
294
294
|
"path": "rules/planr-design-loop/scripts/runtime/packages/protocol/package.json",
|
|
295
|
-
"digest": "sha256:
|
|
295
|
+
"digest": "sha256:6e51f9d61b978532cd129f442a4e88f9f3900e58a7239427ec264c34a1337ac3"
|
|
296
296
|
},
|
|
297
297
|
{
|
|
298
298
|
"path": "rules/planr-design-loop/scripts/runtime/packages/protocol/registry/artifact-theme.json",
|
|
@@ -428,7 +428,7 @@
|
|
|
428
428
|
},
|
|
429
429
|
{
|
|
430
430
|
"path": "rules/planr-design-review/scripts/design.mjs",
|
|
431
|
-
"digest": "sha256:
|
|
431
|
+
"digest": "sha256:e368470cc9863cd20f5d5815c1d1df30a0f8432cbc09160f5b445fdb5420d4be"
|
|
432
432
|
},
|
|
433
433
|
{
|
|
434
434
|
"path": "rules/planr-design-review/scripts/runtime/notices/entities.txt",
|
|
@@ -476,7 +476,7 @@
|
|
|
476
476
|
},
|
|
477
477
|
{
|
|
478
478
|
"path": "rules/planr-design-review/scripts/runtime/packages/protocol/package.json",
|
|
479
|
-
"digest": "sha256:
|
|
479
|
+
"digest": "sha256:6e51f9d61b978532cd129f442a4e88f9f3900e58a7239427ec264c34a1337ac3"
|
|
480
480
|
},
|
|
481
481
|
{
|
|
482
482
|
"path": "rules/planr-design-review/scripts/runtime/packages/protocol/registry/artifact-theme.json",
|
|
@@ -612,7 +612,7 @@
|
|
|
612
612
|
},
|
|
613
613
|
{
|
|
614
614
|
"path": "rules/planr-design/scripts/design.mjs",
|
|
615
|
-
"digest": "sha256:
|
|
615
|
+
"digest": "sha256:e368470cc9863cd20f5d5815c1d1df30a0f8432cbc09160f5b445fdb5420d4be"
|
|
616
616
|
},
|
|
617
617
|
{
|
|
618
618
|
"path": "rules/planr-design/scripts/runtime/notices/entities.txt",
|
|
@@ -660,7 +660,7 @@
|
|
|
660
660
|
},
|
|
661
661
|
{
|
|
662
662
|
"path": "rules/planr-design/scripts/runtime/packages/protocol/package.json",
|
|
663
|
-
"digest": "sha256:
|
|
663
|
+
"digest": "sha256:6e51f9d61b978532cd129f442a4e88f9f3900e58a7239427ec264c34a1337ac3"
|
|
664
664
|
},
|
|
665
665
|
{
|
|
666
666
|
"path": "rules/planr-design/scripts/runtime/packages/protocol/registry/artifact-theme.json",
|
|
@@ -828,7 +828,7 @@
|
|
|
828
828
|
},
|
|
829
829
|
{
|
|
830
830
|
"path": "rules/planr-plan/scripts/design.mjs",
|
|
831
|
-
"digest": "sha256:
|
|
831
|
+
"digest": "sha256:e368470cc9863cd20f5d5815c1d1df30a0f8432cbc09160f5b445fdb5420d4be"
|
|
832
832
|
},
|
|
833
833
|
{
|
|
834
834
|
"path": "rules/planr-plan/scripts/planning-ids.mjs",
|
|
@@ -880,7 +880,7 @@
|
|
|
880
880
|
},
|
|
881
881
|
{
|
|
882
882
|
"path": "rules/planr-plan/scripts/runtime/packages/protocol/package.json",
|
|
883
|
-
"digest": "sha256:
|
|
883
|
+
"digest": "sha256:6e51f9d61b978532cd129f442a4e88f9f3900e58a7239427ec264c34a1337ac3"
|
|
884
884
|
},
|
|
885
885
|
{
|
|
886
886
|
"path": "rules/planr-plan/scripts/runtime/packages/protocol/registry/artifact-theme.json",
|
|
@@ -1043,5 +1043,5 @@
|
|
|
1043
1043
|
"digest": "sha256:6378ad3477e4be8b7e916c4249404c50cafecac1c70ffbf5a1a2fce195dfea16"
|
|
1044
1044
|
}
|
|
1045
1045
|
],
|
|
1046
|
-
"contentDigest": "sha256:
|
|
1046
|
+
"contentDigest": "sha256:b90d6456a743b00c5cee7336112e5680c0f991442ab2666d1ad512360513415f"
|
|
1047
1047
|
}
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
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": [
|