@corca-org/ceal-host-win32-x64 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.exe +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
|
@@ -6,12 +6,6 @@ const require = __cealCreateRequire(import.meta.url);
|
|
|
6
6
|
import { homedir as homedir3 } from "node:os";
|
|
7
7
|
import { join as join6 } from "node:path";
|
|
8
8
|
|
|
9
|
-
// host/session-start-affordance.ts
|
|
10
|
-
var HOST_ENTRY_AFFORDANCE = "When the user asks to use Ceal or provides a link to information that may be available through installed organizational capabilities, first run the bare `ceal` shell command with no arguments; treat that link as a candidate Ceal resource rather than a public web-search target, and let the current Profile capability result supply the exact next steps.";
|
|
11
|
-
function hostSessionStartEntryAffordance(hostName) {
|
|
12
|
-
return `${HOST_ENTRY_AFFORDANCE} This text is the Ceal ${hostName} Host's own SessionStart hook running in this ${hostName} session. The Host owns this session's Request identity, and the generic client authenticates each call automatically; follow the required_action_sequence returned by bare \`ceal\`. Never run \`ceal request create\`, and never type, guess, or reuse --host-session-ref, --host-turn-ref, --prompt-ref, or any other session or turn reference.`;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
9
|
// host/codex/src/codex-adapter.ts
|
|
16
10
|
import { homedir } from "node:os";
|
|
17
11
|
import { isAbsolute as isAbsolute3, join as join3, relative, resolve as resolve2 } from "node:path";
|
|
@@ -88,11 +82,28 @@ var client_wire_contract_default = {
|
|
|
88
82
|
],
|
|
89
83
|
bare_document_fields: [
|
|
90
84
|
"invocation",
|
|
91
|
-
"
|
|
85
|
+
"required_action_sequence",
|
|
86
|
+
"entrypoints",
|
|
92
87
|
"common_concepts",
|
|
93
88
|
"operations",
|
|
94
89
|
"catalog_revision"
|
|
95
90
|
],
|
|
91
|
+
prompt_field: "prompt",
|
|
92
|
+
prompt_schema_version: "ceal.prompt.v1",
|
|
93
|
+
focused_prompt_document_fields: [
|
|
94
|
+
"catalog_revision",
|
|
95
|
+
"prompt"
|
|
96
|
+
],
|
|
97
|
+
focused_prompt_continuation_document_fields: [
|
|
98
|
+
"catalog_revision",
|
|
99
|
+
"remaining_work",
|
|
100
|
+
"prompt"
|
|
101
|
+
],
|
|
102
|
+
discovery_command: "discovery",
|
|
103
|
+
discovery_manifest_schema_version: "ceal.discovery_manifest.v1",
|
|
104
|
+
discovery_manifest_document_fields: [
|
|
105
|
+
"discovery_manifest"
|
|
106
|
+
],
|
|
96
107
|
exit_code_max: 125,
|
|
97
108
|
bare_document_max_bytes: 65536,
|
|
98
109
|
complete_max_bytes: 66019,
|
|
@@ -119,8 +130,15 @@ var CEAL_VERIFIED_ARTIFACT_MAX_BYTES = artifact.max_bytes;
|
|
|
119
130
|
var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_MAX_BYTES = artifact.envelope_max_bytes;
|
|
120
131
|
var CEAL_COMMAND_REQUEST_SCHEMA_VERSION = request.schema_version;
|
|
121
132
|
var CEAL_COMMAND_REQUEST_MAX_BYTES = request.absolute_transport_max_bytes;
|
|
122
|
-
var CEAL_COMMAND_RESPONSE_BARE_DOCUMENT_FIELDS = response.bare_document_fields;
|
|
123
133
|
var CEAL_COMMAND_RESPONSE_BARE_DOCUMENT_MAX_BYTES = response.bare_document_max_bytes;
|
|
134
|
+
var CEAL_COMMAND_RESPONSE_PROMPT_FIELD = response.prompt_field;
|
|
135
|
+
var CEAL_COMMAND_RESPONSE_PROMPT_SCHEMA_VERSION = response.prompt_schema_version;
|
|
136
|
+
var CEAL_COMMAND_RESPONSE_PROMPT_DOCUMENT_FIELDS = Object.freeze([...response.bare_document_fields, response.prompt_field]);
|
|
137
|
+
var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_DOCUMENT_FIELDS = Object.freeze([...response.focused_prompt_document_fields]);
|
|
138
|
+
var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_CONTINUATION_DOCUMENT_FIELDS = Object.freeze([...response.focused_prompt_continuation_document_fields]);
|
|
139
|
+
var CEAL_COMMAND_RESPONSE_DISCOVERY_COMMAND = response.discovery_command;
|
|
140
|
+
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_SCHEMA_VERSION = response.discovery_manifest_schema_version;
|
|
141
|
+
var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_DOCUMENT_FIELDS = Object.freeze([...response.discovery_manifest_document_fields]);
|
|
124
142
|
var CEAL_COMMAND_RESPONSE_MAX_BYTES = response.absolute_transport_max_bytes;
|
|
125
143
|
|
|
126
144
|
// packages/ceal-client-protocol/src/vocabulary.ts
|
|
@@ -156,7 +174,7 @@ var CEAL_OPERATION_RECOVERY_KINDS = vocabulary(["none", "reconcile", "compensate
|
|
|
156
174
|
var CEAL_OPERATION_RECOVERY_STATUSES = vocabulary(["not_started", "active", "completed"]);
|
|
157
175
|
var CEAL_OPERATION_PROVIDER_READBACK_AVAILABILITY = vocabulary(["not_started", "not_applicable", "not_available", "pending", "available"]);
|
|
158
176
|
var CEAL_OPERATION_OFFERED_HANDOFF_STATES = vocabulary(["accepted", "rejected", "unknown"]);
|
|
159
|
-
var CEAL_OPERATION_RECEIPT_AUTHORITY_KEYS = Object.freeze(["instance_ref", "
|
|
177
|
+
var CEAL_OPERATION_RECEIPT_AUTHORITY_KEYS = Object.freeze(["instance_ref", "access_group_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]);
|
|
160
178
|
var CEAL_OPERATION_APPROVAL_DISPOSITIONS = vocabulary([
|
|
161
179
|
"approval_not_required_by_policy",
|
|
162
180
|
"interactive_pending",
|
|
@@ -171,6 +189,8 @@ var CEAL_CAPABILITY_READINESS_VALUES = vocabulary(["ready", "degraded", "unavail
|
|
|
171
189
|
var CEAL_TARGET_REQUIREMENTS = vocabulary(["required", "optional", "none"]);
|
|
172
190
|
var CEAL_AUDIT_OUTCOMES = vocabulary(["succeeded", "denied", "failed"]);
|
|
173
191
|
var CEAL_GATEWAY_PROVIDER_STEP_OUTCOMES = vocabulary(["completed", "rejected", "throttled", "failed"]);
|
|
192
|
+
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"]);
|
|
193
|
+
var CEAL_GATEWAY_READ_REUSE_UNAVAILABLE_REASONS = vocabulary(["not_reported", "storage_unavailable", "coverage_incomplete", "freshness_refresh_required", "not_reusable", "bypassed"]);
|
|
174
194
|
var CEAL_POLICY_DECISIONS = vocabulary(["allowed", "denied", "not_evaluated"]);
|
|
175
195
|
var CEAL_CONNECTOR_ROUTE_PHASES = vocabulary(["scope_observation", "target_selection", "route_resolution"]);
|
|
176
196
|
var CEAL_CONNECTOR_ROUTE_CAUSES = vocabulary(["provider_throttled", "provider_unavailable", "binding_invalid", "scope_limit_exceeded"]);
|
|
@@ -443,8 +463,10 @@ function requireIsoTimestamp(value, message) {
|
|
|
443
463
|
var JSON_DESCRIPTION_CONTROL_CHARACTER = new RegExp("\\p{Cc}", "u");
|
|
444
464
|
|
|
445
465
|
// packages/ceal-client-protocol/src/operation-contract-validation.ts
|
|
446
|
-
var CEAL_OPERATION_AUTHORITY_POLICY_KEYS = Object.freeze(["
|
|
466
|
+
var CEAL_OPERATION_AUTHORITY_POLICY_KEYS = Object.freeze(["access_group", "instance_binding", "target", "admission_recheck"]);
|
|
447
467
|
var MAX_OPERATION_INPUT_RESOLVER_BINDINGS = 96;
|
|
468
|
+
var CEAL_OPERATION_DESCRIPTOR_REQUIRED_ENVELOPE_KEYS = Object.freeze(["schema_version", "id", "input_contract", "result_contract", "policy"]);
|
|
469
|
+
var CEAL_OPERATION_DESCRIPTOR_OPTIONAL_ENVELOPE_KEYS = Object.freeze(["input_resolution", "summary"]);
|
|
448
470
|
var CEAL_OPERATION_RESULT_KEYS = vocabulary(["ok", "operation_id", "operation_receipt", "schema_version", "value"]);
|
|
449
471
|
var CEAL_OPERATION_COMPACT_RESULT_KEYS = vocabulary(["ok", "operation_evidence", "operation_id", "schema_version", "value"]);
|
|
450
472
|
|
|
@@ -518,6 +540,7 @@ var CEAL_SCHEMA_LITERALS = [
|
|
|
518
540
|
"ceal.operation_descriptor.v1",
|
|
519
541
|
"ceal.operation_error.v1",
|
|
520
542
|
"ceal.operation_failure.v1",
|
|
543
|
+
"ceal.operation_failure.compact.v1",
|
|
521
544
|
"ceal.operation_receipt.v1",
|
|
522
545
|
"ceal.operation_result.v1",
|
|
523
546
|
"ceal.operation_result.compact.v1",
|
|
@@ -543,17 +566,16 @@ var CEAL_BOUNDED_SERIES_CATALOG = Object.freeze({
|
|
|
543
566
|
engagement_signal: (root) => join(root, "runtime-state", "slack-feedback.jsonl"),
|
|
544
567
|
runtime_error: (root) => join(root, "runtime-state", "runtime-errors.jsonl"),
|
|
545
568
|
turn_bridge_request: (root) => join(root, ".ceal", "turn-bridge", "requests.jsonl"),
|
|
546
|
-
channel_log: (root) => join(root, "log.jsonl"),
|
|
547
569
|
thread_run_events: (root) => join(root, "run-events.jsonl"),
|
|
548
570
|
bounded_store_sidecar: (root) => `${root}.jsonl`,
|
|
549
571
|
gateway_audit_archive: (root) => `${root}.jsonl`,
|
|
550
572
|
gateway_capability_audit: (root) => join(root, "capability-audit.jsonl"),
|
|
551
573
|
gateway_retrieval_waste_partition: (root) => `${root}.jsonl`,
|
|
552
574
|
gateway_access_policy_publication: (root) => join(root, "access-policy-publications.jsonl"),
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
575
|
+
gateway_access_group_connector_control_audit: (root) => `${root}.audit.jsonl`,
|
|
576
|
+
gateway_access_group_connector_scope_audit: (root) => join(root, "profile-connector-scope-audit.jsonl"),
|
|
577
|
+
gateway_access_group_connector_activity_scope_audit: (root) => join(root, "profile-connector-activity-scope-audit.jsonl"),
|
|
578
|
+
gateway_access_group_connector_readiness_audit: (root) => join(root, "profile-connector-readiness.audit.jsonl"),
|
|
557
579
|
gateway_organization_audit_ledger: (root) => join(root, "organization-ledger.jsonl"),
|
|
558
580
|
gateway_personal_client_audit: (root) => join(root, "audit.jsonl"),
|
|
559
581
|
gateway_personal_client_access_audit: (root) => join(root, "access-audit.jsonl"),
|
|
@@ -604,12 +626,6 @@ var CEAL_AGENT_SESSION_COMMIT_KEYS = vocabulary(["attempt_ref", "expected_sessio
|
|
|
604
626
|
// packages/ceal-client-protocol/src/operation-next-actions.ts
|
|
605
627
|
var CALLER_RECOVERABLE_NEXT_ACTION_VALUES = [
|
|
606
628
|
"select_did_you_mean",
|
|
607
|
-
// The graph, not the argument list, is what the caller must change: the
|
|
608
|
-
// resolver that owns this input has no producing node upstream, and no edit
|
|
609
|
-
// to the invocation can conjure one. `resolver_dependency_absent` carried no
|
|
610
|
-
// remedy at all rather than borrow a word that means something else, so the
|
|
611
|
-
// scorer read a fully-diagnosed, caller-fixable refusal as a failed run.
|
|
612
|
-
"request.graph.append",
|
|
613
629
|
"choose_new_output_path",
|
|
614
630
|
"choose_new_idempotency_key",
|
|
615
631
|
"restart_search",
|
|
@@ -661,8 +677,6 @@ var NON_REMEDY_NEXT_ACTION_VALUES = [
|
|
|
661
677
|
"reconcile_occurrence",
|
|
662
678
|
"reduce_request_size",
|
|
663
679
|
"repair_or_adopt_session",
|
|
664
|
-
"request.effect_approval.read",
|
|
665
|
-
"request.run",
|
|
666
680
|
"retry",
|
|
667
681
|
// The owner -- a correlation hook, an approval hook -- is not serving right
|
|
668
682
|
// now. The caller changes nothing and the same call succeeds once the owner
|
|
@@ -759,12 +773,12 @@ var CEAL_REQUEST_JSON_SCHEMA = {
|
|
|
759
773
|
additionalProperties: false,
|
|
760
774
|
properties: {
|
|
761
775
|
instance_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
762
|
-
|
|
776
|
+
access_group_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
763
777
|
principal_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
764
778
|
execution_subject_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
765
779
|
authority_revision_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source }
|
|
766
780
|
},
|
|
767
|
-
required: ["instance_ref", "
|
|
781
|
+
required: ["instance_ref", "access_group_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]
|
|
768
782
|
},
|
|
769
783
|
prompt_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
770
784
|
host_session_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
|
|
@@ -896,7 +910,7 @@ var CEAL_HOST_OBSERVATION_KINDS = vocabulary(["prompt", "session", "turn", "mode
|
|
|
896
910
|
function isCealHostPromptObservationValue(value) {
|
|
897
911
|
return isOperationRecord(value) && Object.keys(value).length === 1 && isCealDigest(value.body_sha256);
|
|
898
912
|
}
|
|
899
|
-
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;
|
|
913
|
+
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;
|
|
900
914
|
function assertHostObservationValue(value, kind) {
|
|
901
915
|
if (value === void 0) invalid("Ceal Host observation value is invalid.");
|
|
902
916
|
if (kind === "prompt" && !isCealHostPromptObservationValue(value)) invalid("Ceal Host prompt observation must contain only its body digest.");
|
|
@@ -916,6 +930,14 @@ function inspectHostKeys(value) {
|
|
|
916
930
|
}
|
|
917
931
|
}
|
|
918
932
|
|
|
933
|
+
// packages/ceal-client-protocol/src/host-prompt-ref.ts
|
|
934
|
+
var CEAL_HOST_PROMPT_DIGEST_PATTERN = "^[a-f0-9]{64}$";
|
|
935
|
+
var PROMPT_DIGEST = new RegExp(CEAL_HOST_PROMPT_DIGEST_PATTERN, "u");
|
|
936
|
+
function hostProducerPromptRef(promptSha256) {
|
|
937
|
+
if (!PROMPT_DIGEST.test(promptSha256)) throw new TypeError("Canonical Host prompt digest is invalid.");
|
|
938
|
+
return `ceal-host-prompt:${promptSha256}`;
|
|
939
|
+
}
|
|
940
|
+
|
|
919
941
|
// packages/ceal-client-protocol/src/request-effect-approval.ts
|
|
920
942
|
var CEAL_EFFECT_APPROVAL_DECISION_CHECK_PHRASES = Object.freeze([
|
|
921
943
|
"observed after this approval was raised and before it expires",
|
|
@@ -931,6 +953,12 @@ var OWNER_WRITE_STATES = Object.freeze(["attempt_started", "provider_acknowledge
|
|
|
931
953
|
var OWNER_EFFECT_STATES = Object.freeze(["none", "applied", "failed", "unknown", "reconciled"]);
|
|
932
954
|
var OWNER_RECEIPT_STATES = Object.freeze(["pending", "available", "failed", "unknown", "reconciled"]);
|
|
933
955
|
|
|
956
|
+
// packages/ceal-client-protocol/src/thread-excerpt.ts
|
|
957
|
+
var CEAL_THREAD_RECENT_WINDOW = 6;
|
|
958
|
+
var CEAL_THREAD_LAST_APP_MESSAGES_WINDOW = 3;
|
|
959
|
+
var CEAL_THREAD_OLDER_SUMMARY_WINDOW = 4;
|
|
960
|
+
var CEAL_FED_THREAD_MESSAGE_LIMIT = CEAL_THREAD_RECENT_WINDOW + CEAL_THREAD_OLDER_SUMMARY_WINDOW + CEAL_THREAD_LAST_APP_MESSAGES_WINDOW;
|
|
961
|
+
|
|
934
962
|
// packages/ceal-client-protocol/src/request-graph-readiness.ts
|
|
935
963
|
var REQUEST_GRAPH_PRODUCER_TO_APPEND_SCHEMA = {
|
|
936
964
|
type: "object",
|
|
@@ -1010,6 +1038,13 @@ var CEAL_REQUEST_GRAPH_NODE_PREPARE_READINESS_JSON_SCHEMA = {
|
|
|
1010
1038
|
var REQUIRED_FIELDS = Object.freeze(["schema_version", "operation_id", "local_path", "content_json_pointer", "size_bytes", "sha256", "read_argv"]);
|
|
1011
1039
|
var FIELDS = /* @__PURE__ */ new Set([...REQUIRED_FIELDS, "local_result_root", "model_disclosure"]);
|
|
1012
1040
|
|
|
1041
|
+
// packages/ceal-client-protocol/src/session-start-affordance.ts
|
|
1042
|
+
var CEAL_SESSION_ENTRY_INVOCATION = "ceal";
|
|
1043
|
+
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.`;
|
|
1044
|
+
|
|
1045
|
+
// packages/ceal-client-protocol/src/discovery-manifest.ts
|
|
1046
|
+
var CEAL_DISCOVERY_MANIFEST_CONNECTOR_KINDS = vocabulary(["github", "google-workspace", "notion", "slack"]);
|
|
1047
|
+
|
|
1013
1048
|
// packages/ceal-client-protocol/src/conversation-contracts.ts
|
|
1014
1049
|
var CEAL_APPROVAL_POLICY_KINDS = vocabulary(["requester_only", "named_users", "role_based"]);
|
|
1015
1050
|
var CEAL_APPROVAL_TARGET_KINDS = vocabulary([
|
|
@@ -1226,7 +1261,7 @@ var CEAL_PRESENTATION_INTENTS = vocabulary(["progress", ...CEAL_FINAL_PRESENTATI
|
|
|
1226
1261
|
|
|
1227
1262
|
// packages/ceal-client-protocol/src/personal-client-vocabulary.ts
|
|
1228
1263
|
var CEAL_PERSONAL_CLIENT_BINDING_KEYS = vocabulary([
|
|
1229
|
-
"
|
|
1264
|
+
"access_group_ref",
|
|
1230
1265
|
"membership_ref",
|
|
1231
1266
|
"registration_ref",
|
|
1232
1267
|
"client_ref",
|
|
@@ -1241,7 +1276,8 @@ var CEAL_REFRESH_FAILURE_CODES = vocabulary([
|
|
|
1241
1276
|
"refresh_replayed",
|
|
1242
1277
|
"refresh_revoked",
|
|
1243
1278
|
"authority_replaced",
|
|
1244
|
-
"refresh_recovery_unavailable"
|
|
1279
|
+
"refresh_recovery_unavailable",
|
|
1280
|
+
"refresh_recovery_expired"
|
|
1245
1281
|
]);
|
|
1246
1282
|
|
|
1247
1283
|
// packages/ceal-client-protocol/src/device-enrollment.ts
|
|
@@ -1983,7 +2019,6 @@ var HOST_PRODUCER_FRAME_SCHEMA = "ceal.host_producer_frame.v1";
|
|
|
1983
2019
|
var HOST_PRODUCER_MAX_JSON_BYTES = 262144;
|
|
1984
2020
|
var HOST_PRODUCER_FRAME_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
|
|
1985
2021
|
var SAFE_REF4 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
1986
|
-
var DIGEST2 = /^[a-f0-9]{64}$/u;
|
|
1987
2022
|
var PRODUCERS = /* @__PURE__ */ new Set(["codex", "claude"]);
|
|
1988
2023
|
var HOST_PRODUCER_FRAME_KINDS = ["session_started", "turn_started", "user_input", "turn_terminal", "producer_status"];
|
|
1989
2024
|
var FRAME_KINDS = new Set(HOST_PRODUCER_FRAME_KINDS);
|
|
@@ -2024,10 +2059,6 @@ function decodeHostProducerFrame(input) {
|
|
|
2024
2059
|
validateFrame(value);
|
|
2025
2060
|
return value;
|
|
2026
2061
|
}
|
|
2027
|
-
function hostProducerPromptRef(promptSha256) {
|
|
2028
|
-
if (!DIGEST2.test(promptSha256)) throw new TypeError("Canonical Host prompt digest is invalid.");
|
|
2029
|
-
return `ceal-host-prompt:${promptSha256}`;
|
|
2030
|
-
}
|
|
2031
2062
|
function validateFrame(value) {
|
|
2032
2063
|
if (!record(value)) throw new HostProducerFrameError("invalid_frame_shape");
|
|
2033
2064
|
if (value.schema_version !== HOST_PRODUCER_FRAME_SCHEMA) throw new HostProducerFrameError("unsupported_frame_schema", `unsupported_frame_schema: ${refusalFact("schema_version", value.schema_version, HOST_PRODUCER_FRAME_SCHEMA)}`);
|
|
@@ -2502,9 +2533,16 @@ var RELAY_QUARANTINE_MAX_BYTES = 16 * 1024 * 1024;
|
|
|
2502
2533
|
|
|
2503
2534
|
// host/relay/src/relay-admission-store.ts
|
|
2504
2535
|
var DEFAULT_LIMITS = { global_count: 8192, global_bytes: 64 * 1024 * 1024, producer_count: 4096, producer_bytes: 32 * 1024 * 1024 };
|
|
2536
|
+
var RETRY_SECONDS = [1, 2, 4, 8, 16, 32, 60];
|
|
2537
|
+
var MAX_RETRYABLE_ATTEMPTS = RETRY_SECONDS.length + 10;
|
|
2505
2538
|
|
|
2506
2539
|
// host/relay/src/relay-ipc.ts
|
|
2507
2540
|
import { createConnection, createServer } from "node:net";
|
|
2541
|
+
|
|
2542
|
+
// host/relay/src/current-prompt-custody.ts
|
|
2543
|
+
var HOST_CURRENT_PROMPT_MAX_BYTES = 256 * 1024;
|
|
2544
|
+
|
|
2545
|
+
// host/relay/src/relay-ipc.ts
|
|
2508
2546
|
var HOST_RELAY_REQUEST_BINDING_KEYS = Object.freeze([
|
|
2509
2547
|
"schema_version",
|
|
2510
2548
|
"producer_id",
|
|
@@ -2521,6 +2559,8 @@ var HOST_RELAY_REQUEST_BINDING_KEYS = Object.freeze([
|
|
|
2521
2559
|
"host_input_ref"
|
|
2522
2560
|
]);
|
|
2523
2561
|
var HOST_RELAY_IPC_RESPONSE_SCHEMA = "ceal.host_relay_admission.v1";
|
|
2562
|
+
var HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA = "ceal.host_relay_current_prompt_register.v1";
|
|
2563
|
+
var HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA = "ceal.host_relay_current_prompt_result.v1";
|
|
2524
2564
|
var HOST_RELAY_IPC_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
|
|
2525
2565
|
var HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES = 4096;
|
|
2526
2566
|
var HostRelayIpcError = class extends Error {
|
|
@@ -2543,22 +2583,42 @@ var HostRelayIpcAdmissionPort = class {
|
|
|
2543
2583
|
return { code: response2.code, admitted_through_sequence: response2.admitted_through_sequence, delivered_through_sequence: response2.delivered_through_sequence };
|
|
2544
2584
|
}
|
|
2545
2585
|
};
|
|
2586
|
+
var HostRelayCurrentPromptPort = class {
|
|
2587
|
+
endpoint;
|
|
2588
|
+
timeout_ms;
|
|
2589
|
+
constructor(endpoint, timeoutMs = 5e3) {
|
|
2590
|
+
this.endpoint = endpoint;
|
|
2591
|
+
this.timeout_ms = timeoutMs;
|
|
2592
|
+
}
|
|
2593
|
+
async register(input) {
|
|
2594
|
+
const request2 = { schema_version: HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA, ...input };
|
|
2595
|
+
const response2 = await exchange(this.endpoint, encodeLengthPrefixed(request2), this.timeout_ms, decodeCurrentPromptResponseBuffer);
|
|
2596
|
+
if (response2.status !== "registered") throw new HostRelayIpcError("relay_unavailable", response2.status);
|
|
2597
|
+
}
|
|
2598
|
+
};
|
|
2546
2599
|
function submitHostProducerFrame(endpoint, frame, timeoutMs = 5e3) {
|
|
2547
2600
|
return exchange(endpoint, encodeHostProducerFrame(frame), timeoutMs, decodeResponseBuffer);
|
|
2548
2601
|
}
|
|
2549
|
-
function exchange(endpoint, encoded, timeoutMs, decode) {
|
|
2602
|
+
function exchange(endpoint, encoded, timeoutMs, decode, signal) {
|
|
2550
2603
|
return new Promise((resolve3, reject3) => {
|
|
2551
2604
|
const socket = createConnection(endpoint);
|
|
2552
2605
|
let buffer = Buffer.alloc(0);
|
|
2553
2606
|
let settled = false;
|
|
2607
|
+
const aborted = () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC was cancelled."));
|
|
2554
2608
|
const finish = (error, response2) => {
|
|
2555
2609
|
if (settled) return;
|
|
2556
2610
|
settled = true;
|
|
2611
|
+
signal?.removeEventListener("abort", aborted);
|
|
2557
2612
|
socket.destroy();
|
|
2558
2613
|
if (error !== null) reject3(error);
|
|
2559
2614
|
else if (response2 !== void 0) resolve3(response2);
|
|
2560
2615
|
};
|
|
2561
|
-
socket.setTimeout(timeoutMs, () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC timed out.")));
|
|
2616
|
+
if (timeoutMs !== void 0) socket.setTimeout(timeoutMs, () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC timed out.")));
|
|
2617
|
+
if (signal?.aborted === true) {
|
|
2618
|
+
aborted();
|
|
2619
|
+
return;
|
|
2620
|
+
}
|
|
2621
|
+
signal?.addEventListener("abort", aborted, { once: true });
|
|
2562
2622
|
socket.once("error", () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC is unavailable.")));
|
|
2563
2623
|
socket.once("connect", () => socket.write(encoded));
|
|
2564
2624
|
socket.on("data", (chunk) => {
|
|
@@ -2611,6 +2671,34 @@ function decodeResponseBuffer(buffer) {
|
|
|
2611
2671
|
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}` }])}.`);
|
|
2612
2672
|
return decodeHostRelayIpcResponse(buffer);
|
|
2613
2673
|
}
|
|
2674
|
+
function decodeCurrentPromptResponseBuffer(buffer) {
|
|
2675
|
+
const value = decodeLengthPrefixedJson(buffer, HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES);
|
|
2676
|
+
if (value === null) return null;
|
|
2677
|
+
if (!record2(value) || !exactKeys4(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");
|
|
2678
|
+
return { schema_version: HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA, status: value.status };
|
|
2679
|
+
}
|
|
2680
|
+
function decodeLengthPrefixedJson(input, maximum) {
|
|
2681
|
+
if (input.length < HOST_RELAY_IPC_LENGTH_BYTES) return null;
|
|
2682
|
+
const length = input.readUInt32BE(0);
|
|
2683
|
+
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}`)}.`);
|
|
2684
|
+
if (input.length < length + HOST_RELAY_IPC_LENGTH_BYTES) return null;
|
|
2685
|
+
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}` }])}.`);
|
|
2686
|
+
try {
|
|
2687
|
+
return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(input.subarray(HOST_RELAY_IPC_LENGTH_BYTES)));
|
|
2688
|
+
} catch {
|
|
2689
|
+
throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC message is invalid.");
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
function encodeLengthPrefixed(value) {
|
|
2693
|
+
const body = Buffer.from(JSON.stringify(value), "utf8");
|
|
2694
|
+
const output = Buffer.allocUnsafe(body.length + HOST_RELAY_IPC_LENGTH_BYTES);
|
|
2695
|
+
output.writeUInt32BE(body.length, 0);
|
|
2696
|
+
body.copy(output, HOST_RELAY_IPC_LENGTH_BYTES);
|
|
2697
|
+
return output;
|
|
2698
|
+
}
|
|
2699
|
+
function exactKeys4(value, keys) {
|
|
2700
|
+
return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
2701
|
+
}
|
|
2614
2702
|
|
|
2615
2703
|
// host/codex/src/codex-producer.ts
|
|
2616
2704
|
import { createHash as createHash3 } from "node:crypto";
|
|
@@ -3353,6 +3441,8 @@ var CodexTranscriptWatcher = class {
|
|
|
3353
3441
|
now;
|
|
3354
3442
|
log;
|
|
3355
3443
|
retriedMalformedQuarantines = /* @__PURE__ */ new Set();
|
|
3444
|
+
producerInstallationRef;
|
|
3445
|
+
registerCurrentPrompt;
|
|
3356
3446
|
constructor(options) {
|
|
3357
3447
|
if (typeof options.outbox_dir !== "string" || options.outbox_dir.length === 0) throw new CodexHostAdapterError("configuration", "Codex transcript watcher outbox is invalid.");
|
|
3358
3448
|
this.store = new CodexOutboxStore(options.outbox_dir);
|
|
@@ -3362,6 +3452,8 @@ var CodexTranscriptWatcher = class {
|
|
|
3362
3452
|
process.stderr.write(`${line}
|
|
3363
3453
|
`);
|
|
3364
3454
|
});
|
|
3455
|
+
this.producerInstallationRef = options.producer_installation_ref;
|
|
3456
|
+
this.registerCurrentPrompt = options.register_current_prompt;
|
|
3365
3457
|
}
|
|
3366
3458
|
async scanOnce() {
|
|
3367
3459
|
const registrations = await this.store.listTranscriptRegistrations();
|
|
@@ -3506,10 +3598,15 @@ var CodexTranscriptWatcher = class {
|
|
|
3506
3598
|
created_at: record3.timestamp,
|
|
3507
3599
|
expires_at: expiration(this.now, this.outboxRetentionMs)
|
|
3508
3600
|
};
|
|
3601
|
+
await this.registerPrompt(origin, registration, activeTask, currentPromptRef, record3.prompt, envelope.expires_at);
|
|
3509
3602
|
await this.store.put(envelope);
|
|
3510
3603
|
if (origin) await this.store.activateInvocationContext(identity, promptRef, envelope.expires_at);
|
|
3511
3604
|
return { activeTask: { ...activeTask, origin_host_input_ref: activeTask.origin_host_input_ref ?? hostInputRef, prompt_ref: activeTask.prompt_ref ?? currentPromptRef }, enqueued: 1 };
|
|
3512
3605
|
}
|
|
3606
|
+
async registerPrompt(origin, registration, activeTask, promptRef, prompt, expiresAt) {
|
|
3607
|
+
if (!origin || this.producerInstallationRef === void 0 || this.registerCurrentPrompt === void 0) return;
|
|
3608
|
+
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 });
|
|
3609
|
+
}
|
|
3513
3610
|
async processTerminal(registration, activeTask, record3) {
|
|
3514
3611
|
if (activeTask === void 0 || activeTask.codex_turn_id !== record3.turn_id || activeTask.origin_host_input_ref === void 0 || activeTask.prompt_ref === void 0) return { ...activeTask === void 0 ? {} : { activeTask }, enqueued: 0 };
|
|
3515
3612
|
const identity = { host_source_ref: registration.host_source_ref, host_session_ref: registration.host_session_ref, host_turn_ref: activeTask.host_turn_ref };
|
|
@@ -3714,7 +3811,8 @@ function expiration(now, retentionMs) {
|
|
|
3714
3811
|
|
|
3715
3812
|
// host/codex/src/codex-producer-runtime.ts
|
|
3716
3813
|
async function drainCodexProducerOnce(options) {
|
|
3717
|
-
const
|
|
3814
|
+
const promptPort = new HostRelayCurrentPromptPort(options.relay_endpoint, options.timeout_ms);
|
|
3815
|
+
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();
|
|
3718
3816
|
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 } });
|
|
3719
3817
|
return { scanned: scan.enqueued, ...await producer.drainOutbox() };
|
|
3720
3818
|
}
|
|
@@ -3816,7 +3914,6 @@ function sameKeys2(value, required, optional = []) {
|
|
|
3816
3914
|
|
|
3817
3915
|
// host/codex/src/codex-hook-runner.ts
|
|
3818
3916
|
var MAX_STDIN_BYTES = 64 * 1024;
|
|
3819
|
-
var CODEX_SESSION_START_ENTRY_AFFORDANCE = hostSessionStartEntryAffordance("Codex");
|
|
3820
3917
|
async function runCodexHookFromStdin(event, stdin, options) {
|
|
3821
3918
|
const adapter = createCodexHostObservationAdapter(options);
|
|
3822
3919
|
return adapter.handle(event, await readStdin(stdin));
|
|
@@ -3838,17 +3935,21 @@ function defaultCodexHookRunnerOptions(gateway) {
|
|
|
3838
3935
|
async function runCodexHookProcess(args, stdin, options) {
|
|
3839
3936
|
const event = codexHookEventFromArgs(args);
|
|
3840
3937
|
if (event === null) return 0;
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
}
|
|
3847
|
-
|
|
3848
|
-
|
|
3938
|
+
try {
|
|
3939
|
+
const result = await runCodexHookFromStdin(event, stdin, options);
|
|
3940
|
+
if (result.disposition === "rejected") writeCodexHookDiagnostic(result);
|
|
3941
|
+
return 0;
|
|
3942
|
+
} catch (error) {
|
|
3943
|
+
writeCodexHookDiagnostic({ event, disposition: "rejected", reason: error instanceof Error ? error.message.slice(0, 128) : "codex_hook_failed" });
|
|
3944
|
+
return 0;
|
|
3945
|
+
}
|
|
3849
3946
|
}
|
|
3850
|
-
function
|
|
3851
|
-
|
|
3947
|
+
function writeCodexHookDiagnostic(result) {
|
|
3948
|
+
try {
|
|
3949
|
+
process.stderr.write(`${JSON.stringify({ schema_version: "ceal.codex_sessionstart_diagnostic.v1", event: result.event, disposition: result.disposition, ...result.reason === void 0 ? {} : { reason: result.reason } })}
|
|
3950
|
+
`);
|
|
3951
|
+
} catch {
|
|
3952
|
+
}
|
|
3852
3953
|
}
|
|
3853
3954
|
async function readStdin(stdin) {
|
|
3854
3955
|
const chunks = [];
|