@wrongstack/core 0.305.0 → 0.305.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/dist/chronicle/project-server.js +18 -48
- package/dist/coordination/index.d.ts +1 -0
- package/dist/coordination/index.js +2 -0
- package/dist/coordination/mailbox-project-server.js +28 -57
- package/dist/index.js +23 -1
- package/dist/session-catalog/project-server.js +36 -65
- package/dist/types/config/ui.d.ts +7 -4
- package/dist/types/index.js +21 -1
- package/package.json +3 -3
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
// src/chronicle/project-server.ts
|
|
4
4
|
import { randomBytes } from "node:crypto";
|
|
5
|
-
import * as fs10 from "node:fs";
|
|
6
5
|
import * as fsp4 from "node:fs/promises";
|
|
7
6
|
import * as net from "node:net";
|
|
8
7
|
import * as path15 from "node:path";
|
|
8
|
+
import { bindProjectEndpoint } from "@wrongstack/persistence";
|
|
9
9
|
|
|
10
10
|
// src/utils/atomic-write.ts
|
|
11
11
|
import {
|
|
@@ -2923,13 +2923,6 @@ import * as fs7 from "node:fs";
|
|
|
2923
2923
|
import { createRequire } from "node:module";
|
|
2924
2924
|
import * as path12 from "node:path";
|
|
2925
2925
|
|
|
2926
|
-
// src/utils/socket-path.ts
|
|
2927
|
-
import {
|
|
2928
|
-
assertUnixSocketPathWithinLimit,
|
|
2929
|
-
checkUnixSocketPath,
|
|
2930
|
-
unixSocketPathLimit
|
|
2931
|
-
} from "@wrongstack/persistence";
|
|
2932
|
-
|
|
2933
2926
|
// src/chronicle/sqlite-query.ts
|
|
2934
2927
|
var MAX_LIMIT = 1e4;
|
|
2935
2928
|
function encodeCursor2(cursor) {
|
|
@@ -4766,7 +4759,6 @@ function normalizePathKey(value) {
|
|
|
4766
4759
|
|
|
4767
4760
|
// src/chronicle/project-server-endpoint.ts
|
|
4768
4761
|
import { createHash as createHash5 } from "node:crypto";
|
|
4769
|
-
import * as fs9 from "node:fs";
|
|
4770
4762
|
import * as os3 from "node:os";
|
|
4771
4763
|
import * as path14 from "node:path";
|
|
4772
4764
|
|
|
@@ -4802,12 +4794,6 @@ function chronicleProjectServerEndpoint(projectDir) {
|
|
|
4802
4794
|
function chronicleProjectServerMetadataPath(projectDir) {
|
|
4803
4795
|
return path14.join(projectDir, "chronicle", CHRONICLE_PROJECT_SERVER_METADATA_FILE);
|
|
4804
4796
|
}
|
|
4805
|
-
function ensureChronicleProjectServerSocketDirectory(endpoint2) {
|
|
4806
|
-
if (process.platform !== "win32") {
|
|
4807
|
-
assertUnixSocketPathWithinLimit(endpoint2, "chronicle");
|
|
4808
|
-
fs9.mkdirSync(path14.dirname(endpoint2), { recursive: true, mode: 448 });
|
|
4809
|
-
}
|
|
4810
|
-
}
|
|
4811
4797
|
|
|
4812
4798
|
// src/chronicle/project-server.ts
|
|
4813
4799
|
var DEFAULT_IDLE_MS = 5 * 6e4;
|
|
@@ -5264,7 +5250,6 @@ async function stop(_reason) {
|
|
|
5264
5250
|
});
|
|
5265
5251
|
await stopMemoryWatchdog();
|
|
5266
5252
|
}
|
|
5267
|
-
ensureChronicleProjectServerSocketDirectory(endpoint);
|
|
5268
5253
|
var server = net.createServer((socket) => {
|
|
5269
5254
|
if (stopping) {
|
|
5270
5255
|
socket.destroy();
|
|
@@ -5284,42 +5269,28 @@ var server = net.createServer((socket) => {
|
|
|
5284
5269
|
scheduleIdleStop();
|
|
5285
5270
|
});
|
|
5286
5271
|
});
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
}
|
|
5291
|
-
server.on("error", (error) => {
|
|
5292
|
-
if (error.code === "EADDRINUSE" && process.platform === "win32") {
|
|
5272
|
+
void (async () => {
|
|
5273
|
+
const bind = await bindProjectEndpoint({ server, endpoint, service: "chronicle" });
|
|
5274
|
+
if (bind.outcome === "already-owned") {
|
|
5293
5275
|
process.exitCode = 0;
|
|
5294
5276
|
return;
|
|
5295
5277
|
}
|
|
5296
|
-
if (
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
probe.destroy();
|
|
5301
|
-
process.exitCode = 0;
|
|
5302
|
-
});
|
|
5303
|
-
probe.once("error", () => {
|
|
5304
|
-
probe.destroy();
|
|
5305
|
-
try {
|
|
5306
|
-
fs10.rmSync(endpoint, { force: true });
|
|
5307
|
-
} catch {
|
|
5308
|
-
}
|
|
5309
|
-
probingExistingEndpoint = false;
|
|
5310
|
-
listenForOwnership();
|
|
5311
|
-
});
|
|
5278
|
+
if (bind.outcome === "failed") {
|
|
5279
|
+
process.stderr.write(`chronicle project server failed: ${bind.error.message}
|
|
5280
|
+
`);
|
|
5281
|
+
process.exitCode = 1;
|
|
5312
5282
|
return;
|
|
5313
5283
|
}
|
|
5314
|
-
|
|
5315
|
-
}
|
|
5316
|
-
|
|
5317
|
-
if (process.platform !== "win32") {
|
|
5318
|
-
try {
|
|
5319
|
-
fs10.chmodSync(endpoint, 384);
|
|
5320
|
-
} catch {
|
|
5321
|
-
}
|
|
5284
|
+
if (bind.reclaimedStaleEndpoint) {
|
|
5285
|
+
process.stderr.write(`chronicle project server reclaimed stale endpoint ${endpoint}
|
|
5286
|
+
`);
|
|
5322
5287
|
}
|
|
5288
|
+
server.on("error", (error) => {
|
|
5289
|
+
if (stopping) return;
|
|
5290
|
+
process.stderr.write(`chronicle project server error: ${error.message}
|
|
5291
|
+
`);
|
|
5292
|
+
process.exitCode = 1;
|
|
5293
|
+
});
|
|
5323
5294
|
void writeMetadata().then(() => markMetadataWritten?.());
|
|
5324
5295
|
void startChronicleFileObserver({
|
|
5325
5296
|
projectRoot: parsed.projectRoot,
|
|
@@ -5337,8 +5308,7 @@ server.on("listening", () => {
|
|
|
5337
5308
|
watcherLastError = error instanceof Error ? error.message : String(error);
|
|
5338
5309
|
});
|
|
5339
5310
|
scheduleIdleStop();
|
|
5340
|
-
});
|
|
5311
|
+
})();
|
|
5341
5312
|
process.once("SIGINT", () => void stop("SIGINT"));
|
|
5342
5313
|
process.once("SIGTERM", () => void stop("SIGTERM"));
|
|
5343
|
-
listenForOwnership();
|
|
5344
5314
|
//# sourceMappingURL=project-server.js.map
|
|
@@ -34,6 +34,7 @@ export type { MailboxCredentialVerifier, RedactedMailboxCredential, } from './ma
|
|
|
34
34
|
export { redactMailboxCredential } from './mailbox-credential-store.js';
|
|
35
35
|
export { CREDENTIAL_VERIFY_COOLDOWN_MS, CREDENTIAL_VERIFY_MAX_FAILURES, CREDENTIAL_VERIFY_WINDOW_MS, CredentialVerifyThrottle, credentialVerifyThrottle, } from './mailbox-credential-throttle.js';
|
|
36
36
|
export { MailboxEventEmitter } from './mailbox-events.js';
|
|
37
|
+
export { mailboxProjectServerEndpoint, mailboxProjectServerMetadataPath, } from './mailbox-project-server-endpoint.js';
|
|
37
38
|
export { buildDownAlert, buildRecoveryAlert, type DownAlertInput, MAILBOX_HEALTH_DEFAULT_FAILURE_THRESHOLD, MAILBOX_HEALTH_DEFAULT_FROM, MAILBOX_HEALTH_DEFAULT_INTERVAL_MS, MAILBOX_HEALTH_DEFAULT_TIMEOUT_MS, type MailboxHealthEvent, MailboxHealthWatchdog, type MailboxHealthWatchdogOptions, type RecoveryAlertInput, validateWatchdogOptions, type WatchdogConfig, } from './mailbox-health.js';
|
|
38
39
|
export { createMailboxHooks, type MailboxHooksOptions, } from './mailbox-hooks.js';
|
|
39
40
|
export { authorizeMailboxBearerToken, authorizePersistedMailboxCredential, createMailboxHttpRouter, MAILBOX_HTTP_DEFAULT_MAX_AGE_MS, MAILBOX_HTTP_MAX_AGE_CEILING_MS, MAILBOX_HTTP_MAX_BODY_BYTES, MAILBOX_HTTP_RATE_LIMIT_PER_MINUTE, MAILBOX_HTTP_RATE_LIMIT_WINDOW_MS, type MailboxHttpAccessDecision, MailboxHttpRateLimiter, type MailboxHttpRouter, type MailboxHttpRouterOptions, } from './mailbox-http-router.js';
|
|
@@ -31042,6 +31042,8 @@ export {
|
|
|
31042
31042
|
loadRoleKnowledgeManifest,
|
|
31043
31043
|
loadSkillAffinity,
|
|
31044
31044
|
mailboxIdentityBase,
|
|
31045
|
+
mailboxProjectServerEndpoint,
|
|
31046
|
+
mailboxProjectServerMetadataPath,
|
|
31045
31047
|
mailboxSessionTag,
|
|
31046
31048
|
makeAgentSubagentRunner,
|
|
31047
31049
|
makeAskResultTool,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
// src/coordination/mailbox-project-server.ts
|
|
4
4
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
5
|
-
import * as fs5 from "node:fs";
|
|
6
5
|
import * as fsPromises from "node:fs/promises";
|
|
7
6
|
import * as net from "node:net";
|
|
8
7
|
import * as path7 from "node:path";
|
|
8
|
+
import { bindProjectEndpoint } from "@wrongstack/persistence";
|
|
9
9
|
|
|
10
10
|
// src/kernel/events.ts
|
|
11
11
|
var MAX_WILDCARDS = 500;
|
|
@@ -1173,17 +1173,9 @@ var MailboxEventEmitter = class {
|
|
|
1173
1173
|
|
|
1174
1174
|
// src/coordination/mailbox-project-server-endpoint.ts
|
|
1175
1175
|
import { createHash as createHash2 } from "node:crypto";
|
|
1176
|
-
import * as fs2 from "node:fs";
|
|
1177
1176
|
import * as os2 from "node:os";
|
|
1178
1177
|
import * as path4 from "node:path";
|
|
1179
1178
|
|
|
1180
|
-
// src/utils/socket-path.ts
|
|
1181
|
-
import {
|
|
1182
|
-
assertUnixSocketPathWithinLimit,
|
|
1183
|
-
checkUnixSocketPath,
|
|
1184
|
-
unixSocketPathLimit
|
|
1185
|
-
} from "@wrongstack/persistence";
|
|
1186
|
-
|
|
1187
1179
|
// src/coordination/mailbox-project-server-protocol.ts
|
|
1188
1180
|
var MAILBOX_PROJECT_SERVER_PROTOCOL_VERSION = 4;
|
|
1189
1181
|
var MAILBOX_PROJECT_SERVER_MAX_FRAME_CHARS = 16 * 1024 * 1024;
|
|
@@ -1317,16 +1309,10 @@ function mailboxProjectServerEndpoint(projectDir2) {
|
|
|
1317
1309
|
function mailboxProjectServerMetadataPath(projectDir2) {
|
|
1318
1310
|
return path4.join(path4.resolve(projectDir2), MAILBOX_PROJECT_SERVER_METADATA_FILE);
|
|
1319
1311
|
}
|
|
1320
|
-
function ensureMailboxProjectServerSocketDirectory(endpoint2) {
|
|
1321
|
-
if (process.platform !== "win32") {
|
|
1322
|
-
assertUnixSocketPathWithinLimit(endpoint2, "mailbox");
|
|
1323
|
-
fs2.mkdirSync(path4.dirname(endpoint2), { recursive: true, mode: 448 });
|
|
1324
|
-
}
|
|
1325
|
-
}
|
|
1326
1312
|
|
|
1327
1313
|
// src/coordination/sqlite-mailbox.ts
|
|
1328
1314
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
1329
|
-
import * as
|
|
1315
|
+
import * as fs3 from "node:fs";
|
|
1330
1316
|
import * as path6 from "node:path";
|
|
1331
1317
|
|
|
1332
1318
|
// src/coordination/global-mailbox-completion.ts
|
|
@@ -2218,7 +2204,7 @@ function credentialRotate(db, transaction, credentialId, options) {
|
|
|
2218
2204
|
}
|
|
2219
2205
|
|
|
2220
2206
|
// src/coordination/sqlite-mailbox-schema.ts
|
|
2221
|
-
import * as
|
|
2207
|
+
import * as fs2 from "node:fs";
|
|
2222
2208
|
import { createRequire } from "node:module";
|
|
2223
2209
|
import * as path5 from "node:path";
|
|
2224
2210
|
|
|
@@ -2473,7 +2459,7 @@ function migrateLegacyCredentials(ctx) {
|
|
|
2473
2459
|
const legacyPath = path5.join(ctx.projectDir, CREDENTIAL_STORE_FILE);
|
|
2474
2460
|
const credentials = [];
|
|
2475
2461
|
try {
|
|
2476
|
-
for (const line of
|
|
2462
|
+
for (const line of fs2.readFileSync(legacyPath, "utf8").split(/\r?\n/u)) {
|
|
2477
2463
|
if (!line.trim()) continue;
|
|
2478
2464
|
try {
|
|
2479
2465
|
const credential = JSON.parse(line);
|
|
@@ -2526,7 +2512,7 @@ function migrateLegacyFiles(ctx) {
|
|
|
2526
2512
|
function readLegacyMessages(projectDir2) {
|
|
2527
2513
|
try {
|
|
2528
2514
|
return parseMailboxFile(
|
|
2529
|
-
|
|
2515
|
+
fs2.readFileSync(path5.join(projectDir2, GLOBAL_MAILBOX_FILE), "utf8")
|
|
2530
2516
|
);
|
|
2531
2517
|
} catch (error) {
|
|
2532
2518
|
if (error.code === "ENOENT") return [];
|
|
@@ -2535,7 +2521,7 @@ function readLegacyMessages(projectDir2) {
|
|
|
2535
2521
|
}
|
|
2536
2522
|
function readLegacyRegistry(filePath, parseEntry) {
|
|
2537
2523
|
try {
|
|
2538
|
-
const raw = JSON.parse(
|
|
2524
|
+
const raw = JSON.parse(fs2.readFileSync(filePath, "utf8"));
|
|
2539
2525
|
const result = /* @__PURE__ */ new Map();
|
|
2540
2526
|
for (const [id, value] of Object.entries(raw)) {
|
|
2541
2527
|
const parsed = parseEntry(value);
|
|
@@ -2555,7 +2541,7 @@ var HEARTBEAT_TRACKING_TTL_MS = 30 * 6e4;
|
|
|
2555
2541
|
var SqliteMailbox = class {
|
|
2556
2542
|
constructor(projectDir2, events2, eventEmitter2) {
|
|
2557
2543
|
this.projectDir = projectDir2;
|
|
2558
|
-
|
|
2544
|
+
fs3.mkdirSync(projectDir2, { recursive: true });
|
|
2559
2545
|
this.databasePath = path6.join(projectDir2, SQLITE_MAILBOX_FILE);
|
|
2560
2546
|
this.messagePath = this.databasePath;
|
|
2561
2547
|
this.events = events2;
|
|
@@ -3451,7 +3437,6 @@ async function stop(_reason) {
|
|
|
3451
3437
|
}
|
|
3452
3438
|
await stopMemoryWatchdog();
|
|
3453
3439
|
}
|
|
3454
|
-
ensureMailboxProjectServerSocketDirectory(endpoint);
|
|
3455
3440
|
var server = net.createServer((socket) => {
|
|
3456
3441
|
if (stopping) {
|
|
3457
3442
|
socket.destroy();
|
|
@@ -3481,42 +3466,28 @@ var leaseSweep = setInterval(() => {
|
|
|
3481
3466
|
scheduleIdleStop();
|
|
3482
3467
|
}, leaseSweepMs);
|
|
3483
3468
|
leaseSweep.unref?.();
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
}
|
|
3488
|
-
server.on("error", (error) => {
|
|
3489
|
-
if (error.code === "EADDRINUSE" && process.platform === "win32") {
|
|
3469
|
+
void (async () => {
|
|
3470
|
+
const bind = await bindProjectEndpoint({ server, endpoint, service: "mailbox" });
|
|
3471
|
+
if (bind.outcome === "already-owned") {
|
|
3490
3472
|
process.exitCode = 0;
|
|
3491
3473
|
return;
|
|
3492
3474
|
}
|
|
3493
|
-
if (
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
probe.destroy();
|
|
3498
|
-
process.exitCode = 0;
|
|
3499
|
-
});
|
|
3500
|
-
probe.once("error", () => {
|
|
3501
|
-
probe.destroy();
|
|
3502
|
-
try {
|
|
3503
|
-
fs5.rmSync(endpoint, { force: true });
|
|
3504
|
-
} catch {
|
|
3505
|
-
}
|
|
3506
|
-
probingExistingEndpoint = false;
|
|
3507
|
-
listenForOwnership();
|
|
3508
|
-
});
|
|
3475
|
+
if (bind.outcome === "failed") {
|
|
3476
|
+
process.stderr.write(`mailbox project server failed: ${bind.error.message}
|
|
3477
|
+
`);
|
|
3478
|
+
process.exitCode = 1;
|
|
3509
3479
|
return;
|
|
3510
3480
|
}
|
|
3511
|
-
|
|
3512
|
-
}
|
|
3513
|
-
|
|
3514
|
-
if (process.platform !== "win32") {
|
|
3515
|
-
try {
|
|
3516
|
-
fs5.chmodSync(endpoint, 384);
|
|
3517
|
-
} catch {
|
|
3518
|
-
}
|
|
3481
|
+
if (bind.reclaimedStaleEndpoint) {
|
|
3482
|
+
process.stderr.write(`mailbox project server reclaimed stale endpoint ${endpoint}
|
|
3483
|
+
`);
|
|
3519
3484
|
}
|
|
3485
|
+
server.on("error", (error) => {
|
|
3486
|
+
if (stopping) return;
|
|
3487
|
+
process.stderr.write(`mailbox project server error: ${error.message}
|
|
3488
|
+
`);
|
|
3489
|
+
process.exitCode = 1;
|
|
3490
|
+
});
|
|
3520
3491
|
try {
|
|
3521
3492
|
mailbox = new SqliteMailbox(projectDir, events, eventEmitter);
|
|
3522
3493
|
} catch {
|
|
@@ -3526,16 +3497,16 @@ server.on("listening", () => {
|
|
|
3526
3497
|
return;
|
|
3527
3498
|
}
|
|
3528
3499
|
stopAutoCompact = mailbox.startAutoCompactTimer();
|
|
3529
|
-
|
|
3500
|
+
try {
|
|
3501
|
+
await writeMetadata();
|
|
3530
3502
|
markMetadataWritten?.();
|
|
3531
3503
|
scheduleIdleStop();
|
|
3532
|
-
}
|
|
3504
|
+
} catch {
|
|
3533
3505
|
void stop("metadata-write-failed").finally(() => {
|
|
3534
3506
|
process.exitCode = 1;
|
|
3535
3507
|
});
|
|
3536
|
-
}
|
|
3537
|
-
});
|
|
3538
|
-
listenForOwnership();
|
|
3508
|
+
}
|
|
3509
|
+
})();
|
|
3539
3510
|
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
3540
3511
|
process.once(signal, () => {
|
|
3541
3512
|
void stop(signal).finally(() => {
|
package/dist/index.js
CHANGED
|
@@ -3524,7 +3524,27 @@ var THEME_PRESET_IDS = [
|
|
|
3524
3524
|
"ayu-dark",
|
|
3525
3525
|
"everforest",
|
|
3526
3526
|
"night-owl",
|
|
3527
|
-
"synthwave"
|
|
3527
|
+
"synthwave",
|
|
3528
|
+
"github-dark",
|
|
3529
|
+
"material-ocean",
|
|
3530
|
+
"nightfox",
|
|
3531
|
+
"oxocarbon",
|
|
3532
|
+
"catppuccin-macchiato",
|
|
3533
|
+
"catppuccin-frappe",
|
|
3534
|
+
"gruvbox-material",
|
|
3535
|
+
"tokyo-night-storm",
|
|
3536
|
+
"rose-pine-moon",
|
|
3537
|
+
"zenburn",
|
|
3538
|
+
"palenight",
|
|
3539
|
+
"horizon",
|
|
3540
|
+
"sonokai",
|
|
3541
|
+
"edge-dark",
|
|
3542
|
+
"moonfly",
|
|
3543
|
+
"melange",
|
|
3544
|
+
"poimandres",
|
|
3545
|
+
"vitesse-dark",
|
|
3546
|
+
"aura",
|
|
3547
|
+
"dark-plus"
|
|
3528
3548
|
];
|
|
3529
3549
|
|
|
3530
3550
|
// src/types/default-config.ts
|
|
@@ -96346,6 +96366,8 @@ export {
|
|
|
96346
96366
|
logHqAuthAudit,
|
|
96347
96367
|
logicalCalendarTarget,
|
|
96348
96368
|
mailboxIdentityBase,
|
|
96369
|
+
mailboxProjectServerEndpoint,
|
|
96370
|
+
mailboxProjectServerMetadataPath,
|
|
96349
96371
|
mailboxSessionTag,
|
|
96350
96372
|
makeAgentSubagentRunner,
|
|
96351
96373
|
makeAskResultTool,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
// src/session-catalog/project-server.ts
|
|
4
4
|
import { randomBytes as randomBytes2, randomUUID as randomUUID2 } from "node:crypto";
|
|
5
|
-
import * as fs3 from "node:fs";
|
|
6
5
|
import * as fsp from "node:fs/promises";
|
|
7
6
|
import * as net from "node:net";
|
|
8
7
|
import * as path3 from "node:path";
|
|
8
|
+
import { bindProjectEndpoint } from "@wrongstack/persistence";
|
|
9
9
|
|
|
10
10
|
// src/security/file-permissions.ts
|
|
11
11
|
import { chmod } from "node:fs/promises";
|
|
@@ -177,17 +177,9 @@ function useDaemonPerfDefaults() {
|
|
|
177
177
|
|
|
178
178
|
// src/session-catalog/endpoint.ts
|
|
179
179
|
import { createHash } from "node:crypto";
|
|
180
|
-
import * as fs from "node:fs";
|
|
181
180
|
import * as os from "node:os";
|
|
182
181
|
import * as path from "node:path";
|
|
183
182
|
|
|
184
|
-
// src/utils/socket-path.ts
|
|
185
|
-
import {
|
|
186
|
-
assertUnixSocketPathWithinLimit,
|
|
187
|
-
checkUnixSocketPath,
|
|
188
|
-
unixSocketPathLimit
|
|
189
|
-
} from "@wrongstack/persistence";
|
|
190
|
-
|
|
191
183
|
// src/session-catalog/protocol.ts
|
|
192
184
|
var SESSION_CATALOG_PROTOCOL_VERSION = 1;
|
|
193
185
|
var SESSION_CATALOG_MAX_FRAME_CHARS = 4 * 1024 * 1024;
|
|
@@ -218,15 +210,10 @@ function sessionCatalogProjectServerEndpoint(projectDir) {
|
|
|
218
210
|
function sessionCatalogProjectServerMetadataPath(projectDir) {
|
|
219
211
|
return path.join(projectDir, SESSION_CATALOG_METADATA_FILE);
|
|
220
212
|
}
|
|
221
|
-
function ensureSessionCatalogSocketDirectory(endpoint2) {
|
|
222
|
-
if (process.platform === "win32") return;
|
|
223
|
-
assertUnixSocketPathWithinLimit(endpoint2, "session-catalog");
|
|
224
|
-
fs.mkdirSync(path.dirname(endpoint2), { recursive: true, mode: 448 });
|
|
225
|
-
}
|
|
226
213
|
|
|
227
214
|
// src/session-catalog/store.ts
|
|
228
215
|
import { createHash as createHash2, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
229
|
-
import * as
|
|
216
|
+
import * as fs from "node:fs";
|
|
230
217
|
import * as path2 from "node:path";
|
|
231
218
|
|
|
232
219
|
// src/coordination/sqlite-mailbox-schema.ts
|
|
@@ -632,7 +619,7 @@ var SessionCatalogStore = class {
|
|
|
632
619
|
constructor(projectDir) {
|
|
633
620
|
this.projectDir = projectDir;
|
|
634
621
|
this.sessionsDir = path2.join(projectDir, "sessions");
|
|
635
|
-
|
|
622
|
+
fs.mkdirSync(this.sessionsDir, { recursive: true, mode: 448 });
|
|
636
623
|
this.databasePath = path2.join(this.sessionsDir, "catalog.sqlite");
|
|
637
624
|
const Database = loadDatabaseSync();
|
|
638
625
|
this.db = new Database(this.databasePath);
|
|
@@ -650,12 +637,12 @@ var SessionCatalogStore = class {
|
|
|
650
637
|
this.db.close();
|
|
651
638
|
const quarantine = `${this.databasePath}.corrupt-${Date.now()}`;
|
|
652
639
|
try {
|
|
653
|
-
|
|
640
|
+
fs.renameSync(this.databasePath, quarantine);
|
|
654
641
|
} catch {
|
|
655
642
|
}
|
|
656
643
|
for (const suffix of ["-wal", "-shm"]) {
|
|
657
644
|
try {
|
|
658
|
-
|
|
645
|
+
fs.renameSync(`${this.databasePath}${suffix}`, `${quarantine}${suffix}`);
|
|
659
646
|
} catch {
|
|
660
647
|
}
|
|
661
648
|
}
|
|
@@ -881,7 +868,7 @@ var SessionCatalogStore = class {
|
|
|
881
868
|
if (this.maintenanceExists(targetSessionId))
|
|
882
869
|
throw conflict(`Session ${targetSessionId} is under maintenance`);
|
|
883
870
|
const catalog = this.db.prepare("SELECT 1 AS yes FROM sessions WHERE session_id=?").get(targetSessionId);
|
|
884
|
-
if (!catalog && !
|
|
871
|
+
if (!catalog && !fs.existsSync(this.containedPath(`${targetSessionId}.jsonl`)))
|
|
885
872
|
throw new Error(`Session not found: ${targetSessionId}`);
|
|
886
873
|
const reservationId = randomUUID();
|
|
887
874
|
const now = Date.now();
|
|
@@ -1027,7 +1014,7 @@ var SessionCatalogStore = class {
|
|
|
1027
1014
|
transcriptRelativePath = normalizedTranscript;
|
|
1028
1015
|
summaryRelativePath = normalizedSummary;
|
|
1029
1016
|
const transcript = this.containedPath(transcriptRelativePath);
|
|
1030
|
-
const stat =
|
|
1017
|
+
const stat = fs.existsSync(transcript) ? fs.statSync(transcript) : void 0;
|
|
1031
1018
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1032
1019
|
return this.transaction(() => {
|
|
1033
1020
|
const prior = this.db.prepare("SELECT summary_revision FROM sessions WHERE session_id=?").get(summary.id);
|
|
@@ -1150,7 +1137,7 @@ var SessionCatalogStore = class {
|
|
|
1150
1137
|
if (trimmed) summary.name = this.scrubber.scrub(trimmed).slice(0, 500);
|
|
1151
1138
|
else delete summary.name;
|
|
1152
1139
|
const summaryPath = this.containedPath(current.summaryRelativePath);
|
|
1153
|
-
|
|
1140
|
+
fs.mkdirSync(path2.dirname(summaryPath), { recursive: true, mode: 448 });
|
|
1154
1141
|
await atomicWrite(summaryPath, `${JSON.stringify(summary)}
|
|
1155
1142
|
`, { mode: 384 });
|
|
1156
1143
|
try {
|
|
@@ -1213,13 +1200,13 @@ var SessionCatalogStore = class {
|
|
|
1213
1200
|
path2.join(path2.dirname(transcript), path2.basename(sessionId))
|
|
1214
1201
|
];
|
|
1215
1202
|
const trashRoot = path2.join(this.sessionsDir, "_trash", lease.leaseId);
|
|
1216
|
-
|
|
1203
|
+
fs.mkdirSync(trashRoot, { recursive: true, mode: 448 });
|
|
1217
1204
|
const moved = [];
|
|
1218
1205
|
try {
|
|
1219
1206
|
artifacts.forEach((artifact, index) => {
|
|
1220
|
-
if (!
|
|
1207
|
+
if (!fs.existsSync(artifact)) return;
|
|
1221
1208
|
const target = path2.join(trashRoot, `${index}-${path2.basename(artifact)}`);
|
|
1222
|
-
|
|
1209
|
+
fs.renameSync(artifact, target);
|
|
1223
1210
|
moved.push({ from: artifact, to: target });
|
|
1224
1211
|
});
|
|
1225
1212
|
this.transaction(() => {
|
|
@@ -1234,17 +1221,17 @@ var SessionCatalogStore = class {
|
|
|
1234
1221
|
} catch (error) {
|
|
1235
1222
|
for (const item of moved.reverse()) {
|
|
1236
1223
|
try {
|
|
1237
|
-
|
|
1238
|
-
|
|
1224
|
+
fs.mkdirSync(path2.dirname(item.from), { recursive: true, mode: 448 });
|
|
1225
|
+
fs.renameSync(item.to, item.from);
|
|
1239
1226
|
} catch {
|
|
1240
1227
|
}
|
|
1241
1228
|
}
|
|
1242
1229
|
throw error;
|
|
1243
1230
|
}
|
|
1244
1231
|
try {
|
|
1245
|
-
|
|
1232
|
+
fs.rmSync(trashRoot, { recursive: true, force: true });
|
|
1246
1233
|
const trashParent = path2.dirname(trashRoot);
|
|
1247
|
-
if (
|
|
1234
|
+
if (fs.readdirSync(trashParent).length === 0) fs.rmdirSync(trashParent);
|
|
1248
1235
|
} catch {
|
|
1249
1236
|
}
|
|
1250
1237
|
}
|
|
@@ -1281,10 +1268,10 @@ var SessionCatalogStore = class {
|
|
|
1281
1268
|
for (const id of ids) {
|
|
1282
1269
|
try {
|
|
1283
1270
|
const summaryFile = this.containedPath(`${id}.summary.json`);
|
|
1284
|
-
const summary =
|
|
1271
|
+
const summary = fs.existsSync(summaryFile) ? parseJson(fs.readFileSync(summaryFile, "utf8")) : this.summarizeTranscript(id);
|
|
1285
1272
|
if (!summary || summary.id !== id) throw new Error("summary identity mismatch");
|
|
1286
1273
|
const transcript = this.containedPath(`${id}.jsonl`);
|
|
1287
|
-
const stat =
|
|
1274
|
+
const stat = fs.existsSync(transcript) ? fs.statSync(transcript) : void 0;
|
|
1288
1275
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1289
1276
|
this.db.prepare(
|
|
1290
1277
|
"INSERT INTO sessions(session_id,transcript_relative_path,summary_relative_path,summary_json,transcript_size,transcript_mtime_ms,summary_revision,indexed_at,damaged) VALUES (?,?,?,?,?,?,?,?,0)"
|
|
@@ -1325,7 +1312,7 @@ var SessionCatalogStore = class {
|
|
|
1325
1312
|
walkFiles(root, suffix) {
|
|
1326
1313
|
const result = [];
|
|
1327
1314
|
const visit = (dir) => {
|
|
1328
|
-
for (const entry of
|
|
1315
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
1329
1316
|
if (entry.isDirectory()) {
|
|
1330
1317
|
if (entry.name !== "_cas" && entry.name !== "_trash") visit(path2.join(dir, entry.name));
|
|
1331
1318
|
} else if (entry.isFile() && entry.name.endsWith(suffix))
|
|
@@ -1337,7 +1324,7 @@ var SessionCatalogStore = class {
|
|
|
1337
1324
|
}
|
|
1338
1325
|
summarizeTranscript(id) {
|
|
1339
1326
|
const file = this.containedPath(`${id}.jsonl`);
|
|
1340
|
-
const lines =
|
|
1327
|
+
const lines = fs.readFileSync(file, "utf8").split(/\r?\n/);
|
|
1341
1328
|
let start;
|
|
1342
1329
|
let endedAt;
|
|
1343
1330
|
let lastActivityAt;
|
|
@@ -1846,7 +1833,6 @@ async function stop(_reason) {
|
|
|
1846
1833
|
if (process.platform !== "win32") await fsp.rm(endpoint, { force: true }).catch(() => void 0);
|
|
1847
1834
|
await removeOwnedMetadata();
|
|
1848
1835
|
}
|
|
1849
|
-
ensureSessionCatalogSocketDirectory(endpoint);
|
|
1850
1836
|
var server = net.createServer((socket) => {
|
|
1851
1837
|
if (stopping) {
|
|
1852
1838
|
socket.destroy();
|
|
@@ -1870,42 +1856,28 @@ var server = net.createServer((socket) => {
|
|
|
1870
1856
|
scheduleIdleStop(disconnectedIdleMs);
|
|
1871
1857
|
});
|
|
1872
1858
|
});
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
}
|
|
1877
|
-
server.on("error", (error) => {
|
|
1878
|
-
if (error.code === "EADDRINUSE" && process.platform === "win32") {
|
|
1859
|
+
void (async () => {
|
|
1860
|
+
const bind = await bindProjectEndpoint({ server, endpoint, service: "session-catalog" });
|
|
1861
|
+
if (bind.outcome === "already-owned") {
|
|
1879
1862
|
process.exitCode = 0;
|
|
1880
1863
|
return;
|
|
1881
1864
|
}
|
|
1882
|
-
if (
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
probe.destroy();
|
|
1887
|
-
process.exitCode = 0;
|
|
1888
|
-
});
|
|
1889
|
-
probe.once("error", () => {
|
|
1890
|
-
probe.destroy();
|
|
1891
|
-
try {
|
|
1892
|
-
fs3.rmSync(endpoint, { force: true });
|
|
1893
|
-
} catch {
|
|
1894
|
-
}
|
|
1895
|
-
probing = false;
|
|
1896
|
-
listen();
|
|
1897
|
-
});
|
|
1865
|
+
if (bind.outcome === "failed") {
|
|
1866
|
+
process.stderr.write(`session-catalog project server failed: ${bind.error.message}
|
|
1867
|
+
`);
|
|
1868
|
+
process.exitCode = 1;
|
|
1898
1869
|
return;
|
|
1899
1870
|
}
|
|
1900
|
-
|
|
1901
|
-
}
|
|
1902
|
-
|
|
1903
|
-
if (process.platform !== "win32") {
|
|
1904
|
-
try {
|
|
1905
|
-
fs3.chmodSync(endpoint, 384);
|
|
1906
|
-
} catch {
|
|
1907
|
-
}
|
|
1871
|
+
if (bind.reclaimedStaleEndpoint) {
|
|
1872
|
+
process.stderr.write(`session-catalog project server reclaimed stale endpoint ${endpoint}
|
|
1873
|
+
`);
|
|
1908
1874
|
}
|
|
1875
|
+
server.on("error", (error) => {
|
|
1876
|
+
if (stopping) return;
|
|
1877
|
+
process.stderr.write(`session-catalog project server error: ${error.message}
|
|
1878
|
+
`);
|
|
1879
|
+
process.exitCode = 1;
|
|
1880
|
+
});
|
|
1909
1881
|
try {
|
|
1910
1882
|
store = new SessionCatalogStore(parsed.projectDir);
|
|
1911
1883
|
void writeMetadata().then(() => metadataReadyResolve?.()).catch(() => void stop("metadata write failed"));
|
|
@@ -1914,8 +1886,7 @@ server.on("listening", () => {
|
|
|
1914
1886
|
return;
|
|
1915
1887
|
}
|
|
1916
1888
|
scheduleIdleStop();
|
|
1917
|
-
});
|
|
1889
|
+
})();
|
|
1918
1890
|
process.once("SIGINT", () => void stop("SIGINT"));
|
|
1919
1891
|
process.once("SIGTERM", () => void stop("SIGTERM"));
|
|
1920
|
-
listen();
|
|
1921
1892
|
//# sourceMappingURL=project-server.js.map
|
|
@@ -5,10 +5,13 @@
|
|
|
5
5
|
* the TUI runtime can all reference the same string union without
|
|
6
6
|
* importing the TUI package (which would invert the dependency direction).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* This array is the CANONICAL list. The CLI `/theme` command and the boot
|
|
9
|
+
* theme adapter both derive their valid-id sets from it, so adding an entry
|
|
10
|
+
* here needs exactly ONE follow-up: a matching palette + `THEME_OPTIONS` row
|
|
11
|
+
* in `packages/tui/src/theme.ts`. Both are compile-enforced — `themePresets`
|
|
12
|
+
* is typed `Record<ThemePresetId, Theme>` (no cast) and the CLI's `THEME_META`
|
|
13
|
+
* is a total record — so a missing preset fails `tsc`, not the runtime.
|
|
11
14
|
*/
|
|
12
|
-
export declare const THEME_PRESET_IDS: readonly ['catppuccin', 'tokyo-night', 'nord', 'cyberpunk', 'dracula', 'gruvbox-dark', 'solarized-dark', 'one-dark', 'monokai', 'rose-pine', 'kanagawa', 'ayu-dark', 'everforest', 'night-owl', 'synthwave'];
|
|
15
|
+
export declare const THEME_PRESET_IDS: readonly ['catppuccin', 'tokyo-night', 'nord', 'cyberpunk', 'dracula', 'gruvbox-dark', 'solarized-dark', 'one-dark', 'monokai', 'rose-pine', 'kanagawa', 'ayu-dark', 'everforest', 'night-owl', 'synthwave', 'github-dark', 'material-ocean', 'nightfox', 'oxocarbon', 'catppuccin-macchiato', 'catppuccin-frappe', 'gruvbox-material', 'tokyo-night-storm', 'rose-pine-moon', 'zenburn', 'palenight', 'horizon', 'sonokai', 'edge-dark', 'moonfly', 'melange', 'poimandres', 'vitesse-dark', 'aura', 'dark-plus'];
|
|
13
16
|
export type ThemePresetId = (typeof THEME_PRESET_IDS)[number];
|
|
14
17
|
//# sourceMappingURL=ui.d.ts.map
|
package/dist/types/index.js
CHANGED
|
@@ -591,7 +591,27 @@ var THEME_PRESET_IDS = [
|
|
|
591
591
|
"ayu-dark",
|
|
592
592
|
"everforest",
|
|
593
593
|
"night-owl",
|
|
594
|
-
"synthwave"
|
|
594
|
+
"synthwave",
|
|
595
|
+
"github-dark",
|
|
596
|
+
"material-ocean",
|
|
597
|
+
"nightfox",
|
|
598
|
+
"oxocarbon",
|
|
599
|
+
"catppuccin-macchiato",
|
|
600
|
+
"catppuccin-frappe",
|
|
601
|
+
"gruvbox-material",
|
|
602
|
+
"tokyo-night-storm",
|
|
603
|
+
"rose-pine-moon",
|
|
604
|
+
"zenburn",
|
|
605
|
+
"palenight",
|
|
606
|
+
"horizon",
|
|
607
|
+
"sonokai",
|
|
608
|
+
"edge-dark",
|
|
609
|
+
"moonfly",
|
|
610
|
+
"melange",
|
|
611
|
+
"poimandres",
|
|
612
|
+
"vitesse-dark",
|
|
613
|
+
"aura",
|
|
614
|
+
"dark-plus"
|
|
595
615
|
];
|
|
596
616
|
|
|
597
617
|
// src/types/session-markers.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/core",
|
|
3
|
-
"version": "0.305.
|
|
3
|
+
"version": "0.305.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack core: kernel, types, defaults, and shared utilities for the WrongStack CLI agent.",
|
|
6
6
|
"repository": {
|
|
@@ -177,8 +177,8 @@
|
|
|
177
177
|
"wrongstackApiVersion": "0.1.10",
|
|
178
178
|
"dependencies": {
|
|
179
179
|
"zod": "4.4.3",
|
|
180
|
-
"@wrongstack/
|
|
181
|
-
"@wrongstack/
|
|
180
|
+
"@wrongstack/kanban": "0.305.1",
|
|
181
|
+
"@wrongstack/persistence": "0.305.1"
|
|
182
182
|
},
|
|
183
183
|
"devDependencies": {
|
|
184
184
|
"@types/node": "^26.1.2",
|