@moxxy/cli 0.12.2 → 0.12.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 (3) hide show
  1. package/dist/bin.js +1173 -1117
  2. package/dist/bin.js.map +1 -1
  3. package/package.json +2 -2
package/dist/bin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { z as z$1, defineProvider, definePlugin, defineTool, MoxxyError, writeFileAtomic, asTurnId, defineMode, asPluginId, defineChannel, defineTunnelProvider, spawnCliTunnel, isCliTunnelAvailable, createMutex, defineWorkflowExecutor, toFriendlyError, estimateTextTokens, classifyHttpStatus, createStuckLoopDetector, runCompactionIfNeeded, runElisionIfNeeded, collectProviderStream, usageEventFields, isContextOverflowError, emitRequestsAndDetectStuck, executeToolUses, buildSystemPromptWithSkills, projectMessages, defineCompactor, defineCacheStrategy, denyByDefaultResolver, createAllowListResolver, moxxyPath, zodToJsonSchema, fileDiffSummary, runSingleShotTurn, bearerTokenMatches, resolveChannelToken, rotateChannelToken, defineSurface, estimateContextTokens as estimateContextTokens$1, readRequestBody, isFileDiffDisplay, MOXXY_WS_SUBPROTOCOL, defineEmbedder, migrateModeName, bearerGuard, tokenFromWsProtocolHeader, skillFrontmatterSchema, asSkillId, getInstallHint, moxxyHome, defineTranscriber, summarizeTokensByModel, countNodes, createDeferredPermissionResolver, writeFileAtomicSync, encodeLoginPrompt, classifyNetworkError, addModelTotals, ISOLATION_RANK, moxxyPackageSchema, defineCommand, fileDiffVerb, createCallbackResolver, autoAllowResolver, asSessionId, asToolCallId, defineViewRenderer, DEFAULT_VIEW_TAGS, assertNever, isSafeViewUrl, evaluateToolRule, summarizeSessionTokensFromEvents, toDiffRows, diffGutterNo, computeElisionState, toolResultStubbed, toolResultStub, toolResultBytes, conversationalStubbed, conversationalStub, asEventId } from '@moxxy/sdk';
3
+ import { z as z$1, defineProvider, definePlugin, defineTool, MoxxyError, writeFileAtomic, asTurnId, defineMode, asPluginId, defineChannel, defineTunnelProvider, spawnCliTunnel, isCliTunnelAvailable, createMutex, defineWorkflowExecutor, toFriendlyError, estimateTextTokens, classifyHttpStatus, createStuckLoopDetector, runCompactionIfNeeded, runElisionIfNeeded, collectProviderStream, usageEventFields, isContextOverflowError, emitRequestsAndDetectStuck, executeToolUses, buildSystemPromptWithSkills, projectMessages, defineCompactor, defineCacheStrategy, denyByDefaultResolver, createAllowListResolver, moxxyPath, moxxyHome, zodToJsonSchema, fileDiffSummary, runSingleShotTurn, bearerTokenMatches, resolveChannelToken, rotateChannelToken, defineSurface, estimateContextTokens as estimateContextTokens$1, readRequestBody, isFileDiffDisplay, MOXXY_WS_SUBPROTOCOL, renderFrontmatter, defineEmbedder, migrateModeName, bearerGuard, tokenFromWsProtocolHeader, skillFrontmatterSchema, asSkillId, getInstallHint, parseFrontmatterFile, defineTranscriber, summarizeTokensByModel, countNodes, createDeferredPermissionResolver, writeFileAtomicSync, encodeLoginPrompt, classifyNetworkError, addModelTotals, createJsonFileStore, ISOLATION_RANK, moxxyPackageSchema, defineCommand, fileDiffVerb, parseFrontmatter, createCallbackResolver, autoAllowResolver, asSessionId, asToolCallId, defineViewRenderer, DEFAULT_VIEW_TAGS, assertNever, isSafeViewUrl, evaluateToolRule, summarizeSessionTokensFromEvents, toDiffRows, diffGutterNo, computeElisionState, toolResultStubbed, toolResultStub, toolResultBytes, conversationalStubbed, conversationalStub, asEventId } from '@moxxy/sdk';
4
4
  import * as fs28 from 'fs';
5
5
  import fs28__default, { existsSync, promises, ReadStream, readFileSync, statSync, readdirSync, mkdirSync, writeFileSync, unlinkSync, watch, createReadStream } from 'fs';
6
6
  import * as path3 from 'path';
