syntaur 0.69.0 → 0.70.0
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/.claude-plugin/plugin.json +1 -1
- package/dist/dashboard/server.js +74 -41
- package/dist/dashboard/server.js.map +1 -1
- package/dist/index.js +344 -321
- package/dist/index.js.map +1 -1
- package/dist/launch/index.js +319 -32
- package/dist/launch/index.js.map +1 -1
- package/package.json +1 -1
- package/platforms/claude-code/.claude-plugin/plugin.json +1 -1
- package/platforms/codex/.codex-plugin/plugin.json +1 -1
- package/platforms/hermes/plugins/syntaur/__pycache__/__init__.cpython-312.pyc +0 -0
- package/platforms/hermes/plugins/syntaur/__pycache__/boundary.cpython-312.pyc +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "syntaur",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.70.0",
|
|
4
4
|
"description": "Syntaur protocol skills for AI coding agents — assignment, project, plan, and session lifecycle. Cross-agent (Claude Code, Codex, Cursor, OpenCode, Gemini CLI, and more via skills.sh).",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Brennen",
|
package/dist/dashboard/server.js
CHANGED
|
@@ -122,7 +122,7 @@ function getTargetStatus(_from, command, table) {
|
|
|
122
122
|
if (!table) {
|
|
123
123
|
return DEFAULT_COMMAND_TARGETS.get(command) ?? null;
|
|
124
124
|
}
|
|
125
|
-
return table.get(command) ?? table.get(
|
|
125
|
+
return table.get(`${_from}:${command}`) ?? table.get(command) ?? null;
|
|
126
126
|
}
|
|
127
127
|
var DEFAULT_COMMAND_TARGETS, DEFAULT_TRANSITION_TABLE;
|
|
128
128
|
var init_state_machine = __esm({
|
|
@@ -6322,8 +6322,7 @@ async function areDependenciesSatisfied(projectDir, dependsOn, terminalStatuses)
|
|
|
6322
6322
|
if (!await fileExists(depPath)) return false;
|
|
6323
6323
|
try {
|
|
6324
6324
|
const content = await readFile9(depPath, "utf-8");
|
|
6325
|
-
const
|
|
6326
|
-
const status = m ? m[1].trim() : "";
|
|
6325
|
+
const { status } = parseAssignmentFrontmatter(content);
|
|
6327
6326
|
if (!terminalStatuses.has(status)) return false;
|
|
6328
6327
|
} catch {
|
|
6329
6328
|
return false;
|
|
@@ -6438,6 +6437,7 @@ var init_facts = __esm({
|
|
|
6438
6437
|
init_fs();
|
|
6439
6438
|
init_git_worktree();
|
|
6440
6439
|
init_derive();
|
|
6440
|
+
init_frontmatter();
|
|
6441
6441
|
HTML_COMMENT_RE = /<!--[\s\S]*?-->/g;
|
|
6442
6442
|
PLAN_FILE_RE = /^plan(?:-v(\d+))?\.md$/;
|
|
6443
6443
|
}
|
|
@@ -8175,8 +8175,8 @@ function scanKey(serversDir2, projectsDir, assignmentsDir2) {
|
|
|
8175
8175
|
return `${serversDir2}\0${projectsDir}\0${assignmentsDir2 ?? ""}`;
|
|
8176
8176
|
}
|
|
8177
8177
|
function delay(ms) {
|
|
8178
|
-
return new Promise((
|
|
8179
|
-
const timer3 = setTimeout(
|
|
8178
|
+
return new Promise((resolve48) => {
|
|
8179
|
+
const timer3 = setTimeout(resolve48, ms);
|
|
8180
8180
|
if (typeof timer3.unref === "function") {
|
|
8181
8181
|
timer3.unref();
|
|
8182
8182
|
}
|
|
@@ -11991,6 +11991,22 @@ var init_assignment_todos = __esm({
|
|
|
11991
11991
|
}
|
|
11992
11992
|
});
|
|
11993
11993
|
|
|
11994
|
+
// src/utils/path-canon.ts
|
|
11995
|
+
import { realpathSync as realpathSync2 } from "fs";
|
|
11996
|
+
import { resolve as resolve43 } from "path";
|
|
11997
|
+
function canonicalPath(p) {
|
|
11998
|
+
try {
|
|
11999
|
+
return realpathSync2(resolve43(p));
|
|
12000
|
+
} catch {
|
|
12001
|
+
return resolve43(p).replace(/\/+$/, "");
|
|
12002
|
+
}
|
|
12003
|
+
}
|
|
12004
|
+
var init_path_canon = __esm({
|
|
12005
|
+
"src/utils/path-canon.ts"() {
|
|
12006
|
+
"use strict";
|
|
12007
|
+
}
|
|
12008
|
+
});
|
|
12009
|
+
|
|
11994
12010
|
// src/targets/renderers.ts
|
|
11995
12011
|
var RENDERERS;
|
|
11996
12012
|
var init_renderers = __esm({
|
|
@@ -12011,7 +12027,7 @@ var init_renderers = __esm({
|
|
|
12011
12027
|
});
|
|
12012
12028
|
|
|
12013
12029
|
// src/targets/user-descriptors.ts
|
|
12014
|
-
import { resolve as
|
|
12030
|
+
import { resolve as resolve44 } from "path";
|
|
12015
12031
|
import { readFile as readFile30, readdir as readdir18 } from "fs/promises";
|
|
12016
12032
|
var VALID_RENDERER_KEYS;
|
|
12017
12033
|
var init_user_descriptors = __esm({
|
|
@@ -12026,20 +12042,20 @@ var init_user_descriptors = __esm({
|
|
|
12026
12042
|
|
|
12027
12043
|
// src/targets/registry.ts
|
|
12028
12044
|
import { homedir as homedir7 } from "os";
|
|
12029
|
-
import { join as join10, resolve as
|
|
12045
|
+
import { join as join10, resolve as resolve45 } from "path";
|
|
12030
12046
|
function home(...segments) {
|
|
12031
|
-
return
|
|
12047
|
+
return resolve45(homedir7(), ...segments);
|
|
12032
12048
|
}
|
|
12033
12049
|
function hermesHome() {
|
|
12034
12050
|
const env = process.env.HERMES_HOME;
|
|
12035
|
-
return env && env.length > 0 ?
|
|
12051
|
+
return env && env.length > 0 ? resolve45(env) : home(".hermes");
|
|
12036
12052
|
}
|
|
12037
12053
|
function hermesSkillsDir() {
|
|
12038
|
-
return
|
|
12054
|
+
return resolve45(hermesHome(), "skills");
|
|
12039
12055
|
}
|
|
12040
12056
|
function codexHome() {
|
|
12041
12057
|
const env = process.env.CODEX_HOME;
|
|
12042
|
-
return env && env.length > 0 ?
|
|
12058
|
+
return env && env.length > 0 ? resolve45(env) : home(".codex");
|
|
12043
12059
|
}
|
|
12044
12060
|
function toDiscovered(meta) {
|
|
12045
12061
|
if (!meta) return null;
|
|
@@ -12110,7 +12126,7 @@ var init_registry = __esm({
|
|
|
12110
12126
|
skillsShAgentId: "codex",
|
|
12111
12127
|
nativePlugin: "codex",
|
|
12112
12128
|
detect: detectDir(codexHome()),
|
|
12113
|
-
skillsDir: { global:
|
|
12129
|
+
skillsDir: { global: resolve45(codexHome(), "skills") },
|
|
12114
12130
|
instructions: { files: [{ path: "AGENTS.md", renderer: "codexAgents" }] },
|
|
12115
12131
|
sessions: codexSessions
|
|
12116
12132
|
},
|
|
@@ -12179,7 +12195,7 @@ var init_registry = __esm({
|
|
|
12179
12195
|
tier3: {
|
|
12180
12196
|
kind: "hermes-plugin",
|
|
12181
12197
|
source: "platforms/hermes/plugins/syntaur",
|
|
12182
|
-
installDir: () =>
|
|
12198
|
+
installDir: () => resolve45(hermesHome(), "plugins", "syntaur"),
|
|
12183
12199
|
entry: "plugin.yaml"
|
|
12184
12200
|
}
|
|
12185
12201
|
}
|
|
@@ -12199,7 +12215,7 @@ import { execFile as execFile3, execFileSync as execFileSync4 } from "child_proc
|
|
|
12199
12215
|
import { promisify as promisify3 } from "util";
|
|
12200
12216
|
import { statSync as statSync4 } from "fs";
|
|
12201
12217
|
import { readFile as readFile31 } from "fs/promises";
|
|
12202
|
-
import { resolve as
|
|
12218
|
+
import { resolve as resolve46 } from "path";
|
|
12203
12219
|
function emptySummary() {
|
|
12204
12220
|
return { discovered: 0, inserted: 0, revived: 0, swept: 0, skipped: 0, changed: false };
|
|
12205
12221
|
}
|
|
@@ -12252,10 +12268,15 @@ async function defaultOpenFiles(files) {
|
|
|
12252
12268
|
}
|
|
12253
12269
|
return open6;
|
|
12254
12270
|
}
|
|
12271
|
+
function canonicalizeOpenSet(open6) {
|
|
12272
|
+
const out = /* @__PURE__ */ new Set();
|
|
12273
|
+
for (const p of open6) out.add(canonicalPath(p));
|
|
12274
|
+
return out;
|
|
12275
|
+
}
|
|
12255
12276
|
async function readContextLink(cwd, cache3) {
|
|
12256
12277
|
if (cache3.has(cwd)) return cache3.get(cwd);
|
|
12257
12278
|
let link = null;
|
|
12258
|
-
const path =
|
|
12279
|
+
const path = resolve46(cwd, ".syntaur", "context.json");
|
|
12259
12280
|
if (await fileExists(path)) {
|
|
12260
12281
|
try {
|
|
12261
12282
|
const parsed = JSON.parse(await readFile31(path, "utf-8"));
|
|
@@ -12307,7 +12328,9 @@ async function scanSessions(opts = {}, deps = {}) {
|
|
|
12307
12328
|
}
|
|
12308
12329
|
}
|
|
12309
12330
|
summary.discovered = discovered.length;
|
|
12310
|
-
const openSet =
|
|
12331
|
+
const openSet = canonicalizeOpenSet(
|
|
12332
|
+
await openFiles(discovered.map((d) => d.transcriptPath))
|
|
12333
|
+
);
|
|
12311
12334
|
const contextCache = /* @__PURE__ */ new Map();
|
|
12312
12335
|
for (const d of discovered) {
|
|
12313
12336
|
const link = await readContextLink(d.cwd, contextCache);
|
|
@@ -12316,7 +12339,7 @@ async function scanSessions(opts = {}, deps = {}) {
|
|
|
12316
12339
|
continue;
|
|
12317
12340
|
}
|
|
12318
12341
|
const mtime = statMtimeMs(d.transcriptPath);
|
|
12319
|
-
const heldOpen = openSet.has(d.transcriptPath);
|
|
12342
|
+
const heldOpen = openSet.has(canonicalPath(d.transcriptPath));
|
|
12320
12343
|
const isLive = heldOpen || mtime !== null && now() - mtime < FRESH_MTIME_MS;
|
|
12321
12344
|
const prev = getSessionById(d.sessionId);
|
|
12322
12345
|
const status = isLive ? "active" : prev?.status ?? "stopped";
|
|
@@ -12378,12 +12401,14 @@ async function scanSessions(opts = {}, deps = {}) {
|
|
|
12378
12401
|
sweepCandidates.push({ sessionId: row.session_id, transcriptPath: null });
|
|
12379
12402
|
}
|
|
12380
12403
|
}
|
|
12381
|
-
const sweepOpenSet =
|
|
12382
|
-
|
|
12404
|
+
const sweepOpenSet = canonicalizeOpenSet(
|
|
12405
|
+
await openFiles(
|
|
12406
|
+
sweepCandidates.map((c) => c.transcriptPath).filter((p) => p !== null)
|
|
12407
|
+
)
|
|
12383
12408
|
);
|
|
12384
12409
|
for (const candidate of sweepCandidates) {
|
|
12385
12410
|
if (candidate.transcriptPath) {
|
|
12386
|
-
if (sweepOpenSet.has(candidate.transcriptPath)) continue;
|
|
12411
|
+
if (sweepOpenSet.has(canonicalPath(candidate.transcriptPath))) continue;
|
|
12387
12412
|
const mtime = statMtimeMs(candidate.transcriptPath);
|
|
12388
12413
|
if (mtime !== null && now() - mtime < FRESH_MTIME_MS) continue;
|
|
12389
12414
|
const endedAt = mtime !== null ? new Date(mtime).toISOString() : void 0;
|
|
@@ -12404,6 +12429,7 @@ var init_scanner2 = __esm({
|
|
|
12404
12429
|
"src/sessions/scanner.ts"() {
|
|
12405
12430
|
"use strict";
|
|
12406
12431
|
init_fs();
|
|
12432
|
+
init_path_canon();
|
|
12407
12433
|
init_config2();
|
|
12408
12434
|
init_session_id();
|
|
12409
12435
|
init_registry();
|
|
@@ -12457,7 +12483,7 @@ init_assignment_resolver();
|
|
|
12457
12483
|
init_agent_sessions();
|
|
12458
12484
|
import express from "express";
|
|
12459
12485
|
import { createServer } from "http";
|
|
12460
|
-
import { resolve as
|
|
12486
|
+
import { resolve as resolve47 } from "path";
|
|
12461
12487
|
import { writeFile as writeFile8, unlink as unlink9 } from "fs/promises";
|
|
12462
12488
|
import { WebSocketServer, WebSocket } from "ws";
|
|
12463
12489
|
|
|
@@ -18195,6 +18221,12 @@ async function resolveSessionPlan(input, terminal) {
|
|
|
18195
18221
|
}
|
|
18196
18222
|
}
|
|
18197
18223
|
}
|
|
18224
|
+
if (!cwd.trim()) {
|
|
18225
|
+
throw new LaunchError(
|
|
18226
|
+
"workspace-path-invalid",
|
|
18227
|
+
`Session ${input.id} has no recorded working directory and no linked assignment workspace resolved \u2014 refusing to launch in an unknown directory.`
|
|
18228
|
+
);
|
|
18229
|
+
}
|
|
18198
18230
|
const agent = getAgents(input.config).find((a) => a.id === session.agent);
|
|
18199
18231
|
if (!agent) {
|
|
18200
18232
|
throw new LaunchError(
|
|
@@ -18271,7 +18303,7 @@ async function executeLaunchPlan(plan, spawnFn = realSpawn) {
|
|
|
18271
18303
|
`Spawn failed: ${msg}. Verify the terminal is installed and on PATH.`
|
|
18272
18304
|
);
|
|
18273
18305
|
}
|
|
18274
|
-
await new Promise((
|
|
18306
|
+
await new Promise((resolve48, reject) => {
|
|
18275
18307
|
let settled = false;
|
|
18276
18308
|
let stderr = "";
|
|
18277
18309
|
const finishOk = () => {
|
|
@@ -18281,7 +18313,7 @@ async function executeLaunchPlan(plan, spawnFn = realSpawn) {
|
|
|
18281
18313
|
child.unref();
|
|
18282
18314
|
} catch {
|
|
18283
18315
|
}
|
|
18284
|
-
|
|
18316
|
+
resolve48();
|
|
18285
18317
|
};
|
|
18286
18318
|
const finishErr = (remediation) => {
|
|
18287
18319
|
if (settled) return;
|
|
@@ -20044,8 +20076,7 @@ function predictReset(_provider, anchor) {
|
|
|
20044
20076
|
}
|
|
20045
20077
|
function verifyReset(provider, anchor, now) {
|
|
20046
20078
|
const reset = predictReset(provider, anchor);
|
|
20047
|
-
|
|
20048
|
-
return { eligible: false, rescheduleToIso: reset };
|
|
20079
|
+
return { eligible: now.getTime() >= Date.parse(reset) };
|
|
20049
20080
|
}
|
|
20050
20081
|
|
|
20051
20082
|
// src/schedules/triggers.ts
|
|
@@ -20069,13 +20100,15 @@ function evaluateKind(trigger, job, ctx) {
|
|
|
20069
20100
|
switch (trigger.kind) {
|
|
20070
20101
|
case "at": {
|
|
20071
20102
|
const at = Date.parse(trigger.at);
|
|
20072
|
-
const
|
|
20103
|
+
const beforeCreation = !Number.isNaN(createdAtMs) && at < createdAtMs;
|
|
20104
|
+
const due = !Number.isNaN(at) && ctx.now.getTime() >= at && !beforeCreation;
|
|
20073
20105
|
return { due, dedupeKey: `at:${trigger.at}`, nextFireIso: trigger.at };
|
|
20074
20106
|
}
|
|
20075
20107
|
case "in": {
|
|
20076
20108
|
const anchor = Date.parse(trigger.anchorIso);
|
|
20077
20109
|
const fireAt = anchor + trigger.durationMs;
|
|
20078
|
-
const
|
|
20110
|
+
const beforeCreation = !Number.isNaN(createdAtMs) && fireAt < createdAtMs;
|
|
20111
|
+
const due = !Number.isNaN(anchor) && ctx.now.getTime() >= fireAt && !beforeCreation;
|
|
20079
20112
|
const fireIso = Number.isNaN(anchor) ? null : iso(new Date(fireAt));
|
|
20080
20113
|
return { due, dedupeKey: `in:${fireAt}`, nextFireIso: fireIso };
|
|
20081
20114
|
}
|
|
@@ -20109,7 +20142,7 @@ function evaluateAfterReset(trigger, now) {
|
|
|
20109
20142
|
if (v.eligible) {
|
|
20110
20143
|
return { due: true, dedupeKey: `after-reset:${trigger.anchor.windowStartIso}`, nextFireIso: predicted };
|
|
20111
20144
|
}
|
|
20112
|
-
return { due: false, nextFireIso: predicted
|
|
20145
|
+
return { due: false, nextFireIso: predicted };
|
|
20113
20146
|
}
|
|
20114
20147
|
function evaluateWhenStatus(trigger, job, ctx, createdAtMs) {
|
|
20115
20148
|
const fm = ctx.assignment;
|
|
@@ -22809,7 +22842,7 @@ function createTodosRouter(todosDir2, broadcast, projectsDir) {
|
|
|
22809
22842
|
router.post("/:workspace/archive", async (req2, res) => {
|
|
22810
22843
|
try {
|
|
22811
22844
|
const { archivePath: archivePath2 } = await Promise.resolve().then(() => (init_parser2(), parser_exports));
|
|
22812
|
-
const { resolve:
|
|
22845
|
+
const { resolve: resolve48 } = await import("path");
|
|
22813
22846
|
const { readFile: readFile32 } = await import("fs/promises");
|
|
22814
22847
|
const { writeFileForce: writeFileForce2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
22815
22848
|
const workspace = getWorkspaceParam(req2.params.workspace);
|
|
@@ -22826,7 +22859,7 @@ function createTodosRouter(todosDir2, broadcast, projectsDir) {
|
|
|
22826
22859
|
(e) => e.itemIds.every((id) => completedIds.has(id))
|
|
22827
22860
|
);
|
|
22828
22861
|
const archFile = archivePath2(todosDir2, workspace, checklist.archiveInterval);
|
|
22829
|
-
await ensureDir(
|
|
22862
|
+
await ensureDir(resolve48(todosDir2, "archive"));
|
|
22830
22863
|
let archContent = "";
|
|
22831
22864
|
if (await fileExists(archFile)) {
|
|
22832
22865
|
archContent = await readFile32(archFile, "utf-8");
|
|
@@ -25305,7 +25338,7 @@ async function runCcusage(opts = {}) {
|
|
|
25305
25338
|
};
|
|
25306
25339
|
}
|
|
25307
25340
|
function runOnce(binary, args, env, timeoutMs, maxOutputBytes) {
|
|
25308
|
-
return new Promise((
|
|
25341
|
+
return new Promise((resolve48) => {
|
|
25309
25342
|
const child = spawn4(binary, args, {
|
|
25310
25343
|
env: env ?? process.env,
|
|
25311
25344
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -25319,7 +25352,7 @@ function runOnce(binary, args, env, timeoutMs, maxOutputBytes) {
|
|
|
25319
25352
|
if (settled) return;
|
|
25320
25353
|
settled = true;
|
|
25321
25354
|
clearTimeout(timer3);
|
|
25322
|
-
|
|
25355
|
+
resolve48(result);
|
|
25323
25356
|
};
|
|
25324
25357
|
const timer3 = setTimeout(() => {
|
|
25325
25358
|
timedOut = true;
|
|
@@ -25723,7 +25756,7 @@ function createDashboardServer(options) {
|
|
|
25723
25756
|
(async () => {
|
|
25724
25757
|
try {
|
|
25725
25758
|
const configResult = await migrateLegacyConfig(
|
|
25726
|
-
|
|
25759
|
+
resolve47(syntaurRoot(), "config.md")
|
|
25727
25760
|
);
|
|
25728
25761
|
const projectResult = await migrateLegacyProjectFiles(projectsDir);
|
|
25729
25762
|
const summary = summarizeMigration(projectResult, configResult);
|
|
@@ -26246,14 +26279,14 @@ function createDashboardServer(options) {
|
|
|
26246
26279
|
app.use("/api/backup", createBackupRouter());
|
|
26247
26280
|
if (serveStaticUi && dashboardDistPath) {
|
|
26248
26281
|
const sendOpts = { dotfiles: "allow" };
|
|
26249
|
-
app.use("/assets", express.static(
|
|
26282
|
+
app.use("/assets", express.static(resolve47(dashboardDistPath, "assets"), sendOpts));
|
|
26250
26283
|
app.use(express.static(dashboardDistPath, { ...sendOpts, index: false, fallthrough: true }));
|
|
26251
26284
|
app.get("{*path}", async (req2, res) => {
|
|
26252
26285
|
if (req2.path.startsWith("/api") || req2.path === "/ws" || req2.path.startsWith("/assets")) {
|
|
26253
26286
|
res.status(404).json({ error: "Not Found" });
|
|
26254
26287
|
return;
|
|
26255
26288
|
}
|
|
26256
|
-
const indexPath =
|
|
26289
|
+
const indexPath = resolve47(dashboardDistPath, "index.html");
|
|
26257
26290
|
if (!await fileExists(indexPath)) {
|
|
26258
26291
|
res.status(503).send(
|
|
26259
26292
|
'Dashboard not built. Run "npm run build:dashboard" first.'
|
|
@@ -26289,8 +26322,8 @@ function createDashboardServer(options) {
|
|
|
26289
26322
|
if (!await migrationGate()) return;
|
|
26290
26323
|
try {
|
|
26291
26324
|
const context = await resolveDeriveContext2();
|
|
26292
|
-
const projectDir = projectSlug ?
|
|
26293
|
-
const path = projectDir ?
|
|
26325
|
+
const projectDir = projectSlug ? resolve47(projectsDir, projectSlug) : null;
|
|
26326
|
+
const path = projectDir ? resolve47(projectDir, "assignments", assignmentSlug, "assignment.md") : resolve47(assignmentsDir2, assignmentSlug, "assignment.md");
|
|
26294
26327
|
if (!await fileExists(path)) return;
|
|
26295
26328
|
const result = await recomputeAndWrite2(path, {
|
|
26296
26329
|
cause: "derive",
|
|
@@ -26343,8 +26376,8 @@ function createDashboardServer(options) {
|
|
|
26343
26376
|
serversDir: serversDir2,
|
|
26344
26377
|
playbooksDir: playbooksDir2,
|
|
26345
26378
|
todosDir: todosDir2,
|
|
26346
|
-
dbPath:
|
|
26347
|
-
configPath:
|
|
26379
|
+
dbPath: resolve47(syntaurRoot(), "syntaur.db"),
|
|
26380
|
+
configPath: resolve47(syntaurRoot(), "config.md"),
|
|
26348
26381
|
onMessage: broadcast,
|
|
26349
26382
|
onAssignmentChanged: (projectSlug, assignmentSlug) => {
|
|
26350
26383
|
void recomputeOne(projectSlug, assignmentSlug);
|
|
@@ -26412,7 +26445,7 @@ function createDashboardServer(options) {
|
|
|
26412
26445
|
}
|
|
26413
26446
|
});
|
|
26414
26447
|
server.listen(port, () => {
|
|
26415
|
-
const portFile =
|
|
26448
|
+
const portFile = resolve47(syntaurRoot(), "dashboard-port");
|
|
26416
26449
|
writeFile8(portFile, String(port), "utf-8").catch(() => {
|
|
26417
26450
|
});
|
|
26418
26451
|
resolvePromise();
|
|
@@ -26436,7 +26469,7 @@ function createDashboardServer(options) {
|
|
|
26436
26469
|
client.terminate();
|
|
26437
26470
|
}
|
|
26438
26471
|
clients.clear();
|
|
26439
|
-
const portFile =
|
|
26472
|
+
const portFile = resolve47(syntaurRoot(), "dashboard-port");
|
|
26440
26473
|
await unlink9(portFile).catch(() => {
|
|
26441
26474
|
});
|
|
26442
26475
|
server.closeAllConnections?.();
|