@alook/cli 0.0.149 → 0.0.151

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.
@@ -12,10 +12,45 @@ var __export = (target, all) => {
12
12
  set: __exportSetter.bind(all, name)
13
13
  });
14
14
  };
15
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
16
+
17
+ // ../../node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/url-alphabet/index.js
18
+ var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
19
+
20
+ // ../../node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/index.js
21
+ import { webcrypto as crypto2 } from "node:crypto";
22
+ function fillPool(bytes) {
23
+ if (bytes < 0)
24
+ throw new RangeError("Wrong ID size");
25
+ try {
26
+ if (!pool || pool.length < bytes) {
27
+ pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
28
+ crypto2.getRandomValues(pool);
29
+ poolOffset = 0;
30
+ } else if (poolOffset + bytes > pool.length) {
31
+ crypto2.getRandomValues(pool);
32
+ poolOffset = 0;
33
+ }
34
+ } catch (e) {
35
+ pool = undefined;
36
+ throw e;
37
+ }
38
+ poolOffset += bytes;
39
+ }
40
+ function nanoid3(size = 21) {
41
+ fillPool(size |= 0);
42
+ let id = "";
43
+ for (let i = poolOffset - size;i < poolOffset; i++) {
44
+ id += urlAlphabet[pool[i] & 63];
45
+ }
46
+ return id;
47
+ }
48
+ var POOL_SIZE_MULTIPLIER = 128, pool, poolOffset;
49
+ var init_nanoid = () => {};
15
50
 
16
51
  // daemon/session-runner.ts
17
52
  import { mkdir, writeFile, rm, rename } from "fs/promises";
18
- import { mkdirSync as mkdirSync4 } from "fs";
53
+ import { mkdirSync as mkdirSync5 } from "fs";
19
54
  import path from "path";
20
55
 
21
56
  // ../shared/src/constants.ts
@@ -63,6 +98,7 @@ var TERMINAL_ISSUE_STATUSES = [
63
98
  ];
64
99
  var POLL_INTERVAL_MS = Number(process.env.POLL_INTERVAL_MS) || 3000;
65
100
  var OFFLINE_THRESHOLD_MS = Number(process.env.OFFLINE_THRESHOLD_MS) || 30000;
101
+ var COMMUNITY_MACHINE_PAIR_TOKEN_TTL_MS = 15 * 60000;
66
102
  var EVENT_POLL_INTERVAL_MS = Number(process.env.EVENT_POLL_INTERVAL_MS) || 2000;
