@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 CHANGED
@@ -1,5 +1,5 @@
1
1
  # @corca-org/ceal-host
2
2
 
3
- The Ceal Host lifecycle client for Linux and macOS arm64. Install it with `npm install -g @corca-org/ceal-host`, then activate the adjacent signed bundle with `ceal-host install`.
3
+ The nested Ceal Host payload selector for supported platforms. It is installed by `@corca-org/ceal` and intentionally registers no global command.
4
4
 
5
- Use `npm update -g @corca-org/ceal-host && ceal-host update` to update, and `ceal-host uninstall && npm uninstall -g @corca-org/ceal-host` to remove it.
5
+ Install `@corca-org/ceal` to receive the sole global `ceal-host` launcher. A machine migrating from an older direct installation removes this package registration without running lifecycle uninstall, then installs `@corca-org/ceal` and uses its launcher to repair the existing activation.
package/bin/ceal-host.exe CHANGED
Binary file
@@ -110,11 +110,28 @@ var client_wire_contract_default = {
110
110
  ],
111
111
  bare_document_fields: [
112
112
  "invocation",
113
- "next",
113
+ "required_action_sequence",
114
+ "entrypoints",
114
115
  "common_concepts",
115
116
  "operations",
116
117
  "catalog_revision"
117
118
  ],
119
+ prompt_field: "prompt",
120
+ prompt_schema_version: "ceal.prompt.v1",
121
+ focused_prompt_document_fields: [
122
+ "catalog_revision",
123
+ "prompt"
124
+ ],
125
+ focused_prompt_continuation_document_fields: [
126
+ "catalog_revision",
127
+ "remaining_work",
128
+ "prompt"
129
+ ],
130
+ discovery_command: "discovery",
131
+ discovery_manifest_schema_version: "ceal.discovery_manifest.v1",
132
+ discovery_manifest_document_fields: [
133
+ "discovery_manifest"
134
+ ],
118
135
  exit_code_max: 125,
119
136
  bare_document_max_bytes: 65536,
120
137
  complete_max_bytes: 66019,
@@ -141,8 +158,15 @@ var CEAL_VERIFIED_ARTIFACT_MAX_BYTES = artifact.max_bytes;
141
158
  var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_MAX_BYTES = artifact.envelope_max_bytes;
142
159
  var CEAL_COMMAND_REQUEST_SCHEMA_VERSION = request.schema_version;
143
160
  var CEAL_COMMAND_REQUEST_MAX_BYTES = request.absolute_transport_max_bytes;
144
- var CEAL_COMMAND_RESPONSE_BARE_DOCUMENT_FIELDS = response.bare_document_fields;
145
161
  var CEAL_COMMAND_RESPONSE_BARE_DOCUMENT_MAX_BYTES = response.bare_document_max_bytes;
162
+ var CEAL_COMMAND_RESPONSE_PROMPT_FIELD = response.prompt_field;
163
+ var CEAL_COMMAND_RESPONSE_PROMPT_SCHEMA_VERSION = response.prompt_schema_version;
164
+ var CEAL_COMMAND_RESPONSE_PROMPT_DOCUMENT_FIELDS = Object.freeze([...response.bare_document_fields, response.prompt_field]);
165
+ var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_DOCUMENT_FIELDS = Object.freeze([...response.focused_prompt_document_fields]);
166
+ var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_CONTINUATION_DOCUMENT_FIELDS = Object.freeze([...response.focused_prompt_continuation_document_fields]);
167
+ var CEAL_COMMAND_RESPONSE_DISCOVERY_COMMAND = response.discovery_command;
168
+ var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_SCHEMA_VERSION = response.discovery_manifest_schema_version;
169
+ var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_DOCUMENT_FIELDS = Object.freeze([...response.discovery_manifest_document_fields]);
146
170
  var CEAL_COMMAND_RESPONSE_MAX_BYTES = response.absolute_transport_max_bytes;
147
171
 
148
172
  // packages/ceal-client-protocol/src/vocabulary.ts
