@playcraft/cli 0.1.19 → 0.1.21
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.
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
const LOCAL_ATTR = /<(?:script|img|link|source|video|audio|iframe)\b[^>]*?\b(?:src|href)\s*=\s*["']([^"']+)["']/gi;
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/** A CSS `url(`, not the tail of a name such as `createObjectURL(` or `getAudioURL(`. */
|
|
3
|
+
const CSS_URL = /(?<![\w$.-])url\(\s*["']?([^"')]+)["']?\s*\)/gi;
|
|
4
|
+
/** An inline script's body, kept apart from its tag so `<script src>` is still checked. */
|
|
5
|
+
const SCRIPT_BODY = /(<script\b[^>]*>)[\s\S]*?(<\/script\s*>)/gi;
|
|
6
|
+
/**
|
|
7
|
+
* A reference the sealed document would load from the local build, not from the network or inline
|
|
8
|
+
* data. Inline script code is not read: inlined libraries call functions named `…URL(` and build
|
|
9
|
+
* `"url(" + src + ")"` strings at run time, and neither is a file the document loads.
|
|
10
|
+
*/
|
|
4
11
|
export function findExternalLocalReferences(html) {
|
|
12
|
+
const markup = html.replace(SCRIPT_BODY, '$1$2');
|
|
5
13
|
const found = new Set();
|
|
6
14
|
for (const expression of [LOCAL_ATTR, CSS_URL]) {
|
|
7
15
|
expression.lastIndex = 0;
|
|
8
|
-
for (const match of
|
|
16
|
+
for (const match of markup.matchAll(expression)) {
|
|
9
17
|
const value = (match[1] ?? '').trim();
|
|
10
18
|
if (isLocalReference(value))
|
|
11
19
|
found.add(value);
|
|
@@ -246,11 +246,15 @@ async function executeTurn(state, scopeKey, operation, payload, recovery) {
|
|
|
246
246
|
const reserved = state.journal.getOperation(scopeKey) ?? operation;
|
|
247
247
|
if (result.outcome === 'uncertain' || result.outcome === 'failed' || !result.turnId) {
|
|
248
248
|
const failed = result.outcome === 'failed';
|
|
249
|
+
// Codex no longer knows the thread although the binding said it could continue. Marking the
|
|
250
|
+
// binding lost lets the same turn, sent again with the conversation, rebind the session.
|
|
251
|
+
const threadLost = failed && result.error === 'unknown_thread';
|
|
249
252
|
await state.journal.putSession({
|
|
250
253
|
...(state.journal.getSession(sessionId) ?? binding),
|
|
251
254
|
turnStatus: failed ? undefined : 'starting',
|
|
252
255
|
turnBlock: failed ? undefined : 'uncertain',
|
|
253
256
|
activeTurnId: undefined,
|
|
257
|
+
...(threadLost ? { recoverability: 'history_only' } : {}),
|
|
254
258
|
});
|
|
255
259
|
return persist(state, scopeKey, transitionOperation(reserved, failed ? 'failed' : 'uncertain', {
|
|
256
260
|
error: result.outcome === 'failed' ? result.error : 'native_receipt_lost',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readObservedFile, withObservedFile } from '../workspaces/revisions.js';
|
|
2
2
|
import { registerWorkspace, revisionScope, workspaceRoot, WorkspaceContextError } from '../workspaces/registry.js';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
|
-
import { workspaceRegistrationRequestSchema, HTTP_STATUS_BY_ERROR, assertLeaseFence, buildHandshakeDocument, capability, findUntrustedRuntimeFields, gitFileRefSchema, hashOperationPayload, sourceAckSchema, operationAcceptRequestSchema, operationKindSchema, operationScopeKey, resolveIdempotentAccept, nativeHistoryReadSchema, runtimeError, runtimeConnectivityDocumentSchema, unavailableRuntimeCapabilities, } from '@playcraft/common/cloud-workspace/runtime';
|
|
4
|
+
import { workspaceRegistrationRequestSchema, HTTP_STATUS_BY_ERROR, assertLeaseFence, buildHandshakeDocument, capability, findUntrustedRuntimeFields, gitFileRefSchema, hashOperationPayload, isLostThreadError, sourceAckSchema, operationAcceptRequestSchema, operationKindSchema, operationScopeKey, resolveIdempotentAccept, nativeHistoryReadSchema, runtimeError, runtimeConnectivityDocumentSchema, unavailableRuntimeCapabilities, } from '@playcraft/common/cloud-workspace/runtime';
|
|
5
5
|
import { controlTokenMatches, extractControlToken } from './auth.js';
|
|
6
6
|
import { applyRuntimeEndpointPatch } from './endpoints.js';
|
|
7
7
|
import { canExecuteKind, executeOperation } from './dispatch.js';
|
|
@@ -383,7 +383,12 @@ async function acceptOperation(state, request, response) {
|
|
|
383
383
|
}));
|
|
384
384
|
return;
|
|
385
385
|
}
|
|
386
|
-
|
|
386
|
+
// A turn refused for a lost thread never reached Codex. Sent again with the conversation, it
|
|
387
|
+
// runs afresh under the same request, so the message is shown and answered only once.
|
|
388
|
+
const retryWithRecovery = decision.action === 'reuse' && parsed.data.kind === 'session.turn'
|
|
389
|
+
&& Boolean(parsed.data.sessionRecovery) && decision.operation.status === 'failed'
|
|
390
|
+
&& isLostThreadError(decision.operation.error);
|
|
391
|
+
if (decision.action === 'reuse' && !retryWithRecovery) {
|
|
387
392
|
if (decision.operation.status === 'uncertain') {
|
|
388
393
|
writeError(response, runtimeError('uncertain_operation', decision.operation.error ?? 'native_receipt_lost', {
|
|
389
394
|
operationId: decision.operation.operationId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playcraft/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"@gltf-transform/core": "^4.3.0",
|
|
49
49
|
"@gltf-transform/extensions": "^4.3.0",
|
|
50
50
|
"@gltf-transform/functions": "^4.3.0",
|
|
51
|
-
"@playcraft/build": "^0.1.
|
|
52
|
-
"@playcraft/common": "^0.1.
|
|
51
|
+
"@playcraft/build": "^0.1.21",
|
|
52
|
+
"@playcraft/common": "^0.1.21",
|
|
53
53
|
"better-sqlite3-pinned": "npm:better-sqlite3@13.0.3",
|
|
54
54
|
"chokidar": "^4.0.3",
|
|
55
55
|
"commander": "^13.1.0",
|