syntaur 0.16.0 → 0.16.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 (65) hide show
  1. package/dashboard/dist/assets/{_basePickBy-B1S22H85.js → _basePickBy-DTuHiZCP.js} +1 -1
  2. package/dashboard/dist/assets/{_baseUniq-CJIRCCsh.js → _baseUniq-BjbISCNN.js} +1 -1
  3. package/dashboard/dist/assets/{arc-CdlNYTcd.js → arc-D9mCa8If.js} +1 -1
  4. package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-KVI0HWOy.js → architectureDiagram-2XIMDMQ5-CLWheiZu.js} +1 -1
  5. package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-ClnG7gaq.js → blockDiagram-WCTKOSBZ-BBxrVTWB.js} +1 -1
  6. package/dashboard/dist/assets/{c4Diagram-IC4MRINW-BD9lkttL.js → c4Diagram-IC4MRINW-DnhDZ2W3.js} +1 -1
  7. package/dashboard/dist/assets/channel-CN5VmjNa.js +1 -0
  8. package/dashboard/dist/assets/{chunk-4BX2VUAB-BM3DXZMG.js → chunk-4BX2VUAB-DeAfVeDa.js} +1 -1
  9. package/dashboard/dist/assets/{chunk-55IACEB6-DUIbFJ3r.js → chunk-55IACEB6-cKEeGDNI.js} +1 -1
  10. package/dashboard/dist/assets/{chunk-FMBD7UC4-B_cxCRkA.js → chunk-FMBD7UC4-7RuZ6HEq.js} +1 -1
  11. package/dashboard/dist/assets/{chunk-JSJVCQXG-2mLf1WoM.js → chunk-JSJVCQXG-B5dwG0bv.js} +1 -1
  12. package/dashboard/dist/assets/{chunk-KX2RTZJC-BMz3ND2R.js → chunk-KX2RTZJC-DeyQYDVj.js} +1 -1
  13. package/dashboard/dist/assets/{chunk-NQ4KR5QH-DiCxpw3L.js → chunk-NQ4KR5QH-NYo4hSqA.js} +1 -1
  14. package/dashboard/dist/assets/{chunk-QZHKN3VN-BcaWPzd5.js → chunk-QZHKN3VN-CtJFICF8.js} +1 -1
  15. package/dashboard/dist/assets/{chunk-WL4C6EOR-BbsfhS6J.js → chunk-WL4C6EOR-DZ3WYdab.js} +1 -1
  16. package/dashboard/dist/assets/classDiagram-VBA2DB6C-CqLb9GuU.js +1 -0
  17. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-CqLb9GuU.js +1 -0
  18. package/dashboard/dist/assets/clone-DwvrjCQs.js +1 -0
  19. package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-iuQzyyrA.js → cose-bilkent-S5V4N54A-DaYOsf-M.js} +1 -1
  20. package/dashboard/dist/assets/{dagre-KLK3FWXG-C0TB1zg5.js → dagre-KLK3FWXG-DzLc7ykF.js} +1 -1
  21. package/dashboard/dist/assets/{diagram-E7M64L7V-Ck8tvxP2.js → diagram-E7M64L7V-kpjEdOqb.js} +1 -1
  22. package/dashboard/dist/assets/{diagram-IFDJBPK2-rQKIi-sc.js → diagram-IFDJBPK2-D3EHoh6j.js} +1 -1
  23. package/dashboard/dist/assets/{diagram-P4PSJMXO-DS1RGSgx.js → diagram-P4PSJMXO-Cp6Un2ys.js} +1 -1
  24. package/dashboard/dist/assets/{erDiagram-INFDFZHY-BqWCybWW.js → erDiagram-INFDFZHY-DDjOUPWk.js} +1 -1
  25. package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-BCoQtyQ5.js → flowDiagram-PKNHOUZH-CfO51xge.js} +1 -1
  26. package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-CD1BmicP.js → ganttDiagram-A5KZAMGK-BDzAtkcp.js} +1 -1
  27. package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-tGDYOZuO.js → gitGraphDiagram-K3NZZRJ6-JPMFN2zF.js} +1 -1
  28. package/dashboard/dist/assets/{graph-BT0s-094.js → graph-DXDryilu.js} +1 -1
  29. package/dashboard/dist/assets/index-D7UtkCYM.js +515 -0
  30. package/dashboard/dist/assets/{index-D2Yoi6DJ.css → index-DTXSWSzH.css} +1 -1
  31. package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-E4dVb8BD.js → infoDiagram-LFFYTUFH-CYi5kkvz.js} +1 -1
  32. package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-CubuM_ev.js → ishikawaDiagram-PHBUUO56-DQl_IUe8.js} +1 -1
  33. package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-DfyJbgMF.js → journeyDiagram-4ABVD52K-BXXGPcrS.js} +1 -1
  34. package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-BXamajyZ.js → kanban-definition-K7BYSVSG-BqJestUY.js} +1 -1
  35. package/dashboard/dist/assets/{layout-6b_SlWD_.js → layout-D5VdYmWn.js} +1 -1
  36. package/dashboard/dist/assets/{linear-BE0O-66A.js → linear-dZA_O_GN.js} +1 -1
  37. package/dashboard/dist/assets/{mermaid.core-DM3qWr07.js → mermaid.core-B0Ixd1yP.js} +4 -4
  38. package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-puOtERrG.js → mindmap-definition-YRQLILUH-CSJYdSMG.js} +1 -1
  39. package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-cE6l8UBX.js → pieDiagram-SKSYHLDU-DmYrRZHN.js} +1 -1
  40. package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-CgDAyZQP.js → quadrantDiagram-337W2JSQ-La3ce5kE.js} +1 -1
  41. package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-CJrai_8U.js → requirementDiagram-Z7DCOOCP-DPitIZQl.js} +1 -1
  42. package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-Bf72l7UW.js → sankeyDiagram-WA2Y5GQK-CAmCqGkr.js} +1 -1
  43. package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-0D8RN7ds.js → sequenceDiagram-2WXFIKYE-6lEzNTWG.js} +1 -1
  44. package/dashboard/dist/assets/{stateDiagram-RAJIS63D-B8LucUIt.js → stateDiagram-RAJIS63D-DyGKCS2C.js} +1 -1
  45. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-BOmRICoY.js +1 -0
  46. package/dashboard/dist/assets/{timeline-definition-YZTLITO2-DL3Hq8ii.js → timeline-definition-YZTLITO2-D9RxQE3j.js} +1 -1
  47. package/dashboard/dist/assets/{treemap-KZPCXAKY-wF1X4_uI.js → treemap-KZPCXAKY-TuXbGNN4.js} +1 -1
  48. package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-DDAjoGTZ.js → vennDiagram-LZ73GAT5-Bly5knr-.js} +1 -1
  49. package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-T-YmzRW8.js → xychartDiagram-JWTSCODW-CA-5z7-4.js} +1 -1
  50. package/dashboard/dist/index.html +2 -2
  51. package/dist/dashboard/server.js +820 -166
  52. package/dist/dashboard/server.js.map +1 -1
  53. package/dist/index.js +1244 -774
  54. package/dist/index.js.map +1 -1
  55. package/dist/launch/index.d.ts +20 -2
  56. package/dist/launch/index.js +67 -20
  57. package/dist/launch/index.js.map +1 -1
  58. package/package.json +1 -1
  59. package/scripts/install-macos-url-handler.mjs +40 -7
  60. package/dashboard/dist/assets/channel-Cm_FzKJq.js +0 -1
  61. package/dashboard/dist/assets/classDiagram-VBA2DB6C-Bdan2Dp5.js +0 -1
  62. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-Bdan2Dp5.js +0 -1
  63. package/dashboard/dist/assets/clone-9PoPEM_s.js +0 -1
  64. package/dashboard/dist/assets/index-BdSkANCC.js +0 -510
  65. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-D0dc7wxQ.js +0 -1