@@ -178,7 +202,7 @@ var CEAL_OPERATION_RECOVERY_KINDS = vocabulary(["none", "reconcile", "compensate
178
202
  var CEAL_OPERATION_RECOVERY_STATUSES = vocabulary(["not_started", "active", "completed"]);
179
203
  var CEAL_OPERATION_PROVIDER_READBACK_AVAILABILITY = vocabulary(["not_started", "not_applicable", "not_available", "pending", "available"]);
180
204
  var CEAL_OPERATION_OFFERED_HANDOFF_STATES = vocabulary(["accepted", "rejected", "unknown"]);
181
- var CEAL_OPERATION_RECEIPT_AUTHORITY_KEYS = Object.freeze(["instance_ref", "profile_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]);
205
+ var CEAL_OPERATION_RECEIPT_AUTHORITY_KEYS = Object.freeze(["instance_ref", "access_group_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]);
182
206
  var CEAL_OPERATION_APPROVAL_DISPOSITIONS = vocabulary([
183
207
  "approval_not_required_by_policy",
184
208
  "interactive_pending",
@@ -193,6 +217,8 @@ var CEAL_CAPABILITY_READINESS_VALUES = vocabulary(["ready", "degraded", "unavail
193
217
  var CEAL_TARGET_REQUIREMENTS = vocabulary(["required", "optional", "none"]);
194
218
  var CEAL_AUDIT_OUTCOMES = vocabulary(["succeeded", "denied", "failed"]);
195
219
  var CEAL_GATEWAY_PROVIDER_STEP_OUTCOMES = vocabulary(["completed", "rejected", "throttled", "failed"]);
220
+ 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"]);
221
+ var CEAL_GATEWAY_READ_REUSE_UNAVAILABLE_REASONS = vocabulary(["not_reported", "storage_unavailable", "coverage_incomplete", "freshness_refresh_required", "not_reusable", "bypassed"]);
196
222
  var CEAL_POLICY_DECISIONS = vocabulary(["allowed", "denied", "not_evaluated"]);
197
223
  var CEAL_CONNECTOR_ROUTE_PHASES = vocabulary(["scope_observation", "target_selection", "route_resolution"]);
198
224
  var CEAL_CONNECTOR_ROUTE_CAUSES = vocabulary(["provider_throttled", "provider_unavailable", "binding_invalid", "scope_limit_exceeded"]);
@@ -465,8 +491,10 @@ function requireIsoTimestamp(value, message) {
465
491
  var JSON_DESCRIPTION_CONTROL_CHARACTER = new RegExp("\\p{Cc}", "u");
466
492
 
467
493
  // packages/ceal-client-protocol/src/operation-contract-validation.ts
468
- var CEAL_OPERATION_AUTHORITY_POLICY_KEYS = Object.freeze(["profile", "instance_binding", "target", "admission_recheck"]);
494
+ var CEAL_OPERATION_AUTHORITY_POLICY_KEYS = Object.freeze(["access_group", "instance_binding", "target", "admission_recheck"]);
469
495
  var MAX_OPERATION_INPUT_RESOLVER_BINDINGS = 96;
496
+ var CEAL_OPERATION_DESCRIPTOR_REQUIRED_ENVELOPE_KEYS = Object.freeze(["schema_version", "id", "input_contract", "result_contract", "policy"]);
497
+ var CEAL_OPERATION_DESCRIPTOR_OPTIONAL_ENVELOPE_KEYS = Object.freeze(["input_resolution", "summary"]);
470
498
  var CEAL_OPERATION_RESULT_KEYS = vocabulary(["ok", "operation_id", "operation_receipt", "schema_version", "value"]);
471
499
  var CEAL_OPERATION_COMPACT_RESULT_KEYS = vocabulary(["ok", "operation_evidence", "operation_id", "schema_version", "value"]);
472
500
 
@@ -540,6 +568,7 @@ var CEAL_SCHEMA_LITERALS = [
540
568
  "ceal.operation_descriptor.v1",
541
569
  "ceal.operation_error.v1",
542
570
  "ceal.operation_failure.v1",
571
+ "ceal.operation_failure.compact.v1",
543
572
  "ceal.operation_receipt.v1",
544
573
  "ceal.operation_result.v1",
545
574
  "ceal.operation_result.compact.v1",
@@ -565,17 +594,16 @@ var CEAL_BOUNDED_SERIES_CATALOG = Object.freeze({
565
594
  engagement_signal: (root) => join(root, "runtime-state", "slack-feedback.jsonl"),
566
595
  runtime_error: (root) => join(root, "runtime-state", "runtime-errors.jsonl"),
567
596
  turn_bridge_request: (root) => join(root, ".ceal", "turn-bridge", "requests.jsonl"),
568
- channel_log: (root) => join(root, "log.jsonl"),
569
597
  thread_run_events: (root) => join(root, "run-events.jsonl"),
570
598
  bounded_store_sidecar: (root) => `${root}.jsonl`,
571
599
  gateway_audit_archive: (root) => `${root}.jsonl`,
572
600
  gateway_capability_audit: (root) => join(root, "capability-audit.jsonl"),
573
601
  gateway_retrieval_waste_partition: (root) => `${root}.jsonl`,
574
602
  gateway_access_policy_publication: (root) => join(root, "access-policy-publications.jsonl"),
575
- gateway_profile_connector_control_audit: (root) => `${root}.audit.jsonl`,
576
- gateway_profile_connector_scope_audit: (root) => join(root, "profile-connector-scope-audit.jsonl"),
577
- gateway_profile_connector_activity_scope_audit: (root) => join(root, "profile-connector-activity-scope-audit.jsonl"),
578
- gateway_profile_connector_readiness_audit: (root) => join(root, "profile-connector-readiness.audit.jsonl"),
603
+ gateway_access_group_connector_control_audit: (root) => `${root}.audit.jsonl`,
604
+ gateway_access_group_connector_scope_audit: (root) => join(root, "profile-connector-scope-audit.jsonl"),
605
+ gateway_access_group_connector_activity_scope_audit: (root) => join(root, "profile-connector-activity-scope-audit.jsonl"),
606
+ gateway_access_group_connector_readiness_audit: (root) => join(root, "profile-connector-readiness.audit.jsonl"),
579
607
  gateway_organization_audit_ledger: (root) => join(root, "organization-ledger.jsonl"),
580
608
  gateway_personal_client_audit: (root) => join(root, "audit.jsonl"),
581
609
  gateway_personal_client_access_audit: (root) => join(root, "access-audit.jsonl"),
@@ -626,12 +654,6 @@ var CEAL_AGENT_SESSION_COMMIT_KEYS = vocabulary(["attempt_ref", "expected_sessio
626
654
  // packages/ceal-client-protocol/src/operation-next-actions.ts
627
655
  var CALLER_RECOVERABLE_NEXT_ACTION_VALUES = [
628
656
  "select_did_you_mean",
629
- // The graph, not the argument list, is what the caller must change: the
630
- // resolver that owns this input has no producing node upstream, and no edit
631
- // to the invocation can conjure one. `resolver_dependency_absent` carried no
632
- // remedy at all rather than borrow a word that means something else, so the
633
- // scorer read a fully-diagnosed, caller-fixable refusal as a failed run.
634
- "request.graph.append",
635
657
  "choose_new_output_path",
636
658
  "choose_new_idempotency_key",
637
659
  "restart_search",
@@ -683,8 +705,6 @@ var NON_REMEDY_NEXT_ACTION_VALUES = [
683
705
  "reconcile_occurrence",
684
706
  "reduce_request_size",
685
707
  "repair_or_adopt_session",
686
- "request.effect_approval.read",
687
- "request.run",
688
708
  "retry",
689
709
  // The owner -- a correlation hook, an approval hook -- is not serving right
690
710
  // now. The caller changes nothing and the same call succeeds once the owner
@@ -781,12 +801,12 @@ var CEAL_REQUEST_JSON_SCHEMA = {
781
801
  additionalProperties: false,
782
802
  properties: {
783
803
  instance_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
784
- profile_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
804
+ access_group_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
785
805
  principal_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
786
806
  execution_subject_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
787
807
  authority_revision_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source }
788
808
  },
789
- required: ["instance_ref", "profile_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]
809
+ required: ["instance_ref", "access_group_ref", "principal_ref", "execution_subject_ref", "authority_revision_ref"]
790
810
  },
791
811
  prompt_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
792
812
  host_session_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
@@ -918,7 +938,7 @@ var CEAL_HOST_OBSERVATION_KINDS = vocabulary(["prompt", "session", "turn", "mode
918
938
  function isCealHostPromptObservationValue(value) {
919
939
  return isOperationRecord(value) && Object.keys(value).length === 1 && isCealDigest(value.body_sha256);
920
940
  }
921
- 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;
941
+ 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;
922
942
  function assertHostObservationValue(value, kind) {
923
943
  if (value === void 0) invalid("Ceal Host observation value is invalid.");
924
944
  if (kind === "prompt" && !isCealHostPromptObservationValue(value)) invalid("Ceal Host prompt observation must contain only its body digest.");
@@ -938,6 +958,14 @@ function inspectHostKeys(value) {
938
958
  }
939
959
  }
940
960
 
961
+ // packages/ceal-client-protocol/src/host-prompt-ref.ts
962
+ var CEAL_HOST_PROMPT_DIGEST_PATTERN = "^[a-f0-9]{64}$";
963
+ var PROMPT_DIGEST = new RegExp(CEAL_HOST_PROMPT_DIGEST_PATTERN, "u");
964
+ function hostProducerPromptRef(promptSha256) {
965
+ if (!PROMPT_DIGEST.test(promptSha256)) throw new TypeError("Canonical Host prompt digest is invalid.");
966
+ return `ceal-host-prompt:${promptSha256}`;
967
+ }
968
+
941
969
  // packages/ceal-client-protocol/src/request-effect-approval.ts
942
970
  var CEAL_EFFECT_APPROVAL_DECISION_CHECK_PHRASES = Object.freeze([
943
971
  "observed after this approval was raised and before it expires",
@@ -953,6 +981,12 @@ var OWNER_WRITE_STATES = Object.freeze(["attempt_started", "provider_acknowledge
953
981
  var OWNER_EFFECT_STATES = Object.freeze(["none", "applied", "failed", "unknown", "reconciled"]);
954
982
  var OWNER_RECEIPT_STATES = Object.freeze(["pending", "available", "failed", "unknown", "reconciled"]);
955
983
 
984
+ // packages/ceal-client-protocol/src/thread-excerpt.ts
985
+ var CEAL_THREAD_RECENT_WINDOW = 6;
986
+ var CEAL_THREAD_LAST_APP_MESSAGES_WINDOW = 3;
987
+ var CEAL_THREAD_OLDER_SUMMARY_WINDOW = 4;
988
+ var CEAL_FED_THREAD_MESSAGE_LIMIT = CEAL_THREAD_RECENT_WINDOW + CEAL_THREAD_OLDER_SUMMARY_WINDOW + CEAL_THREAD_LAST_APP_MESSAGES_WINDOW;
989
+
956
990
  // packages/ceal-client-protocol/src/request-graph-readiness.ts
957
991
  var REQUEST_GRAPH_PRODUCER_TO_APPEND_SCHEMA = {
958
992
  type: "object",
@@ -1032,6 +1066,13 @@ var CEAL_REQUEST_GRAPH_NODE_PREPARE_READINESS_JSON_SCHEMA = {
1032
1066
  var REQUIRED_FIELDS = Object.freeze(["schema_version", "operation_id", "local_path", "content_json_pointer", "size_bytes", "sha256", "read_argv"]);
1033
1067
  var FIELDS = /* @__PURE__ */ new Set([...REQUIRED_FIELDS, "local_result_root", "model_disclosure"]);
1034
1068
 
1069
+ // packages/ceal-client-protocol/src/session-start-affordance.ts
1070
+ var CEAL_SESSION_ENTRY_INVOCATION = "ceal";
1071
+ 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.`;
1072
+
1073
+ // packages/ceal-client-protocol/src/discovery-manifest.ts
1074
+ var CEAL_DISCOVERY_MANIFEST_CONNECTOR_KINDS = vocabulary(["github", "google-workspace", "notion", "slack"]);
1075
+
1035
1076
  // packages/ceal-client-protocol/src/conversation-contracts.ts
1036
1077
  var CEAL_APPROVAL_POLICY_KINDS = vocabulary(["requester_only", "named_users", "role_based"]);
1037
1078
  var CEAL_APPROVAL_TARGET_KINDS = vocabulary([
@@ -1248,7 +1289,7 @@ var CEAL_PRESENTATION_INTENTS = vocabulary(["progress", ...CEAL_FINAL_PRESENTATI
1248
1289
 
1249
1290
  // packages/ceal-client-protocol/src/personal-client-vocabulary.ts
1250
1291
  var CEAL_PERSONAL_CLIENT_BINDING_KEYS = vocabulary([
1251
- "profile_ref",
1292
+ "access_group_ref",
1252
1293
  "membership_ref",
1253
1294
  "registration_ref",
1254
1295
  "client_ref",
@@ -1263,7 +1304,8 @@ var CEAL_REFRESH_FAILURE_CODES = vocabulary([
1263
1304
  "refresh_replayed",
1264
1305
  "refresh_revoked",
1265
1306
  "authority_replaced",
1266
- "refresh_recovery_unavailable"
1307
+ "refresh_recovery_unavailable",
1308
+ "refresh_recovery_expired"
1267
1309
  ]);
1268
1310
 
1269
1311
  // packages/ceal-client-protocol/src/device-enrollment.ts
@@ -1396,7 +1438,6 @@ var HOST_PRODUCER_FRAME_SCHEMA = "ceal.host_producer_frame.v1";
1396
1438
  var HOST_PRODUCER_MAX_JSON_BYTES = 262144;
1397
1439
  var HOST_PRODUCER_FRAME_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
1398
1440
  var SAFE_REF2 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
1399
- var DIGEST2 = /^[a-f0-9]{64}$/u;
1400
1441
  var PRODUCERS = /* @__PURE__ */ new Set(["codex", "claude"]);
1401
1442
  var HOST_PRODUCER_FRAME_KINDS = ["session_started", "turn_started", "user_input", "turn_terminal", "producer_status"];
1402
1443
  var FRAME_KINDS = new Set(HOST_PRODUCER_FRAME_KINDS);
@@ -1437,10 +1478,6 @@ function decodeHostProducerFrame(input) {
1437
1478
  validateFrame(value);
1438
1479
  return value;
1439
1480
  }
1440
- function hostProducerPromptRef(promptSha256) {
1441
- if (!DIGEST2.test(promptSha256)) throw new TypeError("Canonical Host prompt digest is invalid.");
1442
- return `ceal-host-prompt:${promptSha256}`;
1443
- }
1444
1481
  function validateFrame(value) {
1445
1482
  if (!record2(value)) throw new HostProducerFrameError("invalid_frame_shape");
1446
1483
  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)}`);
@@ -1621,12 +1658,19 @@ var RELAY_QUARANTINE_MAX_BYTES = 16 * 1024 * 1024;
1621
1658
 
1622
1659
  // host/relay/src/relay-admission-store.ts
1623
1660
  var DEFAULT_LIMITS = { global_count: 8192, global_bytes: 64 * 1024 * 1024, producer_count: 4096, producer_bytes: 32 * 1024 * 1024 };
1661
+ var RETRY_SECONDS = [1, 2, 4, 8, 16, 32, 60];
1662
+ var MAX_RETRYABLE_ATTEMPTS = RETRY_SECONDS.length + 10;
1624
1663
 
1625
1664
  // host/relay/src/relay-request-binding-store.ts
1626
1665
  var MAX_STATE_BYTES = 8 * 1024 * 1024;
1627
1666
 
1628
1667
  // host/relay/src/relay-ipc.ts
1629
1668
  import { createConnection, createServer } from "node:net";
1669
+
1670
+ // host/relay/src/current-prompt-custody.ts
1671
+ var HOST_CURRENT_PROMPT_MAX_BYTES = 256 * 1024;
1672
+
1673
+ // host/relay/src/relay-ipc.ts
1630
1674
  var HOST_RELAY_REQUEST_BINDING_KEYS = Object.freeze([
1631
1675
  "schema_version",
1632
1676
  "producer_id",
@@ -1643,6 +1687,8 @@ var HOST_RELAY_REQUEST_BINDING_KEYS = Object.freeze([
1643
1687
  "host_input_ref"
1644
1688
  ]);
1645
1689
  var HOST_RELAY_IPC_RESPONSE_SCHEMA = "ceal.host_relay_admission.v1";
1690
+ var HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA = "ceal.host_relay_current_prompt_register.v1";
1691
+ var HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA = "ceal.host_relay_current_prompt_result.v1";
1646
1692
  var HOST_RELAY_IPC_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
1647
1693
  var HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES = 4096;
1648
1694
  var HostRelayIpcError = class extends Error {
@@ -1665,22 +1711,42 @@ var HostRelayIpcAdmissionPort = class {
1665
1711
  return { code: response2.code, admitted_through_sequence: response2.admitted_through_sequence, delivered_through_sequence: response2.delivered_through_sequence };
1666
1712
  }
1667
1713
  };
1714
+ var HostRelayCurrentPromptPort = class {
1715
+ endpoint;
1716
+ timeout_ms;
1717
+ constructor(endpoint, timeoutMs = 5e3) {
1718
+ this.endpoint = endpoint;
1719
+ this.timeout_ms = timeoutMs;
1720
+ }
1721
+ async register(input) {
1722
+ const request2 = { schema_version: HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA, ...input };
1723
+ const response2 = await exchange(this.endpoint, encodeLengthPrefixed(request2), this.timeout_ms, decodeCurrentPromptResponseBuffer);
1724
+ if (response2.status !== "registered") throw new HostRelayIpcError("relay_unavailable", response2.status);
1725
+ }
1726
+ };
1668
1727
  function submitHostProducerFrame(endpoint, frame, timeoutMs = 5e3) {
1669
1728
  return exchange(endpoint, encodeHostProducerFrame(frame), timeoutMs, decodeResponseBuffer);
1670
1729
  }
1671
- function exchange(endpoint, encoded, timeoutMs, decode) {
1730
+ function exchange(endpoint, encoded, timeoutMs, decode, signal) {
1672
1731
  return new Promise((resolve, reject) => {
1673
1732
  const socket = createConnection(endpoint);
1674
1733
  let buffer = Buffer.alloc(0);
1675
1734
  let settled = false;
1735
+ const aborted = () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC was cancelled."));
1676
1736
  const finish = (error, response2) => {
1677
1737
  if (settled) return;
1678
1738
  settled = true;
1739
+ signal?.removeEventListener("abort", aborted);
1679
1740
  socket.destroy();
1680
1741
  if (error !== null) reject(error);
1681
1742
  else if (response2 !== void 0) resolve(response2);
1682
1743
  };
1683
- socket.setTimeout(timeoutMs, () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC timed out.")));
1744
+ if (timeoutMs !== void 0) socket.setTimeout(timeoutMs, () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC timed out.")));
1745
+ if (signal?.aborted === true) {
1746
+ aborted();
1747
+ return;
1748
+ }
1749
+ signal?.addEventListener("abort", aborted, { once: true });
1684
1750
  socket.once("error", () => finish(new HostRelayIpcError("relay_unavailable", "Host Relay IPC is unavailable.")));
1685
1751
  socket.once("connect", () => socket.write(encoded));
1686
1752
  socket.on("data", (chunk) => {
@@ -1733,6 +1799,34 @@ function decodeResponseBuffer(buffer) {
1733
1799
  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}` }])}.`);
1734
1800
  return decodeHostRelayIpcResponse(buffer);
1735
1801
  }
1802
+ function decodeCurrentPromptResponseBuffer(buffer) {
1803
+ const value = decodeLengthPrefixedJson(buffer, HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES);
1804
+ if (value === null) return null;
1805
+ if (!record3(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");
1806
+ return { schema_version: HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA, status: value.status };
1807
+ }
1808
+ function decodeLengthPrefixedJson(input, maximum) {
1809
+ if (input.length < HOST_RELAY_IPC_LENGTH_BYTES) return null;
1810
+ const length = input.readUInt32BE(0);
1811
+ 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}`)}.`);
1812
+ if (input.length < length + HOST_RELAY_IPC_LENGTH_BYTES) return null;
1813
+ 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}` }])}.`);
1814
+ try {
1815
+ return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(input.subarray(HOST_RELAY_IPC_LENGTH_BYTES)));
1816
+ } catch {
1817
+ throw new HostRelayIpcError("relay_unavailable", "Host Relay IPC message is invalid.");
1818
+ }
1819
+ }
1820
+ function encodeLengthPrefixed(value) {
1821
+ const body = Buffer.from(JSON.stringify(value), "utf8");
1822
+ const output = Buffer.allocUnsafe(body.length + HOST_RELAY_IPC_LENGTH_BYTES);
1823
+ output.writeUInt32BE(body.length, 0);
1824
+ body.copy(output, HOST_RELAY_IPC_LENGTH_BYTES);
1825
+ return output;
1826
+ }
1827
+ function exactKeys2(value, keys) {
1828
+ return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
1829
+ }
1736
1830
 
1737
1831
  // host/invocation-context.ts
1738
1832
  var HOST_INVOCATION_IDENTITY_KEYS = ["host_session_ref", "host_turn_ref", "host_source_ref"];
@@ -1741,7 +1835,7 @@ function invocationContextKey(identity) {
1741
1835
  return cealRequestSha256({ host_source_ref: identity.host_source_ref, host_session_ref: identity.host_session_ref });
1742
1836
  }
1743
1837
  function hasHostInvocationIdentityKeys(value) {
1744
- return exactKeys2(value, HOST_INVOCATION_IDENTITY_KEYS);
1838
+ return exactKeys3(value, HOST_INVOCATION_IDENTITY_KEYS);
1745
1839
  }
1746
1840
  function hasHostInvocationContextKeys(value, optional = []) {
1747
1841
  return requiredKeys(value, HOST_INVOCATION_CONTEXT_REQUIRED_KEYS, optional);
@@ -1757,7 +1851,7 @@ function invocationContextFromTurn(identity, promptRef, expiresAt, descriptor) {
1757
1851
  descriptor.validate(context);
1758
1852
  return Object.freeze(context);
1759
1853
  }
1760
- function exactKeys2(value, keys) {
1854
+ function exactKeys3(value, keys) {
1761
1855
  const actual = Object.keys(value);
1762
1856
  return actual.length === keys.length && keys.every((key) => Object.hasOwn(value, key)) && actual.every((key) => keys.includes(key));
1763
1857
  }
@@ -1969,6 +2063,8 @@ var ClaudeHookAdapter = class {
1969
2063
  this.store = new ClaudeOutboxStore(options.outbox_dir);
1970
2064
  this.now = options.now ?? (() => /* @__PURE__ */ new Date());
1971
2065
  this.optionsSourceRef = options.host_source_ref ?? "claude-host:local";
2066
+ this.producerInstallationRef = options.producer_installation_ref;
2067
+ this.registerCurrentPrompt = options.register_current_prompt;
1972
2068
  }
1973
2069
  async handle(event, raw) {
1974
2070
  let input;
@@ -1981,6 +2077,10 @@ var ClaudeHookAdapter = class {
1981
2077
  const sessionRef = claudeLocalSessionRef(input.session_id);
1982
2078
  const turnRef = input.prompt_id === void 0 ? void 0 : claudeLocalTurnRef(input.session_id, input.prompt_id);
1983
2079
  const frames = mapFrames(input, occurredAt);
2080
+ if (input.hook_event_name === "UserPromptSubmit" && turnRef !== void 0 && this.producerInstallationRef !== void 0 && this.registerCurrentPrompt !== void 0) {
2081
+ const promptRef = hostProducerPromptRef(createHash3("sha256").update(input.prompt, "utf8").digest("hex"));
2082
+ await this.registerCurrentPrompt({ producer_id: "claude", producer_installation_ref: this.producerInstallationRef, local_session_ref: sessionRef, local_turn_ref: turnRef, prompt_ref: promptRef, current_prompt: input.prompt, context_expires_at: new Date(Date.parse(occurredAt) + 24 * 60 * 60 * 1e3).toISOString() });
2083
+ }
1984
2084
  const batchRef = `claude-batch:${cealRequestSha256({ event, session_ref: sessionRef, turn_ref: turnRef ?? null, occurred_at: occurredAt, frames })}`;
1985
2085
  const batch = { schema_version: CLAUDE_OUTBOX_SCHEMA, batch_ref: batchRef, hook_event: event, local_session_ref: sessionRef, ...turnRef === void 0 ? {} : { local_turn_ref: turnRef }, occurred_at: occurredAt, frames };
1986
2086
  await this.store.put(batch);
@@ -2001,6 +2101,8 @@ var ClaudeHookAdapter = class {
2001
2101
  await this.store.activateInvocationContext(identity, hostProducerPromptRef(promptValue.body_sha256), expiresAt, input.cwd);
2002
2102
  }
2003
2103
  optionsSourceRef;
2104
+ producerInstallationRef;
2105
+ registerCurrentPrompt;
2004
2106
  };
2005
2107
  function mapFrames(input, at) {
2006
2108
  if (input.hook_event_name === "SessionStart") return sessionFrames(input, at);
@@ -2171,12 +2273,6 @@ async function drainClaudeProducerOnce(options) {
2171
2273
  import { homedir } from "node:os";
2172
2274
  import { join as join4 } from "node:path";
2173
2275
 
2174
- // host/session-start-affordance.ts
2175
- 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.";
2176
- function hostSessionStartEntryAffordance(hostName) {
2177
- 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.`;
2178
- }
2179
-
2180
2276
  // host/producer-service.ts
2181
2277
  import { constants } from "node:fs";
2182
2278
  import { lstat as lstat2, open as open3 } from "node:fs/promises";
@@ -2357,10 +2453,6 @@ var CLAUDE_PRODUCER_DESCRIPTOR = {
2357
2453
 
2358
2454
  // host/claude/src/claude-hook-runner.ts
2359
2455
  var MAX_STDIN_BYTES = 256 * 1024;
2360
- var CLAUDE_SESSION_START_ENTRY_AFFORDANCE = hostSessionStartEntryAffordance("Claude");
2361
- function claudeSessionStartHookOutput() {
2362
- return { suppressOutput: true, hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: CLAUDE_SESSION_START_ENTRY_AFFORDANCE } };
2363
- }
2364
2456
  async function runClaudeHookFromStdin(event, stdin, options) {
2365
2457
  return new ClaudeHookAdapter(options).handle(event, await readStdin(stdin));
2366
2458
  }
@@ -2371,11 +2463,21 @@ function claudeHookEventFromArgs(args) {
2371
2463
  async function runClaudeHookProcess(args, stdin, options) {
2372
2464
  const event = claudeHookEventFromArgs(args);
2373
2465
  if (event === null) return 0;
2374
- const result = await runClaudeHookFromStdin(event, stdin, options);
2375
- if (event === "SessionStart") process.stdout.write(`${JSON.stringify(claudeSessionStartHookOutput())}
2466
+ try {
2467
+ const result = await runClaudeHookFromStdin(event, stdin, options);
2468
+ if (result.disposition === "rejected") writeClaudeHookDiagnostic(result);
2469
+ return 0;
2470
+ } catch (error) {
2471
+ writeClaudeHookDiagnostic({ event, disposition: "rejected", reason: error instanceof Error ? error.message.slice(0, 128) : "claude_hook_failed" });
2472
+ return 0;
2473
+ }
2474
+ }
2475
+ function writeClaudeHookDiagnostic(result) {
2476
+ try {
2477
+ process.stderr.write(`${JSON.stringify({ schema_version: "ceal.claude_sessionstart_diagnostic.v1", event: result.event, disposition: result.disposition, ...result.reason === void 0 ? {} : { reason: result.reason } })}
2376
2478
  `);
2377
- if (result.disposition === "rejected") return 0;
2378
- return 0;
2479
+ } catch {
2480
+ }
2379
2481
  }
2380
2482
  async function runClaudeHookCli() {
2381
2483
  const args = process.argv.slice(2);
@@ -2384,7 +2486,8 @@ async function runClaudeHookCli() {
2384
2486
  }
2385
2487
  async function installedClaudeHookRunnerOptions(args) {
2386
2488
  const config = await readHostProducerConfig(CLAUDE_PRODUCER_DESCRIPTOR, parseHostProducerConfigFlag(args));
2387
- const options = { outbox_dir: config.outbox_dir };
2489
+ const port = new HostRelayCurrentPromptPort(config.relay_endpoint, config.ipc_timeout_ms);
2490
+ const options = { outbox_dir: config.outbox_dir, producer_installation_ref: config.producer_installation_ref, register_current_prompt: (input) => port.register(input) };
2388
2491
  Object.defineProperty(options, "host_source_ref", { value: config.host_source_ref, enumerable: false });
2389
2492
  return options;
2390
2493
  }