syntaur 0.40.0 → 0.41.2

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.
Files changed (68) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dashboard/dist/assets/{_basePickBy-D6criIXV.js → _basePickBy-CMGil-NY.js} +1 -1
  3. package/dashboard/dist/assets/{_baseUniq-CKxMpzId.js → _baseUniq-DllyUaEJ.js} +1 -1
  4. package/dashboard/dist/assets/{arc-9r-o7jsh.js → arc-C6fNP_LJ.js} +1 -1
  5. package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-CNC47xK1.js → architectureDiagram-2XIMDMQ5-CxXDnbMY.js} +1 -1
  6. package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-CxLXL7nx.js → blockDiagram-WCTKOSBZ-B8UDJhxg.js} +1 -1
  7. package/dashboard/dist/assets/{c4Diagram-IC4MRINW-BLbJctin.js → c4Diagram-IC4MRINW-9XDZP3AD.js} +1 -1
  8. package/dashboard/dist/assets/channel-OsoeK3Lk.js +1 -0
  9. package/dashboard/dist/assets/{chunk-4BX2VUAB-CDbpfqib.js → chunk-4BX2VUAB-D1LR7D9Y.js} +1 -1
  10. package/dashboard/dist/assets/{chunk-55IACEB6-L4WI8t-Y.js → chunk-55IACEB6-sumE5d0X.js} +1 -1
  11. package/dashboard/dist/assets/{chunk-FMBD7UC4-By5-igEn.js → chunk-FMBD7UC4-C-Iy8wke.js} +1 -1
  12. package/dashboard/dist/assets/{chunk-JSJVCQXG-Q9k6_65Q.js → chunk-JSJVCQXG-Clyrcmzt.js} +1 -1
  13. package/dashboard/dist/assets/{chunk-KX2RTZJC-BHIFtGWH.js → chunk-KX2RTZJC-BQqetgrP.js} +1 -1
  14. package/dashboard/dist/assets/{chunk-NQ4KR5QH-B4NuJ8C_.js → chunk-NQ4KR5QH-Cw60fnx2.js} +1 -1
  15. package/dashboard/dist/assets/{chunk-QZHKN3VN-BQyRAT6J.js → chunk-QZHKN3VN-Dv40SU2-.js} +1 -1
  16. package/dashboard/dist/assets/{chunk-WL4C6EOR-De4b_Qs3.js → chunk-WL4C6EOR-DFiOufrs.js} +1 -1
  17. package/dashboard/dist/assets/classDiagram-VBA2DB6C-BKX6nUBp.js +1 -0
  18. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-BKX6nUBp.js +1 -0
  19. package/dashboard/dist/assets/clone-f-TTh9ms.js +1 -0
  20. package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-DrH8QqS8.js → cose-bilkent-S5V4N54A-DV306SRn.js} +1 -1
  21. package/dashboard/dist/assets/{dagre-KLK3FWXG-DPchOAoI.js → dagre-KLK3FWXG-DaQ1pWLV.js} +1 -1
  22. package/dashboard/dist/assets/{diagram-E7M64L7V-jehxXjzH.js → diagram-E7M64L7V-2fsjMT-T.js} +1 -1
  23. package/dashboard/dist/assets/{diagram-IFDJBPK2-Dk0Hd4w_.js → diagram-IFDJBPK2-CoaSyKLw.js} +1 -1
  24. package/dashboard/dist/assets/{diagram-P4PSJMXO-CTg6e3e_.js → diagram-P4PSJMXO-C_j6Kd6q.js} +1 -1
  25. package/dashboard/dist/assets/{erDiagram-INFDFZHY-C53s82M7.js → erDiagram-INFDFZHY-CpOdYJWS.js} +1 -1
  26. package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-DuNh0Fc7.js → flowDiagram-PKNHOUZH-KVRjmhbG.js} +1 -1
  27. package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-B74hkBwP.js → ganttDiagram-A5KZAMGK-CA_n5ynk.js} +1 -1
  28. package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-CTwOleky.js → gitGraphDiagram-K3NZZRJ6-DKkS_iH8.js} +1 -1
  29. package/dashboard/dist/assets/{graph-DuB65SUX.js → graph-C6ehraTW.js} +1 -1
  30. package/dashboard/dist/assets/{index-BZ5hEn-I.css → index-CdHziP5R.css} +1 -1
  31. package/dashboard/dist/assets/{index-IKAckop6.js → index-SW4WrQLg.js} +88 -88
  32. package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-CPgiVLQb.js → infoDiagram-LFFYTUFH-H1Eg4YK9.js} +1 -1
  33. package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-Di5CEnNR.js → ishikawaDiagram-PHBUUO56-DSrc4sub.js} +1 -1
  34. package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-B1RhycTR.js → journeyDiagram-4ABVD52K-Bl_0LgIo.js} +1 -1
  35. package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-vw0FgyVD.js → kanban-definition-K7BYSVSG-Cq2WGyif.js} +1 -1
  36. package/dashboard/dist/assets/{layout-D4u8D4QF.js → layout-DJv9vite.js} +1 -1
  37. package/dashboard/dist/assets/{linear-vN7TVTLe.js → linear-CAef3hQD.js} +1 -1
  38. package/dashboard/dist/assets/{mermaid.core-CkrBXB3x.js → mermaid.core-B_gAmtAa.js} +4 -4
  39. package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-DF83eEZe.js → mindmap-definition-YRQLILUH-4aIWu_CK.js} +1 -1
  40. package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-s6OowTfq.js → pieDiagram-SKSYHLDU-1ThATMqf.js} +1 -1
  41. package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-BdInZyNW.js → quadrantDiagram-337W2JSQ-BEq2jVyN.js} +1 -1
  42. package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-ChbwbMIW.js → requirementDiagram-Z7DCOOCP-DbYJrAQ9.js} +1 -1
  43. package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-DISdO2ue.js → sankeyDiagram-WA2Y5GQK-DMr3kn8l.js} +1 -1
  44. package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-D12TBnwJ.js → sequenceDiagram-2WXFIKYE-BR03-l-y.js} +1 -1
  45. package/dashboard/dist/assets/{stateDiagram-RAJIS63D-CgCT1a9a.js → stateDiagram-RAJIS63D-DUj-dVll.js} +1 -1
  46. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-Dzzbhq6b.js +1 -0
  47. package/dashboard/dist/assets/{timeline-definition-YZTLITO2-Cp3_SQeH.js → timeline-definition-YZTLITO2-DpN8jElm.js} +1 -1
  48. package/dashboard/dist/assets/{treemap-KZPCXAKY-CuMtPlep.js → treemap-KZPCXAKY-CyUTDKiM.js} +1 -1
  49. package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-CoLZAO3b.js → vennDiagram-LZ73GAT5-DRJFiQmT.js} +1 -1
  50. package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-D96zGIQV.js → xychartDiagram-JWTSCODW-DcrZVnQ-.js} +1 -1
  51. package/dashboard/dist/index.html +2 -2
  52. package/dist/dashboard/server.js +139 -24
  53. package/dist/dashboard/server.js.map +1 -1
  54. package/dist/index.js +184 -30
  55. package/dist/index.js.map +1 -1
  56. package/dist/launch/index.d.ts +30 -0
  57. package/dist/launch/index.js +108 -20
  58. package/dist/launch/index.js.map +1 -1
  59. package/package.json +1 -1
  60. package/platforms/claude-code/.claude-plugin/plugin.json +1 -1
  61. package/platforms/codex/.codex-plugin/plugin.json +1 -1
  62. package/platforms/hermes/plugins/syntaur/__pycache__/__init__.cpython-312.pyc +0 -0
  63. package/platforms/hermes/plugins/syntaur/__pycache__/boundary.cpython-312.pyc +0 -0
  64. package/dashboard/dist/assets/channel-3nrYYZ_g.js +0 -1
  65. package/dashboard/dist/assets/classDiagram-VBA2DB6C-B2kUF3N9.js +0 -1
  66. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-B2kUF3N9.js +0 -1
  67. package/dashboard/dist/assets/clone-CNGwk6vy.js +0 -1
  68. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-wC4ehH_U.js +0 -1
