syntaur 0.45.0 → 0.47.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/dashboard/dist/assets/{_basePickBy-RQBuJKcX.js → _basePickBy-DgR0_P-o.js} +1 -1
- package/dashboard/dist/assets/{_baseUniq-_J7s4kD3.js → _baseUniq-C8_Ych09.js} +1 -1
- package/dashboard/dist/assets/{arc-_9SyUgKQ.js → arc-yMHz4vGa.js} +1 -1
- package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-C8LeFMgr.js → architectureDiagram-2XIMDMQ5-ColWcH3P.js} +1 -1
- package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-gMh0EPEh.js → blockDiagram-WCTKOSBZ-Bo8Npvfq.js} +1 -1
- package/dashboard/dist/assets/{c4Diagram-IC4MRINW-cHwecwLI.js → c4Diagram-IC4MRINW-B2ky8AT7.js} +1 -1
- package/dashboard/dist/assets/channel-CUTEvTdk.js +1 -0
- package/dashboard/dist/assets/{chunk-4BX2VUAB-Bb2anYuQ.js → chunk-4BX2VUAB-CyF6Z6dx.js} +1 -1
- package/dashboard/dist/assets/{chunk-55IACEB6-DYIRGzA1.js → chunk-55IACEB6-BJOEnwNN.js} +1 -1
- package/dashboard/dist/assets/{chunk-FMBD7UC4-sgRWBbaF.js → chunk-FMBD7UC4-D3siQyQ4.js} +1 -1
- package/dashboard/dist/assets/{chunk-JSJVCQXG-DlYKMl_j.js → chunk-JSJVCQXG-DKGuxEMf.js} +1 -1
- package/dashboard/dist/assets/{chunk-KX2RTZJC-D0YDLAOF.js → chunk-KX2RTZJC-CNIWWO2F.js} +1 -1
- package/dashboard/dist/assets/{chunk-NQ4KR5QH-D-Y-CUx6.js → chunk-NQ4KR5QH-DXt05c7h.js} +1 -1
- package/dashboard/dist/assets/{chunk-QZHKN3VN-D7FpSvb5.js → chunk-QZHKN3VN-CM63uYnf.js} +1 -1
- package/dashboard/dist/assets/{chunk-WL4C6EOR-CtXgQLdS.js → chunk-WL4C6EOR-Dqvl_14m.js} +1 -1
- package/dashboard/dist/assets/classDiagram-VBA2DB6C-Bkoc7orC.js +1 -0
- package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-Bkoc7orC.js +1 -0
- package/dashboard/dist/assets/clone-CltBg7cH.js +1 -0
- package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-YbTaohoJ.js → cose-bilkent-S5V4N54A-WBLtT1w9.js} +1 -1
- package/dashboard/dist/assets/{dagre-KLK3FWXG-CMtwGAnP.js → dagre-KLK3FWXG-DIdQdwa7.js} +1 -1
- package/dashboard/dist/assets/{diagram-E7M64L7V-D8wBMBAX.js → diagram-E7M64L7V-BEH6P_Sk.js} +1 -1
- package/dashboard/dist/assets/{diagram-IFDJBPK2-DfudLpiJ.js → diagram-IFDJBPK2-BuhxBcSy.js} +1 -1
- package/dashboard/dist/assets/{diagram-P4PSJMXO-CyMy61wE.js → diagram-P4PSJMXO-DPSNVVzN.js} +1 -1
- package/dashboard/dist/assets/{erDiagram-INFDFZHY-BlB4ZQl9.js → erDiagram-INFDFZHY-DYJb_rF5.js} +1 -1
- package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-DbhDQJM3.js → flowDiagram-PKNHOUZH-B9_8BI26.js} +1 -1
- package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-DJFqteNi.js → ganttDiagram-A5KZAMGK-Bsg3QOhs.js} +1 -1
- package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-D8etA_mm.js → gitGraphDiagram-K3NZZRJ6-Cf5G9x_K.js} +1 -1
- package/dashboard/dist/assets/{graph-Ce86jeZn.js → graph-DyXfcrIH.js} +1 -1
- package/dashboard/dist/assets/index-C3kYxhbQ.js +567 -0
- package/dashboard/dist/assets/index-DKr21dk8.css +1 -0
- package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-Cx35U-h8.js → infoDiagram-LFFYTUFH-Bu1zlXs2.js} +1 -1
- package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-C04Y2nj8.js → ishikawaDiagram-PHBUUO56-fb8C-XRT.js} +1 -1
- package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-D8-cxbxE.js → journeyDiagram-4ABVD52K-smlBWs2O.js} +1 -1
- package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-DVKqMylP.js → kanban-definition-K7BYSVSG-Bz1AxFRE.js} +1 -1
- package/dashboard/dist/assets/{layout-98xZDpgu.js → layout-VsTD3onG.js} +1 -1
- package/dashboard/dist/assets/{linear-0jk_IwAc.js → linear-CE8xncGu.js} +1 -1
- package/dashboard/dist/assets/{mermaid.core-C337VWfr.js → mermaid.core-C0KQpDyW.js} +4 -4
- package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-8sNYGYEP.js → mindmap-definition-YRQLILUH-SRE5Immj.js} +1 -1
- package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-afcmzHxf.js → pieDiagram-SKSYHLDU-CaZ_aCcD.js} +1 -1
- package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-B4RjcpOq.js → quadrantDiagram-337W2JSQ-Dd6MIruu.js} +1 -1
- package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-CRavU6cI.js → requirementDiagram-Z7DCOOCP-BBXvP53l.js} +1 -1
- package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-DFomU3z-.js → sankeyDiagram-WA2Y5GQK-DnS1SMIm.js} +1 -1
- package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-CGKO7nmK.js → sequenceDiagram-2WXFIKYE-CLHJ1Uhx.js} +1 -1
- package/dashboard/dist/assets/{stateDiagram-RAJIS63D-BjFI1K8h.js → stateDiagram-RAJIS63D-B6vrAeYw.js} +1 -1
- package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-BeqNZKbk.js +1 -0
- package/dashboard/dist/assets/{timeline-definition-YZTLITO2-BBo8XJFG.js → timeline-definition-YZTLITO2-BlHwGfnL.js} +1 -1
- package/dashboard/dist/assets/{treemap-KZPCXAKY-COd6i6TE.js → treemap-KZPCXAKY-D9kOGUYR.js} +1 -1
- package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-CGQweQ36.js → vennDiagram-LZ73GAT5-BpQgeveT.js} +1 -1
- package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-mfJ5So7N.js → xychartDiagram-JWTSCODW-DRch79fE.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dist/dashboard/server.js +1405 -210
- package/dist/dashboard/server.js.map +1 -1
- package/dist/index.js +2092 -1485
- package/dist/index.js.map +1 -1
- package/dist/launch/index.d.ts +19 -0
- package/dist/launch/index.js +528 -17
- package/dist/launch/index.js.map +1 -1
- package/package.json +1 -1
- package/platforms/SESSION-ID-RESOLUTION.md +41 -4
- package/platforms/claude-code/.claude-plugin/plugin.json +1 -1
- package/platforms/claude-code/hooks/session-cleanup.sh +25 -64
- package/platforms/claude-code/hooks/session-start.sh +35 -109
- package/platforms/claude-code/skills/track-session/SKILL.md +12 -60
- package/platforms/codex/.codex-plugin/plugin.json +1 -1
- package/platforms/codex/skills/track-session/SKILL.md +12 -60
- package/platforms/hermes/plugins/syntaur/__pycache__/__init__.cpython-312.pyc +0 -0
- package/platforms/hermes/plugins/syntaur/__pycache__/boundary.cpython-312.pyc +0 -0
- package/skills/track-session/SKILL.md +12 -60
- package/dashboard/dist/assets/channel-C36dnl_e.js +0 -1
- package/dashboard/dist/assets/classDiagram-VBA2DB6C-BsoGa6_a.js +0 -1
- package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-BsoGa6_a.js +0 -1
- package/dashboard/dist/assets/clone-Bz6jW3OY.js +0 -1
- package/dashboard/dist/assets/index-DRng26Jg.js +0 -567
- package/dashboard/dist/assets/index-DzHQIE2n.css +0 -1
- package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-BtxefYKD.js +0 -1
package/dist/launch/index.js
CHANGED
|
@@ -1989,6 +1989,7 @@ function cloneDefaultConfig() {
|
|
|
1989
1989
|
...DEFAULT_CONFIG,
|
|
1990
1990
|
onboarding: { ...DEFAULT_CONFIG.onboarding },
|
|
1991
1991
|
agentDefaults: { ...DEFAULT_CONFIG.agentDefaults },
|
|
1992
|
+
session: { ...DEFAULT_CONFIG.session },
|
|
1992
1993
|
integrations: { ...DEFAULT_CONFIG.integrations },
|
|
1993
1994
|
backup: DEFAULT_CONFIG.backup ? { ...DEFAULT_CONFIG.backup } : null,
|
|
1994
1995
|
statuses: DEFAULT_CONFIG.statuses ? {
|
|
@@ -3338,6 +3339,11 @@ async function readConfig() {
|
|
|
3338
3339
|
fm["agentDefaults.autoCreateWorktree"]
|
|
3339
3340
|
) ? fm["agentDefaults.autoCreateWorktree"] : DEFAULT_CONFIG.agentDefaults.autoCreateWorktree
|
|
3340
3341
|
},
|
|
3342
|
+
session: {
|
|
3343
|
+
autoTrack: SESSION_AUTO_TRACK_VALUES.includes(
|
|
3344
|
+
fm["session.autoTrack"]
|
|
3345
|
+
) ? fm["session.autoTrack"] : DEFAULT_CONFIG.session.autoTrack
|
|
3346
|
+
},
|
|
3341
3347
|
integrations: {
|
|
3342
3348
|
claudePluginDir: parseOptionalAbsolutePath(
|
|
3343
3349
|
fm["integrations.claudePluginDir"],
|
|
@@ -3437,7 +3443,7 @@ async function updateAgentsConfig(mutation, options = {}) {
|
|
|
3437
3443
|
await writeAgentsConfig(next);
|
|
3438
3444
|
return { previous, next, written: true };
|
|
3439
3445
|
}
|
|
3440
|
-
var DEFAULT_DERIVE_CONFIG, DEFAULT_ASSIGNMENT_TYPES, DEFAULT_CONFIG, AUTO_CREATE_WORKTREE_VALUES, AgentConfigError, DEFAULT_STATUS_COLORS, KNOWN_AGENT_SCALAR_FIELDS, migratedConfigPaths, TerminalConfigError;
|
|
3446
|
+
var DEFAULT_DERIVE_CONFIG, DEFAULT_ASSIGNMENT_TYPES, DEFAULT_CONFIG, AUTO_CREATE_WORKTREE_VALUES, SESSION_AUTO_TRACK_VALUES, AgentConfigError, DEFAULT_STATUS_COLORS, KNOWN_AGENT_SCALAR_FIELDS, migratedConfigPaths, TerminalConfigError;
|
|
3441
3447
|
var init_config2 = __esm({
|
|
3442
3448
|
"src/utils/config.ts"() {
|
|
3443
3449
|
"use strict";
|
|
@@ -3503,6 +3509,9 @@ var init_config2 = __esm({
|
|
|
3503
3509
|
autoApprove: false,
|
|
3504
3510
|
autoCreateWorktree: "ask"
|
|
3505
3511
|
},
|
|
3512
|
+
session: {
|
|
3513
|
+
autoTrack: "all"
|
|
3514
|
+
},
|
|
3506
3515
|
integrations: {
|
|
3507
3516
|
claudePluginDir: null,
|
|
3508
3517
|
codexPluginDir: null,
|
|
@@ -3523,6 +3532,7 @@ var init_config2 = __esm({
|
|
|
3523
3532
|
}
|
|
3524
3533
|
};
|
|
3525
3534
|
AUTO_CREATE_WORKTREE_VALUES = ["skip", "ask", "always"];
|
|
3535
|
+
SESSION_AUTO_TRACK_VALUES = ["all", "workspaces-only", "off"];
|
|
3526
3536
|
AgentConfigError = class extends Error {
|
|
3527
3537
|
};
|
|
3528
3538
|
DEFAULT_STATUS_COLORS = {
|
|
@@ -3946,9 +3956,162 @@ var init_help = __esm({
|
|
|
3946
3956
|
});
|
|
3947
3957
|
|
|
3948
3958
|
// src/dashboard/session-db.ts
|
|
3959
|
+
var session_db_exports = {};
|
|
3960
|
+
__export(session_db_exports, {
|
|
3961
|
+
closeSessionDb: () => closeSessionDb,
|
|
3962
|
+
getSessionDb: () => getSessionDb,
|
|
3963
|
+
initSessionDb: () => initSessionDb,
|
|
3964
|
+
isSessionDbInitialized: () => isSessionDbInitialized,
|
|
3965
|
+
migrateFromMarkdown: () => migrateFromMarkdown,
|
|
3966
|
+
resetSessionDb: () => resetSessionDb
|
|
3967
|
+
});
|
|
3949
3968
|
import Database from "better-sqlite3";
|
|
3950
3969
|
import { resolve as resolve9 } from "path";
|
|
3951
3970
|
import { readdir as readdir5 } from "fs/promises";
|
|
3971
|
+
function initSessionDb(dbPath) {
|
|
3972
|
+
if (db) return db;
|
|
3973
|
+
const finalPath = dbPath ?? resolve9(syntaurRoot(), "syntaur.db");
|
|
3974
|
+
db = new Database(finalPath);
|
|
3975
|
+
db.pragma("journal_mode = WAL");
|
|
3976
|
+
db.exec(SCHEMA_SQL);
|
|
3977
|
+
db.prepare("INSERT OR IGNORE INTO meta (key, value) VALUES (?, ?)").run(
|
|
3978
|
+
"schema_version",
|
|
3979
|
+
SCHEMA_VERSION
|
|
3980
|
+
);
|
|
3981
|
+
const database = db;
|
|
3982
|
+
const runMigrations = database.transaction(() => {
|
|
3983
|
+
const vBeforeV2 = database.prepare("SELECT value FROM meta WHERE key = 'schema_version'").get()?.value;
|
|
3984
|
+
if (vBeforeV2 === "1") {
|
|
3985
|
+
database.exec(`
|
|
3986
|
+
CREATE TABLE sessions_v2 (
|
|
3987
|
+
session_id TEXT PRIMARY KEY,
|
|
3988
|
+
project_slug TEXT,
|
|
3989
|
+
assignment_slug TEXT,
|
|
3990
|
+
agent TEXT NOT NULL,
|
|
3991
|
+
started TEXT NOT NULL,
|
|
3992
|
+
ended TEXT,
|
|
3993
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
3994
|
+
path TEXT,
|
|
3995
|
+
description TEXT,
|
|
3996
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
3997
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
3998
|
+
);
|
|
3999
|
+
INSERT INTO sessions_v2 SELECT session_id, project_slug, assignment_slug, agent, started, ended, status, path, NULL, created_at, updated_at FROM sessions;
|
|
4000
|
+
DROP TABLE sessions;
|
|
4001
|
+
ALTER TABLE sessions_v2 RENAME TO sessions;
|
|
4002
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_slug);
|
|
4003
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_assignment ON sessions(project_slug, assignment_slug);
|
|
4004
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
|
|
4005
|
+
UPDATE meta SET value = '2' WHERE key = 'schema_version';
|
|
4006
|
+
`);
|
|
4007
|
+
}
|
|
4008
|
+
const vBeforeV3 = database.prepare("SELECT value FROM meta WHERE key = 'schema_version'").get()?.value;
|
|
4009
|
+
if (vBeforeV3 === "2") {
|
|
4010
|
+
const v2Columns = database.prepare("PRAGMA table_info(sessions)").all();
|
|
4011
|
+
const v2ColNames = v2Columns.map((c) => c.name);
|
|
4012
|
+
const hasProject = v2ColNames.includes("project_slug");
|
|
4013
|
+
const hasMission = v2ColNames.includes("mission_slug");
|
|
4014
|
+
const projectSlugExpr = hasProject && hasMission ? "COALESCE(project_slug, mission_slug)" : hasProject ? "project_slug" : hasMission ? "mission_slug" : null;
|
|
4015
|
+
if (!projectSlugExpr) {
|
|
4016
|
+
throw new Error(
|
|
4017
|
+
"sessions table has neither project_slug nor mission_slug; cannot migrate from v2 to v3"
|
|
4018
|
+
);
|
|
4019
|
+
}
|
|
4020
|
+
database.exec(`
|
|
4021
|
+
CREATE TABLE sessions_v3 (
|
|
4022
|
+
session_id TEXT PRIMARY KEY,
|
|
4023
|
+
project_slug TEXT,
|
|
4024
|
+
assignment_slug TEXT,
|
|
4025
|
+
agent TEXT NOT NULL,
|
|
4026
|
+
started TEXT NOT NULL,
|
|
4027
|
+
ended TEXT,
|
|
4028
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
4029
|
+
path TEXT,
|
|
4030
|
+
description TEXT,
|
|
4031
|
+
transcript_path TEXT,
|
|
4032
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
4033
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
4034
|
+
);
|
|
4035
|
+
INSERT INTO sessions_v3
|
|
4036
|
+
SELECT session_id, ${projectSlugExpr}, assignment_slug, agent, started, ended, status, path, description, NULL, created_at, updated_at
|
|
4037
|
+
FROM sessions;
|
|
4038
|
+
DROP TABLE sessions;
|
|
4039
|
+
ALTER TABLE sessions_v3 RENAME TO sessions;
|
|
4040
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_slug);
|
|
4041
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_assignment ON sessions(project_slug, assignment_slug);
|
|
4042
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
|
|
4043
|
+
UPDATE meta SET value = '3' WHERE key = 'schema_version';
|
|
4044
|
+
`);
|
|
4045
|
+
}
|
|
4046
|
+
const vBeforeV4 = database.prepare("SELECT value FROM meta WHERE key = 'schema_version'").get()?.value;
|
|
4047
|
+
if (vBeforeV4 === "3") {
|
|
4048
|
+
database.exec(`
|
|
4049
|
+
CREATE TABLE sessions_v4 (
|
|
4050
|
+
session_id TEXT PRIMARY KEY,
|
|
4051
|
+
project_slug TEXT,
|
|
4052
|
+
assignment_slug TEXT,
|
|
4053
|
+
agent TEXT NOT NULL,
|
|
4054
|
+
started TEXT NOT NULL,
|
|
4055
|
+
ended TEXT,
|
|
4056
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
4057
|
+
path TEXT,
|
|
4058
|
+
description TEXT,
|
|
4059
|
+
transcript_path TEXT,
|
|
4060
|
+
pid INTEGER,
|
|
4061
|
+
pid_started_at TEXT,
|
|
4062
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
4063
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
4064
|
+
);
|
|
4065
|
+
INSERT INTO sessions_v4
|
|
4066
|
+
SELECT session_id, project_slug, assignment_slug, agent, started, ended, status, path, description, transcript_path, NULL, NULL, created_at, updated_at
|
|
4067
|
+
FROM sessions;
|
|
4068
|
+
DROP TABLE sessions;
|
|
4069
|
+
ALTER TABLE sessions_v4 RENAME TO sessions;
|
|
4070
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_slug);
|
|
4071
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_assignment ON sessions(project_slug, assignment_slug);
|
|
4072
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
|
|
4073
|
+
UPDATE meta SET value = '4' WHERE key = 'schema_version';
|
|
4074
|
+
`);
|
|
4075
|
+
}
|
|
4076
|
+
const vBeforeV5 = database.prepare("SELECT value FROM meta WHERE key = 'schema_version'").get()?.value;
|
|
4077
|
+
if (vBeforeV5 === "4") {
|
|
4078
|
+
database.exec(`
|
|
4079
|
+
CREATE TABLE sessions_v5 (
|
|
4080
|
+
session_id TEXT PRIMARY KEY,
|
|
4081
|
+
project_slug TEXT,
|
|
4082
|
+
assignment_slug TEXT,
|
|
4083
|
+
agent TEXT NOT NULL,
|
|
4084
|
+
started TEXT NOT NULL,
|
|
4085
|
+
ended TEXT,
|
|
4086
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
4087
|
+
path TEXT,
|
|
4088
|
+
description TEXT,
|
|
4089
|
+
transcript_path TEXT,
|
|
4090
|
+
pid INTEGER,
|
|
4091
|
+
pid_started_at TEXT,
|
|
4092
|
+
original_head_sha TEXT,
|
|
4093
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
4094
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
4095
|
+
);
|
|
4096
|
+
INSERT INTO sessions_v5
|
|
4097
|
+
SELECT session_id, project_slug, assignment_slug, agent, started, ended, status, path, description, transcript_path, pid, pid_started_at, NULL, created_at, updated_at
|
|
4098
|
+
FROM sessions;
|
|
4099
|
+
DROP TABLE sessions;
|
|
4100
|
+
ALTER TABLE sessions_v5 RENAME TO sessions;
|
|
4101
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_slug);
|
|
4102
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_assignment ON sessions(project_slug, assignment_slug);
|
|
4103
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
|
|
4104
|
+
UPDATE meta SET value = '5' WHERE key = 'schema_version';
|
|
4105
|
+
`);
|
|
4106
|
+
}
|
|
4107
|
+
});
|
|
4108
|
+
runMigrations.exclusive();
|
|
4109
|
+
db.exec(POST_MIGRATION_INDEXES_SQL);
|
|
4110
|
+
return db;
|
|
4111
|
+
}
|
|
4112
|
+
function isSessionDbInitialized() {
|
|
4113
|
+
return db !== null;
|
|
4114
|
+
}
|
|
3952
4115
|
function getSessionDb() {
|
|
3953
4116
|
if (!db) {
|
|
3954
4117
|
throw new Error(
|
|
@@ -3957,17 +4120,129 @@ function getSessionDb() {
|
|
|
3957
4120
|
}
|
|
3958
4121
|
return db;
|
|
3959
4122
|
}
|
|
3960
|
-
|
|
4123
|
+
function closeSessionDb() {
|
|
4124
|
+
if (db) {
|
|
4125
|
+
db.close();
|
|
4126
|
+
db = null;
|
|
4127
|
+
}
|
|
4128
|
+
}
|
|
4129
|
+
function resetSessionDb() {
|
|
4130
|
+
db = null;
|
|
4131
|
+
}
|
|
4132
|
+
async function migrateFromMarkdown(projectsDir) {
|
|
4133
|
+
const database = getSessionDb();
|
|
4134
|
+
const count = database.prepare("SELECT COUNT(*) as count FROM sessions").get();
|
|
4135
|
+
if (count.count > 0) return 0;
|
|
4136
|
+
if (!await fileExists(projectsDir)) return 0;
|
|
4137
|
+
const entries = await readdir5(projectsDir, { withFileTypes: true });
|
|
4138
|
+
const allSessions = [];
|
|
4139
|
+
for (const entry of entries) {
|
|
4140
|
+
if (!entry.isDirectory()) continue;
|
|
4141
|
+
const projectDir = resolve9(projectsDir, entry.name);
|
|
4142
|
+
const indexPath = resolve9(projectDir, "_index-sessions.md");
|
|
4143
|
+
if (!await fileExists(indexPath)) continue;
|
|
4144
|
+
const sessions = await parseMarkdownSessionsIndex(indexPath, entry.name);
|
|
4145
|
+
allSessions.push(...sessions);
|
|
4146
|
+
}
|
|
4147
|
+
if (allSessions.length === 0) return 0;
|
|
4148
|
+
const insert = database.prepare(`
|
|
4149
|
+
INSERT OR IGNORE INTO sessions (session_id, project_slug, assignment_slug, agent, started, status, path)
|
|
4150
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
4151
|
+
`);
|
|
4152
|
+
const insertAll = database.transaction((sessions) => {
|
|
4153
|
+
for (const s of sessions) {
|
|
4154
|
+
insert.run(s.sessionId, s.projectSlug, s.assignmentSlug, s.agent, s.started, s.status, s.path);
|
|
4155
|
+
}
|
|
4156
|
+
});
|
|
4157
|
+
insertAll(allSessions);
|
|
4158
|
+
console.log(`Migrated ${allSessions.length} sessions from markdown to SQLite.`);
|
|
4159
|
+
return allSessions.length;
|
|
4160
|
+
}
|
|
4161
|
+
async function parseMarkdownSessionsIndex(filePath, projectSlug) {
|
|
4162
|
+
const { readFile: readFile12 } = await import("fs/promises");
|
|
4163
|
+
const raw = await readFile12(filePath, "utf-8");
|
|
4164
|
+
const sessions = [];
|
|
4165
|
+
const lines = raw.split("\n");
|
|
4166
|
+
let inTable = false;
|
|
4167
|
+
let headerSeen = false;
|
|
4168
|
+
for (const line of lines) {
|
|
4169
|
+
const trimmed = line.trim();
|
|
4170
|
+
if (!trimmed) continue;
|
|
4171
|
+
if (trimmed.startsWith("| Assignment") || trimmed.startsWith("|Assignment")) {
|
|
4172
|
+
inTable = true;
|
|
4173
|
+
headerSeen = false;
|
|
4174
|
+
continue;
|
|
4175
|
+
}
|
|
4176
|
+
if (inTable && !headerSeen && trimmed.match(/^\|[-\s|]+\|$/)) {
|
|
4177
|
+
headerSeen = true;
|
|
4178
|
+
continue;
|
|
4179
|
+
}
|
|
4180
|
+
if (inTable && headerSeen && trimmed.startsWith("|")) {
|
|
4181
|
+
const cells = trimmed.split("|").slice(1, -1).map((c) => c.trim());
|
|
4182
|
+
if (cells.length >= 6) {
|
|
4183
|
+
sessions.push({
|
|
4184
|
+
assignmentSlug: cells[0],
|
|
4185
|
+
agent: cells[1],
|
|
4186
|
+
sessionId: cells[2],
|
|
4187
|
+
started: cells[3],
|
|
4188
|
+
status: cells[4] || "active",
|
|
4189
|
+
path: cells[5],
|
|
4190
|
+
projectSlug
|
|
4191
|
+
});
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
}
|
|
4195
|
+
return sessions;
|
|
4196
|
+
}
|
|
4197
|
+
var db, SCHEMA_VERSION, SCHEMA_SQL, POST_MIGRATION_INDEXES_SQL;
|
|
3961
4198
|
var init_session_db = __esm({
|
|
3962
4199
|
"src/dashboard/session-db.ts"() {
|
|
3963
4200
|
"use strict";
|
|
3964
4201
|
init_paths();
|
|
3965
4202
|
init_fs();
|
|
3966
4203
|
db = null;
|
|
4204
|
+
SCHEMA_VERSION = "5";
|
|
4205
|
+
SCHEMA_SQL = `
|
|
4206
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
4207
|
+
session_id TEXT PRIMARY KEY,
|
|
4208
|
+
project_slug TEXT,
|
|
4209
|
+
assignment_slug TEXT,
|
|
4210
|
+
agent TEXT NOT NULL,
|
|
4211
|
+
started TEXT NOT NULL,
|
|
4212
|
+
ended TEXT,
|
|
4213
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
4214
|
+
path TEXT,
|
|
4215
|
+
description TEXT,
|
|
4216
|
+
transcript_path TEXT,
|
|
4217
|
+
pid INTEGER,
|
|
4218
|
+
pid_started_at TEXT,
|
|
4219
|
+
original_head_sha TEXT,
|
|
4220
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
4221
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
4222
|
+
);
|
|
4223
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
|
|
4224
|
+
CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT);
|
|
4225
|
+
`;
|
|
4226
|
+
POST_MIGRATION_INDEXES_SQL = `
|
|
4227
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_slug);
|
|
4228
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_assignment ON sessions(project_slug, assignment_slug);
|
|
4229
|
+
`;
|
|
3967
4230
|
}
|
|
3968
4231
|
});
|
|
3969
4232
|
|
|
3970
4233
|
// src/dashboard/agent-sessions.ts
|
|
4234
|
+
var agent_sessions_exports = {};
|
|
4235
|
+
__export(agent_sessions_exports, {
|
|
4236
|
+
appendSession: () => appendSession,
|
|
4237
|
+
deleteSessions: () => deleteSessions,
|
|
4238
|
+
getSessionById: () => getSessionById,
|
|
4239
|
+
listAllSessions: () => listAllSessions,
|
|
4240
|
+
listProjectSessions: () => listProjectSessions,
|
|
4241
|
+
listSessionsByAssignment: () => listSessionsByAssignment,
|
|
4242
|
+
parseSessionsIndex: () => parseSessionsIndex,
|
|
4243
|
+
reconcileActiveSessions: () => reconcileActiveSessions,
|
|
4244
|
+
updateSessionStatus: () => updateSessionStatus
|
|
4245
|
+
});
|
|
3971
4246
|
import { readFile as readFile8 } from "fs/promises";
|
|
3972
4247
|
import { resolve as resolve10 } from "path";
|
|
3973
4248
|
function rowToSession(row) {
|
|
@@ -3984,19 +4259,155 @@ function rowToSession(row) {
|
|
|
3984
4259
|
transcriptPath: row.transcript_path ?? null,
|
|
3985
4260
|
pid: row.pid ?? null,
|
|
3986
4261
|
pidStartedAt: row.pid_started_at ?? null,
|
|
3987
|
-
originalHeadSha: row.original_head_sha ?? null
|
|
4262
|
+
originalHeadSha: row.original_head_sha ?? null,
|
|
4263
|
+
updatedAt: row.updated_at ?? null
|
|
3988
4264
|
};
|
|
3989
4265
|
}
|
|
4266
|
+
async function parseSessionsIndex(_projectDir, projectSlug) {
|
|
4267
|
+
const db2 = getSessionDb();
|
|
4268
|
+
const rows = db2.prepare("SELECT * FROM sessions WHERE project_slug = ? ORDER BY started DESC").all(projectSlug);
|
|
4269
|
+
return rows.map(rowToSession);
|
|
4270
|
+
}
|
|
4271
|
+
async function appendSession(_projectDir, session, opts) {
|
|
4272
|
+
const db2 = getSessionDb();
|
|
4273
|
+
db2.prepare(`
|
|
4274
|
+
INSERT INTO sessions (session_id, project_slug, assignment_slug, agent, started, status, path, description, transcript_path, pid, pid_started_at, original_head_sha)
|
|
4275
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
4276
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
4277
|
+
project_slug = COALESCE(NULLIF(excluded.project_slug, ''), project_slug),
|
|
4278
|
+
assignment_slug = COALESCE(NULLIF(excluded.assignment_slug, ''), assignment_slug),
|
|
4279
|
+
agent = excluded.agent,
|
|
4280
|
+
status = CASE
|
|
4281
|
+
WHEN status = 'completed' THEN status
|
|
4282
|
+
WHEN status = 'stopped' AND NOT (? AND excluded.status = 'active') THEN status
|
|
4283
|
+
ELSE excluded.status
|
|
4284
|
+
END,
|
|
4285
|
+
path = COALESCE(NULLIF(excluded.path, ''), path),
|
|
4286
|
+
description = COALESCE(NULLIF(excluded.description, ''), description),
|
|
4287
|
+
transcript_path = COALESCE(NULLIF(excluded.transcript_path, ''), transcript_path),
|
|
4288
|
+
pid = COALESCE(excluded.pid, pid),
|
|
4289
|
+
pid_started_at = COALESCE(NULLIF(excluded.pid_started_at, ''), pid_started_at),
|
|
4290
|
+
original_head_sha = COALESCE(NULLIF(original_head_sha, ''), NULLIF(excluded.original_head_sha, '')),
|
|
4291
|
+
updated_at = datetime('now')
|
|
4292
|
+
`).run(
|
|
4293
|
+
session.sessionId,
|
|
4294
|
+
session.projectSlug ?? null,
|
|
4295
|
+
session.assignmentSlug ?? null,
|
|
4296
|
+
session.agent,
|
|
4297
|
+
session.started,
|
|
4298
|
+
session.status,
|
|
4299
|
+
session.path,
|
|
4300
|
+
session.description ?? null,
|
|
4301
|
+
session.transcriptPath ?? null,
|
|
4302
|
+
session.pid ?? null,
|
|
4303
|
+
session.pidStartedAt ?? null,
|
|
4304
|
+
session.originalHeadSha ?? null,
|
|
4305
|
+
opts?.reviveStopped ? 1 : 0
|
|
4306
|
+
);
|
|
4307
|
+
}
|
|
4308
|
+
async function updateSessionStatus(_projectDir, sessionId, status, endedAt) {
|
|
4309
|
+
const db2 = getSessionDb();
|
|
4310
|
+
const isTerminal = status === "completed" || status === "stopped";
|
|
4311
|
+
const result = isTerminal ? db2.prepare(
|
|
4312
|
+
"UPDATE sessions SET status = ?, ended = COALESCE(?, datetime('now')), updated_at = datetime('now') WHERE session_id = ?"
|
|
4313
|
+
).run(status, endedAt ?? null, sessionId) : db2.prepare(
|
|
4314
|
+
"UPDATE sessions SET status = ?, updated_at = datetime('now') WHERE session_id = ?"
|
|
4315
|
+
).run(status, sessionId);
|
|
4316
|
+
return result.changes > 0;
|
|
4317
|
+
}
|
|
4318
|
+
async function listAllSessions(_projectsDir) {
|
|
4319
|
+
const db2 = getSessionDb();
|
|
4320
|
+
const rows = db2.prepare("SELECT * FROM sessions ORDER BY started DESC").all();
|
|
4321
|
+
return rows.map(rowToSession);
|
|
4322
|
+
}
|
|
3990
4323
|
function getSessionById(sessionId) {
|
|
3991
4324
|
const db2 = getSessionDb();
|
|
3992
4325
|
const row = db2.prepare("SELECT * FROM sessions WHERE session_id = ? LIMIT 1").get(sessionId);
|
|
3993
4326
|
return row ? rowToSession(row) : null;
|
|
3994
4327
|
}
|
|
4328
|
+
async function listProjectSessions(_projectsDir, projectSlug, assignmentSlug) {
|
|
4329
|
+
const db2 = getSessionDb();
|
|
4330
|
+
if (assignmentSlug) {
|
|
4331
|
+
const rows2 = db2.prepare(
|
|
4332
|
+
"SELECT * FROM sessions WHERE project_slug = ? AND assignment_slug = ? ORDER BY started DESC"
|
|
4333
|
+
).all(projectSlug, assignmentSlug);
|
|
4334
|
+
return rows2.map(rowToSession);
|
|
4335
|
+
}
|
|
4336
|
+
const rows = db2.prepare("SELECT * FROM sessions WHERE project_slug = ? ORDER BY started DESC").all(projectSlug);
|
|
4337
|
+
return rows.map(rowToSession);
|
|
4338
|
+
}
|
|
4339
|
+
async function deleteSessions(sessionIds) {
|
|
4340
|
+
if (sessionIds.length === 0) return 0;
|
|
4341
|
+
const db2 = getSessionDb();
|
|
4342
|
+
const placeholders = sessionIds.map(() => "?").join(", ");
|
|
4343
|
+
const result = db2.prepare(`DELETE FROM sessions WHERE session_id IN (${placeholders})`).run(...sessionIds);
|
|
4344
|
+
return result.changes;
|
|
4345
|
+
}
|
|
4346
|
+
async function readAssignmentStatusFromPath(assignmentMdPath) {
|
|
4347
|
+
if (!await fileExists(assignmentMdPath)) return null;
|
|
4348
|
+
const raw = await readFile8(assignmentMdPath, "utf-8");
|
|
4349
|
+
const match = raw.match(/^status:\s*(.+)$/m);
|
|
4350
|
+
return match ? match[1].trim() : null;
|
|
4351
|
+
}
|
|
4352
|
+
async function readAssignmentStatus(projectDir, assignmentSlug) {
|
|
4353
|
+
return readAssignmentStatusFromPath(
|
|
4354
|
+
resolve10(projectDir, "assignments", assignmentSlug, "assignment.md")
|
|
4355
|
+
);
|
|
4356
|
+
}
|
|
4357
|
+
async function reconcileActiveSessions(projectsDir, assignmentsDir) {
|
|
4358
|
+
const db2 = getSessionDb();
|
|
4359
|
+
const activeSessions = db2.prepare("SELECT * FROM sessions WHERE status = 'active' AND assignment_slug IS NOT NULL").all();
|
|
4360
|
+
if (activeSessions.length === 0) return 0;
|
|
4361
|
+
const assignmentStatuses = /* @__PURE__ */ new Map();
|
|
4362
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4363
|
+
for (const session of activeSessions) {
|
|
4364
|
+
const aslug = session.assignment_slug;
|
|
4365
|
+
if (!aslug) continue;
|
|
4366
|
+
const projectKey = session.project_slug ?? "__standalone__";
|
|
4367
|
+
const key = `${projectKey}/${aslug}`;
|
|
4368
|
+
if (seen.has(key)) continue;
|
|
4369
|
+
seen.add(key);
|
|
4370
|
+
if (session.project_slug) {
|
|
4371
|
+
const status = await readAssignmentStatus(
|
|
4372
|
+
resolve10(projectsDir, session.project_slug),
|
|
4373
|
+
aslug
|
|
4374
|
+
);
|
|
4375
|
+
if (status) assignmentStatuses.set(key, status);
|
|
4376
|
+
} else if (assignmentsDir) {
|
|
4377
|
+
const status = await readAssignmentStatusFromPath(
|
|
4378
|
+
resolve10(assignmentsDir, aslug, "assignment.md")
|
|
4379
|
+
);
|
|
4380
|
+
if (status) assignmentStatuses.set(key, status);
|
|
4381
|
+
}
|
|
4382
|
+
}
|
|
4383
|
+
let totalUpdated = 0;
|
|
4384
|
+
for (const session of activeSessions) {
|
|
4385
|
+
const projectKey = session.project_slug ?? "__standalone__";
|
|
4386
|
+
const key = `${projectKey}/${session.assignment_slug}`;
|
|
4387
|
+
const assignmentStatus = assignmentStatuses.get(key);
|
|
4388
|
+
if (!assignmentStatus || !DONE_ASSIGNMENT_STATUSES.has(assignmentStatus)) continue;
|
|
4389
|
+
const newStatus = assignmentStatus === "failed" ? "stopped" : "completed";
|
|
4390
|
+
await updateSessionStatus("", session.session_id, newStatus);
|
|
4391
|
+
totalUpdated++;
|
|
4392
|
+
}
|
|
4393
|
+
return totalUpdated;
|
|
4394
|
+
}
|
|
4395
|
+
async function listSessionsByAssignment(projectSlug, assignmentSlug) {
|
|
4396
|
+
const db2 = getSessionDb();
|
|
4397
|
+
const rows = projectSlug === null ? db2.prepare(
|
|
4398
|
+
"SELECT * FROM sessions WHERE assignment_slug = ? AND project_slug IS NULL ORDER BY started DESC"
|
|
4399
|
+
).all(assignmentSlug) : db2.prepare(
|
|
4400
|
+
"SELECT * FROM sessions WHERE project_slug = ? AND assignment_slug = ? ORDER BY started DESC"
|
|
4401
|
+
).all(projectSlug, assignmentSlug);
|
|
4402
|
+
return rows.map(rowToSession);
|
|
4403
|
+
}
|
|
4404
|
+
var DONE_ASSIGNMENT_STATUSES;
|
|
3995
4405
|
var init_agent_sessions = __esm({
|
|
3996
4406
|
"src/dashboard/agent-sessions.ts"() {
|
|
3997
4407
|
"use strict";
|
|
3998
4408
|
init_fs();
|
|
3999
4409
|
init_session_db();
|
|
4410
|
+
DONE_ASSIGNMENT_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "review"]);
|
|
4000
4411
|
}
|
|
4001
4412
|
});
|
|
4002
4413
|
|
|
@@ -5720,13 +6131,16 @@ async function resolveSessionPlan(input, terminal) {
|
|
|
5720
6131
|
env: process.env,
|
|
5721
6132
|
agentId: agent.id,
|
|
5722
6133
|
fallbackWarning,
|
|
5723
|
-
shellFallbackWarning
|
|
6134
|
+
shellFallbackWarning,
|
|
6135
|
+
// Resume continues the SAME session id; fork mints a new one in-agent.
|
|
6136
|
+
session: { sessionId: (input.mode ?? "resume") === "resume" ? session.sessionId : null }
|
|
5724
6137
|
};
|
|
5725
6138
|
}
|
|
5726
6139
|
|
|
5727
6140
|
// src/launch/execute.ts
|
|
5728
6141
|
import { spawn as spawn3 } from "child_process";
|
|
5729
|
-
import {
|
|
6142
|
+
import { homedir as homedir5 } from "os";
|
|
6143
|
+
import { basename as basename2, join as join5, resolve as resolve14 } from "path";
|
|
5730
6144
|
|
|
5731
6145
|
// src/utils/terminal-probe.ts
|
|
5732
6146
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
@@ -5798,6 +6212,52 @@ function resolveCmuxCli(applicationsDirsOverride, cliDirsOverride, lsappinfoRunn
|
|
|
5798
6212
|
return null;
|
|
5799
6213
|
}
|
|
5800
6214
|
|
|
6215
|
+
// src/launch/execute.ts
|
|
6216
|
+
init_fs();
|
|
6217
|
+
init_config2();
|
|
6218
|
+
|
|
6219
|
+
// src/utils/session-id.ts
|
|
6220
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
6221
|
+
import { mkdirSync, readFileSync, statSync as statSync2, writeFileSync } from "fs";
|
|
6222
|
+
import { homedir as homedir4 } from "os";
|
|
6223
|
+
import { dirname as dirname3, join as join4 } from "path";
|
|
6224
|
+
|
|
6225
|
+
// src/utils/process-info.ts
|
|
6226
|
+
import { execFileSync } from "child_process";
|
|
6227
|
+
function captureProcessStartedAt(pid) {
|
|
6228
|
+
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
6229
|
+
try {
|
|
6230
|
+
const out = execFileSync("ps", ["-o", "lstart=", "-p", String(pid)], {
|
|
6231
|
+
encoding: "utf8",
|
|
6232
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
6233
|
+
});
|
|
6234
|
+
const trimmed = out.trim();
|
|
6235
|
+
return trimmed === "" ? null : trimmed;
|
|
6236
|
+
} catch {
|
|
6237
|
+
return null;
|
|
6238
|
+
}
|
|
6239
|
+
}
|
|
6240
|
+
|
|
6241
|
+
// src/usage/cwd-extractor.ts
|
|
6242
|
+
init_paths();
|
|
6243
|
+
import { open as open2, readdir as readdir8, stat } from "fs/promises";
|
|
6244
|
+
import { join as join3 } from "path";
|
|
6245
|
+
import { homedir as homedir3 } from "os";
|
|
6246
|
+
|
|
6247
|
+
// src/utils/transcript.ts
|
|
6248
|
+
import { open } from "fs/promises";
|
|
6249
|
+
|
|
6250
|
+
// src/usage/cwd-extractor.ts
|
|
6251
|
+
var TAIL_READ_BYTES = 8 * 1024;
|
|
6252
|
+
var TAIL_READ_BYTES_MAX = 64 * 1024;
|
|
6253
|
+
|
|
6254
|
+
// src/utils/session-id.ts
|
|
6255
|
+
function writeRuntimeMarker(pid, marker, dir) {
|
|
6256
|
+
const path = join4(dir, `${pid}.json`);
|
|
6257
|
+
mkdirSync(dirname3(path), { recursive: true });
|
|
6258
|
+
writeFileSync(path, JSON.stringify(marker));
|
|
6259
|
+
}
|
|
6260
|
+
|
|
5801
6261
|
// src/launch/execute.ts
|
|
5802
6262
|
var TerminalNotFoundError = class extends Error {
|
|
5803
6263
|
terminal;
|
|
@@ -5841,7 +6301,7 @@ async function executeLaunchPlan(plan, spawnFn = realSpawn) {
|
|
|
5841
6301
|
`Spawn failed: ${msg}. Verify the terminal is installed and on PATH.`
|
|
5842
6302
|
);
|
|
5843
6303
|
}
|
|
5844
|
-
await new Promise((
|
|
6304
|
+
await new Promise((resolve16, reject) => {
|
|
5845
6305
|
let settled = false;
|
|
5846
6306
|
let stderr = "";
|
|
5847
6307
|
const finishOk = () => {
|
|
@@ -5851,7 +6311,7 @@ async function executeLaunchPlan(plan, spawnFn = realSpawn) {
|
|
|
5851
6311
|
child.unref();
|
|
5852
6312
|
} catch {
|
|
5853
6313
|
}
|
|
5854
|
-
|
|
6314
|
+
resolve16();
|
|
5855
6315
|
};
|
|
5856
6316
|
const finishErr = (remediation) => {
|
|
5857
6317
|
if (settled) return;
|
|
@@ -5887,6 +6347,57 @@ async function executeLaunchPlan(plan, spawnFn = realSpawn) {
|
|
|
5887
6347
|
});
|
|
5888
6348
|
}
|
|
5889
6349
|
});
|
|
6350
|
+
await registerLaunchAtBirth(plan, child);
|
|
6351
|
+
}
|
|
6352
|
+
async function registerLaunchAtBirth(plan, child) {
|
|
6353
|
+
try {
|
|
6354
|
+
const pid = child.pid;
|
|
6355
|
+
if (!pid) return;
|
|
6356
|
+
const autoTrack = (await readConfig()).session.autoTrack;
|
|
6357
|
+
if (autoTrack === "off") return;
|
|
6358
|
+
const sessionId = plan.session?.sessionId ?? null;
|
|
6359
|
+
const procStart = captureProcessStartedAt(pid);
|
|
6360
|
+
const envDir = process.env.SYNTAUR_RUNTIME_SESSIONS_DIR;
|
|
6361
|
+
const markerDir = envDir && envDir.length > 0 ? envDir : join5(homedir5(), ".syntaur", "runtime", "sessions");
|
|
6362
|
+
writeRuntimeMarker(
|
|
6363
|
+
pid,
|
|
6364
|
+
{
|
|
6365
|
+
...sessionId ? { sessionId } : {},
|
|
6366
|
+
agent: plan.agentId,
|
|
6367
|
+
cwd: plan.cwd,
|
|
6368
|
+
...procStart ? { procStart } : {},
|
|
6369
|
+
writtenAt: Date.now()
|
|
6370
|
+
},
|
|
6371
|
+
markerDir
|
|
6372
|
+
);
|
|
6373
|
+
if (!sessionId) return;
|
|
6374
|
+
if (autoTrack === "workspaces-only" && !await fileExists(resolve14(plan.cwd, ".syntaur", "context.json"))) {
|
|
6375
|
+
return;
|
|
6376
|
+
}
|
|
6377
|
+
const { initSessionDb: initSessionDb2 } = await Promise.resolve().then(() => (init_session_db(), session_db_exports));
|
|
6378
|
+
const { appendSession: appendSession2 } = await Promise.resolve().then(() => (init_agent_sessions(), agent_sessions_exports));
|
|
6379
|
+
initSessionDb2();
|
|
6380
|
+
await appendSession2(
|
|
6381
|
+
"",
|
|
6382
|
+
{
|
|
6383
|
+
sessionId,
|
|
6384
|
+
projectSlug: null,
|
|
6385
|
+
assignmentSlug: null,
|
|
6386
|
+
agent: plan.agentId,
|
|
6387
|
+
started: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6388
|
+
status: "active",
|
|
6389
|
+
path: plan.cwd,
|
|
6390
|
+
description: null,
|
|
6391
|
+
transcriptPath: null,
|
|
6392
|
+
pid,
|
|
6393
|
+
pidStartedAt: procStart,
|
|
6394
|
+
originalHeadSha: null
|
|
6395
|
+
},
|
|
6396
|
+
// Resuming a stopped session IS live-process evidence — we just spawned it.
|
|
6397
|
+
{ reviveStopped: true }
|
|
6398
|
+
);
|
|
6399
|
+
} catch {
|
|
6400
|
+
}
|
|
5890
6401
|
}
|
|
5891
6402
|
var CMUX_BUNDLE_ID = "com.cmuxterm.app";
|
|
5892
6403
|
var CMUX_READINESS_MAX_MS = 20 * 250;
|
|
@@ -6036,8 +6547,8 @@ function appleScriptString(value) {
|
|
|
6036
6547
|
init_paths();
|
|
6037
6548
|
init_fs();
|
|
6038
6549
|
import { fileURLToPath } from "url";
|
|
6039
|
-
import { dirname as
|
|
6040
|
-
import { realpathSync, readFileSync, mkdirSync } from "fs";
|
|
6550
|
+
import { dirname as dirname4, resolve as resolve15, join as join6 } from "path";
|
|
6551
|
+
import { realpathSync, readFileSync as readFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
6041
6552
|
var NPX_PATTERNS = [
|
|
6042
6553
|
{ kind: "npm", re: /\/_npx\/([^/]+)\/node_modules(?:\/|$)/ },
|
|
6043
6554
|
{ kind: "pnpm", re: /\/pnpm\/dlx\/([^/]+)\/node_modules(?:\/|$)/ },
|
|
@@ -6062,7 +6573,7 @@ function normalizeSlashes(p) {
|
|
|
6062
6573
|
}
|
|
6063
6574
|
function detectInstallKind(scriptUrl, opts = {}) {
|
|
6064
6575
|
const realpath = opts.realpath ?? realpathSync.native;
|
|
6065
|
-
const readFile12 = opts.readFile ?? ((p) =>
|
|
6576
|
+
const readFile12 = opts.readFile ?? ((p) => readFileSync2(p, "utf-8"));
|
|
6066
6577
|
const ua = opts.envUserAgent !== void 0 ? opts.envUserAgent : process.env.npm_config_user_agent ?? "";
|
|
6067
6578
|
const resolved = resolveScriptPath(scriptUrl, realpath);
|
|
6068
6579
|
if (resolved === null) {
|
|
@@ -6078,14 +6589,14 @@ function detectInstallKind(scriptUrl, opts = {}) {
|
|
|
6078
6589
|
if (GLOBAL_PATTERN.test(norm)) {
|
|
6079
6590
|
return "global";
|
|
6080
6591
|
}
|
|
6081
|
-
let dir =
|
|
6592
|
+
let dir = dirname4(resolved);
|
|
6082
6593
|
for (let depth = 0; depth < 8; depth++) {
|
|
6083
|
-
const pkgJsonPath =
|
|
6594
|
+
const pkgJsonPath = join6(dir, "package.json");
|
|
6084
6595
|
let raw;
|
|
6085
6596
|
try {
|
|
6086
6597
|
raw = readFile12(pkgJsonPath);
|
|
6087
6598
|
} catch {
|
|
6088
|
-
const parent2 =
|
|
6599
|
+
const parent2 = dirname4(dir);
|
|
6089
6600
|
if (parent2 === dir) break;
|
|
6090
6601
|
dir = parent2;
|
|
6091
6602
|
continue;
|
|
@@ -6097,7 +6608,7 @@ function detectInstallKind(scriptUrl, opts = {}) {
|
|
|
6097
6608
|
}
|
|
6098
6609
|
} catch {
|
|
6099
6610
|
}
|
|
6100
|
-
const parent =
|
|
6611
|
+
const parent = dirname4(dir);
|
|
6101
6612
|
if (parent === dir) break;
|
|
6102
6613
|
dir = parent;
|
|
6103
6614
|
}
|
|
@@ -6115,20 +6626,20 @@ function extractNpxHash(scriptUrl, opts = {}) {
|
|
|
6115
6626
|
return null;
|
|
6116
6627
|
}
|
|
6117
6628
|
function nudgeStampDir() {
|
|
6118
|
-
return
|
|
6629
|
+
return resolve15(syntaurRoot(), "npx-handler-nudge");
|
|
6119
6630
|
}
|
|
6120
6631
|
function sanitizeHash(hash) {
|
|
6121
6632
|
return hash.replace(/[^A-Za-z0-9_-]/g, "_") || "_";
|
|
6122
6633
|
}
|
|
6123
6634
|
function nudgeStampPath(hash) {
|
|
6124
|
-
return
|
|
6635
|
+
return join6(nudgeStampDir(), sanitizeHash(hash));
|
|
6125
6636
|
}
|
|
6126
6637
|
async function hasNudgedHash(hash) {
|
|
6127
6638
|
return fileExists(nudgeStampPath(hash));
|
|
6128
6639
|
}
|
|
6129
6640
|
async function recordNudge(hash) {
|
|
6130
6641
|
try {
|
|
6131
|
-
|
|
6642
|
+
mkdirSync2(nudgeStampDir(), { recursive: true });
|
|
6132
6643
|
} catch {
|
|
6133
6644
|
}
|
|
6134
6645
|
try {
|