@@ -477,8 +477,16 @@ function getRetainedChild(childSessionId) {
477
477
  function releaseRetainedChild(childSessionId) {
478
478
  retained.delete(String(childSessionId));
479
479
  }
480
- function clearRetainedChildren() {
481
- retained.clear();
480
+ function clearRetainedChildren(parentSessionId) {
481
+ if (parentSessionId === void 0) {
482
+ retained.clear();
483
+ return;
484
+ }
485
+ const target = String(parentSessionId);
486
+ for (const [childId, entry] of retained) {
487
+ if (String(entry.parentSession.id) === target)
488
+ retained.delete(childId);
489
+ }
482
490
  }
483
491
  var retained;
484
492
  var init_registry = __esm({
@@ -656,9 +664,12 @@ async function resolveChildModel(rt3, spec, label3, childSessionId) {
656
664
  }
657
665
  function buildChildContext(rt3, spec, model, childSessionId, childTurnId, toolRegistry, childLog, spawner) {
658
666
  const { parentSession, parentSignal } = rt3;
667
+ const parentAppCtx = parentSession.appContext();
659
668
  return {
660
669
  sessionId: childSessionId,
661
670
  turnId: childTurnId,
671
+ cwd: parentAppCtx.cwd,
672
+ env: parentAppCtx.env,
662
673
  model,
663
674
  ...spec.systemPrompt !== void 0 ? { systemPrompt: spec.systemPrompt } : {},
664
675
  provider: parentSession.providers.getActive(),
@@ -753,9 +764,12 @@ async function* runTurn(session, prompt, opts = {}) {
753
764
  });
754
765
  const strategy = session.modes.getActive();
755
766
  const effectiveSignal = opts.signal ? AbortSignal.any([session.signal, opts.signal]) : session.signal;
767
+ const appCtx = session.appContext();
756
768
  const ctx = {
757
769
  sessionId: session.id,
758
770
  turnId,
771
+ cwd: appCtx.cwd,
772
+ env: appCtx.env,
759
773
  model,
760
774
  systemPrompt: opts.systemPrompt,
761
775
  provider,
@@ -786,7 +800,7 @@ async function* runTurn(session, prompt, opts = {}) {
786
800
  },
787
801
  emit: (event) => session.log.append(event)
788
802
  };
789
- const turnStartCtx = { ...session.appContext(), turnId, iteration: 0 };
803
+ const turnStartCtx = { ...appCtx, turnId, iteration: 0 };
790
804
  strategyPromise = (async () => {
791
805
  try {
792
806
  await session.dispatcher.dispatchTurnStart(turnStartCtx);
@@ -1169,7 +1183,7 @@ var init_host = __esm({
1169
1183
  this.loaded.set(manifest.packageName, record2);
1170
1184
  this.clearSkip(plugin4.name);
1171
1185
  this.clearSkip(manifest.packageName);
1172
- this.opts.requirements.registerPlugin(plugin4.name, plugin4.version);
1186
+ this.opts.requirements.registerPlugin(manifest.packageName, plugin4.version);
1173
1187
  this.refreshDispatcher();
1174
1188
  }
1175
1189
  async discoverAndLoad(extraPaths) {
@@ -1262,7 +1276,7 @@ var init_host = __esm({
1262
1276
  for (const wfxName of record2.workflowExecutorNames)
1263
1277
  this.opts.workflowExecutors.unregister(wfxName);
1264
1278
  this.loaded.delete(name);
1265
- this.opts.requirements.unregisterPlugin(record2.plugin.name);
1279
+ this.opts.requirements.unregisterPlugin(record2.manifest?.packageName ?? record2.plugin.name);
1266
1280
  this.refreshDispatcher();
1267
1281
  }
1268
1282
  async reload() {
@@ -2248,9 +2262,9 @@ var init_host2 = __esm({
2248
2262
  ...existing.snapshot ? { snapshot: existing.snapshot() } : {}
2249
2263
  };
2250
2264
  }
2251
- const pending = this.opening.get(kind3);
2252
- if (pending)
2253
- return pending;
2265
+ const pending2 = this.opening.get(kind3);
2266
+ if (pending2)
2267
+ return pending2;
2254
2268
  const def = this.registry.get(kind3);
2255
2269
  if (!def)
2256
2270
  throw new Error(`No surface registered for kind: ${kind3}`);
@@ -2366,6 +2380,10 @@ var init_skills = __esm({
2366
2380
  this.byNameIdx.set(skill.frontmatter.name, skill);
2367
2381
  }
2368
2382
  replace(skill) {
2383
+ const prior = this.byId.get(skill.id);
2384
+ if (prior && prior.frontmatter.name !== skill.frontmatter.name) {
2385
+ this.byNameIdx.delete(prior.frontmatter.name);
2386
+ }
2369
2387
  this.byId.set(skill.id, skill);
2370
2388
  this.byNameIdx.set(skill.frontmatter.name, skill);
2371
2389
  }
@@ -2456,8 +2474,8 @@ var init_tools2 = __esm({
2456
2474
  const parseResult = tool.inputSchema.safeParse(input);
2457
2475
  if (!parseResult.success) {
2458
2476
  const issues = parseResult.error.issues.map((iss) => {
2459
- const path62 = iss.path.length ? iss.path.join(".") : "(root)";
2460
- return `${path62}: ${iss.message}`;
2477
+ const path60 = iss.path.length ? iss.path.join(".") : "(root)";
2478
+ return `${path60}: ${iss.message}`;
2461
2479
  }).join("; ");
2462
2480
  throw new Error(`Invalid input for ${name}: ${issues}`);
2463
2481
  }
@@ -3340,7 +3358,7 @@ var init_session = __esm({
3340
3358
  await this.surfaces.closeAll();
3341
3359
  await this.dispatcher.dispatchShutdown(this.appContext());
3342
3360
  } finally {
3343
- clearRetainedChildren();
3361
+ clearRetainedChildren(this.id);
3344
3362
  this.abort(reason);
3345
3363
  }
3346
3364
  }
@@ -3523,111 +3541,10 @@ var init_usage_stats = __esm({
3523
3541
  mergeMutex = createMutex();
3524
3542
  }
3525
3543
  });
3526
-
3527
- // ../core/dist/skills/parse.js
3528
- function parseSkillFile(content) {
3529
- if (!content.startsWith(FRONTMATTER_FENCE + "\n") && !content.startsWith(FRONTMATTER_FENCE + "\r\n")) {
3530
- return { frontmatter: {}, body: content };
3531
- }
3532
- const fenceLen = content.startsWith(FRONTMATTER_FENCE + "\r\n") ? 5 : 4;
3533
- const rest = content.slice(fenceLen);
3534
- const endRe = /\r?\n---(?:\r?\n|$)/;
3535
- const endMatch = endRe.exec(rest);
3536
- if (!endMatch)
3537
- return { frontmatter: {}, body: content };
3538
- const fmText = rest.slice(0, endMatch.index);
3539
- const body = rest.slice(endMatch.index + endMatch[0].length);
3540
- return { frontmatter: parseFrontmatter(fmText), body };
3541
- }
3542
- function parseFrontmatter(text) {
3543
- const result = {};
3544
- const lines = text.split(/\r?\n/);
3545
- for (let i2 = 0; i2 < lines.length; i2++) {
3546
- const line = lines[i2] ?? "";
3547
- const trimmed = line.trim();
3548
- if (!trimmed || trimmed.startsWith("#"))
3549
- continue;
3550
- const colon = trimmed.indexOf(":");
3551
- if (colon === -1)
3552
- continue;
3553
- const key = trimmed.slice(0, colon).trim();
3554
- const raw = trimmed.slice(colon + 1).trim();
3555
- if (raw === "" && i2 + 1 < lines.length && /^\s*-\s/.test(lines[i2 + 1] ?? "")) {
3556
- const items = [];
3557
- while (i2 + 1 < lines.length && /^\s*-\s/.test(lines[i2 + 1] ?? "")) {
3558
- i2 += 1;
3559
- items.push(parseScalar((lines[i2] ?? "").replace(/^\s*-\s*/, "").trim()));
3560
- }
3561
- result[key] = items;
3562
- continue;
3563
- }
3564
- result[key] = parseScalar(raw);
3565
- }
3566
- return result;
3567
- }
3568
- function parseScalar(v3) {
3569
- if (!v3)
3570
- return "";
3571
- if (v3.startsWith("[") && v3.endsWith("]")) {
3572
- const inner = v3.slice(1, -1).trim();
3573
- if (!inner)
3574
- return [];
3575
- return splitArray(inner).map((s2) => parseScalar(s2.trim()));
3576
- }
3577
- if (v3 === "true")
3578
- return true;
3579
- if (v3 === "false")
3580
- return false;
3581
- if (v3 === "null" || v3 === "~")
3582
- return null;
3583
- if (/^-?\d+$/.test(v3))
3584
- return Number(v3);
3585
- if (/^-?\d+\.\d+$/.test(v3))
3586
- return Number(v3);
3587
- return stripQuotes(v3);
3588
- }
3589
- function stripQuotes(s2) {
3590
- if (s2.length >= 2 && (s2.startsWith('"') && s2.endsWith('"') || s2.startsWith("'") && s2.endsWith("'"))) {
3591
- return s2.slice(1, -1);
3592
- }
3593
- return s2;
3594
- }
3595
- function splitArray(s2) {
3596
- const out = [];
3597
- let depth = 0;
3598
- let buf = "";
3599
- let inStr = null;
3600
- for (const c2 of s2) {
3601
- if (inStr) {
3602
- buf += c2;
3603
- if (c2 === inStr)
3604
- inStr = null;
3605
- continue;
3606
- }
3607
- if (c2 === '"' || c2 === "'") {
3608
- inStr = c2;
3609
- buf += c2;
3610
- continue;
3611
- }
3612
- if (c2 === "[" || c2 === "{")
3613
- depth++;
3614
- if (c2 === "]" || c2 === "}")
3615
- depth--;
3616
- if (c2 === "," && depth === 0) {
3617
- out.push(buf);
3618
- buf = "";
3619
- continue;
3620
- }
3621
- buf += c2;
3622
- }
3623
- if (buf.trim())
3624
- out.push(buf);
3625
- return out;
3626
- }
3627
- var FRONTMATTER_FENCE;
3544
+ var parseSkillFile;
3628
3545
  var init_parse2 = __esm({
3629
3546
  "../core/dist/skills/parse.js"() {
3630
- FRONTMATTER_FENCE = "---";
3547
+ parseSkillFile = parseFrontmatterFile;
3631
3548
  }
3632
3549
  });
3633
3550
 
@@ -3748,7 +3665,7 @@ var init_synthesize_draft = __esm({
3748
3665
  The body is the instructions for future invocations. Keep it under 30 lines. Numbered steps preferred.`;
3749
3666
  }
3750
3667
  });
3751
- async function synthesizeSkill(session, intent, scope, opts = {}) {
3668
+ async function synthesizeSkill(session, intent, scope, opts = {}, turnId) {
3752
3669
  const provider = session.providers.getActive();
3753
3670
  const model = opts.model ?? session.lastResolvedModel ?? provider.models[0]?.id ?? "default";
3754
3671
  const draft = await draftSkill(provider, model, intent, session.signal);
@@ -3774,7 +3691,7 @@ async function synthesizeSkill(session, intent, scope, opts = {}) {
3774
3691
  await session.log.append({
3775
3692
  type: "skill_created",
3776
3693
  sessionId: session.id,
3777
- turnId: session.startTurn().turnId,
3694
+ turnId: turnId ?? session.startTurn().turnId,
3778
3695
  source: "system",
3779
3696
  skillId: skill.id,
3780
3697
  name: skill.frontmatter.name,
@@ -3829,8 +3746,8 @@ function buildSynthesizeSkillPlugin(session, opts = {}) {
3829
3746
  scope: z.enum(["user", "project"]).optional().default("user").describe('Where to write the skill. "user" \u2192 ~/.moxxy/skills/ (default, recommended). "project" \u2192 <cwd>/.moxxy/skills/ \u2014 ONLY when the user explicitly asks for a project-scoped skill.')
3830
3747
  }),
3831
3748
  permission: { action: "prompt" },
3832
- handler: async ({ intent, scope }) => {
3833
- const result = await synthesizeSkill(session, intent, scope, opts);
3749
+ handler: async ({ intent, scope }, ctx) => {
3750
+ const result = await synthesizeSkill(session, intent, scope, opts, ctx.turnId);
3834
3751
  return {
3835
3752
  path: result.path,
3836
3753
  scope: result.scope,
@@ -3844,7 +3761,7 @@ function buildSynthesizeSkillPlugin(session, opts = {}) {
3844
3761
  inputSchema: z.object({
3845
3762
  name: z.string().min(1).describe('The exact skill name from the "Available skills" list in the system prompt.')
3846
3763
  }),
3847
- handler: async ({ name }) => {
3764
+ handler: async ({ name }, ctx) => {
3848
3765
  const skill = session.skills.byName(name);
3849
3766
  if (!skill) {
3850
3767
  const known = session.skills.list().map((s2) => s2.frontmatter.name).join(", ");
@@ -3853,7 +3770,7 @@ function buildSynthesizeSkillPlugin(session, opts = {}) {
3853
3770
  await session.log.append({
3854
3771
  type: "skill_invoked",
3855
3772
  sessionId: session.id,
3856
- turnId: session.startTurn().turnId,
3773
+ turnId: ctx.turnId,
3857
3774
  source: "model",
3858
3775
  skillId: skill.id,
3859
3776
  name: skill.frontmatter.name,
@@ -8380,17 +8297,17 @@ var require_visit = __commonJS({
8380
8297
  visit.BREAK = BREAK;
8381
8298
  visit.SKIP = SKIP;
8382
8299
  visit.REMOVE = REMOVE;
8383
- function visit_(key, node, visitor, path62) {
8384
- const ctrl = callVisitor(key, node, visitor, path62);
8300
+ function visit_(key, node, visitor, path60) {
8301
+ const ctrl = callVisitor(key, node, visitor, path60);
8385
8302
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
8386
- replaceNode(key, path62, ctrl);
8387
- return visit_(key, ctrl, visitor, path62);
8303
+ replaceNode(key, path60, ctrl);
8304
+ return visit_(key, ctrl, visitor, path60);
8388
8305
  }
8389
8306
  if (typeof ctrl !== "symbol") {
8390
8307
  if (identity.isCollection(node)) {
8391
- path62 = Object.freeze(path62.concat(node));
8308
+ path60 = Object.freeze(path60.concat(node));
8392
8309
  for (let i2 = 0; i2 < node.items.length; ++i2) {
8393
- const ci = visit_(i2, node.items[i2], visitor, path62);
8310
+ const ci = visit_(i2, node.items[i2], visitor, path60);
8394
8311
  if (typeof ci === "number")
8395
8312
  i2 = ci - 1;
8396
8313
  else if (ci === BREAK)
@@ -8401,13 +8318,13 @@ var require_visit = __commonJS({
8401
8318
  }
8402
8319
  }
8403
8320
  } else if (identity.isPair(node)) {
8404
- path62 = Object.freeze(path62.concat(node));
8405
- const ck = visit_("key", node.key, visitor, path62);
8321
+ path60 = Object.freeze(path60.concat(node));
8322
+ const ck = visit_("key", node.key, visitor, path60);
8406
8323
  if (ck === BREAK)
8407
8324
  return BREAK;
8408
8325
  else if (ck === REMOVE)
8409
8326
  node.key = null;
8410
- const cv = visit_("value", node.value, visitor, path62);
8327
+ const cv = visit_("value", node.value, visitor, path60);
8411
8328
  if (cv === BREAK)
8412
8329
  return BREAK;
8413
8330
  else if (cv === REMOVE)
@@ -8428,17 +8345,17 @@ var require_visit = __commonJS({
8428
8345
  visitAsync.BREAK = BREAK;
8429
8346
  visitAsync.SKIP = SKIP;
8430
8347
  visitAsync.REMOVE = REMOVE;
8431
- async function visitAsync_(key, node, visitor, path62) {
8432
- const ctrl = await callVisitor(key, node, visitor, path62);
8348
+ async function visitAsync_(key, node, visitor, path60) {
8349
+ const ctrl = await callVisitor(key, node, visitor, path60);
8433
8350
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
8434
- replaceNode(key, path62, ctrl);
8435
- return visitAsync_(key, ctrl, visitor, path62);
8351
+ replaceNode(key, path60, ctrl);
8352
+ return visitAsync_(key, ctrl, visitor, path60);
8436
8353
  }
8437
8354
  if (typeof ctrl !== "symbol") {
8438
8355
  if (identity.isCollection(node)) {
8439
- path62 = Object.freeze(path62.concat(node));
8356
+ path60 = Object.freeze(path60.concat(node));
8440
8357
  for (let i2 = 0; i2 < node.items.length; ++i2) {
8441
- const ci = await visitAsync_(i2, node.items[i2], visitor, path62);
8358
+ const ci = await visitAsync_(i2, node.items[i2], visitor, path60);
8442
8359
  if (typeof ci === "number")
8443
8360
  i2 = ci - 1;
8444
8361
  else if (ci === BREAK)
@@ -8449,13 +8366,13 @@ var require_visit = __commonJS({
8449
8366
  }
8450
8367
  }
8451
8368
  } else if (identity.isPair(node)) {
8452
- path62 = Object.freeze(path62.concat(node));
8453
- const ck = await visitAsync_("key", node.key, visitor, path62);
8369
+ path60 = Object.freeze(path60.concat(node));
8370
+ const ck = await visitAsync_("key", node.key, visitor, path60);
8454
8371
  if (ck === BREAK)
8455
8372
  return BREAK;
8456
8373
  else if (ck === REMOVE)
8457
8374
  node.key = null;
8458
- const cv = await visitAsync_("value", node.value, visitor, path62);
8375
+ const cv = await visitAsync_("value", node.value, visitor, path60);
8459
8376
  if (cv === BREAK)
8460
8377
  return BREAK;
8461
8378
  else if (cv === REMOVE)
@@ -8482,23 +8399,23 @@ var require_visit = __commonJS({
8482
8399
  }
8483
8400
  return visitor;
8484
8401
  }
8485
- function callVisitor(key, node, visitor, path62) {
8402
+ function callVisitor(key, node, visitor, path60) {
8486
8403
  if (typeof visitor === "function")
8487
- return visitor(key, node, path62);
8404
+ return visitor(key, node, path60);
8488
8405
  if (identity.isMap(node))
8489
- return visitor.Map?.(key, node, path62);
8406
+ return visitor.Map?.(key, node, path60);
8490
8407
  if (identity.isSeq(node))
8491
- return visitor.Seq?.(key, node, path62);
8408
+ return visitor.Seq?.(key, node, path60);
8492
8409
  if (identity.isPair(node))
8493
- return visitor.Pair?.(key, node, path62);
8410
+ return visitor.Pair?.(key, node, path60);
8494
8411
  if (identity.isScalar(node))
8495
- return visitor.Scalar?.(key, node, path62);
8412
+ return visitor.Scalar?.(key, node, path60);
8496
8413
  if (identity.isAlias(node))
8497
- return visitor.Alias?.(key, node, path62);
8414
+ return visitor.Alias?.(key, node, path60);
8498
8415
  return void 0;
8499
8416
  }
8500
- function replaceNode(key, path62, node) {
8501
- const parent = path62[path62.length - 1];
8417
+ function replaceNode(key, path60, node) {
8418
+ const parent = path60[path60.length - 1];
8502
8419
  if (identity.isCollection(parent)) {
8503
8420
  parent.items[key] = node;
8504
8421
  } else if (identity.isPair(parent)) {
@@ -9099,10 +9016,10 @@ var require_Collection = __commonJS({
9099
9016
  var createNode2 = require_createNode();
9100
9017
  var identity = require_identity();
9101
9018
  var Node = require_Node();
9102
- function collectionFromPath(schema, path62, value) {
9019
+ function collectionFromPath(schema, path60, value) {
9103
9020
  let v3 = value;
9104
- for (let i2 = path62.length - 1; i2 >= 0; --i2) {
9105
- const k3 = path62[i2];
9021
+ for (let i2 = path60.length - 1; i2 >= 0; --i2) {
9022
+ const k3 = path60[i2];
9106
9023
  if (typeof k3 === "number" && Number.isInteger(k3) && k3 >= 0) {
9107
9024
  const a2 = [];
9108
9025
  a2[k3] = v3;
@@ -9121,7 +9038,7 @@ var require_Collection = __commonJS({
9121
9038
  sourceObjects: /* @__PURE__ */ new Map()
9122
9039
  });
9123
9040
  }
9124
- var isEmptyPath = (path62) => path62 == null || typeof path62 === "object" && !!path62[Symbol.iterator]().next().done;
9041
+ var isEmptyPath = (path60) => path60 == null || typeof path60 === "object" && !!path60[Symbol.iterator]().next().done;
9125
9042
  var Collection = class extends Node.NodeBase {
9126
9043
  constructor(type, schema) {
9127
9044
  super(type);
@@ -9151,11 +9068,11 @@ var require_Collection = __commonJS({
9151
9068
  * be a Pair instance or a `{ key, value }` object, which may not have a key
9152
9069
  * that already exists in the map.
9153
9070
  */
9154
- addIn(path62, value) {
9155
- if (isEmptyPath(path62))
9071
+ addIn(path60, value) {
9072
+ if (isEmptyPath(path60))
9156
9073
  this.add(value);
9157
9074
  else {
9158
- const [key, ...rest] = path62;
9075
+ const [key, ...rest] = path60;
9159
9076
  const node = this.get(key, true);
9160
9077
  if (identity.isCollection(node))
9161
9078
  node.addIn(rest, value);
@@ -9169,8 +9086,8 @@ var require_Collection = __commonJS({
9169
9086
  * Removes a value from the collection.
9170
9087
  * @returns `true` if the item was found and removed.
9171
9088
  */
9172
- deleteIn(path62) {
9173
- const [key, ...rest] = path62;
9089
+ deleteIn(path60) {
9090
+ const [key, ...rest] = path60;
9174
9091
  if (rest.length === 0)
9175
9092
  return this.delete(key);
9176
9093
  const node = this.get(key, true);
@@ -9184,8 +9101,8 @@ var require_Collection = __commonJS({
9184
9101
  * scalar values from their surrounding node; to disable set `keepScalar` to
9185
9102
  * `true` (collections are always returned intact).
9186
9103
  */
9187
- getIn(path62, keepScalar) {
9188
- const [key, ...rest] = path62;
9104
+ getIn(path60, keepScalar) {
9105
+ const [key, ...rest] = path60;
9189
9106
  const node = this.get(key, true);
9190
9107
  if (rest.length === 0)
9191
9108
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -9203,8 +9120,8 @@ var require_Collection = __commonJS({
9203
9120
  /**
9204
9121
  * Checks if the collection includes a value with the key `key`.
9205
9122
  */
9206
- hasIn(path62) {
9207
- const [key, ...rest] = path62;
9123
+ hasIn(path60) {
9124
+ const [key, ...rest] = path60;
9208
9125
  if (rest.length === 0)
9209
9126
  return this.has(key);
9210
9127
  const node = this.get(key, true);
@@ -9214,8 +9131,8 @@ var require_Collection = __commonJS({
9214
9131
  * Sets a value in this collection. For `!!set`, `value` needs to be a
9215
9132
  * boolean to add/remove the item from the set.
9216
9133
  */
9217
- setIn(path62, value) {
9218
- const [key, ...rest] = path62;
9134
+ setIn(path60, value) {
9135
+ const [key, ...rest] = path60;
9219
9136
  if (rest.length === 0) {
9220
9137
  this.set(key, value);
9221
9138
  } else {
@@ -11695,9 +11612,9 @@ var require_Document = __commonJS({
11695
11612
  this.contents.add(value);
11696
11613
  }
11697
11614
  /** Adds a value to the document. */
11698
- addIn(path62, value) {
11615
+ addIn(path60, value) {
11699
11616
  if (assertCollection(this.contents))
11700
- this.contents.addIn(path62, value);
11617
+ this.contents.addIn(path60, value);
11701
11618
  }
11702
11619
  /**
11703
11620
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -11772,14 +11689,14 @@ var require_Document = __commonJS({
11772
11689
  * Removes a value from the document.
11773
11690
  * @returns `true` if the item was found and removed.
11774
11691
  */
11775
- deleteIn(path62) {
11776
- if (Collection.isEmptyPath(path62)) {
11692
+ deleteIn(path60) {
11693
+ if (Collection.isEmptyPath(path60)) {
11777
11694
  if (this.contents == null)
11778
11695
  return false;
11779
11696
  this.contents = null;
11780
11697
  return true;
11781
11698
  }
11782
- return assertCollection(this.contents) ? this.contents.deleteIn(path62) : false;
11699
+ return assertCollection(this.contents) ? this.contents.deleteIn(path60) : false;
11783
11700
  }
11784
11701
  /**
11785
11702
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -11794,10 +11711,10 @@ var require_Document = __commonJS({
11794
11711
  * scalar values from their surrounding node; to disable set `keepScalar` to
11795
11712
  * `true` (collections are always returned intact).
11796
11713
  */
11797
- getIn(path62, keepScalar) {
11798
- if (Collection.isEmptyPath(path62))
11714
+ getIn(path60, keepScalar) {
11715
+ if (Collection.isEmptyPath(path60))
11799
11716
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
11800
- return identity.isCollection(this.contents) ? this.contents.getIn(path62, keepScalar) : void 0;
11717
+ return identity.isCollection(this.contents) ? this.contents.getIn(path60, keepScalar) : void 0;
11801
11718
  }
11802
11719
  /**
11803
11720
  * Checks if the document includes a value with the key `key`.
@@ -11808,10 +11725,10 @@ var require_Document = __commonJS({
11808
11725
  /**
11809
11726
  * Checks if the document includes a value at `path`.
11810
11727
  */
11811
- hasIn(path62) {
11812
- if (Collection.isEmptyPath(path62))
11728
+ hasIn(path60) {
11729
+ if (Collection.isEmptyPath(path60))
11813
11730
  return this.contents !== void 0;
11814
- return identity.isCollection(this.contents) ? this.contents.hasIn(path62) : false;
11731
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path60) : false;
11815
11732
  }
11816
11733
  /**
11817
11734
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -11828,13 +11745,13 @@ var require_Document = __commonJS({
11828
11745
  * Sets a value in this document. For `!!set`, `value` needs to be a
11829
11746
  * boolean to add/remove the item from the set.
11830
11747
  */
11831
- setIn(path62, value) {
11832
- if (Collection.isEmptyPath(path62)) {
11748
+ setIn(path60, value) {
11749
+ if (Collection.isEmptyPath(path60)) {
11833
11750
  this.contents = value;
11834
11751
  } else if (this.contents == null) {
11835
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path62), value);
11752
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path60), value);
11836
11753
  } else if (assertCollection(this.contents)) {
11837
- this.contents.setIn(path62, value);
11754
+ this.contents.setIn(path60, value);
11838
11755
  }
11839
11756
  }
11840
11757
  /**
@@ -13774,9 +13691,9 @@ var require_cst_visit = __commonJS({
13774
13691
  visit.BREAK = BREAK;
13775
13692
  visit.SKIP = SKIP;
13776
13693
  visit.REMOVE = REMOVE;
13777
- visit.itemAtPath = (cst, path62) => {
13694
+ visit.itemAtPath = (cst, path60) => {
13778
13695
  let item = cst;
13779
- for (const [field, index] of path62) {
13696
+ for (const [field, index] of path60) {
13780
13697
  const tok = item?.[field];
13781
13698
  if (tok && "items" in tok) {
13782
13699
  item = tok.items[index];
@@ -13785,23 +13702,23 @@ var require_cst_visit = __commonJS({
13785
13702
  }
13786
13703
  return item;
13787
13704
  };
13788
- visit.parentCollection = (cst, path62) => {
13789
- const parent = visit.itemAtPath(cst, path62.slice(0, -1));
13790
- const field = path62[path62.length - 1][0];
13705
+ visit.parentCollection = (cst, path60) => {
13706
+ const parent = visit.itemAtPath(cst, path60.slice(0, -1));
13707
+ const field = path60[path60.length - 1][0];
13791
13708
  const coll = parent?.[field];
13792
13709
  if (coll && "items" in coll)
13793
13710
  return coll;
13794
13711
  throw new Error("Parent collection not found");
13795
13712
  };
13796
- function _visit(path62, item, visitor) {
13797
- let ctrl = visitor(item, path62);
13713
+ function _visit(path60, item, visitor) {
13714
+ let ctrl = visitor(item, path60);
13798
13715
  if (typeof ctrl === "symbol")
13799
13716
  return ctrl;
13800
13717
  for (const field of ["key", "value"]) {
13801
13718
  const token = item[field];
13802
13719
  if (token && "items" in token) {
13803
13720
  for (let i2 = 0; i2 < token.items.length; ++i2) {
13804
- const ci = _visit(Object.freeze(path62.concat([[field, i2]])), token.items[i2], visitor);
13721
+ const ci = _visit(Object.freeze(path60.concat([[field, i2]])), token.items[i2], visitor);
13805
13722
  if (typeof ci === "number")
13806
13723
  i2 = ci - 1;
13807
13724
  else if (ci === BREAK)
@@ -13812,10 +13729,10 @@ var require_cst_visit = __commonJS({
13812
13729
  }
13813
13730
  }
13814
13731
  if (typeof ctrl === "function" && field === "key")
13815
- ctrl = ctrl(item, path62);
13732
+ ctrl = ctrl(item, path60);
13816
13733
  }
13817
13734
  }
13818
- return typeof ctrl === "function" ? ctrl(item, path62) : ctrl;
13735
+ return typeof ctrl === "function" ? ctrl(item, path60) : ctrl;
13819
13736
  }
13820
13737
  exports.visit = visit;
13821
13738
  }
@@ -16537,14 +16454,14 @@ var require_url_state_machine = __commonJS({
16537
16454
  return url2.replace(/\u0009|\u000A|\u000D/g, "");
16538
16455
  }
16539
16456
  function shortenPath(url2) {
16540
- const path62 = url2.path;
16541
- if (path62.length === 0) {
16457
+ const path60 = url2.path;
16458
+ if (path60.length === 0) {
16542
16459
  return;
16543
16460
  }
16544
- if (url2.scheme === "file" && path62.length === 1 && isNormalizedWindowsDriveLetter(path62[0])) {
16461
+ if (url2.scheme === "file" && path60.length === 1 && isNormalizedWindowsDriveLetter(path60[0])) {
16545
16462
  return;
16546
16463
  }
16547
- path62.pop();
16464
+ path60.pop();
16548
16465
  }
16549
16466
  function includesCredentials(url2) {
16550
16467
  return url2.username !== "" || url2.password !== "";
@@ -25767,14 +25684,14 @@ __export(fileFromPath_exports, {
25767
25684
  fileFromPathSync: () => fileFromPathSync,
25768
25685
  isFile: () => isFile
25769
25686
  });
25770
- function createFileFromPath(path62, { mtimeMs, size }, filenameOrOptions, options = {}) {
25687
+ function createFileFromPath(path60, { mtimeMs, size }, filenameOrOptions, options = {}) {
25771
25688
  let filename;
25772
25689
  if (isPlainObject_default2(filenameOrOptions)) {
25773
25690
  [options, filename] = [filenameOrOptions, void 0];
25774
25691
  } else {
25775
25692
  filename = filenameOrOptions;
25776
25693
  }
25777
- const file = new FileFromPath({ path: path62, size, lastModified: mtimeMs });
25694
+ const file = new FileFromPath({ path: path60, size, lastModified: mtimeMs });
25778
25695
  if (!filename) {
25779
25696
  filename = file.name;
25780
25697
  }
@@ -25783,13 +25700,13 @@ function createFileFromPath(path62, { mtimeMs, size }, filenameOrOptions, option
25783
25700
  lastModified: file.lastModified
25784
25701
  });
25785
25702
  }
25786
- function fileFromPathSync(path62, filenameOrOptions, options = {}) {
25787
- const stats = statSync(path62);
25788
- return createFileFromPath(path62, stats, filenameOrOptions, options);
25703
+ function fileFromPathSync(path60, filenameOrOptions, options = {}) {
25704
+ const stats = statSync(path60);
25705
+ return createFileFromPath(path60, stats, filenameOrOptions, options);
25789
25706
  }
25790
- async function fileFromPath2(path62, filenameOrOptions, options) {
25791
- const stats = await promises.stat(path62);
25792
- return createFileFromPath(path62, stats, filenameOrOptions, options);
25707
+ async function fileFromPath2(path60, filenameOrOptions, options) {
25708
+ const stats = await promises.stat(path60);
25709
+ return createFileFromPath(path60, stats, filenameOrOptions, options);
25793
25710
  }
25794
25711
  var import_node_domexception, __classPrivateFieldSet4, __classPrivateFieldGet5, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath;
25795
25712
  var init_fileFromPath = __esm({
@@ -29648,7 +29565,7 @@ var require_has_flag = __commonJS({
29648
29565
  // ../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js
29649
29566
  var require_supports_color = __commonJS({
29650
29567
  "../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js"(exports, module) {
29651
- var os22 = __require("os");
29568
+ var os20 = __require("os");
29652
29569
  var tty2 = __require("tty");
29653
29570
  var hasFlag2 = require_has_flag();
29654
29571
  var { env: env3 } = process;
@@ -29696,7 +29613,7 @@ var require_supports_color = __commonJS({
29696
29613
  return min;
29697
29614
  }
29698
29615
  if (process.platform === "win32") {
29699
- const osRelease = os22.release().split(".");
29616
+ const osRelease = os20.release().split(".");
29700
29617
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
29701
29618
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
29702
29619
  }
@@ -41921,8 +41838,8 @@ var require_utils2 = __commonJS({
41921
41838
  }
41922
41839
  return ind;
41923
41840
  }
41924
- function removeDotSegments(path62) {
41925
- let input = path62;
41841
+ function removeDotSegments(path60) {
41842
+ let input = path60;
41926
41843
  const output = [];
41927
41844
  let nextSlash = -1;
41928
41845
  let len = 0;
@@ -42173,8 +42090,8 @@ var require_schemes = __commonJS({
42173
42090
  wsComponent.secure = void 0;
42174
42091
  }
42175
42092
  if (wsComponent.resourceName) {
42176
- const [path62, query] = wsComponent.resourceName.split("?");
42177
- wsComponent.path = path62 && path62 !== "/" ? path62 : void 0;
42093
+ const [path60, query] = wsComponent.resourceName.split("?");
42094
+ wsComponent.path = path60 && path60 !== "/" ? path60 : void 0;
42178
42095
  wsComponent.query = query;
42179
42096
  wsComponent.resourceName = void 0;
42180
42097
  }
@@ -46332,7 +46249,7 @@ var require_windows = __commonJS({
46332
46249
  module.exports = isexe;
46333
46250
  isexe.sync = sync;
46334
46251
  var fs45 = __require("fs");
46335
- function checkPathExt(path62, options) {
46252
+ function checkPathExt(path60, options) {
46336
46253
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
46337
46254
  if (!pathext) {
46338
46255
  return true;
@@ -46343,25 +46260,25 @@ var require_windows = __commonJS({
46343
46260
  }
46344
46261
  for (var i2 = 0; i2 < pathext.length; i2++) {
46345
46262
  var p3 = pathext[i2].toLowerCase();
46346
- if (p3 && path62.substr(-p3.length).toLowerCase() === p3) {
46263
+ if (p3 && path60.substr(-p3.length).toLowerCase() === p3) {
46347
46264
  return true;
46348
46265
  }
46349
46266
  }
46350
46267
  return false;
46351
46268
  }
46352
- function checkStat(stat2, path62, options) {
46269
+ function checkStat(stat2, path60, options) {
46353
46270
  if (!stat2.isSymbolicLink() && !stat2.isFile()) {
46354
46271
  return false;
46355
46272
  }
46356
- return checkPathExt(path62, options);
46273
+ return checkPathExt(path60, options);
46357
46274
  }
46358
- function isexe(path62, options, cb) {
46359
- fs45.stat(path62, function(er2, stat2) {
46360
- cb(er2, er2 ? false : checkStat(stat2, path62, options));
46275
+ function isexe(path60, options, cb) {
46276
+ fs45.stat(path60, function(er2, stat2) {
46277
+ cb(er2, er2 ? false : checkStat(stat2, path60, options));
46361
46278
  });
46362
46279
  }
46363
- function sync(path62, options) {
46364
- return checkStat(fs45.statSync(path62), path62, options);
46280
+ function sync(path60, options) {
46281
+ return checkStat(fs45.statSync(path60), path60, options);
46365
46282
  }
46366
46283
  }
46367
46284
  });
@@ -46372,13 +46289,13 @@ var require_mode = __commonJS({
46372
46289
  module.exports = isexe;
46373
46290
  isexe.sync = sync;
46374
46291
  var fs45 = __require("fs");
46375
- function isexe(path62, options, cb) {
46376
- fs45.stat(path62, function(er2, stat2) {
46292
+ function isexe(path60, options, cb) {
46293
+ fs45.stat(path60, function(er2, stat2) {
46377
46294
  cb(er2, er2 ? false : checkStat(stat2, options));
46378
46295
  });
46379
46296
  }
46380
- function sync(path62, options) {
46381
- return checkStat(fs45.statSync(path62), options);
46297
+ function sync(path60, options) {
46298
+ return checkStat(fs45.statSync(path60), options);
46382
46299
  }
46383
46300
  function checkStat(stat2, options) {
46384
46301
  return stat2.isFile() && checkMode(stat2, options);
@@ -46411,7 +46328,7 @@ var require_isexe = __commonJS({
46411
46328
  }
46412
46329
  module.exports = isexe;
46413
46330
  isexe.sync = sync;
46414
- function isexe(path62, options, cb) {
46331
+ function isexe(path60, options, cb) {
46415
46332
  if (typeof options === "function") {
46416
46333
  cb = options;
46417
46334
  options = {};
@@ -46421,7 +46338,7 @@ var require_isexe = __commonJS({
46421
46338
  throw new TypeError("callback not provided");
46422
46339
  }
46423
46340
  return new Promise(function(resolve13, reject) {
46424
- isexe(path62, options || {}, function(er2, is) {
46341
+ isexe(path60, options || {}, function(er2, is) {
46425
46342
  if (er2) {
46426
46343
  reject(er2);
46427
46344
  } else {
@@ -46430,7 +46347,7 @@ var require_isexe = __commonJS({
46430
46347
  });
46431
46348
  });
46432
46349
  }
46433
- core(path62, options || {}, function(er2, is) {
46350
+ core(path60, options || {}, function(er2, is) {
46434
46351
  if (er2) {
46435
46352
  if (er2.code === "EACCES" || options && options.ignoreErrors) {
46436
46353
  er2 = null;
@@ -46440,9 +46357,9 @@ var require_isexe = __commonJS({
46440
46357
  cb(er2, is);
46441
46358
  });
46442
46359
  }
46443
- function sync(path62, options) {
46360
+ function sync(path60, options) {
46444
46361
  try {
46445
- return core.sync(path62, options || {});
46362
+ return core.sync(path60, options || {});
46446
46363
  } catch (er2) {
46447
46364
  if (options && options.ignoreErrors || er2.code === "EACCES") {
46448
46365
  return false;
@@ -46458,7 +46375,7 @@ var require_isexe = __commonJS({
46458
46375
  var require_which = __commonJS({
46459
46376
  "../../node_modules/.pnpm/which@2.0.2/node_modules/which/which.js"(exports, module) {
46460
46377
  var isWindows3 = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
46461
- var path62 = __require("path");
46378
+ var path60 = __require("path");
46462
46379
  var COLON = isWindows3 ? ";" : ":";
46463
46380
  var isexe = require_isexe();
46464
46381
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -46496,7 +46413,7 @@ var require_which = __commonJS({
46496
46413
  return opt.all && found.length ? resolve13(found) : reject(getNotFoundError(cmd));
46497
46414
  const ppRaw = pathEnv[i2];
46498
46415
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
46499
- const pCmd = path62.join(pathPart, cmd);
46416
+ const pCmd = path60.join(pathPart, cmd);
46500
46417
  const p3 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
46501
46418
  resolve13(subStep(p3, i2, 0));
46502
46419
  });
@@ -46523,7 +46440,7 @@ var require_which = __commonJS({
46523
46440
  for (let i2 = 0; i2 < pathEnv.length; i2++) {
46524
46441
  const ppRaw = pathEnv[i2];
46525
46442
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
46526
- const pCmd = path62.join(pathPart, cmd);
46443
+ const pCmd = path60.join(pathPart, cmd);
46527
46444
  const p3 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
46528
46445
  for (let j3 = 0; j3 < pathExt.length; j3++) {
46529
46446
  const cur = p3 + pathExt[j3];
@@ -46569,7 +46486,7 @@ var require_path_key = __commonJS({
46569
46486
  // ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js
46570
46487
  var require_resolveCommand = __commonJS({
46571
46488
  "../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module) {
46572
- var path62 = __require("path");
46489
+ var path60 = __require("path");
46573
46490
  var which = require_which();
46574
46491
  var getPathKey = require_path_key();
46575
46492
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -46587,7 +46504,7 @@ var require_resolveCommand = __commonJS({
46587
46504
  try {
46588
46505
  resolved = which.sync(parsed.command, {
46589
46506
  path: env3[getPathKey({ env: env3 })],
46590
- pathExt: withoutPathExt ? path62.delimiter : void 0
46507
+ pathExt: withoutPathExt ? path60.delimiter : void 0
46591
46508
  });
46592
46509
  } catch (e3) {
46593
46510
  } finally {
@@ -46596,7 +46513,7 @@ var require_resolveCommand = __commonJS({
46596
46513
  }
46597
46514
  }
46598
46515
  if (resolved) {
46599
- resolved = path62.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
46516
+ resolved = path60.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
46600
46517
  }
46601
46518
  return resolved;
46602
46519
  }
@@ -46647,8 +46564,8 @@ var require_shebang_command = __commonJS({
46647
46564
  if (!match) {
46648
46565
  return null;
46649
46566
  }
46650
- const [path62, argument] = match[0].replace(/#! ?/, "").split(" ");
46651
- const binary = path62.split("/").pop();
46567
+ const [path60, argument] = match[0].replace(/#! ?/, "").split(" ");
46568
+ const binary = path60.split("/").pop();
46652
46569
  if (binary === "env") {
46653
46570
  return argument;
46654
46571
  }
@@ -46681,7 +46598,7 @@ var require_readShebang = __commonJS({
46681
46598
  // ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js
46682
46599
  var require_parse = __commonJS({
46683
46600
  "../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js"(exports, module) {
46684
- var path62 = __require("path");
46601
+ var path60 = __require("path");
46685
46602
  var resolveCommand = require_resolveCommand();
46686
46603
  var escape4 = require_escape();
46687
46604
  var readShebang = require_readShebang();
@@ -46706,7 +46623,7 @@ var require_parse = __commonJS({
46706
46623
  const needsShell = !isExecutableRegExp.test(commandFile);
46707
46624
  if (parsed.options.forceShell || needsShell) {
46708
46625
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
46709
- parsed.command = path62.normalize(parsed.command);
46626
+ parsed.command = path60.normalize(parsed.command);
46710
46627
  parsed.command = escape4.command(parsed.command);
46711
46628
  parsed.args = parsed.args.map((arg) => escape4.argument(arg, needsDoubleEscapeMetaChars));
46712
46629
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -49503,7 +49420,7 @@ var init_schema = __esm({
49503
49420
  }
49504
49421
  });
49505
49422
  function buildAddServerTool(deps) {
49506
- const { registry, attachServer, writeMcpUsageSkill } = deps;
49423
+ const { registry, attachServer, detachServer, writeMcpUsageSkill } = deps;
49507
49424
  return defineTool({
49508
49425
  name: "mcp_add_server",
49509
49426
  description: 'Register a new MCP server in ~/.moxxy/mcp.json. Pick "stdio" for local commands (npm/uv packages, scripts); pick "http" or "sse" for remote HTTP servers. The new server\'s tools become available after the next moxxy restart. Call mcp_test_server first if you want to verify connectivity before persisting. NEVER pass API keys or tokens in plaintext: store the secret in the vault first (vault_set), then reference it as "${vault:NAME}" in the env/header value \u2014 the placeholder is what gets persisted, and it is resolved only at connect time.',
@@ -49520,15 +49437,20 @@ function buildAddServerTool(deps) {
49520
49437
  }
49521
49438
  const { toolNames, descriptors } = await attachServer(server);
49522
49439
  const stored = { ...server, cachedTools: descriptors };
49523
- await mutateMcpConfig((current) => {
49524
- if (current.servers.some((s2) => s2.name === server.name)) {
49525
- throw new MoxxyError({
49526
- code: "CONFIG_INVALID",
49527
- message: `mcp_add_server: an MCP server named "${server.name}" already exists. Use mcp_remove_server first, or pick a different name.`
49528
- });
49529
- }
49530
- return { next: { servers: [...current.servers, stored] }, result: void 0 };
49531
- });
49440
+ try {
49441
+ await mutateMcpConfig((current) => {
49442
+ if (current.servers.some((s2) => s2.name === server.name)) {
49443
+ throw new MoxxyError({
49444
+ code: "CONFIG_INVALID",
49445
+ message: `mcp_add_server: an MCP server named "${server.name}" already exists. Use mcp_remove_server first, or pick a different name.`
49446
+ });
49447
+ }
49448
+ return { next: { servers: [...current.servers, stored] }, result: void 0 };
49449
+ });
49450
+ } catch (err) {
49451
+ await detachServer(server.name).catch(() => void 0);
49452
+ throw err;
49453
+ }
49532
49454
  let skillResult = null;
49533
49455
  if (input.autoSkill !== false) {
49534
49456
  try {
@@ -49718,6 +49640,7 @@ function buildMcpAdminPluginInternal(opts) {
49718
49640
  buildAddServerTool({
49719
49641
  registry,
49720
49642
  attachServer: runtime.attachServer,
49643
+ detachServer: runtime.detachServer,
49721
49644
  writeMcpUsageSkill
49722
49645
  }),
49723
49646
  buildRemoveServerTool({ detachServer: runtime.detachServer }),
@@ -51007,9 +50930,9 @@ var require_react_development = __commonJS({
51007
50930
  }
51008
50931
  });
51009
50932
  if (payload._status === Uninitialized) {
51010
- var pending = payload;
51011
- pending._status = Pending;
51012
- pending._result = thenable;
50933
+ var pending2 = payload;
50934
+ pending2._status = Pending;
50935
+ pending2._result = thenable;
51013
50936
  }
51014
50937
  }
51015
50938
  if (payload._status === Resolved) {
@@ -63647,12 +63570,12 @@ var require_react_reconciler_development = __commonJS({
63647
63570
  if (updateQueue === null) ;
63648
63571
  else {
63649
63572
  var sharedQueue = updateQueue.shared;
63650
- var pending = sharedQueue.pending;
63651
- if (pending === null) {
63573
+ var pending2 = sharedQueue.pending;
63574
+ if (pending2 === null) {
63652
63575
  update.next = update;
63653
63576
  } else {
63654
- update.next = pending.next;
63655
- pending.next = update;
63577
+ update.next = pending2.next;
63578
+ pending2.next = update;
63656
63579
  }
63657
63580
  sharedQueue.pending = update;
63658
63581
  }
@@ -63917,12 +63840,12 @@ var require_react_reconciler_development = __commonJS({
63917
63840
  }
63918
63841
  }
63919
63842
  if (isUnsafeClassRenderPhaseUpdate()) {
63920
- var pending = sharedQueue.pending;
63921
- if (pending === null) {
63843
+ var pending2 = sharedQueue.pending;
63844
+ if (pending2 === null) {
63922
63845
  update.next = update;
63923
63846
  } else {
63924
- update.next = pending.next;
63925
- pending.next = update;
63847
+ update.next = pending2.next;
63848
+ pending2.next = update;
63926
63849
  }
63927
63850
  sharedQueue.pending = update;
63928
63851
  return unsafe_markUpdateLaneFromFiberToRoot(fiber, lane);
@@ -65363,12 +65286,12 @@ var require_react_reconciler_development = __commonJS({
65363
65286
  }
65364
65287
  function enqueueRenderPhaseUpdate(queue, update) {
65365
65288
  didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
65366
- var pending = queue.pending;
65367
- if (pending === null) {
65289
+ var pending2 = queue.pending;
65290
+ if (pending2 === null) {
65368
65291
  update.next = update;
65369
65292
  } else {
65370
- update.next = pending.next;
65371
- pending.next = update;
65293
+ update.next = pending2.next;
65294
+ pending2.next = update;
65372
65295
  }
65373
65296
  queue.pending = update;
65374
65297
  }
@@ -74535,10 +74458,10 @@ var require_react_reconciler_development = __commonJS({
74535
74458
  var setErrorHandler = null;
74536
74459
  var setSuspenseHandler = null;
74537
74460
  {
74538
- var copyWithDeleteImpl = function(obj, path62, index2) {
74539
- var key = path62[index2];
74461
+ var copyWithDeleteImpl = function(obj, path60, index2) {
74462
+ var key = path60[index2];
74540
74463
  var updated = isArray(obj) ? obj.slice() : assign({}, obj);
74541
- if (index2 + 1 === path62.length) {
74464
+ if (index2 + 1 === path60.length) {
74542
74465
  if (isArray(updated)) {
74543
74466
  updated.splice(key, 1);
74544
74467
  } else {
@@ -74546,11 +74469,11 @@ var require_react_reconciler_development = __commonJS({
74546
74469
  }
74547
74470
  return updated;
74548
74471
  }
74549
- updated[key] = copyWithDeleteImpl(obj[key], path62, index2 + 1);
74472
+ updated[key] = copyWithDeleteImpl(obj[key], path60, index2 + 1);
74550
74473
  return updated;
74551
74474
  };
74552
- var copyWithDelete = function(obj, path62) {
74553
- return copyWithDeleteImpl(obj, path62, 0);
74475
+ var copyWithDelete = function(obj, path60) {
74476
+ return copyWithDeleteImpl(obj, path60, 0);
74554
74477
  };
74555
74478
  var copyWithRenameImpl = function(obj, oldPath, newPath, index2) {
74556
74479
  var oldKey = oldPath[index2];
@@ -74588,17 +74511,17 @@ var require_react_reconciler_development = __commonJS({
74588
74511
  }
74589
74512
  return copyWithRenameImpl(obj, oldPath, newPath, 0);
74590
74513
  };
74591
- var copyWithSetImpl = function(obj, path62, index2, value) {
74592
- if (index2 >= path62.length) {
74514
+ var copyWithSetImpl = function(obj, path60, index2, value) {
74515
+ if (index2 >= path60.length) {
74593
74516
  return value;
74594
74517
  }
74595
- var key = path62[index2];
74518
+ var key = path60[index2];
74596
74519
  var updated = isArray(obj) ? obj.slice() : assign({}, obj);
74597
- updated[key] = copyWithSetImpl(obj[key], path62, index2 + 1, value);
74520
+ updated[key] = copyWithSetImpl(obj[key], path60, index2 + 1, value);
74598
74521
  return updated;
74599
74522
  };
74600
- var copyWithSet = function(obj, path62, value) {
74601
- return copyWithSetImpl(obj, path62, 0, value);
74523
+ var copyWithSet = function(obj, path60, value) {
74524
+ return copyWithSetImpl(obj, path60, 0, value);
74602
74525
  };
74603
74526
  var findHook = function(fiber, id) {
74604
74527
  var currentHook2 = fiber.memoizedState;
@@ -74608,10 +74531,10 @@ var require_react_reconciler_development = __commonJS({
74608
74531
  }
74609
74532
  return currentHook2;
74610
74533
  };
74611
- overrideHookState = function(fiber, id, path62, value) {
74534
+ overrideHookState = function(fiber, id, path60, value) {
74612
74535
  var hook = findHook(fiber, id);
74613
74536
  if (hook !== null) {
74614
- var newState = copyWithSet(hook.memoizedState, path62, value);
74537
+ var newState = copyWithSet(hook.memoizedState, path60, value);
74615
74538
  hook.memoizedState = newState;
74616
74539
  hook.baseState = newState;
74617
74540
  fiber.memoizedProps = assign({}, fiber.memoizedProps);
@@ -74621,10 +74544,10 @@ var require_react_reconciler_development = __commonJS({
74621
74544
  }
74622
74545
  }
74623
74546
  };
74624
- overrideHookStateDeletePath = function(fiber, id, path62) {
74547
+ overrideHookStateDeletePath = function(fiber, id, path60) {
74625
74548
  var hook = findHook(fiber, id);
74626
74549
  if (hook !== null) {
74627
- var newState = copyWithDelete(hook.memoizedState, path62);
74550
+ var newState = copyWithDelete(hook.memoizedState, path60);
74628
74551
  hook.memoizedState = newState;
74629
74552
  hook.baseState = newState;
74630
74553
  fiber.memoizedProps = assign({}, fiber.memoizedProps);
@@ -74647,8 +74570,8 @@ var require_react_reconciler_development = __commonJS({
74647
74570
  }
74648
74571
  }
74649
74572
  };
74650
- overrideProps = function(fiber, path62, value) {
74651
- fiber.pendingProps = copyWithSet(fiber.memoizedProps, path62, value);
74573
+ overrideProps = function(fiber, path60, value) {
74574
+ fiber.pendingProps = copyWithSet(fiber.memoizedProps, path60, value);
74652
74575
  if (fiber.alternate) {
74653
74576
  fiber.alternate.pendingProps = fiber.pendingProps;
74654
74577
  }
@@ -74657,8 +74580,8 @@ var require_react_reconciler_development = __commonJS({
74657
74580
  scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
74658
74581
  }
74659
74582
  };
74660
- overridePropsDeletePath = function(fiber, path62) {
74661
- fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path62);
74583
+ overridePropsDeletePath = function(fiber, path60) {
74584
+ fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path60);
74662
74585
  if (fiber.alternate) {
74663
74586
  fiber.alternate.pendingProps = fiber.pendingProps;
74664
74587
  }
@@ -82100,8 +82023,8 @@ var init_ErrorOverview = __esm({
82100
82023
  init_dist7();
82101
82024
  init_Box();
82102
82025
  init_Text();
82103
- cleanupPath = (path62) => {
82104
- return path62?.replace(`file://${cwd()}/`, "");
82026
+ cleanupPath = (path60) => {
82027
+ return path60?.replace(`file://${cwd()}/`, "");
82105
82028
  };
82106
82029
  stackUtils = new import_stack_utils.default({
82107
82030
  cwd: cwd(),
@@ -86824,10 +86747,10 @@ function useImageAttachments(onError2) {
86824
86747
  }
86825
86748
  const attachments = [];
86826
86749
  for (const id of referencedIds) {
86827
- const pending = imageAttachmentsRef.current.get(id);
86828
- if (!pending)
86750
+ const pending2 = imageAttachmentsRef.current.get(id);
86751
+ if (!pending2)
86829
86752
  continue;
86830
- const att = await pending;
86753
+ const att = await pending2;
86831
86754
  if (att)
86832
86755
  attachments.push(att);
86833
86756
  }
@@ -86853,6 +86776,11 @@ function useTurnRunner(opts) {
86853
86776
  const queueRef = (0, import_react48.useRef)([]);
86854
86777
  const [queueCount, setQueueCount] = (0, import_react48.useState)(0);
86855
86778
  const [priorityMessage, setPriorityMessage] = (0, import_react48.useState)(null);
86779
+ const priorityRef = (0, import_react48.useRef)(null);
86780
+ const setPriority = (value) => {
86781
+ priorityRef.current = value;
86782
+ setPriorityMessage(value);
86783
+ };
86856
86784
  const busyRef = (0, import_react48.useRef)(false);
86857
86785
  const turnControllerRef = (0, import_react48.useRef)(null);
86858
86786
  const runTurnWith = async (text, attachments) => {
@@ -86879,9 +86807,9 @@ function useTurnRunner(opts) {
86879
86807
  setBusy(false);
86880
86808
  busyRef.current = false;
86881
86809
  setBusyStartedAt(null);
86882
- if (priorityMessage) {
86883
- const p3 = priorityMessage;
86884
- setPriorityMessage(null);
86810
+ if (priorityRef.current) {
86811
+ const p3 = priorityRef.current;
86812
+ setPriority(null);
86885
86813
  await runTurnWith(p3.text, p3.attachments);
86886
86814
  } else if (queueRef.current.length > 0) {
86887
86815
  const batch = queueRef.current.splice(0);
@@ -86897,7 +86825,7 @@ function useTurnRunner(opts) {
86897
86825
  return false;
86898
86826
  const first = queueRef.current.shift();
86899
86827
  setQueueCount(queueRef.current.length);
86900
- setPriorityMessage(first);
86828
+ setPriority(first);
86901
86829
  return true;
86902
86830
  };
86903
86831
  const dropFirst = () => {
@@ -86920,7 +86848,8 @@ function useTurnRunner(opts) {
86920
86848
  runTurnWith,
86921
86849
  priorityMessage,
86922
86850
  forceSendFirst,
86923
- dropFirst
86851
+ dropFirst,
86852
+ setPriority
86924
86853
  };
86925
86854
  }
86926
86855
  var import_react48;
@@ -88396,7 +88325,7 @@ var init_WorkflowsPanel = __esm({
88396
88325
  const [loading, setLoading] = import_react57.default.useState(true);
88397
88326
  const [busy, setBusy] = import_react57.default.useState(false);
88398
88327
  const [status, setStatus] = import_react57.default.useState(null);
88399
- const [pending, setPending] = import_react57.default.useState(null);
88328
+ const [pending2, setPending] = import_react57.default.useState(null);
88400
88329
  const [reply2, setReply] = import_react57.default.useState("");
88401
88330
  const reload = import_react57.default.useCallback(async () => {
88402
88331
  if (!view) {
@@ -88415,7 +88344,7 @@ var init_WorkflowsPanel = __esm({
88415
88344
  import_react57.default.useEffect(() => {
88416
88345
  void reload();
88417
88346
  }, [reload]);
88418
- const active = !busy && !pending && !!view && rows.length > 0;
88347
+ const active = !busy && !pending2 && !!view && rows.length > 0;
88419
88348
  const run2 = import_react57.default.useCallback(async (wf) => {
88420
88349
  if (!view || busy)
88421
88350
  return;
@@ -88502,7 +88431,7 @@ var init_WorkflowsPanel = __esm({
88502
88431
  }
88503
88432
  }, { isActive: active });
88504
88433
  use_input_default((input, key) => {
88505
- if (!pending)
88434
+ if (!pending2)
88506
88435
  return;
88507
88436
  if (key.escape) {
88508
88437
  setPending(null);
@@ -88511,7 +88440,7 @@ var init_WorkflowsPanel = __esm({
88511
88440
  return;
88512
88441
  }
88513
88442
  if (key.return) {
88514
- void submitReply(pending, reply2);
88443
+ void submitReply(pending2, reply2);
88515
88444
  return;
88516
88445
  }
88517
88446
  if (key.backspace || key.delete) {
@@ -88520,7 +88449,7 @@ var init_WorkflowsPanel = __esm({
88520
88449
  }
88521
88450
  if (input && !key.ctrl && !key.meta)
88522
88451
  setReply((r2) => r2 + input);
88523
- }, { isActive: !busy && !!pending });
88452
+ }, { isActive: !busy && !!pending2 });
88524
88453
  const termWidth = process.stdout.columns ?? 80;
88525
88454
  const descWidth = Math.max(16, termWidth - NAME_COL3 - SCOPE_COL2 - TRIG_COL - 12);
88526
88455
  const slice = rows.slice(scroll.visible.start, scroll.visible.end);
@@ -88530,7 +88459,7 @@ var init_WorkflowsPanel = __esm({
88530
88459
  const absoluteIndex = scroll.visible.start + i2;
88531
88460
  const focused = absoluteIndex === scroll.cursor;
88532
88461
  return (0, import_jsx_runtime29.jsxs)(Box_default, { children: [(0, import_jsx_runtime29.jsx)(Text, { ...focused ? {} : { dimColor: true }, children: focused ? "\u203A " : " " }), (0, import_jsx_runtime29.jsx)(Text, { color: wf.enabled ? Colors.active : void 0, dimColor: !wf.enabled, children: wf.enabled ? "\u25CF " : "\u25CB " }), (0, import_jsx_runtime29.jsx)(Box_default, { width: NAME_COL3, children: (0, import_jsx_runtime29.jsx)(Text, { bold: focused, children: truncate3(wf.name, NAME_COL3 - 2) }) }), (0, import_jsx_runtime29.jsx)(Box_default, { width: SCOPE_COL2, children: (0, import_jsx_runtime29.jsx)(Text, { dimColor: true, children: wf.scope }) }), (0, import_jsx_runtime29.jsx)(Box_default, { width: TRIG_COL, children: (0, import_jsx_runtime29.jsx)(Text, { dimColor: true, wrap: "truncate", children: wf.triggers }) }), (0, import_jsx_runtime29.jsx)(Box_default, { width: descWidth, children: (0, import_jsx_runtime29.jsx)(Text, { dimColor: true, wrap: "truncate", children: oneLine(wf.description) }) })] }, wf.name);
88533
- }), scroll.canScrollDown ? (0, import_jsx_runtime29.jsx)(Text, { dimColor: true, children: ` \u2193 ${rows.length - scroll.visible.end} more below` }) : null, pending ? (0, import_jsx_runtime29.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: Colors.active, paddingX: 1, children: [(0, import_jsx_runtime29.jsxs)(Text, { color: Colors.active, children: ["\u23F8 Workflow waiting \xB7 ", pending.label] }), pending.prompt ? (0, import_jsx_runtime29.jsx)(Text, { wrap: "wrap", children: oneLine(pending.prompt).slice(0, 280) }) : null, (0, import_jsx_runtime29.jsxs)(Box_default, { marginTop: 1, children: [(0, import_jsx_runtime29.jsx)(Text, { children: "reply \u203A " }), (0, import_jsx_runtime29.jsx)(Text, { children: reply2 || " " })] }), (0, import_jsx_runtime29.jsx)(Text, { dimColor: true, children: "Enter send \xB7 Esc cancel" })] }) : null, status ? (0, import_jsx_runtime29.jsx)(Box_default, { marginTop: 1, children: (0, import_jsx_runtime29.jsx)(Text, { wrap: "truncate-end", children: status }) }) : null] });
88462
+ }), scroll.canScrollDown ? (0, import_jsx_runtime29.jsx)(Text, { dimColor: true, children: ` \u2193 ${rows.length - scroll.visible.end} more below` }) : null, pending2 ? (0, import_jsx_runtime29.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: Colors.active, paddingX: 1, children: [(0, import_jsx_runtime29.jsxs)(Text, { color: Colors.active, children: ["\u23F8 Workflow waiting \xB7 ", pending2.label] }), pending2.prompt ? (0, import_jsx_runtime29.jsx)(Text, { wrap: "wrap", children: oneLine(pending2.prompt).slice(0, 280) }) : null, (0, import_jsx_runtime29.jsxs)(Box_default, { marginTop: 1, children: [(0, import_jsx_runtime29.jsx)(Text, { children: "reply \u203A " }), (0, import_jsx_runtime29.jsx)(Text, { children: reply2 || " " })] }), (0, import_jsx_runtime29.jsx)(Text, { dimColor: true, children: "Enter send \xB7 Esc cancel" })] }) : null, status ? (0, import_jsx_runtime29.jsx)(Box_default, { marginTop: 1, children: (0, import_jsx_runtime29.jsx)(Text, { wrap: "truncate-end", children: status }) }) : null] });
88534
88463
  };
88535
88464
  }
88536
88465
  });
@@ -89122,6 +89051,7 @@ var init_SessionView = __esm({
89122
89051
  setYolo(false);
89123
89052
  turn.queueRef.current = [];
89124
89053
  turn.setQueueCount(0);
89054
+ turn.setPriority(null);
89125
89055
  if (typeof session.reset === "function") {
89126
89056
  void session.reset().then(() => {
89127
89057
  if (notice)
@@ -91173,10 +91103,10 @@ var require_segments = __commonJS({
91173
91103
  const segs = getSegmentsFromString(data, Utils.isKanjiModeEnabled());
91174
91104
  const nodes = buildNodes(segs);
91175
91105
  const graph = buildGraph(nodes, version);
91176
- const path62 = dijkstra.find_path(graph.map, "start", "end");
91106
+ const path60 = dijkstra.find_path(graph.map, "start", "end");
91177
91107
  const optimizedSegs = [];
91178
- for (let i2 = 1; i2 < path62.length - 1; i2++) {
91179
- optimizedSegs.push(graph.table[path62[i2]].node);
91108
+ for (let i2 = 1; i2 < path60.length - 1; i2++) {
91109
+ optimizedSegs.push(graph.table[path60[i2]].node);
91180
91110
  }
91181
91111
  return exports.fromArray(mergeSegments(optimizedSegs));
91182
91112
  };
@@ -93628,7 +93558,7 @@ var require_png2 = __commonJS({
93628
93558
  });
93629
93559
  png.pack();
93630
93560
  };
93631
- exports.renderToFile = function renderToFile(path62, qrData, options, cb) {
93561
+ exports.renderToFile = function renderToFile(path60, qrData, options, cb) {
93632
93562
  if (typeof cb === "undefined") {
93633
93563
  cb = options;
93634
93564
  options = void 0;
@@ -93639,7 +93569,7 @@ var require_png2 = __commonJS({
93639
93569
  called = true;
93640
93570
  cb.apply(null, args);
93641
93571
  };
93642
- const stream = fs45.createWriteStream(path62);
93572
+ const stream = fs45.createWriteStream(path60);
93643
93573
  stream.on("error", done);
93644
93574
  stream.on("close", done);
93645
93575
  exports.renderToFileStream(stream, qrData, options);
@@ -93701,14 +93631,14 @@ var require_utf8 = __commonJS({
93701
93631
  }
93702
93632
  return output;
93703
93633
  };
93704
- exports.renderToFile = function renderToFile(path62, qrData, options, cb) {
93634
+ exports.renderToFile = function renderToFile(path60, qrData, options, cb) {
93705
93635
  if (typeof cb === "undefined") {
93706
93636
  cb = options;
93707
93637
  options = void 0;
93708
93638
  }
93709
93639
  const fs45 = __require("fs");
93710
93640
  const utf8 = exports.render(qrData, options);
93711
- fs45.writeFile(path62, utf8, cb);
93641
+ fs45.writeFile(path60, utf8, cb);
93712
93642
  };
93713
93643
  }
93714
93644
  });
@@ -93829,7 +93759,7 @@ var require_svg_tag = __commonJS({
93829
93759
  return str2;
93830
93760
  }
93831
93761
  function qrToPath(data, size, margin) {
93832
- let path62 = "";
93762
+ let path60 = "";
93833
93763
  let moveBy = 0;
93834
93764
  let newRow = false;
93835
93765
  let lineLength = 0;
@@ -93840,19 +93770,19 @@ var require_svg_tag = __commonJS({
93840
93770
  if (data[i2]) {
93841
93771
  lineLength++;
93842
93772
  if (!(i2 > 0 && col > 0 && data[i2 - 1])) {
93843
- path62 += newRow ? svgCmd("M", col + margin, 0.5 + row + margin) : svgCmd("m", moveBy, 0);
93773
+ path60 += newRow ? svgCmd("M", col + margin, 0.5 + row + margin) : svgCmd("m", moveBy, 0);
93844
93774
  moveBy = 0;
93845
93775
  newRow = false;
93846
93776
  }
93847
93777
  if (!(col + 1 < size && data[i2 + 1])) {
93848
- path62 += svgCmd("h", lineLength);
93778
+ path60 += svgCmd("h", lineLength);
93849
93779
  lineLength = 0;
93850
93780
  }
93851
93781
  } else {
93852
93782
  moveBy++;
93853
93783
  }
93854
93784
  }
93855
- return path62;
93785
+ return path60;
93856
93786
  }
93857
93787
  exports.render = function render2(qrData, options, cb) {
93858
93788
  const opts = Utils.getOptions(options);
@@ -93860,10 +93790,10 @@ var require_svg_tag = __commonJS({
93860
93790
  const data = qrData.modules.data;
93861
93791
  const qrcodesize = size + opts.margin * 2;
93862
93792
  const bg = !opts.color.light.a ? "" : "<path " + getColorAttrib(opts.color.light, "fill") + ' d="M0 0h' + qrcodesize + "v" + qrcodesize + 'H0z"/>';
93863
- const path62 = "<path " + getColorAttrib(opts.color.dark, "stroke") + ' d="' + qrToPath(data, size, opts.margin) + '"/>';
93793
+ const path60 = "<path " + getColorAttrib(opts.color.dark, "stroke") + ' d="' + qrToPath(data, size, opts.margin) + '"/>';
93864
93794
  const viewBox = 'viewBox="0 0 ' + qrcodesize + " " + qrcodesize + '"';
93865
93795
  const width = !opts.width ? "" : 'width="' + opts.width + '" height="' + opts.width + '" ';
93866
- const svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg + path62 + "</svg>\n";
93796
+ const svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg + path60 + "</svg>\n";
93867
93797
  if (typeof cb === "function") {
93868
93798
  cb(null, svgTag);
93869
93799
  }
@@ -93877,7 +93807,7 @@ var require_svg = __commonJS({
93877
93807
  "../../node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/renderer/svg.js"(exports) {
93878
93808
  var svgTagRenderer = require_svg_tag();
93879
93809
  exports.render = svgTagRenderer.render;
93880
- exports.renderToFile = function renderToFile(path62, qrData, options, cb) {
93810
+ exports.renderToFile = function renderToFile(path60, qrData, options, cb) {
93881
93811
  if (typeof cb === "undefined") {
93882
93812
  cb = options;
93883
93813
  options = void 0;
@@ -93885,7 +93815,7 @@ var require_svg = __commonJS({
93885
93815
  const fs45 = __require("fs");
93886
93816
  const svgTag = exports.render(qrData, options);
93887
93817
  const xmlStr = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' + svgTag;
93888
- fs45.writeFile(path62, xmlStr, cb);
93818
+ fs45.writeFile(path60, xmlStr, cb);
93889
93819
  };
93890
93820
  }
93891
93821
  });
@@ -94043,8 +93973,8 @@ var require_server = __commonJS({
94043
93973
  cb
94044
93974
  };
94045
93975
  }
94046
- function getTypeFromFilename(path62) {
94047
- return path62.slice((path62.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
93976
+ function getTypeFromFilename(path60) {
93977
+ return path60.slice((path60.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
94048
93978
  }
94049
93979
  function getRendererFromType(type) {
94050
93980
  switch (type) {
@@ -94108,17 +94038,17 @@ var require_server = __commonJS({
94108
94038
  const renderer2 = getRendererFromType(params.opts.type);
94109
94039
  return render2(renderer2.renderToBuffer, text, params);
94110
94040
  };
94111
- exports.toFile = function toFile3(path62, text, opts, cb) {
94112
- if (typeof path62 !== "string" || !(typeof text === "string" || typeof text === "object")) {
94041
+ exports.toFile = function toFile3(path60, text, opts, cb) {
94042
+ if (typeof path60 !== "string" || !(typeof text === "string" || typeof text === "object")) {
94113
94043
  throw new Error("Invalid argument");
94114
94044
  }
94115
94045
  if (arguments.length < 3 && !canPromise()) {
94116
94046
  throw new Error("Too few arguments provided");
94117
94047
  }
94118
94048
  const params = checkParams(text, opts, cb);
94119
- const type = params.opts.type || getTypeFromFilename(path62);
94049
+ const type = params.opts.type || getTypeFromFilename(path60);
94120
94050
  const renderer2 = getRendererFromType(type);
94121
- const renderToFile = renderer2.renderToFile.bind(null, path62);
94051
+ const renderToFile = renderer2.renderToFile.bind(null, path60);
94122
94052
  return render2(renderToFile, text, params);
94123
94053
  };
94124
94054
  exports.toFileStream = function toFileStream(stream, text, opts) {
@@ -94938,14 +94868,14 @@ var require_util2 = __commonJS({
94938
94868
  }
94939
94869
  const port = url2.port != null ? url2.port : url2.protocol === "https:" ? 443 : 80;
94940
94870
  let origin = url2.origin != null ? url2.origin : `${url2.protocol || ""}//${url2.hostname || ""}:${port}`;
94941
- let path62 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
94871
+ let path60 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
94942
94872
  if (origin[origin.length - 1] === "/") {
94943
94873
  origin = origin.slice(0, origin.length - 1);
94944
94874
  }
94945
- if (path62 && path62[0] !== "/") {
94946
- path62 = `/${path62}`;
94875
+ if (path60 && path60[0] !== "/") {
94876
+ path60 = `/${path60}`;
94947
94877
  }
94948
- return new URL(`${origin}${path62}`);
94878
+ return new URL(`${origin}${path60}`);
94949
94879
  }
94950
94880
  if (!isHttpOrHttpsPrefixed(url2.origin || url2.protocol)) {
94951
94881
  throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
@@ -95395,39 +95325,39 @@ var require_diagnostics = __commonJS({
95395
95325
  });
95396
95326
  diagnosticsChannel.channel("undici:client:sendHeaders").subscribe((evt) => {
95397
95327
  const {
95398
- request: { method, path: path62, origin }
95328
+ request: { method, path: path60, origin }
95399
95329
  } = evt;
95400
- debuglog("sending request to %s %s/%s", method, origin, path62);
95330
+ debuglog("sending request to %s %s/%s", method, origin, path60);
95401
95331
  });
95402
95332
  diagnosticsChannel.channel("undici:request:headers").subscribe((evt) => {
95403
95333
  const {
95404
- request: { method, path: path62, origin },
95334
+ request: { method, path: path60, origin },
95405
95335
  response: { statusCode }
95406
95336
  } = evt;
95407
95337
  debuglog(
95408
95338
  "received response to %s %s/%s - HTTP %d",
95409
95339
  method,
95410
95340
  origin,
95411
- path62,
95341
+ path60,
95412
95342
  statusCode
95413
95343
  );
95414
95344
  });
95415
95345
  diagnosticsChannel.channel("undici:request:trailers").subscribe((evt) => {
95416
95346
  const {
95417
- request: { method, path: path62, origin }
95347
+ request: { method, path: path60, origin }
95418
95348
  } = evt;
95419
- debuglog("trailers received from %s %s/%s", method, origin, path62);
95349
+ debuglog("trailers received from %s %s/%s", method, origin, path60);
95420
95350
  });
95421
95351
  diagnosticsChannel.channel("undici:request:error").subscribe((evt) => {
95422
95352
  const {
95423
- request: { method, path: path62, origin },
95353
+ request: { method, path: path60, origin },
95424
95354
  error: error2
95425
95355
  } = evt;
95426
95356
  debuglog(
95427
95357
  "request to %s %s/%s errored - %s",
95428
95358
  method,
95429
95359
  origin,
95430
- path62,
95360
+ path60,
95431
95361
  error2.message
95432
95362
  );
95433
95363
  });
@@ -95476,9 +95406,9 @@ var require_diagnostics = __commonJS({
95476
95406
  });
95477
95407
  diagnosticsChannel.channel("undici:client:sendHeaders").subscribe((evt) => {
95478
95408
  const {
95479
- request: { method, path: path62, origin }
95409
+ request: { method, path: path60, origin }
95480
95410
  } = evt;
95481
- debuglog("sending request to %s %s/%s", method, origin, path62);
95411
+ debuglog("sending request to %s %s/%s", method, origin, path60);
95482
95412
  });
95483
95413
  }
95484
95414
  diagnosticsChannel.channel("undici:websocket:open").subscribe((evt) => {
@@ -95540,7 +95470,7 @@ var require_request = __commonJS({
95540
95470
  var kHandler = /* @__PURE__ */ Symbol("handler");
95541
95471
  var Request4 = class {
95542
95472
  constructor(origin, {
95543
- path: path62,
95473
+ path: path60,
95544
95474
  method,
95545
95475
  body,
95546
95476
  headers,
@@ -95555,11 +95485,11 @@ var require_request = __commonJS({
95555
95485
  expectContinue,
95556
95486
  servername
95557
95487
  }, handler) {
95558
- if (typeof path62 !== "string") {
95488
+ if (typeof path60 !== "string") {
95559
95489
  throw new InvalidArgumentError("path must be a string");
95560
- } else if (path62[0] !== "/" && !(path62.startsWith("http://") || path62.startsWith("https://")) && method !== "CONNECT") {
95490
+ } else if (path60[0] !== "/" && !(path60.startsWith("http://") || path60.startsWith("https://")) && method !== "CONNECT") {
95561
95491
  throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
95562
- } else if (invalidPathRegex.test(path62)) {
95492
+ } else if (invalidPathRegex.test(path60)) {
95563
95493
  throw new InvalidArgumentError("invalid request path");
95564
95494
  }
95565
95495
  if (typeof method !== "string") {
@@ -95625,7 +95555,7 @@ var require_request = __commonJS({
95625
95555
  this.completed = false;
95626
95556
  this.aborted = false;
95627
95557
  this.upgrade = upgrade || null;
95628
- this.path = query ? buildURL(path62, query) : path62;
95558
+ this.path = query ? buildURL(path60, query) : path60;
95629
95559
  this.origin = origin;
95630
95560
  this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
95631
95561
  this.blocking = blocking == null ? false : blocking;
@@ -100163,7 +100093,7 @@ var require_client_h1 = __commonJS({
100163
100093
  return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
100164
100094
  }
100165
100095
  function writeH1(client, request) {
100166
- const { method, path: path62, host, upgrade, blocking, reset } = request;
100096
+ const { method, path: path60, host, upgrade, blocking, reset } = request;
100167
100097
  let { body, headers, contentLength } = request;
100168
100098
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
100169
100099
  if (util.isFormDataLike(body)) {
@@ -100229,7 +100159,7 @@ var require_client_h1 = __commonJS({
100229
100159
  if (blocking) {
100230
100160
  socket[kBlocking] = true;
100231
100161
  }
100232
- let header = `${method} ${path62} HTTP/1.1\r
100162
+ let header = `${method} ${path60} HTTP/1.1\r
100233
100163
  `;
100234
100164
  if (typeof host === "string") {
100235
100165
  header += `host: ${host}\r
@@ -100754,7 +100684,7 @@ var require_client_h2 = __commonJS({
100754
100684
  }
100755
100685
  function writeH2(client, request) {
100756
100686
  const session = client[kHTTP2Session];
100757
- const { method, path: path62, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
100687
+ const { method, path: path60, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
100758
100688
  let { body } = request;
100759
100689
  if (upgrade) {
100760
100690
  util.errorRequest(client, request, new Error("Upgrade not supported for H2"));
@@ -100821,7 +100751,7 @@ var require_client_h2 = __commonJS({
100821
100751
  });
100822
100752
  return true;
100823
100753
  }
100824
- headers[HTTP2_HEADER_PATH] = path62;
100754
+ headers[HTTP2_HEADER_PATH] = path60;
100825
100755
  headers[HTTP2_HEADER_SCHEME] = "https";
100826
100756
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
100827
100757
  if (body && typeof body.read === "function") {
@@ -101173,9 +101103,9 @@ var require_redirect_handler = __commonJS({
101173
101103
  return this.handler.onHeaders(statusCode, headers, resume, statusText);
101174
101104
  }
101175
101105
  const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
101176
- const path62 = search ? `${pathname}${search}` : pathname;
101106
+ const path60 = search ? `${pathname}${search}` : pathname;
101177
101107
  this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
101178
- this.opts.path = path62;
101108
+ this.opts.path = path60;
101179
101109
  this.opts.origin = origin;
101180
101110
  this.opts.maxRedirections = 0;
101181
101111
  this.opts.query = null;
@@ -101926,8 +101856,8 @@ var require_pool_base = __commonJS({
101926
101856
  }
101927
101857
  get [kPending]() {
101928
101858
  let ret = this[kQueued];
101929
- for (const { [kPending]: pending } of this[kClients]) {
101930
- ret += pending;
101859
+ for (const { [kPending]: pending2 } of this[kClients]) {
101860
+ ret += pending2;
101931
101861
  }
101932
101862
  return ret;
101933
101863
  }
@@ -102400,10 +102330,10 @@ var require_proxy_agent = __commonJS({
102400
102330
  };
102401
102331
  const {
102402
102332
  origin,
102403
- path: path62 = "/",
102333
+ path: path60 = "/",
102404
102334
  headers = {}
102405
102335
  } = opts;
102406
- opts.path = origin + path62;
102336
+ opts.path = origin + path60;
102407
102337
  if (!("host" in headers) && !("Host" in headers)) {
102408
102338
  const { host } = new URL3(origin);
102409
102339
  headers.host = host;
@@ -104311,20 +104241,20 @@ var require_mock_utils = __commonJS({
104311
104241
  }
104312
104242
  return true;
104313
104243
  }
104314
- function safeUrl(path62) {
104315
- if (typeof path62 !== "string") {
104316
- return path62;
104244
+ function safeUrl(path60) {
104245
+ if (typeof path60 !== "string") {
104246
+ return path60;
104317
104247
  }
104318
- const pathSegments = path62.split("?");
104248
+ const pathSegments = path60.split("?");
104319
104249
  if (pathSegments.length !== 2) {
104320
- return path62;
104250
+ return path60;
104321
104251
  }
104322
104252
  const qp = new URLSearchParams(pathSegments.pop());
104323
104253
  qp.sort();
104324
104254
  return [...pathSegments, qp.toString()].join("?");
104325
104255
  }
104326
- function matchKey(mockDispatch2, { path: path62, method, body, headers }) {
104327
- const pathMatch = matchValue(mockDispatch2.path, path62);
104256
+ function matchKey(mockDispatch2, { path: path60, method, body, headers }) {
104257
+ const pathMatch = matchValue(mockDispatch2.path, path60);
104328
104258
  const methodMatch = matchValue(mockDispatch2.method, method);
104329
104259
  const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
104330
104260
  const headersMatch = matchHeaders(mockDispatch2, headers);
@@ -104346,7 +104276,7 @@ var require_mock_utils = __commonJS({
104346
104276
  function getMockDispatch(mockDispatches, key) {
104347
104277
  const basePath = key.query ? buildURL(key.path, key.query) : key.path;
104348
104278
  const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
104349
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path62 }) => matchValue(safeUrl(path62), resolvedPath));
104279
+ let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path60 }) => matchValue(safeUrl(path60), resolvedPath));
104350
104280
  if (matchedMockDispatches.length === 0) {
104351
104281
  throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
104352
104282
  }
@@ -104384,9 +104314,9 @@ var require_mock_utils = __commonJS({
104384
104314
  }
104385
104315
  }
104386
104316
  function buildKey(opts) {
104387
- const { path: path62, method, body, headers, query } = opts;
104317
+ const { path: path60, method, body, headers, query } = opts;
104388
104318
  return {
104389
- path: path62,
104319
+ path: path60,
104390
104320
  method,
104391
104321
  body,
104392
104322
  headers,
@@ -104844,10 +104774,10 @@ var require_pending_interceptors_formatter = __commonJS({
104844
104774
  }
104845
104775
  format(pendingInterceptors) {
104846
104776
  const withPrettyHeaders = pendingInterceptors.map(
104847
- ({ method, path: path62, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
104777
+ ({ method, path: path60, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
104848
104778
  Method: method,
104849
104779
  Origin: origin,
104850
- Path: path62,
104780
+ Path: path60,
104851
104781
  "Status code": statusCode,
104852
104782
  Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
104853
104783
  Invocations: timesInvoked,
@@ -104971,18 +104901,18 @@ var require_mock_agent = __commonJS({
104971
104901
  }
104972
104902
  pendingInterceptors() {
104973
104903
  const mockAgentClients = this[kClients];
104974
- return Array.from(mockAgentClients.entries()).flatMap(([origin, scope]) => scope[kDispatches].map((dispatch3) => ({ ...dispatch3, origin }))).filter(({ pending }) => pending);
104904
+ return Array.from(mockAgentClients.entries()).flatMap(([origin, scope]) => scope[kDispatches].map((dispatch3) => ({ ...dispatch3, origin }))).filter(({ pending: pending2 }) => pending2);
104975
104905
  }
104976
104906
  assertNoPendingInterceptors({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) {
104977
- const pending = this.pendingInterceptors();
104978
- if (pending.length === 0) {
104907
+ const pending2 = this.pendingInterceptors();
104908
+ if (pending2.length === 0) {
104979
104909
  return;
104980
104910
  }
104981
- const pluralizer = new Pluralizer("interceptor", "interceptors").pluralize(pending.length);
104911
+ const pluralizer = new Pluralizer("interceptor", "interceptors").pluralize(pending2.length);
104982
104912
  throw new UndiciError(`
104983
104913
  ${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending:
104984
104914
 
104985
- ${pendingInterceptorsFormatter.format(pending)}
104915
+ ${pendingInterceptorsFormatter.format(pending2)}
104986
104916
  `.trim());
104987
104917
  }
104988
104918
  };
@@ -109686,9 +109616,9 @@ var require_util7 = __commonJS({
109686
109616
  }
109687
109617
  }
109688
109618
  }
109689
- function validateCookiePath(path62) {
109690
- for (let i2 = 0; i2 < path62.length; ++i2) {
109691
- const code = path62.charCodeAt(i2);
109619
+ function validateCookiePath(path60) {
109620
+ for (let i2 = 0; i2 < path60.length; ++i2) {
109621
+ const code = path60.charCodeAt(i2);
109692
109622
  if (code < 32 || // exclude CTLs (0-31)
109693
109623
  code === 127 || // DEL
109694
109624
  code === 59) {
@@ -112348,11 +112278,11 @@ var require_undici = __commonJS({
112348
112278
  if (typeof opts.path !== "string") {
112349
112279
  throw new InvalidArgumentError("invalid opts.path");
112350
112280
  }
112351
- let path62 = opts.path;
112281
+ let path60 = opts.path;
112352
112282
  if (!opts.path.startsWith("/")) {
112353
- path62 = `/${path62}`;
112283
+ path60 = `/${path60}`;
112354
112284
  }
112355
- url2 = new URL(util.parseOrigin(url2).origin + path62);
112285
+ url2 = new URL(util.parseOrigin(url2).origin + path60);
112356
112286
  } else {
112357
112287
  if (!opts) {
112358
112288
  opts = typeof url2 === "object" ? url2 : {};
@@ -113177,6 +113107,8 @@ function verifyTool(deps) {
113177
113107
  }
113178
113108
  const cap = failedAttemptCount(journal) >= MAX_FAILED_ATTEMPTS;
113179
113109
  if (cap) {
113110
+ if (recovered)
113111
+ journal.state = "rolled_back";
113180
113112
  await escalate(deps, ctx, journal, result.message);
113181
113113
  } else {
113182
113114
  await writeJournal(deps.moxxyDir, journal);
@@ -114653,99 +114585,7 @@ async function defaultPrompt() {
114653
114585
  rl.close();
114654
114586
  }
114655
114587
  }
114656
-
114657
- // ../plugin-memory/dist/parse.js
114658
- var FRONTMATTER_FENCE2 = "---";
114659
- var OPENING_FENCE_LF = FRONTMATTER_FENCE2 + "\n";
114660
- var OPENING_FENCE_CRLF = FRONTMATTER_FENCE2 + "\r\n";
114661
- function parseMdFile(content) {
114662
- if (!content.startsWith(OPENING_FENCE_LF) && !content.startsWith(OPENING_FENCE_CRLF)) {
114663
- return { frontmatter: {}, body: content };
114664
- }
114665
- const fenceLen = content.startsWith(OPENING_FENCE_CRLF) ? OPENING_FENCE_CRLF.length : OPENING_FENCE_LF.length;
114666
- const rest = content.slice(fenceLen);
114667
- const m3 = /\r?\n---(?:\r?\n|$)/.exec(rest);
114668
- if (!m3)
114669
- return { frontmatter: {}, body: content };
114670
- return {
114671
- frontmatter: parseFrontmatter2(rest.slice(0, m3.index)),
114672
- body: rest.slice(m3.index + m3[0].length)
114673
- };
114674
- }
114675
- function parseFrontmatter2(text) {
114676
- const result = {};
114677
- const lines = text.split(/\r?\n/);
114678
- for (let i2 = 0; i2 < lines.length; i2++) {
114679
- const trimmed = (lines[i2] ?? "").trim();
114680
- if (!trimmed || trimmed.startsWith("#"))
114681
- continue;
114682
- const colon = trimmed.indexOf(":");
114683
- if (colon === -1)
114684
- continue;
114685
- const key = trimmed.slice(0, colon).trim();
114686
- const raw = trimmed.slice(colon + 1).trim();
114687
- if (raw === "" && i2 + 1 < lines.length && /^\s*-\s/.test(lines[i2 + 1] ?? "")) {
114688
- const items = [];
114689
- while (i2 + 1 < lines.length && /^\s*-\s/.test(lines[i2 + 1] ?? "")) {
114690
- i2 += 1;
114691
- items.push(parseScalar2((lines[i2] ?? "").replace(/^\s*-\s*/, "").trim()));
114692
- }
114693
- result[key] = items;
114694
- continue;
114695
- }
114696
- result[key] = parseScalar2(raw);
114697
- }
114698
- return result;
114699
- }
114700
- function parseScalar2(v3) {
114701
- if (!v3)
114702
- return "";
114703
- if (v3.startsWith("[") && v3.endsWith("]")) {
114704
- const inner = v3.slice(1, -1).trim();
114705
- if (!inner)
114706
- return [];
114707
- return inner.split(",").map((s2) => stripQuotes2(s2.trim()));
114708
- }
114709
- if (v3 === "true")
114710
- return true;
114711
- if (v3 === "false")
114712
- return false;
114713
- if (/^-?\d+$/.test(v3))
114714
- return Number(v3);
114715
- return stripQuotes2(v3);
114716
- }
114717
- function stripQuotes2(s2) {
114718
- if (s2.length >= 2 && (s2.startsWith('"') && s2.endsWith('"') || s2.startsWith("'") && s2.endsWith("'"))) {
114719
- return s2.slice(1, -1);
114720
- }
114721
- return s2;
114722
- }
114723
- function renderFrontmatter(frontmatter) {
114724
- const out = ["---"];
114725
- for (const [k3, v3] of Object.entries(frontmatter)) {
114726
- if (v3 === void 0 || v3 === null)
114727
- continue;
114728
- out.push(`${k3}: ${renderValue(v3)}`);
114729
- }
114730
- out.push("---");
114731
- return out.join("\n");
114732
- }
114733
- function renderValue(v3) {
114734
- if (v3 === null || v3 === void 0)
114735
- return "";
114736
- if (typeof v3 === "string") {
114737
- return needsQuoting(v3) ? `"${v3.replace(/"/g, '\\"')}"` : v3;
114738
- }
114739
- if (typeof v3 === "boolean" || typeof v3 === "number")
114740
- return String(v3);
114741
- if (Array.isArray(v3)) {
114742
- return `[${v3.map((x4) => renderValue(x4)).join(", ")}]`;
114743
- }
114744
- return JSON.stringify(v3);
114745
- }
114746
- function needsQuoting(s2) {
114747
- return s2.includes(":") || s2.includes("#") || s2.includes('"') || s2.startsWith(" ") || s2.endsWith(" ");
114748
- }
114588
+ var parseMdFile = parseFrontmatterFile;
114749
114589
 
114750
114590
  // ../plugin-memory/dist/tfidf.js
114751
114591
  var TfIdfEmbedder = class {
@@ -114907,6 +114747,7 @@ var EmbeddingIndex = class _EmbeddingIndex {
114907
114747
  dim;
114908
114748
  cache = /* @__PURE__ */ new Map();
114909
114749
  dirty = false;
114750
+ loaded = false;
114910
114751
  constructor(dir, embedderName, dim3) {
114911
114752
  this.dir = dir;
114912
114753
  this.embedderName = embedderName;
@@ -114919,9 +114760,12 @@ var EmbeddingIndex = class _EmbeddingIndex {
114919
114760
  return path3.join(this.dir, INDEX_FILE);
114920
114761
  }
114921
114762
  async load() {
114763
+ if (this.loaded)
114764
+ return;
114922
114765
  try {
114923
114766
  const raw = await promises.readFile(this.filePath, "utf8");
114924
114767
  const parsed = JSON.parse(raw);
114768
+ this.loaded = true;
114925
114769
  if (parsed.version !== INDEX_VERSION)
114926
114770
  return;
114927
114771
  if (parsed.embedder !== this.embedderName)
@@ -114934,6 +114778,7 @@ var EmbeddingIndex = class _EmbeddingIndex {
114934
114778
  } catch (err) {
114935
114779
  if (!isEnoent2(err))
114936
114780
  throw err;
114781
+ this.loaded = true;
114937
114782
  }
114938
114783
  }
114939
114784
  /**
@@ -115011,7 +114856,6 @@ function isEnoent3(err) {
115011
114856
  return err instanceof Error && "code" in err && err.code === "ENOENT";
115012
114857
  }
115013
114858
  async function listEntries(dir, filterType) {
115014
- const entries = [];
115015
114859
  let names;
115016
114860
  try {
115017
114861
  names = await promises.readdir(dir, { withFileTypes: true });
@@ -115020,28 +114864,23 @@ async function listEntries(dir, filterType) {
115020
114864
  return [];
115021
114865
  throw err;
115022
114866
  }
115023
- for (const dirent of names) {
115024
- if (!dirent.isFile())
115025
- continue;
115026
- if (!dirent.name.endsWith(".md"))
115027
- continue;
115028
- if (dirent.name === "MEMORY.md")
115029
- continue;
114867
+ const candidates = names.filter((d2) => d2.isFile() && d2.name.endsWith(".md") && d2.name !== "MEMORY.md");
114868
+ const parsed = await Promise.all(candidates.map(async (dirent) => {
115030
114869
  const filePath = path3.join(dir, dirent.name);
115031
114870
  const raw = await promises.readFile(filePath, "utf8");
115032
- const parsed = parseMdFile(raw);
115033
- const result = memoryFrontmatterSchema.safeParse(parsed.frontmatter);
114871
+ const md = parseMdFile(raw);
114872
+ const result = memoryFrontmatterSchema.safeParse(md.frontmatter);
115034
114873
  if (!result.success)
115035
- continue;
114874
+ return null;
115036
114875
  if (filterType && result.data.type !== filterType)
115037
- continue;
115038
- entries.push({
114876
+ return null;
114877
+ return {
115039
114878
  frontmatter: result.data,
115040
- body: parsed.body.trim(),
114879
+ body: md.body.trim(),
115041
114880
  path: filePath
115042
- });
115043
- }
115044
- return entries;
114881
+ };
114882
+ }));
114883
+ return parsed.filter((e3) => e3 !== null);
115045
114884
  }
115046
114885
  async function readEntry(filePath) {
115047
114886
  try {
@@ -115419,6 +115258,7 @@ async function consolidateMemory(store, provider, opts = {}) {
115419
115258
  const all = await store.list();
115420
115259
  const plan = planConsolidation(all, { tag: opts.tag });
115421
115260
  const byName = new Map(all.map((e3) => [e3.frontmatter.name, e3]));
115261
+ const produced = /* @__PURE__ */ new Set();
115422
115262
  const outcomes = [];
115423
115263
  for (const cluster of plan.clusters) {
115424
115264
  const members = cluster.members.map((n2) => byName.get(n2)).filter((e3) => Boolean(e3));
@@ -115450,7 +115290,7 @@ body: ${m3.body}`).join("\n\n");
115450
115290
  const extracted = extractJson(response);
115451
115291
  const parsed = consolidatedSchema.parse(extracted);
115452
115292
  const clusterNames = new Set(cluster.members);
115453
- if (byName.has(parsed.name) && !clusterNames.has(parsed.name)) {
115293
+ if ((byName.has(parsed.name) || produced.has(parsed.name)) && !clusterNames.has(parsed.name)) {
115454
115294
  outcomes.push({
115455
115295
  key: cluster.key,
115456
115296
  merged: cluster.members,
@@ -115466,6 +115306,7 @@ body: ${m3.body}`).join("\n\n");
115466
115306
  body: parsed.body,
115467
115307
  ...parsed.tags ? { tags: parsed.tags } : {}
115468
115308
  });
115309
+ produced.add(parsed.name);
115469
115310
  for (const member of members) {
115470
115311
  if (member.frontmatter.name !== parsed.name) {
115471
115312
  await store.forget(member.frontmatter.name);
@@ -115485,7 +115326,7 @@ function extractJson(text) {
115485
115326
  const candidate = fenced ? fenced[1] : text;
115486
115327
  const start = candidate.indexOf("{");
115487
115328
  const end = candidate.lastIndexOf("}");
115488
- if (start === -1 || end === -1)
115329
+ if (start === -1 || end <= start)
115489
115330
  throw new Error("consolidate: model returned no JSON object");
115490
115331
  return JSON.parse(candidate.slice(start, end + 1));
115491
115332
  }
@@ -115694,13 +115535,13 @@ function buildSessionConfigApplier(session, initial, builtins = [], disabledPack
115694
115535
  );
115695
115536
  return async (next) => {
115696
115537
  const applied = [];
115697
- const pending = [];
115538
+ const pending2 = [];
115698
115539
  if (next.mode !== last.mode) {
115699
115540
  try {
115700
115541
  if (next.mode) session.modes.setActive(next.mode);
115701
115542
  applied.push("mode");
115702
115543
  } catch (err) {
115703
- pending.push(`mode (${err instanceof Error ? err.message : String(err)})`);
115544
+ pending2.push(`mode (${err instanceof Error ? err.message : String(err)})`);
115704
115545
  }
115705
115546
  }
115706
115547
  if (next.compactor !== last.compactor) {
@@ -115708,7 +115549,7 @@ function buildSessionConfigApplier(session, initial, builtins = [], disabledPack
115708
115549
  if (next.compactor) session.compactors.setActive(next.compactor);
115709
115550
  applied.push("compactor");
115710
115551
  } catch (err) {
115711
- pending.push(`compactor (${err instanceof Error ? err.message : String(err)})`);
115552
+ pending2.push(`compactor (${err instanceof Error ? err.message : String(err)})`);
115712
115553
  }
115713
115554
  }
115714
115555
  if (next.context?.caching !== last.context?.caching || next.context?.cacheStrategy !== last.context?.cacheStrategy) {
@@ -115717,7 +115558,7 @@ function buildSessionConfigApplier(session, initial, builtins = [], disabledPack
115717
115558
  else session.cacheStrategies.setActive(next.context?.cacheStrategy ?? "stable-prefix");
115718
115559
  applied.push("cacheStrategy");
115719
115560
  } catch (err) {
115720
- pending.push(`cacheStrategy (${err instanceof Error ? err.message : String(err)})`);
115561
+ pending2.push(`cacheStrategy (${err instanceof Error ? err.message : String(err)})`);
115721
115562
  }
115722
115563
  }
115723
115564
  if (next.context?.elision !== last.context?.elision) {
@@ -115733,14 +115574,14 @@ function buildSessionConfigApplier(session, initial, builtins = [], disabledPack
115733
115574
  applied.push("reasoning");
115734
115575
  }
115735
115576
  if (next.hookTimeoutMs !== last.hookTimeoutMs) {
115736
- pending.push("hookTimeoutMs (restart required)");
115577
+ pending2.push("hookTimeoutMs (restart required)");
115737
115578
  }
115738
115579
  if (providerChanged(last, next)) {
115739
- pending.push("provider.* (restart required)");
115580
+ pending2.push("provider.* (restart required)");
115740
115581
  }
115741
115582
  const toggles = await applyPluginToggles(session, builtinsByName, last, next);
115742
115583
  for (const t2 of toggles.applied) applied.push(`plugins[${t2.name}].enabled=${t2.enabled}`);
115743
- for (const p3 of toggles.pending) pending.push(p3);
115584
+ for (const p3 of toggles.pending) pending2.push(p3);
115744
115585
  if (disabledPackages) {
115745
115586
  for (const [name, settings] of Object.entries(next.plugins ?? {})) {
115746
115587
  if (settings?.enabled === false) disabledPackages.add(name);
@@ -115748,19 +115589,19 @@ function buildSessionConfigApplier(session, initial, builtins = [], disabledPack
115748
115589
  }
115749
115590
  }
115750
115591
  if (!shallowEqual(last.embeddings, next.embeddings)) {
115751
- pending.push("embeddings.* (restart required to rebuild memory embedder)");
115592
+ pending2.push("embeddings.* (restart required to rebuild memory embedder)");
115752
115593
  }
115753
115594
  if (!shallowEqual(last.channels, next.channels)) {
115754
- pending.push("channels.* (applies on next `moxxy <channel>` invocation)");
115595
+ pending2.push("channels.* (applies on next `moxxy <channel>` invocation)");
115755
115596
  }
115756
115597
  if (!shallowEqual(last.skills, next.skills)) {
115757
- pending.push("skills.* (restart to rediscover)");
115598
+ pending2.push("skills.* (restart to rediscover)");
115758
115599
  }
115759
115600
  if (!shallowEqual(last.permissions, next.permissions)) {
115760
- pending.push("permissions.* (restart to reload policy)");
115601
+ pending2.push("permissions.* (restart to reload policy)");
115761
115602
  }
115762
115603
  last = next;
115763
- return { applied, pending };
115604
+ return { applied, pending: pending2 };
115764
115605
  };
115765
115606
  }
115766
115607
  async function applyPluginToggles(session, builtinsByName, last, next) {
@@ -115770,7 +115611,7 @@ async function applyPluginToggles(session, builtinsByName, last, next) {
115770
115611
  ...Object.keys(next.plugins ?? {})
115771
115612
  ]);
115772
115613
  const applied = [];
115773
- const pending = [];
115614
+ const pending2 = [];
115774
115615
  const loaded = new Set(session.pluginHost.list().map((p3) => p3.name));
115775
115616
  for (const name of allNames) {
115776
115617
  const wasEnabled = effectiveEnabled(last, name);
@@ -115790,10 +115631,10 @@ async function applyPluginToggles(session, builtinsByName, last, next) {
115790
115631
  applied.push({ name, enabled: true });
115791
115632
  } catch (err) {
115792
115633
  if (err instanceof PluginRequirementError) {
115793
- pending.push(`plugins[${name}].enabled=true (${err.message})`);
115634
+ pending2.push(`plugins[${name}].enabled=true (${err.message})`);
115794
115635
  continue;
115795
115636
  }
115796
- pending.push(`plugins[${name}].enabled=true (${err instanceof Error ? err.message : String(err)})`);
115637
+ pending2.push(`plugins[${name}].enabled=true (${err instanceof Error ? err.message : String(err)})`);
115797
115638
  }
115798
115639
  } else {
115799
115640
  if (!loaded.has(name)) continue;
@@ -115801,11 +115642,11 @@ async function applyPluginToggles(session, builtinsByName, last, next) {
115801
115642
  await session.pluginHost.unload(name);
115802
115643
  applied.push({ name, enabled: false });
115803
115644
  } catch (err) {
115804
- pending.push(`plugins[${name}].enabled=false (${err instanceof Error ? err.message : String(err)})`);
115645
+ pending2.push(`plugins[${name}].enabled=false (${err instanceof Error ? err.message : String(err)})`);
115805
115646
  }
115806
115647
  }
115807
115648
  }
115808
- return { applied, pending };
115649
+ return { applied, pending: pending2 };
115809
115650
  }
115810
115651
  function effectiveEnabled(cfg, name) {
115811
115652
  const entry = cfg.plugins?.[name];
@@ -116308,13 +116149,13 @@ var MultipartBody = class {
116308
116149
  }
116309
116150
  };
116310
116151
  var fileFromPathWarned = false;
116311
- async function fileFromPath3(path62, ...args) {
116152
+ async function fileFromPath3(path60, ...args) {
116312
116153
  const { fileFromPath: _fileFromPath } = await Promise.resolve().then(() => (init_fileFromPath(), fileFromPath_exports));
116313
116154
  if (!fileFromPathWarned) {
116314
- console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path62)}) instead`);
116155
+ console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path60)}) instead`);
116315
116156
  fileFromPathWarned = true;
116316
116157
  }
116317
- return await _fileFromPath(path62, ...args);
116158
+ return await _fileFromPath(path60, ...args);
116318
116159
  }
116319
116160
  var defaultHttpAgent = new import_agentkeepalive.default({ keepAlive: true, timeout: 5 * 60 * 1e3 });
116320
116161
  var defaultHttpsAgent = new import_agentkeepalive.default.HttpsAgent({ keepAlive: true, timeout: 5 * 60 * 1e3 });
@@ -117037,29 +116878,29 @@ var APIClient = class {
117037
116878
  defaultIdempotencyKey() {
117038
116879
  return `stainless-node-retry-${uuid4()}`;
117039
116880
  }
117040
- get(path62, opts) {
117041
- return this.methodRequest("get", path62, opts);
116881
+ get(path60, opts) {
116882
+ return this.methodRequest("get", path60, opts);
117042
116883
  }
117043
- post(path62, opts) {
117044
- return this.methodRequest("post", path62, opts);
116884
+ post(path60, opts) {
116885
+ return this.methodRequest("post", path60, opts);
117045
116886
  }
117046
- patch(path62, opts) {
117047
- return this.methodRequest("patch", path62, opts);
116887
+ patch(path60, opts) {
116888
+ return this.methodRequest("patch", path60, opts);
117048
116889
  }
117049
- put(path62, opts) {
117050
- return this.methodRequest("put", path62, opts);
116890
+ put(path60, opts) {
116891
+ return this.methodRequest("put", path60, opts);
117051
116892
  }
117052
- delete(path62, opts) {
117053
- return this.methodRequest("delete", path62, opts);
116893
+ delete(path60, opts) {
116894
+ return this.methodRequest("delete", path60, opts);
117054
116895
  }
117055
- methodRequest(method, path62, opts) {
116896
+ methodRequest(method, path60, opts) {
117056
116897
  return this.request(Promise.resolve(opts).then(async (opts2) => {
117057
116898
  const body = opts2 && isBlobLike(opts2?.body) ? new DataView(await opts2.body.arrayBuffer()) : opts2?.body instanceof DataView ? opts2.body : opts2?.body instanceof ArrayBuffer ? new DataView(opts2.body) : opts2 && ArrayBuffer.isView(opts2?.body) ? new DataView(opts2.body.buffer) : opts2?.body;
117058
- return { method, path: path62, ...opts2, body };
116899
+ return { method, path: path60, ...opts2, body };
117059
116900
  }));
117060
116901
  }
117061
- getAPIList(path62, Page3, opts) {
117062
- return this.requestAPIList(Page3, { method: "get", path: path62, ...opts });
116902
+ getAPIList(path60, Page3, opts) {
116903
+ return this.requestAPIList(Page3, { method: "get", path: path60, ...opts });
117063
116904
  }
117064
116905
  calculateContentLength(body) {
117065
116906
  if (typeof body === "string") {
@@ -117078,10 +116919,10 @@ var APIClient = class {
117078
116919
  }
117079
116920
  buildRequest(inputOptions, { retryCount = 0 } = {}) {
117080
116921
  const options = { ...inputOptions };
117081
- const { method, path: path62, query, headers = {} } = options;
116922
+ const { method, path: path60, query, headers = {} } = options;
117082
116923
  const body = ArrayBuffer.isView(options.body) || options.__binaryRequest && typeof options.body === "string" ? options.body : isMultipartBody(options.body) ? options.body.body : options.body ? JSON.stringify(options.body, null, 2) : null;
117083
116924
  const contentLength = this.calculateContentLength(body);
117084
- const url2 = this.buildURL(path62, query);
116925
+ const url2 = this.buildURL(path60, query);
117085
116926
  if ("timeout" in options)
117086
116927
  validatePositiveInteger("timeout", options.timeout);
117087
116928
  options.timeout = options.timeout ?? this.timeout;
@@ -117205,8 +117046,8 @@ var APIClient = class {
117205
117046
  const request = this.makeRequest(options, null);
117206
117047
  return new PagePromise(this, request, Page3);
117207
117048
  }
117208
- buildURL(path62, query) {
117209
- const url2 = isAbsoluteURL(path62) ? new URL(path62) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path62.startsWith("/") ? path62.slice(1) : path62));
117049
+ buildURL(path60, query) {
117050
+ const url2 = isAbsoluteURL(path60) ? new URL(path60) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path60.startsWith("/") ? path60.slice(1) : path60));
117210
117051
  const defaultQuery = this.defaultQuery();
117211
117052
  if (!isEmptyObj(defaultQuery)) {
117212
117053
  query = { ...defaultQuery, ...query };
@@ -120408,13 +120249,13 @@ var MultipartBody2 = class {
120408
120249
  }
120409
120250
  };
120410
120251
  var fileFromPathWarned2 = false;
120411
- async function fileFromPath5(path62, ...args) {
120252
+ async function fileFromPath5(path60, ...args) {
120412
120253
  const { fileFromPath: _fileFromPath } = await Promise.resolve().then(() => (init_fileFromPath(), fileFromPath_exports));
120413
120254
  if (!fileFromPathWarned2) {
120414
- console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path62)}) instead`);
120255
+ console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path60)}) instead`);
120415
120256
  fileFromPathWarned2 = true;
120416
120257
  }
120417
- return await _fileFromPath(path62, ...args);
120258
+ return await _fileFromPath(path60, ...args);
120418
120259
  }
120419
120260
  var defaultHttpAgent2 = new import_agentkeepalive2.default({ keepAlive: true, timeout: 5 * 60 * 1e3 });
120420
120261
  var defaultHttpsAgent2 = new import_agentkeepalive2.default.HttpsAgent({ keepAlive: true, timeout: 5 * 60 * 1e3 });
@@ -121192,29 +121033,29 @@ var APIClient2 = class {
121192
121033
  defaultIdempotencyKey() {
121193
121034
  return `stainless-node-retry-${uuid42()}`;
121194
121035
  }
121195
- get(path62, opts) {
121196
- return this.methodRequest("get", path62, opts);
121036
+ get(path60, opts) {
121037
+ return this.methodRequest("get", path60, opts);
121197
121038
  }
121198
- post(path62, opts) {
121199
- return this.methodRequest("post", path62, opts);
121039
+ post(path60, opts) {
121040
+ return this.methodRequest("post", path60, opts);
121200
121041
  }
121201
- patch(path62, opts) {
121202
- return this.methodRequest("patch", path62, opts);
121042
+ patch(path60, opts) {
121043
+ return this.methodRequest("patch", path60, opts);
121203
121044
  }
121204
- put(path62, opts) {
121205
- return this.methodRequest("put", path62, opts);
121045
+ put(path60, opts) {
121046
+ return this.methodRequest("put", path60, opts);
121206
121047
  }
121207
- delete(path62, opts) {
121208
- return this.methodRequest("delete", path62, opts);
121048
+ delete(path60, opts) {
121049
+ return this.methodRequest("delete", path60, opts);
121209
121050
  }
121210
- methodRequest(method, path62, opts) {
121051
+ methodRequest(method, path60, opts) {
121211
121052
  return this.request(Promise.resolve(opts).then(async (opts2) => {
121212
121053
  const body = opts2 && isBlobLike2(opts2?.body) ? new DataView(await opts2.body.arrayBuffer()) : opts2?.body instanceof DataView ? opts2.body : opts2?.body instanceof ArrayBuffer ? new DataView(opts2.body) : opts2 && ArrayBuffer.isView(opts2?.body) ? new DataView(opts2.body.buffer) : opts2?.body;
121213
- return { method, path: path62, ...opts2, body };
121054
+ return { method, path: path60, ...opts2, body };
121214
121055
  }));
121215
121056
  }
121216
- getAPIList(path62, Page3, opts) {
121217
- return this.requestAPIList(Page3, { method: "get", path: path62, ...opts });
121057
+ getAPIList(path60, Page3, opts) {
121058
+ return this.requestAPIList(Page3, { method: "get", path: path60, ...opts });
121218
121059
  }
121219
121060
  calculateContentLength(body) {
121220
121061
  if (typeof body === "string") {
@@ -121233,10 +121074,10 @@ var APIClient2 = class {
121233
121074
  }
121234
121075
  buildRequest(inputOptions, { retryCount = 0 } = {}) {
121235
121076
  const options = { ...inputOptions };
121236
- const { method, path: path62, query, headers = {} } = options;
121077
+ const { method, path: path60, query, headers = {} } = options;
121237
121078
  const body = ArrayBuffer.isView(options.body) || options.__binaryRequest && typeof options.body === "string" ? options.body : isMultipartBody2(options.body) ? options.body.body : options.body ? JSON.stringify(options.body, null, 2) : null;
121238
121079
  const contentLength = this.calculateContentLength(body);
121239
- const url2 = this.buildURL(path62, query);
121080
+ const url2 = this.buildURL(path60, query);
121240
121081
  if ("timeout" in options)
121241
121082
  validatePositiveInteger2("timeout", options.timeout);
121242
121083
  options.timeout = options.timeout ?? this.timeout;
@@ -121352,8 +121193,8 @@ var APIClient2 = class {
121352
121193
  const request = this.makeRequest(options, null);
121353
121194
  return new PagePromise2(this, request, Page3);
121354
121195
  }
121355
- buildURL(path62, query) {
121356
- const url2 = isAbsoluteURL2(path62) ? new URL(path62) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path62.startsWith("/") ? path62.slice(1) : path62));
121196
+ buildURL(path60, query) {
121197
+ const url2 = isAbsoluteURL2(path60) ? new URL(path60) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path60.startsWith("/") ? path60.slice(1) : path60));
121357
121198
  const defaultQuery = this.defaultQuery();
121358
121199
  if (!isEmptyObj2(defaultQuery)) {
121359
121200
  query = { ...defaultQuery, ...query };
@@ -126384,7 +126225,7 @@ var OpenAIProvider = class {
126384
126225
  yield { type: "error", ...toFriendlyError(err, { provider: this.name }) };
126385
126226
  return;
126386
126227
  }
126387
- const pending = /* @__PURE__ */ new Map();
126228
+ const pending2 = /* @__PURE__ */ new Map();
126388
126229
  let stopReason = "end_turn";
126389
126230
  let usageIn = 0;
126390
126231
  let usageOut = 0;
@@ -126416,7 +126257,7 @@ var OpenAIProvider = class {
126416
126257
  if (delta.tool_calls) {
126417
126258
  for (const tcDelta of delta.tool_calls) {
126418
126259
  const idx = tcDelta.index ?? 0;
126419
- let entry = pending.get(idx);
126260
+ let entry = pending2.get(idx);
126420
126261
  if (!entry) {
126421
126262
  entry = {
126422
126263
  id: tcDelta.id ?? `call_${idx}`,
@@ -126424,7 +126265,7 @@ var OpenAIProvider = class {
126424
126265
  argsBuffer: "",
126425
126266
  emittedStart: false
126426
126267
  };
126427
- pending.set(idx, entry);
126268
+ pending2.set(idx, entry);
126428
126269
  } else if (tcDelta.id) {
126429
126270
  entry.id = tcDelta.id;
126430
126271
  }
@@ -126448,7 +126289,7 @@ var OpenAIProvider = class {
126448
126289
  yield { type: "error", ...toFriendlyError(err, { provider: this.name }) };
126449
126290
  return;
126450
126291
  }
126451
- for (const entry of pending.values()) {
126292
+ for (const entry of pending2.values()) {
126452
126293
  let parsed = {};
126453
126294
  if (entry.argsBuffer) {
126454
126295
  try {
@@ -126778,11 +126619,11 @@ function buildAuthUrl(input) {
126778
126619
  }
126779
126620
  async function runAuthorizationCodeFlow(opts) {
126780
126621
  const port = opts.redirectPort ?? 8765;
126781
- const path62 = opts.redirectPath ?? "/callback";
126622
+ const path60 = opts.redirectPath ?? "/callback";
126782
126623
  const codeVerifier = generateCodeVerifier();
126783
126624
  const codeChallenge = computeCodeChallenge(codeVerifier);
126784
126625
  const state = generateState();
126785
- const redirectUri = `http://localhost:${port}${path62}`;
126626
+ const redirectUri = `http://localhost:${port}${path60}`;
126786
126627
  const authUrl = buildAuthUrl({
126787
126628
  authUrl: opts.authUrl,
126788
126629
  clientId: opts.clientId,
@@ -126794,7 +126635,7 @@ async function runAuthorizationCodeFlow(opts) {
126794
126635
  });
126795
126636
  const codePromise = waitForCallback({
126796
126637
  port,
126797
- path: path62,
126638
+ path: path60,
126798
126639
  expectedState: state,
126799
126640
  timeoutMs: opts.timeoutMs ?? 3e5,
126800
126641
  ...opts.signal ? { signal: opts.signal } : {}
@@ -126817,8 +126658,6 @@ async function runAuthorizationCodeFlow(opts) {
126817
126658
  codeVerifier
126818
126659
  });
126819
126660
  }
126820
-
126821
- // ../plugin-oauth/dist/oauth/poll-until.js
126822
126661
  async function pollUntil(fn, opts) {
126823
126662
  const state = { intervalMs: opts.intervalMs };
126824
126663
  const leadingWait = opts.leadingWait ?? true;
@@ -126827,28 +126666,39 @@ async function pollUntil(fn, opts) {
126827
126666
  let first = true;
126828
126667
  while (Date.now() < deadline) {
126829
126668
  if (opts.signal?.aborted)
126830
- throw new Error(`${label3} aborted`);
126669
+ throw abortedError(label3);
126831
126670
  if (!first || leadingWait) {
126832
126671
  const remaining = deadline - Date.now();
126833
126672
  if (remaining <= 0)
126834
126673
  break;
126835
- await sleep3(Math.min(state.intervalMs, remaining), opts.signal);
126674
+ await sleep3(Math.min(state.intervalMs, remaining), opts.signal, label3);
126836
126675
  }
126837
126676
  first = false;
126838
126677
  const result = await fn(state);
126839
126678
  if ("done" in result)
126840
126679
  return result.done;
126841
126680
  }
126842
- throw new Error(`${label3} timed out waiting for completion`);
126681
+ throw new MoxxyError({
126682
+ code: "OAUTH_FLOW_TIMEOUT",
126683
+ message: `${label3} timed out waiting for completion`,
126684
+ context: { label: label3, timeout_ms: opts.timeoutMs }
126685
+ });
126843
126686
  }
126844
- function sleep3(ms, signal) {
126687
+ function abortedError(label3) {
126688
+ return new MoxxyError({
126689
+ code: "NETWORK_ABORTED",
126690
+ message: `${label3} aborted`,
126691
+ context: { label: label3 }
126692
+ });
126693
+ }
126694
+ function sleep3(ms, signal, label3) {
126845
126695
  return new Promise((resolve13, reject) => {
126846
126696
  if (signal?.aborted)
126847
- return reject(new Error("aborted"));
126697
+ return reject(abortedError(label3));
126848
126698
  const t2 = setTimeout(resolve13, ms);
126849
126699
  const onAbort = () => {
126850
126700
  clearTimeout(t2);
126851
- reject(new Error("aborted"));
126701
+ reject(abortedError(label3));
126852
126702
  };
126853
126703
  signal?.addEventListener("abort", onAbort, { once: true });
126854
126704
  });
@@ -127152,6 +127002,93 @@ async function acquireFileLock(lockPath, staleMs, pollMs, waitMs) {
127152
127002
  function sleep4(ms) {
127153
127003
  return new Promise((resolve13) => setTimeout(resolve13, ms));
127154
127004
  }
127005
+ async function refreshAndStore(vault, spec, stored, retried = false) {
127006
+ if (!stored.tokenSet.refreshToken) {
127007
+ throw spec.noRefreshTokenError();
127008
+ }
127009
+ let refreshed;
127010
+ try {
127011
+ refreshed = await refreshAccessToken({
127012
+ tokenUrl: stored.tokenUrl,
127013
+ clientId: stored.clientId,
127014
+ ...stored.clientSecret ? { clientSecret: stored.clientSecret } : {},
127015
+ refreshToken: stored.tokenSet.refreshToken
127016
+ });
127017
+ } catch (err) {
127018
+ if (!retried && isAuthRejection(err)) {
127019
+ const latest = await readStoredCreds(vault, spec.provider);
127020
+ if (latest?.tokenSet.refreshToken && latest.tokenSet.refreshToken !== stored.tokenSet.refreshToken) {
127021
+ return refreshAndStore(vault, spec, latest, true);
127022
+ }
127023
+ }
127024
+ const net3 = classifyNetworkError(err, { url: stored.tokenUrl, provider: spec.provider });
127025
+ if (net3)
127026
+ throw net3;
127027
+ throw spec.wrapRefreshFailure(err);
127028
+ }
127029
+ const merged = {
127030
+ ...refreshed,
127031
+ refreshToken: refreshed.refreshToken ?? stored.tokenSet.refreshToken
127032
+ };
127033
+ const extras = spec.resolveExtras(merged, stored.extras);
127034
+ await storeTokenSet(vault, spec.provider, merged, {
127035
+ clientId: stored.clientId,
127036
+ ...stored.clientSecret ? { clientSecret: stored.clientSecret } : {},
127037
+ tokenUrl: stored.tokenUrl,
127038
+ ...extras ? { extras } : {}
127039
+ });
127040
+ return { tokens: merged, extras: extras ?? stored.extras };
127041
+ }
127042
+ async function ensureFreshTokens(profile, vault, opts = {}) {
127043
+ const stored = await readStoredCreds(vault, profile.id);
127044
+ if (!stored) {
127045
+ throw new MoxxyError({
127046
+ code: "AUTH_NO_CREDENTIALS",
127047
+ message: `No stored OAuth credentials for "${profile.id}".`,
127048
+ hint: `Run \`moxxy login ${profile.id}\` to sign in.`,
127049
+ context: { provider: profile.id }
127050
+ });
127051
+ }
127052
+ if (!opts.force && !isExpired(stored.tokenSet, opts.skewMs)) {
127053
+ return { tokens: stored.tokenSet, extras: stored.extras };
127054
+ }
127055
+ return withCredentialLock(`oauth-${profile.id}`, async () => {
127056
+ const current = await readStoredCreds(vault, profile.id) ?? stored;
127057
+ const rotatedMeanwhile = current.tokenSet.accessToken !== stored.tokenSet.accessToken;
127058
+ if (!isExpired(current.tokenSet, opts.skewMs) && (!opts.force || rotatedMeanwhile)) {
127059
+ return { tokens: current.tokenSet, extras: current.extras };
127060
+ }
127061
+ return refreshAndStore(vault, profileRefreshSpec(profile), current);
127062
+ });
127063
+ }
127064
+ function profileRefreshSpec(profile) {
127065
+ return {
127066
+ provider: profile.id,
127067
+ noRefreshTokenError: () => new MoxxyError({
127068
+ code: "AUTH_EXPIRED",
127069
+ message: `OAuth token for "${profile.id}" expired and no refresh_token is stored.`,
127070
+ hint: `Re-run \`moxxy login ${profile.id}\` to sign in again.`,
127071
+ context: { provider: profile.id }
127072
+ }),
127073
+ wrapRefreshFailure: (err) => new MoxxyError({
127074
+ code: "AUTH_EXPIRED",
127075
+ message: `Couldn't refresh the OAuth token for "${profile.id}".`,
127076
+ hint: `Re-run \`moxxy login ${profile.id}\` to sign in again.`,
127077
+ context: { provider: profile.id },
127078
+ cause: err
127079
+ }),
127080
+ resolveExtras: (merged, storedExtras) => {
127081
+ const freshAccountId = profile.extractAccountId?.(merged);
127082
+ const freshExtras = profile.extractExtras?.(merged) ?? {};
127083
+ const mergedExtras = { ...storedExtras, ...freshExtras };
127084
+ if (freshAccountId)
127085
+ mergedExtras.account_id = freshAccountId;
127086
+ return mergedExtras;
127087
+ }
127088
+ };
127089
+ }
127090
+
127091
+ // ../plugin-oauth/dist/tools.js
127155
127092
  var providerNameField = z$1.string().min(1).max(60).describe('Stable provider key used as the vault namespace (e.g. "google", "github", "notion"). Lowercase letters, digits, dot/dash/underscore only.');
127156
127093
  function buildOauthAuthorizeTool(deps) {
127157
127094
  return defineTool({
@@ -127218,11 +127155,11 @@ function buildOauthAuthorizeTool(deps) {
127218
127155
  const { computeCodeChallenge: computeCodeChallenge2 } = await Promise.resolve().then(() => (init_pkce(), pkce_exports));
127219
127156
  const challenge = computeCodeChallenge2(verifier);
127220
127157
  const port = input.redirectPort ?? 8765;
127221
- const path62 = input.redirectPath ?? "/callback";
127158
+ const path60 = input.redirectPath ?? "/callback";
127222
127159
  const url2 = buildAuthUrl({
127223
127160
  authUrl: input.authUrl,
127224
127161
  clientId: input.clientId,
127225
- redirectUri: `http://localhost:${port}${path62}`,
127162
+ redirectUri: `http://localhost:${port}${path60}`,
127226
127163
  scopes: input.scopes,
127227
127164
  codeChallenge: challenge,
127228
127165
  state,
@@ -127291,7 +127228,8 @@ function buildOauthGetTokenTool(deps) {
127291
127228
  if (!isExpired(current.tokenSet) && (!forceRefresh || rotatedMeanwhile)) {
127292
127229
  return current.tokenSet;
127293
127230
  }
127294
- return refreshAndStoreCreds(deps.vault, provider, current);
127231
+ const { tokens: tokens2 } = await refreshAndStore(deps.vault, toolRefreshSpec(provider), current);
127232
+ return tokens2;
127295
127233
  });
127296
127234
  return summarizeTokens(provider, tokens, {
127297
127235
  includeAccess: true,
@@ -127312,45 +127250,17 @@ function buildOauthClearTool(deps) {
127312
127250
  }
127313
127251
  });
127314
127252
  }
127315
- async function refreshAndStoreCreds(vault, provider, stored, retried = false) {
127316
- if (!stored.tokenSet.refreshToken) {
127317
- throw new MoxxyError({
127253
+ function toolRefreshSpec(provider) {
127254
+ return {
127255
+ provider,
127256
+ noRefreshTokenError: () => new MoxxyError({
127318
127257
  code: "AUTH_EXPIRED",
127319
127258
  message: `OAuth token for "${provider}" expired and no refresh_token is stored. Re-run oauth_authorize.`,
127320
127259
  context: { provider }
127321
- });
127322
- }
127323
- let refreshed;
127324
- try {
127325
- refreshed = await refreshAccessToken({
127326
- tokenUrl: stored.tokenUrl,
127327
- clientId: stored.clientId,
127328
- ...stored.clientSecret ? { clientSecret: stored.clientSecret } : {},
127329
- refreshToken: stored.tokenSet.refreshToken
127330
- });
127331
- } catch (err) {
127332
- if (!retried && isAuthRejection(err)) {
127333
- const latest = await readStoredCreds(vault, provider);
127334
- if (latest?.tokenSet.refreshToken && latest.tokenSet.refreshToken !== stored.tokenSet.refreshToken) {
127335
- return refreshAndStoreCreds(vault, provider, latest, true);
127336
- }
127337
- }
127338
- const net3 = classifyNetworkError(err, { url: stored.tokenUrl, provider });
127339
- if (net3)
127340
- throw net3;
127341
- throw err;
127342
- }
127343
- const merged = {
127344
- ...refreshed,
127345
- refreshToken: refreshed.refreshToken ?? stored.tokenSet.refreshToken
127260
+ }),
127261
+ wrapRefreshFailure: (err) => err,
127262
+ resolveExtras: (_merged, storedExtras) => Object.keys(storedExtras).length > 0 ? { ...storedExtras } : void 0
127346
127263
  };
127347
- await storeTokenSet(vault, provider, merged, {
127348
- clientId: stored.clientId,
127349
- ...stored.clientSecret ? { clientSecret: stored.clientSecret } : {},
127350
- tokenUrl: stored.tokenUrl,
127351
- ...Object.keys(stored.extras).length > 0 ? { extras: stored.extras } : {}
127352
- });
127353
- return merged;
127354
127264
  }
127355
127265
  function summarizeTokens(provider, tokens, opts = {}) {
127356
127266
  return {
@@ -127393,7 +127303,7 @@ async function runOauthLogin(profile, ctx) {
127393
127303
  }
127394
127304
  async function runBrowserFlow(profile, ctx) {
127395
127305
  const port = profile.redirect?.port ?? 8765;
127396
- const path62 = profile.redirect?.path ?? "/callback";
127306
+ const path60 = profile.redirect?.path ?? "/callback";
127397
127307
  const serviceName = profile.displayName ?? profile.id;
127398
127308
  return runAuthorizationCodeFlow({
127399
127309
  authUrl: profile.authUrl,
@@ -127402,7 +127312,7 @@ async function runBrowserFlow(profile, ctx) {
127402
127312
  ...profile.clientSecret ? { clientSecret: profile.clientSecret } : {},
127403
127313
  scopes: profile.scopes,
127404
127314
  redirectPort: port,
127405
- redirectPath: path62,
127315
+ redirectPath: path60,
127406
127316
  ...profile.extraAuthParams ? { extraAuthParams: profile.extraAuthParams } : {},
127407
127317
  timeoutMs: DEFAULT_BROWSER_TIMEOUT_MS,
127408
127318
  ...ctx.signal ? { signal: ctx.signal } : {},
@@ -127414,7 +127324,7 @@ If your browser doesn't open automatically, paste this URL:
127414
127324
 
127415
127325
  ${url2}
127416
127326
 
127417
- Waiting for callback on http://localhost:${port}${path62} (5 min timeout)\u2026
127327
+ Waiting for callback on http://localhost:${port}${path60} (5 min timeout)\u2026
127418
127328
 
127419
127329
  `);
127420
127330
  }
@@ -127458,80 +127368,6 @@ Polling every ${Math.round(init3.intervalMs / 1e3)}s (${Math.round(init3.expires
127458
127368
  ...ctx.signal ? { signal: ctx.signal } : {}
127459
127369
  });
127460
127370
  }
127461
- async function ensureFreshTokens(profile, vault, opts = {}) {
127462
- const stored = await readStoredCreds(vault, profile.id);
127463
- if (!stored) {
127464
- throw new MoxxyError({
127465
- code: "AUTH_NO_CREDENTIALS",
127466
- message: `No stored OAuth credentials for "${profile.id}".`,
127467
- hint: `Run \`moxxy login ${profile.id}\` to sign in.`,
127468
- context: { provider: profile.id }
127469
- });
127470
- }
127471
- if (!opts.force && !isExpired(stored.tokenSet, opts.skewMs)) {
127472
- return { tokens: stored.tokenSet, extras: stored.extras };
127473
- }
127474
- return withCredentialLock(`oauth-${profile.id}`, async () => {
127475
- const current = await readStoredCreds(vault, profile.id) ?? stored;
127476
- const rotatedMeanwhile = current.tokenSet.accessToken !== stored.tokenSet.accessToken;
127477
- if (!isExpired(current.tokenSet, opts.skewMs) && (!opts.force || rotatedMeanwhile)) {
127478
- return { tokens: current.tokenSet, extras: current.extras };
127479
- }
127480
- return refreshAndStore(profile, vault, current);
127481
- });
127482
- }
127483
- async function refreshAndStore(profile, vault, stored, retried = false) {
127484
- if (!stored.tokenSet.refreshToken) {
127485
- throw new MoxxyError({
127486
- code: "AUTH_EXPIRED",
127487
- message: `OAuth token for "${profile.id}" expired and no refresh_token is stored.`,
127488
- hint: `Re-run \`moxxy login ${profile.id}\` to sign in again.`,
127489
- context: { provider: profile.id }
127490
- });
127491
- }
127492
- let refreshed;
127493
- try {
127494
- refreshed = await refreshAccessToken({
127495
- tokenUrl: stored.tokenUrl,
127496
- clientId: stored.clientId,
127497
- ...stored.clientSecret ? { clientSecret: stored.clientSecret } : {},
127498
- refreshToken: stored.tokenSet.refreshToken
127499
- });
127500
- } catch (err) {
127501
- if (!retried && isAuthRejection(err)) {
127502
- const latest = await readStoredCreds(vault, profile.id);
127503
- if (latest?.tokenSet.refreshToken && latest.tokenSet.refreshToken !== stored.tokenSet.refreshToken) {
127504
- return refreshAndStore(profile, vault, latest, true);
127505
- }
127506
- }
127507
- const net3 = classifyNetworkError(err, { url: stored.tokenUrl, provider: profile.id });
127508
- if (net3)
127509
- throw net3;
127510
- throw new MoxxyError({
127511
- code: "AUTH_EXPIRED",
127512
- message: `Couldn't refresh the OAuth token for "${profile.id}".`,
127513
- hint: `Re-run \`moxxy login ${profile.id}\` to sign in again.`,
127514
- context: { provider: profile.id },
127515
- cause: err
127516
- });
127517
- }
127518
- const merged = {
127519
- ...refreshed,
127520
- refreshToken: refreshed.refreshToken ?? stored.tokenSet.refreshToken
127521
- };
127522
- const freshAccountId = profile.extractAccountId?.(merged);
127523
- const freshExtras = profile.extractExtras?.(merged) ?? {};
127524
- const mergedExtras = { ...stored.extras, ...freshExtras };
127525
- if (freshAccountId)
127526
- mergedExtras.account_id = freshAccountId;
127527
- await storeTokenSet(vault, profile.id, merged, {
127528
- clientId: stored.clientId,
127529
- ...stored.clientSecret ? { clientSecret: stored.clientSecret } : {},
127530
- tokenUrl: stored.tokenUrl,
127531
- extras: mergedExtras
127532
- });
127533
- return { tokens: merged, extras: mergedExtras };
127534
- }
127535
127371
  function openaiDeviceFlow(opts) {
127536
127372
  const initUrl = `${opts.issuer}/api/accounts/deviceauth/usercode`;
127537
127373
  const pollUrl = `${opts.issuer}/api/accounts/deviceauth/token`;
@@ -127553,8 +127389,10 @@ function openaiDeviceFlow(opts) {
127553
127389
  });
127554
127390
  }
127555
127391
  const data = await res.json();
127556
- const intervalSec = Math.max(typeof data.interval === "string" ? parseInt(data.interval, 10) : data.interval ?? 5, 1);
127557
- const expiresInSec = typeof data.expires_in === "string" ? parseInt(data.expires_in, 10) : data.expires_in ?? 600;
127392
+ const rawInterval = typeof data.interval === "string" ? parseInt(data.interval, 10) : data.interval;
127393
+ const intervalSec = Math.max(Number.isFinite(rawInterval) ? rawInterval : 5, 1);
127394
+ const rawExpiresIn = typeof data.expires_in === "string" ? parseInt(data.expires_in, 10) : data.expires_in;
127395
+ const expiresInSec = Number.isFinite(rawExpiresIn) ? rawExpiresIn : 600;
127558
127396
  return {
127559
127397
  userCode: data.user_code,
127560
127398
  verificationUri: opts.verificationUri,
@@ -127576,30 +127414,15 @@ function openaiDeviceFlow(opts) {
127576
127414
  });
127577
127415
  if (res.ok) {
127578
127416
  const data = await res.json();
127579
- const exchangeRes = await fetch(opts.tokenUrl, {
127580
- method: "POST",
127581
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
127582
- body: new URLSearchParams({
127583
- grant_type: "authorization_code",
127417
+ return {
127418
+ done: await exchangeCodeForToken({
127419
+ tokenUrl: opts.tokenUrl,
127584
127420
  code: data.authorization_code,
127585
- redirect_uri: exchangeRedirectUri,
127586
- client_id: clientId,
127587
- code_verifier: data.code_verifier
127588
- }).toString()
127589
- });
127590
- if (!exchangeRes.ok) {
127591
- const text2 = await exchangeRes.text().catch(() => "");
127592
- throw classifyHttpStatus(exchangeRes.status, {
127593
- url: opts.tokenUrl,
127594
- body: text2 || exchangeRes.statusText
127595
- }) ?? new MoxxyError({
127596
- code: "AUTH_INVALID",
127597
- message: `Token endpoint returned ${exchangeRes.status}: ${text2 || exchangeRes.statusText}`,
127598
- context: { status: exchangeRes.status, url: opts.tokenUrl }
127599
- });
127600
- }
127601
- const json = await exchangeRes.json();
127602
- return { done: parseTokenResponse(json) };
127421
+ redirectUri: exchangeRedirectUri,
127422
+ clientId,
127423
+ codeVerifier: data.code_verifier
127424
+ })
127425
+ };
127603
127426
  }
127604
127427
  if (res.status === 403 || res.status === 404) {
127605
127428
  return { pending: true };
@@ -127841,7 +127664,7 @@ function buildCodexHeaders(tokens, sessionId) {
127841
127664
  }
127842
127665
 
127843
127666
  // ../plugin-provider-openai-codex/dist/codex/sse-event-handler.js
127844
- function handleSseEvent(ev, pending, emitReasoning = false) {
127667
+ function handleSseEvent(ev, pending2, emitReasoning = false) {
127845
127668
  const type = ev.type ?? "";
127846
127669
  if (type === "response.output_text.delta" && typeof ev.delta === "string" && ev.delta) {
127847
127670
  return { events: [{ type: "text_delta", delta: ev.delta }] };
@@ -127853,7 +127676,7 @@ function handleSseEvent(ev, pending, emitReasoning = false) {
127853
127676
  return ev.item.encrypted_content ? { events: [{ type: "reasoning_signature", encrypted: ev.item.encrypted_content }] } : {};
127854
127677
  }
127855
127678
  if (type === "response.output_item.added" && ev.item?.type === "function_call") {
127856
- const id = ev.item.id ?? ev.item.call_id ?? `call_${pending.size}`;
127679
+ const id = ev.item.id ?? ev.item.call_id ?? `call_${pending2.size}`;
127857
127680
  const callId = ev.item.call_id ?? id;
127858
127681
  const name = ev.item.name ?? "";
127859
127682
  const entry = {
@@ -127863,7 +127686,7 @@ function handleSseEvent(ev, pending, emitReasoning = false) {
127863
127686
  args: ev.item.arguments ?? "",
127864
127687
  emittedStart: false
127865
127688
  };
127866
- pending.set(id, entry);
127689
+ pending2.set(id, entry);
127867
127690
  if (name) {
127868
127691
  entry.emittedStart = true;
127869
127692
  return { events: [{ type: "tool_use_start", id: callId, name }] };
@@ -127872,7 +127695,7 @@ function handleSseEvent(ev, pending, emitReasoning = false) {
127872
127695
  }
127873
127696
  if (type === "response.function_call_arguments.delta") {
127874
127697
  const id = ev.item_id ?? ev.call_id ?? "";
127875
- const entry = pending.get(id);
127698
+ const entry = pending2.get(id);
127876
127699
  const delta = ev.delta ?? "";
127877
127700
  if (entry && typeof delta === "string") {
127878
127701
  entry.args += delta;
@@ -127890,10 +127713,10 @@ function handleSseEvent(ev, pending, emitReasoning = false) {
127890
127713
  }
127891
127714
  if (type === "response.function_call_arguments.done") {
127892
127715
  const id = ev.item_id ?? ev.call_id ?? "";
127893
- const entry = pending.get(id);
127716
+ const entry = pending2.get(id);
127894
127717
  if (!entry)
127895
127718
  return {};
127896
- pending.delete(id);
127719
+ pending2.delete(id);
127897
127720
  if (typeof ev.arguments === "string" && ev.arguments)
127898
127721
  entry.args = ev.arguments;
127899
127722
  let input = {};
@@ -127950,7 +127773,7 @@ async function* consumeResponsesSse(body, signal, emitReasoning = false) {
127950
127773
  const reader = body.getReader();
127951
127774
  const decoder = new TextDecoder("utf-8");
127952
127775
  let buffer = "";
127953
- const pending = /* @__PURE__ */ new Map();
127776
+ const pending2 = /* @__PURE__ */ new Map();
127954
127777
  let stopReason = "end_turn";
127955
127778
  let usageIn = 0;
127956
127779
  let usageOut = 0;
@@ -127985,7 +127808,7 @@ async function* consumeResponsesSse(body, signal, emitReasoning = false) {
127985
127808
  } catch {
127986
127809
  continue;
127987
127810
  }
127988
- const result = handleSseEvent(json, pending, emitReasoning);
127811
+ const result = handleSseEvent(json, pending2, emitReasoning);
127989
127812
  if (result.events) {
127990
127813
  for (const ev of result.events) {
127991
127814
  if (ev.type === "tool_use_end")
@@ -128013,7 +127836,7 @@ async function* consumeResponsesSse(body, signal, emitReasoning = false) {
128013
127836
  }
128014
127837
  if (errored)
128015
127838
  return;
128016
- for (const entry of pending.values()) {
127839
+ for (const entry of pending2.values()) {
128017
127840
  if (entry.emittedStart) {
128018
127841
  let input = {};
128019
127842
  if (entry.args) {
@@ -128581,11 +128404,14 @@ var claudeCodePlugin = definePlugin({
128581
128404
  // ../plugin-provider-zai/dist/models.js
128582
128405
  var glmModels = [
128583
128406
  // GLM-5 family: coding-first frontier. 5.2 carries a usable 1M context.
128584
- { id: "glm-5.2", contextWindow: 1e6, maxOutputTokens: 128e3, supportsTools: true, supportsStreaming: true },
128585
- { id: "glm-5.1", contextWindow: 2e5, maxOutputTokens: 128e3, supportsTools: true, supportsStreaming: true },
128586
- { id: "glm-5", contextWindow: 2e5, maxOutputTokens: 128e3, supportsTools: true, supportsStreaming: true },
128407
+ // These are reasoning models; the shared OpenAIProvider already streams their
128408
+ // `reasoning_content` deltas, so supportsReasoning gates reasoning_effort +
128409
+ // reasoning-stream surfacing on (without it the capability is dead upstream).
128410
+ { id: "glm-5.2", contextWindow: 1e6, maxOutputTokens: 128e3, supportsTools: true, supportsStreaming: true, supportsReasoning: true },
128411
+ { id: "glm-5.1", contextWindow: 2e5, maxOutputTokens: 128e3, supportsTools: true, supportsStreaming: true, supportsReasoning: true },
128412
+ { id: "glm-5", contextWindow: 2e5, maxOutputTokens: 128e3, supportsTools: true, supportsStreaming: true, supportsReasoning: true },
128587
128413
  // GLM-4.6: prior flagship, 200k context, strong agentic-coding scores.
128588
- { id: "glm-4.6", contextWindow: 2e5, maxOutputTokens: 128e3, supportsTools: true, supportsStreaming: true },
128414
+ { id: "glm-4.6", contextWindow: 2e5, maxOutputTokens: 128e3, supportsTools: true, supportsStreaming: true, supportsReasoning: true },
128589
128415
  // GLM-4.5 tier: general (4.5), lightweight (-air), free/fast (-flash).
128590
128416
  { id: "glm-4.5", contextWindow: 131072, maxOutputTokens: 98304, supportsTools: true, supportsStreaming: true },
128591
128417
  { id: "glm-4.5-air", contextWindow: 131072, maxOutputTokens: 98304, supportsTools: true, supportsStreaming: true },
@@ -128666,13 +128492,16 @@ var xaiPlugin = definePlugin({
128666
128492
 
128667
128493
  // ../plugin-provider-google/dist/models.js
128668
128494
  var geminiModels = [
128669
- // Gemini 3 family: current frontier.
128670
- { id: "gemini-3-pro", contextWindow: 1e6, maxOutputTokens: 65536, supportsTools: true, supportsStreaming: true, supportsImages: true },
128671
- { id: "gemini-3-flash", contextWindow: 1e6, maxOutputTokens: 65536, supportsTools: true, supportsStreaming: true, supportsImages: true },
128672
- // Gemini 2.5 family: widely available, strong price/performance.
128673
- { id: "gemini-2.5-pro", contextWindow: 1e6, maxOutputTokens: 65536, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true },
128674
- { id: "gemini-2.5-flash", contextWindow: 1e6, maxOutputTokens: 65536, supportsTools: true, supportsStreaming: true, supportsImages: true },
128675
- { id: "gemini-2.5-flash-lite", contextWindow: 1e6, maxOutputTokens: 65536, supportsTools: true, supportsStreaming: true, supportsImages: true }
128495
+ // Gemini 3 family: current frontier. Reasoning models that natively accept
128496
+ // PDF document input (supportsDocuments) so the desktop ships raw bytes
128497
+ // instead of degrading to extracted text.
128498
+ { id: "gemini-3-pro", contextWindow: 1e6, maxOutputTokens: 65536, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
128499
+ { id: "gemini-3-flash", contextWindow: 1e6, maxOutputTokens: 65536, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
128500
+ // Gemini 2.5 family: widely available, strong price/performance. pro/flash
128501
+ // are reasoning models; all three take native PDFs.
128502
+ { id: "gemini-2.5-pro", contextWindow: 1e6, maxOutputTokens: 65536, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
128503
+ { id: "gemini-2.5-flash", contextWindow: 1e6, maxOutputTokens: 65536, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true, supportsReasoning: true },
128504
+ { id: "gemini-2.5-flash-lite", contextWindow: 1e6, maxOutputTokens: 65536, supportsTools: true, supportsStreaming: true, supportsImages: true, supportsDocuments: true }
128676
128505
  ];
128677
128506
 
128678
128507
  // ../plugin-provider-google/dist/index.js
@@ -128722,8 +128551,10 @@ var localPlugin = definePlugin({
128722
128551
  version: "0.0.0",
128723
128552
  providers: [localProviderDef]
128724
128553
  });
128725
- var WHISPER_PROVIDER_ID = "openai";
128726
- var DEFAULT_FILENAMES = {
128554
+
128555
+ // ../plugin-stt-whisper/dist/audio.js
128556
+ var MOXXY_PCM16_24KHZ_MIME = "audio/x-moxxy-pcm16-24khz";
128557
+ var WHISPER_FILENAME_BY_MIME = {
128727
128558
  "audio/ogg": "audio.ogg",
128728
128559
  "audio/opus": "audio.opus",
128729
128560
  "audio/mpeg": "audio.mp3",
@@ -128735,6 +128566,59 @@ var DEFAULT_FILENAMES = {
128735
128566
  "audio/mp4": "audio.mp4",
128736
128567
  "audio/flac": "audio.flac"
128737
128568
  };
128569
+ function normalizeWhisperUpload(audio, mimeType, filenamePrefix) {
128570
+ const bytes = audio instanceof Uint8Array ? audio : new Uint8Array(audio);
128571
+ const mt3 = mimeType || "audio/wav";
128572
+ if (mt3 === MOXXY_PCM16_24KHZ_MIME) {
128573
+ return {
128574
+ bytes: pcm16MonoToWav(bytes, 24e3),
128575
+ mimeType: "audio/wav",
128576
+ filename: rename(filenamePrefix, "wav") ?? "audio.wav"
128577
+ };
128578
+ }
128579
+ const defaultName = WHISPER_FILENAME_BY_MIME[mt3] ?? "audio.bin";
128580
+ return {
128581
+ bytes,
128582
+ mimeType: mt3,
128583
+ filename: rename(filenamePrefix, extOf(defaultName)) ?? defaultName
128584
+ };
128585
+ }
128586
+ function rename(prefix, ext) {
128587
+ return prefix ? `${prefix}.${ext}` : void 0;
128588
+ }
128589
+ function extOf(filename) {
128590
+ const dot = filename.lastIndexOf(".");
128591
+ return dot >= 0 ? filename.slice(dot + 1) : "bin";
128592
+ }
128593
+ function pcm16MonoToWav(pcm, sampleRate = 24e3) {
128594
+ const data = pcm instanceof Uint8Array ? pcm : new Uint8Array(pcm);
128595
+ const headerBytes = 44;
128596
+ const wav = new Uint8Array(headerBytes + data.byteLength);
128597
+ const view = new DataView(wav.buffer);
128598
+ writeAscii(wav, 0, "RIFF");
128599
+ view.setUint32(4, 36 + data.byteLength, true);
128600
+ writeAscii(wav, 8, "WAVE");
128601
+ writeAscii(wav, 12, "fmt ");
128602
+ view.setUint32(16, 16, true);
128603
+ view.setUint16(20, 1, true);
128604
+ view.setUint16(22, 1, true);
128605
+ view.setUint32(24, sampleRate, true);
128606
+ view.setUint32(28, sampleRate * 2, true);
128607
+ view.setUint16(32, 2, true);
128608
+ view.setUint16(34, 16, true);
128609
+ writeAscii(wav, 36, "data");
128610
+ view.setUint32(40, data.byteLength, true);
128611
+ wav.set(data, headerBytes);
128612
+ return wav;
128613
+ }
128614
+ function writeAscii(target, offset, value) {
128615
+ for (let i2 = 0; i2 < value.length; i2 += 1) {
128616
+ target[offset + i2] = value.charCodeAt(i2);
128617
+ }
128618
+ }
128619
+
128620
+ // ../plugin-stt-whisper/dist/whisper.js
128621
+ var WHISPER_PROVIDER_ID = "openai";
128738
128622
  var WhisperTranscriber = class {
128739
128623
  name;
128740
128624
  client;
@@ -128750,10 +128634,8 @@ var WhisperTranscriber = class {
128750
128634
  });
128751
128635
  }
128752
128636
  async transcribe(audio, opts = {}) {
128753
- const bytes = audio instanceof Uint8Array ? audio : new Uint8Array(audio);
128754
- const mimeType = opts.mimeType ?? "audio/ogg";
128755
- const filename = DEFAULT_FILENAMES[mimeType] ?? "audio.bin";
128756
- const file = new File([bytes], filename, { type: mimeType });
128637
+ const upload = normalizeWhisperUpload(audio, opts.mimeType ?? "audio/ogg");
128638
+ const file = new File([upload.bytes], upload.filename, { type: upload.mimeType });
128757
128639
  const language = opts.language ?? this.defaultLanguage;
128758
128640
  if (this.model === "whisper-1") {
128759
128641
  const response2 = await this.run(() => this.client.audio.transcriptions.create({
@@ -128817,71 +128699,6 @@ var WhisperTranscriber = class {
128817
128699
  }
128818
128700
  };
128819
128701
 
128820
- // ../plugin-stt-whisper/dist/audio.js
128821
- var MOXXY_PCM16_24KHZ_MIME = "audio/x-moxxy-pcm16-24khz";
128822
- var WHISPER_FILENAME_BY_MIME = {
128823
- "audio/ogg": "audio.ogg",
128824
- "audio/opus": "audio.opus",
128825
- "audio/mpeg": "audio.mp3",
128826
- "audio/mp3": "audio.mp3",
128827
- "audio/wav": "audio.wav",
128828
- "audio/x-wav": "audio.wav",
128829
- "audio/webm": "audio.webm",
128830
- "audio/m4a": "audio.m4a",
128831
- "audio/mp4": "audio.mp4",
128832
- "audio/flac": "audio.flac"
128833
- };
128834
- function normalizeWhisperUpload(audio, mimeType, filenamePrefix) {
128835
- const bytes = audio instanceof Uint8Array ? audio : new Uint8Array(audio);
128836
- const mt3 = mimeType || "audio/wav";
128837
- if (mt3 === MOXXY_PCM16_24KHZ_MIME) {
128838
- return {
128839
- bytes: pcm16MonoToWav(bytes, 24e3),
128840
- mimeType: "audio/wav",
128841
- filename: rename(filenamePrefix, "wav") ?? "audio.wav"
128842
- };
128843
- }
128844
- const defaultName = WHISPER_FILENAME_BY_MIME[mt3] ?? "audio.bin";
128845
- return {
128846
- bytes,
128847
- mimeType: mt3,
128848
- filename: rename(filenamePrefix, extOf(defaultName)) ?? defaultName
128849
- };
128850
- }
128851
- function rename(prefix, ext) {
128852
- return prefix ? `${prefix}.${ext}` : void 0;
128853
- }
128854
- function extOf(filename) {
128855
- const dot = filename.lastIndexOf(".");
128856
- return dot >= 0 ? filename.slice(dot + 1) : "bin";
128857
- }
128858
- function pcm16MonoToWav(pcm, sampleRate = 24e3) {
128859
- const data = pcm instanceof Uint8Array ? pcm : new Uint8Array(pcm);
128860
- const headerBytes = 44;
128861
- const wav = new Uint8Array(headerBytes + data.byteLength);
128862
- const view = new DataView(wav.buffer);
128863
- writeAscii(wav, 0, "RIFF");
128864
- view.setUint32(4, 36 + data.byteLength, true);
128865
- writeAscii(wav, 8, "WAVE");
128866
- writeAscii(wav, 12, "fmt ");
128867
- view.setUint32(16, 16, true);
128868
- view.setUint16(20, 1, true);
128869
- view.setUint16(22, 1, true);
128870
- view.setUint32(24, sampleRate, true);
128871
- view.setUint32(28, sampleRate * 2, true);
128872
- view.setUint16(32, 2, true);
128873
- view.setUint16(34, 16, true);
128874
- writeAscii(wav, 36, "data");
128875
- view.setUint32(40, data.byteLength, true);
128876
- wav.set(data, headerBytes);
128877
- return wav;
128878
- }
128879
- function writeAscii(target, offset, value) {
128880
- for (let i2 = 0; i2 < value.length; i2 += 1) {
128881
- target[offset + i2] = value.charCodeAt(i2);
128882
- }
128883
- }
128884
-
128885
128702
  // ../plugin-stt-whisper/dist/index.js
128886
128703
  function buildWhisperPlugin(opts = {}) {
128887
128704
  const model = opts.model ?? "whisper-1";
@@ -129856,11 +129673,31 @@ var builtinToolsPlugin = definePlugin({
129856
129673
  tools: [...builtinTools]
129857
129674
  });
129858
129675
  var DEFAULT_MODE_NAME = "default";
129676
+ var MAX_CONSECUTIVE_RETRIES = 6;
129677
+ function retryBackoffMs(attempt) {
129678
+ const base2 = 500;
129679
+ const cap = 3e4;
129680
+ return Math.min(cap, base2 * 2 ** Math.max(0, attempt - 1));
129681
+ }
129682
+ var sleepImpl2 = (ms, signal) => new Promise((resolve13) => {
129683
+ if (signal.aborted)
129684
+ return resolve13();
129685
+ const timer = setTimeout(() => {
129686
+ signal.removeEventListener("abort", onAbort);
129687
+ resolve13();
129688
+ }, ms);
129689
+ const onAbort = () => {
129690
+ clearTimeout(timer);
129691
+ resolve13();
129692
+ };
129693
+ signal.addEventListener("abort", onAbort, { once: true });
129694
+ });
129859
129695
  async function* runDefaultMode(ctx) {
129860
129696
  const maxIterations = ctx.maxIterations ?? 500;
129861
129697
  const detector = createStuckLoopDetector();
129862
129698
  const MAX_REACTIVE_COMPACTIONS = 2;
129863
129699
  let reactiveCompactions = 0;
129700
+ let consecutiveRetries = 0;
129864
129701
  for (let iteration = 1; iteration <= maxIterations; iteration++) {
129865
129702
  if (ctx.signal.aborted) {
129866
129703
  yield await ctx.emit({
@@ -129920,19 +129757,52 @@ async function* runDefaultMode(ctx) {
129920
129757
  continue;
129921
129758
  }
129922
129759
  }
129760
+ if (!error2.retryable) {
129761
+ yield await ctx.emit({
129762
+ type: "error",
129763
+ sessionId: ctx.sessionId,
129764
+ turnId: ctx.turnId,
129765
+ source: "system",
129766
+ kind: "fatal",
129767
+ message: error2.message
129768
+ });
129769
+ return;
129770
+ }
129771
+ consecutiveRetries += 1;
129923
129772
  yield await ctx.emit({
129924
129773
  type: "error",
129925
129774
  sessionId: ctx.sessionId,
129926
129775
  turnId: ctx.turnId,
129927
129776
  source: "system",
129928
- kind: error2.retryable ? "retryable" : "fatal",
129777
+ kind: "retryable",
129929
129778
  message: error2.message
129930
129779
  });
129931
- if (!error2.retryable)
129780
+ if (consecutiveRetries >= MAX_CONSECUTIVE_RETRIES) {
129781
+ yield await ctx.emit({
129782
+ type: "error",
129783
+ sessionId: ctx.sessionId,
129784
+ turnId: ctx.turnId,
129785
+ source: "system",
129786
+ kind: "fatal",
129787
+ message: `provider kept returning a retryable error ${consecutiveRetries} times in a row (last: ${error2.message}); giving up rather than hammering the provider.`
129788
+ });
129789
+ return;
129790
+ }
129791
+ await sleepImpl2(retryBackoffMs(consecutiveRetries), ctx.signal);
129792
+ if (ctx.signal.aborted) {
129793
+ yield await ctx.emit({
129794
+ type: "abort",
129795
+ sessionId: ctx.sessionId,
129796
+ turnId: ctx.turnId,
129797
+ source: "system",
129798
+ reason: "signal aborted during retry back-off"
129799
+ });
129932
129800
  return;
129801
+ }
129933
129802
  continue;
129934
129803
  }
129935
129804
  reactiveCompactions = 0;
129805
+ consecutiveRetries = 0;
129936
129806
  if (reasoning) {
129937
129807
  yield await ctx.emit({
129938
129808
  type: "reasoning_message",
@@ -131280,16 +131150,16 @@ var TelegramPermissionResolver = class {
131280
131150
  }
131281
131151
  /** Called by the bot when a permission callback button is clicked. */
131282
131152
  resolvePending(callId, decision) {
131283
- const pending = this.pending.get(callId);
131284
- if (!pending)
131153
+ const pending2 = this.pending.get(callId);
131154
+ if (!pending2)
131285
131155
  return false;
131286
131156
  this.pending.delete(callId);
131287
- pending.resolve(decision);
131157
+ pending2.resolve(decision);
131288
131158
  return true;
131289
131159
  }
131290
131160
  abortAll(reason = "channel closed") {
131291
- for (const pending of this.pending.values()) {
131292
- pending.resolve({ mode: "deny", reason });
131161
+ for (const pending2 of this.pending.values()) {
131162
+ pending2.resolve({ mode: "deny", reason });
131293
131163
  }
131294
131164
  this.pending.clear();
131295
131165
  }
@@ -131328,26 +131198,26 @@ var TelegramApprovalResolver = class {
131328
131198
  }
131329
131199
  /** Resolve directly with an option id (no text). */
131330
131200
  resolvePending(id, optionId) {
131331
- const pending = this.pending.get(id);
131332
- if (!pending)
131201
+ const pending2 = this.pending.get(id);
131202
+ if (!pending2)
131333
131203
  return false;
131334
131204
  this.pending.delete(id);
131335
- pending.resolve({ optionId });
131205
+ pending2.resolve({ optionId });
131336
131206
  return true;
131337
131207
  }
131338
131208
  /** Resolve with an option id AND a free-text follow-up. */
131339
131209
  resolvePendingWithText(id, optionId, text) {
131340
- const pending = this.pending.get(id);
131341
- if (!pending)
131210
+ const pending2 = this.pending.get(id);
131211
+ if (!pending2)
131342
131212
  return false;
131343
131213
  this.pending.delete(id);
131344
- pending.resolve({ optionId, text });
131214
+ pending2.resolve({ optionId, text });
131345
131215
  return true;
131346
131216
  }
131347
131217
  abortAll(reason = "channel closed") {
131348
- for (const pending of this.pending.values()) {
131349
- pending.resolve({
131350
- optionId: pending.request.defaultOptionId ?? pending.request.options[0]?.id ?? "cancel",
131218
+ for (const pending2 of this.pending.values()) {
131219
+ pending2.resolve({
131220
+ optionId: pending2.request.defaultOptionId ?? pending2.request.options[0]?.id ?? "cancel",
131351
131221
  text: reason
131352
131222
  });
131353
131223
  }
@@ -131555,17 +131425,100 @@ function previewArgs(input) {
131555
131425
  return truncJson(input);
131556
131426
  }
131557
131427
  }
131428
+ function tagStackAt(html, idx, seed = []) {
131429
+ const stack = seed.slice();
131430
+ let i2 = 0;
131431
+ let insideTag = false;
131432
+ let insideEntity = false;
131433
+ while (i2 < idx) {
131434
+ const ch = html[i2];
131435
+ if (ch === "<") {
131436
+ const end = html.indexOf(">", i2);
131437
+ if (end === -1) {
131438
+ insideTag = true;
131439
+ break;
131440
+ }
131441
+ if (end >= idx) {
131442
+ insideTag = true;
131443
+ break;
131444
+ }
131445
+ const raw = html.slice(i2, end + 1);
131446
+ const m3 = /^<\s*(\/?)\s*([a-zA-Z][a-zA-Z0-9]*)/.exec(raw);
131447
+ if (m3) {
131448
+ const closing = m3[1] === "/";
131449
+ const name = m3[2].toLowerCase();
131450
+ if (closing) {
131451
+ for (let s2 = stack.length - 1; s2 >= 0; s2--) {
131452
+ if (stack[s2].name === name) {
131453
+ stack.splice(s2, 1);
131454
+ break;
131455
+ }
131456
+ }
131457
+ } else if (!raw.endsWith("/>")) {
131458
+ stack.push({ name, open: raw });
131459
+ }
131460
+ }
131461
+ i2 = end + 1;
131462
+ continue;
131463
+ }
131464
+ if (ch === "&") {
131465
+ const semi = html.indexOf(";", i2);
131466
+ if (semi !== -1 && semi - i2 <= 12 && /^&[a-zA-Z0-9#]+;$/.test(html.slice(i2, semi + 1))) {
131467
+ if (semi >= idx) {
131468
+ insideEntity = true;
131469
+ break;
131470
+ }
131471
+ i2 = semi + 1;
131472
+ continue;
131473
+ }
131474
+ }
131475
+ i2 += 1;
131476
+ }
131477
+ return { stack, insideTag, insideEntity };
131478
+ }
131558
131479
  function splitForTelegram(text, limit2 = TELEGRAM_MESSAGE_LIMIT) {
131480
+ if (text.length <= limit2)
131481
+ return text ? [text] : [];
131559
131482
  const out = [];
131483
+ let carry = [];
131560
131484
  let remaining = text;
131561
131485
  while (remaining.length > limit2) {
131562
- const cut = remaining.lastIndexOf("\n", limit2);
131563
- const idx = cut > 0 ? cut : limit2;
131564
- out.push(remaining.slice(0, idx));
131486
+ const carryLen = carry.reduce((n2, t2) => n2 + t2.open.length, 0);
131487
+ const budget = limit2 - carryLen;
131488
+ let idx = Math.min(budget, remaining.length);
131489
+ const nl = remaining.lastIndexOf("\n", idx);
131490
+ if (nl > 0)
131491
+ idx = nl;
131492
+ let info = tagStackAt(remaining, idx, carry);
131493
+ while ((info.insideTag || info.insideEntity) && idx > 1) {
131494
+ idx -= 1;
131495
+ info = tagStackAt(remaining, idx, carry);
131496
+ }
131497
+ if (info.insideTag || info.insideEntity) {
131498
+ idx = Math.min(budget, remaining.length);
131499
+ while (idx < remaining.length) {
131500
+ const probe = tagStackAt(remaining, idx, carry);
131501
+ if (!probe.insideTag && !probe.insideEntity) {
131502
+ info = probe;
131503
+ break;
131504
+ }
131505
+ idx += 1;
131506
+ }
131507
+ if (idx >= remaining.length)
131508
+ info = tagStackAt(remaining, remaining.length, carry);
131509
+ }
131510
+ if (idx <= 0) {
131511
+ idx = remaining.length;
131512
+ info = tagStackAt(remaining, idx, carry);
131513
+ }
131514
+ const closeTags = info.stack.slice().reverse().map((t2) => `</${t2.name}>`).join("");
131515
+ const head = carry.map((t2) => t2.open).join("") + remaining.slice(0, idx) + closeTags;
131516
+ out.push(head);
131517
+ carry = info.stack;
131565
131518
  remaining = remaining.slice(idx);
131566
131519
  }
131567
131520
  if (remaining)
131568
- out.push(remaining);
131521
+ out.push(carry.map((t2) => t2.open).join("") + remaining);
131569
131522
  return out;
131570
131523
  }
131571
131524
 
@@ -132287,12 +132240,12 @@ async function handleAppr(ctx, data, state, cb) {
132287
132240
  return;
132288
132241
  const approvalId = data.slice(5, idx);
132289
132242
  const optionId = data.slice(idx + 1);
132290
- const pending = state.approvalResolver.getPending(approvalId);
132291
- if (!pending) {
132243
+ const pending2 = state.approvalResolver.getPending(approvalId);
132244
+ if (!pending2) {
132292
132245
  await ctx.answerCallbackQuery({ text: "no pending approval" });
132293
132246
  return;
132294
132247
  }
132295
- const option = pending.request.options.find((o2) => o2.id === optionId);
132248
+ const option = pending2.request.options.find((o2) => o2.id === optionId);
132296
132249
  if (!option) {
132297
132250
  await ctx.answerCallbackQuery({ text: "unknown option" });
132298
132251
  return;
@@ -132349,7 +132302,7 @@ Run \`${cmd}\` then restart moxxy.`, { parse_mode: "Markdown" });
132349
132302
  session.providers.setActive(providerId, cfg);
132350
132303
  }
132351
132304
  cb.setActiveModelOverride(modelId);
132352
- void savePreferences({ providerName: providerId, model: modelId });
132305
+ await savePreferences({ providerName: providerId, model: modelId });
132353
132306
  await ctx.answerCallbackQuery({ text: `\u2192 ${providerId}:${modelId}` });
132354
132307
  if (ctx.callbackQuery?.message) {
132355
132308
  try {
@@ -132371,7 +132324,7 @@ async function handleMode(ctx, data, session) {
132371
132324
  }
132372
132325
  try {
132373
132326
  session.modes.setActive(modeName);
132374
- void savePreferences({ mode: modeName });
132327
+ await savePreferences({ mode: modeName });
132375
132328
  await ctx.answerCallbackQuery({ text: `mode \u2192 ${modeName}` });
132376
132329
  if (ctx.callbackQuery?.message) {
132377
132330
  try {
@@ -132701,7 +132654,6 @@ var TelegramChannel = class {
132701
132654
  yolo: this.yolo,
132702
132655
  busy: this.busy,
132703
132656
  turnController: this.turnController,
132704
- awaitingApprovalText: this.awaitingApprovalText,
132705
132657
  handle: this.handle
132706
132658
  }, {
132707
132659
  pairing: this.pairing,
@@ -134170,17 +134122,23 @@ async function handleTurn(req, res, ctx) {
134170
134122
  reply(res, 400, { error: "bad_request", message: err instanceof Error ? err.message : String(err) });
134171
134123
  return;
134172
134124
  }
134125
+ const controller = new AbortController();
134126
+ const onClose = () => controller.abort();
134127
+ res.on("close", onClose);
134173
134128
  const events = [];
134174
134129
  try {
134175
134130
  for await (const event of ctx.session.runTurn(body.prompt, {
134176
134131
  ...body.model ? { model: body.model } : {},
134177
- ...body.systemPrompt ? { systemPrompt: body.systemPrompt } : {}
134132
+ ...body.systemPrompt ? { systemPrompt: body.systemPrompt } : {},
134133
+ signal: controller.signal
134178
134134
  })) {
134179
134135
  events.push(event);
134180
134136
  }
134181
134137
  } catch (err) {
134182
134138
  reply(res, 500, { error: "turn_failed", message: err instanceof Error ? err.message : String(err) });
134183
134139
  return;
134140
+ } finally {
134141
+ res.off("close", onClose);
134184
134142
  }
134185
134143
  const finalAssistant = events.findLast?.((e3) => e3.type === "assistant_message");
134186
134144
  const assistant = finalAssistant && finalAssistant.type === "assistant_message" ? finalAssistant.content : "";
@@ -134240,17 +134198,23 @@ async function handleTurnAudio(req, res, ctx) {
134240
134198
  reply(res, 422, { error: "empty_transcript", message: "transcriber returned empty text" });
134241
134199
  return;
134242
134200
  }
134201
+ const controller = new AbortController();
134202
+ const onClose = () => controller.abort();
134203
+ res.on("close", onClose);
134243
134204
  const events = [];
134244
134205
  try {
134245
134206
  for await (const event of ctx.session.runTurn(transcript, {
134246
134207
  ...model ? { model } : {},
134247
- ...systemPrompt ? { systemPrompt } : {}
134208
+ ...systemPrompt ? { systemPrompt } : {},
134209
+ signal: controller.signal
134248
134210
  })) {
134249
134211
  events.push(event);
134250
134212
  }
134251
134213
  } catch (err) {
134252
134214
  reply(res, 500, { error: "turn_failed", message: err instanceof Error ? err.message : String(err) });
134253
134215
  return;
134216
+ } finally {
134217
+ res.off("close", onClose);
134254
134218
  }
134255
134219
  const finalAssistant = events.findLast?.((e3) => e3.type === "assistant_message");
134256
134220
  const assistant = finalAssistant && finalAssistant.type === "assistant_message" ? finalAssistant.content : "";
@@ -134354,9 +134318,21 @@ var HttpChannel = class {
134354
134318
  }
134355
134319
  });
134356
134320
  this.server = server;
134321
+ let rejectRunning;
134322
+ let resolveRunning;
134323
+ const running = new Promise((resolve13, reject) => {
134324
+ resolveRunning = resolve13;
134325
+ rejectRunning = reject;
134326
+ });
134357
134327
  const listening = new Promise((resolve13, reject) => {
134358
- server.once("error", reject);
134328
+ const onListenError = (err) => reject(err);
134329
+ server.once("error", onListenError);
134359
134330
  server.listen(this.port, this.host, () => {
134331
+ server.off("error", onListenError);
134332
+ server.on("error", (err) => {
134333
+ this.logger?.warn?.("http server error", { err: String(err) });
134334
+ rejectRunning(err);
134335
+ });
134360
134336
  const addr = server.address();
134361
134337
  this.boundPortValue = typeof addr === "object" && addr ? addr.port : this.port;
134362
134338
  this.logger?.info?.("http channel listening", {
@@ -134368,9 +134344,7 @@ var HttpChannel = class {
134368
134344
  });
134369
134345
  });
134370
134346
  await listening;
134371
- const running = new Promise((resolve13) => {
134372
- server.once("close", () => resolve13());
134373
- });
134347
+ server.once("close", () => resolveRunning());
134374
134348
  return {
134375
134349
  running,
134376
134350
  stop: async () => {
@@ -134448,8 +134422,8 @@ var EventProjector = class {
134448
134422
  if (event.ok && isFileDiffDisplay(display)) {
134449
134423
  return [{ kind: "file-diff", turnId: String(event.turnId), display }];
134450
134424
  }
134451
- const pending = this.presentCalls.get(String(event.callId));
134452
- if (!pending)
134425
+ const pending2 = this.presentCalls.get(String(event.callId));
134426
+ if (!pending2)
134453
134427
  return [];
134454
134428
  this.presentCalls.delete(String(event.callId));
134455
134429
  if (!event.ok) {
@@ -134470,7 +134444,7 @@ var EventProjector = class {
134470
134444
  replaces,
134471
134445
  ...name ? { name } : {},
134472
134446
  doc,
134473
- ...pending.fallbackText ? { fallbackText: pending.fallbackText } : {}
134447
+ ...pending2.fallbackText ? { fallbackText: pending2.fallbackText } : {}
134474
134448
  }
134475
134449
  ];
134476
134450
  }
@@ -135431,15 +135405,33 @@ async function createUnixSocketServer(socketPath, logger = stderrLogger) {
135431
135405
  }
135432
135406
  };
135433
135407
  }
135434
- function connectUnixSocket(socketPath) {
135408
+ var DEFAULT_CONNECT_TIMEOUT_MS = 1e4;
135409
+ function connectUnixSocket(socketPath, opts = {}) {
135410
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
135435
135411
  return new Promise((resolve13, reject) => {
135436
135412
  const socket = net.connect(socketPath);
135413
+ let settled = false;
135414
+ const timer = setTimeout(() => {
135415
+ if (settled)
135416
+ return;
135417
+ settled = true;
135418
+ socket.destroy(new Error(`connect timeout after ${timeoutMs}ms: ${socketPath}`));
135419
+ reject(new Error(`connect timeout after ${timeoutMs}ms: ${socketPath}`));
135420
+ }, timeoutMs);
135437
135421
  const onError2 = (err) => {
135422
+ if (settled)
135423
+ return;
135424
+ settled = true;
135425
+ clearTimeout(timer);
135438
135426
  socket.destroy();
135439
135427
  reject(err);
135440
135428
  };
135441
135429
  socket.once("error", onError2);
135442
135430
  socket.once("connect", () => {
135431
+ if (settled)
135432
+ return;
135433
+ settled = true;
135434
+ clearTimeout(timer);
135443
135435
  socket.removeListener("error", onError2);
135444
135436
  resolve13(new NdjsonTransport(socket));
135445
135437
  });
@@ -137757,43 +137749,55 @@ var MobileChannel = class {
137757
137749
  this.host = host;
137758
137750
  host.register();
137759
137751
  host.wire();
137760
- const localOrigins = advertisedOrigins(this.bindHost, this.port);
137761
- const server = await startWsBridge(bus, {
137762
- port: this.port,
137763
- host: this.bindHost,
137764
- authToken: this.token,
137765
- allowedOrigins: localOrigins,
137766
- // Back-compat ONLY: the QR this channel prints embeds the token as `?t=`
137767
- // (pairing payload); current apps strip it and authenticate via the
137768
- // Sec-WebSocket-Protocol bearer entry, but older installed builds still
137769
- // connect with the token in the WS URL.
137770
- allowQueryToken: true
137771
- });
137772
- this.server = server;
137773
- this.logger?.info?.("mobile channel listening", { address: server.address });
137774
- let tunnelUrl = null;
137775
- const provider = tunnelProviderFor(this.tunnelChoice);
137776
- if (provider) {
137777
- try {
137778
- this.tunnel = await provider.open({ port: this.port, host: this.bindHost });
137779
- tunnelUrl = this.tunnel.url;
137780
- server.setAllowedOrigins([...localOrigins, connectUrlOrigin(tunnelUrl)]);
137781
- this.logger?.info?.("mobile tunnel open", { provider: provider.name, url: tunnelUrl });
137782
- } catch (err) {
137783
- this.logger?.warn?.("mobile tunnel failed; using the local URL", {
137784
- provider: provider.name,
137785
- err: String(err)
137786
- });
137752
+ try {
137753
+ const localOrigins = advertisedOrigins(this.bindHost, this.port);
137754
+ const server = await startWsBridge(bus, {
137755
+ port: this.port,
137756
+ host: this.bindHost,
137757
+ authToken: this.token,
137758
+ allowedOrigins: localOrigins,
137759
+ // Back-compat ONLY: the QR this channel prints embeds the token as `?t=`
137760
+ // (pairing payload); current apps strip it and authenticate via the
137761
+ // Sec-WebSocket-Protocol bearer entry, but older installed builds still
137762
+ // connect with the token in the WS URL.
137763
+ allowQueryToken: true
137764
+ });
137765
+ this.server = server;
137766
+ this.logger?.info?.("mobile channel listening", { address: server.address });
137767
+ let tunnelUrl = null;
137768
+ const provider = tunnelProviderFor(this.tunnelChoice);
137769
+ if (provider) {
137770
+ try {
137771
+ this.tunnel = await provider.open({ port: this.port, host: this.bindHost });
137772
+ tunnelUrl = this.tunnel.url;
137773
+ server.setAllowedOrigins([...localOrigins, connectUrlOrigin(tunnelUrl)]);
137774
+ this.logger?.info?.("mobile tunnel open", { provider: provider.name, url: tunnelUrl });
137775
+ } catch (err) {
137776
+ this.logger?.warn?.("mobile tunnel failed; using the local URL", {
137777
+ provider: provider.name,
137778
+ err: String(err)
137779
+ });
137780
+ }
137787
137781
  }
137782
+ const connectUrl = buildConnectUrl({
137783
+ tunnelUrl,
137784
+ localHost: advertisedHost(this.bindHost),
137785
+ port: this.port,
137786
+ token: this.token
137787
+ });
137788
+ const loopbackOnly = !tunnelUrl && isLoopbackHost(this.bindHost);
137789
+ await printConnectInfo(connectUrl, this.token, loopbackOnly ? "Bound to loopback \u2014 this QR only works on THIS machine (e.g. an iOS/Android\n simulator). For a real phone: opt in to a LAN bind with MOXXY_MOBILE_HOST=0.0.0.0\n (or channels.mobile.bindHost in moxxy.config.ts), or use a tunnel\n (channels.mobile.tunnel: 'cloudflared' | 'ngrok', or MOXXY_MOBILE_TUNNEL)." : void 0);
137790
+ } catch (err) {
137791
+ host.dispose();
137792
+ if (this.tunnel) {
137793
+ await this.tunnel.close().catch(() => void 0);
137794
+ this.tunnel = null;
137795
+ }
137796
+ await this.server?.close().catch(() => void 0);
137797
+ this.server = null;
137798
+ this.host = null;
137799
+ throw err;
137788
137800
  }
137789
- const connectUrl = buildConnectUrl({
137790
- tunnelUrl,
137791
- localHost: advertisedHost(this.bindHost),
137792
- port: this.port,
137793
- token: this.token
137794
- });
137795
- const loopbackOnly = !tunnelUrl && isLoopbackHost(this.bindHost);
137796
- await printConnectInfo(connectUrl, this.token, loopbackOnly ? "Bound to loopback \u2014 this QR only works on THIS machine (e.g. an iOS/Android\n simulator). For a real phone: opt in to a LAN bind with MOXXY_MOBILE_HOST=0.0.0.0\n (or channels.mobile.bindHost in moxxy.config.ts), or use a tunnel\n (channels.mobile.tunnel: 'cloudflared' | 'ngrok', or MOXXY_MOBILE_TUNNEL)." : void 0);
137797
137801
  let resolveRunning;
137798
137802
  const running = new Promise((resolve13) => {
137799
137803
  resolveRunning = resolve13;
@@ -138700,17 +138704,27 @@ async function createTerminalProcess(cwd2) {
138700
138704
 
138701
138705
  // ../plugin-terminal/dist/terminal.js
138702
138706
  var shared = /* @__PURE__ */ new Map();
138703
- async function getSharedTerminal(cwd2) {
138707
+ var pending = /* @__PURE__ */ new Map();
138708
+ async function getSharedTerminal(cwd2, create2 = createTerminalProcess) {
138704
138709
  const existing = shared.get(cwd2);
138705
138710
  if (existing && existing.alive)
138706
138711
  return existing;
138707
- const proc = await createTerminalProcess(cwd2);
138708
- shared.set(cwd2, proc);
138709
- proc.onExit(() => {
138710
- if (shared.get(cwd2) === proc)
138711
- shared.delete(cwd2);
138712
+ const inFlight = pending.get(cwd2);
138713
+ if (inFlight)
138714
+ return inFlight;
138715
+ const promise = (async () => {
138716
+ const proc = await create2(cwd2);
138717
+ shared.set(cwd2, proc);
138718
+ proc.onExit(() => {
138719
+ if (shared.get(cwd2) === proc)
138720
+ shared.delete(cwd2);
138721
+ });
138722
+ return proc;
138723
+ })().finally(() => {
138724
+ pending.delete(cwd2);
138712
138725
  });
138713
- return proc;
138726
+ pending.set(cwd2, promise);
138727
+ return promise;
138714
138728
  }
138715
138729
  function closeAllTerminals() {
138716
138730
  for (const proc of shared.values())
@@ -139502,7 +139516,8 @@ function buildProviderAdminPlugin(opts) {
139502
139516
  });
139503
139517
  }
139504
139518
  const def = buildProviderDef(entry);
139505
- const wasRegistered = providerRegistry.list().some((p3) => p3.name === entry.name);
139519
+ const prevDef = providerRegistry.list().find((p3) => p3.name === entry.name);
139520
+ const wasRegistered = prevDef !== void 0;
139506
139521
  if (wasRegistered)
139507
139522
  providerRegistry.replace(def);
139508
139523
  else
@@ -139510,7 +139525,10 @@ function buildProviderAdminPlugin(opts) {
139510
139525
  try {
139511
139526
  await upsertStoredProvider(entry, configPath);
139512
139527
  } catch (err) {
139513
- providerRegistry.unregister(entry.name);
139528
+ if (wasRegistered && prevDef)
139529
+ providerRegistry.replace(prevDef);
139530
+ else
139531
+ providerRegistry.unregister(entry.name);
139514
139532
  throw err;
139515
139533
  }
139516
139534
  const vaultKeyName2 = providerApiKeyName(entry);
@@ -139738,6 +139756,8 @@ async function compactSession(session) {
139738
139756
  return { kind: "text", text: "nothing to compact: event log is empty" };
139739
139757
  }
139740
139758
  const providerCtxWindow = resolveActiveContextWindow(s2);
139759
+ const provider = safe(() => s2.providers?.getActive()) ?? void 0;
139760
+ const model = provider?.models[0]?.id;
139741
139761
  try {
139742
139762
  const result = await compactor.compact(events, {
139743
139763
  log: s2.log.asReader ? s2.log.asReader() : s2.log,
@@ -139746,12 +139766,21 @@ async function compactSession(session) {
139746
139766
  estimatedTokens: estimateContextTokens$1(s2.log.asReader ? s2.log.asReader() : s2.log),
139747
139767
  reserveForOutput: 0
139748
139768
  },
139749
- signal: s2.signal ?? new AbortController().signal
139769
+ signal: s2.signal ?? new AbortController().signal,
139770
+ ...provider ? { provider } : {},
139771
+ ...model ? { model } : {}
139750
139772
  });
139751
139773
  if (result.tokensSaved <= 0 || result.summary.trim().length === 0) {
139752
139774
  return { kind: "text", text: "nothing to compact yet" };
139753
139775
  }
139754
- await s2.log.append(result);
139776
+ const lastEvent = events[events.length - 1];
139777
+ const emittable = {
139778
+ sessionId: s2.id ?? lastEvent?.sessionId,
139779
+ turnId: lastEvent?.turnId,
139780
+ source: "compactor",
139781
+ ...result
139782
+ };
139783
+ await s2.log.append(emittable);
139755
139784
  const compactedEvents = result.replacedRange[1] - result.replacedRange[0] + 1;
139756
139785
  return {
139757
139786
  kind: "text",
@@ -140328,26 +140357,40 @@ function nextFireTime(expr, after, timeZone) {
140328
140357
  const start = new Date(after.getTime() + 6e4);
140329
140358
  start.setSeconds(0, 0);
140330
140359
  const limit2 = new Date(start.getTime() + 366 * 24 * 60 * 6e4);
140360
+ const explicitZone = !!timeZone && timeZone !== "local";
140331
140361
  const cursor = new Date(start);
140332
140362
  while (cursor <= limit2) {
140333
140363
  const parts = decomposeInZone(cursor, timeZone);
140334
140364
  if (!cron.month.values.has(parts.month)) {
140335
- jumpToNextMonth(cursor, parts, cron.month.values);
140365
+ if (explicitZone) {
140366
+ cursor.setTime(cursor.getTime() + 6e4);
140367
+ } else {
140368
+ jumpToNextMonth(cursor, parts, cron.month.values);
140369
+ }
140336
140370
  continue;
140337
140371
  }
140338
140372
  const domOk = cron.dom.values.has(parts.dom);
140339
140373
  const dowOk = cron.dow.values.has(parts.dow);
140340
140374
  const dayMatches = cron.dom.restricted && cron.dow.restricted ? domOk || dowOk : domOk && dowOk;
140341
140375
  if (!dayMatches) {
140342
- jumpToNextDay(cursor);
140376
+ if (explicitZone)
140377
+ cursor.setTime(cursor.getTime() + 6e4);
140378
+ else
140379
+ jumpToNextDay(cursor);
140343
140380
  continue;
140344
140381
  }
140345
140382
  if (!cron.hour.values.has(parts.hour)) {
140346
- jumpToNextHour(cursor);
140383
+ if (explicitZone)
140384
+ cursor.setTime(cursor.getTime() + 6e4);
140385
+ else
140386
+ jumpToNextHour(cursor);
140347
140387
  continue;
140348
140388
  }
140349
140389
  if (!cron.minute.values.has(parts.minute)) {
140350
- cursor.setMinutes(cursor.getMinutes() + 1, 0, 0);
140390
+ if (explicitZone)
140391
+ cursor.setTime(cursor.getTime() + 6e4);
140392
+ else
140393
+ cursor.setMinutes(cursor.getMinutes() + 1, 0, 0);
140351
140394
  continue;
140352
140395
  }
140353
140396
  return new Date(cursor.getTime());
@@ -140478,6 +140521,76 @@ async function runSchedule(entry, runner, store, inboxOpts = {}) {
140478
140521
  };
140479
140522
  }
140480
140523
 
140524
+ // ../plugin-scheduler/dist/skill-sync.js
140525
+ function toEntryDraft(skill) {
140526
+ const s2 = skill.frontmatter.schedule;
140527
+ if (!s2)
140528
+ return null;
140529
+ if (!s2.cron && s2.runAt === void 0)
140530
+ return null;
140531
+ if (s2.cron && !isValidCron(s2.cron))
140532
+ return null;
140533
+ const runAt = s2.runAt === void 0 ? void 0 : typeof s2.runAt === "string" ? Date.parse(s2.runAt) : s2.runAt;
140534
+ return {
140535
+ name: skill.frontmatter.name,
140536
+ // The body of the skill IS the prompt — the model that runs at
140537
+ // fire time will receive these instructions verbatim.
140538
+ prompt: skill.body.trim() || skill.frontmatter.description,
140539
+ ...s2.cron ? { cron: s2.cron } : {},
140540
+ ...runAt !== void 0 ? { runAt } : {},
140541
+ ...s2.timeZone ? { timeZone: s2.timeZone } : {},
140542
+ ...s2.channel ? { channel: s2.channel } : {},
140543
+ enabled: s2.enabled ?? true,
140544
+ source: "skill",
140545
+ skillName: skill.frontmatter.name
140546
+ };
140547
+ }
140548
+ async function syncSkillSchedules(registry, store) {
140549
+ const wanted = /* @__PURE__ */ new Map();
140550
+ for (const skill of registry.list()) {
140551
+ const draft = toEntryDraft(skill);
140552
+ if (draft)
140553
+ wanted.set(skill.frontmatter.name, draft);
140554
+ }
140555
+ const existing = await store.list();
140556
+ const existingSkill = /* @__PURE__ */ new Map();
140557
+ for (const e3 of existing) {
140558
+ if (e3.source === "skill" && e3.skillName)
140559
+ existingSkill.set(e3.skillName, e3);
140560
+ }
140561
+ let added = 0;
140562
+ let removed = 0;
140563
+ let updated = 0;
140564
+ for (const [skillName2, entry] of existingSkill) {
140565
+ if (!wanted.has(skillName2)) {
140566
+ const ok = await store.delete(entry.id);
140567
+ if (ok)
140568
+ removed += 1;
140569
+ }
140570
+ }
140571
+ for (const [skillName2, draft] of wanted) {
140572
+ const current = existingSkill.get(skillName2);
140573
+ if (!current) {
140574
+ await store.create(draft);
140575
+ added += 1;
140576
+ continue;
140577
+ }
140578
+ const changed = current.prompt !== draft.prompt || current.cron !== draft.cron || current.runAt !== draft.runAt || current.timeZone !== draft.timeZone || current.channel !== draft.channel || current.enabled !== draft.enabled;
140579
+ if (changed) {
140580
+ await store.update(current.id, {
140581
+ prompt: draft.prompt,
140582
+ ...draft.cron ? { cron: draft.cron } : { cron: void 0 },
140583
+ ...draft.runAt !== void 0 ? { runAt: draft.runAt } : { runAt: void 0 },
140584
+ ...draft.timeZone ? { timeZone: draft.timeZone } : { timeZone: void 0 },
140585
+ ...draft.channel ? { channel: draft.channel } : { channel: void 0 },
140586
+ enabled: draft.enabled
140587
+ });
140588
+ updated += 1;
140589
+ }
140590
+ }
140591
+ return { added, removed, updated };
140592
+ }
140593
+
140481
140594
  // ../plugin-scheduler/dist/poller.js
140482
140595
  function isDue(entry, now) {
140483
140596
  if (!entry.enabled)
@@ -140547,6 +140660,15 @@ var SchedulerPoller = class {
140547
140660
  }
140548
140661
  async tickWith(onFired) {
140549
140662
  const now = Date.now();
140663
+ if (this.opts.skills) {
140664
+ try {
140665
+ await syncSkillSchedules(this.opts.skills, this.opts.store);
140666
+ } catch (err) {
140667
+ this.opts.logger?.warn?.("scheduler: skill sync during tick failed", {
140668
+ err: err instanceof Error ? err.message : String(err)
140669
+ });
140670
+ }
140671
+ }
140550
140672
  let schedules;
140551
140673
  try {
140552
140674
  schedules = await this.opts.store.list();
@@ -140577,76 +140699,6 @@ var SchedulerPoller = class {
140577
140699
  }
140578
140700
  };
140579
140701
 
140580
- // ../plugin-scheduler/dist/skill-sync.js
140581
- function toEntryDraft(skill) {
140582
- const s2 = skill.frontmatter.schedule;
140583
- if (!s2)
140584
- return null;
140585
- if (!s2.cron && s2.runAt === void 0)
140586
- return null;
140587
- if (s2.cron && !isValidCron(s2.cron))
140588
- return null;
140589
- const runAt = s2.runAt === void 0 ? void 0 : typeof s2.runAt === "string" ? Date.parse(s2.runAt) : s2.runAt;
140590
- return {
140591
- name: skill.frontmatter.name,
140592
- // The body of the skill IS the prompt — the model that runs at
140593
- // fire time will receive these instructions verbatim.
140594
- prompt: skill.body.trim() || skill.frontmatter.description,
140595
- ...s2.cron ? { cron: s2.cron } : {},
140596
- ...runAt !== void 0 ? { runAt } : {},
140597
- ...s2.timeZone ? { timeZone: s2.timeZone } : {},
140598
- ...s2.channel ? { channel: s2.channel } : {},
140599
- enabled: s2.enabled ?? true,
140600
- source: "skill",
140601
- skillName: skill.frontmatter.name
140602
- };
140603
- }
140604
- async function syncSkillSchedules(registry, store) {
140605
- const wanted = /* @__PURE__ */ new Map();
140606
- for (const skill of registry.list()) {
140607
- const draft = toEntryDraft(skill);
140608
- if (draft)
140609
- wanted.set(skill.frontmatter.name, draft);
140610
- }
140611
- const existing = await store.list();
140612
- const existingSkill = /* @__PURE__ */ new Map();
140613
- for (const e3 of existing) {
140614
- if (e3.source === "skill" && e3.skillName)
140615
- existingSkill.set(e3.skillName, e3);
140616
- }
140617
- let added = 0;
140618
- let removed = 0;
140619
- let updated = 0;
140620
- for (const [skillName2, entry] of existingSkill) {
140621
- if (!wanted.has(skillName2)) {
140622
- const ok = await store.delete(entry.id);
140623
- if (ok)
140624
- removed += 1;
140625
- }
140626
- }
140627
- for (const [skillName2, draft] of wanted) {
140628
- const current = existingSkill.get(skillName2);
140629
- if (!current) {
140630
- await store.create(draft);
140631
- added += 1;
140632
- continue;
140633
- }
140634
- const changed = current.prompt !== draft.prompt || current.cron !== draft.cron || current.runAt !== draft.runAt || current.timeZone !== draft.timeZone || current.channel !== draft.channel || current.enabled !== draft.enabled;
140635
- if (changed) {
140636
- await store.update(current.id, {
140637
- prompt: draft.prompt,
140638
- ...draft.cron ? { cron: draft.cron } : { cron: void 0 },
140639
- ...draft.runAt !== void 0 ? { runAt: draft.runAt } : { runAt: void 0 },
140640
- ...draft.timeZone ? { timeZone: draft.timeZone } : { timeZone: void 0 },
140641
- ...draft.channel ? { channel: draft.channel } : { channel: void 0 },
140642
- enabled: draft.enabled
140643
- });
140644
- updated += 1;
140645
- }
140646
- }
140647
- return { added, removed, updated };
140648
- }
140649
-
140650
140702
  // ../plugin-scheduler/dist/store.js
140651
140703
  init_index_esm();
140652
140704
  var scheduleSourceSchema = z.enum(["manual", "skill", "workflow"]);
@@ -140698,23 +140750,38 @@ function defaultSchedulesFile() {
140698
140750
  return moxxyPath("schedules.json");
140699
140751
  }
140700
140752
  var ScheduleStore = class {
140701
- file;
140702
- cache = null;
140703
- mutex = createMutex();
140753
+ // Generic id-collection store owns the cache, write mutex, RMW `.slice()`
140754
+ // copy, and crash-atomic `{ version: 1, schedules: [...] }` write. A corrupt
140755
+ // or unreadable file resets to empty and is left in place for inspection —
140756
+ // same behavior as before, now via the shared `load` hook.
140757
+ store;
140704
140758
  constructor(opts = {}) {
140705
- this.file = opts.file ?? defaultSchedulesFile();
140759
+ this.store = createJsonFileStore({
140760
+ file: opts.file ?? defaultSchedulesFile(),
140761
+ itemsKey: "schedules",
140762
+ load: (raw) => {
140763
+ if (raw === null)
140764
+ return [];
140765
+ try {
140766
+ const parsed = fileSchema.safeParse(JSON.parse(raw));
140767
+ return parsed.success ? [...parsed.data.schedules] : [];
140768
+ } catch {
140769
+ return [];
140770
+ }
140771
+ },
140772
+ // Non-ENOENT read errors were previously swallowed to an empty store too.
140773
+ onReadError: () => []
140774
+ });
140706
140775
  }
140707
140776
  /** Force a re-read on the next access. Tests use this. */
140708
140777
  invalidate() {
140709
- this.cache = null;
140778
+ this.store.invalidate();
140710
140779
  }
140711
140780
  async list() {
140712
- await this.ensureLoaded();
140713
- return this.cache.slice();
140781
+ return this.store.read();
140714
140782
  }
140715
140783
  async get(id) {
140716
- await this.ensureLoaded();
140717
- return this.cache.find((s2) => s2.id === id) ?? null;
140784
+ return this.store.get(id);
140718
140785
  }
140719
140786
  async create(input) {
140720
140787
  const entry = scheduleEntrySchema.parse({
@@ -140724,7 +140791,7 @@ var ScheduleStore = class {
140724
140791
  enabled: input.enabled ?? true,
140725
140792
  source: input.source ?? "manual"
140726
140793
  });
140727
- await this.mutate((schedules) => {
140794
+ await this.store.mutate((schedules) => {
140728
140795
  schedules.push(entry);
140729
140796
  return schedules;
140730
140797
  });
@@ -140732,7 +140799,7 @@ var ScheduleStore = class {
140732
140799
  }
140733
140800
  async update(id, patch) {
140734
140801
  let updated = null;
140735
- await this.mutate((schedules) => {
140802
+ await this.store.mutate((schedules) => {
140736
140803
  const idx = schedules.findIndex((s2) => s2.id === id);
140737
140804
  if (idx < 0)
140738
140805
  return schedules;
@@ -140745,7 +140812,7 @@ var ScheduleStore = class {
140745
140812
  }
140746
140813
  async delete(id) {
140747
140814
  let removed = false;
140748
- await this.mutate((schedules) => {
140815
+ await this.store.mutate((schedules) => {
140749
140816
  const before = schedules.length;
140750
140817
  const after = schedules.filter((s2) => s2.id !== id);
140751
140818
  removed = after.length < before;
@@ -140760,7 +140827,7 @@ var ScheduleStore = class {
140760
140827
  * untouched.
140761
140828
  */
140762
140829
  async syncSkillSchedule(skillName2, entry) {
140763
- await this.mutate((schedules) => {
140830
+ await this.store.mutate((schedules) => {
140764
140831
  const filtered = schedules.filter((s2) => !(s2.source === "skill" && s2.skillName === skillName2));
140765
140832
  if (entry) {
140766
140833
  filtered.push(scheduleEntrySchema.parse({ ...entry, source: "skill", skillName: skillName2 }));
@@ -140776,7 +140843,7 @@ var ScheduleStore = class {
140776
140843
  * into the shared poller without a separate timer.
140777
140844
  */
140778
140845
  async syncWorkflowSchedule(workflowName2, entry) {
140779
- await this.mutate((schedules) => {
140846
+ await this.store.mutate((schedules) => {
140780
140847
  const filtered = schedules.filter((s2) => !(s2.source === "workflow" && s2.workflowName === workflowName2));
140781
140848
  if (entry) {
140782
140849
  filtered.push(scheduleEntrySchema.parse({ ...entry, source: "workflow", workflowName: workflowName2 }));
@@ -140784,38 +140851,6 @@ var ScheduleStore = class {
140784
140851
  return filtered;
140785
140852
  });
140786
140853
  }
140787
- async ensureLoaded() {
140788
- if (this.cache)
140789
- return;
140790
- try {
140791
- const raw = await readFile(this.file, "utf8");
140792
- const parsed = fileSchema.safeParse(JSON.parse(raw));
140793
- this.cache = parsed.success ? [...parsed.data.schedules] : [];
140794
- } catch (err) {
140795
- if (err.code === "ENOENT") {
140796
- this.cache = [];
140797
- } else {
140798
- this.cache = [];
140799
- }
140800
- }
140801
- }
140802
- /**
140803
- * Read-modify-write the cached array under the write mutex. The
140804
- * mutator receives a fresh shallow copy; whatever it returns becomes
140805
- * the new state. Persists atomically.
140806
- */
140807
- async mutate(fn) {
140808
- await this.mutex.run(async () => {
140809
- await this.ensureLoaded();
140810
- const updated = fn(this.cache.slice());
140811
- this.cache = updated;
140812
- await this.persist(updated);
140813
- });
140814
- }
140815
- async persist(schedules) {
140816
- const payload = JSON.stringify({ version: 1, schedules }, null, 2);
140817
- await writeFileAtomic(this.file, payload);
140818
- }
140819
140854
  };
140820
140855
  var cronOrTimestamp = z$1.object({
140821
140856
  cron: z$1.string().optional(),
@@ -140967,6 +141002,7 @@ function buildSchedulerPlugin(opts) {
140967
141002
  const poller = new SchedulerPoller({
140968
141003
  store,
140969
141004
  runner: opts.runner,
141005
+ ...opts.skills ? { skills: opts.skills } : {},
140970
141006
  ...opts.intervalMs !== void 0 ? { intervalMs: opts.intervalMs } : {},
140971
141007
  ...opts.inbox ? { inbox: opts.inbox } : {},
140972
141008
  ...opts.logger ? { logger: opts.logger } : {},
@@ -140999,8 +141035,9 @@ function buildSchedulerPlugin(opts) {
140999
141035
  },
141000
141036
  // Re-sync skill-driven schedules whenever a skill_created event
141001
141037
  // lands — covers the "the model just synthesized a new skill
141002
- // with a schedule" case. Skill replacements/deletes are handled
141003
- // by the same path because the poller's next tick rescans.
141038
+ // with a schedule" case for an immediate response. Skill edits and
141039
+ // deletes are reconciled by the poller's per-tick re-sync (it is
141040
+ // primed with `opts.skills`).
141004
141041
  onEvent: async (event) => {
141005
141042
  if (event.type !== "skill_created")
141006
141043
  return;
@@ -141222,7 +141259,7 @@ function readHeader(headers, name) {
141222
141259
  return v3[0] ?? null;
141223
141260
  return v3 ?? null;
141224
141261
  }
141225
- function readJsonPath(body, path62) {
141262
+ function readJsonPath(body, path60) {
141226
141263
  let parsed;
141227
141264
  try {
141228
141265
  parsed = JSON.parse(body.toString("utf8"));
@@ -141230,7 +141267,7 @@ function readJsonPath(body, path62) {
141230
141267
  return null;
141231
141268
  }
141232
141269
  let cur = parsed;
141233
- for (const seg of path62.split(".")) {
141270
+ for (const seg of path60.split(".")) {
141234
141271
  if (cur === null || cur === void 0 || typeof cur !== "object")
141235
141272
  return null;
141236
141273
  cur = cur[seg];
@@ -141608,15 +141645,26 @@ function defaultWebhooksFile() {
141608
141645
  var WebhookStore = class {
141609
141646
  file;
141610
141647
  logger;
141611
- cache = null;
141612
141648
  loadWarningMsg = null;
141613
- mutex = createMutex();
141649
+ // Generic id-collection store owns the cache, write mutex, RMW `.slice()`
141650
+ // copy, and crash-atomic `{ version: 1, triggers: [...] }` write. Corruption
141651
+ // policy (preserve aside / quarantine / refuse-on-unreadable) stays here in
141652
+ // the `load`/`onReadError` hooks, byte-for-byte as before.
141653
+ store;
141614
141654
  constructor(opts = {}) {
141615
141655
  this.file = opts.file ?? defaultWebhooksFile();
141616
141656
  this.logger = opts.logger;
141657
+ this.store = createJsonFileStore({
141658
+ file: this.file,
141659
+ itemsKey: "triggers",
141660
+ load: (raw) => this.parseFile(raw),
141661
+ onReadError: (err) => {
141662
+ throw new Error(`webhooks store: cannot read ${this.file}: ${err instanceof Error ? err.message : String(err)} \u2014 refusing to load (and write) until the file is readable again`);
141663
+ }
141664
+ });
141617
141665
  }
141618
141666
  invalidate() {
141619
- this.cache = null;
141667
+ this.store.invalidate();
141620
141668
  this.loadWarningMsg = null;
141621
141669
  }
141622
141670
  /**
@@ -141626,20 +141674,18 @@ var WebhookStore = class {
141626
141674
  * the user learns about it instead of silently losing triggers.
141627
141675
  */
141628
141676
  async loadWarning() {
141629
- await this.ensureLoaded();
141677
+ await this.store.read();
141630
141678
  return this.loadWarningMsg;
141631
141679
  }
141632
141680
  async list() {
141633
- await this.ensureLoaded();
141634
- return this.cache.slice();
141681
+ return this.store.read();
141635
141682
  }
141636
141683
  async get(id) {
141637
- await this.ensureLoaded();
141638
- return this.cache.find((t2) => t2.id === id) ?? null;
141684
+ return this.store.get(id);
141639
141685
  }
141640
141686
  async getByName(name) {
141641
- await this.ensureLoaded();
141642
- return this.cache.find((t2) => t2.name === name) ?? null;
141687
+ const all = await this.store.read();
141688
+ return all.find((t2) => t2.name === name) ?? null;
141643
141689
  }
141644
141690
  async create(input) {
141645
141691
  const existing = await this.getByName(input.name);
@@ -141652,7 +141698,7 @@ var WebhookStore = class {
141652
141698
  enabled: input.enabled ?? true,
141653
141699
  fireCount: 0
141654
141700
  });
141655
- await this.mutate((triggers) => {
141701
+ await this.store.mutate((triggers) => {
141656
141702
  triggers.push(entry);
141657
141703
  return triggers;
141658
141704
  });
@@ -141660,7 +141706,7 @@ var WebhookStore = class {
141660
141706
  }
141661
141707
  async update(id, patch) {
141662
141708
  let updated = null;
141663
- await this.mutate((triggers) => {
141709
+ await this.store.mutate((triggers) => {
141664
141710
  const idx = triggers.findIndex((t2) => t2.id === id);
141665
141711
  if (idx < 0)
141666
141712
  return triggers;
@@ -141673,7 +141719,7 @@ var WebhookStore = class {
141673
141719
  }
141674
141720
  async delete(id) {
141675
141721
  let removed = false;
141676
- await this.mutate((triggers) => {
141722
+ await this.store.mutate((triggers) => {
141677
141723
  const before = triggers.length;
141678
141724
  const after = triggers.filter((t2) => t2.id !== id);
141679
141725
  removed = after.length < before;
@@ -141684,7 +141730,7 @@ var WebhookStore = class {
141684
141730
  /** Atomic increment + outcome write, used by the dispatcher on every fire. */
141685
141731
  async recordFire(id, outcome) {
141686
141732
  let updated = null;
141687
- await this.mutate((triggers) => {
141733
+ await this.store.mutate((triggers) => {
141688
141734
  const idx = triggers.findIndex((t2) => t2.id === id);
141689
141735
  if (idx < 0)
141690
141736
  return triggers;
@@ -141702,31 +141748,26 @@ var WebhookStore = class {
141702
141748
  });
141703
141749
  return updated;
141704
141750
  }
141705
- async ensureLoaded() {
141706
- if (this.cache)
141707
- return;
141751
+ /**
141752
+ * Parse + validate the file contents into the trigger array, owning all
141753
+ * corruption policy. Called by the generic store on load with the raw
141754
+ * UTF-8 string, or `null` when the file is absent (a legitimate fresh
141755
+ * start). A present-but-unreadable file is handled upstream by the
141756
+ * generic's `onReadError` hook (which throws to refuse operation).
141757
+ */
141758
+ async parseFile(raw) {
141708
141759
  this.loadWarningMsg = null;
141709
- let raw;
141710
- try {
141711
- raw = await readFile(this.file, "utf8");
141712
- } catch (err) {
141713
- if (err.code === "ENOENT") {
141714
- this.cache = [];
141715
- return;
141716
- }
141717
- throw new Error(`webhooks store: cannot read ${this.file}: ${err instanceof Error ? err.message : String(err)} \u2014 refusing to load (and write) until the file is readable again`);
141718
- }
141760
+ if (raw === null)
141761
+ return [];
141719
141762
  let json;
141720
141763
  try {
141721
141764
  json = JSON.parse(raw);
141722
141765
  } catch {
141723
- await this.preserveCorruptFile("is not valid JSON");
141724
- return;
141766
+ return this.preserveCorruptFile("is not valid JSON");
141725
141767
  }
141726
141768
  const file = looseFileSchema.safeParse(json);
141727
141769
  if (!file.success) {
141728
- await this.preserveCorruptFile("does not match the expected { version: 1, triggers: [...] } shape");
141729
- return;
141770
+ return this.preserveCorruptFile("does not match the expected { version: 1, triggers: [...] } shape");
141730
141771
  }
141731
141772
  const valid = [];
141732
141773
  const invalid = [];
@@ -141744,7 +141785,7 @@ var WebhookStore = class {
141744
141785
  });
141745
141786
  if (invalid.length > 0)
141746
141787
  await this.quarantineEntries(invalid);
141747
- this.cache = valid;
141788
+ return valid;
141748
141789
  }
141749
141790
  /**
141750
141791
  * The file exists but is unparseable/mis-shaped. Rename it aside (rename,
@@ -141762,7 +141803,7 @@ var WebhookStore = class {
141762
141803
  preserved,
141763
141804
  reason
141764
141805
  });
141765
- this.cache = [];
141806
+ return [];
141766
141807
  }
141767
141808
  /**
141768
141809
  * The file parses but some entries fail validation. Keep the valid ones,
@@ -141785,18 +141826,6 @@ var WebhookStore = class {
141785
141826
  issues: invalid.map((i2) => ({ index: i2.index, issues: i2.issues }))
141786
141827
  });
141787
141828
  }
141788
- async mutate(fn) {
141789
- await this.mutex.run(async () => {
141790
- await this.ensureLoaded();
141791
- const updated = fn(this.cache.slice());
141792
- this.cache = updated;
141793
- await this.persist(updated);
141794
- });
141795
- }
141796
- async persist(triggers) {
141797
- const payload = JSON.stringify({ version: 1, triggers }, null, 2);
141798
- await writeFileAtomic(this.file, payload);
141799
- }
141800
141829
  };
141801
141830
  function timestampSlug() {
141802
141831
  return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
@@ -144431,8 +144460,8 @@ function formatIssues(error2, raw) {
144431
144460
  const field = rest.join(".");
144432
144461
  return field ? `${where}: ${field} ${msg}` : `${where} ${msg}`;
144433
144462
  }
144434
- const path62 = iss.path.join(".");
144435
- return path62 ? `${path62} ${msg}` : `workflow ${msg}`;
144463
+ const path60 = iss.path.join(".");
144464
+ return path60 ? `${path60} ${msg}` : `workflow ${msg}`;
144436
144465
  });
144437
144466
  }
144438
144467
  function validateWorkflow(raw) {
@@ -144644,12 +144673,9 @@ var WorkflowRunStore = class {
144644
144673
  }
144645
144674
  async save(checkpoint) {
144646
144675
  const runId = ulid();
144647
- await promises.mkdir(this.dir, { recursive: true });
144648
144676
  const file = path3.join(this.dir, `${runId}.json`);
144649
144677
  const payload = { ...checkpoint, runId };
144650
- const tmp = `${file}.tmp`;
144651
- await promises.writeFile(tmp, JSON.stringify(payload), "utf8");
144652
- await promises.rename(tmp, file);
144678
+ await writeFileAtomic(file, JSON.stringify(payload));
144653
144679
  return runId;
144654
144680
  }
144655
144681
  async load(runId) {
@@ -144908,9 +144934,11 @@ function buildRunResult(ctx, status, ok, extra) {
144908
144934
  ...extra
144909
144935
  };
144910
144936
  }
144911
- async function runExecutorLoop(ctx) {
144937
+ async function runExecutorLoop(ctx, resumed = false) {
144912
144938
  const { workflow, deps } = ctx;
144913
- await deps.emit?.("workflow_started", { name: workflow.name, steps: workflow.steps.length });
144939
+ if (!resumed) {
144940
+ await deps.emit?.("workflow_started", { name: workflow.name, steps: workflow.steps.length });
144941
+ }
144914
144942
  const settled = (id) => {
144915
144943
  const s2 = ctx.states.get(id)?.status;
144916
144944
  return s2 === "completed" || s2 === "skipped" || s2 === "failed";
@@ -144980,6 +145008,8 @@ async function runExecutorLoop(ctx) {
144980
145008
  const wave = ready.slice(0, Math.max(1, workflow.concurrency));
144981
145009
  const scope = buildScope(ctx, new Date(ctx.now()).toISOString());
144982
145010
  for (const step of wave) {
145011
+ if (aborted)
145012
+ break;
144983
145013
  const st3 = ctx.states.get(step.id);
144984
145014
  st3.startedAt = ctx.now();
144985
145015
  await deps.emit?.("workflow_step_started", {
@@ -145146,7 +145176,7 @@ ${userMessage.trim()}${FINALIZE_REPLY_SUFFIX}`;
145146
145176
  return buildRunResult(ctx, "failed", false, { error: message });
145147
145177
  }
145148
145178
  await store.remove(runId);
145149
- return runExecutorLoop(ctx);
145179
+ return runExecutorLoop(ctx, true);
145150
145180
  }
145151
145181
  function sinkOutput(workflow, states) {
145152
145182
  const needed = /* @__PURE__ */ new Set();
@@ -145231,12 +145261,12 @@ async function runNestedWorkflow(step, scope, ctx, opts) {
145231
145261
  trigger: `workflow:${step.workflow}`
145232
145262
  });
145233
145263
  if (result.status === "paused") {
145234
- return {
145235
- ok: false,
145236
- output: result.output,
145237
- paused: true,
145238
- ...result.interactionAgentId ? { interactionAgentId: result.interactionAgentId } : {}
145239
- };
145264
+ if (result.runId) {
145265
+ const store = deps.runStore ?? defaultWorkflowRunStore;
145266
+ await store.remove(result.runId).catch(() => {
145267
+ });
145268
+ }
145269
+ throw new Error(`nested workflow "${step.workflow}" paused for input (awaitInput); awaitInput is not supported inside a nested workflow \u2014 run it as a top-level workflow instead`);
145240
145270
  }
145241
145271
  if (!result.ok)
145242
145272
  throw new Error(result.error ?? `nested workflow "${step.workflow}" failed`);
@@ -146030,6 +146060,18 @@ async function runCmd2(deps, name) {
146030
146060
  }
146031
146061
  const result = await deps.runNow({ name, trigger: "manual" });
146032
146062
  const steps = result.steps.map((s2) => ` ${statusMark(s2.status)} ${s2.id}${s2.error ? ` \u2014 ${s2.error}` : ""}`).join("\n");
146063
+ if (result.status === "paused") {
146064
+ const pending2 = result.pendingStepId ? result.steps.find((s2) => s2.id === result.pendingStepId) : void 0;
146065
+ const ask = (pending2?.output ?? "").trim();
146066
+ const lines = [
146067
+ `\u23F8 workflow "${name}" is awaiting input` + (result.pendingStepId ? ` at step "${result.pendingStepId}"` : ""),
146068
+ steps,
146069
+ "",
146070
+ ask ? `Question: ${truncate7(ask, 1200)}` : "",
146071
+ result.runId ? `Reply to continue it (run id ${result.runId}).` : "Reply to continue it."
146072
+ ].filter((l2) => l2 !== "");
146073
+ return { kind: "text", text: lines.join("\n") };
146074
+ }
146033
146075
  const head = result.ok ? `\u2713 workflow "${name}" completed` : `\u2717 workflow "${name}" failed${result.error ? `: ${result.error}` : ""}`;
146034
146076
  return { kind: "text", text: `${head}
146035
146077
  ${steps}
@@ -146137,22 +146179,24 @@ async function readLastRun(dir, name) {
146137
146179
  } catch {
146138
146180
  return null;
146139
146181
  }
146140
- const matches = files.filter((f3) => f3.includes(`-${name}-`) && f3.endsWith(".jsonl")).sort();
146141
- const latest = matches[matches.length - 1];
146142
- if (!latest)
146143
- return null;
146144
- try {
146145
- const raw = await promises.readFile(path3.join(dir, latest), "utf8");
146146
- const lines = raw.trim().split("\n").map((l2) => JSON.parse(l2));
146147
- const run2 = lines.find((l2) => l2.kind === "run");
146148
- const steps = lines.filter((l2) => l2.kind === "step");
146149
- const head = `${run2?.ok ? "\u2713" : "\u2717"} ${new Date(Number(run2?.startedAt ?? 0)).toISOString()} (${String(run2?.trigger ?? "?")})`;
146150
- const stepLines = steps.map((s2) => ` ${statusMark(String(s2.status))} ${String(s2.id)}`).join("\n");
146151
- return `${head}
146182
+ const candidates = files.filter((f3) => f3.includes(`-${name}-`) && f3.endsWith(".jsonl")).sort().reverse();
146183
+ for (const file of candidates) {
146184
+ try {
146185
+ const raw = await promises.readFile(path3.join(dir, file), "utf8");
146186
+ const lines = raw.trim().split("\n").map((l2) => JSON.parse(l2));
146187
+ const run2 = lines.find((l2) => l2.kind === "run");
146188
+ if (run2?.workflow !== name)
146189
+ continue;
146190
+ const steps = lines.filter((l2) => l2.kind === "step");
146191
+ const head = `${run2.ok ? "\u2713" : "\u2717"} ${new Date(Number(run2.startedAt ?? 0)).toISOString()} (${String(run2.trigger ?? "?")})`;
146192
+ const stepLines = steps.map((s2) => ` ${statusMark(String(s2.status))} ${String(s2.id)}`).join("\n");
146193
+ return `${head}
146152
146194
  ${stepLines}`;
146153
- } catch {
146154
- return null;
146195
+ } catch {
146196
+ continue;
146197
+ }
146155
146198
  }
146199
+ return null;
146156
146200
  }
146157
146201
  function truncate7(s2, max) {
146158
146202
  return s2.length > max ? `${s2.slice(0, max)}
@@ -146452,6 +146496,7 @@ function buildWorkflowsIntegration(args) {
146452
146496
  });
146453
146497
  }
146454
146498
  }
146499
+ await startFileWatchers();
146455
146500
  }
146456
146501
  const unsubscribe = session.log.subscribe((event) => {
146457
146502
  if (event.type !== "plugin_event" || event.subtype !== "workflow_completed") return;
@@ -146522,7 +146567,6 @@ function buildWorkflowsIntegration(args) {
146522
146567
  onReady: async () => {
146523
146568
  session.workflows = view;
146524
146569
  await syncSchedules();
146525
- await startFileWatchers();
146526
146570
  void defaultWorkflowRunStore.sweepStale().then((n2) => {
146527
146571
  if (n2 > 0) logger?.info?.("workflows: swept stale paused-run checkpoints", { count: n2 });
146528
146572
  }).catch(
@@ -147970,7 +148014,7 @@ async function fetchLatest(pkg = DEFAULT_PKG, opts = {}) {
147970
148014
  var CACHE_TTL_MS = 12 * 60 * 60 * 1e3;
147971
148015
  var PKG = "@moxxy/cli";
147972
148016
  function defaultCacheFile() {
147973
- return path3.join(os5.homedir(), ".moxxy", "update-check.json");
148017
+ return moxxyPath("update-check.json");
147974
148018
  }
147975
148019
  function compareSemver(a2, b3) {
147976
148020
  const parse2 = (s2) => (s2.split("-")[0] ?? "").split(".").map((n2) => Number.parseInt(n2, 10) || 0);
@@ -148259,7 +148303,7 @@ async function collectKey(providerId, controller) {
148259
148303
  }
148260
148304
  }
148261
148305
  function buildProviderAuthContext(vault, opts) {
148262
- const prompt = opts.promptMode === "stdin" ? stdinLinePrompt : opts.headless ? void 0 : clackPrompt;
148306
+ const prompt = opts.promptMode === "stdin" ? makeStdinLinePrompt(opts.stdin ?? process.stdin) : opts.headless ? void 0 : clackPrompt;
148263
148307
  return {
148264
148308
  headless: opts.headless,
148265
148309
  write: opts.write ?? ((s2) => process.stdout.write(s2)),
@@ -148271,33 +148315,35 @@ function buildProviderAuthContext(vault, opts) {
148271
148315
  }
148272
148316
  };
148273
148317
  }
148274
- var lineReader = null;
148275
- var stdinEnded = false;
148276
- var lineQueue = [];
148277
- var lineWaiters = [];
148278
- function ensureLineReader() {
148279
- if (lineReader) return;
148280
- lineReader = createInterface({ input: process.stdin });
148281
- lineReader.on("line", (line) => {
148282
- const waiter = lineWaiters.shift();
148283
- if (waiter) waiter(line);
148284
- else lineQueue.push(line);
148285
- });
148286
- lineReader.on("close", () => {
148287
- stdinEnded = true;
148288
- for (const w4 of lineWaiters.splice(0)) w4("");
148289
- });
148290
- }
148291
- function readStdinLine() {
148292
- ensureLineReader();
148293
- const queued = lineQueue.shift();
148294
- if (queued !== void 0) return Promise.resolve(queued);
148295
- if (stdinEnded) return Promise.resolve("");
148296
- return new Promise((resolve13) => lineWaiters.push(resolve13));
148297
- }
148298
- async function stdinLinePrompt(question, opts) {
148299
- process.stdout.write(encodeLoginPrompt({ question, mask: opts?.mask === true }));
148300
- return await readStdinLine();
148318
+ function makeStdinLinePrompt(input) {
148319
+ let lineReader = null;
148320
+ let stdinEnded = false;
148321
+ const lineQueue = [];
148322
+ const lineWaiters = [];
148323
+ const ensureLineReader = () => {
148324
+ if (lineReader) return;
148325
+ lineReader = createInterface({ input });
148326
+ lineReader.on("line", (line) => {
148327
+ const waiter = lineWaiters.shift();
148328
+ if (waiter) waiter(line);
148329
+ else lineQueue.push(line);
148330
+ });
148331
+ lineReader.on("close", () => {
148332
+ stdinEnded = true;
148333
+ for (const w4 of lineWaiters.splice(0)) w4("");
148334
+ });
148335
+ };
148336
+ const readStdinLine = () => {
148337
+ ensureLineReader();
148338
+ const queued = lineQueue.shift();
148339
+ if (queued !== void 0) return Promise.resolve(queued);
148340
+ if (stdinEnded) return Promise.resolve("");
148341
+ return new Promise((resolve13) => lineWaiters.push(resolve13));
148342
+ };
148343
+ return async (question, promptOpts) => {
148344
+ process.stdout.write(encodeLoginPrompt({ question, mask: promptOpts?.mask === true }));
148345
+ return await readStdinLine();
148346
+ };
148301
148347
  }
148302
148348
  async function clackPrompt(question, opts) {
148303
148349
  const answer = opts?.mask ? await Ce2({ message: question }) : await Pe2({ message: question });
@@ -149376,7 +149422,10 @@ async function runSelfHostedChannel(name, argv, standalone) {
149376
149422
  ...collectExtraFlags(argv)
149377
149423
  });
149378
149424
  const webHandle = name === "web" ? null : await coAttachWebSurface({ primary: name, session, vault, config });
149425
+ let stopping = false;
149379
149426
  const shutdown = async () => {
149427
+ if (stopping) return;
149428
+ stopping = true;
149380
149429
  await webHandle?.stop("SIGINT").catch(() => void 0);
149381
149430
  await runnerServer?.close().catch(() => void 0);
149382
149431
  await handle2.stop("SIGINT");
@@ -150700,32 +150749,39 @@ async function runScheduleNow(argv) {
150700
150749
  process.stderr.write(colors.red("missing id") + "\n usage: moxxy schedule run <id>\n");
150701
150750
  return 2;
150702
150751
  }
150703
- const { session, scheduler: full } = await setupSessionWithConfig({ cwd: process.cwd() });
150704
- const entry = await full.store.get(id);
150705
- if (!entry) {
150706
- process.stderr.write(colors.dim(`no schedule with id ${id}`) + "\n");
150707
- return 1;
150708
- }
150709
- process.stdout.write(`${colors.bold("firing")} ${entry.name}\u2026
150752
+ const { session, scheduler: full } = await setupSessionWithConfig({
150753
+ cwd: process.cwd(),
150754
+ skipInitHooks: true
150755
+ });
150756
+ try {
150757
+ const entry = await full.store.get(id);
150758
+ if (!entry) {
150759
+ process.stderr.write(colors.dim(`no schedule with id ${id}`) + "\n");
150760
+ return 1;
150761
+ }
150762
+ process.stdout.write(`${colors.bold("firing")} ${entry.name}\u2026
150710
150763
  `);
150711
- const outcome = await runSchedule(entry, {
150712
- runPrompt: async ({ prompt, model }) => {
150713
- const { runTurn: runTurn2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
150714
- let text = "";
150715
- for await (const event of runTurn2(session, prompt, model ? { model } : {})) {
150716
- if (event.type === "assistant_message") text = event.content;
150764
+ const outcome = await runSchedule(entry, {
150765
+ runPrompt: async ({ prompt, model }) => {
150766
+ const { runTurn: runTurn2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
150767
+ let text = "";
150768
+ for await (const event of runTurn2(session, prompt, model ? { model } : {})) {
150769
+ if (event.type === "assistant_message") text = event.content;
150770
+ }
150771
+ return { text };
150717
150772
  }
150718
- return { text };
150719
- }
150720
- }, full.store);
150721
- const tag2 = outcome.ok ? colors.bold("done") : colors.red("fail");
150722
- process.stdout.write(
150723
- `${tag2} ${colors.dim("inbox: " + (outcome.inboxPath ?? "(none)"))}
150773
+ }, full.store);
150774
+ const tag2 = outcome.ok ? colors.bold("done") : colors.red("fail");
150775
+ process.stdout.write(
150776
+ `${tag2} ${colors.dim("inbox: " + (outcome.inboxPath ?? "(none)"))}
150724
150777
  ` + (outcome.error ? ` ${colors.red(outcome.error)}
150725
150778
  ` : "") + (outcome.text ? ` ${colors.dim(outcome.text.slice(0, 400))}
150726
150779
  ` : "")
150727
- );
150728
- return outcome.ok ? 0 : 1;
150780
+ );
150781
+ return outcome.ok ? 0 : 1;
150782
+ } finally {
150783
+ await session.close("schedule-run").catch(() => void 0);
150784
+ }
150729
150785
  }
150730
150786
 
150731
150787
  // src/commands/schedule.ts
@@ -152562,7 +152618,7 @@ var COMMANDS = {
152562
152618
  };
152563
152619
  async function main() {
152564
152620
  const argv = parseArgv(process.argv.slice(2));
152565
- await finalizeStagedCoreUpdate(path3.join(os5.homedir(), ".moxxy")).catch(() => void 0);
152621
+ await finalizeStagedCoreUpdate(moxxyHome()).catch(() => void 0);
152566
152622
  const handler = COMMANDS[argv.command];
152567
152623
  if (handler) return handler(argv);
152568
152624
  let isChannel = false;