syntaur 0.74.0 → 0.76.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-CBNQaqzq.js → _basePickBy-BiwSunXO.js} +1 -1
- package/dashboard/dist/assets/{_baseUniq-Bqwz8hnN.js → _baseUniq-DsjKPXxP.js} +1 -1
- package/dashboard/dist/assets/{arc-B6lVW0Fc.js → arc-DlEs4wsF.js} +1 -1
- package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-eKpHkGki.js → architectureDiagram-2XIMDMQ5-DPvCrO57.js} +1 -1
- package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-D3sd7ccQ.js → blockDiagram-WCTKOSBZ-CpNdCY-r.js} +1 -1
- package/dashboard/dist/assets/{c4Diagram-IC4MRINW-0qW21hVQ.js → c4Diagram-IC4MRINW-CC29QJCs.js} +1 -1
- package/dashboard/dist/assets/channel-IutbH48W.js +1 -0
- package/dashboard/dist/assets/{chunk-4BX2VUAB-tDdoFSYw.js → chunk-4BX2VUAB-DKyy-k2D.js} +1 -1
- package/dashboard/dist/assets/{chunk-55IACEB6-BU45eS64.js → chunk-55IACEB6-DjobngQk.js} +1 -1
- package/dashboard/dist/assets/{chunk-FMBD7UC4-C0iT8QWM.js → chunk-FMBD7UC4-BUftm7dV.js} +1 -1
- package/dashboard/dist/assets/{chunk-JSJVCQXG-CELv9Y6Y.js → chunk-JSJVCQXG-Nv7rQv4t.js} +1 -1
- package/dashboard/dist/assets/{chunk-KX2RTZJC-CQA_hH8g.js → chunk-KX2RTZJC-Dg6UhNB9.js} +1 -1
- package/dashboard/dist/assets/{chunk-NQ4KR5QH-BDv-d6qz.js → chunk-NQ4KR5QH-D8neQrJ_.js} +1 -1
- package/dashboard/dist/assets/{chunk-QZHKN3VN-BUOeJd34.js → chunk-QZHKN3VN-Uj9c1naA.js} +1 -1
- package/dashboard/dist/assets/{chunk-WL4C6EOR-DBc-Hsx0.js → chunk-WL4C6EOR-DfeSsP3z.js} +1 -1
- package/dashboard/dist/assets/classDiagram-VBA2DB6C-8IywRj9I.js +1 -0
- package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-8IywRj9I.js +1 -0
- package/dashboard/dist/assets/clone-C6saGiCd.js +1 -0
- package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-C_Q4c3xo.js → cose-bilkent-S5V4N54A-CLfZNKcO.js} +1 -1
- package/dashboard/dist/assets/{dagre-KLK3FWXG-DdI10bBF.js → dagre-KLK3FWXG-DyJLICZx.js} +1 -1
- package/dashboard/dist/assets/{diagram-E7M64L7V-DtCF4Ea9.js → diagram-E7M64L7V-DhQc7Ta3.js} +1 -1
- package/dashboard/dist/assets/{diagram-IFDJBPK2-BVmpBmIK.js → diagram-IFDJBPK2-C6kFO7hB.js} +1 -1
- package/dashboard/dist/assets/{diagram-P4PSJMXO-BH4XFc0W.js → diagram-P4PSJMXO-B6oCiOXk.js} +1 -1
- package/dashboard/dist/assets/{erDiagram-INFDFZHY-CCjG3Ewp.js → erDiagram-INFDFZHY-BsMPaSwJ.js} +1 -1
- package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-V0PT07-Y.js → flowDiagram-PKNHOUZH-DLxEqKtZ.js} +1 -1
- package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-y_85pJZf.js → ganttDiagram-A5KZAMGK-D70pvqxG.js} +1 -1
- package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-B2maPPcL.js → gitGraphDiagram-K3NZZRJ6-D74VHtlE.js} +1 -1
- package/dashboard/dist/assets/{graph-DO1oCTrt.js → graph-C8bz_IEO.js} +1 -1
- package/dashboard/dist/assets/{index-BZwPAi8K.css → index-BetqH_3H.css} +1 -1
- package/dashboard/dist/assets/index-h-X_8om3.js +675 -0
- package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-BIaqpTlK.js → infoDiagram-LFFYTUFH-DivBd0Pz.js} +1 -1
- package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-BaBqTUzg.js → ishikawaDiagram-PHBUUO56-BGihUeOE.js} +1 -1
- package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-CS2l7gmE.js → journeyDiagram-4ABVD52K-C7U4cWHQ.js} +1 -1
- package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-B3Viag1o.js → kanban-definition-K7BYSVSG-CFp_hDTm.js} +1 -1
- package/dashboard/dist/assets/{layout-BQu5nxr5.js → layout-DMSDPqCs.js} +1 -1
- package/dashboard/dist/assets/{linear-DliLQN5_.js → linear-CCC-meYc.js} +1 -1
- package/dashboard/dist/assets/{mermaid.core-y_G2N_4o.js → mermaid.core-BDa2cc2K.js} +4 -4
- package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-EZz-bEA_.js → mindmap-definition-YRQLILUH-DLKvONhO.js} +1 -1
- package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-E67ZAs-E.js → pieDiagram-SKSYHLDU-DAJoGZ93.js} +1 -1
- package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-GU25jLyr.js → quadrantDiagram-337W2JSQ-Bo7haX1W.js} +1 -1
- package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-4Jfq0mB9.js → requirementDiagram-Z7DCOOCP-uEvGz33v.js} +1 -1
- package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-C22SY4ul.js → sankeyDiagram-WA2Y5GQK-cjYoCGCM.js} +1 -1
- package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-CkBh7V9t.js → sequenceDiagram-2WXFIKYE-CYXcNklt.js} +1 -1
- package/dashboard/dist/assets/{stateDiagram-RAJIS63D-n4DRlbfF.js → stateDiagram-RAJIS63D-B5We7jAw.js} +1 -1
- package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-CX9-EpBi.js +1 -0
- package/dashboard/dist/assets/{timeline-definition-YZTLITO2-CGD5ojK7.js → timeline-definition-YZTLITO2-CEqVmnVQ.js} +1 -1
- package/dashboard/dist/assets/{treemap-KZPCXAKY-EZfHxNz6.js → treemap-KZPCXAKY-CE1puPeN.js} +1 -1
- package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-B9x6fx-l.js → vennDiagram-LZ73GAT5-CiiuRUjK.js} +1 -1
- package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-ufzpkH1I.js → xychartDiagram-JWTSCODW-B0OuxFm9.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dist/dashboard/server.js +509 -221
- package/dist/dashboard/server.js.map +1 -1
- package/dist/index.js +1210 -823
- package/dist/index.js.map +1 -1
- package/dist/launch/index.d.ts +69 -7
- package/dist/launch/index.js +229 -24
- 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-BDsImlpM.js +0 -1
- package/dashboard/dist/assets/classDiagram-VBA2DB6C-BhdNnCQ2.js +0 -1
- package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-BhdNnCQ2.js +0 -1
- package/dashboard/dist/assets/clone-B5RwQsX7.js +0 -1
- package/dashboard/dist/assets/index-CG8rQF5o.js +0 -670
- package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-RpTmT3-9.js +0 -1
package/dist/launch/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ declare class OpenUrlError extends Error {
|
|
|
9
9
|
}
|
|
10
10
|
type SessionMode = 'resume' | 'fork';
|
|
11
11
|
interface ParsedOpenUrl {
|
|
12
|
-
kind: 'assignment' | 'session';
|
|
12
|
+
kind: 'assignment' | 'session' | 'standalone';
|
|
13
13
|
id: string;
|
|
14
14
|
/**
|
|
15
15
|
* Optional one-shot terminal override. When present, the launch plan uses
|
|
@@ -43,6 +43,13 @@ interface ParsedOpenUrl {
|
|
|
43
43
|
* to the fallback seed), distinct from `undefined` (no override).
|
|
44
44
|
*/
|
|
45
45
|
prompt?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Optional one-shot Claude `--agent <name>` identity (the `agentName=` query
|
|
48
|
+
* param). The dashboard's discovered-agent picker sends a chosen agent
|
|
49
|
+
* definition here so the launched session adopts it. Only set for
|
|
50
|
+
* `kind === 'assignment'`. Length-bounded like `prompt`.
|
|
51
|
+
*/
|
|
52
|
+
agentName?: string;
|
|
46
53
|
}
|
|
47
54
|
/**
|
|
48
55
|
* Parse a `syntaur://open?assignment=<id>` or `syntaur://open?session=<id>` URL.
|
|
@@ -110,6 +117,24 @@ interface AgentConfig {
|
|
|
110
117
|
* seed. Takes precedence over `playbook`. Single-line (see `serializeAgentsConfig`).
|
|
111
118
|
*/
|
|
112
119
|
launchPrompt?: string;
|
|
120
|
+
/**
|
|
121
|
+
* Optional Claude agent identity, injected as `--agent <value>` (see
|
|
122
|
+
* `agentNameArgs`). When set, the launched session adopts that agent's
|
|
123
|
+
* definition (system prompt + its own model frontmatter), so any profile
|
|
124
|
+
* `model` is suppressed on a fresh launch (see `buildAgentArgv`). Mutually
|
|
125
|
+
* exclusive with `workdir`. Meaningful only for Claude-compatible runners;
|
|
126
|
+
* `--agent` is simply injected when present regardless of runner. Single-line.
|
|
127
|
+
*/
|
|
128
|
+
agentName?: string;
|
|
129
|
+
/**
|
|
130
|
+
* Optional launch cwd override (absolute or `~`-prefixed) for directory-style
|
|
131
|
+
* agents (pi/codex) that load their identity from a launch directory. When set,
|
|
132
|
+
* the session is spawned from this directory instead of the worktree, and the
|
|
133
|
+
* worktree path is injected into the launch prompt (`@worktree` / a synthesized
|
|
134
|
+
* seed) so the agent can `cd` into the code. Mutually exclusive with
|
|
135
|
+
* `agentName`. Existence is validated at launch time, not at config-write time.
|
|
136
|
+
*/
|
|
137
|
+
workdir?: string;
|
|
113
138
|
}
|
|
114
139
|
|
|
115
140
|
/**
|
|
@@ -371,7 +396,7 @@ interface LaunchPlan {
|
|
|
371
396
|
};
|
|
372
397
|
}
|
|
373
398
|
interface ResolveLaunchPlanInput {
|
|
374
|
-
kind: 'assignment' | 'session';
|
|
399
|
+
kind: 'assignment' | 'session' | 'standalone';
|
|
375
400
|
id: string;
|
|
376
401
|
/**
|
|
377
402
|
* Only consulted when `kind === 'session'`. Defaults to `'resume'` so
|
|
@@ -407,6 +432,14 @@ interface ResolveLaunchPlanInput {
|
|
|
407
432
|
* reusing `agent.launchPrompt`). Per-launch only — never written to config.
|
|
408
433
|
*/
|
|
409
434
|
promptOverride?: string;
|
|
435
|
+
/**
|
|
436
|
+
* Only consulted when `kind === 'assignment'`. A one-shot Claude `--agent
|
|
437
|
+
* <name>` identity, wired from `?agentName=<name>` on the incoming
|
|
438
|
+
* `syntaur://` URL (the dashboard's discovered-agent picker). When defined it
|
|
439
|
+
* is applied over the resolved agent before argv assembly, so the launched
|
|
440
|
+
* session adopts that agent definition. Presence-significant; per-launch only.
|
|
441
|
+
*/
|
|
442
|
+
agentName?: string;
|
|
410
443
|
}
|
|
411
444
|
/**
|
|
412
445
|
* Pick the agent the "Open in agent" flow should use. Order of preference:
|
|
@@ -558,11 +591,28 @@ interface ResolveLaunchPromptInput {
|
|
|
558
591
|
playbook?: string | null;
|
|
559
592
|
/** Assignment id (optional only to represent the rare slug-fallback seed). */
|
|
560
593
|
id?: string;
|
|
561
|
-
/**
|
|
562
|
-
|
|
563
|
-
|
|
594
|
+
/**
|
|
595
|
+
* Records directory (where assignment.md lives), for `@assignment`. Optional:
|
|
596
|
+
* standalone launches have no assignment, so `@assignment` warns + stays
|
|
597
|
+
* literal when this is absent.
|
|
598
|
+
*/
|
|
599
|
+
assignmentDir?: string;
|
|
600
|
+
/** Null for a standalone assignment (required-but-nullable — pass `null`). */
|
|
564
601
|
projectSlug: string | null;
|
|
565
|
-
|
|
602
|
+
/** Optional: absent for standalone launches (no assignment). */
|
|
603
|
+
assignmentSlug?: string;
|
|
604
|
+
/**
|
|
605
|
+
* Absolute worktree path, for the `@worktree` token and the directory-agent
|
|
606
|
+
* (`workdir`) default seed. Absent for standalone launches and for plain
|
|
607
|
+
* launches with no worktree; `@worktree` warns + stays literal when absent.
|
|
608
|
+
*/
|
|
609
|
+
worktreePath?: string;
|
|
610
|
+
/**
|
|
611
|
+
* The directory the agent process is actually spawned from. When it differs
|
|
612
|
+
* from `worktreePath` the agent is a directory-agent (`workdir` set), which
|
|
613
|
+
* triggers the worktree-injecting default seed. Absent → no workdir agent.
|
|
614
|
+
*/
|
|
615
|
+
spawnCwd?: string;
|
|
566
616
|
/**
|
|
567
617
|
* Installed playbook slugs, injected by the call site. When provided, a
|
|
568
618
|
* well-formed `@<slug>` not in this set warns and is left literal. When
|
|
@@ -584,7 +634,11 @@ interface ResolveLaunchPromptResult {
|
|
|
584
634
|
* 2. else `playbook` set → synthesize `<@assignment pointer> Run <clause> end-to-end.`
|
|
585
635
|
* (built directly — no `@`-token re-resolution, so a playbook literally named
|
|
586
636
|
* `assignment` cannot collide with the reserved token).
|
|
587
|
-
* 3. else
|
|
637
|
+
* 3. else directory-agent (`worktreePath` set and != `spawnCwd`) → a plain-language
|
|
638
|
+
* seed pointing at the worktree + a `cd`/grab instruction (plain language
|
|
639
|
+
* because a single message fires only one leading slash-command).
|
|
640
|
+
* 4. else assignment context present → today's bare `/grab-assignment` seed.
|
|
641
|
+
* 5. else (standalone, no template/playbook) → empty prompt.
|
|
588
642
|
* `template` wins over `playbook`.
|
|
589
643
|
*/
|
|
590
644
|
declare function resolveLaunchPrompt(input: ResolveLaunchPromptInput): ResolveLaunchPromptResult;
|
|
@@ -609,6 +663,14 @@ declare function effectiveLaunchTemplate(input: {
|
|
|
609
663
|
projectSlug: string | null;
|
|
610
664
|
assignmentSlug: string;
|
|
611
665
|
id?: string;
|
|
666
|
+
/**
|
|
667
|
+
* Set when the agent is a directory-agent (`workdir`). With no explicit
|
|
668
|
+
* `launchPrompt`/`playbook`, the box prefills a `@worktree`-based seed so that
|
|
669
|
+
* re-resolving it at launch (as `promptOverride`) injects the worktree path —
|
|
670
|
+
* a plain bare seed would drop it. The token (not the resolved path) is used
|
|
671
|
+
* so the single resolve at launch fills it in.
|
|
672
|
+
*/
|
|
673
|
+
workdir?: string | null;
|
|
612
674
|
}): string;
|
|
613
675
|
|
|
614
676
|
type InstallKind = 'npx' | 'global' | 'local' | 'unknown';
|
package/dist/launch/index.js
CHANGED
|
@@ -1235,6 +1235,10 @@ function modelFlagArgs(agent) {
|
|
|
1235
1235
|
const m = agent.model?.trim();
|
|
1236
1236
|
return m ? ["--model", m] : [];
|
|
1237
1237
|
}
|
|
1238
|
+
function agentNameArgs(agent) {
|
|
1239
|
+
const n = agent.agentName?.trim();
|
|
1240
|
+
return n ? ["--agent", n] : [];
|
|
1241
|
+
}
|
|
1238
1242
|
function stripModelFlags(args) {
|
|
1239
1243
|
const out = [];
|
|
1240
1244
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -2532,6 +2536,26 @@ function validateAgentList(agents) {
|
|
|
2532
2536
|
`agent "${agent.id}" has invalid launchPrompt \u2014 must be a single line (no newlines)`
|
|
2533
2537
|
);
|
|
2534
2538
|
}
|
|
2539
|
+
if (agent.agentName !== void 0 && /[\r\n]/.test(agent.agentName)) {
|
|
2540
|
+
throw new AgentConfigError(
|
|
2541
|
+
`agent "${agent.id}" has invalid agentName \u2014 must be a single line (no newlines)`
|
|
2542
|
+
);
|
|
2543
|
+
}
|
|
2544
|
+
if (agent.workdir !== void 0 && /[\r\n]/.test(agent.workdir)) {
|
|
2545
|
+
throw new AgentConfigError(
|
|
2546
|
+
`agent "${agent.id}" has invalid workdir \u2014 must be a single line (no newlines)`
|
|
2547
|
+
);
|
|
2548
|
+
}
|
|
2549
|
+
if (agent.agentName !== void 0 && agent.agentName.trim() !== "" && agent.workdir !== void 0 && agent.workdir.trim() !== "") {
|
|
2550
|
+
throw new AgentConfigError(
|
|
2551
|
+
`agent "${agent.id}" sets both agentName and workdir \u2014 these are mutually exclusive`
|
|
2552
|
+
);
|
|
2553
|
+
}
|
|
2554
|
+
if (agent.agentName !== void 0 && agent.agentName.trim() !== "" && agent.model !== void 0 && agent.model.trim() !== "") {
|
|
2555
|
+
throw new AgentConfigError(
|
|
2556
|
+
`agent "${agent.id}" sets both agentName and model \u2014 the agent definition's own model is authoritative; remove the profile model`
|
|
2557
|
+
);
|
|
2558
|
+
}
|
|
2535
2559
|
validateSessionInvocation(agent, "resume", agent.resume);
|
|
2536
2560
|
validateSessionInvocation(agent, "fork", agent.fork);
|
|
2537
2561
|
if (agent.default) defaults++;
|
|
@@ -3352,6 +3376,8 @@ function parseAgentsConfig(content) {
|
|
|
3352
3376
|
...current.model ? { model: current.model } : {},
|
|
3353
3377
|
...current.playbook ? { playbook: current.playbook } : {},
|
|
3354
3378
|
...current.launchPrompt ? { launchPrompt: current.launchPrompt } : {},
|
|
3379
|
+
...current.agentName ? { agentName: current.agentName } : {},
|
|
3380
|
+
...current.workdir ? { workdir: current.workdir } : {},
|
|
3355
3381
|
...current.resume ? { resume: current.resume } : {},
|
|
3356
3382
|
...current.fork ? { fork: current.fork } : {}
|
|
3357
3383
|
});
|
|
@@ -3543,6 +3569,12 @@ function assignAgentField(target, key, rawValue) {
|
|
|
3543
3569
|
case "launchPrompt":
|
|
3544
3570
|
target.launchPrompt = value;
|
|
3545
3571
|
break;
|
|
3572
|
+
case "agentName":
|
|
3573
|
+
target.agentName = value;
|
|
3574
|
+
break;
|
|
3575
|
+
case "workdir":
|
|
3576
|
+
target.workdir = value;
|
|
3577
|
+
break;
|
|
3546
3578
|
}
|
|
3547
3579
|
}
|
|
3548
3580
|
function yamlQuoteScalar(value) {
|
|
@@ -3572,6 +3604,12 @@ function serializeAgentsConfig(agents) {
|
|
|
3572
3604
|
if (a.launchPrompt) {
|
|
3573
3605
|
lines.push(` launchPrompt: ${yamlQuoteScalar(a.launchPrompt)}`);
|
|
3574
3606
|
}
|
|
3607
|
+
if (a.agentName) {
|
|
3608
|
+
lines.push(` agentName: ${yamlQuoteScalar(a.agentName)}`);
|
|
3609
|
+
}
|
|
3610
|
+
if (a.workdir) {
|
|
3611
|
+
lines.push(` workdir: ${yamlQuoteScalar(a.workdir)}`);
|
|
3612
|
+
}
|
|
3575
3613
|
if (a.args && a.args.length > 0) {
|
|
3576
3614
|
lines.push(` args:`);
|
|
3577
3615
|
for (const arg of a.args) {
|
|
@@ -4219,7 +4257,9 @@ var init_config2 = __esm({
|
|
|
4219
4257
|
"resolveFromShellAliases",
|
|
4220
4258
|
"model",
|
|
4221
4259
|
"playbook",
|
|
4222
|
-
"launchPrompt"
|
|
4260
|
+
"launchPrompt",
|
|
4261
|
+
"agentName",
|
|
4262
|
+
"workdir"
|
|
4223
4263
|
]);
|
|
4224
4264
|
migratedConfigPaths = /* @__PURE__ */ new Set();
|
|
4225
4265
|
TerminalConfigError = class extends Error {
|
|
@@ -4463,6 +4503,21 @@ function resolveWorkspaceCwd(input) {
|
|
|
4463
4503
|
invalidReason: `workspace path invalid for ${assignmentSlug}: tried worktreePath ${shown(worktreePath)} and repository ${shown(repository)} \u2014 neither is an existing directory`
|
|
4464
4504
|
};
|
|
4465
4505
|
}
|
|
4506
|
+
function resolveLaunchCwd(agent, worktreeCwd) {
|
|
4507
|
+
const wd = agent.workdir?.trim();
|
|
4508
|
+
if (wd) {
|
|
4509
|
+
const expanded = expandHome(wd);
|
|
4510
|
+
if (!isExistingDir(expanded)) {
|
|
4511
|
+
return {
|
|
4512
|
+
spawnCwd: worktreeCwd,
|
|
4513
|
+
worktreePath: worktreeCwd,
|
|
4514
|
+
invalidReason: `agent "${agent.id}" workdir ${agent.workdir} (resolved ${expanded}) is not an existing directory`
|
|
4515
|
+
};
|
|
4516
|
+
}
|
|
4517
|
+
return { spawnCwd: expanded, worktreePath: worktreeCwd, invalidReason: null };
|
|
4518
|
+
}
|
|
4519
|
+
return { spawnCwd: worktreeCwd, worktreePath: worktreeCwd, invalidReason: null };
|
|
4520
|
+
}
|
|
4466
4521
|
function formatFallbackCwdWarning(opts) {
|
|
4467
4522
|
const missing = [];
|
|
4468
4523
|
if (!opts.worktreePath) missing.push("worktreePath");
|
|
@@ -4474,6 +4529,7 @@ function formatFallbackCwdWarning(opts) {
|
|
|
4474
4529
|
var init_cwd = __esm({
|
|
4475
4530
|
"src/launch/cwd.ts"() {
|
|
4476
4531
|
"use strict";
|
|
4532
|
+
init_paths();
|
|
4477
4533
|
}
|
|
4478
4534
|
});
|
|
4479
4535
|
|
|
@@ -6982,6 +7038,7 @@ function parseOpenUrl(input) {
|
|
|
6982
7038
|
}
|
|
6983
7039
|
const assignmentVals = url.searchParams.getAll("assignment");
|
|
6984
7040
|
const sessionVals = url.searchParams.getAll("session");
|
|
7041
|
+
const standaloneVals = url.searchParams.getAll("standalone");
|
|
6985
7042
|
if (assignmentVals.length > 1) {
|
|
6986
7043
|
throw new OpenUrlError(
|
|
6987
7044
|
"duplicate-param",
|
|
@@ -6994,10 +7051,17 @@ function parseOpenUrl(input) {
|
|
|
6994
7051
|
"URL has more than one `session` query param"
|
|
6995
7052
|
);
|
|
6996
7053
|
}
|
|
6997
|
-
if (
|
|
7054
|
+
if (standaloneVals.length > 1) {
|
|
7055
|
+
throw new OpenUrlError(
|
|
7056
|
+
"duplicate-param",
|
|
7057
|
+
"URL has more than one `standalone` query param"
|
|
7058
|
+
);
|
|
7059
|
+
}
|
|
7060
|
+
const kindsPresent = assignmentVals.length + sessionVals.length + standaloneVals.length;
|
|
7061
|
+
if (kindsPresent > 1) {
|
|
6998
7062
|
throw new OpenUrlError(
|
|
6999
7063
|
"both-ids",
|
|
7000
|
-
"URL has
|
|
7064
|
+
"URL has more than one of `assignment`, `session`, `standalone` \u2014 only one is allowed"
|
|
7001
7065
|
);
|
|
7002
7066
|
}
|
|
7003
7067
|
const terminalVals = url.searchParams.getAll("terminal");
|
|
@@ -7047,6 +7111,37 @@ function parseOpenUrl(input) {
|
|
|
7047
7111
|
}
|
|
7048
7112
|
prompt = value;
|
|
7049
7113
|
}
|
|
7114
|
+
const agentNameVals = url.searchParams.getAll("agentName");
|
|
7115
|
+
if (agentNameVals.length > 1) {
|
|
7116
|
+
throw new OpenUrlError(
|
|
7117
|
+
"duplicate-param",
|
|
7118
|
+
"URL has more than one `agentName` query param"
|
|
7119
|
+
);
|
|
7120
|
+
}
|
|
7121
|
+
let agentName;
|
|
7122
|
+
if (agentNameVals.length === 1 && agentNameVals[0].trim() !== "") {
|
|
7123
|
+
const value = agentNameVals[0];
|
|
7124
|
+
if (value.length > MAX_OPEN_PROMPT_LENGTH) {
|
|
7125
|
+
throw new OpenUrlError(
|
|
7126
|
+
"invalid-prompt",
|
|
7127
|
+
`\`agentName\` query param exceeds ${MAX_OPEN_PROMPT_LENGTH} characters`
|
|
7128
|
+
);
|
|
7129
|
+
}
|
|
7130
|
+
agentName = value;
|
|
7131
|
+
}
|
|
7132
|
+
if (standaloneVals.length === 1) {
|
|
7133
|
+
const id = standaloneVals[0];
|
|
7134
|
+
if (id.trim() === "") {
|
|
7135
|
+
throw new OpenUrlError("missing-id", "`standalone` query param is empty");
|
|
7136
|
+
}
|
|
7137
|
+
return {
|
|
7138
|
+
kind: "standalone",
|
|
7139
|
+
id,
|
|
7140
|
+
...terminal ? { terminal } : {},
|
|
7141
|
+
// standalone identifies the agent by `id`; keep an optional prompt override.
|
|
7142
|
+
...prompt !== void 0 ? { prompt } : {}
|
|
7143
|
+
};
|
|
7144
|
+
}
|
|
7050
7145
|
if (assignmentVals.length === 1) {
|
|
7051
7146
|
const id = assignmentVals[0];
|
|
7052
7147
|
if (id.trim() === "") {
|
|
@@ -7061,7 +7156,8 @@ function parseOpenUrl(input) {
|
|
|
7061
7156
|
...terminal ? { terminal } : {},
|
|
7062
7157
|
...agent ? { agent } : {},
|
|
7063
7158
|
// assignment-only; keep '' (presence-significant) — hence !== undefined.
|
|
7064
|
-
...prompt !== void 0 ? { prompt } : {}
|
|
7159
|
+
...prompt !== void 0 ? { prompt } : {},
|
|
7160
|
+
...agentName ? { agentName } : {}
|
|
7065
7161
|
};
|
|
7066
7162
|
}
|
|
7067
7163
|
if (sessionVals.length === 1) {
|
|
@@ -7097,7 +7193,7 @@ function parseOpenUrl(input) {
|
|
|
7097
7193
|
}
|
|
7098
7194
|
throw new OpenUrlError(
|
|
7099
7195
|
"missing-id",
|
|
7100
|
-
"URL must include
|
|
7196
|
+
"URL must include one of `assignment=<id>`, `session=<id>`, or `standalone=<agentId>`"
|
|
7101
7197
|
);
|
|
7102
7198
|
}
|
|
7103
7199
|
|
|
@@ -7129,8 +7225,19 @@ function resolveTemplate(template, ctx) {
|
|
|
7129
7225
|
const warnings = [];
|
|
7130
7226
|
const prompt = template.replace(TOKEN_RE, (_match, boundary, token) => {
|
|
7131
7227
|
if (token === "assignment") {
|
|
7228
|
+
if (!ctx.assignmentDir) {
|
|
7229
|
+
warnings.push(`launchPrompt: "@assignment" has no assignment context here \u2014 left as literal text.`);
|
|
7230
|
+
return boundary + "@assignment";
|
|
7231
|
+
}
|
|
7132
7232
|
return boundary + assignmentPointer(ctx.id, ctx.assignmentDir);
|
|
7133
7233
|
}
|
|
7234
|
+
if (token === "worktree") {
|
|
7235
|
+
if (!ctx.worktreePath) {
|
|
7236
|
+
warnings.push(`launchPrompt: "@worktree" has no worktree path here \u2014 left as literal text.`);
|
|
7237
|
+
return boundary + "@worktree";
|
|
7238
|
+
}
|
|
7239
|
+
return boundary + ctx.worktreePath;
|
|
7240
|
+
}
|
|
7134
7241
|
if (!isValidSlug(token)) {
|
|
7135
7242
|
warnings.push(`launchPrompt: "@${token}" is not a valid playbook token \u2014 left as literal text.`);
|
|
7136
7243
|
return boundary + "@" + token;
|
|
@@ -7144,16 +7251,37 @@ function resolveTemplate(template, ctx) {
|
|
|
7144
7251
|
return { prompt, warnings };
|
|
7145
7252
|
}
|
|
7146
7253
|
function resolveLaunchPrompt(input) {
|
|
7147
|
-
const {
|
|
7254
|
+
const {
|
|
7255
|
+
template,
|
|
7256
|
+
playbook,
|
|
7257
|
+
id,
|
|
7258
|
+
assignmentDir,
|
|
7259
|
+
projectSlug,
|
|
7260
|
+
assignmentSlug,
|
|
7261
|
+
worktreePath,
|
|
7262
|
+
spawnCwd,
|
|
7263
|
+
knownPlaybookSlugs
|
|
7264
|
+
} = input;
|
|
7148
7265
|
if (template && template.trim()) {
|
|
7149
|
-
return resolveTemplate(template, { id, assignmentDir, knownPlaybookSlugs });
|
|
7266
|
+
return resolveTemplate(template, { id, assignmentDir, worktreePath, knownPlaybookSlugs });
|
|
7150
7267
|
}
|
|
7151
7268
|
const pb = playbook?.trim();
|
|
7152
7269
|
if (pb) {
|
|
7153
|
-
const
|
|
7154
|
-
|
|
7270
|
+
const clause = runPlaybookClause(pb);
|
|
7271
|
+
const prompt = assignmentDir ? `${assignmentPointer(id, assignmentDir)} Run ${clause} end-to-end.` : `Run ${clause} end-to-end.`;
|
|
7272
|
+
return { prompt, warnings: [] };
|
|
7155
7273
|
}
|
|
7156
|
-
|
|
7274
|
+
if (worktreePath && spawnCwd && worktreePath !== spawnCwd) {
|
|
7275
|
+
const grab = bareGrabSeed({ projectSlug, assignmentSlug: assignmentSlug ?? "", id });
|
|
7276
|
+
return {
|
|
7277
|
+
prompt: `The assignment's worktree is at ${worktreePath}. cd there, then grab the assignment with ${grab} and work it end-to-end.`,
|
|
7278
|
+
warnings: []
|
|
7279
|
+
};
|
|
7280
|
+
}
|
|
7281
|
+
if (!assignmentSlug && !id) {
|
|
7282
|
+
return { prompt: "", warnings: [] };
|
|
7283
|
+
}
|
|
7284
|
+
return { prompt: bareGrabSeed({ projectSlug, assignmentSlug: assignmentSlug ?? "", id }), warnings: [] };
|
|
7157
7285
|
}
|
|
7158
7286
|
function effectiveLaunchTemplate(input) {
|
|
7159
7287
|
if (input.launchPrompt && input.launchPrompt.trim()) {
|
|
@@ -7163,6 +7291,14 @@ function effectiveLaunchTemplate(input) {
|
|
|
7163
7291
|
if (pb) {
|
|
7164
7292
|
return `@assignment Run ${runPlaybookClause(pb)} end-to-end.`;
|
|
7165
7293
|
}
|
|
7294
|
+
if (input.workdir && input.workdir.trim()) {
|
|
7295
|
+
const grab = bareGrabSeed({
|
|
7296
|
+
projectSlug: input.projectSlug,
|
|
7297
|
+
assignmentSlug: input.assignmentSlug,
|
|
7298
|
+
id: input.id
|
|
7299
|
+
});
|
|
7300
|
+
return `The assignment's worktree is at @worktree. cd there, then grab the assignment with ${grab} and work it end-to-end.`;
|
|
7301
|
+
}
|
|
7166
7302
|
return bareGrabSeed({
|
|
7167
7303
|
projectSlug: input.projectSlug,
|
|
7168
7304
|
assignmentSlug: input.assignmentSlug,
|
|
@@ -7196,8 +7332,10 @@ function shellQuote(arg) {
|
|
|
7196
7332
|
}
|
|
7197
7333
|
function buildAgentArgv(agent, prompt, env = process.env) {
|
|
7198
7334
|
const position = agent.promptArgPosition ?? "first";
|
|
7199
|
-
const
|
|
7200
|
-
const
|
|
7335
|
+
const prefix = agentNameArgs(agent);
|
|
7336
|
+
const baseArgs = agent.agentName ? [...agent.args ?? []] : applyModelFlag(agent, [...agent.args ?? []]);
|
|
7337
|
+
const positioned = position === "first" ? [prompt, ...baseArgs] : position === "last" ? [...baseArgs, prompt] : baseArgs;
|
|
7338
|
+
const agentArgs = [...prefix, ...positioned];
|
|
7201
7339
|
if (agent.resolveFromShellAliases) {
|
|
7202
7340
|
const requested = env.SHELL;
|
|
7203
7341
|
let shell = requested;
|
|
@@ -7277,8 +7415,60 @@ async function resolveLaunchPlan(input) {
|
|
|
7277
7415
|
if (input.kind === "assignment") {
|
|
7278
7416
|
return resolveAssignmentPlan(input, terminal);
|
|
7279
7417
|
}
|
|
7418
|
+
if (input.kind === "standalone") {
|
|
7419
|
+
return resolveStandalonePlan(input, terminal);
|
|
7420
|
+
}
|
|
7280
7421
|
return resolveSessionPlan(input, terminal);
|
|
7281
7422
|
}
|
|
7423
|
+
async function resolveStandalonePlan(input, terminal) {
|
|
7424
|
+
const agentId = input.agentId ?? input.id;
|
|
7425
|
+
if (!agentId) {
|
|
7426
|
+
throw new LaunchError(
|
|
7427
|
+
"agent-not-configured",
|
|
7428
|
+
"A standalone launch requires an agent id."
|
|
7429
|
+
);
|
|
7430
|
+
}
|
|
7431
|
+
const agent = getAgents(input.config).find((a) => a.id === agentId);
|
|
7432
|
+
if (!agent) {
|
|
7433
|
+
throw new LaunchError(
|
|
7434
|
+
"agent-not-configured",
|
|
7435
|
+
`Agent "${agentId}" requested for a standalone launch is not in your agents list.`
|
|
7436
|
+
);
|
|
7437
|
+
}
|
|
7438
|
+
const wd = agent.workdir?.trim();
|
|
7439
|
+
if (!wd) {
|
|
7440
|
+
throw new LaunchError(
|
|
7441
|
+
"workspace-path-invalid",
|
|
7442
|
+
`Agent "${agent.id}" has no workdir \u2014 a standalone launch requires a valid workdir.`
|
|
7443
|
+
);
|
|
7444
|
+
}
|
|
7445
|
+
const expanded = expandHome(wd);
|
|
7446
|
+
if (!isExistingDir(expanded)) {
|
|
7447
|
+
throw new LaunchError(
|
|
7448
|
+
"workspace-path-invalid",
|
|
7449
|
+
`Agent "${agent.id}" workdir ${agent.workdir} (resolved ${expanded}) is not an existing directory \u2014 a standalone launch requires a valid workdir.`
|
|
7450
|
+
);
|
|
7451
|
+
}
|
|
7452
|
+
const knownPlaybookSlugs = await listPlaybookSlugs(playbooksDir());
|
|
7453
|
+
const template = input.promptOverride !== void 0 ? input.promptOverride : agent.launchPrompt;
|
|
7454
|
+
const { prompt, warnings: promptWarnings } = resolveLaunchPrompt({
|
|
7455
|
+
template,
|
|
7456
|
+
playbook: agent.playbook,
|
|
7457
|
+
projectSlug: null,
|
|
7458
|
+
knownPlaybookSlugs
|
|
7459
|
+
});
|
|
7460
|
+
const { argv, shellFallbackWarning } = buildFreshArgv(agent, prompt);
|
|
7461
|
+
return {
|
|
7462
|
+
terminal,
|
|
7463
|
+
cwd: expanded,
|
|
7464
|
+
argv,
|
|
7465
|
+
env: process.env,
|
|
7466
|
+
agentId: agent.id,
|
|
7467
|
+
fallbackWarning: null,
|
|
7468
|
+
shellFallbackWarning,
|
|
7469
|
+
promptWarnings
|
|
7470
|
+
};
|
|
7471
|
+
}
|
|
7282
7472
|
async function resolveAssignmentPlan(input, terminal) {
|
|
7283
7473
|
const resolved = await resolveAssignmentById(
|
|
7284
7474
|
input.projectsDir,
|
|
@@ -7302,17 +7492,6 @@ async function resolveAssignmentPlan(input, terminal) {
|
|
|
7302
7492
|
`Assignment ${input.id} resolver returned a directory but detail could not be loaded`
|
|
7303
7493
|
);
|
|
7304
7494
|
}
|
|
7305
|
-
const picked = resolveWorkspaceCwd({
|
|
7306
|
-
worktreePath: detail.workspace.worktreePath,
|
|
7307
|
-
repository: detail.workspace.repository,
|
|
7308
|
-
branch: detail.workspace.branch,
|
|
7309
|
-
assignmentSlug: resolved.assignmentSlug
|
|
7310
|
-
});
|
|
7311
|
-
if (picked.cwd === null) {
|
|
7312
|
-
throw new LaunchError("workspace-path-invalid", picked.invalidReason);
|
|
7313
|
-
}
|
|
7314
|
-
const cwd = picked.cwd;
|
|
7315
|
-
const fallbackWarning = picked.fallbackWarning;
|
|
7316
7495
|
let agent;
|
|
7317
7496
|
if (input.agentId) {
|
|
7318
7497
|
const found = getAgents(input.config).find((a) => a.id === input.agentId);
|
|
@@ -7326,6 +7505,30 @@ async function resolveAssignmentPlan(input, terminal) {
|
|
|
7326
7505
|
} else {
|
|
7327
7506
|
agent = pickAgent(input.config);
|
|
7328
7507
|
}
|
|
7508
|
+
if (input.agentName !== void 0) {
|
|
7509
|
+
agent = { ...agent, agentName: input.agentName };
|
|
7510
|
+
}
|
|
7511
|
+
const picked = resolveWorkspaceCwd({
|
|
7512
|
+
worktreePath: detail.workspace.worktreePath,
|
|
7513
|
+
repository: detail.workspace.repository,
|
|
7514
|
+
branch: detail.workspace.branch,
|
|
7515
|
+
assignmentSlug: resolved.assignmentSlug
|
|
7516
|
+
});
|
|
7517
|
+
if (picked.cwd === null) {
|
|
7518
|
+
throw new LaunchError("workspace-path-invalid", picked.invalidReason);
|
|
7519
|
+
}
|
|
7520
|
+
const launchCwd = resolveLaunchCwd(agent, picked.cwd);
|
|
7521
|
+
if (launchCwd.invalidReason) {
|
|
7522
|
+
throw new LaunchError("workspace-path-invalid", launchCwd.invalidReason);
|
|
7523
|
+
}
|
|
7524
|
+
const cwd = launchCwd.spawnCwd;
|
|
7525
|
+
const fallbackWarning = picked.fallbackWarning;
|
|
7526
|
+
const promptWarningsExtra = [];
|
|
7527
|
+
if (input.agentName !== void 0 && input.agentName.trim() && agent.model?.trim()) {
|
|
7528
|
+
promptWarningsExtra.push(
|
|
7529
|
+
`profile model "${agent.model.trim()}" suppressed: agent "${input.agentName.trim()}" defines its own model`
|
|
7530
|
+
);
|
|
7531
|
+
}
|
|
7329
7532
|
const knownPlaybookSlugs = await listPlaybookSlugs(playbooksDir());
|
|
7330
7533
|
const template = input.promptOverride !== void 0 ? input.promptOverride : agent.launchPrompt;
|
|
7331
7534
|
const { prompt, warnings: promptWarnings } = resolveLaunchPrompt({
|
|
@@ -7335,6 +7538,8 @@ async function resolveAssignmentPlan(input, terminal) {
|
|
|
7335
7538
|
assignmentDir: resolved.assignmentDir,
|
|
7336
7539
|
projectSlug: resolved.projectSlug,
|
|
7337
7540
|
assignmentSlug: resolved.assignmentSlug,
|
|
7541
|
+
worktreePath: launchCwd.worktreePath,
|
|
7542
|
+
spawnCwd: launchCwd.spawnCwd,
|
|
7338
7543
|
knownPlaybookSlugs
|
|
7339
7544
|
});
|
|
7340
7545
|
const { argv, shellFallbackWarning } = buildFreshArgv(agent, prompt);
|
|
@@ -7346,7 +7551,7 @@ async function resolveAssignmentPlan(input, terminal) {
|
|
|
7346
7551
|
agentId: agent.id,
|
|
7347
7552
|
fallbackWarning,
|
|
7348
7553
|
shellFallbackWarning,
|
|
7349
|
-
promptWarnings
|
|
7554
|
+
promptWarnings: [...promptWarningsExtra, ...promptWarnings]
|
|
7350
7555
|
};
|
|
7351
7556
|
}
|
|
7352
7557
|
async function resolveSessionPlan(input, terminal) {
|