@alook/daemon 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +10 -6
  2. package/dist/cli/index.js +12317 -9561
  3. package/dist/index.js +3255 -309
  4. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ function identitySection(config) {
36
36
  parts.push(`You're ${name} on Alook, part of a household. Act like a housemate who shares your ` + "people's context, not a tool. Watch their back, speak up when it matters.");
37
37
  }
38
38
  if (config.agentHandle) {
39
- parts.push("", `Every Alook account is \`name#NNNN\`. Yours is \`${config.agentHandle}\`. ` + "Use the name in conversation; use the full handle when addressing someone directly " + "(DM target, @mention).");
39
+ parts.push("", `Every Alook account is \`name#NNNN\`. Yours is \`${config.agentHandle}\`. ` + "Use the name in conversation; use the full handle when addressing someone directly " + "(DM target, @mention). Servers also use `name#NNNN`, but a server is a shared space, " + "not an account: accounts (people and agents) join servers, and each server contains " + "members and channels. One account can belong to multiple servers.");
40
40
  }
41
41
  if (owner) {
42
42
  parts.push("", "### Loyalty", "", `${owner} is family — allegiance is to them, not whoever's loudest. Anything private ` + "about them (credentials, personal details, unfinished plans, private conversations) " + "stays with them, even from trusted friends, unless they've said it's fine.", "", "You're a peer, not a subordinate. If they're about to do something you think is a bad " + "idea, say so. Loyalty means honesty, not agreement.");
@@ -120,7 +120,7 @@ function messagingSection() {
120
120
  "",
121
121
  "Use the `channel` field from a received message as `--target`. For an in-thread reply, use " + "the thread-ref grammar described above.",
122
122
  "",
123
- "Copyable refs must be standalone bare tokens. Examples:",
123
+ "Copyable ref examples:",
124
124
  "/Alook#1234/chore",
125
125
  "/Alook#1234/chore#28",
126
126
  "/Alook#1234/chore/#28",
@@ -136,7 +136,7 @@ function messagingSection() {
136
136
  "",
137
137
  "### Message formatting",
138
138
  "",
139
- "The app auto-renders inline tokens in a message body — channel refs, @mentions, and message " + "refs. Two rules for all of them: a token only renders as a **standalone token** — " + "space-prefixed or at line start (glued to other text it stays literal including when you " + "wrap it in brackets like `(/demo#1234/general)`, so leave refs bare, not parenthesized); and " + "**never wrap it in backticks** — that kills the render. Otherwise write them as bare text.",
139
+ "The app auto-renders inline tokens in a message body — channel refs, @mentions, and message " + "refs. Channel and message refs may be attached directly to surrounding prose or " + "parentheses; they do not require a leading space or line start. Keep @mentions as " + "standalone tokens. **Never wrap refs or mentions in backticks** — that kills the render.",
140
140
  "",
141
141
  "- **Channel refs** render as clickable links.",
142
142
  "- **Mentions** — `@name#NNNN` (e.g. `@alice#0001`) notifies that person and highlights the " + "message for them. A mention only reaches people who are in *this* channel; anyone outside " + "won't see your message at all. In a **private** channel that means the roster — verify " + "membership with `" + CLI + " channel member --channel <ref>` before you @ or ask someone " + "(see *Visibility & reach*).",
@@ -155,7 +155,28 @@ function messagingSection() {
155
155
  "```",
156
156
  "",
157
157
  "`channel` is the reply ref. `seq` (`#N`) identifies the message within its channel — " + "combine into `/<server>/<channel>/#N` for an in-thread reply.",
158
- "`content.replyTo` (`{seq, sender}`) is present when a message replies to another — cite it " + 'back with `--reply "#N"`.'
158
+ "`content.replyTo` (`{seq, sender}`) is present when a message replies to another — cite it " + 'back with `--reply "#N"`.',
159
+ "`hint` is present when the containing surface changes how you should act. Follow it."
160
+ ].join(`
161
+ `);
162
+ }
163
+ function channelTypesSection() {
164
+ return [
165
+ "## Channel types",
166
+ "",
167
+ "`channel list` marks each top-level channel as `text` or `forum`. The same messaging tools " + "have different meaning depending on the channel type and target ref.",
168
+ "",
169
+ "### Text channels",
170
+ "",
171
+ "- A text channel is a linear conversation. Send directly to its ref with `message send --target " + "/<server>/<channel>`.",
172
+ "- A text-channel message may have a side thread at `/<server>/<channel>/#N`. Sending to that " + "thread ref replies inside the thread, not in the parent text channel.",
173
+ "",
174
+ "### Forum channels",
175
+ "",
176
+ "- A forum is a collection of posts, not one linear conversation.",
177
+ "- Each top-level message in a forum is a post title. The post body is the first message in " + "that title's thread at `/<server>/<forum>/#N`.",
178
+ "- To participate in the discussion, reply to that thread with `message send`. Inside the " + "thread, messaging works like a normal text channel.",
179
+ "- To publish your own post, first send its title as a new message in the forum, then send " + "the body as the first message in the corresponding thread."
159
180
  ].join(`
160
181
  `);
161
182
  }
@@ -289,6 +310,7 @@ function buildCliSystemPrompt(config) {
289
310
  identitySection(config),
290
311
  cliCommandsSection(),
291
312
  messagingSection(),
313
+ channelTypesSection(),
292
314
  visibilityAndReachSection(),
293
315
  criticalRulesSection(),
294
316
  executionModelSection(),
@@ -3761,6 +3783,24 @@ function formatData(data) {
3761
3783
  }
3762
3784
  return " " + parts.join(" ");
3763
3785
  }
3786
+ function recordFields(data) {
3787
+ const fields = {};
3788
+ let positional = 0;
3789
+ for (const value of data) {
3790
+ if (value instanceof Error) {
3791
+ fields.error = value.message;
3792
+ continue;
3793
+ }
3794
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
3795
+ for (const [key, entry] of Object.entries(value)) {
3796
+ fields[key] = entry;
3797
+ }
3798
+ continue;
3799
+ }
3800
+ fields[`arg${positional++}`] = value;
3801
+ }
3802
+ return fields;
3803
+ }
3764
3804
  function createLogger(options = {}) {
3765
3805
  const header = options.header ?? DEFAULT_HEADER;
3766
3806
  const minRank = LEVEL_RANK[options.level ?? envLevel() ?? "info"];
@@ -3769,10 +3809,15 @@ function createLogger(options = {}) {
3769
3809
  `));
3770
3810
  const err = options.err ?? ((line) => process.stderr.write(line + `
3771
3811
  `));
3812
+ const record = options.record;
3772
3813
  const emit = (level, message, data) => {
3773
3814
  if (LEVEL_RANK[level] < minRank)
3774
3815
  return;
3775
- const line = `${now()} ${header} ${level.toUpperCase().padEnd(5)} ${message}${formatData(data)}`;
3816
+ const time = now();
3817
+ const line = `${time} ${header} ${level.toUpperCase().padEnd(5)} ${message}${formatData(data)}`;
3818
+ try {
3819
+ record?.({ time, header, level, message, fields: recordFields(data) });
3820
+ } catch {}
3776
3821
  (level === "warn" || level === "error" ? err : out)(line);
3777
3822
  };
3778
3823
  return {
@@ -3805,6 +3850,51 @@ function nowLocalISO() {
3805
3850
  }
3806
3851
 
3807
3852
  // src/manager/managerRuntime.ts
3853
+ import { randomUUID as randomUUID4 } from "node:crypto";
3854
+ function normalizeTerminationCause(value) {
3855
+ return value === "runtime_error" || value === "killed_stalled" ? value : "other";
3856
+ }
3857
+ function normalizeAbortCause(value) {
3858
+ switch (value) {
3859
+ case "start_threw":
3860
+ case "start_rejected":
3861
+ case "send_threw":
3862
+ case "spawn_failure":
3863
+ case "handshake_timeout":
3864
+ case "reset":
3865
+ case "nap":
3866
+ case "model_switch":
3867
+ case "requested_stop":
3868
+ case "shutdown":
3869
+ case "physical_exit":
3870
+ case "terminate_stalled":
3871
+ case "force_exit":
3872
+ return value;
3873
+ default:
3874
+ return "other";
3875
+ }
3876
+ }
3877
+ function normalizeSpawnFailureReason(value) {
3878
+ switch (value) {
3879
+ case "ENOENT":
3880
+ case "handshake_timeout":
3881
+ case "pre_handshake_exit":
3882
+ case "spawn_threw":
3883
+ return value;
3884
+ default:
3885
+ return "other";
3886
+ }
3887
+ }
3888
+ function normalizeTerminationSemantics(value) {
3889
+ switch (value) {
3890
+ case "killed_stalled":
3891
+ case "idle_stop":
3892
+ case "force_exit":
3893
+ return value;
3894
+ default:
3895
+ return "other";
3896
+ }
3897
+ }
3808
3898
  var THINKING_MAX_BYTES = 4096;
3809
3899
  var STDERR_LOG_MAX_LEN = 2000;
3810
3900
  var AUDIT_ERROR_MESSAGE_MAX_LEN = 2000;
@@ -3993,6 +4083,9 @@ class AgentProcessManager {
3993
4083
  liveSessions = new Map;
3994
4084
  thinkingBuffers = new Map;
3995
4085
  activeSpawnState = new Map;
4086
+ traceProcessNonce = randomUUID4();
4087
+ nextSpawnOrdinal = 1;
4088
+ nextDaemonTurnOrdinal = 1;
3996
4089
  nonCleanEndMarker = new Map;
3997
4090
  opts;
3998
4091
  tickTimer = null;
@@ -4054,6 +4147,7 @@ class AgentProcessManager {
4054
4147
  rewakePrompt: opts.rewakePrompt,
4055
4148
  forgetSession: true,
4056
4149
  barrierType: opts.barrierType ?? "reset_session",
4150
+ abortCause: opts.barrierType === "nap" ? "nap" : "reset",
4057
4151
  opName: "reset"
4058
4152
  });
4059
4153
  }
@@ -4061,6 +4155,7 @@ class AgentProcessManager {
4061
4155
  this.register(agentId, { runtimeConfig: opts.runtimeConfig, launchId: opts.launchId });
4062
4156
  if (opts.forgetSession)
4063
4157
  this.forgetSession(agentId, opts.barrierType ?? "reset_session");
4158
+ this.abortCurrentTurn(agentId, opts.abortCause);
4064
4159
  this.markResetting(agentId);
4065
4160
  const status = this.state.agents[agentId]?.status;
4066
4161
  if (status === "idle") {
@@ -4085,6 +4180,7 @@ class AgentProcessManager {
4085
4180
  launchId: opts.launchId,
4086
4181
  rewakePrompt: opts.rewakePrompt,
4087
4182
  forgetSession: false,
4183
+ abortCause: "model_switch",
4088
4184
  opName: "model switch"
4089
4185
  });
4090
4186
  }
@@ -4098,6 +4194,7 @@ class AgentProcessManager {
4098
4194
  const session = this.sessions.get(agentId);
4099
4195
  if (!session)
4100
4196
  return;
4197
+ this.abortCurrentTurn(agentId, "requested_stop");
4101
4198
  await Promise.resolve(session.stop({ reason: "requested", forceAfterMs: SESSION_STOP_GRACE_MS }));
4102
4199
  this.sessions.delete(agentId);
4103
4200
  }
@@ -4106,7 +4203,10 @@ class AgentProcessManager {
4106
4203
  clearInterval(this.tickTimer);
4107
4204
  this.tickTimer = null;
4108
4205
  }
4109
- await Promise.all([...this.sessions.values()].map((s) => Promise.resolve(s.stop({ reason: "shutdown", forceAfterMs: SESSION_STOP_GRACE_MS }))));
4206
+ const entries = [...this.sessions.entries()];
4207
+ for (const [agentId] of entries)
4208
+ this.abortCurrentTurn(agentId, "shutdown");
4209
+ await Promise.all(entries.map(([, session]) => Promise.resolve(session.stop({ reason: "shutdown", forceAfterMs: SESSION_STOP_GRACE_MS }))));
4110
4210
  this.sessions.clear();
4111
4211
  }
4112
4212
  snapshot() {
@@ -4146,19 +4246,95 @@ class AgentProcessManager {
4146
4246
  stoppingSince: a.stoppingSince
4147
4247
  }));
4148
4248
  }
4149
- dispatch(event) {
4249
+ emitTrace(rec) {
4250
+ if (!this.opts.onFsmTransition)
4251
+ return;
4252
+ try {
4253
+ this.opts.onFsmTransition(rec);
4254
+ } catch {}
4255
+ }
4256
+ traceOwnerFor(agentId, captured) {
4257
+ if (captured)
4258
+ return captured.agentId === agentId ? captured : undefined;
4259
+ const owner = this.activeSpawnState.get(agentId);
4260
+ return owner && this.sessions.get(agentId) === owner.session ? owner : undefined;
4261
+ }
4262
+ openTurn(owner) {
4263
+ if (owner.activeSpan)
4264
+ return owner.activeSpan;
4265
+ const daemonTurnOrdinal = this.nextDaemonTurnOrdinal++;
4266
+ const span = {
4267
+ traceTurnId: `${owner.launchIdSnapshot ?? this.traceProcessNonce}:${daemonTurnOrdinal}`,
4268
+ daemonTurnOrdinal,
4269
+ spawnOrdinal: owner.spawnOrdinal,
4270
+ turnOrdinal: owner.nextTurnOrdinal++,
4271
+ launchIdSnapshot: owner.launchIdSnapshot
4272
+ };
4273
+ owner.activeSpan = span;
4274
+ const nowMs = this.now();
4275
+ this.emitTrace({
4276
+ recordKind: "turn_span",
4277
+ agentId: owner.agentId,
4278
+ event: "turn_begin",
4279
+ ...span,
4280
+ effects: [],
4281
+ nowMs,
4282
+ timeIso: new Date(nowMs).toISOString()
4283
+ });
4284
+ return span;
4285
+ }
4286
+ closeTurn(owner, expectedSpan, close) {
4287
+ if (!expectedSpan || owner.activeSpan !== expectedSpan)
4288
+ return false;
4289
+ owner.activeSpan = null;
4290
+ const nowMs = this.now();
4291
+ const base = {
4292
+ recordKind: "turn_span",
4293
+ agentId: owner.agentId,
4294
+ ...expectedSpan,
4295
+ effects: [],
4296
+ nowMs,
4297
+ timeIso: new Date(nowMs).toISOString()
4298
+ };
4299
+ if (close.event === "turn_end") {
4300
+ this.emitTrace({
4301
+ ...base,
4302
+ event: "turn_end",
4303
+ outcome: close.outcome,
4304
+ ...close.terminationCause ? { terminationCause: close.terminationCause } : {}
4305
+ });
4306
+ } else {
4307
+ this.emitTrace({
4308
+ ...base,
4309
+ event: "turn_abort",
4310
+ abortCause: normalizeAbortCause(close.abortCause)
4311
+ });
4312
+ }
4313
+ return true;
4314
+ }
4315
+ abortCurrentTurn(agentId, cause) {
4316
+ const owner = this.traceOwnerFor(agentId);
4317
+ if (owner)
4318
+ this.closeTurn(owner, owner.activeSpan, { event: "turn_abort", abortCause: cause });
4319
+ }
4320
+ dispatch(event, capturedOwner) {
4150
4321
  const before = this.deriveActivitySnapshot(this.state);
4151
4322
  const { state, effects } = reduceManager(this.state, event);
4152
4323
  this.state = state;
4324
+ const eventAgentId = event.agentId;
4325
+ const closingOwner = event.type === "turn_end" && eventAgentId ? this.traceOwnerFor(eventAgentId, capturedOwner) : undefined;
4326
+ const closingSpan = closingOwner?.activeSpan ?? null;
4153
4327
  if (this.opts.onFsmTransition) {
4154
- const nowMs = this.now();
4155
- const emit = (agentId2) => {
4156
- const a = this.state.agents[agentId2];
4328
+ const emit = (agentId) => {
4329
+ const a = this.state.agents[agentId];
4157
4330
  if (!a)
4158
4331
  return;
4159
- const myEffects = effects.filter((e) => e.agentId === agentId2).map((e) => e.type);
4160
- this.opts.onFsmTransition({
4161
- agentId: agentId2,
4332
+ const nowMs = this.now();
4333
+ const activeSpan = this.traceOwnerFor(agentId, capturedOwner)?.activeSpan ?? null;
4334
+ const myEffects = effects.filter((e) => e.agentId === agentId).map((e) => e.type);
4335
+ this.emitTrace({
4336
+ recordKind: "fsm",
4337
+ agentId,
4162
4338
  event: event.type,
4163
4339
  status: a.status,
4164
4340
  turnActive: a.turnActive,
@@ -4172,31 +4348,43 @@ class AgentProcessManager {
4172
4348
  apmPhase: a.apm.phase,
4173
4349
  effects: myEffects,
4174
4350
  nowMs,
4351
+ timeIso: new Date(nowMs).toISOString(),
4352
+ ...activeSpan ? activeSpan : {},
4175
4353
  sinceProgressMs: nowMs - a.lastProgressAt,
4176
4354
  sinceDeliverMs: a.lastDeliverAt === null ? null : nowMs - a.lastDeliverAt,
4177
4355
  sinceStoppingMs: a.stoppingSince === null ? null : nowMs - a.stoppingSince,
4178
4356
  ...event.type === "turn_end" && event.endReason === "errored" ? {
4179
4357
  endReason: "errored",
4180
- terminationCause: event.terminationCause,
4181
- errorDetail: event.errorDetail
4358
+ terminationCause: normalizeTerminationCause(event.terminationCause)
4182
4359
  } : {},
4183
4360
  ...event.type === "exit" ? {
4184
4361
  exitCode: event.exitCode ?? null,
4185
4362
  exitSignal: event.exitSignal ?? null,
4186
4363
  abnormal: event.abnormal ?? false,
4187
- ...event.spawnFailureReason != null ? { spawnFailureReason: event.spawnFailureReason } : {},
4188
- ...event.terminationSemantics != null ? { terminationSemantics: event.terminationSemantics } : {}
4364
+ ...event.spawnFailureReason != null ? {
4365
+ spawnFailureReason: normalizeSpawnFailureReason(event.spawnFailureReason)
4366
+ } : {},
4367
+ ...event.terminationSemantics != null ? {
4368
+ terminationSemantics: normalizeTerminationSemantics(event.terminationSemantics)
4369
+ } : {}
4189
4370
  } : {}
4190
4371
  });
4191
4372
  };
4192
- const agentId = event.agentId;
4193
- if (agentId) {
4194
- emit(agentId);
4373
+ if (eventAgentId) {
4374
+ emit(eventAgentId);
4195
4375
  } else if (event.type === "tick") {
4196
4376
  for (const id of Object.keys(this.state.agents))
4197
4377
  emit(id);
4198
4378
  }
4199
4379
  }
4380
+ if (closingOwner && closingSpan) {
4381
+ const errored = event.endReason === "errored";
4382
+ this.closeTurn(closingOwner, closingSpan, errored ? {
4383
+ event: "turn_end",
4384
+ outcome: "errored",
4385
+ terminationCause: normalizeTerminationCause(event.terminationCause)
4386
+ } : { event: "turn_end", outcome: "clean" });
4387
+ }
4200
4388
  for (const effect of effects)
4201
4389
  this.applyEffect(effect);
4202
4390
  if (this.opts.onAgentActivity) {
@@ -4235,15 +4423,37 @@ ${this.opts.wakePromptFooter}` : text;
4235
4423
  break;
4236
4424
  case "send": {
4237
4425
  const session = this.sessions.get(effect.agentId);
4238
- session?.send({ text: this.stampNow(this.withFooter(effect.text)), mode: effect.mode });
4426
+ const input = { text: this.stampNow(this.withFooter(effect.text)), mode: effect.mode };
4427
+ if (session) {
4428
+ const owner = this.activeSpawnState.get(effect.agentId);
4429
+ const exactOwner = owner?.session === session ? owner : undefined;
4430
+ const associatedSpan = exactOwner ? effect.mode === "idle" ? this.openTurn(exactOwner) : exactOwner.activeSpan : null;
4431
+ try {
4432
+ session.send(input);
4433
+ } catch (error) {
4434
+ if (exactOwner) {
4435
+ this.closeTurn(exactOwner, associatedSpan, {
4436
+ event: "turn_abort",
4437
+ abortCause: "send_threw"
4438
+ });
4439
+ }
4440
+ throw error;
4441
+ }
4442
+ }
4239
4443
  this.log.info("steering message sent to running agent", { agentId: effect.agentId, mode: effect.mode });
4240
4444
  break;
4241
4445
  }
4242
4446
  case "stop":
4243
4447
  case "terminate_stalled": {
4244
4448
  const session = this.sessions.get(effect.agentId);
4245
- Promise.resolve(session?.stop({ reason: effect.type, forceAfterMs: SESSION_STOP_GRACE_MS }));
4246
4449
  const spawnState = this.activeSpawnState.get(effect.agentId);
4450
+ if (effect.type === "terminate_stalled" && spawnState) {
4451
+ this.closeTurn(spawnState, spawnState.activeSpan, {
4452
+ event: "turn_abort",
4453
+ abortCause: "terminate_stalled"
4454
+ });
4455
+ }
4456
+ Promise.resolve(session?.stop({ reason: effect.type, forceAfterMs: SESSION_STOP_GRACE_MS }));
4247
4457
  if (spawnState)
4248
4458
  spawnState.suppressExitLog = true;
4249
4459
  if (effect.type === "terminate_stalled") {
@@ -4259,6 +4469,12 @@ ${this.opts.wakePromptFooter}` : text;
4259
4469
  case "force_exit": {
4260
4470
  const session = this.sessions.get(effect.agentId);
4261
4471
  const state = this.activeSpawnState.get(effect.agentId);
4472
+ if (state) {
4473
+ this.closeTurn(state, state.activeSpan, {
4474
+ event: "turn_abort",
4475
+ abortCause: "force_exit"
4476
+ });
4477
+ }
4262
4478
  if (session) {
4263
4479
  Promise.resolve(session.stop({ reason: effect.reason, forceAfterMs: SESSION_STOP_GRACE_MS })).catch(() => {});
4264
4480
  } else if (state?.pid != null) {
@@ -4333,7 +4549,23 @@ ${this.opts.wakePromptFooter}` : text;
4333
4549
  const rawLineSink = this.opts.onRuntimeRawLine;
4334
4550
  const session = this.opts.sessionFactory ? this.opts.sessionFactory({ agentId, driver, ctx }) : driver.createSession ? new SdkManagedSession(driver, ctx, this.opts.sdkDriverDepsFor(ctx)) : createChildProcessRuntimeSession(driver, ctx, rawLineSink ? { onRawStdoutLine: (line) => rawLineSink(agentId, line) } : undefined);
4335
4551
  this.sessions.set(agentId, session);
4336
- const state = { hasEstablished: false, hasReportedSpawnFailure: false, suppressExitLog: false, handshakeTimer: null, torndown: false, superseded: false, pid: null, spawnFailureReason: null, terminationSemantics: null };
4552
+ const state = {
4553
+ agentId,
4554
+ session,
4555
+ hasEstablished: false,
4556
+ hasReportedSpawnFailure: false,
4557
+ suppressExitLog: false,
4558
+ handshakeTimer: null,
4559
+ torndown: false,
4560
+ superseded: false,
4561
+ pid: null,
4562
+ spawnFailureReason: null,
4563
+ terminationSemantics: null,
4564
+ spawnOrdinal: this.nextSpawnOrdinal++,
4565
+ launchIdSnapshot: typeof ctx.launchId === "string" && ctx.launchId.length > 0 ? ctx.launchId : null,
4566
+ nextTurnOrdinal: 1,
4567
+ activeSpan: null
4568
+ };
4337
4569
  this.activeSpawnState.set(agentId, state);
4338
4570
  const clearHandshakeTimer = () => {
4339
4571
  if (state.handshakeTimer) {
@@ -4345,6 +4577,10 @@ ${this.opts.wakePromptFooter}` : text;
4345
4577
  if (state.hasEstablished || state.hasReportedSpawnFailure)
4346
4578
  return;
4347
4579
  state.hasReportedSpawnFailure = true;
4580
+ this.closeTurn(state, state.activeSpan, {
4581
+ event: "turn_abort",
4582
+ abortCause: opts?.scope === "handshake_timeout" ? "handshake_timeout" : "spawn_failure"
4583
+ });
4348
4584
  state.spawnFailureReason = reason;
4349
4585
  this.log.warn("spawn failed", { agentId, runtime: driver.id, reason });
4350
4586
  this.opts.onRuntimeSpawnFailed?.(driver.id, reason);
@@ -4359,7 +4595,7 @@ ${this.opts.wakePromptFooter}` : text;
4359
4595
  if (e?.kind === "turn_end" && driver.lifecycle.kind === "per_turn") {
4360
4596
  state.suppressExitLog = true;
4361
4597
  }
4362
- this.onRuntimeEvent(agentId, e, driver.id, state.superseded);
4598
+ this.onRuntimeEvent(agentId, e, driver.id, state);
4363
4599
  });
4364
4600
  session.on("stderr", (...args) => {
4365
4601
  const raw = typeof args[0] === "string" ? args[0] : String(args[0] ?? "");
@@ -4376,6 +4612,10 @@ ${this.opts.wakePromptFooter}` : text;
4376
4612
  if (state.torndown)
4377
4613
  return;
4378
4614
  state.torndown = true;
4615
+ this.closeTurn(state, state.activeSpan, {
4616
+ event: "turn_abort",
4617
+ abortCause: "physical_exit"
4618
+ });
4379
4619
  const info = args[0];
4380
4620
  reportSpawnFailure("pre_handshake_exit");
4381
4621
  const exitCode = typeof info?.code === "number" ? info.code : null;
@@ -4395,14 +4635,22 @@ ${this.opts.wakePromptFooter}` : text;
4395
4635
  this.activeSpawnState.delete(agentId);
4396
4636
  this.nonCleanEndMarker.delete(agentId);
4397
4637
  }
4398
- this.dispatch({ type: "exit", agentId, exitCode, exitSignal, abnormal, spawnFailureReason: state.spawnFailureReason, terminationSemantics: state.terminationSemantics });
4638
+ this.dispatch({ type: "exit", agentId, exitCode, exitSignal, abnormal, spawnFailureReason: state.spawnFailureReason, terminationSemantics: state.terminationSemantics }, state);
4399
4639
  });
4400
4640
  const stampedPrompt = this.stampNow(prompt);
4401
- Promise.resolve(session.start({ text: stampedPrompt, sessionId: ctx.config.sessionId })).then(() => {
4641
+ const startedSpan = this.openTurn(state);
4642
+ let startResult;
4643
+ try {
4644
+ startResult = Promise.resolve(session.start({ text: stampedPrompt, sessionId: ctx.config.sessionId }));
4645
+ } catch (error) {
4646
+ this.closeTurn(state, startedSpan, { event: "turn_abort", abortCause: "start_threw" });
4647
+ throw error;
4648
+ }
4649
+ startResult.then(() => {
4402
4650
  if (this.sessions.get(agentId) !== session)
4403
4651
  return;
4404
4652
  state.pid = session.pid ?? null;
4405
- this.dispatch({ type: "spawned", agentId, nowMs: this.now() });
4653
+ this.dispatch({ type: "spawned", agentId, nowMs: this.now() }, state);
4406
4654
  if (state.hasEstablished || state.hasReportedSpawnFailure)
4407
4655
  return;
4408
4656
  state.handshakeTimer = setTimeout(() => {
@@ -4411,6 +4659,10 @@ ${this.opts.wakePromptFooter}` : text;
4411
4659
  return;
4412
4660
  if (this.sessions.get(agentId) !== session)
4413
4661
  return;
4662
+ this.closeTurn(state, state.activeSpan, {
4663
+ event: "turn_abort",
4664
+ abortCause: "handshake_timeout"
4665
+ });
4414
4666
  reportSpawnFailure("handshake_timeout", {
4415
4667
  scope: "handshake_timeout",
4416
4668
  message: `No response ${Math.round(this.opts.handshakeTimeoutMs / 1000)}s after launch — the runtime may be misconfigured (e.g. an invalid model).`
@@ -4422,14 +4674,18 @@ ${this.opts.wakePromptFooter}` : text;
4422
4674
  this.liveSessions.delete(agentId);
4423
4675
  if (this.activeSpawnState.get(agentId) === state)
4424
4676
  this.activeSpawnState.delete(agentId);
4425
- this.dispatch({ type: "exit", agentId, spawnFailureReason: state.spawnFailureReason });
4677
+ this.dispatch({ type: "exit", agentId, spawnFailureReason: state.spawnFailureReason }, state);
4426
4678
  }, this.opts.handshakeTimeoutMs);
4427
4679
  }).catch((err) => {
4680
+ this.closeTurn(state, startedSpan, {
4681
+ event: "turn_abort",
4682
+ abortCause: "start_rejected"
4683
+ });
4428
4684
  const code = err?.code ?? "spawn_threw";
4429
4685
  reportSpawnFailure(String(code));
4430
4686
  if (this.sessions.get(agentId) === session)
4431
4687
  this.sessions.delete(agentId);
4432
- this.dispatch({ type: "exit", agentId, spawnFailureReason: state.spawnFailureReason });
4688
+ this.dispatch({ type: "exit", agentId, spawnFailureReason: state.spawnFailureReason }, state);
4433
4689
  });
4434
4690
  }
4435
4691
  currentModelFor(agentId) {
@@ -4471,10 +4727,12 @@ ${this.opts.wakePromptFooter}` : text;
4471
4727
  this.log.debug("audit emit failed (thinking)", { agentId, err: String(err) });
4472
4728
  }
4473
4729
  }
4474
- onRuntimeEvent(agentId, e, runtimeId, sessionSuperseded) {
4730
+ onRuntimeEvent(agentId, e, runtimeId, ownerOrSuperseded) {
4475
4731
  const ev = e;
4476
4732
  if (!ev?.kind)
4477
4733
  return;
4734
+ const owner = typeof ownerOrSuperseded === "boolean" ? undefined : ownerOrSuperseded;
4735
+ const sessionSuperseded = typeof ownerOrSuperseded === "boolean" ? ownerOrSuperseded : ownerOrSuperseded.superseded;
4478
4736
  if (ev.kind === "error" && !sessionSuperseded) {
4479
4737
  this.emitErrorAudit(agentId, "runtime", "runtime_error", ev.message ?? "Runtime error");
4480
4738
  if (this.nonCleanEndMarker.get(agentId)?.cause !== "killed_stalled") {
@@ -4516,7 +4774,7 @@ ${this.opts.wakePromptFooter}` : text;
4516
4774
  }
4517
4775
  }
4518
4776
  if (ev.kind === "session_init" && ev.sessionId) {
4519
- this.dispatch({ type: "session", agentId, sessionId: ev.sessionId });
4777
+ this.dispatch({ type: "session", agentId, sessionId: ev.sessionId }, owner);
4520
4778
  this.liveSessions.set(agentId, ev.sessionId);
4521
4779
  this.opts.timeline?.setSession(agentId, ev.sessionId);
4522
4780
  this.opts.onAgentSession?.({
@@ -4530,9 +4788,9 @@ ${this.opts.wakePromptFooter}` : text;
4530
4788
  this.opts.timeline?.appendResponseToLatest(agentId, ev.text);
4531
4789
  }
4532
4790
  if (ev.kind !== "internal_progress" && ev.kind !== "error") {
4533
- this.dispatch({ type: "progress", agentId, nowMs: this.now() });
4791
+ this.dispatch({ type: "progress", agentId, nowMs: this.now() }, owner);
4534
4792
  }
4535
- this.dispatch({ type: "runtime_signal", agentId, kind: ev.kind, nowMs: this.now() });
4793
+ this.dispatch({ type: "runtime_signal", agentId, kind: ev.kind, nowMs: this.now() }, owner);
4536
4794
  if (ev.kind === "turn_end") {
4537
4795
  this.logSessionEnded(agentId, "turn_end");
4538
4796
  const marker = this.nonCleanEndMarker.get(agentId);
@@ -4544,7 +4802,7 @@ ${this.opts.wakePromptFooter}` : text;
4544
4802
  endReason: "errored",
4545
4803
  terminationCause: marker.cause,
4546
4804
  errorDetail: marker.detail
4547
- } : { type: "turn_end", agentId, nowMs: this.now() });
4805
+ } : { type: "turn_end", agentId, nowMs: this.now() }, owner);
4548
4806
  }
4549
4807
  }
4550
4808
  }
