agent-transport-system 0.2.6 → 0.2.7

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.
Files changed (3) hide show
  1. package/dist/ats.js +1600 -791
  2. package/dist/ats.js.map +1 -1
  3. package/package.json +1 -1
package/dist/ats.js CHANGED
@@ -11,7 +11,7 @@ import * as clackPrompts from "@clack/prompts";
11
11
  import { cancel, confirm, intro, isCancel, multiselect, note, outro, password, select, spinner, text } from "@clack/prompts";
12
12
  import { execFile, spawn } from "node:child_process";
13
13
  import { access, appendFile, chmod, copyFile, cp, lstat, mkdir, mkdtemp, open, readFile, readdir, readlink, realpath, rename, rm, stat, symlink, writeFile } from "node:fs/promises";
14
- import crypto, { createHash, randomBytes, randomUUID } from "node:crypto";
14
+ import crypto$1, { createHash, randomBytes, randomUUID } from "node:crypto";
15
15
  import pc from "picocolors";
16
16
  import { promisify, stripVTControlCharacters } from "node:util";
17
17
  import stringWidth from "string-width";
@@ -23,7 +23,7 @@ import wrapAnsi from "wrap-ansi";
23
23
  import { Box, Container, Editor, Key, ProcessTerminal, TUI, Text, getEditorKeybindings, matchesKey } from "@mariozechner/pi-tui";
24
24
 
25
25
  //#region package.json
26
- var version$1 = "0.2.6";
26
+ var version$1 = "0.2.7";
27
27
  var package_default = {
28
28
  name: "agent-transport-system",
29
29
  version: version$1,
@@ -2155,7 +2155,7 @@ async function requestLatestPackageVersion(packageName) {
2155
2155
  if (!version) throw new Error("missing version");
2156
2156
  return version;
2157
2157
  } catch (error) {
2158
- throw new Error(`version check failed: invalid registry response: ${toErrorMessage$17(error)}`);
2158
+ throw new Error(`version check failed: invalid registry response: ${toErrorMessage$18(error)}`);
2159
2159
  }
2160
2160
  }
2161
2161
  function compareSemver(a, b) {
@@ -2220,7 +2220,7 @@ function toNonEmptyString(value) {
2220
2220
  const normalized = value.trim();
2221
2221
  return normalized.length > 0 ? normalized : null;
2222
2222
  }
2223
- function toErrorMessage$17(error) {
2223
+ function toErrorMessage$18(error) {
2224
2224
  if (error instanceof Error) return error.message;
2225
2225
  return String(error);
2226
2226
  }
@@ -3415,7 +3415,7 @@ async function storeAccessToken(input) {
3415
3415
  key
3416
3416
  };
3417
3417
  }
3418
- throw new Error(`failed to store access token in macOS Keychain: ${toErrorMessage$16(error)}`);
3418
+ throw new Error(`failed to store access token in macOS Keychain: ${toErrorMessage$17(error)}`);
3419
3419
  }
3420
3420
  if (process.platform === "win32") try {
3421
3421
  await setWindowsDpapiToken({
@@ -3437,7 +3437,7 @@ async function storeAccessToken(input) {
3437
3437
  key
3438
3438
  };
3439
3439
  }
3440
- throw new Error(`failed to store access token via Windows DPAPI: ${toErrorMessage$16(error)}`);
3440
+ throw new Error(`failed to store access token via Windows DPAPI: ${toErrorMessage$17(error)}`);
3441
3441
  }
3442
3442
  if (allowInsecureFallback()) {
3443
3443
  await setInsecureFileToken({
@@ -3678,7 +3678,7 @@ function normalizeToken(value) {
3678
3678
  const normalized = value.trim();
3679
3679
  return normalized.length > 0 ? normalized : null;
3680
3680
  }
3681
- function toErrorMessage$16(error) {
3681
+ function toErrorMessage$17(error) {
3682
3682
  if (error instanceof Error) return error.message;
3683
3683
  return String(error);
3684
3684
  }
@@ -8470,7 +8470,7 @@ var ZodFirstPartyTypeKind;
8470
8470
  (function(ZodFirstPartyTypeKind) {})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
8471
8471
 
8472
8472
  //#endregion
8473
- //#region ../../packages/schemas/dist/envelope-IeNocT0x.js
8473
+ //#region ../../packages/schemas/dist/envelope-BjKosHeX.js
8474
8474
  const providerConversationExternalImportCapabilitySchema = _enum(["unsupported", "by_ref_id"]);
8475
8475
  const providerConversationResumeCapabilitySchema = _enum(["unsupported", "by_ref_id"]);
8476
8476
  const providerConversationDiscoverCapabilitySchema = literal("unsupported");
@@ -9142,6 +9142,97 @@ const spacePasswordSchema = string().min(SPACE_PASSWORD_MIN_LENGTH);
9142
9142
  const createSpacePasswordBodySchema = strictObject({ password: spacePasswordSchema.optional() });
9143
9143
  const upsertSpacePasswordBodySchema = strictObject({ password: spacePasswordSchema });
9144
9144
  const spacePasswordStateSchema = strictObject({ passwordProtected: boolean() });
9145
+ const MAX_SIGNAL_REPLY_TO_PREVIEW_LENGTH = 120;
9146
+ const SPACE_MEMBER_JOIN_NOTICE_PURPOSE = "space_membership_join_notice";
9147
+ const SPACE_MEMBER_REMOVE_NOTICE_PURPOSE = "space_membership_remove_notice";
9148
+ const SPACE_MENTION_REJECT_NOTICE_PURPOSE = "space_mention_reject_notice";
9149
+ const AGENT_REPLYING_PURPOSE = "agent_replying";
9150
+ const AGENT_REPLYING_END_PURPOSE = "agent_replying_end";
9151
+ const AGENT_REPLY_PREVIEW_PURPOSE = "agent_reply_preview";
9152
+ const AGENT_REPLY_PREVIEW_END_PURPOSE = "agent_reply_preview_end";
9153
+ const DISPATCH_ACTIVITY_DISPATCHING_PURPOSE = "dispatch_activity_dispatching";
9154
+ const DISPATCH_ACTIVITY_RETRYING_PURPOSE = "dispatch_activity_retrying";
9155
+ const DISPATCH_ACTIVITY_FAILED_PURPOSE = "dispatch_activity_failed";
9156
+ const CONVERSATION_CONTINUITY_WARNING_PURPOSE = "conversation_continuity_warning";
9157
+ const MENTION_TOKEN_PATTERN$3 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
9158
+ const normalizeMentionToken$1 = (value) => {
9159
+ const normalized = trimmedStringFromUnknown(value);
9160
+ if (!normalized) return;
9161
+ return MENTION_TOKEN_PATTERN$3.test(normalized) ? normalized : void 0;
9162
+ };
9163
+ const signalTextReplyToSchema = object({
9164
+ signalId: preprocess(trimmedStringFromUnknown, string().min(1)),
9165
+ profileId: atsRuntimeProfileIdSchema,
9166
+ profileKind: _enum([
9167
+ "human",
9168
+ "agent",
9169
+ "system"
9170
+ ]).nullable(),
9171
+ profileName: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_PROFILE_NAME_LENGTH)),
9172
+ previewText: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_SIGNAL_REPLY_TO_PREVIEW_LENGTH))
9173
+ });
9174
+ const signalTextMetaSchema = object({
9175
+ transient: literal(true).optional(),
9176
+ clientMessageId: preprocess(trimmedStringFromUnknown, string().max(200)).optional(),
9177
+ sourceEventId: preprocess(trimmedStringFromUnknown, string().max(200)).optional(),
9178
+ purpose: preprocess(trimmedStringFromUnknown, string().min(1).max(80)).optional(),
9179
+ dispatchId: preprocess(trimmedStringFromUnknown, string().max(200)).optional(),
9180
+ targetProfileId: atsRuntimeProfileIdSchema.optional(),
9181
+ targetProfileKind: _enum(["human", "agent"]).optional(),
9182
+ targetProfileName: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_PROFILE_NAME_LENGTH)).optional(),
9183
+ targetProfileHandle: preprocess(normalizeMentionToken$1, string().regex(MENTION_TOKEN_PATTERN$3).max(128)).optional(),
9184
+ targetWakeToken: preprocess(normalizeMentionToken$1, string().regex(MENTION_TOKEN_PATTERN$3).max(128)).optional(),
9185
+ addedByProfileId: atsRuntimeProfileIdSchema.optional(),
9186
+ addedByDisplayName: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_PROFILE_NAME_LENGTH)).optional(),
9187
+ removedByProfileId: atsRuntimeProfileIdSchema.optional(),
9188
+ removedByDisplayName: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_PROFILE_NAME_LENGTH)).optional()
9189
+ });
9190
+ const postedSignalTextMetaSchema = signalTextMetaSchema.superRefine((meta, context) => {
9191
+ if (meta.purpose !== SPACE_MEMBER_JOIN_NOTICE_PURPOSE && meta.purpose !== SPACE_MEMBER_REMOVE_NOTICE_PURPOSE) return;
9192
+ if (!meta.targetProfileId) context.addIssue({
9193
+ code: "custom",
9194
+ message: "targetProfileId is required for space member notices",
9195
+ path: ["targetProfileId"]
9196
+ });
9197
+ if (!meta.targetProfileKind) context.addIssue({
9198
+ code: "custom",
9199
+ message: "targetProfileKind is required for space member notices",
9200
+ path: ["targetProfileKind"]
9201
+ });
9202
+ if (meta.purpose === SPACE_MEMBER_JOIN_NOTICE_PURPOSE && !meta.addedByProfileId) context.addIssue({
9203
+ code: "custom",
9204
+ message: "addedByProfileId is required for space member notices",
9205
+ path: ["addedByProfileId"]
9206
+ });
9207
+ if (meta.purpose === SPACE_MEMBER_JOIN_NOTICE_PURPOSE && !meta.addedByDisplayName) context.addIssue({
9208
+ code: "custom",
9209
+ message: "addedByDisplayName is required for space member notices",
9210
+ path: ["addedByDisplayName"]
9211
+ });
9212
+ if (meta.purpose === SPACE_MEMBER_REMOVE_NOTICE_PURPOSE && !meta.removedByProfileId) context.addIssue({
9213
+ code: "custom",
9214
+ message: "removedByProfileId is required for space member notices",
9215
+ path: ["removedByProfileId"]
9216
+ });
9217
+ if (meta.purpose === SPACE_MEMBER_REMOVE_NOTICE_PURPOSE && !meta.removedByDisplayName) context.addIssue({
9218
+ code: "custom",
9219
+ message: "removedByDisplayName is required for space member notices",
9220
+ path: ["removedByDisplayName"]
9221
+ });
9222
+ });
9223
+ const signalTextDataSchema = object({
9224
+ text: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_TEXT_LENGTH$1)),
9225
+ replyTo: signalTextReplyToSchema.optional(),
9226
+ meta: signalTextMetaSchema.optional()
9227
+ });
9228
+ const signalTextSchema = object({
9229
+ type: literal("signal.text"),
9230
+ data: object({
9231
+ text: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_TEXT_LENGTH$1)),
9232
+ replyTo: signalTextReplyToSchema.optional(),
9233
+ meta: postedSignalTextMetaSchema.optional()
9234
+ })
9235
+ });
9145
9236
  const ATSD_MENTION_DISPATCH_RESULT_SCHEMA_VERSION = 2;
9146
9237
  const atsdMentionDispatchStatusSchema = _enum([
9147
9238
  "dispatch_ready",
@@ -9214,6 +9305,7 @@ const atsdDispatchSourceSignalSnapshotSchema = strictObject({
9214
9305
  ]).nullable(),
9215
9306
  profileWakeToken: string().regex(MENTION_TOKEN_PATTERN$2).max(128).optional()
9216
9307
  });
