@corca-org/ceal-host-linux-arm64 1.0.8 → 1.0.10
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/README.md +2 -2
- package/bin/ceal-host +0 -0
- package/libexec/ceal-host/claude-hook.mjs +149 -46
- package/libexec/ceal-host/claude-invocation-authentication.mjs +103 -127
- package/libexec/ceal-host/claude-producer.mjs +76 -24
- package/libexec/ceal-host/codex-hook.mjs +148 -47
- package/libexec/ceal-host/codex-invocation-authentication.mjs +136 -131
- package/libexec/ceal-host/codex-producer.mjs +136 -32
- package/libexec/ceal-host/control.mjs +157 -40
- package/libexec/ceal-host/relay.mjs +240 -58
- package/package.json +1 -1
- package/share/ceal-host/bundle-manifest.json +12 -12
- package/share/ceal-host/bundle-manifest.sigstore.json +1 -1
|
@@ -2108,11 +2108,28 @@ var client_wire_contract_default = {
|
|
|
2108
2108
|
],
|
|
2109
2109
|
bare_document_fields: [
|
|
2110
2110
|
"invocation",
|
|
2111
|
-
"
|
|
2111
|
+
"required_action_sequence",
|
|
2112
|
+
"entrypoints",
|
|
2112
2113
|
"common_concepts",
|
|
2113
2114
|
"operations",
|
|
2114
2115
|
"catalog_revision"
|
|
2115
2116
|
],
|
|
2117
|
+
prompt_field: "prompt",
|
|
2118
|
+
prompt_schema_version: "ceal.prompt.v1",
|
|
2119
|
+
focused_prompt_document_fields: [
|
|
2120
|
+
"catalog_revision",
|
|
2121
|
+
"prompt"
|
|
2122
|
+
],
|
|
2123
|
+
focused_prompt_continuation_document_fields: [
|
|
2124
|
+
"catalog_revision",
|
|
2125
|
+
"remaining_work",
|
|
2126
|
+
"prompt"
|
|
2127
|
+
],
|
|
2128
|
+
discovery_command: "discovery",
|
|
2129
|
+
discovery_manifest_schema_version: "ceal.discovery_manifest.v1",
|
|
2130
|
+
discovery_manifest_document_fields: [
|
|
2131
|
+
"discovery_manifest"
|
|
2132
|
+
],
|
|
2116
2133
|
exit_code_max: 125,
|
|
2117
2134
|
bare_document_max_bytes: 65536,
|
|
2118
2135
|
complete_max_bytes: 66019,
|
|
@@ -2139,8 +2156,15 @@ var CEAL_VERIFIED_ARTIFACT_MAX_BYTES = artifact.max_bytes;
|
|
|
2139
2156
|
var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_MAX_BYTES = artifact.envelope_max_bytes;
|
|
2140
2157
|
var CEAL_COMMAND_REQUEST_SCHEMA_VERSION = request.schema_version;
|
|
2141
2158
|
var CEAL_COMMAND_REQUEST_MAX_BYTES = request.absolute_transport_max_bytes;
|
|
2142
|
-
var CEAL_COMMAND_RESPONSE_BARE_DOCUMENT_FIELDS = response.bare_document_fields;
|
|
2143
2159
|
var CEAL_COMMAND_RESPONSE_BARE_DOCUMENT_MAX_BYTES = response.bare_document_max_bytes;
|
|
2160
|
+
var CEAL_COMMAND_RESPONSE_PROMPT_FIELD = response.prompt_field;
|
|
2161
|
+
var CEAL_COMMAND_RESPONSE_PROMPT_SCHEMA_VERSION = response.prompt_schema_version;
|
|
2162
|
+
var CEAL_COMMAND_RESPONSE_PROMPT_DOCUMENT_FIELDS = Object.freeze([...response.bare_document_fields, response.prompt_field]);
|
|
2163
|
+
var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_DOCUMENT_FIELDS = Object.freeze([...response.focused_prompt_document_fields]);
|
|
2164
|
+
var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_CONTINUATION_DOCUMENT_FIELDS = Object.freeze([...response.focused_prompt_continuation_document_fields]);
|
|
2165
|
+
var CEAL_COMMAND_RESPONSE_DISCOVERY_COMMAND = response.discovery_command;
|
|
2166
|
+
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_SCHEMA_VERSION = response.discovery_manifest_schema_version;
|
|
2167
|
+
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_DOCUMENT_FIELDS = Object.freeze([...response.discovery_manifest_document_fields]);
|
|
2144
2168
|
var CEAL_COMMAND_RESPONSE_MAX_BYTES = response.absolute_transport_max_bytes;
|
|
2145
2169
|
|
|
2146
2170
|
// packages/ceal-client-protocol/src/vocabulary.ts
|
|
@@ -2176,7 +2200,7 @@ var CEAL_OPERATION_RECOVERY_KINDS = vocabulary(["none", "reconcile", "compensate
|
|
|
2176
2200
|
var CEAL_OPERATION_RECOVERY_STATUSES = vocabulary(["not_started", "active", "completed"]);
|
|
2177
2201
|
var CEAL_OPERATION_PROVIDER_READBACK_AVAILABILITY = vocabulary(["not_started", "not_applicable", "not_available", "pending", "available"]);
|
|
2178
2202
|
var CEAL_OPERATION_OFFERED_HANDOFF_STATES = vocabulary(["accepted", "rejected", "unknown"]);
|
|
2179
|
-
var CEAL_OPERATION_RECEIPT_AUTHORITY_KEYS = Object.freeze(["instance_ref", "
|
|
2203
|
+
var CEAL_OPERATION_RECEIPT_AUTHORITY_KEYS = Object.freeze(["instance_ref", "access_group_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]);
|
|
2180
2204
|
var CEAL_OPERATION_APPROVAL_DISPOSITIONS = vocabulary([
|
|
2181
2205
|
"approval_not_required_by_policy",
|
|
2182
2206
|
"interactive_pending",
|
|
@@ -2191,6 +2215,8 @@ var CEAL_CAPABILITY_READINESS_VALUES = vocabulary(["ready", "degraded", "unavail
|
|
|
2191
2215
|
var CEAL_TARGET_REQUIREMENTS = vocabulary(["required", "optional", "none"]);
|
|
2192
2216
|
var CEAL_AUDIT_OUTCOMES = vocabulary(["succeeded", "denied", "failed"]);
|
|
2193
2217
|
var CEAL_GATEWAY_PROVIDER_STEP_OUTCOMES = vocabulary(["completed", "rejected", "throttled", "failed"]);
|
|
2218
|
+
var CEAL_GATEWAY_READ_REUSE_DISPOSITIONS = vocabulary(["response_cache_hit", "corpus_hit", "corpus_hit_after_revalidation", "corpus_partial_provider_supplement", "provider_direct", "provider_continuation", "reuse_unavailable"]);
|
|
2219
|
+
var CEAL_GATEWAY_READ_REUSE_UNAVAILABLE_REASONS = vocabulary(["not_reported", "storage_unavailable", "coverage_incomplete", "freshness_refresh_required", "not_reusable", "bypassed"]);
|
|
2194
2220
|
var CEAL_POLICY_DECISIONS = vocabulary(["allowed", "denied", "not_evaluated"]);
|
|
2195
2221
|
var CEAL_CONNECTOR_ROUTE_PHASES = vocabulary(["scope_observation", "target_selection", "route_resolution"]);
|
|
2196
2222
|
var CEAL_CONNECTOR_ROUTE_CAUSES = vocabulary(["provider_throttled", "provider_unavailable", "binding_invalid", "scope_limit_exceeded"]);
|
|
@@ -2463,8 +2489,10 @@ function requireIsoTimestamp(value, message) {
|
|
|
2463
2489
|
var JSON_DESCRIPTION_CONTROL_CHARACTER = new RegExp("\\p{Cc}", "u");
|
|
2464
2490
|
|
|
2465
2491
|
// packages/ceal-client-protocol/src/operation-contract-validation.ts
|
|
2466
|
-
var CEAL_OPERATION_AUTHORITY_POLICY_KEYS = Object.freeze(["
|
|
2492
|
+
var CEAL_OPERATION_AUTHORITY_POLICY_KEYS = Object.freeze(["access_group", "instance_binding", "target", "admission_recheck"]);
|
|
2467
2493
|
var MAX_OPERATION_INPUT_RESOLVER_BINDINGS = 96;
|
|
2494
|
+
var CEAL_OPERATION_DESCRIPTOR_REQUIRED_ENVELOPE_KEYS = Object.freeze(["schema_version", "id", "input_contract", "result_contract", "policy"]);
|
|
2495
|
+
var CEAL_OPERATION_DESCRIPTOR_OPTIONAL_ENVELOPE_KEYS = Object.freeze(["input_resolution", "summary"]);
|
|
2468
2496
|
var CEAL_OPERATION_RESULT_KEYS = vocabulary(["ok", "operation_id", "operation_receipt", "schema_version", "value"]);
|
|
2469
2497
|
var CEAL_OPERATION_COMPACT_RESULT_KEYS = vocabulary(["ok", "operation_evidence", "operation_id", "schema_version", "value"]);
|
|
2470
2498
|
|
|
@@ -2538,6 +2566,7 @@ var CEAL_SCHEMA_LITERALS = [
|
|
|
2538
2566
|
"ceal.operation_descriptor.v1",
|
|
2539
2567
|
"ceal.operation_error.v1",
|
|
2540
2568
|
"ceal.operation_failure.v1",
|
|
2569
|
+
"ceal.operation_failure.compact.v1",
|
|
2541
2570
|
"ceal.operation_receipt.v1",
|
|
2542
2571
|
"ceal.operation_result.v1",
|
|
2543
2572
|
"ceal.operation_result.compact.v1",
|
|
@@ -2563,17 +2592,16 @@ var CEAL_BOUNDED_SERIES_CATALOG = Object.freeze({
|
|
|
2563
2592
|
engagement_signal: (root) => join(root, "runtime-state", "slack-feedback.jsonl"),
|
|
2564
2593
|
runtime_error: (root) => join(root, "runtime-state", "runtime-errors.jsonl"),
|
|
2565
2594
|
turn_bridge_request: (root) => join(root, ".ceal", "turn-bridge", "requests.jsonl"),
|
|
2566
|
-
channel_log: (root) => join(root, "log.jsonl"),
|
|
2567
2595
|
thread_run_events: (root) => join(root, "run-events.jsonl"),
|
|
2568
2596
|
bounded_store_sidecar: (root) => `${root}.jsonl`,
|
|
2569
2597
|
gateway_audit_archive: (root) => `${root}.jsonl`,
|
|
2570
2598
|
gateway_capability_audit: (root) => join(root, "capability-audit.jsonl"),
|
|
2571
2599
|
gateway_retrieval_waste_partition: (root) => `${root}.jsonl`,
|
|
2572
2600
|
gateway_access_policy_publication: (root) => join(root, "access-policy-publications.jsonl"),
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2601
|
+
gateway_access_group_connector_control_audit: (root) => `${root}.audit.jsonl`,
|
|
2602
|
+
gateway_access_group_connector_scope_audit: (root) => join(root, "profile-connector-scope-audit.jsonl"),
|
|
2603
|
+
gateway_access_group_connector_activity_scope_audit: (root) => join(root, "profile-connector-activity-scope-audit.jsonl"),
|
|
2604
|
+
gateway_access_group_connector_readiness_audit: (root) => join(root, "profile-connector-readiness.audit.jsonl"),
|
|
2577
2605
|
gateway_organization_audit_ledger: (root) => join(root, "organization-ledger.jsonl"),
|
|
2578
2606
|
gateway_personal_client_audit: (root) => join(root, "audit.jsonl"),
|
|
2579
2607
|
gateway_personal_client_access_audit: (root) => join(root, "access-audit.jsonl"),
|
|
@@ -2624,12 +2652,6 @@ var CEAL_AGENT_SESSION_COMMIT_KEYS = vocabulary(["attempt_ref", "expected_sessio
|
|
|
2624
2652
|
// packages/ceal-client-protocol/src/operation-next-actions.ts
|
|
2625
2653
|
var CALLER_RECOVERABLE_NEXT_ACTION_VALUES = [
|
|
2626
2654
|
"select_did_you_mean",
|
|
2627
|
-
// The graph, not the argument list, is what the caller must change: the
|
|
2628
|
-
// resolver that owns this input has no producing node upstream, and no edit
|
|
2629
|
-
// to the invocation can conjure one. `resolver_dependency_absent` carried no
|
|
2630
|
-
// remedy at all rather than borrow a word that means something else, so the
|
|
2631
|
-
// scorer read a fully-diagnosed, caller-fixable refusal as a failed run.
|
|
2632
|
-
"request.graph.append",
|
|
2633
2655
|
"choose_new_output_path",
|
|
2634
2656
|
"choose_new_idempotency_key",
|
|
2635
2657
|
"restart_search",
|
|
@@ -2681,8 +2703,6 @@ var NON_REMEDY_NEXT_ACTION_VALUES = [
|
|
|
2681
2703
|
"reconcile_occurrence",
|
|
2682
2704
|
"reduce_request_size",
|
|
2683
2705
|
"repair_or_adopt_session",
|
|
2684
|
-
"request.effect_approval.read",
|
|
2685
|
-
"request.run",
|
|
2686
2706
|
"retry",
|
|
2687
2707
|
// The owner -- a correlation hook, an approval hook -- is not serving right
|
|
2688
2708
|
// now. The caller changes nothing and the same call succeeds once the owner
|
|
@@ -2779,12 +2799,12 @@ var CEAL_REQUEST_JSON_SCHEMA = {
|
|
|
2779
2799
|
additionalProperties: false,
|
|
2780
2800
|
properties: {
|
|
2781
2801
|
instance_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
2782
|
-
|
|
2802
|
+
access_group_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
2783
2803
|
principal_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
2784
2804
|
execution_subject_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
2785
2805
|
authority_revision_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source }
|
|
2786
2806
|
},
|
|
2787
|
-
required: ["instance_ref", "
|
|
2807
|
+
required: ["instance_ref", "access_group_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]
|
|
2788
2808
|
},
|
|
2789
2809
|
prompt_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
2790
2810
|
host_session_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
@@ -2917,7 +2937,7 @@ var CEAL_HOST_OBSERVATION_KINDS = vocabulary(["prompt", "session", "turn", "mode
|
|
|
2917
2937
|
function isCealHostPromptObservationValue(value) {
|
|
2918
2938
|
return isOperationRecord(value) && Object.keys(value).length === 1 && isCealDigest(value.body_sha256);
|
|
2919
2939
|
}
|
|
2920
|
-
var HOST_RESERVED_KEY = /^(?:admission|approval|audit|authorization|cancellation|capability|effect|grant|occurrence|operation|policy|profile|provider_readback|receipt|reconciliation|replay|target|write_request)(?:_|$)/iu;
|
|
2940
|
+
var HOST_RESERVED_KEY = /^(?:access_group|admission|approval|audit|authorization|cancellation|capability|effect|grant|occurrence|operation|policy|profile|provider_readback|receipt|reconciliation|replay|target|write_request)(?:_|$)/iu;
|
|
2921
2941
|
function assertHostObservationValue(value, kind) {
|
|
2922
2942
|
if (value === void 0) invalid("Ceal Host observation value is invalid.");
|
|
2923
2943
|
if (kind === "prompt" && !isCealHostPromptObservationValue(value)) invalid("Ceal Host prompt observation must contain only its body digest.");
|
|
@@ -2937,6 +2957,14 @@ function inspectHostKeys(value) {
|
|
|
2937
2957
|
}
|
|
2938
2958
|
}
|
|
2939
2959
|
|
|
2960
|
+
// packages/ceal-client-protocol/src/host-prompt-ref.ts
|
|
2961
|
+
var CEAL_HOST_PROMPT_DIGEST_PATTERN = "^[a-f0-9]{64}$";
|
|
2962
|
+
var PROMPT_DIGEST = new RegExp(CEAL_HOST_PROMPT_DIGEST_PATTERN, "u");
|
|
2963
|
+
function hostProducerPromptRef(promptSha256) {
|
|
2964
|
+
if (!PROMPT_DIGEST.test(promptSha256)) throw new TypeError("Canonical Host prompt digest is invalid.");
|
|
2965
|
+
return `ceal-host-prompt:${promptSha256}`;
|
|
2966
|
+
}
|
|
2967
|
+
|
|
2940
2968
|
// packages/ceal-client-protocol/src/request-effect-approval.ts
|
|
2941
2969
|
var CEAL_EFFECT_APPROVAL_DECISION_CHECK_PHRASES = Object.freeze([
|
|
2942
2970
|
"observed after this approval was raised and before it expires",
|
|
@@ -2952,6 +2980,12 @@ var OWNER_WRITE_STATES = Object.freeze(["attempt_started", "provider_acknowledge
|
|
|
2952
2980
|
var OWNER_EFFECT_STATES = Object.freeze(["none", "applied", "failed", "unknown", "reconciled"]);
|
|
2953
2981
|
var OWNER_RECEIPT_STATES = Object.freeze(["pending", "available", "failed", "unknown", "reconciled"]);
|
|
2954
2982
|
|
|
2983
|
+
// packages/ceal-client-protocol/src/thread-excerpt.ts
|
|
2984
|
+
var CEAL_THREAD_RECENT_WINDOW = 6;
|
|
2985
|
+
var CEAL_THREAD_LAST_APP_MESSAGES_WINDOW = 3;
|
|
2986
|
+
var CEAL_THREAD_OLDER_SUMMARY_WINDOW = 4;
|
|
2987
|
+
var CEAL_FED_THREAD_MESSAGE_LIMIT = CEAL_THREAD_RECENT_WINDOW + CEAL_THREAD_OLDER_SUMMARY_WINDOW + CEAL_THREAD_LAST_APP_MESSAGES_WINDOW;
|
|
2988
|
+
|
|
2955
2989
|
// packages/ceal-client-protocol/src/request-graph-readiness.ts
|
|
2956
2990
|
var REQUEST_GRAPH_PRODUCER_TO_APPEND_SCHEMA = {
|
|
2957
2991
|
type: "object",
|
|
@@ -3031,6 +3065,14 @@ var CEAL_REQUEST_GRAPH_NODE_PREPARE_READINESS_JSON_SCHEMA = {
|
|
|
3031
3065
|
var REQUIRED_FIELDS = Object.freeze(["schema_version", "operation_id", "local_path", "content_json_pointer", "size_bytes", "sha256", "read_argv"]);
|
|
3032
3066
|
var FIELDS = /* @__PURE__ */ new Set([...REQUIRED_FIELDS, "local_result_root", "model_disclosure"]);
|
|
3033
3067
|
|
|
3068
|
+
// packages/ceal-client-protocol/src/session-start-affordance.ts
|
|
3069
|
+
var CEAL_SESSION_ENTRY_INVOCATION = "ceal";
|
|
3070
|
+
var CEAL_LINK_RESOURCE_PRECEDENCE = `When the user asks to use Ceal or provides a link to information that may be available through installed organizational capabilities, run bare \`${CEAL_SESSION_ENTRY_INVOCATION}\`. The Host supplies the current user prompt without exposing it to the client command, and the Gateway returns the applicable entry in that one response. Treat a supplied link as a candidate Ceal resource rather than a public web-search target. Reach for a generic web fetch or web search only when the Gateway offered nothing.`;
|
|
3071
|
+
var HOST_HOOK_TIMEOUT_SECONDS = 1;
|
|
3072
|
+
|
|
3073
|
+
// packages/ceal-client-protocol/src/discovery-manifest.ts
|
|
3074
|
+
var CEAL_DISCOVERY_MANIFEST_CONNECTOR_KINDS = vocabulary(["github", "google-workspace", "notion", "slack"]);
|
|
3075
|
+
|
|
3034
3076
|
// packages/ceal-client-protocol/src/conversation-contracts.ts
|
|
3035
3077
|
var CEAL_APPROVAL_POLICY_KINDS = vocabulary(["requester_only", "named_users", "role_based"]);
|
|
3036
3078
|
var CEAL_APPROVAL_TARGET_KINDS = vocabulary([
|
|
@@ -3247,7 +3289,7 @@ var CEAL_PRESENTATION_INTENTS = vocabulary(["progress", ...CEAL_FINAL_PRESENTATI
|
|
|
3247
3289
|
|
|
3248
3290
|
// packages/ceal-client-protocol/src/personal-client-vocabulary.ts
|
|
3249
3291
|
var CEAL_PERSONAL_CLIENT_BINDING_KEYS = vocabulary([
|
|
3250
|
-
"
|
|
3292
|
+
"access_group_ref",
|
|
3251
3293
|
"membership_ref",
|
|
3252
3294
|
"registration_ref",
|
|
3253
3295
|
"client_ref",
|
|
@@ -3262,7 +3304,8 @@ var CEAL_REFRESH_FAILURE_CODES = vocabulary([
|
|
|
3262
3304
|
"refresh_replayed",
|
|
3263
3305
|
"refresh_revoked",
|
|
3264
3306
|
"authority_replaced",
|
|
3265
|
-
"refresh_recovery_unavailable"
|
|
3307
|
+
"refresh_recovery_unavailable",
|
|
3308
|
+
"refresh_recovery_expired"
|
|
3266
3309
|
]);
|
|
3267
3310
|
|
|
3268
3311
|
// packages/ceal-client-protocol/src/device-enrollment.ts
|
|
@@ -3443,7 +3486,6 @@ var HOST_PRODUCER_FRAME_SCHEMA = "ceal.host_producer_frame.v1";
|
|
|
3443
3486
|
var HOST_PRODUCER_MAX_JSON_BYTES = 262144;
|
|
3444
3487
|
var HOST_PRODUCER_FRAME_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
|
|
3445
3488
|
var SAFE_REF3 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
3446
|
-
var DIGEST2 = /^[a-f0-9]{64}$/u;
|
|
3447
3489
|
var PRODUCERS = /* @__PURE__ */ new Set(["codex", "claude"]);
|
|
3448
3490
|
var HOST_PRODUCER_FRAME_KINDS = ["session_started", "turn_started", "user_input", "turn_terminal", "producer_status"];
|
|
3449
3491
|
var FRAME_KINDS = new Set(HOST_PRODUCER_FRAME_KINDS);
|
|
@@ -3484,10 +3526,6 @@ function decodeHostProducerFrame(input) {
|
|
|
3484
3526
|
validateFrame(value);
|
|
3485
3527
|
return value;
|
|
3486
3528
|
}
|
|
3487
|
-
function hostProducerPromptRef(promptSha256) {
|
|
3488
|
-
if (!DIGEST2.test(promptSha256)) throw new TypeError("Canonical Host prompt digest is invalid.");
|
|
3489
|
-
return `ceal-host-prompt:${promptSha256}`;
|
|
3490
|
-
}
|
|
3491
3529
|
function opaqueHostSourceRef(value) {
|
|
3492
3530
|
return typeof value === "string" && SAFE_REF3.test(value) && !value.startsWith("ceal-host-source:");
|
|
3493
3531
|
}
|
|
@@ -3671,12 +3709,19 @@ var RELAY_QUARANTINE_MAX_BYTES = 16 * 1024 * 1024;
|
|
|
3671
3709
|
|
|
3672
3710
|
// host/relay/src/relay-admission-store.ts
|
|
3673
3711
|
var DEFAULT_LIMITS = { global_count: 8192, global_bytes: 64 * 1024 * 1024, producer_count: 4096, producer_bytes: 32 * 1024 * 1024 };
|
|
3712
|
+
var RETRY_SECONDS = [1, 2, 4, 8, 16, 32, 60];
|
|
3713
|
+
var MAX_RETRYABLE_ATTEMPTS = RETRY_SECONDS.length + 10;
|
|
3674
3714
|
|
|
3675
3715
|
// host/relay/src/relay-request-binding-store.ts
|
|
3676
3716
|
var MAX_STATE_BYTES = 8 * 1024 * 1024;
|
|
3677
3717
|
|
|
3678
3718
|
// host/relay/src/relay-ipc.ts
|
|
3679
3719
|
import { createConnection, createServer } from "node:net";
|
|
3720
|
+
|
|
3721
|
+
// host/relay/src/current-prompt-custody.ts
|
|
3722
|
+
var HOST_CURRENT_PROMPT_MAX_BYTES = 256 * 1024;
|
|
3723
|
+
|
|
3724
|
+
// host/relay/src/relay-ipc.ts
|
|
3680
3725
|
var HOST_RELAY_REQUEST_BINDING_KEYS = Object.freeze([
|
|
3681
3726
|
"schema_version",
|
|
3682
3727
|
"producer_id",
|
|
@@ -3693,6 +3738,8 @@ var HOST_RELAY_REQUEST_BINDING_KEYS = Object.freeze([
|
|
|
3693
3738
|
"host_input_ref"
|
|
3694
3739
|
]);
|
|
3695
3740
|
var HOST_RELAY_IPC_RESPONSE_SCHEMA = "ceal.host_relay_admission.v1";
|
|
3741
|
+
var HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA = "ceal.host_relay_current_prompt_register.v1";
|
|
3742
|
+
var HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA = "ceal.host_relay_current_prompt_result.v1";
|
|
3696
3743
|
var HOST_RELAY_IPC_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
|
|
3697
3744
|
var HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES = 4096;
|
|
3698
3745
|
var HostRelayIpcError = class extends Error {
|
|
@@ -3715,22 +3762,42 @@ var HostRelayIpcAdmissionPort = class {
|
|
|
3715
3762
|
return { code: response2.code, admitted_through_sequence: response2.admitted_through_sequence, delivered_through_sequence: response2.delivered_through_sequence };
|
|
3716
3763
|
}
|
|
3717
3764
|
};
|
|
3765
|
+
var HostRelayCurrentPromptPort = class {
|
|
3766
|
+
endpoint;
|
|
3767
|
+
timeout_ms;
|
|
3768
|
+
constructor(endpoint, timeoutMs = 5e3) {
|
|
3769
|
+
this.endpoint = endpoint;
|
|
3770
|
+
this.timeout_ms = timeoutMs;
|
|
3771
|
+
}
|
|
3772
|
+
async register(input) {
|
|
3773
|
+
const request2 = { schema_version: HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA, ...input };
|
|
3774
|
+
const response2 = await exchange(this.endpoint, encodeLengthPrefixed(request2), this.timeout_ms, decodeCurrentPromptResponseBuffer);
|
|
3775
|
+
if (response2.status !== "registered") throw new HostRelayIpcError("relay_unavailable", response2.status);
|
|
3776
|
+
}
|
|
3777
|
+
};
|
|
3718
3778
|
function submitHostProducerFrame(endpoint, frame, timeoutMs = 5e3) {
|
|
3719
3779
|
return exchange(endpoint, encodeHostProducerFrame(frame), timeoutMs, decodeResponseBuffer);
|
|
3720
3780
|
}
|
|
3721
|
-
function exchange(endpoint, encoded, timeoutMs, decode) {
|
|
3781
|
+
function exchange(endpoint, encoded, timeoutMs, decode, signal) {
|
|
3722
3782
|
return new Promise((resolve, reject2) => {
|
|
3723
3783
|
const socket = createConnection(endpoint);
|
|
3724
3784
|
let buffer = Buffer.alloc(0);
|
|
3725
3785
|
let settled = false;
|
|
3786
|
+
const aborted = () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC was cancelled."));
|
|
3726
3787
|
const finish = (error, response2) => {
|
|
3727
3788
|
if (settled) return;
|
|
3728
3789
|
settled = true;
|
|
3790
|
+
signal?.removeEventListener("abort", aborted);
|
|
3729
3791
|
socket.destroy();
|
|
3730
3792
|
if (error !== null) reject2(error);
|
|
3731
3793
|
else if (response2 !== void 0) resolve(response2);
|
|
3732
3794
|
};
|
|
3733
|
-
socket.setTimeout(timeoutMs, () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC timed out.")));
|
|
3795
|
+
if (timeoutMs !== void 0) socket.setTimeout(timeoutMs, () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC timed out.")));
|
|
3796
|
+
if (signal?.aborted === true) {
|
|
3797
|
+
aborted();
|
|
3798
|
+
return;
|
|
3799
|
+
}
|
|
3800
|
+
signal?.addEventListener("abort", aborted, { once: true });
|
|
3734
3801
|
socket.once("error", () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC is unavailable.")));
|
|
3735
3802
|
socket.once("connect", () => socket.write(encoded));
|
|
3736
3803
|
socket.on("data", (chunk) => {
|
|
@@ -3783,6 +3850,34 @@ function decodeResponseBuffer(buffer) {
|
|
|
3783
3850
|
if (buffer.length !== length + HOST_RELAY_IPC_LENGTH_BYTES) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC returned trailing bytes: ${refusalFacts([{ name: "declared_bytes", value: length, expected: `the received message length minus ${HOST_RELAY_IPC_LENGTH_BYTES}` }, { name: "received_bytes", value: buffer.byteLength, expected: `exactly ${length + HOST_RELAY_IPC_LENGTH_BYTES}` }])}.`);
|
|
3784
3851
|
return decodeHostRelayIpcResponse(buffer);
|
|
3785
3852
|
}
|
|
3853
|
+
function decodeCurrentPromptResponseBuffer(buffer) {
|
|
3854
|
+
const value = decodeLengthPrefixedJson(buffer, HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES);
|
|
3855
|
+
if (value === null) return null;
|
|
3856
|
+
if (!record2(value) || !exactKeys2(value, ["schema_version", "status"]) || value.schema_version !== HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA || value.status !== "registered" && value.status !== "current_prompt_unavailable") throw new HostRelayIpcError("relay_unavailable");
|
|
3857
|
+
return { schema_version: HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA, status: value.status };
|
|
3858
|
+
}
|
|
3859
|
+
function decodeLengthPrefixedJson(input, maximum) {
|
|
3860
|
+
if (input.length < HOST_RELAY_IPC_LENGTH_BYTES) return null;
|
|
3861
|
+
const length = input.readUInt32BE(0);
|
|
3862
|
+
if (length === 0 || length > maximum) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC message length is invalid: ${refusalFact("declared_bytes", length, `between 1 and ${maximum}`)}.`);
|
|
3863
|
+
if (input.length < length + HOST_RELAY_IPC_LENGTH_BYTES) return null;
|
|
3864
|
+
if (input.length !== length + HOST_RELAY_IPC_LENGTH_BYTES) throw new HostRelayIpcError("relay_unavailable", `Host Relay IPC message has trailing bytes: ${refusalFacts([{ name: "declared_bytes", value: length, expected: `the received message length minus ${HOST_RELAY_IPC_LENGTH_BYTES}` }, { name: "received_bytes", value: input.byteLength, expected: `exactly ${length + HOST_RELAY_IPC_LENGTH_BYTES}` }])}.`);
|
|
3865
|
+
try {
|
|
3866
|
+
return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(input.subarray(HOST_RELAY_IPC_LENGTH_BYTES)));
|
|
3867
|
+
} catch {
|
|
3868
|
+
throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC message is invalid.");
|
|
3869
|
+
}
|
|
3870
|
+
}
|
|
3871
|
+
function encodeLengthPrefixed(value) {
|
|
3872
|
+
const body = Buffer.from(JSON.stringify(value), "utf8");
|
|
3873
|
+
const output = Buffer.allocUnsafe(body.length + HOST_RELAY_IPC_LENGTH_BYTES);
|
|
3874
|
+
output.writeUInt32BE(body.length, 0);
|
|
3875
|
+
body.copy(output, HOST_RELAY_IPC_LENGTH_BYTES);
|
|
3876
|
+
return output;
|
|
3877
|
+
}
|
|
3878
|
+
function exactKeys2(value, keys) {
|
|
3879
|
+
return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
3880
|
+
}
|
|
3786
3881
|
|
|
3787
3882
|
// host/claude/src/claude-producer.ts
|
|
3788
3883
|
import { mkdir as mkdir3, readFile as readFile2, rename as rename2, writeFile } from "node:fs/promises";
|
|
@@ -3817,7 +3912,7 @@ function invocationContextKey(identity) {
|
|
|
3817
3912
|
return cealRequestSha256({ host_source_ref: identity.host_source_ref, host_session_ref: identity.host_session_ref });
|
|
3818
3913
|
}
|
|
3819
3914
|
function hasHostInvocationIdentityKeys(value) {
|
|
3820
|
-
return
|
|
3915
|
+
return exactKeys3(value, HOST_INVOCATION_IDENTITY_KEYS);
|
|
3821
3916
|
}
|
|
3822
3917
|
function hasHostInvocationContextKeys(value, optional = []) {
|
|
3823
3918
|
return requiredKeys(value, HOST_INVOCATION_CONTEXT_REQUIRED_KEYS, optional);
|
|
@@ -3833,7 +3928,7 @@ function invocationContextFromTurn(identity, promptRef, expiresAt, descriptor2)
|
|
|
3833
3928
|
descriptor2.validate(context);
|
|
3834
3929
|
return Object.freeze(context);
|
|
3835
3930
|
}
|
|
3836
|
-
function
|
|
3931
|
+
function exactKeys3(value, keys) {
|
|
3837
3932
|
const actual = Object.keys(value);
|
|
3838
3933
|
return actual.length === keys.length && keys.every((key) => Object.hasOwn(value, key)) && actual.every((key) => keys.includes(key));
|
|
3839
3934
|
}
|
|
@@ -5517,6 +5612,8 @@ var CodexTranscriptWatcher = class {
|
|
|
5517
5612
|
now;
|
|
5518
5613
|
log;
|
|
5519
5614
|
retriedMalformedQuarantines = /* @__PURE__ */ new Set();
|
|
5615
|
+
producerInstallationRef;
|
|
5616
|
+
registerCurrentPrompt;
|
|
5520
5617
|
constructor(options) {
|
|
5521
5618
|
if (typeof options.outbox_dir !== "string" || options.outbox_dir.length === 0) throw new CodexHostAdapterError("configuration", "Codex transcript watcher outbox is invalid.");
|
|
5522
5619
|
this.store = new CodexOutboxStore(options.outbox_dir);
|
|
@@ -5526,6 +5623,8 @@ var CodexTranscriptWatcher = class {
|
|
|
5526
5623
|
process.stderr.write(`${line}
|
|
5527
5624
|
`);
|
|
5528
5625
|
});
|
|
5626
|
+
this.producerInstallationRef = options.producer_installation_ref;
|
|
5627
|
+
this.registerCurrentPrompt = options.register_current_prompt;
|
|
5529
5628
|
}
|
|
5530
5629
|
async scanOnce() {
|
|
5531
5630
|
const registrations = await this.store.listTranscriptRegistrations();
|
|
@@ -5670,10 +5769,15 @@ var CodexTranscriptWatcher = class {
|
|
|
5670
5769
|
created_at: record8.timestamp,
|
|
5671
5770
|
expires_at: expiration(this.now, this.outboxRetentionMs)
|
|
5672
5771
|
};
|
|
5772
|
+
await this.registerPrompt(origin, registration, activeTask, currentPromptRef, record8.prompt, envelope.expires_at);
|
|
5673
5773
|
await this.store.put(envelope);
|
|
5674
5774
|
if (origin) await this.store.activateInvocationContext(identity, promptRef, envelope.expires_at);
|
|
5675
5775
|
return { activeTask: { ...activeTask, origin_host_input_ref: activeTask.origin_host_input_ref ?? hostInputRef, prompt_ref: activeTask.prompt_ref ?? currentPromptRef }, enqueued: 1 };
|
|
5676
5776
|
}
|
|
5777
|
+
async registerPrompt(origin, registration, activeTask, promptRef, prompt, expiresAt) {
|
|
5778
|
+
if (!origin || this.producerInstallationRef === void 0 || this.registerCurrentPrompt === void 0) return;
|
|
5779
|
+
await this.registerCurrentPrompt({ producer_id: "codex", producer_installation_ref: this.producerInstallationRef, local_session_ref: registration.host_session_ref, local_turn_ref: activeTask.host_turn_ref, prompt_ref: promptRef, current_prompt: prompt, context_expires_at: expiresAt });
|
|
5780
|
+
}
|
|
5677
5781
|
async processTerminal(registration, activeTask, record8) {
|
|
5678
5782
|
if (activeTask === void 0 || activeTask.codex_turn_id !== record8.turn_id || activeTask.origin_host_input_ref === void 0 || activeTask.prompt_ref === void 0) return { ...activeTask === void 0 ? {} : { activeTask }, enqueued: 0 };
|
|
5679
5783
|
const identity = { host_source_ref: registration.host_source_ref, host_session_ref: registration.host_session_ref, host_turn_ref: activeTask.host_turn_ref };
|
|
@@ -5878,7 +5982,8 @@ function expiration(now, retentionMs) {
|
|
|
5878
5982
|
|
|
5879
5983
|
// host/codex/src/codex-producer-runtime.ts
|
|
5880
5984
|
async function drainCodexProducerOnce(options) {
|
|
5881
|
-
const
|
|
5985
|
+
const promptPort = new HostRelayCurrentPromptPort(options.relay_endpoint, options.timeout_ms);
|
|
5986
|
+
const scan = await new CodexTranscriptWatcher({ outbox_dir: options.outbox_dir, producer_installation_ref: options.producer_installation_ref, register_current_prompt: (input) => promptPort.register(input) }).scanOnce();
|
|
5882
5987
|
const producer = new CodexProducer({ outbox_dir: options.outbox_dir, producer_installation_ref: options.producer_installation_ref, relay: new HostRelayIpcAdmissionPort(options.relay_endpoint, options.timeout_ms), ...options.producer_epoch === void 0 ? {} : { producer_epoch: options.producer_epoch }, ...options.now === void 0 ? {} : { now: options.now } });
|
|
5883
5988
|
return { scanned: scan.enqueued, ...await producer.drainOutbox() };
|
|
5884
5989
|
}
|
|
@@ -6115,7 +6220,7 @@ import { homedir } from "node:os";
|
|
|
6115
6220
|
import { basename, dirname as dirname4, isAbsolute as isAbsolute2, join as join7 } from "node:path";
|
|
6116
6221
|
var HOST_ENTRY_RUNTIME_LINK = "runtime";
|
|
6117
6222
|
var HOST_ENTRY_SERVICES_LINK = "services";
|
|
6118
|
-
var HOST_ENTRY_DIRECTORY = [".ceal", "host"];
|
|
6223
|
+
var HOST_ENTRY_DIRECTORY = [".ceal", "host-entry"];
|
|
6119
6224
|
var HOST_ENTRY_LINKS = [HOST_ENTRY_RUNTIME_LINK, HOST_ENTRY_SERVICES_LINK];
|
|
6120
6225
|
var HostEntryLinkError = class extends Error {
|
|
6121
6226
|
code;
|
|
@@ -6221,7 +6326,6 @@ import { homedir as homedir2 } from "node:os";
|
|
|
6221
6326
|
import { dirname as dirname5, isAbsolute as isAbsolute3, join as join8 } from "node:path";
|
|
6222
6327
|
|
|
6223
6328
|
// host/command-vector.ts
|
|
6224
|
-
var HOST_HOOK_TIMEOUT_SECONDS = 1;
|
|
6225
6329
|
var MAX_ARGUMENTS = 64;
|
|
6226
6330
|
var MAX_COMMAND_BYTES = 4096;
|
|
6227
6331
|
function validateHostCommandVector(vector) {
|
|
@@ -6755,12 +6859,15 @@ function normalizeHookGroups(entries) {
|
|
|
6755
6859
|
}
|
|
6756
6860
|
return groups;
|
|
6757
6861
|
}
|
|
6862
|
+
function ownedHookEntry(command, event) {
|
|
6863
|
+
return { type: "command", command: hookCommand(command, event, "posix"), commandWindows: hookCommand(command, event, "windows"), timeout: HOST_HOOK_TIMEOUT_SECONDS, async: false };
|
|
6864
|
+
}
|
|
6758
6865
|
function mergeOwnedHooks2(config, command) {
|
|
6759
6866
|
const hooks = isRecord7(config.hooks) ? { ...config.hooks } : {};
|
|
6760
6867
|
for (const event of CODEX_HOOK_EVENTS) {
|
|
6761
6868
|
const groups = Array.isArray(hooks[event]) ? normalizeHookGroups(hooks[event]) : [];
|
|
6762
6869
|
const retained = groups.map((group) => ({ ...group, hooks: group.hooks.filter((entry) => !ownedHookHandler(entry)) })).filter((group) => group.hooks.length > 0);
|
|
6763
|
-
retained.push({ hooks: [
|
|
6870
|
+
retained.push({ hooks: [ownedHookEntry(command, event)] });
|
|
6764
6871
|
hooks[event] = retained;
|
|
6765
6872
|
}
|
|
6766
6873
|
return { ...config, hooks };
|
|
@@ -6853,9 +6960,15 @@ function inspectHookCommands(config, command) {
|
|
|
6853
6960
|
const locations = ownedHookLocations(config, event);
|
|
6854
6961
|
if (locations.length !== 1) return [];
|
|
6855
6962
|
const handler = locations[0]?.handler;
|
|
6856
|
-
return handler
|
|
6963
|
+
return ownedHookEntryMatches(handler, ownedHookEntry(command, event)) ? [] : [`owned_hook_drifted:${event}`];
|
|
6857
6964
|
});
|
|
6858
6965
|
}
|
|
6966
|
+
function ownedHookEntryMatches(actual, expected) {
|
|
6967
|
+
if (actual === void 0) return false;
|
|
6968
|
+
const actualKeys = Object.keys(actual).sort();
|
|
6969
|
+
const expectedKeys = Object.keys(expected).sort();
|
|
6970
|
+
return actualKeys.length === expectedKeys.length && expectedKeys.every((key, index) => actualKeys[index] === key && actual[key] === expected[key]);
|
|
6971
|
+
}
|
|
6859
6972
|
async function readTrustConfig(configPath) {
|
|
6860
6973
|
try {
|
|
6861
6974
|
return await readCodexConfig(codexConfigPath(configPath));
|
|
@@ -7232,8 +7345,11 @@ var InstalledHostRuntimeHookAdapter = class {
|
|
|
7232
7345
|
const isInstalled = transition.target.components.includes(producer);
|
|
7233
7346
|
const entry = this.entry(producer, paths);
|
|
7234
7347
|
if (wasInstalled && !isInstalled) {
|
|
7235
|
-
await
|
|
7236
|
-
if (
|
|
7348
|
+
const entryState = await inspectHostEntryLinks(entry.entryRoot, entry.targets);
|
|
7349
|
+
if (entryState !== "drifted") {
|
|
7350
|
+
await uninstallProducerHooks(producer, this.homes);
|
|
7351
|
+
if (!remaining.has(entry.entryRoot)) await removeHostEntryLinks(entry.entryRoot);
|
|
7352
|
+
}
|
|
7237
7353
|
}
|
|
7238
7354
|
if (isInstalled) {
|
|
7239
7355
|
await installHostEntryLinks(entry.entryRoot, entry.targets);
|
|
@@ -8024,7 +8140,8 @@ function createLinuxUserSystemdAdapter(options) {
|
|
|
8024
8140
|
await ensurePrivateUnitDirectory(unitDirectory);
|
|
8025
8141
|
const ownedUnits = await ownedHostUnits(unitDirectory);
|
|
8026
8142
|
for (const service of target.services) await replaceOwnedUnit(unitDirectory, identity, service);
|
|
8027
|
-
|
|
8143
|
+
const removableUnits = target.services.length === 0 ? ownedUnits.filter((unit) => unit.identity === identity) : ownedUnits;
|
|
8144
|
+
for (const unit of removableUnits) {
|
|
8028
8145
|
if (unit.identity === identity && targetByComponent.has(unit.component)) continue;
|
|
8029
8146
|
await invokeSystemctl(run, systemctl, ["--user", "disable", "--now", unitName(unit.identity, unit.component)]);
|
|
8030
8147
|
await removeOwnedUnit(unitDirectory, unit.identity, unit.component);
|
|
@@ -8036,7 +8153,7 @@ function createLinuxUserSystemdAdapter(options) {
|
|
|
8036
8153
|
if (previousByComponent.has(service.component)) await invokeSystemctl(run, systemctl, ["--user", "restart", name]);
|
|
8037
8154
|
await requireExpectedReadback(run, systemctl, unitDirectory, identity, service, "running");
|
|
8038
8155
|
}
|
|
8039
|
-
for (const unit of
|
|
8156
|
+
for (const unit of removableUnits) if (unit.identity !== identity || !targetByComponent.has(unit.component)) await requireAbsentReadback(run, systemctl, unitDirectory, unit.identity, unit.component);
|
|
8040
8157
|
},
|
|
8041
8158
|
async restart({ target, service }) {
|
|
8042
8159
|
const identity = prefixIdentity(target.prefix);
|