@phenx-inc/ctlsurf 0.12.1 → 0.13.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.
- package/out/headless/index.mjs +25 -19
- package/out/headless/index.mjs.map +2 -2
- package/out/main/index.js +30 -18
- package/out/renderer/assets/{cssMode-D7r66wvO.js → cssMode-KhYyY-BM.js} +3 -3
- package/out/renderer/assets/{freemarker2-jSWJIjPG.js → freemarker2-BFsSgcWk.js} +1 -1
- package/out/renderer/assets/{handlebars-BnFyz5RH.js → handlebars-Be6_aBsm.js} +1 -1
- package/out/renderer/assets/{html-Bl5UFavp.js → html-G8mvsyfc.js} +1 -1
- package/out/renderer/assets/{htmlMode-D4VByBT6.js → htmlMode-Cfd5VCjw.js} +3 -3
- package/out/renderer/assets/{index-Cc_TqOCL.css → index-Bi_MjBqs.css} +116 -8
- package/out/renderer/assets/{index-DxhW1emk.js → index-MqgBcJzy.js} +259 -87
- package/out/renderer/assets/{javascript-CMN1OmwG.js → javascript-XyDWi6dC.js} +2 -2
- package/out/renderer/assets/{jsonMode-CJ5AYSPV.js → jsonMode-DZT5gBVW.js} +3 -3
- package/out/renderer/assets/{liquid-BGMIDTEm.js → liquid-BuajCNJ9.js} +1 -1
- package/out/renderer/assets/{lspLanguageFeatures-DGifVYB5.js → lspLanguageFeatures-BYkg2Yc-.js} +1 -1
- package/out/renderer/assets/{mdx-B2Z7R10Q.js → mdx-D0Qx2GMS.js} +1 -1
- package/out/renderer/assets/{python-LMDMSSdn.js → python-ChncNy6S.js} +1 -1
- package/out/renderer/assets/{razor-BZSrziPu.js → razor-C6MUtfaS.js} +1 -1
- package/out/renderer/assets/{tsMode-DF9m6_3n.js → tsMode-C2aMdzdU.js} +1 -1
- package/out/renderer/assets/{typescript-rZeCMf0a.js → typescript-CB71AtAT.js} +1 -1
- package/out/renderer/assets/{xml-fNSZ-7so.js → xml-tHS1Ec9w.js} +1 -1
- package/out/renderer/assets/{yaml-1wxIuvzh.js → yaml-CZcp5ueF.js} +1 -1
- package/out/renderer/index.html +2 -2
- package/package.json +1 -1
- package/src/main/index.ts +9 -0
- package/src/main/orchestrator.ts +1 -1
- package/src/main/ticketStore.ts +26 -20
- package/src/renderer/App.tsx +14 -2
- package/src/renderer/components/CtlsurfPanel.tsx +169 -35
- package/src/renderer/components/TerminalPanel.tsx +7 -21
- package/src/renderer/components/TicketPanel.tsx +80 -24
- package/src/renderer/styles.css +116 -8
package/out/main/index.js
CHANGED
|
@@ -11276,7 +11276,10 @@ function findPageByTitle(pages, title) {
|
|
|
11276
11276
|
}
|
|
11277
11277
|
class TicketStore {
|
|
11278
11278
|
api;
|
|
11279
|
-
|
|
11279
|
+
// Per-cwd cache of the resolved Tickets datastore: the block (the datastore
|
|
11280
|
+
// element) and the Agent Datastore page it lives on. Both ids are handed to
|
|
11281
|
+
// the coding agent so it can read/update tickets via the ctlsurf MCP tools.
|
|
11282
|
+
dsCache = /* @__PURE__ */ new Map();
|
|
11280
11283
|
constructor(api) {
|
|
11281
11284
|
this.api = api;
|
|
11282
11285
|
}
|
|
@@ -11285,11 +11288,11 @@ class TicketStore {
|
|
|
11285
11288
|
const title = input.title?.trim();
|
|
11286
11289
|
if (!title) return { ok: false, error: "Title is required" };
|
|
11287
11290
|
try {
|
|
11288
|
-
const
|
|
11289
|
-
if (!
|
|
11291
|
+
const ds = await this.ensureDatastore(cwd, true);
|
|
11292
|
+
if (!ds) {
|
|
11290
11293
|
return { ok: false, error: "No ctlsurf project found for this folder" };
|
|
11291
11294
|
}
|
|
11292
|
-
await this.api.addRow(blockId, {
|
|
11295
|
+
await this.api.addRow(ds.blockId, {
|
|
11293
11296
|
Title: title,
|
|
11294
11297
|
Description: input.description?.trim() || "",
|
|
11295
11298
|
Status: input.status || "Open",
|
|
@@ -11308,9 +11311,9 @@ class TicketStore {
|
|
|
11308
11311
|
const title = input.title?.trim();
|
|
11309
11312
|
if (!title) return { ok: false, error: "Title is required" };
|
|
11310
11313
|
try {
|
|
11311
|
-
const
|
|
11312
|
-
if (!
|
|
11313
|
-
await this.api.updateRow(blockId, rowId, {
|
|
11314
|
+
const ds = await this.ensureDatastore(cwd, false);
|
|
11315
|
+
if (!ds) return { ok: false, error: "No Tickets datastore for this project" };
|
|
11316
|
+
await this.api.updateRow(ds.blockId, rowId, {
|
|
11314
11317
|
Title: title,
|
|
11315
11318
|
Description: input.description?.trim() || "",
|
|
11316
11319
|
Status: input.status || "Open",
|
|
@@ -11327,9 +11330,9 @@ class TicketStore {
|
|
|
11327
11330
|
* datastore — an unconfigured project simply has no tickets yet. */
|
|
11328
11331
|
async listTickets(cwd) {
|
|
11329
11332
|
try {
|
|
11330
|
-
const
|
|
11331
|
-
if (!
|
|
11332
|
-
const res = await this.api.queryRows(blockId, { orderBy: "Created", order: "desc", limit: 200 });
|
|
11333
|
+
const ds = await this.ensureDatastore(cwd, false);
|
|
11334
|
+
if (!ds) return { ok: true, tickets: [] };
|
|
11335
|
+
const res = await this.api.queryRows(ds.blockId, { orderBy: "Created", order: "desc", limit: 200 });
|
|
11333
11336
|
const tickets = (res?.rows || []).map((r) => ({
|
|
11334
11337
|
id: r.id,
|
|
11335
11338
|
title: String(r.data?.Title ?? ""),
|
|
@@ -11338,14 +11341,14 @@ class TicketStore {
|
|
|
11338
11341
|
priority: String(r.data?.Priority ?? "Med"),
|
|
11339
11342
|
created: r.data?.Created ?? r.created_at ?? null
|
|
11340
11343
|
}));
|
|
11341
|
-
return { ok: true, tickets };
|
|
11344
|
+
return { ok: true, tickets, blockId: ds.blockId, pageId: ds.pageId };
|
|
11342
11345
|
} catch (err) {
|
|
11343
11346
|
log$1(`listTickets failed for ${cwd}: ${err?.message || err}`);
|
|
11344
11347
|
return { ok: false, tickets: [], error: err?.message || String(err) };
|
|
11345
11348
|
}
|
|
11346
11349
|
}
|
|
11347
11350
|
async ensureDatastore(cwd, create) {
|
|
11348
|
-
const cached = this.
|
|
11351
|
+
const cached = this.dsCache.get(cwd);
|
|
11349
11352
|
if (cached) return cached;
|
|
11350
11353
|
let folder = null;
|
|
11351
11354
|
try {
|
|
@@ -11357,11 +11360,13 @@ class TicketStore {
|
|
|
11357
11360
|
const folderDetail = await this.api.getFolder(folder.id);
|
|
11358
11361
|
const agentPage = findPageByTitle(folderDetail?.pages || [], AGENT_DATASTORE_PAGE_TITLE);
|
|
11359
11362
|
if (!agentPage?.id) return null;
|
|
11360
|
-
const
|
|
11363
|
+
const pageId = agentPage.id;
|
|
11364
|
+
const blockId = await this.findOrAdoptBlock(pageId);
|
|
11361
11365
|
if (blockId) {
|
|
11362
11366
|
await this.ensureColumns(blockId);
|
|
11363
|
-
|
|
11364
|
-
|
|
11367
|
+
const ds = { blockId, pageId };
|
|
11368
|
+
this.dsCache.set(cwd, ds);
|
|
11369
|
+
return ds;
|
|
11365
11370
|
}
|
|
11366
11371
|
if (!create) return null;
|
|
11367
11372
|
const columns = COLUMNS.map((c, i) => ({
|
|
@@ -11370,15 +11375,16 @@ class TicketStore {
|
|
|
11370
11375
|
type: c.type,
|
|
11371
11376
|
...c.options ? { options: c.options } : {}
|
|
11372
11377
|
}));
|
|
11373
|
-
const created = await this.api.createBlock(
|
|
11378
|
+
const created = await this.api.createBlock(pageId, {
|
|
11374
11379
|
type: "datastore",
|
|
11375
11380
|
title: DATASTORE_TITLE,
|
|
11376
11381
|
props: { columns, system_key: SYSTEM_KEY }
|
|
11377
11382
|
});
|
|
11378
11383
|
if (created?.id) {
|
|
11379
11384
|
log$1(`Created "${DATASTORE_TITLE}" datastore on Agent Datastore page for ${cwd}`);
|
|
11380
|
-
|
|
11381
|
-
|
|
11385
|
+
const ds = { blockId: created.id, pageId };
|
|
11386
|
+
this.dsCache.set(cwd, ds);
|
|
11387
|
+
return ds;
|
|
11382
11388
|
}
|
|
11383
11389
|
return null;
|
|
11384
11390
|
}
|
|
@@ -12297,6 +12303,12 @@ function createWindow() {
|
|
|
12297
12303
|
mainWindow.webContents.session.setPermissionRequestHandler((_wc, _permission, callback) => {
|
|
12298
12304
|
callback(true);
|
|
12299
12305
|
});
|
|
12306
|
+
mainWindow.webContents.on("did-attach-webview", (_e, contents) => {
|
|
12307
|
+
contents.setWindowOpenHandler(({ url }) => {
|
|
12308
|
+
setImmediate(() => contents.loadURL(url));
|
|
12309
|
+
return { action: "deny" };
|
|
12310
|
+
});
|
|
12311
|
+
});
|
|
12300
12312
|
if (process.env.ELECTRON_RENDERER_URL) {
|
|
12301
12313
|
mainWindow.loadURL(process.env.ELECTRON_RENDERER_URL);
|
|
12302
12314
|
} else {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as createWebWorker, l as languages } from "./index-
|
|
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-
|
|
3
|
-
import { h, i, j, t, k } from "./lspLanguageFeatures-
|
|
1
|
+
import { c as createWebWorker, l as languages } from "./index-MqgBcJzy.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-BYkg2Yc-.js";
|
|
3
|
+
import { h, i, j, t, k } from "./lspLanguageFeatures-BYkg2Yc-.js";
|
|
4
4
|
const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
|
|
5
5
|
class WorkerManager {
|
|
6
6
|
constructor(defaults) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as createWebWorker, l as languages } from "./index-
|
|
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-
|
|
3
|
-
import { a, e, d, R, i, j, t, k } from "./lspLanguageFeatures-
|
|
1
|
+
import { c as createWebWorker, l as languages } from "./index-MqgBcJzy.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-BYkg2Yc-.js";
|
|
3
|
+
import { a, e, d, R, i, j, t, k } from "./lspLanguageFeatures-BYkg2Yc-.js";
|
|
4
4
|
const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
|
|
5
5
|
class WorkerManager {
|
|
6
6
|
constructor(defaults) {
|
|
@@ -7915,13 +7915,88 @@ html, body, #root {
|
|
|
7915
7915
|
width: 100%;
|
|
7916
7916
|
height: 100%;
|
|
7917
7917
|
overflow: hidden;
|
|
7918
|
+
display: flex;
|
|
7919
|
+
flex-direction: column;
|
|
7920
|
+
}
|
|
7921
|
+
|
|
7922
|
+
.ctlsurf-addressbar {
|
|
7923
|
+
flex: 0 0 auto;
|
|
7924
|
+
display: flex;
|
|
7925
|
+
align-items: center;
|
|
7926
|
+
gap: 4px;
|
|
7927
|
+
padding: 5px 6px;
|
|
7928
|
+
background: #1a1b26;
|
|
7929
|
+
border-bottom: 1px solid #2a2b3d;
|
|
7930
|
+
}
|
|
7931
|
+
|
|
7932
|
+
.ctlsurf-nav-btn {
|
|
7933
|
+
flex: 0 0 auto;
|
|
7934
|
+
width: 24px;
|
|
7935
|
+
height: 24px;
|
|
7936
|
+
display: flex;
|
|
7937
|
+
align-items: center;
|
|
7938
|
+
justify-content: center;
|
|
7939
|
+
padding: 0;
|
|
7940
|
+
background: transparent;
|
|
7941
|
+
border: none;
|
|
7942
|
+
border-radius: 4px;
|
|
7943
|
+
color: #a9b1d6;
|
|
7944
|
+
font-size: 16px;
|
|
7945
|
+
line-height: 1;
|
|
7946
|
+
cursor: pointer;
|
|
7947
|
+
}
|
|
7948
|
+
|
|
7949
|
+
.ctlsurf-nav-btn:hover:not(:disabled) {
|
|
7950
|
+
background: #2a2b3d;
|
|
7951
|
+
}
|
|
7952
|
+
|
|
7953
|
+
.ctlsurf-nav-btn:disabled {
|
|
7954
|
+
color: #565f89;
|
|
7955
|
+
opacity: 0.5;
|
|
7956
|
+
cursor: default;
|
|
7957
|
+
}
|
|
7958
|
+
|
|
7959
|
+
.ctlsurf-address-form {
|
|
7960
|
+
flex: 1 1 auto;
|
|
7961
|
+
display: flex;
|
|
7962
|
+
min-width: 0;
|
|
7963
|
+
}
|
|
7964
|
+
|
|
7965
|
+
.ctlsurf-address-input {
|
|
7966
|
+
width: 100%;
|
|
7967
|
+
height: 26px;
|
|
7968
|
+
padding: 0 11px;
|
|
7969
|
+
background: #16161e;
|
|
7970
|
+
border: 1px solid #2a2b3d;
|
|
7971
|
+
border-radius: 13px;
|
|
7972
|
+
color: #c0caf5;
|
|
7973
|
+
font-size: 12px;
|
|
7974
|
+
outline: none;
|
|
7918
7975
|
}
|
|
7919
7976
|
|
|
7920
|
-
.ctlsurf-
|
|
7977
|
+
.ctlsurf-address-input:focus {
|
|
7978
|
+
border-color: #7aa2f7;
|
|
7979
|
+
}
|
|
7980
|
+
|
|
7981
|
+
.ctlsurf-webview-host {
|
|
7982
|
+
flex: 1 1 auto;
|
|
7983
|
+
position: relative;
|
|
7984
|
+
min-height: 0;
|
|
7985
|
+
}
|
|
7986
|
+
|
|
7987
|
+
.ctlsurf-webview-host webview {
|
|
7921
7988
|
width: 100%;
|
|
7922
7989
|
height: 100%;
|
|
7923
7990
|
}
|
|
7924
7991
|
|
|
7992
|
+
.ctlsurf-webview-loading {
|
|
7993
|
+
width: 100%;
|
|
7994
|
+
height: 100%;
|
|
7995
|
+
display: flex;
|
|
7996
|
+
align-items: center;
|
|
7997
|
+
justify-content: center;
|
|
7998
|
+
}
|
|
7999
|
+
|
|
7925
8000
|
/* Status bar */
|
|
7926
8001
|
.statusbar {
|
|
7927
8002
|
height: 24px;
|
|
@@ -9438,24 +9513,57 @@ html, body, #root {
|
|
|
9438
9513
|
.ticket-card {
|
|
9439
9514
|
display: flex;
|
|
9440
9515
|
align-items: stretch;
|
|
9441
|
-
gap: 10px;
|
|
9442
9516
|
background: #15161f;
|
|
9443
9517
|
border: 1px solid #262a3f;
|
|
9444
9518
|
border-radius: 10px;
|
|
9445
|
-
padding: 10px 11px 10px 0;
|
|
9446
|
-
cursor: pointer;
|
|
9447
|
-
text-align: left;
|
|
9448
|
-
font-family: inherit;
|
|
9449
9519
|
overflow: hidden;
|
|
9450
|
-
transition: border-color 0.13s ease, background 0.13s ease
|
|
9520
|
+
transition: border-color 0.13s ease, background 0.13s ease;
|
|
9451
9521
|
}
|
|
9452
9522
|
.ticket-card:hover {
|
|
9453
9523
|
border-color: #3d425f;
|
|
9454
9524
|
background: #181a26;
|
|
9455
9525
|
}
|
|
9456
|
-
|
|
9526
|
+
/* Clickable body of the card — opens the editor. */
|
|
9527
|
+
.ticket-card-open {
|
|
9528
|
+
flex: 1;
|
|
9529
|
+
min-width: 0;
|
|
9530
|
+
display: flex;
|
|
9531
|
+
align-items: stretch;
|
|
9532
|
+
gap: 10px;
|
|
9533
|
+
padding: 10px 11px 10px 0;
|
|
9534
|
+
background: transparent;
|
|
9535
|
+
border: none;
|
|
9536
|
+
color: inherit;
|
|
9537
|
+
cursor: pointer;
|
|
9538
|
+
text-align: left;
|
|
9539
|
+
font-family: inherit;
|
|
9540
|
+
transition: transform 0.06s ease;
|
|
9541
|
+
}
|
|
9542
|
+
.ticket-card-open:active {
|
|
9457
9543
|
transform: scale(0.99);
|
|
9458
9544
|
}
|
|
9545
|
+
/* Trailing button that dispatches the ticket to the coding terminal. */
|
|
9546
|
+
.ticket-card-send {
|
|
9547
|
+
flex-shrink: 0;
|
|
9548
|
+
width: 36px;
|
|
9549
|
+
align-self: stretch;
|
|
9550
|
+
display: flex;
|
|
9551
|
+
align-items: center;
|
|
9552
|
+
justify-content: center;
|
|
9553
|
+
background: transparent;
|
|
9554
|
+
border: none;
|
|
9555
|
+
border-left: 1px solid #262a3f;
|
|
9556
|
+
color: #565f89;
|
|
9557
|
+
cursor: pointer;
|
|
9558
|
+
transition: background 0.13s ease, color 0.13s ease, transform 0.06s ease;
|
|
9559
|
+
}
|
|
9560
|
+
.ticket-card-send:hover {
|
|
9561
|
+
background: #1b2030;
|
|
9562
|
+
color: #7aa2f7;
|
|
9563
|
+
}
|
|
9564
|
+
.ticket-card-send:active {
|
|
9565
|
+
transform: scale(0.9);
|
|
9566
|
+
}
|
|
9459
9567
|
.ticket-card-bar {
|
|
9460
9568
|
width: 3px;
|
|
9461
9569
|
border-radius: 3px;
|