syntaur 0.76.0 → 0.77.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-BiwSunXO.js → _basePickBy-CmtR3VlC.js} +1 -1
- package/dashboard/dist/assets/{_baseUniq-DsjKPXxP.js → _baseUniq-d5yVqkuO.js} +1 -1
- package/dashboard/dist/assets/{arc-DlEs4wsF.js → arc-BTfvlUzk.js} +1 -1
- package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-DPvCrO57.js → architectureDiagram-2XIMDMQ5-ComKmfQn.js} +1 -1
- package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-CpNdCY-r.js → blockDiagram-WCTKOSBZ-69xtTOqC.js} +1 -1
- package/dashboard/dist/assets/{c4Diagram-IC4MRINW-CC29QJCs.js → c4Diagram-IC4MRINW-B5MsrIyR.js} +1 -1
- package/dashboard/dist/assets/channel-B55sx3Pw.js +1 -0
- package/dashboard/dist/assets/{chunk-4BX2VUAB-DKyy-k2D.js → chunk-4BX2VUAB-BV-rQx2S.js} +1 -1
- package/dashboard/dist/assets/{chunk-55IACEB6-DjobngQk.js → chunk-55IACEB6-BHoZ0_2C.js} +1 -1
- package/dashboard/dist/assets/{chunk-FMBD7UC4-BUftm7dV.js → chunk-FMBD7UC4-BZppz6s9.js} +1 -1
- package/dashboard/dist/assets/{chunk-JSJVCQXG-Nv7rQv4t.js → chunk-JSJVCQXG-BKJIycjQ.js} +1 -1
- package/dashboard/dist/assets/{chunk-KX2RTZJC-Dg6UhNB9.js → chunk-KX2RTZJC-Drv6rL3f.js} +1 -1
- package/dashboard/dist/assets/{chunk-NQ4KR5QH-D8neQrJ_.js → chunk-NQ4KR5QH-u1ws00gN.js} +1 -1
- package/dashboard/dist/assets/{chunk-QZHKN3VN-Uj9c1naA.js → chunk-QZHKN3VN-zCyNaZcO.js} +1 -1
- package/dashboard/dist/assets/{chunk-WL4C6EOR-DfeSsP3z.js → chunk-WL4C6EOR-Dz0hDBUx.js} +1 -1
- package/dashboard/dist/assets/classDiagram-VBA2DB6C-Kgg-J05j.js +1 -0
- package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-Kgg-J05j.js +1 -0
- package/dashboard/dist/assets/clone-DXxPBQmb.js +1 -0
- package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-CLfZNKcO.js → cose-bilkent-S5V4N54A-CO0Ms-ys.js} +1 -1
- package/dashboard/dist/assets/{dagre-KLK3FWXG-DyJLICZx.js → dagre-KLK3FWXG-BDBGlQ5i.js} +1 -1
- package/dashboard/dist/assets/{diagram-E7M64L7V-DhQc7Ta3.js → diagram-E7M64L7V-C1jhhA3a.js} +1 -1
- package/dashboard/dist/assets/{diagram-IFDJBPK2-C6kFO7hB.js → diagram-IFDJBPK2-DYA2G930.js} +1 -1
- package/dashboard/dist/assets/{diagram-P4PSJMXO-B6oCiOXk.js → diagram-P4PSJMXO-iox20fhC.js} +1 -1
- package/dashboard/dist/assets/{erDiagram-INFDFZHY-BsMPaSwJ.js → erDiagram-INFDFZHY-CdrG4ZUW.js} +1 -1
- package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-DLxEqKtZ.js → flowDiagram-PKNHOUZH-CMuagI-6.js} +1 -1
- package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-D70pvqxG.js → ganttDiagram-A5KZAMGK-C8jgdfRO.js} +1 -1
- package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-D74VHtlE.js → gitGraphDiagram-K3NZZRJ6-Chu0FgBt.js} +1 -1
- package/dashboard/dist/assets/{graph-C8bz_IEO.js → graph-RWP7g4cL.js} +1 -1
- package/dashboard/dist/assets/{index-h-X_8om3.js → index-BFpKR1Z0.js} +163 -148
- package/dashboard/dist/assets/{index-BetqH_3H.css → index-C6KBRx3q.css} +1 -1
- package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-DivBd0Pz.js → infoDiagram-LFFYTUFH-bIlmxe7x.js} +1 -1
- package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-BGihUeOE.js → ishikawaDiagram-PHBUUO56-CvvXAmzr.js} +1 -1
- package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-C7U4cWHQ.js → journeyDiagram-4ABVD52K-BlSVnlQk.js} +1 -1
- package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-CFp_hDTm.js → kanban-definition-K7BYSVSG-D6kAus7L.js} +1 -1
- package/dashboard/dist/assets/{layout-DMSDPqCs.js → layout-BIoVL4m2.js} +1 -1
- package/dashboard/dist/assets/{linear-CCC-meYc.js → linear-B4ySyXON.js} +1 -1
- package/dashboard/dist/assets/{mermaid.core-BDa2cc2K.js → mermaid.core-B_8IjgQO.js} +4 -4
- package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-DLKvONhO.js → mindmap-definition-YRQLILUH-B6RTS8xi.js} +1 -1
- package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-DAJoGZ93.js → pieDiagram-SKSYHLDU-EntB8Xmg.js} +1 -1
- package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-Bo7haX1W.js → quadrantDiagram-337W2JSQ-UTEbe4g6.js} +1 -1
- package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-uEvGz33v.js → requirementDiagram-Z7DCOOCP-qG2oV68i.js} +1 -1
- package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-cjYoCGCM.js → sankeyDiagram-WA2Y5GQK-C-EzJpn8.js} +1 -1
- package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-CYXcNklt.js → sequenceDiagram-2WXFIKYE-rCjfcAr5.js} +1 -1
- package/dashboard/dist/assets/{stateDiagram-RAJIS63D-B5We7jAw.js → stateDiagram-RAJIS63D-C3hoQmLC.js} +1 -1
- package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-rHFeeHzp.js +1 -0
- package/dashboard/dist/assets/{timeline-definition-YZTLITO2-CEqVmnVQ.js → timeline-definition-YZTLITO2-2gGWKHHW.js} +1 -1
- package/dashboard/dist/assets/{treemap-KZPCXAKY-CE1puPeN.js → treemap-KZPCXAKY-BV6TTFvC.js} +1 -1
- package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-CiiuRUjK.js → vennDiagram-LZ73GAT5-C1aeXQ29.js} +1 -1
- package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-B0OuxFm9.js → xychartDiagram-JWTSCODW-BDbba6Mg.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dist/dashboard/server.js +845 -147
- package/dist/dashboard/server.js.map +1 -1
- package/dist/index.js +1290 -547
- package/dist/index.js.map +1 -1
- package/dist/launch/index.d.ts +41 -0
- package/dist/launch/index.js +200 -21
- 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
- package/dashboard/dist/assets/channel-IutbH48W.js +0 -1
- package/dashboard/dist/assets/classDiagram-VBA2DB6C-8IywRj9I.js +0 -1
- package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-8IywRj9I.js +0 -1
- package/dashboard/dist/assets/clone-C6saGiCd.js +0 -1
- package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-CX9-EpBi.js +0 -1
package/dist/launch/index.d.ts
CHANGED
|
@@ -70,6 +70,10 @@ declare function parseOpenUrl(input: string): ParsedOpenUrl;
|
|
|
70
70
|
type BindableActionKind = 'new-workspace' | 'new-project' | 'new-todo' | 'new-assignment';
|
|
71
71
|
|
|
72
72
|
type PromptArgPosition = 'first' | 'last' | 'none';
|
|
73
|
+
/** Runner family an agent belongs to — the intrinsic "type badge". */
|
|
74
|
+
type RunnerKind = 'claude' | 'pi' | 'codex';
|
|
75
|
+
/** Which discovery source a registered agent's on-disk def was adopted from. */
|
|
76
|
+
type AgentSourceKind = 'claude-global' | 'claude-project' | 'directory';
|
|
73
77
|
/**
|
|
74
78
|
* Per-agent argv recipe for continuing a recorded session in a specific mode.
|
|
75
79
|
*
|
|
@@ -135,6 +139,27 @@ interface AgentConfig {
|
|
|
135
139
|
* `agentName`. Existence is validated at launch time, not at config-write time.
|
|
136
140
|
*/
|
|
137
141
|
workdir?: string;
|
|
142
|
+
/**
|
|
143
|
+
* Intrinsic runner family — the type badge shown in the unified agent list
|
|
144
|
+
* (claude / pi / codex). Authoritative when set; `resolveRunner` infers it for
|
|
145
|
+
* legacy rows. Never a user-toggled "mode". When set explicitly it constrains
|
|
146
|
+
* the identity field: a `claude` runner uses `agentName` (not `workdir`); a
|
|
147
|
+
* `pi`/`codex` runner uses `workdir` (not `agentName`) — enforced in
|
|
148
|
+
* `validateAgentList`.
|
|
149
|
+
*/
|
|
150
|
+
runner?: RunnerKind;
|
|
151
|
+
/**
|
|
152
|
+
* Source pointer (flat scalars, NOT a nested object — so they ride the scalar
|
|
153
|
+
* config-field machinery) to the on-disk def a registered agent was adopted
|
|
154
|
+
* from. The def stays the source of truth for identity content; these exist for
|
|
155
|
+
* display, dedupe ("already registered"), and refresh. `sourcePath` is the
|
|
156
|
+
* `.md` file for a claude agent or the directory for a directory agent (===
|
|
157
|
+
* `workdir`). `sourceRepo` is the repo root for a `claude-project` def (used to
|
|
158
|
+
* reason about cross-repo `--agent` resolution).
|
|
159
|
+
*/
|
|
160
|
+
sourceKind?: AgentSourceKind;
|
|
161
|
+
sourcePath?: string;
|
|
162
|
+
sourceRepo?: string;
|
|
138
163
|
}
|
|
139
164
|
|
|
140
165
|
/**
|
|
@@ -322,6 +347,18 @@ interface HotkeyBindingsConfig {
|
|
|
322
347
|
* - `off`: no automatic DB writes (manual `track-session` still works).
|
|
323
348
|
*/
|
|
324
349
|
type SessionAutoTrack = 'all' | 'workspaces-only' | 'off';
|
|
350
|
+
/**
|
|
351
|
+
* Multi-source agent discovery settings. Sources are individually toggleable;
|
|
352
|
+
* `roots` is the depth-1 directory-scan root list (default `~`). Persisted as an
|
|
353
|
+
* `agentDiscovery:` block whose one-level keys read back as dotted `fm` keys
|
|
354
|
+
* (roots is a `:`-separated scalar to avoid list-parsing in the top-level map).
|
|
355
|
+
*/
|
|
356
|
+
interface AgentDiscoveryConfig {
|
|
357
|
+
claudeGlobal: boolean;
|
|
358
|
+
claudeProject: boolean;
|
|
359
|
+
directory: boolean;
|
|
360
|
+
roots: string[];
|
|
361
|
+
}
|
|
325
362
|
interface SyntaurConfig {
|
|
326
363
|
version: string;
|
|
327
364
|
defaultProjectDir: string;
|
|
@@ -350,6 +387,10 @@ interface SyntaurConfig {
|
|
|
350
387
|
/** Opt-in: run the read-only staleness watchdog on the dashboard loop (emits
|
|
351
388
|
* staleness-detected/cleared audit events; never mutates status). Off by default. */
|
|
352
389
|
stalenessWatchdog: boolean;
|
|
390
|
+
/** Default cwd for a standalone claude-agent launch (null → home at launch). */
|
|
391
|
+
standaloneDefaultCwd: string | null;
|
|
392
|
+
/** Multi-source agent discovery settings (sources on/off + scan roots). */
|
|
393
|
+
agentDiscovery: AgentDiscoveryConfig;
|
|
353
394
|
}
|
|
354
395
|
|
|
355
396
|
/**
|
package/dist/launch/index.js
CHANGED
|
@@ -1239,6 +1239,14 @@ function agentNameArgs(agent) {
|
|
|
1239
1239
|
const n = agent.agentName?.trim();
|
|
1240
1240
|
return n ? ["--agent", n] : [];
|
|
1241
1241
|
}
|
|
1242
|
+
function resolveRunner(agent) {
|
|
1243
|
+
if (agent.runner) return agent.runner;
|
|
1244
|
+
if (agent.agentName && agent.agentName.trim() !== "") return "claude";
|
|
1245
|
+
const cmd = agent.command ?? "";
|
|
1246
|
+
if (/claude/i.test(cmd) || agent.id === "claude") return "claude";
|
|
1247
|
+
if (/codex/i.test(cmd) || agent.id === "codex") return "codex";
|
|
1248
|
+
return "pi";
|
|
1249
|
+
}
|
|
1242
1250
|
function stripModelFlags(args) {
|
|
1243
1251
|
const out = [];
|
|
1244
1252
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -2451,6 +2459,7 @@ __export(config_exports, {
|
|
|
2451
2459
|
parseStatusConfig: () => parseStatusConfig,
|
|
2452
2460
|
parseTerminalConfig: () => parseTerminalConfig,
|
|
2453
2461
|
readConfig: () => readConfig,
|
|
2462
|
+
serializeAgentDiscoveryConfig: () => serializeAgentDiscoveryConfig,
|
|
2454
2463
|
serializeSearchConfig: () => serializeSearchConfig,
|
|
2455
2464
|
serializeStatusConfig: () => serializeStatusConfig,
|
|
2456
2465
|
toTitleCase: () => toTitleCase,
|
|
@@ -2464,6 +2473,7 @@ __export(config_exports, {
|
|
|
2464
2473
|
validateDeriveShape: () => validateDeriveShape,
|
|
2465
2474
|
validateFactDeclarations: () => validateFactDeclarations,
|
|
2466
2475
|
validateStalenessConfig: () => validateStalenessConfig,
|
|
2476
|
+
writeAgentDiscoveryConfig: () => writeAgentDiscoveryConfig,
|
|
2467
2477
|
writeAgentsConfig: () => writeAgentsConfig,
|
|
2468
2478
|
writeHotkeyBindingsConfig: () => writeHotkeyBindingsConfig,
|
|
2469
2479
|
writeSearchConfig: () => writeSearchConfig,
|
|
@@ -2556,6 +2566,50 @@ function validateAgentList(agents) {
|
|
|
2556
2566
|
`agent "${agent.id}" sets both agentName and model \u2014 the agent definition's own model is authoritative; remove the profile model`
|
|
2557
2567
|
);
|
|
2558
2568
|
}
|
|
2569
|
+
if (agent.runner !== void 0 && !RUNNER_KINDS.includes(agent.runner)) {
|
|
2570
|
+
throw new AgentConfigError(
|
|
2571
|
+
`agent "${agent.id}" has invalid runner "${agent.runner}" \u2014 must be one of ${RUNNER_KINDS.join(", ")}`
|
|
2572
|
+
);
|
|
2573
|
+
}
|
|
2574
|
+
if (agent.sourceKind !== void 0 && !AGENT_SOURCE_KINDS.includes(agent.sourceKind)) {
|
|
2575
|
+
throw new AgentConfigError(
|
|
2576
|
+
`agent "${agent.id}" has invalid sourceKind "${agent.sourceKind}" \u2014 must be one of ${AGENT_SOURCE_KINDS.join(", ")}`
|
|
2577
|
+
);
|
|
2578
|
+
}
|
|
2579
|
+
if (agent.sourcePath !== void 0 && /[\r\n]/.test(agent.sourcePath)) {
|
|
2580
|
+
throw new AgentConfigError(
|
|
2581
|
+
`agent "${agent.id}" has invalid sourcePath \u2014 must be a single line (no newlines)`
|
|
2582
|
+
);
|
|
2583
|
+
}
|
|
2584
|
+
if (agent.sourceRepo !== void 0 && /[\r\n]/.test(agent.sourceRepo)) {
|
|
2585
|
+
throw new AgentConfigError(
|
|
2586
|
+
`agent "${agent.id}" has invalid sourceRepo \u2014 must be a single line (no newlines)`
|
|
2587
|
+
);
|
|
2588
|
+
}
|
|
2589
|
+
if (agent.runner === "claude" && agent.workdir !== void 0 && agent.workdir.trim() !== "") {
|
|
2590
|
+
throw new AgentConfigError(
|
|
2591
|
+
`agent "${agent.id}" has runner "claude" but sets workdir \u2014 a claude agent uses agentName, not workdir`
|
|
2592
|
+
);
|
|
2593
|
+
}
|
|
2594
|
+
if ((agent.runner === "pi" || agent.runner === "codex") && agent.agentName !== void 0 && agent.agentName.trim() !== "") {
|
|
2595
|
+
throw new AgentConfigError(
|
|
2596
|
+
`agent "${agent.id}" has runner "${agent.runner}" but sets agentName \u2014 a directory agent uses workdir, not agentName`
|
|
2597
|
+
);
|
|
2598
|
+
}
|
|
2599
|
+
if (agent.runner !== void 0 && agent.sourceKind !== void 0) {
|
|
2600
|
+
const directorySource = agent.sourceKind === "directory";
|
|
2601
|
+
const claudeRunner = agent.runner === "claude";
|
|
2602
|
+
if (directorySource && claudeRunner) {
|
|
2603
|
+
throw new AgentConfigError(
|
|
2604
|
+
`agent "${agent.id}" has sourceKind "directory" but runner "claude" \u2014 a directory source is a pi/codex agent`
|
|
2605
|
+
);
|
|
2606
|
+
}
|
|
2607
|
+
if (!directorySource && !claudeRunner) {
|
|
2608
|
+
throw new AgentConfigError(
|
|
2609
|
+
`agent "${agent.id}" has sourceKind "${agent.sourceKind}" but runner "${agent.runner}" \u2014 a ${agent.sourceKind} source is a claude agent`
|
|
2610
|
+
);
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2559
2613
|
validateSessionInvocation(agent, "resume", agent.resume);
|
|
2560
2614
|
validateSessionInvocation(agent, "fork", agent.fork);
|
|
2561
2615
|
if (agent.default) defaults++;
|
|
@@ -2658,6 +2712,21 @@ function parseInstalledAgents(fm) {
|
|
|
2658
2712
|
}
|
|
2659
2713
|
return Object.keys(installedAgents).length > 0 ? { installedAgents } : {};
|
|
2660
2714
|
}
|
|
2715
|
+
function parseAgentDiscoveryFromFm(fm) {
|
|
2716
|
+
const flag = (key, def) => {
|
|
2717
|
+
const v = fm[key];
|
|
2718
|
+
if (v === void 0) return def;
|
|
2719
|
+
return String(v).toLowerCase() === "true";
|
|
2720
|
+
};
|
|
2721
|
+
const rootsRaw = fm["agentDiscovery.roots"];
|
|
2722
|
+
const roots = rootsRaw !== void 0 && String(rootsRaw).trim() !== "" ? String(rootsRaw).split(":").map((r) => r.trim()).filter((r) => r.length > 0) : [];
|
|
2723
|
+
return {
|
|
2724
|
+
claudeGlobal: flag("agentDiscovery.claudeGlobal", true),
|
|
2725
|
+
claudeProject: flag("agentDiscovery.claudeProject", true),
|
|
2726
|
+
directory: flag("agentDiscovery.directory", true),
|
|
2727
|
+
roots: roots.length > 0 ? roots : DEFAULT_CONFIG.agentDiscovery.roots.slice()
|
|
2728
|
+
};
|
|
2729
|
+
}
|
|
2661
2730
|
function parseStatusConfig(content) {
|
|
2662
2731
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
2663
2732
|
if (!match) return null;
|
|
@@ -3166,6 +3235,43 @@ ${cleanedFm}
|
|
|
3166
3235
|
---${afterFrontmatter}`;
|
|
3167
3236
|
await writeFileForce(configPath, newContent);
|
|
3168
3237
|
}
|
|
3238
|
+
function serializeAgentDiscoveryConfig(cfg) {
|
|
3239
|
+
return [
|
|
3240
|
+
"agentDiscovery:",
|
|
3241
|
+
` claudeGlobal: ${cfg.claudeGlobal}`,
|
|
3242
|
+
` claudeProject: ${cfg.claudeProject}`,
|
|
3243
|
+
` directory: ${cfg.directory}`,
|
|
3244
|
+
` roots: ${cfg.roots.join(":")}`
|
|
3245
|
+
].join("\n");
|
|
3246
|
+
}
|
|
3247
|
+
async function writeAgentDiscoveryConfig(cfg, standaloneDefaultCwd) {
|
|
3248
|
+
const configPath = resolve7(syntaurRoot(), "config.md");
|
|
3249
|
+
const block = serializeAgentDiscoveryConfig(cfg);
|
|
3250
|
+
const scalarLine = standaloneDefaultCwd ? `standaloneDefaultCwd: ${standaloneDefaultCwd}` : "";
|
|
3251
|
+
const additions = [block, scalarLine].filter(Boolean).join("\n");
|
|
3252
|
+
const existing = await fileExists(configPath) ? await readFile5(configPath, "utf-8") : renderConfig({ defaultProjectDir: defaultProjectDir() });
|
|
3253
|
+
const fmMatch = existing.match(/^(---\n)([\s\S]*?)\n(---)/);
|
|
3254
|
+
if (!fmMatch) {
|
|
3255
|
+
const content = `---
|
|
3256
|
+
version: "2.0"
|
|
3257
|
+
defaultProjectDir: ${defaultProjectDir()}
|
|
3258
|
+
${additions}
|
|
3259
|
+
---
|
|
3260
|
+
${existing}`;
|
|
3261
|
+
await writeFileForce(configPath, content);
|
|
3262
|
+
return;
|
|
3263
|
+
}
|
|
3264
|
+
const fmBlock = fmMatch[2];
|
|
3265
|
+
const afterFrontmatter = existing.slice(fmMatch[0].length);
|
|
3266
|
+
let cleanedFm = stripTopLevelBlock(fmBlock, "agentDiscovery");
|
|
3267
|
+
cleanedFm = stripTopLevelScalar(cleanedFm, "standaloneDefaultCwd");
|
|
3268
|
+
const newFm = `${cleanedFm}
|
|
3269
|
+
${additions}`.replace(/^\n+/, "").replace(/\n+$/, "");
|
|
3270
|
+
const newContent = `---
|
|
3271
|
+
${newFm}
|
|
3272
|
+
---${afterFrontmatter}`;
|
|
3273
|
+
await writeFileForce(configPath, newContent);
|
|
3274
|
+
}
|
|
3169
3275
|
function stripTopLevelScalar(fmBlock, key) {
|
|
3170
3276
|
const lines = fmBlock.split("\n");
|
|
3171
3277
|
const keyRegex = new RegExp(`^${key}:\\s*\\S`);
|
|
@@ -3378,6 +3484,10 @@ function parseAgentsConfig(content) {
|
|
|
3378
3484
|
...current.launchPrompt ? { launchPrompt: current.launchPrompt } : {},
|
|
3379
3485
|
...current.agentName ? { agentName: current.agentName } : {},
|
|
3380
3486
|
...current.workdir ? { workdir: current.workdir } : {},
|
|
3487
|
+
...current.runner ? { runner: current.runner } : {},
|
|
3488
|
+
...current.sourceKind ? { sourceKind: current.sourceKind } : {},
|
|
3489
|
+
...current.sourcePath ? { sourcePath: current.sourcePath } : {},
|
|
3490
|
+
...current.sourceRepo ? { sourceRepo: current.sourceRepo } : {},
|
|
3381
3491
|
...current.resume ? { resume: current.resume } : {},
|
|
3382
3492
|
...current.fork ? { fork: current.fork } : {}
|
|
3383
3493
|
});
|
|
@@ -3575,6 +3685,18 @@ function assignAgentField(target, key, rawValue) {
|
|
|
3575
3685
|
case "workdir":
|
|
3576
3686
|
target.workdir = value;
|
|
3577
3687
|
break;
|
|
3688
|
+
case "runner":
|
|
3689
|
+
target.runner = value;
|
|
3690
|
+
break;
|
|
3691
|
+
case "sourceKind":
|
|
3692
|
+
target.sourceKind = value;
|
|
3693
|
+
break;
|
|
3694
|
+
case "sourcePath":
|
|
3695
|
+
target.sourcePath = value;
|
|
3696
|
+
break;
|
|
3697
|
+
case "sourceRepo":
|
|
3698
|
+
target.sourceRepo = value;
|
|
3699
|
+
break;
|
|
3578
3700
|
}
|
|
3579
3701
|
}
|
|
3580
3702
|
function yamlQuoteScalar(value) {
|
|
@@ -3610,6 +3732,18 @@ function serializeAgentsConfig(agents) {
|
|
|
3610
3732
|
if (a.workdir) {
|
|
3611
3733
|
lines.push(` workdir: ${yamlQuoteScalar(a.workdir)}`);
|
|
3612
3734
|
}
|
|
3735
|
+
if (a.runner) {
|
|
3736
|
+
lines.push(` runner: ${yamlQuoteScalar(a.runner)}`);
|
|
3737
|
+
}
|
|
3738
|
+
if (a.sourceKind) {
|
|
3739
|
+
lines.push(` sourceKind: ${yamlQuoteScalar(a.sourceKind)}`);
|
|
3740
|
+
}
|
|
3741
|
+
if (a.sourcePath) {
|
|
3742
|
+
lines.push(` sourcePath: ${yamlQuoteScalar(a.sourcePath)}`);
|
|
3743
|
+
}
|
|
3744
|
+
if (a.sourceRepo) {
|
|
3745
|
+
lines.push(` sourceRepo: ${yamlQuoteScalar(a.sourceRepo)}`);
|
|
3746
|
+
}
|
|
3613
3747
|
if (a.args && a.args.length > 0) {
|
|
3614
3748
|
lines.push(` args:`);
|
|
3615
3749
|
for (const arg of a.args) {
|
|
@@ -4095,7 +4229,12 @@ async function readConfig() {
|
|
|
4095
4229
|
searchConfig: parseSearchConfig(content),
|
|
4096
4230
|
workspaceVisibility: parseWorkspaceVisibilityConfig(fmBlock),
|
|
4097
4231
|
staleness: parseStalenessConfig(content),
|
|
4098
|
-
stalenessWatchdog: String(fm["stalenessWatchdog"]).toLowerCase() === "true"
|
|
4232
|
+
stalenessWatchdog: String(fm["stalenessWatchdog"]).toLowerCase() === "true",
|
|
4233
|
+
standaloneDefaultCwd: parseOptionalAbsolutePath(
|
|
4234
|
+
fm["standaloneDefaultCwd"],
|
|
4235
|
+
"standaloneDefaultCwd"
|
|
4236
|
+
),
|
|
4237
|
+
agentDiscovery: parseAgentDiscoveryFromFm(fm)
|
|
4099
4238
|
};
|
|
4100
4239
|
}
|
|
4101
4240
|
function getAssignmentTypes(config) {
|
|
@@ -4158,7 +4297,7 @@ async function updateAgentsConfig(mutation, options = {}) {
|
|
|
4158
4297
|
await writeAgentsConfig(next);
|
|
4159
4298
|
return { previous, next, written: true };
|
|
4160
4299
|
}
|
|
4161
|
-
var STALENESS_KEY_TO_FIELD, DURATION_RE, DURATION_UNIT_MS, DEFAULT_ASSIGNMENT_TYPES, DEFAULT_CONFIG, AUTO_CREATE_WORKTREE_VALUES, SESSION_AUTO_TRACK_VALUES, AgentConfigError, DEFAULT_STATUS_COLORS, KNOWN_AGENT_SCALAR_FIELDS, migratedConfigPaths, TerminalConfigError;
|
|
4300
|
+
var STALENESS_KEY_TO_FIELD, DURATION_RE, DURATION_UNIT_MS, DEFAULT_ASSIGNMENT_TYPES, DEFAULT_CONFIG, AUTO_CREATE_WORKTREE_VALUES, SESSION_AUTO_TRACK_VALUES, RUNNER_KINDS, AGENT_SOURCE_KINDS, AgentConfigError, DEFAULT_STATUS_COLORS, KNOWN_AGENT_SCALAR_FIELDS, migratedConfigPaths, TerminalConfigError;
|
|
4162
4301
|
var init_config2 = __esm({
|
|
4163
4302
|
"src/utils/config.ts"() {
|
|
4164
4303
|
"use strict";
|
|
@@ -4234,10 +4373,23 @@ var init_config2 = __esm({
|
|
|
4234
4373
|
hidden: []
|
|
4235
4374
|
},
|
|
4236
4375
|
staleness: null,
|
|
4237
|
-
stalenessWatchdog: false
|
|
4376
|
+
stalenessWatchdog: false,
|
|
4377
|
+
standaloneDefaultCwd: null,
|
|
4378
|
+
agentDiscovery: {
|
|
4379
|
+
claudeGlobal: true,
|
|
4380
|
+
claudeProject: true,
|
|
4381
|
+
directory: true,
|
|
4382
|
+
roots: ["~"]
|
|
4383
|
+
}
|
|
4238
4384
|
};
|
|
4239
4385
|
AUTO_CREATE_WORKTREE_VALUES = ["skip", "ask", "always"];
|
|
4240
4386
|
SESSION_AUTO_TRACK_VALUES = ["all", "workspaces-only", "off"];
|
|
4387
|
+
RUNNER_KINDS = ["claude", "pi", "codex"];
|
|
4388
|
+
AGENT_SOURCE_KINDS = [
|
|
4389
|
+
"claude-global",
|
|
4390
|
+
"claude-project",
|
|
4391
|
+
"directory"
|
|
4392
|
+
];
|
|
4241
4393
|
AgentConfigError = class extends Error {
|
|
4242
4394
|
};
|
|
4243
4395
|
DEFAULT_STATUS_COLORS = {
|
|
@@ -4259,7 +4411,11 @@ var init_config2 = __esm({
|
|
|
4259
4411
|
"playbook",
|
|
4260
4412
|
"launchPrompt",
|
|
4261
4413
|
"agentName",
|
|
4262
|
-
"workdir"
|
|
4414
|
+
"workdir",
|
|
4415
|
+
"runner",
|
|
4416
|
+
"sourceKind",
|
|
4417
|
+
"sourcePath",
|
|
4418
|
+
"sourceRepo"
|
|
4263
4419
|
]);
|
|
4264
4420
|
migratedConfigPaths = /* @__PURE__ */ new Set();
|
|
4265
4421
|
TerminalConfigError = class extends Error {
|
|
@@ -4473,6 +4629,7 @@ var init_playbooks = __esm({
|
|
|
4473
4629
|
|
|
4474
4630
|
// src/launch/cwd.ts
|
|
4475
4631
|
import { existsSync, statSync } from "fs";
|
|
4632
|
+
import { homedir as homedir2 } from "os";
|
|
4476
4633
|
import { isAbsolute as isAbsolute2 } from "path";
|
|
4477
4634
|
function isExistingDir(p) {
|
|
4478
4635
|
if (!p || !isAbsolute2(p)) return false;
|
|
@@ -4518,6 +4675,31 @@ function resolveLaunchCwd(agent, worktreeCwd) {
|
|
|
4518
4675
|
}
|
|
4519
4676
|
return { spawnCwd: worktreeCwd, worktreePath: worktreeCwd, invalidReason: null };
|
|
4520
4677
|
}
|
|
4678
|
+
function resolveStandaloneCwd(agent, standaloneDefaultCwd) {
|
|
4679
|
+
const wd = agent.workdir?.trim();
|
|
4680
|
+
if (wd) {
|
|
4681
|
+
const expanded = expandHome(wd);
|
|
4682
|
+
if (!isExistingDir(expanded)) {
|
|
4683
|
+
return {
|
|
4684
|
+
cwd: null,
|
|
4685
|
+
invalidReason: `agent "${agent.id}" workdir ${agent.workdir} (resolved ${expanded}) is not an existing directory \u2014 a standalone launch requires a valid workdir.`
|
|
4686
|
+
};
|
|
4687
|
+
}
|
|
4688
|
+
return { cwd: expanded, invalidReason: null };
|
|
4689
|
+
}
|
|
4690
|
+
if (resolveRunner(agent) === "claude") {
|
|
4691
|
+
const configured = standaloneDefaultCwd?.trim();
|
|
4692
|
+
if (configured) {
|
|
4693
|
+
const expanded = expandHome(configured);
|
|
4694
|
+
if (isExistingDir(expanded)) return { cwd: expanded, invalidReason: null };
|
|
4695
|
+
}
|
|
4696
|
+
return { cwd: homedir2(), invalidReason: null };
|
|
4697
|
+
}
|
|
4698
|
+
return {
|
|
4699
|
+
cwd: null,
|
|
4700
|
+
invalidReason: `agent "${agent.id}" has no workdir \u2014 a standalone launch of a ${resolveRunner(agent)} agent requires a valid workdir.`
|
|
4701
|
+
};
|
|
4702
|
+
}
|
|
4521
4703
|
function formatFallbackCwdWarning(opts) {
|
|
4522
4704
|
const missing = [];
|
|
4523
4705
|
if (!opts.worktreePath) missing.push("worktreePath");
|
|
@@ -4529,6 +4711,7 @@ function formatFallbackCwdWarning(opts) {
|
|
|
4529
4711
|
var init_cwd = __esm({
|
|
4530
4712
|
"src/launch/cwd.ts"() {
|
|
4531
4713
|
"use strict";
|
|
4714
|
+
init_agents_schema();
|
|
4532
4715
|
init_paths();
|
|
4533
4716
|
}
|
|
4534
4717
|
});
|
|
@@ -7435,18 +7618,14 @@ async function resolveStandalonePlan(input, terminal) {
|
|
|
7435
7618
|
`Agent "${agentId}" requested for a standalone launch is not in your agents list.`
|
|
7436
7619
|
);
|
|
7437
7620
|
}
|
|
7438
|
-
const
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
);
|
|
7444
|
-
}
|
|
7445
|
-
const expanded = expandHome(wd);
|
|
7446
|
-
if (!isExistingDir(expanded)) {
|
|
7621
|
+
const { cwd: spawnCwd, invalidReason } = resolveStandaloneCwd(
|
|
7622
|
+
agent,
|
|
7623
|
+
input.config.standaloneDefaultCwd
|
|
7624
|
+
);
|
|
7625
|
+
if (spawnCwd === null) {
|
|
7447
7626
|
throw new LaunchError(
|
|
7448
7627
|
"workspace-path-invalid",
|
|
7449
|
-
`Agent "${agent.id}"
|
|
7628
|
+
invalidReason ?? `Agent "${agent.id}" has no valid standalone launch directory.`
|
|
7450
7629
|
);
|
|
7451
7630
|
}
|
|
7452
7631
|
const knownPlaybookSlugs = await listPlaybookSlugs(playbooksDir());
|
|
@@ -7460,7 +7639,7 @@ async function resolveStandalonePlan(input, terminal) {
|
|
|
7460
7639
|
const { argv, shellFallbackWarning } = buildFreshArgv(agent, prompt);
|
|
7461
7640
|
return {
|
|
7462
7641
|
terminal,
|
|
7463
|
-
cwd:
|
|
7642
|
+
cwd: spawnCwd,
|
|
7464
7643
|
argv,
|
|
7465
7644
|
env: process.env,
|
|
7466
7645
|
agentId: agent.id,
|
|
@@ -7627,13 +7806,13 @@ async function resolveSessionPlan(input, terminal) {
|
|
|
7627
7806
|
|
|
7628
7807
|
// src/launch/execute.ts
|
|
7629
7808
|
import { spawn as spawn3 } from "child_process";
|
|
7630
|
-
import { homedir as
|
|
7809
|
+
import { homedir as homedir6 } from "os";
|
|
7631
7810
|
import { basename as basename2, join as join6, resolve as resolve18 } from "path";
|
|
7632
7811
|
|
|
7633
7812
|
// src/utils/terminal-probe.ts
|
|
7634
7813
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
7635
7814
|
import { existsSync as existsSync2 } from "fs";
|
|
7636
|
-
import { homedir as
|
|
7815
|
+
import { homedir as homedir3 } from "os";
|
|
7637
7816
|
import { join as join3 } from "path";
|
|
7638
7817
|
var APP_BUNDLE_NAMES = {
|
|
7639
7818
|
iterm: "iTerm.app",
|
|
@@ -7645,7 +7824,7 @@ var APP_FIXED_PATHS = {
|
|
|
7645
7824
|
"terminal-app": "/System/Applications/Utilities/Terminal.app"
|
|
7646
7825
|
};
|
|
7647
7826
|
function defaultApplicationsDirs() {
|
|
7648
|
-
return ["/Applications", join3(
|
|
7827
|
+
return ["/Applications", join3(homedir3(), "Applications")];
|
|
7649
7828
|
}
|
|
7650
7829
|
function findAppBundle(terminal, dirs = defaultApplicationsDirs()) {
|
|
7651
7830
|
const fixed = APP_FIXED_PATHS[terminal];
|
|
@@ -7707,7 +7886,7 @@ init_config2();
|
|
|
7707
7886
|
// src/utils/session-id.ts
|
|
7708
7887
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
7709
7888
|
import { mkdirSync, readFileSync as readFileSync2, statSync as statSync3, writeFileSync } from "fs";
|
|
7710
|
-
import { homedir as
|
|
7889
|
+
import { homedir as homedir5 } from "os";
|
|
7711
7890
|
import { dirname as dirname3, join as join5 } from "path";
|
|
7712
7891
|
|
|
7713
7892
|
// src/utils/process-info.ts
|
|
@@ -7730,7 +7909,7 @@ function captureProcessStartedAt(pid) {
|
|
|
7730
7909
|
init_paths();
|
|
7731
7910
|
import { open as open2, readdir as readdir10, stat as stat3 } from "fs/promises";
|
|
7732
7911
|
import { join as join4 } from "path";
|
|
7733
|
-
import { homedir as
|
|
7912
|
+
import { homedir as homedir4 } from "os";
|
|
7734
7913
|
|
|
7735
7914
|
// src/utils/transcript.ts
|
|
7736
7915
|
import { open } from "fs/promises";
|
|
@@ -7848,7 +8027,7 @@ async function registerLaunchAtBirth(plan, child) {
|
|
|
7848
8027
|
const sessionId = plan.session?.sessionId ?? null;
|
|
7849
8028
|
const procStart = captureProcessStartedAt(pid);
|
|
7850
8029
|
const envDir = process.env.SYNTAUR_RUNTIME_SESSIONS_DIR;
|
|
7851
|
-
const markerDir = envDir && envDir.length > 0 ? envDir : join6(
|
|
8030
|
+
const markerDir = envDir && envDir.length > 0 ? envDir : join6(homedir6(), ".syntaur", "runtime", "sessions");
|
|
7852
8031
|
writeRuntimeMarker(
|
|
7853
8032
|
pid,
|
|
7854
8033
|
{
|