agent-transport-system 0.2.6 → 0.2.8

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 +1697 -806
  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.8";
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
  }
@@ -2934,6 +2934,9 @@ async function getDaemonRuntimeStatus(pathInput = {}) {
2934
2934
  autoStart: state.autoStart
2935
2935
  };
2936
2936
  }
2937
+ async function readDaemonServiceRuntimeSnapshot(pathInput = {}) {
2938
+ return await readDaemonServiceRuntimeState(pathInput);
2939
+ }
2937
2940
  function resolveDaemonServiceRuntimeMetadata(input = {}) {
2938
2941
  const env = input.env ?? process.env;
2939
2942
  const managedBySystemService = input.managedBySystemService === true || env[DAEMON_SERVICE_RUNTIME_SYSTEM_SERVICE_ENV] === "1";
@@ -3415,7 +3418,7 @@ async function storeAccessToken(input) {
3415
3418
  key
3416
3419
  };
3417
3420
  }
3418
- throw new Error(`failed to store access token in macOS Keychain: ${toErrorMessage$16(error)}`);
3421
+ throw new Error(`failed to store access token in macOS Keychain: ${toErrorMessage$17(error)}`);
3419
3422
  }
3420
3423
  if (process.platform === "win32") try {
3421
3424
  await setWindowsDpapiToken({
@@ -3437,7 +3440,7 @@ async function storeAccessToken(input) {
3437
3440
  key
3438
3441
  };
3439
3442
  }
3440
- throw new Error(`failed to store access token via Windows DPAPI: ${toErrorMessage$16(error)}`);
3443
+ throw new Error(`failed to store access token via Windows DPAPI: ${toErrorMessage$17(error)}`);
3441
3444
  }
3442
3445
  if (allowInsecureFallback()) {
3443
3446
  await setInsecureFileToken({
@@ -3678,7 +3681,7 @@ function normalizeToken(value) {
3678
3681
  const normalized = value.trim();
3679
3682
  return normalized.length > 0 ? normalized : null;
3680
3683
  }
3681
- function toErrorMessage$16(error) {
3684
+ function toErrorMessage$17(error) {
3682
3685
  if (error instanceof Error) return error.message;
3683
3686
  return String(error);
3684
3687
  }
@@ -8470,7 +8473,7 @@ var ZodFirstPartyTypeKind;
8470
8473
  (function(ZodFirstPartyTypeKind) {})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
8471
8474
 
8472
8475
  //#endregion
8473
- //#region ../../packages/schemas/dist/envelope-IeNocT0x.js
8476
+ //#region ../../packages/schemas/dist/envelope-BjKosHeX.js
8474
8477
  const providerConversationExternalImportCapabilitySchema = _enum(["unsupported", "by_ref_id"]);
8475
8478
  const providerConversationResumeCapabilitySchema = _enum(["unsupported", "by_ref_id"]);
8476
8479
  const providerConversationDiscoverCapabilitySchema = literal("unsupported");
@@ -9142,6 +9145,97 @@ const spacePasswordSchema = string().min(SPACE_PASSWORD_MIN_LENGTH);
9142
9145
  const createSpacePasswordBodySchema = strictObject({ password: spacePasswordSchema.optional() });
9143
9146
  const upsertSpacePasswordBodySchema = strictObject({ password: spacePasswordSchema });
9144
9147
  const spacePasswordStateSchema = strictObject({ passwordProtected: boolean() });
9148
+ const MAX_SIGNAL_REPLY_TO_PREVIEW_LENGTH = 120;
9149
+ const SPACE_MEMBER_JOIN_NOTICE_PURPOSE = "space_membership_join_notice";
9150
+ const SPACE_MEMBER_REMOVE_NOTICE_PURPOSE = "space_membership_remove_notice";
9151
+ const SPACE_MENTION_REJECT_NOTICE_PURPOSE = "space_mention_reject_notice";
9152
+ const AGENT_REPLYING_PURPOSE = "agent_replying";
9153
+ const AGENT_REPLYING_END_PURPOSE = "agent_replying_end";
9154
+ const AGENT_REPLY_PREVIEW_PURPOSE = "agent_reply_preview";
9155
+ const AGENT_REPLY_PREVIEW_END_PURPOSE = "agent_reply_preview_end";
9156
+ const DISPATCH_ACTIVITY_DISPATCHING_PURPOSE = "dispatch_activity_dispatching";
9157
+ const DISPATCH_ACTIVITY_RETRYING_PURPOSE = "dispatch_activity_retrying";
9158
+ const DISPATCH_ACTIVITY_FAILED_PURPOSE = "dispatch_activity_failed";
9159
+ const CONVERSATION_CONTINUITY_WARNING_PURPOSE = "conversation_continuity_warning";
9160
+ const MENTION_TOKEN_PATTERN$3 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
9161
+ const normalizeMentionToken$1 = (value) => {
9162
+ const normalized = trimmedStringFromUnknown(value);
9163
+ if (!normalized) return;
9164
+ return MENTION_TOKEN_PATTERN$3.test(normalized) ? normalized : void 0;
9165
+ };
9166
+ const signalTextReplyToSchema = object({
9167
+ signalId: preprocess(trimmedStringFromUnknown, string().min(1)),
9168
+ profileId: atsRuntimeProfileIdSchema,
9169
+ profileKind: _enum([
9170
+ "human",
9171
+ "agent",
9172
+ "system"
9173
+ ]).nullable(),
9174
+ profileName: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_PROFILE_NAME_LENGTH)),
9175
+ previewText: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_SIGNAL_REPLY_TO_PREVIEW_LENGTH))
9176
+ });
9177
+ const signalTextMetaSchema = object({
9178
+ transient: literal(true).optional(),
9179
+ clientMessageId: preprocess(trimmedStringFromUnknown, string().max(200)).optional(),
9180
+ sourceEventId: preprocess(trimmedStringFromUnknown, string().max(200)).optional(),
9181
+ purpose: preprocess(trimmedStringFromUnknown, string().min(1).max(80)).optional(),
9182
+ dispatchId: preprocess(trimmedStringFromUnknown, string().max(200)).optional(),
9183
+ targetProfileId: atsRuntimeProfileIdSchema.optional(),
9184
+ targetProfileKind: _enum(["human", "agent"]).optional(),
9185
+ targetProfileName: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_PROFILE_NAME_LENGTH)).optional(),
9186
+ targetProfileHandle: preprocess(normalizeMentionToken$1, string().regex(MENTION_TOKEN_PATTERN$3).max(128)).optional(),
9187
+ targetWakeToken: preprocess(normalizeMentionToken$1, string().regex(MENTION_TOKEN_PATTERN$3).max(128)).optional(),
9188
+ addedByProfileId: atsRuntimeProfileIdSchema.optional(),
9189
+ addedByDisplayName: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_PROFILE_NAME_LENGTH)).optional(),
9190
+ removedByProfileId: atsRuntimeProfileIdSchema.optional(),
9191
+ removedByDisplayName: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_PROFILE_NAME_LENGTH)).optional()
9192
+ });
9193
+ const postedSignalTextMetaSchema = signalTextMetaSchema.superRefine((meta, context) => {
9194
+ if (meta.purpose !== SPACE_MEMBER_JOIN_NOTICE_PURPOSE && meta.purpose !== SPACE_MEMBER_REMOVE_NOTICE_PURPOSE) return;
9195
+ if (!meta.targetProfileId) context.addIssue({
9196
+ code: "custom",
9197
+ message: "targetProfileId is required for space member notices",
9198
+ path: ["targetProfileId"]
9199
+ });
9200
+ if (!meta.targetProfileKind) context.addIssue({
9201
+ code: "custom",
9202
+ message: "targetProfileKind is required for space member notices",
9203
+ path: ["targetProfileKind"]
9204
+ });
9205
+ if (meta.purpose === SPACE_MEMBER_JOIN_NOTICE_PURPOSE && !meta.addedByProfileId) context.addIssue({
9206
+ code: "custom",
9207
+ message: "addedByProfileId is required for space member notices",
9208
+ path: ["addedByProfileId"]
9209
+ });
9210
+ if (meta.purpose === SPACE_MEMBER_JOIN_NOTICE_PURPOSE && !meta.addedByDisplayName) context.addIssue({
9211
+ code: "custom",
9212
+ message: "addedByDisplayName is required for space member notices",
9213
+ path: ["addedByDisplayName"]
9214
+ });
9215
+ if (meta.purpose === SPACE_MEMBER_REMOVE_NOTICE_PURPOSE && !meta.removedByProfileId) context.addIssue({
9216
+ code: "custom",
9217
+ message: "removedByProfileId is required for space member notices",
9218
+ path: ["removedByProfileId"]
9219
+ });
9220
+ if (meta.purpose === SPACE_MEMBER_REMOVE_NOTICE_PURPOSE && !meta.removedByDisplayName) context.addIssue({
9221
+ code: "custom",
9222
+ message: "removedByDisplayName is required for space member notices",
9223
+ path: ["removedByDisplayName"]
9224
+ });
9225
+ });
9226
+ const signalTextDataSchema = object({
9227
+ text: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_TEXT_LENGTH$1)),
9228
+ replyTo: signalTextReplyToSchema.optional(),
9229
+ meta: signalTextMetaSchema.optional()
9230
+ });
9231
+ const signalTextSchema = object({
9232
+ type: literal("signal.text"),
9233
+ data: object({
9234
+ text: preprocess(trimmedStringFromUnknown, string().min(1).max(MAX_TEXT_LENGTH$1)),
9235
+ replyTo: signalTextReplyToSchema.optional(),
9236
+ meta: postedSignalTextMetaSchema.optional()
9237
+ })
9238
+ });
9145
9239
  const ATSD_MENTION_DISPATCH_RESULT_SCHEMA_VERSION = 2;
9146
9240
  const atsdMentionDispatchStatusSchema = _enum([
9147
9241
  "dispatch_ready",
@@ -9214,6 +9308,7 @@ const atsdDispatchSourceSignalSnapshotSchema = strictObject({
9214
9308
  ]).nullable(),
9215
9309
  profileWakeToken: string().regex(MENTION_TOKEN_PATTERN$2).max(128).optional()
9216
9310
  });