67
103
  var MeetingStatus = {
68
104
  PENDING: "pending",
@@ -76,9 +112,24 @@ var TERMINAL_MEETING_STATUSES = [
76
112
  MeetingStatus.COMPLETED,
77
113
  MeetingStatus.FAILED
78
114
  ];
79
- var DEV_WEB_URL = process.env.ALOOK_SERVER_URL || "http://localhost:3000";
80
- var DEV_WS_DO_URL = process.env.DEV_WS_DO_URL || "http://localhost:8789";
81
- var DEV_EMAIL_WORKER_URL = process.env.DEV_EMAIL_WORKER_URL || "http://localhost:8787";
115
+ var COMMUNITY_BOT_NAME_MIN = 1;
116
+ var COMMUNITY_BOT_NAME_MAX = 32;
117
+ var COMMUNITY_BOT_DESCRIPTION_MAX = 1024;
118
+ var COMMUNITY_BOT_IMAGE_URL_MAX = 2048;
119
+ var DEV_PORTS = {
120
+ web: 3000,
121
+ emailWorker: 8787,
122
+ wsDo: 8789,
123
+ wakeWorker: 8790
124
+ };
125
+ var DEV_WEB_URL = process.env.ALOOK_SERVER_URL || `http://localhost:${DEV_PORTS.web}`;
126
+ var DEV_WS_DO_URL = process.env.DEV_WS_DO_URL || `http://localhost:${DEV_PORTS.wsDo}`;
127
+ var DEV_EMAIL_WORKER_URL = process.env.DEV_EMAIL_WORKER_URL || `http://localhost:${DEV_PORTS.emailWorker}`;
128
+ var DEV_WAKE_WORKER_URL = process.env.DEV_WAKE_WORKER_URL || `http://localhost:${DEV_PORTS.wakeWorker}`;
129
+ // ../shared/src/constants/community.ts
130
+ var MAX_MESSAGE_CONTENT_LENGTH = 4000;
131
+ var MAX_ATTACHMENT_SIZE_BYTES = 25 * 1024 * 1024;
132
+ var MAX_SERVER_ICON_SIZE_BYTES = 5 * 1024 * 1024;
82
133
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
83
134
  var exports_external = {};
84
135
  __export(exports_external, {
@@ -14843,7 +14894,149 @@ var CreateThreadRequestSchema = exports_external.object({
14843
14894
  content: exports_external.string().optional().default(""),
14844
14895
  attachment_ids: exports_external.array(exports_external.string()).optional()
14845
14896
  });
14846
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/entity.js
14897
+ var COMMUNITY_RUNTIME_ID_MAX = 64;
14898
+ var COMMUNITY_RUNTIME_VERSION_MAX = 64;
14899
+ var COMMUNITY_RUNTIME_LIST_MAX = 64;
14900
+ var RUNTIME_ID_RE = /^[A-Za-z0-9._@/-]+$/;
14901
+ var CommunityMachineRuntimeSchema = exports_external.object({
14902
+ id: exports_external.string().min(1).max(COMMUNITY_RUNTIME_ID_MAX).regex(RUNTIME_ID_RE, "invalid runtime id charset"),
14903
+ version: exports_external.string().max(COMMUNITY_RUNTIME_VERSION_MAX).optional(),
14904
+ status: exports_external.enum(["healthy", "unhealthy"]).catch("healthy").default("healthy"),
14905
+ lastError: exports_external.string().max(128).optional(),
14906
+ lastErrorAt: exports_external.string().optional()
14907
+ });
14908
+ var CommunityMachineRuntimeListSchema = exports_external.array(CommunityMachineRuntimeSchema).max(COMMUNITY_RUNTIME_LIST_MAX).transform((list) => {
14909
+ const seen = new Set;
14910
+ const out = [];
14911
+ for (const r of list) {
14912
+ if (seen.has(r.id))
14913
+ continue;
14914
+ seen.add(r.id);
14915
+ out.push(r);
14916
+ }
14917
+ return out;
14918
+ });
14919
+ var CommunityMachineSummarySchema = exports_external.object({
14920
+ id: exports_external.string(),
14921
+ hostname: exports_external.string(),
14922
+ displayName: exports_external.string(),
14923
+ platform: exports_external.string(),
14924
+ arch: exports_external.string(),
14925
+ osRelease: exports_external.string(),
14926
+ daemonVersion: exports_external.string(),
14927
+ lastSeenAt: exports_external.string().nullable(),
14928
+ status: exports_external.enum(["online", "offline"]),
14929
+ availableRuntimes: exports_external.array(CommunityMachineRuntimeSchema).default([]),
14930
+ lastRuntimeError: exports_external.object({
14931
+ requested: exports_external.string(),
14932
+ available: exports_external.array(exports_external.string()),
14933
+ at: exports_external.string()
14934
+ }).optional(),
14935
+ createdAt: exports_external.string(),
14936
+ updatedAt: exports_external.string()
14937
+ });
14938
+ var HostReadyMessageSchema = exports_external.object({
14939
+ type: exports_external.literal("ready"),
14940
+ runtimeReport: CommunityMachineRuntimeListSchema,
14941
+ runningAgents: exports_external.array(exports_external.string()).default([]),
14942
+ hostname: exports_external.string().optional(),
14943
+ platform: exports_external.string().optional(),
14944
+ arch: exports_external.string().optional(),
14945
+ osRelease: exports_external.string().optional(),
14946
+ daemonVersion: exports_external.string().optional()
14947
+ });
14948
+ var CommunityDaemonReadySchema = exports_external.object({
14949
+ runtimeReport: CommunityMachineRuntimeListSchema.optional(),
14950
+ runningAgents: exports_external.array(exports_external.string()).default([]),
14951
+ hostname: exports_external.string().optional(),
14952
+ os: exports_external.string().optional(),
14953
+ arch: exports_external.string().optional(),
14954
+ osRelease: exports_external.string().optional(),
14955
+ daemonVersion: exports_external.string().optional()
14956
+ });
14957
+ var SessionErrorFrameSchema = exports_external.object({
14958
+ type: exports_external.literal("session.error"),
14959
+ code: exports_external.enum(["runtime_not_available"]),
14960
+ agentId: exports_external.string().optional(),
14961
+ payload: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
14962
+ });
14963
+ var CommunityPairTokenResponseSchema = exports_external.object({
14964
+ tokenId: exports_external.string(),
14965
+ expiresAt: exports_external.string()
14966
+ });
14967
+ var CommunityDaemonActivateRequestSchema = exports_external.object({
14968
+ hostname: exports_external.string(),
14969
+ platform: exports_external.string(),
14970
+ arch: exports_external.string(),
14971
+ osRelease: exports_external.string().optional(),
14972
+ daemonVersion: exports_external.string().optional(),
14973
+ runtimeReport: CommunityMachineRuntimeListSchema.optional()
14974
+ });
14975
+ var CommunityDaemonActivateResponseSchema = exports_external.object({
14976
+ credential: exports_external.string(),
14977
+ machineId: exports_external.string(),
14978
+ expiresAt: exports_external.string().nullable()
14979
+ });
14980
+ var CommunityDaemonEnrollAgentRequestSchema = exports_external.object({
14981
+ agentId: exports_external.string().min(1).max(128)
14982
+ });
14983
+ var CommunityDaemonEnrollAgentResponseSchema = exports_external.object({
14984
+ runnerKey: exports_external.string(),
14985
+ expiresAt: exports_external.string().nullable()
14986
+ });
14987
+ var BotImageUrlSchema = exports_external.string().max(COMMUNITY_BOT_IMAGE_URL_MAX).refine((v) => v.startsWith("https://") || v.startsWith("avatar:"), {
14988
+ message: "image must be an https URL or an avatar: config"
14989
+ });
14990
+ var CommunityBotCreateRequestSchema = exports_external.object({
14991
+ name: exports_external.string().trim().min(COMMUNITY_BOT_NAME_MIN).max(COMMUNITY_BOT_NAME_MAX),
14992
+ description: exports_external.string().max(COMMUNITY_BOT_DESCRIPTION_MAX).optional(),
14993
+ machineId: exports_external.string().min(1),
14994
+ runtime: exports_external.string().min(1),
14995
+ image: BotImageUrlSchema.optional()
14996
+ });
14997
+ var CommunityBotPatchRequestSchema = exports_external.object({
14998
+ name: exports_external.string().trim().min(COMMUNITY_BOT_NAME_MIN).max(COMMUNITY_BOT_NAME_MAX).optional(),
14999
+ description: exports_external.string().max(COMMUNITY_BOT_DESCRIPTION_MAX).optional(),
15000
+ image: BotImageUrlSchema.nullable().optional()
15001
+ }).refine((v) => v.name !== undefined || v.description !== undefined || v.image !== undefined, {
15002
+ message: "at least one field must be provided"
15003
+ });
15004
+ var CommunityBotAddToServerRequestSchema = exports_external.object({
15005
+ botId: exports_external.string().min(1)
15006
+ });
15007
+ var CommunityAgentMessageContentSchema = exports_external.object({ text: exports_external.string().min(1).max(MAX_MESSAGE_CONTENT_LENGTH) }).catchall(exports_external.unknown());
15008
+ var CommunityAgentSeqSchema = exports_external.number().int().min(0);
15009
+ var CommunityAgentPositiveSeqSchema = exports_external.number().int().min(1);
15010
+ var CommunityAgentCursorSchema = exports_external.object({
15011
+ channel: exports_external.string().min(1),
15012
+ seq: CommunityAgentPositiveSeqSchema
15013
+ });
15014
+ var CommunityAgentSendRequestSchema = exports_external.object({
15015
+ channel: exports_external.string().min(1),
15016
+ content: CommunityAgentMessageContentSchema,
15017
+ seenUpToSeq: CommunityAgentSeqSchema.optional()
15018
+ });
15019
+ var CommunityAgentInboxPullRequestSchema = exports_external.object({
15020
+ max: exports_external.number().int().min(1).max(200).optional()
15021
+ });
15022
+ var CommunityAgentAckRequestSchema = exports_external.object({
15023
+ cursors: exports_external.array(CommunityAgentCursorSchema).min(1)
15024
+ });
15025
+ var CommunityAgentReadRequestSchema = exports_external.object({
15026
+ channel: exports_external.string().min(1),
15027
+ before: CommunityAgentSeqSchema.optional(),
15028
+ after: CommunityAgentSeqSchema.optional(),
15029
+ around: CommunityAgentSeqSchema.optional(),
15030
+ limit: exports_external.number().int().min(1).max(200).optional()
15031
+ }).refine((v) => [v.before, v.after, v.around].filter((x) => x !== undefined).length <= 1, { message: "at most one of before/after/around may be supplied" });
15032
+ var CommunityAgentResolveRequestSchema = exports_external.object({
15033
+ channel: exports_external.string().min(1),
15034
+ seq: CommunityAgentSeqSchema
15035
+ });
15036
+ var CommunityAgentListChannelsRequestSchema = exports_external.object({
15037
+ server: exports_external.string().min(1).optional()
15038
+ });
15039
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/entity.js
14847
15040
  var entityKind = Symbol.for("drizzle:entityKind");
14848
15041
  var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
14849
15042
  function is(value, type) {
@@ -14868,48 +15061,7 @@ function is(value, type) {
14868
15061
  return false;
14869
15062
  }
14870
15063
 
14871
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/table.utils.js
14872
- var TableName = Symbol.for("drizzle:Name");
14873
-
14874
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/table.js
14875
- var Schema = Symbol.for("drizzle:Schema");
14876
- var Columns = Symbol.for("drizzle:Columns");
14877
- var ExtraConfigColumns = Symbol.for("drizzle:ExtraConfigColumns");
14878
- var OriginalName = Symbol.for("drizzle:OriginalName");
14879
- var BaseName = Symbol.for("drizzle:BaseName");
14880
- var IsAlias = Symbol.for("drizzle:IsAlias");
14881
- var ExtraConfigBuilder = Symbol.for("drizzle:ExtraConfigBuilder");
14882
- var IsDrizzleTable = Symbol.for("drizzle:IsDrizzleTable");
14883
-
14884
- class Table {
14885
- static [entityKind] = "Table";
14886
- static Symbol = {
14887
- Name: TableName,
14888
- Schema,
14889
- OriginalName,
14890
- Columns,
14891
- ExtraConfigColumns,
14892
- BaseName,
14893
- IsAlias,
14894
- ExtraConfigBuilder
14895
- };
14896
- [TableName];
14897
- [OriginalName];
14898
- [Schema];
14899
- [Columns];
14900
- [ExtraConfigColumns];
14901
- [BaseName];
14902
- [IsAlias] = false;
14903
- [IsDrizzleTable] = true;
14904
- [ExtraConfigBuilder] = undefined;
14905
- constructor(name, schema, baseName) {
14906
- this[TableName] = this[OriginalName] = name;
14907
- this[Schema] = schema;
14908
- this[BaseName] = baseName;
14909
- }
14910
- }
14911
-
14912
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/column.js
15064
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/column.js
14913
15065
  class Column {
14914
15066
  constructor(table, config2) {
14915
15067
  this.table = table;
@@ -14959,7 +15111,7 @@ class Column {
14959
15111
  }
14960
15112
  }
14961
15113
 
14962
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/column-builder.js
15114
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/column-builder.js
14963
15115
  class ColumnBuilder {
14964
15116
  static [entityKind] = "ColumnBuilder";
14965
15117
  config;
@@ -15015,17 +15167,20 @@ class ColumnBuilder {
15015
15167
  }
15016
15168
  }
15017
15169
 
15018
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/tracing-utils.js
15170
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/table.utils.js
15171
+ var TableName = Symbol.for("drizzle:Name");
15172
+
15173
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/tracing-utils.js
15019
15174
  function iife(fn, ...args) {
15020
15175
  return fn(...args);
15021
15176
  }
15022
15177
 
15023
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/pg-core/unique-constraint.js
15178
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/pg-core/unique-constraint.js
15024
15179
  function uniqueKeyName(table, columns) {
15025
15180
  return `${table[TableName]}_${columns.join("_")}_unique`;
15026
15181
  }
15027
15182
 
15028
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/pg-core/columns/common.js
15183
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/pg-core/columns/common.js
15029
15184
  class PgColumn extends Column {
15030
15185
  constructor(table, config2) {
15031
15186
  if (!config2.uniqueName) {
@@ -15074,7 +15229,7 @@ class ExtraConfigColumn extends PgColumn {
15074
15229
  }
15075
15230
  }
15076
15231
 
15077
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/pg-core/columns/enum.js
15232
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/pg-core/columns/enum.js
15078
15233
  class PgEnumObjectColumn extends PgColumn {
15079
15234
  static [entityKind] = "PgEnumObjectColumn";
15080
15235
  enum;
@@ -15104,7 +15259,7 @@ class PgEnumColumn extends PgColumn {
15104
15259
  }
15105
15260
  }
15106
15261
 
15107
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/subquery.js
15262
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/subquery.js
15108
15263
  class Subquery {
15109
15264
  static [entityKind] = "Subquery";
15110
15265
  constructor(sql, fields, alias, isWith = false, usedTables = []) {
@@ -15119,10 +15274,10 @@ class Subquery {
15119
15274
  }
15120
15275
  }
15121
15276
 
15122
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/version.js
15277
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/version.js
15123
15278
  var version2 = "0.45.2";
15124
15279
 
15125
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/tracing.js
15280
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/tracing.js
15126
15281
  var otel;
15127
15282
  var rawTracer;
15128
15283
  var tracer = {
@@ -15149,10 +15304,48 @@ var tracer = {
15149
15304
  }
15150
15305
  };
15151
15306
 
15152
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/view-common.js
15307
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/view-common.js
15153
15308
  var ViewBaseConfig = Symbol.for("drizzle:ViewBaseConfig");
15154
15309
 
15155
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sql/sql.js
15310
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/table.js
15311
+ var Schema = Symbol.for("drizzle:Schema");
15312
+ var Columns = Symbol.for("drizzle:Columns");
15313
+ var ExtraConfigColumns = Symbol.for("drizzle:ExtraConfigColumns");
15314
+ var OriginalName = Symbol.for("drizzle:OriginalName");
15315
+ var BaseName = Symbol.for("drizzle:BaseName");
15316
+ var IsAlias = Symbol.for("drizzle:IsAlias");
15317
+ var ExtraConfigBuilder = Symbol.for("drizzle:ExtraConfigBuilder");
15318
+ var IsDrizzleTable = Symbol.for("drizzle:IsDrizzleTable");
15319
+
15320
+ class Table {
15321
+ static [entityKind] = "Table";
15322
+ static Symbol = {
15323
+ Name: TableName,
15324
+ Schema,
15325
+ OriginalName,
15326
+ Columns,
15327
+ ExtraConfigColumns,
15328
+ BaseName,
15329
+ IsAlias,
15330
+ ExtraConfigBuilder
15331
+ };
15332
+ [TableName];
15333
+ [OriginalName];
15334
+ [Schema];
15335
+ [Columns];
15336
+ [ExtraConfigColumns];
15337
+ [BaseName];
15338
+ [IsAlias] = false;
15339
+ [IsDrizzleTable] = true;
15340
+ [ExtraConfigBuilder] = undefined;
15341
+ constructor(name, schema, baseName) {
15342
+ this[TableName] = this[OriginalName] = name;
15343
+ this[Schema] = schema;
15344
+ this[BaseName] = baseName;
15345
+ }
15346
+ }
15347
+
15348
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sql/sql.js
15156
15349
  function isSQLWrapper(value) {
15157
15350
  return value !== null && value !== undefined && typeof value.getSQL === "function";
15158
15351
  }
@@ -15512,7 +15705,7 @@ Subquery.prototype.getSQL = function() {
15512
15705
  return new SQL([this]);
15513
15706
  };
15514
15707
 
15515
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/utils.js
15708
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/utils.js
15516
15709
  function getColumnNameAndConfig(a, b) {
15517
15710
  return {
15518
15711
  name: typeof a === "string" && a.length > 0 ? a : "",
@@ -15521,7 +15714,32 @@ function getColumnNameAndConfig(a, b) {
15521
15714
  }
15522
15715
  var textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder;
15523
15716
 
15524
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/foreign-keys.js
15717
+ // ../shared/src/db/community-schema.ts
15718
+ var exports_community_schema = {};
15719
+ __export(exports_community_schema, {
15720
+ communityUserProfile: () => communityUserProfile,
15721
+ communityServerMember: () => communityServerMember,
15722
+ communityServerInvite: () => communityServerInvite,
15723
+ communityServerFolderItem: () => communityServerFolderItem,
15724
+ communityServerFolder: () => communityServerFolder,
15725
+ communityServer: () => communityServer,
15726
+ communityReadState: () => communityReadState,
15727
+ communityReaction: () => communityReaction,
15728
+ communityPin: () => communityPin,
15729
+ communityNotificationSetting: () => communityNotificationSetting,
15730
+ communityMessageSeq: () => communityMessageSeq,
15731
+ communityMessage: () => communityMessage,
15732
+ communityMention: () => communityMention,
15733
+ communityFriendship: () => communityFriendship,
15734
+ communityDmConversation: () => communityDmConversation,
15735
+ communityChannel: () => communityChannel,
15736
+ communityCategory: () => communityCategory,
15737
+ communityBotApprovalRequest: () => communityBotApprovalRequest,
15738
+ communityAuditLog: () => communityAuditLog,
15739
+ communityAttachment: () => communityAttachment
15740
+ });
15741
+
15742
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/foreign-keys.js
15525
15743
  class ForeignKeyBuilder {
15526
15744
  static [entityKind] = "SQLiteForeignKeyBuilder";
15527
15745
  reference;
@@ -15589,7 +15807,7 @@ function foreignKey(config2) {
15589
15807
  return new ForeignKeyBuilder(mappedConfig);
15590
15808
  }
15591
15809
 
15592
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/unique-constraint.js
15810
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/unique-constraint.js
15593
15811
  function uniqueKeyName2(table, columns) {
15594
15812
  return `${table[TableName]}_${columns.join("_")}_unique`;
15595
15813
  }
@@ -15634,7 +15852,7 @@ class UniqueConstraint {
15634
15852
  }
15635
15853
  }
15636
15854
 
15637
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/columns/common.js
15855
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/common.js
15638
15856
  class SQLiteColumnBuilder extends ColumnBuilder {
15639
15857
  static [entityKind] = "SQLiteColumnBuilder";
15640
15858
  foreignKeyConfigs = [];
@@ -15685,7 +15903,7 @@ class SQLiteColumn extends Column {
15685
15903
  static [entityKind] = "SQLiteColumn";
15686
15904
  }
15687
15905
 
15688
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/columns/blob.js
15906
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/blob.js
15689
15907
  class SQLiteBigIntBuilder extends SQLiteColumnBuilder {
15690
15908
  static [entityKind] = "SQLiteBigIntBuilder";
15691
15909
  constructor(name) {
@@ -15773,7 +15991,7 @@ function blob(a, b) {
15773
15991
  return new SQLiteBlobBufferBuilder(name);
15774
15992
  }
15775
15993
 
15776
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/columns/custom.js
15994
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/custom.js
15777
15995
  class SQLiteCustomColumnBuilder extends SQLiteColumnBuilder {
15778
15996
  static [entityKind] = "SQLiteCustomColumnBuilder";
15779
15997
  constructor(name, fieldConfig, customTypeParams) {
@@ -15814,7 +16032,7 @@ function customType(customTypeParams) {
15814
16032
  };
15815
16033
  }
15816
16034
 
15817
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/columns/integer.js
16035
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/integer.js
15818
16036
  class SQLiteBaseIntegerBuilder extends SQLiteColumnBuilder {
15819
16037
  static [entityKind] = "SQLiteBaseIntegerBuilder";
15820
16038
  constructor(name, dataType, columnType) {
@@ -15916,7 +16134,7 @@ function integer2(a, b) {
15916
16134
  return new SQLiteIntegerBuilder(name);
15917
16135
  }
15918
16136
 
15919
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/columns/numeric.js
16137
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/numeric.js
15920
16138
  class SQLiteNumericBuilder extends SQLiteColumnBuilder {
15921
16139
  static [entityKind] = "SQLiteNumericBuilder";
15922
16140
  constructor(name) {
@@ -15986,7 +16204,7 @@ function numeric(a, b) {
15986
16204
  return mode === "number" ? new SQLiteNumericNumberBuilder(name) : mode === "bigint" ? new SQLiteNumericBigIntBuilder(name) : new SQLiteNumericBuilder(name);
15987
16205
  }
15988
16206
 
15989
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/columns/real.js
16207
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/real.js
15990
16208
  class SQLiteRealBuilder extends SQLiteColumnBuilder {
15991
16209
  static [entityKind] = "SQLiteRealBuilder";
15992
16210
  constructor(name) {
@@ -16007,7 +16225,7 @@ function real(name) {
16007
16225
  return new SQLiteRealBuilder(name ?? "");
16008
16226
  }
16009
16227
 
16010
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/columns/text.js
16228
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/text.js
16011
16229
  class SQLiteTextBuilder extends SQLiteColumnBuilder {
16012
16230
  static [entityKind] = "SQLiteTextBuilder";
16013
16231
  constructor(name, config2) {
@@ -16062,7 +16280,7 @@ function text(a, b = {}) {
16062
16280
  return new SQLiteTextBuilder(name, config2);
16063
16281
  }
16064
16282
 
16065
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/columns/all.js
16283
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/all.js
16066
16284
  function getSQLiteColumnBuilders() {
16067
16285
  return {
16068
16286
  blob,
@@ -16074,7 +16292,7 @@ function getSQLiteColumnBuilders() {
16074
16292
  };
16075
16293
  }
16076
16294
 
16077
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/table.js
16295
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/table.js
16078
16296
  var InlineForeignKeys = Symbol.for("drizzle:SQLiteInlineForeignKeys");
16079
16297
 
16080
16298
  class SQLiteTable extends Table {
@@ -16108,7 +16326,7 @@ var sqliteTable = (name, columns, extraConfig) => {
16108
16326
  return sqliteTableBase(name, columns, extraConfig);
16109
16327
  };
16110
16328
 
16111
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/indexes.js
16329
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/indexes.js
16112
16330
  class IndexBuilderOn {
16113
16331
  constructor(name, unique2) {
16114
16332
  this.name = name;
@@ -16150,8 +16368,11 @@ class Index {
16150
16368
  function index(name) {
16151
16369
  return new IndexBuilderOn(name, false);
16152
16370
  }
16371
+ function uniqueIndex(name) {
16372
+ return new IndexBuilderOn(name, true);
16373
+ }
16153
16374
 
16154
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/sqlite-core/primary-keys.js
16375
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/primary-keys.js
16155
16376
  function primaryKey(...config2) {
16156
16377
  if (config2[0].columns) {
16157
16378
  return new PrimaryKeyBuilder(config2[0].columns, config2[0].name);
@@ -16186,44 +16407,48 @@ class PrimaryKey {
16186
16407
  }
16187
16408
  }
16188
16409
 
16189
- // ../../node_modules/.pnpm/nanoid@5.1.15/node_modules/nanoid/index.js
16190
- import { webcrypto as crypto } from "node:crypto";
16191
-
16192
- // ../../node_modules/.pnpm/nanoid@5.1.15/node_modules/nanoid/url-alphabet/index.js
16193
- var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
16194
-
16195
- // ../../node_modules/.pnpm/nanoid@5.1.15/node_modules/nanoid/index.js
16196
- var POOL_SIZE_MULTIPLIER = 128;
16197
- var pool;
16198
- var poolOffset;
16199
- function fillPool(bytes) {
16200
- if (bytes < 0)
16201
- throw new RangeError("Wrong ID size");
16202
- try {
16203
- if (!pool || pool.length < bytes) {
16204
- pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
16205
- crypto.getRandomValues(pool);
16206
- poolOffset = 0;
16207
- } else if (poolOffset + bytes > pool.length) {
16208
- crypto.getRandomValues(pool);
16209
- poolOffset = 0;
16210
- }
16211
- } catch (e) {
16212
- pool = undefined;
16213
- throw e;
16214
- }
16215
- poolOffset += bytes;
16216
- }
16217
- function nanoid3(size = 21) {
16218
- fillPool(size |= 0);
16219
- let id = "";
16220
- for (let i = poolOffset - size;i < poolOffset; i++) {
16221
- id += urlAlphabet[pool[i] & 63];
16222
- }
16223
- return id;
16224
- }
16410
+ // ../shared/src/db/community-schema.ts
16411
+ init_nanoid();
16225
16412
 
16226
16413
  // ../shared/src/db/schema.ts
16414
+ var exports_schema = {};
16415
+ __export(exports_schema, {
16416
+ workspaceInvite: () => workspaceInvite,
16417
+ workspaceFileRequest: () => workspaceFileRequest,
16418
+ workspace: () => workspace,
16419
+ verification: () => verification,
16420
+ user: () => user,
16421
+ taskMessage: () => taskMessage,
16422
+ session: () => session,
16423
+ messageFlag: () => messageFlag,
16424
+ message: () => message,
16425
+ member: () => member,
16426
+ meetingSession: () => meetingSession,
16427
+ machineToken: () => machineToken,
16428
+ machine: () => machine,
16429
+ issueComment: () => issueComment,
16430
+ issue: () => issue2,
16431
+ inboxUnread: () => inboxUnread,
16432
+ emails: () => emails,
16433
+ conversationReadState: () => conversationReadState,
16434
+ conversationMap: () => conversationMap,
16435
+ conversation: () => conversation,
16436
+ channel: () => channel,
16437
+ calendarEvent: () => calendarEvent,
16438
+ artifact: () => artifact,
16439
+ agentWhitelist: () => agentWhitelist,
16440
+ agentTaskQueue: () => agentTaskQueue,
16441
+ agentSkill: () => agentSkill,
16442
+ agentSidebarOrder: () => agentSidebarOrder,
16443
+ agentRuntime: () => agentRuntime,
16444
+ agentPin: () => agentPin,
16445
+ agentLink: () => agentLink,
16446
+ agentEmailAccount: () => agentEmailAccount,
16447
+ agentAccess: () => agentAccess,
16448
+ agent: () => agent,
16449
+ account: () => account
16450
+ });
16451
+ init_nanoid();
16227
16452
  var user = sqliteTable("user", {
16228
16453
  id: text("id").primaryKey().$defaultFn(() => nanoid3()),
16229
16454
  name: text("name").notNull().default(""),
@@ -16231,8 +16456,12 @@ var user = sqliteTable("user", {
16231
16456
  emailVerified: integer2("emailVerified", { mode: "boolean" }),
16232
16457
  image: text("image"),
16233
16458
  createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
16234
- updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString())
16235
- });
16459
+ updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString()),
16460
+ isBot: integer2("isBot", { mode: "boolean" }).notNull().default(false),
16461
+ ownerUserId: text("ownerUserId"),
16462
+ deletedAt: text("deletedAt"),
16463
+ discriminator: text("discriminator").notNull().default("0000")
16464
+ }, (t) => [index("idx_user_ownerUserId_isBot").on(t.ownerUserId, t.isBot)]);
16236
16465
  var session = sqliteTable("session", {
16237
16466
  id: text("id").primaryKey().$defaultFn(() => nanoid3()),
16238
16467
  userId: text("userId").notNull().references(() => user.id, { onDelete: "cascade" }),
@@ -16768,84 +16997,518 @@ var inboxUnread = sqliteTable("inbox_unread", {
16768
16997
  unique("inbox_unread_conv_user").on(t.conversationId, t.userId),
16769
16998
  index("idx_inbox_unread_user_ws").on(t.userId, t.workspaceId, t.taskType, t.completedAt)
16770
16999
  ]);
16771
- // ../shared/src/db/queries/task.ts
16772
- var DEFAULT_STALE_SECONDS = Number(process.env.ALOOK_STALE_DISPATCH_TIMEOUT_S) || 20;
16773
- var DEFAULT_STALE_RUNNING_SECONDS = Number(process.env.ALOOK_STALE_RUNNING_TIMEOUT_S) || 3600;
16774
- // ../shared/src/utils/email.ts
16775
- var DOMAIN = `@${process.env.ALOOK_DOMAIN || "alook.ai"}`;
16776
- var RESERVED_HANDLES = new Set([
16777
- "no-reply",
16778
- "noreply",
16779
- "admin",
16780
- "support",
16781
- "help",
16782
- "info",
16783
- "postmaster",
16784
- "abuse",
16785
- "security",
16786
- "mailer-daemon",
16787
- "root",
16788
- "webmaster",
16789
- "hostmaster",
16790
- "system",
16791
- "alook"
17000
+
17001
+ // ../shared/src/db/community-schema.ts
17002
+ var communityServer = sqliteTable("community_server", {
17003
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17004
+ name: text("name").notNull(),
17005
+ description: text("description").default(""),
17006
+ icon: text("icon"),
17007
+ ownerId: text("owner_id").notNull().references(() => user.id, { onDelete: "restrict" }),
17008
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
17009
+ });
17010
+ var communityCategory = sqliteTable("community_category", {
17011
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17012
+ serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
17013
+ name: text("name").notNull(),
17014
+ position: integer2("position").default(0),
17015
+ private: integer2("private").default(0),
17016
+ creatorId: text("creator_id").references(() => user.id, { onDelete: "set null" })
17017
+ }, (t) => [unique("uq_category_server_name").on(t.serverId, t.name)]);
17018
+ var communityChannel = sqliteTable("community_channel", {
17019
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17020
+ serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
17021
+ categoryId: text("category_id").references(() => communityCategory.id, {
17022
+ onDelete: "set null"
17023
+ }),
17024
+ name: text("name").notNull(),
17025
+ type: text("type").notNull().default("text"),
17026
+ topic: text("topic").default(""),
17027
+ position: integer2("position").default(0),
17028
+ forumTags: text("forum_tags"),
17029
+ parentChannelId: text("parent_channel_id").references(() => communityChannel.id, {
17030
+ onDelete: "cascade"
17031
+ }),
17032
+ creatorId: text("creator_id").references(() => user.id, { onDelete: "set null" }),
17033
+ messageCount: integer2("message_count").default(0),
17034
+ archived: integer2("archived").default(0),
17035
+ parentMessageId: text("parent_message_id"),
17036
+ lastMessageAt: text("last_message_at"),
17037
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
17038
+ }, (t) => [
17039
+ index("idx_channel_server_position").on(t.serverId, t.position),
17040
+ index("idx_channel_server_last_message").on(t.serverId, t.lastMessageAt),
17041
+ index("idx_channel_parent").on(t.parentChannelId)
16792
17042
  ]);
16793
- function toAlookAddress(h) {
16794
- return `${h}${DOMAIN}`;
16795
- }
16796
- // ../shared/src/mode.ts
16797
- function isLocalUrl(url2) {
16798
- try {
16799
- const { hostname: hostname3 } = new URL(url2);
16800
- return ["localhost", "127.0.0.1", "0.0.0.0"].includes(hostname3);
16801
- } catch {
16802
- return false;
16803
- }
16804
- }
16805
- function hasWindow() {
16806
- return typeof globalThis !== "undefined" && "window" in globalThis;
16807
- }
16808
- function isTauri() {
16809
- return hasWindow() && typeof window !== "undefined" && "__TAURI__" in window;
16810
- }
16811
- function isMobile() {
16812
- if (!isTauri())
16813
- return false;
16814
- const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
16815
- return /(android|iphone|ipad|ipod)/i.test(ua);
16816
- }
16817
- function resolveMode(signals) {
16818
- if (signals.tauri || isTauri()) {
16819
- if (signals.tauriPlatform === "mobile" || isMobile())
16820
- return "mobile";
16821
- return "desktop";
16822
- }
16823
- if (signals.nodeEnv === "development" && !signals.cmdPrefix)
16824
- return "dev";
16825
- if (signals.serverUrl && !signals.cmdPrefix && signals.nodeEnv !== "production" && isLocalUrl(signals.serverUrl))
16826
- return "dev";
16827
- if (signals.cmdPrefix)
16828
- return "app";
16829
- if (signals.hostname && ["localhost", "127.0.0.1"].includes(signals.hostname))
16830
- return "app";
16831
- return "production";
16832
- }
16833
- function cliCommand(mode) {
16834
- switch (mode) {
16835
- case "dev":
16836
- return "pnpm dev:cli";
16837
- case "app":
16838
- return "npx @alook/app cli";
16839
- case "desktop":
16840
- case "mobile":
16841
- case "production":
16842
- return "npx @alook/cli";
16843
- }
16844
- }
16845
- // daemon/client.ts
16846
- class DaemonClient {
16847
- baseURL;
16848
- constructor(baseURL) {
17043
+ var communityDmConversation = sqliteTable("community_dm_conversation", {
17044
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17045
+ user1Id: text("user1_id").references(() => user.id, { onDelete: "set null" }),
17046
+ user2Id: text("user2_id").references(() => user.id, { onDelete: "set null" }),
17047
+ lastMessageAt: text("last_message_at"),
17048
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
17049
+ }, (t) => [
17050
+ unique("uq_dm_conversation_users").on(t.user1Id, t.user2Id),
17051
+ index("idx_dm_conversation_user1_last_message").on(t.user1Id, t.lastMessageAt),
17052
+ index("idx_dm_conversation_user2_last_message").on(t.user2Id, t.lastMessageAt)
17053
+ ]);
17054
+ var communityMessage = sqliteTable("community_message", {
17055
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17056
+ authorId: text("author_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17057
+ content: text("content").notNull().default(""),
17058
+ type: text("type").notNull().default("default"),
17059
+ mentionType: text("mention_type"),
17060
+ replyToId: text("reply_to_id"),
17061
+ embeds: text("embeds"),
17062
+ flags: integer2("flags").default(0),
17063
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
17064
+ channelId: text("channel_id").references(() => communityChannel.id, {
17065
+ onDelete: "cascade"
17066
+ }),
17067
+ dmConversationId: text("dm_conversation_id").references(() => communityDmConversation.id, { onDelete: "cascade" }),
17068
+ seq: integer2("seq").notNull().default(0)
17069
+ }, (t) => [
17070
+ index("idx_message_channel_created").on(t.channelId, t.createdAt),
17071
+ index("idx_message_channel_mention_created").on(t.channelId, t.mentionType, t.createdAt),
17072
+ index("idx_message_dm_created").on(t.dmConversationId, t.createdAt)
17073
+ ]);
17074
+ var communityMessageSeq = sqliteTable("community_message_seq", {
17075
+ scopeKey: text("scope_key").primaryKey(),
17076
+ nextSeq: integer2("next_seq").notNull()
17077
+ });
17078
+ var communityServerMember = sqliteTable("community_server_member", {
17079
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17080
+ serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
17081
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17082
+ role: text("role").default("member"),
17083
+ nickname: text("nickname"),
17084
+ railOrder: integer2("rail_order").default(0),
17085
+ joinedAt: text("joined_at").notNull().$defaultFn(() => new Date().toISOString())
17086
+ }, (t) => [
17087
+ unique("uq_server_member_server_user").on(t.serverId, t.userId),
17088
+ index("idx_server_member_user").on(t.userId),
17089
+ index("idx_server_member_user_rail_order").on(t.userId, t.railOrder)
17090
+ ]);
17091
+ var communityServerFolder = sqliteTable("community_server_folder", {
17092
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17093
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17094
+ name: text("name").notNull(),
17095
+ position: integer2("position").default(0)
17096
+ }, (t) => [index("idx_server_folder_user_position").on(t.userId, t.position)]);
17097
+ var communityServerFolderItem = sqliteTable("community_server_folder_item", {
17098
+ folderId: text("folder_id").notNull().references(() => communityServerFolder.id, { onDelete: "cascade" }),
17099
+ serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
17100
+ position: integer2("position").default(0)
17101
+ }, (t) => [
17102
+ primaryKey({ columns: [t.folderId, t.serverId] }),
17103
+ index("idx_server_folder_item_folder_position").on(t.folderId, t.position)
17104
+ ]);
17105
+ var communityServerInvite = sqliteTable("community_server_invite", {
17106
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17107
+ serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
17108
+ createdBy: text("created_by").references(() => user.id, { onDelete: "set null" }),
17109
+ token: text("token").unique().notNull().$defaultFn(() => nanoid3(10)),
17110
+ maxUses: integer2("max_uses"),
17111
+ uses: integer2("uses").default(0),
17112
+ expiresAt: text("expires_at"),
17113
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
17114
+ });
17115
+ var communityFriendship = sqliteTable("community_friendship", {
17116
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17117
+ requesterId: text("requester_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17118
+ addresseeId: text("addressee_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17119
+ status: text("status").notNull().default("pending"),
17120
+ blockerId: text("blocker_id"),
17121
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
17122
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
17123
+ }, (t) => [
17124
+ unique("uq_friendship_requester_addressee").on(t.requesterId, t.addresseeId),
17125
+ index("idx_friendship_addressee_status").on(t.addresseeId, t.status),
17126
+ index("idx_friendship_requester_status").on(t.requesterId, t.status)
17127
+ ]);
17128
+ var communityReadState = sqliteTable("community_read_state", {
17129
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17130
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17131
+ channelId: text("channel_id").references(() => communityChannel.id, {
17132
+ onDelete: "cascade"
17133
+ }),
17134
+ dmConversationId: text("dm_conversation_id").references(() => communityDmConversation.id, { onDelete: "cascade" }),
17135
+ lastReadAt: text("last_read_at").notNull(),
17136
+ lastReadMessageId: text("last_read_message_id"),
17137
+ lastReadSeq: integer2("last_read_seq").notNull().default(0)
17138
+ }, (t) => [index("idx_read_state_user").on(t.userId)]);
17139
+ var communityReaction = sqliteTable("community_reaction", {
17140
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17141
+ messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
17142
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17143
+ emoji: text("emoji").notNull(),
17144
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
17145
+ }, (t) => [
17146
+ unique("uq_reaction_message_user_emoji").on(t.messageId, t.userId, t.emoji),
17147
+ index("idx_reaction_message").on(t.messageId)
17148
+ ]);
17149
+ var communityAttachment = sqliteTable("community_attachment", {
17150
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17151
+ messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
17152
+ filename: text("filename").notNull(),
17153
+ url: text("url").notNull(),
17154
+ contentType: text("content_type"),
17155
+ size: integer2("size"),
17156
+ width: integer2("width"),
17157
+ height: integer2("height"),
17158
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
17159
+ }, (t) => [index("idx_attachment_message").on(t.messageId)]);
17160
+ var communityPin = sqliteTable("community_pin", {
17161
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17162
+ channelId: text("channel_id").notNull().references(() => communityChannel.id, { onDelete: "cascade" }),
17163
+ messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
17164
+ pinnedBy: text("pinned_by").references(() => user.id, { onDelete: "set null" }),
17165
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
17166
+ }, (t) => [
17167
+ unique("uq_pin_channel_message").on(t.channelId, t.messageId),
17168
+ index("idx_pin_channel").on(t.channelId)
17169
+ ]);
17170
+ var communityMention = sqliteTable("community_mention", {
17171
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17172
+ messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
17173
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17174
+ kind: text("kind").notNull().default("mention"),
17175
+ read: integer2("read").default(0)
17176
+ }, (t) => [
17177
+ index("idx_mention_user_read").on(t.userId, t.read),
17178
+ index("idx_mention_message").on(t.messageId)
17179
+ ]);
17180
+ var communityUserProfile = sqliteTable("community_user_profile", {
17181
+ userId: text("user_id").primaryKey().references(() => user.id, { onDelete: "cascade" }),
17182
+ aboutMe: text("about_me").default(""),
17183
+ bannerColor: text("banner_color")
17184
+ });
17185
+ var communityNotificationSetting = sqliteTable("community_notification_setting", {
17186
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17187
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17188
+ serverId: text("server_id").references(() => communityServer.id, {
17189
+ onDelete: "cascade"
17190
+ }),
17191
+ channelId: text("channel_id").references(() => communityChannel.id, {
17192
+ onDelete: "cascade"
17193
+ }),
17194
+ level: text("level").notNull().default("all")
17195
+ }, (t) => [index("idx_notification_setting_user").on(t.userId)]);
17196
+ var communityAuditLog = sqliteTable("community_audit_log", {
17197
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
17198
+ serverId: text("server_id").references(() => communityServer.id, {
17199
+ onDelete: "cascade"
17200
+ }),
17201
+ actorId: text("actor_id").references(() => user.id, { onDelete: "set null" }),
17202
+ action: text("action").notNull(),
17203
+ targetType: text("target_type").notNull(),
17204
+ targetId: text("target_id").notNull(),
17205
+ changes: text("changes"),
17206
+ reason: text("reason"),
17207
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
17208
+ }, (t) => [
17209
+ index("idx_audit_log_server_created").on(t.serverId, t.createdAt),
17210
+ index("idx_audit_log_server_action").on(t.serverId, t.action),
17211
+ index("idx_audit_log_actor_created").on(t.actorId, t.createdAt)
17212
+ ]);
17213
+ var communityBotApprovalRequest = sqliteTable("community_bot_approval_request", {
17214
+ id: text("id").primaryKey().$defaultFn(() => "bar_" + nanoid3()),
17215
+ botId: text("bot_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17216
+ kind: text("kind").notNull(),
17217
+ serverId: text("server_id").references(() => communityServer.id, {
17218
+ onDelete: "cascade"
17219
+ }),
17220
+ requestedByUserId: text("requested_by_user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17221
+ dmMessageId: text("dm_message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
17222
+ status: text("status").notNull().default("pending"),
17223
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
17224
+ resolvedAt: text("resolved_at")
17225
+ }, (t) => [index("idx_community_bot_approval_bot").on(t.botId, t.status)]);
17226
+
17227
+ // ../shared/src/logger.ts
17228
+ var LEVELS = {
17229
+ debug: 0,
17230
+ info: 1,
17231
+ warn: 2,
17232
+ error: 3,
17233
+ silent: 4
17234
+ };
17235
+
17236
+ class Logger {
17237
+ service;
17238
+ level;
17239
+ pretty;
17240
+ fields;
17241
+ constructor(opts, fields) {
17242
+ this.service = opts.service;
17243
+ this.level = LEVELS[opts.level ?? "info"];
17244
+ this.pretty = opts.pretty ?? false;
17245
+ this.fields = fields ?? {};
17246
+ }
17247
+ debug(msg, ctx) {
17248
+ this.write("debug", msg, ctx);
17249
+ }
17250
+ info(msg, ctx) {
17251
+ this.write("info", msg, ctx);
17252
+ }
17253
+ warn(msg, ctx) {
17254
+ this.write("warn", msg, ctx);
17255
+ }
17256
+ error(msg, ctx) {
17257
+ this.write("error", msg, ctx);
17258
+ }
17259
+ child(fields) {
17260
+ const merged = { ...this.fields, ...fields };
17261
+ const child = new Logger({ service: this.service, level: this.levelName(), pretty: this.pretty }, merged);
17262
+ return child;
17263
+ }
17264
+ levelName() {
17265
+ for (const [name, num] of Object.entries(LEVELS)) {
17266
+ if (num === this.level)
17267
+ return name;
17268
+ }
17269
+ return "info";
17270
+ }
17271
+ write(level, msg, ctx) {
17272
+ if (LEVELS[level] < this.level)
17273
+ return;
17274
+ const entry = {
17275
+ level,
17276
+ msg,
17277
+ service: this.service,
17278
+ ...this.fields,
17279
+ ...ctx,
17280
+ ts: new Date().toISOString()
17281
+ };
17282
+ for (const [k, v] of Object.entries(entry)) {
17283
+ if (v instanceof Error) {
17284
+ entry[k] = { message: v.message, stack: v.stack };
17285
+ }
17286
+ }
17287
+ let line;
17288
+ if (this.pretty) {
17289
+ const ts = entry.ts.replace("T", " ").replace("Z", "");
17290
+ const lvl = entry.level.toUpperCase().padEnd(5);
17291
+ const pairs = Object.entries(entry).filter(([k]) => k !== "level" && k !== "msg" && k !== "service" && k !== "ts").map(([k, v]) => `${k}=${typeof v === "object" ? JSON.stringify(v) : v}`).join(" ");
17292
+ line = `${ts} ${lvl} [${entry.service}] ${entry.msg}${pairs ? " " + pairs : ""}`;
17293
+ } else {
17294
+ line = JSON.stringify(entry);
17295
+ }
17296
+ if (level === "error") {
17297
+ console.error(line);
17298
+ } else {
17299
+ console.log(line);
17300
+ }
17301
+ }
17302
+ }
17303
+ function createLogger(opts) {
17304
+ return new Logger(opts);
17305
+ }
17306
+
17307
+ // ../shared/src/db/queries/community/message.ts
17308
+ var log = createLogger({ service: "community-queries" });
17309
+
17310
+ // ../shared/src/db/community-machine-schema.ts
17311
+ var exports_community_machine_schema = {};
17312
+ __export(exports_community_machine_schema, {
17313
+ communityMachineToken: () => communityMachineToken,
17314
+ communityMachineCredential: () => communityMachineCredential,
17315
+ communityMachine: () => communityMachine,
17316
+ communityBotBinding: () => communityBotBinding,
17317
+ communityAgentRunnerKey: () => communityAgentRunnerKey
17318
+ });
17319
+ init_nanoid();
17320
+ var communityMachineToken = sqliteTable("community_machine_token", {
17321
+ id: text("id").primaryKey().$defaultFn(() => "cmt_" + nanoid3(32)),
17322
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17323
+ machineId: text("machine_id"),
17324
+ status: text("status").notNull().default("pending"),
17325
+ expiresAt: text("expires_at").notNull(),
17326
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
17327
+ lastUsedAt: text("last_used_at")
17328
+ }, (t) => [
17329
+ index("idx_community_machine_token_user_status").on(t.userId, t.status),
17330
+ uniqueIndex("uq_community_machine_token_user_pending").on(t.userId).where(sql`status = 'pending'`)
17331
+ ]);
17332
+ var communityMachine = sqliteTable("community_machine", {
17333
+ id: text("id").primaryKey().$defaultFn(() => "cm_" + nanoid3()),
17334
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17335
+ displayName: text("display_name").notNull().default(""),
17336
+ hostname: text("hostname").notNull().default(""),
17337
+ platform: text("platform").notNull().default(""),
17338
+ arch: text("arch").notNull().default(""),
17339
+ osRelease: text("os_release").notNull().default(""),
17340
+ daemonVersion: text("daemon_version").notNull().default(""),
17341
+ metadata: text("metadata"),
17342
+ availableRuntimes: text("available_runtimes", { mode: "json" }).$type().notNull().default([]),
17343
+ status: text("status").notNull().default("offline"),
17344
+ lastSeenAt: text("last_seen_at"),
17345
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
17346
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
17347
+ }, (t) => [
17348
+ index("idx_community_machine_user_last_seen").on(t.userId, t.lastSeenAt),
17349
+ index("idx_community_machine_user_updated").on(t.userId, t.updatedAt),
17350
+ index("idx_community_machine_user_status").on(t.userId, t.status)
17351
+ ]);
17352
+ var communityMachineCredential = sqliteTable("community_machine_credential", {
17353
+ id: text("id").primaryKey().$defaultFn(() => "cmkid_" + nanoid3()),
17354
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17355
+ machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "cascade" }),
17356
+ credentialHash: text("credential_hash").notNull().unique(),
17357
+ doName: text("do_name").notNull().unique(),
17358
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
17359
+ lastUsedAt: text("last_used_at"),
17360
+ revokedAt: text("revoked_at")
17361
+ }, (t) => [
17362
+ index("idx_community_machine_credential_user").on(t.userId),
17363
+ index("idx_community_machine_credential_machine").on(t.machineId)
17364
+ ]);
17365
+ var communityBotBinding = sqliteTable("community_bot_binding", {
17366
+ userId: text("user_id").primaryKey().references(() => user.id, { onDelete: "cascade" }),
17367
+ machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "restrict" }),
17368
+ runtime: text("runtime").notNull(),
17369
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
17370
+ }, (t) => [index("idx_community_bot_binding_machine").on(t.machineId)]);
17371
+ var communityAgentRunnerKey = sqliteTable("community_agent_runner_key", {
17372
+ id: text("id").primaryKey().$defaultFn(() => "crkid_" + nanoid3()),
17373
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
17374
+ machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "cascade" }),
17375
+ agentId: text("agent_id").notNull(),
17376
+ runnerKeyHash: text("runner_key_hash").notNull().unique(),
17377
+ doName: text("do_name").notNull().unique(),
17378
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
17379
+ revokedAt: text("revoked_at")
17380
+ }, (t) => [
17381
+ index("idx_community_agent_runner_key_machine_agent").on(t.machineId, t.agentId)
17382
+ ]);
17383
+
17384
+ // ../shared/src/db/queries/community/agent-inbox.ts
17385
+ var AGENT_MESSAGE_COLUMNS = {
17386
+ id: communityMessage.id,
17387
+ authorId: communityMessage.authorId,
17388
+ content: communityMessage.content,
17389
+ createdAt: communityMessage.createdAt,
17390
+ channelId: communityMessage.channelId,
17391
+ dmConversationId: communityMessage.dmConversationId,
17392
+ seq: communityMessage.seq
17393
+ };
17394
+ // ../shared/src/db/index.ts
17395
+ var allSchema = { ...exports_schema, ...exports_community_schema, ...exports_community_machine_schema };
17396
+ // ../shared/src/db/queries/user.ts
17397
+ var publicUserColumns = {
17398
+ id: user.id,
17399
+ name: user.name,
17400
+ email: user.email,
17401
+ emailVerified: user.emailVerified,
17402
+ image: user.image,
17403
+ createdAt: user.createdAt,
17404
+ updatedAt: user.updatedAt,
17405
+ discriminator: user.discriminator
17406
+ };
17407
+ var internalUserColumns = {
17408
+ ...publicUserColumns,
17409
+ isBot: user.isBot,
17410
+ ownerUserId: user.ownerUserId,
17411
+ deletedAt: user.deletedAt
17412
+ };
17413
+ // ../shared/src/db/queries/task.ts
17414
+ var DEFAULT_STALE_SECONDS = Number(process.env.ALOOK_STALE_DISPATCH_TIMEOUT_S) || 20;
17415
+ var DEFAULT_STALE_RUNNING_SECONDS = Number(process.env.ALOOK_STALE_RUNNING_TIMEOUT_S) || 3600;
17416
+ // ../shared/src/utils/email.ts
17417
+ var DOMAIN = `@${process.env.ALOOK_DOMAIN || "alook.ai"}`;
17418
+ var RESERVED_HANDLES = new Set([
17419
+ "no-reply",
17420
+ "noreply",
17421
+ "admin",
17422
+ "support",
17423
+ "help",
17424
+ "info",
17425
+ "postmaster",
17426
+ "abuse",
17427
+ "security",
17428
+ "mailer-daemon",
17429
+ "root",
17430
+ "webmaster",
17431
+ "hostmaster",
17432
+ "system",
17433
+ "alook"
17434
+ ]);
17435
+ function toAlookAddress(h) {
17436
+ return `${h}${DOMAIN}`;
17437
+ }
17438
+ // ../shared/src/db/queries/community/channel.ts
17439
+ var log2 = createLogger({ service: "community-queries" });
17440
+ var CHANNEL_COLUMNS = {
17441
+ id: communityChannel.id,
17442
+ serverId: communityChannel.serverId,
17443
+ categoryId: communityChannel.categoryId,
17444
+ name: communityChannel.name,
17445
+ type: communityChannel.type,
17446
+ topic: communityChannel.topic,
17447
+ position: communityChannel.position,
17448
+ forumTags: communityChannel.forumTags,
17449
+ parentChannelId: communityChannel.parentChannelId,
17450
+ creatorId: communityChannel.creatorId,
17451
+ messageCount: communityChannel.messageCount,
17452
+ archived: communityChannel.archived,
17453
+ parentMessageId: communityChannel.parentMessageId,
17454
+ lastMessageAt: communityChannel.lastMessageAt,
17455
+ createdAt: communityChannel.createdAt
17456
+ };
17457
+ // ../shared/src/db/queries/community/search.ts
17458
+ var FTS_KEYWORDS = new Set(["and", "or", "not", "near"]);
17459
+ // ../shared/src/mode.ts
17460
+ function isLocalUrl(url2) {
17461
+ try {
17462
+ const { hostname: hostname3 } = new URL(url2);
17463
+ return ["localhost", "127.0.0.1", "0.0.0.0"].includes(hostname3);
17464
+ } catch {
17465
+ return false;
17466
+ }
17467
+ }
17468
+ function hasWindow() {
17469
+ return typeof globalThis !== "undefined" && "window" in globalThis;
17470
+ }
17471
+ function isTauri() {
17472
+ return hasWindow() && typeof window !== "undefined" && "__TAURI__" in window;
17473
+ }
17474
+ function isMobile() {
17475
+ if (!isTauri())
17476
+ return false;
17477
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
17478
+ return /(android|iphone|ipad|ipod)/i.test(ua);
17479
+ }
17480
+ function resolveMode(signals) {
17481
+ if (signals.tauri || isTauri()) {
17482
+ if (signals.tauriPlatform === "mobile" || isMobile())
17483
+ return "mobile";
17484
+ return "desktop";
17485
+ }
17486
+ if (signals.nodeEnv === "development" && !signals.cmdPrefix)
17487
+ return "dev";
17488
+ if (signals.serverUrl && !signals.cmdPrefix && signals.nodeEnv !== "production" && isLocalUrl(signals.serverUrl))
17489
+ return "dev";
17490
+ if (signals.cmdPrefix)
17491
+ return "app";
17492
+ if (signals.hostname && ["localhost", "127.0.0.1"].includes(signals.hostname))
17493
+ return "app";
17494
+ return "production";
17495
+ }
17496
+ function cliCommand(mode) {
17497
+ switch (mode) {
17498
+ case "dev":
17499
+ return "pnpm dev:cli";
17500
+ case "app":
17501
+ return "npx @alook/app cli";
17502
+ case "desktop":
17503
+ case "mobile":
17504
+ case "production":
17505
+ return "npx @alook/cli";
17506
+ }
17507
+ }
17508
+ // daemon/client.ts
17509
+ class DaemonClient {
17510
+ baseURL;
17511
+ constructor(baseURL) {
16849
17512
  this.baseURL = baseURL;
16850
17513
  }
16851
17514
  async request(method, path, token, body) {
@@ -16972,7 +17635,7 @@ import { createInterface } from "readline";
16972
17635
  import { execSync } from "child_process";
16973
17636
 
16974
17637
  // lib/logger.ts
16975
- var LEVELS = {
17638
+ var LEVELS2 = {
16976
17639
  debug: 0,
16977
17640
  info: 1,
16978
17641
  warn: 2,
@@ -17018,12 +17681,12 @@ class Logger2 {
17018
17681
  module;
17019
17682
  constructor(opts = {}) {
17020
17683
  const envLevel = process.env.ALOOK_LOG_LEVEL;
17021
- this.level = LEVELS[opts.level ?? envLevel ?? "info"];
17684
+ this.level = LEVELS2[opts.level ?? envLevel ?? "info"];
17022
17685
  this.color = useColor();
17023
17686
  this.module = opts.module;
17024
17687
  }
17025
17688
  setLevel(level) {
17026
- this.level = LEVELS[level];
17689
+ this.level = LEVELS2[level];
17027
17690
  }
17028
17691
  child(module) {
17029
17692
  const child = new Logger2({ level: this.levelName(), module });
@@ -17042,14 +17705,14 @@ class Logger2 {
17042
17705
  this.write("error", msg, args);
17043
17706
  }
17044
17707
  levelName() {
17045
- for (const [name, num] of Object.entries(LEVELS)) {
17708
+ for (const [name, num] of Object.entries(LEVELS2)) {
17046
17709
  if (num === this.level)
17047
17710
  return name;
17048
17711
  }
17049
17712
  return "info";
17050
17713
  }
17051
17714
  write(level, msg, args) {
17052
- if (LEVELS[level] < this.level)
17715
+ if (LEVELS2[level] < this.level)
17053
17716
  return;
17054
17717
  const ts = timestamp();
17055
17718
  const label = LABELS[level];
@@ -17070,7 +17733,7 @@ class Logger2 {
17070
17733
  if (a instanceof Error) {
17071
17734
  dest.write(` ${a.message}
17072
17735
  `);
17073
- if (a.stack && this.level <= LEVELS.debug) {
17736
+ if (a.stack && this.level <= LEVELS2.debug) {
17074
17737
  dest.write(` ${a.stack}
17075
17738
  `);
17076
17739
  }
@@ -17089,10 +17752,10 @@ class Logger2 {
17089
17752
  function createLogger2(opts) {
17090
17753
  return new Logger2(opts);
17091
17754
  }
17092
- var log = createLogger2();
17755
+ var log3 = createLogger2();
17093
17756
 
17094
17757
  // daemon/kill-tree.ts
17095
- var log2 = createLogger2({ module: "kill-tree" });
17758
+ var log4 = createLogger2({ module: "kill-tree" });
17096
17759
  function killGraceMs() {
17097
17760
  return Number(process.env.ALOOK_KILL_GRACE_MS) || 2000;
17098
17761
  }
@@ -17146,7 +17809,7 @@ async function killProcessTree(pid, opts) {
17146
17809
  await new Promise((r) => setTimeout(r, POLL_MS));
17147
17810
  }
17148
17811
  if (isAlive(pid)) {
17149
- log2.warn(`pid=${pid} survived SIGTERM after ${graceMs}ms — escalating to SIGKILL`);
17812
+ log4.warn(`pid=${pid} survived SIGTERM after ${graceMs}ms — escalating to SIGKILL`);
17150
17813
  signalTree(pid, "SIGKILL");
17151
17814
  }
17152
17815
  }
@@ -17155,19 +17818,135 @@ async function killProcessTree(pid, opts) {
17155
17818
  class ClaudeBackend {
17156
17819
  cliPath;
17157
17820
  name = "claude";
17821
+ lifecycle = { kind: "persistent", stdin: "gated", inFlightWake: "queue" };
17822
+ busyDeliveryMode = "gated";
17823
+ supportsStdinNotification = true;
17158
17824
  constructor(cliPath) {
17159
17825
  this.cliPath = cliPath;
17160
17826
  }
17827
+ parseLine(line) {
17828
+ if (!line.trim())
17829
+ return [];
17830
+ let event;
17831
+ try {
17832
+ event = JSON.parse(line);
17833
+ } catch {
17834
+ return [{ kind: "log", content: line, level: "debug" }];
17835
+ }
17836
+ const events = [];
17837
+ const eventType = event.type;
17838
+ switch (eventType) {
17839
+ case "assistant": {
17840
+ const message2 = event.message;
17841
+ if (!message2)
17842
+ break;
17843
+ const content = message2.content;
17844
+ if (!Array.isArray(content))
17845
+ break;
17846
+ for (const block of content) {
17847
+ if (block.type === "text") {
17848
+ events.push({ kind: "text", text: block.text || "" });
17849
+ } else if (block.type === "thinking") {
17850
+ events.push({ kind: "thinking", text: block.text || "" });
17851
+ } else if (block.type === "tool_use") {
17852
+ events.push({ kind: "tool_call", name: block.name || "", input: block.input, callId: block.id });
17853
+ }
17854
+ }
17855
+ break;
17856
+ }
17857
+ case "result": {
17858
+ const result = event.result;
17859
+ const isError = event.is_error;
17860
+ if (isError) {
17861
+ events.push({ kind: "error", message: result || "unknown error" });
17862
+ }
17863
+ const resultSessionId = event.session_id;
17864
+ events.push({ kind: "turn_end", sessionId: resultSessionId || undefined });
17865
+ const usage = event.usage;
17866
+ if (usage || event.total_cost_usd != null) {
17867
+ events.push({
17868
+ kind: "telemetry",
17869
+ name: "token_usage",
17870
+ source: "claude_result_usage",
17871
+ usageKind: "per_turn",
17872
+ attrs: {
17873
+ inputTokens: usage?.input_tokens,
17874
+ outputTokens: usage?.output_tokens,
17875
+ cachedInputTokens: usage?.cache_read_input_tokens,
17876
+ cacheCreationInputTokens: usage?.cache_creation_input_tokens,
17877
+ totalCostUsd: event.total_cost_usd,
17878
+ durationMs: event.duration_ms,
17879
+ durationApiMs: event.duration_api_ms,
17880
+ numTurns: event.num_turns,
17881
+ resultSubtype: event.subtype,
17882
+ resultIsError: event.is_error,
17883
+ serviceTier: usage?.service_tier
17884
+ }
17885
+ });
17886
+ }
17887
+ break;
17888
+ }
17889
+ case "tool_result": {
17890
+ const toolUseId = event.tool_use_id;
17891
+ const content = event.content;
17892
+ events.push({ kind: "tool_output", callId: toolUseId, output: content });
17893
+ break;
17894
+ }
17895
+ case "system": {
17896
+ const subtype = event.subtype;
17897
+ if (subtype === "init") {
17898
+ const sid = event.session_id;
17899
+ events.push({ kind: "session_init", sessionId: sid || "" });
17900
+ } else if (subtype === "context_pruning" || subtype === "compaction") {
17901
+ events.push({ kind: "compaction_started" });
17902
+ } else if (subtype === "compaction_finished" || subtype === "context_pruning_finished") {
17903
+ events.push({ kind: "compaction_finished" });
17904
+ } else if (subtype === "status" || subtype === "stream_event") {
17905
+ events.push({
17906
+ kind: "internal_progress",
17907
+ source: "claude_system",
17908
+ itemType: subtype,
17909
+ payloadBytes: line.length
17910
+ });
17911
+ }
17912
+ break;
17913
+ }
17914
+ case "control_request": {
17915
+ const requestId = event.request_id;
17916
+ if (requestId) {
17917
+ events.push({ kind: "permission_request", requestId, payload: event.payload });
17918
+ }
17919
+ break;
17920
+ }
17921
+ default: {
17922
+ events.push({ kind: "log", content: line, level: "debug" });
17923
+ }
17924
+ }
17925
+ return events;
17926
+ }
17927
+ encodeStdinMessage(text2, mode, opts) {
17928
+ const msg = {
17929
+ type: "user",
17930
+ message: {
17931
+ role: "user",
17932
+ content: [{ type: "text", text: text2 }]
17933
+ }
17934
+ };
17935
+ if (opts?.sessionId) {
17936
+ msg.session_id = opts.sessionId;
17937
+ }
17938
+ return JSON.stringify(msg);
17939
+ }
17161
17940
  execute(prompt, options) {
17162
- const args = [
17163
- "-p",
17164
- prompt,
17165
- "--output-format",
17166
- "stream-json",
17167
- "--verbose",
17168
- "--permission-mode",
17169
- "bypassPermissions"
17170
- ];
17941
+ const useStdinPrompt = options.steeringEnabled === true;
17942
+ const args = [];
17943
+ if (!useStdinPrompt) {
17944
+ args.push("-p", prompt);
17945
+ }
17946
+ args.push("--output-format", "stream-json", "--verbose", "--permission-mode", "bypassPermissions");
17947
+ if (useStdinPrompt) {
17948
+ args.push("--input-format", "stream-json");
17949
+ }
17171
17950
  if (options.model) {
17172
17951
  args.push("--model", options.model);
17173
17952
  }
@@ -17224,15 +18003,58 @@ class ClaudeBackend {
17224
18003
  r();
17225
18004
  }
17226
18005
  };
18006
+ const parsedEventQueue = [];
18007
+ let parsedEventResolve = null;
18008
+ let parsedEventDone = false;
18009
+ const pushParsedEvent = (evt) => {
18010
+ parsedEventQueue.push(evt);
18011
+ if (parsedEventResolve) {
18012
+ const r = parsedEventResolve;
18013
+ parsedEventResolve = null;
18014
+ r();
18015
+ }
18016
+ };
18017
+ const stdinWriteQueue = [];
18018
+ let stdinDraining = false;
18019
+ const enqueueStdinWrite = (data) => {
18020
+ stdinWriteQueue.push(data);
18021
+ drainStdinQueue();
18022
+ };
18023
+ const drainStdinQueue = () => {
18024
+ if (stdinDraining)
18025
+ return;
18026
+ stdinDraining = true;
18027
+ while (stdinWriteQueue.length > 0) {
18028
+ const line = stdinWriteQueue.shift();
18029
+ try {
18030
+ proc.stdin?.write(line + `
18031
+ `);
18032
+ } catch {}
18033
+ }
18034
+ stdinDraining = false;
18035
+ };
17227
18036
  const resultPromise = new Promise((resolve) => {
17228
18037
  const stderrChunks = [];
17229
18038
  proc.stderr?.on("data", (chunk) => {
17230
18039
  stderrChunks.push(chunk.toString());
17231
18040
  });
17232
18041
  const rl = createInterface({ input: proc.stdout });
18042
+ if (useStdinPrompt) {
18043
+ const initialMsg = JSON.stringify({
18044
+ type: "user",
18045
+ message: {
18046
+ role: "user",
18047
+ content: [{ type: "text", text: prompt }]
18048
+ }
18049
+ });
18050
+ enqueueStdinWrite(initialMsg);
18051
+ }
17233
18052
  rl.on("line", (line) => {
17234
18053
  if (!line.trim())
17235
18054
  return;
18055
+ const parsed = this.parseLine(line);
18056
+ for (const pe of parsed)
18057
+ pushParsedEvent(pe);
17236
18058
  let event;
17237
18059
  try {
17238
18060
  event = JSON.parse(line);
@@ -17278,6 +18100,13 @@ class ClaudeBackend {
17278
18100
  resultStatus = "failed";
17279
18101
  lastError = result || "unknown error";
17280
18102
  }
18103
+ if (useStdinPrompt) {
18104
+ setTimeout(() => {
18105
+ try {
18106
+ proc.stdin?.end();
18107
+ } catch {}
18108
+ }, 100);
18109
+ }
17281
18110
  break;
17282
18111
  }
17283
18112
  case "tool_result": {
@@ -17302,7 +18131,7 @@ class ClaudeBackend {
17302
18131
  break;
17303
18132
  }
17304
18133
  case "control_request": {
17305
- handleControlRequest(proc, event);
18134
+ handleControlRequest(proc, event, enqueueStdinWrite);
17306
18135
  break;
17307
18136
  }
17308
18137
  default: {
@@ -17319,11 +18148,17 @@ class ClaudeBackend {
17319
18148
  lastError = `spawn error: ${err.message}`;
17320
18149
  resolveSessionId(lastSessionId);
17321
18150
  messageDone = true;
18151
+ parsedEventDone = true;
17322
18152
  if (messageResolve) {
17323
18153
  const r = messageResolve;
17324
18154
  messageResolve = null;
17325
18155
  r();
17326
18156
  }
18157
+ if (parsedEventResolve) {
18158
+ const r = parsedEventResolve;
18159
+ parsedEventResolve = null;
18160
+ r();
18161
+ }
17327
18162
  resolve({
17328
18163
  status: "failed",
17329
18164
  output: "",
@@ -17346,11 +18181,17 @@ class ClaudeBackend {
17346
18181
  }
17347
18182
  resolveSessionId(lastSessionId);
17348
18183
  messageDone = true;
18184
+ parsedEventDone = true;
17349
18185
  if (messageResolve) {
17350
18186
  const r = messageResolve;
17351
18187
  messageResolve = null;
17352
18188
  r();
17353
18189
  }
18190
+ if (parsedEventResolve) {
18191
+ const r = parsedEventResolve;
18192
+ parsedEventResolve = null;
18193
+ r();
18194
+ }
17354
18195
  resolve({
17355
18196
  status: resultStatus,
17356
18197
  output: lastOutput,
@@ -17377,10 +18218,47 @@ class ClaudeBackend {
17377
18218
  };
17378
18219
  }
17379
18220
  };
17380
- return { pid: proc.pid, messages, sessionId: sessionIdPromise, result: resultPromise };
18221
+ const parsedEvents = {
18222
+ [Symbol.asyncIterator]() {
18223
+ return {
18224
+ async next() {
18225
+ while (parsedEventQueue.length === 0 && !parsedEventDone) {
18226
+ await new Promise((resolve) => {
18227
+ parsedEventResolve = resolve;
18228
+ });
18229
+ }
18230
+ if (parsedEventQueue.length > 0) {
18231
+ return { value: parsedEventQueue.shift(), done: false };
18232
+ }
18233
+ return { value: undefined, done: true };
18234
+ }
18235
+ };
18236
+ }
18237
+ };
18238
+ const send = (text2, mode) => {
18239
+ const encoded = this.encodeStdinMessage(text2, mode, { sessionId: lastSessionId || undefined });
18240
+ if (!encoded)
18241
+ return { ok: false, reason: "encoding failed" };
18242
+ if (!proc.stdin || proc.stdin.destroyed)
18243
+ return { ok: false, reason: "stdin closed" };
18244
+ enqueueStdinWrite(encoded);
18245
+ return { ok: true };
18246
+ };
18247
+ const descriptor = {
18248
+ lifecycle: this.lifecycle,
18249
+ busyDeliveryMode: this.busyDeliveryMode,
18250
+ supportsStdinNotification: this.supportsStdinNotification
18251
+ };
18252
+ const closeStdin = () => {
18253
+ try {
18254
+ if (proc.stdin && !proc.stdin.destroyed)
18255
+ proc.stdin.end();
18256
+ } catch {}
18257
+ };
18258
+ return { pid: proc.pid, messages, parsedEvents, sessionId: sessionIdPromise, result: resultPromise, send, closeStdin, descriptor };
17381
18259
  }
17382
18260
  }
17383
- function handleControlRequest(proc, event) {
18261
+ function handleControlRequest(proc, event, enqueueStdinWrite) {
17384
18262
  const requestId = event.request_id;
17385
18263
  if (!requestId)
17386
18264
  return;
@@ -17409,10 +18287,14 @@ function handleControlRequest(proc, event) {
17409
18287
  }
17410
18288
  }
17411
18289
  });
17412
- try {
17413
- proc.stdin?.write(approval + `
18290
+ if (enqueueStdinWrite) {
18291
+ enqueueStdinWrite(approval);
18292
+ } else {
18293
+ try {
18294
+ proc.stdin?.write(approval + `
17414
18295
  `);
17415
- } catch {}
18296
+ } catch {}
18297
+ }
17416
18298
  }
17417
18299
 
17418
18300
  // daemon/agent/codex.ts
@@ -17444,9 +18326,196 @@ function extractThreadID(response) {
17444
18326
  class CodexBackend {
17445
18327
  cliPath;
17446
18328
  name = "codex";
18329
+ lifecycle = { kind: "persistent", stdin: "direct", inFlightWake: "steer" };
18330
+ busyDeliveryMode = "direct";
18331
+ supportsStdinNotification = true;
18332
+ _rpcId = 0;
17447
18333
  constructor(cliPath) {
17448
18334
  this.cliPath = cliPath;
17449
18335
  }
18336
+ parseLine(line) {
18337
+ if (!line.trim())
18338
+ return [];
18339
+ let msg;
18340
+ try {
18341
+ msg = JSON.parse(line);
18342
+ } catch {
18343
+ return [{ kind: "log", content: line, level: "debug" }];
18344
+ }
18345
+ if (msg.id !== undefined && !msg.method)
18346
+ return [];
18347
+ if (msg.id !== undefined && msg.method)
18348
+ return [];
18349
+ if (!msg.method)
18350
+ return [{ kind: "log", content: line, level: "debug" }];
18351
+ const method = msg.method;
18352
+ const params = msg.params || {};
18353
+ if (method === "codex/event") {
18354
+ return this.parseLegacyEvent(params);
18355
+ }
18356
+ const events = [];
18357
+ switch (method) {
18358
+ case "turn/started":
18359
+ break;
18360
+ case "turn/completed": {
18361
+ const turn = params.turn;
18362
+ const status = turn?.status || params.status || "";
18363
+ if (status === "error" || status === "failed") {
18364
+ const turnErr = turn?.error;
18365
+ events.push({ kind: "error", message: turnErr?.message || "codex turn failed" });
18366
+ }
18367
+ events.push({ kind: "turn_end" });
18368
+ break;
18369
+ }
18370
+ case "error": {
18371
+ const errObj = params.error;
18372
+ const errMsg = errObj?.message || params.message || "";
18373
+ const willRetry = params.willRetry === true;
18374
+ if (errMsg && !willRetry) {
18375
+ events.push({ kind: "error", message: errMsg });
18376
+ }
18377
+ break;
18378
+ }
18379
+ case "thread/status/changed": {
18380
+ const statusObj = params.status;
18381
+ const statusType = typeof statusObj === "object" && statusObj !== null ? statusObj.type || "" : statusObj || "";
18382
+ if (statusType === "idle") {
18383
+ events.push({ kind: "turn_end" });
18384
+ }
18385
+ break;
18386
+ }
18387
+ case "item/started": {
18388
+ const item = params.item;
18389
+ if (!item)
18390
+ break;
18391
+ const itemType = item.type;
18392
+ if (itemType === "commandExecution" || itemType === "fileChange") {
18393
+ events.push({
18394
+ kind: "tool_call",
18395
+ name: itemType === "commandExecution" ? "exec_command" : "patch_apply",
18396
+ callId: item.id,
18397
+ input: item
18398
+ });
18399
+ } else if (itemType === "mcpToolCall") {
18400
+ events.push({
18401
+ kind: "tool_call",
18402
+ name: `mcp_${item.name || "tool"}`,
18403
+ callId: item.id,
18404
+ input: item
18405
+ });
18406
+ } else if (itemType === "webSearch") {
18407
+ events.push({
18408
+ kind: "tool_call",
18409
+ name: "web_search",
18410
+ callId: item.id,
18411
+ input: item
18412
+ });
18413
+ } else if (itemType === "collabAgentToolCall") {
18414
+ events.push({
18415
+ kind: "tool_call",
18416
+ name: "collab_agent",
18417
+ callId: item.id,
18418
+ input: item
18419
+ });
18420
+ } else if (itemType === "contextCompaction") {
18421
+ events.push({ kind: "compaction_started" });
18422
+ }
18423
+ break;
18424
+ }
18425
+ case "item/completed": {
18426
+ const item = params.item;
18427
+ if (!item)
18428
+ break;
18429
+ const itemType = item.type;
18430
+ if (itemType === "commandExecution") {
18431
+ events.push({ kind: "tool_output", callId: item.id, output: item.aggregatedOutput || "" });
18432
+ } else if (itemType === "fileChange") {
18433
+ events.push({ kind: "tool_output", callId: item.id, output: "" });
18434
+ } else if (itemType === "mcpToolCall") {
18435
+ events.push({ kind: "tool_output", callId: item.id, name: `mcp_${item.name || "tool"}`, output: item.output || "" });
18436
+ } else if (itemType === "agentMessage") {
18437
+ const flatText = item.text;
18438
+ if (flatText) {
18439
+ events.push({ kind: "text", text: flatText });
18440
+ } else {
18441
+ const content = item.content;
18442
+ if (Array.isArray(content)) {
18443
+ for (const block of content) {
18444
+ if ((block.type === "output_text" || block.type === "text") && block.text) {
18445
+ events.push({ kind: "text", text: block.text });
18446
+ }
18447
+ }
18448
+ }
18449
+ }
18450
+ } else if (itemType === "reasoning") {
18451
+ events.push({ kind: "thinking", text: item.text || "" });
18452
+ } else if (itemType === "contextCompaction") {
18453
+ events.push({ kind: "compaction_finished" });
18454
+ }
18455
+ break;
18456
+ }
18457
+ case "item/agentMessage/delta": {
18458
+ const delta = params.delta;
18459
+ if (delta)
18460
+ events.push({ kind: "text", text: delta });
18461
+ break;
18462
+ }
18463
+ default:
18464
+ events.push({ kind: "log", content: JSON.stringify(msg), level: "debug" });
18465
+ }
18466
+ return events;
18467
+ }
18468
+ parseLegacyEvent(params) {
18469
+ const eventType = params.type;
18470
+ if (!eventType)
18471
+ return [];
18472
+ const events = [];
18473
+ switch (eventType) {
18474
+ case "agent_message": {
18475
+ const text2 = params.text || params.message || "";
18476
+ if (text2)
18477
+ events.push({ kind: "text", text: text2 });
18478
+ break;
18479
+ }
18480
+ case "exec_command_begin":
18481
+ events.push({ kind: "tool_call", name: "exec_command", callId: params.id, input: params });
18482
+ break;
18483
+ case "exec_command_end":
18484
+ events.push({ kind: "tool_output", callId: params.id, output: params.output || "" });
18485
+ break;
18486
+ case "patch_apply_begin":
18487
+ events.push({ kind: "tool_call", name: "patch_apply", callId: params.id, input: params });
18488
+ break;
18489
+ case "patch_apply_end":
18490
+ events.push({ kind: "tool_output", callId: params.id, output: params.output || "" });
18491
+ break;
18492
+ case "task_complete":
18493
+ events.push({ kind: "turn_end" });
18494
+ break;
18495
+ case "turn_aborted":
18496
+ events.push({ kind: "turn_end" });
18497
+ break;
18498
+ default:
18499
+ break;
18500
+ }
18501
+ return events;
18502
+ }
18503
+ encodeStdinMessage(text2, mode, opts) {
18504
+ const threadId = opts?.threadId;
18505
+ if (!threadId)
18506
+ return null;
18507
+ const id = opts?.requestId ?? ++this._rpcId;
18508
+ const method = mode === "busy" ? "turn/steer" : "turn/start";
18509
+ return JSON.stringify({
18510
+ jsonrpc: "2.0",
18511
+ id,
18512
+ method,
18513
+ params: {
18514
+ threadId,
18515
+ input: [{ type: "text", text: text2 }]
18516
+ }
18517
+ });
18518
+ }
17450
18519
  execute(prompt, options) {
17451
18520
  const proc = spawn2(this.cliPath, ["app-server", "--listen", "stdio://", "--config", "sandbox_mode=danger-full-access"], {
17452
18521
  cwd: options.cwd,
@@ -17495,6 +18564,9 @@ class CodexBackend {
17495
18564
  const messageQueue = [];
17496
18565
  let messageResolve = null;
17497
18566
  let messageDone = false;
18567
+ const parsedEventQueue = [];
18568
+ let parsedEventResolve = null;
18569
+ let parsedEventDone = false;
17498
18570
  const pushMessage = (msg) => {
17499
18571
  messageQueue.push(msg);
17500
18572
  if (messageResolve) {
@@ -17503,6 +18575,14 @@ class CodexBackend {
17503
18575
  r();
17504
18576
  }
17505
18577
  };
18578
+ const pushParsedEvent = (evt) => {
18579
+ parsedEventQueue.push(evt);
18580
+ if (parsedEventResolve) {
18581
+ const r = parsedEventResolve;
18582
+ parsedEventResolve = null;
18583
+ r();
18584
+ }
18585
+ };
17506
18586
  const writeStdin = (data) => {
17507
18587
  try {
17508
18588
  proc.stdin?.write(data + `
@@ -17535,17 +18615,20 @@ class CodexBackend {
17535
18615
  if (msg && !turnError)
17536
18616
  turnError = msg;
17537
18617
  };
18618
+ const steeringKeepAlive = options.steeringEnabled === true;
17538
18619
  const triggerTurnDone = (aborted2) => {
17539
18620
  if (turnDoneTriggered)
17540
18621
  return;
17541
18622
  turnDoneTriggered = true;
17542
18623
  resultStatus = aborted2 ? "aborted" : "completed";
17543
- try {
17544
- proc.stdin?.end();
17545
- } catch {}
17546
- try {
17547
- proc.kill("SIGTERM");
17548
- } catch {}
18624
+ if (!steeringKeepAlive) {
18625
+ try {
18626
+ proc.stdin?.end();
18627
+ } catch {}
18628
+ try {
18629
+ proc.kill("SIGTERM");
18630
+ } catch {}
18631
+ }
17549
18632
  };
17550
18633
  const handleServerRequest = (msg) => {
17551
18634
  const method = msg.method;
@@ -17766,6 +18849,9 @@ class CodexBackend {
17766
18849
  rl.on("line", (line) => {
17767
18850
  if (!line.trim())
17768
18851
  return;
18852
+ const parsed = this.parseLine(line);
18853
+ for (const pe of parsed)
18854
+ pushParsedEvent(pe);
17769
18855
  let msg;
17770
18856
  try {
17771
18857
  msg = JSON.parse(line);
@@ -17852,11 +18938,17 @@ class CodexBackend {
17852
18938
  closeAllPending("spawn error");
17853
18939
  resolveSessionId(sessionId);
17854
18940
  messageDone = true;
18941
+ parsedEventDone = true;
17855
18942
  if (messageResolve) {
17856
18943
  const r = messageResolve;
17857
18944
  messageResolve = null;
17858
18945
  r();
17859
18946
  }
18947
+ if (parsedEventResolve) {
18948
+ const r = parsedEventResolve;
18949
+ parsedEventResolve = null;
18950
+ r();
18951
+ }
17860
18952
  resolve({
17861
18953
  status: "failed",
17862
18954
  output: "",
@@ -17886,11 +18978,17 @@ class CodexBackend {
17886
18978
  }
17887
18979
  resolveSessionId(sessionId);
17888
18980
  messageDone = true;
18981
+ parsedEventDone = true;
17889
18982
  if (messageResolve) {
17890
18983
  const r = messageResolve;
17891
18984
  messageResolve = null;
17892
18985
  r();
17893
18986
  }
18987
+ if (parsedEventResolve) {
18988
+ const r = parsedEventResolve;
18989
+ parsedEventResolve = null;
18990
+ r();
18991
+ }
17894
18992
  resolve({
17895
18993
  status: resultStatus,
17896
18994
  output: lastOutput,
@@ -17906,18 +19004,55 @@ class CodexBackend {
17906
19004
  async next() {
17907
19005
  while (messageQueue.length === 0 && !messageDone) {
17908
19006
  await new Promise((resolve) => {
17909
- messageResolve = resolve;
19007
+ messageResolve = resolve;
19008
+ });
19009
+ }
19010
+ if (messageQueue.length > 0) {
19011
+ return { value: messageQueue.shift(), done: false };
19012
+ }
19013
+ return { value: undefined, done: true };
19014
+ }
19015
+ };
19016
+ }
19017
+ };
19018
+ const parsedEvents = {
19019
+ [Symbol.asyncIterator]() {
19020
+ return {
19021
+ async next() {
19022
+ while (parsedEventQueue.length === 0 && !parsedEventDone) {
19023
+ await new Promise((resolve) => {
19024
+ parsedEventResolve = resolve;
17910
19025
  });
17911
19026
  }
17912
- if (messageQueue.length > 0) {
17913
- return { value: messageQueue.shift(), done: false };
19027
+ if (parsedEventQueue.length > 0) {
19028
+ return { value: parsedEventQueue.shift(), done: false };
17914
19029
  }
17915
19030
  return { value: undefined, done: true };
17916
19031
  }
17917
19032
  };
17918
19033
  }
17919
19034
  };
17920
- return { pid: proc.pid, messages, sessionId: sessionIdPromise, result: resultPromise };
19035
+ const send = (text2, mode) => {
19036
+ if (!proc.stdin || proc.stdin.destroyed)
19037
+ return { ok: false, reason: "stdin closed" };
19038
+ const encoded = this.encodeStdinMessage(text2, mode, { threadId: sessionId, requestId: ++requestId });
19039
+ if (!encoded)
19040
+ return { ok: false, reason: "encoding failed (no threadId)" };
19041
+ writeStdin(encoded);
19042
+ return { ok: true };
19043
+ };
19044
+ const descriptor = {
19045
+ lifecycle: this.lifecycle,
19046
+ busyDeliveryMode: this.busyDeliveryMode,
19047
+ supportsStdinNotification: this.supportsStdinNotification
19048
+ };
19049
+ const closeStdin = () => {
19050
+ try {
19051
+ if (proc.stdin && !proc.stdin.destroyed)
19052
+ proc.stdin.end();
19053
+ } catch {}
19054
+ };
19055
+ return { pid: proc.pid, messages, parsedEvents, sessionId: sessionIdPromise, result: resultPromise, send, closeStdin, descriptor };
17921
19056
  }
17922
19057
  }
17923
19058
 
@@ -17927,9 +19062,102 @@ import { createInterface as createInterface3 } from "readline";
17927
19062
  class OpenCodeBackend {
17928
19063
  cliPath;
17929
19064
  name = "opencode";
19065
+ lifecycle = { kind: "per_turn", inFlightWake: "coalesce_into_pending" };
19066
+ busyDeliveryMode = "none";
19067
+ supportsStdinNotification = false;
17930
19068
  constructor(cliPath) {
17931
19069
  this.cliPath = cliPath;
17932
19070
  }
19071
+ parseLine(line) {
19072
+ if (!line.trim())
19073
+ return [];
19074
+ let event;
19075
+ try {
19076
+ event = JSON.parse(line);
19077
+ } catch {
19078
+ return [{ kind: "log", content: line, level: "debug" }];
19079
+ }
19080
+ const events = [];
19081
+ const eventType = event.type;
19082
+ const part = event.part;
19083
+ const eventSessionId = event.sessionID || event.session_id;
19084
+ switch (eventType) {
19085
+ case "session": {
19086
+ const sessionId = event.session_id;
19087
+ if (sessionId)
19088
+ events.push({ kind: "session_init", sessionId });
19089
+ break;
19090
+ }
19091
+ case "message": {
19092
+ const role = event.role;
19093
+ const content = event.content;
19094
+ if (role === "assistant" && content) {
19095
+ events.push({ kind: "text", text: content });
19096
+ }
19097
+ break;
19098
+ }
19099
+ case "text": {
19100
+ const text2 = part?.text || event.content || "";
19101
+ if (text2)
19102
+ events.push({ kind: "text", text: text2 });
19103
+ break;
19104
+ }
19105
+ case "thinking": {
19106
+ const content = part?.thinking || event.content || "";
19107
+ events.push({ kind: "thinking", text: content });
19108
+ break;
19109
+ }
19110
+ case "tool_call":
19111
+ events.push({
19112
+ kind: "tool_call",
19113
+ name: event.name || part?.name || "",
19114
+ callId: event.call_id || part?.id || "",
19115
+ input: event.input || part?.input
19116
+ });
19117
+ break;
19118
+ case "tool_result":
19119
+ events.push({
19120
+ kind: "tool_output",
19121
+ callId: event.call_id || part?.id || "",
19122
+ output: event.output || part?.output || ""
19123
+ });
19124
+ break;
19125
+ case "error": {
19126
+ const content = event.message || event.content || part?.error || "";
19127
+ events.push({ kind: "error", message: content });
19128
+ events.push({ kind: "turn_end" });
19129
+ break;
19130
+ }
19131
+ case "step_start":
19132
+ break;
19133
+ case "step_finish": {
19134
+ const reason = part?.reason;
19135
+ if (reason === "stop" || reason === "end_turn") {
19136
+ events.push({ kind: "turn_end" });
19137
+ }
19138
+ break;
19139
+ }
19140
+ case "done":
19141
+ case "complete": {
19142
+ const status = event.status;
19143
+ if (status === "error" || status === "failed") {
19144
+ const output = event.output;
19145
+ events.push({ kind: "error", message: output || "task failed" });
19146
+ }
19147
+ events.push({ kind: "turn_end" });
19148
+ break;
19149
+ }
19150
+ default:
19151
+ events.push({ kind: "log", content: line, level: "debug" });
19152
+ }
19153
+ if (eventSessionId && events.length > 0 && events[0].kind !== "session_init") {
19154
+ events.unshift({ kind: "session_init", sessionId: eventSessionId });
19155
+ }
19156
+ return events;
19157
+ }
19158
+ encodeStdinMessage() {
19159
+ return null;
19160
+ }
17933
19161
  execute(prompt, options) {
17934
19162
  const args = ["run", "--format", "json", "--dir", options.cwd];
17935
19163
  if (options.model) {
@@ -17987,6 +19215,9 @@ class OpenCodeBackend {
17987
19215
  const messageQueue = [];
17988
19216
  let messageResolve = null;
17989
19217
  let messageDone = false;
19218
+ const parsedEventQueue = [];
19219
+ let parsedEventResolve = null;
19220
+ let parsedEventDone = false;
17990
19221
  const pushMessage = (msg) => {
17991
19222
  messageQueue.push(msg);
17992
19223
  if (messageResolve) {
@@ -17995,6 +19226,14 @@ class OpenCodeBackend {
17995
19226
  r();
17996
19227
  }
17997
19228
  };
19229
+ const pushParsedEvent = (evt) => {
19230
+ parsedEventQueue.push(evt);
19231
+ if (parsedEventResolve) {
19232
+ const r = parsedEventResolve;
19233
+ parsedEventResolve = null;
19234
+ r();
19235
+ }
19236
+ };
17998
19237
  const resultPromise = new Promise((resolve) => {
17999
19238
  const stderrChunks = [];
18000
19239
  proc.stderr?.on("data", (chunk) => {
@@ -18004,6 +19243,9 @@ class OpenCodeBackend {
18004
19243
  rl.on("line", (line) => {
18005
19244
  if (!line.trim())
18006
19245
  return;
19246
+ const parsed = this.parseLine(line);
19247
+ for (const pe of parsed)
19248
+ pushParsedEvent(pe);
18007
19249
  let event;
18008
19250
  try {
18009
19251
  event = JSON.parse(line);
@@ -18115,11 +19357,17 @@ class OpenCodeBackend {
18115
19357
  lastError = `spawn error: ${err.message}`;
18116
19358
  resolveSessionId(lastSessionId);
18117
19359
  messageDone = true;
19360
+ parsedEventDone = true;
18118
19361
  if (messageResolve) {
18119
19362
  const r = messageResolve;
18120
19363
  messageResolve = null;
18121
19364
  r();
18122
19365
  }
19366
+ if (parsedEventResolve) {
19367
+ const r = parsedEventResolve;
19368
+ parsedEventResolve = null;
19369
+ r();
19370
+ }
18123
19371
  resolve({
18124
19372
  status: "failed",
18125
19373
  output: "",
@@ -18144,11 +19392,17 @@ class OpenCodeBackend {
18144
19392
  }
18145
19393
  resolveSessionId(lastSessionId);
18146
19394
  messageDone = true;
19395
+ parsedEventDone = true;
18147
19396
  if (messageResolve) {
18148
19397
  const r = messageResolve;
18149
19398
  messageResolve = null;
18150
19399
  r();
18151
19400
  }
19401
+ if (parsedEventResolve) {
19402
+ const r = parsedEventResolve;
19403
+ parsedEventResolve = null;
19404
+ r();
19405
+ }
18152
19406
  resolve({
18153
19407
  status: resultStatus,
18154
19408
  output: lastOutput,
@@ -18175,7 +19429,32 @@ class OpenCodeBackend {
18175
19429
  };
18176
19430
  }
18177
19431
  };
18178
- return { pid: proc.pid, messages, sessionId: sessionIdPromise, result: resultPromise };
19432
+ const parsedEvents = {
19433
+ [Symbol.asyncIterator]() {
19434
+ return {
19435
+ async next() {
19436
+ while (parsedEventQueue.length === 0 && !parsedEventDone) {
19437
+ await new Promise((resolve) => {
19438
+ parsedEventResolve = resolve;
19439
+ });
19440
+ }
19441
+ if (parsedEventQueue.length > 0) {
19442
+ return { value: parsedEventQueue.shift(), done: false };
19443
+ }
19444
+ return { value: undefined, done: true };
19445
+ }
19446
+ };
19447
+ }
19448
+ };
19449
+ const send = () => {
19450
+ return { ok: false, reason: "unsupported" };
19451
+ };
19452
+ const descriptor = {
19453
+ lifecycle: this.lifecycle,
19454
+ busyDeliveryMode: this.busyDeliveryMode,
19455
+ supportsStdinNotification: this.supportsStdinNotification
19456
+ };
19457
+ return { pid: proc.pid, messages, parsedEvents, sessionId: sessionIdPromise, result: resultPromise, send, descriptor };
18179
19458
  }
18180
19459
  }
18181
19460
 
@@ -18658,7 +19937,7 @@ function releaseLock(lockPath) {
18658
19937
  }
18659
19938
 
18660
19939
  // daemon/execenv/timeline.ts
18661
- var log3 = createLogger2({ module: "timeline" });
19940
+ var log5 = createLogger2({ module: "timeline" });
18662
19941
  function readJsonl(filePath) {
18663
19942
  let content;
18664
19943
  try {
@@ -18727,7 +20006,7 @@ async function initEntryAsync(timelineDir, entry) {
18727
20006
  acquired = acquireLock(lockPath);
18728
20007
  }
18729
20008
  if (!acquired) {
18730
- log3.debug(`Timeline initEntry: could not acquire lock for ${filename}`);
20009
+ log5.debug(`Timeline initEntry: could not acquire lock for ${filename}`);
18731
20010
  return;
18732
20011
  }
18733
20012
  try {
@@ -18737,7 +20016,7 @@ async function initEntryAsync(timelineDir, entry) {
18737
20016
  releaseLock(lockPath);
18738
20017
  }
18739
20018
  } catch (err) {
18740
- log3.debug("Timeline initEntry failed", err);
20019
+ log5.debug("Timeline initEntry failed", err);
18741
20020
  }
18742
20021
  }
18743
20022
  function updateEntry(timelineDir, taskId, updater) {
@@ -18747,7 +20026,7 @@ function updateEntry(timelineDir, taskId, updater) {
18747
20026
  try {
18748
20027
  const acquired = acquireLock(lockPath);
18749
20028
  if (!acquired) {
18750
- log3.debug(`Timeline updateEntry: lock held for ${filename}, skipping`);
20029
+ log5.debug(`Timeline updateEntry: lock held for ${filename}, skipping`);
18751
20030
  continue;
18752
20031
  }
18753
20032
  try {
@@ -18780,10 +20059,10 @@ function updateEntry(timelineDir, taskId, updater) {
18780
20059
  releaseLock(lockPath);
18781
20060
  }
18782
20061
  } catch (err) {
18783
- log3.debug(`Timeline updateEntry failed for ${filename}`, err);
20062
+ log5.debug(`Timeline updateEntry failed for ${filename}`, err);
18784
20063
  }
18785
20064
  }
18786
- log3.debug(`Timeline updateEntry: task_id ${taskId} not found in last 7 days`);
20065
+ log5.debug(`Timeline updateEntry: task_id ${taskId} not found in last 7 days`);
18787
20066
  }
18788
20067
  function createTimelineEntry(taskId, prompt, type, sessionId, pid, provider, contextKey, detailedLog) {
18789
20068
  return {
@@ -18818,7 +20097,7 @@ function findResumableSessionByContextKey(timelineDir, contextKey, provider) {
18818
20097
  // daemon/execenv/steering.ts
18819
20098
  import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, readFileSync as readFileSync3, unlinkSync as unlinkSync2, readdirSync, statSync as statSync2 } from "fs";
18820
20099
  import { join as join5 } from "path";
18821
- var log4 = createLogger2({ module: "steering" });
20100
+ var log6 = createLogger2({ module: "steering" });
18822
20101
  var INTENT_DIR_NAME = ".kill_intents";
18823
20102
  var INTENT_STALE_MS = 10 * 60 * 1000;
18824
20103
  function intentFilePath(baseDir, taskId) {
@@ -18840,6 +20119,636 @@ function clearKillIntent(baseDir, taskId) {
18840
20119
  } catch {}
18841
20120
  }
18842
20121
 
20122
+ // daemon/steering/mailbox.ts
20123
+ import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4, readFileSync as readFileSync4, renameSync as renameSync2, readdirSync as readdirSync2, unlinkSync as unlinkSync3, rmSync, existsSync as existsSync2, watch } from "fs";
20124
+ import { join as join6 } from "path";
20125
+ var log7 = createLogger2({ module: "mailbox" });
20126
+ function inboxDir(baseDir, contextKey) {
20127
+ const safeKey = contextKey.replace(/[^a-zA-Z0-9_:-]/g, "_");
20128
+ return join6(baseDir, ".steering", safeKey, "inbox");
20129
+ }
20130
+ function ackDir(baseDir, contextKey) {
20131
+ const safeKey = contextKey.replace(/[^a-zA-Z0-9_:-]/g, "_");
20132
+ return join6(baseDir, ".steering", safeKey, "ack");
20133
+ }
20134
+ function steeringDir(baseDir, contextKey) {
20135
+ const safeKey = contextKey.replace(/[^a-zA-Z0-9_:-]/g, "_");
20136
+ return join6(baseDir, ".steering", safeKey);
20137
+ }
20138
+ function readSteerMessage(filePath) {
20139
+ try {
20140
+ const content = readFileSync4(filePath, "utf-8");
20141
+ return JSON.parse(content);
20142
+ } catch {
20143
+ return null;
20144
+ }
20145
+ }
20146
+ function writeAck(baseDir, contextKey, seq) {
20147
+ const ack = ackDir(baseDir, contextKey);
20148
+ mkdirSync4(ack, { recursive: true });
20149
+ writeFileSync4(join6(ack, `${seq}.ack`), "");
20150
+ }
20151
+ function writeNack(baseDir, contextKey, seq, reason) {
20152
+ const ack = ackDir(baseDir, contextKey);
20153
+ mkdirSync4(ack, { recursive: true });
20154
+ writeFileSync4(join6(ack, `${seq}.nack`), JSON.stringify({ reason }));
20155
+ }
20156
+ function cleanupInboxFile(baseDir, contextKey, seq) {
20157
+ try {
20158
+ unlinkSync3(join6(inboxDir(baseDir, contextKey), `${seq}.json`));
20159
+ } catch {}
20160
+ }
20161
+ function cleanupSteeringDir(baseDir, contextKey) {
20162
+ const dir = steeringDir(baseDir, contextKey);
20163
+ try {
20164
+ rmSync(dir, { recursive: true, force: true });
20165
+ } catch {}
20166
+ }
20167
+ function watchInbox(baseDir, contextKey, onMessage) {
20168
+ const inbox = inboxDir(baseDir, contextKey);
20169
+ mkdirSync4(inbox, { recursive: true });
20170
+ const seen = new Set;
20171
+ let stopped = false;
20172
+ const scan = () => {
20173
+ if (stopped)
20174
+ return;
20175
+ try {
20176
+ const files = readdirSync2(inbox).filter((f) => f.endsWith(".json") && !f.endsWith(".tmp")).sort();
20177
+ for (const file2 of files) {
20178
+ if (seen.has(file2))
20179
+ continue;
20180
+ const seq = file2.replace(/\.json$/, "");
20181
+ const srcPath = join6(inbox, file2);
20182
+ const claimPath = join6(inbox, `${seq}.processing`);
20183
+ try {
20184
+ renameSync2(srcPath, claimPath);
20185
+ } catch {
20186
+ continue;
20187
+ }
20188
+ seen.add(file2);
20189
+ const msg = readSteerMessage(claimPath);
20190
+ try {
20191
+ unlinkSync3(claimPath);
20192
+ } catch {}
20193
+ if (msg) {
20194
+ onMessage(seq, msg);
20195
+ }
20196
+ }
20197
+ } catch {}
20198
+ };
20199
+ scan();
20200
+ let watcher = null;
20201
+ try {
20202
+ watcher = watch(inbox, () => {
20203
+ if (!stopped)
20204
+ scan();
20205
+ });
20206
+ } catch {
20207
+ log7.debug("fs.watch failed, relying on polling only");
20208
+ }
20209
+ const pollTimer = setInterval(scan, 200);
20210
+ return {
20211
+ stop() {
20212
+ stopped = true;
20213
+ clearInterval(pollTimer);
20214
+ watcher?.close();
20215
+ }
20216
+ };
20217
+ }
20218
+
20219
+ // daemon/steering/turnState.ts
20220
+ class RuntimeTurnState {
20221
+ currentTurnId = null;
20222
+ steeringGateActive = false;
20223
+ get isInTurn() {
20224
+ return this.currentTurnId !== null;
20225
+ }
20226
+ get turnId() {
20227
+ return this.currentTurnId;
20228
+ }
20229
+ get canSteerBusy() {
20230
+ return Boolean(this.currentTurnId && !this.steeringGateActive);
20231
+ }
20232
+ markTurnStarted(turnId) {
20233
+ if (turnId !== undefined && turnId !== null) {
20234
+ this.currentTurnId = turnId;
20235
+ }
20236
+ this.steeringGateActive = false;
20237
+ }
20238
+ adoptTurnId(turnId) {
20239
+ this.currentTurnId = turnId;
20240
+ }
20241
+ markToolBoundary() {
20242
+ this.steeringGateActive = true;
20243
+ }
20244
+ markProgress() {
20245
+ this.steeringGateActive = false;
20246
+ }
20247
+ markTurnCompleted() {
20248
+ this.currentTurnId = null;
20249
+ this.steeringGateActive = false;
20250
+ }
20251
+ reset() {
20252
+ this.currentTurnId = null;
20253
+ this.steeringGateActive = false;
20254
+ }
20255
+ }
20256
+
20257
+ // daemon/steering/apmStateMachine.ts
20258
+ var MAX_APM_GATED_STEERING_EVENTS = 12;
20259
+ function createInitialApmState() {
20260
+ return {
20261
+ isIdle: false,
20262
+ expectedTerminationReason: null,
20263
+ phase: "idle",
20264
+ outstandingToolUses: 0,
20265
+ compacting: false,
20266
+ toolBoundaryFlushDisabled: false,
20267
+ lastFlushReason: null,
20268
+ recentEvents: [],
20269
+ pendingMessages: []
20270
+ };
20271
+ }
20272
+ function reduceApmGatedToolUse(state, input) {
20273
+ if (input.kind === "tool_call") {
20274
+ return {
20275
+ nextState: {
20276
+ ...state,
20277
+ isIdle: false,
20278
+ phase: "tool_wait",
20279
+ outstandingToolUses: state.outstandingToolUses + 1
20280
+ },
20281
+ hadOutstandingToolUse: state.outstandingToolUses > 0,
20282
+ shouldFlushToolBatch: false
20283
+ };
20284
+ }
20285
+ const hadOutstandingToolUse = state.outstandingToolUses > 0;
20286
+ const outstandingToolUses = Math.max(0, state.outstandingToolUses - 1);
20287
+ return {
20288
+ nextState: {
20289
+ ...state,
20290
+ isIdle: false,
20291
+ phase: "tool_boundary",
20292
+ outstandingToolUses
20293
+ },
20294
+ hadOutstandingToolUse,
20295
+ shouldFlushToolBatch: hadOutstandingToolUse && outstandingToolUses === 0
20296
+ };
20297
+ }
20298
+ function reduceApmGatedCompaction(state, input) {
20299
+ if (input.kind === "compaction_started") {
20300
+ return { nextState: { ...state, isIdle: false, phase: "compacting", compacting: true } };
20301
+ }
20302
+ if (input.kind === "compaction_interrupted") {
20303
+ return { nextState: { ...state, isIdle: false, compacting: false } };
20304
+ }
20305
+ return {
20306
+ nextState: { ...state, isIdle: false, phase: "assistant_continuation", compacting: false }
20307
+ };
20308
+ }
20309
+ function reduceApmGatedFlushReadiness(state, input) {
20310
+ if (!input.isGated)
20311
+ return { shouldNotify: false, blockedReason: "non_gated", effects: [] };
20312
+ if (!input.hasSession)
20313
+ return { shouldNotify: false, blockedReason: "missing_session", effects: [] };
20314
+ if (input.inboxLength === 0)
20315
+ return { shouldNotify: false, blockedReason: "empty_inbox", effects: [] };
20316
+ if (state.toolBoundaryFlushDisabled) {
20317
+ return { shouldNotify: false, blockedReason: "tool_boundary_flush_disabled", effects: [] };
20318
+ }
20319
+ if (state.compacting)
20320
+ return { shouldNotify: false, blockedReason: "compacting", effects: [] };
20321
+ if (state.outstandingToolUses > 0) {
20322
+ return { shouldNotify: false, blockedReason: "outstanding_tool_uses", effects: [] };
20323
+ }
20324
+ return {
20325
+ shouldNotify: true,
20326
+ blockedReason: null,
20327
+ effects: [{ kind: "notify_stdin", reason: input.reason, stdinMode: "busy", clauseId: "SMR-002" }]
20328
+ };
20329
+ }
20330
+ function reduceApmGatedTurnEnd(state, input = {}) {
20331
+ const shouldDeliverQueuedMessages = Boolean(input.inboxLength && input.inboxLength > 0 && input.supportsStdinNotification && input.hasSession);
20332
+ return {
20333
+ nextState: {
20334
+ ...state,
20335
+ isIdle: !shouldDeliverQueuedMessages,
20336
+ phase: "idle",
20337
+ outstandingToolUses: 0,
20338
+ compacting: false,
20339
+ pendingMessages: shouldDeliverQueuedMessages ? state.pendingMessages : []
20340
+ },
20341
+ effects: shouldDeliverQueuedMessages ? [{ kind: "deliver_stdin", reason: "turn_end", stdinMode: "idle", clauseId: "SMR-002" }] : []
20342
+ };
20343
+ }
20344
+ function reduceApmGatedError(state, input = {}) {
20345
+ const shouldDisableToolBoundaryFlush = input.disableToolBoundaryFlush === true;
20346
+ return {
20347
+ nextState: {
20348
+ ...state,
20349
+ phase: "error",
20350
+ compacting: false,
20351
+ toolBoundaryFlushDisabled: state.toolBoundaryFlushDisabled || shouldDisableToolBoundaryFlush
20352
+ },
20353
+ shouldDisableToolBoundaryFlush
20354
+ };
20355
+ }
20356
+ function reduceApmGatedRecentEvent(state, input) {
20357
+ const summary = `${input.event}:${state.phase}:tools=${state.outstandingToolUses}:compact=${state.compacting}`;
20358
+ return {
20359
+ nextState: {
20360
+ ...state,
20361
+ recentEvents: [...state.recentEvents, summary].slice(-MAX_APM_GATED_STEERING_EVENTS)
20362
+ }
20363
+ };
20364
+ }
20365
+ function reduceApmGatedEnqueue(state, message2) {
20366
+ return {
20367
+ nextState: {
20368
+ ...state,
20369
+ pendingMessages: [...state.pendingMessages, message2]
20370
+ }
20371
+ };
20372
+ }
20373
+ function reduceApmStalledRecoveryTermination(state, input) {
20374
+ if (input.inboxLength === 0) {
20375
+ return { nextState: state, shouldTerminate: false, alreadyRecovering: false, blockedReason: "empty_inbox" };
20376
+ }
20377
+ if (state.expectedTerminationReason === "stalled_recovery") {
20378
+ return { nextState: state, shouldTerminate: false, alreadyRecovering: true, blockedReason: null };
20379
+ }
20380
+ const supportsStdinNotification = input.busyDeliveryMode !== "none";
20381
+ const directStdinRuntime = supportsStdinNotification && input.busyDeliveryMode === "direct";
20382
+ const canRestartDirectStdinProcess = directStdinRuntime && input.hasSession && (state.outstandingToolUses === 0 || input.hasDirectStdinRecoveryEvidence);
20383
+ const canRestartStalledProcess = !supportsStdinNotification || canRestartDirectStdinProcess;
20384
+ if (!canRestartStalledProcess) {
20385
+ return {
20386
+ nextState: state,
20387
+ shouldTerminate: false,
20388
+ alreadyRecovering: false,
20389
+ blockedReason: "runtime_not_restartable"
20390
+ };
20391
+ }
20392
+ if (input.staleForMs < input.staleThresholdMs && !input.runtimeProgressIsStale) {
20393
+ return {
20394
+ nextState: state,
20395
+ shouldTerminate: false,
20396
+ alreadyRecovering: false,
20397
+ blockedReason: "runtime_progress_recent"
20398
+ };
20399
+ }
20400
+ return {
20401
+ nextState: { ...state, expectedTerminationReason: "stalled_recovery" },
20402
+ shouldTerminate: true,
20403
+ alreadyRecovering: false,
20404
+ blockedReason: null
20405
+ };
20406
+ }
20407
+ function reduceApmStartupTimeoutTermination(state, input) {
20408
+ if (input.hasRuntimeProgressEvent) {
20409
+ return { nextState: state, shouldTerminate: false, blockedReason: "runtime_progress_started" };
20410
+ }
20411
+ return {
20412
+ nextState: { ...state, isIdle: false, expectedTerminationReason: "startup_timeout" },
20413
+ shouldTerminate: true,
20414
+ blockedReason: null
20415
+ };
20416
+ }
20417
+
20418
+ // daemon/steering/notificationState.ts
20419
+ function inboxNoticeMessageIdentity(message2) {
20420
+ const seq = typeof message2.seq === "number" && Number.isFinite(message2.seq) && message2.seq > 0 ? Math.floor(message2.seq) : null;
20421
+ if (seq !== null)
20422
+ return `s:${seq}`;
20423
+ const id = typeof message2.message_id === "string" && message2.message_id.length > 0 ? message2.message_id : typeof message2.id === "string" && message2.id.length > 0 ? message2.id : "";
20424
+ return id.length > 0 ? `m:${id}` : "";
20425
+ }
20426
+ class RuntimeNotificationState {
20427
+ pendingCountValue = 0;
20428
+ timerValue = null;
20429
+ lastNoticeFingerprint = null;
20430
+ lastNoticeSessionId = null;
20431
+ lastEncodeFailedFingerprint = null;
20432
+ lastEncodeFailedSessionId = null;
20433
+ contributedIdentities = new Set;
20434
+ contributionSessionId = null;
20435
+ get pendingCount() {
20436
+ return this.pendingCountValue;
20437
+ }
20438
+ isDuplicateNotice(fingerprint, sessionId) {
20439
+ if (fingerprint.length === 0)
20440
+ return false;
20441
+ return this.lastNoticeFingerprint === fingerprint && this.lastNoticeSessionId === sessionId;
20442
+ }
20443
+ recordNoticeWritten(fingerprint, sessionId, messages = []) {
20444
+ this.lastNoticeFingerprint = fingerprint;
20445
+ this.lastNoticeSessionId = sessionId;
20446
+ this.lastEncodeFailedFingerprint = null;
20447
+ this.lastEncodeFailedSessionId = null;
20448
+ this.ensureContributionSession(sessionId);
20449
+ for (const message2 of messages) {
20450
+ const identity = inboxNoticeMessageIdentity(message2);
20451
+ if (identity.length > 0)
20452
+ this.contributedIdentities.add(identity);
20453
+ }
20454
+ }
20455
+ recordNoticeEncodeFailed(fingerprint, sessionId) {
20456
+ if (fingerprint.length === 0)
20457
+ return;
20458
+ this.lastEncodeFailedFingerprint = fingerprint;
20459
+ this.lastEncodeFailedSessionId = sessionId;
20460
+ }
20461
+ isDuplicateEncodeFailedNotice(fingerprint, sessionId) {
20462
+ if (fingerprint.length === 0)
20463
+ return false;
20464
+ return this.lastEncodeFailedFingerprint === fingerprint && this.lastEncodeFailedSessionId === sessionId;
20465
+ }
20466
+ filterUncontributedMessages(messages, sessionId) {
20467
+ if (this.contributionSessionId !== sessionId)
20468
+ return messages;
20469
+ return messages.filter((m) => {
20470
+ const identity = inboxNoticeMessageIdentity(m);
20471
+ return identity.length === 0 || !this.contributedIdentities.has(identity);
20472
+ });
20473
+ }
20474
+ add(count = 1) {
20475
+ this.pendingCountValue += count;
20476
+ }
20477
+ schedule(callback, delayMs) {
20478
+ if (this.timerValue)
20479
+ return false;
20480
+ this.timerValue = setTimeout(() => {
20481
+ this.timerValue = null;
20482
+ callback();
20483
+ }, delayMs);
20484
+ this.timerValue.unref?.();
20485
+ return true;
20486
+ }
20487
+ takePendingAndClearTimer() {
20488
+ const count = this.pendingCountValue;
20489
+ this.pendingCountValue = 0;
20490
+ if (this.timerValue) {
20491
+ clearTimeout(this.timerValue);
20492
+ this.timerValue = null;
20493
+ }
20494
+ return count;
20495
+ }
20496
+ ensureContributionSession(sessionId) {
20497
+ if (this.contributionSessionId !== sessionId) {
20498
+ this.contributionSessionId = sessionId;
20499
+ this.contributedIdentities = new Set;
20500
+ }
20501
+ }
20502
+ }
20503
+
20504
+ // daemon/steering/progressState.ts
20505
+ class RuntimeProgressState {
20506
+ lastEventAt;
20507
+ lastEventKind = null;
20508
+ _staleSince = null;
20509
+ _isStale = false;
20510
+ constructor(now = Date.now()) {
20511
+ this.lastEventAt = now;
20512
+ }
20513
+ get isStale() {
20514
+ return this._isStale;
20515
+ }
20516
+ get staleSince() {
20517
+ return this._staleSince;
20518
+ }
20519
+ get lastActivity() {
20520
+ return this.lastEventAt;
20521
+ }
20522
+ ageMs(nowMs = Date.now()) {
20523
+ return nowMs - this.lastEventAt;
20524
+ }
20525
+ recordRealEvent(kind, now = Date.now()) {
20526
+ this.lastEventAt = now;
20527
+ this.lastEventKind = kind;
20528
+ this._isStale = false;
20529
+ this._staleSince = null;
20530
+ }
20531
+ recordInternalProgress(kind, now = Date.now()) {
20532
+ this.lastEventAt = now;
20533
+ this.lastEventKind = kind;
20534
+ }
20535
+ markStale(now = Date.now()) {
20536
+ if (this._isStale)
20537
+ return;
20538
+ this._isStale = true;
20539
+ this._staleSince = now;
20540
+ }
20541
+ shouldMarkStale(thresholdMs, now = Date.now()) {
20542
+ if (this._isStale)
20543
+ return false;
20544
+ return this.ageMs(now) > thresholdMs;
20545
+ }
20546
+ processEvent(event, now = Date.now()) {
20547
+ switch (event.kind) {
20548
+ case "text":
20549
+ case "tool_call":
20550
+ case "tool_output":
20551
+ case "turn_end":
20552
+ case "session_init":
20553
+ case "error":
20554
+ this.recordRealEvent(event.kind, now);
20555
+ break;
20556
+ case "internal_progress":
20557
+ case "compaction_started":
20558
+ case "compaction_finished":
20559
+ case "telemetry":
20560
+ case "thinking":
20561
+ this.recordInternalProgress(event.kind, now);
20562
+ break;
20563
+ default:
20564
+ this.recordInternalProgress(event.kind, now);
20565
+ }
20566
+ }
20567
+ }
20568
+
20569
+ // daemon/steering/errorDiagnostics.ts
20570
+ var ACTION_BY_CLASS = {
20571
+ RateLimitError: "retry_backoff",
20572
+ AuthError: "abort",
20573
+ NotFoundError: "report",
20574
+ ModelConfigError: "abort",
20575
+ TimeoutError: "retry",
20576
+ ProviderConnectionError: "retry_jitter",
20577
+ ProviderStreamError: "retry",
20578
+ ProviderServerError: "retry",
20579
+ ProviderApiError: "report",
20580
+ RuntimeError: "report"
20581
+ };
20582
+ var EXPLICIT_TOKEN_RE = /\b([A-Z][A-Za-z0-9_]*(?:Error|Exception))\b/;
20583
+ var EXPLICIT_TOKEN_MAP = {
20584
+ RateLimitError: "RateLimitError",
20585
+ TooManyRequestsError: "RateLimitError",
20586
+ AuthenticationError: "AuthError",
20587
+ AuthorizationError: "AuthError",
20588
+ PermissionError: "AuthError",
20589
+ NotFoundError: "NotFoundError",
20590
+ ModelNotFoundError: "ModelConfigError",
20591
+ TimeoutError: "TimeoutError",
20592
+ ConnectionError: "ProviderConnectionError",
20593
+ APIConnectionError: "ProviderConnectionError",
20594
+ StreamError: "ProviderStreamError",
20595
+ InternalServerError: "ProviderServerError",
20596
+ APIError: "ProviderApiError",
20597
+ BadRequestError: "ProviderApiError"
20598
+ };
20599
+ function extractHttpStatus(message2) {
20600
+ const labeled = /\b(?:HTTP|status(?:\s+code)?|API\s+Error)[:\s]+([45]\d{2})\b/i.exec(message2);
20601
+ if (labeled)
20602
+ return Number(labeled[1]);
20603
+ const semantic = /\b([45]\d{2})\s+(?:Unauthorized|Forbidden|Not Found|Too Many Requests|Internal Server Error|Bad Gateway|Service Unavailable|Gateway Timeout)\b/i.exec(message2);
20604
+ return semantic ? Number(semantic[1]) : null;
20605
+ }
20606
+ var AUTH_ACTION_REQUIRED_PATTERNS = [
20607
+ /access token could not be refreshed/i,
20608
+ /\btoken_(?:revoked|invalidated)\b/i,
20609
+ /refresh token was already used/i,
20610
+ /access token.*invalidated/i,
20611
+ /authentication token has been invalidated/i,
20612
+ /logged out or signed in to another account/i,
20613
+ /not logged in/i,
20614
+ /not signed in/i,
20615
+ /login required/i,
20616
+ /log in first/i,
20617
+ /please log in/i,
20618
+ /authentication failed/i,
20619
+ /auth(?:entication)? failed/i,
20620
+ /authentication timed out/i,
20621
+ /missing (?:api )?token/i,
20622
+ /no (?:api )?token/i,
20623
+ /missing credentials/i,
20624
+ /credentials? not found/i,
20625
+ /invalid api key/i,
20626
+ /api key (?:is )?not set/i,
20627
+ /token revoked/i,
20628
+ /refresh token expired/i,
20629
+ /session expired/i,
20630
+ /unauthorized/i,
20631
+ /forbidden/i,
20632
+ /invalid.?token/i
20633
+ ];
20634
+ var RATE_LIMIT_PATTERNS = [
20635
+ /too many requests/i,
20636
+ /rate.?limit/i,
20637
+ /quota.?exceeded/i,
20638
+ /overloaded/i
20639
+ ];
20640
+ var MODEL_CONFIG_PATTERNS = [
20641
+ /model.?not.?(?:found|supported|available)/i,
20642
+ /invalid.?model/i,
20643
+ /does not exist/i
20644
+ ];
20645
+ var TIMEOUT_PATTERNS = [
20646
+ /timeout/i,
20647
+ /ETIMEDOUT/,
20648
+ /timed.?out/i,
20649
+ /deadline.?exceeded/i
20650
+ ];
20651
+ var CONNECTION_PATTERNS = [
20652
+ /ECONNREFUSED/,
20653
+ /ECONNRESET/,
20654
+ /ENETUNREACH/,
20655
+ /EHOSTUNREACH/,
20656
+ /EAI_AGAIN/,
20657
+ /ENOTFOUND/,
20658
+ /connection.?refused/i,
20659
+ /connection.?reset/i,
20660
+ /network.?error/i,
20661
+ /Unable to connect to API/i
20662
+ ];
20663
+ var STREAM_PATTERNS = [
20664
+ /stream.?error/i,
20665
+ /stream closed before response/i,
20666
+ /error decoding response body/i,
20667
+ /premature.?close/i,
20668
+ /aborted/i
20669
+ ];
20670
+ var SERVER_PATTERNS = [
20671
+ /internal.?server/i,
20672
+ /bad.?gateway/i,
20673
+ /service.?unavailable/i
20674
+ ];
20675
+ function classifyByExplicitToken(message2) {
20676
+ const match = EXPLICIT_TOKEN_RE.exec(message2);
20677
+ if (!match)
20678
+ return null;
20679
+ const token = match[1];
20680
+ return EXPLICIT_TOKEN_MAP[token] ?? null;
20681
+ }
20682
+ function classifyByHttpStatus(httpStatus) {
20683
+ if (httpStatus === 429)
20684
+ return "RateLimitError";
20685
+ if (httpStatus === 401 || httpStatus === 403)
20686
+ return "AuthError";
20687
+ if (httpStatus === 404)
20688
+ return "NotFoundError";
20689
+ if (httpStatus >= 500)
20690
+ return "ProviderServerError";
20691
+ return "ProviderApiError";
20692
+ }
20693
+ function classifyByTextPatterns(message2) {
20694
+ for (const pat of RATE_LIMIT_PATTERNS) {
20695
+ if (pat.test(message2))
20696
+ return "RateLimitError";
20697
+ }
20698
+ for (const pat of AUTH_ACTION_REQUIRED_PATTERNS) {
20699
+ if (pat.test(message2))
20700
+ return "AuthError";
20701
+ }
20702
+ for (const pat of MODEL_CONFIG_PATTERNS) {
20703
+ if (pat.test(message2))
20704
+ return "ModelConfigError";
20705
+ }
20706
+ for (const pat of TIMEOUT_PATTERNS) {
20707
+ if (pat.test(message2))
20708
+ return "TimeoutError";
20709
+ }
20710
+ for (const pat of CONNECTION_PATTERNS) {
20711
+ if (pat.test(message2))
20712
+ return "ProviderConnectionError";
20713
+ }
20714
+ for (const pat of STREAM_PATTERNS) {
20715
+ if (pat.test(message2))
20716
+ return "ProviderStreamError";
20717
+ }
20718
+ for (const pat of SERVER_PATTERNS) {
20719
+ if (pat.test(message2))
20720
+ return "ProviderServerError";
20721
+ }
20722
+ return null;
20723
+ }
20724
+ function classifyRuntimeError(message2, httpStatus) {
20725
+ const byToken = classifyByExplicitToken(message2);
20726
+ if (byToken) {
20727
+ return { errorClass: byToken, action: ACTION_BY_CLASS[byToken], reason: message2 };
20728
+ }
20729
+ const status = httpStatus ?? extractHttpStatus(message2);
20730
+ if (status !== null && status !== undefined) {
20731
+ const cls = classifyByHttpStatus(status);
20732
+ return { errorClass: cls, action: ACTION_BY_CLASS[cls], reason: message2 };
20733
+ }
20734
+ const byPattern = classifyByTextPatterns(message2);
20735
+ if (byPattern) {
20736
+ return { errorClass: byPattern, action: ACTION_BY_CLASS[byPattern], reason: message2 };
20737
+ }
20738
+ return { errorClass: "RuntimeError", action: "report", reason: message2 };
20739
+ }
20740
+ function scrubDiagnosticText(text2) {
20741
+ let scrubbed = text2;
20742
+ scrubbed = scrubbed.replace(/sk-ant-[a-zA-Z0-9_-]+/g, "sk-ant-***");
20743
+ scrubbed = scrubbed.replace(/sk-proj-[a-zA-Z0-9_-]+/g, "sk-proj-***");
20744
+ scrubbed = scrubbed.replace(/sk-[a-zA-Z0-9_-]{20,}/g, "sk-***");
20745
+ scrubbed = scrubbed.replace(/Bearer\s+[a-zA-Z0-9._-]+/gi, "Bearer ***");
20746
+ scrubbed = scrubbed.replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, "***@***.***");
20747
+ scrubbed = scrubbed.replace(/:\/\/[^:@\s]+:[^@\s]+@/g, "://***:***@");
20748
+ scrubbed = scrubbed.replace(/\/(?:Users|home)\/[a-zA-Z0-9._-]+/g, "/***");
20749
+ return scrubbed;
20750
+ }
20751
+
18843
20752
  // daemon/prompt.ts
18844
20753
  var DM_RESPONSE_NOTICE = "Reply with `alook sync send-dm` — that's the only thing the user sees; your task output and reasoning are not shown." + " Talk to them at milestones like a colleague would, and don't end your turn without sending what they need." + " If this task will take more than 30 seconds, send a quick ack first so the user knows you're on it." + " IMPORTANT: If you were working on a previous task before this message arrived, do NOT silently drop it. After handling this message, return to any prior unfinished work and report the result to the user.";
18845
20754
  var EMAIL_NOTICE = "This task was triggered by an incoming email. Reply to the sender via email — use the email sending tool to respond." + " If you need more information or confirmation, email them and then exit." + " Do not wait — when they reply, a new task will be triggered automatically and you will be woken up with their response." + " IMPORTANT: Do not let this email interrupt any task you were previously working on. After handling this email, return to your original task and make sure it reaches completion.";
@@ -18935,7 +20844,7 @@ function buildPrompt(task, attachments) {
18935
20844
  }
18936
20845
 
18937
20846
  // daemon/session-runner.ts
18938
- var log5 = createLogger2({ module: "session-runner" });
20847
+ var log8 = createLogger2({ module: "session-runner" });
18939
20848
  var ATTACHMENTS_BASE = tempDir("alook-attachments");
18940
20849
  async function writeMarkerFile(workspacesRoot, marker) {
18941
20850
  const dir = path.join(workspacesRoot, ".pending_completions");
@@ -18983,20 +20892,20 @@ async function reportToServer(fn, markerData, workspacesRoot) {
18983
20892
  } catch (e) {
18984
20893
  lastErr = e;
18985
20894
  if (isClientError(e)) {
18986
- log5.info(`server report for task ${markerData.taskId}: task already in terminal state (${e})`);
20895
+ log8.info(`server report for task ${markerData.taskId}: task already in terminal state (${e})`);
18987
20896
  return;
18988
20897
  }
18989
20898
  if (attempt < RETRY_DELAYS.length && isRetryableError(e)) {
18990
- log5.debug(`server report attempt ${attempt + 1} failed for task ${markerData.taskId}, retrying in ${RETRY_DELAYS[attempt]}ms`);
20899
+ log8.debug(`server report attempt ${attempt + 1} failed for task ${markerData.taskId}, retrying in ${RETRY_DELAYS[attempt]}ms`);
18991
20900
  await new Promise((r) => setTimeout(r, RETRY_DELAYS[attempt]));
18992
20901
  }
18993
20902
  }
18994
20903
  }
18995
- log5.warn(`server report failed for task ${markerData.taskId} after retries, writing marker: ${lastErr}`);
20904
+ log8.warn(`server report failed for task ${markerData.taskId} after retries, writing marker: ${lastErr}`);
18996
20905
  try {
18997
20906
  await writeMarkerFile(workspacesRoot, markerData);
18998
20907
  } catch (writeErr) {
18999
- log5.error(`marker write also failed for task ${markerData.taskId}: ${writeErr}`);
20908
+ log8.error(`marker write also failed for task ${markerData.taskId}: ${writeErr}`);
19000
20909
  }
19001
20910
  }
19002
20911
  function sanitizeFilename(name) {
@@ -19027,12 +20936,12 @@ async function downloadAttachments(client, token, workspaceId, taskId, attachmen
19027
20936
  }
19028
20937
  async function runSession(input) {
19029
20938
  const { task, provider, cliPath, model, serverURL, token, workspacesRoot, agentTimeout, messageInactivityTimeout } = input;
19030
- log5.info(`starting (task=${task.id}, type=${task.type}, agent=${task.agentId}, provider=${provider}, model=${model || "default"})`);
20939
+ log8.info(`starting (task=${task.id}, type=${task.type}, agent=${task.agentId}, provider=${provider}, model=${model || "default"})`);
19031
20940
  const client = new DaemonClient(serverURL);
19032
20941
  const backend = createBackend(provider, cliPath);
19033
20942
  const agentBaseDir = path.join(workspacesRoot, task.workspaceId, task.agentId, "workdir");
19034
20943
  const timelineDir = path.join(agentBaseDir, ".context_timeline").replace(/\\/g, "/");
19035
- mkdirSync4(timelineDir, { recursive: true });
20944
+ mkdirSync5(timelineDir, { recursive: true });
19036
20945
  await initEntryAsync(timelineDir, createTimelineEntry(task.id, task.prompt, task.type, undefined, process.pid, provider, task.contextKey, input.logFilePath));
19037
20946
  const { workDir, env } = prepare({ workspacesRoot, token }, task);
19038
20947
  let killed = false;
@@ -19050,16 +20959,22 @@ async function runSession(input) {
19050
20959
  try {
19051
20960
  await client.reportMessages(token, task.id, batch);
19052
20961
  } catch (e) {
19053
- log5.debug("message report failed", e);
20962
+ log8.debug("message report failed", e);
19054
20963
  }
19055
20964
  };
20965
+ let mailboxWatcher = null;
20966
+ let stalledRecoveryTimer;
19056
20967
  const onKill = async () => {
19057
20968
  if (killed)
19058
20969
  return;
19059
20970
  killed = true;
19060
- log5.info(`killed by signal (messages=${seq}, tools=${toolCount})`);
20971
+ log8.info(`killed by signal (messages=${seq}, tools=${toolCount})`);
20972
+ if (mailboxWatcher)
20973
+ mailboxWatcher.stop();
20974
+ if (stalledRecoveryTimer)
20975
+ clearInterval(stalledRecoveryTimer);
19061
20976
  if (agentPid !== undefined) {
19062
- log5.info(`killing inner agent group (pid=${agentPid})`);
20977
+ log8.info(`killing inner agent group (pid=${agentPid})`);
19063
20978
  await killProcessTree(agentPid);
19064
20979
  }
19065
20980
  if (flushTimer)
@@ -19102,14 +21017,14 @@ async function runSession(input) {
19102
21017
  const attachmentIds = task.context?.attachment_ids ?? [];
19103
21018
  let attachments;
19104
21019
  if (attachmentIds.length > 0) {
19105
- log5.info(`downloading ${attachmentIds.length} attachment(s)`);
21020
+ log8.info(`downloading ${attachmentIds.length} attachment(s)`);
19106
21021
  try {
19107
21022
  attachments = await downloadAttachments(client, token, task.workspaceId, task.id, attachmentIds);
19108
- log5.info(`attachments ready (${attachments.length} file(s))`);
21023
+ log8.info(`attachments ready (${attachments.length} file(s))`);
19109
21024
  } catch (e) {
19110
21025
  await cleanupAttachments(task.id);
19111
21026
  const errMsg = `failed to download attachments: ${e}`;
19112
- log5.error(errMsg);
21027
+ log8.error(errMsg);
19113
21028
  updateEntry(timelineDir, task.id, (entry) => {
19114
21029
  entry.pid = null;
19115
21030
  entry.status = "failed";
@@ -19126,32 +21041,301 @@ async function runSession(input) {
19126
21041
  const prompt = input.promptOverride ?? buildPrompt(task, attachments);
19127
21042
  const resumeSessionId = task.contextKey ? findResumableSessionByContextKey(timelineDir, task.contextKey, provider) ?? undefined : undefined;
19128
21043
  if (resumeSessionId) {
19129
- log5.info(`resuming session ${resumeSessionId} (context_key: ${task.contextKey})`);
21044
+ log8.info(`resuming session ${resumeSessionId} (context_key: ${task.contextKey})`);
19130
21045
  }
19131
21046
  const session2 = backend.execute(prompt, {
19132
21047
  cwd: workDir,
19133
21048
  model: model || undefined,
19134
21049
  env,
19135
21050
  timeout: agentTimeout,
19136
- resumeSessionId
21051
+ resumeSessionId,
21052
+ steeringEnabled: input.steeringEnabled
19137
21053
  });
19138
21054
  agentPid = session2.pid;
19139
21055
  if (killed) {
19140
21056
  if (agentPid !== undefined) {
19141
- log5.info(`kill landed during spawn — reaping inner agent group (pid=${agentPid})`);
21057
+ log8.info(`kill landed during spawn — reaping inner agent group (pid=${agentPid})`);
19142
21058
  await killProcessTree(agentPid);
19143
21059
  }
19144
21060
  process.exit(1);
19145
21061
  }
19146
21062
  const earlySessionId = await session2.sessionId;
19147
- log5.info(`agent started (pid=${agentPid ?? "unknown"}, session=${earlySessionId})`);
19148
- log5.info(JSON.stringify({ role: "user", type: "text", content: prompt }));
21063
+ log8.info(`agent started (pid=${agentPid ?? "unknown"}, session=${earlySessionId})`);
21064
+ log8.info(JSON.stringify({ role: "user", type: "text", content: prompt }));
19149
21065
  updateEntry(timelineDir, task.id, (entry) => {
19150
21066
  entry.session_id = earlySessionId || null;
19151
21067
  if (earlySessionId)
19152
21068
  entry.agent_started = true;
19153
21069
  });
19154
21070
  flushTimer = setInterval(flushMessages, FLUSH_INTERVAL_MS);
21071
+ const turnState = new RuntimeTurnState;
21072
+ let apmState = createInitialApmState();
21073
+ const notificationState = new RuntimeNotificationState;
21074
+ const progressState = new RuntimeProgressState;
21075
+ const pendingSteeredTasks = new Set;
21076
+ const pendingAcks = [];
21077
+ let hasReceivedProgressEvent = false;
21078
+ if (input.steeringEnabled && input.steeringMailboxDir && task.contextKey) {
21079
+ const descriptor = session2.descriptor;
21080
+ const STALLED_THRESHOLD_MS = 120000;
21081
+ const STALLED_CHECK_INTERVAL_MS = 30000;
21082
+ if (session2.parsedEvents) {
21083
+ const parsedIter = session2.parsedEvents[Symbol.asyncIterator]();
21084
+ const consumeParsedEvents = async () => {
21085
+ try {
21086
+ while (!killed) {
21087
+ const { value: event, done } = await parsedIter.next();
21088
+ if (done)
21089
+ break;
21090
+ hasReceivedProgressEvent = true;
21091
+ progressState.processEvent(event);
21092
+ const recentResult = reduceApmGatedRecentEvent(apmState, { event: event.kind });
21093
+ apmState = recentResult.nextState;
21094
+ if (event.kind === "error") {
21095
+ const classified = classifyRuntimeError(event.message);
21096
+ log8.info(`steering: error classified as ${classified.errorClass}: ${scrubDiagnosticText(event.message)}`);
21097
+ const errResult = reduceApmGatedError(apmState, { disableToolBoundaryFlush: true });
21098
+ apmState = errResult.nextState;
21099
+ }
21100
+ switch (event.kind) {
21101
+ case "tool_call":
21102
+ case "thinking":
21103
+ case "compaction_started":
21104
+ turnState.markToolBoundary();
21105
+ break;
21106
+ case "text":
21107
+ case "tool_output":
21108
+ case "compaction_finished":
21109
+ turnState.markProgress();
21110
+ break;
21111
+ }
21112
+ switch (event.kind) {
21113
+ case "session_init":
21114
+ turnState.markTurnStarted(event.sessionId);
21115
+ break;
21116
+ case "text":
21117
+ if (!turnState.isInTurn)
21118
+ turnState.markTurnStarted();
21119
+ break;
21120
+ case "tool_call": {
21121
+ if (!turnState.isInTurn)
21122
+ turnState.markTurnStarted();
21123
+ const result2 = reduceApmGatedToolUse(apmState, { kind: "tool_call" });
21124
+ apmState = result2.nextState;
21125
+ break;
21126
+ }
21127
+ case "tool_output": {
21128
+ const result2 = reduceApmGatedToolUse(apmState, { kind: "tool_output" });
21129
+ apmState = result2.nextState;
21130
+ if (result2.shouldFlushToolBatch && session2.send && apmState.pendingMessages.length > 0) {
21131
+ const readiness = reduceApmGatedFlushReadiness(apmState, {
21132
+ isGated: descriptor?.busyDeliveryMode === "gated",
21133
+ hasSession: !!earlySessionId,
21134
+ inboxLength: apmState.pendingMessages.length,
21135
+ reason: "tool_batch_complete"
21136
+ });
21137
+ if (readiness.shouldNotify) {
21138
+ let allSent = true;
21139
+ for (const msg of apmState.pendingMessages) {
21140
+ const sendResult = session2.send(msg, "busy");
21141
+ if (!sendResult.ok) {
21142
+ allSent = false;
21143
+ break;
21144
+ }
21145
+ }
21146
+ if (allSent) {
21147
+ apmState = { ...apmState, pendingMessages: [] };
21148
+ for (const ack of pendingAcks) {
21149
+ notificationState.recordNoticeWritten(String(ack.seq), ack.sessionId, [{ id: String(ack.seq) }]);
21150
+ writeAck(agentBaseDir, task.contextKey, ack.seq);
21151
+ }
21152
+ pendingAcks.length = 0;
21153
+ }
21154
+ }
21155
+ }
21156
+ break;
21157
+ }
21158
+ case "compaction_started":
21159
+ case "compaction_finished": {
21160
+ const result2 = reduceApmGatedCompaction(apmState, { kind: event.kind });
21161
+ apmState = result2.nextState;
21162
+ if (event.kind === "compaction_finished" && session2.send && apmState.pendingMessages.length > 0) {
21163
+ const readiness = reduceApmGatedFlushReadiness(apmState, {
21164
+ isGated: descriptor?.busyDeliveryMode === "gated",
21165
+ hasSession: !!earlySessionId,
21166
+ inboxLength: apmState.pendingMessages.length,
21167
+ reason: "compaction_finished"
21168
+ });
21169
+ if (readiness.shouldNotify) {
21170
+ let allSent = true;
21171
+ for (const msg of apmState.pendingMessages) {
21172
+ const sendResult = session2.send(msg, "busy");
21173
+ if (!sendResult.ok) {
21174
+ allSent = false;
21175
+ break;
21176
+ }
21177
+ }
21178
+ if (allSent) {
21179
+ apmState = { ...apmState, pendingMessages: [] };
21180
+ for (const ack of pendingAcks) {
21181
+ notificationState.recordNoticeWritten(String(ack.seq), ack.sessionId, [{ id: String(ack.seq) }]);
21182
+ writeAck(agentBaseDir, task.contextKey, ack.seq);
21183
+ }
21184
+ pendingAcks.length = 0;
21185
+ }
21186
+ }
21187
+ }
21188
+ break;
21189
+ }
21190
+ case "turn_end": {
21191
+ const result2 = reduceApmGatedTurnEnd(apmState, {
21192
+ inboxLength: apmState.pendingMessages.length,
21193
+ supportsStdinNotification: descriptor?.supportsStdinNotification,
21194
+ hasSession: !!earlySessionId
21195
+ });
21196
+ apmState = result2.nextState;
21197
+ let flushedOk = false;
21198
+ for (const eff of result2.effects) {
21199
+ if (eff.kind === "deliver_stdin" && session2.send) {
21200
+ let allSent = true;
21201
+ for (const msg of apmState.pendingMessages) {
21202
+ const sendResult = session2.send(msg, eff.stdinMode);
21203
+ if (!sendResult.ok) {
21204
+ log8.warn("steering: send failed during turn_end flush", { reason: sendResult.reason });
21205
+ allSent = false;
21206
+ break;
21207
+ }
21208
+ }
21209
+ if (allSent) {
21210
+ apmState = { ...apmState, pendingMessages: [] };
21211
+ flushedOk = true;
21212
+ }
21213
+ }
21214
+ }
21215
+ if (flushedOk && pendingAcks.length > 0) {
21216
+ for (const ack of pendingAcks) {
21217
+ notificationState.recordNoticeWritten(String(ack.seq), ack.sessionId, [{ id: String(ack.seq) }]);
21218
+ writeAck(agentBaseDir, task.contextKey, ack.seq);
21219
+ }
21220
+ pendingAcks.length = 0;
21221
+ }
21222
+ if (flushedOk || apmState.pendingMessages.length === 0) {
21223
+ for (const steeredId of pendingSteeredTasks) {
21224
+ client.completeTask(token, steeredId, { output: "" }).catch((e) => {
21225
+ log8.debug(`steering: failed to complete steered task ${steeredId}`, e);
21226
+ });
21227
+ }
21228
+ pendingSteeredTasks.clear();
21229
+ }
21230
+ turnState.markTurnCompleted();
21231
+ break;
21232
+ }
21233
+ }
21234
+ }
21235
+ } catch (err) {
21236
+ log8.warn("steering: consumeParsedEvents error", { err: err instanceof Error ? err.message : String(err) });
21237
+ }
21238
+ };
21239
+ consumeParsedEvents().catch((err) => {
21240
+ log8.error("steering: consumeParsedEvents unhandled error", { err: err instanceof Error ? err.message : String(err) });
21241
+ });
21242
+ }
21243
+ stalledRecoveryTimer = setInterval(() => {
21244
+ if (killed)
21245
+ return;
21246
+ if (!hasReceivedProgressEvent) {
21247
+ const startupResult = reduceApmStartupTimeoutTermination(apmState, {
21248
+ hasRuntimeProgressEvent: hasReceivedProgressEvent
21249
+ });
21250
+ apmState = startupResult.nextState;
21251
+ if (startupResult.shouldTerminate) {
21252
+ log8.warn("steering: startup timeout — no progress events received, killing agent");
21253
+ if (agentPid !== undefined)
21254
+ killProcessTree(agentPid);
21255
+ return;
21256
+ }
21257
+ }
21258
+ const staleForMs = progressState.ageMs();
21259
+ if (staleForMs > STALLED_THRESHOLD_MS && !progressState.isStale) {
21260
+ progressState.markStale();
21261
+ }
21262
+ const stalledResult = reduceApmStalledRecoveryTermination(apmState, {
21263
+ inboxLength: apmState.pendingMessages.length,
21264
+ staleForMs,
21265
+ staleThresholdMs: STALLED_THRESHOLD_MS,
21266
+ runtimeProgressIsStale: progressState.isStale,
21267
+ hasSession: !!earlySessionId,
21268
+ busyDeliveryMode: descriptor?.busyDeliveryMode ?? "none",
21269
+ hasDirectStdinRecoveryEvidence: false
21270
+ });
21271
+ apmState = stalledResult.nextState;
21272
+ if (stalledResult.shouldTerminate) {
21273
+ log8.warn(`steering: stalled recovery — agent stale for ${(staleForMs / 1000).toFixed(1)}s with ${apmState.pendingMessages.length} pending messages, killing`);
21274
+ if (agentPid !== undefined)
21275
+ killProcessTree(agentPid);
21276
+ }
21277
+ }, STALLED_CHECK_INTERVAL_MS);
21278
+ mailboxWatcher = watchInbox(agentBaseDir, task.contextKey, (seq2, message2) => {
21279
+ const sessionId = earlySessionId || "";
21280
+ if (notificationState.isDuplicateNotice(String(seq2), sessionId)) {
21281
+ writeAck(agentBaseDir, task.contextKey, seq2);
21282
+ cleanupInboxFile(agentBaseDir, task.contextKey, seq2);
21283
+ return;
21284
+ }
21285
+ const busyMode = session2.descriptor?.busyDeliveryMode;
21286
+ let delivered = false;
21287
+ if (busyMode === "direct" && session2.send) {
21288
+ const result2 = session2.send(message2.text, turnState.isInTurn ? "busy" : "idle");
21289
+ if (result2.ok) {
21290
+ notificationState.recordNoticeWritten(String(seq2), sessionId, [{ id: String(seq2) }]);
21291
+ writeAck(agentBaseDir, task.contextKey, seq2);
21292
+ delivered = true;
21293
+ } else {
21294
+ writeNack(agentBaseDir, task.contextKey, seq2, result2.reason || "send failed");
21295
+ }
21296
+ } else if (busyMode === "gated") {
21297
+ const enqueueResult = reduceApmGatedEnqueue(apmState, message2.text);
21298
+ apmState = enqueueResult.nextState;
21299
+ if (turnState.canSteerBusy && session2.send && apmState.pendingMessages.length > 0) {
21300
+ const readiness = reduceApmGatedFlushReadiness(apmState, {
21301
+ isGated: true,
21302
+ hasSession: !!earlySessionId,
21303
+ inboxLength: apmState.pendingMessages.length,
21304
+ reason: "enqueue"
21305
+ });
21306
+ if (readiness.shouldNotify) {
21307
+ let allSent = true;
21308
+ for (const msg of apmState.pendingMessages) {
21309
+ const sendResult = session2.send(msg, "busy");
21310
+ if (!sendResult.ok) {
21311
+ allSent = false;
21312
+ break;
21313
+ }
21314
+ }
21315
+ if (allSent) {
21316
+ apmState = { ...apmState, pendingMessages: [] };
21317
+ }
21318
+ }
21319
+ }
21320
+ if (apmState.pendingMessages.length === 0) {
21321
+ notificationState.recordNoticeWritten(String(seq2), sessionId, [{ id: String(seq2) }]);
21322
+ writeAck(agentBaseDir, task.contextKey, seq2);
21323
+ } else {
21324
+ pendingAcks.push({ seq: seq2, sessionId });
21325
+ }
21326
+ delivered = true;
21327
+ } else {
21328
+ writeNack(agentBaseDir, task.contextKey, seq2, "unsupported backend");
21329
+ }
21330
+ if (delivered && message2.taskId) {
21331
+ pendingSteeredTasks.add(message2.taskId);
21332
+ client.startTask(token, message2.taskId).catch((e) => {
21333
+ log8.debug(`steering: failed to start steered task ${message2.taskId}`, e);
21334
+ });
21335
+ }
21336
+ cleanupInboxFile(agentBaseDir, task.contextKey, seq2);
21337
+ });
21338
+ }
19155
21339
  const INACTIVITY_TIMEOUT_MS = messageInactivityTimeout ?? 5 * 60 * 1000;
19156
21340
  let inactivityTimedOut = false;
19157
21341
  try {
@@ -19167,7 +21351,7 @@ async function runSession(input) {
19167
21351
  ]) : next);
19168
21352
  if (raceResult === "timeout") {
19169
21353
  inactivityTimedOut = true;
19170
- log5.warn(`message inactivity timeout (${INACTIVITY_TIMEOUT_MS / 1000}s) — killing agent`);
21354
+ log8.warn(`message inactivity timeout (${INACTIVITY_TIMEOUT_MS / 1000}s) — killing agent`);
19171
21355
  if (session2.pid !== undefined) {
19172
21356
  await killProcessTree(session2.pid);
19173
21357
  }
@@ -19182,9 +21366,9 @@ async function runSession(input) {
19182
21366
  if (msg.type === "tool-use")
19183
21367
  toolCount++;
19184
21368
  if (msg.type === "tool-result" && msg.output && msg.output.length > 500) {
19185
- log5.info(JSON.stringify({ role: "assistant", ...msg, output: msg.output.slice(0, 500) + `... (${msg.output.length} chars)` }));
21369
+ log8.info(JSON.stringify({ role: "assistant", ...msg, output: msg.output.slice(0, 500) + `... (${msg.output.length} chars)` }));
19186
21370
  } else {
19187
- log5.info(JSON.stringify({ role: "assistant", ...msg }));
21371
+ log8.info(JSON.stringify({ role: "assistant", ...msg }));
19188
21372
  }
19189
21373
  if (msg.type === "status" || msg.type === "log")
19190
21374
  continue;
@@ -19223,6 +21407,13 @@ async function runSession(input) {
19223
21407
  result.status = "failed";
19224
21408
  result.error = `message inactivity timeout (no messages for ${INACTIVITY_TIMEOUT_MS / 1000}s)`;
19225
21409
  }
21410
+ if (stalledRecoveryTimer)
21411
+ clearInterval(stalledRecoveryTimer);
21412
+ if (mailboxWatcher) {
21413
+ mailboxWatcher.stop();
21414
+ if (task.contextKey)
21415
+ cleanupSteeringDir(agentBaseDir, task.contextKey);
21416
+ }
19226
21417
  await cleanupAttachments(task.id);
19227
21418
  if (result.status === "completed") {
19228
21419
  updateEntry(timelineDir, task.id, (entry) => {
@@ -19245,18 +21436,18 @@ async function runSession(input) {
19245
21436
  body.session_id = result.sessionId;
19246
21437
  await reportToServer(() => client.completeTask(token, task.id, body), { taskId: task.id, type: "complete", payload: body, token, serverURL, createdAt: new Date().toISOString() }, workspacesRoot);
19247
21438
  const dur = (result.durationMs / 1000).toFixed(1);
19248
- log5.info(`completed (duration=${dur}s, messages=${seq}, tools=${toolCount})`);
21439
+ log8.info(`completed (duration=${dur}s, messages=${seq}, tools=${toolCount})`);
19249
21440
  } else {
19250
21441
  const errorMsg = result.error || "agent exited unexpectedly";
19251
21442
  await reportToServer(() => client.failTask(token, task.id, errorMsg), { taskId: task.id, type: "fail", payload: { error: errorMsg }, token, serverURL, createdAt: new Date().toISOString() }, workspacesRoot);
19252
21443
  const dur = (result.durationMs / 1000).toFixed(1);
19253
- log5.info(`failed (duration=${dur}s, messages=${seq}, tools=${toolCount}) — ${result.error}`);
21444
+ log8.info(`failed (duration=${dur}s, messages=${seq}, tools=${toolCount}) — ${result.error}`);
19254
21445
  }
19255
21446
  }
19256
21447
  async function main() {
19257
21448
  const encoded = process.argv[2];
19258
21449
  if (!encoded) {
19259
- log5.error("session-runner: missing base64-encoded input argument");
21450
+ log8.error("session-runner: missing base64-encoded input argument");
19260
21451
  process.exit(1);
19261
21452
  }
19262
21453
  let input;
@@ -19264,14 +21455,14 @@ async function main() {
19264
21455
  const json2 = Buffer.from(encoded, "base64").toString("utf-8");
19265
21456
  input = JSON.parse(json2);
19266
21457
  } catch (e) {
19267
- log5.error("session-runner: failed to parse input", e);
21458
+ log8.error("session-runner: failed to parse input", e);
19268
21459
  process.exit(1);
19269
21460
  }
19270
21461
  const client = new DaemonClient(input.serverURL);
19271
21462
  try {
19272
21463
  await runSession(input);
19273
21464
  } catch (e) {
19274
- log5.error(`session-runner: unhandled error for task ${input.task.id}`, e);
21465
+ log8.error(`session-runner: unhandled error for task ${input.task.id}`, e);
19275
21466
  await cleanupAttachments(input.task.id);
19276
21467
  const timelineDir = path.join(input.workspacesRoot, input.task.workspaceId, input.task.agentId, "workdir", ".context_timeline").replace(/\\/g, "/");
19277
21468
  updateEntry(timelineDir, input.task.id, (entry) => {