9308
+ const atsdDispatchReplyToSnapshotSchema = signalTextReplyToSchema;
9217
9309
  const atsdDispatchQueueLegacyMessageSchemaV1 = strictObject({
9218
9310
  v: literal(1),
9219
9311
  dispatchId: string().min(1),
@@ -9228,6 +9320,7 @@ const atsdDispatchQueueMessageSchema = strictObject({
9228
9320
  dispatchId: string().min(1),
9229
9321
  spaceId: string().min(1),
9230
9322
  sourceEventId: string().min(1),
9323
+ sourceClientMessageId: string().min(1).max(200).nullable().optional(),
9231
9324
  targetProfileId: string().min(1),
9232
9325
  targetProfileWakeToken: string().regex(MENTION_TOKEN_PATTERN$2).max(128).optional(),
9233
9326
  dispatchChainId: string().min(1),
@@ -9247,6 +9340,7 @@ const atsdDispatchQueueMessageSchema = strictObject({
9247
9340
  dispatchRulesSnapshot: atsdDispatchRulesSnapshotSchema,
9248
9341
  dispatchSnapshot: atsdDispatchSnapshotSchema,
9249
9342
  sourceSignalSnapshot: atsdDispatchSourceSignalSnapshotSchema.optional(),
9343
+ replyToSnapshot: atsdDispatchReplyToSnapshotSchema.optional(),
9250
9344
  spaceNameSnapshot: string().min(1).nullable().optional(),
9251
9345
  sourceProfileNameSnapshot: string().min(1).nullable().optional(),
9252
9346
  targetProfileNameSnapshot: string().min(1).nullable().optional(),
@@ -9285,6 +9379,7 @@ const atsdDispatchQueueMessageSchema = strictObject({
9285
9379
  message: "controllerSnapshot target binding fields must match dispatchSnapshot"
9286
9380
  });
9287
9381
  });
9382
+ const atsdDispatchQueueIngressSchema = discriminatedUnion("v", [atsdDispatchQueueLegacyMessageSchemaV1, atsdDispatchQueueMessageSchema]);
9288
9383
  const ATSD_TASK_RESULT_SCHEMA_VERSION = 3;
9289
9384
  const ATSD_TASK_RESULT_SCHEMA_VERSION_PREVIOUS = 2;
9290
9385
  const ATSD_TASK_RESULT_SCHEMA_VERSION_LEGACY = 1;
@@ -9404,6 +9499,7 @@ const atsdTaskResultEnvelopeSchema = union([
9404
9499
  atsdTaskResultEnvelopeSchemaV1
9405
9500
  ]);
9406
9501
  const DAEMON_HUB_SCHEMA_VERSION = 1;
9502
+ const MENTION_TOKEN_PATTERN$1 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
9407
9503
  const daemonHubErrorCodeSchema = _enum([
9408
9504
  "daemon.session.reject_conflict",
9409
9505
  "daemon.session.not_found",
@@ -9468,6 +9564,46 @@ const daemonHubLookupRouteResponseSchema = discriminatedUnion("online", [strictO
9468
9564
  online: literal(false),
9469
9565
  reasonCode: daemonHubErrorCodeSchema
9470
9566
  })]);
9567
+ const daemonHubDispatchSourceSignalSchema = strictObject({
9568
+ profileId: string().min(1).nullable(),
9569
+ profileKind: _enum([
9570
+ "agent",
9571
+ "human",
9572
+ "system"
9573
+ ]).nullable(),
9574
+ profileHandle: string().regex(MENTION_TOKEN_PATTERN$1).max(128).optional(),
9575
+ profileWakeToken: string().regex(MENTION_TOKEN_PATTERN$1).max(128).optional(),
9576
+ text: string().min(1).max(MAX_TEXT_LENGTH$1)
9577
+ });
9578
+ const daemonHubDeliverDispatchPayloadSchema = strictObject({
9579
+ attemptId: string().min(1),
9580
+ dispatchId: string().min(1),
9581
+ taskId: string().min(1),
9582
+ spaceId: string().min(1),
9583
+ sourceEventId: string().min(1),
9584
+ sourceSignal: daemonHubDispatchSourceSignalSchema,
9585
+ targetProfileId: string().min(1),
9586
+ dispatchContractVersion: number().int().positive(),
9587
+ dispatchPolicy: runtimeDispatchPolicySchema,
9588
+ controllerSnapshot: atsdDispatchControllerSnapshotSchema,
9589
+ contextIdMappingSpec: runtimeAgentContextIdMappingSpecSchema.nullable(),
9590
+ dispatchRulesSnapshot: atsdDispatchRulesSnapshotSchema,
9591
+ enqueuedAtMs: number().int().nonnegative(),
9592
+ idempotencyKey: string().min(1),
9593
+ spacePassword: spacePasswordSchema.optional(),
9594
+ targetProfileName: string().min(1).max(MAX_PROFILE_NAME_LENGTH).optional(),
9595
+ targetProfileHandle: string().regex(MENTION_TOKEN_PATTERN$1).max(128).optional(),
9596
+ targetProfileWakeToken: string().regex(MENTION_TOKEN_PATTERN$1).max(128).optional(),
9597
+ conversationBinding: conversationBindingRecordSchema.optional(),
9598
+ deliveryRecoveryReason: atsdDispatchDeliveryRecoveryReasonSchema.optional(),
9599
+ dispatchChainId: string().min(1).optional(),
9600
+ autoRelayDepth: number().int().nonnegative().optional(),
9601
+ visitedProfileIds: array(string().min(1)).max(256).optional(),
9602
+ visitedProfileIdsHash: string().min(1).optional(),
9603
+ transportMode: runtimeTransportModeSchema.nullable().optional(),
9604
+ streamingMode: runtimeStreamingModeSchema.optional(),
9605
+ sourceSignalSnapshot: atsdDispatchSourceSignalSnapshotSchema.optional()
9606
+ });
9471
9607
  const daemonHubDeliverDispatchRequestSchema = strictObject({
9472
9608
  v: literal(DAEMON_HUB_SCHEMA_VERSION),
9473
9609
  dispatchId: string().min(1),
@@ -9478,7 +9614,7 @@ const daemonHubDeliverDispatchRequestSchema = strictObject({
9478
9614
  connectionGeneration: number().int().positive(),
9479
9615
  leaseEpoch: number().int().positive(),
9480
9616
  deliveryRecoveryReason: atsdDispatchDeliveryRecoveryReasonSchema.optional(),
9481
- payload: record(string(), unknown())
9617
+ payload: daemonHubDeliverDispatchPayloadSchema
9482
9618
  });
9483
9619
  const daemonHubDeliverDispatchResponseSchema = strictObject({
9484
9620
  accepted: boolean(),
@@ -10066,76 +10202,6 @@ const helloAckSchema = object({
10066
10202
  type: literal("system.hello.ack"),
10067
10203
  profile: profileSchema
10068
10204
  });
10069
- const SPACE_MEMBER_JOIN_NOTICE_PURPOSE = "space_membership_join_notice";
10070
- const SPACE_MEMBER_REMOVE_NOTICE_PURPOSE = "space_membership_remove_notice";
10071
- const SPACE_MENTION_REJECT_NOTICE_PURPOSE = "space_mention_reject_notice";
10072
- const AGENT_REPLY_PREVIEW_PURPOSE = "agent_reply_preview";
10073
- const AGENT_REPLY_PREVIEW_END_PURPOSE = "agent_reply_preview_end";
10074
- const CONVERSATION_CONTINUITY_WARNING_PURPOSE = "conversation_continuity_warning";
10075
- const MENTION_TOKEN_PATTERN$1 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
10076
- const normalizeMentionToken$1 = (value) => {
10077
- const normalized = trimmedStringFromUnknown(value);
10078
- if (!normalized) return;
10079
- return MENTION_TOKEN_PATTERN$1.test(normalized) ? normalized : void 0;
10080
- };
10081
- const signalTextMetaSchema = object({
10082
- transient: literal(true).optional(),
10083
- purpose: preprocess(trimmedStringFromUnknown, string().min(1).max(80)).optional(),
10084
- dispatchId: preprocess(trimmedStringFromUnknown, string().max(200)).optional(),
10085
- targetProfileId: atsRuntimeProfileIdSchema.optional(),
10086
- targetProfileKind: _enum(["human", "agent"]).optional(),
10087
- targetProfileName: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_PROFILE_NAME_LENGTH)).optional(),
10088
- targetProfileHandle: preprocess(normalizeMentionToken$1, string().regex(MENTION_TOKEN_PATTERN$1).max(128)).optional(),
10089
- targetWakeToken: preprocess(normalizeMentionToken$1, string().regex(MENTION_TOKEN_PATTERN$1).max(128)).optional(),
10090
- addedByProfileId: atsRuntimeProfileIdSchema.optional(),
10091
- addedByDisplayName: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_PROFILE_NAME_LENGTH)).optional(),
10092
- removedByProfileId: atsRuntimeProfileIdSchema.optional(),
10093
- removedByDisplayName: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_PROFILE_NAME_LENGTH)).optional()
10094
- });
10095
- const postedSignalTextMetaSchema = signalTextMetaSchema.superRefine((meta, context) => {
10096
- if (meta.purpose !== SPACE_MEMBER_JOIN_NOTICE_PURPOSE && meta.purpose !== SPACE_MEMBER_REMOVE_NOTICE_PURPOSE) return;
10097
- if (!meta.targetProfileId) context.addIssue({
10098
- code: "custom",
10099
- message: "targetProfileId is required for space member notices",
10100
- path: ["targetProfileId"]
10101
- });
10102
- if (!meta.targetProfileKind) context.addIssue({
10103
- code: "custom",
10104
- message: "targetProfileKind is required for space member notices",
10105
- path: ["targetProfileKind"]
10106
- });
10107
- if (meta.purpose === SPACE_MEMBER_JOIN_NOTICE_PURPOSE && !meta.addedByProfileId) context.addIssue({
10108
- code: "custom",
10109
- message: "addedByProfileId is required for space member notices",
10110
- path: ["addedByProfileId"]
10111
- });
10112
- if (meta.purpose === SPACE_MEMBER_JOIN_NOTICE_PURPOSE && !meta.addedByDisplayName) context.addIssue({
10113
- code: "custom",
10114
- message: "addedByDisplayName is required for space member notices",
10115
- path: ["addedByDisplayName"]
10116
- });
10117
- if (meta.purpose === SPACE_MEMBER_REMOVE_NOTICE_PURPOSE && !meta.removedByProfileId) context.addIssue({
10118
- code: "custom",
10119
- message: "removedByProfileId is required for space member notices",
10120
- path: ["removedByProfileId"]
10121
- });
10122
- if (meta.purpose === SPACE_MEMBER_REMOVE_NOTICE_PURPOSE && !meta.removedByDisplayName) context.addIssue({
10123
- code: "custom",
10124
- message: "removedByDisplayName is required for space member notices",
10125
- path: ["removedByDisplayName"]
10126
- });
10127
- });
10128
- const signalTextDataSchema = object({
10129
- text: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_TEXT_LENGTH$1)),
10130
- meta: signalTextMetaSchema.optional()
10131
- });
10132
- const signalTextSchema = object({
10133
- type: literal("signal.text"),
10134
- data: object({
10135
- text: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_TEXT_LENGTH$1)),
10136
- meta: postedSignalTextMetaSchema.optional()
10137
- })
10138
- });
10139
10205
  const baseEnvelopeShape = {
10140
10206
  v: literal(1),
10141
10207
  id: nonEmptyTrimmedStringFromUnknown,
@@ -12440,15 +12506,6 @@ function parseRuntimeTransportMode(value) {
12440
12506
  if (value === "local-cli") return value;
12441
12507
  return null;
12442
12508
  }
12443
- function parseControllerKind(value) {
12444
- if (value === "builtin" || value === "custom") return value;
12445
- return null;
12446
- }
12447
- function parseDispatchSourceProfileKind(value) {
12448
- const normalized = normalizeText$12(value).toLowerCase();
12449
- if (normalized === "agent" || normalized === "human" || normalized === "system") return normalized;
12450
- return null;
12451
- }
12452
12509
  function parseContextIdMappingSpec(value) {
12453
12510
  const record = asRecord(value);
12454
12511
  if (!record) return null;
@@ -12485,7 +12542,7 @@ function normalizeOptionalText$21(value) {
12485
12542
  function nowIsoString() {
12486
12543
  return (/* @__PURE__ */ new Date()).toISOString();
12487
12544
  }
12488
- function toErrorMessage$15(error) {
12545
+ function toErrorMessage$16(error) {
12489
12546
  if (error instanceof Error) return error.message;
12490
12547
  return String(error);
12491
12548
  }
@@ -15015,6 +15072,58 @@ async function readObservedRuntimeState() {
15015
15072
  });
15016
15073
  }
15017
15074
 
15075
+ //#endregion
15076
+ //#region src/system/daemon-service-start-recovery.ts
15077
+ const ROOT_ERROR_PATTERN$1 = /\s*Try re-running the command as root for richer errors\.?/i;
15078
+ async function startDaemonSystemServiceWithAutoRepair(input) {
15079
+ let autoRepairAttempted = false;
15080
+ try {
15081
+ await input.systemManager.start();
15082
+ return { autoRepairAttempted };
15083
+ } catch (error) {
15084
+ if (!shouldAttemptLaunchdAutoRepair({
15085
+ controller: input.systemManager.controller,
15086
+ error
15087
+ })) throw error;
15088
+ autoRepairAttempted = true;
15089
+ await input.onAutoRepairAttempt?.();
15090
+ try {
15091
+ await input.systemManager.uninstall().catch(() => void 0);
15092
+ await input.systemManager.install(input.serviceCommandSpec);
15093
+ await input.systemManager.start();
15094
+ await input.onAutoRepairRecovered?.();
15095
+ return { autoRepairAttempted };
15096
+ } catch (retryError) {
15097
+ throw buildLaunchdAutoRepairFailureError({
15098
+ initialError: error,
15099
+ retryError
15100
+ });
15101
+ }
15102
+ }
15103
+ }
15104
+ function sanitizeSystemServiceErrorMessage$1(message) {
15105
+ return message.replace(ROOT_ERROR_PATTERN$1, "");
15106
+ }
15107
+ function isLaunchdBootstrapIosError$1(message) {
15108
+ const normalized = message.toLowerCase();
15109
+ return normalized.includes("bootstrap failed") && normalized.includes("input/output error");
15110
+ }
15111
+ function shouldAttemptLaunchdAutoRepair(input) {
15112
+ if (input.controller !== "launchd") return false;
15113
+ return isLaunchdBootstrapIosError$1(sanitizeSystemServiceErrorMessage$1(toErrorMessage$15(input.error)));
15114
+ }
15115
+ function buildLaunchdAutoRepairFailureError(input) {
15116
+ return new Error([
15117
+ "launchd auto-repair retry failed.",
15118
+ `initial error: ${toErrorMessage$15(input.initialError)}`,
15119
+ `retry error: ${toErrorMessage$15(input.retryError)}`
15120
+ ].join(" "));
15121
+ }
15122
+ function toErrorMessage$15(error) {
15123
+ if (error instanceof Error) return error.message;
15124
+ return String(error);
15125
+ }
15126
+
15018
15127
  //#endregion
15019
15128
  //#region src/system/daemon-service-alignment-executor.ts
15020
15129
  const ALIGNMENT_STOP_WAIT_MS = 3e3;
@@ -15138,7 +15247,10 @@ async function runDaemonServiceFullAlignmentLocked(input) {
15138
15247
  }
15139
15248
  if (shouldRestoreBackground) {
15140
15249
  await input.emitProgress("starting_background_service");
15141
- await serviceManager.start();
15250
+ await startDaemonSystemServiceWithAutoRepair({
15251
+ serviceCommandSpec: buildDaemonSystemServiceCommandSpec({ controller: serviceManager.controller }),
15252
+ systemManager: serviceManager
15253
+ });
15142
15254
  await waitForAlignmentBackgroundStartup({ manager: serviceManager });
15143
15255
  input.state.restoredBackground = true;
15144
15256
  }
@@ -20372,7 +20484,7 @@ const ATS_HEADER_VISITED_PROFILE_IDS = "x-ats-visited-profile-ids";
20372
20484
  const ATS_HEADER_VISITED_PROFILE_IDS_HASH = "x-ats-visited-profile-ids-hash";
20373
20485
  function buildAtsRequestHeaders(input) {
20374
20486
  const headers = {};
20375
- headers[ATS_HEADER_REQUEST_ID] = normalize$1(input.requestId) || crypto.randomUUID();
20487
+ headers[ATS_HEADER_REQUEST_ID] = normalize$1(input.requestId) || crypto$1.randomUUID();
20376
20488
  const profile = normalize$1(input.profile);
20377
20489
  if (profile) headers[ATS_HEADER_PROFILE] = profile;
20378
20490
  const profileId = normalize$1(input.profileId);
@@ -24120,18 +24232,15 @@ const MENTION_TOKEN_REGEX$1 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
24120
24232
  const COMPACT_DISPATCH_BOOTSTRAP_TEMPLATE_VERSION = "compact-dispatch-bootstrap-v1";
24121
24233
  function parseDispatchTask(input) {
24122
24234
  const payload = resolveDispatchTaskPayload(input.deliverRequest);
24123
- if (!payload) return null;
24124
24235
  const requiredFields = resolveDispatchTaskRequiredFields({
24125
24236
  deliverRequest: input.deliverRequest,
24126
24237
  payload
24127
24238
  });
24128
24239
  if (!requiredFields) return null;
24129
- const sourceSignal = asRecord(payload.sourceSignal);
24130
- const sourceSignalSnapshot = asRecord(payload.sourceSignalSnapshot);
24131
- const mentionSourceProfileId = normalizeOptionalText$21(sourceSignal?.profileId) ?? normalizeOptionalText$21(sourceSignalSnapshot?.profileId);
24132
- const mentionSourceProfileKind = parseDispatchSourceProfileKind(sourceSignal?.profileKind ?? sourceSignalSnapshot?.profileKind);
24133
- const mentionSourceProfileWakeToken = normalizeOptionalText$21(sourceSignal?.profileWakeToken) ?? normalizeOptionalText$21(sourceSignalSnapshot?.profileWakeToken);
24134
- const prompt = normalizeOptionalText$21(sourceSignal?.text) ?? normalizeOptionalText$21(sourceSignalSnapshot?.text);
24240
+ const mentionSourceProfileId = normalizeOptionalText$21(payload.sourceSignal.profileId) ?? normalizeOptionalText$21(payload.sourceSignalSnapshot?.profileId);
24241
+ const mentionSourceProfileKind = payload.sourceSignal.profileKind ?? payload.sourceSignalSnapshot?.profileKind ?? null;
24242
+ const mentionSourceProfileWakeToken = normalizeOptionalText$21(payload.sourceSignal.profileWakeToken) ?? normalizeOptionalText$21(payload.sourceSignalSnapshot?.profileWakeToken);
24243
+ const prompt = normalizeOptionalText$21(payload.sourceSignal.text) ?? normalizeOptionalText$21(payload.sourceSignalSnapshot?.text);
24135
24244
  const targetProfileWakeToken = normalizeOptionalText$21(payload.targetProfileWakeToken);
24136
24245
  const triggerMode = "mention_only";
24137
24246
  const sequence = normalizeNonNegativeInteger$1(payload.enqueuedAtMs) ?? Date.now();
@@ -24142,11 +24251,11 @@ function parseDispatchTask(input) {
24142
24251
  });
24143
24252
  if (!(prompt && controllerSelection)) return null;
24144
24253
  const fallbackControllerSettings = createDefaultRuntimeAgentControllerSettings(controllerSelection.controllerRef);
24145
- const conversationBinding = resolveConversationBindingSnapshot(payload);
24254
+ const conversationBinding = payload.conversationBinding ?? null;
24146
24255
  const deliveryRecoveryReason = resolveDeliveryRecoveryReason(payload);
24147
- const transportMode = parseTransportMode(payload.transportMode) ?? input.fallbackRouteConfig?.transportMode ?? fallbackControllerSettings.transportMode;
24148
- const streamingMode = parseStreamingMode(payload.streamingMode) ?? input.fallbackRouteConfig?.streamingMode ?? fallbackControllerSettings.streamingMode;
24149
- const contextIdMappingSpec = parseContextIdMappingSpec(payload.contextIdMappingSpec) ?? input.fallbackRouteConfig?.contextIdMappingSpec ?? fallbackControllerSettings.contextIdMappingSpec;
24256
+ const transportMode = payload.transportMode ?? input.fallbackRouteConfig?.transportMode ?? fallbackControllerSettings.transportMode;
24257
+ const streamingMode = payload.streamingMode ?? input.fallbackRouteConfig?.streamingMode ?? fallbackControllerSettings.streamingMode;
24258
+ const contextIdMappingSpec = payload.contextIdMappingSpec ?? input.fallbackRouteConfig?.contextIdMappingSpec ?? fallbackControllerSettings.contextIdMappingSpec;
24150
24259
  return {
24151
24260
  ...requiredFields,
24152
24261
  conversationBinding,
@@ -24169,16 +24278,8 @@ function resolveDeliveryRecoveryReason(payload) {
24169
24278
  if (normalized === "connection_replaced" || normalized === "route_lost") return normalized;
24170
24279
  return null;
24171
24280
  }
24172
- function resolveConversationBindingSnapshot(payload) {
24173
- const candidate = payload.conversationBinding;
24174
- if (!candidate) return null;
24175
- const parsed = conversationBindingRecordSchema.safeParse(candidate);
24176
- return parsed.success ? parsed.data : null;
24177
- }
24178
24281
  function resolveDispatchTaskPayload(request) {
24179
- const { payload } = request;
24180
- if (!payload || typeof payload !== "object" || Array.isArray(payload)) return null;
24181
- return payload;
24282
+ return request.payload;
24182
24283
  }
24183
24284
  function resolveDispatchTaskRequiredFields(input) {
24184
24285
  const dispatchId = normalizeOptionalText$21(input.payload.dispatchId) ?? input.deliverRequest.dispatchId;
@@ -24198,9 +24299,8 @@ function resolveDispatchTaskRequiredFields(input) {
24198
24299
  };
24199
24300
  }
24200
24301
  function resolveDispatchTaskControllerSelection(input) {
24201
- const controllerSnapshot = asRecord(input.payload.controllerSnapshot);
24202
- const controllerRef = normalizeOptionalText$21(controllerSnapshot?.controllerRef) ?? input.fallbackControllerRef;
24203
- const controllerKind = parseControllerKind(controllerSnapshot?.controllerKind) ?? input.fallbackControllerKind;
24302
+ const controllerRef = normalizeOptionalText$21(input.payload.controllerSnapshot.controllerRef) ?? input.fallbackControllerRef;
24303
+ const controllerKind = input.payload.controllerSnapshot.controllerKind ?? input.fallbackControllerKind;
24204
24304
  if (!(controllerRef && controllerKind)) return null;
24205
24305
  return {
24206
24306
  controllerKind,
@@ -24414,10 +24514,10 @@ async function resolveDispatchMentionSourceContext(input) {
24414
24514
  }
24415
24515
  }
24416
24516
  function buildDispatchCorrelation(input) {
24417
- const payload = input.deliverRequest.payload && typeof input.deliverRequest.payload === "object" && !Array.isArray(input.deliverRequest.payload) ? input.deliverRequest.payload : {};
24517
+ const payload = input.deliverRequest.payload;
24418
24518
  return {
24419
24519
  attemptId: input.parsedTask?.attemptId ?? normalizeOptionalText$21(payload.attemptId) ?? normalizeOptionalText$21(input.deliverRequest.attemptId) ?? "unknown-attempt",
24420
- controllerRef: input.parsedTask?.controllerRef ?? normalizeOptionalText$21(asRecord(payload.controllerSnapshot)?.controllerRef),
24520
+ controllerRef: input.parsedTask?.controllerRef ?? normalizeOptionalText$21(payload.controllerSnapshot.controllerRef),
24421
24521
  dispatchId: input.parsedTask?.dispatchId ?? normalizeOptionalText$21(payload.dispatchId) ?? input.deliverRequest.dispatchId,
24422
24522
  sourceEventId: input.parsedTask?.sourceEventId ?? normalizeOptionalText$21(payload.sourceEventId) ?? "unknown-source-event",
24423
24523
  targetProfileId: input.parsedTask?.targetProfileId ?? normalizeOptionalText$21(payload.targetProfileId) ?? input.deliverRequest.profileId,
@@ -24710,7 +24810,7 @@ async function syncDaemonRouteCatalogState(input) {
24710
24810
  return {
24711
24811
  status: "failed",
24712
24812
  reason: "load_failed",
24713
- errorMessage: toErrorMessage$15(error)
24813
+ errorMessage: toErrorMessage$16(error)
24714
24814
  };
24715
24815
  }
24716
24816
  const nextFingerprint = buildRouteCatalogFingerprint(nextCatalog);
@@ -24725,7 +24825,7 @@ async function syncDaemonRouteCatalogState(input) {
24725
24825
  return {
24726
24826
  status: "failed",
24727
24827
  reason: "register_failed",
24728
- errorMessage: toErrorMessage$15(error)
24828
+ errorMessage: toErrorMessage$16(error)
24729
24829
  };
24730
24830
  }
24731
24831
  const diff = buildRouteCatalogDiff({
@@ -24829,7 +24929,9 @@ function createDispatchBackpressureQueue(input) {
24829
24929
  controllerKey: selectedTask.controllerKey,
24830
24930
  dispatchId: selectedTask.dispatchId,
24831
24931
  profileId: selectedTask.profileId,
24932
+ spaceId: selectedTask.spaceId,
24832
24933
  taskId: selectedTask.taskId,
24934
+ targetLabel: selectedTask.targetLabel,
24833
24935
  transportMode: selectedTask.transportMode,
24834
24936
  ...buildSnapshot(selectedTask.profileId, selectedTask.controllerKey)
24835
24937
  };
@@ -24847,7 +24949,9 @@ function createDispatchBackpressureQueue(input) {
24847
24949
  errorMessage: completionResult.errorMessage,
24848
24950
  profileId: selectedTask.profileId,
24849
24951
  result: completionResult.result,
24952
+ spaceId: selectedTask.spaceId,
24850
24953
  taskId: selectedTask.taskId,
24954
+ targetLabel: selectedTask.targetLabel,
24851
24955
  transportMode: selectedTask.transportMode
24852
24956
  });
24853
24957
  }).catch((error) => {
@@ -24861,7 +24965,9 @@ function createDispatchBackpressureQueue(input) {
24861
24965
  errorMessage: toErrorMessage$8(error),
24862
24966
  profileId: selectedTask.profileId,
24863
24967
  result: "failed",
24968
+ spaceId: selectedTask.spaceId,
24864
24969
  taskId: selectedTask.taskId,
24970
+ targetLabel: selectedTask.targetLabel,
24865
24971
  transportMode: selectedTask.transportMode
24866
24972
  });
24867
24973
  }).finally(() => {
@@ -26836,7 +26942,9 @@ function enqueueDispatchDeliverFrame(input) {
26836
26942
  controllerKey: queueLogMeta.controllerKey,
26837
26943
  dispatchId: correlation.dispatchId,
26838
26944
  profileId: deliverRequest.profileId,
26945
+ spaceId: queueLogMeta.spaceId,
26839
26946
  taskId: correlation.taskId,
26947
+ targetLabel: queueLogMeta.targetLabel,
26840
26948
  transportMode: queueLogMeta.transportMode,
26841
26949
  run: async () => {
26842
26950
  return await handleDispatchDeliverFrame({
@@ -26878,7 +26986,7 @@ function enqueueDispatchDeliverFrame(input) {
26878
26986
  emitRunLine({
26879
26987
  presenter: input.presenter,
26880
26988
  code: "daemon.run.dispatch_queue_rejected",
26881
- text: `dispatch queue rejected task ${correlation.taskId}: queue is full`,
26989
+ text: `dispatch queue rejected task ${correlation.taskId} for ${queueLogMeta.targetLabel}: queue is full`,
26882
26990
  payload: {
26883
26991
  adapterId: queueLogMeta.adapterId,
26884
26992
  activeForController: enqueueResult.snapshot.activeForController,
@@ -26895,8 +27003,10 @@ function enqueueDispatchDeliverFrame(input) {
26895
27003
  queueDepth: enqueueResult.snapshot.queueDepth,
26896
27004
  queueMax: enqueueResult.snapshot.limits.queueMax,
26897
27005
  result: "failed",
27006
+ spaceId: queueLogMeta.spaceId,
26898
27007
  step: "rejected",
26899
27008
  taskId: correlation.taskId,
27009
+ targetLabel: queueLogMeta.targetLabel,
26900
27010
  transportMode: queueLogMeta.transportMode
26901
27011
  }
26902
27012
  });
@@ -26905,7 +27015,7 @@ function enqueueDispatchDeliverFrame(input) {
26905
27015
  emitRunLine({
26906
27016
  presenter: input.presenter,
26907
27017
  code: "daemon.run.dispatch_queue_enqueued",
26908
- text: `dispatch queue enqueued task ${correlation.taskId}`,
27018
+ text: `dispatch queue enqueued task ${correlation.taskId} for ${queueLogMeta.targetLabel}`,
26909
27019
  payload: {
26910
27020
  adapterId: queueLogMeta.adapterId,
26911
27021
  activeForController: enqueueResult.snapshot.activeForController,
@@ -26924,8 +27034,10 @@ function enqueueDispatchDeliverFrame(input) {
26924
27034
  queueDepth: enqueueResult.snapshot.queueDepth,
26925
27035
  queueMax: enqueueResult.snapshot.limits.queueMax,
26926
27036
  result: null,
27037
+ spaceId: queueLogMeta.spaceId,
26927
27038
  step: "enqueued",
26928
27039
  taskId: correlation.taskId,
27040
+ targetLabel: queueLogMeta.targetLabel,
26929
27041
  transportMode: queueLogMeta.transportMode
26930
27042
  }
26931
27043
  });
@@ -27684,7 +27796,7 @@ function toTaskExecutionError(error) {
27684
27796
  return {
27685
27797
  errorCode: "dispatch.execution_failed",
27686
27798
  errorType: "internal",
27687
- message: toErrorMessage$15(error)
27799
+ message: toErrorMessage$16(error)
27688
27800
  };
27689
27801
  }
27690
27802
  function normalizeOptionalContextId(contextId) {
@@ -27863,6 +27975,8 @@ function resolveDispatchQueueLogMeta(input) {
27863
27975
  if (!parsedTask) return {
27864
27976
  adapterId: null,
27865
27977
  controllerKey: `profile:${input.deliverRequest.profileId}`,
27978
+ spaceId: null,
27979
+ targetLabel: `profile:${input.deliverRequest.profileId}`,
27866
27980
  transportMode: null
27867
27981
  };
27868
27982
  const support = resolveLocalRuntimeControllerSupport({
@@ -27876,9 +27990,16 @@ function resolveDispatchQueueLogMeta(input) {
27876
27990
  controllerRef: parsedTask.controllerRef,
27877
27991
  profileId: input.deliverRequest.profileId
27878
27992
  }),
27993
+ spaceId: parsedTask.spaceId,
27994
+ targetLabel: resolveDispatchQueueTargetLabel(parsedTask),
27879
27995
  transportMode: parsedTask.transportMode
27880
27996
  };
27881
27997
  }
27998
+ function resolveDispatchQueueTargetLabel(parsedTask) {
27999
+ const wakeToken = normalizeOptionalText$21(parsedTask.targetProfileWakeToken);
28000
+ if (wakeToken) return wakeToken.startsWith("@") ? wakeToken : `@${wakeToken}`;
28001
+ return `profile:${parsedTask.targetProfileId}`;
28002
+ }
27882
28003
  function buildDispatchControllerKey(input) {
27883
28004
  const normalizedControllerKind = typeof input.controllerKind === "string" ? input.controllerKind.trim() : "";
27884
28005
  const normalizedControllerRef = typeof input.controllerRef === "string" ? input.controllerRef.trim() : "";
@@ -28202,7 +28323,7 @@ async function runDaemonSocketSession(input) {
28202
28323
  emitRunLine({
28203
28324
  presenter: input.presenter,
28204
28325
  code: "daemon.run.dispatch_queue_started",
28205
- text: `dispatch queue started task ${event.taskId}`,
28326
+ text: `dispatch queue started task ${event.taskId} for ${event.targetLabel}`,
28206
28327
  payload: {
28207
28328
  adapterId: event.adapterId,
28208
28329
  activeForController: event.activeForController,
@@ -28219,16 +28340,18 @@ async function runDaemonSocketSession(input) {
28219
28340
  queueDepth: event.queueDepth,
28220
28341
  queueMax: event.limits.queueMax,
28221
28342
  result: null,
28343
+ spaceId: event.spaceId,
28222
28344
  step: "started",
28223
28345
  taskId: event.taskId,
28346
+ targetLabel: event.targetLabel,
28224
28347
  transportMode: event.transportMode
28225
28348
  }
28226
28349
  });
28227
28350
  },
28228
28351
  onTaskCompleted: (event) => {
28229
- let completionText = `dispatch queue failed task ${event.taskId}`;
28230
- if (event.result === "success") completionText = `dispatch queue completed task ${event.taskId}`;
28231
- else if (event.result === "partial_success") completionText = `dispatch queue partially completed task ${event.taskId}`;
28352
+ let completionText = `dispatch queue failed task ${event.taskId} for ${event.targetLabel}`;
28353
+ if (event.result === "success") completionText = `dispatch queue completed task ${event.taskId} for ${event.targetLabel}`;
28354
+ else if (event.result === "partial_success") completionText = `dispatch queue partially completed task ${event.taskId} for ${event.targetLabel}`;
28232
28355
  emitRunLine({
28233
28356
  presenter: input.presenter,
28234
28357
  code: "daemon.run.dispatch_queue_completed",
@@ -28250,8 +28373,10 @@ async function runDaemonSocketSession(input) {
28250
28373
  queueDepth: event.queueDepth,
28251
28374
  queueMax: event.limits.queueMax,
28252
28375
  result: event.result,
28376
+ spaceId: event.spaceId,
28253
28377
  step: "completed",
28254
28378
  taskId: event.taskId,
28379
+ targetLabel: event.targetLabel,
28255
28380
  transportMode: event.transportMode
28256
28381
  }
28257
28382
  });
@@ -28370,7 +28495,7 @@ async function runDaemonSocketSession(input) {
28370
28495
  emitRunLine({
28371
28496
  presenter: input.presenter,
28372
28497
  code: "daemon.run.heartbeat_failed",
28373
- text: `heartbeat failed (${String(consecutiveHeartbeatFailures)}/${String(HEARTBEAT_CONSECUTIVE_FAILURES_BEFORE_CLOSE)}): ${toErrorMessage$15(error)}`
28498
+ text: `heartbeat failed (${String(consecutiveHeartbeatFailures)}/${String(HEARTBEAT_CONSECUTIVE_FAILURES_BEFORE_CLOSE)}): ${toErrorMessage$16(error)}`
28374
28499
  });
28375
28500
  if (shouldCloseSocket) {
28376
28501
  input.socket.close(1011, "heartbeat_failed");
@@ -28402,7 +28527,7 @@ async function runDaemonSocketSession(input) {
28402
28527
  emitRunLine({
28403
28528
  presenter: input.presenter,
28404
28529
  code: "daemon.run.heartbeat_failed",
28405
- text: `heartbeat failed: ${toErrorMessage$15(error)}`
28530
+ text: `heartbeat failed: ${toErrorMessage$16(error)}`
28406
28531
  });
28407
28532
  });
28408
28533
  }, normalizedDelayMs);
@@ -28444,7 +28569,7 @@ async function runDaemonSocketSession(input) {
28444
28569
  emitRunLine({
28445
28570
  presenter: input.presenter,
28446
28571
  code: "daemon.run.catalog_sync_signal_read_failed",
28447
- text: `catalog sync signal read failed: ${toErrorMessage$15(error)}`
28572
+ text: `catalog sync signal read failed: ${toErrorMessage$16(error)}`
28448
28573
  });
28449
28574
  }).finally(() => {
28450
28575
  scheduleCatalogSyncSignalPoll();
@@ -28618,7 +28743,7 @@ async function runDaemonSocketSession(input) {
28618
28743
  emitRunLine({
28619
28744
  presenter: input.presenter,
28620
28745
  code: "daemon.run.socket_error",
28621
- text: `daemon stream socket error: ${toErrorMessage$15(error)}`
28746
+ text: `daemon stream socket error: ${toErrorMessage$16(error)}`
28622
28747
  });
28623
28748
  });
28624
28749
  input.socket.onMessage((raw) => {
@@ -28994,7 +29119,7 @@ const backupAndCleanRuntimeState = async (input) => {
28994
29119
  appliedAt: input.nowIso,
28995
29120
  backupPaths,
28996
29121
  cleanedPaths,
28997
- errorMessage: toErrorMessage$15(error),
29122
+ errorMessage: toErrorMessage$16(error),
28998
29123
  fromEpoch: input.fromEpoch,
28999
29124
  reason: input.reason,
29000
29125
  status: "failed",
@@ -29168,7 +29293,7 @@ const runDaemonServiceLoop = async (input) => {
29168
29293
  emitRunLine({
29169
29294
  presenter: input.presenter,
29170
29295
  code: "daemon.run.projection_sync_failed",
29171
- text: `local projection repair failed before route registration: ${toErrorMessage$15(error)}`
29296
+ text: `local projection repair failed before route registration: ${toErrorMessage$16(error)}`
29172
29297
  });
29173
29298
  return null;
29174
29299
  });
@@ -29292,7 +29417,7 @@ const runDaemonServiceLoop = async (input) => {
29292
29417
  action: reconcileDecision.action,
29293
29418
  backoffMs,
29294
29419
  driftClass: reconcileDecision.driftClass,
29295
- error: toErrorMessage$15(error),
29420
+ error: toErrorMessage$16(error),
29296
29421
  foregroundActive: reconcileDecision.foregroundActive,
29297
29422
  lifecycleLocked: reconcileDecision.lifecycleLocked,
29298
29423
  owner: reconcileDecision.owner,
@@ -29303,7 +29428,7 @@ const runDaemonServiceLoop = async (input) => {
29303
29428
  action: reconcileDecision.action,
29304
29429
  backoffMs,
29305
29430
  driftClass: reconcileDecision.driftClass,
29306
- error: toErrorMessage$15(error),
29431
+ error: toErrorMessage$16(error),
29307
29432
  foregroundActive: reconcileDecision.foregroundActive,
29308
29433
  lifecycleLocked: reconcileDecision.lifecycleLocked,
29309
29434
  owner: reconcileDecision.owner,
@@ -29313,11 +29438,11 @@ const runDaemonServiceLoop = async (input) => {
29313
29438
  emitRunLine({
29314
29439
  presenter: input.presenter,
29315
29440
  code: "daemon.run.reconnect",
29316
- text: `daemon stream reconnect scheduled in ${String(backoffMs)}ms (${toErrorMessage$15(error)})`,
29441
+ text: `daemon stream reconnect scheduled in ${String(backoffMs)}ms (${toErrorMessage$16(error)})`,
29317
29442
  payload: {
29318
29443
  attempt: reconnectAttempt,
29319
29444
  backoffMs,
29320
- error: toErrorMessage$15(error)
29445
+ error: toErrorMessage$16(error)
29321
29446
  }
29322
29447
  });
29323
29448
  await sleep$5(backoffMs);
@@ -29766,12 +29891,6 @@ const QUIET_PRESENTER = {
29766
29891
  line: () => void 0,
29767
29892
  data: () => void 0
29768
29893
  };
29769
- const AUTO_STOP_WAIT_MS = 3e3;
29770
- const AUTO_STOP_POLL_MS = 200;
29771
- const NOT_INSTALLED_DAEMON_STATUS$1 = {
29772
- installed: false,
29773
- state: null
29774
- };
29775
29894
  async function resolveDaemonLocalServiceDemand(input) {
29776
29895
  const projection = await syncDeviceRuntimeStateProjection({ mode: "check" }).catch(() => null);
29777
29896
  const ownerUserId = normalizeOptionalString$7(input.ownerUserId);
@@ -29803,7 +29922,7 @@ async function resolveDaemonLocalServiceDemand(input) {
29803
29922
  return {
29804
29923
  decision: "indeterminate",
29805
29924
  hasWakeableLocalRoute: false,
29806
- reason: `failed to load local daemon routes: ${toErrorMessage$15(error)}`,
29925
+ reason: `failed to load local daemon routes: ${toErrorMessage$16(error)}`,
29807
29926
  wakeableLocalRouteCount: 0,
29808
29927
  projection
29809
29928
  };
@@ -29823,84 +29942,6 @@ async function resolveDaemonLocalServiceDemand(input) {
29823
29942
  projection
29824
29943
  };
29825
29944
  }
29826
- async function maybeAutoStopIdleBackgroundDaemonService(input) {
29827
- const localDemand = await resolveDaemonLocalServiceDemand({
29828
- ownerUserId: input.ownerUserId,
29829
- runtimeWorkdir: input.runtimeWorkdir
29830
- });
29831
- if (localDemand.decision !== "allow_auto_stop") return {
29832
- autoStopped: false,
29833
- effectiveRuntimeStatus: null,
29834
- localDemand
29835
- };
29836
- const status = await getDaemonStatus().catch(() => NOT_INSTALLED_DAEMON_STATUS$1);
29837
- if (!status.installed) return {
29838
- autoStopped: false,
29839
- effectiveRuntimeStatus: null,
29840
- localDemand
29841
- };
29842
- const runtimeState = await resolveDaemonRuntimeState(status);
29843
- if (!runtimeState || runtimeState.status !== "running" || runtimeState.mode !== "background" || runtimeState.managedBySystemService !== true) return {
29844
- autoStopped: false,
29845
- effectiveRuntimeStatus: runtimeState?.status ?? null,
29846
- localDemand
29847
- };
29848
- const { serviceManager, serviceManagerStatus } = await resolveDaemonServiceManagerForRuntimeState({
29849
- runtimeState,
29850
- status
29851
- });
29852
- const effectiveRuntimeStatus = getEffectiveDaemonRuntimeStatus({
29853
- runtimeState,
29854
- serviceManagerStatus
29855
- });
29856
- if (!serviceManager || effectiveRuntimeStatus !== "running") return {
29857
- autoStopped: false,
29858
- effectiveRuntimeStatus,
29859
- localDemand
29860
- };
29861
- try {
29862
- await serviceManager.stop();
29863
- if (!await waitForDaemonSystemServiceToStop({
29864
- manager: serviceManager,
29865
- waitMs: AUTO_STOP_WAIT_MS,
29866
- pollMs: AUTO_STOP_POLL_MS
29867
- })) {
29868
- input.presenter.line({
29869
- code: `${input.codePrefix}.auto_stop_failed`,
29870
- text: "ATS could not auto-stop the background service. Run `ats service stop` if you want it off right now."
29871
- });
29872
- return {
29873
- autoStopped: false,
29874
- effectiveRuntimeStatus,
29875
- localDemand
29876
- };
29877
- }
29878
- await clearDaemonServiceRuntimeState();
29879
- input.presenter.line({
29880
- code: `${input.codePrefix}.auto_stopped`,
29881
- text: formatDaemonAutoStoppedMessage(localDemand)
29882
- });
29883
- return {
29884
- autoStopped: true,
29885
- effectiveRuntimeStatus: "not_running",
29886
- localDemand
29887
- };
29888
- } catch (error) {
29889
- input.presenter.line({
29890
- code: `${input.codePrefix}.auto_stop_failed`,
29891
- text: `ATS could not auto-stop the background service. ${toErrorMessage$15(error)}`
29892
- });
29893
- return {
29894
- autoStopped: false,
29895
- effectiveRuntimeStatus,
29896
- localDemand
29897
- };
29898
- }
29899
- }
29900
- function formatDaemonAutoStoppedMessage(localDemand) {
29901
- if (localDemand.projection?.status === "ok" && localDemand.projection.projectedControllerIds.length === 0) return "ATS stopped the background service because this device currently has no projected local agents to wake.";
29902
- return "ATS stopped the background service because this device currently has no wakeable local agents.";
29903
- }
29904
29945
  function normalizeOptionalString$7(value) {
29905
29946
  const normalized = String(value ?? "").trim();
29906
29947
  return normalized.length > 0 ? normalized : null;
@@ -31507,6 +31548,7 @@ async function completeDaemonReinstallStart(input) {
31507
31548
  targetDesiredState: input.targetDesiredState,
31508
31549
  startAfterInstallMode: input.resolved.startAfterInstallMode
31509
31550
  }) === "never") {
31551
+ if (await maybePromptToRunDaemonAfterStoppedReinstall({ runtime: input.runtime })) return await autoStartDaemonAfterReinstall(input);
31510
31552
  await clearDaemonStartFailureStateSafely();
31511
31553
  if (input.resolved.emitStatusAfterSuccess) await input.resolved.runStatus({
31512
31554
  agentOverviewHandled: true,
@@ -31530,10 +31572,19 @@ async function completeDaemonReinstallStart(input) {
31530
31572
  }
31531
31573
  return await autoStartDaemonAfterReinstall(input);
31532
31574
  }
31575
+ async function maybePromptToRunDaemonAfterStoppedReinstall(input) {
31576
+ if (input.runtime.resolvedView !== "human" || !canUseInteractivePrompts(input.runtime)) return false;
31577
+ const selected = await confirm({
31578
+ message: "ATS Service is repaired and currently stopped. Run it now in the background?",
31579
+ initialValue: true
31580
+ });
31581
+ return !(isCancel(selected) || !selected);
31582
+ }
31533
31583
  async function autoStartDaemonAfterReinstall(input) {
31534
31584
  if (await runDaemonAfterReinstallStartWithRetry({
31535
31585
  presenter: input.presenter,
31536
31586
  resolved: input.resolved,
31587
+ startRetryDelayMs: input.resolved.startRetryDelayMs,
31537
31588
  view: input.runtime.resolvedView
31538
31589
  }) !== "started") return {
31539
31590
  ok: false,
@@ -31578,7 +31629,7 @@ async function runDaemonAfterReinstallStartWithRetry(input) {
31578
31629
  })).ok ? "started" : "failed_with_card";
31579
31630
  } catch (error) {
31580
31631
  if (attempt < REINSTALL_START_RETRY_ATTEMPTS) {
31581
- await sleep(REINSTALL_START_RETRY_DELAY_MS);
31632
+ await sleep(input.startRetryDelayMs);
31582
31633
  continue;
31583
31634
  }
31584
31635
  const startupDiagnostic = await readDaemonStartFailureLogDiagnostic({ cursor: startFailureLogCursor });
@@ -31673,6 +31724,7 @@ function resolveDaemonReinstallOptions(options) {
31673
31724
  timeoutPolicy: options.timeoutPolicy ?? "abort",
31674
31725
  skipConfirm: options.skipConfirm ?? false,
31675
31726
  verifyWaitMs: options.verifyWaitMs ?? REINSTALL_VERIFY_WAIT_MS,
31727
+ startRetryDelayMs: options.startRetryDelayMs ?? REINSTALL_START_RETRY_DELAY_MS,
31676
31728
  startAfterInstallMode: options.startAfterInstallMode ?? "default",
31677
31729
  emitStatusAfterSuccess: options.emitStatusAfterSuccess ?? true
31678
31730
  };
@@ -32520,22 +32572,6 @@ function isPermissionOrAuthorizationError(message) {
32520
32572
  const normalized = message.toLowerCase();
32521
32573
  return normalized.includes("permission") || normalized.includes("operation not permitted") || normalized.includes("access is denied") || normalized.includes("requires admin") || normalized.includes("elevation") || normalized.includes("access denied") || normalized.includes("not authorized");
32522
32574
  }
32523
- function shouldAttemptLaunchdAutoRepair(input) {
32524
- if (input.controller !== "launchd") return false;
32525
- return isLaunchdBootstrapIosError(sanitizeSystemServiceErrorMessage(toErrorMessage$6(input.error)));
32526
- }
32527
- async function runLaunchdAutoRepairRetry(input) {
32528
- await input.systemManager.uninstall().catch(() => void 0);
32529
- await input.systemManager.install(input.serviceCommandSpec);
32530
- await input.systemManager.start();
32531
- }
32532
- function buildLaunchdAutoRepairFailureError(input) {
32533
- return new Error([
32534
- "launchd auto-repair retry failed.",
32535
- `initial error: ${toErrorMessage$6(input.initialError)}`,
32536
- `retry error: ${toErrorMessage$6(input.retryError)}`
32537
- ].join(" "));
32538
- }
32539
32575
  async function waitForSystemServiceStartup(input) {
32540
32576
  const deadlineMs = Date.now() + input.waitMs;
32541
32577
  while (Date.now() < deadlineMs) {
@@ -33136,7 +33172,7 @@ function buildDaemonStopWarningText(input) {
33136
33172
  if (input.reason === "process_timeout") return formatInlineAtsCliCommands(`Service process (pid=${String(input.pid)}) did not exit after ${String(STOP_WAIT_MS)}ms. Run \`ats service stop --force\` to kill.`);
33137
33173
  return formatInlineAtsCliCommands(`ATS could not stop the local service cleanly.${input.errorMessage ? ` ${input.errorMessage}` : ""} Run \`ats service stop --force\` and retry.`);
33138
33174
  }
33139
- async function runDaemonRun(input) {
33175
+ async function runDaemonRun(input, options = {}) {
33140
33176
  const runtime = await resolveRuntimeContext({ view: input.view });
33141
33177
  const presenter = createPresenter(runtime);
33142
33178
  emitDaemonOverviewIfAgent({
@@ -33218,6 +33254,8 @@ async function runDaemonRun(input) {
33218
33254
  }
33219
33255
  if (isDetachedDaemonServiceRun()) return await runSystemDaemonCore({
33220
33256
  input,
33257
+ systemServiceStartupPollMs: options.systemServiceStartupPollMs,
33258
+ systemServiceStartupWaitMs: options.systemServiceStartupWaitMs,
33221
33259
  runtime,
33222
33260
  presenter,
33223
33261
  mode,
@@ -33226,6 +33264,8 @@ async function runDaemonRun(input) {
33226
33264
  return await withDaemonServiceRunLock(async () => {
33227
33265
  return await runSystemDaemonCore({
33228
33266
  input,
33267
+ systemServiceStartupPollMs: options.systemServiceStartupPollMs,
33268
+ systemServiceStartupWaitMs: options.systemServiceStartupWaitMs,
33229
33269
  runtime,
33230
33270
  presenter,
33231
33271
  mode,
@@ -33244,7 +33284,7 @@ async function runDaemonBackgroundStartForDecision(input) {
33244
33284
  })).ok ? "started" : "failed_with_card";
33245
33285
  }
33246
33286
  async function runSystemDaemonCore(context) {
33247
- const { input, presenter, runtime, mode, daemonVersion } = context;
33287
+ const { input, presenter, runtime, mode, daemonVersion, systemServiceStartupPollMs, systemServiceStartupWaitMs } = context;
33248
33288
  await cleanupDaemonServiceRuntimeState();
33249
33289
  const isSystemServiceBootstrap = isManagedSystemServiceBootstrapRun();
33250
33290
  const runConfig = await resolveContractFirstDaemonRunConfig({
@@ -33369,6 +33409,8 @@ async function runSystemDaemonCore(context) {
33369
33409
  });
33370
33410
  return await runDaemonBackgroundStart({
33371
33411
  daemonVersion,
33412
+ systemServiceStartupPollMs,
33413
+ systemServiceStartupWaitMs,
33372
33414
  runtime,
33373
33415
  presenter,
33374
33416
  mode,
@@ -33421,6 +33463,8 @@ async function runDaemonBackgroundStart(input) {
33421
33463
  });
33422
33464
  const runResult = await runSystemServiceManager({
33423
33465
  daemonVersion: input.daemonVersion,
33466
+ startupPollMs: input.systemServiceStartupPollMs,
33467
+ startupWaitMs: input.systemServiceStartupWaitMs,
33424
33468
  runtime: input.runtime,
33425
33469
  presenter: input.presenter,
33426
33470
  mode: input.mode,
@@ -33665,27 +33709,18 @@ async function runSystemServiceManager(input) {
33665
33709
  startSpinner?.start("Starting ATS Service...");
33666
33710
  try {
33667
33711
  await input.systemManager.install(serviceCommandSpec);
33668
- await input.systemManager.start();
33669
- } catch (error) {
33670
- if (shouldAttemptLaunchdAutoRepair({
33671
- controller: input.systemManager.controller,
33672
- error
33673
- })) {
33674
- autoRepairAttempted = true;
33675
- startSpinner?.message("ATS is repairing a local service issue...");
33676
- try {
33677
- await runLaunchdAutoRepairRetry({
33678
- systemManager: input.systemManager,
33679
- serviceCommandSpec
33680
- });
33712
+ autoRepairAttempted = (await startDaemonSystemServiceWithAutoRepair({
33713
+ serviceCommandSpec,
33714
+ systemManager: input.systemManager,
33715
+ onAutoRepairAttempt: () => {
33716
+ startSpinner?.message("ATS is repairing a local service issue...");
33717
+ },
33718
+ onAutoRepairRecovered: () => {
33681
33719
  startSpinner?.message("Starting ATS Service...");
33682
- } catch (retryError) {
33683
- startupError = buildLaunchdAutoRepairFailureError({
33684
- initialError: error,
33685
- retryError
33686
- });
33687
33720
  }
33688
- } else startupError = error;
33721
+ })).autoRepairAttempted;
33722
+ } catch (error) {
33723
+ startupError = error;
33689
33724
  }
33690
33725
  if (startupError) {
33691
33726
  startSpinner?.clear();
@@ -33706,8 +33741,8 @@ async function runSystemServiceManager(input) {
33706
33741
  const startupStatus = await waitForSystemServiceStartup({
33707
33742
  expectedVersion: input.daemonVersion,
33708
33743
  manager: input.systemManager,
33709
- waitMs: resolveSystemServiceStartupWaitMs(input.systemManager.controller),
33710
- pollMs: SERVICE_STARTUP_POLL_MS
33744
+ waitMs: input.startupWaitMs ?? resolveSystemServiceStartupWaitMs(input.systemManager.controller),
33745
+ pollMs: input.startupPollMs ?? SERVICE_STARTUP_POLL_MS
33711
33746
  });
33712
33747
  await cleanupInactiveDaemonServiceBundles();
33713
33748
  await clearDaemonStartFailureStateSafely();
@@ -45318,10 +45353,13 @@ function makeHello(profile) {
45318
45353
  profile
45319
45354
  };
45320
45355
  }
45321
- function makeTextSignal(text) {
45356
+ function makeTextSignal(text, options) {
45322
45357
  return {
45323
45358
  type: "signal.text",
45324
- data: { text }
45359
+ data: {
45360
+ text,
45361
+ ...options?.meta ? { meta: options.meta } : {}
45362
+ }
45325
45363
  };
45326
45364
  }
45327
45365
  function sanitizeText(value) {
@@ -45450,6 +45488,94 @@ function appendOptionalBooleanField(payload, key, value) {
45450
45488
  if (typeof value === "boolean") payload[key] = value;
45451
45489
  }
45452
45490
 
45491
+ //#endregion
45492
+ //#region src/space/space-display-projection.ts
45493
+ function buildSpaceDisplayProjection(input) {
45494
+ const currentProfileId = normalizeSpaceDisplayText(input.currentProfileId);
45495
+ const currentProfileName = normalizeSpaceDisplayText(input.currentProfileName);
45496
+ const creatorProfileName = normalizeSpaceDisplayText(input.creatorProfileName);
45497
+ const creatorProfileId = normalizeSpaceDisplayText(input.creatorProfileId);
45498
+ const availableViaProfileName = normalizeSpaceDisplayText(input.availableViaProfileName);
45499
+ const availableViaProfileId = normalizeSpaceDisplayText(input.availableViaProfileId);
45500
+ return {
45501
+ spaceId: normalizeSpaceDisplayText(input.spaceId),
45502
+ spaceName: normalizeSpaceDisplayText(input.spaceName),
45503
+ creatorProfileName,
45504
+ creatorProfileId,
45505
+ creatorDisplayName: resolveSpaceProfileDisplayName({
45506
+ currentProfileId,
45507
+ currentProfileName,
45508
+ profileId: creatorProfileId,
45509
+ profileName: creatorProfileName
45510
+ }),
45511
+ availableViaProfileName,
45512
+ availableViaProfileId,
45513
+ availableViaDisplayName: resolveSpaceProfileDisplayName({
45514
+ currentProfileId,
45515
+ currentProfileName,
45516
+ profileId: availableViaProfileId,
45517
+ profileName: availableViaProfileName
45518
+ }),
45519
+ spaceCreatedAt: normalizeSpaceDisplayText(input.spaceCreatedAt),
45520
+ lastJoinedAt: normalizeSpaceDisplayText(input.lastJoinedAt),
45521
+ passwordProtected: typeof input.passwordProtected === "boolean" ? input.passwordProtected : null
45522
+ };
45523
+ }
45524
+ function buildSpaceMetadataFields(input) {
45525
+ const fields = [
45526
+ {
45527
+ id: "spaceId",
45528
+ label: "Space ID",
45529
+ value: formatSpaceDisplayValue(input.projection.spaceId)
45530
+ },
45531
+ {
45532
+ id: "spaceCreator",
45533
+ label: "Space Creator",
45534
+ value: formatSpaceDisplayValue(input.projection.creatorDisplayName, "unknown-profile")
45535
+ },
45536
+ {
45537
+ id: "spaceCreatorProfileId",
45538
+ label: "Space Creator Profile ID",
45539
+ value: formatSpaceDisplayValue(input.projection.creatorProfileId, "unknown-profile")
45540
+ }
45541
+ ];
45542
+ if (input.includeAvailableVia === true) fields.push({
45543
+ id: "availableVia",
45544
+ label: "Available via",
45545
+ value: formatSpaceDisplayValue(input.projection.availableViaDisplayName)
45546
+ }, {
45547
+ id: "availableViaProfileId",
45548
+ label: "Available via Profile ID",
45549
+ value: formatSpaceDisplayValue(input.projection.availableViaProfileId)
45550
+ });
45551
+ if (input.includeCreatedAt === true) fields.push({
45552
+ id: "spaceCreatedAt",
45553
+ label: "Space Created",
45554
+ value: formatSpaceDisplayValue(input.projection.spaceCreatedAt)
45555
+ });
45556
+ if (input.includeLastJoinedAt === true) fields.push({
45557
+ id: "lastJoinedAt",
45558
+ label: "Last joined",
45559
+ value: formatSpaceDisplayValue(input.projection.lastJoinedAt)
45560
+ });
45561
+ return fields;
45562
+ }
45563
+ function formatSpaceDisplayValue(value, fallback = "unknown") {
45564
+ return value ?? fallback;
45565
+ }
45566
+ function resolveSpaceDisplayName(value, fallback) {
45567
+ return value ?? fallback;
45568
+ }
45569
+ function normalizeSpaceDisplayText(value) {
45570
+ const normalized = sanitizeTerminalDisplayText(value, "single-line").trim();
45571
+ return normalized.length > 0 ? normalized : null;
45572
+ }
45573
+ function resolveSpaceProfileDisplayName(input) {
45574
+ if (input.profileName) return input.profileName;
45575
+ if (input.profileId && input.currentProfileId && input.profileId === input.currentProfileId) return input.currentProfileName ?? input.profileId;
45576
+ return input.profileId;
45577
+ }
45578
+
45453
45579
  //#endregion
45454
45580
  //#region src/ui/controller-display.ts
45455
45581
  function resolveControllerDisplayName(controllerRef) {
@@ -45964,6 +46090,17 @@ function findMatchingAgentSnapshot(input) {
45964
46090
  //#endregion
45965
46091
  //#region src/space/mention-token.ts
45966
46092
  const MENTION_TOKEN_VALUE_PATTERN$1 = /^[a-z0-9][a-z0-9._-]{0,127}$/;
46093
+ const MENTION_TOKEN_TEXT_PATTERN = /(^|[^\w\\])@([A-Za-z0-9][A-Za-z0-9._-]{0,127})/g;
46094
+ const TRAILING_MENTION_PUNCTUATION_PATTERN$1 = /[.,!?;:,。!?;:]+$/u;
46095
+ function extractMentionTokensFromText(text) {
46096
+ const mentions = [];
46097
+ for (const match of text.matchAll(MENTION_TOKEN_TEXT_PATTERN)) {
46098
+ const mentionToken = stripTrailingMentionTokenPunctuation(String(match[2] ?? "").trim());
46099
+ if (!mentionToken) continue;
46100
+ mentions.push(mentionToken);
46101
+ }
46102
+ return mentions;
46103
+ }
45967
46104
  function resolvePreferredSpaceMemberMentionToken(input) {
45968
46105
  const tokenOwners = buildMentionTokenOwners(input.snapshot);
45969
46106
  const explicitToken = input.member.profileKind === "agent" ? normalizeMentionTokenValue(input.member.wakeToken) : null;
@@ -46023,6 +46160,11 @@ function normalizeMentionTokenValue(value) {
46023
46160
  if (!(normalized && MENTION_TOKEN_VALUE_PATTERN$1.test(normalized))) return null;
46024
46161
  return normalized;
46025
46162
  }
46163
+ function stripTrailingMentionTokenPunctuation(value) {
46164
+ const normalized = value.trim();
46165
+ if (!normalized) return "";
46166
+ return normalized.replace(TRAILING_MENTION_PUNCTUATION_PATTERN$1, "") || normalized;
46167
+ }
46026
46168
 
46027
46169
  //#endregion
46028
46170
  //#region src/ui/space-mention-highlight.ts
@@ -46119,8 +46261,6 @@ const AGENT_CONTEXT_HIDDEN_TOKENS = new Set([
46119
46261
  ]);
46120
46262
  const CLAUDE_CONTROLLER_REF_PATTERN = /claude/i;
46121
46263
  const DAEMON_WORKING_DIRECTORY_CACHE_TTL_MS = 5e3;
46122
- const TRANSIENT_HINT_START_PURPOSE$1 = "agent_replying";
46123
- const TRANSIENT_HINT_END_PURPOSE$1 = "agent_replying_end";
46124
46264
  const MENTION_DISPATCH_HINT_META_PURPOSE = "mention_dispatch_hint";
46125
46265
  const MENTION_FAILURE_HINT_PREFIX = "Mention skipped for \"";
46126
46266
  const MENTION_FAILURE_HINT_LEGACY_PREFIX = "Mention skipped. Try this:";
@@ -46189,38 +46329,38 @@ function buildSpaceInfoCardLines(input) {
46189
46329
  });
46190
46330
  }
46191
46331
  function buildSpaceInfoData(input) {
46192
- const spaceName = sanitizeTrimmedSingleLineText(input.spaceName);
46193
- const spaceCreatedAt = sanitizeTrimmedSingleLineText(input.spaceCreatedAt);
46194
- const spaceCreatorName = sanitizeTrimmedSingleLineText(input.spaceCreatorName);
46195
- const spaceCreatorId = sanitizeTrimmedSingleLineText(input.spaceCreatorId);
46196
- const spaceId = sanitizeTrimmedSingleLineText(input.spaceId);
46332
+ const projection = buildSpaceDisplayProjection({
46333
+ spaceId: input.spaceId,
46334
+ spaceName: input.spaceName,
46335
+ creatorProfileId: input.spaceCreatorId,
46336
+ creatorProfileName: input.spaceCreatorName,
46337
+ spaceCreatedAt: input.spaceCreatedAt,
46338
+ passwordProtected: input.passwordProtected
46339
+ });
46197
46340
  const gatewayUrl = sanitizeTrimmedSingleLineText(input.gatewayUrl);
46341
+ const metadataFacts = buildSpaceMetadataFields({
46342
+ projection,
46343
+ includeCreatedAt: true
46344
+ }).map((field) => {
46345
+ if (field.id !== "spaceCreator") return {
46346
+ label: field.label,
46347
+ value: field.value
46348
+ };
46349
+ return {
46350
+ label: field.label,
46351
+ value: projection.creatorDisplayName && projection.creatorProfileId ? colorizePersonLabel(projection.creatorDisplayName, {
46352
+ profileId: projection.creatorProfileId,
46353
+ profileName: projection.creatorDisplayName
46354
+ }, { spaceMembersSnapshot: input.spaceMembersSnapshot }) : formatSpaceDisplayValue(projection.creatorDisplayName, "(unknown)")
46355
+ };
46356
+ });
46198
46357
  return {
46199
46358
  facts: [
46200
46359
  {
46201
46360
  label: "Space Name",
46202
- value: spaceName || "(unnamed)"
46203
- },
46204
- {
46205
- label: "Space ID",
46206
- value: spaceId
46207
- },
46208
- {
46209
- label: "Space Created",
46210
- value: spaceCreatedAt || "(unknown)"
46211
- },
46212
- {
46213
- label: "Space Creator",
46214
- value: spaceCreatorName && spaceCreatorId ? colorizePersonLabel(spaceCreatorName, {
46215
- ownerUserId: spaceCreatorId,
46216
- profileId: spaceCreatorId,
46217
- profileName: spaceCreatorName
46218
- }, { spaceMembersSnapshot: input.spaceMembersSnapshot }) : spaceCreatorName || "(unknown)"
46219
- },
46220
- {
46221
- label: "Space Creator ID",
46222
- value: spaceCreatorId || "(unknown)"
46361
+ value: resolveSpaceDisplayName(projection.spaceName, "(unnamed)")
46223
46362
  },
46363
+ ...metadataFacts,
46224
46364
  {
46225
46365
  label: "Security",
46226
46366
  value: resolveSpaceSecurityLabel(input.passwordProtected)
@@ -46234,7 +46374,7 @@ function buildSpaceInfoData(input) {
46234
46374
  value: sanitizeTrimmedSingleLineText(input.modeLabel) || "(unknown)"
46235
46375
  }
46236
46376
  ],
46237
- joinCommand: formatAtsCliCommand(`ats space join ${spaceId}`),
46377
+ joinCommand: formatAtsCliCommand(`ats space join ${input.spaceId}`),
46238
46378
  publicWarningLines: isPublicSpace(input.passwordProtected) ? buildPublicSpaceWarningLines() : []
46239
46379
  };
46240
46380
  }
@@ -46365,15 +46505,15 @@ function buildSpaceMembersPanelLines(snapshot) {
46365
46505
  }
46366
46506
  function buildSpaceMembersPanelSource(snapshot) {
46367
46507
  return { sections: [buildSpaceMembersPanelSectionSource({
46368
- id: "humans",
46369
- members: snapshot.humans,
46370
- snapshot,
46371
- title: "👤 Humans"
46372
- }), buildSpaceMembersPanelSectionSource({
46373
46508
  id: "agents",
46374
46509
  members: snapshot.agents,
46375
46510
  snapshot,
46376
46511
  title: "🤖 Agents"
46512
+ }), buildSpaceMembersPanelSectionSource({
46513
+ id: "humans",
46514
+ members: snapshot.humans,
46515
+ snapshot,
46516
+ title: "👤 Humans"
46377
46517
  })].filter((section) => section.items.length > 0) };
46378
46518
  }
46379
46519
  function buildSpaceMembersLoadingPanelLines() {
@@ -46658,13 +46798,13 @@ function isTransientSignalTextHint(event) {
46658
46798
  if (rawMeta.transient !== true) return false;
46659
46799
  const purpose = String(rawMeta.purpose ?? "").trim();
46660
46800
  if (!purpose) return true;
46661
- return purpose === TRANSIENT_HINT_START_PURPOSE$1 || purpose === CONVERSATION_CONTINUITY_WARNING_PURPOSE || purpose === AGENT_REPLY_PREVIEW_PURPOSE;
46801
+ return purpose === AGENT_REPLYING_PURPOSE || purpose === CONVERSATION_CONTINUITY_WARNING_PURPOSE || purpose === AGENT_REPLY_PREVIEW_PURPOSE || purpose === DISPATCH_ACTIVITY_DISPATCHING_PURPOSE || purpose === DISPATCH_ACTIVITY_RETRYING_PURPOSE || purpose === DISPATCH_ACTIVITY_FAILED_PURPOSE;
46662
46802
  }
46663
46803
  function isTransientSignalTextHintClearEvent(event) {
46664
46804
  const rawMeta = resolveSignalTextMeta$1(event);
46665
46805
  if (!rawMeta || rawMeta.transient !== true) return false;
46666
46806
  const purpose = String(rawMeta.purpose ?? "").trim();
46667
- return purpose === TRANSIENT_HINT_END_PURPOSE$1 || purpose === AGENT_REPLY_PREVIEW_END_PURPOSE;
46807
+ return purpose === AGENT_REPLYING_END_PURPOSE || purpose === AGENT_REPLY_PREVIEW_END_PURPOSE;
46668
46808
  }
46669
46809
  function resolveSignalTextMeta$1(event) {
46670
46810
  if (!event.data || typeof event.data !== "object" || Array.isArray(event.data)) return null;
@@ -47426,6 +47566,9 @@ const SPACE_INFO_FULL_WIDTH_LABELS = new Set(["Space Name", "Space ID"]);
47426
47566
  const MEMBERS_SEARCH_LABEL = "Type to search";
47427
47567
  const MEMBERS_SEARCH_PLACEHOLDER = "Filter members by name, @wake, ID, or owner";
47428
47568
  const MEMBERS_NO_MATCHES_LINE = pc.dim("No matching members found.");
47569
+ const LOGS_SEARCH_LABEL = "Type to search";
47570
+ const LOGS_SEARCH_PLACEHOLDER = "Filter logs by actor, action, or text";
47571
+ const LOGS_NO_MATCHES_LINE = pc.dim("No matching logs found.");
47429
47572
  function buildHelpPanelBlocks() {
47430
47573
  return buildPanelBodyBlocks([buildPanelLinesSection(listSpaceSlashCommands().map((command) => {
47431
47574
  return `${pc.cyan(command.trigger)} ${pc.dim(command.description)}`;
@@ -47458,6 +47601,31 @@ function buildLogsPanelBlocks(input) {
47458
47601
  if (sections.length > 0) return sections;
47459
47602
  return buildPanelBodyBlocks([buildPanelLinesSection([pc.dim("No logs yet.")])]);
47460
47603
  }
47604
+ function buildLogsSearchableListViewState(input) {
47605
+ const normalizedQuery = normalizeSearchQuery(input.query);
47606
+ const filteredSections = filterLogsSections(input.sections, normalizedQuery);
47607
+ return {
47608
+ activeItemId: resolveLogsSearchableActiveItemId({
47609
+ preferredActiveItemId: input.activeItemId,
47610
+ query: input.query,
47611
+ sections: input.sections
47612
+ }),
47613
+ control: {
47614
+ label: LOGS_SEARCH_LABEL,
47615
+ placeholder: LOGS_SEARCH_PLACEHOLDER,
47616
+ query: input.query
47617
+ },
47618
+ emptyLines: resolveLogsEmptyLines(filteredSections.length, normalizedQuery),
47619
+ sections: filteredSections.map((section) => ({
47620
+ id: section.id,
47621
+ title: section.title,
47622
+ items: section.items.map((item) => ({
47623
+ id: item.id,
47624
+ lines: item.lines
47625
+ }))
47626
+ }))
47627
+ };
47628
+ }
47461
47629
  function buildMembersSearchableListViewState(input) {
47462
47630
  const normalizedQuery = normalizeSearchQuery(input.query);
47463
47631
  if (!input.snapshot) return {
@@ -47503,6 +47671,11 @@ function resolveMembersSearchableActiveItemId(input) {
47503
47671
  if (itemIds.length === 0) return null;
47504
47672
  return itemIds.includes(input.preferredActiveItemId ?? "") ? input.preferredActiveItemId : itemIds[0] ?? null;
47505
47673
  }
47674
+ function resolveLogsSearchableActiveItemId(input) {
47675
+ const itemIds = filterLogsSections(input.sections, normalizeSearchQuery(input.query)).flatMap((section) => section.items.map((item) => item.id));
47676
+ if (itemIds.length === 0) return null;
47677
+ return itemIds.includes(input.preferredActiveItemId ?? "") ? input.preferredActiveItemId : itemIds[0] ?? null;
47678
+ }
47506
47679
  function buildMembersPanelLines(input) {
47507
47680
  if (!input.snapshot) {
47508
47681
  if (input.refreshError) return ["Couldn't load the current Space members.", pc.dim("Try /members again in a few seconds.")];
@@ -47511,8 +47684,24 @@ function buildMembersPanelLines(input) {
47511
47684
  return buildSpaceMembersPanelLines(input.snapshot);
47512
47685
  }
47513
47686
  function buildLogsPanelSection(section) {
47514
- if (section.lines.length === 0) return null;
47515
- return buildPanelLinesSection([pc.bold(section.title), ...section.lines]);
47687
+ if (section.items.length === 0) return null;
47688
+ return buildPanelLinesSection([pc.bold(section.title), ...section.items.flatMap((item) => item.lines)]);
47689
+ }
47690
+ function filterLogsSections(sections, normalizedQuery) {
47691
+ const sourceSections = sections.map((section) => ({
47692
+ id: section.kind,
47693
+ title: section.title,
47694
+ items: section.items.map((item) => ({
47695
+ id: item.id,
47696
+ lines: item.lines,
47697
+ searchKey: buildLogsSearchKey(section.title, item.lines)
47698
+ }))
47699
+ }));
47700
+ if (!normalizedQuery) return sourceSections;
47701
+ return sourceSections.map((section) => ({
47702
+ ...section,
47703
+ items: section.items.filter((item) => item.searchKey.includes(normalizedQuery))
47704
+ })).filter((section) => section.items.length > 0);
47516
47705
  }
47517
47706
  function filterMembersPanelSections(sections, normalizedQuery) {
47518
47707
  if (!normalizedQuery) return [...sections];
@@ -47525,6 +47714,13 @@ function filterMembersPanelSections(sections, normalizedQuery) {
47525
47714
  function normalizeSearchQuery(query) {
47526
47715
  return query.trim().toLowerCase();
47527
47716
  }
47717
+ function resolveLogsEmptyLines(sectionCount, normalizedQuery) {
47718
+ if (sectionCount > 0) return [];
47719
+ return normalizedQuery ? [LOGS_NO_MATCHES_LINE] : [pc.dim("No logs yet.")];
47720
+ }
47721
+ function buildLogsSearchKey(title, lines) {
47722
+ return normalizeSearchQuery([title, ...lines].map((line) => stripVTControlCharacters(line)).join(" "));
47723
+ }
47528
47724
  function resolveConnectionModeLabel(connectionMode) {
47529
47725
  if (connectionMode === "watch") return "watch-only stream";
47530
47726
  if (connectionMode === "history") return "history viewer";
@@ -47606,10 +47802,10 @@ const SPACE_PANEL_DEFINITION_BY_KIND = new Map([
47606
47802
  contentAlign: "left",
47607
47803
  kind: "logs",
47608
47804
  title: "🗒️ Space Logs",
47609
- mode: "readonly",
47805
+ mode: "searchable_list",
47610
47806
  layout: "centered_modal",
47611
47807
  surfaceVariant: "dark",
47612
- instructionPreset: "readonly-close"
47808
+ instructionPreset: "searchable-list-close"
47613
47809
  }
47614
47810
  ].map((definition) => [definition.kind, definition]));
47615
47811
  const PANEL_INSTRUCTION_PRESETS = {
@@ -47887,6 +48083,79 @@ function assertUnreachable$1(value) {
47887
48083
  throw new Error(`Unknown panel body block: ${JSON.stringify(value)}`);
47888
48084
  }
47889
48085
 
48086
+ //#endregion
48087
+ //#region src/space/pending-outbound-status.ts
48088
+ const PREVIEW_MAX_VISIBLE_CHARS$1 = 240;
48089
+ const PREVIEW_MIN_VISIBLE_CHARS$1 = 24;
48090
+ const PREVIEW_ELLIPSIS$1 = "...";
48091
+ const STATUS_SYSTEM_PREFIX = "* 📣 system · ";
48092
+ const STATUS_PREVIEW_PREFIX = "sending: ";
48093
+ function formatPendingOutboundStatusText(input) {
48094
+ const normalizedText = normalizePendingOutboundText(input.pendingText);
48095
+ if (!normalizedText) return "sending...";
48096
+ const targetLabel = resolveSingleMentionTargetLabel(normalizedText);
48097
+ if (targetLabel) return `Sending to ${targetLabel}...`;
48098
+ return `${STATUS_PREVIEW_PREFIX}${truncatePreviewHead$1(normalizedText, resolvePendingOutboundPreviewWidth({ terminalColumns: input.terminalColumns }))}`;
48099
+ }
48100
+ function buildPendingOutboundDispatchRowDrafts(input) {
48101
+ const normalizedText = normalizePendingOutboundText(input.pendingText);
48102
+ if (!normalizedText) return [{
48103
+ statusText: "sending...",
48104
+ targetLabel: "",
48105
+ targetWakeToken: null
48106
+ }];
48107
+ const uniqueMentionTokens = resolveUniqueMentionTokens(normalizedText);
48108
+ if (uniqueMentionTokens.length === 0) return [{
48109
+ statusText: formatPendingOutboundStatusText(input),
48110
+ targetLabel: "",
48111
+ targetWakeToken: null
48112
+ }];
48113
+ return uniqueMentionTokens.map((mentionToken) => {
48114
+ const targetLabel = `@${mentionToken}`;
48115
+ return {
48116
+ statusText: `Sending to ${targetLabel}...`,
48117
+ targetLabel,
48118
+ targetWakeToken: mentionToken
48119
+ };
48120
+ });
48121
+ }
48122
+ function normalizePendingOutboundText(value) {
48123
+ return sanitizeTerminalDisplayText(value, "single-line").replace(/\s+/g, " ").trim();
48124
+ }
48125
+ function resolveSingleMentionTargetLabel(value) {
48126
+ const uniqueMentionTokens = resolveUniqueMentionTokens(value);
48127
+ const mentionToken = uniqueMentionTokens.length === 1 ? uniqueMentionTokens[0] : null;
48128
+ if (!mentionToken) return null;
48129
+ return mentionToken.startsWith("@") ? mentionToken : `@${mentionToken}`;
48130
+ }
48131
+ function resolvePendingOutboundPreviewWidth(input) {
48132
+ const prefixWidth = stringWidth(`${STATUS_SYSTEM_PREFIX}${STATUS_PREVIEW_PREFIX}`);
48133
+ if (input.terminalColumns === null) return PREVIEW_MAX_VISIBLE_CHARS$1;
48134
+ const availableWidth = input.terminalColumns - prefixWidth;
48135
+ return Math.max(PREVIEW_MIN_VISIBLE_CHARS$1, Math.min(PREVIEW_MAX_VISIBLE_CHARS$1, availableWidth));
48136
+ }
48137
+ function truncatePreviewHead$1(value, maxWidth) {
48138
+ if (stringWidth(value) <= maxWidth) return value;
48139
+ const truncatedWidth = Math.max(0, maxWidth - stringWidth(PREVIEW_ELLIPSIS$1));
48140
+ let head = "";
48141
+ for (const char of value) {
48142
+ if (stringWidth(head) + stringWidth(char) > truncatedWidth) break;
48143
+ head += char;
48144
+ }
48145
+ return `${head}${PREVIEW_ELLIPSIS$1}`;
48146
+ }
48147
+ function resolveUniqueMentionTokens(value) {
48148
+ const seenMentionTokens = /* @__PURE__ */ new Set();
48149
+ const uniqueMentionTokens = [];
48150
+ for (const mentionToken of extractMentionTokensFromText(value)) {
48151
+ const dedupeKey = mentionToken.toLowerCase();
48152
+ if (seenMentionTokens.has(dedupeKey)) continue;
48153
+ seenMentionTokens.add(dedupeKey);
48154
+ uniqueMentionTokens.push(mentionToken);
48155
+ }
48156
+ return uniqueMentionTokens;
48157
+ }
48158
+
47890
48159
  //#endregion
47891
48160
  //#region src/space/preflight.ts
47892
48161
  const HTTP_STATUS_PREFIX_RE = /^HTTP\s+(\d{3}):\s*(.*)$/i;
@@ -48218,7 +48487,7 @@ var SpaceSessionRuntime = class {
48218
48487
  #input;
48219
48488
  #listeners = /* @__PURE__ */ new Set();
48220
48489
  #bufferedLiveEvents = [];
48221
- #pendingSentTexts = [];
48490
+ #pendingSentMessages = [];
48222
48491
  #ws = null;
48223
48492
  #started = false;
48224
48493
  #stopRequested = false;
@@ -48290,22 +48559,29 @@ var SpaceSessionRuntime = class {
48290
48559
  if (!this.#ws) {
48291
48560
  this.#emit({
48292
48561
  type: "send.failed",
48562
+ clientMessageId: "unknown-client-message",
48293
48563
  text,
48294
48564
  error: "space connection is not started"
48295
48565
  });
48296
48566
  return false;
48297
48567
  }
48568
+ const clientMessageId = crypto.randomUUID();
48298
48569
  try {
48299
- this.#ws.send(JSON.stringify(makeTextSignal(text)));
48300
- this.#rememberPendingSentText(text);
48570
+ this.#ws.send(JSON.stringify(makeTextSignal(text, { meta: { clientMessageId } })));
48571
+ this.#rememberPendingSentMessage({
48572
+ clientMessageId,
48573
+ text
48574
+ });
48301
48575
  this.#emit({
48302
48576
  type: "send.queued",
48577
+ clientMessageId,
48303
48578
  text
48304
48579
  });
48305
48580
  return true;
48306
48581
  } catch (error) {
48307
48582
  this.#emit({
48308
48583
  type: "send.failed",
48584
+ clientMessageId,
48309
48585
  text,
48310
48586
  error: this.#input.formatError(error)
48311
48587
  });
@@ -48364,20 +48640,34 @@ var SpaceSessionRuntime = class {
48364
48640
  source
48365
48641
  });
48366
48642
  }
48367
- #rememberPendingSentText(text) {
48643
+ #rememberPendingSentMessage(message) {
48368
48644
  const pendingLimit = this.#input.pendingSendLimit ?? DEFAULT_PENDING_SEND_LIMIT;
48369
- if (this.#pendingSentTexts.length >= pendingLimit) this.#pendingSentTexts.shift();
48370
- this.#pendingSentTexts.push(text);
48645
+ if (this.#pendingSentMessages.length >= pendingLimit) this.#pendingSentMessages.shift();
48646
+ this.#pendingSentMessages.push(message);
48371
48647
  }
48372
48648
  #maybeEmitSendConfirmed(event) {
48373
48649
  if (event.type !== "signal.text") return;
48374
48650
  const profileId = String(event.profile?.profileId ?? "").trim();
48375
48651
  if (!profileId || profileId !== this.#input.selfProfileId) return;
48376
48652
  const text = typeof event.data?.text === "string" ? event.data.text : "";
48377
- if (this.#pendingSentTexts[0] !== text) return;
48378
- this.#pendingSentTexts.shift();
48653
+ const clientMessageId = resolveClientMessageId(event);
48654
+ if (clientMessageId) {
48655
+ const matchingIndex = this.#pendingSentMessages.findIndex((message) => message.clientMessageId === clientMessageId);
48656
+ if (matchingIndex < 0) return;
48657
+ this.#pendingSentMessages.splice(matchingIndex, 1);
48658
+ this.#emit({
48659
+ type: "send.confirmed",
48660
+ clientMessageId,
48661
+ text,
48662
+ event
48663
+ });
48664
+ return;
48665
+ }
48666
+ if (this.#pendingSentMessages[0]?.text !== text) return;
48667
+ const pendingMessage = this.#pendingSentMessages.shift() ?? null;
48379
48668
  this.#emit({
48380
48669
  type: "send.confirmed",
48670
+ clientMessageId: pendingMessage?.clientMessageId ?? null,
48381
48671
  text,
48382
48672
  event
48383
48673
  });
@@ -48406,6 +48696,12 @@ function safeJsonParse$2(value) {
48406
48696
  return null;
48407
48697
  }
48408
48698
  }
48699
+ function resolveClientMessageId(event) {
48700
+ const meta = event.data && typeof event.data === "object" && !Array.isArray(event.data) ? event.data.meta : null;
48701
+ if (!(meta && typeof meta === "object") || Array.isArray(meta)) return null;
48702
+ const clientMessageId = String(meta.clientMessageId ?? "").trim();
48703
+ return clientMessageId.length > 0 ? clientMessageId : null;
48704
+ }
48409
48705
 
48410
48706
  //#endregion
48411
48707
  //#region src/space/session-profile.ts
@@ -48777,11 +49073,15 @@ const TRANSCRIPT_BUBBLE_VERTICAL_PADDING = 1;
48777
49073
  const TRANSCRIPT_BUBBLE_META_GAP_LINES = 1;
48778
49074
  const TRANSCRIPT_BUBBLE_BODY_PREFIX = "› ";
48779
49075
  const TRANSCRIPT_BUBBLE_BODY_CONTINUATION_PREFIX = " ";
49076
+ const TRANSCRIPT_BUBBLE_REPLY_CONNECTED_BODY_PREFIX = "╰─› ";
49077
+ const TRANSCRIPT_BUBBLE_REPLY_CONNECTED_BODY_CONTINUATION_PREFIX = " ";
49078
+ const TRANSCRIPT_REPLY_PREVIEW_MAX_VISIBLE_WIDTH = 24;
48780
49079
  const TRANSCRIPT_HUMAN_BUBBLE_BACKGROUND = buildAnsiBackgroundColor(ATS_COMPOSER_SURFACE_BG_RGB);
48781
49080
  const TRANSCRIPT_NEUTRAL_BUBBLE_BACKGROUND = "\x1B[48;2;33;33;33m";
48782
49081
  const ANSI_BACKGROUND_RESET = "\x1B[49m";
48783
49082
  const ANSI_ESCAPE_PATTERN = "(?:\\u001B\\[[0-9;]*m)*";
48784
49083
  const TRANSCRIPT_GROUP_KIND_PATTERN = /^profile:(human|agent|unknown):/u;
49084
+ const PROFILE_GROUP_KEY_PATTERN = /^profile:(human|agent|unknown):(.+)$/u;
48785
49085
  const PRESENCE_TRACE_JOINED_LABEL = "joined";
48786
49086
  const PRESENCE_TRACE_LEFT_LABEL = "left";
48787
49087
  const PRESENCE_TRACE_JOIN_LABEL = "join";
@@ -48945,60 +49245,120 @@ function canCoalesceAdjacentHumanPlainTextBlocks(previousBlock, nextBlock) {
48945
49245
  return previousBlock.groupKey === nextBlock.groupKey && previousBlock.speakerProfileId === nextBlock.speakerProfileId && previousBlock.speakerKind === nextBlock.speakerKind && previousBlock.highlightKind === nextBlock.highlightKind;
48946
49246
  }
48947
49247
  function buildHumanLogsSections(input) {
48948
- const presenceLines = [...input.firstJoinBlocks.flatMap((block) => buildPresenceFirstJoinRows(block)), ...input.allBlocks.flatMap((block) => {
49248
+ const presenceItems = [...input.firstJoinBlocks.map((block, index) => ({
49249
+ id: `presence:first-join:${String(index)}`,
49250
+ lines: buildPresenceFirstJoinRows(block)
49251
+ })), ...input.allBlocks.flatMap((block, index) => {
48949
49252
  if (block.kind !== "presence_trace_group") return [];
48950
- return [buildPresenceTraceRowText(block)];
49253
+ return [{
49254
+ id: `presence:trace:${String(index)}`,
49255
+ lines: [buildPresenceTraceRowText(block)]
49256
+ }];
48951
49257
  })];
48952
- const membershipLines = input.allBlocks.flatMap((block) => {
49258
+ const membershipItems = input.allBlocks.flatMap((block, index) => {
48953
49259
  if (block.kind !== "membership_trace_group") return [];
48954
- return buildMembershipTraceRows(block);
49260
+ return [{
49261
+ id: `membership:${String(index)}`,
49262
+ lines: buildMembershipTraceRows(block)
49263
+ }];
48955
49264
  });
48956
- const systemLines = input.allBlocks.flatMap((block) => {
49265
+ const systemItems = input.allBlocks.flatMap((block, index) => {
48957
49266
  if (block.kind !== "system_group") return [];
48958
- return buildSystemClusterRowsFromSystemLines(block.lines);
49267
+ return [{
49268
+ id: `system:${String(index)}`,
49269
+ lines: buildSystemClusterRowsFromSystemLines(block.lines)
49270
+ }];
48959
49271
  });
48960
49272
  return [
48961
- {
48962
- kind: "presence",
48963
- title: "Presence",
48964
- lines: presenceLines
48965
- },
48966
- {
48967
- kind: "membership",
48968
- title: "Membership",
48969
- lines: membershipLines
48970
- },
48971
- {
48972
- kind: "system",
48973
- title: "System",
48974
- lines: systemLines
48975
- }
49273
+ buildHumanLogsSection("presence", "Presence", presenceItems),
49274
+ buildHumanLogsSection("membership", "Membership", membershipItems),
49275
+ buildHumanLogsSection("system", "System", systemItems)
48976
49276
  ];
48977
49277
  }
49278
+ function buildHumanLogsSection(kind, title, items) {
49279
+ return {
49280
+ kind,
49281
+ title,
49282
+ items,
49283
+ lines: items.flatMap((item) => item.lines)
49284
+ };
49285
+ }
48978
49286
  function buildPresenceFirstJoinBlocks(items, membersSnapshot) {
48979
49287
  const blocks = [];
48980
49288
  const seenActorKeys = /* @__PURE__ */ new Set();
49289
+ const actorKeysWithPriorTranscriptActivity = /* @__PURE__ */ new Set();
48981
49290
  for (const item of items) {
48982
- if (!(isPresenceTranscriptItem(item) && item.presenceAction === "join")) continue;
48983
- const actorKey = resolvePresenceActorKey(item);
48984
- if (!(actorKey && !seenActorKeys.has(actorKey))) continue;
48985
- const actorIdentity = resolvePresenceActorIdentity(item, membersSnapshot);
48986
- blocks.push({
48987
- kind: "presence_first_join_group",
48988
- groupKey: item.groupKey,
48989
- actorKey,
48990
- actorProfileId: item.actorProfileId?.trim() || null,
48991
- actorKind: item.actorKind ?? "unknown",
48992
- actorAvatar: item.actorAvatar?.trim() || resolvePresenceActorAvatar(item),
48993
- actorLabel: item.actorLabel?.trim() || "unknown",
48994
- actorOwnerUserId: actorIdentity.ownerUserId,
48995
- actorOwnerName: actorIdentity.ownerName,
48996
- ts: typeof item.ts === "number" ? item.ts : 0
48997
- });
48998
- seenActorKeys.add(actorKey);
49291
+ const nextBlock = buildPresenceFirstJoinBlock({
49292
+ item,
49293
+ membersSnapshot,
49294
+ seenActorKeys,
49295
+ actorKeysWithPriorTranscriptActivity
49296
+ });
49297
+ if (nextBlock) blocks.push(nextBlock);
49298
+ registerTranscriptActorActivity(item, actorKeysWithPriorTranscriptActivity);
48999
49299
  }
49000
49300
  return blocks;
49001
49301
  }
49302
+ function buildPresenceFirstJoinBlock(input) {
49303
+ if (!(isPresenceTranscriptItem(input.item) && input.item.presenceAction === "join")) return null;
49304
+ const actorKey = resolvePresenceActorKey(input.item);
49305
+ if (!actorKey || input.seenActorKeys.has(actorKey)) return null;
49306
+ input.seenActorKeys.add(actorKey);
49307
+ if (!shouldRenderPresenceFirstJoinBlock({
49308
+ item: input.item,
49309
+ actorKey,
49310
+ membersSnapshot: input.membersSnapshot,
49311
+ actorKeysWithPriorTranscriptActivity: input.actorKeysWithPriorTranscriptActivity
49312
+ })) return null;
49313
+ const actorIdentity = resolvePresenceActorIdentity(input.item, input.membersSnapshot);
49314
+ return {
49315
+ kind: "presence_first_join_group",
49316
+ groupKey: input.item.groupKey,
49317
+ actorKey,
49318
+ actorProfileId: input.item.actorProfileId?.trim() || null,
49319
+ actorKind: input.item.actorKind ?? "unknown",
49320
+ actorAvatar: input.item.actorAvatar?.trim() || resolvePresenceActorAvatar(input.item),
49321
+ actorLabel: input.item.actorLabel?.trim() || "unknown",
49322
+ actorOwnerUserId: actorIdentity.ownerUserId,
49323
+ actorOwnerName: actorIdentity.ownerName,
49324
+ ts: typeof input.item.ts === "number" ? input.item.ts : 0
49325
+ };
49326
+ }
49327
+ function shouldRenderPresenceFirstJoinBlock(input) {
49328
+ if (input.actorKeysWithPriorTranscriptActivity.has(input.actorKey)) return false;
49329
+ const knownFirstEnteredAtMs = resolvePresenceActorFirstEnteredAtMs(input.item, input.membersSnapshot);
49330
+ if (knownFirstEnteredAtMs === null) return true;
49331
+ const joinTs = typeof input.item.ts === "number" ? input.item.ts : null;
49332
+ return joinTs !== null && joinTs === knownFirstEnteredAtMs;
49333
+ }
49334
+ function registerTranscriptActorActivity(item, actorKeys) {
49335
+ for (const actorKey of resolveTranscriptActorActivityKeys(item)) actorKeys.add(actorKey);
49336
+ }
49337
+ function resolveTranscriptActorActivityKeys(item) {
49338
+ if (isPresenceTranscriptItem(item)) {
49339
+ const actorKey = resolvePresenceActorKey(item);
49340
+ return actorKey ? [actorKey] : [];
49341
+ }
49342
+ if (isMembershipNoticeTranscriptItem(item)) {
49343
+ const notice = resolveMembershipNoticePayload(item);
49344
+ if (!notice) return [];
49345
+ const actorKey = resolveMembershipActorKey(notice);
49346
+ return actorKey ? [actorKey] : [];
49347
+ }
49348
+ const actorKey = resolveTranscriptContentActorKey(item);
49349
+ return actorKey ? [actorKey] : [];
49350
+ }
49351
+ function resolveTranscriptContentActorKey(item) {
49352
+ const itemProfileId = item.profile?.profileId?.trim();
49353
+ if (itemProfileId) return itemProfileId;
49354
+ const groupProfileId = resolveProfileIdFromGroupKey(item.groupKey);
49355
+ if (groupProfileId) return groupProfileId;
49356
+ const itemProfileName = item.profile?.profileName?.trim();
49357
+ if ((item.profile?.kind === "human" || item.profile?.kind === "agent" || item.profile?.kind === "unknown") && itemProfileName) return `${item.profile.kind}:${itemProfileName}`;
49358
+ const fallbackMatch = PROFILE_GROUP_KEY_PATTERN.exec(item.groupKey);
49359
+ if (!fallbackMatch) return "";
49360
+ return `${fallbackMatch[1]}:${fallbackMatch[2]}`;
49361
+ }
49002
49362
  function attachCurrentPresenceStatusToLastMessageCards(blocks, membersSnapshot, items) {
49003
49363
  const lastMessageLocationByActorKey = /* @__PURE__ */ new Map();
49004
49364
  const currentStatusByActorKey = buildCurrentPresenceStatusByActorKey({
@@ -49356,6 +49716,10 @@ function createTranscriptBubbleMessage(input) {
49356
49716
  speakerIdentity: input.speakerIdentity,
49357
49717
  spaceMembersSnapshot: input.spaceMembersSnapshot
49358
49718
  });
49719
+ const replyLine = resolveTranscriptBubbleReplyLine({
49720
+ replyRef: input.item.replyRef,
49721
+ membersSnapshot: input.spaceMembersSnapshot ?? null
49722
+ });
49359
49723
  return {
49360
49724
  primaryLine: rawLines[0] ?? "",
49361
49725
  headerBaseLeading,
@@ -49367,6 +49731,7 @@ function createTranscriptBubbleMessage(input) {
49367
49731
  }),
49368
49732
  headerStatusBadge: null,
49369
49733
  headerTrailing: header.trailing,
49734
+ ...replyLine ? { replyLine } : {},
49370
49735
  bodyLines,
49371
49736
  bodyDetailLines,
49372
49737
  metaLines,
@@ -49465,12 +49830,18 @@ function renderTranscriptBubbleMessage(message, block, contentWidth) {
49465
49830
  contentWidth
49466
49831
  });
49467
49832
  for (const headerLine of headerLines) lines.push(renderBubbleLine(headerLine, block, contentWidth));
49468
- if (message.bodyLines.length > 0 && headerLines.length > 0) appendBubblePaddingLines(lines, TRANSCRIPT_BUBBLE_META_GAP_LINES, block, contentWidth);
49833
+ if (message.replyLine) {
49834
+ if (headerLines.length > 0) appendBubblePaddingLines(lines, TRANSCRIPT_BUBBLE_META_GAP_LINES, block, contentWidth);
49835
+ for (const wrappedLine of wrapBubbleLine(pc.dim(message.replyLine), contentWidth)) lines.push(renderBubbleLine(wrappedLine, block, contentWidth));
49836
+ }
49837
+ if (message.bodyLines.length > 0 && headerLines.length > 0 && !message.replyLine) appendBubblePaddingLines(lines, TRANSCRIPT_BUBBLE_META_GAP_LINES, block, contentWidth);
49838
+ const bodyPrefixes = resolveTranscriptBubbleBodyPrefixes(Boolean(message.replyLine));
49469
49839
  for (const [index, bodyLine] of message.bodyLines.entries()) {
49470
49840
  const wrappedBodyLines = wrapBubbleBodyLine({
49471
49841
  line: bodyLine,
49472
49842
  contentWidth,
49473
- withLeadPrefix: index === 0
49843
+ leadPrefix: index === 0 ? bodyPrefixes.firstLinePrefix : bodyPrefixes.otherLinePrefix,
49844
+ continuationPrefix: bodyPrefixes.otherLinePrefix
49474
49845
  });
49475
49846
  for (const wrappedLine of wrappedBodyLines) lines.push(renderBubbleLine(wrappedLine, block, contentWidth));
49476
49847
  }
@@ -49513,6 +49884,49 @@ function buildTranscriptBubbleHeaderAuxLeading(input) {
49513
49884
  }, { spaceMembersSnapshot: input.spaceMembersSnapshot }));
49514
49885
  return headerSegments.length > 0 ? headerSegments.join("") : null;
49515
49886
  }
49887
+ function resolveTranscriptBubbleReplyLine(input) {
49888
+ const replyRef = input.replyRef;
49889
+ if (!replyRef) return null;
49890
+ const profileLabel = resolveTranscriptReplyProfileLabel({
49891
+ replyRef,
49892
+ membersSnapshot: input.membersSnapshot
49893
+ });
49894
+ const previewText = resolveTranscriptReplyPreviewText(replyRef.previewText);
49895
+ return previewText ? `reply to ${profileLabel} · ${previewText}` : `reply to ${profileLabel}`;
49896
+ }
49897
+ function resolveTranscriptReplyProfileLabel(input) {
49898
+ const profileId = sanitizeTranscriptReplyDisplayText(input.replyRef.profileId);
49899
+ if (profileId && input.membersSnapshot) {
49900
+ const humanMatch = input.membersSnapshot.humans.find((member) => member.profileId === profileId);
49901
+ const agentMatch = input.membersSnapshot.agents.find((member) => member.profileId === profileId);
49902
+ const snapshotName = humanMatch?.profileName?.trim() || agentMatch?.profileName?.trim() || "";
49903
+ if (snapshotName) return snapshotName;
49904
+ }
49905
+ return sanitizeTranscriptReplyDisplayText(input.replyRef.profileName) || profileId || "unknown";
49906
+ }
49907
+ function resolveTranscriptReplyPreviewText(value) {
49908
+ const sanitizedPreview = sanitizeTranscriptReplyDisplayText(value);
49909
+ if (!sanitizedPreview) return "";
49910
+ return truncateTranscriptReplyPreview(sanitizedPreview, TRANSCRIPT_REPLY_PREVIEW_MAX_VISIBLE_WIDTH);
49911
+ }
49912
+ function sanitizeTranscriptReplyDisplayText(value) {
49913
+ return sanitizeTerminalDisplayText(value, "single-line").replace(/\s+/gu, " ").trim();
49914
+ }
49915
+ function truncateTranscriptReplyPreview(value, maxVisibleWidth) {
49916
+ if (measureVisibleWidth$1(value) <= maxVisibleWidth) return value;
49917
+ if (maxVisibleWidth <= 1) return "…";
49918
+ const ellipsis = "…";
49919
+ const targetWidth = maxVisibleWidth - measureVisibleWidth$1(ellipsis);
49920
+ let result = "";
49921
+ let currentWidth = 0;
49922
+ for (const char of value) {
49923
+ const nextWidth = currentWidth + stringWidth(char);
49924
+ if (nextWidth > targetWidth) break;
49925
+ result += char;
49926
+ currentWidth = nextWidth;
49927
+ }
49928
+ return `${result.trimEnd()}${ellipsis}`;
49929
+ }
49516
49930
  function joinTranscriptBubbleHeaderLeading(input) {
49517
49931
  const segments = [input.baseLeading];
49518
49932
  if (input.auxLeading) segments.push(input.auxLeading);
@@ -49616,7 +50030,7 @@ function buildPresenceFirstJoinRows(block) {
49616
50030
  }
49617
50031
  function buildPresenceFirstJoinRowText(block) {
49618
50032
  return [
49619
- formatPresenceTraceClock(block.ts),
50033
+ formatPresenceTraceDateTime(block.ts),
49620
50034
  "·",
49621
50035
  buildSystemActorLabel({
49622
50036
  actorAvatar: block.actorAvatar,
@@ -49709,10 +50123,20 @@ function buildSystemActorLabel(input) {
49709
50123
  return `${input.actorAvatar ? `${input.actorAvatar} ` : ""}${input.actorLabel}`;
49710
50124
  }
49711
50125
  function resolvePresenceTraceTimeLabel(block) {
49712
- const startLabel = formatPresenceTraceClock(block.startTs);
49713
- const endLabel = formatPresenceTraceClock(block.endTs);
49714
- if ((block.count ?? 1) <= 1 || startLabel === endLabel) return startLabel;
49715
- return `${startLabel}–${endLabel}`;
50126
+ const startDateLabel = formatPresenceTraceDate(block.startTs);
50127
+ const startClockLabel = formatPresenceTraceClock(block.startTs);
50128
+ const endDateLabel = formatPresenceTraceDate(block.endTs);
50129
+ const endClockLabel = formatPresenceTraceClock(block.endTs);
50130
+ if ((block.count ?? 1) <= 1 || startDateLabel === endDateLabel && startClockLabel === endClockLabel) return `${startDateLabel} ${startClockLabel}`;
50131
+ if (startDateLabel === endDateLabel) return `${startDateLabel} ${startClockLabel}–${endClockLabel}`;
50132
+ return `${startDateLabel} ${startClockLabel}–${endDateLabel} ${endClockLabel}`;
50133
+ }
50134
+ function formatPresenceTraceDateTime(ts) {
50135
+ return `${formatPresenceTraceDate(ts)} ${formatPresenceTraceClock(ts)}`;
50136
+ }
50137
+ function formatPresenceTraceDate(ts) {
50138
+ const date = new Date(ts);
50139
+ return `${`${date.getFullYear()}`}${`${date.getMonth() + 1}`.padStart(2, "0")}${`${date.getDate()}`.padStart(2, "0")}`;
49716
50140
  }
49717
50141
  function formatPresenceTraceClock(ts) {
49718
50142
  const date = new Date(ts);
@@ -49734,14 +50158,23 @@ function wrapBubbleLine(line, contentWidth) {
49734
50158
  }).split("\n");
49735
50159
  }
49736
50160
  function wrapBubbleBodyLine(input) {
49737
- const leadPrefix = input.withLeadPrefix ? renderAtsBrandAccent(TRANSCRIPT_BUBBLE_BODY_PREFIX) : TRANSCRIPT_BUBBLE_BODY_CONTINUATION_PREFIX;
49738
- const prefixWidth = input.withLeadPrefix ? stringWidth(TRANSCRIPT_BUBBLE_BODY_PREFIX) : stringWidth(TRANSCRIPT_BUBBLE_BODY_CONTINUATION_PREFIX);
50161
+ const leadPrefix = input.leadPrefix === TRANSCRIPT_BUBBLE_BODY_CONTINUATION_PREFIX || input.leadPrefix === TRANSCRIPT_BUBBLE_REPLY_CONNECTED_BODY_CONTINUATION_PREFIX ? input.leadPrefix : renderAtsBrandAccent(input.leadPrefix);
50162
+ const prefixWidth = stringWidth(input.leadPrefix);
49739
50163
  const prefixedContentWidth = Math.max(1, input.contentWidth - prefixWidth);
49740
50164
  return wrapAnsi(input.line, prefixedContentWidth, {
49741
50165
  hard: true,
49742
50166
  trim: false,
49743
50167
  wordWrap: true
49744
- }).split("\n").map((wrappedLine, index) => index === 0 ? `${leadPrefix}${wrappedLine}` : `${TRANSCRIPT_BUBBLE_BODY_CONTINUATION_PREFIX}${wrappedLine}`);
50168
+ }).split("\n").map((wrappedLine, index) => index === 0 ? `${leadPrefix}${wrappedLine}` : `${input.continuationPrefix}${wrappedLine}`);
50169
+ }
50170
+ function resolveTranscriptBubbleBodyPrefixes(hasReplyLine) {
50171
+ return hasReplyLine ? {
50172
+ firstLinePrefix: TRANSCRIPT_BUBBLE_REPLY_CONNECTED_BODY_PREFIX,
50173
+ otherLinePrefix: TRANSCRIPT_BUBBLE_REPLY_CONNECTED_BODY_CONTINUATION_PREFIX
50174
+ } : {
50175
+ firstLinePrefix: TRANSCRIPT_BUBBLE_BODY_PREFIX,
50176
+ otherLinePrefix: TRANSCRIPT_BUBBLE_BODY_CONTINUATION_PREFIX
50177
+ };
49745
50178
  }
49746
50179
  function renderBubbleLine(line, block, contentWidth) {
49747
50180
  const visibleWidth = measureVisibleWidth$1(line);
@@ -49894,25 +50327,26 @@ function resolvePresenceActorKey(item) {
49894
50327
  return "";
49895
50328
  }
49896
50329
  function resolvePresenceActorIdentity(item, membersSnapshot) {
49897
- const actorProfileId = item.actorProfileId?.trim();
49898
- if (!(actorProfileId && membersSnapshot)) return {};
49899
- if (item.actorKind === "agent") {
49900
- const agentSnapshot = membersSnapshot.agents.find((member) => member.profileId === actorProfileId) ?? null;
49901
- if (!agentSnapshot) return {};
49902
- return {
49903
- ownerUserId: agentSnapshot.ownerUserId,
49904
- ownerName: agentSnapshot.ownerName
49905
- };
49906
- }
49907
- if (item.actorKind === "human") {
49908
- const humanSnapshot = membersSnapshot.humans.find((member) => member.profileId === actorProfileId) ?? null;
49909
- if (!humanSnapshot) return {};
49910
- return {
49911
- ownerUserId: humanSnapshot.ownerUserId,
49912
- ownerName: humanSnapshot.ownerName
49913
- };
49914
- }
49915
- return {};
50330
+ const matchedSnapshot = resolvePresenceActorMemberSnapshot(item, membersSnapshot);
50331
+ if (!matchedSnapshot) return {};
50332
+ return {
50333
+ ownerUserId: matchedSnapshot.ownerUserId,
50334
+ ownerName: matchedSnapshot.ownerName
50335
+ };
50336
+ }
50337
+ function resolvePresenceActorFirstEnteredAtMs(item, membersSnapshot) {
50338
+ const firstEnteredAt = resolvePresenceActorMemberSnapshot(item, membersSnapshot)?.firstEnteredAt ?? null;
50339
+ if (!firstEnteredAt) return null;
50340
+ const parsed = Date.parse(firstEnteredAt);
50341
+ return Number.isFinite(parsed) ? parsed : null;
50342
+ }
50343
+ function resolvePresenceActorMemberSnapshot(item, membersSnapshot) {
50344
+ if (!membersSnapshot) return null;
50345
+ const actorProfileId = item.actorProfileId?.trim() || "";
50346
+ const actorLabel = item.actorLabel?.trim().toLowerCase() || "";
50347
+ if (item.actorKind === "agent") return membersSnapshot.agents.find((member) => member.profileId === actorProfileId || !actorProfileId && actorLabel.length > 0 && member.profileName.trim().toLowerCase() === actorLabel) ?? null;
50348
+ if (item.actorKind === "human") return membersSnapshot.humans.find((member) => member.profileId === actorProfileId || !actorProfileId && actorLabel.length > 0 && member.profileName.trim().toLowerCase() === actorLabel) ?? null;
50349
+ return null;
49916
50350
  }
49917
50351
  function resolveMembershipActorKey(notice) {
49918
50352
  if (notice.actorProfileId?.trim()) return notice.actorProfileId.trim();
@@ -49996,69 +50430,122 @@ function resolveSystemClusterContentWidth(width) {
49996
50430
 
49997
50431
  //#endregion
49998
50432
  //#region src/space/view/build-composer-activity-view-state.ts
50433
+ const MAX_COMPOSER_ACTIVITY_ROWS = 2;
49999
50434
  function buildComposerActivityViewState(source, spaceMembersSnapshot) {
50000
- const actors = buildReplyingActors(source.replyingDispatches);
50001
- const leadActor = selectLeadActor(actors);
50002
- const hasReplyingActors = actors.length > 0;
50003
- const pendingOutboundText = source.pendingOutboundText.trim();
50004
- if (!hasReplyingActors) return {
50005
- visible: pendingOutboundText.length > 0,
50006
- mode: pendingOutboundText.length > 0 ? "sending" : "idle",
50435
+ const rowCandidates = buildComposerActivityRowCandidates({
50436
+ nowMs: source.nowMs,
50437
+ rows: source.rows
50438
+ });
50439
+ const visibleRows = selectVisibleRows(rowCandidates);
50440
+ const leadRow = visibleRows.at(-1) ?? null;
50441
+ const actors = visibleRows.flatMap((row) => row.actors);
50442
+ const overflowCount = Math.max(0, rowCandidates.length - visibleRows.length);
50443
+ if (!leadRow) return {
50444
+ visible: false,
50445
+ mode: "idle",
50446
+ rows: [],
50447
+ overflowCount: 0,
50007
50448
  actors: [],
50008
50449
  leadActor: null,
50009
50450
  elapsedSeconds: null,
50010
50451
  previewText: "",
50011
50452
  hint: null,
50012
- pendingOutboundText,
50013
50453
  spaceMembersSnapshot: spaceMembersSnapshot ?? null
50014
50454
  };
50015
- const previewText = leadActor?.latestPreviewText.trim() ?? "";
50016
50455
  return {
50017
50456
  visible: true,
50018
- mode: previewText ? "streaming" : "replying",
50457
+ mode: leadRow.mode,
50458
+ rows: visibleRows,
50459
+ overflowCount,
50019
50460
  actors,
50020
- leadActor,
50021
- elapsedSeconds: leadActor ? Math.max(0, Math.floor((source.nowMs - leadActor.startedAtMs) / 1e3)) : null,
50022
- previewText,
50023
- hint: null,
50024
- pendingOutboundText,
50461
+ leadActor: leadRow.leadActor,
50462
+ elapsedSeconds: leadRow.elapsedSeconds,
50463
+ previewText: leadRow.previewText,
50464
+ hint: leadRow.hint,
50025
50465
  spaceMembersSnapshot: spaceMembersSnapshot ?? null
50026
50466
  };
50027
50467
  }
50028
- function buildReplyingActors(replyingDispatches) {
50029
- const actorByProfileId = /* @__PURE__ */ new Map();
50030
- for (const dispatch of replyingDispatches) {
50031
- const existing = actorByProfileId.get(dispatch.targetProfileId);
50032
- if (!existing) {
50033
- actorByProfileId.set(dispatch.targetProfileId, {
50034
- profileId: dispatch.targetProfileId,
50035
- label: dispatch.targetLabel,
50036
- startedAtMs: dispatch.startedAtMs,
50037
- updatedAtMs: dispatch.updatedAtMs,
50038
- latestPreviewText: dispatch.latestPreviewText,
50039
- latestPreviewUpdatedAtMs: dispatch.latestPreviewUpdatedAtMs
50040
- });
50041
- continue;
50042
- }
50043
- const nextPreviewIsNewer = (dispatch.latestPreviewUpdatedAtMs ?? Number.NEGATIVE_INFINITY) > (existing.latestPreviewUpdatedAtMs ?? Number.NEGATIVE_INFINITY);
50044
- actorByProfileId.set(dispatch.targetProfileId, {
50045
- profileId: existing.profileId,
50046
- label: existing.label || dispatch.targetLabel,
50047
- startedAtMs: Math.min(existing.startedAtMs, dispatch.startedAtMs),
50048
- updatedAtMs: Math.max(existing.updatedAtMs, dispatch.updatedAtMs),
50049
- latestPreviewText: nextPreviewIsNewer ? dispatch.latestPreviewText : existing.latestPreviewText,
50050
- latestPreviewUpdatedAtMs: nextPreviewIsNewer ? dispatch.latestPreviewUpdatedAtMs : existing.latestPreviewUpdatedAtMs
50051
- });
50468
+ function buildComposerActivityRowCandidates(input) {
50469
+ return input.rows.map((row) => toComposerActivityRowCandidate({
50470
+ nowMs: input.nowMs,
50471
+ row
50472
+ }));
50473
+ }
50474
+ function toComposerActivityRowCandidate(input) {
50475
+ const actor = toDispatchActivityActor(input.row);
50476
+ if (input.row.stage === "replying") {
50477
+ const previewText = input.row.latestPreviewText.trim();
50478
+ return {
50479
+ key: input.row.rowId,
50480
+ mode: previewText ? "streaming" : "replying",
50481
+ actors: actor ? [actor] : [],
50482
+ leadActor: actor,
50483
+ elapsedSeconds: Math.max(0, Math.floor((input.nowMs - input.row.createdAtMs) / 1e3)),
50484
+ previewText,
50485
+ hint: null,
50486
+ previewUpdatedAtMs: input.row.latestPreviewUpdatedAtMs ?? Number.NEGATIVE_INFINITY,
50487
+ startedAtMs: input.row.createdAtMs,
50488
+ updatedAtMs: input.row.updatedAtMs
50489
+ };
50052
50490
  }
50053
- return [...actorByProfileId.values()].sort((left, right) => {
50054
- const previewDelta = (right.latestPreviewUpdatedAtMs ?? Number.NEGATIVE_INFINITY) - (left.latestPreviewUpdatedAtMs ?? Number.NEGATIVE_INFINITY);
50055
- if (previewDelta !== 0) return previewDelta;
50056
- if (right.updatedAtMs !== left.updatedAtMs) return right.updatedAtMs - left.updatedAtMs;
50057
- return left.label.localeCompare(right.label);
50058
- });
50491
+ if (input.row.stage === "sending") return {
50492
+ key: input.row.rowId,
50493
+ mode: "sending",
50494
+ actors: [],
50495
+ leadActor: null,
50496
+ elapsedSeconds: Math.max(0, Math.floor((input.nowMs - input.row.createdAtMs) / 1e3)),
50497
+ previewText: "",
50498
+ hint: input.row.statusText || "sending...",
50499
+ previewUpdatedAtMs: Number.NEGATIVE_INFINITY,
50500
+ startedAtMs: input.row.createdAtMs,
50501
+ updatedAtMs: input.row.updatedAtMs
50502
+ };
50503
+ let mode = "warning";
50504
+ if (input.row.stage === "dispatching") mode = "dispatching";
50505
+ else if (input.row.stage === "retrying") mode = "retrying";
50506
+ return {
50507
+ key: input.row.rowId,
50508
+ mode,
50509
+ actors: actor ? [actor] : [],
50510
+ leadActor: actor,
50511
+ elapsedSeconds: Math.max(0, Math.floor((input.nowMs - input.row.createdAtMs) / 1e3)),
50512
+ previewText: "",
50513
+ hint: input.row.warningText || input.row.statusText || resolveDispatchActivityHintFallback(input.row),
50514
+ previewUpdatedAtMs: Number.NEGATIVE_INFINITY,
50515
+ startedAtMs: input.row.createdAtMs,
50516
+ updatedAtMs: input.row.updatedAtMs
50517
+ };
50518
+ }
50519
+ function selectVisibleRows(rowCandidates) {
50520
+ return [...rowCandidates].sort(compareComposerActivityRowsByRecencyDesc).slice(0, MAX_COMPOSER_ACTIVITY_ROWS).sort(compareComposerActivityRowsByRenderOrderAsc).map(({ previewUpdatedAtMs, startedAtMs, updatedAtMs, ...row }) => row);
50059
50521
  }
50060
- function selectLeadActor(actors) {
50061
- return actors[0] ?? null;
50522
+ function compareComposerActivityRowsByRecencyDesc(left, right) {
50523
+ if (right.updatedAtMs !== left.updatedAtMs) return right.updatedAtMs - left.updatedAtMs;
50524
+ if (right.previewUpdatedAtMs !== left.previewUpdatedAtMs) return right.previewUpdatedAtMs - left.previewUpdatedAtMs;
50525
+ if (right.startedAtMs !== left.startedAtMs) return right.startedAtMs - left.startedAtMs;
50526
+ return left.key.localeCompare(right.key);
50527
+ }
50528
+ function compareComposerActivityRowsByRenderOrderAsc(left, right) {
50529
+ if (left.updatedAtMs !== right.updatedAtMs) return left.updatedAtMs - right.updatedAtMs;
50530
+ if (left.previewUpdatedAtMs !== right.previewUpdatedAtMs) return left.previewUpdatedAtMs - right.previewUpdatedAtMs;
50531
+ if (left.startedAtMs !== right.startedAtMs) return left.startedAtMs - right.startedAtMs;
50532
+ return left.key.localeCompare(right.key);
50533
+ }
50534
+ function toDispatchActivityActor(row) {
50535
+ if (!row.targetProfileId) return null;
50536
+ return {
50537
+ profileId: row.targetProfileId,
50538
+ label: row.targetLabel,
50539
+ startedAtMs: row.createdAtMs,
50540
+ updatedAtMs: row.updatedAtMs,
50541
+ latestPreviewText: row.latestPreviewText,
50542
+ latestPreviewUpdatedAtMs: row.latestPreviewUpdatedAtMs
50543
+ };
50544
+ }
50545
+ function resolveDispatchActivityHintFallback(row) {
50546
+ if (row.stage === "dispatching") return `${row.targetLabel} is dispatching...`;
50547
+ if (row.stage === "retrying") return `${row.targetLabel} is retrying...`;
50548
+ return `${row.targetLabel} couldn't reply right now`;
50062
50549
  }
50063
50550
 
50064
50551
  //#endregion
@@ -50185,6 +50672,11 @@ function buildSpaceSessionViewState(input) {
50185
50672
  sessionProfile: context.profile
50186
50673
  });
50187
50674
  const logsBlocks = buildLogsPanelBlocks({ sections: humanTranscriptProjection.logsSections });
50675
+ const logsSearchableList = buildLogsSearchableListViewState({
50676
+ activeItemId: screenState.overlay.interaction.activeItemId,
50677
+ query: screenState.overlay.interaction.query,
50678
+ sections: humanTranscriptProjection.logsSections
50679
+ });
50188
50680
  const membersBlocks = buildMembersPanelBlocks({
50189
50681
  snapshot: screenState.members.snapshot,
50190
50682
  refreshError: screenState.members.refreshError
@@ -50204,7 +50696,10 @@ function buildSpaceSessionViewState(input) {
50204
50696
  space: spaceBlocks
50205
50697
  },
50206
50698
  headerMetaTextByKind: { members: buildMembersPanelUpdatedAtLabel(screenState.members.updatedAtMs) },
50207
- searchableListByKind: { members: membersSearchableList }
50699
+ searchableListByKind: {
50700
+ logs: logsSearchableList,
50701
+ members: membersSearchableList
50702
+ }
50208
50703
  });
50209
50704
  const transcriptBlocks = humanTranscriptProjection.transcriptBlocks;
50210
50705
  const spaceSummary = buildSpaceSummaryViewState({
@@ -50213,8 +50708,7 @@ function buildSpaceSessionViewState(input) {
50213
50708
  });
50214
50709
  const composerActivity = buildComposerActivityViewState(resources?.composerActivity ?? {
50215
50710
  nowMs: Date.now(),
50216
- pendingOutboundText: "",
50217
- replyingDispatches: []
50711
+ rows: []
50218
50712
  }, screenState.members.snapshot);
50219
50713
  const visibleComposerActivity = composerVisible ? composerActivity : {
50220
50714
  ...composerActivity,
@@ -50470,14 +50964,14 @@ var ComposerActivityStrip = class {
50470
50964
  #activity = {
50471
50965
  visible: false,
50472
50966
  mode: "idle",
50967
+ rows: [],
50968
+ overflowCount: 0,
50473
50969
  actors: [],
50474
50970
  leadActor: null,
50475
50971
  elapsedSeconds: null,
50476
50972
  previewText: "",
50477
- hint: null,
50478
- pendingOutboundText: ""
50973
+ hint: null
50479
50974
  };
50480
- #activityBaseElapsedSeconds = 0;
50481
50975
  #activityBaseSetAtMs = Date.now();
50482
50976
  #tick = 0;
50483
50977
  #timer = null;
@@ -50489,7 +50983,6 @@ var ComposerActivityStrip = class {
50489
50983
  const isWaiting = isWaitingComposerActivity(activity);
50490
50984
  if (!wasWaiting && isWaiting) this.#tick = 0;
50491
50985
  this.#activity = activity;
50492
- this.#activityBaseElapsedSeconds = activity.elapsedSeconds ?? 0;
50493
50986
  this.#activityBaseSetAtMs = Date.now();
50494
50987
  this.#syncTimer();
50495
50988
  this.#tui.requestRender();
@@ -50502,16 +50995,12 @@ var ComposerActivityStrip = class {
50502
50995
  invalidate() {}
50503
50996
  render(width) {
50504
50997
  if (!shouldRenderComposerActivity(this.#activity)) return [];
50505
- return ["", ...wrapAnsi(buildInlineActivityLine({
50998
+ return ["", ...buildActivityLines({
50506
50999
  activity: this.#activity,
50507
51000
  tick: this.#tick,
50508
- elapsedSeconds: this.#resolveElapsedSeconds(),
51001
+ elapsedDeltaSeconds: this.#resolveElapsedDeltaSeconds(),
50509
51002
  width
50510
- }), Math.max(1, width), {
50511
- hard: true,
50512
- trim: false,
50513
- wordWrap: true
50514
- }).split("\n")];
51003
+ })];
50515
51004
  }
50516
51005
  #syncTimer() {
50517
51006
  if (shouldAnimateComposerActivity(this.#activity)) {
@@ -50524,55 +51013,81 @@ var ComposerActivityStrip = class {
50524
51013
  }
50525
51014
  this.stop();
50526
51015
  }
50527
- #resolveElapsedSeconds() {
51016
+ #resolveElapsedDeltaSeconds() {
50528
51017
  if (!shouldRenderComposerActivity(this.#activity)) return 0;
50529
- const deltaSeconds = Math.max(0, Math.floor((Date.now() - this.#activityBaseSetAtMs) / 1e3));
50530
- return this.#activityBaseElapsedSeconds + deltaSeconds;
51018
+ return Math.max(0, Math.floor((Date.now() - this.#activityBaseSetAtMs) / 1e3));
50531
51019
  }
50532
51020
  };
50533
51021
  function shouldRenderComposerActivity(activity) {
50534
- return activity.visible && activity.mode !== "idle";
51022
+ return activity.visible && activity.mode !== "idle" && activity.rows.length > 0;
50535
51023
  }
50536
51024
  function shouldAnimateComposerActivity(activity) {
50537
- return shouldRenderComposerActivity(activity);
51025
+ return shouldRenderComposerActivity(activity) && activity.rows.some((row) => row.mode !== "warning");
50538
51026
  }
50539
51027
  function isWaitingComposerActivity(activity) {
50540
- return shouldRenderComposerActivity(activity) && activity.previewText.trim().length === 0;
51028
+ return shouldRenderComposerActivity(activity) && activity.rows.some((row) => row.mode !== "warning" && row.previewText.trim().length === 0);
50541
51029
  }
50542
- function buildStatusLine(input) {
50543
- const actors = input.activity.actors.map((actor) => {
50544
- const matchingAgent = input.activity.spaceMembersSnapshot?.agents.find((candidate) => candidate.profileId === actor.profileId) ?? null;
51030
+ function buildReplyingStatusLine(input) {
51031
+ const actors = input.row.actors.map((actor) => {
51032
+ const matchingAgent = input.spaceMembersSnapshot?.agents.find((candidate) => candidate.profileId === actor.profileId) ?? null;
50545
51033
  return colorizeAgentLabel(actor.label, {
50546
51034
  controllerRef: matchingAgent?.controllerRef,
50547
51035
  profileId: actor.profileId,
50548
51036
  profileName: actor.label
50549
- }, { spaceMembersSnapshot: input.activity.spaceMembersSnapshot });
51037
+ }, { spaceMembersSnapshot: input.spaceMembersSnapshot });
50550
51038
  }).join(pc.dim(", "));
50551
- const linkingVerb = input.activity.actors.length > 1 ? "are" : "is";
51039
+ const linkingVerb = input.row.actors.length > 1 ? "are" : "is";
50552
51040
  const modeLabel = resolveStatusModeLabel({
50553
51041
  elapsedSeconds: input.elapsedSeconds,
50554
- previewText: input.activity.previewText
51042
+ previewText: input.row.previewText
50555
51043
  });
50556
- const modeSuffix = input.activity.previewText.trim().length > 0 ? "" : resolveAnimatedStatusDots(input.tick);
51044
+ const modeSuffix = input.row.previewText.trim().length > 0 ? "" : resolveAnimatedStatusDots(input.tick);
50557
51045
  return `${actors} ${pc.dim(linkingVerb)} ${pc.dim(`${modeLabel}${modeSuffix}`)}`;
50558
51046
  }
50559
- function buildInlineActivityLine(input) {
51047
+ function buildActivityLines(input) {
51048
+ const lines = [];
51049
+ if (input.activity.overflowCount > 0) lines.push(pc.dim(`+${input.activity.overflowCount} more active`));
51050
+ for (const row of input.activity.rows) {
51051
+ const wrappedLines = wrapAnsi(buildActivityRowLine({
51052
+ row,
51053
+ spaceMembersSnapshot: input.activity.spaceMembersSnapshot,
51054
+ tick: input.tick,
51055
+ elapsedSeconds: resolveRowElapsedSeconds({
51056
+ row,
51057
+ elapsedDeltaSeconds: input.elapsedDeltaSeconds
51058
+ }),
51059
+ width: input.width
51060
+ }), Math.max(1, input.width), {
51061
+ hard: true,
51062
+ trim: false,
51063
+ wordWrap: true
51064
+ }).split("\n");
51065
+ lines.push(...wrappedLines);
51066
+ }
51067
+ return lines;
51068
+ }
51069
+ function buildActivityRowLine(input) {
50560
51070
  const spinner = STRIP_SPINNER_FRAMES[input.tick % STRIP_SPINNER_FRAMES.length] ?? "⠋";
50561
- if (input.activity.mode === "sending") return [
50562
- spacePiTuiTheme.accentText(spinner),
50563
- pc.white("sending"),
50564
- pc.dim(input.activity.pendingOutboundText || "sending...")
51071
+ if (input.row.mode === "sending") {
51072
+ const sendingText = input.row.hint || "sending...";
51073
+ return [spacePiTuiTheme.accentText(spinner), pc.white(sendingText)].join(` ${pc.dim("·")} `);
51074
+ }
51075
+ if (input.row.mode === "dispatching" || input.row.mode === "retrying" || input.row.mode === "warning") return [
51076
+ input.row.mode === "warning" ? pc.yellow("!") : spacePiTuiTheme.accentText(spinner),
51077
+ input.row.mode === "warning" ? pc.dim("now") : pc.dim(`${input.elapsedSeconds}s`),
51078
+ pc.white(input.row.hint ?? "")
50565
51079
  ].join(` ${pc.dim("·")} `);
50566
51080
  const statusLine = [
50567
51081
  spacePiTuiTheme.accentText(spinner),
50568
51082
  pc.dim(`${input.elapsedSeconds}s`),
50569
- buildStatusLine({
50570
- activity: input.activity,
51083
+ buildReplyingStatusLine({
51084
+ row: input.row,
51085
+ spaceMembersSnapshot: input.spaceMembersSnapshot,
50571
51086
  elapsedSeconds: input.elapsedSeconds,
50572
51087
  tick: input.tick
50573
51088
  })
50574
51089
  ].join(` ${pc.dim("·")} `);
50575
- const previewText = input.activity.previewText.trim();
51090
+ const previewText = input.row.previewText.trim();
50576
51091
  if (!previewText) return statusLine;
50577
51092
  const separator = ` ${pc.dim("·")} `;
50578
51093
  const availableWidth = Math.max(0, input.width - stringWidth(stripVTControlCharacters(statusLine)) - stringWidth(stripVTControlCharacters(separator)));
@@ -50584,6 +51099,9 @@ function buildInlineActivityLine(input) {
50584
51099
  });
50585
51100
  return `${statusLine}${separator}${pc.dim(windowText)}`;
50586
51101
  }
51102
+ function resolveRowElapsedSeconds(input) {
51103
+ return (input.row.elapsedSeconds ?? 0) + input.elapsedDeltaSeconds;
51104
+ }
50587
51105
  function resolveStatusModeLabel(input) {
50588
51106
  if (input.previewText.trim().length > 0) return "streaming";
50589
51107
  return STATUS_LABELS[Math.floor(input.elapsedSeconds / STATUS_LABEL_CYCLE_SECONDS) % STATUS_LABELS.length] ?? STATUS_LABELS[0];
@@ -52718,6 +53236,7 @@ function buildSpaceTranscriptItem(input) {
52718
53236
  const groupKey = resolveTextLineGroupKey(input.event);
52719
53237
  const profile = buildTranscriptItemProfileSnapshot(input.event);
52720
53238
  const systemPurpose = resolveTranscriptItemSystemPurpose(input.event);
53239
+ const replyRef = isSignalEnvelope$1(input.event) ? resolveTranscriptReplyRef(input.event) : void 0;
52721
53240
  if (isSignalEnvelope$1(input.event)) {
52722
53241
  if (input.event.type === "presence.join" || input.event.type === "presence.quit") return {
52723
53242
  line: input.line,
@@ -52751,7 +53270,8 @@ function buildSpaceTranscriptItem(input) {
52751
53270
  formattedMessage: input.formattedMessage ?? void 0,
52752
53271
  profile,
52753
53272
  systemPurpose,
52754
- ts: input.event.ts
53273
+ ts: input.event.ts,
53274
+ ...groupKey === SYSTEM_MESSAGE_GROUP_KEY || !replyRef ? {} : { replyRef }
52755
53275
  };
52756
53276
  }
52757
53277
  return {
@@ -52894,6 +53414,31 @@ function resolveTranscriptItemSystemPurpose(event) {
52894
53414
  const meta = resolveSignalTextMetaFromEnvelope$1(event);
52895
53415
  return typeof meta?.purpose === "string" ? meta.purpose : null;
52896
53416
  }
53417
+ function resolveTranscriptReplyRef(event) {
53418
+ if (event.type !== "signal.text") return;
53419
+ const replyToRecord = resolveSignalTextReplyToRecord(event.data);
53420
+ if (!replyToRecord) return;
53421
+ const signalId = sanitizeTranscriptReplyText(replyToRecord.signalId);
53422
+ const profileId = sanitizeTranscriptReplyText(replyToRecord.profileId);
53423
+ const profileName = sanitizeTranscriptReplyText(replyToRecord.profileName);
53424
+ if (!(signalId && (profileName || profileId))) return;
53425
+ return {
53426
+ signalId,
53427
+ profileId,
53428
+ profileKind: replyToRecord.profileKind === "human" || replyToRecord.profileKind === "agent" || replyToRecord.profileKind === "system" ? replyToRecord.profileKind : null,
53429
+ profileName,
53430
+ previewText: sanitizeTranscriptReplyText(replyToRecord.previewText)
53431
+ };
53432
+ }
53433
+ function resolveSignalTextReplyToRecord(data) {
53434
+ if (!(data && typeof data === "object" && !Array.isArray(data))) return null;
53435
+ const replyTo = data.replyTo;
53436
+ if (!(replyTo && typeof replyTo === "object" && !Array.isArray(replyTo))) return null;
53437
+ return replyTo;
53438
+ }
53439
+ function sanitizeTranscriptReplyText(value) {
53440
+ return sanitizeTerminalDisplayText(typeof value === "string" ? value : "", "single-line").replace(/\s+/gu, " ").trim();
53441
+ }
52897
53442
  function resolveTranscriptActorKind(kind) {
52898
53443
  return kind === "human" || kind === "agent" ? kind : "unknown";
52899
53444
  }
@@ -52919,8 +53464,6 @@ const HTTP_ERROR_MESSAGE_REGEX$1 = /^HTTP\s+(\d{3}):\s*(.*)$/i;
52919
53464
  const WS_UNEXPECTED_SERVER_RESPONSE_REGEX = /unexpected server response:\s*(\d{3})/i;
52920
53465
  const LAST_SEEN_FUTURE_SKEW_TOLERANCE_MS = 3e4;
52921
53466
  const MENTION_ALIAS_TOKEN_REGEX$1 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
52922
- const TRANSIENT_HINT_START_PURPOSE = "agent_replying";
52923
- const TRANSIENT_HINT_END_PURPOSE = "agent_replying_end";
52924
53467
  const REPLYING_HINT_FALLBACK_CLEAR_MS = 18e4;
52925
53468
  const REPLYING_STATUS_SYSTEM_LABEL = "📣 system";
52926
53469
  const REPLYING_STATUS_AGENT_LABEL = "🤖";
@@ -52985,14 +53528,31 @@ function handleInteractiveRuntimeEvent(input) {
52985
53528
  input.handleMembersUpdatedEvent(input.event);
52986
53529
  return;
52987
53530
  case "send.queued":
52988
- enqueuePendingOutboundConfirmation(input.pendingOutboundConfirmationQueue, input.event.text);
52989
- input.syncOverlayLine();
53531
+ upsertPendingOutboundRows({
53532
+ enableLocalEcho: input.enableLocalEcho,
53533
+ rowsById: input.rowsById,
53534
+ text: input.event.text,
53535
+ clientMessageId: input.event.clientMessageId,
53536
+ terminalColumns: resolveReplyingStatusColumns(),
53537
+ nowMs: Date.now()
53538
+ });
53539
+ input.syncActivityPresentation();
52990
53540
  return;
52991
53541
  case "send.confirmed":
52992
- dequeuePendingOutboundConfirmationIfHeadMatch(input.pendingOutboundConfirmationQueue, input.event.text);
52993
- input.syncOverlayLine();
53542
+ confirmPendingOutboundRows({
53543
+ rowsById: input.rowsById,
53544
+ clientMessageId: input.event.clientMessageId,
53545
+ sourceEventId: input.event.event.id,
53546
+ nowMs: Date.now()
53547
+ });
53548
+ input.syncActivityPresentation();
52994
53549
  return;
52995
53550
  case "send.failed":
53551
+ clearPendingOutboundRowsByClientMessageId({
53552
+ rowsById: input.rowsById,
53553
+ clientMessageId: input.event.clientMessageId
53554
+ });
53555
+ input.syncActivityPresentation();
52996
53556
  input.reportOutboundSendFailure({
52997
53557
  error: `couldn't send the message: ${input.event.error}`,
52998
53558
  hint: "rejoin the space and try sending it again"
@@ -53243,7 +53803,7 @@ async function runConnect(input) {
53243
53803
  let liveFloorTs = initialLiveFloorTs;
53244
53804
  let pendingLastSeen = null;
53245
53805
  let pendingTimer = null;
53246
- const pendingOutboundConfirmationQueue = [];
53806
+ const activityRowsById = /* @__PURE__ */ new Map();
53247
53807
  let rl = null;
53248
53808
  let hasPrintedTextLine = false;
53249
53809
  let lastPrintedTextLineGroupKey = null;
@@ -53259,21 +53819,17 @@ async function runConnect(input) {
53259
53819
  const enableReplyingPromptStatus = shouldHideSubmittedInputLine;
53260
53820
  const composePromptPrefix = pc.dim("[draft] ");
53261
53821
  let composeDraftState = emptyComposeDraft();
53262
- const replyingStatusByDispatchId = /* @__PURE__ */ new Map();
53263
53822
  let replyingStatusSweepTimer = null;
53264
53823
  const pruneExpiredReplyingStatuses = () => {
53265
- if (!enableReplyingPromptStatus || replyingStatusByDispatchId.size === 0) return;
53266
- const now = Date.now();
53267
- for (const [dispatchId, state] of replyingStatusByDispatchId) if (state.expiresAtMs <= now) replyingStatusByDispatchId.delete(dispatchId);
53824
+ if (!enableReplyingPromptStatus || activityRowsById.size === 0) return;
53825
+ pruneExpiredDispatchRows(activityRowsById, Date.now());
53268
53826
  };
53269
53827
  const resolveReplyingStatusTexts = () => {
53270
53828
  pruneExpiredReplyingStatuses();
53271
- if (replyingStatusByDispatchId.size === 0) return [];
53272
- const terminalColumns = resolveReplyingStatusColumns();
53273
- return [...replyingStatusByDispatchId.values()].sort((a, b) => b.updatedAtMs - a.updatedAtMs).map((status) => formatReplyingStatusText({
53274
- state: status,
53275
- terminalColumns
53276
- }));
53829
+ return resolveDispatchRowStatusTexts({
53830
+ rowsById: activityRowsById,
53831
+ terminalColumns: resolveReplyingStatusColumns()
53832
+ });
53277
53833
  };
53278
53834
  const resolveInputPrompt = () => {
53279
53835
  const baseInputPrompt = formatInputPrompt(profileIdentity, { spaceMembersSnapshot });
@@ -53342,12 +53898,6 @@ async function runConnect(input) {
53342
53898
  visibleReplyingStatusLineRows = countRenderedTerminalRows(normalizedText);
53343
53899
  };
53344
53900
  const syncReplyingStatusPresentation = () => {
53345
- const pendingOutboundStatus = resolvePendingOutboundStatus();
53346
- if (pendingOutboundStatus) {
53347
- renderVisibleReplyingStatusLine(`${pc.dim(`* ${REPLYING_STATUS_SYSTEM_LABEL}`)} ${pc.dim("·")} ${pc.dim(pendingOutboundStatus)}`);
53348
- refreshInputPrompt();
53349
- return;
53350
- }
53351
53901
  const promptStatuses = resolveReplyingStatusTexts();
53352
53902
  if (promptStatuses.length > 0) {
53353
53903
  const decoratedReplyingStatus = promptStatuses.map((statusText) => {
@@ -53362,10 +53912,9 @@ async function runConnect(input) {
53362
53912
  clearTimeout(replyingStatusSweepTimer);
53363
53913
  replyingStatusSweepTimer = null;
53364
53914
  }
53365
- if (!enableReplyingPromptStatus || replyingStatusByDispatchId.size === 0) return;
53366
- let nearestExpiryMs = Number.POSITIVE_INFINITY;
53367
- for (const state of replyingStatusByDispatchId.values()) if (state.expiresAtMs < nearestExpiryMs) nearestExpiryMs = state.expiresAtMs;
53368
- if (!Number.isFinite(nearestExpiryMs)) return;
53915
+ if (!enableReplyingPromptStatus || activityRowsById.size === 0) return;
53916
+ const nearestExpiryMs = resolveNearestDispatchRowExpiryMs(activityRowsById);
53917
+ if (nearestExpiryMs === null) return;
53369
53918
  const delayMs = Math.max(250, nearestExpiryMs - Date.now());
53370
53919
  replyingStatusSweepTimer = setTimeout(() => {
53371
53920
  pruneExpiredReplyingStatuses();
@@ -53375,15 +53924,15 @@ async function runConnect(input) {
53375
53924
  };
53376
53925
  const handleReplyingHintStatusEvent = (event) => {
53377
53926
  if (!enableReplyingPromptStatus || event.type !== "signal.text") return;
53378
- const replyingHintEvent = resolveReplyingHintEvent(event);
53927
+ const replyingHintEvent = resolveDispatchActivityEvent(event);
53379
53928
  let statusChanged = false;
53380
- if (replyingHintEvent) statusChanged = upsertReplyingStatusState({
53381
- replyingStatusByDispatchId,
53929
+ if (replyingHintEvent) statusChanged = upsertDispatchActivityStatusState({
53930
+ rowsById: activityRowsById,
53382
53931
  event: replyingHintEvent,
53383
53932
  nowMs: Date.now()
53384
53933
  });
53385
- else statusChanged = clearReplyingStatusesForSignal({
53386
- replyingStatusByDispatchId,
53934
+ else statusChanged = clearDispatchActivitiesForSignal({
53935
+ rowsById: activityRowsById,
53387
53936
  event
53388
53937
  });
53389
53938
  if (!statusChanged) return;
@@ -53442,7 +53991,12 @@ async function runConnect(input) {
53442
53991
  };
53443
53992
  const consumePendingOutboundConfirmation = (event) => {
53444
53993
  if (event.type !== "signal.text" || event.profile?.profileId !== profileIdentity.profileId) return;
53445
- if (!dequeuePendingOutboundConfirmationIfHeadMatch(pendingOutboundConfirmationQueue, typeof event.data?.text === "string" ? event.data.text : "")) return;
53994
+ if (!confirmPendingOutboundRows({
53995
+ rowsById: activityRowsById,
53996
+ clientMessageId: resolveSignalClientMessageId(event),
53997
+ sourceEventId: event.id,
53998
+ nowMs: Date.now()
53999
+ })) return;
53446
54000
  syncReplyingStatusPresentation();
53447
54001
  };
53448
54002
  const resolveTextRenderEvent = (event) => {
@@ -53585,7 +54139,7 @@ async function runConnect(input) {
53585
54139
  processIgnoredOlderThanLiveFloorSignal({
53586
54140
  event,
53587
54141
  seenSignalIds: catchupSeenSignalIds,
53588
- onReplyingHintEvent: handleReplyingHintStatusEvent
54142
+ onDispatchActivityEvent: handleReplyingHintStatusEvent
53589
54143
  });
53590
54144
  return;
53591
54145
  }
@@ -53793,8 +54347,7 @@ async function runConnect(input) {
53793
54347
  if (runtime.resolvedView === "human") refreshInputPrompt();
53794
54348
  }
53795
54349
  function reportPendingOutboundUnconfirmed(inputPending) {
53796
- if (pendingOutboundConfirmationQueue.length === 0) return;
53797
- pendingOutboundConfirmationQueue.length = 0;
54350
+ if (!clearUnconfirmedPendingOutboundRows(activityRowsById)) return;
53798
54351
  syncReplyingStatusPresentation();
53799
54352
  const reasonSuffix = inputPending.reason ? ` (${inputPending.reason})` : "";
53800
54353
  presenter.event("error", "connect.error", {
@@ -53803,18 +54356,6 @@ async function runConnect(input) {
53803
54356
  });
53804
54357
  process.exitCode = 1;
53805
54358
  }
53806
- function resolvePendingOutboundStatus() {
53807
- if (!enableLocalEcho) return "";
53808
- const pendingText = pendingOutboundConfirmationQueue[0];
53809
- if (!pendingText) return "";
53810
- const normalizedText = normalizePreviewDisplayText(pendingText);
53811
- if (!normalizedText) return "sending...";
53812
- const statusPrefix = "sending: ";
53813
- return `${statusPrefix}${truncatePreviewHead(normalizedText, resolvePreviewContentWidth({
53814
- previewPrefix: statusPrefix,
53815
- terminalColumns: resolveReplyingStatusColumns()
53816
- }))}`;
53817
- }
53818
54359
  const sendOutboundText = (outboundText) => {
53819
54360
  if (isClosing || wsEnded) {
53820
54361
  reportOutboundSendFailure({
@@ -53823,8 +54364,9 @@ async function runConnect(input) {
53823
54364
  });
53824
54365
  return;
53825
54366
  }
54367
+ const clientMessageId = crypto.randomUUID();
53826
54368
  try {
53827
- ws.send(JSON.stringify(makeTextSignal(outboundText)));
54369
+ ws.send(JSON.stringify(makeTextSignal(outboundText, { meta: { clientMessageId } })));
53828
54370
  } catch (error) {
53829
54371
  reportOutboundSendFailure({
53830
54372
  error: `couldn't send the message: ${toErrorMessage$3(error)}`,
@@ -53832,7 +54374,14 @@ async function runConnect(input) {
53832
54374
  });
53833
54375
  return;
53834
54376
  }
53835
- enqueuePendingOutboundConfirmation(pendingOutboundConfirmationQueue, outboundText);
54377
+ upsertPendingOutboundRows({
54378
+ enableLocalEcho,
54379
+ rowsById: activityRowsById,
54380
+ text: outboundText,
54381
+ clientMessageId,
54382
+ terminalColumns: resolveReplyingStatusColumns(),
54383
+ nowMs: Date.now()
54384
+ });
53836
54385
  syncReplyingStatusPresentation();
53837
54386
  if (runtime.resolvedView === "human") refreshInputPrompt();
53838
54387
  };
@@ -53906,8 +54455,7 @@ async function runInteractiveHumanTextSession(input) {
53906
54455
  resources: {
53907
54456
  composerActivity: {
53908
54457
  nowMs: Date.now(),
53909
- pendingOutboundText: resolvePendingOutboundStatus(),
53910
- replyingDispatches: toReplyingDispatchStates(replyingStatusByDispatchId)
54458
+ rows: toComposerDispatchRows(activityRowsById)
53911
54459
  },
53912
54460
  sessionDiagnostics
53913
54461
  },
@@ -53928,8 +54476,7 @@ async function runInteractiveHumanTextSession(input) {
53928
54476
  getResources: () => ({
53929
54477
  composerActivity: {
53930
54478
  nowMs: Date.now(),
53931
- pendingOutboundText: resolvePendingOutboundStatus(),
53932
- replyingDispatches: toReplyingDispatchStates(replyingStatusByDispatchId)
54479
+ rows: toComposerDispatchRows(activityRowsById)
53933
54480
  },
53934
54481
  sessionDiagnostics
53935
54482
  }),
@@ -53944,8 +54491,7 @@ async function runInteractiveHumanTextSession(input) {
53944
54491
  shell.render(buildCurrentViewState());
53945
54492
  });
53946
54493
  };
53947
- const pendingOutboundConfirmationQueue = [];
53948
- const replyingStatusByDispatchId = /* @__PURE__ */ new Map();
54494
+ const activityRowsById = /* @__PURE__ */ new Map();
53949
54495
  const catchupSeenSignalIds = /* @__PURE__ */ new Set();
53950
54496
  let mentionHighlightIndex = null;
53951
54497
  let liveFloorTs = input.initialLiveFloorTs;
@@ -54156,40 +54702,17 @@ async function runInteractiveHumanTextSession(input) {
54156
54702
  input.presenter.event("info", "connect.warn.cursor_sync_paused");
54157
54703
  };
54158
54704
  const pruneExpiredReplyingStatuses = () => {
54159
- if (replyingStatusByDispatchId.size === 0) return;
54160
- const now = Date.now();
54161
- for (const [dispatchId, state] of replyingStatusByDispatchId) if (state.expiresAtMs <= now) replyingStatusByDispatchId.delete(dispatchId);
54705
+ if (activityRowsById.size === 0) return;
54706
+ pruneExpiredDispatchRows(activityRowsById, Date.now());
54162
54707
  };
54163
54708
  const resolveReplyingStatusTexts = () => {
54164
54709
  pruneExpiredReplyingStatuses();
54165
- if (replyingStatusByDispatchId.size === 0) return [];
54166
- const terminalColumns = resolveReplyingStatusColumns();
54167
- return [...replyingStatusByDispatchId.values()].sort((left, right) => right.updatedAtMs - left.updatedAtMs).map((status) => formatReplyingStatusText({
54168
- state: status,
54169
- terminalColumns
54170
- }));
54171
- };
54172
- const resolvePendingOutboundStatus = () => {
54173
- if (!input.enableLocalEcho) return "";
54174
- const pendingText = pendingOutboundConfirmationQueue[0];
54175
- if (!pendingText) return "";
54176
- const normalizedText = normalizePreviewDisplayText(pendingText);
54177
- if (!normalizedText) return "sending...";
54178
- const statusPrefix = "sending: ";
54179
- return `${statusPrefix}${truncatePreviewHead(normalizedText, resolvePreviewContentWidth({
54180
- previewPrefix: statusPrefix,
54710
+ return resolveDispatchRowStatusTexts({
54711
+ rowsById: activityRowsById,
54181
54712
  terminalColumns: resolveReplyingStatusColumns()
54182
- }))}`;
54713
+ });
54183
54714
  };
54184
54715
  const syncOverlayLine = () => {
54185
- const pendingOutboundStatus = resolvePendingOutboundStatus();
54186
- if (pendingOutboundStatus) {
54187
- store.dispatch({
54188
- type: "status.overlay.updated",
54189
- line: `* ${REPLYING_STATUS_SYSTEM_LABEL} · ${pendingOutboundStatus}`
54190
- });
54191
- return;
54192
- }
54193
54716
  const replyingStatuses = resolveReplyingStatusTexts();
54194
54717
  if (replyingStatuses.length === 0) {
54195
54718
  store.dispatch({
@@ -54206,37 +54729,40 @@ async function runInteractiveHumanTextSession(input) {
54206
54729
  line: decoratedReplyingStatus
54207
54730
  });
54208
54731
  };
54732
+ const syncComposerActivityPresentation = () => {
54733
+ syncOverlayLine();
54734
+ if (piTuiSessionMount) piTuiSessionMount.renderCurrentViewState();
54735
+ };
54209
54736
  const scheduleReplyingStatusSweep = () => {
54210
54737
  if (replyingStatusSweepTimer) {
54211
54738
  clearTimeout(replyingStatusSweepTimer);
54212
54739
  replyingStatusSweepTimer = null;
54213
54740
  }
54214
- if (replyingStatusByDispatchId.size === 0) return;
54215
- let nearestExpiryMs = Number.POSITIVE_INFINITY;
54216
- for (const state of replyingStatusByDispatchId.values()) if (state.expiresAtMs < nearestExpiryMs) nearestExpiryMs = state.expiresAtMs;
54217
- if (!Number.isFinite(nearestExpiryMs)) return;
54741
+ if (activityRowsById.size === 0) return;
54742
+ const nearestExpiryMs = resolveNearestDispatchRowExpiryMs(activityRowsById);
54743
+ if (nearestExpiryMs === null) return;
54218
54744
  const delayMs = Math.max(250, nearestExpiryMs - Date.now());
54219
54745
  replyingStatusSweepTimer = setTimeout(() => {
54220
54746
  pruneExpiredReplyingStatuses();
54221
- syncOverlayLine();
54747
+ syncComposerActivityPresentation();
54222
54748
  scheduleReplyingStatusSweep();
54223
54749
  }, delayMs);
54224
54750
  };
54225
54751
  const handleReplyingHintStatusEvent = (event) => {
54226
- const replyingHintEvent = resolveReplyingHintEvent(event);
54752
+ const replyingHintEvent = resolveDispatchActivityEvent(event);
54227
54753
  let statusChanged = false;
54228
- if (replyingHintEvent) statusChanged = upsertReplyingStatusState({
54229
- replyingStatusByDispatchId,
54754
+ if (replyingHintEvent) statusChanged = upsertDispatchActivityStatusState({
54755
+ rowsById: activityRowsById,
54230
54756
  event: replyingHintEvent,
54231
54757
  nowMs: Date.now()
54232
54758
  });
54233
- else statusChanged = clearReplyingStatusesForSignal({
54234
- replyingStatusByDispatchId,
54759
+ else statusChanged = clearDispatchActivitiesForSignal({
54760
+ rowsById: activityRowsById,
54235
54761
  event
54236
54762
  });
54237
54763
  if (!statusChanged) return;
54238
54764
  scheduleReplyingStatusSweep();
54239
- syncOverlayLine();
54765
+ syncComposerActivityPresentation();
54240
54766
  };
54241
54767
  const flushLastSeen = async () => {
54242
54768
  if (!pendingLastSeen) return;
@@ -54291,15 +54817,14 @@ async function runInteractiveHumanTextSession(input) {
54291
54817
  scheduleLastSeen(event.ts);
54292
54818
  };
54293
54819
  const reportOutboundSendFailure = (failure) => {
54294
- syncOverlayLine();
54820
+ syncComposerActivityPresentation();
54295
54821
  shell.prepareExternalWrite();
54296
54822
  input.presenter.event("error", "connect.error", failure);
54297
54823
  process.exitCode = 1;
54298
54824
  };
54299
54825
  const reportPendingOutboundUnconfirmed = (pending) => {
54300
- if (pendingOutboundConfirmationQueue.length === 0) return;
54301
- pendingOutboundConfirmationQueue.length = 0;
54302
- syncOverlayLine();
54826
+ if (!clearUnconfirmedPendingOutboundRows(activityRowsById)) return;
54827
+ syncComposerActivityPresentation();
54303
54828
  const reasonSuffix = pending.reason ? ` (${pending.reason})` : "";
54304
54829
  shell.prepareExternalWrite();
54305
54830
  input.presenter.event("error", "connect.error", {
@@ -54338,7 +54863,7 @@ async function runInteractiveHumanTextSession(input) {
54338
54863
  processIgnoredOlderThanLiveFloorSignal({
54339
54864
  event: ignoredEvent,
54340
54865
  seenSignalIds: catchupSeenSignalIds,
54341
- onReplyingHintEvent: handleReplyingHintStatusEvent
54866
+ onDispatchActivityEvent: handleReplyingHintStatusEvent
54342
54867
  });
54343
54868
  },
54344
54869
  scheduleMembersSnapshotRefresh,
@@ -54475,10 +55000,11 @@ async function runInteractiveHumanTextSession(input) {
54475
55000
  handleHistoryLoadedEvent,
54476
55001
  handleIncomingEvent,
54477
55002
  handleMembersUpdatedEvent,
54478
- pendingOutboundConfirmationQueue,
55003
+ rowsById: activityRowsById,
55004
+ enableLocalEcho: input.enableLocalEcho,
54479
55005
  reportOutboundSendFailure,
54480
55006
  store,
54481
- syncOverlayLine
55007
+ syncActivityPresentation: syncComposerActivityPresentation
54482
55008
  });
54483
55009
  });
54484
55010
  function cleanup(why) {
@@ -55050,109 +55576,322 @@ function emitReplaySignals(input, signals) {
55050
55576
  rememberSeenSignalId(input.seenSignalIds, event.id);
55051
55577
  }
55052
55578
  }
55053
- function enqueuePendingOutboundConfirmation(queue, text) {
55054
- if (queue.length >= PENDING_OUTBOUND_CONFIRMATION_MAX) queue.shift();
55055
- queue.push(text);
55579
+ function buildPendingDispatchRowId(clientMessageId, targetWakeToken) {
55580
+ return `pending:${clientMessageId}:${targetWakeToken ?? "__generic__"}`;
55056
55581
  }
55057
- function dequeuePendingOutboundConfirmationIfHeadMatch(queue, text) {
55058
- if (queue[0] !== text) return false;
55059
- queue.splice(0, 1);
55582
+ function upsertPendingOutboundRows(input) {
55583
+ if (!input.enableLocalEcho) return false;
55584
+ const drafts = buildPendingOutboundDispatchRowDrafts({
55585
+ pendingText: input.text,
55586
+ terminalColumns: input.terminalColumns
55587
+ });
55588
+ if (drafts.length === 0) return false;
55589
+ for (const draft of drafts) input.rowsById.set(buildPendingDispatchRowId(input.clientMessageId, draft.targetWakeToken), {
55590
+ rowId: buildPendingDispatchRowId(input.clientMessageId, draft.targetWakeToken),
55591
+ dispatchId: null,
55592
+ sourceEventId: null,
55593
+ sourceClientMessageId: input.clientMessageId,
55594
+ targetProfileId: null,
55595
+ targetWakeToken: draft.targetWakeToken,
55596
+ targetLabel: draft.targetLabel,
55597
+ stage: "sending",
55598
+ createdAtMs: input.nowMs,
55599
+ updatedAtMs: input.nowMs,
55600
+ expiresAtMs: null,
55601
+ latestPreviewText: "",
55602
+ latestPreviewUpdatedAtMs: null,
55603
+ statusText: draft.statusText,
55604
+ warningText: ""
55605
+ });
55606
+ trimPendingOutboundRows(input.rowsById);
55060
55607
  return true;
55061
55608
  }
55062
- function clearReplyingStatusesForSignal(input) {
55063
- if (input.replyingStatusByDispatchId.size === 0) return false;
55609
+ function trimPendingOutboundRows(rowsById) {
55610
+ if (rowsById.size <= PENDING_OUTBOUND_CONFIRMATION_MAX) return;
55611
+ const removableRows = [...rowsById.values()].filter((row) => row.stage === "sending" && row.dispatchId === null && row.sourceEventId === null).sort((left, right) => left.createdAtMs - right.createdAtMs);
55612
+ while (rowsById.size > PENDING_OUTBOUND_CONFIRMATION_MAX && removableRows.length > 0) {
55613
+ const oldestRow = removableRows.shift();
55614
+ if (!oldestRow) break;
55615
+ rowsById.delete(oldestRow.rowId);
55616
+ }
55617
+ }
55618
+ function confirmPendingOutboundRows(input) {
55619
+ if (!input.clientMessageId) return false;
55620
+ let changed = false;
55621
+ for (const [rowId, row] of input.rowsById) {
55622
+ if (row.sourceClientMessageId !== input.clientMessageId) continue;
55623
+ if (row.targetWakeToken === null) {
55624
+ input.rowsById.delete(rowId);
55625
+ changed = true;
55626
+ continue;
55627
+ }
55628
+ input.rowsById.set(rowId, {
55629
+ ...row,
55630
+ sourceEventId: input.sourceEventId,
55631
+ updatedAtMs: input.nowMs
55632
+ });
55633
+ changed = true;
55634
+ }
55635
+ return changed;
55636
+ }
55637
+ function clearPendingOutboundRowsByClientMessageId(input) {
55638
+ if (!input.clientMessageId) return false;
55639
+ let changed = false;
55640
+ for (const [rowId, row] of input.rowsById) {
55641
+ if (row.sourceClientMessageId !== input.clientMessageId) continue;
55642
+ input.rowsById.delete(rowId);
55643
+ changed = true;
55644
+ }
55645
+ return changed;
55646
+ }
55647
+ function clearUnconfirmedPendingOutboundRows(rowsById) {
55648
+ let changed = false;
55649
+ for (const [rowId, row] of rowsById) if (row.stage === "sending" && row.dispatchId === null && row.sourceEventId === null) {
55650
+ rowsById.delete(rowId);
55651
+ changed = true;
55652
+ }
55653
+ return changed;
55654
+ }
55655
+ function pruneExpiredDispatchRows(rowsById, nowMs) {
55656
+ let changed = false;
55657
+ for (const [rowId, row] of rowsById) {
55658
+ if (typeof row.expiresAtMs !== "number" || row.expiresAtMs > nowMs) continue;
55659
+ rowsById.delete(rowId);
55660
+ changed = true;
55661
+ }
55662
+ return changed;
55663
+ }
55664
+ function resolveNearestDispatchRowExpiryMs(rowsById) {
55665
+ let nearestExpiryMs = null;
55666
+ for (const row of rowsById.values()) {
55667
+ if (typeof row.expiresAtMs !== "number") continue;
55668
+ if (nearestExpiryMs === null || row.expiresAtMs < nearestExpiryMs) nearestExpiryMs = row.expiresAtMs;
55669
+ }
55670
+ return nearestExpiryMs;
55671
+ }
55672
+ function resolveDispatchRowStatusTexts(input) {
55673
+ if (input.rowsById.size === 0) return [];
55674
+ return [...input.rowsById.values()].sort((left, right) => right.updatedAtMs - left.updatedAtMs).map((state) => formatReplyingStatusText({
55675
+ state,
55676
+ terminalColumns: input.terminalColumns
55677
+ }));
55678
+ }
55679
+ function toDispatchActivityIdentity(event) {
55680
+ return {
55681
+ dispatchId: event.dispatchId,
55682
+ sourceClientMessageId: event.sourceClientMessageId,
55683
+ sourceEventId: event.sourceEventId,
55684
+ targetLabel: "targetLabel" in event ? event.targetLabel : event.targetProfileId,
55685
+ targetProfileId: event.targetProfileId,
55686
+ targetWakeToken: event.targetWakeToken
55687
+ };
55688
+ }
55689
+ function buildDispatchActivityRowId(input) {
55690
+ const { identity } = input;
55691
+ if (identity.dispatchId) return `dispatch:${identity.dispatchId}`;
55692
+ if (identity.sourceEventId && identity.targetWakeToken) return `event:${identity.sourceEventId}:${identity.targetWakeToken}`;
55693
+ if (identity.sourceClientMessageId && identity.targetWakeToken) return `client:${identity.sourceClientMessageId}:${identity.targetWakeToken}`;
55694
+ if (identity.targetProfileId) return `profile:${identity.targetProfileId}`;
55695
+ return `label:${identity.targetLabel}`;
55696
+ }
55697
+ function findMatchingDispatchActivityRowEntry(input) {
55698
+ for (const entry of input.rowsById) if (entry[1].dispatchId === input.identity.dispatchId) return entry;
55699
+ if (input.identity.sourceEventId && input.identity.targetWakeToken) {
55700
+ for (const entry of input.rowsById) if (entry[1].sourceEventId === input.identity.sourceEventId && entry[1].targetWakeToken === input.identity.targetWakeToken) return entry;
55701
+ }
55702
+ if (input.identity.sourceClientMessageId && input.identity.targetWakeToken) {
55703
+ for (const entry of input.rowsById) if (entry[1].sourceClientMessageId === input.identity.sourceClientMessageId && entry[1].targetWakeToken === input.identity.targetWakeToken) return entry;
55704
+ }
55705
+ return null;
55706
+ }
55707
+ function mergeDispatchActivityIdentity(input) {
55708
+ return {
55709
+ rowId: input.rowId,
55710
+ dispatchId: input.event.dispatchId,
55711
+ sourceEventId: input.event.sourceEventId ?? input.existing?.sourceEventId ?? null,
55712
+ sourceClientMessageId: input.event.sourceClientMessageId ?? input.existing?.sourceClientMessageId ?? null,
55713
+ targetProfileId: input.event.targetProfileId ?? input.existing?.targetProfileId ?? null,
55714
+ targetWakeToken: input.event.targetWakeToken ?? input.existing?.targetWakeToken ?? null,
55715
+ targetLabel: ("targetLabel" in input.event ? input.event.targetLabel : null) ?? input.existing?.targetLabel ?? input.event.targetProfileId,
55716
+ stage: input.existing?.stage ?? "dispatching",
55717
+ createdAtMs: input.existing?.createdAtMs ?? input.nowMs,
55718
+ updatedAtMs: input.nowMs,
55719
+ expiresAtMs: input.existing?.expiresAtMs ?? null,
55720
+ latestPreviewText: input.existing?.latestPreviewText ?? "",
55721
+ latestPreviewUpdatedAtMs: input.existing?.latestPreviewUpdatedAtMs ?? null,
55722
+ statusText: input.existing?.statusText ?? "",
55723
+ warningText: input.existing?.warningText ?? ""
55724
+ };
55725
+ }
55726
+ function clearDispatchActivitiesForSignal(input) {
55727
+ if (input.rowsById.size === 0) return false;
55064
55728
  if (!resolveNonTransientSignalText(input.event)) return false;
55065
55729
  const senderProfileId = String(input.event.profile?.profileId ?? "").trim();
55066
55730
  if (!senderProfileId) return false;
55067
55731
  const dispatchId = resolveReplyingSignalDispatchId(input.event);
55068
- if (dispatchId && input.replyingStatusByDispatchId.has(dispatchId)) {
55069
- input.replyingStatusByDispatchId.delete(dispatchId);
55732
+ if (dispatchId) for (const [rowId, row] of input.rowsById) {
55733
+ if (row.dispatchId !== dispatchId) continue;
55734
+ input.rowsById.delete(rowId);
55070
55735
  return true;
55071
55736
  }
55072
- let latestDispatchId = null;
55737
+ let latestRowId = null;
55073
55738
  let latestUpdatedAtMs = Number.NEGATIVE_INFINITY;
55074
- for (const [dispatchId, state] of input.replyingStatusByDispatchId) {
55075
- if (state.targetProfileId !== senderProfileId) continue;
55076
- if (state.updatedAtMs > latestUpdatedAtMs) {
55077
- latestUpdatedAtMs = state.updatedAtMs;
55078
- latestDispatchId = dispatchId;
55739
+ for (const [rowId, row] of input.rowsById) {
55740
+ if (row.targetProfileId !== senderProfileId || row.stage === "sending") continue;
55741
+ if (row.updatedAtMs > latestUpdatedAtMs) {
55742
+ latestUpdatedAtMs = row.updatedAtMs;
55743
+ latestRowId = rowId;
55079
55744
  }
55080
55745
  }
55081
- if (!latestDispatchId) return false;
55082
- input.replyingStatusByDispatchId.delete(latestDispatchId);
55746
+ if (!latestRowId) return false;
55747
+ input.rowsById.delete(latestRowId);
55083
55748
  return true;
55084
55749
  }
55085
- function upsertReplyingStatusState(input) {
55086
- if (input.event.kind === "end") return input.replyingStatusByDispatchId.delete(input.event.dispatchId);
55087
- const existing = input.replyingStatusByDispatchId.get(input.event.dispatchId) ?? null;
55088
- if (input.event.kind === "preview_end") {
55089
- if (!existing) return false;
55090
- input.replyingStatusByDispatchId.set(input.event.dispatchId, {
55091
- ...existing,
55092
- updatedAtMs: input.nowMs,
55093
- latestPreviewText: "",
55094
- latestPreviewUpdatedAtMs: null,
55095
- expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55096
- warningText: ""
55750
+ function upsertDispatchActivityStatusState(input) {
55751
+ const existingEntry = findMatchingDispatchActivityRowEntry({
55752
+ identity: toDispatchActivityIdentity(input.event),
55753
+ rowsById: input.rowsById
55754
+ });
55755
+ const existing = existingEntry?.[1] ?? null;
55756
+ const rowId = existingEntry?.[0] ?? buildDispatchActivityRowId({ identity: toDispatchActivityIdentity(input.event) });
55757
+ switch (input.event.kind) {
55758
+ case "end": return existingEntry ? input.rowsById.delete(existingEntry[0]) : false;
55759
+ case "preview_end": return applyPreviewEndDispatchActivityState({
55760
+ existing,
55761
+ map: input.rowsById,
55762
+ rowId,
55763
+ nowMs: input.nowMs
55097
55764
  });
55098
- return true;
55765
+ case "warning": return applyWarningDispatchActivityState({
55766
+ existing,
55767
+ event: input.event,
55768
+ map: input.rowsById,
55769
+ rowId,
55770
+ nowMs: input.nowMs
55771
+ });
55772
+ case "dispatching":
55773
+ case "retrying": return applyStatusDispatchActivityState({
55774
+ existing,
55775
+ event: input.event,
55776
+ map: input.rowsById,
55777
+ rowId,
55778
+ nowMs: input.nowMs
55779
+ });
55780
+ case "replying_start": return applyReplyingStartDispatchActivityState({
55781
+ existing,
55782
+ event: input.event,
55783
+ map: input.rowsById,
55784
+ rowId,
55785
+ nowMs: input.nowMs
55786
+ });
55787
+ case "preview": return applyPreviewDispatchActivityState({
55788
+ existing,
55789
+ event: input.event,
55790
+ map: input.rowsById,
55791
+ rowId,
55792
+ nowMs: input.nowMs
55793
+ });
55794
+ default: return false;
55099
55795
  }
55100
- if (input.event.kind === "warning") {
55101
- if (existing?.displayKind === "replying") {
55102
- input.replyingStatusByDispatchId.set(input.event.dispatchId, {
55103
- ...existing,
55104
- updatedAtMs: input.nowMs,
55105
- expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55106
- statusText: input.event.text,
55107
- warningText: input.event.text
55108
- });
55109
- return true;
55110
- }
55111
- input.replyingStatusByDispatchId.set(input.event.dispatchId, {
55112
- displayKind: "warning",
55113
- targetProfileId: input.event.targetProfileId,
55114
- targetLabel: input.event.targetLabel,
55115
- startedAtMs: existing?.startedAtMs ?? input.nowMs,
55796
+ }
55797
+ function applyPreviewEndDispatchActivityState(input) {
55798
+ if (!input.existing) return false;
55799
+ input.map.set(input.rowId, {
55800
+ ...input.existing,
55801
+ updatedAtMs: input.nowMs,
55802
+ latestPreviewText: "",
55803
+ latestPreviewUpdatedAtMs: null,
55804
+ expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55805
+ warningText: ""
55806
+ });
55807
+ return true;
55808
+ }
55809
+ function applyWarningDispatchActivityState(input) {
55810
+ if (input.event.preserveActivityMode && input.existing?.stage === "replying") {
55811
+ input.map.set(input.rowId, {
55812
+ ...input.existing,
55116
55813
  updatedAtMs: input.nowMs,
55117
- latestPreviewText: "",
55118
- latestPreviewUpdatedAtMs: null,
55119
55814
  expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55120
55815
  statusText: input.event.text,
55121
55816
  warningText: input.event.text
55122
55817
  });
55123
55818
  return true;
55124
55819
  }
55125
- if (input.event.kind === "replying_start") {
55126
- input.replyingStatusByDispatchId.set(input.event.dispatchId, {
55127
- displayKind: "replying",
55128
- targetProfileId: input.event.targetProfileId,
55129
- targetLabel: input.event.targetLabel,
55130
- startedAtMs: existing?.startedAtMs ?? input.nowMs,
55131
- updatedAtMs: input.nowMs,
55132
- latestPreviewText: existing?.latestPreviewText ?? "",
55133
- latestPreviewUpdatedAtMs: existing?.latestPreviewUpdatedAtMs ?? null,
55134
- expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55135
- statusText: existing?.statusText ?? "",
55136
- warningText: ""
55137
- });
55138
- return true;
55139
- }
55140
- input.replyingStatusByDispatchId.set(input.event.dispatchId, {
55141
- displayKind: "replying",
55142
- targetProfileId: input.event.targetProfileId,
55143
- targetLabel: input.event.targetLabel,
55144
- startedAtMs: existing?.startedAtMs ?? input.nowMs,
55820
+ input.map.set(input.rowId, {
55821
+ ...mergeDispatchActivityIdentity({
55822
+ event: input.event,
55823
+ existing: input.existing,
55824
+ nowMs: input.nowMs,
55825
+ rowId: input.rowId
55826
+ }),
55827
+ stage: "warning",
55828
+ updatedAtMs: input.nowMs,
55829
+ latestPreviewText: "",
55830
+ latestPreviewUpdatedAtMs: null,
55831
+ expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55832
+ statusText: input.event.text,
55833
+ warningText: input.event.text
55834
+ });
55835
+ return true;
55836
+ }
55837
+ function applyStatusDispatchActivityState(input) {
55838
+ input.map.set(input.rowId, {
55839
+ ...mergeDispatchActivityIdentity({
55840
+ event: input.event,
55841
+ existing: input.existing,
55842
+ nowMs: input.nowMs,
55843
+ rowId: input.rowId
55844
+ }),
55845
+ stage: input.event.kind === "dispatching" ? "dispatching" : "retrying",
55846
+ updatedAtMs: input.nowMs,
55847
+ latestPreviewText: "",
55848
+ latestPreviewUpdatedAtMs: null,
55849
+ expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55850
+ statusText: input.event.text,
55851
+ warningText: ""
55852
+ });
55853
+ return true;
55854
+ }
55855
+ function applyReplyingStartDispatchActivityState(input) {
55856
+ input.map.set(input.rowId, {
55857
+ ...mergeDispatchActivityIdentity({
55858
+ event: input.event,
55859
+ existing: input.existing,
55860
+ nowMs: input.nowMs,
55861
+ rowId: input.rowId
55862
+ }),
55863
+ stage: "replying",
55864
+ updatedAtMs: input.nowMs,
55865
+ latestPreviewText: input.existing?.latestPreviewText ?? "",
55866
+ latestPreviewUpdatedAtMs: input.existing?.latestPreviewUpdatedAtMs ?? null,
55867
+ expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55868
+ statusText: input.existing?.statusText ?? "",
55869
+ warningText: ""
55870
+ });
55871
+ return true;
55872
+ }
55873
+ function applyPreviewDispatchActivityState(input) {
55874
+ input.map.set(input.rowId, {
55875
+ ...mergeDispatchActivityIdentity({
55876
+ event: input.event,
55877
+ existing: input.existing,
55878
+ nowMs: input.nowMs,
55879
+ rowId: input.rowId
55880
+ }),
55881
+ stage: "replying",
55145
55882
  updatedAtMs: input.nowMs,
55146
55883
  latestPreviewText: input.event.previewText,
55147
55884
  latestPreviewUpdatedAtMs: input.nowMs,
55148
55885
  expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55149
- statusText: existing?.statusText ?? "",
55886
+ statusText: input.existing?.statusText ?? "",
55150
55887
  warningText: ""
55151
55888
  });
55152
55889
  return true;
55153
55890
  }
55154
55891
  function formatReplyingStatusText(input) {
55155
- if (input.state.displayKind === "warning") return input.state.warningText || input.state.statusText;
55892
+ if (input.state.stage === "sending") return input.state.statusText || "sending...";
55893
+ if (input.state.stage === "warning") return input.state.warningText || input.state.statusText;
55894
+ if (input.state.stage === "dispatching" || input.state.stage === "retrying") return input.state.statusText || `${input.state.targetLabel} ${input.state.stage === "dispatching" ? "is dispatching..." : "is retrying..."}`;
55156
55895
  if (input.state.warningText) return input.state.warningText;
55157
55896
  const previewText = input.state.latestPreviewText.trim();
55158
55897
  if (!previewText) return `${input.state.targetLabel} is replying...`;
@@ -55162,17 +55901,8 @@ function formatReplyingStatusText(input) {
55162
55901
  terminalColumns: input.terminalColumns
55163
55902
  }))}`;
55164
55903
  }
55165
- function toReplyingDispatchStates(replyingStatusByDispatchId) {
55166
- return [...replyingStatusByDispatchId.entries()].filter(([, state]) => state.displayKind === "replying").map(([dispatchId, state]) => ({
55167
- dispatchId,
55168
- targetProfileId: state.targetProfileId,
55169
- targetLabel: state.targetLabel,
55170
- startedAtMs: state.startedAtMs,
55171
- updatedAtMs: state.updatedAtMs,
55172
- latestPreviewText: state.latestPreviewText,
55173
- latestPreviewUpdatedAtMs: state.latestPreviewUpdatedAtMs,
55174
- expiresAtMs: state.expiresAtMs
55175
- }));
55904
+ function toComposerDispatchRows(rowsById) {
55905
+ return [...rowsById.values()];
55176
55906
  }
55177
55907
  async function replayRecentSignals(input) {
55178
55908
  if (input.limit <= 0) return;
@@ -55295,8 +56025,8 @@ function shouldIgnoreIncomingSignal(input) {
55295
56025
  function processIgnoredOlderThanLiveFloorSignal(input) {
55296
56026
  if (!isSignalEnvelope(input.event)) return false;
55297
56027
  rememberSeenSignalId(input.seenSignalIds, input.event.id);
55298
- if (!resolveReplyingHintEvent(input.event)) return false;
55299
- input.onReplyingHintEvent(input.event);
56028
+ if (!resolveDispatchActivityEvent(input.event)) return false;
56029
+ input.onDispatchActivityEvent(input.event);
55300
56030
  return true;
55301
56031
  }
55302
56032
  function resolveReplyingSignalDispatchId(event) {
@@ -55624,15 +56354,15 @@ function shouldRefreshSpaceMetaForEvent(event) {
55624
56354
  function ignoreAsyncResult(promise) {
55625
56355
  promise.catch(() => void 0);
55626
56356
  }
55627
- function isReplyingHintPurpose(purpose) {
55628
- return purpose === TRANSIENT_HINT_START_PURPOSE || purpose === TRANSIENT_HINT_END_PURPOSE || purpose === CONVERSATION_CONTINUITY_WARNING_PURPOSE || purpose === AGENT_REPLY_PREVIEW_PURPOSE || purpose === AGENT_REPLY_PREVIEW_END_PURPOSE;
56357
+ function isDispatchActivityPurpose(purpose) {
56358
+ return purpose === AGENT_REPLYING_PURPOSE || purpose === AGENT_REPLYING_END_PURPOSE || purpose === CONVERSATION_CONTINUITY_WARNING_PURPOSE || purpose === AGENT_REPLY_PREVIEW_PURPOSE || purpose === AGENT_REPLY_PREVIEW_END_PURPOSE || purpose === DISPATCH_ACTIVITY_DISPATCHING_PURPOSE || purpose === DISPATCH_ACTIVITY_RETRYING_PURPOSE || purpose === DISPATCH_ACTIVITY_FAILED_PURPOSE;
55629
56359
  }
55630
- function resolveReplyingHintBase(event) {
56360
+ function resolveDispatchActivityBase(event) {
55631
56361
  if (event.type !== "signal.text") return null;
55632
56362
  const meta = resolveSignalTextMetaFromEnvelope(event);
55633
56363
  if (!meta || meta.transient !== true) return null;
55634
56364
  const purpose = String(meta.purpose ?? "").trim();
55635
- if (!isReplyingHintPurpose(purpose)) return null;
56365
+ if (!isDispatchActivityPurpose(purpose)) return null;
55636
56366
  const dispatchId = String(meta.dispatchId ?? "").trim();
55637
56367
  if (!dispatchId) return null;
55638
56368
  const targetProfileId = String(meta.targetProfileId ?? "").trim();
@@ -55641,45 +56371,85 @@ function resolveReplyingHintBase(event) {
55641
56371
  meta,
55642
56372
  purpose,
55643
56373
  dispatchId,
55644
- targetProfileId
56374
+ sourceClientMessageId: normalizeOptionalMetaText(meta.sourceClientMessageId),
56375
+ sourceEventId: normalizeOptionalMetaText(meta.sourceEventId),
56376
+ targetProfileId,
56377
+ targetWakeToken: normalizeOptionalMetaText(meta.targetWakeToken)
55645
56378
  };
55646
56379
  }
55647
- function resolveReplyingHintTargetLabel(input) {
55648
- return (input.purpose === TRANSIENT_HINT_START_PURPOSE ? extractReplyingTargetLabelFromText(String(input.event.data?.text ?? "")) : null) ?? normalizeOptionalMetaText(input.meta.targetProfileName) ?? normalizeOptionalMetaText(input.event.profile?.profileName) ?? input.targetProfileId;
56380
+ function resolveDispatchActivityTargetLabel(input) {
56381
+ return resolveMentionTokenLabel(normalizeOptionalMetaText(input.meta.targetWakeToken)) ?? (input.purpose === AGENT_REPLYING_PURPOSE ? extractReplyingTargetLabelFromText(String(input.event.data?.text ?? "")) : null) ?? normalizeOptionalMetaText(input.meta.targetProfileName) ?? normalizeOptionalMetaText(input.event.profile?.profileName) ?? input.targetProfileId;
55649
56382
  }
55650
56383
  function resolveContinuityWarningText(event) {
55651
56384
  return sanitizeTerminalDisplayText(String(event.data?.text ?? ""), "single-line").trim() || null;
55652
56385
  }
55653
- function resolveReplyingHintEvent(event) {
55654
- const base = resolveReplyingHintBase(event);
56386
+ function resolveDispatchActivityEvent(event) {
56387
+ const base = resolveDispatchActivityBase(event);
55655
56388
  if (!base) return null;
55656
- const { dispatchId, meta, purpose, targetProfileId } = base;
55657
- if (purpose === TRANSIENT_HINT_END_PURPOSE) return {
56389
+ const { dispatchId, meta, purpose, sourceClientMessageId, sourceEventId, targetProfileId, targetWakeToken } = base;
56390
+ if (purpose === AGENT_REPLYING_END_PURPOSE) return {
55658
56391
  kind: "end",
55659
56392
  dispatchId,
55660
- targetProfileId
56393
+ sourceClientMessageId,
56394
+ sourceEventId,
56395
+ targetProfileId,
56396
+ targetWakeToken
55661
56397
  };
55662
- const targetLabel = resolveReplyingHintTargetLabel({
56398
+ const targetLabel = resolveDispatchActivityTargetLabel({
55663
56399
  event,
55664
56400
  purpose,
55665
56401
  meta,
55666
56402
  targetProfileId
55667
56403
  });
56404
+ if (purpose === DISPATCH_ACTIVITY_DISPATCHING_PURPOSE) {
56405
+ const text = resolveContinuityWarningText(event);
56406
+ if (!text) return null;
56407
+ return {
56408
+ kind: "dispatching",
56409
+ dispatchId,
56410
+ sourceClientMessageId,
56411
+ sourceEventId,
56412
+ targetProfileId,
56413
+ targetLabel,
56414
+ targetWakeToken,
56415
+ text
56416
+ };
56417
+ }
56418
+ if (purpose === DISPATCH_ACTIVITY_RETRYING_PURPOSE) {
56419
+ const text = resolveContinuityWarningText(event);
56420
+ if (!text) return null;
56421
+ return {
56422
+ kind: "retrying",
56423
+ dispatchId,
56424
+ sourceClientMessageId,
56425
+ sourceEventId,
56426
+ targetProfileId,
56427
+ targetLabel,
56428
+ targetWakeToken,
56429
+ text
56430
+ };
56431
+ }
55668
56432
  if (purpose === AGENT_REPLY_PREVIEW_PURPOSE) {
55669
56433
  const previewText = normalizePreviewDisplayText(String(event.data?.text ?? ""));
55670
56434
  if (!previewText) return null;
55671
56435
  return {
55672
56436
  kind: "preview",
55673
56437
  dispatchId,
56438
+ sourceClientMessageId,
56439
+ sourceEventId,
55674
56440
  targetProfileId,
55675
56441
  targetLabel,
56442
+ targetWakeToken,
55676
56443
  previewText
55677
56444
  };
55678
56445
  }
55679
56446
  if (purpose === AGENT_REPLY_PREVIEW_END_PURPOSE) return {
55680
56447
  kind: "preview_end",
55681
56448
  dispatchId,
55682
- targetProfileId
56449
+ sourceClientMessageId,
56450
+ sourceEventId,
56451
+ targetProfileId,
56452
+ targetWakeToken
55683
56453
  };
55684
56454
  if (purpose === CONVERSATION_CONTINUITY_WARNING_PURPOSE) {
55685
56455
  const text = resolveContinuityWarningText(event);
@@ -55687,16 +56457,38 @@ function resolveReplyingHintEvent(event) {
55687
56457
  return {
55688
56458
  kind: "warning",
55689
56459
  dispatchId,
56460
+ sourceClientMessageId,
56461
+ sourceEventId,
55690
56462
  targetProfileId,
55691
56463
  targetLabel,
55692
- text
56464
+ targetWakeToken,
56465
+ text,
56466
+ preserveActivityMode: true
56467
+ };
56468
+ }
56469
+ if (purpose === DISPATCH_ACTIVITY_FAILED_PURPOSE) {
56470
+ const text = resolveContinuityWarningText(event);
56471
+ if (!text) return null;
56472
+ return {
56473
+ kind: "warning",
56474
+ dispatchId,
56475
+ sourceClientMessageId,
56476
+ sourceEventId,
56477
+ targetProfileId,
56478
+ targetLabel,
56479
+ targetWakeToken,
56480
+ text,
56481
+ preserveActivityMode: false
55693
56482
  };
55694
56483
  }
55695
56484
  return {
55696
56485
  kind: "replying_start",
55697
56486
  dispatchId,
56487
+ sourceClientMessageId,
56488
+ sourceEventId,
55698
56489
  targetProfileId,
55699
- targetLabel
56490
+ targetLabel,
56491
+ targetWakeToken
55700
56492
  };
55701
56493
  }
55702
56494
  function resolveNonTransientSignalText(event) {
@@ -55710,6 +56502,9 @@ function resolveSignalTextMetaFromEnvelope(event) {
55710
56502
  if (!meta || typeof meta !== "object" || Array.isArray(meta)) return null;
55711
56503
  return meta;
55712
56504
  }
56505
+ function resolveSignalClientMessageId(event) {
56506
+ return normalizeOptionalMetaText(resolveSignalTextMetaFromEnvelope(event)?.clientMessageId);
56507
+ }
55713
56508
  function normalizePreviewDisplayText(value) {
55714
56509
  return sanitizeTerminalDisplayText(value, "single-line").replace(/\s+/g, " ").trim();
55715
56510
  }
@@ -55747,6 +56542,10 @@ function normalizeOptionalMetaText(value) {
55747
56542
  const normalized = value.trim();
55748
56543
  return normalized.length > 0 ? normalized : null;
55749
56544
  }
56545
+ function resolveMentionTokenLabel(value) {
56546
+ if (!value) return null;
56547
+ return value.startsWith("@") ? value : `@${value}`;
56548
+ }
55750
56549
  function extractReplyingTargetLabelFromText(text) {
55751
56550
  const normalized = sanitizeTerminalDisplayText(text, "single-line").trim();
55752
56551
  return REPLYING_TARGET_LABEL_REGEX.exec(normalized)?.[1] ?? null;
@@ -58338,11 +59137,7 @@ async function resolveSpaceJoinTarget(input) {
58338
59137
  });
58339
59138
  }
58340
59139
  async function prepareSpaceJoinServiceState(input) {
58341
- const autoStopResult = input.interactiveHuman ? await maybeAutoStopIdleBackgroundDaemonService({
58342
- codePrefix: "space.join.service",
58343
- ownerUserId: input.atsProfile.ownerUserId,
58344
- presenter: input.presenter
58345
- }) : null;
59140
+ const localDemand = input.interactiveHuman ? await resolveDaemonLocalServiceDemand({ ownerUserId: input.atsProfile.ownerUserId }).catch(() => null) : null;
58346
59141
  const hasExplicitBaseUrlInput = String(input.input.baseUrl ?? "").trim().length > 0;
58347
59142
  const baseUrl = input.input.resolvedBaseUrl ?? await resolveBaseUrl(input.input.baseUrl);
58348
59143
  await emitSpaceCommandPreflight({
@@ -58353,7 +59148,7 @@ async function prepareSpaceJoinServiceState(input) {
58353
59148
  resolvedView: input.resolvedView
58354
59149
  });
58355
59150
  await maybeOfferDaemonStartBeforeSpaceJoin({
58356
- autoStopLocalDemand: autoStopResult?.localDemand ?? null,
59151
+ localDemand,
58357
59152
  presenter: input.presenter,
58358
59153
  view: input.input.view
58359
59154
  });
@@ -58365,7 +59160,7 @@ async function prepareSpaceJoinServiceState(input) {
58365
59160
  async function maybeOfferDaemonStartBeforeSpaceJoin(input) {
58366
59161
  const runtime = await resolveRuntimeContext({ view: input.view });
58367
59162
  if (runtime.resolvedView !== "human" || !canUseInteractivePrompts(runtime)) return;
58368
- if (input.autoStopLocalDemand?.decision !== "keep_running") return;
59163
+ if (input.localDemand?.decision !== "keep_running") return;
58369
59164
  const daemonStatus = await getDaemonStatus().catch(() => NOT_INSTALLED_DAEMON_STATUS);
58370
59165
  if (!daemonStatus.installed) return;
58371
59166
  const runtimeState = await resolveDaemonRuntimeState(daemonStatus);
@@ -59049,6 +59844,7 @@ async function runSpaceDelete(input) {
59049
59844
  const outcome = await runSpaceDeleteAttempt({
59050
59845
  targets: targets.targets,
59051
59846
  currentProfileId: profile,
59847
+ currentProfileName: atsProfile.profileName,
59052
59848
  allowBackToSelection: targets.allowBackToSelection,
59053
59849
  runtime,
59054
59850
  presenter,
@@ -59067,6 +59863,7 @@ async function runSpaceDeleteAttempt(input) {
59067
59863
  const confirmation = await confirmDeleteTargets({
59068
59864
  targets: input.targets,
59069
59865
  currentProfileId: input.currentProfileId,
59866
+ currentProfileName: input.currentProfileName,
59070
59867
  allowBack: input.allowBackToSelection
59071
59868
  });
59072
59869
  if (confirmation === "cancelled") return "cancelled";
@@ -59138,7 +59935,8 @@ async function confirmDeleteTargets(input) {
59138
59935
  const confirmed = await confirm({
59139
59936
  message: buildDeleteConfirmationMessage({
59140
59937
  targets: input.targets,
59141
- currentProfileId: input.currentProfileId
59938
+ currentProfileId: input.currentProfileId,
59939
+ currentProfileName: input.currentProfileName
59142
59940
  }),
59143
59941
  initialValue: false
59144
59942
  });
@@ -59164,7 +59962,8 @@ async function confirmDeleteTargets(input) {
59164
59962
  const decision = await select({
59165
59963
  message: buildDeleteConfirmationMessage({
59166
59964
  targets: input.targets,
59167
- currentProfileId: input.currentProfileId
59965
+ currentProfileId: input.currentProfileId,
59966
+ currentProfileName: input.currentProfileName
59168
59967
  }),
59169
59968
  options: [
59170
59969
  {
@@ -60683,6 +61482,48 @@ async function resolveOwnedKnownSpacesForDelete(input) {
60683
61482
  }
60684
61483
  return owned;
60685
61484
  }
61485
+ async function resolveExplicitSpaceDeleteTarget(input) {
61486
+ const matchedKnown = await findKnownSpaceForDeleteBySpaceId({
61487
+ atsProfile: input.atsProfile,
61488
+ baseUrl: input.baseUrl,
61489
+ space: input.space
61490
+ });
61491
+ if (matchedKnown) return toSpaceDeleteTarget(matchedKnown);
61492
+ const matchedLocal = (await listSpaceConfigs({ profile: input.atsProfile.atsProfileId })).find((item) => item.space === input.space);
61493
+ if (matchedLocal) return toSpaceDeleteTarget(toKnownSpaceOptionFromLocal(matchedLocal, input.atsProfile));
61494
+ return toSpaceDeleteTarget(await hydrateKnownSpaceForDeleteFromMeta({
61495
+ item: {
61496
+ source: "local",
61497
+ space: input.space,
61498
+ baseUrl: input.baseUrl
61499
+ },
61500
+ profile: input.atsProfile.atsProfileId,
61501
+ profileName: input.atsProfile.profileName,
61502
+ baseUrl: input.baseUrl
61503
+ }));
61504
+ }
61505
+ async function findKnownSpaceForDeleteBySpaceId(input) {
61506
+ const matched = (await resolveKnownSpacesForSelection({
61507
+ atsProfile: input.atsProfile,
61508
+ baseUrl: input.baseUrl,
61509
+ command: "delete"
61510
+ }).catch(() => null))?.items.find((item) => item.space === input.space);
61511
+ if (!matched) return null;
61512
+ const [authorized] = await resolveOwnedKnownSpacesForDelete({
61513
+ known: [matched],
61514
+ profile: input.atsProfile.atsProfileId,
61515
+ profileName: input.atsProfile.profileName,
61516
+ ownerUserId: input.atsProfile.ownerUserId,
61517
+ baseUrl: input.baseUrl
61518
+ });
61519
+ if (authorized) return authorized;
61520
+ return await hydrateKnownSpaceForDeleteFromMeta({
61521
+ item: matched,
61522
+ profile: input.atsProfile.atsProfileId,
61523
+ profileName: input.atsProfile.profileName,
61524
+ baseUrl: input.baseUrl
61525
+ });
61526
+ }
60686
61527
  async function resolveKnownSpacesForPasswordSelection(input) {
60687
61528
  return (await Promise.all(input.known.map((item) => hydrateKnownSpacePasswordProtection({
60688
61529
  item,
@@ -61336,19 +62177,14 @@ async function resolveSpaceDeleteTargets(input) {
61336
62177
  space: explicitSpace,
61337
62178
  resolvedView: input.resolvedView
61338
62179
  });
61339
- const matched = (await listSpaceConfigs({ profile: input.atsProfile.atsProfileId })).find((item) => item.space === explicitSpace);
61340
62180
  return {
61341
62181
  status: "submitted",
61342
62182
  allowBackToSelection: false,
61343
- targets: [{
61344
- space: explicitSpace,
61345
- ...matched?.baseUrl ? { baseUrl: matched.baseUrl } : {},
61346
- ...matched?.name ? { name: matched.name } : {},
61347
- ...matched?.creator?.profileName ? { creatorProfileName: matched.creator.profileName } : {},
61348
- ...resolveLocalCreatorProfileId(matched?.creator) ? { creatorProfileId: resolveLocalCreatorProfileId(matched?.creator) } : {},
61349
- ...resolveLocalCreatorOwnerUserId(matched?.creator) ? { creatorOwnerUserId: resolveLocalCreatorOwnerUserId(matched?.creator) } : {},
61350
- ...typeof matched?.creator?.kind === "string" ? { creatorKind: matched.creator.kind } : {}
61351
- }]
62183
+ targets: [await resolveExplicitSpaceDeleteTarget({
62184
+ atsProfile: input.atsProfile,
62185
+ baseUrl: input.baseUrl,
62186
+ space: explicitSpace
62187
+ })]
61352
62188
  };
61353
62189
  }
61354
62190
  if (!input.allowPrompt) {
@@ -61831,7 +62667,7 @@ function buildKnownSpaceProfileMap(profiles) {
61831
62667
  return byId;
61832
62668
  }
61833
62669
  function resolveKnownSpaceVisibilityScope(input) {
61834
- if (input.atsProfile.profileKind === "human" && input.atsProfile.isDefault === true && (input.command === "join" || input.command === "watch" || input.command === "guidelines")) return "owner";
62670
+ if (input.atsProfile.profileKind === "human" && input.atsProfile.isDefault === true && (input.command === "join" || input.command === "watch" || input.command === "guidelines" || input.command === "delete")) return "owner";
61835
62671
  return "profile";
61836
62672
  }
61837
62673
  async function resolveKnownSpacesForSelectionByProfile(input) {
@@ -62857,17 +63693,14 @@ function buildHumanKnownSpaceSearchItems(input) {
62857
63693
  }];
62858
63694
  }
62859
63695
  function buildHumanKnownSpaceDetailLine(input) {
62860
- const idLabel = `ID ${shortenSpaceId(input.space.space)}`;
62861
- const creatorLabel = resolveHumanKnownSpaceCreatorDisplay({
62862
- space: input.space,
62863
- currentProfileId: input.currentProfileId,
62864
- currentProfileName: input.currentProfileName
62865
- });
62866
- const viaLabel = resolveHumanKnownSpaceAvailableViaDisplay({
63696
+ const projection = buildKnownSpaceDisplayProjection({
62867
63697
  space: input.space,
62868
63698
  currentProfileId: input.currentProfileId,
62869
63699
  currentProfileName: input.currentProfileName
62870
63700
  });
63701
+ const idLabel = `ID ${shortenSpaceId(formatSpaceDisplayValue(projection.spaceId))}`;
63702
+ const creatorLabel = projection.creatorDisplayName;
63703
+ const viaLabel = projection.availableViaDisplayName;
62871
63704
  const parts = [idLabel];
62872
63705
  if (creatorLabel) parts.push(`Created by ${creatorLabel}`);
62873
63706
  if (viaLabel && viaLabel !== creatorLabel) parts.push(`via ${viaLabel}`);
@@ -62876,45 +63709,22 @@ function buildHumanKnownSpaceDetailLine(input) {
62876
63709
  return parts.join(" · ");
62877
63710
  }
62878
63711
  function buildHumanKnownSpaceSearchText(input) {
62879
- return [
62880
- sanitizeSingleLinePromptText(input.space.space),
62881
- sanitizeSingleLinePromptText(normalizeOptionalString$2(input.space.name)),
62882
- sanitizeSingleLinePromptText(normalizeOptionalString$2(input.space.creatorProfileName)),
62883
- sanitizeSingleLinePromptText(normalizeOptionalString$2(input.space.creatorProfileId)),
62884
- sanitizeSingleLinePromptText(normalizeOptionalString$2(input.space.creatorOwnerUserId)),
62885
- sanitizeSingleLinePromptText(normalizeOptionalString$2(input.space.availableViaProfileName)),
62886
- sanitizeSingleLinePromptText(normalizeOptionalString$2(input.space.availableViaProfileId)),
62887
- resolveHumanKnownSpaceCreatorDisplay({
62888
- space: input.space,
62889
- currentProfileId: input.currentProfileId,
62890
- currentProfileName: input.currentProfileName
62891
- }),
62892
- resolveHumanKnownSpaceAvailableViaDisplay({
62893
- space: input.space,
62894
- currentProfileId: input.currentProfileId,
62895
- currentProfileName: input.currentProfileName
62896
- })
62897
- ].filter((value) => typeof value === "string").join("\n");
62898
- }
62899
- function resolveHumanKnownSpaceCreatorDisplay(input) {
62900
- const creator = formatCreatorNameForDisplay({
62901
- creatorProfileName: input.space.creatorProfileName,
62902
- creatorProfileId: input.space.creatorProfileId,
62903
- currentProfileId: input.currentProfileId,
62904
- currentProfileName: input.currentProfileName
62905
- });
62906
- if (creator !== "unknown-profile") return sanitizeSingleLinePromptText(creator);
62907
- return sanitizeSingleLinePromptText(normalizeOptionalString$2(input.space.creatorOwnerUserId));
62908
- }
62909
- function resolveHumanKnownSpaceAvailableViaDisplay(input) {
62910
- const via = formatCreatorNameForDisplay({
62911
- creatorProfileName: input.space.availableViaProfileName,
62912
- creatorProfileId: input.space.availableViaProfileId,
63712
+ const projection = buildKnownSpaceDisplayProjection({
63713
+ space: input.space,
62913
63714
  currentProfileId: input.currentProfileId,
62914
63715
  currentProfileName: input.currentProfileName
62915
63716
  });
62916
- if (via === "unknown-profile") return null;
62917
- return sanitizeSingleLinePromptText(via);
63717
+ return [
63718
+ formatSpaceDisplayValue(projection.spaceId, ""),
63719
+ formatSpaceDisplayValue(projection.spaceName, ""),
63720
+ formatSpaceDisplayValue(projection.creatorProfileName, ""),
63721
+ formatSpaceDisplayValue(projection.creatorProfileId, ""),
63722
+ sanitizeSingleLinePromptText(normalizeOptionalString$2(input.space.creatorOwnerUserId)),
63723
+ formatSpaceDisplayValue(projection.availableViaProfileName, ""),
63724
+ formatSpaceDisplayValue(projection.availableViaProfileId, ""),
63725
+ formatSpaceDisplayValue(projection.creatorDisplayName, ""),
63726
+ formatSpaceDisplayValue(projection.availableViaDisplayName, "")
63727
+ ].filter((value) => typeof value === "string").join("\n");
62918
63728
  }
62919
63729
  function resolveKnownSpaceJoinedTimestamp(space) {
62920
63730
  return normalizeOptionalString$2(space.lastJoinedAt) ?? resolveKnownSpaceLastSeenTimestamp(space.lastSeenTs);
@@ -62964,7 +63774,7 @@ async function promptSpaceDeleteSelection(input) {
62964
63774
  if (input.known.length === 0) {
62965
63775
  if (input.resolvedView === "human") {
62966
63776
  const manual = await promptHumanManualSpaceId({
62967
- message: "No spaces created by your user were found. Enter a space ID manually",
63777
+ message: "No spaces you can delete were found. Enter a space ID manually",
62968
63778
  description: "Paste a 64-character hex space ID to delete it.",
62969
63779
  allowBack: input.allowBack === true
62970
63780
  });
@@ -62975,7 +63785,7 @@ async function promptSpaceDeleteSelection(input) {
62975
63785
  targets: [{ space: manual.value }]
62976
63786
  };
62977
63787
  }
62978
- const manual = await promptManualSpace("No spaces created by your user were found. Enter a space ID (64-character hex):", input.resolvedView);
63788
+ const manual = await promptManualSpace("No spaces you can delete were found. Enter a space ID (64-character hex):", input.resolvedView);
62979
63789
  return manual ? {
62980
63790
  status: "submitted",
62981
63791
  allowBackToSelection: true,
@@ -63141,6 +63951,18 @@ function toSpaceDeleteTarget(space) {
63141
63951
  ...space.creatorKind === void 0 ? {} : { creatorKind: space.creatorKind }
63142
63952
  };
63143
63953
  }
63954
+ function toKnownSpaceOptionFromDeleteTarget(target) {
63955
+ return {
63956
+ source: "local",
63957
+ space: target.space,
63958
+ ...target.baseUrl ? { baseUrl: target.baseUrl } : {},
63959
+ ...target.name === void 0 ? {} : { name: target.name },
63960
+ ...target.creatorProfileName === void 0 ? {} : { creatorProfileName: target.creatorProfileName },
63961
+ ...target.creatorProfileId === void 0 ? {} : { creatorProfileId: target.creatorProfileId },
63962
+ ...target.creatorOwnerUserId === void 0 ? {} : { creatorOwnerUserId: target.creatorOwnerUserId },
63963
+ ...target.creatorKind === void 0 ? {} : { creatorKind: target.creatorKind }
63964
+ };
63965
+ }
63144
63966
  function normalizeSpaceDeleteSelection(value) {
63145
63967
  if (!Array.isArray(value)) return [];
63146
63968
  const selected = [];
@@ -63196,7 +64018,10 @@ function normalizeKnownSpaceVisibilityScope(visibilityScope) {
63196
64018
  return visibilityScope === "owner" ? "owner" : "profile";
63197
64019
  }
63198
64020
  function formatKnownSpaceName(input) {
63199
- const name = sanitizeSingleLinePromptText(input.space.name) || "untitled-space";
64021
+ const name = resolveSpaceDisplayName(buildKnownSpaceDisplayProjection({
64022
+ space: input.space,
64023
+ currentProfileId: input.currentProfileId
64024
+ }).spaceName, "untitled-space");
63200
64025
  if (input.command === "password") return input.space.passwordProtected === true ? `🔒 ${name}` : name;
63201
64026
  return input.resolvedView === "human" && input.space.passwordProtected === true ? `🔒 - ${name}` : name;
63202
64027
  }
@@ -63253,35 +64078,19 @@ function buildKnownSpaceData(item, index) {
63253
64078
  };
63254
64079
  }
63255
64080
  function formatKnownSpaceDetailLines(input) {
63256
- const creatorProfileName = formatCreatorNameForDisplay({
63257
- creatorProfileName: input.space.creatorProfileName,
63258
- creatorProfileId: input.space.creatorProfileId,
63259
- currentProfileId: input.currentProfileId,
63260
- currentProfileName: input.currentProfileName
63261
- });
63262
- const availableViaProfileName = formatCreatorNameForDisplay({
63263
- creatorProfileName: input.space.availableViaProfileName,
63264
- creatorProfileId: input.space.availableViaProfileId,
64081
+ const projection = buildKnownSpaceDisplayProjection({
64082
+ space: input.space,
63265
64083
  currentProfileId: input.currentProfileId,
63266
64084
  currentProfileName: input.currentProfileName
63267
64085
  });
63268
- const creatorId = resolveCreatorIdForDisplay({
63269
- creatorOwnerUserId: input.space.creatorOwnerUserId,
63270
- creatorProfileId: input.space.creatorProfileId
63271
- });
63272
- const creatorProfileId = normalizeDisplayValue(input.space.creatorProfileId, "unknown-profile");
63273
- const createdAt = normalizeDisplayValue(input.space.spaceCreatedAt);
63274
- const lastJoined = normalizeDisplayValue(resolveKnownSpaceJoinedTimestamp(input.space));
63275
- const lines = [
63276
- `Space ID: ${normalizeDisplayValue(input.space.space)}`,
63277
- `Creator: ${creatorProfileName}`,
63278
- `Creator ID: ${creatorId}`,
63279
- `Creator Profile ID: ${creatorProfileId}`,
63280
- `Available via: ${normalizeDisplayValue(availableViaProfileName)}`,
63281
- `Available via Profile ID: ${normalizeDisplayValue(input.space.availableViaProfileId)}`,
63282
- `Created: ${createdAt}`,
63283
- `Last joined: ${lastJoined}`
63284
- ];
64086
+ const detailVariant = input.detailVariant ?? "full";
64087
+ const lines = buildSpaceMetadataFields({
64088
+ projection,
64089
+ includeAvailableVia: detailVariant !== "delete_confirmation",
64090
+ includeCreatedAt: detailVariant !== "delete_confirmation",
64091
+ includeLastJoinedAt: detailVariant !== "delete_confirmation"
64092
+ }).map((field) => `${field.label}: ${field.value}`);
64093
+ if (detailVariant === "delete_confirmation") return lines;
63285
64094
  if (input.resolvedView === "human") {
63286
64095
  if (input.space.source === "local") lines.push("Source: local cache");
63287
64096
  return lines;
@@ -63364,40 +64173,44 @@ function resolveGatewayHost(baseUrl) {
63364
64173
  return null;
63365
64174
  }
63366
64175
  }
63367
- function formatCreatorNameForDisplay(input) {
63368
- const creatorProfileName = sanitizeSingleLinePromptText(normalizeOptionalString$2(input.creatorProfileName));
63369
- if (creatorProfileName) return creatorProfileName;
63370
- const creatorProfileId = sanitizeSingleLinePromptText(normalizeOptionalString$2(input.creatorProfileId));
63371
- if (creatorProfileId === sanitizeSingleLinePromptText(normalizeOptionalString$2(input.currentProfileId)) && sanitizeSingleLinePromptText(normalizeOptionalString$2(input.currentProfileName))) return sanitizeSingleLinePromptText(normalizeOptionalString$2(input.currentProfileName)) || "unknown-profile";
63372
- return normalizeDisplayValue(creatorProfileId, "unknown-profile");
63373
- }
63374
- function resolveCreatorIdForDisplay(input) {
63375
- return sanitizeSingleLinePromptText(normalizeOptionalString$2(input.creatorOwnerUserId)) || sanitizeSingleLinePromptText(normalizeOptionalString$2(input.creatorProfileId)) || "unknown-owner";
63376
- }
63377
64176
  function normalizeDisplayValue(value, fallback = "unknown") {
63378
64177
  const normalized = sanitizeSingleLinePromptText(String(value ?? ""));
63379
64178
  return normalized.length > 0 ? normalized : fallback;
63380
64179
  }
64180
+ function buildKnownSpaceDisplayProjection(input) {
64181
+ return buildSpaceDisplayProjection({
64182
+ currentProfileId: input.currentProfileId,
64183
+ currentProfileName: input.currentProfileName,
64184
+ spaceId: input.space.space,
64185
+ spaceName: input.space.name,
64186
+ creatorProfileId: input.space.creatorProfileId,
64187
+ creatorProfileName: input.space.creatorProfileName,
64188
+ availableViaProfileId: input.space.availableViaProfileId,
64189
+ availableViaProfileName: input.space.availableViaProfileName,
64190
+ spaceCreatedAt: input.space.spaceCreatedAt,
64191
+ lastJoinedAt: resolveKnownSpaceJoinedTimestamp(input.space),
64192
+ passwordProtected: input.space.passwordProtected
64193
+ });
64194
+ }
63381
64195
  function buildDeleteConfirmationMessage(input) {
63382
64196
  const count = input.targets.length;
63383
64197
  const lines = [count === 1 ? "Delete this space permanently?" : `Delete ${String(count)} spaces permanently?`, "This action permanently deletes space data for everyone."];
63384
64198
  for (const [index, target] of input.targets.entries()) {
63385
- const spaceName = normalizeDisplayValue(target.name, "untitled-space");
63386
- const creator = formatCreatorNameForDisplay({
63387
- creatorProfileName: target.creatorProfileName,
63388
- creatorProfileId: target.creatorProfileId,
63389
- currentProfileId: input.currentProfileId
63390
- });
63391
- const creatorId = resolveCreatorIdForDisplay({
63392
- creatorOwnerUserId: target.creatorOwnerUserId,
63393
- creatorProfileId: target.creatorProfileId
63394
- });
63395
- const creatorProfileId = normalizeDisplayValue(target.creatorProfileId, "unknown-profile");
63396
- lines.push(`${String(index + 1)}. ${spaceName}`);
63397
- lines.push(` Space ID: ${target.space}`);
63398
- lines.push(` Creator: ${creator}`);
63399
- lines.push(` Creator ID: ${creatorId}`);
63400
- lines.push(` Creator Profile ID: ${creatorProfileId}`);
64199
+ const knownSpace = toKnownSpaceOptionFromDeleteTarget(target);
64200
+ lines.push(`${String(index + 1)}. ${formatKnownSpaceName({
64201
+ space: knownSpace,
64202
+ resolvedView: "human",
64203
+ currentProfileId: input.currentProfileId,
64204
+ command: "delete"
64205
+ })}`);
64206
+ lines.push(...formatKnownSpaceDetailLines({
64207
+ space: knownSpace,
64208
+ resolvedView: "human",
64209
+ currentProfileId: input.currentProfileId,
64210
+ currentProfileName: input.currentProfileName,
64211
+ detailVariant: "delete_confirmation",
64212
+ command: "delete"
64213
+ }).map((line) => ` ${line}`));
63401
64214
  }
63402
64215
  return lines.join("\n");
63403
64216
  }
@@ -63408,7 +64221,7 @@ function buildHumanSpaceDeleteBlockedError(input) {
63408
64221
  if (resolveUpstreamStatus(parsed) !== 403) return null;
63409
64222
  if (!isSpaceDeleteOwnerRestrictionError(parsed)) return null;
63410
64223
  const spaceName = normalizeDisplayValue(input.target.name, "this space");
63411
- return /* @__PURE__ */ new Error(`Delete blocked: you can only delete spaces you created (${spaceName}).`);
64224
+ return /* @__PURE__ */ new Error(`Delete blocked: this human profile can only delete its own spaces or your owned agent-created spaces (${spaceName}).`);
63412
64225
  }
63413
64226
  function isSpaceDeleteOwnerRestrictionError(input) {
63414
64227
  const code = input.code.toLowerCase();
@@ -63432,11 +64245,11 @@ function renderHumanSpaceDeleteBlockedCard(input) {
63432
64245
  },
63433
64246
  {
63434
64247
  label: "Reason",
63435
- value: "You can only delete spaces created by your user."
64248
+ value: "This human profile can only delete its own spaces or your owned agent-created spaces."
63436
64249
  },
63437
64250
  {
63438
64251
  label: "Try",
63439
- value: "Select a space created by your user, then retry."
64252
+ value: "Switch to the human creator profile, or choose an agent-created space your user owns."
63440
64253
  }
63441
64254
  ],
63442
64255
  sanitize: true,
@@ -64154,13 +64967,9 @@ async function runStartServiceStep(input) {
64154
64967
  return "continue";
64155
64968
  }
64156
64969
  async function runInstalledCurrentStartServiceStep(input) {
64157
- const localDemandResult = input.runtime.resolvedView === "human" && input.interactive ? await maybeAutoStopIdleBackgroundDaemonService({
64158
- codePrefix: "start.service",
64159
- ownerUserId: input.ownerUserId,
64160
- presenter: input.presenter
64161
- }) : null;
64970
+ const localDemand = input.runtime.resolvedView === "human" && input.interactive ? await resolveDaemonLocalServiceDemand({ ownerUserId: input.ownerUserId }).catch(() => null) : null;
64162
64971
  if (input.readiness.service.runtime?.status === "running") return "continue";
64163
- if (localDemandResult && localDemandResult.localDemand.decision !== "keep_running") return "continue";
64972
+ if (localDemand && localDemand.decision !== "keep_running") return "continue";
64164
64973
  if (!input.interactive) {
64165
64974
  input.presenter.line({
64166
64975
  code: "start.service.non_interactive",
@@ -67148,9 +67957,9 @@ withSpaceProfileOption(spaceCmd.command("delete").description("Delete one or mor
67148
67957
  }
67149
67958
  });
67150
67959
  });
67151
- withSpaceProfileOption(spaceCmd.command("join").description("Join a space and chat interactively.").argument("[space]", "Space ID (64-character hex)").option("--local-echo", "Show local optimistic echo before server events (disabled by default)", false).option("--no-local-echo", "Clean mode: only render server events (default)", false).option("--history-limit <n>", "Recent history preload size on join (default: 100; 0 disables preload)", "100").option("--role <text>", "Role in this space").option("--role-instructions <text>", "Role instructions for this space").option("--mention-alias <token>", "Space-level mention alias (used by @alias in this space)").option("--password <value>", "Space password for protected access").option("--output <mode>", "Output mode: ndjson|text (default: text)", "text").option("--raw-stream", AGENT_RAW_STREAM_OPTION_DESCRIPTION, false)).action(async (space, opts, command) => {
67960
+ withSpaceProfileOption(spaceCmd.command("join").description("Join a space and chat interactively.").argument("[space]", "Space ID (64-character hex)").option("--local-echo", "Show local optimistic echo before server events (enabled by default in human interactive join)").option("--no-local-echo", "Clean mode: only render server events").option("--history-limit <n>", "Recent history preload size on join (default: 100; 0 disables preload)", "100").option("--role <text>", "Role in this space").option("--role-instructions <text>", "Role instructions for this space").option("--mention-alias <token>", "Space-level mention alias (used by @alias in this space)").option("--password <value>", "Space password for protected access").option("--output <mode>", "Output mode: ndjson|text (default: text)", "text").option("--raw-stream", AGENT_RAW_STREAM_OPTION_DESCRIPTION, false)).action(async (space, opts, command) => {
67152
67961
  const cliOptions = resolveSpaceCommandCliOptions(command, opts);
67153
- const localEcho = opts.noLocalEcho === true ? false : opts.localEcho === true;
67962
+ const localEcho = opts.noLocalEcho !== true;
67154
67963
  const view = getGlobalViewOption();
67155
67964
  if (view === "agent" && normalizeOptionalString(space) === null) {
67156
67965
  await runSpaceJoin({