syntaur 0.6.1 → 0.7.1

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 (81) hide show
  1. package/README.md +2 -2
  2. package/dashboard/dist/assets/{_basePickBy-DTYUlCEg.js → _basePickBy-CIZortGD.js} +1 -1
  3. package/dashboard/dist/assets/{_baseUniq-C0Y4HRd5.js → _baseUniq-BHP5NBQ7.js} +1 -1
  4. package/dashboard/dist/assets/{arc-BFx2eqN9.js → arc-BLtQy7Cl.js} +1 -1
  5. package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-Erol1JD6.js → architectureDiagram-2XIMDMQ5-0mhIBjWy.js} +1 -1
  6. package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-kSkh6VkS.js → blockDiagram-WCTKOSBZ-CM7K5Tf5.js} +1 -1
  7. package/dashboard/dist/assets/{c4Diagram-IC4MRINW-C04oKzvX.js → c4Diagram-IC4MRINW-gsbeygvS.js} +1 -1
  8. package/dashboard/dist/assets/channel-FWLgstBg.js +1 -0
  9. package/dashboard/dist/assets/{chunk-4BX2VUAB-C3t0tXt-.js → chunk-4BX2VUAB-CneRz9Nd.js} +1 -1
  10. package/dashboard/dist/assets/{chunk-55IACEB6-2cnyEL0b.js → chunk-55IACEB6-uetANWHd.js} +1 -1
  11. package/dashboard/dist/assets/{chunk-FMBD7UC4-DIY9MTNi.js → chunk-FMBD7UC4-3-tNszoF.js} +1 -1
  12. package/dashboard/dist/assets/{chunk-JSJVCQXG-Cw8fpqpE.js → chunk-JSJVCQXG-DOO88rZD.js} +1 -1
  13. package/dashboard/dist/assets/{chunk-KX2RTZJC-BAhd66XV.js → chunk-KX2RTZJC-Bnc1CFy2.js} +1 -1
  14. package/dashboard/dist/assets/{chunk-NQ4KR5QH-RzXwoxk3.js → chunk-NQ4KR5QH-BfViC1Ms.js} +1 -1
  15. package/dashboard/dist/assets/{chunk-QZHKN3VN-Dgri4sGz.js → chunk-QZHKN3VN-CgjyAt2l.js} +1 -1
  16. package/dashboard/dist/assets/{chunk-WL4C6EOR-DYLj9JRa.js → chunk-WL4C6EOR-BYFermSR.js} +1 -1
  17. package/dashboard/dist/assets/classDiagram-VBA2DB6C-BAvQTSn_.js +1 -0
  18. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-BAvQTSn_.js +1 -0
  19. package/dashboard/dist/assets/clone-rSEllQ1P.js +1 -0
  20. package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-DfY_Fnfu.js → cose-bilkent-S5V4N54A-CE-k5SLv.js} +1 -1
  21. package/dashboard/dist/assets/{dagre-KLK3FWXG-CyTKIVSK.js → dagre-KLK3FWXG-CX7Br8LQ.js} +1 -1
  22. package/dashboard/dist/assets/{diagram-E7M64L7V-Krub7Xxo.js → diagram-E7M64L7V-t-xhWjCU.js} +1 -1
  23. package/dashboard/dist/assets/{diagram-IFDJBPK2-giUl9uHz.js → diagram-IFDJBPK2-BVhcTXsJ.js} +1 -1
  24. package/dashboard/dist/assets/{diagram-P4PSJMXO-oAtnO3C9.js → diagram-P4PSJMXO-fxt8ZSca.js} +1 -1
  25. package/dashboard/dist/assets/{erDiagram-INFDFZHY-eYaVjXqo.js → erDiagram-INFDFZHY-C20k2bxX.js} +1 -1
  26. package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-or5S0_Sb.js → flowDiagram-PKNHOUZH-CdeygexM.js} +1 -1
  27. package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-C9R1lsme.js → ganttDiagram-A5KZAMGK-CPsoOAV-.js} +1 -1
  28. package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-BQwsDzvp.js → gitGraphDiagram-K3NZZRJ6-t0tCTIZy.js} +1 -1
  29. package/dashboard/dist/assets/{graph-EQOX1wg8.js → graph-Bcqd31wL.js} +1 -1
  30. package/dashboard/dist/assets/{index-u80fISp0.css → index-bLWoSCLL.css} +1 -1
  31. package/dashboard/dist/assets/{index-Cy7yjuqO.js → index-eS0wtDO0.js} +87 -87
  32. package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-BjLlQWxk.js → infoDiagram-LFFYTUFH-DgoKvH3N.js} +1 -1
  33. package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-BNjydh4j.js → ishikawaDiagram-PHBUUO56-CGr4P8do.js} +1 -1
  34. package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-DNzE7TgQ.js → journeyDiagram-4ABVD52K-CHYRi6wF.js} +1 -1
  35. package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-FbNvGx6i.js → kanban-definition-K7BYSVSG-kwzqrFcW.js} +1 -1
  36. package/dashboard/dist/assets/{layout-B2yZvlWs.js → layout-wud47qGs.js} +1 -1
  37. package/dashboard/dist/assets/{linear-p68yY_14.js → linear-DG5js90X.js} +1 -1
  38. package/dashboard/dist/assets/{mermaid.core-D558akcW.js → mermaid.core-BDw69uC2.js} +4 -4
  39. package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-CZPgesSK.js → mindmap-definition-YRQLILUH-Dw_uyg1-.js} +1 -1
  40. package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-CdXMWspp.js → pieDiagram-SKSYHLDU-C7NBi6tK.js} +1 -1
  41. package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-D7tq22ZY.js → quadrantDiagram-337W2JSQ-_N_BSBd4.js} +1 -1
  42. package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-ByZxUSmd.js → requirementDiagram-Z7DCOOCP-BqUiqfP1.js} +1 -1
  43. package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-CZon9rRY.js → sankeyDiagram-WA2Y5GQK-C2Qq5ULW.js} +1 -1
  44. package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-nbELB6rb.js → sequenceDiagram-2WXFIKYE-BOCF2z8f.js} +1 -1
  45. package/dashboard/dist/assets/{stateDiagram-RAJIS63D-D_OPKr5B.js → stateDiagram-RAJIS63D-BvDyTxC5.js} +1 -1
  46. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-TaLLhLWD.js +1 -0
  47. package/dashboard/dist/assets/{timeline-definition-YZTLITO2-Cxuvk1D2.js → timeline-definition-YZTLITO2-DNNZxSrG.js} +1 -1
  48. package/dashboard/dist/assets/{treemap-KZPCXAKY-C0CRpL92.js → treemap-KZPCXAKY-C6hOdiGH.js} +1 -1
  49. package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-DijCj6M3.js → vennDiagram-LZ73GAT5-FmXl6puP.js} +1 -1
  50. package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-CdpE0oRi.js → xychartDiagram-JWTSCODW-Bjav12WG.js} +1 -1
  51. package/dashboard/dist/index.html +2 -2
  52. package/dist/dashboard/server.js +22 -15
  53. package/dist/dashboard/server.js.map +1 -1
  54. package/dist/index.js +93 -60
  55. package/dist/index.js.map +1 -1
  56. package/package.json +1 -1
  57. package/platforms/claude-code/README.md +3 -3
  58. package/platforms/claude-code/agents/syntaur-expert.md +12 -4
  59. package/platforms/claude-code/commands/save-session-summary/save-session-summary.md +24 -0
  60. package/platforms/claude-code/hooks/hooks.json +10 -0
  61. package/platforms/claude-code/hooks/session-start.sh +26 -1
  62. package/platforms/claude-code/references/file-ownership.md +2 -1
  63. package/platforms/claude-code/references/protocol-summary.md +6 -1
  64. package/platforms/claude-code/skills/track-session/SKILL.md +86 -0
  65. package/platforms/codex/README.md +2 -2
  66. package/platforms/codex/agents/syntaur-operator.md +6 -4
  67. package/platforms/codex/commands/save-session-summary.md +23 -0
  68. package/platforms/codex/references/file-ownership.md +2 -1
  69. package/platforms/codex/references/protocol-summary.md +6 -1
  70. package/vendor/syntaur-skills/skills/complete-assignment/SKILL.md +2 -0
  71. package/vendor/syntaur-skills/skills/grab-assignment/SKILL.md +7 -2
  72. package/vendor/syntaur-skills/skills/plan-assignment/SKILL.md +3 -1
  73. package/vendor/syntaur-skills/skills/save-session-summary/SKILL.md +113 -0
  74. package/vendor/syntaur-skills/skills/syntaur-protocol/SKILL.md +23 -4
  75. package/vendor/syntaur-skills/skills/syntaur-protocol/references/file-ownership.md +2 -1
  76. package/vendor/syntaur-skills/skills/syntaur-protocol/references/protocol-summary.md +6 -1
  77. package/dashboard/dist/assets/channel-C82tBKZ7.js +0 -1
  78. package/dashboard/dist/assets/classDiagram-VBA2DB6C-STOZ51tg.js +0 -1
  79. package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-STOZ51tg.js +0 -1
  80. package/dashboard/dist/assets/clone-TzhWk-Bj.js +0 -1
  81. package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-4pLM5B3m.js +0 -1
