@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
|
@@ -62,7 +62,6 @@ var client_wire_contract_default = {
|
|
|
62
62
|
length: 72,
|
|
63
63
|
pattern: "^catalog:[a-f0-9]{64}$"
|
|
64
64
|
},
|
|
65
|
-
max_bytes: 4194304,
|
|
66
65
|
envelope_max_bytes: 389
|
|
67
66
|
},
|
|
68
67
|
command_request: {
|
|
@@ -149,8 +148,7 @@ var client_wire_contract_default = {
|
|
|
149
148
|
],
|
|
150
149
|
exit_code_max: 125,
|
|
151
150
|
bare_document_max_bytes: 65536,
|
|
152
|
-
complete_max_bytes: 66019
|
|
153
|
-
absolute_transport_max_bytes: 4194304
|
|
151
|
+
complete_max_bytes: 66019
|
|
154
152
|
},
|
|
155
153
|
resource_stream: {
|
|
156
154
|
path: "/api/ceal/v2/resources",
|
|
@@ -165,6 +163,9 @@ var client_wire_contract_default = {
|
|
|
165
163
|
"fetch"
|
|
166
164
|
],
|
|
167
165
|
ref_flag: "--ref"
|
|
166
|
+
},
|
|
167
|
+
encoded_json_document: {
|
|
168
|
+
max_bytes: 4194304
|
|
168
169
|
}
|
|
169
170
|
};
|
|
170
171
|
|
|
@@ -174,6 +175,7 @@ var commandResolution = CEAL_CLIENT_WIRE_CONTRACT.command_resolution;
|
|
|
174
175
|
var commandResolutionAuthority = commandResolution.authority;
|
|
175
176
|
var commandResolutionSemanticOptions = commandResolution.semantic_options;
|
|
176
177
|
var CEAL_GATEWAY_COMMAND_RESOLUTION_SCHEMA_VERSION = commandResolution.schema_version;
|
|
178
|
+
var CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES = CEAL_CLIENT_WIRE_CONTRACT.encoded_json_document.max_bytes;
|
|
177
179
|
var artifact = CEAL_CLIENT_WIRE_CONTRACT.artifact_descriptor;
|
|
178
180
|
var request = CEAL_CLIENT_WIRE_CONTRACT.command_request;
|
|
179
181
|
var response = CEAL_CLIENT_WIRE_CONTRACT.command_response;
|
|
@@ -187,7 +189,7 @@ var CEAL_VERIFIED_ARTIFACT_DIGEST_LENGTH = artifact.digest.length;
|
|
|
187
189
|
var CEAL_VERIFIED_ARTIFACT_DIGEST_PATTERN = artifact.digest.pattern;
|
|
188
190
|
var CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_LENGTH = artifact.catalog_revision.length;
|
|
189
191
|
var CEAL_VERIFIED_ARTIFACT_CATALOG_REVISION_PATTERN = artifact.catalog_revision.pattern;
|
|
190
|
-
var CEAL_VERIFIED_ARTIFACT_MAX_BYTES =
|
|
192
|
+
var CEAL_VERIFIED_ARTIFACT_MAX_BYTES = CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES;
|
|
191
193
|
var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_MAX_BYTES = artifact.envelope_max_bytes;
|
|
192
194
|
var CEAL_COMMAND_REQUEST_SCHEMA_VERSION = request.schema_version;
|
|
193
195
|
var CEAL_COMMAND_REQUEST_MAX_BYTES = request.absolute_transport_max_bytes;
|
|
@@ -201,7 +203,6 @@ var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_CONTINUATION_DOCUMENT_FIELDS = Object.f
|
|
|
201
203
|
var CEAL_COMMAND_RESPONSE_DISCOVERY_COMMAND = response.discovery_command;
|
|
202
204
|
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_SCHEMA_VERSION = response.discovery_manifest_schema_version;
|
|
203
205
|
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_DOCUMENT_FIELDS = Object.freeze([...response.discovery_manifest_document_fields]);
|
|
204
|
-
var CEAL_COMMAND_RESPONSE_MAX_BYTES = response.absolute_transport_max_bytes;
|
|
205
206
|
|
|
206
207
|
// packages/ceal-client-protocol/src/vocabulary.ts
|
|
207
208
|
function vocabulary(words) {
|
|
@@ -492,7 +493,6 @@ function cut(text) {
|
|
|
492
493
|
var CEAL_OPERATION_ACCESS_CLASSES = vocabulary(["read", "write"]);
|
|
493
494
|
|
|
494
495
|
// packages/ceal-client-protocol/src/domain-vocabulary.ts
|
|
495
|
-
var CEAL_INTEGRATION_KINDS = vocabulary(["github", "google-workspace", "notion", "slack"]);
|
|
496
496
|
var CEAL_CONNECTOR_STATUSES = vocabulary(["active", "disabled", "disconnected"]);
|
|
497
497
|
var CEAL_CONNECTOR_CUSTODIES = vocabulary(["organization", "personal"]);
|
|
498
498
|
var CEAL_PROVIDER_BOUNDARY_KINDS = vocabulary([
|
|
@@ -858,7 +858,7 @@ var NON_REMEDY_NEXT_ACTION_VALUES = [
|
|
|
858
858
|
"operator_action",
|
|
859
859
|
"recover",
|
|
860
860
|
"reconcile",
|
|
861
|
-
// Reconciliation of one named occurrence, not of the deployment:
|
|
861
|
+
// Reconciliation of one named occurrence, not of the deployment: an
|
|
862
862
|
// occurrence with no admitted input commitment cannot be replayed safely and
|
|
863
863
|
// no edit to the call changes that. `reconcile` is the deployment-wide word.
|
|
864
864
|
"reconcile_occurrence",
|
|
@@ -988,7 +988,7 @@ var CEAL_ACTIVITY_V3_KINDS = vocabulary(["authored", "edited", "messaged", "resp
|
|
|
988
988
|
var CEAL_RESOURCE_TIME_BASES = vocabulary(["created", "modified", "viewed"]);
|
|
989
989
|
var CEAL_RESOURCE_SEARCH_ORDERS = vocabulary(["relevance", "modified", "viewed", "created"]);
|
|
990
990
|
var CEAL_RESOURCE_SEARCH_DIRECTIONS = vocabulary(["ascending", "descending"]);
|
|
991
|
-
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"]);
|
|
991
|
+
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"]);
|
|
992
992
|
var CEAL_ARTIFACT_STAGE_TERMINALS = vocabulary(["chunk_accepted", "artifact_ready", "idempotency_replayed"]);
|
|
993
993
|
var CEAL_READ_ITEM_KINDS = vocabulary(["conversation", "identity", "usergroup", "message", "file", "document"]);
|
|
994
994
|
var CEAL_LEASED_MESSAGE_SEARCH_COMPLETENESS = vocabulary(["complete", "continuation_available", "truncated"]);
|
|
@@ -1042,6 +1042,7 @@ var RESOURCE_ROW_KEY_RULES = Object.freeze({
|
|
|
1042
1042
|
title: { required: true, timestamp: false },
|
|
1043
1043
|
container_label: { required: true, timestamp: false },
|
|
1044
1044
|
container_ref: { required: false, timestamp: false },
|
|
1045
|
+
source_url: { required: false, timestamp: false },
|
|
1045
1046
|
source: { required: true, timestamp: false },
|
|
1046
1047
|
owner: { required: false, timestamp: false },
|
|
1047
1048
|
counterparts: { required: false, timestamp: false },
|
|
@@ -1411,6 +1412,18 @@ var CEAL_REQUEST_GRAPH_NODE_PREPARE_READINESS_JSON_SCHEMA = {
|
|
|
1411
1412
|
required: ["node_ref", "operation_id", "resolver_owned", "gateway_derived"]
|
|
1412
1413
|
};
|
|
1413
1414
|
|
|
1415
|
+
// packages/ceal-client-protocol/src/host-invocation-authentication.ts
|
|
1416
|
+
var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA = "ceal.host_invocation_authentication_result.v1";
|
|
1417
|
+
var CEAL_HOST_NONCE_ENCODED_CHARACTERS = 43;
|
|
1418
|
+
var CEAL_HOST_CLIENT_NONCE_PATTERN = new RegExp(`^[A-Za-z0-9_-]{${CEAL_HOST_NONCE_ENCODED_CHARACTERS}}$`, "u");
|
|
1419
|
+
var CEAL_HOST_CONTEXT_TOKEN_PATTERN = new RegExp(`^ceal_context_[A-Za-z0-9_-]{${CEAL_HOST_NONCE_ENCODED_CHARACTERS}}$`, "u");
|
|
1420
|
+
var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_MAX_BYTES = new TextEncoder().encode(`${JSON.stringify({
|
|
1421
|
+
schema_version: CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA,
|
|
1422
|
+
context_token: `ceal_context_${"A".repeat(CEAL_HOST_NONCE_ENCODED_CHARACTERS)}`,
|
|
1423
|
+
expires_at: (/* @__PURE__ */ new Date("+010000-01-01T00:00:00.000Z")).toISOString()
|
|
1424
|
+
})}
|
|
1425
|
+
`).byteLength;
|
|
1426
|
+
|
|
1414
1427
|
// packages/ceal-client-protocol/src/client-result-materialization.ts
|
|
1415
1428
|
var CEAL_MODEL_VISIBLE_COMMAND_OUTPUT_MAX_BYTES = 32 * 1024;
|
|
1416
1429
|
var REQUIRED_FIELDS2 = Object.freeze(["schema_version", "operation_id", "read_argv"]);
|
|
@@ -2991,7 +3004,6 @@ function assertHostProducerSourcePaths(stateRoot, config, producer, platform = p
|
|
|
2991
3004
|
// host/producer-service.ts
|
|
2992
3005
|
import { constants } from "node:fs";
|
|
2993
3006
|
import { lstat as lstat3, open as open4 } from "node:fs/promises";
|
|
2994
|
-
var MAX_CONFIG_BYTES = 32 * 1024;
|
|
2995
3007
|
var SAFE_REF7 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
2996
3008
|
var HOST_PRODUCER_CONFIG_FLAG = "--ceal-host-config";
|
|
2997
3009
|
var HostProducerServiceError = class extends Error {
|
|
@@ -3002,7 +3014,8 @@ var HostProducerServiceError = class extends Error {
|
|
|
3002
3014
|
this.code = code;
|
|
3003
3015
|
}
|
|
3004
3016
|
};
|
|
3005
|
-
var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint"
|
|
3017
|
+
var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint"];
|
|
3018
|
+
var HOST_PRODUCER_TIMING_DEFAULTS = Object.freeze({ reconcile_interval_ms: 250, retry_backoff_ms: 1e3, ipc_timeout_ms: 5e3 });
|
|
3006
3019
|
function hostProducerExtraPath(extras, key) {
|
|
3007
3020
|
const value = extras[key];
|
|
3008
3021
|
if (value === void 0) throw hostProducerError("invalid_config");
|
|
@@ -3046,15 +3059,17 @@ async function readProducerConfigText(configPath, platform, error) {
|
|
|
3046
3059
|
const noFollow = typeof constants.O_NOFOLLOW === "number" ? constants.O_NOFOLLOW : 0;
|
|
3047
3060
|
const handle = await openConfigFile(configPath, constants.O_RDONLY | noFollow, error);
|
|
3048
3061
|
try {
|
|
3049
|
-
|
|
3050
|
-
|
|
3062
|
+
const opened = await handle.stat();
|
|
3063
|
+
validateConfigFile(opened, platform, error);
|
|
3064
|
+
validateOpenedFile(opened, pathStat, platform, error);
|
|
3065
|
+
return await readBoundedConfig(handle, opened.size, error);
|
|
3051
3066
|
} finally {
|
|
3052
3067
|
await handle.close();
|
|
3053
3068
|
}
|
|
3054
3069
|
}
|
|
3055
3070
|
function decodeProducerConfigCore(text, options) {
|
|
3056
3071
|
const value = parseCanonicalJson(text, options.error);
|
|
3057
|
-
if (!isRecord6(value) || !
|
|
3072
|
+
if (!isRecord6(value) || !hasConfigKeys(value, options.keys) || value.schema_version !== options.schema) throw options.error("invalid_config");
|
|
3058
3073
|
const hostSourceRef = typeof value.host_source_ref === "string" ? value.host_source_ref : "";
|
|
3059
3074
|
const installationRef = typeof value.producer_installation_ref === "string" ? value.producer_installation_ref : "";
|
|
3060
3075
|
const producerEpoch = validateIdentity3(hostSourceRef, installationRef, value.producer_epoch, options.error);
|
|
@@ -3065,7 +3080,7 @@ function decodeProducerConfigCore(text, options) {
|
|
|
3065
3080
|
assertProducerAbsolutePath(value[key], options.platform, "runtime", options.error);
|
|
3066
3081
|
extraPaths[key] = value[key];
|
|
3067
3082
|
}
|
|
3068
|
-
const intervals = validateIntervals(value.reconcile_interval_ms, value.retry_backoff_ms, value.ipc_timeout_ms, options.error);
|
|
3083
|
+
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);
|
|
3069
3084
|
return {
|
|
3070
3085
|
extra_paths: Object.freeze(extraPaths),
|
|
3071
3086
|
host_source_ref: hostSourceRef,
|
|
@@ -3094,7 +3109,7 @@ async function configPathStat(configPath, error) {
|
|
|
3094
3109
|
}
|
|
3095
3110
|
function validateConfigFile(value, platform, error) {
|
|
3096
3111
|
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" }]));
|
|
3097
|
-
if (value.size <= 0 || value.size >
|
|
3112
|
+
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}`));
|
|
3098
3113
|
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" }]));
|
|
3099
3114
|
}
|
|
3100
3115
|
async function openConfigFile(configPath, flags, error) {
|
|
@@ -3108,12 +3123,17 @@ function validateOpenedFile(opened, pathStat, platform, error) {
|
|
|
3108
3123
|
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" }]));
|
|
3109
3124
|
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) }]));
|
|
3110
3125
|
}
|
|
3111
|
-
async function readBoundedConfig(handle, error) {
|
|
3112
|
-
const buffer = Buffer.allocUnsafe(
|
|
3113
|
-
|
|
3114
|
-
|
|
3126
|
+
async function readBoundedConfig(handle, expectedBytes, error) {
|
|
3127
|
+
const buffer = Buffer.allocUnsafe(expectedBytes + 1);
|
|
3128
|
+
let offset = 0;
|
|
3129
|
+
while (offset < buffer.byteLength) {
|
|
3130
|
+
const { bytesRead } = await handle.read(buffer, offset, buffer.byteLength - offset, offset);
|
|
3131
|
+
if (bytesRead === 0) break;
|
|
3132
|
+
offset += bytesRead;
|
|
3133
|
+
}
|
|
3134
|
+
if (offset !== expectedBytes) throw error("invalid_config", refusalFact("bytes_read", offset, `the opened file's ${expectedBytes} bytes without growth or truncation`));
|
|
3115
3135
|
try {
|
|
3116
|
-
return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0,
|
|
3136
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0, offset));
|
|
3117
3137
|
} catch {
|
|
3118
3138
|
throw error("invalid_config");
|
|
3119
3139
|
}
|
|
@@ -3141,9 +3161,8 @@ function validateIntervals(reconcile, retry, timeout, error) {
|
|
|
3141
3161
|
if (!boundedMilliseconds(reconcile) || !boundedMilliseconds(retry) || !boundedMilliseconds(timeout)) throw error("invalid_config");
|
|
3142
3162
|
return [reconcile, retry, timeout];
|
|
3143
3163
|
}
|
|
3144
|
-
function
|
|
3145
|
-
|
|
3146
|
-
return observed.length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
3164
|
+
function hasConfigKeys(value, required) {
|
|
3165
|
+
return required.every((key) => Object.hasOwn(value, key)) && Object.keys(value).every((key) => required.includes(key) || Object.hasOwn(HOST_PRODUCER_TIMING_DEFAULTS, key));
|
|
3147
3166
|
}
|
|
3148
3167
|
function isRecord6(value) {
|
|
3149
3168
|
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 },
|
|
@@ -1409,8 +1410,15 @@ var CEAL_REQUEST_GRAPH_NODE_PREPARE_READINESS_JSON_SCHEMA = {
|
|
|
1409
1410
|
// packages/ceal-client-protocol/src/host-invocation-authentication.ts
|
|
1410
1411
|
var CEAL_HOST_INVOCATION_AUTHENTICATION_REQUEST_SCHEMA = "ceal.host_invocation_authentication_request.v1";
|
|
1411
1412
|
var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA = "ceal.host_invocation_authentication_result.v1";
|
|
1412
|
-
var
|
|
1413
|
-
var
|
|
1413
|
+
var CEAL_HOST_NONCE_ENCODED_CHARACTERS = 43;
|
|
1414
|
+
var CEAL_HOST_CLIENT_NONCE_PATTERN = new RegExp(`^[A-Za-z0-9_-]{${CEAL_HOST_NONCE_ENCODED_CHARACTERS}}$`, "u");
|
|
1415
|
+
var CEAL_HOST_CONTEXT_TOKEN_PATTERN = new RegExp(`^ceal_context_[A-Za-z0-9_-]{${CEAL_HOST_NONCE_ENCODED_CHARACTERS}}$`, "u");
|
|
1416
|
+
var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_MAX_BYTES = new TextEncoder().encode(`${JSON.stringify({
|
|
1417
|
+
schema_version: CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA,
|
|
1418
|
+
context_token: `ceal_context_${"A".repeat(CEAL_HOST_NONCE_ENCODED_CHARACTERS)}`,
|
|
1419
|
+
expires_at: (/* @__PURE__ */ new Date("+010000-01-01T00:00:00.000Z")).toISOString()
|
|
1420
|
+
})}
|
|
1421
|
+
`).byteLength;
|
|
1414
1422
|
function decodeCealHostInvocationAuthenticationRequest(value) {
|
|
1415
1423
|
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)) {
|
|
1416
1424
|
throw new TypeError("The Host invocation authentication request is invalid.");
|
|
@@ -2385,7 +2393,6 @@ function assertHostProducerSourcePaths(stateRoot, config, producer, platform = p
|
|
|
2385
2393
|
// host/producer-service.ts
|
|
2386
2394
|
import { constants } from "node:fs";
|
|
2387
2395
|
import { lstat as lstat2, open as open3 } from "node:fs/promises";
|
|
2388
|
-
var MAX_CONFIG_BYTES = 32 * 1024;
|
|
2389
2396
|
var SAFE_REF4 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
2390
2397
|
var HOST_PRODUCER_CONFIG_FLAG = "--ceal-host-config";
|
|
2391
2398
|
var HostProducerServiceError = class extends Error {
|
|
@@ -2396,7 +2403,8 @@ var HostProducerServiceError = class extends Error {
|
|
|
2396
2403
|
this.code = code;
|
|
2397
2404
|
}
|
|
2398
2405
|
};
|
|
2399
|
-
var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint"
|
|
2406
|
+
var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint"];
|
|
2407
|
+
var HOST_PRODUCER_TIMING_DEFAULTS = Object.freeze({ reconcile_interval_ms: 250, retry_backoff_ms: 1e3, ipc_timeout_ms: 5e3 });
|
|
2400
2408
|
function hostProducerExtraPath(extras, key) {
|
|
2401
2409
|
const value = extras[key];
|
|
2402
2410
|
if (value === void 0) throw hostProducerError("invalid_config");
|
|
@@ -2440,15 +2448,17 @@ async function readProducerConfigText(configPath, platform, error) {
|
|
|
2440
2448
|
const noFollow = typeof constants.O_NOFOLLOW === "number" ? constants.O_NOFOLLOW : 0;
|
|
2441
2449
|
const handle = await openConfigFile(configPath, constants.O_RDONLY | noFollow, error);
|
|
2442
2450
|
try {
|
|
2443
|
-
|
|
2444
|
-
|
|
2451
|
+
const opened = await handle.stat();
|
|
2452
|
+
validateConfigFile(opened, platform, error);
|
|
2453
|
+
validateOpenedFile(opened, pathStat, platform, error);
|
|
2454
|
+
return await readBoundedConfig(handle, opened.size, error);
|
|
2445
2455
|
} finally {
|
|
2446
2456
|
await handle.close();
|
|
2447
2457
|
}
|
|
2448
2458
|
}
|
|
2449
2459
|
function decodeProducerConfigCore(text, options) {
|
|
2450
2460
|
const value = parseCanonicalJson(text, options.error);
|
|
2451
|
-
if (!isRecord2(value) || !
|
|
2461
|
+
if (!isRecord2(value) || !hasConfigKeys(value, options.keys) || value.schema_version !== options.schema) throw options.error("invalid_config");
|
|
2452
2462
|
const hostSourceRef = typeof value.host_source_ref === "string" ? value.host_source_ref : "";
|
|
2453
2463
|
const installationRef = typeof value.producer_installation_ref === "string" ? value.producer_installation_ref : "";
|
|
2454
2464
|
const producerEpoch = validateIdentity(hostSourceRef, installationRef, value.producer_epoch, options.error);
|
|
@@ -2459,7 +2469,7 @@ function decodeProducerConfigCore(text, options) {
|
|
|
2459
2469
|
assertProducerAbsolutePath(value[key], options.platform, "runtime", options.error);
|
|
2460
2470
|
extraPaths[key] = value[key];
|
|
2461
2471
|
}
|
|
2462
|
-
const intervals = validateIntervals(value.reconcile_interval_ms, value.retry_backoff_ms, value.ipc_timeout_ms, options.error);
|
|
2472
|
+
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);
|
|
2463
2473
|
return {
|
|
2464
2474
|
extra_paths: Object.freeze(extraPaths),
|
|
2465
2475
|
host_source_ref: hostSourceRef,
|
|
@@ -2488,7 +2498,7 @@ async function configPathStat(configPath, error) {
|
|
|
2488
2498
|
}
|
|
2489
2499
|
function validateConfigFile(value, platform, error) {
|
|
2490
2500
|
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" }]));
|
|
2491
|
-
if (value.size <= 0 || value.size >
|
|
2501
|
+
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}`));
|
|
2492
2502
|
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" }]));
|
|
2493
2503
|
}
|
|
2494
2504
|
async function openConfigFile(configPath, flags, error) {
|
|
@@ -2502,12 +2512,17 @@ function validateOpenedFile(opened, pathStat, platform, error) {
|
|
|
2502
2512
|
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" }]));
|
|
2503
2513
|
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) }]));
|
|
2504
2514
|
}
|
|
2505
|
-
async function readBoundedConfig(handle, error) {
|
|
2506
|
-
const buffer = Buffer.allocUnsafe(
|
|
2507
|
-
|
|
2508
|
-
|
|
2515
|
+
async function readBoundedConfig(handle, expectedBytes, error) {
|
|
2516
|
+
const buffer = Buffer.allocUnsafe(expectedBytes + 1);
|
|
2517
|
+
let offset = 0;
|
|
2518
|
+
while (offset < buffer.byteLength) {
|
|
2519
|
+
const { bytesRead } = await handle.read(buffer, offset, buffer.byteLength - offset, offset);
|
|
2520
|
+
if (bytesRead === 0) break;
|
|
2521
|
+
offset += bytesRead;
|
|
2522
|
+
}
|
|
2523
|
+
if (offset !== expectedBytes) throw error("invalid_config", refusalFact("bytes_read", offset, `the opened file's ${expectedBytes} bytes without growth or truncation`));
|
|
2509
2524
|
try {
|
|
2510
|
-
return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0,
|
|
2525
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0, offset));
|
|
2511
2526
|
} catch {
|
|
2512
2527
|
throw error("invalid_config");
|
|
2513
2528
|
}
|
|
@@ -2535,9 +2550,8 @@ function validateIntervals(reconcile, retry, timeout, error) {
|
|
|
2535
2550
|
if (!boundedMilliseconds(reconcile) || !boundedMilliseconds(retry) || !boundedMilliseconds(timeout)) throw error("invalid_config");
|
|
2536
2551
|
return [reconcile, retry, timeout];
|
|
2537
2552
|
}
|
|
2538
|
-
function
|
|
2539
|
-
|
|
2540
|
-
return observed.length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
2553
|
+
function hasConfigKeys(value, required) {
|
|
2554
|
+
return required.every((key) => Object.hasOwn(value, key)) && Object.keys(value).every((key) => required.includes(key) || Object.hasOwn(HOST_PRODUCER_TIMING_DEFAULTS, key));
|
|
2541
2555
|
}
|
|
2542
2556
|
function isRecord2(value) {
|
|
2543
2557
|
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 },
|
|
@@ -1447,6 +1448,18 @@ var CEAL_REQUEST_GRAPH_NODE_PREPARE_READINESS_JSON_SCHEMA = {
|
|
|
1447
1448
|
required: ["node_ref", "operation_id", "resolver_owned", "gateway_derived"]
|
|
1448
1449
|
};
|
|
1449
1450
|
|
|
1451
|
+
// packages/ceal-client-protocol/src/host-invocation-authentication.ts
|
|
1452
|
+
var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA = "ceal.host_invocation_authentication_result.v1";
|
|
1453
|
+
var CEAL_HOST_NONCE_ENCODED_CHARACTERS = 43;
|
|
1454
|
+
var CEAL_HOST_CLIENT_NONCE_PATTERN = new RegExp(`^[A-Za-z0-9_-]{${CEAL_HOST_NONCE_ENCODED_CHARACTERS}}$`, "u");
|
|
1455
|
+
var CEAL_HOST_CONTEXT_TOKEN_PATTERN = new RegExp(`^ceal_context_[A-Za-z0-9_-]{${CEAL_HOST_NONCE_ENCODED_CHARACTERS}}$`, "u");
|
|
1456
|
+
var CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_MAX_BYTES = new TextEncoder().encode(`${JSON.stringify({
|
|
1457
|
+
schema_version: CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA,
|
|
1458
|
+
context_token: `ceal_context_${"A".repeat(CEAL_HOST_NONCE_ENCODED_CHARACTERS)}`,
|
|
1459
|
+
expires_at: (/* @__PURE__ */ new Date("+010000-01-01T00:00:00.000Z")).toISOString()
|
|
1460
|
+
})}
|
|
1461
|
+
`).byteLength;
|
|
1462
|
+
|
|
1450
1463
|
// packages/ceal-client-protocol/src/client-result-materialization.ts
|
|
1451
1464
|
var CEAL_MODEL_VISIBLE_COMMAND_OUTPUT_MAX_BYTES = 32 * 1024;
|
|
1452
1465
|
var REQUIRED_FIELDS2 = Object.freeze(["schema_version", "operation_id", "read_argv"]);
|
|
@@ -1600,7 +1613,6 @@ function waitForAbort(signal, milliseconds) {
|
|
|
1600
1613
|
}
|
|
1601
1614
|
|
|
1602
1615
|
// host/producer-service.ts
|
|
1603
|
-
var MAX_CONFIG_BYTES = 32 * 1024;
|
|
1604
1616
|
var SAFE_REF2 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
1605
1617
|
var HOST_PRODUCER_SERVE_COMMAND_PREFIX = ["serve", "--config"];
|
|
1606
1618
|
var HostProducerServiceError = class extends Error {
|
|
@@ -1611,7 +1623,8 @@ var HostProducerServiceError = class extends Error {
|
|
|
1611
1623
|
this.code = code;
|
|
1612
1624
|
}
|
|
1613
1625
|
};
|
|
1614
|
-
var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint"
|
|
1626
|
+
var HOST_PRODUCER_CONFIG_KEYS = ["schema_version", "host_source_ref", "producer_installation_ref", "producer_epoch", "outbox_dir", "relay_endpoint"];
|
|
1627
|
+
var HOST_PRODUCER_TIMING_DEFAULTS = Object.freeze({ reconcile_interval_ms: 250, retry_backoff_ms: 1e3, ipc_timeout_ms: 5e3 });
|
|
1615
1628
|
function hostProducerExtraPath(extras, key) {
|
|
1616
1629
|
const value = extras[key];
|
|
1617
1630
|
if (value === void 0) throw hostProducerError("invalid_config");
|
|
@@ -1658,15 +1671,17 @@ async function readProducerConfigText(configPath, platform, error) {
|
|
|
1658
1671
|
const noFollow = typeof constants.O_NOFOLLOW === "number" ? constants.O_NOFOLLOW : 0;
|
|
1659
1672
|
const handle = await openConfigFile(configPath, constants.O_RDONLY | noFollow, error);
|
|
1660
1673
|
try {
|
|
1661
|
-
|
|
1662
|
-
|
|
1674
|
+
const opened = await handle.stat();
|
|
1675
|
+
validateConfigFile(opened, platform, error);
|
|
1676
|
+
validateOpenedFile(opened, pathStat, platform, error);
|
|
1677
|
+
return await readBoundedConfig(handle, opened.size, error);
|
|
1663
1678
|
} finally {
|
|
1664
1679
|
await handle.close();
|
|
1665
1680
|
}
|
|
1666
1681
|
}
|
|
1667
1682
|
function decodeProducerConfigCore(text, options) {
|
|
1668
1683
|
const value = parseCanonicalJson(text, options.error);
|
|
1669
|
-
if (!isRecord(value) || !
|
|
1684
|
+
if (!isRecord(value) || !hasConfigKeys(value, options.keys) || value.schema_version !== options.schema) throw options.error("invalid_config");
|
|
1670
1685
|
const hostSourceRef = typeof value.host_source_ref === "string" ? value.host_source_ref : "";
|
|
1671
1686
|
const installationRef = typeof value.producer_installation_ref === "string" ? value.producer_installation_ref : "";
|
|
1672
1687
|
const producerEpoch = validateIdentity(hostSourceRef, installationRef, value.producer_epoch, options.error);
|
|
@@ -1677,7 +1692,7 @@ function decodeProducerConfigCore(text, options) {
|
|
|
1677
1692
|
assertProducerAbsolutePath(value[key], options.platform, "runtime", options.error);
|
|
1678
1693
|
extraPaths[key] = value[key];
|
|
1679
1694
|
}
|
|
1680
|
-
const intervals = validateIntervals(value.reconcile_interval_ms, value.retry_backoff_ms, value.ipc_timeout_ms, options.error);
|
|
1695
|
+
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);
|
|
1681
1696
|
return {
|
|
1682
1697
|
extra_paths: Object.freeze(extraPaths),
|
|
1683
1698
|
host_source_ref: hostSourceRef,
|
|
@@ -1717,7 +1732,7 @@ async function configPathStat(configPath, error) {
|
|
|
1717
1732
|
}
|
|
1718
1733
|
function validateConfigFile(value, platform, error) {
|
|
1719
1734
|
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" }]));
|
|
1720
|
-
if (value.size <= 0 || value.size >
|
|
1735
|
+
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}`));
|
|
1721
1736
|
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" }]));
|
|
1722
1737
|
}
|
|
1723
1738
|
async function openConfigFile(configPath, flags, error) {
|
|
@@ -1731,12 +1746,17 @@ function validateOpenedFile(opened, pathStat, platform, error) {
|
|
|
1731
1746
|
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" }]));
|
|
1732
1747
|
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) }]));
|
|
1733
1748
|
}
|
|
1734
|
-
async function readBoundedConfig(handle, error) {
|
|
1735
|
-
const buffer = Buffer.allocUnsafe(
|
|
1736
|
-
|
|
1737
|
-
|
|
1749
|
+
async function readBoundedConfig(handle, expectedBytes, error) {
|
|
1750
|
+
const buffer = Buffer.allocUnsafe(expectedBytes + 1);
|
|
1751
|
+
let offset = 0;
|
|
1752
|
+
while (offset < buffer.byteLength) {
|
|
1753
|
+
const { bytesRead } = await handle.read(buffer, offset, buffer.byteLength - offset, offset);
|
|
1754
|
+
if (bytesRead === 0) break;
|
|
1755
|
+
offset += bytesRead;
|
|
1756
|
+
}
|
|
1757
|
+
if (offset !== expectedBytes) throw error("invalid_config", refusalFact("bytes_read", offset, `the opened file's ${expectedBytes} bytes without growth or truncation`));
|
|
1738
1758
|
try {
|
|
1739
|
-
return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0,
|
|
1759
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0, offset));
|
|
1740
1760
|
} catch {
|
|
1741
1761
|
throw error("invalid_config");
|
|
1742
1762
|
}
|
|
@@ -1764,9 +1784,8 @@ function validateIntervals(reconcile, retry, timeout, error) {
|
|
|
1764
1784
|
if (!boundedMilliseconds(reconcile) || !boundedMilliseconds(retry) || !boundedMilliseconds(timeout)) throw error("invalid_config");
|
|
1765
1785
|
return [reconcile, retry, timeout];
|
|
1766
1786
|
}
|
|
1767
|
-
function
|
|
1768
|
-
|
|
1769
|
-
return observed.length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
1787
|
+
function hasConfigKeys(value, required) {
|
|
1788
|
+
return required.every((key) => Object.hasOwn(value, key)) && Object.keys(value).every((key) => required.includes(key) || Object.hasOwn(HOST_PRODUCER_TIMING_DEFAULTS, key));
|
|
1770
1789
|
}
|
|
1771
1790
|
function isRecord(value) {
|
|
1772
1791
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|