package/dist/index.js CHANGED
@@ -1794,6 +1794,28 @@ var init_hotkeysCatalog = __esm({
1794
1794
  });
1795
1795
 
1796
1796
  // src/utils/agents-schema.ts
1797
+ function modelFlagArgs(agent) {
1798
+ const m = agent.model?.trim();
1799
+ return m ? ["--model", m] : [];
1800
+ }
1801
+ function stripModelFlags(args) {
1802
+ const out = [];
1803
+ for (let i = 0; i < args.length; i++) {
1804
+ const a = args[i];
1805
+ if (a === "--model" || a === "-m") {
1806
+ i++;
1807
+ continue;
1808
+ }
1809
+ if (a.startsWith("--model=") || a.startsWith("-m=")) continue;
1810
+ out.push(a);
1811
+ }
1812
+ return out;
1813
+ }
1814
+ function applyModelFlag(agent, baseArgs) {
1815
+ const flag = modelFlagArgs(agent);
1816
+ if (flag.length === 0) return baseArgs;
1817
+ return [...stripModelFlags(baseArgs), ...flag];
1818
+ }
1797
1819
  var BUILTIN_AGENTS, AGENT_ID_PATTERN, PROMPT_ARG_POSITIONS;
1798
1820
  var init_agents_schema = __esm({
1799
1821
  "src/utils/agents-schema.ts"() {
@@ -1848,6 +1870,19 @@ var init_agents_schema = __esm({
1848
1870
  }
1849
1871
  });
1850
1872
 
1873
+ // src/utils/slug.ts
1874
+ function slugify(title) {
1875
+ return title.toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
1876
+ }
1877
+ function isValidSlug(slug) {
1878
+ return /^[a-z0-9]+(-[a-z0-9]+)*$/.test(slug);
1879
+ }
1880
+ var init_slug = __esm({
1881
+ "src/utils/slug.ts"() {
1882
+ "use strict";
1883
+ }
1884
+ });
1885
+
1851
1886
  // src/utils/terminal-schema.ts
1852
1887
  var TERMINAL_CHOICES;
1853
1888
  var init_terminal_schema = __esm({
@@ -1972,6 +2007,16 @@ function validateAgentList(agents) {
1972
2007
  `agent "${agent.id}" has invalid promptArgPosition "${agent.promptArgPosition}" \u2014 expected first|last|none`
1973
2008
  );
1974
2009
  }
2010
+ if (agent.model !== void 0 && /[\r\n]/.test(agent.model)) {
2011
+ throw new AgentConfigError(
2012
+ `agent "${agent.id}" has invalid model \u2014 must be a single line (no newlines)`
2013
+ );
2014
+ }
2015
+ if (agent.playbook !== void 0 && agent.playbook.trim() !== "" && !isValidSlug(agent.playbook)) {
2016
+ throw new AgentConfigError(
2017
+ `agent "${agent.id}" has invalid playbook "${agent.playbook}" \u2014 must be a valid playbook slug`
2018
+ );
2019
+ }
1975
2020
  validateSessionInvocation(agent, "resume", agent.resume);
1976
2021
  validateSessionInvocation(agent, "fork", agent.fork);
1977
2022
  if (agent.default) defaults++;
@@ -2676,6 +2721,8 @@ function parseAgentsConfig(content) {
2676
2721
  ...current.promptArgPosition ? { promptArgPosition: current.promptArgPosition } : {},
2677
2722
  ...current.default ? { default: true } : {},
2678
2723
  ...current.resolveFromShellAliases ? { resolveFromShellAliases: true } : {},
2724
+ ...current.model ? { model: current.model } : {},
2725
+ ...current.playbook ? { playbook: current.playbook } : {},
2679
2726
  ...current.resume ? { resume: current.resume } : {},
2680
2727
  ...current.fork ? { fork: current.fork } : {}
2681
2728
  });
@@ -2858,6 +2905,12 @@ function assignAgentField(target, key, rawValue) {
2858
2905
  case "resolveFromShellAliases":
2859
2906
  target.resolveFromShellAliases = value === "true";
2860
2907
  break;
2908
+ case "model":
2909
+ target.model = value;
2910
+ break;
2911
+ case "playbook":
2912
+ target.playbook = value;
2913
+ break;
2861
2914
  }
2862
2915
  }
2863
2916
  function yamlQuoteScalar(value) {
@@ -2878,6 +2931,12 @@ function serializeAgentsConfig(agents) {
2878
2931
  lines.push(` - id: ${yamlQuoteScalar(a.id)}`);
2879
2932
  lines.push(` label: ${yamlQuoteScalar(a.label)}`);
2880
2933
  lines.push(` command: ${yamlQuoteScalar(a.command)}`);
2934
+ if (a.model) {
2935
+ lines.push(` model: ${yamlQuoteScalar(a.model)}`);
2936
+ }
2937
+ if (a.playbook) {
2938
+ lines.push(` playbook: ${yamlQuoteScalar(a.playbook)}`);
2939
+ }
2881
2940
  if (a.args && a.args.length > 0) {
2882
2941
  lines.push(` args:`);
2883
2942
  for (const arg of a.args) {
@@ -3260,6 +3319,7 @@ var init_config2 = __esm({
3260
3319
  init_lifecycle();
3261
3320
  init_hotkeysCatalog();
3262
3321
  init_agents_schema();
3322
+ init_slug();
3263
3323
  init_terminal_schema();
3264
3324
  init_workspace_visibility_schema();
3265
3325
  DEFAULT_ASSIGNMENT_TYPES = {
@@ -3319,7 +3379,9 @@ var init_config2 = __esm({
3319
3379
  "command",
3320
3380
  "promptArgPosition",
3321
3381
  "default",
3322
- "resolveFromShellAliases"
3382
+ "resolveFromShellAliases",
3383
+ "model",
3384
+ "playbook"
3323
3385
  ]);
3324
3386
  migratedConfigPaths = /* @__PURE__ */ new Set();
3325
3387
  TerminalConfigError = class extends Error {
@@ -3327,19 +3389,6 @@ var init_config2 = __esm({
3327
3389
  }
3328
3390
  });
3329
3391
 
3330
- // src/utils/slug.ts
3331
- function slugify(title) {
3332
- return title.toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
3333
- }
3334
- function isValidSlug(slug) {
3335
- return /^[a-z0-9]+(-[a-z0-9]+)*$/.test(slug);
3336
- }
3337
- var init_slug = __esm({
3338
- "src/utils/slug.ts"() {
3339
- "use strict";
3340
- }
3341
- });
3342
-
3343
3392
  // src/utils/playbooks.ts
3344
3393
  import { resolve as resolve7 } from "path";
3345
3394
  import { readdir as readdir3, readFile as readFile6, unlink } from "fs/promises";
@@ -8501,7 +8550,7 @@ function shellQuote(arg) {
8501
8550
  }
8502
8551
  function buildAgentArgv(agent, prompt, env = process.env) {
8503
8552
  const position = agent.promptArgPosition ?? "first";
8504
- const baseArgs = [...agent.args ?? []];
8553
+ const baseArgs = applyModelFlag(agent, [...agent.args ?? []]);
8505
8554
  const agentArgs = position === "first" ? [prompt, ...baseArgs] : position === "last" ? [...baseArgs, prompt] : baseArgs;
8506
8555
  if (agent.resolveFromShellAliases) {
8507
8556
  const requested = env.SHELL;
@@ -8581,7 +8630,7 @@ async function launchAgent(options) {
8581
8630
  );
8582
8631
  const { argv, shellFallbackWarning } = buildAgentArgv(
8583
8632
  agent,
8584
- INITIAL_PROMPT({ projectSlug, assignmentSlug })
8633
+ INITIAL_PROMPT({ projectSlug, assignmentSlug, playbook: agent.playbook })
8585
8634
  );
8586
8635
  if (shellFallbackWarning) {
8587
8636
  console.warn(shellFallbackWarning);
@@ -8621,16 +8670,22 @@ var init_launch = __esm({
8621
8670
  "src/tui/launch.ts"() {
8622
8671
  "use strict";
8623
8672
  init_api();
8673
+ init_agents_schema();
8624
8674
  init_cwd();
8625
8675
  init_cwd();
8626
8676
  INITIAL_PROMPT = (params2) => {
8627
- if (params2.projectSlug) {
8628
- return `/grab-assignment ${params2.projectSlug} ${params2.assignmentSlug}`;
8629
- }
8630
- if (params2.id) {
8631
- return `/grab-assignment --id ${params2.id}`;
8677
+ const playbook = params2.playbook?.trim();
8678
+ if (!playbook) {
8679
+ if (params2.projectSlug) {
8680
+ return `/grab-assignment ${params2.projectSlug} ${params2.assignmentSlug}`;
8681
+ }
8682
+ if (params2.id) {
8683
+ return `/grab-assignment --id ${params2.id}`;
8684
+ }
8685
+ return `/grab-assignment ${params2.assignmentSlug}`;
8632
8686
  }
8633
- return `/grab-assignment ${params2.assignmentSlug}`;
8687
+ const grabClause = params2.projectSlug ? `the assignment \`${params2.projectSlug}/${params2.assignmentSlug}\` using the /grab-assignment skill` : params2.id ? `the assignment id \`${params2.id}\` using /grab-assignment --id ${params2.id}` : `the assignment \`${params2.assignmentSlug}\` using the /grab-assignment skill`;
8688
+ return `Grab ${grabClause}, then load and run the \`${playbook}\` playbook using the /run-playbook skill and carry it out end-to-end.`;
8634
8689
  };
8635
8690
  }
8636
8691
  });
@@ -14133,6 +14188,24 @@ function mapAgentErrorToFieldErrors(err2) {
14133
14188
  fieldErrors: [{ field: "default", message: "only one agent may be default" }]
14134
14189
  };
14135
14190
  }
14191
+ match = message.match(/^agent "([^"]+)" has invalid playbook/);
14192
+ if (match) {
14193
+ return {
14194
+ error: message,
14195
+ fieldErrors: [
14196
+ { id: match[1], field: "playbook", message: "must be a valid playbook slug" }
14197
+ ]
14198
+ };
14199
+ }
14200
+ match = message.match(/^agent "([^"]+)" has invalid model/);
14201
+ if (match) {
14202
+ return {
14203
+ error: message,
14204
+ fieldErrors: [
14205
+ { id: match[1], field: "model", message: "must be a single line" }
14206
+ ]
14207
+ };
14208
+ }
14136
14209
  return { error: message };
14137
14210
  }
14138
14211
  function coerceAgentRow(raw2, index) {
@@ -14239,6 +14312,34 @@ function coerceAgentRow(raw2, index) {
14239
14312
  }
14240
14313
  cleaned.default = entry.default;
14241
14314
  }
14315
+ if (entry.model !== void 0) {
14316
+ if (typeof entry.model !== "string") {
14317
+ return {
14318
+ ok: false,
14319
+ status: 400,
14320
+ body: {
14321
+ error: `agents[${index}].model must be a string`,
14322
+ fieldErrors: [{ id, field: "model", message: "model must be a string" }]
14323
+ }
14324
+ };
14325
+ }
14326
+ const model = entry.model.trim();
14327
+ if (model) cleaned.model = model;
14328
+ }
14329
+ if (entry.playbook !== void 0) {
14330
+ if (typeof entry.playbook !== "string") {
14331
+ return {
14332
+ ok: false,
14333
+ status: 400,
14334
+ body: {
14335
+ error: `agents[${index}].playbook must be a string`,
14336
+ fieldErrors: [{ id, field: "playbook", message: "playbook must be a string" }]
14337
+ }
14338
+ };
14339
+ }
14340
+ const playbook = entry.playbook.trim();
14341
+ if (playbook) cleaned.playbook = playbook;
14342
+ }
14242
14343
  return { ok: true, value: cleaned };
14243
14344
  }
14244
14345
  function createAgentsRouter() {
@@ -14477,6 +14578,17 @@ function parseOpenUrl(input4) {
14477
14578
  }
14478
14579
  terminal = candidate;
14479
14580
  }
14581
+ const agentVals = url.searchParams.getAll("agent");
14582
+ if (agentVals.length > 1) {
14583
+ throw new OpenUrlError(
14584
+ "duplicate-param",
14585
+ "URL has more than one `agent` query param"
14586
+ );
14587
+ }
14588
+ let agent;
14589
+ if (agentVals.length === 1 && agentVals[0].trim() !== "") {
14590
+ agent = agentVals[0];
14591
+ }
14480
14592
  if (assignmentVals.length === 1) {
14481
14593
  const id = assignmentVals[0];
14482
14594
  if (id.trim() === "") {
@@ -14485,7 +14597,12 @@ function parseOpenUrl(input4) {
14485
14597
  "`assignment` query param is empty"
14486
14598
  );
14487
14599
  }
14488
- return { kind: "assignment", id, ...terminal ? { terminal } : {} };
14600
+ return {
14601
+ kind: "assignment",
14602
+ id,
14603
+ ...terminal ? { terminal } : {},
14604
+ ...agent ? { agent } : {}
14605
+ };
14489
14606
  }
14490
14607
  if (sessionVals.length === 1) {
14491
14608
  const id = sessionVals[0];
@@ -14510,7 +14627,13 @@ function parseOpenUrl(input4) {
14510
14627
  }
14511
14628
  mode = raw2;
14512
14629
  }
14513
- return { kind: "session", id, mode, ...terminal ? { terminal } : {} };
14630
+ return {
14631
+ kind: "session",
14632
+ id,
14633
+ mode,
14634
+ ...terminal ? { terminal } : {},
14635
+ ...agent ? { agent } : {}
14636
+ };
14514
14637
  }
14515
14638
  throw new OpenUrlError(
14516
14639
  "missing-id",
@@ -14527,6 +14650,7 @@ init_cwd();
14527
14650
  init_agent_sessions();
14528
14651
 
14529
14652
  // src/launch/argv.ts
14653
+ init_agents_schema();
14530
14654
  init_launch();
14531
14655
  import { isAbsolute as isAbsolute6 } from "path";
14532
14656
  var buildFreshArgv = buildAgentArgv;
@@ -14542,7 +14666,7 @@ function buildSessionArgv(agent, sessionId, mode, env = process.env) {
14542
14666
  (a) => a === "{id}" ? sessionId : a
14543
14667
  );
14544
14668
  const command = invocation.command ?? agent.command;
14545
- const agentArgs = [...agent.args ?? [], ...substituted];
14669
+ const agentArgs = [...applyModelFlag(agent, [...agent.args ?? []]), ...substituted];
14546
14670
  if (agent.resolveFromShellAliases) {
14547
14671
  const requested = env.SHELL;
14548
14672
  let shell = requested;
@@ -14623,13 +14747,26 @@ async function resolveAssignmentPlan(input4, terminal) {
14623
14747
  }
14624
14748
  const cwd = picked.cwd;
14625
14749
  const fallbackWarning = picked.fallbackWarning;
14626
- const agent = pickAgent(input4.config);
14750
+ let agent;
14751
+ if (input4.agentId) {
14752
+ const found = getAgents(input4.config).find((a) => a.id === input4.agentId);
14753
+ if (!found) {
14754
+ throw new LaunchError(
14755
+ "agent-not-configured",
14756
+ `Agent "${input4.agentId}" requested in the open URL is not in your agents list.`
14757
+ );
14758
+ }
14759
+ agent = found;
14760
+ } else {
14761
+ agent = pickAgent(input4.config);
14762
+ }
14627
14763
  const { argv, shellFallbackWarning } = buildFreshArgv(
14628
14764
  agent,
14629
14765
  INITIAL_PROMPT({
14630
14766
  projectSlug: resolved.projectSlug,
14631
14767
  assignmentSlug: resolved.assignmentSlug,
14632
- id: resolved.id
14768
+ id: resolved.id,
14769
+ playbook: agent.playbook
14633
14770
  })
14634
14771
  );
14635
14772
  return {
@@ -24502,7 +24639,8 @@ async function urlCommand(input4, options = {}) {
24502
24639
  config,
24503
24640
  projectsDir: projectsDir2,
24504
24641
  assignmentsDir: assignmentsDir(),
24505
- terminalOverride: parsed.terminal
24642
+ terminalOverride: parsed.terminal,
24643
+ agentId: parsed.kind === "assignment" ? parsed.agent : void 0
24506
24644
  });
24507
24645
  if (plan.fallbackWarning) {
24508
24646
  console.error(plan.fallbackWarning);
@@ -29254,6 +29392,8 @@ agentsCommand.command("list").description("List configured agents (or built-in d
29254
29392
  if (agent.default) flags.push("default");
29255
29393
  if (agent.resolveFromShellAliases) flags.push("shell-alias");
29256
29394
  if (agent.promptArgPosition) flags.push(`prompt=${agent.promptArgPosition}`);
29395
+ if (agent.model) flags.push(`model=${agent.model}`);
29396
+ if (agent.playbook) flags.push(`playbook=${agent.playbook}`);
29257
29397
  const flagStr = flags.length > 0 ? ` [${flags.join(", ")}]` : "";
29258
29398
  const args = agent.args && agent.args.length > 0 ? ` ${agent.args.join(" ")}` : "";
29259
29399
  console.log(` ${agent.id.padEnd(12)} ${agent.label.padEnd(20)} ${agent.command}${args}${flagStr}`);
@@ -29262,7 +29402,7 @@ agentsCommand.command("list").description("List configured agents (or built-in d
29262
29402
  reportAndExit(error);
29263
29403
  }
29264
29404
  });
29265
- agentsCommand.command("add").description("Add a new agent to ~/.syntaur/config.md").requiredOption("--id <id>", "Agent id (slug)").requiredOption("--label <label>", "Display label").requiredOption("--command <command>", "Absolute path or bare binary name").option("--args <csv>", "Comma-separated default args").option("--prompt-arg-position <position>", "first | last | none").option("--default", "Mark this agent as the default launch target").option("--resolve-from-shell-aliases", "Run via $SHELL -i -c (for shell aliases)").option("--dry-run", "Validate and print the proposed config without writing").action(async (options) => {
29405
+ agentsCommand.command("add").description("Add a new agent to ~/.syntaur/config.md").requiredOption("--id <id>", "Agent id (slug)").requiredOption("--label <label>", "Display label").requiredOption("--command <command>", "Absolute path or bare binary name").option("--args <csv>", "Comma-separated default args").option("--prompt-arg-position <position>", "first | last | none").option("--default", "Mark this agent as the default launch target").option("--resolve-from-shell-aliases", "Run via $SHELL -i -c (for shell aliases)").option("--model <model>", "LLM model injected as --model <value> at launch").option("--playbook <slug>", "Playbook slug to run end-to-end on a fresh launch").option("--dry-run", "Validate and print the proposed config without writing").action(async (options) => {
29266
29406
  try {
29267
29407
  const agent = buildAgentFromOptions(options, null);
29268
29408
  const mutation = {
@@ -29302,7 +29442,7 @@ agentsCommand.command("remove <id>").description("Remove an agent from ~/.syntau
29302
29442
  reportAndExit(error);
29303
29443
  }
29304
29444
  });
29305
- agentsCommand.command("set <id>").description("Update one or more fields on an existing agent").option("--label <label>", "Display label").option("--command <command>", "Absolute path or bare binary name").option("--args <csv>", "Comma-separated default args").option("--prompt-arg-position <position>", "first | last | none").option("--default", "Mark this agent as the default (clears any prior default)").option("--no-default", "Unset the default flag on this agent").option("--resolve-from-shell-aliases", "Run via $SHELL -i -c (for shell aliases)").option("--no-resolve-from-shell-aliases", "Disable shell-alias resolution for this agent").option("--dry-run", "Validate and print the proposed config without writing").action(async (id, options) => {
29445
+ agentsCommand.command("set <id>").description("Update one or more fields on an existing agent").option("--label <label>", "Display label").option("--command <command>", "Absolute path or bare binary name").option("--args <csv>", "Comma-separated default args").option("--prompt-arg-position <position>", "first | last | none").option("--default", "Mark this agent as the default (clears any prior default)").option("--no-default", "Unset the default flag on this agent").option("--resolve-from-shell-aliases", "Run via $SHELL -i -c (for shell aliases)").option("--no-resolve-from-shell-aliases", "Disable shell-alias resolution for this agent").option("--model <model>", "LLM model injected as --model <value> (empty string clears)").option("--playbook <slug>", "Playbook slug to run on a fresh launch (empty string clears)").option("--dry-run", "Validate and print the proposed config without writing").action(async (id, options) => {
29306
29446
  try {
29307
29447
  const mutation = {
29308
29448
  kind: "set",
@@ -29376,6 +29516,8 @@ function buildAgentFromOptions(options, existing) {
29376
29516
  }
29377
29517
  if (options.default) agent.default = true;
29378
29518
  if (options.resolveFromShellAliases) agent.resolveFromShellAliases = true;
29519
+ if (options.model && options.model.trim()) agent.model = options.model.trim();
29520
+ if (options.playbook && options.playbook.trim()) agent.playbook = options.playbook.trim();
29379
29521
  validateAgentList([...existing ? [] : [], agent]);
29380
29522
  return agent;
29381
29523
  }
@@ -29397,6 +29539,16 @@ function mergeOptionsIntoAgent(existing, options) {
29397
29539
  if (options.default === false) delete merged.default;
29398
29540
  if (options.resolveFromShellAliases === true) merged.resolveFromShellAliases = true;
29399
29541
  if (options.resolveFromShellAliases === false) delete merged.resolveFromShellAliases;
29542
+ if (options.model !== void 0) {
29543
+ const model = options.model.trim();
29544
+ if (model) merged.model = model;
29545
+ else delete merged.model;
29546
+ }
29547
+ if (options.playbook !== void 0) {
29548
+ const playbook = options.playbook.trim();
29549
+ if (playbook) merged.playbook = playbook;
29550
+ else delete merged.playbook;
29551
+ }
29400
29552
  return merged;
29401
29553
  }
29402
29554
  function parseArgsCsv(csv) {
@@ -29434,6 +29586,8 @@ function formatAgentLine(a) {
29434
29586
  if (a.default) flags.push("default");
29435
29587
  if (a.resolveFromShellAliases) flags.push("shell-alias");
29436
29588
  if (a.promptArgPosition) flags.push(`prompt=${a.promptArgPosition}`);
29589
+ if (a.model) flags.push(`model=${a.model}`);
29590
+ if (a.playbook) flags.push(`playbook=${a.playbook}`);
29437
29591
  if (a.args && a.args.length > 0) flags.push(`args=[${a.args.join(", ")}]`);
29438
29592
  const suffix = flags.length > 0 ? ` (${flags.join(", ")})` : "";
29439
29593
  return `${a.id}: ${a.label} \u2192 ${a.command}${suffix}`;