@@ -1,6 +1,8 @@
1
1
  import { SpawnOptions, ChildProcess } from 'node:child_process';
2
2
 
3
- type OpenUrlErrorCode = 'bad-scheme' | 'bad-host' | 'missing-id' | 'both-ids' | 'malformed' | 'duplicate-param' | 'bad-mode';
3
+ type TerminalChoice = 'terminal-app' | 'iterm' | 'ghostty' | 'alacritty' | 'warp' | 'kitty';
4
+
5
+ type OpenUrlErrorCode = 'bad-scheme' | 'bad-host' | 'missing-id' | 'both-ids' | 'malformed' | 'duplicate-param' | 'bad-terminal' | 'bad-mode';
4
6
  declare class OpenUrlError extends Error {
5
7
  readonly code: OpenUrlErrorCode;
6
8
  constructor(code: OpenUrlErrorCode, message: string);
@@ -9,6 +11,13 @@ type SessionMode = 'resume' | 'fork';
9
11
  interface ParsedOpenUrl {
10
12
  kind: 'assignment' | 'session';
11
13
  id: string;
14
+ /**
15
+ * Optional one-shot terminal override. When present, the launch plan uses
16
+ * this instead of the configured `terminal:`. The dashboard's
17
+ * missing-terminal fallback dialog sets this so a confirm-to-fallback flow
18
+ * doesn't require mutating user config.
19
+ */
20
+ terminal?: TerminalChoice;
12
21
  /**
13
22
  * Only set when `kind === 'session'`. Defaults to `'resume'` when the URL
14
23
  * has no `mode` query param. Distinguishes "continue this session under the
@@ -27,6 +36,8 @@ interface ParsedOpenUrl {
27
36
  * - exactly one of `assignment` or `session` query params must be present
28
37
  * - neither param may be duplicated
29
38
  * - when `session` is present, optional `mode=resume|fork` (default `resume`)
39
+ * - optional `terminal=<choice>` one-shot override (validated against
40
+ * `TERMINAL_CHOICES`)
30
41
  *
31
42
  * Throws OpenUrlError with a structured code on any failure.
32
43
  */
@@ -116,7 +127,7 @@ interface ThemeConfig {
116
127
  interface HotkeyBindingsConfig {
117
128
  bindings: Partial<Record<BindableActionKind, string>>;
118
129
  }
119
- type TerminalChoice = 'terminal-app' | 'iterm' | 'ghostty' | 'alacritty' | 'warp' | 'kitty';
130
+
120
131
  interface SyntaurConfig {
121
132
  version: string;
122
133
  defaultProjectDir: string;
@@ -181,6 +192,13 @@ interface ResolveLaunchPlanInput {
181
192
  config: SyntaurConfig;
182
193
  projectsDir: string;
183
194
  assignmentsDir: string;
195
+ /**
196
+ * One-shot terminal override. When set, used in place of
197
+ * `getTerminal(config)`. Wired through from `?terminal=<choice>` on the
198
+ * incoming `syntaur://` URL so the dashboard's missing-terminal fallback
199
+ * dialog can confirm a different terminal without mutating user config.
200
+ */
201
+ terminalOverride?: TerminalChoice;
184
202
  }
185
203
  /**
186
204
  * Pick the agent the "Open in agent" flow should use. Order of preference:
@@ -3,6 +3,22 @@ var __esm = (fn, res) => function __init() {
3
3
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
4
4
  };
5
5
 
6
+ // src/utils/terminal-schema.ts
7
+ var TERMINAL_CHOICES;
8
+ var init_terminal_schema = __esm({
9
+ "src/utils/terminal-schema.ts"() {
10
+ "use strict";
11
+ TERMINAL_CHOICES = [
12
+ "terminal-app",
13
+ "iterm",
14
+ "ghostty",
15
+ "alacritty",
16
+ "warp",
17
+ "kitty"
18
+ ];
19
+ }
20
+ });
21
+
6
22
  // src/utils/paths.ts
7
23
  import { homedir } from "os";
8
24
  import { resolve } from "path";
@@ -265,6 +281,7 @@ var init_agents_schema = __esm({
265
281
 
266
282
  // src/utils/config.ts
267
283
  import { readFile as readFile2 } from "fs/promises";
284
+ import { spawnSync } from "child_process";
268
285
  import { resolve as resolve3, isAbsolute } from "path";
269
286
  function parseAgentCommand(value, agentId) {
270
287
  if (typeof value !== "string" || value.trim() === "") {
@@ -889,9 +906,20 @@ function parseTerminalConfig(value) {
889
906
  return trimmed;
890
907
  }
891
908
  function getTerminal(config) {
892
- return config.terminal ?? "terminal-app";
909
+ if (config.terminal) return config.terminal;
910
+ if (process.platform === "darwin") return "terminal-app";
911
+ if (process.platform === "linux") {
912
+ const order = ["kitty", "alacritty", "warp"];
913
+ for (const candidate of order) {
914
+ const result = spawnSync("which", [candidate], { encoding: "utf-8" });
915
+ if (result.status === 0 && result.stdout.trim().length > 0) {
916
+ return candidate;
917
+ }
918
+ }
919
+ }
920
+ return "terminal-app";
893
921
  }
894
- var TERMINAL_CHOICES, DEFAULT_CONFIG, AUTO_CREATE_WORKTREE_VALUES, AgentConfigError, KNOWN_AGENT_SCALAR_FIELDS, migratedConfigPaths, TerminalConfigError;
922
+ var DEFAULT_CONFIG, AUTO_CREATE_WORKTREE_VALUES, AgentConfigError, KNOWN_AGENT_SCALAR_FIELDS, migratedConfigPaths, TerminalConfigError;
895
923
  var init_config2 = __esm({
896
924
  "src/utils/config.ts"() {
897
925
  "use strict";
@@ -901,14 +929,7 @@ var init_config2 = __esm({
901
929
  init_fs_migration();
902
930
  init_hotkeysCatalog();
903
931
  init_agents_schema();
904
- TERMINAL_CHOICES = [
905
- "terminal-app",
906
- "iterm",
907
- "ghostty",
908
- "alacritty",
909
- "warp",
910
- "kitty"
911
- ];
932
+ init_terminal_schema();
912
933
  DEFAULT_CONFIG = {
913
934
  version: "2.0",
914
935
  defaultProjectDir: defaultProjectDir(),
@@ -1001,6 +1022,12 @@ function parseListField(frontmatter, fieldName) {
1001
1022
  }
1002
1023
  return results;
1003
1024
  }
1025
+ function unquoteYamlString(value) {
1026
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
1027
+ return value.slice(1, -1);
1028
+ }
1029
+ return value;
1030
+ }
1004
1031
  function parseProject(fileContent) {
1005
1032
  const [fm, body] = extractFrontmatter(fileContent);
1006
1033
  const slug = getField(fm, "slug") ?? getField(fm, "mission") ?? "";
@@ -1016,6 +1043,7 @@ function parseProject(fileContent) {
1016
1043
  updated: getField(fm, "updated") ?? "",
1017
1044
  tags: parseListField(fm, "tags"),
1018
1045
  workspace: getField(fm, "workspace"),
1046
+ repositories: parseListField(fm, "repositories").map(unquoteYamlString),
1019
1047
  externalIds: parseExternalIds(fm),
1020
1048
  body
1021
1049
  };
@@ -2464,6 +2492,7 @@ var init_api = __esm({
2464
2492
  });
2465
2493
 
2466
2494
  // src/launch/url.ts
2495
+ init_terminal_schema();
2467
2496
  var OpenUrlError = class extends Error {
2468
2497
  code;
2469
2498
  constructor(code, message) {
@@ -2515,6 +2544,24 @@ function parseOpenUrl(input) {
2515
2544
  "URL has both `assignment` and `session` query params \u2014 only one is allowed"
2516
2545
  );
2517
2546
  }
2547
+ const terminalVals = url.searchParams.getAll("terminal");
2548
+ if (terminalVals.length > 1) {
2549
+ throw new OpenUrlError(
2550
+ "duplicate-param",
2551
+ "URL has more than one `terminal` query param"
2552
+ );
2553
+ }
2554
+ let terminal;
2555
+ if (terminalVals.length === 1 && terminalVals[0].trim() !== "") {
2556
+ const candidate = terminalVals[0];
2557
+ if (!TERMINAL_CHOICES.includes(candidate)) {
2558
+ throw new OpenUrlError(
2559
+ "bad-terminal",
2560
+ `\`terminal\` query param must be one of: ${TERMINAL_CHOICES.join(", ")}`
2561
+ );
2562
+ }
2563
+ terminal = candidate;
2564
+ }
2518
2565
  if (assignmentVals.length === 1) {
2519
2566
  const id = assignmentVals[0];
2520
2567
  if (id.trim() === "") {
@@ -2523,7 +2570,7 @@ function parseOpenUrl(input) {
2523
2570
  "`assignment` query param is empty"
2524
2571
  );
2525
2572
  }
2526
- return { kind: "assignment", id };
2573
+ return { kind: "assignment", id, ...terminal ? { terminal } : {} };
2527
2574
  }
2528
2575
  if (sessionVals.length === 1) {
2529
2576
  const id = sessionVals[0];
@@ -2548,7 +2595,7 @@ function parseOpenUrl(input) {
2548
2595
  }
2549
2596
  mode = raw;
2550
2597
  }
2551
- return { kind: "session", id, mode };
2598
+ return { kind: "session", id, mode, ...terminal ? { terminal } : {} };
2552
2599
  }
2553
2600
  throw new OpenUrlError(
2554
2601
  "missing-id",
@@ -2671,7 +2718,7 @@ function pickAgent(config) {
2671
2718
  return agents.find((a) => a.default) ?? agents[0];
2672
2719
  }
2673
2720
  async function resolveLaunchPlan(input) {
2674
- const terminal = getTerminal(input.config);
2721
+ const terminal = input.terminalOverride ?? getTerminal(input.config);
2675
2722
  if (input.kind === "assignment") {
2676
2723
  return resolveAssignmentPlan(input, terminal);
2677
2724
  }
@@ -2914,19 +2961,19 @@ function buildTerminalInvocation(plan) {
2914
2961
  command: "osascript",
2915
2962
  args: [
2916
2963
  "-e",
2917
- 'tell application "Ghostty"',
2964
+ 'tell application "Ghostty" to activate',
2918
2965
  "-e",
2919
- "activate",
2966
+ "delay 0.3",
2920
2967
  "-e",
2921
- "set newWin to (new window)",
2968
+ 'tell application "System Events"',
2922
2969
  "-e",
2923
- "delay 0.2",
2970
+ 'keystroke "n" using command down',
2924
2971
  "-e",
2925
- "set t to terminal 1 of selected tab of newWin",
2972
+ "delay 0.4",
2926
2973
  "-e",
2927
- `input text ${appleScriptString(cdAndRun)} to t`,
2974
+ `keystroke ${appleScriptString(cdAndRun)}`,
2928
2975
  "-e",
2929
- 'send key "enter" to t',
2976
+ "key code 36",
2930
2977
  "-e",
2931
2978
  "end tell"
2932
2979
  ]