@phenx-inc/ctlsurf 0.15.0 → 0.15.1

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 (29) hide show
  1. package/out/headless/index.mjs +89 -71
  2. package/out/headless/index.mjs.map +3 -3
  3. package/out/main/index.js +90 -72
  4. package/out/preload/index.js +1 -1
  5. package/out/renderer/assets/{cssMode-CJR4iD-G.js → cssMode-B77M9HlN.js} +3 -3
  6. package/out/renderer/assets/{freemarker2-BRI9ISq9.js → freemarker2-oUT2zvyQ.js} +1 -1
  7. package/out/renderer/assets/{handlebars-3hL6XIZI.js → handlebars-jCckoi5j.js} +1 -1
  8. package/out/renderer/assets/{html-Dd5_vBoP.js → html-kAgrAaKW.js} +1 -1
  9. package/out/renderer/assets/{htmlMode-DgNtlKcG.js → htmlMode-DIWkIawy.js} +3 -3
  10. package/out/renderer/assets/{index-5azC4yNn.js → index-CN3UN7Tm.js} +32 -27
  11. package/out/renderer/assets/{javascript-D0vPLEJg.js → javascript-B9GYUE-I.js} +2 -2
  12. package/out/renderer/assets/{jsonMode-DBvR0zMu.js → jsonMode-BzFKTZjJ.js} +3 -3
  13. package/out/renderer/assets/{liquid-CLoc6Tx7.js → liquid-Ccw-S_Y6.js} +1 -1
  14. package/out/renderer/assets/{lspLanguageFeatures-CiaMaQoY.js → lspLanguageFeatures-BE0g7ubH.js} +1 -1
  15. package/out/renderer/assets/{mdx-DTsq6tlv.js → mdx-oXeAA0qU.js} +1 -1
  16. package/out/renderer/assets/{python-D04DpZDr.js → python-DlSX3TvA.js} +1 -1
  17. package/out/renderer/assets/{razor-Di6CJ6s8.js → razor-ButO9S7r.js} +1 -1
  18. package/out/renderer/assets/{tsMode-mfv6mHOv.js → tsMode-CTCpE-67.js} +1 -1
  19. package/out/renderer/assets/{typescript-CDA0Hhef.js → typescript-9o62WOnS.js} +1 -1
  20. package/out/renderer/assets/{xml-BU0voRuq.js → xml-C4nOH2_D.js} +1 -1
  21. package/out/renderer/assets/{yaml-qzFWnaZJ.js → yaml-mXYgKoWW.js} +1 -1
  22. package/out/renderer/index.html +1 -1
  23. package/package.json +1 -1
  24. package/src/main/index.ts +2 -2
  25. package/src/main/orchestrator.ts +2 -2
  26. package/src/main/ticketStore.ts +100 -66
  27. package/src/preload/index.ts +3 -3
  28. package/src/renderer/App.tsx +2 -2
  29. package/src/renderer/components/TicketPanel.tsx +16 -5
