@corca-org/ceal-host-linux-arm64 1.0.14 → 1.0.15
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/bin/ceal-host +0 -0
- package/libexec/ceal-host/claude-hook.mjs +42 -23
- package/libexec/ceal-host/claude-invocation-authentication.mjs +39 -25
- package/libexec/ceal-host/claude-producer.mjs +42 -23
- package/libexec/ceal-host/codex-hook.mjs +42 -23
- package/libexec/ceal-host/codex-invocation-authentication.mjs +39 -25
- package/libexec/ceal-host/codex-producer.mjs +42 -23
- package/libexec/ceal-host/control.mjs +44 -25
- package/libexec/ceal-host/relay.mjs +18 -10
- package/package.json +1 -1
- package/share/ceal-host/bundle-manifest.json +12 -12
- package/share/ceal-host/bundle-manifest.sigstore.json +1 -1
package/bin/ceal-host
CHANGED
|
Binary file
|
|
@@ -78,7 +78,6 @@ var client_wire_contract_default = {
|
|
|
78
78
|
length: 72,
|
|
79
79
|
pattern: "^catalog:[a-f0-9]{64}$"
|
|
80
80
|
},
|
|
81
|
-
max_bytes: 4194304,
|
|
82
81
|
envelope_max_bytes: 389
|
|
83
82
|
},
|
|
84
83
|
command_request: {
|
|
@@ -165,8 +164,7 @@ var client_wire_contract_default = {
|
|
|
165
164
|
],
|
|
166
165
|
exit_code_max: 125,
|
|
167
166
|
bare_document_max_bytes: 65536,
|
|
168
|
-
complete_max_bytes: 66019
|
|
169
|
-
absolute_transport_max_bytes: 4194304
|
|
167
|
+
complete_max_bytes: 66019
|
|
170
168
|
},
|
|
171
169
|
resource_stream: {
|
|
172
170
|
path: "/api/ceal/v2/resources",
|
|
@@ -181,6 +179,9 @@ var client_wire_contract_default = {
|
|
|
181
179
|
"fetch"
|
|
182
180
|
],
|
|
183
181
|
ref_flag: "--ref"
|
|
182
|
+
},
|
|
183
|
+
encoded_json_document: {
|
|
184
|
+
max_bytes: 4194304
|
|
184
185
|
}
|
|
185
186
|
};
|
|
186
187
|
|
|
@@ -190,6 +191,7 @@ var commandResolution = CEAL_CLIENT_WIRE_CONTRACT.command_resolution;
|
|
|
190
191
|
var commandResolutionAuthority = commandResolution.authority;
|
|
191
192
|
var commandResolutionSemanticOptions = commandResolution.semantic_options;
|
|
192
193
|
var CEAL_GATEWAY_COMMAND_RESOLUTION_SCHEMA_VERSION = commandResolution.schema_version;
|
|
194
|
+
var CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES = CEAL_CLIENT_WIRE_CONTRACT.encoded_json_document.max_bytes;
|
|
193
195
|
var artifact = CEAL_CLIENT_WIRE_CONTRACT.artifact_descriptor;
|
|
194
196
|
var request = CEAL_CLIENT_WIRE_CONTRACT.command_request;
|
|
195
197
|
var response = CEAL_CLIENT_WIRE_CONTRACT.command_response;
|
|
@@ -203,7 +205,7 @@ var CEAL_VERIFIED_ARTIFACT_DIGEST_LENGTH = artifact.digest.length;
|
|
|
203
205
|
var CEAL_VERIFIED_ARTIFACT_DIGEST_PATTERN = artifact.digest.pattern;
|
|
204
206
|
var CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_LENGTH = artifact.catalog_revision.length;
|
|
205
207
|
var CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_PATTERN = artifact.catalog_revision.pattern;
|
|
206
|
-
var CEAL_VERIFIED_ARTIFACT_MAX_BYTES =
|
|
208
|
+
var CEAL_VERIFIED_ARTIFACT_MAX_BYTES = CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES;
|
|
207
209
|
var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_MAX_BYTES = artifact.envelope_max_bytes;
|
|
208
210
|
var CEAL_COMMAND_REQUEST_SCHEMA_VERSION = request.schema_version;
|
|
209
211
|
var CEAL_COMMAND_REQUEST_MAX_BYTES = request.absolute_transport_max_bytes;
|
|
@@ -217,7 +219,6 @@ var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_CONTINUATION_DOCUMENT_FIELDS = Object.f
|
|
|
217
219
|
var CEAL_COMMAND_RESPONSE_DISCOVERY_COMMAND = response.discovery_command;
|
|
218
220
|
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_SCHEMA_VERSION = response.discovery_manifest_schema_version;
|
|
219
221
|
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_DOCUMENT_FIELDS = Object.freeze([...response.discovery_manifest_document_fields]);
|
|
220
|
-
var CEAL_COMMAND_RESPONSE_MAX_BYTES = response.absolute_transport_max_bytes;
|
|
221
222
|
|
|
222
223
|
// packages/ceal-client-protocol/src/vocabulary.ts
|
|
223
224
|
function vocabulary(words) {
|
|
@@ -508,7 +509,6 @@ function cut(text) {
|
|
|
508
509
|
var CEAL_OPERATION_ACCESS_CLASSES = vocabulary(["read", "write"]);
|
|
509
510
|
|
|
510
511
|
// packages/ceal-client-protocol/src/domain-vocabulary.ts
|
|
511
|
-
var CEAL_INTEGRATION_KINDS = vocabulary(["github", "google-workspace", "notion", "slack"]);
|
|
512
512
|
var CEAL_CONNECTOR_STATUSES = vocabulary(["active", "disabled", "disconnected"]);
|
|
513
513
|
var CEAL_CONNECTOR_CUSTODIES = vocabulary(["organization", "personal"]);
|
|
514
514
|
var CEAL_PROVIDER_BOUNDARY_KINDS = vocabulary([
|
|
@@ -874,7 +874,7 @@ var NON_REMEDY_NEXT_ACTION_VALUES = [
|
|
|
874
874
|
"operator_action",
|
|
875
875
|
"recover",
|
|
876
876
|
"reconcile",
|
|
877
|
-
// Reconciliation of one named occurrence, not of the deployment:
|
|
877
|
+
// Reconciliation of one named occurrence, not of the deployment: an
|
|
878
878
|
// occurrence with no admitted input commitment cannot be replayed safely and
|
|
879
879
|
// no edit to the call changes that. `reconcile` is the deployment-wide word.
|
|
880
880
|
"reconcile_occurrence",
|
|
@@ -1004,7 +1004,7 @@ var CEAL_ACTIVITY_V3_KINDS = vocabulary(["authored", "edited", "messaged", "resp
|
|
|
1004
1004
|
var CEAL_RESOURCE_TIME_BASES = vocabulary(["created", "modified", "viewed"]);
|
|
1005
1005
|
var CEAL_RESOURCE_SEARCH_ORDERS = vocabulary(["relevance", "modified", "viewed", "created"]);
|
|
1006
1006
|
var CEAL_RESOURCE_SEARCH_DIRECTIONS = vocabulary(["ascending", "descending"]);
|
|
1007
|
-
var CEAL_RESOURCE_SEARCH_FILTERS = vocabulary(["query", "modified_since", "since", "until", "authored_by_me", "include_replies", "kinds", "container_ref", "container_refs", "addressed_to_me", "unread"]);
|
|
1007
|
+
var CEAL_RESOURCE_SEARCH_FILTERS = vocabulary(["query", "modified_since", "since", "until", "authored_by_me", "include_replies", "kinds", "container_ref", "container_refs", "container_names", "addressed_to_me", "unread"]);
|
|
1008
1008
|
var CEAL_ARTIFACT_STAGE_TERMINALS = vocabulary(["chunk_accepted", "artifact_ready", "idempotency_replayed"]);
|
|
1009
1009
|
var CEAL_READ_ITEM_KINDS = vocabulary(["conversation", "identity", "usergroup", "message", "file", "document"]);
|
|
1010
1010
|
var CEAL_LEASED_MESSAGE_SEARCH_COMPLETENESS = vocabulary(["complete", "continuation_available", "truncated"]);
|
|
@@ -1058,6 +1058,7 @@ var RESOURCE_ROW_KEY_RULES = Object.freeze({
|
|
|
1058
1058
|
title: { required: true, timestamp: false },
|
|
1059
1059
|
container_label: { required: true, timestamp: false },
|
|
1060
1060
|
container_ref: { required: false, timestamp: false },
|
|
1061
|
+
source_url: { required: false, timestamp: false },
|
|
1061
1062
|
source: { required: true, timestamp: false },
|
|
1062
1063
|
owner: { required: false, timestamp: false },
|
|
1063
1064
|
counterparts: { required: false, timestamp: false },
|
|
@@ -1427,6 +1428,18 @@ var CEAL_REQUEST_GRAPH_NODE_PREPARE_READINESS_JSON_SCHEMA = {
|
|
|
1427
1428
|
required: ["node_ref", "operation_id", "resolver_owned", "gateway_derived"]
|
|
1428
1429
|
};
|
|
1429
1430
|
|
|
1431
|
+
// packages/ceal-client-protocol/src/host-invocation-authentication.ts
|
|
1432
|
+
var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA = "ceal.host_invocation_authentication_result.v1";
|
|
1433
|
+
var CEAL_HOST_NONCE_ENCODED_CHARACTERS = 43;
|
|
1434
|
+
var CEAL_HOST_CLIENT_NONCE_PATTERN = new RegExp(`^[A-Za-z0-9_-]{${CEAL_HOST_NONCE_ENCODED_CHARACTERS}}$`, "u");
|
|
1435
|
+
var CEAL_HOST_CONTEXT_TOKEN_PATTERN = new RegExp(`^ceal_context_[A-Za-z0-9_-]{${CEAL_HOST_NONCE_ENCODED_CHARACTERS}}$`, "u");
|
|
1436
|
+
var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_MAX_BYTES = new TextEncoder().encode(`${JSON.stringify({
|
|
1437
|
+
schema_version: CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA,
|
|
1438
|
+
context_token: `ceal_context_${"A".repeat(CEAL_HOST_NONCE_ENCODED_CHARACTERS)}`,
|
|
1439
|
+
expires_at: (/* @__PURE__ */ new Date("+010000-01-01T00:00:00.000Z")).toISOString()
|
|
1440
|
+
})}
|
|
1441
|
+
`).byteLength;
|
|
1442
|
+
|
|
1430
1443
|
// packages/ceal-client-protocol/src/client-result-materialization.ts
|
|
1431
1444
|
var CEAL_MODEL_VISIBLE_COMMAND_OUTPUT_MAX_BYTES = 32 * 1024;
|
|
1432
1445
|
var REQUIRED_FIELDS2 = Object.freeze(["schema_version", "operation_id", "read_argv"]);
|
|
@@ -2604,7 +2617,6 @@ function assertHostProducerSourcePaths(stateRoot, config, producer, platform = p
|
|
|
2604
2617
|
// host/producer-service.ts
|
|
2605
2618
|
import { constants } from "node:fs";
|
|
2606
2619
|
import { lstat as lstat2, open as open3 } from "node:fs/promises";
|
|
2607
|
-
var MAX_CONFIG_BYTES = 32 * 1024;
|
|
2608
2620
|
var SAFE_REF5 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
2609
2621
|
var HOST_PRODUCER_CONFIG_FLAG = "--ceal-host-config";
|
|
2610
2622
|
var HostProducerServiceError = class extends Error {
|
|
@@ -2615,7 +2627,8 @@ var HostProducerServiceError = class extends Error {
|
|
|
2615
2627
|
this.code = code3;
|
|
2616
2628
|
}
|
|
2617
2629
|
};
|
|
2618
|
-
var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint"
|
|
2630
|
+
var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint"];
|
|
2631
|
+
var HOST_PRODUCER_TIMING_DEFAULTS = Object.freeze({ reconcile_interval_ms: 250, retry_backoff_ms: 1e3, ipc_timeout_ms: 5e3 });
|
|
2619
2632
|
function parseHostProducerConfigFlag(args, platform = process.platform) {
|
|
2620
2633
|
return parseProducerHostConfigFlag(args, HOST_PRODUCER_CONFIG_FLAG, platform, hostProducerError);
|
|
2621
2634
|
}
|
|
@@ -2654,15 +2667,17 @@ async function readProducerConfigText(configPath, platform, error) {
|
|
|
2654
2667
|
const noFollow = typeof constants.O_NOFOLLOW === "number" ? constants.O_NOFOLLOW : 0;
|
|
2655
2668
|
const handle = await openConfigFile(configPath, constants.O_RDONLY | noFollow, error);
|
|
2656
2669
|
try {
|
|
2657
|
-
|
|
2658
|
-
|
|
2670
|
+
const opened = await handle.stat();
|
|
2671
|
+
validateConfigFile(opened, platform, error);
|
|
2672
|
+
validateOpenedFile(opened, pathStat, platform, error);
|
|
2673
|
+
return await readBoundedConfig(handle, opened.size, error);
|
|
2659
2674
|
} finally {
|
|
2660
2675
|
await handle.close();
|
|
2661
2676
|
}
|
|
2662
2677
|
}
|
|
2663
2678
|
function decodeProducerConfigCore(text, options) {
|
|
2664
2679
|
const value = parseCanonicalJson(text, options.error);
|
|
2665
|
-
if (!isRecord2(value) || !
|
|
2680
|
+
if (!isRecord2(value) || !hasConfigKeys(value, options.keys) || value.schema_version !== options.schema) throw options.error("invalid_config");
|
|
2666
2681
|
const hostSourceRef = typeof value.host_source_ref === "string" ? value.host_source_ref : "";
|
|
2667
2682
|
const installationRef = typeof value.producer_installation_ref === "string" ? value.producer_installation_ref : "";
|
|
2668
2683
|
const producerEpoch = validateIdentity2(hostSourceRef, installationRef, value.producer_epoch, options.error);
|
|
@@ -2673,7 +2688,7 @@ function decodeProducerConfigCore(text, options) {
|
|
|
2673
2688
|
assertProducerAbsolutePath(value[key], options.platform, "runtime", options.error);
|
|
2674
2689
|
extraPaths[key] = value[key];
|
|
2675
2690
|
}
|
|
2676
|
-
const intervals = validateIntervals(value.reconcile_interval_ms, value.retry_backoff_ms, value.ipc_timeout_ms, options.error);
|
|
2691
|
+
const intervals = validateIntervals(value.reconcile_interval_ms === void 0 ? HOST_PRODUCER_TIMING_DEFAULTS.reconcile_interval_ms : value.reconcile_interval_ms, value.retry_backoff_ms === void 0 ? HOST_PRODUCER_TIMING_DEFAULTS.retry_backoff_ms : value.retry_backoff_ms, value.ipc_timeout_ms === void 0 ? HOST_PRODUCER_TIMING_DEFAULTS.ipc_timeout_ms : value.ipc_timeout_ms, options.error);
|
|
2677
2692
|
return {
|
|
2678
2693
|
extra_paths: Object.freeze(extraPaths),
|
|
2679
2694
|
host_source_ref: hostSourceRef,
|
|
@@ -2702,7 +2717,7 @@ async function configPathStat(configPath, error) {
|
|
|
2702
2717
|
}
|
|
2703
2718
|
function validateConfigFile(value, platform, error) {
|
|
2704
2719
|
if (!value.isFile() || value.isSymbolicLink()) throw error("invalid_config", refusalFacts([{ name: "config_is_file", value: value.isFile(), expected: "true" }, { name: "config_is_symlink", value: value.isSymbolicLink(), expected: "false" }]));
|
|
2705
|
-
if (value.size <= 0 || value.size >
|
|
2720
|
+
if (value.size <= 0 || value.size > CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES) throw error("invalid_config", refusalFact("config_bytes", value.size, `between 1 and ${CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES}`));
|
|
2706
2721
|
if (platform !== "win32" && (value.uid !== process.getuid?.() || (value.mode & 63) !== 0)) throw error("config_not_private", refusalFacts([{ name: "platform", value: platform, expected: "win32 or owner-private" }, { name: "config_uid", value: value.uid, expected: "the current user" }, { name: "config_mode", value: value.mode, expected: "owner-private" }]));
|
|
2707
2722
|
}
|
|
2708
2723
|
async function openConfigFile(configPath, flags, error) {
|
|
@@ -2716,12 +2731,17 @@ function validateOpenedFile(opened, pathStat, platform, error) {
|
|
|
2716
2731
|
if (!opened.isFile()) throw error("config_unavailable", refusalFacts([{ name: "opened_is_file", value: opened.isFile(), expected: "true" }, { name: "opened_mode", value: opened.mode.toString(8), expected: "a regular file mode" }]));
|
|
2717
2732
|
if (platform !== "win32" && (opened.dev !== pathStat.dev || opened.ino !== pathStat.ino)) throw error("config_unavailable", refusalFacts([{ name: "platform", value: platform, expected: "win32, or the same file the path named" }, { name: "opened_device", value: opened.dev, expected: String(pathStat.dev) }, { name: "opened_inode", value: opened.ino, expected: String(pathStat.ino) }]));
|
|
2718
2733
|
}
|
|
2719
|
-
async function readBoundedConfig(handle, error) {
|
|
2720
|
-
const buffer = Buffer.allocUnsafe(
|
|
2721
|
-
|
|
2722
|
-
|
|
2734
|
+
async function readBoundedConfig(handle, expectedBytes, error) {
|
|
2735
|
+
const buffer = Buffer.allocUnsafe(expectedBytes + 1);
|
|
2736
|
+
let offset = 0;
|
|
2737
|
+
while (offset < buffer.byteLength) {
|
|
2738
|
+
const { bytesRead } = await handle.read(buffer, offset, buffer.byteLength - offset, offset);
|
|
2739
|
+
if (bytesRead === 0) break;
|
|
2740
|
+
offset += bytesRead;
|
|
2741
|
+
}
|
|
2742
|
+
if (offset !== expectedBytes) throw error("invalid_config", refusalFact("bytes_read", offset, `the opened file's ${expectedBytes} bytes without growth or truncation`));
|
|
2723
2743
|
try {
|
|
2724
|
-
return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0,
|
|
2744
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0, offset));
|
|
2725
2745
|
} catch {
|
|
2726
2746
|
throw error("invalid_config");
|
|
2727
2747
|
}
|
|
@@ -2749,9 +2769,8 @@ function validateIntervals(reconcile, retry, timeout, error) {
|
|
|
2749
2769
|
if (!boundedMilliseconds(reconcile) || !boundedMilliseconds(retry) || !boundedMilliseconds(timeout)) throw error("invalid_config");
|
|
2750
2770
|
return [reconcile, retry, timeout];
|
|
2751
2771
|
}
|
|
2752
|
-
function
|
|
2753
|
-
|
|
2754
|
-
return observed.length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
2772
|
+
function hasConfigKeys(value, required) {
|
|
2773
|
+
return required.every((key) => Object.hasOwn(value, key)) && Object.keys(value).every((key) => required.includes(key) || Object.hasOwn(HOST_PRODUCER_TIMING_DEFAULTS, key));
|
|
2755
2774
|
}
|
|
2756
2775
|
function isRecord2(value) {
|
|
2757
2776
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -54,7 +54,6 @@ var client_wire_contract_default = {
|
|
|
54
54
|
length: 72,
|
|
55
55
|
pattern: "^catalog:[a-f0-9]{64}$"
|
|
56
56
|
},
|
|
57
|
-
max_bytes: 4194304,
|
|
58
57
|
envelope_max_bytes: 389
|
|
59
58
|
},
|
|
60
59
|
command_request: {
|
|
@@ -141,8 +140,7 @@ var client_wire_contract_default = {
|
|
|
141
140
|
],
|
|
142
141
|
exit_code_max: 125,
|
|
143
142
|
bare_document_max_bytes: 65536,
|
|
144
|
-
complete_max_bytes: 66019
|
|
145
|
-
absolute_transport_max_bytes: 4194304
|
|
143
|
+
complete_max_bytes: 66019
|
|
146
144
|
},
|
|
147
145
|
resource_stream: {
|
|
148
146
|
path: "/api/ceal/v2/resources",
|
|
@@ -157,6 +155,9 @@ var client_wire_contract_default = {
|
|
|
157
155
|
"fetch"
|
|
158
156
|
],
|
|
159
157
|
ref_flag: "--ref"
|
|
158
|
+
},
|
|
159
|
+
encoded_json_document: {
|
|
160
|
+
max_bytes: 4194304
|
|
160
161
|
}
|
|
161
162
|
};
|
|
162
163
|
|
|
@@ -166,6 +167,7 @@ var commandResolution = CEAL_CLIENT_WIRE_CONTRACT.command_resolution;
|
|
|
166
167
|
var commandResolutionAuthority = commandResolution.authority;
|
|
167
168
|
var commandResolutionSemanticOptions = commandResolution.semantic_options;
|
|
168
169
|
var CEAL_GATEWAY_COMMAND_RESOLUTION_SCHEMA_VERSION = commandResolution.schema_version;
|
|
170
|
+
var CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES = CEAL_CLIENT_WIRE_CONTRACT.encoded_json_document.max_bytes;
|
|
169
171
|
var artifact = CEAL_CLIENT_WIRE_CONTRACT.artifact_descriptor;
|
|
170
172
|
var request = CEAL_CLIENT_WIRE_CONTRACT.command_request;
|
|
171
173
|
var response = CEAL_CLIENT_WIRE_CONTRACT.command_response;
|
|
@@ -179,7 +181,7 @@ var CEAL_VERIFIED_ARTIFACT_DIGEST_LENGTH = artifact.digest.length;
|
|
|
179
181
|
var CEAL_VERIFIED_ARTIFACT_DIGEST_PATTERN = artifact.digest.pattern;
|
|
180
182
|
var CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_LENGTH = artifact.catalog_revision.length;
|
|
181
183
|
var CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_PATTERN = artifact.catalog_revision.pattern;
|
|
182
|
-
var CEAL_VERIFIED_ARTIFACT_MAX_BYTES =
|
|
184
|
+
var CEAL_VERIFIED_ARTIFACT_MAX_BYTES = CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES;
|
|
183
185
|
var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_MAX_BYTES = artifact.envelope_max_bytes;
|
|
184
186
|
var CEAL_COMMAND_REQUEST_SCHEMA_VERSION = request.schema_version;
|
|
185
187
|
var CEAL_COMMAND_REQUEST_MAX_BYTES = request.absolute_transport_max_bytes;
|
|
@@ -193,7 +195,6 @@ var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_CONTINUATION_DOCUMENT_FIELDS = Object.f
|
|
|
193
195
|
var CEAL_COMMAND_RESPONSE_DISCOVERY_COMMAND = response.discovery_command;
|
|
194
196
|
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_SCHEMA_VERSION = response.discovery_manifest_schema_version;
|
|
195
197
|
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_DOCUMENT_FIELDS = Object.freeze([...response.discovery_manifest_document_fields]);
|
|
196
|
-
var CEAL_COMMAND_RESPONSE_MAX_BYTES = response.absolute_transport_max_bytes;
|
|
197
198
|
|
|
198
199
|
// packages/ceal-client-protocol/src/vocabulary.ts
|
|
199
200
|
function vocabulary(words) {
|
|
@@ -487,7 +488,6 @@ function cut(text) {
|
|
|
487
488
|
var CEAL_OPERATION_ACCESS_CLASSES = vocabulary(["read", "write"]);
|
|
488
489
|
|
|
489
490
|
// packages/ceal-client-protocol/src/domain-vocabulary.ts
|
|
490
|
-
var CEAL_INTEGRATION_KINDS = vocabulary(["github", "google-workspace", "notion", "slack"]);
|
|
491
491
|
var CEAL_CONNECTOR_STATUSES = vocabulary(["active", "disabled", "disconnected"]);
|
|
492
492
|
var CEAL_CONNECTOR_CUSTODIES = vocabulary(["organization", "personal"]);
|
|
493
493
|
var CEAL_PROVIDER_BOUNDARY_KINDS = vocabulary([
|
|
@@ -853,7 +853,7 @@ var NON_REMEDY_NEXT_ACTION_VALUES = [
|
|
|
853
853
|
"operator_action",
|
|
854
854
|
"recover",
|
|
855
855
|
"reconcile",
|
|
856
|
-
// Reconciliation of one named occurrence, not of the deployment:
|
|
856
|
+
// Reconciliation of one named occurrence, not of the deployment: an
|
|
857
857
|
// occurrence with no admitted input commitment cannot be replayed safely and
|
|
858
858
|
// no edit to the call changes that. `reconcile` is the deployment-wide word.
|
|
859
859
|
"reconcile_occurrence",
|
|
@@ -983,7 +983,7 @@ var CEAL_ACTIVITY_V3_KINDS = vocabulary(["authored", "edited", "messaged", "resp
|
|
|
983
983
|
var CEAL_RESOURCE_TIME_BASES = vocabulary(["created", "modified", "viewed"]);
|
|
984
984
|
var CEAL_RESOURCE_SEARCH_ORDERS = vocabulary(["relevance", "modified", "viewed", "created"]);
|
|
985
985
|
var CEAL_RESOURCE_SEARCH_DIRECTIONS = vocabulary(["ascending", "descending"]);
|
|
986
|
-
var CEAL_RESOURCE_SEARCH_FILTERS = vocabulary(["query", "modified_since", "since", "until", "authored_by_me", "include_replies", "kinds", "container_ref", "container_refs", "addressed_to_me", "unread"]);
|
|
986
|
+
var CEAL_RESOURCE_SEARCH_FILTERS = vocabulary(["query", "modified_since", "since", "until", "authored_by_me", "include_replies", "kinds", "container_ref", "container_refs", "container_names", "addressed_to_me", "unread"]);
|
|
987
987
|
var CEAL_ARTIFACT_STAGE_TERMINALS = vocabulary(["chunk_accepted", "artifact_ready", "idempotency_replayed"]);
|
|
988
988
|
var CEAL_READ_ITEM_KINDS = vocabulary(["conversation", "identity", "usergroup", "message", "file", "document"]);
|
|
989
989
|
var CEAL_LEASED_MESSAGE_SEARCH_COMPLETENESS = vocabulary(["complete", "continuation_available", "truncated"]);
|
|
@@ -1037,6 +1037,7 @@ var RESOURCE_ROW_KEY_RULES = Object.freeze({
|
|
|
1037
1037
|
title: { required: true, timestamp: false },
|
|
1038
1038
|
container_label: { required: true, timestamp: false },
|
|
1039
1039
|
container_ref: { required: false, timestamp: false },
|
|
1040
|
+
source_url: { required: false, timestamp: false },
|
|
1040
1041
|
source: { required: true, timestamp: false },
|
|
1041
1042
|
owner: { required: false, timestamp: false },
|
|
1042
1043
|
counterparts: { required: false, timestamp: false },
|
|
@@ -1399,8 +1400,15 @@ var CEAL_REQUEST_GRAPH_NODE_PREPARE_READINESS_JSON_SCHEMA = {
|
|
|
1399
1400
|
// packages/ceal-client-protocol/src/host-invocation-authentication.ts
|
|
1400
1401
|
var CEAL_HOST_INVOCATION_AUTHENTICATION_REQUEST_SCHEMA = "ceal.host_invocation_authentication_request.v1";
|
|
1401
1402
|
var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA = "ceal.host_invocation_authentication_result.v1";
|
|
1402
|
-
var
|
|
1403
|
-
var
|
|
1403
|
+
var CEAL_HOST_NONCE_ENCODED_CHARACTERS = 43;
|
|
1404
|
+
var CEAL_HOST_CLIENT_NONCE_PATTERN = new RegExp(`^[A-Za-z0-9_-]{${CEAL_HOST_NONCE_ENCODED_CHARACTERS}}$`, "u");
|
|
1405
|
+
var CEAL_HOST_CONTEXT_TOKEN_PATTERN = new RegExp(`^ceal_context_[A-Za-z0-9_-]{${CEAL_HOST_NONCE_ENCODED_CHARACTERS}}$`, "u");
|
|
1406
|
+
var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_MAX_BYTES = new TextEncoder().encode(`${JSON.stringify({
|
|
1407
|
+
schema_version: CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA,
|
|
1408
|
+
context_token: `ceal_context_${"A".repeat(CEAL_HOST_NONCE_ENCODED_CHARACTERS)}`,
|
|
1409
|
+
expires_at: (/* @__PURE__ */ new Date("+010000-01-01T00:00:00.000Z")).toISOString()
|
|
1410
|
+
})}
|
|
1411
|
+
`).byteLength;
|
|
1404
1412
|
function decodeCealHostInvocationAuthenticationRequest(value) {
|
|
1405
1413
|
if (!isCealJsonRecord(value) || !exactKeys(value, ["schema_version", "client_nonce"]) || value.schema_version !== CEAL_HOST_INVOCATION_AUTHENTICATION_REQUEST_SCHEMA || typeof value.client_nonce !== "string" || !CEAL_HOST_CLIENT_NONCE_PATTERN.test(value.client_nonce)) {
|
|
1406
1414
|
throw new TypeError("The Host invocation authentication request is invalid.");
|
|
@@ -2254,7 +2262,6 @@ function assertHostProducerSourcePaths(stateRoot, config, producer, platform = p
|
|
|
2254
2262
|
// host/producer-service.ts
|
|
2255
2263
|
import { constants } from "node:fs";
|
|
2256
2264
|
import { lstat as lstat2, open as open2 } from "node:fs/promises";
|
|
2257
|
-
var MAX_CONFIG_BYTES = 32 * 1024;
|
|
2258
2265
|
var SAFE_REF3 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
2259
2266
|
var HOST_PRODUCER_CONFIG_FLAG = "--ceal-host-config";
|
|
2260
2267
|
var HostProducerServiceError = class extends Error {
|
|
@@ -2265,7 +2272,8 @@ var HostProducerServiceError = class extends Error {
|
|
|
2265
2272
|
this.code = code3;
|
|
2266
2273
|
}
|
|
2267
2274
|
};
|
|
2268
|
-
var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint"
|
|
2275
|
+
var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint"];
|
|
2276
|
+
var HOST_PRODUCER_TIMING_DEFAULTS = Object.freeze({ reconcile_interval_ms: 250, retry_backoff_ms: 1e3, ipc_timeout_ms: 5e3 });
|
|
2269
2277
|
function parseHostProducerConfigFlag(args, platform = process.platform) {
|
|
2270
2278
|
return parseProducerHostConfigFlag(args, HOST_PRODUCER_CONFIG_FLAG, platform, hostProducerError);
|
|
2271
2279
|
}
|
|
@@ -2304,15 +2312,17 @@ async function readProducerConfigText(configPath, platform, error) {
|
|
|
2304
2312
|
const noFollow = typeof constants.O_NOFOLLOW === "number" ? constants.O_NOFOLLOW : 0;
|
|
2305
2313
|
const handle = await openConfigFile(configPath, constants.O_RDONLY | noFollow, error);
|
|
2306
2314
|
try {
|
|
2307
|
-
|
|
2308
|
-
|
|
2315
|
+
const opened = await handle.stat();
|
|
2316
|
+
validateConfigFile(opened, platform, error);
|
|
2317
|
+
validateOpenedFile(opened, pathStat, platform, error);
|
|
2318
|
+
return await readBoundedConfig(handle, opened.size, error);
|
|
2309
2319
|
} finally {
|
|
2310
2320
|
await handle.close();
|
|
2311
2321
|
}
|
|
2312
2322
|
}
|
|
2313
2323
|
function decodeProducerConfigCore(text, options) {
|
|
2314
2324
|
const value = parseCanonicalJson(text, options.error);
|
|
2315
|
-
if (!isRecord(value) || !
|
|
2325
|
+
if (!isRecord(value) || !hasConfigKeys(value, options.keys) || value.schema_version !== options.schema) throw options.error("invalid_config");
|
|
2316
2326
|
const hostSourceRef = typeof value.host_source_ref === "string" ? value.host_source_ref : "";
|
|
2317
2327
|
const installationRef = typeof value.producer_installation_ref === "string" ? value.producer_installation_ref : "";
|
|
2318
2328
|
const producerEpoch = validateIdentity(hostSourceRef, installationRef, value.producer_epoch, options.error);
|
|
@@ -2323,7 +2333,7 @@ function decodeProducerConfigCore(text, options) {
|
|
|
2323
2333
|
assertProducerAbsolutePath(value[key], options.platform, "runtime", options.error);
|
|
2324
2334
|
extraPaths[key] = value[key];
|
|
2325
2335
|
}
|
|
2326
|
-
const intervals = validateIntervals(value.reconcile_interval_ms, value.retry_backoff_ms, value.ipc_timeout_ms, options.error);
|
|
2336
|
+
const intervals = validateIntervals(value.reconcile_interval_ms === void 0 ? HOST_PRODUCER_TIMING_DEFAULTS.reconcile_interval_ms : value.reconcile_interval_ms, value.retry_backoff_ms === void 0 ? HOST_PRODUCER_TIMING_DEFAULTS.retry_backoff_ms : value.retry_backoff_ms, value.ipc_timeout_ms === void 0 ? HOST_PRODUCER_TIMING_DEFAULTS.ipc_timeout_ms : value.ipc_timeout_ms, options.error);
|
|
2327
2337
|
return {
|
|
2328
2338
|
extra_paths: Object.freeze(extraPaths),
|
|
2329
2339
|
host_source_ref: hostSourceRef,
|
|
@@ -2352,7 +2362,7 @@ async function configPathStat(configPath, error) {
|
|
|
2352
2362
|
}
|
|
2353
2363
|
function validateConfigFile(value, platform, error) {
|
|
2354
2364
|
if (!value.isFile() || value.isSymbolicLink()) throw error("invalid_config", refusalFacts([{ name: "config_is_file", value: value.isFile(), expected: "true" }, { name: "config_is_symlink", value: value.isSymbolicLink(), expected: "false" }]));
|
|
2355
|
-
if (value.size <= 0 || value.size >
|
|
2365
|
+
if (value.size <= 0 || value.size > CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES) throw error("invalid_config", refusalFact("config_bytes", value.size, `between 1 and ${CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES}`));
|
|
2356
2366
|
if (platform !== "win32" && (value.uid !== process.getuid?.() || (value.mode & 63) !== 0)) throw error("config_not_private", refusalFacts([{ name: "platform", value: platform, expected: "win32 or owner-private" }, { name: "config_uid", value: value.uid, expected: "the current user" }, { name: "config_mode", value: value.mode, expected: "owner-private" }]));
|
|
2357
2367
|
}
|
|
2358
2368
|
async function openConfigFile(configPath, flags, error) {
|
|
@@ -2366,12 +2376,17 @@ function validateOpenedFile(opened, pathStat, platform, error) {
|
|
|
2366
2376
|
if (!opened.isFile()) throw error("config_unavailable", refusalFacts([{ name: "opened_is_file", value: opened.isFile(), expected: "true" }, { name: "opened_mode", value: opened.mode.toString(8), expected: "a regular file mode" }]));
|
|
2367
2377
|
if (platform !== "win32" && (opened.dev !== pathStat.dev || opened.ino !== pathStat.ino)) throw error("config_unavailable", refusalFacts([{ name: "platform", value: platform, expected: "win32, or the same file the path named" }, { name: "opened_device", value: opened.dev, expected: String(pathStat.dev) }, { name: "opened_inode", value: opened.ino, expected: String(pathStat.ino) }]));
|
|
2368
2378
|
}
|
|
2369
|
-
async function readBoundedConfig(handle, error) {
|
|
2370
|
-
const buffer = Buffer.allocUnsafe(
|
|
2371
|
-
|
|
2372
|
-
|
|
2379
|
+
async function readBoundedConfig(handle, expectedBytes, error) {
|
|
2380
|
+
const buffer = Buffer.allocUnsafe(expectedBytes + 1);
|
|
2381
|
+
let offset = 0;
|
|
2382
|
+
while (offset < buffer.byteLength) {
|
|
2383
|
+
const { bytesRead } = await handle.read(buffer, offset, buffer.byteLength - offset, offset);
|
|
2384
|
+
if (bytesRead === 0) break;
|
|
2385
|
+
offset += bytesRead;
|
|
2386
|
+
}
|
|
2387
|
+
if (offset !== expectedBytes) throw error("invalid_config", refusalFact("bytes_read", offset, `the opened file's ${expectedBytes} bytes without growth or truncation`));
|
|
2373
2388
|
try {
|
|
2374
|
-
return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0,
|
|
2389
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0, offset));
|
|
2375
2390
|
} catch {
|
|
2376
2391
|
throw error("invalid_config");
|
|
2377
2392
|
}
|
|
@@ -2399,9 +2414,8 @@ function validateIntervals(reconcile, retry, timeout, error) {
|
|
|
2399
2414
|
if (!boundedMilliseconds(reconcile) || !boundedMilliseconds(retry) || !boundedMilliseconds(timeout)) throw error("invalid_config");
|
|
2400
2415
|
return [reconcile, retry, timeout];
|
|
2401
2416
|
}
|
|
2402
|
-
function
|
|
2403
|
-
|
|
2404
|
-
return observed.length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
2417
|
+
function hasConfigKeys(value, required) {
|
|
2418
|
+
return required.every((key) => Object.hasOwn(value, key)) && Object.keys(value).every((key) => required.includes(key) || Object.hasOwn(HOST_PRODUCER_TIMING_DEFAULTS, key));
|
|
2405
2419
|
}
|
|
2406
2420
|
function isRecord(value) {
|
|
2407
2421
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -98,7 +98,6 @@ var client_wire_contract_default = {
|
|
|
98
98
|
length: 72,
|
|
99
99
|
pattern: "^catalog:[a-f0-9]{64}$"
|
|
100
100
|
},
|
|
101
|
-
max_bytes: 4194304,
|
|
102
101
|
envelope_max_bytes: 389
|
|
103
102
|
},
|
|
104
103
|
command_request: {
|
|
@@ -185,8 +184,7 @@ var client_wire_contract_default = {
|
|
|
185
184
|
],
|
|
186
185
|
exit_code_max: 125,
|
|
187
186
|
bare_document_max_bytes: 65536,
|
|
188
|
-
complete_max_bytes: 66019
|
|
189
|
-
absolute_transport_max_bytes: 4194304
|
|
187
|
+
complete_max_bytes: 66019
|
|
190
188
|
},
|
|
191
189
|
resource_stream: {
|
|
192
190
|
path: "/api/ceal/v2/resources",
|
|
@@ -201,6 +199,9 @@ var client_wire_contract_default = {
|
|
|
201
199
|
"fetch"
|
|
202
200
|
],
|
|
203
201
|
ref_flag: "--ref"
|
|
202
|
+
},
|
|
203
|
+
encoded_json_document: {
|
|
204
|
+
max_bytes: 4194304
|
|
204
205
|
}
|
|
205
206
|
};
|
|
206
207
|
|
|
@@ -210,6 +211,7 @@ var commandResolution = CEAL_CLIENT_WIRE_CONTRACT.command_resolution;
|
|
|
210
211
|
var commandResolutionAuthority = commandResolution.authority;
|
|
211
212
|
var commandResolutionSemanticOptions = commandResolution.semantic_options;
|
|
212
213
|
var CEAL_GATEWAY_COMMAND_RESOLUTION_SCHEMA_VERSION = commandResolution.schema_version;
|
|
214
|
+
var CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES = CEAL_CLIENT_WIRE_CONTRACT.encoded_json_document.max_bytes;
|
|
213
215
|
var artifact = CEAL_CLIENT_WIRE_CONTRACT.artifact_descriptor;
|
|
214
216
|
var request = CEAL_CLIENT_WIRE_CONTRACT.command_request;
|
|
215
217
|
var response = CEAL_CLIENT_WIRE_CONTRACT.command_response;
|
|
@@ -223,7 +225,7 @@ var CEAL_VERIFIED_ARTIFACT_DIGEST_LENGTH = artifact.digest.length;
|
|
|
223
225
|
var CEAL_VERIFIED_ARTIFACT_DIGEST_PATTERN = artifact.digest.pattern;
|
|
224
226
|
var CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_LENGTH = artifact.catalog_revision.length;
|
|
225
227
|
var CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_PATTERN = artifact.catalog_revision.pattern;
|
|
226
|
-
var CEAL_VERIFIED_ARTIFACT_MAX_BYTES =
|
|
228
|
+
var CEAL_VERIFIED_ARTIFACT_MAX_BYTES = CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES;
|
|
227
229
|
var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_MAX_BYTES = artifact.envelope_max_bytes;
|
|
228
230
|
var CEAL_COMMAND_REQUEST_SCHEMA_VERSION = request.schema_version;
|
|
229
231
|
var CEAL_COMMAND_REQUEST_MAX_BYTES = request.absolute_transport_max_bytes;
|
|
@@ -237,7 +239,6 @@ var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_CONTINUATION_DOCUMENT_FIELDS = Object.f
|
|
|
237
239
|
var CEAL_COMMAND_RESPONSE_DISCOVERY_COMMAND = response.discovery_command;
|
|
238
240
|
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_SCHEMA_VERSION = response.discovery_manifest_schema_version;
|
|
239
241
|
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_DOCUMENT_FIELDS = Object.freeze([...response.discovery_manifest_document_fields]);
|
|
240
|
-
var CEAL_COMMAND_RESPONSE_MAX_BYTES = response.absolute_transport_max_bytes;
|
|
241
242
|
|
|
242
243
|
// packages/ceal-client-protocol/src/vocabulary.ts
|
|
243
244
|
function vocabulary(words) {
|
|
@@ -528,7 +529,6 @@ function cut(text) {
|
|
|
528
529
|
var CEAL_OPERATION_ACCESS_CLASSES = vocabulary(["read", "write"]);
|
|
529
530
|
|
|
530
531
|
// packages/ceal-client-protocol/src/domain-vocabulary.ts
|
|
531
|
-
var CEAL_INTEGRATION_KINDS = vocabulary(["github", "google-workspace", "notion", "slack"]);
|
|
532
532
|
var CEAL_CONNECTOR_STATUSES = vocabulary(["active", "disabled", "disconnected"]);
|
|
533
533
|
var CEAL_CONNECTOR_CUSTODIES = vocabulary(["organization", "personal"]);
|
|
534
534
|
var CEAL_PROVIDER_BOUNDARY_KINDS = vocabulary([
|
|
@@ -894,7 +894,7 @@ var NON_REMEDY_NEXT_ACTION_VALUES = [
|
|
|
894
894
|
"operator_action",
|
|
895
895
|
"recover",
|
|
896
896
|
"reconcile",
|
|
897
|
-
// Reconciliation of one named occurrence, not of the deployment:
|
|
897
|
+
// Reconciliation of one named occurrence, not of the deployment: an
|
|
898
898
|
// occurrence with no admitted input commitment cannot be replayed safely and
|
|
899
899
|
// no edit to the call changes that. `reconcile` is the deployment-wide word.
|
|
900
900
|
"reconcile_occurrence",
|
|
@@ -1024,7 +1024,7 @@ var CEAL_ACTIVITY_V3_KINDS = vocabulary(["authored", "edited", "messaged", "resp
|
|
|
1024
1024
|
var CEAL_RESOURCE_TIME_BASES = vocabulary(["created", "modified", "viewed"]);
|
|
1025
1025
|
var CEAL_RESOURCE_SEARCH_ORDERS = vocabulary(["relevance", "modified", "viewed", "created"]);
|
|
1026
1026
|
var CEAL_RESOURCE_SEARCH_DIRECTIONS = vocabulary(["ascending", "descending"]);
|
|
1027
|
-
var CEAL_RESOURCE_SEARCH_FILTERS = vocabulary(["query", "modified_since", "since", "until", "authored_by_me", "include_replies", "kinds", "container_ref", "container_refs", "addressed_to_me", "unread"]);
|
|
1027
|
+
var CEAL_RESOURCE_SEARCH_FILTERS = vocabulary(["query", "modified_since", "since", "until", "authored_by_me", "include_replies", "kinds", "container_ref", "container_refs", "container_names", "addressed_to_me", "unread"]);
|
|
1028
1028
|
var CEAL_ARTIFACT_STAGE_TERMINALS = vocabulary(["chunk_accepted", "artifact_ready", "idempotency_replayed"]);
|
|
1029
1029
|
var CEAL_READ_ITEM_KINDS = vocabulary(["conversation", "identity", "usergroup", "message", "file", "document"]);
|
|
1030
1030
|
var CEAL_LEASED_MESSAGE_SEARCH_COMPLETENESS = vocabulary(["complete", "continuation_available", "truncated"]);
|
|
@@ -1078,6 +1078,7 @@ var RESOURCE_ROW_KEY_RULES = Object.freeze({
|
|
|
1078
1078
|
title: { required: true, timestamp: false },
|
|
1079
1079
|
container_label: { required: true, timestamp: false },
|
|
1080
1080
|
container_ref: { required: false, timestamp: false },
|
|
1081
|
+
source_url: { required: false, timestamp: false },
|
|
1081
1082
|
source: { required: true, timestamp: false },
|
|
1082
1083
|
owner: { required: false, timestamp: false },
|
|
1083
1084
|
counterparts: { required: false, timestamp: false },
|
|
@@ -1437,6 +1438,18 @@ var CEAL_REQUEST_GRAPH_NODE_PREPARE_READINESS_JSON_SCHEMA = {
|
|
|
1437
1438
|
required: ["node_ref", "operation_id", "resolver_owned", "gateway_derived"]
|
|
1438
1439
|
};
|
|
1439
1440
|
|
|
1441
|
+
// packages/ceal-client-protocol/src/host-invocation-authentication.ts
|
|
1442
|
+
var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA = "ceal.host_invocation_authentication_result.v1";
|
|
1443
|
+
var CEAL_HOST_NONCE_ENCODED_CHARACTERS = 43;
|
|
1444
|
+
var CEAL_HOST_CLIENT_NONCE_PATTERN = new RegExp(`^[A-Za-z0-9_-]{${CEAL_HOST_NONCE_ENCODED_CHARACTERS}}$`, "u");
|
|
1445
|
+
var CEAL_HOST_CONTEXT_TOKEN_PATTERN = new RegExp(`^ceal_context_[A-Za-z0-9_-]{${CEAL_HOST_NONCE_ENCODED_CHARACTERS}}$`, "u");
|
|
1446
|
+
var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_MAX_BYTES = new TextEncoder().encode(`${JSON.stringify({
|
|
1447
|
+
schema_version: CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA,
|
|
1448
|
+
context_token: `ceal_context_${"A".repeat(CEAL_HOST_NONCE_ENCODED_CHARACTERS)}`,
|
|
1449
|
+
expires_at: (/* @__PURE__ */ new Date("+010000-01-01T00:00:00.000Z")).toISOString()
|
|
1450
|
+
})}
|
|
1451
|
+
`).byteLength;
|
|
1452
|
+
|
|
1440
1453
|
// packages/ceal-client-protocol/src/client-result-materialization.ts
|
|
1441
1454
|
var CEAL_MODEL_VISIBLE_COMMAND_OUTPUT_MAX_BYTES = 32 * 1024;
|
|
1442
1455
|
var REQUIRED_FIELDS2 = Object.freeze(["schema_version", "operation_id", "read_argv"]);
|
|
@@ -1590,7 +1603,6 @@ function waitForAbort(signal, milliseconds) {
|
|
|
1590
1603
|
}
|
|
1591
1604
|
|
|
1592
1605
|
// host/producer-service.ts
|
|
1593
|
-
var MAX_CONFIG_BYTES = 32 * 1024;
|
|
1594
1606
|
var SAFE_REF2 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
1595
1607
|
var HOST_PRODUCER_SERVE_COMMAND_PREFIX = ["serve", "--config"];
|
|
1596
1608
|
var HostProducerServiceError = class extends Error {
|
|
@@ -1601,7 +1613,8 @@ var HostProducerServiceError = class extends Error {
|
|
|
1601
1613
|
this.code = code3;
|
|
1602
1614
|
}
|
|
1603
1615
|
};
|
|
1604
|
-
var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint"
|
|
1616
|
+
var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint"];
|
|
1617
|
+
var HOST_PRODUCER_TIMING_DEFAULTS = Object.freeze({ reconcile_interval_ms: 250, retry_backoff_ms: 1e3, ipc_timeout_ms: 5e3 });
|
|
1605
1618
|
function parseHostProducerServeArgs(args, platform = process.platform) {
|
|
1606
1619
|
return parseProducerServeArgs(args, platform, hostProducerError);
|
|
1607
1620
|
}
|
|
@@ -1643,15 +1656,17 @@ async function readProducerConfigText(configPath, platform, error) {
|
|
|
1643
1656
|
const noFollow = typeof constants.O_NOFOLLOW === "number" ? constants.O_NOFOLLOW : 0;
|
|
1644
1657
|
const handle = await openConfigFile(configPath, constants.O_RDONLY | noFollow, error);
|
|
1645
1658
|
try {
|
|
1646
|
-
|
|
1647
|
-
|
|
1659
|
+
const opened = await handle.stat();
|
|
1660
|
+
validateConfigFile(opened, platform, error);
|
|
1661
|
+
validateOpenedFile(opened, pathStat, platform, error);
|
|
1662
|
+
return await readBoundedConfig(handle, opened.size, error);
|
|
1648
1663
|
} finally {
|
|
1649
1664
|
await handle.close();
|
|
1650
1665
|
}
|
|
1651
1666
|
}
|
|
1652
1667
|
function decodeProducerConfigCore(text, options) {
|
|
1653
1668
|
const value = parseCanonicalJson(text, options.error);
|
|
1654
|
-
if (!isRecord(value) || !
|
|
1669
|
+
if (!isRecord(value) || !hasConfigKeys(value, options.keys) || value.schema_version !== options.schema) throw options.error("invalid_config");
|
|
1655
1670
|
const hostSourceRef = typeof value.host_source_ref === "string" ? value.host_source_ref : "";
|
|
1656
1671
|
const installationRef = typeof value.producer_installation_ref === "string" ? value.producer_installation_ref : "";
|
|
1657
1672
|
const producerEpoch = validateIdentity(hostSourceRef, installationRef, value.producer_epoch, options.error);
|
|
@@ -1662,7 +1677,7 @@ function decodeProducerConfigCore(text, options) {
|
|
|
1662
1677
|
assertProducerAbsolutePath(value[key], options.platform, "runtime", options.error);
|
|
1663
1678
|
extraPaths[key] = value[key];
|
|
1664
1679
|
}
|
|
1665
|
-
const intervals = validateIntervals(value.reconcile_interval_ms, value.retry_backoff_ms, value.ipc_timeout_ms, options.error);
|
|
1680
|
+
const intervals = validateIntervals(value.reconcile_interval_ms === void 0 ? HOST_PRODUCER_TIMING_DEFAULTS.reconcile_interval_ms : value.reconcile_interval_ms, value.retry_backoff_ms === void 0 ? HOST_PRODUCER_TIMING_DEFAULTS.retry_backoff_ms : value.retry_backoff_ms, value.ipc_timeout_ms === void 0 ? HOST_PRODUCER_TIMING_DEFAULTS.ipc_timeout_ms : value.ipc_timeout_ms, options.error);
|
|
1666
1681
|
return {
|
|
1667
1682
|
extra_paths: Object.freeze(extraPaths),
|
|
1668
1683
|
host_source_ref: hostSourceRef,
|
|
@@ -1702,7 +1717,7 @@ async function configPathStat(configPath, error) {
|
|
|
1702
1717
|
}
|
|
1703
1718
|
function validateConfigFile(value, platform, error) {
|
|
1704
1719
|
if (!value.isFile() || value.isSymbolicLink()) throw error("invalid_config", refusalFacts([{ name: "config_is_file", value: value.isFile(), expected: "true" }, { name: "config_is_symlink", value: value.isSymbolicLink(), expected: "false" }]));
|
|
1705
|
-
if (value.size <= 0 || value.size >
|
|
1720
|
+
if (value.size <= 0 || value.size > CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES) throw error("invalid_config", refusalFact("config_bytes", value.size, `between 1 and ${CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES}`));
|
|
1706
1721
|
if (platform !== "win32" && (value.uid !== process.getuid?.() || (value.mode & 63) !== 0)) throw error("config_not_private", refusalFacts([{ name: "platform", value: platform, expected: "win32 or owner-private" }, { name: "config_uid", value: value.uid, expected: "the current user" }, { name: "config_mode", value: value.mode, expected: "owner-private" }]));
|
|
1707
1722
|
}
|
|
1708
1723
|
async function openConfigFile(configPath, flags, error) {
|
|
@@ -1716,12 +1731,17 @@ function validateOpenedFile(opened, pathStat, platform, error) {
|
|
|
1716
1731
|
if (!opened.isFile()) throw error("config_unavailable", refusalFacts([{ name: "opened_is_file", value: opened.isFile(), expected: "true" }, { name: "opened_mode", value: opened.mode.toString(8), expected: "a regular file mode" }]));
|
|
1717
1732
|
if (platform !== "win32" && (opened.dev !== pathStat.dev || opened.ino !== pathStat.ino)) throw error("config_unavailable", refusalFacts([{ name: "platform", value: platform, expected: "win32, or the same file the path named" }, { name: "opened_device", value: opened.dev, expected: String(pathStat.dev) }, { name: "opened_inode", value: opened.ino, expected: String(pathStat.ino) }]));
|
|
1718
1733
|
}
|
|
1719
|
-
async function readBoundedConfig(handle, error) {
|
|
1720
|
-
const buffer = Buffer.allocUnsafe(
|
|
1721
|
-
|
|
1722
|
-
|
|
1734
|
+
async function readBoundedConfig(handle, expectedBytes, error) {
|
|
1735
|
+
const buffer = Buffer.allocUnsafe(expectedBytes + 1);
|
|
1736
|
+
let offset = 0;
|
|
1737
|
+
while (offset < buffer.byteLength) {
|
|
1738
|
+
const { bytesRead } = await handle.read(buffer, offset, buffer.byteLength - offset, offset);
|
|
1739
|
+
if (bytesRead === 0) break;
|
|
1740
|
+
offset += bytesRead;
|
|
1741
|
+
}
|
|
1742
|
+
if (offset !== expectedBytes) throw error("invalid_config", refusalFact("bytes_read", offset, `the opened file's ${expectedBytes} bytes without growth or truncation`));
|
|
1723
1743
|
try {
|
|
1724
|
-
return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0,
|
|
1744
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0, offset));
|
|
1725
1745
|
} catch {
|
|
1726
1746
|
throw error("invalid_config");
|
|
1727
1747
|
}
|
|
@@ -1749,9 +1769,8 @@ function validateIntervals(reconcile, retry, timeout, error) {
|
|
|
1749
1769
|
if (!boundedMilliseconds(reconcile) || !boundedMilliseconds(retry) || !boundedMilliseconds(timeout)) throw error("invalid_config");
|
|
1750
1770
|
return [reconcile, retry, timeout];
|
|
1751
1771
|
}
|
|
1752
|
-
function
|
|
1753
|
-
|
|
1754
|
-
return observed.length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
1772
|
+
function hasConfigKeys(value, required) {
|
|
1773
|
+
return required.every((key) => Object.hasOwn(value, key)) && Object.keys(value).every((key) => required.includes(key) || Object.hasOwn(HOST_PRODUCER_TIMING_DEFAULTS, key));
|
|
1755
1774
|
}
|
|
1756
1775
|
function isRecord(value) {
|
|
1757
1776
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|