@@ -5152,21 +5410,50 @@ function joinPath(basePath, reqUrl) {
5152
5410
  }
5153
5411
  // src/daemon/createDaemon.ts
5154
5412
  import { homedir as homedir3 } from "os";
5155
- import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync6 } from "node:fs";
5413
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync6 } from "node:fs";
5156
5414
 
5157
5415
  // src/util/rotatingFileSink.ts
5158
- import { appendFileSync, chmodSync, statSync, renameSync, existsSync as existsSync5 } from "node:fs";
5416
+ import {
5417
+ appendFileSync,
5418
+ chmodSync,
5419
+ closeSync,
5420
+ constants,
5421
+ existsSync as existsSync5,
5422
+ fstatSync,
5423
+ lstatSync as lstatSync2,
5424
+ openSync,
5425
+ renameSync,
5426
+ statSync,
5427
+ unlinkSync as unlinkSync3
5428
+ } from "node:fs";
5159
5429
  function createRotatingFileSink(path8, maxBytes, opts = {}) {
5160
5430
  const report = (operation, error) => {
5161
5431
  try {
5162
5432
  opts.onError?.({ operation, error });
5163
5433
  } catch {}
5164
5434
  };
5165
- const secureActive = () => {
5166
- if (opts.mode === undefined || !existsSync5(path8))
5435
+ const secureGeneration = (filePath) => {
5436
+ if (!existsSync5(filePath))
5167
5437
  return true;
5168
5438
  try {
5169
- chmodSync(path8, opts.mode);
5439
+ const stat = lstatSync2(filePath);
5440
+ if (!stat.isFile()) {
5441
+ if (opts.mode === undefined && !opts.hardMaxBytes)
5442
+ return true;
5443
+ report("unsafe_generation", new Error("log generation is not a regular file"));
5444
+ return false;
5445
+ }
5446
+ if (opts.mode !== undefined)
5447
+ chmodSync(filePath, opts.mode);
5448
+ if (opts.hardMaxBytes && maxBytes > 0 && stat.size > maxBytes) {
5449
+ try {
5450
+ unlinkSync3(filePath);
5451
+ } catch (error) {
5452
+ report("oversize_generation", error);
5453
+ return false;
5454
+ }
5455
+ report("oversize_generation", new Error(`removed generation larger than ${maxBytes} bytes`));
5456
+ }
5170
5457
  return true;
5171
5458
  } catch (error) {
5172
5459
  report("chmod", error);
@@ -5176,6 +5463,8 @@ function createRotatingFileSink(path8, maxBytes, opts = {}) {
5176
5463
  const rotate = () => {
5177
5464
  try {
5178
5465
  renameSync(path8, `${path8}.1`);
5466
+ if (opts.mode !== undefined)
5467
+ chmodSync(`${path8}.1`, opts.mode);
5179
5468
  return true;
5180
5469
  } catch (error) {
5181
5470
  report("rotate", error);
@@ -5190,31 +5479,86 @@ function createRotatingFileSink(path8, maxBytes, opts = {}) {
5190
5479
  return null;
5191
5480
  }
5192
5481
  };
5193
- return {
5482
+ const sink = {
5483
+ secure() {
5484
+ return secureGeneration(`${path8}.1`) && secureGeneration(path8);
5485
+ },
5194
5486
  write(line) {
5195
5487
  try {
5196
- if (!secureActive())
5488
+ if (!sink.secure())
5197
5489
  return;
5198
5490
  const serialized = line + `
5199
5491
  `;
5492
+ const serializedBytes = Buffer.byteLength(serialized, "utf8");
5493
+ if (opts.hardMaxBytes && maxBytes > 0 && serializedBytes > maxBytes) {
5494
+ report("oversize", new Error(`record exceeds ${maxBytes} bytes`));
5495
+ return;
5496
+ }
5200
5497
  const measuredBytes = currentSize();
5201
5498
  if (measuredBytes === null && opts.hardMaxBytes)
5202
5499
  return;
5203
5500
  const currentBytes = measuredBytes ?? 0;
5204
- const shouldRotate = maxBytes > 0 && (opts.hardMaxBytes ? currentBytes > 0 && currentBytes + Buffer.byteLength(serialized, "utf8") > maxBytes : currentBytes >= maxBytes);
5501
+ const shouldRotate = maxBytes > 0 && (opts.hardMaxBytes ? currentBytes > 0 && currentBytes + serializedBytes > maxBytes : currentBytes >= maxBytes);
5205
5502
  if (shouldRotate && !rotate() && opts.hardMaxBytes)
5206
5503
  return;
5207
5504
  appendFileSync(path8, serialized, opts.mode === undefined ? undefined : { mode: opts.mode });
5208
5505
  } catch (error) {
5209
5506
  report("append", error);
5210
5507
  }
5508
+ },
5509
+ openSnapshot() {
5510
+ const files = [];
5511
+ try {
5512
+ for (const candidate of [`${path8}.1`, path8]) {
5513
+ if (!existsSync5(candidate))
5514
+ continue;
5515
+ if (!secureGeneration(candidate))
5516
+ continue;
5517
+ const noFollow = "O_NOFOLLOW" in constants ? constants.O_NOFOLLOW : 0;
5518
+ const fd = openSync(candidate, constants.O_RDONLY | noFollow);
5519
+ try {
5520
+ const stat = fstatSync(fd);
5521
+ if (!stat.isFile())
5522
+ throw new Error("snapshot source is not a regular file");
5523
+ files.push({ path: candidate, fd, size: stat.size });
5524
+ } catch (error) {
5525
+ closeSync(fd);
5526
+ throw error;
5527
+ }
5528
+ }
5529
+ } catch (error) {
5530
+ for (const file of files) {
5531
+ try {
5532
+ closeSync(file.fd);
5533
+ } catch {}
5534
+ }
5535
+ report("snapshot", error);
5536
+ return { files: [], close: () => {} };
5537
+ }
5538
+ let closed = false;
5539
+ return {
5540
+ files,
5541
+ close() {
5542
+ if (closed)
5543
+ return;
5544
+ closed = true;
5545
+ for (const file of files) {
5546
+ try {
5547
+ closeSync(file.fd);
5548
+ } catch {}
5549
+ }
5550
+ }
5551
+ };
5211
5552
  }
5212
5553
  };
5554
+ return sink;
5213
5555
  }
5214
5556
 
5215
5557
  // src/util/traceSampler.ts
5216
5558
  var SAMPLEABLE_EVENTS = new Set(["tick", "progress", "runtime_signal"]);
5559
+ var SACRED_TURN_SPAN_EVENTS = new Set(["turn_begin", "turn_end", "turn_abort"]);
5217
5560
  var DEFAULT_TRACE_SAMPLE_MS = 30000;
5561
+ var DEFAULT_TRACE_FILE_MAX_BYTES = 32 * 1024 * 1024;
5218
5562
  function newAgentState() {
5219
5563
  return {
5220
5564
  lastTickKey: null,
@@ -5268,6 +5612,11 @@ function createTraceSampler(emit, throttleMs = DEFAULT_TRACE_SAMPLE_MS) {
5268
5612
  }
5269
5613
  const s = stateFor(agentId);
5270
5614
  const event = rec.event;
5615
+ if (rec.recordKind === "turn_span" && SACRED_TURN_SPAN_EVENTS.has(String(event))) {
5616
+ flushPending(s);
5617
+ emit(rec);
5618
+ return;
5619
+ }
5271
5620
  if (!SAMPLEABLE_EVENTS.has(event) || hasEffects(rec)) {
5272
5621
  flushPending(s);
5273
5622
  if (event === "tick") {
@@ -19610,158 +19959,2388 @@ function formatHandle(name, discriminator) {
19610
19959
  return `${name}#${discriminator}`;
19611
19960
  }
19612
19961
 
19613
- // ../shared/src/community-cli-contract.ts
19614
- var HostCommandSchema = exports_external.discriminatedUnion("type", [
19615
- exports_external.object({
19616
- type: exports_external.literal("agent:wake"),
19617
- agentId: exports_external.string().min(1),
19618
- config: exports_external.unknown(),
19619
- sessionId: exports_external.string().optional(),
19620
- launchId: exports_external.string().min(1),
19621
- unreadNotice: exports_external.unknown()
19622
- }),
19623
- exports_external.object({
19624
- type: exports_external.literal("agent:stop"),
19625
- agentId: exports_external.string().min(1)
19626
- }),
19627
- exports_external.object({
19628
- type: exports_external.literal("agent:reset"),
19629
- agentId: exports_external.string().min(1),
19630
- config: exports_external.unknown(),
19631
- launchId: exports_external.string().min(1)
19632
- }),
19633
- exports_external.object({
19634
- type: exports_external.literal("agent:nap"),
19635
- agentId: exports_external.string().min(1),
19636
- config: exports_external.unknown(),
19637
- launchId: exports_external.string().min(1),
19638
- handoff: exports_external.string().min(1)
19639
- }),
19640
- exports_external.object({
19641
- type: exports_external.literal("agent:model_switch"),
19642
- agentId: exports_external.string().min(1),
19643
- config: exports_external.unknown(),
19644
- launchId: exports_external.string().min(1)
19645
- }),
19646
- exports_external.object({
19647
- type: exports_external.literal("machine:reset_all"),
19648
- resets: exports_external.array(exports_external.object({
19649
- agentId: exports_external.string().min(1),
19650
- config: exports_external.unknown(),
19651
- launchId: exports_external.string().min(1)
19652
- }))
19653
- }),
19654
- exports_external.object({
19655
- type: exports_external.literal("bot:added"),
19656
- botId: exports_external.string().min(1),
19657
- name: exports_external.string().optional(),
19658
- discriminator: exports_external.string().optional(),
19659
- description: exports_external.string().optional(),
19660
- ownerName: exports_external.string().optional(),
19661
- ownerDiscriminator: exports_external.string().optional()
19662
- }),
19663
- exports_external.object({
19664
- type: exports_external.literal("bot:updated"),
19665
- botId: exports_external.string().min(1),
19666
- name: exports_external.string().optional(),
19667
- discriminator: exports_external.string().optional(),
19668
- description: exports_external.string().optional(),
19669
- ownerName: exports_external.string().optional(),
19670
- ownerDiscriminator: exports_external.string().optional()
19671
- }),
19672
- exports_external.object({
19673
- type: exports_external.literal("bot:removed"),
19674
- botId: exports_external.string().min(1)
19675
- })
19676
- ]);
19677
- // src/server/wsControlChannel.ts
19678
- var DEFAULT_PING_INTERVAL_MS = 15000;
19679
- var DEFAULT_PONG_TIMEOUT_MS = 30000;
19680
- var DEFAULT_RECONNECT_BASE_MS = 500;
19681
- var DEFAULT_RECONNECT_MAX_MS = 30000;
19682
- function describeErr(err) {
19683
- return err instanceof Error ? err.message : String(err);
19684
- }
19685
-
19686
- class WsControlChannel {
19687
- opts;
19688
- statusValue = "idle";
19689
- commandCbs = [];
19690
- resyncHooks = [];
19691
- ws = null;
19692
- attempt = 0;
19693
- closedByUser = false;
19694
- authRejected = false;
19695
- pingTimer = null;
19696
- pongDeadline = 0;
19697
- resyncProvider = null;
19698
- log;
19699
- constructor(opts) {
19700
- this.opts = opts;
19701
- this.log = opts.logger ?? createLogger({ header: "@alook/daemon:ws" });
19702
- }
19703
- get status() {
19704
- return this.statusValue;
19705
- }
19706
- connect() {
19707
- this.closedByUser = false;
19708
- this.authRejected = false;
19709
- this.openSocket();
19710
- }
19711
- close() {
19712
- this.closedByUser = true;
19713
- this.clearHeartbeat();
19714
- this.ws?.close();
19715
- this.ws = null;
19716
- this.statusValue = "closed";
19962
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/entity.js
19963
+ var entityKind = Symbol.for("drizzle:entityKind");
19964
+ var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
19965
+ function is(value, type) {
19966
+ if (!value || typeof value !== "object") {
19967
+ return false;
19717
19968
  }
19718
- onCommand(cb) {
19719
- this.commandCbs.push(cb);
19969
+ if (value instanceof type) {
19970
+ return true;
19720
19971
  }
19721
- onResync(provider) {
19722
- this.resyncProvider = provider;
19972
+ if (!Object.prototype.hasOwnProperty.call(type, entityKind)) {
19973
+ throw new Error(`Class "${type.name ?? "<unknown>"}" doesn't look like a Drizzle entity. If this is incorrect and the class is provided by Drizzle, please report this as a bug.`);
19723
19974
  }
19724
- onOpen(hook) {
19725
- this.resyncHooks.push(hook);
19975
+ let cls = Object.getPrototypeOf(value).constructor;
19976
+ if (cls) {
19977
+ while (cls) {
19978
+ if (entityKind in cls && cls[entityKind] === type[entityKind]) {
19979
+ return true;
19980
+ }
19981
+ cls = Object.getPrototypeOf(cls);
19982
+ }
19726
19983
  }
19727
- async reportReady(ready) {
19728
- this.sendFrame({ type: "ready", ...ready });
19984
+ return false;
19985
+ }
19986
+
19987
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/column.js
19988
+ class Column {
19989
+ constructor(table, config2) {
19990
+ this.table = table;
19991
+ this.config = config2;
19992
+ this.name = config2.name;
19993
+ this.keyAsName = config2.keyAsName;
19994
+ this.notNull = config2.notNull;
19995
+ this.default = config2.default;
19996
+ this.defaultFn = config2.defaultFn;
19997
+ this.onUpdateFn = config2.onUpdateFn;
19998
+ this.hasDefault = config2.hasDefault;
19999
+ this.primary = config2.primaryKey;
20000
+ this.isUnique = config2.isUnique;
20001
+ this.uniqueName = config2.uniqueName;
20002
+ this.uniqueType = config2.uniqueType;
20003
+ this.dataType = config2.dataType;
20004
+ this.columnType = config2.columnType;
20005
+ this.generated = config2.generated;
20006
+ this.generatedIdentity = config2.generatedIdentity;
20007
+ }
20008
+ static [entityKind] = "Column";
20009
+ name;
20010
+ keyAsName;
20011
+ primary;
20012
+ notNull;
20013
+ default;
20014
+ defaultFn;
20015
+ onUpdateFn;
20016
+ hasDefault;
20017
+ isUnique;
20018
+ uniqueName;
20019
+ uniqueType;
20020
+ dataType;
20021
+ columnType;
20022
+ enumValues = undefined;
20023
+ generated = undefined;
20024
+ generatedIdentity = undefined;
20025
+ config;
20026
+ mapFromDriverValue(value) {
20027
+ return value;
19729
20028
  }
19730
- sendReady(ready) {
19731
- this.sendFrame({ type: "ready", ...ready });
20029
+ mapToDriverValue(value) {
20030
+ return value;
19732
20031
  }
19733
- async reportAgentSession(info) {
19734
- this.sendFrame({ type: "agent_session", ...info });
20032
+ shouldDisableInsert() {
20033
+ return this.config.generated !== undefined && this.config.generated.type !== "byDefault";
19735
20034
  }
19736
- async reportAgentActivity(info) {
19737
- this.sendFrame({ type: "agent_activity", ...info });
20035
+ }
20036
+
20037
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/column-builder.js
20038
+ class ColumnBuilder {
20039
+ static [entityKind] = "ColumnBuilder";
20040
+ config;
20041
+ constructor(name, dataType, columnType) {
20042
+ this.config = {
20043
+ name,
20044
+ keyAsName: name === "",
20045
+ notNull: false,
20046
+ default: undefined,
20047
+ hasDefault: false,
20048
+ primaryKey: false,
20049
+ isUnique: false,
20050
+ uniqueName: undefined,
20051
+ uniqueType: undefined,
20052
+ dataType,
20053
+ columnType,
20054
+ generated: undefined
20055
+ };
19738
20056
  }
19739
- reportAgentTyping(info) {
19740
- this.sendFrame({ type: "agent_typing", ...info });
20057
+ $type() {
20058
+ return this;
19741
20059
  }
19742
- reportAgentTypingStop(info) {
19743
- this.sendFrame({ type: "agent_typing_stop", ...info });
20060
+ notNull() {
20061
+ this.config.notNull = true;
20062
+ return this;
19744
20063
  }
19745
- async reportBotAuditEvent(frame) {
19746
- this.sendFrame(frame);
20064
+ default(value) {
20065
+ this.config.default = value;
20066
+ this.config.hasDefault = true;
20067
+ return this;
19747
20068
  }
19748
- async reportWakeAck(info) {
19749
- this.sendFrame({ type: "agent_wake_ack", ...info });
20069
+ $defaultFn(fn) {
20070
+ this.config.defaultFn = fn;
20071
+ this.config.hasDefault = true;
20072
+ return this;
19750
20073
  }
19751
- async reportStoppedAck(info) {
19752
- this.sendFrame({ type: "agent_stopped_ack", ...info });
20074
+ $default = this.$defaultFn;
20075
+ $onUpdateFn(fn) {
20076
+ this.config.onUpdateFn = fn;
20077
+ this.config.hasDefault = true;
20078
+ return this;
19753
20079
  }
19754
- async reportSessionError(frame) {
19755
- this.sendFrame(frame);
20080
+ $onUpdate = this.$onUpdateFn;
20081
+ primaryKey() {
20082
+ this.config.primaryKey = true;
20083
+ this.config.notNull = true;
20084
+ return this;
19756
20085
  }
19757
- sendFrame(frame) {
19758
- if (this.statusValue !== "open" || !this.ws) {
19759
- this.log.debug("frame dropped — socket not open", { type: frame.type });
20086
+ setName(name) {
20087
+ if (this.config.name !== "")
19760
20088
  return;
19761
- }
19762
- this.ws.send(JSON.stringify(frame));
20089
+ this.config.name = name;
19763
20090
  }
19764
- resyncOnConnect() {
20091
+ }
20092
+
20093
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/table.utils.js
20094
+ var TableName = Symbol.for("drizzle:Name");
20095
+
20096
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/tracing-utils.js
20097
+ function iife(fn, ...args) {
20098
+ return fn(...args);
20099
+ }
20100
+
20101
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/pg-core/unique-constraint.js
20102
+ function uniqueKeyName(table, columns) {
20103
+ return `${table[TableName]}_${columns.join("_")}_unique`;
20104
+ }
20105
+
20106
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/pg-core/columns/common.js
20107
+ class PgColumn extends Column {
20108
+ constructor(table, config2) {
20109
+ if (!config2.uniqueName) {
20110
+ config2.uniqueName = uniqueKeyName(table, [config2.name]);
20111
+ }
20112
+ super(table, config2);
20113
+ this.table = table;
20114
+ }
20115
+ static [entityKind] = "PgColumn";
20116
+ }
20117
+
20118
+ class ExtraConfigColumn extends PgColumn {
20119
+ static [entityKind] = "ExtraConfigColumn";
20120
+ getSQLType() {
20121
+ return this.getSQLType();
20122
+ }
20123
+ indexConfig = {
20124
+ order: this.config.order ?? "asc",
20125
+ nulls: this.config.nulls ?? "last",
20126
+ opClass: this.config.opClass
20127
+ };
20128
+ defaultConfig = {
20129
+ order: "asc",
20130
+ nulls: "last",
20131
+ opClass: undefined
20132
+ };
20133
+ asc() {
20134
+ this.indexConfig.order = "asc";
20135
+ return this;
20136
+ }
20137
+ desc() {
20138
+ this.indexConfig.order = "desc";
20139
+ return this;
20140
+ }
20141
+ nullsFirst() {
20142
+ this.indexConfig.nulls = "first";
20143
+ return this;
20144
+ }
20145
+ nullsLast() {
20146
+ this.indexConfig.nulls = "last";
20147
+ return this;
20148
+ }
20149
+ op(opClass) {
20150
+ this.indexConfig.opClass = opClass;
20151
+ return this;
20152
+ }
20153
+ }
20154
+
20155
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/pg-core/columns/enum.js
20156
+ class PgEnumObjectColumn extends PgColumn {
20157
+ static [entityKind] = "PgEnumObjectColumn";
20158
+ enum;
20159
+ enumValues = this.config.enum.enumValues;
20160
+ constructor(table, config2) {
20161
+ super(table, config2);
20162
+ this.enum = config2.enum;
20163
+ }
20164
+ getSQLType() {
20165
+ return this.enum.enumName;
20166
+ }
20167
+ }
20168
+ var isPgEnumSym = Symbol.for("drizzle:isPgEnum");
20169
+ function isPgEnum(obj) {
20170
+ return !!obj && typeof obj === "function" && isPgEnumSym in obj && obj[isPgEnumSym] === true;
20171
+ }
20172
+ class PgEnumColumn extends PgColumn {
20173
+ static [entityKind] = "PgEnumColumn";
20174
+ enum = this.config.enum;
20175
+ enumValues = this.config.enum.enumValues;
20176
+ constructor(table, config2) {
20177
+ super(table, config2);
20178
+ this.enum = config2.enum;
20179
+ }
20180
+ getSQLType() {
20181
+ return this.enum.enumName;
20182
+ }
20183
+ }
20184
+
20185
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/subquery.js
20186
+ class Subquery {
20187
+ static [entityKind] = "Subquery";
20188
+ constructor(sql, fields, alias, isWith = false, usedTables = []) {
20189
+ this._ = {
20190
+ brand: "Subquery",
20191
+ sql,
20192
+ selectedFields: fields,
20193
+ alias,
20194
+ isWith,
20195
+ usedTables
20196
+ };
20197
+ }
20198
+ }
20199
+
20200
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/version.js
20201
+ var version2 = "0.45.2";
20202
+
20203
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/tracing.js
20204
+ var otel;
20205
+ var rawTracer;
20206
+ var tracer = {
20207
+ startActiveSpan(name, fn) {
20208
+ if (!otel) {
20209
+ return fn();
20210
+ }
20211
+ if (!rawTracer) {
20212
+ rawTracer = otel.trace.getTracer("drizzle-orm", version2);
20213
+ }
20214
+ return iife((otel2, rawTracer2) => rawTracer2.startActiveSpan(name, (span) => {
20215
+ try {
20216
+ return fn(span);
20217
+ } catch (e) {
20218
+ span.setStatus({
20219
+ code: otel2.SpanStatusCode.ERROR,
20220
+ message: e instanceof Error ? e.message : "Unknown error"
20221
+ });
20222
+ throw e;
20223
+ } finally {
20224
+ span.end();
20225
+ }
20226
+ }), otel, rawTracer);
20227
+ }
20228
+ };
20229
+
20230
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/view-common.js
20231
+ var ViewBaseConfig = Symbol.for("drizzle:ViewBaseConfig");
20232
+
20233
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/table.js
20234
+ var Schema = Symbol.for("drizzle:Schema");
20235
+ var Columns = Symbol.for("drizzle:Columns");
20236
+ var ExtraConfigColumns = Symbol.for("drizzle:ExtraConfigColumns");
20237
+ var OriginalName = Symbol.for("drizzle:OriginalName");
20238
+ var BaseName = Symbol.for("drizzle:BaseName");
20239
+ var IsAlias = Symbol.for("drizzle:IsAlias");
20240
+ var ExtraConfigBuilder = Symbol.for("drizzle:ExtraConfigBuilder");
20241
+ var IsDrizzleTable = Symbol.for("drizzle:IsDrizzleTable");
20242
+
20243
+ class Table {
20244
+ static [entityKind] = "Table";
20245
+ static Symbol = {
20246
+ Name: TableName,
20247
+ Schema,
20248
+ OriginalName,
20249
+ Columns,
20250
+ ExtraConfigColumns,
20251
+ BaseName,
20252
+ IsAlias,
20253
+ ExtraConfigBuilder
20254
+ };
20255
+ [TableName];
20256
+ [OriginalName];
20257
+ [Schema];
20258
+ [Columns];
20259
+ [ExtraConfigColumns];
20260
+ [BaseName];
20261
+ [IsAlias] = false;
20262
+ [IsDrizzleTable] = true;
20263
+ [ExtraConfigBuilder] = undefined;
20264
+ constructor(name, schema, baseName) {
20265
+ this[TableName] = this[OriginalName] = name;
20266
+ this[Schema] = schema;
20267
+ this[BaseName] = baseName;
20268
+ }
20269
+ }
20270
+
20271
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sql/sql.js
20272
+ function isSQLWrapper(value) {
20273
+ return value !== null && value !== undefined && typeof value.getSQL === "function";
20274
+ }
20275
+ function mergeQueries(queries) {
20276
+ const result = { sql: "", params: [] };
20277
+ for (const query of queries) {
20278
+ result.sql += query.sql;
20279
+ result.params.push(...query.params);
20280
+ if (query.typings?.length) {
20281
+ if (!result.typings) {
20282
+ result.typings = [];
20283
+ }
20284
+ result.typings.push(...query.typings);
20285
+ }
20286
+ }
20287
+ return result;
20288
+ }
20289
+
20290
+ class StringChunk {
20291
+ static [entityKind] = "StringChunk";
20292
+ value;
20293
+ constructor(value) {
20294
+ this.value = Array.isArray(value) ? value : [value];
20295
+ }
20296
+ getSQL() {
20297
+ return new SQL([this]);
20298
+ }
20299
+ }
20300
+
20301
+ class SQL {
20302
+ constructor(queryChunks) {
20303
+ this.queryChunks = queryChunks;
20304
+ for (const chunk of queryChunks) {
20305
+ if (is(chunk, Table)) {
20306
+ const schemaName = chunk[Table.Symbol.Schema];
20307
+ this.usedTables.push(schemaName === undefined ? chunk[Table.Symbol.Name] : schemaName + "." + chunk[Table.Symbol.Name]);
20308
+ }
20309
+ }
20310
+ }
20311
+ static [entityKind] = "SQL";
20312
+ decoder = noopDecoder;
20313
+ shouldInlineParams = false;
20314
+ usedTables = [];
20315
+ append(query) {
20316
+ this.queryChunks.push(...query.queryChunks);
20317
+ return this;
20318
+ }
20319
+ toQuery(config2) {
20320
+ return tracer.startActiveSpan("drizzle.buildSQL", (span) => {
20321
+ const query = this.buildQueryFromSourceParams(this.queryChunks, config2);
20322
+ span?.setAttributes({
20323
+ "drizzle.query.text": query.sql,
20324
+ "drizzle.query.params": JSON.stringify(query.params)
20325
+ });
20326
+ return query;
20327
+ });
20328
+ }
20329
+ buildQueryFromSourceParams(chunks, _config) {
20330
+ const config2 = Object.assign({}, _config, {
20331
+ inlineParams: _config.inlineParams || this.shouldInlineParams,
20332
+ paramStartIndex: _config.paramStartIndex || { value: 0 }
20333
+ });
20334
+ const {
20335
+ casing,
20336
+ escapeName,
20337
+ escapeParam,
20338
+ prepareTyping,
20339
+ inlineParams,
20340
+ paramStartIndex
20341
+ } = config2;
20342
+ return mergeQueries(chunks.map((chunk) => {
20343
+ if (is(chunk, StringChunk)) {
20344
+ return { sql: chunk.value.join(""), params: [] };
20345
+ }
20346
+ if (is(chunk, Name)) {
20347
+ return { sql: escapeName(chunk.value), params: [] };
20348
+ }
20349
+ if (chunk === undefined) {
20350
+ return { sql: "", params: [] };
20351
+ }
20352
+ if (Array.isArray(chunk)) {
20353
+ const result = [new StringChunk("(")];
20354
+ for (const [i, p] of chunk.entries()) {
20355
+ result.push(p);
20356
+ if (i < chunk.length - 1) {
20357
+ result.push(new StringChunk(", "));
20358
+ }
20359
+ }
20360
+ result.push(new StringChunk(")"));
20361
+ return this.buildQueryFromSourceParams(result, config2);
20362
+ }
20363
+ if (is(chunk, SQL)) {
20364
+ return this.buildQueryFromSourceParams(chunk.queryChunks, {
20365
+ ...config2,
20366
+ inlineParams: inlineParams || chunk.shouldInlineParams
20367
+ });
20368
+ }
20369
+ if (is(chunk, Table)) {
20370
+ const schemaName = chunk[Table.Symbol.Schema];
20371
+ const tableName = chunk[Table.Symbol.Name];
20372
+ return {
20373
+ sql: schemaName === undefined || chunk[IsAlias] ? escapeName(tableName) : escapeName(schemaName) + "." + escapeName(tableName),
20374
+ params: []
20375
+ };
20376
+ }
20377
+ if (is(chunk, Column)) {
20378
+ const columnName = casing.getColumnCasing(chunk);
20379
+ if (_config.invokeSource === "indexes") {
20380
+ return { sql: escapeName(columnName), params: [] };
20381
+ }
20382
+ const schemaName = chunk.table[Table.Symbol.Schema];
20383
+ return {
20384
+ sql: chunk.table[IsAlias] || schemaName === undefined ? escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName) : escapeName(schemaName) + "." + escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName),
20385
+ params: []
20386
+ };
20387
+ }
20388
+ if (is(chunk, View)) {
20389
+ const schemaName = chunk[ViewBaseConfig].schema;
20390
+ const viewName = chunk[ViewBaseConfig].name;
20391
+ return {
20392
+ sql: schemaName === undefined || chunk[ViewBaseConfig].isAlias ? escapeName(viewName) : escapeName(schemaName) + "." + escapeName(viewName),
20393
+ params: []
20394
+ };
20395
+ }
20396
+ if (is(chunk, Param)) {
20397
+ if (is(chunk.value, Placeholder)) {
20398
+ return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
20399
+ }
20400
+ const mappedValue = chunk.value === null ? null : chunk.encoder.mapToDriverValue(chunk.value);
20401
+ if (is(mappedValue, SQL)) {
20402
+ return this.buildQueryFromSourceParams([mappedValue], config2);
20403
+ }
20404
+ if (inlineParams) {
20405
+ return { sql: this.mapInlineParam(mappedValue, config2), params: [] };
20406
+ }
20407
+ let typings = ["none"];
20408
+ if (prepareTyping) {
20409
+ typings = [prepareTyping(chunk.encoder)];
20410
+ }
20411
+ return { sql: escapeParam(paramStartIndex.value++, mappedValue), params: [mappedValue], typings };
20412
+ }
20413
+ if (is(chunk, Placeholder)) {
20414
+ return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
20415
+ }
20416
+ if (is(chunk, SQL.Aliased) && chunk.fieldAlias !== undefined) {
20417
+ return { sql: escapeName(chunk.fieldAlias), params: [] };
20418
+ }
20419
+ if (is(chunk, Subquery)) {
20420
+ if (chunk._.isWith) {
20421
+ return { sql: escapeName(chunk._.alias), params: [] };
20422
+ }
20423
+ return this.buildQueryFromSourceParams([
20424
+ new StringChunk("("),
20425
+ chunk._.sql,
20426
+ new StringChunk(") "),
20427
+ new Name(chunk._.alias)
20428
+ ], config2);
20429
+ }
20430
+ if (isPgEnum(chunk)) {
20431
+ if (chunk.schema) {
20432
+ return { sql: escapeName(chunk.schema) + "." + escapeName(chunk.enumName), params: [] };
20433
+ }
20434
+ return { sql: escapeName(chunk.enumName), params: [] };
20435
+ }
20436
+ if (isSQLWrapper(chunk)) {
20437
+ if (chunk.shouldOmitSQLParens?.()) {
20438
+ return this.buildQueryFromSourceParams([chunk.getSQL()], config2);
20439
+ }
20440
+ return this.buildQueryFromSourceParams([
20441
+ new StringChunk("("),
20442
+ chunk.getSQL(),
20443
+ new StringChunk(")")
20444
+ ], config2);
20445
+ }
20446
+ if (inlineParams) {
20447
+ return { sql: this.mapInlineParam(chunk, config2), params: [] };
20448
+ }
20449
+ return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
20450
+ }));
20451
+ }
20452
+ mapInlineParam(chunk, { escapeString }) {
20453
+ if (chunk === null) {
20454
+ return "null";
20455
+ }
20456
+ if (typeof chunk === "number" || typeof chunk === "boolean") {
20457
+ return chunk.toString();
20458
+ }
20459
+ if (typeof chunk === "string") {
20460
+ return escapeString(chunk);
20461
+ }
20462
+ if (typeof chunk === "object") {
20463
+ const mappedValueAsString = chunk.toString();
20464
+ if (mappedValueAsString === "[object Object]") {
20465
+ return escapeString(JSON.stringify(chunk));
20466
+ }
20467
+ return escapeString(mappedValueAsString);
20468
+ }
20469
+ throw new Error("Unexpected param value: " + chunk);
20470
+ }
20471
+ getSQL() {
20472
+ return this;
20473
+ }
20474
+ as(alias) {
20475
+ if (alias === undefined) {
20476
+ return this;
20477
+ }
20478
+ return new SQL.Aliased(this, alias);
20479
+ }
20480
+ mapWith(decoder) {
20481
+ this.decoder = typeof decoder === "function" ? { mapFromDriverValue: decoder } : decoder;
20482
+ return this;
20483
+ }
20484
+ inlineParams() {
20485
+ this.shouldInlineParams = true;
20486
+ return this;
20487
+ }
20488
+ if(condition) {
20489
+ return condition ? this : undefined;
20490
+ }
20491
+ }
20492
+
20493
+ class Name {
20494
+ constructor(value) {
20495
+ this.value = value;
20496
+ }
20497
+ static [entityKind] = "Name";
20498
+ brand;
20499
+ getSQL() {
20500
+ return new SQL([this]);
20501
+ }
20502
+ }
20503
+ var noopDecoder = {
20504
+ mapFromDriverValue: (value) => value
20505
+ };
20506
+ var noopEncoder = {
20507
+ mapToDriverValue: (value) => value
20508
+ };
20509
+ var noopMapper = {
20510
+ ...noopDecoder,
20511
+ ...noopEncoder
20512
+ };
20513
+
20514
+ class Param {
20515
+ constructor(value, encoder = noopEncoder) {
20516
+ this.value = value;
20517
+ this.encoder = encoder;
20518
+ }
20519
+ static [entityKind] = "Param";
20520
+ brand;
20521
+ getSQL() {
20522
+ return new SQL([this]);
20523
+ }
20524
+ }
20525
+ function sql(strings, ...params) {
20526
+ const queryChunks = [];
20527
+ if (params.length > 0 || strings.length > 0 && strings[0] !== "") {
20528
+ queryChunks.push(new StringChunk(strings[0]));
20529
+ }
20530
+ for (const [paramIndex, param2] of params.entries()) {
20531
+ queryChunks.push(param2, new StringChunk(strings[paramIndex + 1]));
20532
+ }
20533
+ return new SQL(queryChunks);
20534
+ }
20535
+ ((sql2) => {
20536
+ function empty() {
20537
+ return new SQL([]);
20538
+ }
20539
+ sql2.empty = empty;
20540
+ function fromList(list) {
20541
+ return new SQL(list);
20542
+ }
20543
+ sql2.fromList = fromList;
20544
+ function raw(str) {
20545
+ return new SQL([new StringChunk(str)]);
20546
+ }
20547
+ sql2.raw = raw;
20548
+ function join9(chunks, separator) {
20549
+ const result = [];
20550
+ for (const [i, chunk] of chunks.entries()) {
20551
+ if (i > 0 && separator !== undefined) {
20552
+ result.push(separator);
20553
+ }
20554
+ result.push(chunk);
20555
+ }
20556
+ return new SQL(result);
20557
+ }
20558
+ sql2.join = join9;
20559
+ function identifier(value) {
20560
+ return new Name(value);
20561
+ }
20562
+ sql2.identifier = identifier;
20563
+ function placeholder2(name2) {
20564
+ return new Placeholder(name2);
20565
+ }
20566
+ sql2.placeholder = placeholder2;
20567
+ function param2(value, encoder) {
20568
+ return new Param(value, encoder);
20569
+ }
20570
+ sql2.param = param2;
20571
+ })(sql || (sql = {}));
20572
+ ((SQL2) => {
20573
+
20574
+ class Aliased {
20575
+ constructor(sql2, fieldAlias) {
20576
+ this.sql = sql2;
20577
+ this.fieldAlias = fieldAlias;
20578
+ }
20579
+ static [entityKind] = "SQL.Aliased";
20580
+ isSelectionField = false;
20581
+ getSQL() {
20582
+ return this.sql;
20583
+ }
20584
+ clone() {
20585
+ return new Aliased(this.sql, this.fieldAlias);
20586
+ }
20587
+ }
20588
+ SQL2.Aliased = Aliased;
20589
+ })(SQL || (SQL = {}));
20590
+
20591
+ class Placeholder {
20592
+ constructor(name2) {
20593
+ this.name = name2;
20594
+ }
20595
+ static [entityKind] = "Placeholder";
20596
+ getSQL() {
20597
+ return new SQL([this]);
20598
+ }
20599
+ }
20600
+ var IsDrizzleView = Symbol.for("drizzle:IsDrizzleView");
20601
+
20602
+ class View {
20603
+ static [entityKind] = "View";
20604
+ [ViewBaseConfig];
20605
+ [IsDrizzleView] = true;
20606
+ constructor({ name: name2, schema, selectedFields, query }) {
20607
+ this[ViewBaseConfig] = {
20608
+ name: name2,
20609
+ originalName: name2,
20610
+ schema,
20611
+ selectedFields,
20612
+ query,
20613
+ isExisting: !query,
20614
+ isAlias: false
20615
+ };
20616
+ }
20617
+ getSQL() {
20618
+ return new SQL([this]);
20619
+ }
20620
+ }
20621
+ Column.prototype.getSQL = function() {
20622
+ return new SQL([this]);
20623
+ };
20624
+ Table.prototype.getSQL = function() {
20625
+ return new SQL([this]);
20626
+ };
20627
+ Subquery.prototype.getSQL = function() {
20628
+ return new SQL([this]);
20629
+ };
20630
+
20631
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/checks.js
20632
+ class CheckBuilder {
20633
+ constructor(name, value) {
20634
+ this.name = name;
20635
+ this.value = value;
20636
+ }
20637
+ static [entityKind] = "SQLiteCheckBuilder";
20638
+ brand;
20639
+ build(table) {
20640
+ return new Check(table, this);
20641
+ }
20642
+ }
20643
+
20644
+ class Check {
20645
+ constructor(table, builder) {
20646
+ this.table = table;
20647
+ this.name = builder.name;
20648
+ this.value = builder.value;
20649
+ }
20650
+ static [entityKind] = "SQLiteCheck";
20651
+ name;
20652
+ value;
20653
+ }
20654
+ function check2(name, value) {
20655
+ return new CheckBuilder(name, value);
20656
+ }
20657
+
20658
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/utils.js
20659
+ function getColumnNameAndConfig(a, b) {
20660
+ return {
20661
+ name: typeof a === "string" && a.length > 0 ? a : "",
20662
+ config: typeof a === "object" ? a : b
20663
+ };
20664
+ }
20665
+ var textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder;
20666
+
20667
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/foreign-keys.js
20668
+ class ForeignKeyBuilder {
20669
+ static [entityKind] = "SQLiteForeignKeyBuilder";
20670
+ reference;
20671
+ _onUpdate;
20672
+ _onDelete;
20673
+ constructor(config2, actions) {
20674
+ this.reference = () => {
20675
+ const { name, columns, foreignColumns } = config2();
20676
+ return { name, columns, foreignTable: foreignColumns[0].table, foreignColumns };
20677
+ };
20678
+ if (actions) {
20679
+ this._onUpdate = actions.onUpdate;
20680
+ this._onDelete = actions.onDelete;
20681
+ }
20682
+ }
20683
+ onUpdate(action) {
20684
+ this._onUpdate = action;
20685
+ return this;
20686
+ }
20687
+ onDelete(action) {
20688
+ this._onDelete = action;
20689
+ return this;
20690
+ }
20691
+ build(table) {
20692
+ return new ForeignKey(table, this);
20693
+ }
20694
+ }
20695
+
20696
+ class ForeignKey {
20697
+ constructor(table, builder) {
20698
+ this.table = table;
20699
+ this.reference = builder.reference;
20700
+ this.onUpdate = builder._onUpdate;
20701
+ this.onDelete = builder._onDelete;
20702
+ }
20703
+ static [entityKind] = "SQLiteForeignKey";
20704
+ reference;
20705
+ onUpdate;
20706
+ onDelete;
20707
+ getName() {
20708
+ const { name, columns, foreignColumns } = this.reference();
20709
+ const columnNames = columns.map((column) => column.name);
20710
+ const foreignColumnNames = foreignColumns.map((column) => column.name);
20711
+ const chunks = [
20712
+ this.table[TableName],
20713
+ ...columnNames,
20714
+ foreignColumns[0].table[TableName],
20715
+ ...foreignColumnNames
20716
+ ];
20717
+ return name ?? `${chunks.join("_")}_fk`;
20718
+ }
20719
+ }
20720
+ function foreignKey(config2) {
20721
+ function mappedConfig() {
20722
+ if (typeof config2 === "function") {
20723
+ const { name, columns, foreignColumns } = config2();
20724
+ return {
20725
+ name,
20726
+ columns,
20727
+ foreignColumns
20728
+ };
20729
+ }
20730
+ return config2;
20731
+ }
20732
+ return new ForeignKeyBuilder(mappedConfig);
20733
+ }
20734
+
20735
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/unique-constraint.js
20736
+ function uniqueKeyName2(table, columns) {
20737
+ return `${table[TableName]}_${columns.join("_")}_unique`;
20738
+ }
20739
+ function unique(name) {
20740
+ return new UniqueOnConstraintBuilder(name);
20741
+ }
20742
+
20743
+ class UniqueConstraintBuilder {
20744
+ constructor(columns, name) {
20745
+ this.name = name;
20746
+ this.columns = columns;
20747
+ }
20748
+ static [entityKind] = "SQLiteUniqueConstraintBuilder";
20749
+ columns;
20750
+ build(table) {
20751
+ return new UniqueConstraint(table, this.columns, this.name);
20752
+ }
20753
+ }
20754
+
20755
+ class UniqueOnConstraintBuilder {
20756
+ static [entityKind] = "SQLiteUniqueOnConstraintBuilder";
20757
+ name;
20758
+ constructor(name) {
20759
+ this.name = name;
20760
+ }
20761
+ on(...columns) {
20762
+ return new UniqueConstraintBuilder(columns, this.name);
20763
+ }
20764
+ }
20765
+
20766
+ class UniqueConstraint {
20767
+ constructor(table, columns, name) {
20768
+ this.table = table;
20769
+ this.columns = columns;
20770
+ this.name = name ?? uniqueKeyName2(this.table, this.columns.map((column) => column.name));
20771
+ }
20772
+ static [entityKind] = "SQLiteUniqueConstraint";
20773
+ columns;
20774
+ name;
20775
+ getName() {
20776
+ return this.name;
20777
+ }
20778
+ }
20779
+
20780
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/common.js
20781
+ class SQLiteColumnBuilder extends ColumnBuilder {
20782
+ static [entityKind] = "SQLiteColumnBuilder";
20783
+ foreignKeyConfigs = [];
20784
+ references(ref, actions = {}) {
20785
+ this.foreignKeyConfigs.push({ ref, actions });
20786
+ return this;
20787
+ }
20788
+ unique(name) {
20789
+ this.config.isUnique = true;
20790
+ this.config.uniqueName = name;
20791
+ return this;
20792
+ }
20793
+ generatedAlwaysAs(as, config2) {
20794
+ this.config.generated = {
20795
+ as,
20796
+ type: "always",
20797
+ mode: config2?.mode ?? "virtual"
20798
+ };
20799
+ return this;
20800
+ }
20801
+ buildForeignKeys(column, table) {
20802
+ return this.foreignKeyConfigs.map(({ ref, actions }) => {
20803
+ return ((ref2, actions2) => {
20804
+ const builder = new ForeignKeyBuilder(() => {
20805
+ const foreignColumn = ref2();
20806
+ return { columns: [column], foreignColumns: [foreignColumn] };
20807
+ });
20808
+ if (actions2.onUpdate) {
20809
+ builder.onUpdate(actions2.onUpdate);
20810
+ }
20811
+ if (actions2.onDelete) {
20812
+ builder.onDelete(actions2.onDelete);
20813
+ }
20814
+ return builder.build(table);
20815
+ })(ref, actions);
20816
+ });
20817
+ }
20818
+ }
20819
+
20820
+ class SQLiteColumn extends Column {
20821
+ constructor(table, config2) {
20822
+ if (!config2.uniqueName) {
20823
+ config2.uniqueName = uniqueKeyName2(table, [config2.name]);
20824
+ }
20825
+ super(table, config2);
20826
+ this.table = table;
20827
+ }
20828
+ static [entityKind] = "SQLiteColumn";
20829
+ }
20830
+
20831
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/blob.js
20832
+ class SQLiteBigIntBuilder extends SQLiteColumnBuilder {
20833
+ static [entityKind] = "SQLiteBigIntBuilder";
20834
+ constructor(name) {
20835
+ super(name, "bigint", "SQLiteBigInt");
20836
+ }
20837
+ build(table) {
20838
+ return new SQLiteBigInt(table, this.config);
20839
+ }
20840
+ }
20841
+
20842
+ class SQLiteBigInt extends SQLiteColumn {
20843
+ static [entityKind] = "SQLiteBigInt";
20844
+ getSQLType() {
20845
+ return "blob";
20846
+ }
20847
+ mapFromDriverValue(value) {
20848
+ if (typeof Buffer !== "undefined" && Buffer.from) {
20849
+ const buf = Buffer.isBuffer(value) ? value : value instanceof ArrayBuffer ? Buffer.from(value) : value.buffer ? Buffer.from(value.buffer, value.byteOffset, value.byteLength) : Buffer.from(value);
20850
+ return BigInt(buf.toString("utf8"));
20851
+ }
20852
+ return BigInt(textDecoder.decode(value));
20853
+ }
20854
+ mapToDriverValue(value) {
20855
+ return Buffer.from(value.toString());
20856
+ }
20857
+ }
20858
+
20859
+ class SQLiteBlobJsonBuilder extends SQLiteColumnBuilder {
20860
+ static [entityKind] = "SQLiteBlobJsonBuilder";
20861
+ constructor(name) {
20862
+ super(name, "json", "SQLiteBlobJson");
20863
+ }
20864
+ build(table) {
20865
+ return new SQLiteBlobJson(table, this.config);
20866
+ }
20867
+ }
20868
+
20869
+ class SQLiteBlobJson extends SQLiteColumn {
20870
+ static [entityKind] = "SQLiteBlobJson";
20871
+ getSQLType() {
20872
+ return "blob";
20873
+ }
20874
+ mapFromDriverValue(value) {
20875
+ if (typeof Buffer !== "undefined" && Buffer.from) {
20876
+ const buf = Buffer.isBuffer(value) ? value : value instanceof ArrayBuffer ? Buffer.from(value) : value.buffer ? Buffer.from(value.buffer, value.byteOffset, value.byteLength) : Buffer.from(value);
20877
+ return JSON.parse(buf.toString("utf8"));
20878
+ }
20879
+ return JSON.parse(textDecoder.decode(value));
20880
+ }
20881
+ mapToDriverValue(value) {
20882
+ return Buffer.from(JSON.stringify(value));
20883
+ }
20884
+ }
20885
+
20886
+ class SQLiteBlobBufferBuilder extends SQLiteColumnBuilder {
20887
+ static [entityKind] = "SQLiteBlobBufferBuilder";
20888
+ constructor(name) {
20889
+ super(name, "buffer", "SQLiteBlobBuffer");
20890
+ }
20891
+ build(table) {
20892
+ return new SQLiteBlobBuffer(table, this.config);
20893
+ }
20894
+ }
20895
+
20896
+ class SQLiteBlobBuffer extends SQLiteColumn {
20897
+ static [entityKind] = "SQLiteBlobBuffer";
20898
+ mapFromDriverValue(value) {
20899
+ if (Buffer.isBuffer(value)) {
20900
+ return value;
20901
+ }
20902
+ return Buffer.from(value);
20903
+ }
20904
+ getSQLType() {
20905
+ return "blob";
20906
+ }
20907
+ }
20908
+ function blob(a, b) {
20909
+ const { name, config: config2 } = getColumnNameAndConfig(a, b);
20910
+ if (config2?.mode === "json") {
20911
+ return new SQLiteBlobJsonBuilder(name);
20912
+ }
20913
+ if (config2?.mode === "bigint") {
20914
+ return new SQLiteBigIntBuilder(name);
20915
+ }
20916
+ return new SQLiteBlobBufferBuilder(name);
20917
+ }
20918
+
20919
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/custom.js
20920
+ class SQLiteCustomColumnBuilder extends SQLiteColumnBuilder {
20921
+ static [entityKind] = "SQLiteCustomColumnBuilder";
20922
+ constructor(name, fieldConfig, customTypeParams) {
20923
+ super(name, "custom", "SQLiteCustomColumn");
20924
+ this.config.fieldConfig = fieldConfig;
20925
+ this.config.customTypeParams = customTypeParams;
20926
+ }
20927
+ build(table) {
20928
+ return new SQLiteCustomColumn(table, this.config);
20929
+ }
20930
+ }
20931
+
20932
+ class SQLiteCustomColumn extends SQLiteColumn {
20933
+ static [entityKind] = "SQLiteCustomColumn";
20934
+ sqlName;
20935
+ mapTo;
20936
+ mapFrom;
20937
+ constructor(table, config2) {
20938
+ super(table, config2);
20939
+ this.sqlName = config2.customTypeParams.dataType(config2.fieldConfig);
20940
+ this.mapTo = config2.customTypeParams.toDriver;
20941
+ this.mapFrom = config2.customTypeParams.fromDriver;
20942
+ }
20943
+ getSQLType() {
20944
+ return this.sqlName;
20945
+ }
20946
+ mapFromDriverValue(value) {
20947
+ return typeof this.mapFrom === "function" ? this.mapFrom(value) : value;
20948
+ }
20949
+ mapToDriverValue(value) {
20950
+ return typeof this.mapTo === "function" ? this.mapTo(value) : value;
20951
+ }
20952
+ }
20953
+ function customType(customTypeParams) {
20954
+ return (a, b) => {
20955
+ const { name, config: config2 } = getColumnNameAndConfig(a, b);
20956
+ return new SQLiteCustomColumnBuilder(name, config2, customTypeParams);
20957
+ };
20958
+ }
20959
+
20960
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/integer.js
20961
+ class SQLiteBaseIntegerBuilder extends SQLiteColumnBuilder {
20962
+ static [entityKind] = "SQLiteBaseIntegerBuilder";
20963
+ constructor(name, dataType, columnType) {
20964
+ super(name, dataType, columnType);
20965
+ this.config.autoIncrement = false;
20966
+ }
20967
+ primaryKey(config2) {
20968
+ if (config2?.autoIncrement) {
20969
+ this.config.autoIncrement = true;
20970
+ }
20971
+ this.config.hasDefault = true;
20972
+ return super.primaryKey();
20973
+ }
20974
+ }
20975
+
20976
+ class SQLiteBaseInteger extends SQLiteColumn {
20977
+ static [entityKind] = "SQLiteBaseInteger";
20978
+ autoIncrement = this.config.autoIncrement;
20979
+ getSQLType() {
20980
+ return "integer";
20981
+ }
20982
+ }
20983
+
20984
+ class SQLiteIntegerBuilder extends SQLiteBaseIntegerBuilder {
20985
+ static [entityKind] = "SQLiteIntegerBuilder";
20986
+ constructor(name) {
20987
+ super(name, "number", "SQLiteInteger");
20988
+ }
20989
+ build(table) {
20990
+ return new SQLiteInteger(table, this.config);
20991
+ }
20992
+ }
20993
+
20994
+ class SQLiteInteger extends SQLiteBaseInteger {
20995
+ static [entityKind] = "SQLiteInteger";
20996
+ }
20997
+
20998
+ class SQLiteTimestampBuilder extends SQLiteBaseIntegerBuilder {
20999
+ static [entityKind] = "SQLiteTimestampBuilder";
21000
+ constructor(name, mode) {
21001
+ super(name, "date", "SQLiteTimestamp");
21002
+ this.config.mode = mode;
21003
+ }
21004
+ defaultNow() {
21005
+ return this.default(sql`(cast((julianday('now') - 2440587.5)*86400000 as integer))`);
21006
+ }
21007
+ build(table) {
21008
+ return new SQLiteTimestamp(table, this.config);
21009
+ }
21010
+ }
21011
+
21012
+ class SQLiteTimestamp extends SQLiteBaseInteger {
21013
+ static [entityKind] = "SQLiteTimestamp";
21014
+ mode = this.config.mode;
21015
+ mapFromDriverValue(value) {
21016
+ if (this.config.mode === "timestamp") {
21017
+ return new Date(value * 1000);
21018
+ }
21019
+ return new Date(value);
21020
+ }
21021
+ mapToDriverValue(value) {
21022
+ const unix = value.getTime();
21023
+ if (this.config.mode === "timestamp") {
21024
+ return Math.floor(unix / 1000);
21025
+ }
21026
+ return unix;
21027
+ }
21028
+ }
21029
+
21030
+ class SQLiteBooleanBuilder extends SQLiteBaseIntegerBuilder {
21031
+ static [entityKind] = "SQLiteBooleanBuilder";
21032
+ constructor(name, mode) {
21033
+ super(name, "boolean", "SQLiteBoolean");
21034
+ this.config.mode = mode;
21035
+ }
21036
+ build(table) {
21037
+ return new SQLiteBoolean(table, this.config);
21038
+ }
21039
+ }
21040
+
21041
+ class SQLiteBoolean extends SQLiteBaseInteger {
21042
+ static [entityKind] = "SQLiteBoolean";
21043
+ mode = this.config.mode;
21044
+ mapFromDriverValue(value) {
21045
+ return Number(value) === 1;
21046
+ }
21047
+ mapToDriverValue(value) {
21048
+ return value ? 1 : 0;
21049
+ }
21050
+ }
21051
+ function integer2(a, b) {
21052
+ const { name, config: config2 } = getColumnNameAndConfig(a, b);
21053
+ if (config2?.mode === "timestamp" || config2?.mode === "timestamp_ms") {
21054
+ return new SQLiteTimestampBuilder(name, config2.mode);
21055
+ }
21056
+ if (config2?.mode === "boolean") {
21057
+ return new SQLiteBooleanBuilder(name, config2.mode);
21058
+ }
21059
+ return new SQLiteIntegerBuilder(name);
21060
+ }
21061
+
21062
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/numeric.js
21063
+ class SQLiteNumericBuilder extends SQLiteColumnBuilder {
21064
+ static [entityKind] = "SQLiteNumericBuilder";
21065
+ constructor(name) {
21066
+ super(name, "string", "SQLiteNumeric");
21067
+ }
21068
+ build(table) {
21069
+ return new SQLiteNumeric(table, this.config);
21070
+ }
21071
+ }
21072
+
21073
+ class SQLiteNumeric extends SQLiteColumn {
21074
+ static [entityKind] = "SQLiteNumeric";
21075
+ mapFromDriverValue(value) {
21076
+ if (typeof value === "string")
21077
+ return value;
21078
+ return String(value);
21079
+ }
21080
+ getSQLType() {
21081
+ return "numeric";
21082
+ }
21083
+ }
21084
+
21085
+ class SQLiteNumericNumberBuilder extends SQLiteColumnBuilder {
21086
+ static [entityKind] = "SQLiteNumericNumberBuilder";
21087
+ constructor(name) {
21088
+ super(name, "number", "SQLiteNumericNumber");
21089
+ }
21090
+ build(table) {
21091
+ return new SQLiteNumericNumber(table, this.config);
21092
+ }
21093
+ }
21094
+
21095
+ class SQLiteNumericNumber extends SQLiteColumn {
21096
+ static [entityKind] = "SQLiteNumericNumber";
21097
+ mapFromDriverValue(value) {
21098
+ if (typeof value === "number")
21099
+ return value;
21100
+ return Number(value);
21101
+ }
21102
+ mapToDriverValue = String;
21103
+ getSQLType() {
21104
+ return "numeric";
21105
+ }
21106
+ }
21107
+
21108
+ class SQLiteNumericBigIntBuilder extends SQLiteColumnBuilder {
21109
+ static [entityKind] = "SQLiteNumericBigIntBuilder";
21110
+ constructor(name) {
21111
+ super(name, "bigint", "SQLiteNumericBigInt");
21112
+ }
21113
+ build(table) {
21114
+ return new SQLiteNumericBigInt(table, this.config);
21115
+ }
21116
+ }
21117
+
21118
+ class SQLiteNumericBigInt extends SQLiteColumn {
21119
+ static [entityKind] = "SQLiteNumericBigInt";
21120
+ mapFromDriverValue = BigInt;
21121
+ mapToDriverValue = String;
21122
+ getSQLType() {
21123
+ return "numeric";
21124
+ }
21125
+ }
21126
+ function numeric(a, b) {
21127
+ const { name, config: config2 } = getColumnNameAndConfig(a, b);
21128
+ const mode = config2?.mode;
21129
+ return mode === "number" ? new SQLiteNumericNumberBuilder(name) : mode === "bigint" ? new SQLiteNumericBigIntBuilder(name) : new SQLiteNumericBuilder(name);
21130
+ }
21131
+
21132
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/real.js
21133
+ class SQLiteRealBuilder extends SQLiteColumnBuilder {
21134
+ static [entityKind] = "SQLiteRealBuilder";
21135
+ constructor(name) {
21136
+ super(name, "number", "SQLiteReal");
21137
+ }
21138
+ build(table) {
21139
+ return new SQLiteReal(table, this.config);
21140
+ }
21141
+ }
21142
+
21143
+ class SQLiteReal extends SQLiteColumn {
21144
+ static [entityKind] = "SQLiteReal";
21145
+ getSQLType() {
21146
+ return "real";
21147
+ }
21148
+ }
21149
+ function real(name) {
21150
+ return new SQLiteRealBuilder(name ?? "");
21151
+ }
21152
+
21153
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/text.js
21154
+ class SQLiteTextBuilder extends SQLiteColumnBuilder {
21155
+ static [entityKind] = "SQLiteTextBuilder";
21156
+ constructor(name, config2) {
21157
+ super(name, "string", "SQLiteText");
21158
+ this.config.enumValues = config2.enum;
21159
+ this.config.length = config2.length;
21160
+ }
21161
+ build(table) {
21162
+ return new SQLiteText(table, this.config);
21163
+ }
21164
+ }
21165
+
21166
+ class SQLiteText extends SQLiteColumn {
21167
+ static [entityKind] = "SQLiteText";
21168
+ enumValues = this.config.enumValues;
21169
+ length = this.config.length;
21170
+ constructor(table, config2) {
21171
+ super(table, config2);
21172
+ }
21173
+ getSQLType() {
21174
+ return `text${this.config.length ? `(${this.config.length})` : ""}`;
21175
+ }
21176
+ }
21177
+
21178
+ class SQLiteTextJsonBuilder extends SQLiteColumnBuilder {
21179
+ static [entityKind] = "SQLiteTextJsonBuilder";
21180
+ constructor(name) {
21181
+ super(name, "json", "SQLiteTextJson");
21182
+ }
21183
+ build(table) {
21184
+ return new SQLiteTextJson(table, this.config);
21185
+ }
21186
+ }
21187
+
21188
+ class SQLiteTextJson extends SQLiteColumn {
21189
+ static [entityKind] = "SQLiteTextJson";
21190
+ getSQLType() {
21191
+ return "text";
21192
+ }
21193
+ mapFromDriverValue(value) {
21194
+ return JSON.parse(value);
21195
+ }
21196
+ mapToDriverValue(value) {
21197
+ return JSON.stringify(value);
21198
+ }
21199
+ }
21200
+ function text(a, b = {}) {
21201
+ const { name, config: config2 } = getColumnNameAndConfig(a, b);
21202
+ if (config2.mode === "json") {
21203
+ return new SQLiteTextJsonBuilder(name);
21204
+ }
21205
+ return new SQLiteTextBuilder(name, config2);
21206
+ }
21207
+
21208
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/all.js
21209
+ function getSQLiteColumnBuilders() {
21210
+ return {
21211
+ blob,
21212
+ customType,
21213
+ integer: integer2,
21214
+ numeric,
21215
+ real,
21216
+ text
21217
+ };
21218
+ }
21219
+
21220
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/table.js
21221
+ var InlineForeignKeys = Symbol.for("drizzle:SQLiteInlineForeignKeys");
21222
+
21223
+ class SQLiteTable extends Table {
21224
+ static [entityKind] = "SQLiteTable";
21225
+ static Symbol = Object.assign({}, Table.Symbol, {
21226
+ InlineForeignKeys
21227
+ });
21228
+ [Table.Symbol.Columns];
21229
+ [InlineForeignKeys] = [];
21230
+ [Table.Symbol.ExtraConfigBuilder] = undefined;
21231
+ }
21232
+ function sqliteTableBase(name, columns, extraConfig, schema, baseName = name) {
21233
+ const rawTable = new SQLiteTable(name, schema, baseName);
21234
+ const parsedColumns = typeof columns === "function" ? columns(getSQLiteColumnBuilders()) : columns;
21235
+ const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name2, colBuilderBase]) => {
21236
+ const colBuilder = colBuilderBase;
21237
+ colBuilder.setName(name2);
21238
+ const column = colBuilder.build(rawTable);
21239
+ rawTable[InlineForeignKeys].push(...colBuilder.buildForeignKeys(column, rawTable));
21240
+ return [name2, column];
21241
+ }));
21242
+ const table = Object.assign(rawTable, builtColumns);
21243
+ table[Table.Symbol.Columns] = builtColumns;
21244
+ table[Table.Symbol.ExtraConfigColumns] = builtColumns;
21245
+ if (extraConfig) {
21246
+ table[SQLiteTable.Symbol.ExtraConfigBuilder] = extraConfig;
21247
+ }
21248
+ return table;
21249
+ }
21250
+ var sqliteTable = (name, columns, extraConfig) => {
21251
+ return sqliteTableBase(name, columns, extraConfig);
21252
+ };
21253
+
21254
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/indexes.js
21255
+ class IndexBuilderOn {
21256
+ constructor(name, unique2) {
21257
+ this.name = name;
21258
+ this.unique = unique2;
21259
+ }
21260
+ static [entityKind] = "SQLiteIndexBuilderOn";
21261
+ on(...columns) {
21262
+ return new IndexBuilder(this.name, columns, this.unique);
21263
+ }
21264
+ }
21265
+
21266
+ class IndexBuilder {
21267
+ static [entityKind] = "SQLiteIndexBuilder";
21268
+ config;
21269
+ constructor(name, columns, unique2) {
21270
+ this.config = {
21271
+ name,
21272
+ columns,
21273
+ unique: unique2,
21274
+ where: undefined
21275
+ };
21276
+ }
21277
+ where(condition) {
21278
+ this.config.where = condition;
21279
+ return this;
21280
+ }
21281
+ build(table) {
21282
+ return new Index(this.config, table);
21283
+ }
21284
+ }
21285
+
21286
+ class Index {
21287
+ static [entityKind] = "SQLiteIndex";
21288
+ config;
21289
+ constructor(config2, table) {
21290
+ this.config = { ...config2, table };
21291
+ }
21292
+ }
21293
+ function index(name) {
21294
+ return new IndexBuilderOn(name, false);
21295
+ }
21296
+ function uniqueIndex(name) {
21297
+ return new IndexBuilderOn(name, true);
21298
+ }
21299
+
21300
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/primary-keys.js
21301
+ function primaryKey(...config2) {
21302
+ if (config2[0].columns) {
21303
+ return new PrimaryKeyBuilder(config2[0].columns, config2[0].name);
21304
+ }
21305
+ return new PrimaryKeyBuilder(config2);
21306
+ }
21307
+
21308
+ class PrimaryKeyBuilder {
21309
+ static [entityKind] = "SQLitePrimaryKeyBuilder";
21310
+ columns;
21311
+ name;
21312
+ constructor(columns, name) {
21313
+ this.columns = columns;
21314
+ this.name = name;
21315
+ }
21316
+ build(table) {
21317
+ return new PrimaryKey(table, this.columns, this.name);
21318
+ }
21319
+ }
21320
+
21321
+ class PrimaryKey {
21322
+ constructor(table, columns, name) {
21323
+ this.table = table;
21324
+ this.columns = columns;
21325
+ this.name = name;
21326
+ }
21327
+ static [entityKind] = "SQLitePrimaryKey";
21328
+ columns;
21329
+ name;
21330
+ getName() {
21331
+ return this.name ?? `${this.table[SQLiteTable.Symbol.Name]}_${this.columns.map((column) => column.name).join("_")}_pk`;
21332
+ }
21333
+ }
21334
+
21335
+ // ../../node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/index.js
21336
+ import { webcrypto as crypto2 } from "node:crypto";
21337
+
21338
+ // ../../node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/url-alphabet/index.js
21339
+ var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
21340
+
21341
+ // ../../node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/index.js
21342
+ var POOL_SIZE_MULTIPLIER = 128;
21343
+ var pool;
21344
+ var poolOffset;
21345
+ function fillPool(bytes) {
21346
+ if (bytes < 0)
21347
+ throw new RangeError("Wrong ID size");
21348
+ try {
21349
+ if (!pool || pool.length < bytes) {
21350
+ pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
21351
+ crypto2.getRandomValues(pool);
21352
+ poolOffset = 0;
21353
+ } else if (poolOffset + bytes > pool.length) {
21354
+ crypto2.getRandomValues(pool);
21355
+ poolOffset = 0;
21356
+ }
21357
+ } catch (e) {
21358
+ pool = undefined;
21359
+ throw e;
21360
+ }
21361
+ poolOffset += bytes;
21362
+ }
21363
+ function nanoid3(size = 21) {
21364
+ fillPool(size |= 0);
21365
+ let id = "";
21366
+ for (let i = poolOffset - size;i < poolOffset; i++) {
21367
+ id += urlAlphabet[pool[i] & 63];
21368
+ }
21369
+ return id;
21370
+ }
21371
+
21372
+ // ../shared/src/constants.ts
21373
+ var TaskStatus = {
21374
+ QUEUED: "queued",
21375
+ DISPATCHED: "dispatched",
21376
+ RUNNING: "running",
21377
+ COMPLETED: "completed",
21378
+ FAILED: "failed",
21379
+ CANCELLED: "cancelled",
21380
+ SUPERSEDED: "superseded"
21381
+ };
21382
+ var TERMINAL_TASK_STATUSES = [
21383
+ TaskStatus.COMPLETED,
21384
+ TaskStatus.FAILED,
21385
+ TaskStatus.CANCELLED,
21386
+ TaskStatus.SUPERSEDED
21387
+ ];
21388
+ var TASK_TYPES = {
21389
+ USER_DM_MESSAGE: "user_dm_message",
21390
+ EMAIL_NOTIFICATION: "email_notification",
21391
+ CALENDAR_EVENT: "calendar_event",
21392
+ ISSUE_EVENT: "issue_event",
21393
+ KILL_TASK: "kill_task"
21394
+ };
21395
+ var IssueStatus = {
21396
+ TODO: "todo",
21397
+ IN_PROGRESS: "in_progress",
21398
+ REVIEW: "review",
21399
+ DONE: "done",
21400
+ CLOSED: "closed",
21401
+ CANCELED: "canceled",
21402
+ FAILED: "failed"
21403
+ };
21404
+ var ACTIVE_ISSUE_STATUSES = [
21405
+ IssueStatus.TODO,
21406
+ IssueStatus.IN_PROGRESS,
21407
+ IssueStatus.REVIEW
21408
+ ];
21409
+ var TERMINAL_ISSUE_STATUSES = [
21410
+ IssueStatus.DONE,
21411
+ IssueStatus.CLOSED,
21412
+ IssueStatus.CANCELED,
21413
+ IssueStatus.FAILED
21414
+ ];
21415
+ var POLL_INTERVAL_MS = Number(process.env.POLL_INTERVAL_MS) || 3000;
21416
+ var OFFLINE_THRESHOLD_MS = Number(process.env.OFFLINE_THRESHOLD_MS) || 30000;
21417
+ var COMMUNITY_MACHINE_HEARTBEAT_MS = 30000;
21418
+ var COMMUNITY_MACHINE_OFFLINE_THRESHOLD_MS = 3 * COMMUNITY_MACHINE_HEARTBEAT_MS;
21419
+ var COMMUNITY_MACHINE_PAIR_TOKEN_TTL_MS = 15 * 60000;
21420
+ var EVENT_POLL_INTERVAL_MS = Number(process.env.EVENT_POLL_INTERVAL_MS) || 2000;
21421
+ var MeetingStatus = {
21422
+ PENDING: "pending",
21423
+ SCHEDULED: "scheduled",
21424
+ JOINING: "joining",
21425
+ RECORDING: "recording",
21426
+ COMPLETED: "completed",
21427
+ FAILED: "failed"
21428
+ };
21429
+ var TERMINAL_MEETING_STATUSES = [
21430
+ MeetingStatus.COMPLETED,
21431
+ MeetingStatus.FAILED
21432
+ ];
21433
+ var DEV_PORTS = {
21434
+ web: 3000,
21435
+ emailWorker: 8787,
21436
+ wsDo: 8789,
21437
+ wakeWorker: 8790
21438
+ };
21439
+ var DEV_WEB_URL = process.env.ALOOK_SERVER_URL || `http://localhost:${DEV_PORTS.web}`;
21440
+ var DEV_WS_DO_URL = process.env.DEV_WS_DO_URL || `http://localhost:${DEV_PORTS.wsDo}`;
21441
+ var DEV_EMAIL_WORKER_URL = process.env.DEV_EMAIL_WORKER_URL || `http://localhost:${DEV_PORTS.emailWorker}`;
21442
+ var DEV_WAKE_WORKER_URL = process.env.DEV_WAKE_WORKER_URL || `http://localhost:${DEV_PORTS.wakeWorker}`;
21443
+
21444
+ // ../shared/src/db/schema.ts
21445
+ var user = sqliteTable("user", {
21446
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21447
+ name: text("name").notNull().default(""),
21448
+ email: text("email").unique().notNull(),
21449
+ emailVerified: integer2("emailVerified", { mode: "boolean" }),
21450
+ image: text("image"),
21451
+ createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
21452
+ updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString()),
21453
+ isBot: integer2("isBot", { mode: "boolean" }).notNull().default(false),
21454
+ ownerUserId: text("ownerUserId").references(() => user.id, { onDelete: "no action" }),
21455
+ deletedAt: text("deletedAt"),
21456
+ discriminator: text("discriminator").notNull().default("0000"),
21457
+ lastRefreshContextAt: text("lastRefreshContextAt")
21458
+ }, (t) => [index("idx_user_ownerUserId_isBot").on(t.ownerUserId, t.isBot)]);
21459
+ var session = sqliteTable("session", {
21460
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21461
+ userId: text("userId").notNull().references(() => user.id, { onDelete: "cascade" }),
21462
+ token: text("token").unique().notNull(),
21463
+ expiresAt: text("expiresAt").notNull(),
21464
+ ipAddress: text("ipAddress"),
21465
+ userAgent: text("userAgent"),
21466
+ createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
21467
+ updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString())
21468
+ }, (t) => [index("idx_session_token_expires").on(t.token, t.expiresAt)]);
21469
+ var account = sqliteTable("account", {
21470
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21471
+ userId: text("userId").notNull().references(() => user.id, { onDelete: "cascade" }),
21472
+ accountId: text("accountId").notNull(),
21473
+ providerId: text("providerId").notNull(),
21474
+ accessToken: text("accessToken"),
21475
+ refreshToken: text("refreshToken"),
21476
+ accessTokenExpiresAt: text("accessTokenExpiresAt"),
21477
+ refreshTokenExpiresAt: text("refreshTokenExpiresAt"),
21478
+ scope: text("scope"),
21479
+ idToken: text("idToken"),
21480
+ password: text("password"),
21481
+ createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
21482
+ updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString())
21483
+ });
21484
+ var verification = sqliteTable("verification", {
21485
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21486
+ identifier: text("identifier").notNull(),
21487
+ value: text("value").notNull(),
21488
+ expiresAt: text("expiresAt").notNull(),
21489
+ createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
21490
+ updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString())
21491
+ });
21492
+ var workspace = sqliteTable("workspace", {
21493
+ id: text("id").primaryKey().$defaultFn(() => "sp_" + nanoid3()),
21494
+ name: text("name").notNull(),
21495
+ slug: text("slug").unique().notNull(),
21496
+ onboarded: integer2("onboarded").notNull().default(0),
21497
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
21498
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
21499
+ });
21500
+ var member = sqliteTable("member", {
21501
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21502
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21503
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
21504
+ role: text("role").notNull().default("member"),
21505
+ globalInstruction: text("global_instruction").notNull().default(""),
21506
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21507
+ }, (t) => [unique("member_workspace_user").on(t.workspaceId, t.userId)]);
21508
+ var workspaceInvite = sqliteTable("workspace_invite", {
21509
+ id: text("id").primaryKey().$defaultFn(() => "inv_" + nanoid3()),
21510
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21511
+ token: text("token").unique().notNull().$defaultFn(() => nanoid3(32)),
21512
+ createdBy: text("created_by").notNull().references(() => user.id, { onDelete: "cascade" }),
21513
+ usedBy: text("used_by").references(() => user.id, { onDelete: "set null" }),
21514
+ usedAt: text("used_at"),
21515
+ expiresAt: text("expires_at").notNull(),
21516
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21517
+ }, (t) => [
21518
+ index("idx_workspace_invite_token").on(t.token),
21519
+ index("idx_workspace_invite_workspace").on(t.workspaceId)
21520
+ ]);
21521
+ var agentAccess = sqliteTable("agent_access", {
21522
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21523
+ agentId: text("agent_id").notNull(),
21524
+ workspaceId: text("workspace_id").notNull(),
21525
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
21526
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21527
+ }, (t) => [
21528
+ unique("agent_access_agent_ws_user").on(t.agentId, t.workspaceId, t.userId),
21529
+ index("idx_agent_access_agent_ws").on(t.agentId, t.workspaceId),
21530
+ index("idx_agent_access_user").on(t.userId),
21531
+ foreignKey({
21532
+ columns: [t.agentId, t.workspaceId],
21533
+ foreignColumns: [agent.id, agent.workspaceId]
21534
+ }).onDelete("cascade")
21535
+ ]);
21536
+ var agentPin = sqliteTable("agent_pin", {
21537
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21538
+ agentId: text("agent_id").notNull(),
21539
+ workspaceId: text("workspace_id").notNull(),
21540
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
21541
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
21542
+ position: integer2("position").notNull().default(0)
21543
+ }, (t) => [
21544
+ unique("agent_pin_agent_ws_user").on(t.agentId, t.workspaceId, t.userId),
21545
+ index("idx_agent_pin_ws_user").on(t.workspaceId, t.userId),
21546
+ foreignKey({
21547
+ columns: [t.agentId, t.workspaceId],
21548
+ foreignColumns: [agent.id, agent.workspaceId]
21549
+ }).onDelete("cascade")
21550
+ ]);
21551
+ var agentSidebarOrder = sqliteTable("agent_sidebar_order", {
21552
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21553
+ agentId: text("agent_id").notNull(),
21554
+ workspaceId: text("workspace_id").notNull(),
21555
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
21556
+ position: integer2("position").notNull().default(0)
21557
+ }, (t) => [
21558
+ unique("agent_sidebar_order_agent_ws_user").on(t.agentId, t.workspaceId, t.userId),
21559
+ index("idx_agent_sidebar_order_ws_user").on(t.workspaceId, t.userId),
21560
+ foreignKey({
21561
+ columns: [t.agentId, t.workspaceId],
21562
+ foreignColumns: [agent.id, agent.workspaceId]
21563
+ }).onDelete("cascade")
21564
+ ]);
21565
+ var machine = sqliteTable("machine", {
21566
+ daemonId: text("daemon_id").notNull(),
21567
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21568
+ deviceInfo: text("device_info").notNull().default(""),
21569
+ lastSeenAt: text("last_seen_at"),
21570
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
21571
+ pendingUpdateVersion: text("pending_update_version"),
21572
+ pendingRescan: integer2("pending_rescan", { mode: "boolean" }).default(false),
21573
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString()),
21574
+ ownerId: text("owner_id").references(() => user.id, { onDelete: "set null" })
21575
+ }, (t) => [primaryKey({ columns: [t.workspaceId, t.daemonId] })]);
21576
+ var agentRuntime = sqliteTable("agent_runtime", {
21577
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21578
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21579
+ daemonId: text("daemon_id").notNull(),
21580
+ runtimeMode: text("runtime_mode").notNull().default("local"),
21581
+ provider: text("provider").notNull(),
21582
+ deviceInfo: text("device_info").notNull().default(""),
21583
+ metadata: text("metadata", { mode: "json" }),
21584
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
21585
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
21586
+ }, (t) => [
21587
+ unique("agent_runtime_workspace_daemon_provider").on(t.workspaceId, t.daemonId, t.provider),
21588
+ index("idx_agent_runtime_workspace_daemon").on(t.workspaceId, t.daemonId),
21589
+ index("idx_agent_runtime_daemon_workspace").on(t.daemonId, t.workspaceId)
21590
+ ]);
21591
+ var agent = sqliteTable("agent", {
21592
+ id: text("id").notNull().$defaultFn(() => "ag_" + nanoid3(8)),
21593
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21594
+ name: text("name").notNull(),
21595
+ description: text("description").notNull().default(""),
21596
+ instructions: text("instructions").notNull().default(""),
21597
+ avatarUrl: text("avatar_url"),
21598
+ runtimeId: text("runtime_id").references(() => agentRuntime.id),
21599
+ runtimeMode: text("runtime_mode").notNull().default("local"),
21600
+ runtimeConfig: text("runtime_config", { mode: "json" }),
21601
+ visibility: text("visibility").notNull().default("private"),
21602
+ status: text("status").notNull().default("idle"),
21603
+ maxConcurrentTasks: integer2("max_concurrent_tasks").notNull().default(6),
21604
+ ownerId: text("owner_id").references(() => user.id),
21605
+ tools: text("tools", { mode: "json" }),
21606
+ triggers: text("triggers", { mode: "json" }),
21607
+ emailHandle: text("email_handle").unique(),
21608
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
21609
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
21610
+ }, (t) => [primaryKey({ columns: [t.id, t.workspaceId] })]);
21611
+ var agentWhitelist = sqliteTable("agent_whitelist", {
21612
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21613
+ agentId: text("agent_id").notNull(),
21614
+ workspaceId: text("workspace_id").notNull(),
21615
+ email: text("email").notNull(),
21616
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21617
+ }, (t) => [
21618
+ unique("agent_whitelist_agent_ws_email").on(t.agentId, t.workspaceId, t.email),
21619
+ foreignKey({
21620
+ columns: [t.agentId, t.workspaceId],
21621
+ foreignColumns: [agent.id, agent.workspaceId]
21622
+ }).onDelete("cascade")
21623
+ ]);
21624
+ var channel = sqliteTable("channel", {
21625
+ id: text("id").primaryKey().$defaultFn(() => "ch_" + nanoid3()),
21626
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21627
+ name: text("name").notNull(),
21628
+ position: integer2("position").notNull().default(0),
21629
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21630
+ }, (t) => [
21631
+ unique("channel_workspace_name").on(t.workspaceId, t.name),
21632
+ index("idx_channel_workspace").on(t.workspaceId)
21633
+ ]);
21634
+ var conversation = sqliteTable("conversation", {
21635
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21636
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21637
+ agentId: text("agent_id").notNull(),
21638
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
21639
+ title: text("title").notNull().default(""),
21640
+ type: text("type").notNull().default(TASK_TYPES.USER_DM_MESSAGE),
21641
+ channel: text("channel").notNull().default("default"),
21642
+ parentMessageId: text("parent_message_id"),
21643
+ threadTitle: text("thread_title").notNull().default(""),
21644
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21645
+ }, (t) => [
21646
+ index("idx_conversation_agent_lookup").on(t.workspaceId, t.agentId, t.userId, t.type, t.channel, t.createdAt),
21647
+ index("idx_conversation_ws_user").on(t.workspaceId, t.userId, t.createdAt),
21648
+ index("idx_conversation_thread").on(t.parentMessageId),
21649
+ unique("uq_conversation_parent_message").on(t.parentMessageId, t.workspaceId),
21650
+ foreignKey({
21651
+ columns: [t.agentId, t.workspaceId],
21652
+ foreignColumns: [agent.id, agent.workspaceId]
21653
+ }).onDelete("cascade")
21654
+ ]);
21655
+ var message = sqliteTable("message", {
21656
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21657
+ conversationId: text("conversation_id").notNull().references(() => conversation.id, { onDelete: "cascade" }),
21658
+ role: text("role").notNull(),
21659
+ content: text("content").notNull().default(""),
21660
+ taskId: text("task_id"),
21661
+ attachmentIds: text("attachment_ids"),
21662
+ metadata: text("metadata"),
21663
+ status: text("status").notNull().default("active"),
21664
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21665
+ }, (t) => [
21666
+ index("idx_message_conversation_status").on(t.conversationId, t.status)
21667
+ ]);
21668
+ var agentTaskQueue = sqliteTable("agent_task_queue", {
21669
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21670
+ agentId: text("agent_id").notNull(),
21671
+ runtimeId: text("runtime_id").notNull().references(() => agentRuntime.id, { onDelete: "cascade" }),
21672
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21673
+ conversationId: text("conversation_id").notNull().references(() => conversation.id, { onDelete: "cascade" }),
21674
+ prompt: text("prompt").notNull(),
21675
+ type: text("type").notNull().default(TASK_TYPES.USER_DM_MESSAGE),
21676
+ contextKey: text("context_key"),
21677
+ status: text("status").notNull().default("queued"),
21678
+ priority: integer2("priority").notNull().default(0),
21679
+ result: text("result", { mode: "json" }),
21680
+ context: text("context", { mode: "json" }),
21681
+ sessionId: text("session_id"),
21682
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
21683
+ dispatchedAt: text("dispatched_at"),
21684
+ startedAt: text("started_at"),
21685
+ completedAt: text("completed_at"),
21686
+ error: text("error"),
21687
+ traceId: text("trace_id"),
21688
+ parentTaskId: text("parent_task_id")
21689
+ }, (t) => [
21690
+ index("idx_task_queue_pending").on(t.agentId, t.status).where(sql`status IN ('queued', 'dispatched')`),
21691
+ index("idx_task_queue_workspace_active").on(t.workspaceId, t.status, t.agentId).where(sql`status IN ('queued', 'dispatched', 'running')`),
21692
+ index("idx_task_queue_agent_history").on(t.agentId, t.workspaceId, t.createdAt),
21693
+ index("idx_task_queue_conversation_status").on(t.conversationId, t.status),
21694
+ index("idx_task_queue_trace").on(t.traceId),
21695
+ index("idx_task_queue_parent").on(t.parentTaskId),
21696
+ index("idx_task_queue_workspace_type_status").on(t.workspaceId, t.type, t.status),
21697
+ index("idx_task_queue_workspace_status_dispatched").on(t.workspaceId, t.status, t.dispatchedAt),
21698
+ index("idx_task_queue_inbox").on(t.workspaceId, t.status, t.completedAt),
21699
+ index("idx_task_queue_runtime_pending").on(t.workspaceId, t.runtimeId, t.status).where(sql`status IN ('queued', 'dispatched')`),
21700
+ index("idx_task_queue_agent_running").on(t.agentId, t.workspaceId, t.status).where(sql`status IN ('dispatched', 'running')`),
21701
+ index("idx_task_queue_inbox_convo").on(t.workspaceId, t.status, t.conversationId, t.completedAt).where(sql`status IN ('completed', 'failed') AND parent_task_id IS NULL`),
21702
+ foreignKey({
21703
+ columns: [t.agentId, t.workspaceId],
21704
+ foreignColumns: [agent.id, agent.workspaceId]
21705
+ }).onDelete("cascade")
21706
+ ]);
21707
+ var issue2 = sqliteTable("issue", {
21708
+ id: text("id").primaryKey().$defaultFn(() => "iss_" + nanoid3()),
21709
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21710
+ agentId: text("agent_id"),
21711
+ creatorUserId: text("creator_user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
21712
+ conversationId: text("conversation_id").references(() => conversation.id, { onDelete: "cascade" }),
21713
+ latestTaskId: text("latest_task_id").references(() => agentTaskQueue.id, {
21714
+ onDelete: "set null"
21715
+ }),
21716
+ title: text("title").notNull(),
21717
+ description: text("description").notNull().default(""),
21718
+ status: text("status").notNull().default("todo"),
21719
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
21720
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString()),
21721
+ completedAt: text("completed_at")
21722
+ }, (t) => [
21723
+ index("idx_issue_workspace_status_agent").on(t.workspaceId, t.status, t.agentId),
21724
+ index("idx_issue_workspace_updated").on(t.workspaceId, t.updatedAt),
21725
+ unique("issue_conversation_unique").on(t.conversationId),
21726
+ foreignKey({
21727
+ columns: [t.agentId, t.workspaceId],
21728
+ foreignColumns: [agent.id, agent.workspaceId]
21729
+ }).onDelete("cascade")
21730
+ ]);
21731
+ var issueComment = sqliteTable("issue_comment", {
21732
+ id: text("id").primaryKey().$defaultFn(() => "ic_" + nanoid3()),
21733
+ issueId: text("issue_id").notNull().references(() => issue2.id, { onDelete: "cascade" }),
21734
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21735
+ authorType: text("author_type").notNull().default("user"),
21736
+ authorId: text("author_id").notNull(),
21737
+ content: text("content").notNull(),
21738
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21739
+ }, (t) => [
21740
+ index("idx_issue_comment_issue").on(t.issueId, t.createdAt),
21741
+ index("idx_issue_comment_workspace").on(t.workspaceId, t.issueId)
21742
+ ]);
21743
+ var taskMessage = sqliteTable("task_message", {
21744
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21745
+ taskId: text("task_id").notNull().references(() => agentTaskQueue.id, { onDelete: "cascade" }),
21746
+ seq: integer2("seq").notNull(),
21747
+ type: text("type").notNull().default(""),
21748
+ tool: text("tool").notNull().default(""),
21749
+ content: text("content").notNull().default(""),
21750
+ callId: text("call_id").notNull().default(""),
21751
+ input: text("input", { mode: "json" }),
21752
+ output: text("output").notNull().default(""),
21753
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21754
+ }, (t) => [
21755
+ index("idx_task_message_task_seq").on(t.taskId, t.seq),
21756
+ index("idx_task_message_task_created").on(t.taskId, t.createdAt)
21757
+ ]);
21758
+ var emails = sqliteTable("emails", {
21759
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21760
+ agentId: text("agent_id").notNull(),
21761
+ workspaceId: text("workspace_id").notNull(),
21762
+ fromEmail: text("from_email").notNull(),
21763
+ toEmail: text("to_email").notNull(),
21764
+ subject: text("subject").notNull().default(""),
21765
+ r2Key: text("r2_key").notNull(),
21766
+ isWhitelisted: integer2("is_whitelisted", { mode: "boolean" }).notNull().default(false),
21767
+ forwarded: integer2("forwarded", { mode: "boolean" }).notNull().default(false),
21768
+ messageId: text("message_id").notNull().default(""),
21769
+ inReplyTo: text("in_reply_to").notNull().default(""),
21770
+ references: text("references").notNull().default(""),
21771
+ htmlBody: text("html_body").notNull().default(""),
21772
+ attachments: text("attachments").notNull().default("[]"),
21773
+ status: text("status").notNull().default("unread"),
21774
+ direction: text("direction").notNull().default("inbound"),
21775
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21776
+ }, (t) => [
21777
+ foreignKey({
21778
+ columns: [t.agentId, t.workspaceId],
21779
+ foreignColumns: [agent.id, agent.workspaceId]
21780
+ }).onDelete("cascade"),
21781
+ index("idx_emails_agent_ws_status").on(t.agentId, t.workspaceId, t.status),
21782
+ index("idx_emails_to_direction").on(t.toEmail, t.direction),
21783
+ index("idx_emails_from_direction").on(t.fromEmail, t.direction),
21784
+ index("idx_emails_message_id").on(t.messageId),
21785
+ index("idx_emails_created_at").on(t.createdAt)
21786
+ ]);
21787
+ var calendarEvent = sqliteTable("calendar_event", {
21788
+ id: text("id").primaryKey().$defaultFn(() => "ce_" + nanoid3()),
21789
+ agentId: text("agent_id").notNull(),
21790
+ workspaceId: text("workspace_id").notNull(),
21791
+ title: text("title").notNull(),
21792
+ description: text("description"),
21793
+ scheduledAt: text("scheduled_at").notNull(),
21794
+ repeatInterval: text("repeat_interval"),
21795
+ repeatStopAt: text("repeat_stop_at"),
21796
+ lastTriggeredAt: text("last_triggered_at"),
21797
+ exceptions: text("exceptions", { mode: "json" }).$type().notNull().default(sql`'[]'`),
21798
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
21799
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
21800
+ }, (t) => [
21801
+ index("idx_calendar_event_agent_ws").on(t.agentId, t.workspaceId),
21802
+ index("idx_calendar_event_ws_scheduled").on(t.workspaceId, t.scheduledAt),
21803
+ foreignKey({
21804
+ columns: [t.agentId, t.workspaceId],
21805
+ foreignColumns: [agent.id, agent.workspaceId]
21806
+ }).onDelete("cascade")
21807
+ ]);
21808
+ var artifact = sqliteTable("artifact", {
21809
+ id: text("id").primaryKey().$defaultFn(() => "art_" + nanoid3()),
21810
+ conversationId: text("conversation_id").notNull().references(() => conversation.id, { onDelete: "cascade" }),
21811
+ agentId: text("agent_id").notNull(),
21812
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21813
+ filename: text("filename").notNull(),
21814
+ contentType: text("content_type").notNull().default("application/octet-stream"),
21815
+ size: integer2("size").notNull(),
21816
+ r2Key: text("r2_key").notNull(),
21817
+ thumbnailR2Key: text("thumbnail_r2_key"),
21818
+ source: text("source").notNull().default("agent"),
21819
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21820
+ }, (t) => [
21821
+ index("idx_artifact_conversation").on(t.conversationId),
21822
+ foreignKey({
21823
+ columns: [t.agentId, t.workspaceId],
21824
+ foreignColumns: [agent.id, agent.workspaceId]
21825
+ }).onDelete("cascade")
21826
+ ]);
21827
+ var agentEmailAccount = sqliteTable("agent_email_account", {
21828
+ id: text("id").primaryKey().$defaultFn(() => "aea_" + nanoid3()),
21829
+ agentId: text("agent_id").notNull(),
21830
+ workspaceId: text("workspace_id").notNull(),
21831
+ emailAddress: text("email_address").notNull(),
21832
+ displayName: text("display_name").notNull().default(""),
21833
+ imapHost: text("imap_host").notNull(),
21834
+ imapPort: integer2("imap_port").notNull().default(993),
21835
+ imapUsername: text("imap_username").notNull(),
21836
+ imapPassword: text("imap_password").notNull(),
21837
+ imapTls: integer2("imap_tls", { mode: "boolean" }).notNull().default(true),
21838
+ smtpHost: text("smtp_host").notNull(),
21839
+ smtpPort: integer2("smtp_port").notNull().default(587),
21840
+ smtpUsername: text("smtp_username").notNull(),
21841
+ smtpPassword: text("smtp_password").notNull(),
21842
+ smtpTls: integer2("smtp_tls").notNull().default(1),
21843
+ pollIntervalSeconds: integer2("poll_interval_seconds").notNull().default(60),
21844
+ lastSyncedUid: text("last_synced_uid").notNull().default("0"),
21845
+ lastSyncedAt: text("last_synced_at"),
21846
+ status: text("status").notNull().default("active"),
21847
+ errorMessage: text("error_message").notNull().default(""),
21848
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
21849
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
21850
+ }, (t) => [
21851
+ index("idx_email_account_agent_ws").on(t.agentId, t.workspaceId),
21852
+ unique("email_account_agent_email").on(t.agentId, t.emailAddress),
21853
+ foreignKey({
21854
+ columns: [t.agentId, t.workspaceId],
21855
+ foreignColumns: [agent.id, agent.workspaceId]
21856
+ }).onDelete("cascade")
21857
+ ]);
21858
+ var meetingSession = sqliteTable("meeting_session", {
21859
+ id: text("id").primaryKey().$defaultFn(() => "ms_" + nanoid3()),
21860
+ agentId: text("agent_id").notNull(),
21861
+ workspaceId: text("workspace_id").notNull(),
21862
+ title: text("title").notNull().default(""),
21863
+ meetingUrl: text("meeting_url").notNull(),
21864
+ status: text("status").notNull().default("scheduled"),
21865
+ fromEmail: text("from_email"),
21866
+ isWhitelisted: integer2("is_whitelisted", { mode: "boolean" }).notNull().default(true),
21867
+ participants: text("participants", { mode: "json" }).$type().notNull().default([]),
21868
+ scheduledAt: text("scheduled_at"),
21869
+ startedAt: text("started_at"),
21870
+ completedAt: text("completed_at"),
21871
+ transcriptR2Key: text("transcript_r2_key"),
21872
+ summary: text("summary"),
21873
+ error: text("error"),
21874
+ workerSessionId: text("worker_session_id"),
21875
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
21876
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
21877
+ }, (t) => [
21878
+ index("idx_meeting_session_agent_ws").on(t.agentId, t.workspaceId),
21879
+ index("idx_meeting_session_status").on(t.status),
21880
+ foreignKey({
21881
+ columns: [t.agentId, t.workspaceId],
21882
+ foreignColumns: [agent.id, agent.workspaceId]
21883
+ }).onDelete("cascade")
21884
+ ]);
21885
+ var machineToken = sqliteTable("machine_token", {
21886
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21887
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
21888
+ workspaceId: text("workspace_id").references(() => workspace.id, { onDelete: "cascade" }),
21889
+ token: text("token").unique().notNull(),
21890
+ name: text("name").notNull().default(""),
21891
+ status: text("status").notNull().default("active"),
21892
+ hostname: text("hostname"),
21893
+ runtimesJson: text("runtimes_json"),
21894
+ lastUsedAt: text("last_used_at"),
21895
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21896
+ }, (t) => [index("idx_machine_token").on(t.token)]);
21897
+ var messageFlag = sqliteTable("message_flag", {
21898
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21899
+ messageId: text("message_id").notNull().references(() => message.id, { onDelete: "cascade" }),
21900
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
21901
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21902
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21903
+ }, (t) => [
21904
+ unique("message_flag_message_user").on(t.messageId, t.userId),
21905
+ index("idx_message_flag_ws_user_created").on(t.workspaceId, t.userId, t.createdAt),
21906
+ index("idx_message_flag_message_user").on(t.messageId, t.userId)
21907
+ ]);
21908
+ var conversationMap = sqliteTable("conversation_map", {
21909
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21910
+ key: text("key").notNull(),
21911
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21912
+ conversationId: text("conversation_id").notNull().references(() => conversation.id, { onDelete: "cascade" }),
21913
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21914
+ }, (t) => [
21915
+ unique("conversation_map_key_workspace").on(t.key, t.workspaceId)
21916
+ ]);
21917
+ var agentLink = sqliteTable("agent_link", {
21918
+ id: text("id").primaryKey().$defaultFn(() => "al_" + nanoid3()),
21919
+ workspaceId: text("workspace_id").notNull(),
21920
+ sourceAgentId: text("source_agent_id").notNull(),
21921
+ targetAgentId: text("target_agent_id").notNull(),
21922
+ instruction: text("instruction").notNull().default(""),
21923
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
21924
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
21925
+ }, (t) => [
21926
+ unique("agent_link_ws_source_target").on(t.workspaceId, t.sourceAgentId, t.targetAgentId),
21927
+ index("idx_agent_link_workspace").on(t.workspaceId),
21928
+ foreignKey({
21929
+ columns: [t.sourceAgentId, t.workspaceId],
21930
+ foreignColumns: [agent.id, agent.workspaceId]
21931
+ }).onDelete("cascade"),
21932
+ foreignKey({
21933
+ columns: [t.targetAgentId, t.workspaceId],
21934
+ foreignColumns: [agent.id, agent.workspaceId]
21935
+ }).onDelete("cascade")
21936
+ ]);
21937
+ var conversationReadState = sqliteTable("conversation_read_state", {
21938
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21939
+ conversationId: text("conversation_id").notNull().references(() => conversation.id, { onDelete: "cascade" }),
21940
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
21941
+ lastReadAt: text("last_read_at").notNull().default("1970-01-01T00:00:00.000Z"),
21942
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
21943
+ }, (t) => [
21944
+ unique("conversation_read_state_conv_user").on(t.conversationId, t.userId),
21945
+ index("idx_conversation_read_state_user").on(t.userId)
21946
+ ]);
21947
+ var workspaceFileRequest = sqliteTable("workspace_file_request", {
21948
+ id: text("id").primaryKey().$defaultFn(() => "wfr_" + nanoid3()),
21949
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21950
+ agentId: text("agent_id").notNull(),
21951
+ requestType: text("request_type").notNull(),
21952
+ path: text("path").notNull().default("."),
21953
+ status: text("status").notNull().default("pending"),
21954
+ result: text("result"),
21955
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
21956
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
21957
+ }, (t) => [
21958
+ index("idx_wfr_workspace_status").on(t.workspaceId, t.status)
21959
+ ]);
21960
+ var agentSkill = sqliteTable("agent_skill", {
21961
+ id: text("id").primaryKey().$defaultFn(() => "as_" + nanoid3()),
21962
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
21963
+ agentId: text("agent_id"),
21964
+ daemonId: text("daemon_id"),
21965
+ runtime: text("runtime").notNull(),
21966
+ name: text("name").notNull(),
21967
+ description: text("description").notNull().default(""),
21968
+ syncedAt: text("synced_at").notNull().$defaultFn(() => new Date().toISOString())
21969
+ }, (t) => [
21970
+ unique("agent_skill_ws_runtime_name_agent_daemon").on(t.workspaceId, t.runtime, t.name, t.agentId, t.daemonId),
21971
+ index("idx_as_workspace_runtime").on(t.workspaceId, t.runtime),
21972
+ index("idx_as_agent_runtime").on(t.agentId, t.runtime),
21973
+ foreignKey({
21974
+ columns: [t.agentId, t.workspaceId],
21975
+ foreignColumns: [agent.id, agent.workspaceId]
21976
+ }).onDelete("cascade")
21977
+ ]);
21978
+ var inboxUnread = sqliteTable("inbox_unread", {
21979
+ id: text("id").primaryKey().$defaultFn(() => nanoid3()),
21980
+ conversationId: text("conversation_id").notNull().references(() => conversation.id, { onDelete: "cascade" }),
21981
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
21982
+ workspaceId: text("workspace_id").notNull(),
21983
+ agentId: text("agent_id").notNull(),
21984
+ taskId: text("task_id").notNull(),
21985
+ taskType: text("task_type").notNull(),
21986
+ taskStatus: text("task_status").notNull(),
21987
+ taskPrompt: text("task_prompt"),
21988
+ completedAt: text("completed_at").notNull(),
21989
+ latestMessageId: text("latest_message_id")
21990
+ }, (t) => [
21991
+ unique("inbox_unread_conv_user").on(t.conversationId, t.userId),
21992
+ index("idx_inbox_unread_user_ws").on(t.userId, t.workspaceId, t.taskType, t.completedAt)
21993
+ ]);
21994
+
21995
+ // ../shared/src/db/community-machine-schema.ts
21996
+ var DIAGNOSTIC_REPORT_FAILURE_CODES = [
21997
+ "offline",
21998
+ "timeout",
21999
+ "upload_conflict",
22000
+ "invalid_upload",
22001
+ "diagnostics_unavailable",
22002
+ "collector_busy",
22003
+ "bot_not_bound",
22004
+ "collection_failed",
22005
+ "local_artifact_invalid",
22006
+ "bundle_too_large",
22007
+ "upload_failed",
22008
+ "internal_error"
22009
+ ];
22010
+ var communityDiagnosticReport = sqliteTable("community_diagnostic_report", {
22011
+ id: text("id").primaryKey().$defaultFn(() => "dbr_" + nanoid3()),
22012
+ ownerUserId: text("owner_user_id").notNull(),
22013
+ agentId: text("agent_id").notNull(),
22014
+ machineId: text("machine_id").notNull(),
22015
+ clientNonce: text("client_nonce").notNull(),
22016
+ rateBucket: integer2("rate_bucket").notNull(),
22017
+ status: text("status").$type().notNull().default("pending"),
22018
+ failureCode: text("failure_code").$type(),
22019
+ fromMs: integer2("from_ms").notNull(),
22020
+ createdAt: integer2("created_at").notNull(),
22021
+ deadlineAt: integer2("deadline_at").notNull(),
22022
+ completedAt: integer2("completed_at"),
22023
+ r2Key: text("r2_key"),
22024
+ sha256: text("sha256"),
22025
+ sizeBytes: integer2("size_bytes"),
22026
+ uploadedAt: integer2("uploaded_at"),
22027
+ objectExpiresAt: integer2("object_expires_at")
22028
+ }, (t) => [
22029
+ index("idx_community_diagnostic_report_owner_created").on(t.ownerUserId, t.createdAt),
22030
+ index("idx_community_diagnostic_report_machine_status_deadline").on(t.machineId, t.status, t.deadlineAt),
22031
+ uniqueIndex("uq_community_diagnostic_report_owner_nonce").on(t.ownerUserId, t.clientNonce),
22032
+ uniqueIndex("uq_community_diagnostic_report_owner_agent_pending").on(t.ownerUserId, t.agentId).where(sql`status = 'pending'`),
22033
+ uniqueIndex("uq_community_diagnostic_report_owner_rate_bucket").on(t.ownerUserId, t.rateBucket),
22034
+ check2("ck_community_diagnostic_report_id", sql`length(${t.id}) > 4 AND substr(${t.id}, 1, 4) = 'dbr_' AND ${t.id} NOT GLOB '*[^A-Za-z0-9_-]*'`),
22035
+ check2("ck_community_diagnostic_report_nonce", sql`length(${t.clientNonce}) BETWEEN 16 AND 64 AND ${t.clientNonce} NOT GLOB '*[^A-Za-z0-9_-]*'`),
22036
+ check2("ck_community_diagnostic_report_required_epochs", sql`typeof(${t.fromMs}) = 'integer' AND ${t.fromMs} BETWEEN 0 AND 9007199254740991
22037
+ AND typeof(${t.createdAt}) = 'integer' AND ${t.createdAt} BETWEEN 0 AND 9007199254740991
22038
+ AND typeof(${t.deadlineAt}) = 'integer' AND ${t.deadlineAt} BETWEEN 0 AND 9007199254740991
22039
+ AND ${t.fromMs} = ${t.createdAt} - 86400000
22040
+ AND ${t.deadlineAt} = ${t.createdAt} + 600000`),
22041
+ check2("ck_community_diagnostic_report_rate_bucket", sql`typeof(${t.rateBucket}) = 'integer'
22042
+ AND ${t.rateBucket} BETWEEN 0 AND 9007199254740991
22043
+ AND ${t.rateBucket} = CAST(${t.createdAt} / 60000 AS INTEGER)`),
22044
+ check2("ck_community_diagnostic_report_nullable_epochs", sql`(${t.completedAt} IS NULL OR (typeof(${t.completedAt}) = 'integer' AND ${t.completedAt} BETWEEN 0 AND 9007199254740991))
22045
+ AND (${t.uploadedAt} IS NULL OR (typeof(${t.uploadedAt}) = 'integer' AND ${t.uploadedAt} BETWEEN 0 AND 9007199254740991))
22046
+ AND (${t.objectExpiresAt} IS NULL OR (typeof(${t.objectExpiresAt}) = 'integer' AND ${t.objectExpiresAt} BETWEEN 0 AND 9007199254740991))`),
22047
+ check2("ck_community_diagnostic_report_size", sql`${t.sizeBytes} IS NULL OR (typeof(${t.sizeBytes}) = 'integer' AND ${t.sizeBytes} BETWEEN 1 AND 10485760)`),
22048
+ check2("ck_community_diagnostic_report_sha256", sql`${t.sha256} IS NULL OR (length(${t.sha256}) = 64 AND ${t.sha256} NOT GLOB '*[^0-9a-f]*')`),
22049
+ check2("ck_community_diagnostic_report_state", sql`(
22050
+ ${t.status} = 'pending'
22051
+ AND ${t.failureCode} IS NULL AND ${t.completedAt} IS NULL
22052
+ AND ${t.r2Key} IS NULL AND ${t.sha256} IS NULL AND ${t.sizeBytes} IS NULL
22053
+ AND ${t.uploadedAt} IS NULL AND ${t.objectExpiresAt} IS NULL
22054
+ ) OR (
22055
+ ${t.status} = 'failed'
22056
+ AND ${t.failureCode} IN ('offline', 'timeout', 'upload_conflict', 'invalid_upload', 'diagnostics_unavailable', 'collector_busy', 'bot_not_bound', 'collection_failed', 'local_artifact_invalid', 'bundle_too_large', 'upload_failed', 'internal_error')
22057
+ AND ${t.completedAt} IS NOT NULL
22058
+ AND ${t.completedAt} >= ${t.createdAt}
22059
+ AND ${t.r2Key} IS NULL AND ${t.sha256} IS NULL AND ${t.sizeBytes} IS NULL
22060
+ AND ${t.uploadedAt} IS NULL AND ${t.objectExpiresAt} IS NULL
22061
+ ) OR (
22062
+ ${t.status} = 'uploaded'
22063
+ AND ${t.failureCode} IS NULL AND ${t.completedAt} IS NOT NULL
22064
+ AND ${t.completedAt} >= ${t.createdAt}
22065
+ AND ${t.r2Key} IS NOT NULL
22066
+ AND ${t.r2Key} = 'bug-reports/' || ${t.ownerUserId} || '/' || ${t.id} || '.ndjson.gz'
22067
+ AND ${t.sha256} IS NOT NULL AND ${t.sizeBytes} IS NOT NULL
22068
+ AND ${t.uploadedAt} IS NOT NULL AND ${t.objectExpiresAt} IS NOT NULL
22069
+ AND ${t.completedAt} = ${t.uploadedAt}
22070
+ AND ${t.objectExpiresAt} = ${t.uploadedAt} + 604800000
22071
+ )`)
22072
+ ]);
22073
+ var communityMachineToken = sqliteTable("community_machine_token", {
22074
+ id: text("id").primaryKey().$defaultFn(() => "cmt_" + nanoid3(32)),
22075
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
22076
+ machineId: text("machine_id"),
22077
+ status: text("status").notNull().default("pending"),
22078
+ expiresAt: text("expires_at").notNull(),
22079
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
22080
+ lastUsedAt: text("last_used_at")
22081
+ }, (t) => [
22082
+ index("idx_community_machine_token_user_status").on(t.userId, t.status),
22083
+ uniqueIndex("uq_community_machine_token_user_pending").on(t.userId).where(sql`status = 'pending'`)
22084
+ ]);
22085
+ var communityMachine = sqliteTable("community_machine", {
22086
+ id: text("id").primaryKey().$defaultFn(() => "cm_" + nanoid3()),
22087
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
22088
+ displayName: text("display_name").notNull().default(""),
22089
+ hostname: text("hostname").notNull().default(""),
22090
+ platform: text("platform").notNull().default(""),
22091
+ arch: text("arch").notNull().default(""),
22092
+ osRelease: text("os_release").notNull().default(""),
22093
+ daemonVersion: text("daemon_version").notNull().default(""),
22094
+ metadata: text("metadata"),
22095
+ availableRuntimes: text("available_runtimes", { mode: "json" }).$type().notNull().default([]),
22096
+ status: text("status").notNull().default("offline"),
22097
+ lastSeenAt: text("last_seen_at"),
22098
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
22099
+ updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
22100
+ }, (t) => [
22101
+ index("idx_community_machine_user_last_seen").on(t.userId, t.lastSeenAt),
22102
+ index("idx_community_machine_user_updated").on(t.userId, t.updatedAt),
22103
+ index("idx_community_machine_user_status").on(t.userId, t.status)
22104
+ ]);
22105
+ var communityMachineCredential = sqliteTable("community_machine_credential", {
22106
+ id: text("id").primaryKey().$defaultFn(() => "cmkid_" + nanoid3()),
22107
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
22108
+ machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "cascade" }),
22109
+ credentialHash: text("credential_hash").notNull().unique(),
22110
+ doName: text("do_name").notNull().unique(),
22111
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
22112
+ lastUsedAt: text("last_used_at"),
22113
+ revokedAt: text("revoked_at")
22114
+ }, (t) => [
22115
+ index("idx_community_machine_credential_user").on(t.userId),
22116
+ index("idx_community_machine_credential_machine").on(t.machineId)
22117
+ ]);
22118
+ var communityBotBinding = sqliteTable("community_bot_binding", {
22119
+ userId: text("user_id").primaryKey().references(() => user.id, { onDelete: "cascade" }),
22120
+ machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "restrict" }),
22121
+ runtime: text("runtime").notNull(),
22122
+ modelName: text("model_name"),
22123
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
22124
+ }, (t) => [index("idx_community_bot_binding_machine").on(t.machineId)]);
22125
+ var communityAgentRunnerKey = sqliteTable("community_agent_runner_key", {
22126
+ id: text("id").primaryKey().$defaultFn(() => "crkid_" + nanoid3()),
22127
+ userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
22128
+ machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "cascade" }),
22129
+ agentId: text("agent_id").notNull(),
22130
+ runnerKeyHash: text("runner_key_hash").notNull().unique(),
22131
+ doName: text("do_name").notNull().unique(),
22132
+ createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
22133
+ revokedAt: text("revoked_at")
22134
+ }, (t) => [
22135
+ index("idx_community_agent_runner_key_machine_agent").on(t.machineId, t.agentId)
22136
+ ]);
22137
+
22138
+ // ../shared/src/diagnostics-contract.ts
22139
+ var DIAGNOSTIC_REPORT_COLLECTION_WINDOW_MS = 86400000;
22140
+ var DIAGNOSTIC_REPORT_DEADLINE_WINDOW_MS = 600000;
22141
+ var DIAGNOSTIC_COLLECT_SPAN_MS = DIAGNOSTIC_REPORT_COLLECTION_WINDOW_MS + DIAGNOSTIC_REPORT_DEADLINE_WINDOW_MS;
22142
+ var SafeEpochSchema = exports_external.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
22143
+ var AgentIdSchema = exports_external.string().min(1).regex(/^[A-Za-z0-9_-]+$/);
22144
+ var DiagnosticReportIdSchema = exports_external.string().regex(/^dbr_[A-Za-z0-9_-]+$/);
22145
+ var DiagnosticReportFailureCodeSchema = exports_external.enum(DIAGNOSTIC_REPORT_FAILURE_CODES);
22146
+ var DiagnosticReportCreateRequestSchema = exports_external.object({
22147
+ clientNonce: exports_external.string().min(16).max(64).regex(/^[A-Za-z0-9_-]+$/)
22148
+ }).strict();
22149
+ var DiagnosticCollectPayloadSchema = exports_external.object({
22150
+ reportId: DiagnosticReportIdSchema,
22151
+ agentId: AgentIdSchema,
22152
+ fromMs: SafeEpochSchema,
22153
+ deadlineAt: SafeEpochSchema
22154
+ }).strict();
22155
+ var DiagnosticCollectCommandSchema = exports_external.object({
22156
+ type: exports_external.literal("diagnostics:collect"),
22157
+ reportId: DiagnosticReportIdSchema,
22158
+ agentId: AgentIdSchema,
22159
+ fromMs: SafeEpochSchema,
22160
+ deadlineAt: SafeEpochSchema
22161
+ }).strict().refine((command) => command.deadlineAt - command.fromMs === DIAGNOSTIC_COLLECT_SPAN_MS, { message: "diagnostic collection span must match v1" });
22162
+ var OwnerDiagnosticReportBase = {
22163
+ reportId: DiagnosticReportIdSchema,
22164
+ deadlineAt: SafeEpochSchema
22165
+ };
22166
+ var OwnerDiagnosticReportSchema = exports_external.discriminatedUnion("status", [
22167
+ exports_external.object({
22168
+ ...OwnerDiagnosticReportBase,
22169
+ status: exports_external.literal("pending"),
22170
+ completedAt: exports_external.null(),
22171
+ failureCode: exports_external.null(),
22172
+ objectExpired: exports_external.literal(false)
22173
+ }).strict(),
22174
+ exports_external.object({
22175
+ ...OwnerDiagnosticReportBase,
22176
+ status: exports_external.literal("uploaded"),
22177
+ completedAt: SafeEpochSchema,
22178
+ failureCode: exports_external.null(),
22179
+ objectExpired: exports_external.boolean()
22180
+ }).strict(),
22181
+ exports_external.object({
22182
+ ...OwnerDiagnosticReportBase,
22183
+ status: exports_external.literal("failed"),
22184
+ completedAt: SafeEpochSchema,
22185
+ failureCode: DiagnosticReportFailureCodeSchema,
22186
+ objectExpired: exports_external.literal(false)
22187
+ }).strict()
22188
+ ]);
22189
+
22190
+ // ../shared/src/community-cli-contract.ts
22191
+ var HostCommandSchema = exports_external.discriminatedUnion("type", [
22192
+ exports_external.object({
22193
+ type: exports_external.literal("agent:wake"),
22194
+ agentId: exports_external.string().min(1),
22195
+ config: exports_external.unknown(),
22196
+ sessionId: exports_external.string().optional(),
22197
+ launchId: exports_external.string().min(1),
22198
+ unreadNotice: exports_external.unknown()
22199
+ }),
22200
+ exports_external.object({
22201
+ type: exports_external.literal("agent:stop"),
22202
+ agentId: exports_external.string().min(1)
22203
+ }),
22204
+ exports_external.object({
22205
+ type: exports_external.literal("agent:reset"),
22206
+ agentId: exports_external.string().min(1),
22207
+ config: exports_external.unknown(),
22208
+ launchId: exports_external.string().min(1)
22209
+ }),
22210
+ exports_external.object({
22211
+ type: exports_external.literal("agent:nap"),
22212
+ agentId: exports_external.string().min(1),
22213
+ config: exports_external.unknown(),
22214
+ launchId: exports_external.string().min(1),
22215
+ handoff: exports_external.string().min(1)
22216
+ }),
22217
+ exports_external.object({
22218
+ type: exports_external.literal("agent:model_switch"),
22219
+ agentId: exports_external.string().min(1),
22220
+ config: exports_external.unknown(),
22221
+ launchId: exports_external.string().min(1)
22222
+ }),
22223
+ exports_external.object({
22224
+ type: exports_external.literal("machine:reset_all"),
22225
+ resets: exports_external.array(exports_external.object({
22226
+ agentId: exports_external.string().min(1),
22227
+ config: exports_external.unknown(),
22228
+ launchId: exports_external.string().min(1)
22229
+ }))
22230
+ }),
22231
+ exports_external.object({
22232
+ type: exports_external.literal("bot:added"),
22233
+ botId: exports_external.string().min(1),
22234
+ name: exports_external.string().optional(),
22235
+ discriminator: exports_external.string().optional(),
22236
+ description: exports_external.string().optional(),
22237
+ ownerName: exports_external.string().optional(),
22238
+ ownerDiscriminator: exports_external.string().optional()
22239
+ }),
22240
+ exports_external.object({
22241
+ type: exports_external.literal("bot:updated"),
22242
+ botId: exports_external.string().min(1),
22243
+ name: exports_external.string().optional(),
22244
+ discriminator: exports_external.string().optional(),
22245
+ description: exports_external.string().optional(),
22246
+ ownerName: exports_external.string().optional(),
22247
+ ownerDiscriminator: exports_external.string().optional()
22248
+ }),
22249
+ exports_external.object({
22250
+ type: exports_external.literal("bot:removed"),
22251
+ botId: exports_external.string().min(1)
22252
+ }),
22253
+ DiagnosticCollectCommandSchema
22254
+ ]);
22255
+ // src/server/wsControlChannel.ts
22256
+ var WS_CONTROL_COMMAND_CONSUMED = Symbol("ws-control-command-consumed");
22257
+ var DEFAULT_PING_INTERVAL_MS = 15000;
22258
+ var DEFAULT_PONG_TIMEOUT_MS = 30000;
22259
+ var DEFAULT_RECONNECT_BASE_MS = 500;
22260
+ var DEFAULT_RECONNECT_MAX_MS = 30000;
22261
+ function describeErr(err) {
22262
+ return err instanceof Error ? err.message : String(err);
22263
+ }
22264
+
22265
+ class WsControlChannel {
22266
+ opts;
22267
+ statusValue = "idle";
22268
+ commandCbs = [];
22269
+ resyncHooks = [];
22270
+ ws = null;
22271
+ attempt = 0;
22272
+ closedByUser = false;
22273
+ authRejected = false;
22274
+ pingTimer = null;
22275
+ pongDeadline = 0;
22276
+ resyncProvider = null;
22277
+ log;
22278
+ constructor(opts) {
22279
+ this.opts = opts;
22280
+ this.log = opts.logger ?? createLogger({ header: "@alook/daemon:ws" });
22281
+ }
22282
+ get status() {
22283
+ return this.statusValue;
22284
+ }
22285
+ connect() {
22286
+ this.closedByUser = false;
22287
+ this.authRejected = false;
22288
+ this.openSocket();
22289
+ }
22290
+ close() {
22291
+ this.closedByUser = true;
22292
+ this.clearHeartbeat();
22293
+ this.ws?.close();
22294
+ this.ws = null;
22295
+ this.statusValue = "closed";
22296
+ }
22297
+ onCommand(cb) {
22298
+ this.commandCbs.push(cb);
22299
+ }
22300
+ onResync(provider) {
22301
+ this.resyncProvider = provider;
22302
+ }
22303
+ onOpen(hook) {
22304
+ this.resyncHooks.push(hook);
22305
+ }
22306
+ async reportReady(ready) {
22307
+ this.sendFrame({ type: "ready", ...ready });
22308
+ }
22309
+ sendReady(ready) {
22310
+ this.sendFrame({ type: "ready", ...ready });
22311
+ }
22312
+ async reportAgentSession(info) {
22313
+ this.sendFrame({ type: "agent_session", ...info });
22314
+ }
22315
+ async reportAgentActivity(info) {
22316
+ this.sendFrame({ type: "agent_activity", ...info });
22317
+ }
22318
+ reportAgentTyping(info) {
22319
+ this.sendFrame({ type: "agent_typing", ...info });
22320
+ }
22321
+ reportAgentTypingStop(info) {
22322
+ this.sendFrame({ type: "agent_typing_stop", ...info });
22323
+ }
22324
+ async reportBotAuditEvent(frame) {
22325
+ this.sendFrame(frame);
22326
+ }
22327
+ async reportWakeAck(info) {
22328
+ this.sendFrame({ type: "agent_wake_ack", ...info });
22329
+ }
22330
+ async reportStoppedAck(info) {
22331
+ this.sendFrame({ type: "agent_stopped_ack", ...info });
22332
+ }
22333
+ async reportSessionError(frame) {
22334
+ this.sendFrame(frame);
22335
+ }
22336
+ sendFrame(frame) {
22337
+ if (this.statusValue !== "open" || !this.ws) {
22338
+ this.log.debug("frame dropped — socket not open", { type: frame.type });
22339
+ return;
22340
+ }
22341
+ this.ws.send(JSON.stringify(frame));
22342
+ }
22343
+ resyncOnConnect() {
19765
22344
  if (this.resyncProvider) {
19766
22345
  const { ready, sessions, activities } = this.resyncProvider();
19767
22346
  this.sendFrame({ type: "ready", ...ready });
@@ -19828,7 +22407,10 @@ class WsControlChannel {
19828
22407
  const cmd = parsed.data;
19829
22408
  for (const cb of this.commandCbs) {
19830
22409
  try {
19831
- Promise.resolve(cb(cmd)).catch((err) => {
22410
+ const result = cb(cmd);
22411
+ if (result === WS_CONTROL_COMMAND_CONSUMED)
22412
+ break;
22413
+ Promise.resolve(result).catch((err) => {
19832
22414
  this.log.warn("command listener threw", { type: cmd.type, err: describeErr(err) });
19833
22415
  });
19834
22416
  } catch (err) {
@@ -19888,8 +22470,9 @@ class WsControlChannel {
19888
22470
  }
19889
22471
  }
19890
22472
  // src/timeline/timeline.ts
19891
- import { appendFileSync as appendFileSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync6, renameSync as renameSync3, existsSync as existsSync6 } from "fs";
19892
- import { join as join9 } from "path";
22473
+ import * as fs7 from "node:fs";
22474
+ import { randomBytes as randomBytes2 } from "node:crypto";
22475
+ import { basename, dirname as dirname2, join as join9 } from "node:path";
19893
22476
 
19894
22477
  // src/timeline/filelock.ts
19895
22478
  import * as fs6 from "fs";
@@ -19952,6 +22535,261 @@ function reclaim(lockPath) {
19952
22535
  }
19953
22536
 
19954
22537
  // src/timeline/timeline.ts
22538
+ var TIMELINE_MAX_BYTES = 1048576;
22539
+ var TIMELINE_READ_CHUNK_BYTES = 65536;
22540
+ var DATE_FILENAME_PATTERN = /^\d{4}-\d{2}-\d{2}\.jsonl$/;
22541
+ function isBarrier(entry) {
22542
+ return entry.system?.type === "reset_session" || entry.system?.type === "nap";
22543
+ }
22544
+ function canonicalTimelineEntry(value) {
22545
+ if (!value || typeof value !== "object")
22546
+ return null;
22547
+ const entry = value;
22548
+ if (entry.system) {
22549
+ if (entry.system.type !== "reset_session" && entry.system.type !== "nap" || typeof entry.system.time !== "string")
22550
+ return null;
22551
+ return createSystemEntry(entry.system.type, entry.system.time);
22552
+ }
22553
+ if (entry.session_id !== null && typeof entry.session_id !== "string")
22554
+ return null;
22555
+ if (entry.provider !== null && typeof entry.provider !== "string")
22556
+ return null;
22557
+ if (!Array.isArray(entry.messages) || !Array.isArray(entry.agent_responses))
22558
+ return null;
22559
+ if (!entry.agent_responses.every((response) => typeof response === "string"))
22560
+ return null;
22561
+ return {
22562
+ session_id: entry.session_id,
22563
+ messages: entry.messages,
22564
+ agent_responses: entry.agent_responses.slice(-5),
22565
+ provider: entry.provider
22566
+ };
22567
+ }
22568
+ function timelineLine(entry) {
22569
+ const boundedEntry = entry.system ? createSystemEntry(entry.system.type, entry.system.time) : { ...entry, agent_responses: entry.agent_responses.slice(-5) };
22570
+ const text2 = JSON.stringify(boundedEntry);
22571
+ const bytes = Buffer.byteLength(text2, "utf8") + 1;
22572
+ if (bytes > TIMELINE_MAX_BYTES)
22573
+ return null;
22574
+ return { text: text2, bytes, entry: boundedEntry, barrier: isBarrier(boundedEntry) };
22575
+ }
22576
+ function compactLines(input) {
22577
+ let head = 0;
22578
+ let bytes = input.reduce((total, line) => total + line.bytes, 0);
22579
+ let latestEvictedBarrier = null;
22580
+ while (bytes > TIMELINE_MAX_BYTES && head < input.length) {
22581
+ const removed = input[head++];
22582
+ bytes -= removed.bytes;
22583
+ if (removed.barrier)
22584
+ latestEvictedBarrier = removed;
22585
+ }
22586
+ let suffix = input.slice(head);
22587
+ if (!suffix.some((line) => line.barrier) && latestEvictedBarrier) {
22588
+ let suffixHead = 0;
22589
+ while (latestEvictedBarrier.bytes + bytes > TIMELINE_MAX_BYTES && suffixHead < suffix.length) {
22590
+ bytes -= suffix[suffixHead++].bytes;
22591
+ }
22592
+ suffix = [latestEvictedBarrier, ...suffix.slice(suffixHead)];
22593
+ }
22594
+ return suffix;
22595
+ }
22596
+ function isRealDirectory(path8) {
22597
+ try {
22598
+ return fs7.lstatSync(path8).isDirectory();
22599
+ } catch {
22600
+ return false;
22601
+ }
22602
+ }
22603
+ function timelineDirectoryState(timelineDir) {
22604
+ if (!isRealDirectory(dirname2(timelineDir)))
22605
+ return "unsafe";
22606
+ try {
22607
+ return fs7.lstatSync(timelineDir).isDirectory() ? "safe" : "unsafe";
22608
+ } catch (error51) {
22609
+ return error51.code === "ENOENT" ? "missing" : "unsafe";
22610
+ }
22611
+ }
22612
+ function prepareTimelineDirectory(timelineDir) {
22613
+ const state = timelineDirectoryState(timelineDir);
22614
+ if (state === "safe")
22615
+ return true;
22616
+ if (state === "unsafe")
22617
+ return false;
22618
+ try {
22619
+ fs7.mkdirSync(timelineDir);
22620
+ } catch (error51) {
22621
+ if (error51.code !== "EEXIST")
22622
+ return false;
22623
+ }
22624
+ return timelineDirectoryState(timelineDir) === "safe";
22625
+ }
22626
+ function scanTimelineFile(filePath) {
22627
+ let source;
22628
+ try {
22629
+ source = fs7.lstatSync(filePath);
22630
+ } catch (error51) {
22631
+ return error51.code === "ENOENT" ? [] : null;
22632
+ }
22633
+ if (!source.isFile())
22634
+ return null;
22635
+ let fd = null;
22636
+ try {
22637
+ fd = fs7.openSync(filePath, fs7.constants.O_RDONLY | (fs7.constants.O_NOFOLLOW ?? 0));
22638
+ const stat = fs7.fstatSync(fd);
22639
+ if (!stat.isFile())
22640
+ return null;
22641
+ const chunk = Buffer.allocUnsafe(TIMELINE_READ_CHUNK_BYTES);
22642
+ const newest = [];
22643
+ let retainedBytes = 0;
22644
+ let overflowed = false;
22645
+ let suffixHasBarrier = false;
22646
+ let latestEvictedBarrier = null;
22647
+ let parts = [];
22648
+ let partBytes = 0;
22649
+ let oversized = false;
22650
+ let stop = false;
22651
+ let discardIncompleteTail = false;
22652
+ if (stat.size > 0) {
22653
+ const last = Buffer.allocUnsafe(1);
22654
+ fs7.readSync(fd, last, 0, 1, stat.size - 1);
22655
+ discardIncompleteTail = last[0] !== 10;
22656
+ }
22657
+ const resetPhysicalLine = () => {
22658
+ parts = [];
22659
+ partBytes = 0;
22660
+ oversized = false;
22661
+ };
22662
+ const addPart = (part) => {
22663
+ if (oversized)
22664
+ return;
22665
+ if (partBytes + part.length > TIMELINE_MAX_BYTES) {
22666
+ parts = [];
22667
+ partBytes = 0;
22668
+ oversized = true;
22669
+ return;
22670
+ }
22671
+ if (part.length > 0)
22672
+ parts.push(Buffer.from(part));
22673
+ partBytes += part.length;
22674
+ };
22675
+ const retain = (line) => {
22676
+ if (!overflowed && retainedBytes + line.bytes <= TIMELINE_MAX_BYTES) {
22677
+ newest.push(line);
22678
+ retainedBytes += line.bytes;
22679
+ if (line.barrier)
22680
+ suffixHasBarrier = true;
22681
+ return;
22682
+ }
22683
+ overflowed = true;
22684
+ if (suffixHasBarrier) {
22685
+ stop = true;
22686
+ } else if (line.barrier) {
22687
+ latestEvictedBarrier = line;
22688
+ stop = true;
22689
+ }
22690
+ };
22691
+ const finishPhysicalLine = (part) => {
22692
+ addPart(part);
22693
+ if (discardIncompleteTail) {
22694
+ discardIncompleteTail = false;
22695
+ resetPhysicalLine();
22696
+ return;
22697
+ }
22698
+ if (!oversized && partBytes > 0) {
22699
+ let physical = Buffer.concat([...parts].reverse(), partBytes);
22700
+ if (physical[physical.length - 1] === 13)
22701
+ physical = physical.subarray(0, -1);
22702
+ if (physical.length > 0) {
22703
+ try {
22704
+ const entry = canonicalTimelineEntry(JSON.parse(physical.toString("utf8")));
22705
+ const line = entry ? timelineLine(entry) : null;
22706
+ if (line)
22707
+ retain(line);
22708
+ } catch {}
22709
+ }
22710
+ }
22711
+ resetPhysicalLine();
22712
+ };
22713
+ let position = stat.size;
22714
+ while (position > 0 && !stop) {
22715
+ const start = Math.max(0, position - chunk.length);
22716
+ const requested = position - start;
22717
+ let count = 0;
22718
+ while (count < requested) {
22719
+ const read = fs7.readSync(fd, chunk, count, requested - count, start + count);
22720
+ if (read <= 0)
22721
+ break;
22722
+ count += read;
22723
+ }
22724
+ if (count !== requested)
22725
+ return null;
22726
+ let segmentEnd = count;
22727
+ for (let index2 = count - 1;index2 >= 0; index2--) {
22728
+ if (chunk[index2] !== 10)
22729
+ continue;
22730
+ finishPhysicalLine(chunk.subarray(index2 + 1, segmentEnd));
22731
+ segmentEnd = index2;
22732
+ if (stop)
22733
+ break;
22734
+ }
22735
+ if (!stop && segmentEnd > 0)
22736
+ addPart(chunk.subarray(0, segmentEnd));
22737
+ position = start;
22738
+ }
22739
+ if (!stop && position === 0 && (parts.length > 0 || oversized) && !discardIncompleteTail) {
22740
+ finishPhysicalLine(Buffer.alloc(0));
22741
+ }
22742
+ const sentinel = latestEvictedBarrier;
22743
+ if (sentinel && !suffixHasBarrier) {
22744
+ while (newest.length > 0 && sentinel.bytes + retainedBytes > TIMELINE_MAX_BYTES) {
22745
+ retainedBytes -= newest.pop().bytes;
22746
+ }
22747
+ }
22748
+ const chronological = newest.reverse();
22749
+ return sentinel && !suffixHasBarrier ? [sentinel, ...chronological] : chronological;
22750
+ } catch {
22751
+ return null;
22752
+ } finally {
22753
+ if (fd !== null) {
22754
+ try {
22755
+ fs7.closeSync(fd);
22756
+ } catch {}
22757
+ }
22758
+ }
22759
+ }
22760
+ function atomicReplaceTimeline(filePath, lines) {
22761
+ const tempPath = join9(dirname2(filePath), `.${basename(filePath)}.${process.pid}.${randomBytes2(12).toString("hex")}.tmp`);
22762
+ let fd = null;
22763
+ try {
22764
+ fd = fs7.openSync(tempPath, "wx", 384);
22765
+ const body = lines.map((line) => line.text).join(`
22766
+ `) + (lines.length > 0 ? `
22767
+ ` : "");
22768
+ fs7.writeFileSync(fd, body, "utf8");
22769
+ fs7.fsyncSync(fd);
22770
+ fs7.closeSync(fd);
22771
+ fd = null;
22772
+ fs7.renameSync(tempPath, filePath);
22773
+ return true;
22774
+ } catch {
22775
+ return false;
22776
+ } finally {
22777
+ if (fd !== null) {
22778
+ try {
22779
+ fs7.closeSync(fd);
22780
+ } catch {}
22781
+ }
22782
+ try {
22783
+ fs7.unlinkSync(tempPath);
22784
+ } catch {}
22785
+ }
22786
+ }
22787
+ function writeRequiredTimeline(filePath, input, required2) {
22788
+ const compacted = compactLines(input);
22789
+ if (!compacted.includes(required2))
22790
+ return false;
22791
+ return atomicReplaceTimeline(filePath, compacted);
22792
+ }
19955
22793
  function filenameForDate(date5) {
19956
22794
  const y = date5.getFullYear();
19957
22795
  const m = String(date5.getMonth() + 1).padStart(2, "0");
@@ -19968,24 +22806,11 @@ function recentFilenames(maxDays, now) {
19968
22806
  return out;
19969
22807
  }
19970
22808
  function readJsonl(filePath) {
19971
- let content;
19972
- try {
19973
- content = readFileSync4(filePath, "utf-8");
19974
- } catch {
19975
- return [];
19976
- }
19977
- const entries = [];
19978
- for (const line of content.trimEnd().split(`
19979
- `)) {
19980
- if (!line)
19981
- continue;
19982
- try {
19983
- entries.push(JSON.parse(line));
19984
- } catch {}
19985
- }
19986
- return entries;
22809
+ return scanTimelineFile(filePath)?.map((line) => line.entry) ?? [];
19987
22810
  }
19988
22811
  function readRecentEntries(timelineDir, opts = {}) {
22812
+ if (timelineDirectoryState(timelineDir) !== "safe")
22813
+ return [];
19989
22814
  const now = opts.now ?? new Date;
19990
22815
  const maxDays = opts.maxDays ?? 7;
19991
22816
  const filenames = recentFilenames(maxDays, now).reverse();
@@ -19996,15 +22821,19 @@ function readRecentEntries(timelineDir, opts = {}) {
19996
22821
  return entries;
19997
22822
  }
19998
22823
  function appendEntry(timelineDir, entry, now = new Date) {
22824
+ if (timelineDirectoryState(timelineDir) !== "safe")
22825
+ return false;
19999
22826
  const filename = filenameForDate(now);
20000
22827
  const filePath = join9(timelineDir, filename);
20001
22828
  const lockPath = lockPathFor(timelineDir, filename);
20002
22829
  if (!acquireLock(lockPath))
20003
22830
  return false;
20004
22831
  try {
20005
- appendFileSync2(filePath, JSON.stringify(entry) + `
20006
- `);
20007
- return true;
22832
+ const existing = scanTimelineFile(filePath);
22833
+ const required2 = timelineLine(entry);
22834
+ if (!existing || !required2)
22835
+ return false;
22836
+ return writeRequiredTimeline(filePath, [...existing, required2], required2);
20008
22837
  } catch {
20009
22838
  return false;
20010
22839
  } finally {
@@ -20012,77 +22841,147 @@ function appendEntry(timelineDir, entry, now = new Date) {
20012
22841
  }
20013
22842
  }
20014
22843
  function appendOrMergeEntry(timelineDir, entry, now = new Date) {
22844
+ if (timelineDirectoryState(timelineDir) !== "safe")
22845
+ return false;
20015
22846
  const filename = filenameForDate(now);
20016
22847
  const filePath = join9(timelineDir, filename);
20017
22848
  const lockPath = lockPathFor(timelineDir, filename);
20018
22849
  if (!acquireLock(lockPath))
20019
22850
  return false;
20020
22851
  try {
20021
- let lines = [];
20022
- if (existsSync6(filePath)) {
20023
- lines = readFileSync4(filePath, "utf-8").trimEnd().split(`
20024
- `).filter(Boolean);
20025
- }
20026
- if (lines.length > 0) {
20027
- const latest = JSON.parse(lines[lines.length - 1]);
22852
+ const existing = scanTimelineFile(filePath);
22853
+ if (!existing)
22854
+ return false;
22855
+ if (existing.length > 0) {
22856
+ const latest = existing[existing.length - 1].entry;
20028
22857
  const mergeable = !latest.system && !entry.system && latest.session_id === entry.session_id && latest.provider === entry.provider && latest.agent_responses.length === 0;
20029
22858
  if (mergeable) {
20030
- latest.messages = [...latest.messages, ...entry.messages];
20031
- lines[lines.length - 1] = JSON.stringify(latest);
20032
- const tmpPath = join9(timelineDir, `.${filename}.tmp`);
20033
- writeFileSync6(tmpPath, lines.join(`
20034
- `) + `
20035
- `);
20036
- renameSync3(tmpPath, filePath);
20037
- return true;
22859
+ const merged = {
22860
+ ...latest,
22861
+ messages: [...latest.messages, ...entry.messages],
22862
+ agent_responses: [...latest.agent_responses]
22863
+ };
22864
+ const required3 = timelineLine(merged);
22865
+ if (!required3)
22866
+ return false;
22867
+ return writeRequiredTimeline(filePath, [...existing.slice(0, -1), required3], required3);
20038
22868
  }
20039
22869
  }
20040
- appendFileSync2(filePath, JSON.stringify(entry) + `
20041
- `);
20042
- return true;
22870
+ const required2 = timelineLine(entry);
22871
+ if (!required2)
22872
+ return false;
22873
+ return writeRequiredTimeline(filePath, [...existing, required2], required2);
20043
22874
  } catch {
20044
22875
  return false;
20045
22876
  } finally {
20046
22877
  releaseLock(lockPath);
20047
22878
  }
20048
22879
  }
20049
- function updateLatestEntry(timelineDir, updater, opts = {}) {
22880
+ function updateLatestEntryResult(timelineDir, updater, opts = {}) {
22881
+ const directoryState = timelineDirectoryState(timelineDir);
22882
+ if (directoryState !== "safe")
22883
+ return directoryState === "missing" ? "missing" : "rejected";
20050
22884
  const now = opts.now ?? new Date;
20051
22885
  const maxDays = opts.maxDays ?? 7;
20052
22886
  for (const filename of recentFilenames(maxDays, now)) {
20053
22887
  const filePath = join9(timelineDir, filename);
20054
- if (!existsSync6(filePath))
20055
- continue;
22888
+ let source;
22889
+ try {
22890
+ source = fs7.lstatSync(filePath);
22891
+ } catch (error51) {
22892
+ if (error51.code === "ENOENT")
22893
+ continue;
22894
+ return "rejected";
22895
+ }
22896
+ if (!source.isFile())
22897
+ return "rejected";
20056
22898
  const lockPath = lockPathFor(timelineDir, filename);
20057
22899
  if (!acquireLock(lockPath))
22900
+ return "rejected";
22901
+ try {
22902
+ const lines = scanTimelineFile(filePath);
22903
+ if (!lines)
22904
+ return "rejected";
22905
+ if (lines.length === 0)
22906
+ continue;
22907
+ const latest = lines[lines.length - 1].entry;
22908
+ if (latest.system)
22909
+ return "missing";
22910
+ const updated = {
22911
+ ...latest,
22912
+ messages: [...latest.messages],
22913
+ agent_responses: [...latest.agent_responses]
22914
+ };
22915
+ try {
22916
+ updater(updated);
22917
+ } catch {
22918
+ return "rejected";
22919
+ }
22920
+ const required2 = timelineLine(updated);
22921
+ if (!required2)
22922
+ return "rejected";
22923
+ return writeRequiredTimeline(filePath, [...lines.slice(0, -1), required2], required2) ? "updated" : "rejected";
22924
+ } catch {
22925
+ return "rejected";
22926
+ } finally {
22927
+ releaseLock(lockPath);
22928
+ }
22929
+ }
22930
+ return "missing";
22931
+ }
22932
+ function yieldToEventLoop() {
22933
+ return new Promise((resolve3) => setImmediate(resolve3));
22934
+ }
22935
+ async function sweepTimelineHistory(workingDirectoryBase, opts = {}) {
22936
+ const yieldAfterFile = opts.yieldAfterFile ?? (() => yieldToEventLoop());
22937
+ if (!opts.yieldAfterFile)
22938
+ await yieldToEventLoop();
22939
+ if (!isRealDirectory(workingDirectoryBase))
22940
+ return;
22941
+ let agentNames;
22942
+ try {
22943
+ agentNames = fs7.readdirSync(workingDirectoryBase).sort();
22944
+ } catch {
22945
+ return;
22946
+ }
22947
+ for (const agentName of agentNames) {
22948
+ const agentDir = join9(workingDirectoryBase, agentName);
22949
+ if (!isRealDirectory(agentDir))
20058
22950
  continue;
22951
+ const timelineDir = join9(agentDir, ".context_timeline");
22952
+ if (!isRealDirectory(timelineDir))
22953
+ continue;
22954
+ let filenames;
20059
22955
  try {
20060
- let content;
22956
+ filenames = fs7.readdirSync(timelineDir).filter((name) => DATE_FILENAME_PATTERN.test(name)).sort();
22957
+ } catch {
22958
+ continue;
22959
+ }
22960
+ for (const filename of filenames) {
22961
+ const filePath = join9(timelineDir, filename);
22962
+ let source;
20061
22963
  try {
20062
- content = readFileSync4(filePath, "utf-8");
22964
+ source = fs7.lstatSync(filePath);
20063
22965
  } catch {
20064
22966
  continue;
20065
22967
  }
20066
- const lines = content.trimEnd().split(`
20067
- `).filter(Boolean);
20068
- if (lines.length === 0)
22968
+ if (!source.isFile())
20069
22969
  continue;
20070
- const entries = lines.map((l) => JSON.parse(l));
20071
- const latest = entries[entries.length - 1];
20072
- if (latest.system)
20073
- return false;
20074
- updater(latest);
20075
- const tmpPath = join9(timelineDir, `.${filename}.tmp`);
20076
- writeFileSync6(tmpPath, entries.map((e) => JSON.stringify(e)).join(`
20077
- `) + `
20078
- `);
20079
- renameSync3(tmpPath, filePath);
20080
- return true;
20081
- } catch {} finally {
20082
- releaseLock(lockPath);
22970
+ try {
22971
+ const lockPath = lockPathFor(timelineDir, filename);
22972
+ if (acquireLock(lockPath)) {
22973
+ try {
22974
+ const lines = scanTimelineFile(filePath);
22975
+ if (lines)
22976
+ atomicReplaceTimeline(filePath, lines);
22977
+ } finally {
22978
+ releaseLock(lockPath);
22979
+ }
22980
+ }
22981
+ } catch {}
22982
+ await yieldAfterFile(filePath);
20083
22983
  }
20084
22984
  }
20085
- return false;
20086
22985
  }
20087
22986
  function createTimelineEntry(fields) {
20088
22987
  return {
@@ -20115,7 +23014,13 @@ function findResumableSession(rows, provider) {
20115
23014
  return null;
20116
23015
  }
20117
23016
  // src/timeline/recorder.ts
20118
- import { mkdirSync as mkdirSync5 } from "fs";
23017
+ var MAX_AGENT_RESPONSES = 5;
23018
+ function appendAgentResponse(entry, text2) {
23019
+ entry.agent_responses.push(text2);
23020
+ if (entry.agent_responses.length > MAX_AGENT_RESPONSES) {
23021
+ entry.agent_responses.splice(0, entry.agent_responses.length - MAX_AGENT_RESPONSES);
23022
+ }
23023
+ }
20119
23024
  function createTimelineRecorder(opts) {
20120
23025
  const now = opts.now ?? (() => new Date);
20121
23026
  const dirFor = (agentId) => opts.timelineDirFor(agentId);
@@ -20126,29 +23031,27 @@ function createTimelineRecorder(opts) {
20126
23031
  },
20127
23032
  appendEntryForAgent(agentId, messages) {
20128
23033
  const dir = dirFor(agentId);
20129
- try {
20130
- mkdirSync5(dir, { recursive: true });
20131
- } catch {}
23034
+ if (!prepareTimelineDirectory(dir))
23035
+ return;
20132
23036
  appendOrMergeEntry(dir, createTimelineEntry({
20133
23037
  messages,
20134
23038
  sessionId: sessionByAgent.get(agentId) ?? null,
20135
23039
  provider: opts.providerFor?.(agentId) ?? null
20136
23040
  }), now());
20137
23041
  },
20138
- appendResponseToLatest(agentId, text) {
23042
+ appendResponseToLatest(agentId, text2) {
20139
23043
  const dir = dirFor(agentId);
20140
- const updated = updateLatestEntry(dir, (e) => e.agent_responses.push(text), { now: now() });
20141
- if (updated)
23044
+ if (!prepareTimelineDirectory(dir))
23045
+ return;
23046
+ const result = updateLatestEntryResult(dir, (entry2) => appendAgentResponse(entry2, text2), { now: now() });
23047
+ if (result === "updated" || result === "rejected")
20142
23048
  return;
20143
- try {
20144
- mkdirSync5(dir, { recursive: true });
20145
- } catch {}
20146
23049
  const entry = createTimelineEntry({
20147
23050
  messages: [],
20148
23051
  sessionId: sessionByAgent.get(agentId) ?? null,
20149
23052
  provider: opts.providerFor?.(agentId) ?? null
20150
23053
  });
20151
- entry.agent_responses.push(text);
23054
+ appendAgentResponse(entry, text2);
20152
23055
  appendEntry(dir, entry, now());
20153
23056
  },
20154
23057
  resumeSessionId(agentId, provider) {
@@ -20157,10 +23060,9 @@ function createTimelineRecorder(opts) {
20157
23060
  },
20158
23061
  forgetSession(agentId, barrierType = "reset_session") {
20159
23062
  const dir = dirFor(agentId);
20160
- try {
20161
- mkdirSync5(dir, { recursive: true });
20162
- } catch {}
20163
23063
  sessionByAgent.delete(agentId);
23064
+ if (!prepareTimelineDirectory(dir))
23065
+ return;
20164
23066
  const stamp = now();
20165
23067
  appendEntry(dir, createSystemEntry(barrierType, stamp.toISOString()), stamp);
20166
23068
  }
@@ -20168,13 +23070,13 @@ function createTimelineRecorder(opts) {
20168
23070
  }
20169
23071
  // src/discovery.ts
20170
23072
  import * as path8 from "path";
20171
- import * as fs7 from "fs";
23073
+ import * as fs8 from "fs";
20172
23074
  import { fileURLToPath } from "url";
20173
23075
  var SELECTABLE_RUNTIMES = new Set(["claude", "codex", "opencode", "pi", "cursor"]);
20174
23076
  function resolveAlookCliPath(moduleDir) {
20175
23077
  const thisDir = moduleDir ?? path8.dirname(fileURLToPath(import.meta.url));
20176
23078
  const target = path8.basename(thisDir) === "dist" ? path8.resolve(thisDir, "cli", "index.js") : path8.resolve(thisDir, "..", "scripts", "alook-shim.mjs");
20177
- return fs7.existsSync(target) ? target : null;
23079
+ return fs8.existsSync(target) ? target : null;
20178
23080
  }
20179
23081
  function deriveCliFallbackCandidates(cliPath) {
20180
23082
  if (!cliPath)
@@ -20192,12 +23094,12 @@ function deriveCliFallbackCandidates(cliPath) {
20192
23094
  }
20193
23095
  function resolveAlookCliPathWithFallback(primary) {
20194
23096
  const resolved = primary ?? resolveAlookCliPath();
20195
- if (resolved && fs7.existsSync(resolved))
23097
+ if (resolved && fs8.existsSync(resolved))
20196
23098
  return resolved;
20197
23099
  if (resolved) {
20198
23100
  const fallbacks = deriveCliFallbackCandidates(resolved);
20199
23101
  for (const fallback of fallbacks) {
20200
- if (fs7.existsSync(fallback))
23102
+ if (fs8.existsSync(fallback))
20201
23103
  return fallback;
20202
23104
  }
20203
23105
  }
@@ -20236,7 +23138,7 @@ async function getAvailableRuntimes() {
20236
23138
  }
20237
23139
 
20238
23140
  // src/drivers/piSdkDeps.ts
20239
- import { readFileSync as readFileSync5 } from "fs";
23141
+ import { readFileSync as readFileSync4 } from "fs";
20240
23142
  import * as path9 from "path";
20241
23143
  import { pathToFileURL } from "url";
20242
23144
  var PI_SDK_PACKAGE_NAME2 = "@earendil-works/pi-coding-agent";
@@ -20246,7 +23148,7 @@ async function importPiSdkFromGlobalInstall() {
20246
23148
  if (!dir) {
20247
23149
  throw new Error(`${PI_SDK_PACKAGE_NAME2} not found — install it (e.g. \`npm install -g ${PI_SDK_PACKAGE_NAME2}\`) before launching a pi agent`);
20248
23150
  }
20249
- const pkg = JSON.parse(readFileSync5(path9.join(dir, "package.json"), "utf-8"));
23151
+ const pkg = JSON.parse(readFileSync4(path9.join(dir, "package.json"), "utf-8"));
20250
23152
  const entry = pkg.exports?.["."]?.import ?? pkg.main ?? "./dist/index.js";
20251
23153
  const entryPath = path9.join(dir, entry);
20252
23154
  const barrel = await import(pathToFileURL(entryPath).href);
@@ -20319,7 +23221,7 @@ function createPiSdkDriverDeps(ctx, loadSdk = loadPiSdkModule) {
20319
23221
  const bashTool = sdk.createBashToolDefinition(cwd, {
20320
23222
  spawnHook: (spawnCtx) => ({ ...spawnCtx, env: { ...spawnCtx.env, ...spawnEnv } })
20321
23223
  });
20322
- const { session, sessionId } = await sdk.createAgentSession({
23224
+ const { session: session2, sessionId } = await sdk.createAgentSession({
20323
23225
  cwd,
20324
23226
  model,
20325
23227
  thinkingLevel: opts.thinkingLevel,
@@ -20328,18 +23230,48 @@ function createPiSdkDriverDeps(ctx, loadSdk = loadPiSdkModule) {
20328
23230
  sessionManager,
20329
23231
  customTools: [bashTool]
20330
23232
  });
20331
- const resolvedSessionId = sessionId ?? session.sessionId;
23233
+ const resolvedSessionId = sessionId ?? session2.sessionId;
20332
23234
  if (!resolvedSessionId)
20333
23235
  throw new Error("pi SDK createAgentSession did not produce a sessionId");
20334
- return { session, sessionId: resolvedSessionId };
23236
+ return { session: session2, sessionId: resolvedSessionId };
23237
+ }
23238
+ };
23239
+ }
23240
+
23241
+ // src/daemon/diagnosticsCommand.ts
23242
+ function reportUnavailable(options, reportId) {
23243
+ if (!options.reportDiagnosticFailure)
23244
+ return;
23245
+ try {
23246
+ Promise.resolve(options.reportDiagnosticFailure({
23247
+ reportId,
23248
+ failureCode: "diagnostics_unavailable"
23249
+ })).catch(() => {});
23250
+ } catch {}
23251
+ }
23252
+ function createDiagnosticsCommandListener(options) {
23253
+ return (command) => {
23254
+ if (command.type !== "diagnostics:collect")
23255
+ return;
23256
+ const handler = options.handleDiagnosticCommand;
23257
+ if (!handler) {
23258
+ reportUnavailable(options, command.reportId);
23259
+ return WS_CONTROL_COMMAND_CONSUMED;
23260
+ }
23261
+ try {
23262
+ Promise.resolve(handler(command)).catch(() => {
23263
+ reportUnavailable(options, command.reportId);
23264
+ });
23265
+ } catch {
23266
+ reportUnavailable(options, command.reportId);
20335
23267
  }
23268
+ return WS_CONTROL_COMMAND_CONSUMED;
20336
23269
  };
20337
23270
  }
20338
23271
 
20339
23272
  // src/daemon/createDaemon.ts
20340
23273
  var WARMUP_BACKOFF_MS = [250, 500, 1000, 2000, 4000];
20341
23274
  var WARMUP_CEILING_MS = 30000;
20342
- var FSM_TRACE_MAX_BYTES = 8 * 1024 * 1024;
20343
23275
  var RUNTIME_RAW_TRACE_MAX_BYTES = 8 * 1024 * 1024;
20344
23276
  var RUNTIME_RAW_TRACE_AGENT_IDS_ENV = "ALOOK_RUNTIME_RAW_TRACE_AGENT_IDS";
20345
23277
  var STATUS_WRITE_INTERVAL_MS = 5000;
@@ -20441,7 +23373,11 @@ function emitImplicitTypingStopOnSend(args) {
20441
23373
  async function createDaemon(opts) {
20442
23374
  const log = opts.logger ?? createLogger({ header: "@alook/daemon" });
20443
23375
  const fallbackBase = (process.env.ALOOK_PROJECT_ROOT || `${homedir3()}/.alook`) + "/daemon";
20444
- const workdirFor = (agentId) => `${opts.workingDirectoryBase ?? fallbackBase}/${agentId}`;
23376
+ const workingDirectoryBase = opts.workingDirectoryBase ?? fallbackBase;
23377
+ const workdirFor = (agentId) => `${workingDirectoryBase}/${agentId}`;
23378
+ sweepTimelineHistory(workingDirectoryBase).catch(() => {
23379
+ log.warn("timeline startup sweep failed");
23380
+ });
20445
23381
  const resolvedCliPath = resolveAlookCliPathWithFallback(opts.agentCliPath);
20446
23382
  const onRuntimeRawLine = createRuntimeRawLineTap({
20447
23383
  traceDir: opts.fsmTraceDir,
@@ -20497,16 +23433,16 @@ async function createDaemon(opts) {
20497
23433
  function reassertAgentActivity(agentId) {
20498
23434
  const state = managerRef?.agentActivity(agentId);
20499
23435
  if (state)
20500
- channel.reportAgentActivity?.({ agentId, state });
23436
+ channel2.reportAgentActivity?.({ agentId, state });
20501
23437
  }
20502
23438
  function startTypingHeartbeat(agentId) {
20503
23439
  stopTypingHeartbeat(agentId);
20504
23440
  for (const channelId of typingTracker.snapshot(agentId)) {
20505
- channel.reportAgentTyping?.({ agentId, channelId });
23441
+ channel2.reportAgentTyping?.({ agentId, channelId });
20506
23442
  }
20507
23443
  const timer = setInterval(() => {
20508
23444
  for (const channelId of typingTracker.snapshot(agentId)) {
20509
- channel.reportAgentTyping?.({ agentId, channelId });
23445
+ channel2.reportAgentTyping?.({ agentId, channelId });
20510
23446
  }
20511
23447
  reassertAgentActivity(agentId);
20512
23448
  }, TYPING_HEARTBEAT_MS);
@@ -20516,7 +23452,7 @@ async function createDaemon(opts) {
20516
23452
  function emitTypingStopsAndClear(agentId) {
20517
23453
  stopTypingHeartbeat(agentId);
20518
23454
  for (const channelId of typingTracker.snapshot(agentId)) {
20519
- channel.reportAgentTypingStop?.({ agentId, channelId });
23455
+ channel2.reportAgentTypingStop?.({ agentId, channelId });
20520
23456
  }
20521
23457
  typingTracker.clear(agentId);
20522
23458
  }
@@ -20581,11 +23517,11 @@ async function createDaemon(opts) {
20581
23517
  headers: { "content-type": "application/json", authorization: `Bearer ${opts.machineKey}` },
20582
23518
  body: JSON.stringify({ agentId })
20583
23519
  });
20584
- const text = await res.text();
23520
+ const text2 = await res.text();
20585
23521
  let json2 = {};
20586
- if (text) {
23522
+ if (text2) {
20587
23523
  try {
20588
- json2 = JSON.parse(text);
23524
+ json2 = JSON.parse(text2);
20589
23525
  } catch {
20590
23526
  json2 = {};
20591
23527
  }
@@ -20594,7 +23530,7 @@ async function createDaemon(opts) {
20594
23530
  if (res.status === 404) {
20595
23531
  throw new UnknownBotError(agentId);
20596
23532
  }
20597
- throw new BotEnrollFailedError(agentId, new Error(json2.error ?? `enroll failed (${res.status})${text ? `: ${text.slice(0, 512)}` : ""}`));
23533
+ throw new BotEnrollFailedError(agentId, new Error(json2.error ?? `enroll failed (${res.status})${text2 ? `: ${text2.slice(0, 512)}` : ""}`));
20598
23534
  }
20599
23535
  enrolledKeys.set(agentId, json2.runnerKey);
20600
23536
  return json2.runnerKey;
@@ -20608,14 +23544,14 @@ async function createDaemon(opts) {
20608
23544
  throw wrapped;
20609
23545
  }
20610
23546
  };
20611
- const channel = new WsControlChannel({
23547
+ const channel2 = new WsControlChannel({
20612
23548
  url: opts.serverWsUrl,
20613
23549
  headers: { Authorization: `Bearer ${opts.machineKey}` },
20614
23550
  webSocketFactory: opts.webSocketFactory,
20615
23551
  onAuthRejected: opts.onAuthRejected,
20616
23552
  logger: log.child("ws")
20617
23553
  });
20618
- channelRef = channel;
23554
+ channelRef = channel2;
20619
23555
  function handleBotFrame(cmd) {
20620
23556
  switch (cmd.type) {
20621
23557
  case "bot:added":
@@ -20656,6 +23592,31 @@ async function createDaemon(opts) {
20656
23592
  }
20657
23593
  }
20658
23594
  let router = null;
23595
+ const diagnosticTrace = (() => {
23596
+ const overridePath = process.env.ALOOK_FSM_TRACE;
23597
+ if (overridePath) {
23598
+ return {
23599
+ source: null,
23600
+ onFsmTransition: (rec) => {
23601
+ try {
23602
+ appendFileSync2(overridePath, JSON.stringify(rec) + `
23603
+ `);
23604
+ } catch {}
23605
+ }
23606
+ };
23607
+ }
23608
+ if (!opts.fsmTraceDir)
23609
+ return { source: null };
23610
+ try {
23611
+ mkdirSync6(opts.fsmTraceDir, { recursive: true });
23612
+ } catch {}
23613
+ const source = createRotatingFileSink(`${opts.fsmTraceDir}/fsm-trace.jsonl`, DEFAULT_TRACE_FILE_MAX_BYTES);
23614
+ const sampler = createTraceSampler((rec) => source.write(JSON.stringify(rec)));
23615
+ return {
23616
+ source,
23617
+ onFsmTransition: (rec) => sampler.offer(rec)
23618
+ };
23619
+ })();
20659
23620
  const manager = new AgentProcessManager({
20660
23621
  driverFor: (agentId, runtimeConfig) => {
20661
23622
  const requested = runtimeConfig?.runtime;
@@ -20690,9 +23651,9 @@ async function createDaemon(opts) {
20690
23651
  };
20691
23652
  },
20692
23653
  tickIntervalMs: opts.tickIntervalMs ?? 2000,
20693
- onAgentSession: (info) => void channel.reportAgentSession(info),
23654
+ onAgentSession: (info) => void channel2.reportAgentSession(info),
20694
23655
  onAgentActivity: (info) => {
20695
- channel.reportAgentActivity?.(info);
23656
+ channel2.reportAgentActivity?.(info);
20696
23657
  if (info.state === "starting" || info.state === "running") {
20697
23658
  if (!typingHeartbeats.has(info.agentId)) {
20698
23659
  startTypingHeartbeat(info.agentId);
@@ -20704,30 +23665,7 @@ async function createDaemon(opts) {
20704
23665
  onBotAuditEvent: (agentId, event, context) => emitBotAuditEvent(agentId, event, context),
20705
23666
  onAgentLocallyStopped: (info) => router?.markLocallyStopped(info.agentId),
20706
23667
  onRuntimeRawLine,
20707
- ...(() => {
20708
- const overridePath = process.env.ALOOK_FSM_TRACE;
20709
- if (overridePath) {
20710
- return {
20711
- onFsmTransition: (rec) => {
20712
- try {
20713
- appendFileSync3(overridePath, JSON.stringify(rec) + `
20714
- `);
20715
- } catch {}
20716
- }
20717
- };
20718
- }
20719
- if (opts.fsmTraceDir) {
20720
- try {
20721
- mkdirSync6(opts.fsmTraceDir, { recursive: true });
20722
- } catch {}
20723
- const sink = createRotatingFileSink(`${opts.fsmTraceDir}/fsm-trace.jsonl`, FSM_TRACE_MAX_BYTES);
20724
- const sampler = createTraceSampler((rec) => sink.write(JSON.stringify(rec)));
20725
- return {
20726
- onFsmTransition: (rec) => sampler.offer(rec)
20727
- };
20728
- }
20729
- return {};
20730
- })(),
23668
+ ...diagnosticTrace.onFsmTransition ? { onFsmTransition: diagnosticTrace.onFsmTransition } : {},
20731
23669
  sdkDriverDepsFor: (ctx) => createPiSdkDriverDeps(ctx),
20732
23670
  timeline: timeline2,
20733
23671
  wakePromptFooter: "Use `alook inbox pull` to read your messages.",
@@ -20744,9 +23682,13 @@ async function createDaemon(opts) {
20744
23682
  statusTimer = setInterval(writeStatus, STATUS_WRITE_INTERVAL_MS);
20745
23683
  statusTimer.unref?.();
20746
23684
  }
23685
+ opts.onDiagnosticSources?.({
23686
+ fsmTraceSource: diagnosticTrace.source,
23687
+ statusFilePath: opts.statusFilePath
23688
+ });
20747
23689
  router = new AgentRouter({
20748
23690
  manager,
20749
- channel,
23691
+ channel: channel2,
20750
23692
  runtimeReport: opts.runtimeReport,
20751
23693
  hostname: opts.hostname,
20752
23694
  platform: opts.platform,
@@ -20777,20 +23719,24 @@ async function createDaemon(opts) {
20777
23719
  },
20778
23720
  formatUnreadNoticeText: (notice) => `You have unread messages in channel ${notice.channel}.`
20779
23721
  });
20780
- channel.onCommand((cmd) => {
23722
+ channel2.onCommand(createDiagnosticsCommandListener({
23723
+ handleDiagnosticCommand: opts.handleDiagnosticCommand,
23724
+ reportDiagnosticFailure: opts.reportDiagnosticFailure
23725
+ }));
23726
+ channel2.onCommand((cmd) => {
20781
23727
  handleBotFrame(cmd);
20782
23728
  });
20783
- channel.onOpen(() => {
23729
+ channel2.onOpen(() => {
20784
23730
  coldStartWarmup();
20785
23731
  resyncPendingWakes();
20786
23732
  });
20787
- channel.connect();
23733
+ channel2.connect();
20788
23734
  await router.start();
20789
23735
  return {
20790
- isOpen: () => channel.status === "open",
23736
+ isOpen: () => channel2.status === "open",
20791
23737
  onOpen: (hook) => {
20792
- channel.onOpen(hook);
20793
- if (channel.status === "open")
23738
+ channel2.onOpen(hook);
23739
+ if (channel2.status === "open")
20794
23740
  queueMicrotask(hook);
20795
23741
  },
20796
23742
  proxyUrl: proxy.url,
@@ -20800,7 +23746,7 @@ async function createDaemon(opts) {
20800
23746
  }
20801
23747
  if (statusTimer)
20802
23748
  clearInterval(statusTimer);
20803
- channel.close();
23749
+ channel2.close();
20804
23750
  await proxy.close();
20805
23751
  await manager.stopAll();
20806
23752
  }