package/out/main/index.js CHANGED
@@ -11002,11 +11002,11 @@ function isSameLocalDay(a, b2) {
11002
11002
  function log$4(...args) {
11003
11003
  log$5("[time-tracker]", ...args);
11004
11004
  }
11005
- function findPageByTitle$2(pages, title) {
11005
+ function findPageByTitle$1(pages, title) {
11006
11006
  for (const p2 of pages) {
11007
11007
  if (p2?.title === title) return p2;
11008
11008
  if (p2?.children?.length) {
11009
- const c = findPageByTitle$2(p2.children, title);
11009
+ const c = findPageByTitle$1(p2.children, title);
11010
11010
  if (c) return c;
11011
11011
  }
11012
11012
  }
@@ -11184,7 +11184,7 @@ class TimeTracker {
11184
11184
  }
11185
11185
  if (!folder?.id) return null;
11186
11186
  const folderDetail = await this.api.getFolder(folder.id);
11187
- const agentPage = findPageByTitle$2(folderDetail?.pages || [], AGENT_DATASTORE_PAGE_TITLE$2);
11187
+ const agentPage = findPageByTitle$1(folderDetail?.pages || [], AGENT_DATASTORE_PAGE_TITLE$2);
11188
11188
  if (!agentPage?.id) return null;
11189
11189
  const blockId = await this.findOrAdoptBlock(agentPage.id);
11190
11190
  if (blockId) {
@@ -11289,21 +11289,19 @@ const COLUMNS$1 = [
11289
11289
  function log$3(...args) {
11290
11290
  log$5("[ticket-store]", ...args);
11291
11291
  }
11292
- function findPageByTitle$1(pages, title) {
11292
+ function findPagesByTitle(pages, title) {
11293
+ const found = [];
11293
11294
  for (const p2 of pages) {
11294
- if (p2?.title === title) return p2;
11295
- if (p2?.children?.length) {
11296
- const c = findPageByTitle$1(p2.children, title);
11297
- if (c) return c;
11298
- }
11295
+ if (p2?.title === title) found.push(p2);
11296
+ if (p2?.children?.length) found.push(...findPagesByTitle(p2.children, title));
11299
11297
  }
11300
- return null;
11298
+ return found;
11301
11299
  }
11302
11300
  class TicketStore {
11303
11301
  api;
11304
- // Per-cwd cache of the resolved Tickets datastore: the block (the datastore
11305
- // element) and the Agent Datastore page it lives on. Both ids are handed to
11306
- // the coding agent so it can read/update tickets via the ctlsurf MCP tools.
11302
+ // Per-cwd cache of every resolved Tickets datastore. `primary` is where new
11303
+ // tickets are written and what gets handed to the coding agent; `all` covers
11304
+ // duplicate Agent Datastore pages so listing misses nothing.
11307
11305
  dsCache = /* @__PURE__ */ new Map();
11308
11306
  constructor(api) {
11309
11307
  this.api = api;
@@ -11313,11 +11311,11 @@ class TicketStore {
11313
11311
  const title = input.title?.trim();
11314
11312
  if (!title) return { ok: false, error: "Title is required" };
11315
11313
  try {
11316
- const ds = await this.ensureDatastore(cwd, true);
11317
- if (!ds) {
11314
+ const stores = await this.resolveStores(cwd, true);
11315
+ if (!stores) {
11318
11316
  return { ok: false, error: "No ctlsurf project found for this folder" };
11319
11317
  }
11320
- await this.api.addRow(ds.blockId, {
11318
+ await this.api.addRow(stores.primary.blockId, {
11321
11319
  Title: title,
11322
11320
  Description: input.description?.trim() || "",
11323
11321
  Status: input.status || "Open",
@@ -11331,14 +11329,15 @@ class TicketStore {
11331
11329
  return { ok: false, error: err?.message || String(err) };
11332
11330
  }
11333
11331
  }
11334
- /** Updates an existing ticket row in the project's Tickets datastore. */
11335
- async updateTicket(cwd, rowId, input) {
11332
+ /** Updates an existing ticket row. `blockId` names the store the row lives
11333
+ * in (from listTickets); without it the primary store is assumed. */
11334
+ async updateTicket(cwd, rowId, input, blockId) {
11336
11335
  const title = input.title?.trim();
11337
11336
  if (!title) return { ok: false, error: "Title is required" };
11338
11337
  try {
11339
- const ds = await this.ensureDatastore(cwd, false);
11340
- if (!ds) return { ok: false, error: "No Tickets datastore for this project" };
11341
- await this.api.updateRow(ds.blockId, rowId, {
11338
+ const stores = await this.resolveStores(cwd, false);
11339
+ if (!stores) return { ok: false, error: "No Tickets datastore for this project" };
11340
+ await this.api.updateRow(blockId || stores.primary.blockId, rowId, {
11342
11341
  Title: title,
11343
11342
  Description: input.description?.trim() || "",
11344
11343
  Status: input.status || "Open",
@@ -11351,28 +11350,39 @@ class TicketStore {
11351
11350
  return { ok: false, error: err?.message || String(err) };
11352
11351
  }
11353
11352
  }
11354
- /** Lists existing tickets for the project, newest first. Does not create the
11355
- * datastore — an unconfigured project simply has no tickets yet. */
11353
+ /** Lists existing tickets across every Tickets store in the project's
11354
+ * folder, newest first. Does not create the datastore — an unconfigured
11355
+ * project simply has no tickets yet. */
11356
11356
  async listTickets(cwd) {
11357
11357
  try {
11358
- const ds = await this.ensureDatastore(cwd, false);
11359
- if (!ds) return { ok: true, tickets: [] };
11360
- const res = await this.api.queryRows(ds.blockId, { orderBy: "Created", order: "desc", limit: 200 });
11361
- const tickets = (res?.rows || []).map((r) => ({
11362
- id: r.id,
11363
- title: String(r.data?.Title ?? ""),
11364
- description: String(r.data?.Description ?? ""),
11365
- status: String(r.data?.Status ?? "Open"),
11366
- priority: String(r.data?.Priority ?? "Med"),
11367
- created: r.data?.Created ?? r.created_at ?? null
11368
- }));
11369
- return { ok: true, tickets, blockId: ds.blockId, pageId: ds.pageId };
11358
+ const stores = await this.resolveStores(cwd, false);
11359
+ if (!stores) return { ok: true, tickets: [] };
11360
+ const tickets = [];
11361
+ for (const ds of stores.all) {
11362
+ const res = await this.api.queryRows(ds.blockId, { orderBy: "Created", order: "desc", limit: 200 });
11363
+ for (const r of res?.rows || []) {
11364
+ tickets.push({
11365
+ id: r.id,
11366
+ title: String(r.data?.Title ?? ""),
11367
+ description: String(r.data?.Description ?? ""),
11368
+ status: String(r.data?.Status ?? "Open"),
11369
+ priority: String(r.data?.Priority ?? "Med"),
11370
+ created: r.data?.Created ?? r.created_at ?? null,
11371
+ blockId: ds.blockId,
11372
+ pageId: ds.pageId
11373
+ });
11374
+ }
11375
+ }
11376
+ if (stores.all.length > 1) {
11377
+ tickets.sort((a, b2) => (b2.created || "").localeCompare(a.created || ""));
11378
+ }
11379
+ return { ok: true, tickets, blockId: stores.primary.blockId, pageId: stores.primary.pageId };
11370
11380
  } catch (err) {
11371
11381
  log$3(`listTickets failed for ${cwd}: ${err?.message || err}`);
11372
11382
  return { ok: false, tickets: [], error: err?.message || String(err) };
11373
11383
  }
11374
11384
  }
11375
- async ensureDatastore(cwd, create) {
11385
+ async resolveStores(cwd, create) {
11376
11386
  const cached = this.dsCache.get(cwd);
11377
11387
  if (cached) return cached;
11378
11388
  let folder = null;
@@ -11383,17 +11393,27 @@ class TicketStore {
11383
11393
  }
11384
11394
  if (!folder?.id) return null;
11385
11395
  const folderDetail = await this.api.getFolder(folder.id);
11386
- const agentPage = findPageByTitle$1(folderDetail?.pages || [], AGENT_DATASTORE_PAGE_TITLE$1);
11387
- if (!agentPage?.id) return null;
11388
- const pageId = agentPage.id;
11389
- const blockId = await this.findOrAdoptBlock(pageId);
11390
- if (blockId) {
11391
- await this.ensureColumns(blockId);
11392
- const ds = { blockId, pageId };
11393
- this.dsCache.set(cwd, ds);
11394
- return ds;
11396
+ const agentPages = findPagesByTitle(folderDetail?.pages || [], AGENT_DATASTORE_PAGE_TITLE$1);
11397
+ if (agentPages.length === 0) return null;
11398
+ const rootPath = folder.root_path || cwd;
11399
+ agentPages.sort((a, b2) => Number(b2?.root_path === rootPath) - Number(a?.root_path === rootPath));
11400
+ if (agentPages.length > 1) {
11401
+ log$3(`Found ${agentPages.length} "Agent Datastore" pages for ${cwd}; aggregating tickets across all of them`);
11402
+ }
11403
+ const all = [];
11404
+ for (const page of agentPages) {
11405
+ for (const blockId of await this.findTicketBlocks(page.id)) {
11406
+ all.push({ blockId, pageId: page.id });
11407
+ }
11408
+ }
11409
+ if (all.length > 0) {
11410
+ for (const ds of all) await this.ensureColumns(ds.blockId);
11411
+ const stores = { primary: all[0], all };
11412
+ this.dsCache.set(cwd, stores);
11413
+ return stores;
11395
11414
  }
11396
11415
  if (!create) return null;
11416
+ const pageId = agentPages[0].id;
11397
11417
  const columns = COLUMNS$1.map((c, i) => ({
11398
11418
  id: `col_${i}`,
11399
11419
  name: c.name,
@@ -11408,47 +11428,45 @@ class TicketStore {
11408
11428
  if (created?.id) {
11409
11429
  log$3(`Created "${DATASTORE_TITLE}" datastore on Agent Datastore page for ${cwd}`);
11410
11430
  const ds = { blockId: created.id, pageId };
11411
- this.dsCache.set(cwd, ds);
11412
- return ds;
11431
+ const stores = { primary: ds, all: [ds] };
11432
+ this.dsCache.set(cwd, stores);
11433
+ return stores;
11413
11434
  }
11414
11435
  return null;
11415
11436
  }
11416
- /** Finds an existing Tickets block on the page. Prefers a system_key match
11417
- * (which survives title renames). Falls back to title match for legacy blocks
11418
- * and backfills system_key on the way out. */
11419
- async findOrAdoptBlock(pageId) {
11437
+ /** Finds every Tickets block on the page: system_key matches first, then
11438
+ * title matches for legacy blocks. When no system_key block exists, the
11439
+ * first legacy block is adopted (system_key backfilled so it survives a
11440
+ * later rename); extra title matches are still listed but left unstamped so
11441
+ * the primary can't flip between sessions. */
11442
+ async findTicketBlocks(pageId) {
11420
11443
  const summaries = await this.api.getPageBlockSummaries(pageId) || [];
11421
11444
  const datastoreSummaries = summaries.filter((b2) => b2?.type === "datastore" && b2?.id);
11422
- if (datastoreSummaries.length === 0) return null;
11423
- let titleFallbackId = null;
11424
- let titleFallbackProps = null;
11445
+ if (datastoreSummaries.length === 0) return [];
11446
+ const keyed = [];
11447
+ const legacy = [];
11425
11448
  for (const s of datastoreSummaries) {
11426
11449
  try {
11427
11450
  const block = await this.api.getBlock(s.id);
11428
11451
  const props = block?.props || {};
11429
- if (props.system_key === SYSTEM_KEY) {
11430
- return s.id;
11431
- }
11432
- if (s.title === DATASTORE_TITLE && titleFallbackId === null) {
11433
- titleFallbackId = s.id;
11434
- titleFallbackProps = props;
11435
- }
11452
+ if (props.system_key === SYSTEM_KEY) keyed.push(s.id);
11453
+ else if (s.title === DATASTORE_TITLE) legacy.push({ id: s.id, props });
11436
11454
  } catch (err) {
11437
11455
  log$3(`getBlock(${s.id}) failed during lookup: ${err?.message || err}`);
11438
11456
  }
11439
11457
  }
11440
- if (titleFallbackId) {
11458
+ if (keyed.length === 0 && legacy.length > 0) {
11459
+ const adopt = legacy[0];
11441
11460
  try {
11442
- await this.api.updateBlock(titleFallbackId, {
11443
- props: { ...titleFallbackProps || {}, system_key: SYSTEM_KEY }
11461
+ await this.api.updateBlock(adopt.id, {
11462
+ props: { ...adopt.props, system_key: SYSTEM_KEY }
11444
11463
  });
11445
- log$3(`Backfilled system_key on legacy Tickets block ${titleFallbackId}`);
11464
+ log$3(`Backfilled system_key on legacy Tickets block ${adopt.id}`);
11446
11465
  } catch (err) {
11447
- log$3(`backfill system_key failed on ${titleFallbackId}: ${err?.message || err}`);
11466
+ log$3(`backfill system_key failed on ${adopt.id}: ${err?.message || err}`);
11448
11467
  }
11449
- return titleFallbackId;
11450
11468
  }
11451
- return null;
11469
+ return [...keyed, ...legacy.map((l) => l.id)];
11452
11470
  }
11453
11471
  async ensureColumns(blockId) {
11454
11472
  try {
@@ -23328,13 +23346,13 @@ class Orchestrator {
23328
23346
  }
23329
23347
  return this.ticketStore.addTicket(cwd, input);
23330
23348
  }
23331
- async updateTicketForActiveTab(rowId, input) {
23349
+ async updateTicketForActiveTab(rowId, input, blockId) {
23332
23350
  const cwd = this.getActiveTabProjectPath();
23333
23351
  if (!cwd) return { ok: false, error: "No active terminal tab" };
23334
23352
  if (!this.ctlsurfApi.getApiKey()) {
23335
23353
  return { ok: false, error: "ctlsurf API key not configured" };
23336
23354
  }
23337
- return this.ticketStore.updateTicket(cwd, rowId, input);
23355
+ return this.ticketStore.updateTicket(cwd, rowId, input, blockId);
23338
23356
  }
23339
23357
  async listTicketsForActiveTab() {
23340
23358
  const cwd = this.getActiveTabProjectPath();
@@ -23960,8 +23978,8 @@ electron.ipcMain.handle("tickets:project", () => {
23960
23978
  electron.ipcMain.handle("tickets:add", async (_event, input) => {
23961
23979
  return orchestrator.addTicketForActiveTab(input);
23962
23980
  });
23963
- electron.ipcMain.handle("tickets:update", async (_event, rowId, input) => {
23964
- return orchestrator.updateTicketForActiveTab(rowId, input);
23981
+ electron.ipcMain.handle("tickets:update", async (_event, rowId, input, blockId) => {
23982
+ return orchestrator.updateTicketForActiveTab(rowId, input, blockId);
23965
23983
  });
23966
23984
  electron.ipcMain.handle("tickets:list", async () => {
23967
23985
  return orchestrator.listTicketsForActiveTab();
@@ -73,7 +73,7 @@ const api = {
73
73
  // Tickets (active tab)
74
74
  getTicketProject: () => electron.ipcRenderer.invoke("tickets:project"),
75
75
  addTicket: (input) => electron.ipcRenderer.invoke("tickets:add", input),
76
- updateTicket: (rowId, input) => electron.ipcRenderer.invoke("tickets:update", rowId, input),
76
+ updateTicket: (rowId, input, blockId) => electron.ipcRenderer.invoke("tickets:update", rowId, input, blockId),
77
77
  listTickets: () => electron.ipcRenderer.invoke("tickets:list"),
78
78
  // Chat logging (global)
79
79
  getLogChat: () => electron.ipcRenderer.invoke("logchat:get"),
@@ -1,6 +1,6 @@
1
- import { c as createWebWorker, l as languages } from "./index-5azC4yNn.js";
2
- import { C as CompletionAdapter, H as HoverAdapter, D as DocumentHighlightAdapter, a as DefinitionAdapter, R as ReferenceAdapter, b as DocumentSymbolAdapter, c as RenameAdapter, d as DocumentColorAdapter, F as FoldingRangeAdapter, e as DiagnosticsAdapter, S as SelectionRangeAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider } from "./lspLanguageFeatures-CiaMaQoY.js";
3
- import { h, i, j, t, k } from "./lspLanguageFeatures-CiaMaQoY.js";
1
+ import { c as createWebWorker, l as languages } from "./index-CN3UN7Tm.js";
2
+ import { C as CompletionAdapter, H as HoverAdapter, D as DocumentHighlightAdapter, a as DefinitionAdapter, R as ReferenceAdapter, b as DocumentSymbolAdapter, c as RenameAdapter, d as DocumentColorAdapter, F as FoldingRangeAdapter, e as DiagnosticsAdapter, S as SelectionRangeAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider } from "./lspLanguageFeatures-BE0g7ubH.js";
3
+ import { h, i, j, t, k } from "./lspLanguageFeatures-BE0g7ubH.js";
4
4
  const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
5
5
  class WorkerManager {
6
6
  constructor(defaults) {
@@ -1,4 +1,4 @@
1
- import { l as languages } from "./index-5azC4yNn.js";
1
+ import { l as languages } from "./index-CN3UN7Tm.js";
2
2
  const EMPTY_ELEMENTS = [
3
3
  "assign",
4
4
  "flush",
@@ -1,4 +1,4 @@
1
- import { l as languages } from "./index-5azC4yNn.js";
1
+ import { l as languages } from "./index-CN3UN7Tm.js";
2
2
  const EMPTY_ELEMENTS = [
3
3
  "area",
4
4
  "base",
@@ -1,4 +1,4 @@
1
- import { l as languages } from "./index-5azC4yNn.js";
1
+ import { l as languages } from "./index-CN3UN7Tm.js";
2
2
  const EMPTY_ELEMENTS = [
3
3
  "area",
4
4
  "base",
@@ -1,6 +1,6 @@
1
- import { c as createWebWorker, l as languages } from "./index-5azC4yNn.js";
2
- import { H as HoverAdapter, D as DocumentHighlightAdapter, h as DocumentLinkAdapter, F as FoldingRangeAdapter, b as DocumentSymbolAdapter, S as SelectionRangeAdapter, c as RenameAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider, C as CompletionAdapter } from "./lspLanguageFeatures-CiaMaQoY.js";
3
- import { a, e, d, R, i, j, t, k } from "./lspLanguageFeatures-CiaMaQoY.js";
1
+ import { c as createWebWorker, l as languages } from "./index-CN3UN7Tm.js";
2
+ import { H as HoverAdapter, D as DocumentHighlightAdapter, h as DocumentLinkAdapter, F as FoldingRangeAdapter, b as DocumentSymbolAdapter, S as SelectionRangeAdapter, c as RenameAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider, C as CompletionAdapter } from "./lspLanguageFeatures-BE0g7ubH.js";
3
+ import { a, e, d, R, i, j, t, k } from "./lspLanguageFeatures-BE0g7ubH.js";
4
4
  const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
5
5
  class WorkerManager {
6
6
  constructor(defaults) {
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./cssMode-CJR4iD-G.js","./lspLanguageFeatures-CiaMaQoY.js","./htmlMode-DgNtlKcG.js","./jsonMode-DBvR0zMu.js","./javascript-D0vPLEJg.js","./typescript-CDA0Hhef.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./cssMode-B77M9HlN.js","./lspLanguageFeatures-BE0g7ubH.js","./htmlMode-DIWkIawy.js","./jsonMode-BzFKTZjJ.js","./javascript-B9GYUE-I.js","./typescript-9o62WOnS.js"])))=>i.map(i=>d[i]);
2
2
  function getDefaultExportFromCjs(x) {
3
3
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
4
4
  }
@@ -208416,7 +208416,7 @@ const lessDefaults = new LanguageServiceDefaultsImpl$3(
208416
208416
  modeConfigurationDefault$2
208417
208417
  );
208418
208418
  function getMode$3() {
208419
- return __vitePreload(() => import("./cssMode-CJR4iD-G.js"), true ? __vite__mapDeps([0,1]) : void 0, import.meta.url);
208419
+ return __vitePreload(() => import("./cssMode-B77M9HlN.js"), true ? __vite__mapDeps([0,1]) : void 0, import.meta.url);
208420
208420
  }
208421
208421
  languages.onLanguage("less", () => {
208422
208422
  getMode$3().then((mode2) => mode2.setupMode(lessDefaults));
@@ -208521,7 +208521,7 @@ const razorLanguageService = registerHTMLLanguageService(
208521
208521
  );
208522
208522
  const razorDefaults = razorLanguageService.defaults;
208523
208523
  function getMode$2() {
208524
- return __vitePreload(() => import("./htmlMode-DgNtlKcG.js"), true ? __vite__mapDeps([2,1]) : void 0, import.meta.url);
208524
+ return __vitePreload(() => import("./htmlMode-DIWkIawy.js"), true ? __vite__mapDeps([2,1]) : void 0, import.meta.url);
208525
208525
  }
208526
208526
  function registerHTMLLanguageService(languageId, options = optionsDefault, modeConfiguration = getConfigurationDefault(languageId)) {
208527
208527
  const defaults = new LanguageServiceDefaultsImpl$2(languageId, options, modeConfiguration);
@@ -208605,7 +208605,7 @@ const jsonDefaults = new LanguageServiceDefaultsImpl$1(
208605
208605
  );
208606
208606
  const getWorker$1 = () => getMode$1().then((mode2) => mode2.getWorker());
208607
208607
  function getMode$1() {
208608
- return __vitePreload(() => import("./jsonMode-DBvR0zMu.js"), true ? __vite__mapDeps([3,1]) : void 0, import.meta.url);
208608
+ return __vitePreload(() => import("./jsonMode-BzFKTZjJ.js"), true ? __vite__mapDeps([3,1]) : void 0, import.meta.url);
208609
208609
  }
208610
208610
  languages.register({
208611
208611
  id: "json",
@@ -208851,7 +208851,7 @@ const getJavaScriptWorker = () => {
208851
208851
  return getMode().then((mode) => mode.getJavaScriptWorker());
208852
208852
  };
208853
208853
  function getMode() {
208854
- return __vitePreload(() => import("./tsMode-mfv6mHOv.js"), true ? [] : void 0, import.meta.url);
208854
+ return __vitePreload(() => import("./tsMode-CTCpE-67.js"), true ? [] : void 0, import.meta.url);
208855
208855
  }
208856
208856
  languages.onLanguage("typescript", () => {
208857
208857
  return getMode().then((mode) => mode.setupTypeScript(typescriptDefaults));
@@ -209046,49 +209046,49 @@ registerLanguage({
209046
209046
  extensions: [".ftl", ".ftlh", ".ftlx"],
209047
209047
  aliases: ["FreeMarker2", "Apache FreeMarker2"],
209048
209048
  loader: () => {
209049
- return __vitePreload(() => import("./freemarker2-BRI9ISq9.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
209049
+ return __vitePreload(() => import("./freemarker2-oUT2zvyQ.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
209050
209050
  }
209051
209051
  });
209052
209052
  registerLanguage({
209053
209053
  id: "freemarker2.tag-angle.interpolation-dollar",
209054
209054
  aliases: ["FreeMarker2 (Angle/Dollar)", "Apache FreeMarker2 (Angle/Dollar)"],
209055
209055
  loader: () => {
209056
- return __vitePreload(() => import("./freemarker2-BRI9ISq9.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationDollar);
209056
+ return __vitePreload(() => import("./freemarker2-oUT2zvyQ.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationDollar);
209057
209057
  }
209058
209058
  });
209059
209059
  registerLanguage({
209060
209060
  id: "freemarker2.tag-bracket.interpolation-dollar",
209061
209061
  aliases: ["FreeMarker2 (Bracket/Dollar)", "Apache FreeMarker2 (Bracket/Dollar)"],
209062
209062
  loader: () => {
209063
- return __vitePreload(() => import("./freemarker2-BRI9ISq9.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationDollar);
209063
+ return __vitePreload(() => import("./freemarker2-oUT2zvyQ.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationDollar);
209064
209064
  }
209065
209065
  });
209066
209066
  registerLanguage({
209067
209067
  id: "freemarker2.tag-angle.interpolation-bracket",
209068
209068
  aliases: ["FreeMarker2 (Angle/Bracket)", "Apache FreeMarker2 (Angle/Bracket)"],
209069
209069
  loader: () => {
209070
- return __vitePreload(() => import("./freemarker2-BRI9ISq9.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationBracket);
209070
+ return __vitePreload(() => import("./freemarker2-oUT2zvyQ.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationBracket);
209071
209071
  }
209072
209072
  });
209073
209073
  registerLanguage({
209074
209074
  id: "freemarker2.tag-bracket.interpolation-bracket",
209075
209075
  aliases: ["FreeMarker2 (Bracket/Bracket)", "Apache FreeMarker2 (Bracket/Bracket)"],
209076
209076
  loader: () => {
209077
- return __vitePreload(() => import("./freemarker2-BRI9ISq9.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationBracket);
209077
+ return __vitePreload(() => import("./freemarker2-oUT2zvyQ.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationBracket);
209078
209078
  }
209079
209079
  });
209080
209080
  registerLanguage({
209081
209081
  id: "freemarker2.tag-auto.interpolation-dollar",
209082
209082
  aliases: ["FreeMarker2 (Auto/Dollar)", "Apache FreeMarker2 (Auto/Dollar)"],
209083
209083
  loader: () => {
209084
- return __vitePreload(() => import("./freemarker2-BRI9ISq9.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
209084
+ return __vitePreload(() => import("./freemarker2-oUT2zvyQ.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
209085
209085
  }
209086
209086
  });
209087
209087
  registerLanguage({
209088
209088
  id: "freemarker2.tag-auto.interpolation-bracket",
209089
209089
  aliases: ["FreeMarker2 (Auto/Bracket)", "Apache FreeMarker2 (Auto/Bracket)"],
209090
209090
  loader: () => {
209091
- return __vitePreload(() => import("./freemarker2-BRI9ISq9.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationBracket);
209091
+ return __vitePreload(() => import("./freemarker2-oUT2zvyQ.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationBracket);
209092
209092
  }
209093
209093
  });
209094
209094
  registerLanguage({
@@ -209109,7 +209109,7 @@ registerLanguage({
209109
209109
  extensions: [".handlebars", ".hbs"],
209110
209110
  aliases: ["Handlebars", "handlebars", "hbs"],
209111
209111
  mimetypes: ["text/x-handlebars-template"],
209112
- loader: () => __vitePreload(() => import("./handlebars-3hL6XIZI.js"), true ? [] : void 0, import.meta.url)
209112
+ loader: () => __vitePreload(() => import("./handlebars-jCckoi5j.js"), true ? [] : void 0, import.meta.url)
209113
209113
  });
209114
209114
  registerLanguage({
209115
209115
  id: "hcl",
@@ -209122,7 +209122,7 @@ registerLanguage({
209122
209122
  extensions: [".html", ".htm", ".shtml", ".xhtml", ".mdoc", ".jsp", ".asp", ".aspx", ".jshtm"],
209123
209123
  aliases: ["HTML", "htm", "html", "xhtml"],
209124
209124
  mimetypes: ["text/html", "text/x-jshtm", "text/template", "text/ng-template"],
209125
- loader: () => __vitePreload(() => import("./html-Dd5_vBoP.js"), true ? [] : void 0, import.meta.url)
209125
+ loader: () => __vitePreload(() => import("./html-kAgrAaKW.js"), true ? [] : void 0, import.meta.url)
209126
209126
  });
209127
209127
  registerLanguage({
209128
209128
  id: "ini",
@@ -209145,7 +209145,7 @@ registerLanguage({
209145
209145
  filenames: ["jakefile"],
209146
209146
  aliases: ["JavaScript", "javascript", "js"],
209147
209147
  mimetypes: ["text/javascript"],
209148
- loader: () => __vitePreload(() => import("./javascript-D0vPLEJg.js"), true ? __vite__mapDeps([4,5]) : void 0, import.meta.url)
209148
+ loader: () => __vitePreload(() => import("./javascript-B9GYUE-I.js"), true ? __vite__mapDeps([4,5]) : void 0, import.meta.url)
209149
209149
  });
209150
209150
  registerLanguage({
209151
209151
  id: "julia",
@@ -209184,7 +209184,7 @@ registerLanguage({
209184
209184
  extensions: [".liquid", ".html.liquid"],
209185
209185
  aliases: ["Liquid", "liquid"],
209186
209186
  mimetypes: ["application/liquid"],
209187
- loader: () => __vitePreload(() => import("./liquid-CLoc6Tx7.js"), true ? [] : void 0, import.meta.url)
209187
+ loader: () => __vitePreload(() => import("./liquid-Ccw-S_Y6.js"), true ? [] : void 0, import.meta.url)
209188
209188
  });
209189
209189
  registerLanguage({
209190
209190
  id: "m3",
@@ -209202,7 +209202,7 @@ registerLanguage({
209202
209202
  id: "mdx",
209203
209203
  extensions: [".mdx"],
209204
209204
  aliases: ["MDX", "mdx"],
209205
- loader: () => __vitePreload(() => import("./mdx-DTsq6tlv.js"), true ? [] : void 0, import.meta.url)
209205
+ loader: () => __vitePreload(() => import("./mdx-oXeAA0qU.js"), true ? [] : void 0, import.meta.url)
209206
209206
  });
209207
209207
  registerLanguage({
209208
209208
  id: "mips",
@@ -209301,7 +209301,7 @@ registerLanguage({
209301
209301
  extensions: [".py", ".rpy", ".pyw", ".cpy", ".gyp", ".gypi"],
209302
209302
  aliases: ["Python", "py"],
209303
209303
  firstLine: "^#!/.*\\bpython[0-9.-]*\\b",
209304
- loader: () => __vitePreload(() => import("./python-D04DpZDr.js"), true ? [] : void 0, import.meta.url)
209304
+ loader: () => __vitePreload(() => import("./python-DlSX3TvA.js"), true ? [] : void 0, import.meta.url)
209305
209305
  });
209306
209306
  registerLanguage({
209307
209307
  id: "qsharp",
@@ -209320,7 +209320,7 @@ registerLanguage({
209320
209320
  extensions: [".cshtml"],
209321
209321
  aliases: ["Razor", "razor"],
209322
209322
  mimetypes: ["text/x-cshtml"],
209323
- loader: () => __vitePreload(() => import("./razor-Di6CJ6s8.js"), true ? [] : void 0, import.meta.url)
209323
+ loader: () => __vitePreload(() => import("./razor-ButO9S7r.js"), true ? [] : void 0, import.meta.url)
209324
209324
  });
209325
209325
  registerLanguage({
209326
209326
  id: "redis",
@@ -209453,7 +209453,7 @@ registerLanguage({
209453
209453
  aliases: ["TypeScript", "ts", "typescript"],
209454
209454
  mimetypes: ["text/typescript"],
209455
209455
  loader: () => {
209456
- return __vitePreload(() => import("./typescript-CDA0Hhef.js"), true ? [] : void 0, import.meta.url);
209456
+ return __vitePreload(() => import("./typescript-9o62WOnS.js"), true ? [] : void 0, import.meta.url);
209457
209457
  }
209458
209458
  });
209459
209459
  registerLanguage({
@@ -209498,14 +209498,14 @@ registerLanguage({
209498
209498
  firstLine: "(\\<\\?xml.*)|(\\<svg)|(\\<\\!doctype\\s+svg)",
209499
209499
  aliases: ["XML", "xml"],
209500
209500
  mimetypes: ["text/xml", "application/xml", "application/xaml+xml", "application/xml-dtd"],
209501
- loader: () => __vitePreload(() => import("./xml-BU0voRuq.js"), true ? [] : void 0, import.meta.url)
209501
+ loader: () => __vitePreload(() => import("./xml-C4nOH2_D.js"), true ? [] : void 0, import.meta.url)
209502
209502
  });
209503
209503
  registerLanguage({
209504
209504
  id: "yaml",
209505
209505
  extensions: [".yaml", ".yml"],
209506
209506
  aliases: ["YAML", "yaml", "YML", "yml"],
209507
209507
  mimetypes: ["application/x-yaml", "text/x-yaml"],
209508
- loader: () => __vitePreload(() => import("./yaml-qzFWnaZJ.js"), true ? [] : void 0, import.meta.url)
209508
+ loader: () => __vitePreload(() => import("./yaml-mXYgKoWW.js"), true ? [] : void 0, import.meta.url)
209509
209509
  });
209510
209510
  var __defProp = Object.defineProperty;
209511
209511
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -214235,10 +214235,12 @@ function ticketPrompt(t, refs) {
214235
214235
  "ctlsurf references (use the ctlsurf MCP tools to read details or update status):",
214236
214236
  `- Ticket row ID: ${t.id}`
214237
214237
  );
214238
- if (refs) {
214238
+ const blockId = t.blockId ?? refs?.blockId;
214239
+ const pageId = t.pageId ?? refs?.pageId;
214240
+ if (blockId && pageId) {
214239
214241
  lines.push(
214240
- `- Tickets datastore block ID: ${refs.blockId}`,
214241
- `- Agent Datastore page ID: ${refs.pageId}`
214242
+ `- Tickets datastore block ID: ${blockId}`,
214243
+ `- Agent Datastore page ID: ${pageId}`
214242
214244
  );
214243
214245
  }
214244
214246
  return lines.join("\n");
@@ -214307,6 +214309,7 @@ function TicketPane({ onSendToTerminal }) {
214307
214309
  const [listError, setListError] = reactExports.useState(null);
214308
214310
  const [showDone, setShowDone] = reactExports.useState(false);
214309
214311
  const [editingId, setEditingId] = reactExports.useState(null);
214312
+ const [editingBlockId, setEditingBlockId] = reactExports.useState(null);
214310
214313
  const [title, setTitle] = reactExports.useState("");
214311
214314
  const [description, setDescription] = reactExports.useState("");
214312
214315
  const [status2, setStatus] = reactExports.useState(STATUS_OPTIONS[0].value);
@@ -214353,6 +214356,7 @@ function TicketPane({ onSendToTerminal }) {
214353
214356
  }, [refreshList]);
214354
214357
  const openNewForm = reactExports.useCallback(() => {
214355
214358
  setEditingId(null);
214359
+ setEditingBlockId(null);
214356
214360
  setTitle("");
214357
214361
  setDescription("");
214358
214362
  setStatus(STATUS_OPTIONS[0].value);
@@ -214362,6 +214366,7 @@ function TicketPane({ onSendToTerminal }) {
214362
214366
  }, []);
214363
214367
  const openEditForm = reactExports.useCallback((t) => {
214364
214368
  setEditingId(t.id);
214369
+ setEditingBlockId(t.blockId ?? null);
214365
214370
  setTitle(t.title);
214366
214371
  setDescription(t.description);
214367
214372
  setStatus(STATUS_OPTIONS.some((o) => o.value === t.status) ? t.status : STATUS_OPTIONS[0].value);
@@ -214374,7 +214379,7 @@ function TicketPane({ onSendToTerminal }) {
214374
214379
  setSave({ kind: "saving" });
214375
214380
  const payload = { title: title.trim(), description: description.trim(), status: status2, priority };
214376
214381
  try {
214377
- const r = editingId ? await window.worker.updateTicket(editingId, payload) : await window.worker.addTicket(payload);
214382
+ const r = editingId ? await window.worker.updateTicket(editingId, payload, editingBlockId ?? void 0) : await window.worker.addTicket(payload);
214378
214383
  if (r?.ok) {
214379
214384
  setView("list");
214380
214385
  void refreshList();
@@ -214384,7 +214389,7 @@ function TicketPane({ onSendToTerminal }) {
214384
214389
  } catch (err) {
214385
214390
  setSave({ kind: "error", message: err?.message || "Failed to save ticket" });
214386
214391
  }
214387
- }, [title, description, status2, priority, editingId, save.kind, refreshList]);
214392
+ }, [title, description, status2, priority, editingId, editingBlockId, save.kind, refreshList]);
214388
214393
  reactExports.useEffect(() => {
214389
214394
  if (view !== "form") return;
214390
214395
  const onKey = (e) => {
@@ -1,5 +1,5 @@
1
- import { conf as conf$1, language as language$1 } from "./typescript-CDA0Hhef.js";
2
- import "./index-5azC4yNn.js";
1
+ import { conf as conf$1, language as language$1 } from "./typescript-9o62WOnS.js";
2
+ import "./index-CN3UN7Tm.js";
3
3
  const conf = conf$1;
4
4
  const language = {
5
5
  // Set defaultToken to invalid to see what you do not tokenize yet
@@ -1,6 +1,6 @@
1
- import { c as createWebWorker, l as languages, e as editor } from "./index-5azC4yNn.js";
2
- import { f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider, C as CompletionAdapter, H as HoverAdapter, b as DocumentSymbolAdapter, d as DocumentColorAdapter, F as FoldingRangeAdapter, S as SelectionRangeAdapter, e as DiagnosticsAdapter } from "./lspLanguageFeatures-CiaMaQoY.js";
3
- import { a, D, h, R, c, i, j, t, k } from "./lspLanguageFeatures-CiaMaQoY.js";
1
+ import { c as createWebWorker, l as languages, e as editor } from "./index-CN3UN7Tm.js";
2
+ import { f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider, C as CompletionAdapter, H as HoverAdapter, b as DocumentSymbolAdapter, d as DocumentColorAdapter, F as FoldingRangeAdapter, S as SelectionRangeAdapter, e as DiagnosticsAdapter } from "./lspLanguageFeatures-BE0g7ubH.js";
3
+ import { a, D, h, R, c, i, j, t, k } from "./lspLanguageFeatures-BE0g7ubH.js";
4
4
  const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
5
5
  class WorkerManager {
6
6
  constructor(defaults) {
@@ -1,4 +1,4 @@
1
- import { l as languages } from "./index-5azC4yNn.js";
1
+ import { l as languages } from "./index-CN3UN7Tm.js";
2
2
  const EMPTY_ELEMENTS = [
3
3
  "area",
4
4
  "base",
@@ -1,4 +1,4 @@
1
- import { R as Range$1, l as languages, e as editor, U as Uri, M as MarkerSeverity } from "./index-5azC4yNn.js";
1
+ import { R as Range$1, l as languages, e as editor, U as Uri, M as MarkerSeverity } from "./index-CN3UN7Tm.js";
2
2
  var DocumentUri;
3
3
  (function(DocumentUri2) {
4
4
  function is(value) {
@@ -1,4 +1,4 @@
1
- import { l as languages } from "./index-5azC4yNn.js";
1
+ import { l as languages } from "./index-CN3UN7Tm.js";
2
2
  const conf = {
3
3
  comments: {
4
4
  blockComment: ["{/*", "*/}"]
@@ -1,4 +1,4 @@
1
- import { l as languages } from "./index-5azC4yNn.js";
1
+ import { l as languages } from "./index-CN3UN7Tm.js";
2
2
  const conf = {
3
3
  comments: {
4
4
  lineComment: "#",
@@ -1,4 +1,4 @@
1
- import { l as languages } from "./index-5azC4yNn.js";
1
+ import { l as languages } from "./index-CN3UN7Tm.js";
2
2
  const EMPTY_ELEMENTS = [
3
3
  "area",
4
4
  "base",
@@ -1,4 +1,4 @@
1
- import { c as createWebWorker, e as editor, U as Uri, a as MarkerTag, M as MarkerSeverity, l as languages, t as typescriptDefaults, R as Range } from "./index-5azC4yNn.js";
1
+ import { c as createWebWorker, e as editor, U as Uri, a as MarkerTag, M as MarkerSeverity, l as languages, t as typescriptDefaults, R as Range } from "./index-CN3UN7Tm.js";
2
2
  class WorkerManager {
3
3
  constructor(_modeId, _defaults) {
4
4
  this._modeId = _modeId;