package/dist/index.js CHANGED
@@ -148,7 +148,7 @@ function extractFrontmatter(fileContent) {
148
148
  }
149
149
  function parseSimpleValue(raw) {
150
150
  const trimmed = raw.trim();
151
- if (trimmed === "null" || trimmed === "") return null;
151
+ if (trimmed === "null" || trimmed === "~" || trimmed === "") return null;
152
152
  if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
153
153
  return trimmed.slice(1, -1);
154
154
  }
@@ -199,6 +199,7 @@ function parseProject(fileContent) {
199
199
  updated: getField(fm, "updated") ?? "",
200
200
  tags: parseListField(fm, "tags"),
201
201
  workspace: getField(fm, "workspace"),
202
+ externalIds: parseExternalIds(fm),
202
203
  body
203
204
  };
204
205
  }
@@ -243,16 +244,14 @@ function parseExternalIds(frontmatter) {
243
244
  const colonIdx = line.indexOf(":");
244
245
  if (colonIdx < 0) continue;
245
246
  const key = line.slice(0, colonIdx).trim().replace(/^-\s+/, "");
246
- const value = line.slice(colonIdx + 1).trim();
247
- if (key && value) {
248
- entry[key] = value;
249
- }
247
+ if (!key) continue;
248
+ entry[key] = parseSimpleValue(line.slice(colonIdx + 1));
250
249
  }
