@pellux/goodvibes-sdk 1.0.0 → 1.2.0
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/contracts/artifacts/operator-contract.json +2878 -264
- package/dist/events/communication.d.ts +1 -1
- package/dist/platform/agents/orchestrator-runner.d.ts +5 -5
- package/dist/platform/agents/orchestrator-runner.js +6 -6
- package/dist/platform/agents/orchestrator.d.ts +4 -4
- package/dist/platform/agents/orchestrator.js +2 -2
- package/dist/platform/agents/wrfc-controller.d.ts +1 -1
- package/dist/platform/agents/wrfc-controller.js +3 -3
- package/dist/platform/calendar/index.d.ts +2 -2
- package/dist/platform/calendar/index.js +3 -3
- package/dist/platform/calendar/oauth-providers.d.ts +1 -1
- package/dist/platform/calendar/oauth-providers.js +1 -1
- package/dist/platform/calendar/oauth-types.d.ts +1 -1
- package/dist/platform/calendar/oauth-types.js +1 -1
- package/dist/platform/companion/companion-chat-branching.d.ts +66 -0
- package/dist/platform/companion/companion-chat-branching.d.ts.map +1 -0
- package/dist/platform/companion/companion-chat-branching.js +142 -0
- package/dist/platform/companion/companion-chat-broker-bridge.d.ts +1 -1
- package/dist/platform/companion/companion-chat-broker-bridge.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-broker-sync.d.ts +2 -2
- package/dist/platform/companion/companion-chat-broker-sync.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-broker-sync.js +1 -1
- package/dist/platform/companion/companion-chat-manager.d.ts +26 -5
- package/dist/platform/companion/companion-chat-manager.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-manager.js +67 -81
- package/dist/platform/companion/companion-chat-routes.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-routes.js +77 -1
- package/dist/platform/companion/companion-chat-turn-execution.d.ts +61 -0
- package/dist/platform/companion/companion-chat-turn-execution.d.ts.map +1 -0
- package/dist/platform/companion/companion-chat-turn-execution.js +107 -0
- package/dist/platform/companion/companion-chat-types.d.ts +67 -0
- package/dist/platform/companion/companion-chat-types.d.ts.map +1 -1
- package/dist/platform/config/credential-status.d.ts +1 -1
- package/dist/platform/config/credential-status.js +1 -1
- package/dist/platform/config/index.d.ts +1 -1
- package/dist/platform/config/index.js +1 -1
- package/dist/platform/config/manager.d.ts +1 -1
- package/dist/platform/config/manager.js +1 -1
- package/dist/platform/config/migrations.d.ts +2 -2
- package/dist/platform/config/migrations.js +2 -2
- package/dist/platform/config/schema-domain-runtime.d.ts +8 -0
- package/dist/platform/config/schema-domain-runtime.d.ts.map +1 -1
- package/dist/platform/config/schema-domain-runtime.js +32 -0
- package/dist/platform/config/schema-types.d.ts +10 -2
- package/dist/platform/config/schema-types.d.ts.map +1 -1
- package/dist/platform/control-plane/gateway-scope-enforcement.js +2 -2
- package/dist/platform/control-plane/index.d.ts +2 -0
- package/dist/platform/control-plane/index.d.ts.map +1 -1
- package/dist/platform/control-plane/index.js +5 -1
- package/dist/platform/control-plane/invoke-input-validation.d.ts +1 -1
- package/dist/platform/control-plane/invoke-input-validation.js +1 -1
- package/dist/platform/control-plane/method-catalog-calendar.d.ts +2 -2
- package/dist/platform/control-plane/method-catalog-calendar.js +2 -2
- package/dist/platform/control-plane/method-catalog-channels.js +3 -3
- package/dist/platform/control-plane/method-catalog-control-automation.js +4 -4
- package/dist/platform/control-plane/method-catalog-control-companion.d.ts +1 -1
- package/dist/platform/control-plane/method-catalog-control-companion.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-control-companion.js +43 -0
- package/dist/platform/control-plane/method-catalog-control-core.js +3 -3
- package/dist/platform/control-plane/method-catalog-email.d.ts +1 -1
- package/dist/platform/control-plane/method-catalog-email.js +1 -1
- package/dist/platform/control-plane/method-catalog-fleet.d.ts +1 -1
- package/dist/platform/control-plane/method-catalog-push.d.ts +30 -0
- package/dist/platform/control-plane/method-catalog-push.d.ts.map +1 -0
- package/dist/platform/control-plane/method-catalog-push.js +80 -0
- package/dist/platform/control-plane/method-catalog-route-reconcile.d.ts +1 -1
- package/dist/platform/control-plane/method-catalog-runtime.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-runtime.js +177 -1
- package/dist/platform/control-plane/method-catalog.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog.js +2 -0
- package/dist/platform/control-plane/operator-contract-schemas-fleet.js +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts +15 -0
- package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-runtime.js +81 -0
- package/dist/platform/control-plane/routes/checkpoints.d.ts +1 -1
- package/dist/platform/control-plane/routes/fleet.d.ts +2 -2
- package/dist/platform/control-plane/routes/fleet.js +1 -1
- package/dist/platform/control-plane/routes/gateway-verb-error.d.ts +1 -1
- package/dist/platform/control-plane/routes/gateway-verb-error.js +1 -1
- package/dist/platform/control-plane/routes/index.js +1 -1
- package/dist/platform/control-plane/routes/invocation-params.d.ts +1 -1
- package/dist/platform/control-plane/routes/push.d.ts +26 -0
- package/dist/platform/control-plane/routes/push.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/push.js +104 -0
- package/dist/platform/control-plane/routes/register-gateway-verb-groups.d.ts +31 -0
- package/dist/platform/control-plane/routes/register-gateway-verb-groups.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/register-gateway-verb-groups.js +16 -0
- package/dist/platform/control-plane/routes/register-w3-s2.d.ts +2 -2
- package/dist/platform/control-plane/routes/session-search.d.ts +4 -4
- package/dist/platform/control-plane/session-broker.d.ts +1 -1
- package/dist/platform/control-plane/session-broker.js +1 -1
- package/dist/platform/control-plane/session-store-importer.d.ts +1 -1
- package/dist/platform/control-plane/session-store-importer.js +1 -1
- package/dist/platform/control-plane/session-types.d.ts +1 -1
- package/dist/platform/core/orchestrator-runtime.d.ts +4 -4
- package/dist/platform/core/orchestrator-tool-runtime.d.ts +1 -1
- package/dist/platform/core/orchestrator-turn-loop.d.ts +6 -6
- package/dist/platform/core/orchestrator-turn-loop.d.ts.map +1 -1
- package/dist/platform/core/orchestrator-turn-loop.js +23 -22
- package/dist/platform/core/orchestrator.d.ts +10 -10
- package/dist/platform/core/orchestrator.d.ts.map +1 -1
- package/dist/platform/core/orchestrator.js +8 -8
- package/dist/platform/daemon/boot.d.ts +6 -0
- package/dist/platform/daemon/boot.d.ts.map +1 -1
- package/dist/platform/daemon/boot.js +1 -0
- package/dist/platform/daemon/control-plane.js +2 -2
- package/dist/platform/daemon/facade.d.ts +4 -7
- package/dist/platform/daemon/facade.d.ts.map +1 -1
- package/dist/platform/daemon/facade.js +5 -7
- package/dist/platform/daemon/http/router-session-broker-adapter.d.ts +1 -1
- package/dist/platform/daemon/http/router.d.ts +1 -0
- package/dist/platform/daemon/http/router.d.ts.map +1 -1
- package/dist/platform/daemon/http/router.js +36 -19
- package/dist/platform/daemon/http/runtime-route-types.d.ts +1 -1
- package/dist/platform/daemon/http/runtime-route-types.d.ts.map +1 -1
- package/dist/platform/daemon/http/webui-serving.d.ts +68 -0
- package/dist/platform/daemon/http/webui-serving.d.ts.map +1 -0
- package/dist/platform/daemon/http/webui-serving.js +230 -0
- package/dist/platform/knowledge/knowledge-api.d.ts +1 -1
- package/dist/platform/orchestration/budget.d.ts +2 -2
- package/dist/platform/orchestration/cancellation.d.ts +2 -2
- package/dist/platform/orchestration/controller-compat.d.ts +2 -3
- package/dist/platform/orchestration/controller-compat.d.ts.map +1 -1
- package/dist/platform/orchestration/dirty-guard.js +1 -1
- package/dist/platform/orchestration/engine.d.ts.map +1 -1
- package/dist/platform/orchestration/engine.js +3 -4
- package/dist/platform/orchestration/persistence.js +2 -2
- package/dist/platform/orchestration/phase-runner.d.ts +4 -4
- package/dist/platform/orchestration/scheduler.d.ts +1 -1
- package/dist/platform/orchestration/types.d.ts +3 -3
- package/dist/platform/presentation/glyphs.d.ts +1 -1
- package/dist/platform/presentation/glyphs.js +1 -1
- package/dist/platform/presentation/index.d.ts +3 -3
- package/dist/platform/presentation/index.js +3 -3
- package/dist/platform/presentation/thinking-phrases.d.ts +1 -1
- package/dist/platform/presentation/thinking-phrases.js +1 -1
- package/dist/platform/presentation/waiting-wording.d.ts +1 -1
- package/dist/platform/presentation/waiting-wording.js +1 -1
- package/dist/platform/push/delivery.d.ts +48 -0
- package/dist/platform/push/delivery.d.ts.map +1 -0
- package/dist/platform/push/delivery.js +117 -0
- package/dist/platform/push/encryption.d.ts +41 -0
- package/dist/platform/push/encryption.d.ts.map +1 -0
- package/dist/platform/push/encryption.js +82 -0
- package/dist/platform/push/index.d.ts +17 -0
- package/dist/platform/push/index.d.ts.map +1 -0
- package/dist/platform/push/index.js +10 -0
- package/dist/platform/push/service.d.ts +75 -0
- package/dist/platform/push/service.d.ts.map +1 -0
- package/dist/platform/push/service.js +95 -0
- package/dist/platform/push/subscription-store.d.ts +50 -0
- package/dist/platform/push/subscription-store.d.ts.map +1 -0
- package/dist/platform/push/subscription-store.js +123 -0
- package/dist/platform/push/types.d.ts +68 -0
- package/dist/platform/push/types.d.ts.map +1 -0
- package/dist/platform/push/types.js +13 -0
- package/dist/platform/push/vapid.d.ts +54 -0
- package/dist/platform/push/vapid.d.ts.map +1 -0
- package/dist/platform/push/vapid.js +113 -0
- package/dist/platform/runtime/feature-flags/flags.js +3 -3
- package/dist/platform/runtime/fleet/adapters/agent.d.ts +2 -2
- package/dist/platform/runtime/fleet/adapters/agent.d.ts.map +1 -1
- package/dist/platform/runtime/fleet/adapters/agent.js +4 -4
- package/dist/platform/runtime/fleet/adapters/automation.d.ts +1 -1
- package/dist/platform/runtime/fleet/adapters/automation.js +1 -1
- package/dist/platform/runtime/fleet/adapters/code-index.d.ts +1 -1
- package/dist/platform/runtime/fleet/adapters/code-index.js +1 -1
- package/dist/platform/runtime/fleet/adapters/orchestration.js +1 -1
- package/dist/platform/runtime/fleet/adapters/schedule.d.ts +4 -4
- package/dist/platform/runtime/fleet/adapters/schedule.js +4 -4
- package/dist/platform/runtime/fleet/adapters/trigger.d.ts +3 -4
- package/dist/platform/runtime/fleet/adapters/trigger.d.ts.map +1 -1
- package/dist/platform/runtime/fleet/adapters/trigger.js +3 -4
- package/dist/platform/runtime/fleet/adapters/wrfc.js +1 -1
- package/dist/platform/runtime/fleet/registry.d.ts +7 -7
- package/dist/platform/runtime/fleet/registry.d.ts.map +1 -1
- package/dist/platform/runtime/fleet/registry.js +3 -3
- package/dist/platform/runtime/fleet/types.d.ts +9 -9
- package/dist/platform/runtime/fleet/types.d.ts.map +1 -1
- package/dist/platform/runtime/memory-spine/client.d.ts +240 -0
- package/dist/platform/runtime/memory-spine/client.d.ts.map +1 -0
- package/dist/platform/runtime/memory-spine/client.js +221 -0
- package/dist/platform/runtime/memory-spine/index.d.ts +17 -0
- package/dist/platform/runtime/memory-spine/index.d.ts.map +1 -0
- package/dist/platform/runtime/memory-spine/index.js +16 -0
- package/dist/platform/runtime/memory-spine/recall-snapshot.d.ts +74 -0
- package/dist/platform/runtime/memory-spine/recall-snapshot.d.ts.map +1 -0
- package/dist/platform/runtime/memory-spine/recall-snapshot.js +74 -0
- package/dist/platform/runtime/operator-client.d.ts +1 -1
- package/dist/platform/runtime/services.d.ts +6 -6
- package/dist/platform/runtime/services.d.ts.map +1 -1
- package/dist/platform/runtime/services.js +9 -9
- package/dist/platform/runtime/session-spine/union-cache.d.ts +1 -1
- package/dist/platform/runtime/session-spine/union-cache.js +1 -1
- package/dist/platform/state/canonical-memory.d.ts +7 -7
- package/dist/platform/state/canonical-memory.js +8 -8
- package/dist/platform/state/code-index-chunking.js +1 -1
- package/dist/platform/state/code-index-db.d.ts +1 -1
- package/dist/platform/state/code-index-store.js +1 -1
- package/dist/platform/state/index.d.ts +2 -2
- package/dist/platform/state/index.d.ts.map +1 -1
- package/dist/platform/state/index.js +1 -1
- package/dist/platform/state/memory-recall-contract.d.ts +59 -4
- package/dist/platform/state/memory-recall-contract.d.ts.map +1 -1
- package/dist/platform/state/memory-recall-contract.js +79 -3
- package/dist/platform/state/memory-registry.d.ts +8 -0
- package/dist/platform/state/memory-registry.d.ts.map +1 -1
- package/dist/platform/state/memory-registry.js +10 -0
- package/dist/platform/state/memory-vector-store.js +1 -1
- package/dist/platform/state/sqlite-vec-loader.d.ts +1 -1
- package/dist/platform/state/sqlite-vec-loader.js +1 -1
- package/dist/platform/state/vibe-projection.d.ts +3 -3
- package/dist/platform/state/vibe-projection.js +3 -3
- package/dist/platform/tools/agent/manager.d.ts +10 -10
- package/dist/platform/tools/agent/manager.js +7 -7
- package/dist/platform/tools/exec/runtime.js +5 -5
- package/dist/platform/tools/exec/schema.d.ts +1 -1
- package/dist/platform/tools/exec/schema.d.ts.map +1 -1
- package/dist/platform/tools/fetch/runtime.d.ts +1 -1
- package/dist/platform/tools/registry.d.ts +1 -1
- package/dist/platform/tools/registry.js +1 -1
- package/dist/platform/types/tools.d.ts +1 -1
- package/dist/platform/utils/request-body.d.ts.map +1 -1
- package/dist/platform/utils/request-body.js +50 -5
- package/dist/platform/version.js +1 -1
- package/dist/platform/voice/index.d.ts +2 -0
- package/dist/platform/voice/index.d.ts.map +1 -1
- package/dist/platform/voice/index.js +3 -0
- package/dist/platform/voice/spoken-turn/audio-sink.d.ts +111 -0
- package/dist/platform/voice/spoken-turn/audio-sink.d.ts.map +1 -0
- package/dist/platform/voice/spoken-turn/audio-sink.js +1 -0
- package/dist/platform/voice/spoken-turn/controller.d.ts +117 -0
- package/dist/platform/voice/spoken-turn/controller.d.ts.map +1 -0
- package/dist/platform/voice/spoken-turn/controller.js +448 -0
- package/dist/platform/voice/spoken-turn/index.d.ts +16 -0
- package/dist/platform/voice/spoken-turn/index.d.ts.map +1 -0
- package/dist/platform/voice/spoken-turn/index.js +12 -0
- package/dist/platform/voice/spoken-turn/text-chunker.d.ts +33 -0
- package/dist/platform/voice/spoken-turn/text-chunker.d.ts.map +1 -0
- package/dist/platform/voice/spoken-turn/text-chunker.js +97 -0
- package/package.json +13 -9
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* webui-serving.ts
|
|
3
|
+
*
|
|
4
|
+
* Two opt-in capabilities that let a browser-hosted web UI reach the daemon:
|
|
5
|
+
*
|
|
6
|
+
* 1. Same-origin bundle serving (PRIMARY). When `controlPlane.webui.serve` is
|
|
7
|
+
* on, the daemon serves a configured build directory at `/` so the bundle
|
|
8
|
+
* and the API share an origin — the browser's same-origin policy is then a
|
|
9
|
+
* non-issue. This is wire-compatible with `tailscale serve`, which fronts
|
|
10
|
+
* the single daemon origin over HTTPS: bundle + API arrive same-origin.
|
|
11
|
+
* The bundle is public (served without a token); the app itself
|
|
12
|
+
* token-authenticates its API calls, so no wire data leaks from serving
|
|
13
|
+
* static files.
|
|
14
|
+
*
|
|
15
|
+
* 2. Cross-origin request support (SECONDARY). When `controlPlane.cors.enabled`
|
|
16
|
+
* is on, OPTIONS preflight is answered and Access-Control-Allow-* headers
|
|
17
|
+
* are emitted ONLY for origins on the explicit `controlPlane.cors.allowedOrigins`
|
|
18
|
+
* allowlist (the Vite dev server, a deliberately separate origin, etc.).
|
|
19
|
+
* There is no wildcard: the matched origin is echoed back, credentials are
|
|
20
|
+
* allowlist-gated, and `Vary: Origin` is always set so caches stay correct.
|
|
21
|
+
*
|
|
22
|
+
* BOTH default OFF. With both off the daemon behaves exactly as before: no bundle
|
|
23
|
+
* is served and no Access-Control-Allow-Origin is ever emitted. The loopback
|
|
24
|
+
* default posture is unchanged; these capabilities are explicit opt-ins, never
|
|
25
|
+
* auto-enabled by network host mode.
|
|
26
|
+
*/
|
|
27
|
+
import { resolve, sep } from 'node:path';
|
|
28
|
+
import { readStringList } from '../helpers.js';
|
|
29
|
+
function readConfig(configManager, key) {
|
|
30
|
+
const getter = configManager.get;
|
|
31
|
+
return typeof getter === 'function' ? getter.call(configManager, key) : undefined;
|
|
32
|
+
}
|
|
33
|
+
/** Read the current serving posture from config. Cheap; called per request. */
|
|
34
|
+
export function resolveWebuiServingPosture(configManager) {
|
|
35
|
+
const serveBundle = readConfig(configManager, 'controlPlane.webui.serve') === true;
|
|
36
|
+
const bundleDirRaw = readConfig(configManager, 'controlPlane.webui.bundleDir');
|
|
37
|
+
const corsEnabled = readConfig(configManager, 'controlPlane.cors.enabled') === true;
|
|
38
|
+
const allowedOrigins = readStringList(readConfig(configManager, 'controlPlane.cors.allowedOrigins')) ?? [];
|
|
39
|
+
const openaiPrefixRaw = readConfig(configManager, 'controlPlane.openaiCompatible.pathPrefix');
|
|
40
|
+
return {
|
|
41
|
+
serveBundle,
|
|
42
|
+
bundleDir: typeof bundleDirRaw === 'string' ? bundleDirRaw.trim() : '',
|
|
43
|
+
cors: { enabled: corsEnabled, allowedOrigins },
|
|
44
|
+
openaiPathPrefix: typeof openaiPrefixRaw === 'string' && openaiPrefixRaw.trim() ? openaiPrefixRaw.trim() : '/v1',
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// CORS (secondary path)
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
/** Append a token to an existing Vary header without duplicating it. */
|
|
51
|
+
function appendVary(existing, token) {
|
|
52
|
+
if (!existing)
|
|
53
|
+
return token;
|
|
54
|
+
const parts = existing.split(',').map((p) => p.trim()).filter(Boolean);
|
|
55
|
+
if (parts.some((p) => p.toLowerCase() === token.toLowerCase()))
|
|
56
|
+
return existing;
|
|
57
|
+
return [...parts, token].join(', ');
|
|
58
|
+
}
|
|
59
|
+
/** True when the origin is on the explicit allowlist (exact match, no wildcard). */
|
|
60
|
+
function isOriginAllowed(origin, allowlist) {
|
|
61
|
+
return allowlist.includes(origin);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Answer a CORS preflight (OPTIONS). Emits Access-Control-Allow-* only for an
|
|
65
|
+
* allowlisted origin; a non-allowlisted origin is refused honestly (403, no
|
|
66
|
+
* Access-Control-Allow-Origin) so the browser preflight fails cleanly.
|
|
67
|
+
*/
|
|
68
|
+
export function handleCorsPreflight(req, posture) {
|
|
69
|
+
const origin = req.headers.get('origin');
|
|
70
|
+
// A preflight with no Origin is not a browser CORS preflight — answer 204 with
|
|
71
|
+
// no allow-origin (nothing to grant); never emit a wildcard.
|
|
72
|
+
if (origin === null) {
|
|
73
|
+
return new Response(null, { status: 204, headers: { Vary: 'Origin' } });
|
|
74
|
+
}
|
|
75
|
+
if (!isOriginAllowed(origin, posture.cors.allowedOrigins)) {
|
|
76
|
+
return Response.json({ error: 'ORIGIN_NOT_ALLOWED', code: 'ORIGIN_NOT_ALLOWED', message: 'Origin is not on controlPlane.cors.allowedOrigins.' }, { status: 403, headers: { Vary: 'Origin' } });
|
|
77
|
+
}
|
|
78
|
+
// Echo the requested headers when present, otherwise a safe default that always
|
|
79
|
+
// includes Authorization so the bearer-token API flow works cross-origin.
|
|
80
|
+
const requestedHeaders = req.headers.get('access-control-request-headers');
|
|
81
|
+
const allowHeaders = requestedHeaders && requestedHeaders.trim()
|
|
82
|
+
? requestedHeaders
|
|
83
|
+
: 'Authorization, Content-Type';
|
|
84
|
+
return new Response(null, {
|
|
85
|
+
status: 204,
|
|
86
|
+
headers: {
|
|
87
|
+
'Access-Control-Allow-Origin': origin,
|
|
88
|
+
'Access-Control-Allow-Credentials': 'true',
|
|
89
|
+
'Access-Control-Allow-Methods': 'GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS',
|
|
90
|
+
'Access-Control-Allow-Headers': allowHeaders,
|
|
91
|
+
'Access-Control-Max-Age': '600',
|
|
92
|
+
Vary: 'Origin',
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Decorate an actual (non-preflight) response with CORS headers when the request
|
|
98
|
+
* carries an allowlisted Origin. `Vary: Origin` is always added while CORS is
|
|
99
|
+
* enabled so caches never serve an allow-origin to the wrong origin. A
|
|
100
|
+
* non-allowlisted origin gets Vary but NO Access-Control-Allow-Origin — the
|
|
101
|
+
* browser then blocks the read honestly.
|
|
102
|
+
*/
|
|
103
|
+
export function applyCorsHeaders(req, response, posture) {
|
|
104
|
+
const origin = req.headers.get('origin');
|
|
105
|
+
if (origin === null)
|
|
106
|
+
return response;
|
|
107
|
+
const headers = new Headers(response.headers);
|
|
108
|
+
headers.set('Vary', appendVary(headers.get('Vary'), 'Origin'));
|
|
109
|
+
if (isOriginAllowed(origin, posture.cors.allowedOrigins)) {
|
|
110
|
+
headers.set('Access-Control-Allow-Origin', origin);
|
|
111
|
+
headers.set('Access-Control-Allow-Credentials', 'true');
|
|
112
|
+
}
|
|
113
|
+
return new Response(response.body, { status: response.status, statusText: response.statusText, headers });
|
|
114
|
+
}
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// Static bundle serving (primary path)
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
/** Extension → content type for the common web-bundle asset kinds. */
|
|
119
|
+
const CONTENT_TYPES = {
|
|
120
|
+
html: 'text/html; charset=utf-8',
|
|
121
|
+
js: 'text/javascript; charset=utf-8',
|
|
122
|
+
mjs: 'text/javascript; charset=utf-8',
|
|
123
|
+
css: 'text/css; charset=utf-8',
|
|
124
|
+
json: 'application/json; charset=utf-8',
|
|
125
|
+
map: 'application/json; charset=utf-8',
|
|
126
|
+
svg: 'image/svg+xml',
|
|
127
|
+
png: 'image/png',
|
|
128
|
+
jpg: 'image/jpeg',
|
|
129
|
+
jpeg: 'image/jpeg',
|
|
130
|
+
gif: 'image/gif',
|
|
131
|
+
webp: 'image/webp',
|
|
132
|
+
avif: 'image/avif',
|
|
133
|
+
ico: 'image/x-icon',
|
|
134
|
+
woff: 'font/woff',
|
|
135
|
+
woff2: 'font/woff2',
|
|
136
|
+
ttf: 'font/ttf',
|
|
137
|
+
wasm: 'application/wasm',
|
|
138
|
+
txt: 'text/plain; charset=utf-8',
|
|
139
|
+
webmanifest: 'application/manifest+json',
|
|
140
|
+
};
|
|
141
|
+
function extensionOf(pathname) {
|
|
142
|
+
const base = pathname.slice(pathname.lastIndexOf('/') + 1);
|
|
143
|
+
const dot = base.lastIndexOf('.');
|
|
144
|
+
return dot > 0 ? base.slice(dot + 1).toLowerCase() : '';
|
|
145
|
+
}
|
|
146
|
+
function contentTypeFor(pathname) {
|
|
147
|
+
return CONTENT_TYPES[extensionOf(pathname)] ?? 'application/octet-stream';
|
|
148
|
+
}
|
|
149
|
+
/** True when a path belongs to the daemon API/route surface and must never be
|
|
150
|
+
* served as a static file (API routes keep precedence). Boundary-aware so a SPA
|
|
151
|
+
* route like `/tasks` is not mistaken for the daemon's `/task` route. */
|
|
152
|
+
function isReservedApiPath(pathname, openaiPrefix) {
|
|
153
|
+
const reserved = ['/api', '/login', '/webhook', '/task', openaiPrefix];
|
|
154
|
+
return reserved.some((base) => pathname === base || pathname.startsWith(`${base}/`));
|
|
155
|
+
}
|
|
156
|
+
/** True when the request looks like an SPA navigation (HTML document) rather than
|
|
157
|
+
* a fetch for a concrete asset — used to decide whether the index.html fallback
|
|
158
|
+
* applies. A missing concrete asset must 404, not return the HTML shell. */
|
|
159
|
+
function isNavigationRequest(req, pathname) {
|
|
160
|
+
if (extensionOf(pathname) === '')
|
|
161
|
+
return true;
|
|
162
|
+
return (req.headers.get('accept') ?? '').includes('text/html');
|
|
163
|
+
}
|
|
164
|
+
function cacheControlFor(pathname, isShell) {
|
|
165
|
+
if (isShell || extensionOf(pathname) === 'html')
|
|
166
|
+
return 'no-cache';
|
|
167
|
+
if (pathname.includes('/assets/'))
|
|
168
|
+
return 'public, max-age=31536000, immutable';
|
|
169
|
+
return 'public, max-age=3600';
|
|
170
|
+
}
|
|
171
|
+
async function fileResponse(req, file, pathname, isShell) {
|
|
172
|
+
const headers = {
|
|
173
|
+
'Content-Type': contentTypeFor(pathname),
|
|
174
|
+
'Cache-Control': cacheControlFor(pathname, isShell),
|
|
175
|
+
};
|
|
176
|
+
if (req.method === 'HEAD') {
|
|
177
|
+
const size = await file.size;
|
|
178
|
+
return new Response(null, { status: 200, headers: { ...headers, 'Content-Length': String(size) } });
|
|
179
|
+
}
|
|
180
|
+
return new Response(file, { status: 200, headers });
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Serve a file from the configured bundle directory, with SPA fallback to
|
|
184
|
+
* index.html for navigation routes. Returns null when serving is disabled, the
|
|
185
|
+
* request is not a GET/HEAD, or the path is a reserved API route — in every
|
|
186
|
+
* "null" case the caller continues with normal daemon routing, so behavior is
|
|
187
|
+
* unchanged when the capability is off. Path traversal outside the bundle
|
|
188
|
+
* directory is refused with 403.
|
|
189
|
+
*/
|
|
190
|
+
export async function serveWebuiBundle(req, posture) {
|
|
191
|
+
if (!posture.serveBundle || !posture.bundleDir)
|
|
192
|
+
return null;
|
|
193
|
+
if (req.method !== 'GET' && req.method !== 'HEAD')
|
|
194
|
+
return null;
|
|
195
|
+
const url = new URL(req.url);
|
|
196
|
+
let pathname;
|
|
197
|
+
try {
|
|
198
|
+
pathname = decodeURIComponent(url.pathname);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
return new Response('Bad Request', { status: 400 });
|
|
202
|
+
}
|
|
203
|
+
if (pathname.includes('\0'))
|
|
204
|
+
return new Response('Bad Request', { status: 400 });
|
|
205
|
+
if (isReservedApiPath(pathname, posture.openaiPathPrefix))
|
|
206
|
+
return null;
|
|
207
|
+
const root = resolve(posture.bundleDir);
|
|
208
|
+
const relative = pathname === '/' ? 'index.html' : pathname.replace(/^\/+/, '');
|
|
209
|
+
const resolved = resolve(root, relative);
|
|
210
|
+
// Reject anything that escapes the bundle root (path traversal).
|
|
211
|
+
if (resolved !== root && !resolved.startsWith(root + sep)) {
|
|
212
|
+
return new Response('Forbidden', { status: 403 });
|
|
213
|
+
}
|
|
214
|
+
const file = Bun.file(resolved);
|
|
215
|
+
if (await file.exists()) {
|
|
216
|
+
const isShell = resolved === resolve(root, 'index.html');
|
|
217
|
+
// Derive the content type from the resolved file path, not the request path —
|
|
218
|
+
// a `GET /` serves index.html and must answer text/html, not octet-stream.
|
|
219
|
+
return fileResponse(req, file, resolved, isShell);
|
|
220
|
+
}
|
|
221
|
+
// SPA fallback: an unknown navigation route serves the app shell; a missing
|
|
222
|
+
// concrete asset is an honest 404 (never the HTML shell in a JS/CSS request).
|
|
223
|
+
if (isNavigationRequest(req, pathname)) {
|
|
224
|
+
const indexFile = Bun.file(resolve(root, 'index.html'));
|
|
225
|
+
if (await indexFile.exists()) {
|
|
226
|
+
return fileResponse(req, indexFile, '/index.html', true);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return new Response('Not Found', { status: 404 });
|
|
230
|
+
}
|
|
@@ -75,7 +75,7 @@ export interface MemoryApi {
|
|
|
75
75
|
export type MemoryApiRegistry = Pick<MemoryRegistry, 'add' | 'doctor' | 'delete' | 'exportBundle' | 'get' | 'getAll' | 'importBundle' | 'link' | 'linksFor' | 'rebuildVectors' | 'rebuildVectorsAsync' | 'review' | 'reviewQueue' | 'search' | 'searchSemantic' | 'update' | 'vectorStats'>;
|
|
76
76
|
/**
|
|
77
77
|
* memory-api-parallel query surface for the repo source-tree code index
|
|
78
|
-
* (
|
|
78
|
+
* (Stage A, see CHANGELOG 0.38.0). Deliberately NOT folded into MemoryApi:
|
|
79
79
|
* CodeContextResult/CodeIndexStats are a different record shape than
|
|
80
80
|
* MemoryRecord, and code-index retrieval carries no cls/reviewState/trustTier
|
|
81
81
|
* provenance semantics — see createCodeIndexApi / createMemoryApi below.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
2
|
/**
|
|
3
|
-
* Budget enforcement (
|
|
3
|
+
* Budget enforcement (see CHANGELOG 0.38.0). Enforcement point is BEFORE the
|
|
4
4
|
* scheduler claims an item into a new phase (i.e. before a new agent spawn)
|
|
5
5
|
* — never mid-item. An in-flight item's phase always runs to completion even
|
|
6
6
|
* if a later check here would refuse a NEW claim: honest semantics, never a
|
|
7
|
-
* mid-run kill on budget
|
|
7
|
+
* mid-run kill on budget.
|
|
8
8
|
*
|
|
9
9
|
* Usage is summed directly from WorkItem.usage, which phase-runner.ts
|
|
10
10
|
* populates from the SAME `priceUsage` function threaded through
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
2
|
/**
|
|
3
|
-
* Per-work-item cancellation registry (
|
|
4
|
-
* cooperative-cancellation
|
|
3
|
+
* Per-work-item cancellation registry (see CHANGELOG 0.38.0) — closing a
|
|
4
|
+
* previously deferred cooperative-cancellation gap.
|
|
5
5
|
*
|
|
6
6
|
* One AbortController per in-flight WorkItem. `engine.kill(itemId)` aborts
|
|
7
7
|
* the controller here AND calls `agentManager.cancel(agentId, 'kill')` — the
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
2
|
/**
|
|
3
|
-
* Controller-compat (
|
|
4
|
-
* migration
|
|
5
|
-
* divergences section).
|
|
3
|
+
* Controller-compat (see CHANGELOG 0.38.0) — stage 1 of the 3-stage WrfcController
|
|
4
|
+
* migration.
|
|
6
5
|
*
|
|
7
6
|
* `fromChainSpec()` produces the canned two-phase engineer->review
|
|
8
7
|
* WORKSTREAM SPEC that a `WrfcController.createChain(ownerRecord)` call
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller-compat.d.ts","sourceRoot":"","sources":["../../../src/platform/orchestration/controller-compat.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF
|
|
1
|
+
{"version":3,"file":"controller-compat.d.ts","sourceRoot":"","sources":["../../../src/platform/orchestration/controller-compat.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,eAAe,EAAE,QAAQ,SAAI,GAAG,SAAS,EAAE,CAK5F;AAED,wBAAgB,aAAa,CAC3B,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,MAAM,CAAC,EAC7C,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,KAAK,GAAG,aAAa,CAAC,GACxD,qBAAqB,CAOvB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
2
|
/**
|
|
3
|
-
* Dirty-residue guard (
|
|
3
|
+
* Dirty-residue guard (see CHANGELOG 0.38.0) — prevents an orchestration
|
|
4
4
|
* engine run's scoped commit from sweeping in uncommitted changes that were
|
|
5
5
|
* ALREADY sitting in the working tree before this engine launched (typically
|
|
6
6
|
* residue left behind by a previously killed run sharing the same
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/platform/orchestration/engine.ts"],"names":[],"mappings":"AAAA,qFAAqF;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/platform/orchestration/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
2
|
/**
|
|
3
|
-
* OrchestrationEngine (
|
|
3
|
+
* OrchestrationEngine (see CHANGELOG 0.38.0) — owns Workstream state and drives the
|
|
4
4
|
* pipeline. WRAPS a canned/authored workstream; does not rewrite or touch
|
|
5
|
-
* WrfcController (stage 1 of the 3-stage migration — see controller-compat.ts
|
|
6
|
-
* and the work-order report).
|
|
5
|
+
* WrfcController (stage 1 of the 3-stage migration — see controller-compat.ts).
|
|
7
6
|
*
|
|
8
7
|
* The tick loop is reactive, not timer-driven: `start()` runs one tick;
|
|
9
8
|
* every phase-run completion re-runs tick() for its workstream. Because JS
|
|
@@ -49,7 +48,7 @@ export function createOrchestrationEngine(deps) {
|
|
|
49
48
|
listeners.add(listener);
|
|
50
49
|
return () => listeners.delete(listener);
|
|
51
50
|
}
|
|
52
|
-
// Dirty-residue guard (
|
|
51
|
+
// Dirty-residue guard (see CHANGELOG 0.38.0): snapshot the working tree's
|
|
53
52
|
// dirty paths + content hashes ONCE, right at engine launch (synchronous —
|
|
54
53
|
// see dirty-guard.ts's doc comment for why this must not be a promise
|
|
55
54
|
// backed by real subprocess I/O), before any phase of this run has had a
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
2
|
/**
|
|
3
|
-
* Persistence (
|
|
3
|
+
* Persistence (see CHANGELOG 0.38.0) — mirrors the WrfcController chain seams
|
|
4
4
|
* exactly: serializeChain:323 / deserializeChain:345 (including the
|
|
5
5
|
* future-schemaVersion-reject guard at :364) / importChain:402. Writes to
|
|
6
6
|
* `.goodvibes/orchestration/<workstreamId>.json` — SEPARATE from the TUI's
|
|
@@ -164,7 +164,7 @@ export function attachDebouncedWriter(projectRoot, getWorkstream, getCompletedRe
|
|
|
164
164
|
timers.set(workstreamId, timer);
|
|
165
165
|
}
|
|
166
166
|
const unsubscribe = subscribe((event) => {
|
|
167
|
-
// 'dirty-tree-at-launch' (
|
|
167
|
+
// 'dirty-tree-at-launch' (see CHANGELOG 0.38.0) is engine-wide, not
|
|
168
168
|
// workstream-scoped — it has no workstreamId to schedule a write for.
|
|
169
169
|
if (event.type === 'dirty-tree-at-launch')
|
|
170
170
|
return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
2
|
/**
|
|
3
|
-
* Phase-runner (
|
|
3
|
+
* Phase-runner (see CHANGELOG 0.38.0) — runs one WorkItem through one Phase: spawn
|
|
4
4
|
* agent, await completion, verify claims, run gates, commit, cleanup.
|
|
5
5
|
*
|
|
6
6
|
* REUSES the hardened WRFC primitives verbatim (same functions WrfcController
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* itself has either. This module therefore mirrors WrfcController's ACTUAL
|
|
27
27
|
* (shared-directory) behavior rather than the brief's aspirational
|
|
28
28
|
* per-item-isolated-worktree fan-out; true fan-out isolation is a valuable,
|
|
29
|
-
* separately-scoped follow-up
|
|
29
|
+
* separately-scoped follow-up.
|
|
30
30
|
*
|
|
31
31
|
* SECOND REALITY-WINS DIVERGENCE: AgentManager.spawn()'s root-spawn
|
|
32
32
|
* normalization (tools/agent/wrfc-batch-policy.ts isRootReviewRoleTask) force
|
|
@@ -84,8 +84,8 @@ export interface PhaseRunnerDeps {
|
|
|
84
84
|
readonly priceUsage?: ((model: string | undefined, usage: WorkItemUsage) => number | null) | undefined;
|
|
85
85
|
readonly skipClaimVerification?: boolean | undefined;
|
|
86
86
|
/**
|
|
87
|
-
* The dirty-tree snapshot taken synchronously at engine launch (
|
|
88
|
-
*
|
|
87
|
+
* The dirty-tree snapshot taken synchronously at engine launch (see
|
|
88
|
+
* CHANGELOG 0.38.0 and dirty-guard.ts). Absent (undefined) degrades to
|
|
89
89
|
* today's behavior: no exclusion, every candidate path is committed.
|
|
90
90
|
*/
|
|
91
91
|
readonly launchDirtySnapshot?: DirtyLaunchSnapshot | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
2
|
/**
|
|
3
|
-
* Scheduler (
|
|
3
|
+
* Scheduler (see CHANGELOG 0.38.0) — pure capacity-matching helpers, no side
|
|
4
4
|
* effects. The hard departure from WrfcController's pairwise
|
|
5
5
|
* engineer<->reviewer binding (startReview:883/startFix:1042): each tick,
|
|
6
6
|
* for every phase in ordinal order, free capacity slots (capacity minus
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** SDK-owned platform module. This implementation is maintained in goodvibes-sdk. */
|
|
2
2
|
/**
|
|
3
|
-
* Orchestration engine — the model (
|
|
3
|
+
* Orchestration engine — the model (see CHANGELOG 0.38.0).
|
|
4
4
|
*
|
|
5
5
|
* A phase/work-item pipeline layered OVER (not replacing) WrfcController. The
|
|
6
6
|
* hard departure from WrfcController is pipeline semantics: an item advances
|
|
@@ -297,7 +297,7 @@ export interface GateOutcome {
|
|
|
297
297
|
readonly unsatisfiedConstraintIds?: readonly string[] | undefined;
|
|
298
298
|
}
|
|
299
299
|
/**
|
|
300
|
-
* Recorded on a PhaseResult when a scoped commit (
|
|
300
|
+
* Recorded on a PhaseResult when a scoped commit (see CHANGELOG 0.38.0)
|
|
301
301
|
* excluded one or more candidate paths because they were already dirty
|
|
302
302
|
* before this engine run launched and this phase never actually touched
|
|
303
303
|
* them (see dirty-guard.ts's excludeUntouchedLaunchResidue). `skipped: true`
|
|
@@ -521,7 +521,7 @@ export type OrchestrationEvent = {
|
|
|
521
521
|
readonly disposition: 'adopted' | 'reported';
|
|
522
522
|
}
|
|
523
523
|
/**
|
|
524
|
-
* Emitted once per engine instance (
|
|
524
|
+
* Emitted once per engine instance (see CHANGELOG 0.38.0), right after the
|
|
525
525
|
* launch-time dirty-tree snapshot resolves, ONLY when it is non-empty.
|
|
526
526
|
* Engine-wide, not workstream-scoped — `workstreamId` is absent (unlike
|
|
527
527
|
* every other variant above) because it fires before any workstream is
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* and src/renderer/status-glyphs.ts (STATE_GLYPHS).
|
|
5
5
|
*
|
|
6
6
|
* This is one of the four genuinely-duplicated presentation tables named by the
|
|
7
|
-
*
|
|
7
|
+
* renderer/input parity audit (see CHANGELOG 1.0.0; both the TUI and the agent shipped a near-twin
|
|
8
8
|
* copy). The TUI is the reference: it is the more-complete, more-recently-fixed
|
|
9
9
|
* copy, and per the presentation-contract decision record its `status` group is
|
|
10
10
|
* the one both renderers converge on.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* and src/renderer/status-glyphs.ts (STATE_GLYPHS).
|
|
5
5
|
*
|
|
6
6
|
* This is one of the four genuinely-duplicated presentation tables named by the
|
|
7
|
-
*
|
|
7
|
+
* renderer/input parity audit (see CHANGELOG 1.0.0; both the TUI and the agent shipped a near-twin
|
|
8
8
|
* copy). The TUI is the reference: it is the more-complete, more-recently-fixed
|
|
9
9
|
* copy, and per the presentation-contract decision record its `status` group is
|
|
10
10
|
* the one both renderers converge on.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @pellux/goodvibes-sdk/platform/presentation
|
|
3
3
|
*
|
|
4
4
|
* The presentation contract — the four genuinely-duplicated presentation
|
|
5
|
-
* tables named by the
|
|
5
|
+
* tables named by the renderer/input parity audit (see CHANGELOG 1.0.0; goodvibes-tui vs
|
|
6
6
|
* goodvibes-agent), hoisted into one pure, dependency-free module per Mike's
|
|
7
7
|
* SDK-boundary rule (machinery needed by 2+ surfaces => SDK):
|
|
8
8
|
*
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
* The TUI is the reference for every value here; dark stays byte-identical to
|
|
16
16
|
* today's TUI. See docs/decisions/2026-07-05-presentation-contract-sdk-extraction.md
|
|
17
17
|
* for the full decision record, including the GLYPHS status-group reconciliation
|
|
18
|
-
* ruling and the consumption plan (agent this
|
|
19
|
-
* a
|
|
18
|
+
* ruling and the consumption plan (the agent picks this up via R4; the TUI swap is
|
|
19
|
+
* deferred to a future coherence pass).
|
|
20
20
|
*
|
|
21
21
|
* PURE — no fs, no terminal I/O, no process globals. Painting stays
|
|
22
22
|
* renderer-owned; this module owns only tokens and pure wording functions.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @pellux/goodvibes-sdk/platform/presentation
|
|
3
3
|
*
|
|
4
4
|
* The presentation contract — the four genuinely-duplicated presentation
|
|
5
|
-
* tables named by the
|
|
5
|
+
* tables named by the renderer/input parity audit (see CHANGELOG 1.0.0; goodvibes-tui vs
|
|
6
6
|
* goodvibes-agent), hoisted into one pure, dependency-free module per Mike's
|
|
7
7
|
* SDK-boundary rule (machinery needed by 2+ surfaces => SDK):
|
|
8
8
|
*
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
* The TUI is the reference for every value here; dark stays byte-identical to
|
|
16
16
|
* today's TUI. See docs/decisions/2026-07-05-presentation-contract-sdk-extraction.md
|
|
17
17
|
* for the full decision record, including the GLYPHS status-group reconciliation
|
|
18
|
-
* ruling and the consumption plan (agent this
|
|
19
|
-
* a
|
|
18
|
+
* ruling and the consumption plan (the agent picks this up via R4; the TUI swap is
|
|
19
|
+
* deferred to a future coherence pass).
|
|
20
20
|
*
|
|
21
21
|
* PURE — no fs, no terminal I/O, no process globals. Painting stays
|
|
22
22
|
* renderer-owned; this module owns only tokens and pure wording functions.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* thinking-phrases.ts — the rotating "thinking" phrase pool, hoisted from
|
|
3
3
|
* `goodvibes-tui` src/renderer/ui-factory.ts (THINKING_PHRASES). Verbatim
|
|
4
|
-
* identical to the agent's copy today (per the
|
|
4
|
+
* identical to the agent's copy today (per the renderer/input parity audit) — a pure
|
|
5
5
|
* move, no reconciliation needed.
|
|
6
6
|
*
|
|
7
7
|
* Vaporwave / good-vibes themed; shown by waitingPhrase()'s 'thinking' case
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* thinking-phrases.ts — the rotating "thinking" phrase pool, hoisted from
|
|
3
3
|
* `goodvibes-tui` src/renderer/ui-factory.ts (THINKING_PHRASES). Verbatim
|
|
4
|
-
* identical to the agent's copy today (per the
|
|
4
|
+
* identical to the agent's copy today (per the renderer/input parity audit) — a pure
|
|
5
5
|
* move, no reconciliation needed.
|
|
6
6
|
*
|
|
7
7
|
* Vaporwave / good-vibes themed; shown by waitingPhrase()'s 'thinking' case
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* TUI's precedence order — approval beats reconnect beats pre-first-token
|
|
12
12
|
* beats stalled beats thinking) and calls waitingPhrase(state, ctx) for the
|
|
13
13
|
* exact wording. Neither renderer should carry its own copy of these five
|
|
14
|
-
* strings/rotation — that duplication is exactly what the
|
|
14
|
+
* strings/rotation — that duplication is exactly what the renderer/input parity audit found
|
|
15
15
|
* (the agent's ui-factory.ts:308-313 was rotating-only, with no honest
|
|
16
16
|
* stall/reconnect/approval split at all).
|
|
17
17
|
*
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* TUI's precedence order — approval beats reconnect beats pre-first-token
|
|
12
12
|
* beats stalled beats thinking) and calls waitingPhrase(state, ctx) for the
|
|
13
13
|
* exact wording. Neither renderer should carry its own copy of these five
|
|
14
|
-
* strings/rotation — that duplication is exactly what the
|
|
14
|
+
* strings/rotation — that duplication is exactly what the renderer/input parity audit found
|
|
15
15
|
* (the agent's ui-factory.ts:308-313 was rotating-only, with no honest
|
|
16
16
|
* stall/reconnect/approval split at all).
|
|
17
17
|
*
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* push/delivery.ts
|
|
3
|
+
*
|
|
4
|
+
* The single place a push message is actually encrypted and sent. Every send —
|
|
5
|
+
* a `push.subscriptions.verify` test, or an approval/completion fan-out — flows
|
|
6
|
+
* through `deliverToSubscription`, so the honesty rules live in one spot:
|
|
7
|
+
*
|
|
8
|
+
* - A push service that answers 404/410 means the browser subscription is gone;
|
|
9
|
+
* the record is pruned and the receipt says `pruned`, never a fake success.
|
|
10
|
+
* - Any other non-2xx (or a transport error) is reported as `failed` with the
|
|
11
|
+
* status/reason, never swallowed into a success.
|
|
12
|
+
* - The request carries the RFC 8188 `Content-Encoding: aes128gcm` body plus
|
|
13
|
+
* the `TTL`, `Urgency`, and VAPID `Authorization` headers a push service
|
|
14
|
+
* requires.
|
|
15
|
+
*
|
|
16
|
+
* The endpoint is whatever the browser registered. In tests that is a local
|
|
17
|
+
* HTTP sink; in production it is the browser vendor's push service. This module
|
|
18
|
+
* never contacts a hard-coded external service of its own.
|
|
19
|
+
*/
|
|
20
|
+
import type { VapidManager } from './vapid.js';
|
|
21
|
+
import type { PushSubscriptionStore } from './subscription-store.js';
|
|
22
|
+
import type { PushDeliveryReceipt, PushMessage, StoredPushSubscription } from './types.js';
|
|
23
|
+
/** The `fetch` slice used to POST an encrypted payload. Injectable for tests. */
|
|
24
|
+
export type PushTransport = (url: string, init: {
|
|
25
|
+
method: string;
|
|
26
|
+
headers: Record<string, string>;
|
|
27
|
+
body: Buffer;
|
|
28
|
+
}) => Promise<{
|
|
29
|
+
status: number;
|
|
30
|
+
}>;
|
|
31
|
+
export interface DeliveryDeps {
|
|
32
|
+
readonly vapid: VapidManager;
|
|
33
|
+
readonly store: PushSubscriptionStore;
|
|
34
|
+
readonly transport?: PushTransport | undefined;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Encrypt and send one message to one subscription, prune-on-gone, and return
|
|
38
|
+
* an honest receipt. The subscription's `lastOutcome` is stamped either way.
|
|
39
|
+
*/
|
|
40
|
+
export declare function deliverToSubscription(subscription: StoredPushSubscription, message: PushMessage, deps: DeliveryDeps): Promise<PushDeliveryReceipt>;
|
|
41
|
+
/**
|
|
42
|
+
* Fan one message out to every stored subscription, delivering (and pruning) in
|
|
43
|
+
* sequence. Returns one receipt per subscription — an empty array when there
|
|
44
|
+
* are no subscriptions at all (the honest "nobody to notify" result, not a
|
|
45
|
+
* silent success).
|
|
46
|
+
*/
|
|
47
|
+
export declare function deliverToAll(message: PushMessage, deps: DeliveryDeps): Promise<PushDeliveryReceipt[]>;
|
|
48
|
+
//# sourceMappingURL=delivery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../../../src/platform/push/delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EACV,mBAAmB,EACnB,WAAW,EACX,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,iFAAiF;AACjF,MAAM,MAAM,aAAa,GAAG,CAC1B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,KACpE,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAgCjC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;CAChD;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,sBAAsB,EACpC,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,mBAAmB,CAAC,CAyD9B;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAOhC"}
|