9311
+ const atsdDispatchReplyToSnapshotSchema = signalTextReplyToSchema;
9217
9312
  const atsdDispatchQueueLegacyMessageSchemaV1 = strictObject({
9218
9313
  v: literal(1),
9219
9314
  dispatchId: string().min(1),
@@ -9228,6 +9323,7 @@ const atsdDispatchQueueMessageSchema = strictObject({
9228
9323
  dispatchId: string().min(1),
9229
9324
  spaceId: string().min(1),
9230
9325
  sourceEventId: string().min(1),
9326
+ sourceClientMessageId: string().min(1).max(200).nullable().optional(),
9231
9327
  targetProfileId: string().min(1),
9232
9328
  targetProfileWakeToken: string().regex(MENTION_TOKEN_PATTERN$2).max(128).optional(),
9233
9329
  dispatchChainId: string().min(1),
@@ -9247,6 +9343,7 @@ const atsdDispatchQueueMessageSchema = strictObject({
9247
9343
  dispatchRulesSnapshot: atsdDispatchRulesSnapshotSchema,
9248
9344
  dispatchSnapshot: atsdDispatchSnapshotSchema,
9249
9345
  sourceSignalSnapshot: atsdDispatchSourceSignalSnapshotSchema.optional(),
9346
+ replyToSnapshot: atsdDispatchReplyToSnapshotSchema.optional(),
9250
9347
  spaceNameSnapshot: string().min(1).nullable().optional(),
9251
9348
  sourceProfileNameSnapshot: string().min(1).nullable().optional(),
9252
9349
  targetProfileNameSnapshot: string().min(1).nullable().optional(),
@@ -9285,6 +9382,7 @@ const atsdDispatchQueueMessageSchema = strictObject({
9285
9382
  message: "controllerSnapshot target binding fields must match dispatchSnapshot"
9286
9383
  });
9287
9384
  });
9385
+ const atsdDispatchQueueIngressSchema = discriminatedUnion("v", [atsdDispatchQueueLegacyMessageSchemaV1, atsdDispatchQueueMessageSchema]);
9288
9386
  const ATSD_TASK_RESULT_SCHEMA_VERSION = 3;
9289
9387
  const ATSD_TASK_RESULT_SCHEMA_VERSION_PREVIOUS = 2;
9290
9388
  const ATSD_TASK_RESULT_SCHEMA_VERSION_LEGACY = 1;
@@ -9404,6 +9502,7 @@ const atsdTaskResultEnvelopeSchema = union([
9404
9502
  atsdTaskResultEnvelopeSchemaV1
9405
9503
  ]);
9406
9504
  const DAEMON_HUB_SCHEMA_VERSION = 1;
9505
+ const MENTION_TOKEN_PATTERN$1 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
9407
9506
  const daemonHubErrorCodeSchema = _enum([
9408
9507
  "daemon.session.reject_conflict",
9409
9508
  "daemon.session.not_found",
@@ -9468,6 +9567,46 @@ const daemonHubLookupRouteResponseSchema = discriminatedUnion("online", [strictO
9468
9567
  online: literal(false),
9469
9568
  reasonCode: daemonHubErrorCodeSchema
9470
9569
  })]);
9570
+ const daemonHubDispatchSourceSignalSchema = strictObject({
9571
+ profileId: string().min(1).nullable(),
9572
+ profileKind: _enum([
9573
+ "agent",
9574
+ "human",
9575
+ "system"
9576
+ ]).nullable(),
9577
+ profileHandle: string().regex(MENTION_TOKEN_PATTERN$1).max(128).optional(),
9578
+ profileWakeToken: string().regex(MENTION_TOKEN_PATTERN$1).max(128).optional(),
9579
+ text: string().min(1).max(MAX_TEXT_LENGTH$1)
9580
+ });
9581
+ const daemonHubDeliverDispatchPayloadSchema = strictObject({
9582
+ attemptId: string().min(1),
9583
+ dispatchId: string().min(1),
9584
+ taskId: string().min(1),
9585
+ spaceId: string().min(1),
9586
+ sourceEventId: string().min(1),
9587
+ sourceSignal: daemonHubDispatchSourceSignalSchema,
9588
+ targetProfileId: string().min(1),
9589
+ dispatchContractVersion: number().int().positive(),
9590
+ dispatchPolicy: runtimeDispatchPolicySchema,
9591
+ controllerSnapshot: atsdDispatchControllerSnapshotSchema,
9592
+ contextIdMappingSpec: runtimeAgentContextIdMappingSpecSchema.nullable(),
9593
+ dispatchRulesSnapshot: atsdDispatchRulesSnapshotSchema,
9594
+ enqueuedAtMs: number().int().nonnegative(),
9595
+ idempotencyKey: string().min(1),
9596
+ spacePassword: spacePasswordSchema.optional(),
9597
+ targetProfileName: string().min(1).max(MAX_PROFILE_NAME_LENGTH).optional(),
9598
+ targetProfileHandle: string().regex(MENTION_TOKEN_PATTERN$1).max(128).optional(),
9599
+ targetProfileWakeToken: string().regex(MENTION_TOKEN_PATTERN$1).max(128).optional(),
9600
+ conversationBinding: conversationBindingRecordSchema.optional(),
9601
+ deliveryRecoveryReason: atsdDispatchDeliveryRecoveryReasonSchema.optional(),
9602
+ dispatchChainId: string().min(1).optional(),
9603
+ autoRelayDepth: number().int().nonnegative().optional(),
9604
+ visitedProfileIds: array(string().min(1)).max(256).optional(),
9605
+ visitedProfileIdsHash: string().min(1).optional(),
9606
+ transportMode: runtimeTransportModeSchema.nullable().optional(),
9607
+ streamingMode: runtimeStreamingModeSchema.optional(),
9608
+ sourceSignalSnapshot: atsdDispatchSourceSignalSnapshotSchema.optional()
9609
+ });
9471
9610
  const daemonHubDeliverDispatchRequestSchema = strictObject({
9472
9611
  v: literal(DAEMON_HUB_SCHEMA_VERSION),
9473
9612
  dispatchId: string().min(1),
@@ -9478,7 +9617,7 @@ const daemonHubDeliverDispatchRequestSchema = strictObject({
9478
9617
  connectionGeneration: number().int().positive(),
9479
9618
  leaseEpoch: number().int().positive(),
9480
9619
  deliveryRecoveryReason: atsdDispatchDeliveryRecoveryReasonSchema.optional(),
9481
- payload: record(string(), unknown())
9620
+ payload: daemonHubDeliverDispatchPayloadSchema
9482
9621
  });
9483
9622
  const daemonHubDeliverDispatchResponseSchema = strictObject({
9484
9623
  accepted: boolean(),
@@ -10066,76 +10205,6 @@ const helloAckSchema = object({
10066
10205
  type: literal("system.hello.ack"),
10067
10206
  profile: profileSchema
10068
10207
  });
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
10208
  const baseEnvelopeShape = {
10140
10209
  v: literal(1),
10141
10210
  id: nonEmptyTrimmedStringFromUnknown,
@@ -12440,15 +12509,6 @@ function parseRuntimeTransportMode(value) {
12440
12509
  if (value === "local-cli") return value;
12441
12510
  return null;
12442
12511
  }
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
12512
  function parseContextIdMappingSpec(value) {
12453
12513
  const record = asRecord(value);
12454
12514
  if (!record) return null;
@@ -12485,7 +12545,7 @@ function normalizeOptionalText$21(value) {
12485
12545
  function nowIsoString() {
12486
12546
  return (/* @__PURE__ */ new Date()).toISOString();
12487
12547
  }
12488
- function toErrorMessage$15(error) {
12548
+ function toErrorMessage$16(error) {
12489
12549
  if (error instanceof Error) return error.message;
12490
12550
  return String(error);
12491
12551
  }
@@ -14342,12 +14402,26 @@ function matchesDaemonCliLane(normalizedCommand, preset, pathInput) {
14342
14402
  return normalizedCommand.includes(ATS_PACKAGE_INSTALL_ENTRY_SEGMENT) && !normalizedCommand.includes(canaryPackageInstallRoot) && !normalizedCommand.includes(ATS_DEV_LOCAL_ENTRY_SEGMENT);
14343
14403
  }
14344
14404
  function collapseLauncherWrapperProcesses(processes) {
14345
- const launcherPidSet = new Set(processes.filter((processInfo) => processInfo.ownership === "stable_launcher").map((processInfo) => processInfo.pid));
14405
+ const launcherPidSet = /* @__PURE__ */ new Set();
14406
+ for (const processInfo of processes) if (processInfo.ownership === "stable_launcher") launcherPidSet.add(processInfo.pid);
14346
14407
  if (launcherPidSet.size === 0) return processes;
14347
- return processes.filter((processInfo) => {
14348
- if (processInfo.ownership !== "stable_launcher") return true;
14349
- return !processes.some((candidate) => candidate.pid !== processInfo.pid && candidate.parentPid === processInfo.pid && candidate.ownership !== "stable_launcher" && launcherPidSet.has(processInfo.pid));
14350
- });
14408
+ const collapsedProcesses = [];
14409
+ for (const processInfo of processes) {
14410
+ if (processInfo.ownership === "stable_launcher") {
14411
+ if (processes.some((candidate) => candidate.pid !== processInfo.pid && candidate.parentPid === processInfo.pid && candidate.ownership !== "stable_launcher")) continue;
14412
+ collapsedProcesses.push(processInfo);
14413
+ continue;
14414
+ }
14415
+ if (processInfo.parentPid !== null && launcherPidSet.has(processInfo.parentPid)) {
14416
+ collapsedProcesses.push({
14417
+ ...processInfo,
14418
+ ownership: processInfo.ownership === "unknown" ? processInfo.ownership : "stable_launcher"
14419
+ });
14420
+ continue;
14421
+ }
14422
+ collapsedProcesses.push(processInfo);
14423
+ }
14424
+ return collapsedProcesses;
14351
14425
  }
14352
14426
  async function listWindowsProcesses() {
14353
14427
  const output = await runCommand$1("powershell", [
@@ -15015,6 +15089,58 @@ async function readObservedRuntimeState() {
15015
15089
  });
15016
15090
  }
15017
15091
 
15092
+ //#endregion
15093
+ //#region src/system/daemon-service-start-recovery.ts
15094
+ const ROOT_ERROR_PATTERN$1 = /\s*Try re-running the command as root for richer errors\.?/i;
15095
+ async function startDaemonSystemServiceWithAutoRepair(input) {
15096
+ let autoRepairAttempted = false;
15097
+ try {
15098
+ await input.systemManager.start();
15099
+ return { autoRepairAttempted };
15100
+ } catch (error) {
15101
+ if (!shouldAttemptLaunchdAutoRepair({
15102
+ controller: input.systemManager.controller,
15103
+ error
15104
+ })) throw error;
15105
+ autoRepairAttempted = true;
15106
+ await input.onAutoRepairAttempt?.();
15107
+ try {
15108
+ await input.systemManager.uninstall().catch(() => void 0);
15109
+ await input.systemManager.install(input.serviceCommandSpec);
15110
+ await input.systemManager.start();
15111
+ await input.onAutoRepairRecovered?.();
15112
+ return { autoRepairAttempted };
15113
+ } catch (retryError) {
15114
+ throw buildLaunchdAutoRepairFailureError({
15115
+ initialError: error,
15116
+ retryError
15117
+ });
15118
+ }
15119
+ }
15120
+ }
15121
+ function sanitizeSystemServiceErrorMessage$1(message) {
15122
+ return message.replace(ROOT_ERROR_PATTERN$1, "");
15123
+ }
15124
+ function isLaunchdBootstrapIosError$1(message) {
15125
+ const normalized = message.toLowerCase();
15126
+ return normalized.includes("bootstrap failed") && normalized.includes("input/output error");
15127
+ }
15128
+ function shouldAttemptLaunchdAutoRepair(input) {
15129
+ if (input.controller !== "launchd") return false;
15130
+ return isLaunchdBootstrapIosError$1(sanitizeSystemServiceErrorMessage$1(toErrorMessage$15(input.error)));
15131
+ }
15132
+ function buildLaunchdAutoRepairFailureError(input) {
15133
+ return new Error([
15134
+ "launchd auto-repair retry failed.",
15135
+ `initial error: ${toErrorMessage$15(input.initialError)}`,
15136
+ `retry error: ${toErrorMessage$15(input.retryError)}`
15137
+ ].join(" "));
15138
+ }
15139
+ function toErrorMessage$15(error) {
15140
+ if (error instanceof Error) return error.message;
15141
+ return String(error);
15142
+ }
15143
+
15018
15144
  //#endregion
15019
15145
  //#region src/system/daemon-service-alignment-executor.ts
15020
15146
  const ALIGNMENT_STOP_WAIT_MS = 3e3;
@@ -15138,7 +15264,10 @@ async function runDaemonServiceFullAlignmentLocked(input) {
15138
15264
  }
15139
15265
  if (shouldRestoreBackground) {
15140
15266
  await input.emitProgress("starting_background_service");
15141
- await serviceManager.start();
15267
+ await startDaemonSystemServiceWithAutoRepair({
15268
+ serviceCommandSpec: buildDaemonSystemServiceCommandSpec({ controller: serviceManager.controller }),
15269
+ systemManager: serviceManager
15270
+ });
15142
15271
  await waitForAlignmentBackgroundStartup({ manager: serviceManager });
15143
15272
  input.state.restoredBackground = true;
15144
15273
  }
@@ -15195,8 +15324,9 @@ function buildBlockedAlignmentResult(input) {
15195
15324
  };
15196
15325
  }
15197
15326
  async function resolveAlignmentCommandOptions(input) {
15198
- const [currentContract, runtimePaths, fallbackProfile] = await Promise.all([
15327
+ const [currentContract, runtimeSnapshot, runtimePaths, fallbackProfile] = await Promise.all([
15199
15328
  Promise.resolve(input.inventory.serviceContract ?? readDaemonServiceContract()).catch(() => null),
15329
+ readDaemonServiceRuntimeSnapshot().catch(() => null),
15200
15330
  ensureDaemonRuntimePaths().catch(() => null),
15201
15331
  resolveAtsProfileOrNull({
15202
15332
  allowDefaultFallback: true,
@@ -15204,8 +15334,8 @@ async function resolveAlignmentCommandOptions(input) {
15204
15334
  persistSelection: false
15205
15335
  }).catch(() => null)
15206
15336
  ]);
15207
- const gatewayUrl = await Promise.resolve(resolveBaseUrl(input.gatewayUrl ?? currentContract?.gatewayUrl ?? void 0)).catch(() => input.gatewayUrl ?? currentContract?.gatewayUrl);
15208
- const profile = normalizeText$12(input.profile) ?? currentContract?.profileId ?? fallbackProfile?.atsProfileId;
15337
+ const gatewayUrl = await Promise.resolve(resolveBaseUrl(input.gatewayUrl ?? currentContract?.gatewayUrl ?? runtimeSnapshot?.gatewayUrl ?? void 0)).catch(() => input.gatewayUrl ?? currentContract?.gatewayUrl ?? runtimeSnapshot?.gatewayUrl);
15338
+ const profile = normalizeOptionalText$21(input.profile) ?? currentContract?.profileId ?? normalizeOptionalText$21(runtimeSnapshot?.profile) ?? fallbackProfile?.atsProfileId;
15209
15339
  const deviceId = runtimePaths ? await resolveDaemonDeviceId({
15210
15340
  deviceId: input.deviceId ?? currentContract?.deviceId,
15211
15341
  deviceIdPath: runtimePaths.deviceIdPath
@@ -20372,7 +20502,7 @@ const ATS_HEADER_VISITED_PROFILE_IDS = "x-ats-visited-profile-ids";
20372
20502
  const ATS_HEADER_VISITED_PROFILE_IDS_HASH = "x-ats-visited-profile-ids-hash";
20373
20503
  function buildAtsRequestHeaders(input) {
20374
20504
  const headers = {};
20375
- headers[ATS_HEADER_REQUEST_ID] = normalize$1(input.requestId) || crypto.randomUUID();
20505
+ headers[ATS_HEADER_REQUEST_ID] = normalize$1(input.requestId) || crypto$1.randomUUID();
20376
20506
  const profile = normalize$1(input.profile);
20377
20507
  if (profile) headers[ATS_HEADER_PROFILE] = profile;
20378
20508
  const profileId = normalize$1(input.profileId);
@@ -22587,6 +22717,11 @@ const classifyCodexFailure = (input) => {
22587
22717
  errorType: "adapter",
22588
22718
  message: providerMessage
22589
22719
  };
22720
+ if (isConfigFailure(lowered)) return {
22721
+ code: "config.invalid",
22722
+ errorType: "config",
22723
+ message: toConfigInvalidMessage(providerMessage)
22724
+ };
22590
22725
  }
22591
22726
  const stderrText = normalizeOptionalText$12(input.stderrText);
22592
22727
  if (stderrText) return {
@@ -22618,6 +22753,12 @@ const isQuotaFailure$1 = (value) => {
22618
22753
  const isRateLimitFailure$1 = (value) => {
22619
22754
  return value.includes("429") || value.includes("rate limit") || value.includes("too many requests");
22620
22755
  };
22756
+ const isConfigFailure = (value) => {
22757
+ return value.includes("model_not_found") || value.includes("requested model") || value.includes("unknown model") || value.includes("invalid model") || value.includes("does not exist") && value.includes("model") || value.includes("invalid_request_error") && value.includes("model") || value.includes("\"param\": \"model\"");
22758
+ };
22759
+ const toConfigInvalidMessage = (value) => {
22760
+ return value.toLowerCase().startsWith("config.invalid:") ? value : `config.invalid: ${value}`;
22761
+ };
22621
22762
  function normalizeText$4(value) {
22622
22763
  return String(value ?? "").trim();
22623
22764
  }
@@ -24120,18 +24261,15 @@ const MENTION_TOKEN_REGEX$1 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
24120
24261
  const COMPACT_DISPATCH_BOOTSTRAP_TEMPLATE_VERSION = "compact-dispatch-bootstrap-v1";
24121
24262
  function parseDispatchTask(input) {
24122
24263
  const payload = resolveDispatchTaskPayload(input.deliverRequest);
24123
- if (!payload) return null;
24124
24264
  const requiredFields = resolveDispatchTaskRequiredFields({
24125
24265
  deliverRequest: input.deliverRequest,
24126
24266
  payload
24127
24267
  });
24128
24268
  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);
24269
+ const mentionSourceProfileId = normalizeOptionalText$21(payload.sourceSignal.profileId) ?? normalizeOptionalText$21(payload.sourceSignalSnapshot?.profileId);
24270
+ const mentionSourceProfileKind = payload.sourceSignal.profileKind ?? payload.sourceSignalSnapshot?.profileKind ?? null;
24271
+ const mentionSourceProfileWakeToken = normalizeOptionalText$21(payload.sourceSignal.profileWakeToken) ?? normalizeOptionalText$21(payload.sourceSignalSnapshot?.profileWakeToken);
24272
+ const prompt = normalizeOptionalText$21(payload.sourceSignal.text) ?? normalizeOptionalText$21(payload.sourceSignalSnapshot?.text);
24135
24273
  const targetProfileWakeToken = normalizeOptionalText$21(payload.targetProfileWakeToken);
24136
24274
  const triggerMode = "mention_only";
24137
24275
  const sequence = normalizeNonNegativeInteger$1(payload.enqueuedAtMs) ?? Date.now();
@@ -24142,11 +24280,11 @@ function parseDispatchTask(input) {
24142
24280
  });
24143
24281
  if (!(prompt && controllerSelection)) return null;
24144
24282
  const fallbackControllerSettings = createDefaultRuntimeAgentControllerSettings(controllerSelection.controllerRef);
24145
- const conversationBinding = resolveConversationBindingSnapshot(payload);
24283
+ const conversationBinding = payload.conversationBinding ?? null;
24146
24284
  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;
24285
+ const transportMode = payload.transportMode ?? input.fallbackRouteConfig?.transportMode ?? fallbackControllerSettings.transportMode;
24286
+ const streamingMode = payload.streamingMode ?? input.fallbackRouteConfig?.streamingMode ?? fallbackControllerSettings.streamingMode;
24287
+ const contextIdMappingSpec = payload.contextIdMappingSpec ?? input.fallbackRouteConfig?.contextIdMappingSpec ?? fallbackControllerSettings.contextIdMappingSpec;
24150
24288
  return {
24151
24289
  ...requiredFields,
24152
24290
  conversationBinding,
@@ -24169,16 +24307,8 @@ function resolveDeliveryRecoveryReason(payload) {
24169
24307
  if (normalized === "connection_replaced" || normalized === "route_lost") return normalized;
24170
24308
  return null;
24171
24309
  }
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
24310
  function resolveDispatchTaskPayload(request) {
24179
- const { payload } = request;
24180
- if (!payload || typeof payload !== "object" || Array.isArray(payload)) return null;
24181
- return payload;
24311
+ return request.payload;
24182
24312
  }
24183
24313
  function resolveDispatchTaskRequiredFields(input) {
24184
24314
  const dispatchId = normalizeOptionalText$21(input.payload.dispatchId) ?? input.deliverRequest.dispatchId;
@@ -24198,9 +24328,8 @@ function resolveDispatchTaskRequiredFields(input) {
24198
24328
  };
24199
24329
  }
24200
24330
  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;
24331
+ const controllerRef = normalizeOptionalText$21(input.payload.controllerSnapshot.controllerRef) ?? input.fallbackControllerRef;
24332
+ const controllerKind = input.payload.controllerSnapshot.controllerKind ?? input.fallbackControllerKind;
24204
24333
  if (!(controllerRef && controllerKind)) return null;
24205
24334
  return {
24206
24335
  controllerKind,
@@ -24414,10 +24543,10 @@ async function resolveDispatchMentionSourceContext(input) {
24414
24543
  }
24415
24544
  }
24416
24545
  function buildDispatchCorrelation(input) {
24417
- const payload = input.deliverRequest.payload && typeof input.deliverRequest.payload === "object" && !Array.isArray(input.deliverRequest.payload) ? input.deliverRequest.payload : {};
24546
+ const payload = input.deliverRequest.payload;
24418
24547
  return {
24419
24548
  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),
24549
+ controllerRef: input.parsedTask?.controllerRef ?? normalizeOptionalText$21(payload.controllerSnapshot.controllerRef),
24421
24550
  dispatchId: input.parsedTask?.dispatchId ?? normalizeOptionalText$21(payload.dispatchId) ?? input.deliverRequest.dispatchId,
24422
24551
  sourceEventId: input.parsedTask?.sourceEventId ?? normalizeOptionalText$21(payload.sourceEventId) ?? "unknown-source-event",
24423
24552
  targetProfileId: input.parsedTask?.targetProfileId ?? normalizeOptionalText$21(payload.targetProfileId) ?? input.deliverRequest.profileId,
@@ -24710,7 +24839,7 @@ async function syncDaemonRouteCatalogState(input) {
24710
24839
  return {
24711
24840
  status: "failed",
24712
24841
  reason: "load_failed",
24713
- errorMessage: toErrorMessage$15(error)
24842
+ errorMessage: toErrorMessage$16(error)
24714
24843
  };
24715
24844
  }
24716
24845
  const nextFingerprint = buildRouteCatalogFingerprint(nextCatalog);
@@ -24725,7 +24854,7 @@ async function syncDaemonRouteCatalogState(input) {
24725
24854
  return {
24726
24855
  status: "failed",
24727
24856
  reason: "register_failed",
24728
- errorMessage: toErrorMessage$15(error)
24857
+ errorMessage: toErrorMessage$16(error)
24729
24858
  };
24730
24859
  }
24731
24860
  const diff = buildRouteCatalogDiff({
@@ -24829,7 +24958,9 @@ function createDispatchBackpressureQueue(input) {
24829
24958
  controllerKey: selectedTask.controllerKey,
24830
24959
  dispatchId: selectedTask.dispatchId,
24831
24960
  profileId: selectedTask.profileId,
24961
+ spaceId: selectedTask.spaceId,
24832
24962
  taskId: selectedTask.taskId,
24963
+ targetLabel: selectedTask.targetLabel,
24833
24964
  transportMode: selectedTask.transportMode,
24834
24965
  ...buildSnapshot(selectedTask.profileId, selectedTask.controllerKey)
24835
24966
  };
@@ -24847,7 +24978,9 @@ function createDispatchBackpressureQueue(input) {
24847
24978
  errorMessage: completionResult.errorMessage,
24848
24979
  profileId: selectedTask.profileId,
24849
24980
  result: completionResult.result,
24981
+ spaceId: selectedTask.spaceId,
24850
24982
  taskId: selectedTask.taskId,
24983
+ targetLabel: selectedTask.targetLabel,
24851
24984
  transportMode: selectedTask.transportMode
24852
24985
  });
24853
24986
  }).catch((error) => {
@@ -24861,7 +24994,9 @@ function createDispatchBackpressureQueue(input) {
24861
24994
  errorMessage: toErrorMessage$8(error),
24862
24995
  profileId: selectedTask.profileId,
24863
24996
  result: "failed",
24997
+ spaceId: selectedTask.spaceId,
24864
24998
  taskId: selectedTask.taskId,
24999
+ targetLabel: selectedTask.targetLabel,
24865
25000
  transportMode: selectedTask.transportMode
24866
25001
  });
24867
25002
  }).finally(() => {
@@ -26836,7 +26971,9 @@ function enqueueDispatchDeliverFrame(input) {
26836
26971
  controllerKey: queueLogMeta.controllerKey,
26837
26972
  dispatchId: correlation.dispatchId,
26838
26973
  profileId: deliverRequest.profileId,
26974
+ spaceId: queueLogMeta.spaceId,
26839
26975
  taskId: correlation.taskId,
26976
+ targetLabel: queueLogMeta.targetLabel,
26840
26977
  transportMode: queueLogMeta.transportMode,
26841
26978
  run: async () => {
26842
26979
  return await handleDispatchDeliverFrame({
@@ -26878,7 +27015,7 @@ function enqueueDispatchDeliverFrame(input) {
26878
27015
  emitRunLine({
26879
27016
  presenter: input.presenter,
26880
27017
  code: "daemon.run.dispatch_queue_rejected",
26881
- text: `dispatch queue rejected task ${correlation.taskId}: queue is full`,
27018
+ text: `dispatch queue rejected task ${correlation.taskId} for ${queueLogMeta.targetLabel}: queue is full`,
26882
27019
  payload: {
26883
27020
  adapterId: queueLogMeta.adapterId,
26884
27021
  activeForController: enqueueResult.snapshot.activeForController,
@@ -26895,8 +27032,10 @@ function enqueueDispatchDeliverFrame(input) {
26895
27032
  queueDepth: enqueueResult.snapshot.queueDepth,
26896
27033
  queueMax: enqueueResult.snapshot.limits.queueMax,
26897
27034
  result: "failed",
27035
+ spaceId: queueLogMeta.spaceId,
26898
27036
  step: "rejected",
26899
27037
  taskId: correlation.taskId,
27038
+ targetLabel: queueLogMeta.targetLabel,
26900
27039
  transportMode: queueLogMeta.transportMode
26901
27040
  }
26902
27041
  });
@@ -26905,7 +27044,7 @@ function enqueueDispatchDeliverFrame(input) {
26905
27044
  emitRunLine({
26906
27045
  presenter: input.presenter,
26907
27046
  code: "daemon.run.dispatch_queue_enqueued",
26908
- text: `dispatch queue enqueued task ${correlation.taskId}`,
27047
+ text: `dispatch queue enqueued task ${correlation.taskId} for ${queueLogMeta.targetLabel}`,
26909
27048
  payload: {
26910
27049
  adapterId: queueLogMeta.adapterId,
26911
27050
  activeForController: enqueueResult.snapshot.activeForController,
@@ -26924,8 +27063,10 @@ function enqueueDispatchDeliverFrame(input) {
26924
27063
  queueDepth: enqueueResult.snapshot.queueDepth,
26925
27064
  queueMax: enqueueResult.snapshot.limits.queueMax,
26926
27065
  result: null,
27066
+ spaceId: queueLogMeta.spaceId,
26927
27067
  step: "enqueued",
26928
27068
  taskId: correlation.taskId,
27069
+ targetLabel: queueLogMeta.targetLabel,
26929
27070
  transportMode: queueLogMeta.transportMode
26930
27071
  }
26931
27072
  });
@@ -27684,7 +27825,7 @@ function toTaskExecutionError(error) {
27684
27825
  return {
27685
27826
  errorCode: "dispatch.execution_failed",
27686
27827
  errorType: "internal",
27687
- message: toErrorMessage$15(error)
27828
+ message: toErrorMessage$16(error)
27688
27829
  };
27689
27830
  }
27690
27831
  function normalizeOptionalContextId(contextId) {
@@ -27863,6 +28004,8 @@ function resolveDispatchQueueLogMeta(input) {
27863
28004
  if (!parsedTask) return {
27864
28005
  adapterId: null,
27865
28006
  controllerKey: `profile:${input.deliverRequest.profileId}`,
28007
+ spaceId: null,
28008
+ targetLabel: `profile:${input.deliverRequest.profileId}`,
27866
28009
  transportMode: null
27867
28010
  };
27868
28011
  const support = resolveLocalRuntimeControllerSupport({
@@ -27876,9 +28019,16 @@ function resolveDispatchQueueLogMeta(input) {
27876
28019
  controllerRef: parsedTask.controllerRef,
27877
28020
  profileId: input.deliverRequest.profileId
27878
28021
  }),
28022
+ spaceId: parsedTask.spaceId,
28023
+ targetLabel: resolveDispatchQueueTargetLabel(parsedTask),
27879
28024
  transportMode: parsedTask.transportMode
27880
28025
  };
27881
28026
  }
28027
+ function resolveDispatchQueueTargetLabel(parsedTask) {
28028
+ const wakeToken = normalizeOptionalText$21(parsedTask.targetProfileWakeToken);
28029
+ if (wakeToken) return wakeToken.startsWith("@") ? wakeToken : `@${wakeToken}`;
28030
+ return `profile:${parsedTask.targetProfileId}`;
28031
+ }
27882
28032
  function buildDispatchControllerKey(input) {
27883
28033
  const normalizedControllerKind = typeof input.controllerKind === "string" ? input.controllerKind.trim() : "";
27884
28034
  const normalizedControllerRef = typeof input.controllerRef === "string" ? input.controllerRef.trim() : "";
@@ -28202,7 +28352,7 @@ async function runDaemonSocketSession(input) {
28202
28352
  emitRunLine({
28203
28353
  presenter: input.presenter,
28204
28354
  code: "daemon.run.dispatch_queue_started",
28205
- text: `dispatch queue started task ${event.taskId}`,
28355
+ text: `dispatch queue started task ${event.taskId} for ${event.targetLabel}`,
28206
28356
  payload: {
28207
28357
  adapterId: event.adapterId,
28208
28358
  activeForController: event.activeForController,
@@ -28219,16 +28369,18 @@ async function runDaemonSocketSession(input) {
28219
28369
  queueDepth: event.queueDepth,
28220
28370
  queueMax: event.limits.queueMax,
28221
28371
  result: null,
28372
+ spaceId: event.spaceId,
28222
28373
  step: "started",
28223
28374
  taskId: event.taskId,
28375
+ targetLabel: event.targetLabel,
28224
28376
  transportMode: event.transportMode
28225
28377
  }
28226
28378
  });
28227
28379
  },
28228
28380
  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}`;
28381
+ let completionText = `dispatch queue failed task ${event.taskId} for ${event.targetLabel}`;
28382
+ if (event.result === "success") completionText = `dispatch queue completed task ${event.taskId} for ${event.targetLabel}`;
28383
+ else if (event.result === "partial_success") completionText = `dispatch queue partially completed task ${event.taskId} for ${event.targetLabel}`;
28232
28384
  emitRunLine({
28233
28385
  presenter: input.presenter,
28234
28386
  code: "daemon.run.dispatch_queue_completed",
@@ -28250,8 +28402,10 @@ async function runDaemonSocketSession(input) {
28250
28402
  queueDepth: event.queueDepth,
28251
28403
  queueMax: event.limits.queueMax,
28252
28404
  result: event.result,
28405
+ spaceId: event.spaceId,
28253
28406
  step: "completed",
28254
28407
  taskId: event.taskId,
28408
+ targetLabel: event.targetLabel,
28255
28409
  transportMode: event.transportMode
28256
28410
  }
28257
28411
  });
@@ -28370,7 +28524,7 @@ async function runDaemonSocketSession(input) {
28370
28524
  emitRunLine({
28371
28525
  presenter: input.presenter,
28372
28526
  code: "daemon.run.heartbeat_failed",
28373
- text: `heartbeat failed (${String(consecutiveHeartbeatFailures)}/${String(HEARTBEAT_CONSECUTIVE_FAILURES_BEFORE_CLOSE)}): ${toErrorMessage$15(error)}`
28527
+ text: `heartbeat failed (${String(consecutiveHeartbeatFailures)}/${String(HEARTBEAT_CONSECUTIVE_FAILURES_BEFORE_CLOSE)}): ${toErrorMessage$16(error)}`
28374
28528
  });
28375
28529
  if (shouldCloseSocket) {
28376
28530
  input.socket.close(1011, "heartbeat_failed");
@@ -28402,7 +28556,7 @@ async function runDaemonSocketSession(input) {
28402
28556
  emitRunLine({
28403
28557
  presenter: input.presenter,
28404
28558
  code: "daemon.run.heartbeat_failed",
28405
- text: `heartbeat failed: ${toErrorMessage$15(error)}`
28559
+ text: `heartbeat failed: ${toErrorMessage$16(error)}`
28406
28560
  });
28407
28561
  });
28408
28562
  }, normalizedDelayMs);
@@ -28444,7 +28598,7 @@ async function runDaemonSocketSession(input) {
28444
28598
  emitRunLine({
28445
28599
  presenter: input.presenter,
28446
28600
  code: "daemon.run.catalog_sync_signal_read_failed",
28447
- text: `catalog sync signal read failed: ${toErrorMessage$15(error)}`
28601
+ text: `catalog sync signal read failed: ${toErrorMessage$16(error)}`
28448
28602
  });
28449
28603
  }).finally(() => {
28450
28604
  scheduleCatalogSyncSignalPoll();
@@ -28618,7 +28772,7 @@ async function runDaemonSocketSession(input) {
28618
28772
  emitRunLine({
28619
28773
  presenter: input.presenter,
28620
28774
  code: "daemon.run.socket_error",
28621
- text: `daemon stream socket error: ${toErrorMessage$15(error)}`
28775
+ text: `daemon stream socket error: ${toErrorMessage$16(error)}`
28622
28776
  });
28623
28777
  });
28624
28778
  input.socket.onMessage((raw) => {
@@ -28994,7 +29148,7 @@ const backupAndCleanRuntimeState = async (input) => {
28994
29148
  appliedAt: input.nowIso,
28995
29149
  backupPaths,
28996
29150
  cleanedPaths,
28997
- errorMessage: toErrorMessage$15(error),
29151
+ errorMessage: toErrorMessage$16(error),
28998
29152
  fromEpoch: input.fromEpoch,
28999
29153
  reason: input.reason,
29000
29154
  status: "failed",
@@ -29168,7 +29322,7 @@ const runDaemonServiceLoop = async (input) => {
29168
29322
  emitRunLine({
29169
29323
  presenter: input.presenter,
29170
29324
  code: "daemon.run.projection_sync_failed",
29171
- text: `local projection repair failed before route registration: ${toErrorMessage$15(error)}`
29325
+ text: `local projection repair failed before route registration: ${toErrorMessage$16(error)}`
29172
29326
  });
29173
29327
  return null;
29174
29328
  });
@@ -29292,7 +29446,7 @@ const runDaemonServiceLoop = async (input) => {
29292
29446
  action: reconcileDecision.action,
29293
29447
  backoffMs,
29294
29448
  driftClass: reconcileDecision.driftClass,
29295
- error: toErrorMessage$15(error),
29449
+ error: toErrorMessage$16(error),
29296
29450
  foregroundActive: reconcileDecision.foregroundActive,
29297
29451
  lifecycleLocked: reconcileDecision.lifecycleLocked,
29298
29452
  owner: reconcileDecision.owner,
@@ -29303,7 +29457,7 @@ const runDaemonServiceLoop = async (input) => {
29303
29457
  action: reconcileDecision.action,
29304
29458
  backoffMs,
29305
29459
  driftClass: reconcileDecision.driftClass,
29306
- error: toErrorMessage$15(error),
29460
+ error: toErrorMessage$16(error),
29307
29461
  foregroundActive: reconcileDecision.foregroundActive,
29308
29462
  lifecycleLocked: reconcileDecision.lifecycleLocked,
29309
29463
  owner: reconcileDecision.owner,
@@ -29313,11 +29467,11 @@ const runDaemonServiceLoop = async (input) => {
29313
29467
  emitRunLine({
29314
29468
  presenter: input.presenter,
29315
29469
  code: "daemon.run.reconnect",
29316
- text: `daemon stream reconnect scheduled in ${String(backoffMs)}ms (${toErrorMessage$15(error)})`,
29470
+ text: `daemon stream reconnect scheduled in ${String(backoffMs)}ms (${toErrorMessage$16(error)})`,
29317
29471
  payload: {
29318
29472
  attempt: reconnectAttempt,
29319
29473
  backoffMs,
29320
- error: toErrorMessage$15(error)
29474
+ error: toErrorMessage$16(error)
29321
29475
  }
29322
29476
  });
29323
29477
  await sleep$5(backoffMs);
@@ -29766,12 +29920,6 @@ const QUIET_PRESENTER = {
29766
29920
  line: () => void 0,
29767
29921
  data: () => void 0
29768
29922
  };
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
29923
  async function resolveDaemonLocalServiceDemand(input) {
29776
29924
  const projection = await syncDeviceRuntimeStateProjection({ mode: "check" }).catch(() => null);
29777
29925
  const ownerUserId = normalizeOptionalString$7(input.ownerUserId);
@@ -29803,7 +29951,7 @@ async function resolveDaemonLocalServiceDemand(input) {
29803
29951
  return {
29804
29952
  decision: "indeterminate",
29805
29953
  hasWakeableLocalRoute: false,
29806
- reason: `failed to load local daemon routes: ${toErrorMessage$15(error)}`,
29954
+ reason: `failed to load local daemon routes: ${toErrorMessage$16(error)}`,
29807
29955
  wakeableLocalRouteCount: 0,
29808
29956
  projection
29809
29957
  };
@@ -29823,84 +29971,6 @@ async function resolveDaemonLocalServiceDemand(input) {
29823
29971
  projection
29824
29972
  };
29825
29973
  }
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
29974
  function normalizeOptionalString$7(value) {
29905
29975
  const normalized = String(value ?? "").trim();
29906
29976
  return normalized.length > 0 ? normalized : null;
@@ -31507,6 +31577,7 @@ async function completeDaemonReinstallStart(input) {
31507
31577
  targetDesiredState: input.targetDesiredState,
31508
31578
  startAfterInstallMode: input.resolved.startAfterInstallMode
31509
31579
  }) === "never") {
31580
+ if (await maybePromptToRunDaemonAfterStoppedReinstall({ runtime: input.runtime })) return await autoStartDaemonAfterReinstall(input);
31510
31581
  await clearDaemonStartFailureStateSafely();
31511
31582
  if (input.resolved.emitStatusAfterSuccess) await input.resolved.runStatus({
31512
31583
  agentOverviewHandled: true,
@@ -31530,10 +31601,19 @@ async function completeDaemonReinstallStart(input) {
31530
31601
  }
31531
31602
  return await autoStartDaemonAfterReinstall(input);
31532
31603
  }
31604
+ async function maybePromptToRunDaemonAfterStoppedReinstall(input) {
31605
+ if (input.runtime.resolvedView !== "human" || !canUseInteractivePrompts(input.runtime)) return false;
31606
+ const selected = await confirm({
31607
+ message: "ATS Service is repaired and currently stopped. Run it now in the background?",
31608
+ initialValue: true
31609
+ });
31610
+ return !(isCancel(selected) || !selected);
31611
+ }
31533
31612
  async function autoStartDaemonAfterReinstall(input) {
31534
31613
  if (await runDaemonAfterReinstallStartWithRetry({
31535
31614
  presenter: input.presenter,
31536
31615
  resolved: input.resolved,
31616
+ startRetryDelayMs: input.resolved.startRetryDelayMs,
31537
31617
  view: input.runtime.resolvedView
31538
31618
  }) !== "started") return {
31539
31619
  ok: false,
@@ -31578,7 +31658,7 @@ async function runDaemonAfterReinstallStartWithRetry(input) {
31578
31658
  })).ok ? "started" : "failed_with_card";
31579
31659
  } catch (error) {
31580
31660
  if (attempt < REINSTALL_START_RETRY_ATTEMPTS) {
31581
- await sleep(REINSTALL_START_RETRY_DELAY_MS);
31661
+ await sleep(input.startRetryDelayMs);
31582
31662
  continue;
31583
31663
  }
31584
31664
  const startupDiagnostic = await readDaemonStartFailureLogDiagnostic({ cursor: startFailureLogCursor });
@@ -31673,6 +31753,7 @@ function resolveDaemonReinstallOptions(options) {
31673
31753
  timeoutPolicy: options.timeoutPolicy ?? "abort",
31674
31754
  skipConfirm: options.skipConfirm ?? false,
31675
31755
  verifyWaitMs: options.verifyWaitMs ?? REINSTALL_VERIFY_WAIT_MS,
31756
+ startRetryDelayMs: options.startRetryDelayMs ?? REINSTALL_START_RETRY_DELAY_MS,
31676
31757
  startAfterInstallMode: options.startAfterInstallMode ?? "default",
31677
31758
  emitStatusAfterSuccess: options.emitStatusAfterSuccess ?? true
31678
31759
  };
@@ -32520,22 +32601,6 @@ function isPermissionOrAuthorizationError(message) {
32520
32601
  const normalized = message.toLowerCase();
32521
32602
  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
32603
  }
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
32604
  async function waitForSystemServiceStartup(input) {
32540
32605
  const deadlineMs = Date.now() + input.waitMs;
32541
32606
  while (Date.now() < deadlineMs) {
@@ -33136,7 +33201,7 @@ function buildDaemonStopWarningText(input) {
33136
33201
  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
33202
  return formatInlineAtsCliCommands(`ATS could not stop the local service cleanly.${input.errorMessage ? ` ${input.errorMessage}` : ""} Run \`ats service stop --force\` and retry.`);
33138
33203
  }
33139
- async function runDaemonRun(input) {
33204
+ async function runDaemonRun(input, options = {}) {
33140
33205
  const runtime = await resolveRuntimeContext({ view: input.view });
33141
33206
  const presenter = createPresenter(runtime);
33142
33207
  emitDaemonOverviewIfAgent({
@@ -33218,6 +33283,8 @@ async function runDaemonRun(input) {
33218
33283
  }
33219
33284
  if (isDetachedDaemonServiceRun()) return await runSystemDaemonCore({
33220
33285
  input,
33286
+ systemServiceStartupPollMs: options.systemServiceStartupPollMs,
33287
+ systemServiceStartupWaitMs: options.systemServiceStartupWaitMs,
33221
33288
  runtime,
33222
33289
  presenter,
33223
33290
  mode,
@@ -33226,6 +33293,8 @@ async function runDaemonRun(input) {
33226
33293
  return await withDaemonServiceRunLock(async () => {
33227
33294
  return await runSystemDaemonCore({
33228
33295
  input,
33296
+ systemServiceStartupPollMs: options.systemServiceStartupPollMs,
33297
+ systemServiceStartupWaitMs: options.systemServiceStartupWaitMs,
33229
33298
  runtime,
33230
33299
  presenter,
33231
33300
  mode,
@@ -33244,7 +33313,7 @@ async function runDaemonBackgroundStartForDecision(input) {
33244
33313
  })).ok ? "started" : "failed_with_card";
33245
33314
  }
33246
33315
  async function runSystemDaemonCore(context) {
33247
- const { input, presenter, runtime, mode, daemonVersion } = context;
33316
+ const { input, presenter, runtime, mode, daemonVersion, systemServiceStartupPollMs, systemServiceStartupWaitMs } = context;
33248
33317
  await cleanupDaemonServiceRuntimeState();
33249
33318
  const isSystemServiceBootstrap = isManagedSystemServiceBootstrapRun();
33250
33319
  const runConfig = await resolveContractFirstDaemonRunConfig({
@@ -33369,6 +33438,8 @@ async function runSystemDaemonCore(context) {
33369
33438
  });
33370
33439
  return await runDaemonBackgroundStart({
33371
33440
  daemonVersion,
33441
+ systemServiceStartupPollMs,
33442
+ systemServiceStartupWaitMs,
33372
33443
  runtime,
33373
33444
  presenter,
33374
33445
  mode,
@@ -33421,6 +33492,8 @@ async function runDaemonBackgroundStart(input) {
33421
33492
  });
33422
33493
  const runResult = await runSystemServiceManager({
33423
33494
  daemonVersion: input.daemonVersion,
33495
+ startupPollMs: input.systemServiceStartupPollMs,
33496
+ startupWaitMs: input.systemServiceStartupWaitMs,
33424
33497
  runtime: input.runtime,
33425
33498
  presenter: input.presenter,
33426
33499
  mode: input.mode,
@@ -33508,11 +33581,11 @@ function emitDaemonRecoveredStartedState(input) {
33508
33581
  });
33509
33582
  }
33510
33583
  async function resolveDaemonServiceProfileId(input) {
33511
- const explicitProfile = normalizeText(input.explicitProfile);
33584
+ const explicitProfile = normalizeOptionalText$21(input.explicitProfile);
33512
33585
  if (explicitProfile) return explicitProfile;
33513
- const sessionProfile = normalizeText(input.runtime.profile) ?? normalizeText(input.runtime.atsProfileId);
33586
+ const sessionProfile = normalizeOptionalText$21(input.runtime.profile) ?? normalizeOptionalText$21(input.runtime.atsProfileId);
33514
33587
  if (sessionProfile) return sessionProfile;
33515
- const selectedProfileId = normalizeText(getCurrentCommandCheckState().selectedProfile?.atsProfileId);
33588
+ const selectedProfileId = normalizeOptionalText$21(getCurrentCommandCheckState().selectedProfile?.atsProfileId);
33516
33589
  if (selectedProfileId) return selectedProfileId;
33517
33590
  return (await resolveAtsProfileOrNull({
33518
33591
  allowDefaultFallback: input.runtime.resolvedView === "human",
@@ -33665,27 +33738,18 @@ async function runSystemServiceManager(input) {
33665
33738
  startSpinner?.start("Starting ATS Service...");
33666
33739
  try {
33667
33740
  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
- });
33741
+ autoRepairAttempted = (await startDaemonSystemServiceWithAutoRepair({
33742
+ serviceCommandSpec,
33743
+ systemManager: input.systemManager,
33744
+ onAutoRepairAttempt: () => {
33745
+ startSpinner?.message("ATS is repairing a local service issue...");
33746
+ },
33747
+ onAutoRepairRecovered: () => {
33681
33748
  startSpinner?.message("Starting ATS Service...");
33682
- } catch (retryError) {
33683
- startupError = buildLaunchdAutoRepairFailureError({
33684
- initialError: error,
33685
- retryError
33686
- });
33687
33749
  }
33688
- } else startupError = error;
33750
+ })).autoRepairAttempted;
33751
+ } catch (error) {
33752
+ startupError = error;
33689
33753
  }
33690
33754
  if (startupError) {
33691
33755
  startSpinner?.clear();
@@ -33706,8 +33770,8 @@ async function runSystemServiceManager(input) {
33706
33770
  const startupStatus = await waitForSystemServiceStartup({
33707
33771
  expectedVersion: input.daemonVersion,
33708
33772
  manager: input.systemManager,
33709
- waitMs: resolveSystemServiceStartupWaitMs(input.systemManager.controller),
33710
- pollMs: SERVICE_STARTUP_POLL_MS
33773
+ waitMs: input.startupWaitMs ?? resolveSystemServiceStartupWaitMs(input.systemManager.controller),
33774
+ pollMs: input.startupPollMs ?? SERVICE_STARTUP_POLL_MS
33711
33775
  });
33712
33776
  await cleanupInactiveDaemonServiceBundles();
33713
33777
  await clearDaemonStartFailureStateSafely();
@@ -34615,7 +34679,7 @@ async function resolveServiceStatus() {
34615
34679
  installedVersion: daemonStatus.state.daemonVersion
34616
34680
  };
34617
34681
  const runtime = await readCurrentDaemonRuntimeContext({ status: daemonStatus }).catch(() => null);
34618
- if (!runtime || runtime.effectiveRuntimeStatus !== "running" || runtime.runtimeStatus.status !== "running") return {
34682
+ if (!runtime || runtime.effectiveRuntimeStatus !== "running") return {
34619
34683
  kind: "not_running",
34620
34684
  runtimeStatus: runtime?.runtimeStatus ?? null
34621
34685
  };
@@ -45318,10 +45382,13 @@ function makeHello(profile) {
45318
45382
  profile
45319
45383
  };
45320
45384
  }
45321
- function makeTextSignal(text) {
45385
+ function makeTextSignal(text, options) {
45322
45386
  return {
45323
45387
  type: "signal.text",
45324
- data: { text }
45388
+ data: {
45389
+ text,
45390
+ ...options?.meta ? { meta: options.meta } : {}
45391
+ }
45325
45392
  };
45326
45393
  }
45327
45394
  function sanitizeText(value) {
@@ -45450,6 +45517,94 @@ function appendOptionalBooleanField(payload, key, value) {
45450
45517
  if (typeof value === "boolean") payload[key] = value;
45451
45518
  }
45452
45519
 
45520
+ //#endregion
45521
+ //#region src/space/space-display-projection.ts
45522
+ function buildSpaceDisplayProjection(input) {
45523
+ const currentProfileId = normalizeSpaceDisplayText(input.currentProfileId);
45524
+ const currentProfileName = normalizeSpaceDisplayText(input.currentProfileName);
45525
+ const creatorProfileName = normalizeSpaceDisplayText(input.creatorProfileName);
45526
+ const creatorProfileId = normalizeSpaceDisplayText(input.creatorProfileId);
45527
+ const availableViaProfileName = normalizeSpaceDisplayText(input.availableViaProfileName);
45528
+ const availableViaProfileId = normalizeSpaceDisplayText(input.availableViaProfileId);
45529
+ return {
45530
+ spaceId: normalizeSpaceDisplayText(input.spaceId),
45531
+ spaceName: normalizeSpaceDisplayText(input.spaceName),
45532
+ creatorProfileName,
45533
+ creatorProfileId,
45534
+ creatorDisplayName: resolveSpaceProfileDisplayName({
45535
+ currentProfileId,
45536
+ currentProfileName,
45537
+ profileId: creatorProfileId,
45538
+ profileName: creatorProfileName
45539
+ }),
45540
+ availableViaProfileName,
45541
+ availableViaProfileId,
45542
+ availableViaDisplayName: resolveSpaceProfileDisplayName({
45543
+ currentProfileId,
45544
+ currentProfileName,
45545
+ profileId: availableViaProfileId,
45546
+ profileName: availableViaProfileName
45547
+ }),
45548
+ spaceCreatedAt: normalizeSpaceDisplayText(input.spaceCreatedAt),
45549
+ lastJoinedAt: normalizeSpaceDisplayText(input.lastJoinedAt),
45550
+ passwordProtected: typeof input.passwordProtected === "boolean" ? input.passwordProtected : null
45551
+ };
45552
+ }
45553
+ function buildSpaceMetadataFields(input) {
45554
+ const fields = [
45555
+ {
45556
+ id: "spaceId",
45557
+ label: "Space ID",
45558
+ value: formatSpaceDisplayValue(input.projection.spaceId)
45559
+ },
45560
+ {
45561
+ id: "spaceCreator",
45562
+ label: "Space Creator",
45563
+ value: formatSpaceDisplayValue(input.projection.creatorDisplayName, "unknown-profile")
45564
+ },
45565
+ {
45566
+ id: "spaceCreatorProfileId",
45567
+ label: "Space Creator Profile ID",
45568
+ value: formatSpaceDisplayValue(input.projection.creatorProfileId, "unknown-profile")
45569
+ }
45570
+ ];
45571
+ if (input.includeAvailableVia === true) fields.push({
45572
+ id: "availableVia",
45573
+ label: "Available via",
45574
+ value: formatSpaceDisplayValue(input.projection.availableViaDisplayName)
45575
+ }, {
45576
+ id: "availableViaProfileId",
45577
+ label: "Available via Profile ID",
45578
+ value: formatSpaceDisplayValue(input.projection.availableViaProfileId)
45579
+ });
45580
+ if (input.includeCreatedAt === true) fields.push({
45581
+ id: "spaceCreatedAt",
45582
+ label: "Space Created",
45583
+ value: formatSpaceDisplayValue(input.projection.spaceCreatedAt)
45584
+ });
45585
+ if (input.includeLastJoinedAt === true) fields.push({
45586
+ id: "lastJoinedAt",
45587
+ label: "Last joined",
45588
+ value: formatSpaceDisplayValue(input.projection.lastJoinedAt)
45589
+ });
45590
+ return fields;
45591
+ }
45592
+ function formatSpaceDisplayValue(value, fallback = "unknown") {
45593
+ return value ?? fallback;
45594
+ }
45595
+ function resolveSpaceDisplayName(value, fallback) {
45596
+ return value ?? fallback;
45597
+ }
45598
+ function normalizeSpaceDisplayText(value) {
45599
+ const normalized = sanitizeTerminalDisplayText(value, "single-line").trim();
45600
+ return normalized.length > 0 ? normalized : null;
45601
+ }
45602
+ function resolveSpaceProfileDisplayName(input) {
45603
+ if (input.profileName) return input.profileName;
45604
+ if (input.profileId && input.currentProfileId && input.profileId === input.currentProfileId) return input.currentProfileName ?? input.profileId;
45605
+ return input.profileId;
45606
+ }
45607
+
45453
45608
  //#endregion
45454
45609
  //#region src/ui/controller-display.ts
45455
45610
  function resolveControllerDisplayName(controllerRef) {
@@ -45964,6 +46119,17 @@ function findMatchingAgentSnapshot(input) {
45964
46119
  //#endregion
45965
46120
  //#region src/space/mention-token.ts
45966
46121
  const MENTION_TOKEN_VALUE_PATTERN$1 = /^[a-z0-9][a-z0-9._-]{0,127}$/;
46122
+ const MENTION_TOKEN_TEXT_PATTERN = /(^|[^\w\\])@([A-Za-z0-9][A-Za-z0-9._-]{0,127})/g;
46123
+ const TRAILING_MENTION_PUNCTUATION_PATTERN$1 = /[.,!?;:,。!?;:]+$/u;
46124
+ function extractMentionTokensFromText(text) {
46125
+ const mentions = [];
46126
+ for (const match of text.matchAll(MENTION_TOKEN_TEXT_PATTERN)) {
46127
+ const mentionToken = stripTrailingMentionTokenPunctuation(String(match[2] ?? "").trim());
46128
+ if (!mentionToken) continue;
46129
+ mentions.push(mentionToken);
46130
+ }
46131
+ return mentions;
46132
+ }
45967
46133
  function resolvePreferredSpaceMemberMentionToken(input) {
45968
46134
  const tokenOwners = buildMentionTokenOwners(input.snapshot);
45969
46135
  const explicitToken = input.member.profileKind === "agent" ? normalizeMentionTokenValue(input.member.wakeToken) : null;
@@ -46023,6 +46189,11 @@ function normalizeMentionTokenValue(value) {
46023
46189
  if (!(normalized && MENTION_TOKEN_VALUE_PATTERN$1.test(normalized))) return null;
46024
46190
  return normalized;
46025
46191
  }
46192
+ function stripTrailingMentionTokenPunctuation(value) {
46193
+ const normalized = value.trim();
46194
+ if (!normalized) return "";
46195
+ return normalized.replace(TRAILING_MENTION_PUNCTUATION_PATTERN$1, "") || normalized;
46196
+ }
46026
46197
 
46027
46198
  //#endregion
46028
46199
  //#region src/ui/space-mention-highlight.ts
@@ -46119,8 +46290,6 @@ const AGENT_CONTEXT_HIDDEN_TOKENS = new Set([
46119
46290
  ]);
46120
46291
  const CLAUDE_CONTROLLER_REF_PATTERN = /claude/i;
46121
46292
  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
46293
  const MENTION_DISPATCH_HINT_META_PURPOSE = "mention_dispatch_hint";
46125
46294
  const MENTION_FAILURE_HINT_PREFIX = "Mention skipped for \"";
46126
46295
  const MENTION_FAILURE_HINT_LEGACY_PREFIX = "Mention skipped. Try this:";
@@ -46189,38 +46358,38 @@ function buildSpaceInfoCardLines(input) {
46189
46358
  });
46190
46359
  }
46191
46360
  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);
46361
+ const projection = buildSpaceDisplayProjection({
46362
+ spaceId: input.spaceId,
46363
+ spaceName: input.spaceName,
46364
+ creatorProfileId: input.spaceCreatorId,
46365
+ creatorProfileName: input.spaceCreatorName,
46366
+ spaceCreatedAt: input.spaceCreatedAt,
46367
+ passwordProtected: input.passwordProtected
46368
+ });
46197
46369
  const gatewayUrl = sanitizeTrimmedSingleLineText(input.gatewayUrl);
46370
+ const metadataFacts = buildSpaceMetadataFields({
46371
+ projection,
46372
+ includeCreatedAt: true
46373
+ }).map((field) => {
46374
+ if (field.id !== "spaceCreator") return {
46375
+ label: field.label,
46376
+ value: field.value
46377
+ };
46378
+ return {
46379
+ label: field.label,
46380
+ value: projection.creatorDisplayName && projection.creatorProfileId ? colorizePersonLabel(projection.creatorDisplayName, {
46381
+ profileId: projection.creatorProfileId,
46382
+ profileName: projection.creatorDisplayName
46383
+ }, { spaceMembersSnapshot: input.spaceMembersSnapshot }) : formatSpaceDisplayValue(projection.creatorDisplayName, "(unknown)")
46384
+ };
46385
+ });
46198
46386
  return {
46199
46387
  facts: [
46200
46388
  {
46201
46389
  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)"
46390
+ value: resolveSpaceDisplayName(projection.spaceName, "(unnamed)")
46223
46391
  },
46392
+ ...metadataFacts,
46224
46393
  {
46225
46394
  label: "Security",
46226
46395
  value: resolveSpaceSecurityLabel(input.passwordProtected)
@@ -46234,7 +46403,7 @@ function buildSpaceInfoData(input) {
46234
46403
  value: sanitizeTrimmedSingleLineText(input.modeLabel) || "(unknown)"
46235
46404
  }
46236
46405
  ],
46237
- joinCommand: formatAtsCliCommand(`ats space join ${spaceId}`),
46406
+ joinCommand: formatAtsCliCommand(`ats space join ${input.spaceId}`),
46238
46407
  publicWarningLines: isPublicSpace(input.passwordProtected) ? buildPublicSpaceWarningLines() : []
46239
46408
  };
46240
46409
  }
@@ -46365,15 +46534,15 @@ function buildSpaceMembersPanelLines(snapshot) {
46365
46534
  }
46366
46535
  function buildSpaceMembersPanelSource(snapshot) {
46367
46536
  return { sections: [buildSpaceMembersPanelSectionSource({
46368
- id: "humans",
46369
- members: snapshot.humans,
46370
- snapshot,
46371
- title: "👤 Humans"
46372
- }), buildSpaceMembersPanelSectionSource({
46373
46537
  id: "agents",
46374
46538
  members: snapshot.agents,
46375
46539
  snapshot,
46376
46540
  title: "🤖 Agents"
46541
+ }), buildSpaceMembersPanelSectionSource({
46542
+ id: "humans",
46543
+ members: snapshot.humans,
46544
+ snapshot,
46545
+ title: "👤 Humans"
46377
46546
  })].filter((section) => section.items.length > 0) };
46378
46547
  }
46379
46548
  function buildSpaceMembersLoadingPanelLines() {
@@ -46658,13 +46827,13 @@ function isTransientSignalTextHint(event) {
46658
46827
  if (rawMeta.transient !== true) return false;
46659
46828
  const purpose = String(rawMeta.purpose ?? "").trim();
46660
46829
  if (!purpose) return true;
46661
- return purpose === TRANSIENT_HINT_START_PURPOSE$1 || purpose === CONVERSATION_CONTINUITY_WARNING_PURPOSE || purpose === AGENT_REPLY_PREVIEW_PURPOSE;
46830
+ 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
46831
  }
46663
46832
  function isTransientSignalTextHintClearEvent(event) {
46664
46833
  const rawMeta = resolveSignalTextMeta$1(event);
46665
46834
  if (!rawMeta || rawMeta.transient !== true) return false;
46666
46835
  const purpose = String(rawMeta.purpose ?? "").trim();
46667
- return purpose === TRANSIENT_HINT_END_PURPOSE$1 || purpose === AGENT_REPLY_PREVIEW_END_PURPOSE;
46836
+ return purpose === AGENT_REPLYING_END_PURPOSE || purpose === AGENT_REPLY_PREVIEW_END_PURPOSE;
46668
46837
  }
46669
46838
  function resolveSignalTextMeta$1(event) {
46670
46839
  if (!event.data || typeof event.data !== "object" || Array.isArray(event.data)) return null;
@@ -47426,6 +47595,9 @@ const SPACE_INFO_FULL_WIDTH_LABELS = new Set(["Space Name", "Space ID"]);
47426
47595
  const MEMBERS_SEARCH_LABEL = "Type to search";
47427
47596
  const MEMBERS_SEARCH_PLACEHOLDER = "Filter members by name, @wake, ID, or owner";
47428
47597
  const MEMBERS_NO_MATCHES_LINE = pc.dim("No matching members found.");
47598
+ const LOGS_SEARCH_LABEL = "Type to search";
47599
+ const LOGS_SEARCH_PLACEHOLDER = "Filter logs by actor, action, or text";
47600
+ const LOGS_NO_MATCHES_LINE = pc.dim("No matching logs found.");
47429
47601
  function buildHelpPanelBlocks() {
47430
47602
  return buildPanelBodyBlocks([buildPanelLinesSection(listSpaceSlashCommands().map((command) => {
47431
47603
  return `${pc.cyan(command.trigger)} ${pc.dim(command.description)}`;
@@ -47458,6 +47630,31 @@ function buildLogsPanelBlocks(input) {
47458
47630
  if (sections.length > 0) return sections;
47459
47631
  return buildPanelBodyBlocks([buildPanelLinesSection([pc.dim("No logs yet.")])]);
47460
47632
  }
47633
+ function buildLogsSearchableListViewState(input) {
47634
+ const normalizedQuery = normalizeSearchQuery(input.query);
47635
+ const filteredSections = filterLogsSections(input.sections, normalizedQuery);
47636
+ return {
47637
+ activeItemId: resolveLogsSearchableActiveItemId({
47638
+ preferredActiveItemId: input.activeItemId,
47639
+ query: input.query,
47640
+ sections: input.sections
47641
+ }),
47642
+ control: {
47643
+ label: LOGS_SEARCH_LABEL,
47644
+ placeholder: LOGS_SEARCH_PLACEHOLDER,
47645
+ query: input.query
47646
+ },
47647
+ emptyLines: resolveLogsEmptyLines(filteredSections.length, normalizedQuery),
47648
+ sections: filteredSections.map((section) => ({
47649
+ id: section.id,
47650
+ title: section.title,
47651
+ items: section.items.map((item) => ({
47652
+ id: item.id,
47653
+ lines: item.lines
47654
+ }))
47655
+ }))
47656
+ };
47657
+ }
47461
47658
  function buildMembersSearchableListViewState(input) {
47462
47659
  const normalizedQuery = normalizeSearchQuery(input.query);
47463
47660
  if (!input.snapshot) return {
@@ -47503,6 +47700,11 @@ function resolveMembersSearchableActiveItemId(input) {
47503
47700
  if (itemIds.length === 0) return null;
47504
47701
  return itemIds.includes(input.preferredActiveItemId ?? "") ? input.preferredActiveItemId : itemIds[0] ?? null;
47505
47702
  }
47703
+ function resolveLogsSearchableActiveItemId(input) {
47704
+ const itemIds = filterLogsSections(input.sections, normalizeSearchQuery(input.query)).flatMap((section) => section.items.map((item) => item.id));
47705
+ if (itemIds.length === 0) return null;
47706
+ return itemIds.includes(input.preferredActiveItemId ?? "") ? input.preferredActiveItemId : itemIds[0] ?? null;
47707
+ }
47506
47708
  function buildMembersPanelLines(input) {
47507
47709
  if (!input.snapshot) {
47508
47710
  if (input.refreshError) return ["Couldn't load the current Space members.", pc.dim("Try /members again in a few seconds.")];
@@ -47511,8 +47713,24 @@ function buildMembersPanelLines(input) {
47511
47713
  return buildSpaceMembersPanelLines(input.snapshot);
47512
47714
  }
47513
47715
  function buildLogsPanelSection(section) {
47514
- if (section.lines.length === 0) return null;
47515
- return buildPanelLinesSection([pc.bold(section.title), ...section.lines]);
47716
+ if (section.items.length === 0) return null;
47717
+ return buildPanelLinesSection([pc.bold(section.title), ...section.items.flatMap((item) => item.lines)]);
47718
+ }
47719
+ function filterLogsSections(sections, normalizedQuery) {
47720
+ const sourceSections = sections.map((section) => ({
47721
+ id: section.kind,
47722
+ title: section.title,
47723
+ items: section.items.map((item) => ({
47724
+ id: item.id,
47725
+ lines: item.lines,
47726
+ searchKey: buildLogsSearchKey(section.title, item.lines)
47727
+ }))
47728
+ }));
47729
+ if (!normalizedQuery) return sourceSections;
47730
+ return sourceSections.map((section) => ({
47731
+ ...section,
47732
+ items: section.items.filter((item) => item.searchKey.includes(normalizedQuery))
47733
+ })).filter((section) => section.items.length > 0);
47516
47734
  }
47517
47735
  function filterMembersPanelSections(sections, normalizedQuery) {
47518
47736
  if (!normalizedQuery) return [...sections];
@@ -47525,6 +47743,13 @@ function filterMembersPanelSections(sections, normalizedQuery) {
47525
47743
  function normalizeSearchQuery(query) {
47526
47744
  return query.trim().toLowerCase();
47527
47745
  }
47746
+ function resolveLogsEmptyLines(sectionCount, normalizedQuery) {
47747
+ if (sectionCount > 0) return [];
47748
+ return normalizedQuery ? [LOGS_NO_MATCHES_LINE] : [pc.dim("No logs yet.")];
47749
+ }
47750
+ function buildLogsSearchKey(title, lines) {
47751
+ return normalizeSearchQuery([title, ...lines].map((line) => stripVTControlCharacters(line)).join(" "));
47752
+ }
47528
47753
  function resolveConnectionModeLabel(connectionMode) {
47529
47754
  if (connectionMode === "watch") return "watch-only stream";
47530
47755
  if (connectionMode === "history") return "history viewer";
@@ -47606,10 +47831,10 @@ const SPACE_PANEL_DEFINITION_BY_KIND = new Map([
47606
47831
  contentAlign: "left",
47607
47832
  kind: "logs",
47608
47833
  title: "🗒️ Space Logs",
47609
- mode: "readonly",
47834
+ mode: "searchable_list",
47610
47835
  layout: "centered_modal",
47611
47836
  surfaceVariant: "dark",
47612
- instructionPreset: "readonly-close"
47837
+ instructionPreset: "searchable-list-close"
47613
47838
  }
47614
47839
  ].map((definition) => [definition.kind, definition]));
47615
47840
  const PANEL_INSTRUCTION_PRESETS = {
@@ -47887,6 +48112,79 @@ function assertUnreachable$1(value) {
47887
48112
  throw new Error(`Unknown panel body block: ${JSON.stringify(value)}`);
47888
48113
  }
47889
48114
 
48115
+ //#endregion
48116
+ //#region src/space/pending-outbound-status.ts
48117
+ const PREVIEW_MAX_VISIBLE_CHARS$1 = 240;
48118
+ const PREVIEW_MIN_VISIBLE_CHARS$1 = 24;
48119
+ const PREVIEW_ELLIPSIS$1 = "...";
48120
+ const STATUS_SYSTEM_PREFIX = "* 📣 system · ";
48121
+ const STATUS_PREVIEW_PREFIX = "sending: ";
48122
+ function formatPendingOutboundStatusText(input) {
48123
+ const normalizedText = normalizePendingOutboundText(input.pendingText);
48124
+ if (!normalizedText) return "sending...";
48125
+ const targetLabel = resolveSingleMentionTargetLabel(normalizedText);
48126
+ if (targetLabel) return `Sending to ${targetLabel}...`;
48127
+ return `${STATUS_PREVIEW_PREFIX}${truncatePreviewHead$1(normalizedText, resolvePendingOutboundPreviewWidth({ terminalColumns: input.terminalColumns }))}`;
48128
+ }
48129
+ function buildPendingOutboundDispatchRowDrafts(input) {
48130
+ const normalizedText = normalizePendingOutboundText(input.pendingText);
48131
+ if (!normalizedText) return [{
48132
+ statusText: "sending...",
48133
+ targetLabel: "",
48134
+ targetWakeToken: null
48135
+ }];
48136
+ const uniqueMentionTokens = resolveUniqueMentionTokens(normalizedText);
48137
+ if (uniqueMentionTokens.length === 0) return [{
48138
+ statusText: formatPendingOutboundStatusText(input),
48139
+ targetLabel: "",
48140
+ targetWakeToken: null
48141
+ }];
48142
+ return uniqueMentionTokens.map((mentionToken) => {
48143
+ const targetLabel = `@${mentionToken}`;
48144
+ return {
48145
+ statusText: `Sending to ${targetLabel}...`,
48146
+ targetLabel,
48147
+ targetWakeToken: mentionToken
48148
+ };
48149
+ });
48150
+ }
48151
+ function normalizePendingOutboundText(value) {
48152
+ return sanitizeTerminalDisplayText(value, "single-line").replace(/\s+/g, " ").trim();
48153
+ }
48154
+ function resolveSingleMentionTargetLabel(value) {
48155
+ const uniqueMentionTokens = resolveUniqueMentionTokens(value);
48156
+ const mentionToken = uniqueMentionTokens.length === 1 ? uniqueMentionTokens[0] : null;
48157
+ if (!mentionToken) return null;
48158
+ return mentionToken.startsWith("@") ? mentionToken : `@${mentionToken}`;
48159
+ }
48160
+ function resolvePendingOutboundPreviewWidth(input) {
48161
+ const prefixWidth = stringWidth(`${STATUS_SYSTEM_PREFIX}${STATUS_PREVIEW_PREFIX}`);
48162
+ if (input.terminalColumns === null) return PREVIEW_MAX_VISIBLE_CHARS$1;
48163
+ const availableWidth = input.terminalColumns - prefixWidth;
48164
+ return Math.max(PREVIEW_MIN_VISIBLE_CHARS$1, Math.min(PREVIEW_MAX_VISIBLE_CHARS$1, availableWidth));
48165
+ }
48166
+ function truncatePreviewHead$1(value, maxWidth) {
48167
+ if (stringWidth(value) <= maxWidth) return value;
48168
+ const truncatedWidth = Math.max(0, maxWidth - stringWidth(PREVIEW_ELLIPSIS$1));
48169
+ let head = "";
48170
+ for (const char of value) {
48171
+ if (stringWidth(head) + stringWidth(char) > truncatedWidth) break;
48172
+ head += char;
48173
+ }
48174
+ return `${head}${PREVIEW_ELLIPSIS$1}`;
48175
+ }
48176
+ function resolveUniqueMentionTokens(value) {
48177
+ const seenMentionTokens = /* @__PURE__ */ new Set();
48178
+ const uniqueMentionTokens = [];
48179
+ for (const mentionToken of extractMentionTokensFromText(value)) {
48180
+ const dedupeKey = mentionToken.toLowerCase();
48181
+ if (seenMentionTokens.has(dedupeKey)) continue;
48182
+ seenMentionTokens.add(dedupeKey);
48183
+ uniqueMentionTokens.push(mentionToken);
48184
+ }
48185
+ return uniqueMentionTokens;
48186
+ }
48187
+
47890
48188
  //#endregion
47891
48189
  //#region src/space/preflight.ts
47892
48190
  const HTTP_STATUS_PREFIX_RE = /^HTTP\s+(\d{3}):\s*(.*)$/i;
@@ -48218,7 +48516,7 @@ var SpaceSessionRuntime = class {
48218
48516
  #input;
48219
48517
  #listeners = /* @__PURE__ */ new Set();
48220
48518
  #bufferedLiveEvents = [];
48221
- #pendingSentTexts = [];
48519
+ #pendingSentMessages = [];
48222
48520
  #ws = null;
48223
48521
  #started = false;
48224
48522
  #stopRequested = false;
@@ -48290,22 +48588,29 @@ var SpaceSessionRuntime = class {
48290
48588
  if (!this.#ws) {
48291
48589
  this.#emit({
48292
48590
  type: "send.failed",
48591
+ clientMessageId: "unknown-client-message",
48293
48592
  text,
48294
48593
  error: "space connection is not started"
48295
48594
  });
48296
48595
  return false;
48297
48596
  }
48597
+ const clientMessageId = crypto.randomUUID();
48298
48598
  try {
48299
- this.#ws.send(JSON.stringify(makeTextSignal(text)));
48300
- this.#rememberPendingSentText(text);
48599
+ this.#ws.send(JSON.stringify(makeTextSignal(text, { meta: { clientMessageId } })));
48600
+ this.#rememberPendingSentMessage({
48601
+ clientMessageId,
48602
+ text
48603
+ });
48301
48604
  this.#emit({
48302
48605
  type: "send.queued",
48606
+ clientMessageId,
48303
48607
  text
48304
48608
  });
48305
48609
  return true;
48306
48610
  } catch (error) {
48307
48611
  this.#emit({
48308
48612
  type: "send.failed",
48613
+ clientMessageId,
48309
48614
  text,
48310
48615
  error: this.#input.formatError(error)
48311
48616
  });
@@ -48364,20 +48669,34 @@ var SpaceSessionRuntime = class {
48364
48669
  source
48365
48670
  });
48366
48671
  }
48367
- #rememberPendingSentText(text) {
48672
+ #rememberPendingSentMessage(message) {
48368
48673
  const pendingLimit = this.#input.pendingSendLimit ?? DEFAULT_PENDING_SEND_LIMIT;
48369
- if (this.#pendingSentTexts.length >= pendingLimit) this.#pendingSentTexts.shift();
48370
- this.#pendingSentTexts.push(text);
48674
+ if (this.#pendingSentMessages.length >= pendingLimit) this.#pendingSentMessages.shift();
48675
+ this.#pendingSentMessages.push(message);
48371
48676
  }
48372
48677
  #maybeEmitSendConfirmed(event) {
48373
48678
  if (event.type !== "signal.text") return;
48374
48679
  const profileId = String(event.profile?.profileId ?? "").trim();
48375
48680
  if (!profileId || profileId !== this.#input.selfProfileId) return;
48376
48681
  const text = typeof event.data?.text === "string" ? event.data.text : "";
48377
- if (this.#pendingSentTexts[0] !== text) return;
48378
- this.#pendingSentTexts.shift();
48682
+ const clientMessageId = resolveClientMessageId(event);
48683
+ if (clientMessageId) {
48684
+ const matchingIndex = this.#pendingSentMessages.findIndex((message) => message.clientMessageId === clientMessageId);
48685
+ if (matchingIndex < 0) return;
48686
+ this.#pendingSentMessages.splice(matchingIndex, 1);
48687
+ this.#emit({
48688
+ type: "send.confirmed",
48689
+ clientMessageId,
48690
+ text,
48691
+ event
48692
+ });
48693
+ return;
48694
+ }
48695
+ if (this.#pendingSentMessages[0]?.text !== text) return;
48696
+ const pendingMessage = this.#pendingSentMessages.shift() ?? null;
48379
48697
  this.#emit({
48380
48698
  type: "send.confirmed",
48699
+ clientMessageId: pendingMessage?.clientMessageId ?? null,
48381
48700
  text,
48382
48701
  event
48383
48702
  });
@@ -48406,6 +48725,12 @@ function safeJsonParse$2(value) {
48406
48725
  return null;
48407
48726
  }
48408
48727
  }
48728
+ function resolveClientMessageId(event) {
48729
+ const meta = event.data && typeof event.data === "object" && !Array.isArray(event.data) ? event.data.meta : null;
48730
+ if (!(meta && typeof meta === "object") || Array.isArray(meta)) return null;
48731
+ const clientMessageId = String(meta.clientMessageId ?? "").trim();
48732
+ return clientMessageId.length > 0 ? clientMessageId : null;
48733
+ }
48409
48734
 
48410
48735
  //#endregion
48411
48736
  //#region src/space/session-profile.ts
@@ -48777,11 +49102,15 @@ const TRANSCRIPT_BUBBLE_VERTICAL_PADDING = 1;
48777
49102
  const TRANSCRIPT_BUBBLE_META_GAP_LINES = 1;
48778
49103
  const TRANSCRIPT_BUBBLE_BODY_PREFIX = "› ";
48779
49104
  const TRANSCRIPT_BUBBLE_BODY_CONTINUATION_PREFIX = " ";
49105
+ const TRANSCRIPT_BUBBLE_REPLY_CONNECTED_BODY_PREFIX = "╰─› ";
49106
+ const TRANSCRIPT_BUBBLE_REPLY_CONNECTED_BODY_CONTINUATION_PREFIX = " ";
49107
+ const TRANSCRIPT_REPLY_PREVIEW_MAX_VISIBLE_WIDTH = 24;
48780
49108
  const TRANSCRIPT_HUMAN_BUBBLE_BACKGROUND = buildAnsiBackgroundColor(ATS_COMPOSER_SURFACE_BG_RGB);
48781
49109
  const TRANSCRIPT_NEUTRAL_BUBBLE_BACKGROUND = "\x1B[48;2;33;33;33m";
48782
49110
  const ANSI_BACKGROUND_RESET = "\x1B[49m";
48783
49111
  const ANSI_ESCAPE_PATTERN = "(?:\\u001B\\[[0-9;]*m)*";
48784
49112
  const TRANSCRIPT_GROUP_KIND_PATTERN = /^profile:(human|agent|unknown):/u;
49113
+ const PROFILE_GROUP_KEY_PATTERN = /^profile:(human|agent|unknown):(.+)$/u;
48785
49114
  const PRESENCE_TRACE_JOINED_LABEL = "joined";
48786
49115
  const PRESENCE_TRACE_LEFT_LABEL = "left";
48787
49116
  const PRESENCE_TRACE_JOIN_LABEL = "join";
@@ -48945,60 +49274,119 @@ function canCoalesceAdjacentHumanPlainTextBlocks(previousBlock, nextBlock) {
48945
49274
  return previousBlock.groupKey === nextBlock.groupKey && previousBlock.speakerProfileId === nextBlock.speakerProfileId && previousBlock.speakerKind === nextBlock.speakerKind && previousBlock.highlightKind === nextBlock.highlightKind;
48946
49275
  }
48947
49276
  function buildHumanLogsSections(input) {
48948
- const presenceLines = [...input.firstJoinBlocks.flatMap((block) => buildPresenceFirstJoinRows(block)), ...input.allBlocks.flatMap((block) => {
49277
+ const presenceItems = [...input.firstJoinBlocks.map((block, index) => ({
49278
+ id: `presence:first-join:${String(index)}`,
49279
+ lines: buildPresenceFirstJoinRows(block)
49280
+ })), ...input.allBlocks.flatMap((block, index) => {
48949
49281
  if (block.kind !== "presence_trace_group") return [];
48950
- return [buildPresenceTraceRowText(block)];
49282
+ return [{
49283
+ id: `presence:trace:${String(index)}`,
49284
+ lines: [buildPresenceTraceRowText(block)]
49285
+ }];
48951
49286
  })];
48952
- const membershipLines = input.allBlocks.flatMap((block) => {
49287
+ const membershipItems = input.allBlocks.flatMap((block, index) => {
48953
49288
  if (block.kind !== "membership_trace_group") return [];
48954
- return buildMembershipTraceRows(block);
48955
- });
48956
- const systemLines = input.allBlocks.flatMap((block) => {
48957
- if (block.kind !== "system_group") return [];
48958
- return buildSystemClusterRowsFromSystemLines(block.lines);
49289
+ return [{
49290
+ id: `membership:${String(index)}`,
49291
+ lines: buildMembershipTraceRows(block)
49292
+ }];
48959
49293
  });
48960
49294
  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
- }
49295
+ buildHumanLogsSection("system", "System", input.allBlocks.flatMap((block, index) => {
49296
+ if (block.kind !== "system_group") return [];
49297
+ return [{
49298
+ id: `system:${String(index)}`,
49299
+ lines: buildSystemClusterRowsFromSystemLines(block.lines)
49300
+ }];
49301
+ })),
49302
+ buildHumanLogsSection("membership", "Membership", membershipItems),
49303
+ buildHumanLogsSection("presence", "Presence", presenceItems)
48976
49304
  ];
48977
49305
  }
49306
+ function buildHumanLogsSection(kind, title, items) {
49307
+ return {
49308
+ kind,
49309
+ title,
49310
+ items,
49311
+ lines: items.flatMap((item) => item.lines)
49312
+ };
49313
+ }
48978
49314
  function buildPresenceFirstJoinBlocks(items, membersSnapshot) {
48979
49315
  const blocks = [];
48980
49316
  const seenActorKeys = /* @__PURE__ */ new Set();
49317
+ const actorKeysWithPriorTranscriptActivity = /* @__PURE__ */ new Set();
48981
49318
  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);
49319
+ const nextBlock = buildPresenceFirstJoinBlock({
49320
+ item,
49321
+ membersSnapshot,
49322
+ seenActorKeys,
49323
+ actorKeysWithPriorTranscriptActivity
49324
+ });
49325
+ if (nextBlock) blocks.push(nextBlock);
49326
+ registerTranscriptActorActivity(item, actorKeysWithPriorTranscriptActivity);
48999
49327
  }
49000
49328
  return blocks;
49001
49329
  }
49330
+ function buildPresenceFirstJoinBlock(input) {
49331
+ if (!(isPresenceTranscriptItem(input.item) && input.item.presenceAction === "join")) return null;
49332
+ const actorKey = resolvePresenceActorKey(input.item);
49333
+ if (!actorKey || input.seenActorKeys.has(actorKey)) return null;
49334
+ input.seenActorKeys.add(actorKey);
49335
+ if (!shouldRenderPresenceFirstJoinBlock({
49336
+ item: input.item,
49337
+ actorKey,
49338
+ membersSnapshot: input.membersSnapshot,
49339
+ actorKeysWithPriorTranscriptActivity: input.actorKeysWithPriorTranscriptActivity
49340
+ })) return null;
49341
+ const actorIdentity = resolvePresenceActorIdentity(input.item, input.membersSnapshot);
49342
+ return {
49343
+ kind: "presence_first_join_group",
49344
+ groupKey: input.item.groupKey,
49345
+ actorKey,
49346
+ actorProfileId: input.item.actorProfileId?.trim() || null,
49347
+ actorKind: input.item.actorKind ?? "unknown",
49348
+ actorAvatar: input.item.actorAvatar?.trim() || resolvePresenceActorAvatar(input.item),
49349
+ actorLabel: input.item.actorLabel?.trim() || "unknown",
49350
+ actorOwnerUserId: actorIdentity.ownerUserId,
49351
+ actorOwnerName: actorIdentity.ownerName,
49352
+ ts: typeof input.item.ts === "number" ? input.item.ts : 0
49353
+ };
49354
+ }
49355
+ function shouldRenderPresenceFirstJoinBlock(input) {
49356
+ if (input.actorKeysWithPriorTranscriptActivity.has(input.actorKey)) return false;
49357
+ const knownFirstEnteredAtMs = resolvePresenceActorFirstEnteredAtMs(input.item, input.membersSnapshot);
49358
+ if (knownFirstEnteredAtMs === null) return true;
49359
+ const joinTs = typeof input.item.ts === "number" ? input.item.ts : null;
49360
+ return joinTs !== null && joinTs === knownFirstEnteredAtMs;
49361
+ }
49362
+ function registerTranscriptActorActivity(item, actorKeys) {
49363
+ for (const actorKey of resolveTranscriptActorActivityKeys(item)) actorKeys.add(actorKey);
49364
+ }
49365
+ function resolveTranscriptActorActivityKeys(item) {
49366
+ if (isPresenceTranscriptItem(item)) {
49367
+ const actorKey = resolvePresenceActorKey(item);
49368
+ return actorKey ? [actorKey] : [];
49369
+ }
49370
+ if (isMembershipNoticeTranscriptItem(item)) {
49371
+ const notice = resolveMembershipNoticePayload(item);
49372
+ if (!notice) return [];
49373
+ const actorKey = resolveMembershipActorKey(notice);
49374
+ return actorKey ? [actorKey] : [];
49375
+ }
49376
+ const actorKey = resolveTranscriptContentActorKey(item);
49377
+ return actorKey ? [actorKey] : [];
49378
+ }
49379
+ function resolveTranscriptContentActorKey(item) {
49380
+ const itemProfileId = item.profile?.profileId?.trim();
49381
+ if (itemProfileId) return itemProfileId;
49382
+ const groupProfileId = resolveProfileIdFromGroupKey(item.groupKey);
49383
+ if (groupProfileId) return groupProfileId;
49384
+ const itemProfileName = item.profile?.profileName?.trim();
49385
+ if ((item.profile?.kind === "human" || item.profile?.kind === "agent" || item.profile?.kind === "unknown") && itemProfileName) return `${item.profile.kind}:${itemProfileName}`;
49386
+ const fallbackMatch = PROFILE_GROUP_KEY_PATTERN.exec(item.groupKey);
49387
+ if (!fallbackMatch) return "";
49388
+ return `${fallbackMatch[1]}:${fallbackMatch[2]}`;
49389
+ }
49002
49390
  function attachCurrentPresenceStatusToLastMessageCards(blocks, membersSnapshot, items) {
49003
49391
  const lastMessageLocationByActorKey = /* @__PURE__ */ new Map();
49004
49392
  const currentStatusByActorKey = buildCurrentPresenceStatusByActorKey({
@@ -49356,6 +49744,10 @@ function createTranscriptBubbleMessage(input) {
49356
49744
  speakerIdentity: input.speakerIdentity,
49357
49745
  spaceMembersSnapshot: input.spaceMembersSnapshot
49358
49746
  });
49747
+ const replyLine = resolveTranscriptBubbleReplyLine({
49748
+ replyRef: input.item.replyRef,
49749
+ membersSnapshot: input.spaceMembersSnapshot ?? null
49750
+ });
49359
49751
  return {
49360
49752
  primaryLine: rawLines[0] ?? "",
49361
49753
  headerBaseLeading,
@@ -49367,6 +49759,7 @@ function createTranscriptBubbleMessage(input) {
49367
49759
  }),
49368
49760
  headerStatusBadge: null,
49369
49761
  headerTrailing: header.trailing,
49762
+ ...replyLine ? { replyLine } : {},
49370
49763
  bodyLines,
49371
49764
  bodyDetailLines,
49372
49765
  metaLines,
@@ -49465,12 +49858,18 @@ function renderTranscriptBubbleMessage(message, block, contentWidth) {
49465
49858
  contentWidth
49466
49859
  });
49467
49860
  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);
49861
+ if (message.replyLine) {
49862
+ if (headerLines.length > 0) appendBubblePaddingLines(lines, TRANSCRIPT_BUBBLE_META_GAP_LINES, block, contentWidth);
49863
+ for (const wrappedLine of wrapBubbleLine(pc.dim(message.replyLine), contentWidth)) lines.push(renderBubbleLine(wrappedLine, block, contentWidth));
49864
+ }
49865
+ if (message.bodyLines.length > 0 && headerLines.length > 0 && !message.replyLine) appendBubblePaddingLines(lines, TRANSCRIPT_BUBBLE_META_GAP_LINES, block, contentWidth);
49866
+ const bodyPrefixes = resolveTranscriptBubbleBodyPrefixes(Boolean(message.replyLine));
49469
49867
  for (const [index, bodyLine] of message.bodyLines.entries()) {
49470
49868
  const wrappedBodyLines = wrapBubbleBodyLine({
49471
49869
  line: bodyLine,
49472
49870
  contentWidth,
49473
- withLeadPrefix: index === 0
49871
+ leadPrefix: index === 0 ? bodyPrefixes.firstLinePrefix : bodyPrefixes.otherLinePrefix,
49872
+ continuationPrefix: bodyPrefixes.otherLinePrefix
49474
49873
  });
49475
49874
  for (const wrappedLine of wrappedBodyLines) lines.push(renderBubbleLine(wrappedLine, block, contentWidth));
49476
49875
  }
@@ -49513,6 +49912,49 @@ function buildTranscriptBubbleHeaderAuxLeading(input) {
49513
49912
  }, { spaceMembersSnapshot: input.spaceMembersSnapshot }));
49514
49913
  return headerSegments.length > 0 ? headerSegments.join("") : null;
49515
49914
  }
49915
+ function resolveTranscriptBubbleReplyLine(input) {
49916
+ const replyRef = input.replyRef;
49917
+ if (!replyRef) return null;
49918
+ const profileLabel = resolveTranscriptReplyProfileLabel({
49919
+ replyRef,
49920
+ membersSnapshot: input.membersSnapshot
49921
+ });
49922
+ const previewText = resolveTranscriptReplyPreviewText(replyRef.previewText);
49923
+ return previewText ? `reply to ${profileLabel} · ${previewText}` : `reply to ${profileLabel}`;
49924
+ }
49925
+ function resolveTranscriptReplyProfileLabel(input) {
49926
+ const profileId = sanitizeTranscriptReplyDisplayText(input.replyRef.profileId);
49927
+ if (profileId && input.membersSnapshot) {
49928
+ const humanMatch = input.membersSnapshot.humans.find((member) => member.profileId === profileId);
49929
+ const agentMatch = input.membersSnapshot.agents.find((member) => member.profileId === profileId);
49930
+ const snapshotName = humanMatch?.profileName?.trim() || agentMatch?.profileName?.trim() || "";
49931
+ if (snapshotName) return snapshotName;
49932
+ }
49933
+ return sanitizeTranscriptReplyDisplayText(input.replyRef.profileName) || profileId || "unknown";
49934
+ }
49935
+ function resolveTranscriptReplyPreviewText(value) {
49936
+ const sanitizedPreview = sanitizeTranscriptReplyDisplayText(value);
49937
+ if (!sanitizedPreview) return "";
49938
+ return truncateTranscriptReplyPreview(sanitizedPreview, TRANSCRIPT_REPLY_PREVIEW_MAX_VISIBLE_WIDTH);
49939
+ }
49940
+ function sanitizeTranscriptReplyDisplayText(value) {
49941
+ return sanitizeTerminalDisplayText(value, "single-line").replace(/\s+/gu, " ").trim();
49942
+ }
49943
+ function truncateTranscriptReplyPreview(value, maxVisibleWidth) {
49944
+ if (measureVisibleWidth$1(value) <= maxVisibleWidth) return value;
49945
+ if (maxVisibleWidth <= 1) return "…";
49946
+ const ellipsis = "…";
49947
+ const targetWidth = maxVisibleWidth - measureVisibleWidth$1(ellipsis);
49948
+ let result = "";
49949
+ let currentWidth = 0;
49950
+ for (const char of value) {
49951
+ const nextWidth = currentWidth + stringWidth(char);
49952
+ if (nextWidth > targetWidth) break;
49953
+ result += char;
49954
+ currentWidth = nextWidth;
49955
+ }
49956
+ return `${result.trimEnd()}${ellipsis}`;
49957
+ }
49516
49958
  function joinTranscriptBubbleHeaderLeading(input) {
49517
49959
  const segments = [input.baseLeading];
49518
49960
  if (input.auxLeading) segments.push(input.auxLeading);
@@ -49616,7 +50058,7 @@ function buildPresenceFirstJoinRows(block) {
49616
50058
  }
49617
50059
  function buildPresenceFirstJoinRowText(block) {
49618
50060
  return [
49619
- formatPresenceTraceClock(block.ts),
50061
+ formatPresenceTraceDateTime(block.ts),
49620
50062
  "·",
49621
50063
  buildSystemActorLabel({
49622
50064
  actorAvatar: block.actorAvatar,
@@ -49709,10 +50151,20 @@ function buildSystemActorLabel(input) {
49709
50151
  return `${input.actorAvatar ? `${input.actorAvatar} ` : ""}${input.actorLabel}`;
49710
50152
  }
49711
50153
  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}`;
50154
+ const startDateLabel = formatPresenceTraceDate(block.startTs);
50155
+ const startClockLabel = formatPresenceTraceClock(block.startTs);
50156
+ const endDateLabel = formatPresenceTraceDate(block.endTs);
50157
+ const endClockLabel = formatPresenceTraceClock(block.endTs);
50158
+ if ((block.count ?? 1) <= 1 || startDateLabel === endDateLabel && startClockLabel === endClockLabel) return `${startDateLabel} ${startClockLabel}`;
50159
+ if (startDateLabel === endDateLabel) return `${startDateLabel} ${startClockLabel}–${endClockLabel}`;
50160
+ return `${startDateLabel} ${startClockLabel}–${endDateLabel} ${endClockLabel}`;
50161
+ }
50162
+ function formatPresenceTraceDateTime(ts) {
50163
+ return `${formatPresenceTraceDate(ts)} ${formatPresenceTraceClock(ts)}`;
50164
+ }
50165
+ function formatPresenceTraceDate(ts) {
50166
+ const date = new Date(ts);
50167
+ return `${`${date.getFullYear()}`}${`${date.getMonth() + 1}`.padStart(2, "0")}${`${date.getDate()}`.padStart(2, "0")}`;
49716
50168
  }
49717
50169
  function formatPresenceTraceClock(ts) {
49718
50170
  const date = new Date(ts);
@@ -49734,14 +50186,23 @@ function wrapBubbleLine(line, contentWidth) {
49734
50186
  }).split("\n");
49735
50187
  }
49736
50188
  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);
50189
+ const leadPrefix = input.leadPrefix === TRANSCRIPT_BUBBLE_BODY_CONTINUATION_PREFIX || input.leadPrefix === TRANSCRIPT_BUBBLE_REPLY_CONNECTED_BODY_CONTINUATION_PREFIX ? input.leadPrefix : renderAtsBrandAccent(input.leadPrefix);
50190
+ const prefixWidth = stringWidth(input.leadPrefix);
49739
50191
  const prefixedContentWidth = Math.max(1, input.contentWidth - prefixWidth);
49740
50192
  return wrapAnsi(input.line, prefixedContentWidth, {
49741
50193
  hard: true,
49742
50194
  trim: false,
49743
50195
  wordWrap: true
49744
- }).split("\n").map((wrappedLine, index) => index === 0 ? `${leadPrefix}${wrappedLine}` : `${TRANSCRIPT_BUBBLE_BODY_CONTINUATION_PREFIX}${wrappedLine}`);
50196
+ }).split("\n").map((wrappedLine, index) => index === 0 ? `${leadPrefix}${wrappedLine}` : `${input.continuationPrefix}${wrappedLine}`);
50197
+ }
50198
+ function resolveTranscriptBubbleBodyPrefixes(hasReplyLine) {
50199
+ return hasReplyLine ? {
50200
+ firstLinePrefix: TRANSCRIPT_BUBBLE_REPLY_CONNECTED_BODY_PREFIX,
50201
+ otherLinePrefix: TRANSCRIPT_BUBBLE_REPLY_CONNECTED_BODY_CONTINUATION_PREFIX
50202
+ } : {
50203
+ firstLinePrefix: TRANSCRIPT_BUBBLE_BODY_PREFIX,
50204
+ otherLinePrefix: TRANSCRIPT_BUBBLE_BODY_CONTINUATION_PREFIX
50205
+ };
49745
50206
  }
49746
50207
  function renderBubbleLine(line, block, contentWidth) {
49747
50208
  const visibleWidth = measureVisibleWidth$1(line);
@@ -49894,25 +50355,26 @@ function resolvePresenceActorKey(item) {
49894
50355
  return "";
49895
50356
  }
49896
50357
  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 {};
50358
+ const matchedSnapshot = resolvePresenceActorMemberSnapshot(item, membersSnapshot);
50359
+ if (!matchedSnapshot) return {};
50360
+ return {
50361
+ ownerUserId: matchedSnapshot.ownerUserId,
50362
+ ownerName: matchedSnapshot.ownerName
50363
+ };
50364
+ }
50365
+ function resolvePresenceActorFirstEnteredAtMs(item, membersSnapshot) {
50366
+ const firstEnteredAt = resolvePresenceActorMemberSnapshot(item, membersSnapshot)?.firstEnteredAt ?? null;
50367
+ if (!firstEnteredAt) return null;
50368
+ const parsed = Date.parse(firstEnteredAt);
50369
+ return Number.isFinite(parsed) ? parsed : null;
50370
+ }
50371
+ function resolvePresenceActorMemberSnapshot(item, membersSnapshot) {
50372
+ if (!membersSnapshot) return null;
50373
+ const actorProfileId = item.actorProfileId?.trim() || "";
50374
+ const actorLabel = item.actorLabel?.trim().toLowerCase() || "";
50375
+ if (item.actorKind === "agent") return membersSnapshot.agents.find((member) => member.profileId === actorProfileId || !actorProfileId && actorLabel.length > 0 && member.profileName.trim().toLowerCase() === actorLabel) ?? null;
50376
+ if (item.actorKind === "human") return membersSnapshot.humans.find((member) => member.profileId === actorProfileId || !actorProfileId && actorLabel.length > 0 && member.profileName.trim().toLowerCase() === actorLabel) ?? null;
50377
+ return null;
49916
50378
  }
49917
50379
  function resolveMembershipActorKey(notice) {
49918
50380
  if (notice.actorProfileId?.trim()) return notice.actorProfileId.trim();
@@ -49996,69 +50458,125 @@ function resolveSystemClusterContentWidth(width) {
49996
50458
 
49997
50459
  //#endregion
49998
50460
  //#region src/space/view/build-composer-activity-view-state.ts
50461
+ const MAX_COMPOSER_ACTIVITY_ROWS = 2;
49999
50462
  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",
50463
+ const rowCandidates = buildComposerActivityRowCandidates({
50464
+ nowMs: source.nowMs,
50465
+ rows: source.rows
50466
+ });
50467
+ const visibleRows = selectVisibleRows(rowCandidates);
50468
+ const leadRow = visibleRows.at(-1) ?? null;
50469
+ const actors = visibleRows.flatMap((row) => row.actors);
50470
+ const overflowCount = Math.max(0, rowCandidates.length - visibleRows.length);
50471
+ if (!leadRow) return {
50472
+ visible: false,
50473
+ mode: "idle",
50474
+ rows: [],
50475
+ overflowCount: 0,
50007
50476
  actors: [],
50008
50477
  leadActor: null,
50009
50478
  elapsedSeconds: null,
50010
50479
  previewText: "",
50011
50480
  hint: null,
50012
- pendingOutboundText,
50013
50481
  spaceMembersSnapshot: spaceMembersSnapshot ?? null
50014
50482
  };
50015
- const previewText = leadActor?.latestPreviewText.trim() ?? "";
50016
50483
  return {
50017
50484
  visible: true,
50018
- mode: previewText ? "streaming" : "replying",
50485
+ mode: leadRow.mode,
50486
+ rows: visibleRows,
50487
+ overflowCount,
50019
50488
  actors,
50020
- leadActor,
50021
- elapsedSeconds: leadActor ? Math.max(0, Math.floor((source.nowMs - leadActor.startedAtMs) / 1e3)) : null,
50022
- previewText,
50023
- hint: null,
50024
- pendingOutboundText,
50489
+ leadActor: leadRow.leadActor,
50490
+ elapsedSeconds: leadRow.elapsedSeconds,
50491
+ previewText: leadRow.previewText,
50492
+ hint: leadRow.hint,
50025
50493
  spaceMembersSnapshot: spaceMembersSnapshot ?? null
50026
50494
  };
50027
50495
  }
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
- });
50496
+ function buildComposerActivityRowCandidates(input) {
50497
+ return input.rows.map((row) => toComposerActivityRowCandidate({
50498
+ nowMs: input.nowMs,
50499
+ row
50500
+ }));
50501
+ }
50502
+ function toComposerActivityRowCandidate(input) {
50503
+ const actor = toDispatchActivityActor(input.row);
50504
+ if (input.row.stage === "replying") {
50505
+ const previewText = input.row.latestPreviewText.trim();
50506
+ return {
50507
+ key: input.row.rowId,
50508
+ mode: previewText ? "streaming" : "replying",
50509
+ targetLabel: input.row.targetLabel,
50510
+ actors: actor ? [actor] : [],
50511
+ leadActor: actor,
50512
+ elapsedSeconds: Math.max(0, Math.floor((input.nowMs - input.row.createdAtMs) / 1e3)),
50513
+ previewText,
50514
+ hint: null,
50515
+ previewUpdatedAtMs: input.row.latestPreviewUpdatedAtMs ?? Number.NEGATIVE_INFINITY,
50516
+ startedAtMs: input.row.createdAtMs,
50517
+ updatedAtMs: input.row.updatedAtMs
50518
+ };
50052
50519
  }
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
- });
50520
+ if (input.row.stage === "sending") return {
50521
+ key: input.row.rowId,
50522
+ mode: "sending",
50523
+ targetLabel: input.row.targetLabel,
50524
+ actors: [],
50525
+ leadActor: null,
50526
+ elapsedSeconds: Math.max(0, Math.floor((input.nowMs - input.row.createdAtMs) / 1e3)),
50527
+ previewText: "",
50528
+ hint: input.row.statusText || "sending...",
50529
+ previewUpdatedAtMs: Number.NEGATIVE_INFINITY,
50530
+ startedAtMs: input.row.createdAtMs,
50531
+ updatedAtMs: input.row.updatedAtMs
50532
+ };
50533
+ let mode = "warning";
50534
+ if (input.row.stage === "dispatching") mode = "dispatching";
50535
+ else if (input.row.stage === "retrying") mode = "retrying";
50536
+ return {
50537
+ key: input.row.rowId,
50538
+ mode,
50539
+ targetLabel: input.row.targetLabel,
50540
+ actors: actor ? [actor] : [],
50541
+ leadActor: actor,
50542
+ elapsedSeconds: Math.max(0, Math.floor((input.nowMs - input.row.createdAtMs) / 1e3)),
50543
+ previewText: "",
50544
+ hint: input.row.warningText || input.row.statusText || resolveDispatchActivityHintFallback(input.row),
50545
+ previewUpdatedAtMs: Number.NEGATIVE_INFINITY,
50546
+ startedAtMs: input.row.createdAtMs,
50547
+ updatedAtMs: input.row.updatedAtMs
50548
+ };
50549
+ }
50550
+ function selectVisibleRows(rowCandidates) {
50551
+ return [...rowCandidates].sort(compareComposerActivityRowsByRecencyDesc).slice(0, MAX_COMPOSER_ACTIVITY_ROWS).sort(compareComposerActivityRowsByRenderOrderAsc).map(({ previewUpdatedAtMs, startedAtMs, updatedAtMs, ...row }) => row);
50552
+ }
50553
+ function compareComposerActivityRowsByRecencyDesc(left, right) {
50554
+ if (right.updatedAtMs !== left.updatedAtMs) return right.updatedAtMs - left.updatedAtMs;
50555
+ if (right.previewUpdatedAtMs !== left.previewUpdatedAtMs) return right.previewUpdatedAtMs - left.previewUpdatedAtMs;
50556
+ if (right.startedAtMs !== left.startedAtMs) return right.startedAtMs - left.startedAtMs;
50557
+ return left.key.localeCompare(right.key);
50059
50558
  }
50060
- function selectLeadActor(actors) {
50061
- return actors[0] ?? null;
50559
+ function compareComposerActivityRowsByRenderOrderAsc(left, right) {
50560
+ if (left.updatedAtMs !== right.updatedAtMs) return left.updatedAtMs - right.updatedAtMs;
50561
+ if (left.previewUpdatedAtMs !== right.previewUpdatedAtMs) return left.previewUpdatedAtMs - right.previewUpdatedAtMs;
50562
+ if (left.startedAtMs !== right.startedAtMs) return left.startedAtMs - right.startedAtMs;
50563
+ return left.key.localeCompare(right.key);
50564
+ }
50565
+ function toDispatchActivityActor(row) {
50566
+ if (!row.targetProfileId) return null;
50567
+ return {
50568
+ profileId: row.targetProfileId,
50569
+ label: row.targetLabel,
50570
+ startedAtMs: row.createdAtMs,
50571
+ updatedAtMs: row.updatedAtMs,
50572
+ latestPreviewText: row.latestPreviewText,
50573
+ latestPreviewUpdatedAtMs: row.latestPreviewUpdatedAtMs
50574
+ };
50575
+ }
50576
+ function resolveDispatchActivityHintFallback(row) {
50577
+ if (row.stage === "dispatching") return `${row.targetLabel} is dispatching...`;
50578
+ if (row.stage === "retrying") return `${row.targetLabel} is retrying...`;
50579
+ return `${row.targetLabel} couldn't reply right now`;
50062
50580
  }
50063
50581
 
50064
50582
  //#endregion
@@ -50185,6 +50703,11 @@ function buildSpaceSessionViewState(input) {
50185
50703
  sessionProfile: context.profile
50186
50704
  });
50187
50705
  const logsBlocks = buildLogsPanelBlocks({ sections: humanTranscriptProjection.logsSections });
50706
+ const logsSearchableList = buildLogsSearchableListViewState({
50707
+ activeItemId: screenState.overlay.interaction.activeItemId,
50708
+ query: screenState.overlay.interaction.query,
50709
+ sections: humanTranscriptProjection.logsSections
50710
+ });
50188
50711
  const membersBlocks = buildMembersPanelBlocks({
50189
50712
  snapshot: screenState.members.snapshot,
50190
50713
  refreshError: screenState.members.refreshError
@@ -50204,7 +50727,10 @@ function buildSpaceSessionViewState(input) {
50204
50727
  space: spaceBlocks
50205
50728
  },
50206
50729
  headerMetaTextByKind: { members: buildMembersPanelUpdatedAtLabel(screenState.members.updatedAtMs) },
50207
- searchableListByKind: { members: membersSearchableList }
50730
+ searchableListByKind: {
50731
+ logs: logsSearchableList,
50732
+ members: membersSearchableList
50733
+ }
50208
50734
  });
50209
50735
  const transcriptBlocks = humanTranscriptProjection.transcriptBlocks;
50210
50736
  const spaceSummary = buildSpaceSummaryViewState({
@@ -50213,8 +50739,7 @@ function buildSpaceSessionViewState(input) {
50213
50739
  });
50214
50740
  const composerActivity = buildComposerActivityViewState(resources?.composerActivity ?? {
50215
50741
  nowMs: Date.now(),
50216
- pendingOutboundText: "",
50217
- replyingDispatches: []
50742
+ rows: []
50218
50743
  }, screenState.members.snapshot);
50219
50744
  const visibleComposerActivity = composerVisible ? composerActivity : {
50220
50745
  ...composerActivity,
@@ -50465,19 +50990,20 @@ const STATUS_TRAILING_DOT_FRAMES = [
50465
50990
  "..."
50466
50991
  ];
50467
50992
  const PREVIEW_GAP = " ";
50993
+ const ACTIVITY_TARGET_LABEL_PREFIX_REGEX = /^@/u;
50468
50994
  var ComposerActivityStrip = class {
50469
50995
  #tui;
50470
50996
  #activity = {
50471
50997
  visible: false,
50472
50998
  mode: "idle",
50999
+ rows: [],
51000
+ overflowCount: 0,
50473
51001
  actors: [],
50474
51002
  leadActor: null,
50475
51003
  elapsedSeconds: null,
50476
51004
  previewText: "",
50477
- hint: null,
50478
- pendingOutboundText: ""
51005
+ hint: null
50479
51006
  };
50480
- #activityBaseElapsedSeconds = 0;
50481
51007
  #activityBaseSetAtMs = Date.now();
50482
51008
  #tick = 0;
50483
51009
  #timer = null;
@@ -50489,7 +51015,6 @@ var ComposerActivityStrip = class {
50489
51015
  const isWaiting = isWaitingComposerActivity(activity);
50490
51016
  if (!wasWaiting && isWaiting) this.#tick = 0;
50491
51017
  this.#activity = activity;
50492
- this.#activityBaseElapsedSeconds = activity.elapsedSeconds ?? 0;
50493
51018
  this.#activityBaseSetAtMs = Date.now();
50494
51019
  this.#syncTimer();
50495
51020
  this.#tui.requestRender();
@@ -50502,16 +51027,12 @@ var ComposerActivityStrip = class {
50502
51027
  invalidate() {}
50503
51028
  render(width) {
50504
51029
  if (!shouldRenderComposerActivity(this.#activity)) return [];
50505
- return ["", ...wrapAnsi(buildInlineActivityLine({
51030
+ return ["", ...buildActivityLines({
50506
51031
  activity: this.#activity,
50507
51032
  tick: this.#tick,
50508
- elapsedSeconds: this.#resolveElapsedSeconds(),
51033
+ elapsedDeltaSeconds: this.#resolveElapsedDeltaSeconds(),
50509
51034
  width
50510
- }), Math.max(1, width), {
50511
- hard: true,
50512
- trim: false,
50513
- wordWrap: true
50514
- }).split("\n")];
51035
+ })];
50515
51036
  }
50516
51037
  #syncTimer() {
50517
51038
  if (shouldAnimateComposerActivity(this.#activity)) {
@@ -50524,55 +51045,83 @@ var ComposerActivityStrip = class {
50524
51045
  }
50525
51046
  this.stop();
50526
51047
  }
50527
- #resolveElapsedSeconds() {
51048
+ #resolveElapsedDeltaSeconds() {
50528
51049
  if (!shouldRenderComposerActivity(this.#activity)) return 0;
50529
- const deltaSeconds = Math.max(0, Math.floor((Date.now() - this.#activityBaseSetAtMs) / 1e3));
50530
- return this.#activityBaseElapsedSeconds + deltaSeconds;
51050
+ return Math.max(0, Math.floor((Date.now() - this.#activityBaseSetAtMs) / 1e3));
50531
51051
  }
50532
51052
  };
50533
51053
  function shouldRenderComposerActivity(activity) {
50534
- return activity.visible && activity.mode !== "idle";
51054
+ return activity.visible && activity.mode !== "idle" && activity.rows.length > 0;
50535
51055
  }
50536
51056
  function shouldAnimateComposerActivity(activity) {
50537
- return shouldRenderComposerActivity(activity);
51057
+ return shouldRenderComposerActivity(activity) && activity.rows.some((row) => row.mode !== "warning");
50538
51058
  }
50539
51059
  function isWaitingComposerActivity(activity) {
50540
- return shouldRenderComposerActivity(activity) && activity.previewText.trim().length === 0;
51060
+ return shouldRenderComposerActivity(activity) && activity.rows.some((row) => row.mode !== "warning" && row.previewText.trim().length === 0);
50541
51061
  }
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;
51062
+ function buildReplyingStatusLine(input) {
51063
+ const actors = input.row.actors.map((actor) => {
51064
+ const matchingAgent = input.spaceMembersSnapshot?.agents.find((candidate) => candidate.profileId === actor.profileId) ?? null;
50545
51065
  return colorizeAgentLabel(actor.label, {
50546
51066
  controllerRef: matchingAgent?.controllerRef,
50547
51067
  profileId: actor.profileId,
50548
51068
  profileName: actor.label
50549
- }, { spaceMembersSnapshot: input.activity.spaceMembersSnapshot });
51069
+ }, { spaceMembersSnapshot: input.spaceMembersSnapshot });
50550
51070
  }).join(pc.dim(", "));
50551
- const linkingVerb = input.activity.actors.length > 1 ? "are" : "is";
51071
+ const linkingVerb = input.row.actors.length > 1 ? "are" : "is";
50552
51072
  const modeLabel = resolveStatusModeLabel({
50553
51073
  elapsedSeconds: input.elapsedSeconds,
50554
- previewText: input.activity.previewText
51074
+ previewText: input.row.previewText
50555
51075
  });
50556
- const modeSuffix = input.activity.previewText.trim().length > 0 ? "" : resolveAnimatedStatusDots(input.tick);
51076
+ const modeSuffix = input.row.previewText.trim().length > 0 ? "" : resolveAnimatedStatusDots(input.tick);
50557
51077
  return `${actors} ${pc.dim(linkingVerb)} ${pc.dim(`${modeLabel}${modeSuffix}`)}`;
50558
51078
  }
50559
- function buildInlineActivityLine(input) {
51079
+ function buildActivityLines(input) {
51080
+ const lines = [];
51081
+ if (input.activity.overflowCount > 0) lines.push(pc.dim(`+${input.activity.overflowCount} more active`));
51082
+ for (const row of input.activity.rows) {
51083
+ const wrappedLines = wrapAnsi(buildActivityRowLine({
51084
+ row,
51085
+ spaceMembersSnapshot: input.activity.spaceMembersSnapshot,
51086
+ tick: input.tick,
51087
+ elapsedSeconds: resolveRowElapsedSeconds({
51088
+ row,
51089
+ elapsedDeltaSeconds: input.elapsedDeltaSeconds
51090
+ }),
51091
+ width: input.width
51092
+ }), Math.max(1, input.width), {
51093
+ hard: true,
51094
+ trim: false,
51095
+ wordWrap: true
51096
+ }).split("\n");
51097
+ lines.push(...wrappedLines);
51098
+ }
51099
+ return lines;
51100
+ }
51101
+ function buildActivityRowLine(input) {
50560
51102
  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...")
50565
- ].join(` ${pc.dim("·")} `);
51103
+ if (input.row.mode === "sending") return buildSendingStatusLine({
51104
+ row: input.row,
51105
+ spaceMembersSnapshot: input.spaceMembersSnapshot,
51106
+ spinner
51107
+ });
51108
+ if (input.row.mode === "dispatching" || input.row.mode === "retrying" || input.row.mode === "warning") return buildStatusHintLine({
51109
+ glyph: input.row.mode === "warning" ? pc.yellow("!") : spacePiTuiTheme.accentText(spinner),
51110
+ elapsedLabel: input.row.mode === "warning" ? pc.dim("now") : pc.dim(`${input.elapsedSeconds}s`),
51111
+ row: input.row,
51112
+ spaceMembersSnapshot: input.spaceMembersSnapshot
51113
+ });
50566
51114
  const statusLine = [
50567
51115
  spacePiTuiTheme.accentText(spinner),
50568
51116
  pc.dim(`${input.elapsedSeconds}s`),
50569
- buildStatusLine({
50570
- activity: input.activity,
51117
+ buildReplyingStatusLine({
51118
+ row: input.row,
51119
+ spaceMembersSnapshot: input.spaceMembersSnapshot,
50571
51120
  elapsedSeconds: input.elapsedSeconds,
50572
51121
  tick: input.tick
50573
51122
  })
50574
51123
  ].join(` ${pc.dim("·")} `);
50575
- const previewText = input.activity.previewText.trim();
51124
+ const previewText = input.row.previewText.trim();
50576
51125
  if (!previewText) return statusLine;
50577
51126
  const separator = ` ${pc.dim("·")} `;
50578
51127
  const availableWidth = Math.max(0, input.width - stringWidth(stripVTControlCharacters(statusLine)) - stringWidth(stripVTControlCharacters(separator)));
@@ -50584,6 +51133,57 @@ function buildInlineActivityLine(input) {
50584
51133
  });
50585
51134
  return `${statusLine}${separator}${pc.dim(windowText)}`;
50586
51135
  }
51136
+ function buildSendingStatusLine(input) {
51137
+ const sendingText = input.row.hint || "sending...";
51138
+ return [spacePiTuiTheme.accentText(input.spinner), formatHintWithColoredTargetLabel({
51139
+ hint: sendingText,
51140
+ targetLabel: input.row.targetLabel,
51141
+ spaceMembersSnapshot: input.spaceMembersSnapshot
51142
+ })].join(` ${pc.dim("·")} `);
51143
+ }
51144
+ function buildStatusHintLine(input) {
51145
+ return [
51146
+ input.glyph,
51147
+ input.elapsedLabel,
51148
+ formatHintWithColoredTargetLabel({
51149
+ hint: input.row.hint ?? "",
51150
+ targetLabel: input.row.targetLabel,
51151
+ spaceMembersSnapshot: input.spaceMembersSnapshot
51152
+ })
51153
+ ].join(` ${pc.dim("·")} `);
51154
+ }
51155
+ function formatHintWithColoredTargetLabel(input) {
51156
+ const targetLabel = input.targetLabel?.trim() ?? "";
51157
+ if (!(targetLabel && input.hint.includes(targetLabel))) return pc.white(input.hint);
51158
+ const coloredTargetLabel = resolveColoredTargetLabel({
51159
+ spaceMembersSnapshot: input.spaceMembersSnapshot,
51160
+ targetLabel
51161
+ });
51162
+ const [prefix, suffix = ""] = input.hint.split(targetLabel, 2);
51163
+ return `${pc.white(prefix)}${coloredTargetLabel}${pc.white(suffix)}`;
51164
+ }
51165
+ function resolveColoredTargetLabel(input) {
51166
+ const normalizedTargetLabel = normalizeActivityTargetLabel(input.targetLabel);
51167
+ const matchingAgent = input.spaceMembersSnapshot?.agents.find((candidate) => {
51168
+ return [
51169
+ candidate.wakeToken,
51170
+ candidate.wakeLabel,
51171
+ candidate.profileName,
51172
+ candidate.profileId
51173
+ ].some((value) => normalizeActivityTargetLabel(value) === normalizedTargetLabel);
51174
+ }) ?? null;
51175
+ return colorizeAgentLabel(input.targetLabel, {
51176
+ controllerRef: matchingAgent?.controllerRef,
51177
+ profileId: matchingAgent?.profileId,
51178
+ profileName: matchingAgent?.profileName || normalizedTargetLabel || input.targetLabel
51179
+ }, { spaceMembersSnapshot: input.spaceMembersSnapshot });
51180
+ }
51181
+ function normalizeActivityTargetLabel(value) {
51182
+ return stripVTControlCharacters(String(value ?? "")).trim().replace(ACTIVITY_TARGET_LABEL_PREFIX_REGEX, "");
51183
+ }
51184
+ function resolveRowElapsedSeconds(input) {
51185
+ return (input.row.elapsedSeconds ?? 0) + input.elapsedDeltaSeconds;
51186
+ }
50587
51187
  function resolveStatusModeLabel(input) {
50588
51188
  if (input.previewText.trim().length > 0) return "streaming";
50589
51189
  return STATUS_LABELS[Math.floor(input.elapsedSeconds / STATUS_LABEL_CYCLE_SECONDS) % STATUS_LABELS.length] ?? STATUS_LABELS[0];
@@ -52718,6 +53318,7 @@ function buildSpaceTranscriptItem(input) {
52718
53318
  const groupKey = resolveTextLineGroupKey(input.event);
52719
53319
  const profile = buildTranscriptItemProfileSnapshot(input.event);
52720
53320
  const systemPurpose = resolveTranscriptItemSystemPurpose(input.event);
53321
+ const replyRef = isSignalEnvelope$1(input.event) ? resolveTranscriptReplyRef(input.event) : void 0;
52721
53322
  if (isSignalEnvelope$1(input.event)) {
52722
53323
  if (input.event.type === "presence.join" || input.event.type === "presence.quit") return {
52723
53324
  line: input.line,
@@ -52751,7 +53352,8 @@ function buildSpaceTranscriptItem(input) {
52751
53352
  formattedMessage: input.formattedMessage ?? void 0,
52752
53353
  profile,
52753
53354
  systemPurpose,
52754
- ts: input.event.ts
53355
+ ts: input.event.ts,
53356
+ ...groupKey === SYSTEM_MESSAGE_GROUP_KEY || !replyRef ? {} : { replyRef }
52755
53357
  };
52756
53358
  }
52757
53359
  return {
@@ -52894,6 +53496,31 @@ function resolveTranscriptItemSystemPurpose(event) {
52894
53496
  const meta = resolveSignalTextMetaFromEnvelope$1(event);
52895
53497
  return typeof meta?.purpose === "string" ? meta.purpose : null;
52896
53498
  }
53499
+ function resolveTranscriptReplyRef(event) {
53500
+ if (event.type !== "signal.text") return;
53501
+ const replyToRecord = resolveSignalTextReplyToRecord(event.data);
53502
+ if (!replyToRecord) return;
53503
+ const signalId = sanitizeTranscriptReplyText(replyToRecord.signalId);
53504
+ const profileId = sanitizeTranscriptReplyText(replyToRecord.profileId);
53505
+ const profileName = sanitizeTranscriptReplyText(replyToRecord.profileName);
53506
+ if (!(signalId && (profileName || profileId))) return;
53507
+ return {
53508
+ signalId,
53509
+ profileId,
53510
+ profileKind: replyToRecord.profileKind === "human" || replyToRecord.profileKind === "agent" || replyToRecord.profileKind === "system" ? replyToRecord.profileKind : null,
53511
+ profileName,
53512
+ previewText: sanitizeTranscriptReplyText(replyToRecord.previewText)
53513
+ };
53514
+ }
53515
+ function resolveSignalTextReplyToRecord(data) {
53516
+ if (!(data && typeof data === "object" && !Array.isArray(data))) return null;
53517
+ const replyTo = data.replyTo;
53518
+ if (!(replyTo && typeof replyTo === "object" && !Array.isArray(replyTo))) return null;
53519
+ return replyTo;
53520
+ }
53521
+ function sanitizeTranscriptReplyText(value) {
53522
+ return sanitizeTerminalDisplayText(typeof value === "string" ? value : "", "single-line").replace(/\s+/gu, " ").trim();
53523
+ }
52897
53524
  function resolveTranscriptActorKind(kind) {
52898
53525
  return kind === "human" || kind === "agent" ? kind : "unknown";
52899
53526
  }
@@ -52919,8 +53546,6 @@ const HTTP_ERROR_MESSAGE_REGEX$1 = /^HTTP\s+(\d{3}):\s*(.*)$/i;
52919
53546
  const WS_UNEXPECTED_SERVER_RESPONSE_REGEX = /unexpected server response:\s*(\d{3})/i;
52920
53547
  const LAST_SEEN_FUTURE_SKEW_TOLERANCE_MS = 3e4;
52921
53548
  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
53549
  const REPLYING_HINT_FALLBACK_CLEAR_MS = 18e4;
52925
53550
  const REPLYING_STATUS_SYSTEM_LABEL = "📣 system";
52926
53551
  const REPLYING_STATUS_AGENT_LABEL = "🤖";
@@ -52985,14 +53610,31 @@ function handleInteractiveRuntimeEvent(input) {
52985
53610
  input.handleMembersUpdatedEvent(input.event);
52986
53611
  return;
52987
53612
  case "send.queued":
52988
- enqueuePendingOutboundConfirmation(input.pendingOutboundConfirmationQueue, input.event.text);
52989
- input.syncOverlayLine();
53613
+ upsertPendingOutboundRows({
53614
+ enableLocalEcho: input.enableLocalEcho,
53615
+ rowsById: input.rowsById,
53616
+ text: input.event.text,
53617
+ clientMessageId: input.event.clientMessageId,
53618
+ terminalColumns: resolveReplyingStatusColumns(),
53619
+ nowMs: Date.now()
53620
+ });
53621
+ input.syncActivityPresentation();
52990
53622
  return;
52991
53623
  case "send.confirmed":
52992
- dequeuePendingOutboundConfirmationIfHeadMatch(input.pendingOutboundConfirmationQueue, input.event.text);
52993
- input.syncOverlayLine();
53624
+ confirmPendingOutboundRows({
53625
+ rowsById: input.rowsById,
53626
+ clientMessageId: input.event.clientMessageId,
53627
+ sourceEventId: input.event.event.id,
53628
+ nowMs: Date.now()
53629
+ });
53630
+ input.syncActivityPresentation();
52994
53631
  return;
52995
53632
  case "send.failed":
53633
+ clearPendingOutboundRowsByClientMessageId({
53634
+ rowsById: input.rowsById,
53635
+ clientMessageId: input.event.clientMessageId
53636
+ });
53637
+ input.syncActivityPresentation();
52996
53638
  input.reportOutboundSendFailure({
52997
53639
  error: `couldn't send the message: ${input.event.error}`,
52998
53640
  hint: "rejoin the space and try sending it again"
@@ -53243,7 +53885,7 @@ async function runConnect(input) {
53243
53885
  let liveFloorTs = initialLiveFloorTs;
53244
53886
  let pendingLastSeen = null;
53245
53887
  let pendingTimer = null;
53246
- const pendingOutboundConfirmationQueue = [];
53888
+ const activityRowsById = /* @__PURE__ */ new Map();
53247
53889
  let rl = null;
53248
53890
  let hasPrintedTextLine = false;
53249
53891
  let lastPrintedTextLineGroupKey = null;
@@ -53259,21 +53901,17 @@ async function runConnect(input) {
53259
53901
  const enableReplyingPromptStatus = shouldHideSubmittedInputLine;
53260
53902
  const composePromptPrefix = pc.dim("[draft] ");
53261
53903
  let composeDraftState = emptyComposeDraft();
53262
- const replyingStatusByDispatchId = /* @__PURE__ */ new Map();
53263
53904
  let replyingStatusSweepTimer = null;
53264
53905
  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);
53906
+ if (!enableReplyingPromptStatus || activityRowsById.size === 0) return;
53907
+ pruneExpiredDispatchRows(activityRowsById, Date.now());
53268
53908
  };
53269
53909
  const resolveReplyingStatusTexts = () => {
53270
53910
  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
- }));
53911
+ return resolveDispatchRowStatusTexts({
53912
+ rowsById: activityRowsById,
53913
+ terminalColumns: resolveReplyingStatusColumns()
53914
+ });
53277
53915
  };
53278
53916
  const resolveInputPrompt = () => {
53279
53917
  const baseInputPrompt = formatInputPrompt(profileIdentity, { spaceMembersSnapshot });
@@ -53342,12 +53980,6 @@ async function runConnect(input) {
53342
53980
  visibleReplyingStatusLineRows = countRenderedTerminalRows(normalizedText);
53343
53981
  };
53344
53982
  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
53983
  const promptStatuses = resolveReplyingStatusTexts();
53352
53984
  if (promptStatuses.length > 0) {
53353
53985
  const decoratedReplyingStatus = promptStatuses.map((statusText) => {
@@ -53362,10 +53994,9 @@ async function runConnect(input) {
53362
53994
  clearTimeout(replyingStatusSweepTimer);
53363
53995
  replyingStatusSweepTimer = null;
53364
53996
  }
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;
53997
+ if (!enableReplyingPromptStatus || activityRowsById.size === 0) return;
53998
+ const nearestExpiryMs = resolveNearestDispatchRowExpiryMs(activityRowsById);
53999
+ if (nearestExpiryMs === null) return;
53369
54000
  const delayMs = Math.max(250, nearestExpiryMs - Date.now());
53370
54001
  replyingStatusSweepTimer = setTimeout(() => {
53371
54002
  pruneExpiredReplyingStatuses();
@@ -53375,15 +54006,15 @@ async function runConnect(input) {
53375
54006
  };
53376
54007
  const handleReplyingHintStatusEvent = (event) => {
53377
54008
  if (!enableReplyingPromptStatus || event.type !== "signal.text") return;
53378
- const replyingHintEvent = resolveReplyingHintEvent(event);
54009
+ const replyingHintEvent = resolveDispatchActivityEvent(event);
53379
54010
  let statusChanged = false;
53380
- if (replyingHintEvent) statusChanged = upsertReplyingStatusState({
53381
- replyingStatusByDispatchId,
54011
+ if (replyingHintEvent) statusChanged = upsertDispatchActivityStatusState({
54012
+ rowsById: activityRowsById,
53382
54013
  event: replyingHintEvent,
53383
54014
  nowMs: Date.now()
53384
54015
  });
53385
- else statusChanged = clearReplyingStatusesForSignal({
53386
- replyingStatusByDispatchId,
54016
+ else statusChanged = clearDispatchActivitiesForSignal({
54017
+ rowsById: activityRowsById,
53387
54018
  event
53388
54019
  });
53389
54020
  if (!statusChanged) return;
@@ -53442,7 +54073,12 @@ async function runConnect(input) {
53442
54073
  };
53443
54074
  const consumePendingOutboundConfirmation = (event) => {
53444
54075
  if (event.type !== "signal.text" || event.profile?.profileId !== profileIdentity.profileId) return;
53445
- if (!dequeuePendingOutboundConfirmationIfHeadMatch(pendingOutboundConfirmationQueue, typeof event.data?.text === "string" ? event.data.text : "")) return;
54076
+ if (!confirmPendingOutboundRows({
54077
+ rowsById: activityRowsById,
54078
+ clientMessageId: resolveSignalClientMessageId(event),
54079
+ sourceEventId: event.id,
54080
+ nowMs: Date.now()
54081
+ })) return;
53446
54082
  syncReplyingStatusPresentation();
53447
54083
  };
53448
54084
  const resolveTextRenderEvent = (event) => {
@@ -53585,7 +54221,7 @@ async function runConnect(input) {
53585
54221
  processIgnoredOlderThanLiveFloorSignal({
53586
54222
  event,
53587
54223
  seenSignalIds: catchupSeenSignalIds,
53588
- onReplyingHintEvent: handleReplyingHintStatusEvent
54224
+ onDispatchActivityEvent: handleReplyingHintStatusEvent
53589
54225
  });
53590
54226
  return;
53591
54227
  }
@@ -53793,8 +54429,7 @@ async function runConnect(input) {
53793
54429
  if (runtime.resolvedView === "human") refreshInputPrompt();
53794
54430
  }
53795
54431
  function reportPendingOutboundUnconfirmed(inputPending) {
53796
- if (pendingOutboundConfirmationQueue.length === 0) return;
53797
- pendingOutboundConfirmationQueue.length = 0;
54432
+ if (!clearUnconfirmedPendingOutboundRows(activityRowsById)) return;
53798
54433
  syncReplyingStatusPresentation();
53799
54434
  const reasonSuffix = inputPending.reason ? ` (${inputPending.reason})` : "";
53800
54435
  presenter.event("error", "connect.error", {
@@ -53803,18 +54438,6 @@ async function runConnect(input) {
53803
54438
  });
53804
54439
  process.exitCode = 1;
53805
54440
  }
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
54441
  const sendOutboundText = (outboundText) => {
53819
54442
  if (isClosing || wsEnded) {
53820
54443
  reportOutboundSendFailure({
@@ -53823,8 +54446,9 @@ async function runConnect(input) {
53823
54446
  });
53824
54447
  return;
53825
54448
  }
54449
+ const clientMessageId = crypto.randomUUID();
53826
54450
  try {
53827
- ws.send(JSON.stringify(makeTextSignal(outboundText)));
54451
+ ws.send(JSON.stringify(makeTextSignal(outboundText, { meta: { clientMessageId } })));
53828
54452
  } catch (error) {
53829
54453
  reportOutboundSendFailure({
53830
54454
  error: `couldn't send the message: ${toErrorMessage$3(error)}`,
@@ -53832,7 +54456,14 @@ async function runConnect(input) {
53832
54456
  });
53833
54457
  return;
53834
54458
  }
53835
- enqueuePendingOutboundConfirmation(pendingOutboundConfirmationQueue, outboundText);
54459
+ upsertPendingOutboundRows({
54460
+ enableLocalEcho,
54461
+ rowsById: activityRowsById,
54462
+ text: outboundText,
54463
+ clientMessageId,
54464
+ terminalColumns: resolveReplyingStatusColumns(),
54465
+ nowMs: Date.now()
54466
+ });
53836
54467
  syncReplyingStatusPresentation();
53837
54468
  if (runtime.resolvedView === "human") refreshInputPrompt();
53838
54469
  };
@@ -53906,8 +54537,7 @@ async function runInteractiveHumanTextSession(input) {
53906
54537
  resources: {
53907
54538
  composerActivity: {
53908
54539
  nowMs: Date.now(),
53909
- pendingOutboundText: resolvePendingOutboundStatus(),
53910
- replyingDispatches: toReplyingDispatchStates(replyingStatusByDispatchId)
54540
+ rows: toComposerDispatchRows(activityRowsById)
53911
54541
  },
53912
54542
  sessionDiagnostics
53913
54543
  },
@@ -53928,8 +54558,7 @@ async function runInteractiveHumanTextSession(input) {
53928
54558
  getResources: () => ({
53929
54559
  composerActivity: {
53930
54560
  nowMs: Date.now(),
53931
- pendingOutboundText: resolvePendingOutboundStatus(),
53932
- replyingDispatches: toReplyingDispatchStates(replyingStatusByDispatchId)
54561
+ rows: toComposerDispatchRows(activityRowsById)
53933
54562
  },
53934
54563
  sessionDiagnostics
53935
54564
  }),
@@ -53944,8 +54573,7 @@ async function runInteractiveHumanTextSession(input) {
53944
54573
  shell.render(buildCurrentViewState());
53945
54574
  });
53946
54575
  };
53947
- const pendingOutboundConfirmationQueue = [];
53948
- const replyingStatusByDispatchId = /* @__PURE__ */ new Map();
54576
+ const activityRowsById = /* @__PURE__ */ new Map();
53949
54577
  const catchupSeenSignalIds = /* @__PURE__ */ new Set();
53950
54578
  let mentionHighlightIndex = null;
53951
54579
  let liveFloorTs = input.initialLiveFloorTs;
@@ -54156,40 +54784,17 @@ async function runInteractiveHumanTextSession(input) {
54156
54784
  input.presenter.event("info", "connect.warn.cursor_sync_paused");
54157
54785
  };
54158
54786
  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);
54787
+ if (activityRowsById.size === 0) return;
54788
+ pruneExpiredDispatchRows(activityRowsById, Date.now());
54162
54789
  };
54163
54790
  const resolveReplyingStatusTexts = () => {
54164
54791
  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,
54792
+ return resolveDispatchRowStatusTexts({
54793
+ rowsById: activityRowsById,
54181
54794
  terminalColumns: resolveReplyingStatusColumns()
54182
- }))}`;
54795
+ });
54183
54796
  };
54184
54797
  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
54798
  const replyingStatuses = resolveReplyingStatusTexts();
54194
54799
  if (replyingStatuses.length === 0) {
54195
54800
  store.dispatch({
@@ -54206,37 +54811,40 @@ async function runInteractiveHumanTextSession(input) {
54206
54811
  line: decoratedReplyingStatus
54207
54812
  });
54208
54813
  };
54814
+ const syncComposerActivityPresentation = () => {
54815
+ syncOverlayLine();
54816
+ if (piTuiSessionMount) piTuiSessionMount.renderCurrentViewState();
54817
+ };
54209
54818
  const scheduleReplyingStatusSweep = () => {
54210
54819
  if (replyingStatusSweepTimer) {
54211
54820
  clearTimeout(replyingStatusSweepTimer);
54212
54821
  replyingStatusSweepTimer = null;
54213
54822
  }
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;
54823
+ if (activityRowsById.size === 0) return;
54824
+ const nearestExpiryMs = resolveNearestDispatchRowExpiryMs(activityRowsById);
54825
+ if (nearestExpiryMs === null) return;
54218
54826
  const delayMs = Math.max(250, nearestExpiryMs - Date.now());
54219
54827
  replyingStatusSweepTimer = setTimeout(() => {
54220
54828
  pruneExpiredReplyingStatuses();
54221
- syncOverlayLine();
54829
+ syncComposerActivityPresentation();
54222
54830
  scheduleReplyingStatusSweep();
54223
54831
  }, delayMs);
54224
54832
  };
54225
54833
  const handleReplyingHintStatusEvent = (event) => {
54226
- const replyingHintEvent = resolveReplyingHintEvent(event);
54834
+ const replyingHintEvent = resolveDispatchActivityEvent(event);
54227
54835
  let statusChanged = false;
54228
- if (replyingHintEvent) statusChanged = upsertReplyingStatusState({
54229
- replyingStatusByDispatchId,
54836
+ if (replyingHintEvent) statusChanged = upsertDispatchActivityStatusState({
54837
+ rowsById: activityRowsById,
54230
54838
  event: replyingHintEvent,
54231
54839
  nowMs: Date.now()
54232
54840
  });
54233
- else statusChanged = clearReplyingStatusesForSignal({
54234
- replyingStatusByDispatchId,
54841
+ else statusChanged = clearDispatchActivitiesForSignal({
54842
+ rowsById: activityRowsById,
54235
54843
  event
54236
54844
  });
54237
54845
  if (!statusChanged) return;
54238
54846
  scheduleReplyingStatusSweep();
54239
- syncOverlayLine();
54847
+ syncComposerActivityPresentation();
54240
54848
  };
54241
54849
  const flushLastSeen = async () => {
54242
54850
  if (!pendingLastSeen) return;
@@ -54291,15 +54899,14 @@ async function runInteractiveHumanTextSession(input) {
54291
54899
  scheduleLastSeen(event.ts);
54292
54900
  };
54293
54901
  const reportOutboundSendFailure = (failure) => {
54294
- syncOverlayLine();
54902
+ syncComposerActivityPresentation();
54295
54903
  shell.prepareExternalWrite();
54296
54904
  input.presenter.event("error", "connect.error", failure);
54297
54905
  process.exitCode = 1;
54298
54906
  };
54299
54907
  const reportPendingOutboundUnconfirmed = (pending) => {
54300
- if (pendingOutboundConfirmationQueue.length === 0) return;
54301
- pendingOutboundConfirmationQueue.length = 0;
54302
- syncOverlayLine();
54908
+ if (!clearUnconfirmedPendingOutboundRows(activityRowsById)) return;
54909
+ syncComposerActivityPresentation();
54303
54910
  const reasonSuffix = pending.reason ? ` (${pending.reason})` : "";
54304
54911
  shell.prepareExternalWrite();
54305
54912
  input.presenter.event("error", "connect.error", {
@@ -54338,7 +54945,7 @@ async function runInteractiveHumanTextSession(input) {
54338
54945
  processIgnoredOlderThanLiveFloorSignal({
54339
54946
  event: ignoredEvent,
54340
54947
  seenSignalIds: catchupSeenSignalIds,
54341
- onReplyingHintEvent: handleReplyingHintStatusEvent
54948
+ onDispatchActivityEvent: handleReplyingHintStatusEvent
54342
54949
  });
54343
54950
  },
54344
54951
  scheduleMembersSnapshotRefresh,
@@ -54475,10 +55082,11 @@ async function runInteractiveHumanTextSession(input) {
54475
55082
  handleHistoryLoadedEvent,
54476
55083
  handleIncomingEvent,
54477
55084
  handleMembersUpdatedEvent,
54478
- pendingOutboundConfirmationQueue,
55085
+ rowsById: activityRowsById,
55086
+ enableLocalEcho: input.enableLocalEcho,
54479
55087
  reportOutboundSendFailure,
54480
55088
  store,
54481
- syncOverlayLine
55089
+ syncActivityPresentation: syncComposerActivityPresentation
54482
55090
  });
54483
55091
  });
54484
55092
  function cleanup(why) {
@@ -55050,109 +55658,322 @@ function emitReplaySignals(input, signals) {
55050
55658
  rememberSeenSignalId(input.seenSignalIds, event.id);
55051
55659
  }
55052
55660
  }
55053
- function enqueuePendingOutboundConfirmation(queue, text) {
55054
- if (queue.length >= PENDING_OUTBOUND_CONFIRMATION_MAX) queue.shift();
55055
- queue.push(text);
55661
+ function buildPendingDispatchRowId(clientMessageId, targetWakeToken) {
55662
+ return `pending:${clientMessageId}:${targetWakeToken ?? "__generic__"}`;
55056
55663
  }
55057
- function dequeuePendingOutboundConfirmationIfHeadMatch(queue, text) {
55058
- if (queue[0] !== text) return false;
55059
- queue.splice(0, 1);
55664
+ function upsertPendingOutboundRows(input) {
55665
+ if (!input.enableLocalEcho) return false;
55666
+ const drafts = buildPendingOutboundDispatchRowDrafts({
55667
+ pendingText: input.text,
55668
+ terminalColumns: input.terminalColumns
55669
+ });
55670
+ if (drafts.length === 0) return false;
55671
+ for (const draft of drafts) input.rowsById.set(buildPendingDispatchRowId(input.clientMessageId, draft.targetWakeToken), {
55672
+ rowId: buildPendingDispatchRowId(input.clientMessageId, draft.targetWakeToken),
55673
+ dispatchId: null,
55674
+ sourceEventId: null,
55675
+ sourceClientMessageId: input.clientMessageId,
55676
+ targetProfileId: null,
55677
+ targetWakeToken: draft.targetWakeToken,
55678
+ targetLabel: draft.targetLabel,
55679
+ stage: "sending",
55680
+ createdAtMs: input.nowMs,
55681
+ updatedAtMs: input.nowMs,
55682
+ expiresAtMs: null,
55683
+ latestPreviewText: "",
55684
+ latestPreviewUpdatedAtMs: null,
55685
+ statusText: draft.statusText,
55686
+ warningText: ""
55687
+ });
55688
+ trimPendingOutboundRows(input.rowsById);
55060
55689
  return true;
55061
55690
  }
55062
- function clearReplyingStatusesForSignal(input) {
55063
- if (input.replyingStatusByDispatchId.size === 0) return false;
55691
+ function trimPendingOutboundRows(rowsById) {
55692
+ if (rowsById.size <= PENDING_OUTBOUND_CONFIRMATION_MAX) return;
55693
+ const removableRows = [...rowsById.values()].filter((row) => row.stage === "sending" && row.dispatchId === null && row.sourceEventId === null).sort((left, right) => left.createdAtMs - right.createdAtMs);
55694
+ while (rowsById.size > PENDING_OUTBOUND_CONFIRMATION_MAX && removableRows.length > 0) {
55695
+ const oldestRow = removableRows.shift();
55696
+ if (!oldestRow) break;
55697
+ rowsById.delete(oldestRow.rowId);
55698
+ }
55699
+ }
55700
+ function confirmPendingOutboundRows(input) {
55701
+ if (!input.clientMessageId) return false;
55702
+ let changed = false;
55703
+ for (const [rowId, row] of input.rowsById) {
55704
+ if (row.sourceClientMessageId !== input.clientMessageId) continue;
55705
+ if (row.targetWakeToken === null) {
55706
+ input.rowsById.delete(rowId);
55707
+ changed = true;
55708
+ continue;
55709
+ }
55710
+ input.rowsById.set(rowId, {
55711
+ ...row,
55712
+ sourceEventId: input.sourceEventId,
55713
+ updatedAtMs: input.nowMs
55714
+ });
55715
+ changed = true;
55716
+ }
55717
+ return changed;
55718
+ }
55719
+ function clearPendingOutboundRowsByClientMessageId(input) {
55720
+ if (!input.clientMessageId) return false;
55721
+ let changed = false;
55722
+ for (const [rowId, row] of input.rowsById) {
55723
+ if (row.sourceClientMessageId !== input.clientMessageId) continue;
55724
+ input.rowsById.delete(rowId);
55725
+ changed = true;
55726
+ }
55727
+ return changed;
55728
+ }
55729
+ function clearUnconfirmedPendingOutboundRows(rowsById) {
55730
+ let changed = false;
55731
+ for (const [rowId, row] of rowsById) if (row.stage === "sending" && row.dispatchId === null && row.sourceEventId === null) {
55732
+ rowsById.delete(rowId);
55733
+ changed = true;
55734
+ }
55735
+ return changed;
55736
+ }
55737
+ function pruneExpiredDispatchRows(rowsById, nowMs) {
55738
+ let changed = false;
55739
+ for (const [rowId, row] of rowsById) {
55740
+ if (typeof row.expiresAtMs !== "number" || row.expiresAtMs > nowMs) continue;
55741
+ rowsById.delete(rowId);
55742
+ changed = true;
55743
+ }
55744
+ return changed;
55745
+ }
55746
+ function resolveNearestDispatchRowExpiryMs(rowsById) {
55747
+ let nearestExpiryMs = null;
55748
+ for (const row of rowsById.values()) {
55749
+ if (typeof row.expiresAtMs !== "number") continue;
55750
+ if (nearestExpiryMs === null || row.expiresAtMs < nearestExpiryMs) nearestExpiryMs = row.expiresAtMs;
55751
+ }
55752
+ return nearestExpiryMs;
55753
+ }
55754
+ function resolveDispatchRowStatusTexts(input) {
55755
+ if (input.rowsById.size === 0) return [];
55756
+ return [...input.rowsById.values()].sort((left, right) => right.updatedAtMs - left.updatedAtMs).map((state) => formatReplyingStatusText({
55757
+ state,
55758
+ terminalColumns: input.terminalColumns
55759
+ }));
55760
+ }
55761
+ function toDispatchActivityIdentity(event) {
55762
+ return {
55763
+ dispatchId: event.dispatchId,
55764
+ sourceClientMessageId: event.sourceClientMessageId,
55765
+ sourceEventId: event.sourceEventId,
55766
+ targetLabel: "targetLabel" in event ? event.targetLabel : event.targetProfileId,
55767
+ targetProfileId: event.targetProfileId,
55768
+ targetWakeToken: event.targetWakeToken
55769
+ };
55770
+ }
55771
+ function buildDispatchActivityRowId(input) {
55772
+ const { identity } = input;
55773
+ if (identity.dispatchId) return `dispatch:${identity.dispatchId}`;
55774
+ if (identity.sourceEventId && identity.targetWakeToken) return `event:${identity.sourceEventId}:${identity.targetWakeToken}`;
55775
+ if (identity.sourceClientMessageId && identity.targetWakeToken) return `client:${identity.sourceClientMessageId}:${identity.targetWakeToken}`;
55776
+ if (identity.targetProfileId) return `profile:${identity.targetProfileId}`;
55777
+ return `label:${identity.targetLabel}`;
55778
+ }
55779
+ function findMatchingDispatchActivityRowEntry(input) {
55780
+ for (const entry of input.rowsById) if (entry[1].dispatchId === input.identity.dispatchId) return entry;
55781
+ if (input.identity.sourceEventId && input.identity.targetWakeToken) {
55782
+ for (const entry of input.rowsById) if (entry[1].sourceEventId === input.identity.sourceEventId && entry[1].targetWakeToken === input.identity.targetWakeToken) return entry;
55783
+ }
55784
+ if (input.identity.sourceClientMessageId && input.identity.targetWakeToken) {
55785
+ for (const entry of input.rowsById) if (entry[1].sourceClientMessageId === input.identity.sourceClientMessageId && entry[1].targetWakeToken === input.identity.targetWakeToken) return entry;
55786
+ }
55787
+ return null;
55788
+ }
55789
+ function mergeDispatchActivityIdentity(input) {
55790
+ return {
55791
+ rowId: input.rowId,
55792
+ dispatchId: input.event.dispatchId,
55793
+ sourceEventId: input.event.sourceEventId ?? input.existing?.sourceEventId ?? null,
55794
+ sourceClientMessageId: input.event.sourceClientMessageId ?? input.existing?.sourceClientMessageId ?? null,
55795
+ targetProfileId: input.event.targetProfileId ?? input.existing?.targetProfileId ?? null,
55796
+ targetWakeToken: input.event.targetWakeToken ?? input.existing?.targetWakeToken ?? null,
55797
+ targetLabel: ("targetLabel" in input.event ? input.event.targetLabel : null) ?? input.existing?.targetLabel ?? input.event.targetProfileId,
55798
+ stage: input.existing?.stage ?? "dispatching",
55799
+ createdAtMs: input.existing?.createdAtMs ?? input.nowMs,
55800
+ updatedAtMs: input.nowMs,
55801
+ expiresAtMs: input.existing?.expiresAtMs ?? null,
55802
+ latestPreviewText: input.existing?.latestPreviewText ?? "",
55803
+ latestPreviewUpdatedAtMs: input.existing?.latestPreviewUpdatedAtMs ?? null,
55804
+ statusText: input.existing?.statusText ?? "",
55805
+ warningText: input.existing?.warningText ?? ""
55806
+ };
55807
+ }
55808
+ function clearDispatchActivitiesForSignal(input) {
55809
+ if (input.rowsById.size === 0) return false;
55064
55810
  if (!resolveNonTransientSignalText(input.event)) return false;
55065
55811
  const senderProfileId = String(input.event.profile?.profileId ?? "").trim();
55066
55812
  if (!senderProfileId) return false;
55067
55813
  const dispatchId = resolveReplyingSignalDispatchId(input.event);
55068
- if (dispatchId && input.replyingStatusByDispatchId.has(dispatchId)) {
55069
- input.replyingStatusByDispatchId.delete(dispatchId);
55814
+ if (dispatchId) for (const [rowId, row] of input.rowsById) {
55815
+ if (row.dispatchId !== dispatchId) continue;
55816
+ input.rowsById.delete(rowId);
55070
55817
  return true;
55071
55818
  }
55072
- let latestDispatchId = null;
55819
+ let latestRowId = null;
55073
55820
  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;
55821
+ for (const [rowId, row] of input.rowsById) {
55822
+ if (row.targetProfileId !== senderProfileId || row.stage === "sending") continue;
55823
+ if (row.updatedAtMs > latestUpdatedAtMs) {
55824
+ latestUpdatedAtMs = row.updatedAtMs;
55825
+ latestRowId = rowId;
55079
55826
  }
55080
55827
  }
55081
- if (!latestDispatchId) return false;
55082
- input.replyingStatusByDispatchId.delete(latestDispatchId);
55828
+ if (!latestRowId) return false;
55829
+ input.rowsById.delete(latestRowId);
55083
55830
  return true;
55084
55831
  }
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: ""
55832
+ function upsertDispatchActivityStatusState(input) {
55833
+ const existingEntry = findMatchingDispatchActivityRowEntry({
55834
+ identity: toDispatchActivityIdentity(input.event),
55835
+ rowsById: input.rowsById
55836
+ });
55837
+ const existing = existingEntry?.[1] ?? null;
55838
+ const rowId = existingEntry?.[0] ?? buildDispatchActivityRowId({ identity: toDispatchActivityIdentity(input.event) });
55839
+ switch (input.event.kind) {
55840
+ case "end": return existingEntry ? input.rowsById.delete(existingEntry[0]) : false;
55841
+ case "preview_end": return applyPreviewEndDispatchActivityState({
55842
+ existing,
55843
+ map: input.rowsById,
55844
+ rowId,
55845
+ nowMs: input.nowMs
55097
55846
  });
55098
- return true;
55847
+ case "warning": return applyWarningDispatchActivityState({
55848
+ existing,
55849
+ event: input.event,
55850
+ map: input.rowsById,
55851
+ rowId,
55852
+ nowMs: input.nowMs
55853
+ });
55854
+ case "dispatching":
55855
+ case "retrying": return applyStatusDispatchActivityState({
55856
+ existing,
55857
+ event: input.event,
55858
+ map: input.rowsById,
55859
+ rowId,
55860
+ nowMs: input.nowMs
55861
+ });
55862
+ case "replying_start": return applyReplyingStartDispatchActivityState({
55863
+ existing,
55864
+ event: input.event,
55865
+ map: input.rowsById,
55866
+ rowId,
55867
+ nowMs: input.nowMs
55868
+ });
55869
+ case "preview": return applyPreviewDispatchActivityState({
55870
+ existing,
55871
+ event: input.event,
55872
+ map: input.rowsById,
55873
+ rowId,
55874
+ nowMs: input.nowMs
55875
+ });
55876
+ default: return false;
55099
55877
  }
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,
55878
+ }
55879
+ function applyPreviewEndDispatchActivityState(input) {
55880
+ if (!input.existing) return false;
55881
+ input.map.set(input.rowId, {
55882
+ ...input.existing,
55883
+ updatedAtMs: input.nowMs,
55884
+ latestPreviewText: "",
55885
+ latestPreviewUpdatedAtMs: null,
55886
+ expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55887
+ warningText: ""
55888
+ });
55889
+ return true;
55890
+ }
55891
+ function applyWarningDispatchActivityState(input) {
55892
+ if (input.event.preserveActivityMode && input.existing?.stage === "replying") {
55893
+ input.map.set(input.rowId, {
55894
+ ...input.existing,
55116
55895
  updatedAtMs: input.nowMs,
55117
- latestPreviewText: "",
55118
- latestPreviewUpdatedAtMs: null,
55119
55896
  expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55120
55897
  statusText: input.event.text,
55121
55898
  warningText: input.event.text
55122
55899
  });
55123
55900
  return true;
55124
55901
  }
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,
55902
+ input.map.set(input.rowId, {
55903
+ ...mergeDispatchActivityIdentity({
55904
+ event: input.event,
55905
+ existing: input.existing,
55906
+ nowMs: input.nowMs,
55907
+ rowId: input.rowId
55908
+ }),
55909
+ stage: "warning",
55910
+ updatedAtMs: input.nowMs,
55911
+ latestPreviewText: "",
55912
+ latestPreviewUpdatedAtMs: null,
55913
+ expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55914
+ statusText: input.event.text,
55915
+ warningText: input.event.text
55916
+ });
55917
+ return true;
55918
+ }
55919
+ function applyStatusDispatchActivityState(input) {
55920
+ input.map.set(input.rowId, {
55921
+ ...mergeDispatchActivityIdentity({
55922
+ event: input.event,
55923
+ existing: input.existing,
55924
+ nowMs: input.nowMs,
55925
+ rowId: input.rowId
55926
+ }),
55927
+ stage: input.event.kind === "dispatching" ? "dispatching" : "retrying",
55928
+ updatedAtMs: input.nowMs,
55929
+ latestPreviewText: "",
55930
+ latestPreviewUpdatedAtMs: null,
55931
+ expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55932
+ statusText: input.event.text,
55933
+ warningText: ""
55934
+ });
55935
+ return true;
55936
+ }
55937
+ function applyReplyingStartDispatchActivityState(input) {
55938
+ input.map.set(input.rowId, {
55939
+ ...mergeDispatchActivityIdentity({
55940
+ event: input.event,
55941
+ existing: input.existing,
55942
+ nowMs: input.nowMs,
55943
+ rowId: input.rowId
55944
+ }),
55945
+ stage: "replying",
55946
+ updatedAtMs: input.nowMs,
55947
+ latestPreviewText: input.existing?.latestPreviewText ?? "",
55948
+ latestPreviewUpdatedAtMs: input.existing?.latestPreviewUpdatedAtMs ?? null,
55949
+ expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55950
+ statusText: input.existing?.statusText ?? "",
55951
+ warningText: ""
55952
+ });
55953
+ return true;
55954
+ }
55955
+ function applyPreviewDispatchActivityState(input) {
55956
+ input.map.set(input.rowId, {
55957
+ ...mergeDispatchActivityIdentity({
55958
+ event: input.event,
55959
+ existing: input.existing,
55960
+ nowMs: input.nowMs,
55961
+ rowId: input.rowId
55962
+ }),
55963
+ stage: "replying",
55145
55964
  updatedAtMs: input.nowMs,
55146
55965
  latestPreviewText: input.event.previewText,
55147
55966
  latestPreviewUpdatedAtMs: input.nowMs,
55148
55967
  expiresAtMs: input.nowMs + REPLYING_HINT_FALLBACK_CLEAR_MS,
55149
- statusText: existing?.statusText ?? "",
55968
+ statusText: input.existing?.statusText ?? "",
55150
55969
  warningText: ""
55151
55970
  });
55152
55971
  return true;
55153
55972
  }
55154
55973
  function formatReplyingStatusText(input) {
55155
- if (input.state.displayKind === "warning") return input.state.warningText || input.state.statusText;
55974
+ if (input.state.stage === "sending") return input.state.statusText || "sending...";
55975
+ if (input.state.stage === "warning") return input.state.warningText || input.state.statusText;
55976
+ 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
55977
  if (input.state.warningText) return input.state.warningText;
55157
55978
  const previewText = input.state.latestPreviewText.trim();
55158
55979
  if (!previewText) return `${input.state.targetLabel} is replying...`;
@@ -55162,17 +55983,8 @@ function formatReplyingStatusText(input) {
55162
55983
  terminalColumns: input.terminalColumns
55163
55984
  }))}`;
55164
55985
  }
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
- }));
55986
+ function toComposerDispatchRows(rowsById) {
55987
+ return [...rowsById.values()];
55176
55988
  }
55177
55989
  async function replayRecentSignals(input) {
55178
55990
  if (input.limit <= 0) return;
@@ -55295,8 +56107,8 @@ function shouldIgnoreIncomingSignal(input) {
55295
56107
  function processIgnoredOlderThanLiveFloorSignal(input) {
55296
56108
  if (!isSignalEnvelope(input.event)) return false;
55297
56109
  rememberSeenSignalId(input.seenSignalIds, input.event.id);
55298
- if (!resolveReplyingHintEvent(input.event)) return false;
55299
- input.onReplyingHintEvent(input.event);
56110
+ if (!resolveDispatchActivityEvent(input.event)) return false;
56111
+ input.onDispatchActivityEvent(input.event);
55300
56112
  return true;
55301
56113
  }
55302
56114
  function resolveReplyingSignalDispatchId(event) {
@@ -55624,15 +56436,15 @@ function shouldRefreshSpaceMetaForEvent(event) {
55624
56436
  function ignoreAsyncResult(promise) {
55625
56437
  promise.catch(() => void 0);
55626
56438
  }
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;
56439
+ function isDispatchActivityPurpose(purpose) {
56440
+ 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
56441
  }
55630
- function resolveReplyingHintBase(event) {
56442
+ function resolveDispatchActivityBase(event) {
55631
56443
  if (event.type !== "signal.text") return null;
55632
56444
  const meta = resolveSignalTextMetaFromEnvelope(event);
55633
56445
  if (!meta || meta.transient !== true) return null;
55634
56446
  const purpose = String(meta.purpose ?? "").trim();
55635
- if (!isReplyingHintPurpose(purpose)) return null;
56447
+ if (!isDispatchActivityPurpose(purpose)) return null;
55636
56448
  const dispatchId = String(meta.dispatchId ?? "").trim();
55637
56449
  if (!dispatchId) return null;
55638
56450
  const targetProfileId = String(meta.targetProfileId ?? "").trim();
@@ -55641,45 +56453,85 @@ function resolveReplyingHintBase(event) {
55641
56453
  meta,
55642
56454
  purpose,
55643
56455
  dispatchId,
55644
- targetProfileId
56456
+ sourceClientMessageId: normalizeOptionalMetaText(meta.sourceClientMessageId),
56457
+ sourceEventId: normalizeOptionalMetaText(meta.sourceEventId),
56458
+ targetProfileId,
56459
+ targetWakeToken: normalizeOptionalMetaText(meta.targetWakeToken)
55645
56460
  };
55646
56461
  }
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;
56462
+ function resolveDispatchActivityTargetLabel(input) {
56463
+ 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
56464
  }
55650
56465
  function resolveContinuityWarningText(event) {
55651
56466
  return sanitizeTerminalDisplayText(String(event.data?.text ?? ""), "single-line").trim() || null;
55652
56467
  }
55653
- function resolveReplyingHintEvent(event) {
55654
- const base = resolveReplyingHintBase(event);
56468
+ function resolveDispatchActivityEvent(event) {
56469
+ const base = resolveDispatchActivityBase(event);
55655
56470
  if (!base) return null;
55656
- const { dispatchId, meta, purpose, targetProfileId } = base;
55657
- if (purpose === TRANSIENT_HINT_END_PURPOSE) return {
56471
+ const { dispatchId, meta, purpose, sourceClientMessageId, sourceEventId, targetProfileId, targetWakeToken } = base;
56472
+ if (purpose === AGENT_REPLYING_END_PURPOSE) return {
55658
56473
  kind: "end",
55659
56474
  dispatchId,
55660
- targetProfileId
56475
+ sourceClientMessageId,
56476
+ sourceEventId,
56477
+ targetProfileId,
56478
+ targetWakeToken
55661
56479
  };
55662
- const targetLabel = resolveReplyingHintTargetLabel({
56480
+ const targetLabel = resolveDispatchActivityTargetLabel({
55663
56481
  event,
55664
56482
  purpose,
55665
56483
  meta,
55666
56484
  targetProfileId
55667
56485
  });
56486
+ if (purpose === DISPATCH_ACTIVITY_DISPATCHING_PURPOSE) {
56487
+ const text = resolveContinuityWarningText(event);
56488
+ if (!text) return null;
56489
+ return {
56490
+ kind: "dispatching",
56491
+ dispatchId,
56492
+ sourceClientMessageId,
56493
+ sourceEventId,
56494
+ targetProfileId,
56495
+ targetLabel,
56496
+ targetWakeToken,
56497
+ text
56498
+ };
56499
+ }
56500
+ if (purpose === DISPATCH_ACTIVITY_RETRYING_PURPOSE) {
56501
+ const text = resolveContinuityWarningText(event);
56502
+ if (!text) return null;
56503
+ return {
56504
+ kind: "retrying",
56505
+ dispatchId,
56506
+ sourceClientMessageId,
56507
+ sourceEventId,
56508
+ targetProfileId,
56509
+ targetLabel,
56510
+ targetWakeToken,
56511
+ text
56512
+ };
56513
+ }
55668
56514
  if (purpose === AGENT_REPLY_PREVIEW_PURPOSE) {
55669
56515
  const previewText = normalizePreviewDisplayText(String(event.data?.text ?? ""));
55670
56516
  if (!previewText) return null;
55671
56517
  return {
55672
56518
  kind: "preview",
55673
56519
  dispatchId,
56520
+ sourceClientMessageId,
56521
+ sourceEventId,
55674
56522
  targetProfileId,
55675
56523
  targetLabel,
56524
+ targetWakeToken,
55676
56525
  previewText
55677
56526
  };
55678
56527
  }
55679
56528
  if (purpose === AGENT_REPLY_PREVIEW_END_PURPOSE) return {
55680
56529
  kind: "preview_end",
55681
56530
  dispatchId,
55682
- targetProfileId
56531
+ sourceClientMessageId,
56532
+ sourceEventId,
56533
+ targetProfileId,
56534
+ targetWakeToken
55683
56535
  };
55684
56536
  if (purpose === CONVERSATION_CONTINUITY_WARNING_PURPOSE) {
55685
56537
  const text = resolveContinuityWarningText(event);
@@ -55687,16 +56539,38 @@ function resolveReplyingHintEvent(event) {
55687
56539
  return {
55688
56540
  kind: "warning",
55689
56541
  dispatchId,
56542
+ sourceClientMessageId,
56543
+ sourceEventId,
55690
56544
  targetProfileId,
55691
56545
  targetLabel,
55692
- text
56546
+ targetWakeToken,
56547
+ text,
56548
+ preserveActivityMode: true
56549
+ };
56550
+ }
56551
+ if (purpose === DISPATCH_ACTIVITY_FAILED_PURPOSE) {
56552
+ const text = resolveContinuityWarningText(event);
56553
+ if (!text) return null;
56554
+ return {
56555
+ kind: "warning",
56556
+ dispatchId,
56557
+ sourceClientMessageId,
56558
+ sourceEventId,
56559
+ targetProfileId,
56560
+ targetLabel,
56561
+ targetWakeToken,
56562
+ text,
56563
+ preserveActivityMode: false
55693
56564
  };
55694
56565
  }
55695
56566
  return {
55696
56567
  kind: "replying_start",
55697
56568
  dispatchId,
56569
+ sourceClientMessageId,
56570
+ sourceEventId,
55698
56571
  targetProfileId,
55699
- targetLabel
56572
+ targetLabel,
56573
+ targetWakeToken
55700
56574
  };
55701
56575
  }
55702
56576
  function resolveNonTransientSignalText(event) {
@@ -55710,6 +56584,9 @@ function resolveSignalTextMetaFromEnvelope(event) {
55710
56584
  if (!meta || typeof meta !== "object" || Array.isArray(meta)) return null;
55711
56585
  return meta;
55712
56586
  }
56587
+ function resolveSignalClientMessageId(event) {
56588
+ return normalizeOptionalMetaText(resolveSignalTextMetaFromEnvelope(event)?.clientMessageId);
56589
+ }
55713
56590
  function normalizePreviewDisplayText(value) {
55714
56591
  return sanitizeTerminalDisplayText(value, "single-line").replace(/\s+/g, " ").trim();
55715
56592
  }
@@ -55747,6 +56624,10 @@ function normalizeOptionalMetaText(value) {
55747
56624
  const normalized = value.trim();
55748
56625
  return normalized.length > 0 ? normalized : null;
55749
56626
  }
56627
+ function resolveMentionTokenLabel(value) {
56628
+ if (!value) return null;
56629
+ return value.startsWith("@") ? value : `@${value}`;
56630
+ }
55750
56631
  function extractReplyingTargetLabelFromText(text) {
55751
56632
  const normalized = sanitizeTerminalDisplayText(text, "single-line").trim();
55752
56633
  return REPLYING_TARGET_LABEL_REGEX.exec(normalized)?.[1] ?? null;
@@ -58338,11 +59219,7 @@ async function resolveSpaceJoinTarget(input) {
58338
59219
  });
58339
59220
  }
58340
59221
  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;
59222
+ const localDemand = input.interactiveHuman ? await resolveDaemonLocalServiceDemand({ ownerUserId: input.atsProfile.ownerUserId }).catch(() => null) : null;
58346
59223
  const hasExplicitBaseUrlInput = String(input.input.baseUrl ?? "").trim().length > 0;
58347
59224
  const baseUrl = input.input.resolvedBaseUrl ?? await resolveBaseUrl(input.input.baseUrl);
58348
59225
  await emitSpaceCommandPreflight({
@@ -58353,7 +59230,7 @@ async function prepareSpaceJoinServiceState(input) {
58353
59230
  resolvedView: input.resolvedView
58354
59231
  });
58355
59232
  await maybeOfferDaemonStartBeforeSpaceJoin({
58356
- autoStopLocalDemand: autoStopResult?.localDemand ?? null,
59233
+ localDemand,
58357
59234
  presenter: input.presenter,
58358
59235
  view: input.input.view
58359
59236
  });
@@ -58365,7 +59242,7 @@ async function prepareSpaceJoinServiceState(input) {
58365
59242
  async function maybeOfferDaemonStartBeforeSpaceJoin(input) {
58366
59243
  const runtime = await resolveRuntimeContext({ view: input.view });
58367
59244
  if (runtime.resolvedView !== "human" || !canUseInteractivePrompts(runtime)) return;
58368
- if (input.autoStopLocalDemand?.decision !== "keep_running") return;
59245
+ if (input.localDemand?.decision !== "keep_running") return;
58369
59246
  const daemonStatus = await getDaemonStatus().catch(() => NOT_INSTALLED_DAEMON_STATUS);
58370
59247
  if (!daemonStatus.installed) return;
58371
59248
  const runtimeState = await resolveDaemonRuntimeState(daemonStatus);
@@ -59049,6 +59926,7 @@ async function runSpaceDelete(input) {
59049
59926
  const outcome = await runSpaceDeleteAttempt({
59050
59927
  targets: targets.targets,
59051
59928
  currentProfileId: profile,
59929
+ currentProfileName: atsProfile.profileName,
59052
59930
  allowBackToSelection: targets.allowBackToSelection,
59053
59931
  runtime,
59054
59932
  presenter,
@@ -59067,6 +59945,7 @@ async function runSpaceDeleteAttempt(input) {
59067
59945
  const confirmation = await confirmDeleteTargets({
59068
59946
  targets: input.targets,
59069
59947
  currentProfileId: input.currentProfileId,
59948
+ currentProfileName: input.currentProfileName,
59070
59949
  allowBack: input.allowBackToSelection
59071
59950
  });
59072
59951
  if (confirmation === "cancelled") return "cancelled";
@@ -59138,7 +60017,8 @@ async function confirmDeleteTargets(input) {
59138
60017
  const confirmed = await confirm({
59139
60018
  message: buildDeleteConfirmationMessage({
59140
60019
  targets: input.targets,
59141
- currentProfileId: input.currentProfileId
60020
+ currentProfileId: input.currentProfileId,
60021
+ currentProfileName: input.currentProfileName
59142
60022
  }),
59143
60023
  initialValue: false
59144
60024
  });
@@ -59164,7 +60044,8 @@ async function confirmDeleteTargets(input) {
59164
60044
  const decision = await select({
59165
60045
  message: buildDeleteConfirmationMessage({
59166
60046
  targets: input.targets,
59167
- currentProfileId: input.currentProfileId
60047
+ currentProfileId: input.currentProfileId,
60048
+ currentProfileName: input.currentProfileName
59168
60049
  }),
59169
60050
  options: [
59170
60051
  {
@@ -60683,6 +61564,48 @@ async function resolveOwnedKnownSpacesForDelete(input) {
60683
61564
  }
60684
61565
  return owned;
60685
61566
  }
61567
+ async function resolveExplicitSpaceDeleteTarget(input) {
61568
+ const matchedKnown = await findKnownSpaceForDeleteBySpaceId({
61569
+ atsProfile: input.atsProfile,
61570
+ baseUrl: input.baseUrl,
61571
+ space: input.space
61572
+ });
61573
+ if (matchedKnown) return toSpaceDeleteTarget(matchedKnown);
61574
+ const matchedLocal = (await listSpaceConfigs({ profile: input.atsProfile.atsProfileId })).find((item) => item.space === input.space);
61575
+ if (matchedLocal) return toSpaceDeleteTarget(toKnownSpaceOptionFromLocal(matchedLocal, input.atsProfile));
61576
+ return toSpaceDeleteTarget(await hydrateKnownSpaceForDeleteFromMeta({
61577
+ item: {
61578
+ source: "local",
61579
+ space: input.space,
61580
+ baseUrl: input.baseUrl
61581
+ },
61582
+ profile: input.atsProfile.atsProfileId,
61583
+ profileName: input.atsProfile.profileName,
61584
+ baseUrl: input.baseUrl
61585
+ }));
61586
+ }
61587
+ async function findKnownSpaceForDeleteBySpaceId(input) {
61588
+ const matched = (await resolveKnownSpacesForSelection({
61589
+ atsProfile: input.atsProfile,
61590
+ baseUrl: input.baseUrl,
61591
+ command: "delete"
61592
+ }).catch(() => null))?.items.find((item) => item.space === input.space);
61593
+ if (!matched) return null;
61594
+ const [authorized] = await resolveOwnedKnownSpacesForDelete({
61595
+ known: [matched],
61596
+ profile: input.atsProfile.atsProfileId,
61597
+ profileName: input.atsProfile.profileName,
61598
+ ownerUserId: input.atsProfile.ownerUserId,
61599
+ baseUrl: input.baseUrl
61600
+ });
61601
+ if (authorized) return authorized;
61602
+ return await hydrateKnownSpaceForDeleteFromMeta({
61603
+ item: matched,
61604
+ profile: input.atsProfile.atsProfileId,
61605
+ profileName: input.atsProfile.profileName,
61606
+ baseUrl: input.baseUrl
61607
+ });
61608
+ }
60686
61609
  async function resolveKnownSpacesForPasswordSelection(input) {
60687
61610
  return (await Promise.all(input.known.map((item) => hydrateKnownSpacePasswordProtection({
60688
61611
  item,
@@ -61336,19 +62259,14 @@ async function resolveSpaceDeleteTargets(input) {
61336
62259
  space: explicitSpace,
61337
62260
  resolvedView: input.resolvedView
61338
62261
  });
61339
- const matched = (await listSpaceConfigs({ profile: input.atsProfile.atsProfileId })).find((item) => item.space === explicitSpace);
61340
62262
  return {
61341
62263
  status: "submitted",
61342
62264
  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
- }]
62265
+ targets: [await resolveExplicitSpaceDeleteTarget({
62266
+ atsProfile: input.atsProfile,
62267
+ baseUrl: input.baseUrl,
62268
+ space: explicitSpace
62269
+ })]
61352
62270
  };
61353
62271
  }
61354
62272
  if (!input.allowPrompt) {
@@ -61831,7 +62749,7 @@ function buildKnownSpaceProfileMap(profiles) {
61831
62749
  return byId;
61832
62750
  }
61833
62751
  function resolveKnownSpaceVisibilityScope(input) {
61834
- if (input.atsProfile.profileKind === "human" && input.atsProfile.isDefault === true && (input.command === "join" || input.command === "watch" || input.command === "guidelines")) return "owner";
62752
+ if (input.atsProfile.profileKind === "human" && input.atsProfile.isDefault === true && (input.command === "join" || input.command === "watch" || input.command === "guidelines" || input.command === "delete")) return "owner";
61835
62753
  return "profile";
61836
62754
  }
61837
62755
  async function resolveKnownSpacesForSelectionByProfile(input) {
@@ -62857,17 +63775,14 @@ function buildHumanKnownSpaceSearchItems(input) {
62857
63775
  }];
62858
63776
  }
62859
63777
  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({
63778
+ const projection = buildKnownSpaceDisplayProjection({
62867
63779
  space: input.space,
62868
63780
  currentProfileId: input.currentProfileId,
62869
63781
  currentProfileName: input.currentProfileName
62870
63782
  });
63783
+ const idLabel = `ID ${shortenSpaceId(formatSpaceDisplayValue(projection.spaceId))}`;
63784
+ const creatorLabel = projection.creatorDisplayName;
63785
+ const viaLabel = projection.availableViaDisplayName;
62871
63786
  const parts = [idLabel];
62872
63787
  if (creatorLabel) parts.push(`Created by ${creatorLabel}`);
62873
63788
  if (viaLabel && viaLabel !== creatorLabel) parts.push(`via ${viaLabel}`);
@@ -62876,45 +63791,22 @@ function buildHumanKnownSpaceDetailLine(input) {
62876
63791
  return parts.join(" · ");
62877
63792
  }
62878
63793
  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,
63794
+ const projection = buildKnownSpaceDisplayProjection({
63795
+ space: input.space,
62913
63796
  currentProfileId: input.currentProfileId,
62914
63797
  currentProfileName: input.currentProfileName
62915
63798
  });
62916
- if (via === "unknown-profile") return null;
62917
- return sanitizeSingleLinePromptText(via);
63799
+ return [
63800
+ formatSpaceDisplayValue(projection.spaceId, ""),
63801
+ formatSpaceDisplayValue(projection.spaceName, ""),
63802
+ formatSpaceDisplayValue(projection.creatorProfileName, ""),
63803
+ formatSpaceDisplayValue(projection.creatorProfileId, ""),
63804
+ sanitizeSingleLinePromptText(normalizeOptionalString$2(input.space.creatorOwnerUserId)),
63805
+ formatSpaceDisplayValue(projection.availableViaProfileName, ""),
63806
+ formatSpaceDisplayValue(projection.availableViaProfileId, ""),
63807
+ formatSpaceDisplayValue(projection.creatorDisplayName, ""),
63808
+ formatSpaceDisplayValue(projection.availableViaDisplayName, "")
63809
+ ].filter((value) => typeof value === "string").join("\n");
62918
63810
  }
62919
63811
  function resolveKnownSpaceJoinedTimestamp(space) {
62920
63812
  return normalizeOptionalString$2(space.lastJoinedAt) ?? resolveKnownSpaceLastSeenTimestamp(space.lastSeenTs);
@@ -62964,7 +63856,7 @@ async function promptSpaceDeleteSelection(input) {
62964
63856
  if (input.known.length === 0) {
62965
63857
  if (input.resolvedView === "human") {
62966
63858
  const manual = await promptHumanManualSpaceId({
62967
- message: "No spaces created by your user were found. Enter a space ID manually",
63859
+ message: "No spaces you can delete were found. Enter a space ID manually",
62968
63860
  description: "Paste a 64-character hex space ID to delete it.",
62969
63861
  allowBack: input.allowBack === true
62970
63862
  });
@@ -62975,7 +63867,7 @@ async function promptSpaceDeleteSelection(input) {
62975
63867
  targets: [{ space: manual.value }]
62976
63868
  };
62977
63869
  }
62978
- const manual = await promptManualSpace("No spaces created by your user were found. Enter a space ID (64-character hex):", input.resolvedView);
63870
+ const manual = await promptManualSpace("No spaces you can delete were found. Enter a space ID (64-character hex):", input.resolvedView);
62979
63871
  return manual ? {
62980
63872
  status: "submitted",
62981
63873
  allowBackToSelection: true,
@@ -63141,6 +64033,18 @@ function toSpaceDeleteTarget(space) {
63141
64033
  ...space.creatorKind === void 0 ? {} : { creatorKind: space.creatorKind }
63142
64034
  };
63143
64035
  }
64036
+ function toKnownSpaceOptionFromDeleteTarget(target) {
64037
+ return {
64038
+ source: "local",
64039
+ space: target.space,
64040
+ ...target.baseUrl ? { baseUrl: target.baseUrl } : {},
64041
+ ...target.name === void 0 ? {} : { name: target.name },
64042
+ ...target.creatorProfileName === void 0 ? {} : { creatorProfileName: target.creatorProfileName },
64043
+ ...target.creatorProfileId === void 0 ? {} : { creatorProfileId: target.creatorProfileId },
64044
+ ...target.creatorOwnerUserId === void 0 ? {} : { creatorOwnerUserId: target.creatorOwnerUserId },
64045
+ ...target.creatorKind === void 0 ? {} : { creatorKind: target.creatorKind }
64046
+ };
64047
+ }
63144
64048
  function normalizeSpaceDeleteSelection(value) {
63145
64049
  if (!Array.isArray(value)) return [];
63146
64050
  const selected = [];
@@ -63196,7 +64100,10 @@ function normalizeKnownSpaceVisibilityScope(visibilityScope) {
63196
64100
  return visibilityScope === "owner" ? "owner" : "profile";
63197
64101
  }
63198
64102
  function formatKnownSpaceName(input) {
63199
- const name = sanitizeSingleLinePromptText(input.space.name) || "untitled-space";
64103
+ const name = resolveSpaceDisplayName(buildKnownSpaceDisplayProjection({
64104
+ space: input.space,
64105
+ currentProfileId: input.currentProfileId
64106
+ }).spaceName, "untitled-space");
63200
64107
  if (input.command === "password") return input.space.passwordProtected === true ? `🔒 ${name}` : name;
63201
64108
  return input.resolvedView === "human" && input.space.passwordProtected === true ? `🔒 - ${name}` : name;
63202
64109
  }
@@ -63253,35 +64160,19 @@ function buildKnownSpaceData(item, index) {
63253
64160
  };
63254
64161
  }
63255
64162
  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,
64163
+ const projection = buildKnownSpaceDisplayProjection({
64164
+ space: input.space,
63265
64165
  currentProfileId: input.currentProfileId,
63266
64166
  currentProfileName: input.currentProfileName
63267
64167
  });
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
- ];
64168
+ const detailVariant = input.detailVariant ?? "full";
64169
+ const lines = buildSpaceMetadataFields({
64170
+ projection,
64171
+ includeAvailableVia: detailVariant !== "delete_confirmation",
64172
+ includeCreatedAt: detailVariant !== "delete_confirmation",
64173
+ includeLastJoinedAt: detailVariant !== "delete_confirmation"
64174
+ }).map((field) => `${field.label}: ${field.value}`);
64175
+ if (detailVariant === "delete_confirmation") return lines;
63285
64176
  if (input.resolvedView === "human") {
63286
64177
  if (input.space.source === "local") lines.push("Source: local cache");
63287
64178
  return lines;
@@ -63364,40 +64255,44 @@ function resolveGatewayHost(baseUrl) {
63364
64255
  return null;
63365
64256
  }
63366
64257
  }
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
64258
  function normalizeDisplayValue(value, fallback = "unknown") {
63378
64259
  const normalized = sanitizeSingleLinePromptText(String(value ?? ""));
63379
64260
  return normalized.length > 0 ? normalized : fallback;
63380
64261
  }
64262
+ function buildKnownSpaceDisplayProjection(input) {
64263
+ return buildSpaceDisplayProjection({
64264
+ currentProfileId: input.currentProfileId,
64265
+ currentProfileName: input.currentProfileName,
64266
+ spaceId: input.space.space,
64267
+ spaceName: input.space.name,
64268
+ creatorProfileId: input.space.creatorProfileId,
64269
+ creatorProfileName: input.space.creatorProfileName,
64270
+ availableViaProfileId: input.space.availableViaProfileId,
64271
+ availableViaProfileName: input.space.availableViaProfileName,
64272
+ spaceCreatedAt: input.space.spaceCreatedAt,
64273
+ lastJoinedAt: resolveKnownSpaceJoinedTimestamp(input.space),
64274
+ passwordProtected: input.space.passwordProtected
64275
+ });
64276
+ }
63381
64277
  function buildDeleteConfirmationMessage(input) {
63382
64278
  const count = input.targets.length;
63383
64279
  const lines = [count === 1 ? "Delete this space permanently?" : `Delete ${String(count)} spaces permanently?`, "This action permanently deletes space data for everyone."];
63384
64280
  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}`);
64281
+ const knownSpace = toKnownSpaceOptionFromDeleteTarget(target);
64282
+ lines.push(`${String(index + 1)}. ${formatKnownSpaceName({
64283
+ space: knownSpace,
64284
+ resolvedView: "human",
64285
+ currentProfileId: input.currentProfileId,
64286
+ command: "delete"
64287
+ })}`);
64288
+ lines.push(...formatKnownSpaceDetailLines({
64289
+ space: knownSpace,
64290
+ resolvedView: "human",
64291
+ currentProfileId: input.currentProfileId,
64292
+ currentProfileName: input.currentProfileName,
64293
+ detailVariant: "delete_confirmation",
64294
+ command: "delete"
64295
+ }).map((line) => ` ${line}`));
63401
64296
  }
63402
64297
  return lines.join("\n");
63403
64298
  }
@@ -63408,7 +64303,7 @@ function buildHumanSpaceDeleteBlockedError(input) {
63408
64303
  if (resolveUpstreamStatus(parsed) !== 403) return null;
63409
64304
  if (!isSpaceDeleteOwnerRestrictionError(parsed)) return null;
63410
64305
  const spaceName = normalizeDisplayValue(input.target.name, "this space");
63411
- return /* @__PURE__ */ new Error(`Delete blocked: you can only delete spaces you created (${spaceName}).`);
64306
+ return /* @__PURE__ */ new Error(`Delete blocked: this human profile can only delete its own spaces or your owned agent-created spaces (${spaceName}).`);
63412
64307
  }
63413
64308
  function isSpaceDeleteOwnerRestrictionError(input) {
63414
64309
  const code = input.code.toLowerCase();
@@ -63432,11 +64327,11 @@ function renderHumanSpaceDeleteBlockedCard(input) {
63432
64327
  },
63433
64328
  {
63434
64329
  label: "Reason",
63435
- value: "You can only delete spaces created by your user."
64330
+ value: "This human profile can only delete its own spaces or your owned agent-created spaces."
63436
64331
  },
63437
64332
  {
63438
64333
  label: "Try",
63439
- value: "Select a space created by your user, then retry."
64334
+ value: "Switch to the human creator profile, or choose an agent-created space your user owns."
63440
64335
  }
63441
64336
  ],
63442
64337
  sanitize: true,
@@ -64154,13 +65049,9 @@ async function runStartServiceStep(input) {
64154
65049
  return "continue";
64155
65050
  }
64156
65051
  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;
65052
+ const localDemand = input.runtime.resolvedView === "human" && input.interactive ? await resolveDaemonLocalServiceDemand({ ownerUserId: input.ownerUserId }).catch(() => null) : null;
64162
65053
  if (input.readiness.service.runtime?.status === "running") return "continue";
64163
- if (localDemandResult && localDemandResult.localDemand.decision !== "keep_running") return "continue";
65054
+ if (localDemand && localDemand.decision !== "keep_running") return "continue";
64164
65055
  if (!input.interactive) {
64165
65056
  input.presenter.line({
64166
65057
  code: "start.service.non_interactive",
@@ -67148,9 +68039,9 @@ withSpaceProfileOption(spaceCmd.command("delete").description("Delete one or mor
67148
68039
  }
67149
68040
  });
67150
68041
  });
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) => {
68042
+ 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
68043
  const cliOptions = resolveSpaceCommandCliOptions(command, opts);
67153
- const localEcho = opts.noLocalEcho === true ? false : opts.localEcho === true;
68044
+ const localEcho = opts.noLocalEcho !== true;
67154
68045
  const view = getGlobalViewOption();
67155
68046
  if (view === "agent" && normalizeOptionalString(space) === null) {
67156
68047
  await runSpaceJoin({