251
- if (entry["system"] && entry["id"] && entry["url"]) {
250
+ if (entry["system"] && entry["id"]) {
252
251
  results.push({
253
252
  system: entry["system"],
254
253
  id: entry["id"],
255
- url: entry["url"]
254
+ url: entry["url"] || null
256
255
  });
257
256
  }
258
257
  }
@@ -2017,8 +2016,9 @@ ${todosSection}## Context
2017
2016
  - [Progress](./progress.md)
2018
2017
  - [Comments](./comments.md)
2019
2018
  - [Scratchpad](./scratchpad.md)
2020
- - [Handoff](./handoff.md)
2019
+ - [Handoff](./handoff.md) \u2014 cross-ticket outbound
2021
2020
  - [Decision Record](./decision-record.md)
2021
+ - [Sessions](./sessions/) \u2014 per-session continuity summaries (one \`<session-id>/summary.md\` per session)
2022
2022
  `;
2023
2023
  }
2024
2024
  var init_assignment = __esm({
@@ -2072,6 +2072,13 @@ var init_handoff = __esm({
2072
2072
  }
2073
2073
  });
2074
2074
 
2075
+ // src/templates/session-summary.ts
2076
+ var init_session_summary = __esm({
2077
+ "src/templates/session-summary.ts"() {
2078
+ "use strict";
2079
+ }
2080
+ });
2081
+
2075
2082
  // src/templates/progress.ts
2076
2083
  function renderProgress(params2) {
2077
2084
  return `---
@@ -2322,8 +2329,11 @@ You are working within the Syntaur protocol for multi-agent project coordination
2322
2329
  progress.md # Agent-writable, append-only: timestamped progress log
2323
2330
  comments.md # CLI-mediated: threaded questions/notes/feedback (via \`syntaur comment\`)
2324
2331
  scratchpad.md # Agent-writable: working notes
2325
- handoff.md # Agent-writable: append-only handoff log
2332
+ handoff.md # Agent-writable: append-only cross-ticket outbound at completion
2326
2333
  decision-record.md # Agent-writable: append-only decision log
2334
+ sessions/
2335
+ <session-id>/
2336
+ summary.md # Agent-writable: per-session continuity (single doc, overwritten)
2327
2337
  resources/
2328
2338
  _index.md # Derived (read-only)
2329
2339
  <resource-slug>.md # Shared-writable
@@ -2339,13 +2349,15 @@ You are working within the Syntaur protocol for multi-agent project coordination
2339
2349
  scratchpad.md
2340
2350
  handoff.md
2341
2351
  decision-record.md
2352
+ sessions/<session-id>/summary.md # Per-session continuity (same as project-nested)
2342
2353
  \`\`\`
2343
2354
 
2344
2355
  ## Write Boundary Rules (CRITICAL)
2345
2356
 
2346
2357
  ### Files you may WRITE:
2347
2358
  1. **Your assignment folder** -- only the assignment you are currently working on:
2348
- - \`assignment.md\`, \`plan*.md\` (0 or more versioned plan files), \`progress.md\`, \`scratchpad.md\`, \`handoff.md\`, \`decision-record.md\`
2359
+ - \`assignment.md\`, \`plan*.md\` (0 or more versioned plan files), \`progress.md\`, \`scratchpad.md\`, \`handoff.md\` (cross-ticket outbound at completion), \`decision-record.md\`
2360
+ - \`sessions/<session-id>/summary.md\` -- per-session continuity (single doc per session id, overwritten on save). Distinct from \`handoff.md\`.
2349
2361
  - Path (project-nested): \`~/.syntaur/projects/<project>/assignments/<your-assignment>/\`
2350
2362
  - Path (standalone): \`~/.syntaur/assignments/<your-assignment-uuid>/\`
2351
2363
  2. **Shared resources and memories** at the project level:
@@ -2449,7 +2461,8 @@ Before starting work, read these files in order:
2449
2461
  3. any \`${params2.assignmentDir}/plan*.md\` files linked from active todos in the \`## Todos\` section (may be 0, 1, or many)
2450
2462
  4. \`${params2.assignmentDir}/progress.md\` -- reverse-chron progress log (if present)
2451
2463
  5. \`${params2.assignmentDir}/comments.md\` -- threaded questions/notes/feedback (if present)
2452
- 6. \`${params2.assignmentDir}/handoff.md\` -- previous session handoff notes
2464
+ 6. \`${params2.assignmentDir}/handoff.md\` -- cross-ticket outbound history (entries from prior agents/humans handing this assignment off)
2465
+ 7. The latest \`${params2.assignmentDir}/sessions/<sid>/summary.md\` if present -- previous-session continuity (selected by \`summary.md\` file mtime; read it for "what was done / what's next" before resuming work in flight)
2453
2466
 
2454
2467
  ## Your Writable Files
2455
2468
 
@@ -2460,6 +2473,7 @@ You may write directly to these files inside your assignment folder:
2460
2473
  - \`${params2.assignmentDir}/scratchpad.md\`
2461
2474
  - \`${params2.assignmentDir}/handoff.md\`
2462
2475
  - \`${params2.assignmentDir}/decision-record.md\`
2476
+ - \`${params2.assignmentDir}/sessions/<session-id>/summary.md\` (per-session continuity)
2463
2477
 
2464
2478
  Do NOT edit \`${params2.assignmentDir}/comments.md\` directly \u2014 use \`syntaur comment\`. Do NOT edit other assignments' files \u2014 use \`syntaur request\` for cross-assignment todos.
2465
2479
 
@@ -2495,7 +2509,8 @@ If the global Syntaur Codex plugin is installed, prefer these workflows instead
2495
2509
  - \`create-assignment\` -- create a new assignment (use \`--type <bug|feature|chore|...>\` to classify; use \`--one-off\` to create a standalone assignment at \`~/.syntaur/assignments/<uuid>/\` with no parent project)
2496
2510
  - \`grab-assignment\` -- claim work, create \`.syntaur/context.json\`, and register a session
2497
2511
  - \`plan-assignment\` -- write a versioned plan file (\`plan.md\`, \`plan-v2.md\`, ...) and link it from the \`## Todos\` section of \`assignment.md\`
2498
- - \`complete-assignment\` -- append the handoff, append a final entry to \`progress.md\`, close the session, and transition state
2512
+ - \`complete-assignment\` -- write the cross-ticket \`handoff.md\` entry, append a final entry to \`progress.md\`, close the session, and transition state
2513
+ - \`save-session-summary\` -- write per-session continuity at \`<assignmentDir>/sessions/<sessionId>/summary.md\` for resume across sessions of the same agent. Codex has no \`PreCompact\` hook event \u2014 invoke this manually before compaction or session end.
2499
2514
  - \`track-session\` -- manage tracked tmux sessions for the dashboard
2500
2515
 
2501
2516
  If the plugin is unavailable, follow the same workflow manually with the \`syntaur\` CLI and keep the protocol files current yourself.
@@ -2509,7 +2524,8 @@ Before starting work, read these files in order:
2509
2524
  4. any \`${params2.assignmentDir}/plan*.md\` files linked from active todos in the \`## Todos\` section (may be 0, 1, or many)
2510
2525
  5. \`${params2.assignmentDir}/progress.md\` -- reverse-chron progress log (if present)
2511
2526
  6. \`${params2.assignmentDir}/comments.md\` -- threaded questions/notes/feedback (if present)
2512
- 7. \`${params2.assignmentDir}/handoff.md\` -- previous session handoff notes
2527
+ 7. \`${params2.assignmentDir}/handoff.md\` -- cross-ticket outbound history (entries from prior agents/humans handing this assignment off)
2528
+ 8. The latest \`${params2.assignmentDir}/sessions/<sid>/summary.md\` if present -- previous-session continuity (read it for "what was done / what's next" before resuming work in flight)
2513
2529
 
2514
2530
  ## Context File
2515
2531
 
@@ -2537,8 +2553,11 @@ Before starting work, read these files in order:
2537
2553
  progress.md # Agent-writable, append-only: timestamped progress log
2538
2554
  comments.md # CLI-mediated: threaded questions/notes/feedback (via \`syntaur comment\`)
2539
2555
  scratchpad.md # Agent-writable: working notes
2540
- handoff.md # Agent-writable: append-only handoff log
2556
+ handoff.md # Agent-writable: append-only cross-ticket outbound at completion
2541
2557
  decision-record.md # Agent-writable: append-only decision log
2558
+ sessions/
2559
+ <session-id>/
2560
+ summary.md # Agent-writable: per-session continuity (single doc, overwritten)
2542
2561
  resources/
2543
2562
  _index.md # Derived (read-only)
2544
2563
  <resource-slug>.md # Shared-writable
@@ -2554,13 +2573,15 @@ Before starting work, read these files in order:
2554
2573
  scratchpad.md
2555
2574
  handoff.md
2556
2575
  decision-record.md
2576
+ sessions/<session-id>/summary.md # Per-session continuity (same as project-nested)
2557
2577
  \`\`\`
2558
2578
 
2559
2579
  ## Write Boundary Rules (CRITICAL)
2560
2580
 
2561
2581
  ### Files you may WRITE:
2562
2582
  1. **Your assignment folder** -- only the assignment you are currently working on:
2563
- - \`assignment.md\`, \`plan*.md\` (0 or more versioned plan files), \`progress.md\`, \`scratchpad.md\`, \`handoff.md\`, \`decision-record.md\`
2583
+ - \`assignment.md\`, \`plan*.md\` (0 or more versioned plan files), \`progress.md\`, \`scratchpad.md\`, \`handoff.md\` (cross-ticket outbound at completion), \`decision-record.md\`
2584
+ - \`sessions/<session-id>/summary.md\` -- per-session continuity (single doc per session id, overwritten on save). Distinct from \`handoff.md\`.
2564
2585
  - Path: \`${params2.assignmentDir}/\`
2565
2586
  2. **Shared resources and memories** at the project level:
2566
2587
  - \`${params2.projectDir}/resources/<slug>.md\`
@@ -2639,7 +2660,7 @@ Read each linked playbook and follow the rules in its body section. The \`when_t
2639
2660
  - Slugs are lowercase, hyphen-separated. For standalone assignments, \`slug\` is display-only; the folder is named by the UUID.
2640
2661
  - Always read \`project.md\` at the project level (when project-nested) before starting work.
2641
2662
  - Keep \`assignment.md\` acceptance criteria and \`## Todos\` updated as work lands; append timestamped entries to \`progress.md\` (never to \`assignment.md\`).
2642
- - Keep active plan file(s) current after planning changes and \`handoff.md\` current before leaving the task.
2663
+ - Keep active plan file(s) current after planning changes. Write \`handoff.md\` (via \`complete-assignment\`) at the cross-ticket boundary; write \`sessions/<sid>/summary.md\` (via \`/save-session-summary\`) before compaction or before ending a session mid-assignment so a future session can resume cleanly.
2643
2664
  - When requirements shift, supersede the prior plan todo (\`- [x] ~~...~~ (superseded by plan-v<N>)\`) and write a new plan file instead of rewriting the old one.
2644
2665
  - Record questions, notes, and feedback via \`syntaur comment\`. Never edit \`comments.md\` directly. Resolve questions via the dashboard UI (toggle on the question entry).
2645
2666
  - To route work to another assignment, use \`syntaur request\`.
@@ -2683,6 +2704,7 @@ var init_templates = __esm({
2683
2704
  init_plan();
2684
2705
  init_scratchpad();
2685
2706
  init_handoff();
2707
+ init_session_summary();
2686
2708
  init_progress();
2687
2709
  init_comments();
2688
2710
  init_decision_record();
@@ -2998,7 +3020,7 @@ function extractFrontmatter2(fileContent) {
2998
3020
  }
2999
3021
  function parseSimpleValue2(raw) {
3000
3022
  const trimmed = raw.trim();
3001
- if (trimmed === "null") return null;
3023
+ if (trimmed === "null" || trimmed === "~" || trimmed === "") return null;
3002
3024
  if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
3003
3025
  return trimmed.slice(1, -1);
3004
3026
  }
@@ -3046,16 +3068,14 @@ function parseExternalIds2(frontmatter) {
3046
3068
  const colonIdx = line.indexOf(":");
3047
3069
  if (colonIdx < 0) continue;
3048
3070
  const key = line.slice(0, colonIdx).trim().replace(/^-\s+/, "");
3049
- const value = line.slice(colonIdx + 1).trim();
3050
- if (key && value) {
3051
- entry[key] = value;
3052
- }
3071
+ if (!key) continue;
3072
+ entry[key] = parseSimpleValue2(line.slice(colonIdx + 1));
3053
3073
  }
3054
- if (entry["system"] && entry["id"] && entry["url"]) {
3074
+ if (entry["system"] && entry["id"]) {
3055
3075
  results.push({
3056
3076
  system: entry["system"],
3057
3077
  id: entry["id"],
3058
- url: entry["url"]
3078
+ url: entry["url"] || null
3059
3079
  });
3060
3080
  }
3061
3081
  }
@@ -4799,6 +4819,7 @@ async function getProjectDetail(projectsDir2, slug) {
4799
4819
  created: project.created,
4800
4820
  updated,
4801
4821
  tags: project.tags,
4822
+ externalIds: project.externalIds,
4802
4823
  body: project.body,
4803
4824
  progress: rollup.progress,
4804
4825
  needsAttention: rollup.needsAttention,
@@ -13258,12 +13279,18 @@ var REQUIRED_SKILLS = [
13258
13279
  "plan-assignment",
13259
13280
  "complete-assignment",
13260
13281
  "create-assignment",
13261
- "create-project"
13282
+ "create-project",
13283
+ "save-session-summary"
13262
13284
  ];
13263
13285
  function getVendoredSkillsDir() {
13264
13286
  const here = dirname9(fileURLToPath4(import.meta.url));
13265
13287
  return resolve26(here, "..", "vendor", "syntaur-skills", "skills");
13266
13288
  }
13289
+ function getPlatformSkillsDir(target) {
13290
+ const here = dirname9(fileURLToPath4(import.meta.url));
13291
+ const kind = target === "claude" ? "claude-code" : "codex";
13292
+ return resolve26(here, "..", "platforms", kind, "skills");
13293
+ }
13267
13294
  function defaultSkillTargetDir(target) {
13268
13295
  if (target === "claude") return resolve26(homedir3(), ".claude", "skills");
13269
13296
  return resolve26(homedir3(), ".codex", "skills");
@@ -13318,8 +13345,24 @@ async function skillMatches(srcDir, destDir) {
13318
13345
  if (destFiles.length !== srcFiles.length) return false;
13319
13346
  return true;
13320
13347
  }
13348
+ async function installSkillDir(srcDir, destDir, skillName, source, force) {
13349
+ if (!await fileExists(destDir)) {
13350
+ await copyDir(srcDir, destDir);
13351
+ return { skill: skillName, status: "installed", targetPath: destDir, source };
13352
+ }
13353
+ if (await skillMatches(srcDir, destDir)) {
13354
+ return { skill: skillName, status: "already-current", targetPath: destDir, source };
13355
+ }
13356
+ if (force) {
13357
+ await rm4(destDir, { recursive: true, force: true });
13358
+ await copyDir(srcDir, destDir);
13359
+ return { skill: skillName, status: "overwritten", targetPath: destDir, source };
13360
+ }
13361
+ return { skill: skillName, status: "differs-preserved", targetPath: destDir, source };
13362
+ }
13321
13363
  async function installSkills(options) {
13322
13364
  const source = options.sourceDir ?? getVendoredSkillsDir();
13365
+ const platformSource = options.platformSkillsDir ?? getPlatformSkillsDir(options.target);
13323
13366
  const targetRoot = options.targetDir ?? defaultSkillTargetDir(options.target);
13324
13367
  const force = options.force ?? false;
13325
13368
  if (!await fileExists(source)) {
@@ -13331,39 +13374,19 @@ async function installSkills(options) {
13331
13374
  await mkdir4(targetRoot, { recursive: true });
13332
13375
  for (const skill of REQUIRED_SKILLS) {
13333
13376
  const srcDir = join3(source, skill);
13334
- const destDir = join3(targetRoot, skill);
13335
13377
  if (!await fileExists(srcDir)) continue;
13336
- if (!await fileExists(destDir)) {
13337
- await copyDir(srcDir, destDir);
13338
- results.push({
13339
- skill,
13340
- status: "installed",
13341
- targetPath: destDir
13342
- });
13343
- continue;
13344
- }
13345
- if (await skillMatches(srcDir, destDir)) {
13346
- results.push({
13347
- skill,
13348
- status: "already-current",
13349
- targetPath: destDir
13350
- });
13351
- continue;
13352
- }
13353
- if (force) {
13354
- await rm4(destDir, { recursive: true, force: true });
13355
- await copyDir(srcDir, destDir);
13356
- results.push({
13357
- skill,
13358
- status: "overwritten",
13359
- targetPath: destDir
13360
- });
13361
- } else {
13362
- results.push({
13363
- skill,
13364
- status: "differs-preserved",
13365
- targetPath: destDir
13366
- });
13378
+ const destDir = join3(targetRoot, skill);
13379
+ results.push(await installSkillDir(srcDir, destDir, skill, "shared", force));
13380
+ }
13381
+ if (options.target === "claude" && await fileExists(platformSource)) {
13382
+ const entries = await readdir11(platformSource, { withFileTypes: true });
13383
+ for (const entry of entries) {
13384
+ if (!entry.isDirectory()) continue;
13385
+ const skill = entry.name;
13386
+ if (REQUIRED_SKILLS.includes(skill)) continue;
13387
+ const srcDir = join3(platformSource, skill);
13388
+ const destDir = join3(targetRoot, skill);
13389
+ results.push(await installSkillDir(srcDir, destDir, skill, "platform", force));
13367
13390
  }
13368
13391
  }
13369
13392
  return results;
@@ -13371,8 +13394,16 @@ async function installSkills(options) {
13371
13394
  async function uninstallSkills(options) {
13372
13395
  const targetRoot = options.targetDir ?? defaultSkillTargetDir(options.target);
13373
13396
  if (!await fileExists(targetRoot)) return [];
13397
+ const known = new Set(REQUIRED_SKILLS);
13398
+ const platformSource = options.platformSkillsDir ?? getPlatformSkillsDir(options.target);
13399
+ if (options.target === "claude" && await fileExists(platformSource)) {
13400
+ const entries = await readdir11(platformSource, { withFileTypes: true });
13401
+ for (const entry of entries) {
13402
+ if (entry.isDirectory()) known.add(entry.name);
13403
+ }
13404
+ }
13374
13405
  const removed = [];
13375
- for (const skill of REQUIRED_SKILLS) {
13406
+ for (const skill of known) {
13376
13407
  const destDir = join3(targetRoot, skill);
13377
13408
  if (!await fileExists(destDir)) continue;
13378
13409
  const skillMd = join3(destDir, "SKILL.md");
@@ -13506,9 +13537,10 @@ async function installPluginCommand(options) {
13506
13537
  }
13507
13538
  }
13508
13539
  console.log("\nThe plugin is now available in Claude Code.");
13509
- console.log(" Slash commands: /grab-assignment, /plan-assignment, /complete-assignment, /create-assignment, /create-project");
13540
+ console.log(" Slash commands: /grab-assignment, /plan-assignment, /complete-assignment, /create-assignment, /create-project, /track-session, /save-session-summary");
13510
13541
  console.log(" Background: syntaur-protocol skill (auto-invoked)");
13511
- console.log(" Hook: write boundary enforcement (PreToolUse) + SessionStart/End");
13542
+ console.log(" Claude-specific skill: track-session (agent session registration)");
13543
+ console.log(" Hook: write boundary enforcement (PreToolUse) + SessionStart/End + PreCompact (prompts /save-session-summary)");
13512
13544
  }
13513
13545
 
13514
13546
  // src/commands/install-statusline.ts
@@ -14058,9 +14090,10 @@ async function installCodexPluginCommand(options) {
14058
14090
  }
14059
14091
  console.log("\nThe plugin is now available to Codex.");
14060
14092
  console.log(
14061
- " Protocol skills: syntaur-protocol, create-project, create-assignment, grab-assignment, plan-assignment, complete-assignment"
14093
+ " Protocol skills: syntaur-protocol, create-project, create-assignment, grab-assignment, plan-assignment, complete-assignment, save-session-summary"
14062
14094
  );
14063
14095
  console.log(" Codex-specific: track-session skill (rollout path aware)");
14096
+ console.log(" Slash commands: /track-session, /save-session-summary (no PreCompact hook on Codex \u2014 invoke manually before compaction)");
14064
14097
  console.log(" Hooks: write boundary enforcement, session cleanup");
14065
14098
  }
14066
14099