@statechange/council 0.6.0 → 0.8.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.
Files changed (150) hide show
  1. package/README.md +27 -27
  2. package/dist/cli.js +15 -15
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/councilor.d.ts +7 -0
  5. package/dist/commands/councilor.js +98 -0
  6. package/dist/commands/councilor.js.map +1 -0
  7. package/dist/commands/discuss.d.ts +2 -2
  8. package/dist/commands/discuss.js +14 -14
  9. package/dist/commands/discuss.js.map +1 -1
  10. package/dist/commands/history.js +2 -2
  11. package/dist/commands/history.js.map +1 -1
  12. package/dist/commands/list.js +7 -7
  13. package/dist/commands/list.js.map +1 -1
  14. package/dist/core/conversation-engine.d.ts +3 -3
  15. package/dist/core/conversation-engine.js +35 -35
  16. package/dist/core/conversation-engine.js.map +1 -1
  17. package/dist/core/councilor-loader.d.ts +4 -0
  18. package/dist/core/councilor-loader.js +98 -0
  19. package/dist/core/councilor-loader.js.map +1 -0
  20. package/dist/core/councilor-registry.d.ts +12 -0
  21. package/dist/core/councilor-registry.js +131 -0
  22. package/dist/core/councilor-registry.js.map +1 -0
  23. package/dist/core/excalidraw-cheatsheet.js +2 -2
  24. package/dist/core/history.d.ts +1 -1
  25. package/dist/core/history.js +1 -1
  26. package/dist/core/history.js.map +1 -1
  27. package/dist/core/infographic.js +4 -4
  28. package/dist/core/infographic.js.map +1 -1
  29. package/dist/core/output-formatter.js +2 -2
  30. package/dist/core/output-formatter.js.map +1 -1
  31. package/dist/core/secretary.js +7 -7
  32. package/dist/core/secretary.js.map +1 -1
  33. package/dist/core/skill-loader.d.ts +2 -2
  34. package/dist/core/skill-loader.js +6 -6
  35. package/dist/core/skill-loader.js.map +1 -1
  36. package/dist/electron/ipc-handlers.js +29 -29
  37. package/dist/electron/ipc-handlers.js.map +1 -1
  38. package/dist/electron/preload.js +5 -5
  39. package/dist/electron/preload.js.map +1 -1
  40. package/dist/types.d.ts +16 -13
  41. package/dist/types.js +1 -1
  42. package/dist/types.js.map +1 -1
  43. package/dist-electron/main.js +299 -296
  44. package/dist-electron/preload.mjs +1 -1
  45. package/dist-renderer/assets/{ar-SA-G6X2FPQ2-DXBh7WuV.js → ar-SA-G6X2FPQ2-DJTj94ZY.js} +1 -1
  46. package/dist-renderer/assets/{arc-D_n8J5SI.js → arc-3qXpUeCd.js} +1 -1
  47. package/dist-renderer/assets/{az-AZ-76LH7QW2-em6ZG9h0.js → az-AZ-76LH7QW2-1qnzBARG.js} +1 -1
  48. package/dist-renderer/assets/{bg-BG-XCXSNQG7-agu_XNxA.js → bg-BG-XCXSNQG7-BIZ5IFAv.js} +1 -1
  49. package/dist-renderer/assets/{blockDiagram-38ab4fdb-D1jpM-pu.js → blockDiagram-38ab4fdb-JwSYiuLB.js} +1 -1
  50. package/dist-renderer/assets/{bn-BD-2XOGV67Q-Y2AVxREy.js → bn-BD-2XOGV67Q-DiYpgYAg.js} +1 -1
  51. package/dist-renderer/assets/{c4Diagram-3d4e48cf-K75joZkc.js → c4Diagram-3d4e48cf-DUCtOTzV.js} +1 -1
  52. package/dist-renderer/assets/{ca-ES-6MX7JW3Y-DSUAGL6k.js → ca-ES-6MX7JW3Y-CV2JFVcm.js} +1 -1
  53. package/dist-renderer/assets/channel-BFQOS5-A.js +1 -0
  54. package/dist-renderer/assets/{classDiagram-70f12bd4-Dn1c2ZKw.js → classDiagram-70f12bd4-DY_je9I9.js} +1 -1
  55. package/dist-renderer/assets/{classDiagram-v2-f2320105-DwlW6q7H.js → classDiagram-v2-f2320105-Dm2xf0kS.js} +1 -1
  56. package/dist-renderer/assets/clone-BdgQjyvt.js +1 -0
  57. package/dist-renderer/assets/{createText-2e5e7dd3-BdGe-pcn.js → createText-2e5e7dd3-BU4YlynJ.js} +1 -1
  58. package/dist-renderer/assets/{cs-CZ-2BRQDIVT-DhhKBwfp.js → cs-CZ-2BRQDIVT-DgefxJv2.js} +1 -1
  59. package/dist-renderer/assets/{da-DK-5WZEPLOC-BXBIUFpK.js → da-DK-5WZEPLOC-CQeMoU_Y.js} +1 -1
  60. package/dist-renderer/assets/{de-DE-XR44H4JA-DdNoTfJ3.js → de-DE-XR44H4JA-Cm7XiExL.js} +1 -1
  61. package/dist-renderer/assets/{edges-e0da2a9e-B71iAGdZ.js → edges-e0da2a9e-DU4SF3SK.js} +1 -1
  62. package/dist-renderer/assets/{el-GR-BZB4AONW-CHvoll3l.js → el-GR-BZB4AONW-BKDtOlnf.js} +1 -1
  63. package/dist-renderer/assets/{erDiagram-9861fffd-CYB5wwYg.js → erDiagram-9861fffd-D_cCijmv.js} +1 -1
  64. package/dist-renderer/assets/{es-ES-U4NZUMDT-ndnyt5b3.js → es-ES-U4NZUMDT-Blb_L7K-.js} +1 -1
  65. package/dist-renderer/assets/{eu-ES-A7QVB2H4-4d18XNGh.js → eu-ES-A7QVB2H4-BZJBLMeO.js} +1 -1
  66. package/dist-renderer/assets/{fa-IR-HGAKTJCU-DslQwLpv.js → fa-IR-HGAKTJCU-C8gu07sI.js} +1 -1
  67. package/dist-renderer/assets/{fi-FI-Z5N7JZ37-DiHPxROG.js → fi-FI-Z5N7JZ37-0j8c6s09.js} +1 -1
  68. package/dist-renderer/assets/{flowDb-956e92f1-B9ZZIH6j.js → flowDb-956e92f1-BYeD7SW0.js} +1 -1
  69. package/dist-renderer/assets/{flowDiagram-66a62f08-Dp2DmvQc.js → flowDiagram-66a62f08-D_7wXttk.js} +1 -1
  70. package/dist-renderer/assets/flowDiagram-v2-96b9c2cf-ue4yLZei.js +1 -0
  71. package/dist-renderer/assets/{flowchart-elk-definition-4a651766-CVmjBy5D.js → flowchart-elk-definition-4a651766-G1tSg-iY.js} +1 -1
  72. package/dist-renderer/assets/{fr-FR-RHASNOE6-DroH4cCM.js → fr-FR-RHASNOE6-_cfaQNNq.js} +1 -1
  73. package/dist-renderer/assets/{ganttDiagram-c361ad54-SGHeXdlJ.js → ganttDiagram-c361ad54-Dk5lBh7P.js} +1 -1
  74. package/dist-renderer/assets/{gitGraphDiagram-72cf32ee-fBlPRtHx.js → gitGraphDiagram-72cf32ee-BzJAQtIC.js} +1 -1
  75. package/dist-renderer/assets/{gl-ES-HMX3MZ6V-B5sN7Uzl.js → gl-ES-HMX3MZ6V-GM5nrSrW.js} +1 -1
  76. package/dist-renderer/assets/{graph-BUgnMBv6.js → graph-C_xi4PaI.js} +1 -1
  77. package/dist-renderer/assets/{he-IL-6SHJWFNN-BK97a2ym.js → he-IL-6SHJWFNN-DvBtF7-G.js} +1 -1
  78. package/dist-renderer/assets/{hi-IN-IWLTKZ5I-DCZlvEWO.js → hi-IN-IWLTKZ5I-CNEB0-5K.js} +1 -1
  79. package/dist-renderer/assets/{hu-HU-A5ZG7DT2-I8vGLYrC.js → hu-HU-A5ZG7DT2-BmzYfJwp.js} +1 -1
  80. package/dist-renderer/assets/{id-ID-SAP4L64H-D7Zj-WBO.js → id-ID-SAP4L64H-CGCjaOLU.js} +1 -1
  81. package/dist-renderer/assets/{index-3862675e-CqgKkg4w.js → index-3862675e-C8a4355J.js} +1 -1
  82. package/dist-renderer/assets/index-CYsh274_.css +1 -0
  83. package/dist-renderer/assets/index-Cc7m7vZn.js +51 -0
  84. package/dist-renderer/assets/{index-9YedcJtH.js → index-x_yLI1Xq.js} +4 -4
  85. package/dist-renderer/assets/{infoDiagram-f8f76790-DojFopZJ.js → infoDiagram-f8f76790-BsJdteru.js} +1 -1
  86. package/dist-renderer/assets/{it-IT-JPQ66NNP-BBWhTSgs.js → it-IT-JPQ66NNP-vK6cBs4I.js} +1 -1
  87. package/dist-renderer/assets/{ja-JP-DBVTYXUO-z4i_Gp8C.js → ja-JP-DBVTYXUO-oUvELdsq.js} +1 -1
  88. package/dist-renderer/assets/{journeyDiagram-49397b02-CJ36K1NH.js → journeyDiagram-49397b02-BZcn-joQ.js} +1 -1
  89. package/dist-renderer/assets/{kaa-6HZHGXH3-B_WtQlVr.js → kaa-6HZHGXH3-39-zh5xR.js} +1 -1
  90. package/dist-renderer/assets/{kab-KAB-ZGHBKWFO-DTtORPAb.js → kab-KAB-ZGHBKWFO-DIwwJSlv.js} +1 -1
  91. package/dist-renderer/assets/{kk-KZ-P5N5QNE5-CPVxS5Do.js → kk-KZ-P5N5QNE5-jEG0G6v4.js} +1 -1
  92. package/dist-renderer/assets/{km-KH-HSX4SM5Z-Cwm0mGEA.js → km-KH-HSX4SM5Z-f0MtADYu.js} +1 -1
  93. package/dist-renderer/assets/{ko-KR-MTYHY66A-B7XhlbiR.js → ko-KR-MTYHY66A-D0sjNbcb.js} +1 -1
  94. package/dist-renderer/assets/{ku-TR-6OUDTVRD-CPCWoAyz.js → ku-TR-6OUDTVRD-D_uqAOZU.js} +1 -1
  95. package/dist-renderer/assets/{layout--e2IpTlO.js → layout-Bho0HnCB.js} +1 -1
  96. package/dist-renderer/assets/{line-oAyHL3iY.js → line-BvfrpBJA.js} +1 -1
  97. package/dist-renderer/assets/{linear-BoN-rD3R.js → linear-CzjqC3F_.js} +1 -1
  98. package/dist-renderer/assets/{lt-LT-XHIRWOB4-CyI4_Tq3.js → lt-LT-XHIRWOB4-Ct0yC4CT.js} +1 -1
  99. package/dist-renderer/assets/{lv-LV-5QDEKY6T-DLljN33x.js → lv-LV-5QDEKY6T-nkNbPHg0.js} +1 -1
  100. package/dist-renderer/assets/{mindmap-definition-fc14e90a-CnLgRQ_O.js → mindmap-definition-fc14e90a-BHot8rEp.js} +1 -1
  101. package/dist-renderer/assets/{mr-IN-CRQNXWMA-CLAaPXvA.js → mr-IN-CRQNXWMA-B861rik7.js} +1 -1
  102. package/dist-renderer/assets/{my-MM-5M5IBNSE-EGw1M9CW.js → my-MM-5M5IBNSE-SOXg7PeE.js} +1 -1
  103. package/dist-renderer/assets/{nb-NO-T6EIAALU-CrpHBY71.js → nb-NO-T6EIAALU-D22gGzt7.js} +1 -1
  104. package/dist-renderer/assets/{nl-NL-IS3SIHDZ-BGiRPMkX.js → nl-NL-IS3SIHDZ-CJxOBLb1.js} +1 -1
  105. package/dist-renderer/assets/{nn-NO-6E72VCQL-Bg9--0vP.js → nn-NO-6E72VCQL-FGcbdlO3.js} +1 -1
  106. package/dist-renderer/assets/{oc-FR-POXYY2M6-3aNzRUH5.js → oc-FR-POXYY2M6-s7Swo1Cu.js} +1 -1
  107. package/dist-renderer/assets/{pa-IN-N4M65BXN-CQ1Qt20e.js → pa-IN-N4M65BXN-DFJMREPh.js} +1 -1
  108. package/dist-renderer/assets/{percentages-BXMCSKIN-BdcO8JE0.js → percentages-BXMCSKIN-BhceqxTM.js} +7 -7
  109. package/dist-renderer/assets/{pica-DAe8i4qi.js → pica-ej4Z4fjh.js} +1 -1
  110. package/dist-renderer/assets/{pieDiagram-8a3498a8-C2C4gnpI.js → pieDiagram-8a3498a8-CnDnQfd0.js} +1 -1
  111. package/dist-renderer/assets/{pl-PL-T2D74RX3-DgbjC8Ll.js → pl-PL-T2D74RX3-uXVmB6im.js} +1 -1
  112. package/dist-renderer/assets/{pt-BR-5N22H2LF-DuWVGxtI.js → pt-BR-5N22H2LF-8kdgECeZ.js} +1 -1
  113. package/dist-renderer/assets/{pt-PT-UZXXM6DQ-CbndO7_y.js → pt-PT-UZXXM6DQ-D4vr9vo6.js} +1 -1
  114. package/dist-renderer/assets/{quadrantDiagram-120e2f19-BlmT42uD.js → quadrantDiagram-120e2f19-DlUESmO2.js} +1 -1
  115. package/dist-renderer/assets/{requirementDiagram-deff3bca-DZp4Qu-J.js → requirementDiagram-deff3bca-CfOs9jR8.js} +1 -1
  116. package/dist-renderer/assets/{ro-RO-JPDTUUEW-YgTIqyaS.js → ro-RO-JPDTUUEW-CztO0tWv.js} +1 -1
  117. package/dist-renderer/assets/{ru-RU-B4JR7IUQ-B4-xC-bY.js → ru-RU-B4JR7IUQ-aVURliDr.js} +1 -1
  118. package/dist-renderer/assets/{sankeyDiagram-04a897e0-DQU3Sh4e.js → sankeyDiagram-04a897e0-DRRc8FSN.js} +1 -1
  119. package/dist-renderer/assets/{sequenceDiagram-704730f1-BMDPHAvO.js → sequenceDiagram-704730f1-BaswaqQO.js} +1 -1
  120. package/dist-renderer/assets/{si-LK-N5RQ5JYF-xJBJNkkH.js → si-LK-N5RQ5JYF-B2KWtx6N.js} +1 -1
  121. package/dist-renderer/assets/{sk-SK-C5VTKIMK-D3oM9sTx.js → sk-SK-C5VTKIMK-DlRzLxRJ.js} +1 -1
  122. package/dist-renderer/assets/{sl-SI-NN7IZMDC-Dr3hNCQI.js → sl-SI-NN7IZMDC-Ox8yiRTS.js} +1 -1
  123. package/dist-renderer/assets/{stateDiagram-587899a1-kJVlt2mB.js → stateDiagram-587899a1-DSEEonbL.js} +1 -1
  124. package/dist-renderer/assets/{stateDiagram-v2-d93cdb3a-Oo192ox1.js → stateDiagram-v2-d93cdb3a-C135NgbB.js} +1 -1
  125. package/dist-renderer/assets/{styles-6aaf32cf-Cw1X4bWF.js → styles-6aaf32cf-X5nh1pD3.js} +1 -1
  126. package/dist-renderer/assets/{styles-9a916d00-BIBcInOQ.js → styles-9a916d00-BCZu272E.js} +1 -1
  127. package/dist-renderer/assets/{styles-c10674c1-DboG8Lt4.js → styles-c10674c1-C5JGHSaS.js} +1 -1
  128. package/dist-renderer/assets/{subset-shared.chunk-ZAiO-eLl.js → subset-shared.chunk-CzgdV5hf.js} +1 -1
  129. package/dist-renderer/assets/{subset-worker.chunk-B6PRRmQb.js → subset-worker.chunk-DfLYxc1O.js} +1 -1
  130. package/dist-renderer/assets/{sv-SE-XGPEYMSR-CegwfGx6.js → sv-SE-XGPEYMSR-CizFbLCT.js} +1 -1
  131. package/dist-renderer/assets/{svgDrawCommon-08f97a94-Dn29OsMT.js → svgDrawCommon-08f97a94-Cv5ZIzzk.js} +1 -1
  132. package/dist-renderer/assets/{ta-IN-2NMHFXQM-tSe3kTsK.js → ta-IN-2NMHFXQM-B66K2LEN.js} +1 -1
  133. package/dist-renderer/assets/{th-TH-HPSO5L25-DiuZcD9o.js → th-TH-HPSO5L25-DvHt1SBY.js} +1 -1
  134. package/dist-renderer/assets/{timeline-definition-85554ec2-DAY01_uJ.js → timeline-definition-85554ec2-C955-u4m.js} +1 -1
  135. package/dist-renderer/assets/{tr-TR-DEFEU3FU-f-T831Ou.js → tr-TR-DEFEU3FU-u0AuqRoD.js} +1 -1
  136. package/dist-renderer/assets/{uk-UA-QMV73CPH-oa90pxqd.js → uk-UA-QMV73CPH-IwAiPvJL.js} +1 -1
  137. package/dist-renderer/assets/{vi-VN-M7AON7JQ-CFBU2l5s.js → vi-VN-M7AON7JQ-Dh6Aj3f5.js} +1 -1
  138. package/dist-renderer/assets/{xychartDiagram-e933f94c-B6py5YKf.js → xychartDiagram-e933f94c-Bst4jMma.js} +1 -1
  139. package/dist-renderer/assets/{zh-CN-LNUGB5OW-R4K3nYOI.js → zh-CN-LNUGB5OW-BVXMa9T3.js} +1 -1
  140. package/dist-renderer/assets/{zh-HK-E62DVLB3-BjLHW6lU.js → zh-HK-E62DVLB3-DYEIu92z.js} +1 -1
  141. package/dist-renderer/assets/{zh-TW-RAJ6MFWO-e20gphGm.js → zh-TW-RAJ6MFWO-Dm9oSthu.js} +1 -1
  142. package/dist-renderer/index.html +2 -2
  143. package/package.json +2 -2
  144. package/skills/council-manage/SKILL.md +45 -45
  145. package/skills/council-setup-keys/SKILL.md +2 -2
  146. package/dist-renderer/assets/channel-B90-0NuK.js +0 -1
  147. package/dist-renderer/assets/clone-DEtBvu0Z.js +0 -1
  148. package/dist-renderer/assets/flowDiagram-v2-96b9c2cf-BsIp2X-N.js +0 -1
  149. package/dist-renderer/assets/index-DJ14s8KN.js +0 -51
  150. package/dist-renderer/assets/index-HXjW9ZG3.css +0 -1
@@ -23,94 +23,94 @@ const Ke = k.object({
23
23
  skills: k.array(k.string()).default([]),
24
24
  temperature: k.number().min(0).max(2).optional(),
25
25
  avatar: k.string().optional()
26
- }), je = (o, r) => [
27
- d(o, "skills", r, "SKILL.md"),
28
- d(process.cwd(), ".claude", "skills", r, "SKILL.md"),
29
- d(v(), ".agents", "skills", r, "SKILL.md"),
30
- d(v(), ".claude", "skills", r, "SKILL.md")
26
+ }), je = (o, s) => [
27
+ d(o, "skills", s, "SKILL.md"),
28
+ d(process.cwd(), ".claude", "skills", s, "SKILL.md"),
29
+ d(v(), ".agents", "skills", s, "SKILL.md"),
30
+ d(v(), ".claude", "skills", s, "SKILL.md")
31
31
  ];
32
- async function Be(o, r) {
33
- for (const t of je(r, o))
32
+ async function Be(o, s) {
33
+ for (const t of je(s, o))
34
34
  if (E(t)) {
35
- const e = await w(t, "utf-8"), { content: s } = X(e);
36
- return s.trim();
35
+ const e = await w(t, "utf-8"), { content: r } = X(e);
36
+ return r.trim();
37
37
  }
38
38
  return null;
39
39
  }
40
- async function Ge(o, r) {
40
+ async function Ge(o, s) {
41
41
  const t = [];
42
42
  for (const e of o) {
43
- const s = await Be(e, r);
44
- s && t.push(`## Skill: ${e}
43
+ const r = await Be(e, s);
44
+ r && t.push(`## Skill: ${e}
45
45
 
46
- ${s}`);
46
+ ${r}`);
47
47
  }
48
48
  return t.join(`
49
49
 
50
50
  `);
51
51
  }
52
- function Fe(o, r) {
53
- return o ? o.startsWith("http://") || o.startsWith("https://") ? o : `council-file://${o.startsWith("/") ? o : d(r, o)}` : void 0;
52
+ function Fe(o, s) {
53
+ return o ? o.startsWith("http://") || o.startsWith("https://") ? o : `council-file://${o.startsWith("/") ? o : d(s, o)}` : void 0;
54
54
  }
55
- async function We(o, r) {
55
+ async function We(o, s) {
56
56
  const t = /\{\{(.+?)\}\}/g;
57
57
  let e = o;
58
- for (const s of o.matchAll(t)) {
59
- const n = s[1].trim(), a = d(r, n);
58
+ for (const r of o.matchAll(t)) {
59
+ const n = r[1].trim(), a = d(s, n);
60
60
  if (E(a)) {
61
61
  const i = await w(a, "utf-8");
62
- e = e.replace(s[0], i.trim());
62
+ e = e.replace(r[0], i.trim());
63
63
  } else
64
- e = e.replace(s[0], `[Reference not found: ${n}]`);
64
+ e = e.replace(r[0], `[Reference not found: ${n}]`);
65
65
  }
66
66
  return e;
67
67
  }
68
68
  async function oe(o) {
69
- const r = G(o), t = d(r, "ABOUT.md");
69
+ const s = G(o), t = d(s, "ABOUT.md");
70
70
  if (!E(t))
71
- throw new Error(`No ABOUT.md found in ${r}`);
72
- const e = await w(t, "utf-8"), { data: s, content: n } = X(e), a = Ke.parse(s);
73
- let i = await We(n.trim(), r);
71
+ throw new Error(`No ABOUT.md found in ${s}`);
72
+ const e = await w(t, "utf-8"), { data: r, content: n } = X(e), a = Ke.parse(r);
73
+ let i = await We(n.trim(), s);
74
74
  if (a.skills.length > 0) {
75
- const u = await Ge(a.skills, r);
75
+ const u = await Ge(a.skills, s);
76
76
  u && (i += `
77
77
 
78
78
  ` + u);
79
79
  }
80
80
  return {
81
- id: C(r),
81
+ id: C(s),
82
82
  frontmatter: a,
83
83
  systemPrompt: i,
84
- dirPath: r,
85
- avatarUrl: Fe(a.avatar, r)
84
+ dirPath: s,
85
+ avatarUrl: Fe(a.avatar, s)
86
86
  };
87
87
  }
88
- async function se(o, r) {
88
+ async function re(o, s) {
89
89
  const t = [], e = /* @__PURE__ */ new Set();
90
- if (r?.length) {
91
- for (const s of r)
92
- if (E(d(s, "ABOUT.md")))
90
+ if (s?.length) {
91
+ for (const r of s)
92
+ if (E(d(r, "ABOUT.md")))
93
93
  try {
94
- const n = await oe(s);
94
+ const n = await oe(r);
95
95
  e.has(n.id) || (t.push(n), e.add(n.id));
96
96
  } catch {
97
97
  }
98
98
  }
99
99
  if (E(o)) {
100
- const s = await V(o);
101
- for (const n of s) {
100
+ const r = await V(o);
101
+ for (const n of r) {
102
102
  const a = d(o, n);
103
103
  (await he(a)).isDirectory() && E(d(a, "ABOUT.md")) && (e.has(C(a)) || (t.push(await oe(a)), e.add(C(a))));
104
104
  }
105
105
  }
106
106
  if (t.length === 0)
107
107
  throw new Error(
108
- `No counsellors found. Searched ${o}${r?.length ? ` and ${r.length} registered path(s)` : ""}.
109
- Create one with: mkdir -p ~/.ai-council/counsellors/my-counsellor && council counsellor add ~/.ai-council/counsellors/my-counsellor`
108
+ `No councilors found. Searched ${o}${s?.length ? ` and ${s.length} registered path(s)` : ""}.
109
+ Create one with: mkdir -p ~/.ai-council/councilors/my-councilor && council councilor add ~/.ai-council/councilors/my-councilor`
110
110
  );
111
111
  return t;
112
112
  }
113
- const Me = U(R), ge = d(v(), ".ai-council", "config.json"), re = d(v(), ".ai-council", "counsellors");
113
+ const Me = U(R), ge = d(v(), ".ai-council", "config.json"), se = d(v(), ".ai-council", "councilors");
114
114
  async function Q() {
115
115
  try {
116
116
  return JSON.parse(await w(ge, "utf-8"));
@@ -119,37 +119,40 @@ async function Q() {
119
119
  }
120
120
  }
121
121
  async function Z(o) {
122
- const r = d(v(), ".ai-council");
123
- await N(r, { recursive: !0 }), await P(ge, JSON.stringify(o, null, 2), "utf-8");
122
+ const s = d(v(), ".ai-council");
123
+ await N(s, { recursive: !0 }), await P(ge, JSON.stringify(o, null, 2), "utf-8");
124
+ }
125
+ function Ye(o) {
126
+ return o.councilors ?? o.counsellors ?? {};
124
127
  }
125
128
  function ae(o) {
126
- return Object.values(o.counsellors ?? {}).map((r) => r.path);
129
+ return Object.values(Ye(o)).map((s) => s.path);
127
130
  }
128
- async function Ye(o) {
129
- const r = G(o), t = d(r, "ABOUT.md");
131
+ async function He(o) {
132
+ const s = G(o), t = d(s, "ABOUT.md");
130
133
  if (!E(t))
131
- throw new Error(`No ABOUT.md found in ${r}`);
132
- const e = C(r), s = await Q(), n = s.counsellors ?? {};
134
+ throw new Error(`No ABOUT.md found in ${s}`);
135
+ const e = C(s), r = await Q(), n = r.councilors ?? {};
133
136
  if (n[e])
134
- throw new Error(`Counsellor "${e}" is already registered (path: ${n[e].path})`);
137
+ throw new Error(`Councilor "${e}" is already registered (path: ${n[e].path})`);
135
138
  const u = (await w(t, "utf-8")).match(/^name:\s*["']?(.+?)["']?\s*$/m)?.[1] ?? e;
136
139
  return n[e] = {
137
- path: r,
140
+ path: s,
138
141
  source: "local",
139
142
  addedAt: (/* @__PURE__ */ new Date()).toISOString()
140
- }, s.counsellors = n, await Z(s), { id: e, name: u };
143
+ }, r.councilors = n, await Z(r), { id: e, name: u };
141
144
  }
142
- async function He(o) {
143
- await N(re, { recursive: !0 });
144
- const r = C(o, ".git").replace(/\.git$/, ""), t = d(re, r);
145
+ async function Je(o) {
146
+ await N(se, { recursive: !0 });
147
+ const s = C(o, ".git").replace(/\.git$/, ""), t = d(se, s);
145
148
  if (E(t))
146
149
  throw new Error(`Directory already exists: ${t}. Remove it first or use a different URL.`);
147
150
  await Me("git", ["clone", "--depth", "1", o, t]);
148
- const e = [], s = await Q(), n = s.counsellors ?? {};
151
+ const e = [], r = await Q(), n = r.councilors ?? {};
149
152
  if (E(d(t, "ABOUT.md"))) {
150
- const a = r;
153
+ const a = s;
151
154
  if (n[a])
152
- throw new Error(`Counsellor "${a}" is already registered`);
155
+ throw new Error(`Councilor "${a}" is already registered`);
153
156
  const c = (await w(d(t, "ABOUT.md"), "utf-8")).match(/^name:\s*["']?(.+?)["']?\s*$/m)?.[1] ?? a;
154
157
  n[a] = {
155
158
  path: t,
@@ -175,18 +178,18 @@ async function He(o) {
175
178
  }
176
179
  }
177
180
  if (e.length === 0)
178
- throw await F(t, { recursive: !0, force: !0 }), new Error("No counsellors found in cloned repository (no ABOUT.md files)");
181
+ throw await F(t, { recursive: !0, force: !0 }), new Error("No councilors found in cloned repository (no ABOUT.md files)");
179
182
  }
180
- return s.counsellors = n, await Z(s), e;
183
+ return r.councilors = n, await Z(r), e;
181
184
  }
182
- async function Je(o, r = !1) {
183
- const t = await Q(), e = t.counsellors ?? {}, s = e[o];
184
- if (!s)
185
- throw new Error(`Counsellor "${o}" is not registered`);
186
- r && s.source === "git" && E(s.path) && await F(s.path, { recursive: !0, force: !0 }), delete e[o], t.counsellors = e, await Z(t);
185
+ async function ze(o, s = !1) {
186
+ const t = await Q(), e = t.councilors ?? {}, r = e[o];
187
+ if (!r)
188
+ throw new Error(`Councilor "${o}" is not registered`);
189
+ s && r.source === "git" && E(r.path) && await F(r.path, { recursive: !0, force: !0 }), delete e[o], t.councilors = e, await Z(t);
187
190
  }
188
- function ze(o) {
189
- const r = new Re({
191
+ function Ve(o) {
192
+ const s = new Re({
190
193
  apiKey: o.apiKey ?? process.env.ANTHROPIC_API_KEY,
191
194
  ...o.baseUrl ? { baseURL: o.baseUrl } : {}
192
195
  });
@@ -194,7 +197,7 @@ function ze(o) {
194
197
  name: "anthropic",
195
198
  defaultModel: "claude-sonnet-4-5-20250929",
196
199
  async chat(t) {
197
- const e = await r.messages.create({
200
+ const e = await s.messages.create({
198
201
  model: t.model,
199
202
  max_tokens: 4096,
200
203
  system: t.systemPrompt,
@@ -213,7 +216,7 @@ function ze(o) {
213
216
  };
214
217
  },
215
218
  async *chatStream(t) {
216
- const e = r.messages.stream({
219
+ const e = s.messages.stream({
217
220
  model: t.model,
218
221
  max_tokens: 4096,
219
222
  system: t.systemPrompt,
@@ -225,19 +228,19 @@ function ze(o) {
225
228
  });
226
229
  for await (const n of e)
227
230
  n.type === "content_block_delta" && n.delta.type === "text_delta" && (yield { delta: n.delta.text });
228
- const s = await e.finalMessage();
231
+ const r = await e.finalMessage();
229
232
  yield {
230
233
  delta: "",
231
234
  tokenUsage: {
232
- input: s.usage.input_tokens,
233
- output: s.usage.output_tokens
235
+ input: r.usage.input_tokens,
236
+ output: r.usage.output_tokens
234
237
  }
235
238
  };
236
239
  }
237
240
  };
238
241
  }
239
- function Ve(o) {
240
- const r = new Ue({
242
+ function Xe(o) {
243
+ const s = new Ue({
241
244
  apiKey: o.apiKey ?? process.env.OPENAI_API_KEY,
242
245
  ...o.baseUrl ? { baseURL: o.baseUrl } : {}
243
246
  });
@@ -245,7 +248,7 @@ function Ve(o) {
245
248
  name: "openai",
246
249
  defaultModel: "gpt-4o",
247
250
  async chat(t) {
248
- const e = await r.chat.completions.create({
251
+ const e = await s.chat.completions.create({
249
252
  model: t.model,
250
253
  messages: [
251
254
  { role: "system", content: t.systemPrompt },
@@ -262,39 +265,39 @@ function Ve(o) {
262
265
  };
263
266
  },
264
267
  async *chatStream(t) {
265
- const e = await r.chat.completions.create({
268
+ const e = await s.chat.completions.create({
266
269
  model: t.model,
267
270
  messages: [
268
271
  { role: "system", content: t.systemPrompt },
269
- ...t.messages.map((s) => ({
270
- role: s.role,
271
- content: s.content
272
+ ...t.messages.map((r) => ({
273
+ role: r.role,
274
+ content: r.content
272
275
  }))
273
276
  ],
274
277
  ...t.temperature !== void 0 ? { temperature: t.temperature } : {},
275
278
  stream: !0,
276
279
  stream_options: { include_usage: !0 }
277
280
  });
278
- for await (const s of e) {
279
- const n = s.choices[0]?.delta?.content;
280
- n && (yield { delta: n }), s.usage && (yield {
281
+ for await (const r of e) {
282
+ const n = r.choices[0]?.delta?.content;
283
+ n && (yield { delta: n }), r.usage && (yield {
281
284
  delta: "",
282
285
  tokenUsage: {
283
- input: s.usage.prompt_tokens,
284
- output: s.usage.completion_tokens
286
+ input: r.usage.prompt_tokens,
287
+ output: r.usage.completion_tokens
285
288
  }
286
289
  });
287
290
  }
288
291
  }
289
292
  };
290
293
  }
291
- function Xe(o) {
292
- const r = o.apiKey ?? process.env.GOOGLE_API_KEY ?? "", t = new Te(r);
294
+ function Qe(o) {
295
+ const s = o.apiKey ?? process.env.GOOGLE_API_KEY ?? "", t = new Te(s);
293
296
  return {
294
297
  name: "google",
295
298
  defaultModel: "gemini-2.0-flash",
296
299
  async chat(e) {
297
- const s = t.getGenerativeModel({
300
+ const r = t.getGenerativeModel({
298
301
  model: e.model,
299
302
  systemInstruction: e.systemPrompt,
300
303
  generationConfig: {
@@ -303,7 +306,7 @@ function Xe(o) {
303
306
  }), n = e.messages.slice(0, -1).map((m) => ({
304
307
  role: m.role === "assistant" ? "model" : "user",
305
308
  parts: [{ text: m.content }]
306
- })), a = s.startChat({ history: n }), i = e.messages[e.messages.length - 1], c = (await a.sendMessage(i?.content ?? "")).response;
309
+ })), a = r.startChat({ history: n }), i = e.messages[e.messages.length - 1], c = (await a.sendMessage(i?.content ?? "")).response;
307
310
  return {
308
311
  content: c.text(),
309
312
  tokenUsage: c.usageMetadata ? {
@@ -313,7 +316,7 @@ function Xe(o) {
313
316
  };
314
317
  },
315
318
  async *chatStream(e) {
316
- const s = t.getGenerativeModel({
319
+ const r = t.getGenerativeModel({
317
320
  model: e.model,
318
321
  systemInstruction: e.systemPrompt,
319
322
  generationConfig: {
@@ -322,7 +325,7 @@ function Xe(o) {
322
325
  }), n = e.messages.slice(0, -1).map((m) => ({
323
326
  role: m.role === "assistant" ? "model" : "user",
324
327
  parts: [{ text: m.content }]
325
- })), a = s.startChat({ history: n }), i = e.messages[e.messages.length - 1], u = await a.sendMessageStream(i?.content ?? "");
328
+ })), a = r.startChat({ history: n }), i = e.messages[e.messages.length - 1], u = await a.sendMessageStream(i?.content ?? "");
326
329
  for await (const m of u.stream) {
327
330
  const y = m.text();
328
331
  y && (yield { delta: y });
@@ -338,21 +341,21 @@ function Xe(o) {
338
341
  }
339
342
  };
340
343
  }
341
- function Qe(o) {
342
- const r = new Le({
344
+ function Ze(o) {
345
+ const s = new Le({
343
346
  host: o.baseUrl ?? "http://localhost:11434"
344
347
  });
345
348
  return {
346
349
  name: "ollama",
347
350
  defaultModel: "llama3.2",
348
351
  async chat(t) {
349
- const e = await r.chat({
352
+ const e = await s.chat({
350
353
  model: t.model,
351
354
  messages: [
352
355
  { role: "system", content: t.systemPrompt },
353
- ...t.messages.map((s) => ({
354
- role: s.role,
355
- content: s.content
356
+ ...t.messages.map((r) => ({
357
+ role: r.role,
358
+ content: r.content
356
359
  }))
357
360
  ],
358
361
  options: {
@@ -368,7 +371,7 @@ function Qe(o) {
368
371
  };
369
372
  },
370
373
  async *chatStream(t) {
371
- const e = await r.chat({
374
+ const e = await s.chat({
372
375
  model: t.model,
373
376
  messages: [
374
377
  { role: "system", content: t.systemPrompt },
@@ -382,59 +385,59 @@ function Qe(o) {
382
385
  },
383
386
  stream: !0
384
387
  });
385
- let s, n;
388
+ let r, n;
386
389
  for await (const a of e)
387
- a.message.content && (yield { delta: a.message.content }), a.done && (s = a.prompt_eval_count, n = a.eval_count);
390
+ a.message.content && (yield { delta: a.message.content }), a.done && (r = a.prompt_eval_count, n = a.eval_count);
388
391
  yield {
389
392
  delta: "",
390
- tokenUsage: s !== void 0 ? { input: s ?? 0, output: n ?? 0 } : void 0
393
+ tokenUsage: r !== void 0 ? { input: r ?? 0, output: n ?? 0 } : void 0
391
394
  };
392
395
  }
393
396
  };
394
397
  }
395
398
  const ie = {
396
- anthropic: ze,
397
- openai: Ve,
398
- google: Xe,
399
- ollama: Qe
399
+ anthropic: Ve,
400
+ openai: Xe,
401
+ google: Qe,
402
+ ollama: Ze
400
403
  };
401
404
  let T = null;
402
- async function Ze() {
405
+ async function qe() {
403
406
  if (T) return T;
404
407
  const o = d(v(), ".ai-council", "config.json");
405
408
  try {
406
- const r = await w(o, "utf-8");
407
- T = JSON.parse(r);
409
+ const s = await w(o, "utf-8");
410
+ T = JSON.parse(s);
408
411
  } catch {
409
412
  T = { backends: {} };
410
413
  }
411
414
  return T;
412
415
  }
413
416
  const z = /* @__PURE__ */ new Map();
414
- function qe() {
417
+ function et() {
415
418
  T = null, z.clear();
416
419
  }
417
420
  async function W(o) {
418
- const r = z.get(o);
419
- if (r) return r;
421
+ const s = z.get(o);
422
+ if (s) return s;
420
423
  const t = ie[o];
421
424
  if (!t)
422
425
  throw new Error(`Unknown backend: "${o}". Available: ${Object.keys(ie).join(", ")}`);
423
- const s = (await Ze()).backends[o] ?? {}, n = t(s);
426
+ const r = (await qe()).backends[o] ?? {}, n = t(r);
424
427
  return z.set(o, n), n;
425
428
  }
426
- function et() {
427
- return '\n## Excalidraw Element Reference\n\nOutput a JSON array of Excalidraw elements. Each element needs these fields:\n\n### Common Fields (all elements)\n- `type`: "rectangle" | "ellipse" | "diamond" | "text" | "arrow" | "line"\n- `id`: unique string (e.g. "rect1", "text1", "arrow1")\n- `x`, `y`: number (top-left origin, x increases right, y increases down)\n- `width`, `height`: number\n- `strokeColor`: hex string (e.g. "#1e1e1e")\n- `backgroundColor`: hex string or "transparent"\n- `fillStyle`: "solid" | "hachure" | "cross-hatch"\n- `strokeWidth`: 1 | 2 | 4\n- `roughness`: 0 (sharp) | 1 (sketchy)\n- `opacity`: 100\n- `angle`: 0\n- `seed`: any integer (e.g. 1)\n- `version`: 1\n- `isDeleted`: false\n- `groupIds`: []\n- `boundElements`: null or array of { id: string, type: "text" | "arrow" }\n- `link`: null\n- `locked`: false\n\n### Text Elements\nAdditional fields: `text`, `fontSize` (16-24), `fontFamily` (1=hand, 2=normal, 3=mono), `textAlign` ("left"|"center"|"right"), `verticalAlign` ("top"|"middle"), `baseline`: 0, `containerId`: null or parent shape id\n\n### Arrow/Line Elements\nAdditional fields: `points` (array of [x,y] relative to element x,y — first point always [0,0]), `startBinding` and `endBinding`: null or { elementId: string, focus: 0, gap: 5 }, `lastCommittedPoint`: null, `startArrowhead`: null, `endArrowhead`: "arrow" | null\n\n### Color Palette\n- Blue: "#1971c2", Light blue bg: "#a5d8ff"\n- Green: "#2f9e44", Light green bg: "#b2f2bb"\n- Red: "#e03131", Light red bg: "#ffc9c9"\n- Orange: "#e8590c", Light orange bg: "#ffd8a8"\n- Purple: "#7048e8", Light purple bg: "#d0bfff"\n- Yellow: "#f08c00", Light yellow bg: "#ffec99"\n- Gray: "#868e96", Light gray bg: "#dee2e6"\n- Dark: "#1e1e1e"\n\n### Layout Tips\n- Space shapes ~200px apart horizontally, ~150px vertically\n- Typical shape size: 160×80 for rectangles, 120×60 for ellipses\n- Center text inside shapes using containerId\n- Use arrows to show relationships (agreement, disagreement, influence)\n\n### Compact Example\n```json\n[\n {"type":"rectangle","id":"r1","x":50,"y":50,"width":160,"height":80,"strokeColor":"#1971c2","backgroundColor":"#a5d8ff","fillStyle":"solid","strokeWidth":2,"roughness":1,"opacity":100,"angle":0,"seed":1,"version":1,"isDeleted":false,"groupIds":[],"boundElements":[{"id":"t1","type":"text"},{"id":"a1","type":"arrow"}],"link":null,"locked":false},\n {"type":"text","id":"t1","x":60,"y":70,"width":140,"height":40,"text":"Counsellor A","fontSize":16,"fontFamily":2,"textAlign":"center","verticalAlign":"middle","baseline":0,"containerId":"r1","strokeColor":"#1e1e1e","backgroundColor":"transparent","fillStyle":"solid","strokeWidth":1,"roughness":0,"opacity":100,"angle":0,"seed":2,"version":1,"isDeleted":false,"groupIds":[],"boundElements":null,"link":null,"locked":false},\n {"type":"rectangle","id":"r2","x":350,"y":50,"width":160,"height":80,"strokeColor":"#2f9e44","backgroundColor":"#b2f2bb","fillStyle":"solid","strokeWidth":2,"roughness":1,"opacity":100,"angle":0,"seed":3,"version":1,"isDeleted":false,"groupIds":[],"boundElements":[{"id":"t2","type":"text"},{"id":"a1","type":"arrow"}],"link":null,"locked":false},\n {"type":"text","id":"t2","x":360,"y":70,"width":140,"height":40,"text":"Counsellor B","fontSize":16,"fontFamily":2,"textAlign":"center","verticalAlign":"middle","baseline":0,"containerId":"r2","strokeColor":"#1e1e1e","backgroundColor":"transparent","fillStyle":"solid","strokeWidth":1,"roughness":0,"opacity":100,"angle":0,"seed":4,"version":1,"isDeleted":false,"groupIds":[],"boundElements":null,"link":null,"locked":false},\n {"type":"arrow","id":"a1","x":210,"y":90,"width":140,"height":0,"points":[[0,0],[140,0]],"startBinding":{"elementId":"r1","focus":0,"gap":5},"endBinding":{"elementId":"r2","focus":0,"gap":5},"startArrowhead":null,"endArrowhead":"arrow","strokeColor":"#1e1e1e","backgroundColor":"transparent","fillStyle":"solid","strokeWidth":2,"roughness":1,"opacity":100,"angle":0,"seed":5,"version":1,"isDeleted":false,"groupIds":[],"boundElements":null,"link":null,"locked":false,"lastCommittedPoint":null}\n]\n```\n'.trim();
429
+ function tt() {
430
+ return '\n## Excalidraw Element Reference\n\nOutput a JSON array of Excalidraw elements. Each element needs these fields:\n\n### Common Fields (all elements)\n- `type`: "rectangle" | "ellipse" | "diamond" | "text" | "arrow" | "line"\n- `id`: unique string (e.g. "rect1", "text1", "arrow1")\n- `x`, `y`: number (top-left origin, x increases right, y increases down)\n- `width`, `height`: number\n- `strokeColor`: hex string (e.g. "#1e1e1e")\n- `backgroundColor`: hex string or "transparent"\n- `fillStyle`: "solid" | "hachure" | "cross-hatch"\n- `strokeWidth`: 1 | 2 | 4\n- `roughness`: 0 (sharp) | 1 (sketchy)\n- `opacity`: 100\n- `angle`: 0\n- `seed`: any integer (e.g. 1)\n- `version`: 1\n- `isDeleted`: false\n- `groupIds`: []\n- `boundElements`: null or array of { id: string, type: "text" | "arrow" }\n- `link`: null\n- `locked`: false\n\n### Text Elements\nAdditional fields: `text`, `fontSize` (16-24), `fontFamily` (1=hand, 2=normal, 3=mono), `textAlign` ("left"|"center"|"right"), `verticalAlign` ("top"|"middle"), `baseline`: 0, `containerId`: null or parent shape id\n\n### Arrow/Line Elements\nAdditional fields: `points` (array of [x,y] relative to element x,y — first point always [0,0]), `startBinding` and `endBinding`: null or { elementId: string, focus: 0, gap: 5 }, `lastCommittedPoint`: null, `startArrowhead`: null, `endArrowhead`: "arrow" | null\n\n### Color Palette\n- Blue: "#1971c2", Light blue bg: "#a5d8ff"\n- Green: "#2f9e44", Light green bg: "#b2f2bb"\n- Red: "#e03131", Light red bg: "#ffc9c9"\n- Orange: "#e8590c", Light orange bg: "#ffd8a8"\n- Purple: "#7048e8", Light purple bg: "#d0bfff"\n- Yellow: "#f08c00", Light yellow bg: "#ffec99"\n- Gray: "#868e96", Light gray bg: "#dee2e6"\n- Dark: "#1e1e1e"\n\n### Layout Tips\n- Space shapes ~200px apart horizontally, ~150px vertically\n- Typical shape size: 160×80 for rectangles, 120×60 for ellipses\n- Center text inside shapes using containerId\n- Use arrows to show relationships (agreement, disagreement, influence)\n\n### Compact Example\n```json\n[\n {"type":"rectangle","id":"r1","x":50,"y":50,"width":160,"height":80,"strokeColor":"#1971c2","backgroundColor":"#a5d8ff","fillStyle":"solid","strokeWidth":2,"roughness":1,"opacity":100,"angle":0,"seed":1,"version":1,"isDeleted":false,"groupIds":[],"boundElements":[{"id":"t1","type":"text"},{"id":"a1","type":"arrow"}],"link":null,"locked":false},\n {"type":"text","id":"t1","x":60,"y":70,"width":140,"height":40,"text":"Councilor A","fontSize":16,"fontFamily":2,"textAlign":"center","verticalAlign":"middle","baseline":0,"containerId":"r1","strokeColor":"#1e1e1e","backgroundColor":"transparent","fillStyle":"solid","strokeWidth":1,"roughness":0,"opacity":100,"angle":0,"seed":2,"version":1,"isDeleted":false,"groupIds":[],"boundElements":null,"link":null,"locked":false},\n {"type":"rectangle","id":"r2","x":350,"y":50,"width":160,"height":80,"strokeColor":"#2f9e44","backgroundColor":"#b2f2bb","fillStyle":"solid","strokeWidth":2,"roughness":1,"opacity":100,"angle":0,"seed":3,"version":1,"isDeleted":false,"groupIds":[],"boundElements":[{"id":"t2","type":"text"},{"id":"a1","type":"arrow"}],"link":null,"locked":false},\n {"type":"text","id":"t2","x":360,"y":70,"width":140,"height":40,"text":"Councilor B","fontSize":16,"fontFamily":2,"textAlign":"center","verticalAlign":"middle","baseline":0,"containerId":"r2","strokeColor":"#1e1e1e","backgroundColor":"transparent","fillStyle":"solid","strokeWidth":1,"roughness":0,"opacity":100,"angle":0,"seed":4,"version":1,"isDeleted":false,"groupIds":[],"boundElements":null,"link":null,"locked":false},\n {"type":"arrow","id":"a1","x":210,"y":90,"width":140,"height":0,"points":[[0,0],[140,0]],"startBinding":{"elementId":"r1","focus":0,"gap":5},"endBinding":{"elementId":"r2","focus":0,"gap":5},"startArrowhead":null,"endArrowhead":"arrow","strokeColor":"#1e1e1e","backgroundColor":"transparent","fillStyle":"solid","strokeWidth":2,"roughness":1,"opacity":100,"angle":0,"seed":5,"version":1,"isDeleted":false,"groupIds":[],"boundElements":null,"link":null,"locked":false,"lastCommittedPoint":null}\n]\n```\n'.trim();
428
431
  }
429
- const M = "---EXCALIDRAW---", tt = `You are the Secretary of a council discussion. Your job is to synthesize a clear, structured summary of the conversation that just took place.
432
+ const M = "---EXCALIDRAW---", nt = `You are the Secretary of a council discussion. Your job is to synthesize a clear, structured summary of the conversation that just took place.
430
433
 
431
434
  Structure your summary with these sections:
432
435
 
433
436
  ## Individual Positions
434
- Briefly summarize each counsellor's key arguments and stance.
437
+ Briefly summarize each councilor's key arguments and stance.
435
438
 
436
439
  ## Points of Convergence
437
- Where did the counsellors agree? What common ground emerged?
440
+ Where did the councilors agree? What common ground emerged?
438
441
 
439
442
  ## Points of Divergence
440
443
  Where did they disagree? What are the key tensions?
@@ -443,29 +446,29 @@ Where did they disagree? What are the key tensions?
443
446
  What are the most important takeaways? What would you recommend based on the full discussion?
444
447
 
445
448
  Be concise but thorough. Use markdown formatting.`;
446
- function nt(o) {
447
- const r = [];
448
- r.push(`Topic: ${o.topic}`), r.push(`Counsellors: ${o.counsellors.map((e) => e.name).join(", ")}`), r.push(`Rounds: ${o.rounds}`), r.push("");
449
+ function ot(o) {
450
+ const s = [];
451
+ s.push(`Topic: ${o.topic}`), s.push(`Councilors: ${o.councilors.map((e) => e.name).join(", ")}`), s.push(`Rounds: ${o.rounds}`), s.push("");
449
452
  let t = 0;
450
453
  for (const e of o.turns)
451
- e.round !== t && (t = e.round, r.push(`--- Round ${t} ---`), r.push("")), r.push(`[${e.counsellorName}]:`), r.push(e.content), r.push("");
452
- return r.join(`
454
+ e.round !== t && (t = e.round, s.push(`--- Round ${t} ---`), s.push("")), s.push(`[${e.councilorName}]:`), s.push(e.content), s.push("");
455
+ return s.join(`
453
456
  `);
454
457
  }
455
- async function ot({
458
+ async function rt({
456
459
  result: o,
457
- config: r,
460
+ config: s,
458
461
  onChunk: t,
459
462
  signal: e
460
463
  }) {
461
- const s = r.secretary;
462
- if (!s?.backend)
464
+ const r = s.secretary;
465
+ if (!r?.backend)
463
466
  throw new Error("No secretary backend configured");
464
- const n = await W(s.backend), a = s.model ?? n.defaultModel, i = s.systemPrompt || tt, u = et(), c = `${i}
467
+ const n = await W(r.backend), a = r.model ?? n.defaultModel, i = r.systemPrompt || nt, u = tt(), c = `${i}
465
468
 
466
469
  ${u}
467
470
 
468
- After your text summary, output \`${M}\` on its own line, then a JSON array of Excalidraw elements showing a visual map of where each counsellor stands on the topic. Use shapes for each counsellor with their name, arrows to show relationships (agreement/disagreement), and position them to visually represent the discussion dynamics.`, m = nt(o), y = {
471
+ After your text summary, output \`${M}\` on its own line, then a JSON array of Excalidraw elements showing a visual map of where each councilor stands on the topic. Use shapes for each councilor with their name, arrows to show relationships (agreement/disagreement), and position them to visually represent the discussion dynamics.`, m = ot(o), y = {
469
472
  model: a,
470
473
  systemPrompt: c,
471
474
  messages: [{ role: "user", content: `Please summarize this council discussion and create a position diagram:
@@ -494,20 +497,20 @@ ${m}` }],
494
497
  return { text: b, diagram: g };
495
498
  }
496
499
  const st = "You are the Secretary of a council debate. Briefly summarize this round of discussion. Note emerging agreements, disagreements, and shifts in position. 2-3 paragraphs max. Use markdown formatting.";
497
- async function rt({
500
+ async function at({
498
501
  result: o,
499
- roundNumber: r,
502
+ roundNumber: s,
500
503
  config: t,
501
504
  onChunk: e,
502
- signal: s
505
+ signal: r
503
506
  }) {
504
507
  const n = t.secretary;
505
508
  if (!n?.backend)
506
509
  throw new Error("No secretary backend configured");
507
- const a = await W(n.backend), i = n.model ?? a.defaultModel, u = o.turns.filter((h) => h.round === r), c = [];
508
- c.push(`Topic: ${o.topic}`), c.push(`Round ${r}${r === 1 ? " (Constructive)" : " (Rebuttal)"}`), c.push("");
510
+ const a = await W(n.backend), i = n.model ?? a.defaultModel, u = o.turns.filter((h) => h.round === s), c = [];
511
+ c.push(`Topic: ${o.topic}`), c.push(`Round ${s}${s === 1 ? " (Constructive)" : " (Rebuttal)"}`), c.push("");
509
512
  for (const h of u)
510
- c.push(`[${h.counsellorName}]:`), c.push(h.content), c.push("");
513
+ c.push(`[${h.councilorName}]:`), c.push(h.content), c.push("");
511
514
  const m = {
512
515
  model: i,
513
516
  systemPrompt: st,
@@ -520,25 +523,25 @@ ${c.join(`
520
523
  let y = "";
521
524
  if (a.chatStream)
522
525
  for await (const h of a.chatStream(m)) {
523
- if (s?.aborted) break;
526
+ if (r?.aborted) break;
524
527
  y += h.delta, h.delta && e && e(h.delta);
525
528
  }
526
529
  else
527
530
  y = (await a.chat(m)).content, e && e(y);
528
531
  return y.trim();
529
532
  }
530
- async function at({
533
+ async function it({
531
534
  topic: o,
532
- firstRoundTurns: r,
535
+ firstRoundTurns: s,
533
536
  config: t
534
537
  }) {
535
538
  const e = t.secretary;
536
539
  if (!e?.backend)
537
540
  throw new Error("No secretary backend configured");
538
- const s = await W(e.backend), n = e.model ?? s.defaultModel, a = r.map((u) => `[${u.counsellorName}]: ${u.content.slice(0, 300)}`).join(`
541
+ const r = await W(e.backend), n = e.model ?? r.defaultModel, a = s.map((u) => `[${u.councilorName}]: ${u.content.slice(0, 300)}`).join(`
539
542
 
540
543
  `);
541
- return (await s.chat({
544
+ return (await r.chat({
542
545
  model: n,
543
546
  systemPrompt: "Generate a concise title (max 8 words) for this council discussion. Return only the title, no quotes or punctuation at the end.",
544
547
  messages: [
@@ -553,13 +556,13 @@ ${a}`
553
556
  temperature: 0.3
554
557
  })).content.trim().replace(/^["']+|["']+$/g, "").replace(/[.!?]+$/, "").trim();
555
558
  }
556
- const ye = d(v(), ".ai-council"), it = d(ye, "council.log");
559
+ const ye = d(v(), ".ai-council"), ct = d(ye, "council.log");
557
560
  let ce = !1;
558
- async function ct() {
561
+ async function lt() {
559
562
  ce || (await N(ye, { recursive: !0 }), ce = !0);
560
563
  }
561
- function lt(o, r, t, e) {
562
- let n = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${o} [${r}] ${t}`;
564
+ function ut(o, s, t, e) {
565
+ let n = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${o} [${s}] ${t}`;
563
566
  if (e !== void 0) {
564
567
  const a = e instanceof Error ? `${e.message}
565
568
  ${e.stack ?? ""}` : typeof e == "string" ? e : JSON.stringify(e, null, 2);
@@ -570,79 +573,79 @@ ${e.stack ?? ""}` : typeof e == "string" ? e : JSON.stringify(e, null, 2);
570
573
  return n + `
571
574
  `;
572
575
  }
573
- async function Y(o, r, t, e) {
576
+ async function Y(o, s, t, e) {
574
577
  try {
575
- await ct(), await xe(it, lt(o, r, t, e));
578
+ await lt(), await xe(ct, ut(o, s, t, e));
576
579
  } catch {
577
580
  }
578
581
  }
579
582
  const _ = {
580
- info: (o, r, t) => Y("INFO", o, r, t),
581
- warn: (o, r, t) => Y("WARN", o, r, t),
582
- error: (o, r, t) => Y("ERROR", o, r, t)
583
+ info: (o, s, t) => Y("INFO", o, s, t),
584
+ warn: (o, s, t) => Y("WARN", o, s, t),
585
+ error: (o, s, t) => Y("ERROR", o, s, t)
583
586
  };
584
- function ut(o, r, t, e, s) {
587
+ function dt(o, s, t, e, r) {
585
588
  const n = [{ role: "user", content: o }];
586
589
  if (e?.length) {
587
590
  for (const a of e)
588
- a.counsellorId === t ? n.push({ role: "assistant", content: a.content }) : n.push({
591
+ a.councilorId === t ? n.push({ role: "assistant", content: a.content }) : n.push({
589
592
  role: "user",
590
- content: `[${a.counsellorName}, Round ${a.round}]: ${a.content}`
593
+ content: `[${a.councilorName}, Round ${a.round}]: ${a.content}`
591
594
  });
592
- s && n.push({
595
+ r && n.push({
593
596
  role: "user",
594
- content: `[Secretary Summary]: ${s}`
597
+ content: `[Secretary Summary]: ${r}`
595
598
  });
596
599
  }
597
- for (const a of r)
598
- a.counsellorId === t ? n.push({ role: "assistant", content: a.content }) : n.push({
600
+ for (const a of s)
601
+ a.councilorId === t ? n.push({ role: "assistant", content: a.content }) : n.push({
599
602
  role: "user",
600
- content: `[${a.counsellorName}, Round ${a.round}]: ${a.content}`
603
+ content: `[${a.councilorName}, Round ${a.round}]: ${a.content}`
601
604
  });
602
605
  return n;
603
606
  }
604
- function dt(o, r, t, e) {
605
- const s = [{ role: "user", content: o }];
607
+ function mt(o, s, t, e) {
608
+ const r = [{ role: "user", content: o }];
606
609
  if (e === 1)
607
- return s;
608
- const n = r.filter((i) => i.round === 1);
610
+ return r;
611
+ const n = s.filter((i) => i.round === 1);
609
612
  for (const i of n)
610
- i.counsellorId === t ? s.push({ role: "assistant", content: i.content }) : s.push({
613
+ i.councilorId === t ? r.push({ role: "assistant", content: i.content }) : r.push({
611
614
  role: "user",
612
- content: `[${i.counsellorName}, Constructive]: ${i.content}`
615
+ content: `[${i.councilorName}, Constructive]: ${i.content}`
613
616
  });
614
617
  const a = e - 1;
615
618
  if (a > 1) {
616
- const i = r.filter((u) => u.round === a);
619
+ const i = s.filter((u) => u.round === a);
617
620
  for (const u of i)
618
- u.counsellorId === t ? s.push({ role: "assistant", content: u.content }) : s.push({
621
+ u.councilorId === t ? r.push({ role: "assistant", content: u.content }) : r.push({
619
622
  role: "user",
620
- content: `[${u.counsellorName}, Round ${a}]: ${u.content}`
623
+ content: `[${u.councilorName}, Round ${a}]: ${u.content}`
621
624
  });
622
625
  }
623
- for (const i of r)
624
- i.counsellorId === t && i.round !== 1 && i.round !== a && i.round < e && s.push({ role: "assistant", content: i.content });
625
- return s;
626
+ for (const i of s)
627
+ i.councilorId === t && i.round !== 1 && i.round !== a && i.round < e && r.push({ role: "assistant", content: i.content });
628
+ return r;
626
629
  }
627
- function mt(o, r) {
630
+ function pt(o, s) {
628
631
  const t = [...o];
629
- let e = r | 0;
630
- const s = () => {
632
+ let e = s | 0;
633
+ const r = () => {
631
634
  e = e + 1831565813 | 0;
632
635
  let n = Math.imul(e ^ e >>> 15, 1 | e);
633
636
  return n = n + Math.imul(n ^ n >>> 7, 61 | n) ^ n, ((n ^ n >>> 14) >>> 0) / 4294967296;
634
637
  };
635
638
  for (let n = t.length - 1; n > 0; n--) {
636
- const a = Math.floor(s() * (n + 1));
639
+ const a = Math.floor(r() * (n + 1));
637
640
  [t[n], t[a]] = [t[a], t[n]];
638
641
  }
639
642
  return t;
640
643
  }
641
- function H(o, r, t, e, s, n) {
644
+ function H(o, s, t, e, r, n) {
642
645
  return {
643
646
  topic: o.topic,
644
647
  topicSource: o.topicSource,
645
- counsellors: o.counsellors.map((a) => ({
648
+ councilors: o.councilors.map((a) => ({
646
649
  id: a.id,
647
650
  name: a.frontmatter.name,
648
651
  description: a.frontmatter.description,
@@ -651,32 +654,32 @@ function H(o, r, t, e, s, n) {
651
654
  avatarUrl: a.avatarUrl
652
655
  })),
653
656
  rounds: o.rounds,
654
- turns: r,
657
+ turns: s,
655
658
  startedAt: t,
656
659
  completedAt: (/* @__PURE__ */ new Date()).toISOString(),
657
- totalTokenUsage: { input: e, output: s },
660
+ totalTokenUsage: { input: e, output: r },
658
661
  ...n && Object.keys(n).length > 0 ? { roundSummaries: n } : {},
659
662
  ...o.mode === "debate" ? { mode: "debate" } : {}
660
663
  };
661
664
  }
662
- async function pt(o, r, t, e, s) {
665
+ async function ft(o, s, t, e, r) {
663
666
  let n;
664
667
  typeof o == "string" ? n = {
665
668
  topic: o,
666
- topicSource: r,
667
- counsellors: t,
669
+ topicSource: s,
670
+ councilors: t,
668
671
  rounds: e,
669
- onEvent: s
672
+ onEvent: r
670
673
  } : n = o;
671
674
  const a = (/* @__PURE__ */ new Date()).toISOString(), i = [];
672
675
  let u = 0, c = 0;
673
676
  const m = n.mode === "debate", y = {}, h = n.previousTurns?.length ? Math.max(...n.previousTurns.map((p) => p.round)) : 0;
674
- _.info("conversation", `Starting ${m ? "debate" : "freeform"} — ${n.counsellors.length} counsellors, ${n.rounds} rounds`, {
675
- counsellors: n.counsellors.map((p) => `${p.frontmatter.name} (${p.frontmatter.backend}/${p.frontmatter.model ?? "default"})`),
677
+ _.info("conversation", `Starting ${m ? "debate" : "freeform"} — ${n.councilors.length} councilors, ${n.rounds} rounds`, {
678
+ councilors: n.councilors.map((p) => `${p.frontmatter.name} (${p.frontmatter.backend}/${p.frontmatter.model ?? "default"})`),
676
679
  topic: n.topic.slice(0, 200)
677
680
  });
678
681
  for (let p = 1; p <= n.rounds; p++) {
679
- const b = m && p > 1 ? mt(n.counsellors, p) : n.counsellors;
682
+ const b = m && p > 1 ? pt(n.councilors, p) : n.councilors;
680
683
  for (const l of b) {
681
684
  if (n.signal?.aborted)
682
685
  return H(n, i, a, u, c, y);
@@ -685,9 +688,9 @@ async function pt(o, r, t, e, s) {
685
688
  f && (i.push(f), n.onEvent({ type: "turn_complete", turn: f }));
686
689
  }
687
690
  const g = p + h;
688
- n.onEvent({ type: "turn_start", round: g, counsellorName: l.frontmatter.name });
691
+ n.onEvent({ type: "turn_start", round: g, councilorName: l.frontmatter.name });
689
692
  try {
690
- const f = await W(l.frontmatter.backend), D = l.frontmatter.model ?? f.defaultModel, _e = m ? dt(n.topic, i, l.id, p) : ut(n.topic, i, l.id, n.previousTurns, n.previousSummary), q = {
693
+ const f = await W(l.frontmatter.backend), D = l.frontmatter.model ?? f.defaultModel, _e = m ? mt(n.topic, i, l.id, p) : dt(n.topic, i, l.id, n.previousTurns, n.previousSummary), q = {
691
694
  model: D,
692
695
  systemPrompt: l.systemPrompt,
693
696
  messages: _e,
@@ -698,7 +701,7 @@ async function pt(o, r, t, e, s) {
698
701
  K = "";
699
702
  for await (const O of f.chatStream(q)) {
700
703
  if (n.signal?.aborted) break;
701
- K += O.delta, O.delta && n.onEvent({ type: "turn_chunk", counsellorName: l.frontmatter.name, delta: O.delta }), O.tokenUsage && (x = O.tokenUsage);
704
+ K += O.delta, O.delta && n.onEvent({ type: "turn_chunk", councilorName: l.frontmatter.name, delta: O.delta }), O.tokenUsage && (x = O.tokenUsage);
702
705
  }
703
706
  } else {
704
707
  const O = await f.chat(q);
@@ -706,8 +709,8 @@ async function pt(o, r, t, e, s) {
706
709
  }
707
710
  const ee = {
708
711
  round: g,
709
- counsellorId: l.id,
710
- counsellorName: l.frontmatter.name,
712
+ councilorId: l.id,
713
+ councilorName: l.frontmatter.name,
711
714
  content: K,
712
715
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
713
716
  model: D,
@@ -718,14 +721,14 @@ async function pt(o, r, t, e, s) {
718
721
  x && (u += x.input, c += x.output), i.push(ee), n.onEvent({ type: "turn_complete", turn: ee });
719
722
  } catch (f) {
720
723
  const D = f instanceof Error ? f.message : String(f);
721
- _.error("conversation", `Turn failed for ${l.frontmatter.name} (round ${p}, model ${l.frontmatter.model ?? "default"}, backend ${l.frontmatter.backend})`, f), n.onEvent({ type: "error", counsellorName: l.frontmatter.name, error: D });
724
+ _.error("conversation", `Turn failed for ${l.frontmatter.name} (round ${p}, model ${l.frontmatter.model ?? "default"}, backend ${l.frontmatter.backend})`, f), n.onEvent({ type: "error", councilorName: l.frontmatter.name, error: D });
722
725
  }
723
726
  }
724
727
  if (n.onEvent({ type: "round_complete", round: p }), m && n.config?.secretary?.backend && !n.signal?.aborted)
725
728
  try {
726
729
  const l = H(n, i, a, u, c, y);
727
730
  n.onEvent({ type: "round_summary_start", round: p });
728
- const g = await rt({
731
+ const g = await at({
729
732
  result: l,
730
733
  roundNumber: p,
731
734
  config: n.config,
@@ -742,74 +745,74 @@ async function pt(o, r, t, e, s) {
742
745
  return H(n, i, a, u, c, y);
743
746
  }
744
747
  const I = d(v(), ".ai-council", "history");
745
- function ft(o) {
748
+ function ht(o) {
746
749
  return o.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40);
747
750
  }
748
- async function ht(o) {
751
+ async function gt(o) {
749
752
  await N(I, { recursive: !0 });
750
- const r = new Date(o.startedAt).toISOString().replace(/[:.]/g, "-").slice(0, 19), t = ft(o.topic), e = `${r}-${t}`, s = d(I, `${e}.json`);
751
- return await P(s, JSON.stringify(o, null, 2), "utf-8"), e;
753
+ const s = new Date(o.startedAt).toISOString().replace(/[:.]/g, "-").slice(0, 19), t = ht(o.topic), e = `${s}-${t}`, r = d(I, `${e}.json`);
754
+ return await P(r, JSON.stringify(o, null, 2), "utf-8"), e;
752
755
  }
753
- async function gt() {
756
+ async function yt() {
754
757
  await N(I, { recursive: !0 });
755
- const o = await V(I), r = [];
758
+ const o = await V(I), s = [];
756
759
  for (const t of o)
757
760
  if (t.endsWith(".json"))
758
761
  try {
759
- const e = await w(d(I, t), "utf-8"), s = JSON.parse(e);
760
- r.push({
762
+ const e = await w(d(I, t), "utf-8"), r = JSON.parse(e);
763
+ s.push({
761
764
  id: C(t, ".json"),
762
- topic: s.topic,
763
- title: s.title,
764
- counsellors: s.counsellors.map((n) => n.name),
765
- rounds: s.rounds,
766
- startedAt: s.startedAt,
767
- completedAt: s.completedAt
765
+ topic: r.topic,
766
+ title: r.title,
767
+ councilors: r.councilors.map((n) => n.name),
768
+ rounds: r.rounds,
769
+ startedAt: r.startedAt,
770
+ completedAt: r.completedAt
768
771
  });
769
772
  } catch {
770
773
  }
771
- return r.sort((t, e) => e.startedAt.localeCompare(t.startedAt));
774
+ return s.sort((t, e) => e.startedAt.localeCompare(t.startedAt));
772
775
  }
773
776
  async function le(o) {
774
- const r = d(I, `${o}.json`), t = await w(r, "utf-8"), e = JSON.parse(t);
777
+ const s = d(I, `${o}.json`), t = await w(s, "utf-8"), e = JSON.parse(t);
775
778
  return e.infographic && !e.infographics && (e.infographics = [e.infographic], delete e.infographic), e;
776
779
  }
777
- async function yt(o) {
778
- const r = d(I, `${o}.json`);
779
- await F(r);
780
+ async function wt(o) {
781
+ const s = d(I, `${o}.json`);
782
+ await F(s);
780
783
  }
781
- async function wt(o, r) {
782
- const t = d(I, `${o}.json`), e = await w(t, "utf-8"), s = JSON.parse(e);
783
- s.infographics || (s.infographics = []), s.infographics.push(r), await P(t, JSON.stringify(s, null, 2), "utf-8");
784
+ async function bt(o, s) {
785
+ const t = d(I, `${o}.json`), e = await w(t, "utf-8"), r = JSON.parse(e);
786
+ r.infographics || (r.infographics = []), r.infographics.push(s), await P(t, JSON.stringify(r, null, 2), "utf-8");
784
787
  }
785
- async function bt(o, r) {
786
- const t = d(I, `${o}.json`), e = await w(t, "utf-8"), s = JSON.parse(e);
787
- s.infographics && r >= 0 && r < s.infographics.length && s.infographics.splice(r, 1), await P(t, JSON.stringify(s, null, 2), "utf-8");
788
+ async function vt(o, s) {
789
+ const t = d(I, `${o}.json`), e = await w(t, "utf-8"), r = JSON.parse(e);
790
+ r.infographics && s >= 0 && s < r.infographics.length && r.infographics.splice(s, 1), await P(t, JSON.stringify(r, null, 2), "utf-8");
788
791
  }
789
792
  const we = De(import.meta.url);
790
- function vt(o) {
791
- const r = o.counsellors.map((e) => e.name).join(", "), t = o.summary ?? o.turns.map((e) => `${e.counsellorName}: ${e.content.slice(0, 200)}`).join(`
793
+ function kt(o) {
794
+ const s = o.councilors.map((e) => e.name).join(", "), t = o.summary ?? o.turns.map((e) => `${e.councilorName}: ${e.content.slice(0, 200)}`).join(`
792
795
  `);
793
796
  return [
794
797
  "Create a professional infographic summarizing a panel discussion.",
795
798
  `Topic: ${o.topic.slice(0, 300)}`,
796
799
  `Key points: ${t.slice(0, 1500)}`,
797
- `Panelists: ${r}`,
800
+ `Panelists: ${s}`,
798
801
  "Use a clean, modern design with sections for convergence points, divergence points, and key takeaways.",
799
802
  "Include relevant icons and visual hierarchy. Use a horizontal landscape layout."
800
803
  ].join(" ");
801
804
  }
802
- function kt(o) {
805
+ function _t(o) {
803
806
  if (o.infographic?.backend) return o.infographic.backend;
804
- const r = !!(o.backends.google?.apiKey || process.env.GOOGLE_API_KEY), t = !!(o.backends.openai?.apiKey || process.env.OPENAI_API_KEY);
805
- return r ? "google" : t ? "openai" : null;
807
+ const s = !!(o.backends.google?.apiKey || process.env.GOOGLE_API_KEY), t = !!(o.backends.openai?.apiKey || process.env.OPENAI_API_KEY);
808
+ return s ? "google" : t ? "openai" : null;
806
809
  }
807
- async function _t(o, r) {
810
+ async function Et(o, s) {
808
811
  const t = we("openai").default, n = (await new t({
809
- apiKey: r.backends.openai?.apiKey || process.env.OPENAI_API_KEY,
810
- ...r.backends.openai?.baseUrl ? { baseURL: r.backends.openai.baseUrl } : {}
812
+ apiKey: s.backends.openai?.apiKey || process.env.OPENAI_API_KEY,
813
+ ...s.backends.openai?.baseUrl ? { baseURL: s.backends.openai.baseUrl } : {}
811
814
  }).images.generate({
812
- model: "gpt-image-1",
815
+ model: "gpt-image-1.5",
813
816
  prompt: o,
814
817
  quality: "high",
815
818
  size: "1536x1024"
@@ -817,11 +820,11 @@ async function _t(o, r) {
817
820
  if (!n) throw new Error("No image data returned from OpenAI");
818
821
  return n;
819
822
  }
820
- async function Et(o, r) {
821
- const { GoogleGenAI: t } = we("@google/genai"), e = r.backends.google?.apiKey || process.env.GOOGLE_API_KEY;
823
+ async function St(o, s) {
824
+ const { GoogleGenAI: t } = we("@google/genai"), e = s.backends.google?.apiKey || process.env.GOOGLE_API_KEY;
822
825
  if (!e) throw new Error("No Google API key configured");
823
826
  const a = (await new t({ apiKey: e }).models.generateContent({
824
- model: "gemini-3-pro-image-preview",
827
+ model: "gemini-3.1-flash-image-preview",
825
828
  contents: o,
826
829
  config: {
827
830
  responseModalities: ["IMAGE", "TEXT"]
@@ -833,11 +836,11 @@ async function Et(o, r) {
833
836
  return i.inlineData.data;
834
837
  throw new Error("No image data in Gemini response");
835
838
  }
836
- async function ue(o, r, t) {
837
- const e = t ?? kt(r);
839
+ async function ue(o, s, t) {
840
+ const e = t ?? _t(s);
838
841
  if (!e) throw new Error("No image-capable backend configured (need OpenAI or Google API key)");
839
- const s = vt(o);
840
- return e === "openai" ? _t(s, r) : Et(s, r);
842
+ const r = kt(o);
843
+ return e === "openai" ? Et(r, s) : St(r, s);
841
844
  }
842
845
  const be = {
843
846
  anthropic: "https://api.anthropic.com",
@@ -858,24 +861,24 @@ const be = {
858
861
  "gemini-1.5-pro",
859
862
  "gemini-1.5-flash"
860
863
  ];
861
- async function St(o, r) {
864
+ async function At(o, s) {
862
865
  try {
863
866
  switch (o) {
864
867
  case "ollama": {
865
868
  const { Ollama: t } = await import("ollama");
866
- return { connected: !0, models: (await new t({ host: r.baseUrl || be.ollama }).list()).models.map((a) => a.name).sort() };
869
+ return { connected: !0, models: (await new t({ host: s.baseUrl || be.ollama }).list()).models.map((a) => a.name).sort() };
867
870
  }
868
871
  case "openai": {
869
872
  const { default: t } = await import("openai");
870
873
  return { connected: !0, models: (await new t({
871
- apiKey: r.apiKey || process.env.OPENAI_API_KEY,
872
- ...r.baseUrl ? { baseURL: r.baseUrl } : {}
874
+ apiKey: s.apiKey || process.env.OPENAI_API_KEY,
875
+ ...s.baseUrl ? { baseURL: s.baseUrl } : {}
873
876
  }).models.list()).data.map((a) => a.id).filter((a) => a.startsWith("gpt-") || a.startsWith("o") || a.startsWith("chatgpt-")).sort() };
874
877
  }
875
878
  case "anthropic": {
876
879
  const { default: t } = await import("@anthropic-ai/sdk"), e = new t({
877
- apiKey: r.apiKey || process.env.ANTHROPIC_API_KEY,
878
- ...r.baseUrl ? { baseURL: r.baseUrl } : {}
880
+ apiKey: s.apiKey || process.env.ANTHROPIC_API_KEY,
881
+ ...s.baseUrl ? { baseURL: s.baseUrl } : {}
879
882
  });
880
883
  try {
881
884
  return { connected: !0, models: (await e.models.list({ limit: 100 })).data.map((a) => a.id).sort() };
@@ -884,7 +887,7 @@ async function St(o, r) {
884
887
  }
885
888
  }
886
889
  case "google": {
887
- const t = r.apiKey || process.env.GOOGLE_API_KEY || "";
890
+ const t = s.apiKey || process.env.GOOGLE_API_KEY || "";
888
891
  if (!t) return { connected: !1, models: j, error: "No API key" };
889
892
  const e = await fetch(
890
893
  `https://generativelanguage.googleapis.com/v1beta/models?key=${t}`
@@ -905,20 +908,20 @@ async function St(o, r) {
905
908
  }
906
909
  }
907
910
  let A = null, B = [];
908
- function At(o, r) {
911
+ function It(o, s) {
909
912
  o.handle("app:getCouncilDir", async () => {
910
913
  const t = process.env.COUNCIL_CWD || process.cwd();
911
914
  return G(t, "council");
912
- }), o.handle("counsellors:list", async (t, e) => {
913
- const s = d(v(), ".ai-council", "config.json");
915
+ }), o.handle("councilors:list", async (t, e) => {
916
+ const r = d(v(), ".ai-council", "config.json");
914
917
  let n = { backends: {} };
915
918
  try {
916
- const c = await w(s, "utf-8");
919
+ const c = await w(r, "utf-8");
917
920
  n = JSON.parse(c);
918
921
  } catch {
919
922
  }
920
- const a = ae(n), i = n.counsellors ?? {};
921
- return (await se(e, a)).map((c) => {
923
+ const a = ae(n), i = n.councilors ?? {};
924
+ return (await re(e, a)).map((c) => {
922
925
  const m = i[c.id];
923
926
  return {
924
927
  id: c.id,
@@ -934,16 +937,16 @@ function At(o, r) {
934
937
  registryUrl: m?.url
935
938
  };
936
939
  });
937
- }), o.handle("counsellors:get", async (t, e) => {
938
- const s = d(e, "ABOUT.md"), n = await w(s, "utf-8"), { data: a, content: i } = X(n);
940
+ }), o.handle("councilors:get", async (t, e) => {
941
+ const r = d(e, "ABOUT.md"), n = await w(r, "utf-8"), { data: a, content: i } = X(n);
939
942
  return { frontmatter: a, body: i.trim(), raw: n };
940
- }), o.handle("counsellors:save", async (t, e, s) => {
943
+ }), o.handle("councilors:save", async (t, e, r) => {
941
944
  const n = d(e, "ABOUT.md");
942
- return await P(n, s, "utf-8"), { success: !0 };
943
- }), o.handle("counsellors:create", async (t, e, s, n) => {
944
- const a = d(e, s);
945
+ return await P(n, r, "utf-8"), { success: !0 };
946
+ }), o.handle("councilors:create", async (t, e, r, n) => {
947
+ const a = d(e, r);
945
948
  return await N(a, { recursive: !0 }), await P(d(a, "ABOUT.md"), n, "utf-8"), { success: !0, dirPath: a };
946
- }), o.handle("counsellors:delete", async (t, e) => (await F(e, { recursive: !0, force: !0 }), { success: !0 })), o.handle("config:get", async () => {
949
+ }), o.handle("councilors:delete", async (t, e) => (await F(e, { recursive: !0, force: !0 }), { success: !0 })), o.handle("config:get", async () => {
947
950
  const t = d(v(), ".ai-council", "config.json");
948
951
  let e = { backends: {} };
949
952
  try {
@@ -951,7 +954,7 @@ function At(o, r) {
951
954
  e = JSON.parse(i);
952
955
  } catch {
953
956
  }
954
- const s = {
957
+ const r = {
955
958
  ANTHROPIC_API_KEY: !!process.env.ANTHROPIC_API_KEY,
956
959
  OPENAI_API_KEY: !!process.env.OPENAI_API_KEY,
957
960
  GOOGLE_API_KEY: !!process.env.GOOGLE_API_KEY
@@ -960,18 +963,18 @@ function At(o, r) {
960
963
  OPENAI_API_KEY: n(process.env.OPENAI_API_KEY),
961
964
  GOOGLE_API_KEY: n(process.env.GOOGLE_API_KEY)
962
965
  };
963
- return { config: e, envStatus: s, envKeySuffix: a, defaultUrls: be };
964
- }), o.handle("backend:probe", async (t, e, s) => St(e, s)), o.handle("config:save", async (t, e) => {
965
- const s = d(v(), ".ai-council");
966
- return await N(s, { recursive: !0 }), await P(d(s, "config.json"), JSON.stringify(e, null, 2), "utf-8"), qe(), { success: !0 };
966
+ return { config: e, envStatus: r, envKeySuffix: a, defaultUrls: be };
967
+ }), o.handle("backend:probe", async (t, e, r) => At(e, r)), o.handle("config:save", async (t, e) => {
968
+ const r = d(v(), ".ai-council");
969
+ return await N(r, { recursive: !0 }), await P(d(r, "config.json"), JSON.stringify(e, null, 2), "utf-8"), et(), { success: !0 };
967
970
  }), o.handle("discussion:start", async (t, e) => {
968
- const s = r();
969
- if (!s) return { error: "No window" };
971
+ const r = s();
972
+ if (!r) return { error: "No window" };
970
973
  const n = (a) => {
971
- s.isDestroyed() || s.webContents.send("discussion:event", a);
974
+ r.isDestroyed() || r.webContents.send("discussion:event", a);
972
975
  };
973
976
  try {
974
- A && A.abort(), A = new AbortController(), B = [], _.info("ipc:discussion", "Starting discussion", { councilDir: e.councilDir, counsellorIds: e.counsellorIds, rounds: e.rounds, mode: e.mode });
977
+ A && A.abort(), A = new AbortController(), B = [], _.info("ipc:discussion", "Starting discussion", { councilDir: e.councilDir, councilorIds: e.councilorIds, rounds: e.rounds, mode: e.mode });
975
978
  const a = d(v(), ".ai-council", "config.json");
976
979
  let i = { backends: {} };
977
980
  try {
@@ -980,16 +983,16 @@ function At(o, r) {
980
983
  } catch {
981
984
  }
982
985
  const u = ae(i);
983
- _.info("ipc:discussion", `Loading counsellors from ${e.councilDir} + ${u.length} registered paths`);
984
- const c = await se(e.councilDir, u), m = e.counsellorIds?.length ? c.filter((l) => e.counsellorIds.includes(l.id)) : c;
985
- if (_.info("ipc:discussion", `Resolved ${m.length} counsellors: ${m.map((l) => l.id).join(", ")}`), m.length === 0) {
986
- n({ type: "error", counsellorName: "", error: "No counsellors found" });
986
+ _.info("ipc:discussion", `Loading councilors from ${e.councilDir} + ${u.length} registered paths`);
987
+ const c = await re(e.councilDir, u), m = e.councilorIds?.length ? c.filter((l) => e.councilorIds.includes(l.id)) : c;
988
+ if (_.info("ipc:discussion", `Resolved ${m.length} councilors: ${m.map((l) => l.id).join(", ")}`), m.length === 0) {
989
+ n({ type: "error", councilorName: "", error: "No councilors found" });
987
990
  return;
988
991
  }
989
992
  const y = async () => B.length === 0 ? null : {
990
993
  round: 0,
991
- counsellorId: "__user__",
992
- counsellorName: "You",
994
+ councilorId: "__user__",
995
+ councilorName: "You",
993
996
  content: B.shift(),
994
997
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
995
998
  model: "human",
@@ -997,7 +1000,7 @@ function At(o, r) {
997
1000
  }, h = !!e.previousTurns?.length, p = {
998
1001
  topic: e.topic,
999
1002
  topicSource: e.topicSource,
1000
- counsellors: m,
1003
+ councilors: m,
1001
1004
  rounds: e.rounds,
1002
1005
  onEvent: n,
1003
1006
  beforeTurn: y,
@@ -1006,11 +1009,11 @@ function At(o, r) {
1006
1009
  config: i,
1007
1010
  previousTurns: e.previousTurns,
1008
1011
  previousSummary: e.previousSummary
1009
- }, b = await pt(p);
1012
+ }, b = await ft(p);
1010
1013
  if (i.secretary?.backend)
1011
1014
  try {
1012
1015
  n({ type: "summary_start" });
1013
- const l = await ot({
1016
+ const l = await rt({
1014
1017
  result: b,
1015
1018
  config: i,
1016
1019
  onChunk: (g) => {
@@ -1020,11 +1023,11 @@ function At(o, r) {
1020
1023
  });
1021
1024
  b.summary = l.text, l.diagram && (b.diagram = l.diagram), n({ type: "summary_complete", summary: l.text, diagram: l.diagram });
1022
1025
  } catch (l) {
1023
- _.error("ipc:discussion", "Secretary summary failed", l), n({ type: "error", counsellorName: "Secretary", error: l instanceof Error ? l.message : String(l) });
1026
+ _.error("ipc:discussion", "Secretary summary failed", l), n({ type: "error", councilorName: "Secretary", error: l instanceof Error ? l.message : String(l) });
1024
1027
  }
1025
1028
  if (i.secretary?.backend)
1026
1029
  try {
1027
- const l = b.turns.filter((f) => f.round === 1), g = await at({
1030
+ const l = b.turns.filter((f) => f.round === 1), g = await it({
1028
1031
  topic: b.topic,
1029
1032
  firstRoundTurns: l,
1030
1033
  config: i
@@ -1044,27 +1047,27 @@ function At(o, r) {
1044
1047
  }
1045
1048
  e.continuedFrom && (b.continuedFrom = e.continuedFrom), n({ type: "complete", result: b });
1046
1049
  try {
1047
- await ht(b);
1050
+ await gt(b);
1048
1051
  } catch (l) {
1049
1052
  _.error("ipc:discussion", "Failed to save to history", l);
1050
1053
  }
1051
1054
  } catch (a) {
1052
- _.error("ipc:discussion", "Discussion failed", a), n({ type: "error", counsellorName: "", error: a instanceof Error ? a.message : String(a) });
1055
+ _.error("ipc:discussion", "Discussion failed", a), n({ type: "error", councilorName: "", error: a instanceof Error ? a.message : String(a) });
1053
1056
  } finally {
1054
1057
  A = null;
1055
1058
  }
1056
- }), o.handle("discussion:stop", async () => (A && (A.abort(), A = null), { success: !0 })), o.handle("discussion:inject", async (t, e) => (B.push(e), { success: !0 })), o.handle("registry:add-local", async (t, e) => Ye(e)), o.handle("registry:add-remote", async (t, e) => He(e)), o.handle("registry:remove", async (t, e, s) => (await Je(e, s), { success: !0 })), o.handle("shell:open-in-finder", async (t, e) => {
1059
+ }), o.handle("discussion:stop", async () => (A && (A.abort(), A = null), { success: !0 })), o.handle("discussion:inject", async (t, e) => (B.push(e), { success: !0 })), o.handle("registry:add-local", async (t, e) => He(e)), o.handle("registry:add-remote", async (t, e) => Je(e)), o.handle("registry:remove", async (t, e, r) => (await ze(e, r), { success: !0 })), o.handle("shell:open-in-finder", async (t, e) => {
1057
1060
  te.showItemInFolder(d(e, "ABOUT.md"));
1058
1061
  }), o.handle("shell:open-in-terminal", async (t, e) => {
1059
1062
  await U(R)("open", ["-a", "Terminal", e]);
1060
1063
  }), o.handle("shell:open-in-editor", async (t, e) => {
1061
- const s = U(R);
1064
+ const r = U(R);
1062
1065
  try {
1063
- await s("code", [e]);
1066
+ await r("code", [e]);
1064
1067
  } catch {
1065
1068
  te.openPath(e);
1066
1069
  }
1067
- }), o.handle("history:list", async () => gt()), o.handle("history:get", async (t, e) => le(e)), o.handle("history:delete", async (t, e) => (await yt(e), { success: !0 })), o.handle("infographic:generate", async (t, e, s) => {
1070
+ }), o.handle("history:list", async () => yt()), o.handle("history:get", async (t, e) => le(e)), o.handle("history:delete", async (t, e) => (await wt(e), { success: !0 })), o.handle("infographic:generate", async (t, e, r) => {
1068
1071
  const n = d(v(), ".ai-council", "config.json");
1069
1072
  let a = { backends: {} };
1070
1073
  try {
@@ -1072,10 +1075,10 @@ function At(o, r) {
1072
1075
  a = JSON.parse(c);
1073
1076
  } catch {
1074
1077
  }
1075
- const i = await le(e), u = await ue(i, a, s);
1076
- return await wt(e, u), { infographic: u };
1077
- }), o.handle("infographic:delete", async (t, e, s) => (await bt(e, s), { success: !0 })), o.handle("file:read-as-text", async (t, e) => {
1078
- const s = C(e), n = s.includes(".") ? "." + s.split(".").pop().toLowerCase() : "", a = /* @__PURE__ */ new Set([
1078
+ const i = await le(e), u = await ue(i, a, r);
1079
+ return await bt(e, u), { infographic: u };
1080
+ }), o.handle("infographic:delete", async (t, e, r) => (await vt(e, r), { success: !0 })), o.handle("file:read-as-text", async (t, e) => {
1081
+ const r = C(e), n = r.includes(".") ? "." + r.split(".").pop().toLowerCase() : "", a = /* @__PURE__ */ new Set([
1079
1082
  ".txt",
1080
1083
  ".md",
1081
1084
  ".csv",
@@ -1126,9 +1129,9 @@ function At(o, r) {
1126
1129
  if (a.has(n))
1127
1130
  try {
1128
1131
  const u = await w(e, "utf-8");
1129
- return { name: s, content: u };
1132
+ return { name: r, content: u };
1130
1133
  } catch (u) {
1131
- return { name: s, content: `[Error reading file: ${u instanceof Error ? u.message : String(u)}]` };
1134
+ return { name: r, content: `[Error reading file: ${u instanceof Error ? u.message : String(u)}]` };
1132
1135
  }
1133
1136
  if (i.has(n)) {
1134
1137
  const u = U(R);
@@ -1138,16 +1141,16 @@ function At(o, r) {
1138
1141
  maxBuffer: 10485760
1139
1142
  // 10 MB
1140
1143
  });
1141
- return { name: s, content: c };
1144
+ return { name: r, content: c };
1142
1145
  } catch (c) {
1143
1146
  const m = c instanceof Error ? c.message : String(c);
1144
1147
  return m.includes("ENOENT") ? {
1145
- name: s,
1148
+ name: r,
1146
1149
  content: `[Cannot convert ${n} file: markitdown is not installed. Run: pip install 'markitdown[all]']`
1147
- } : { name: s, content: `[Error converting file: ${m}]` };
1150
+ } : { name: r, content: `[Error converting file: ${m}]` };
1148
1151
  }
1149
1152
  }
1150
- return { name: s, content: `[Unsupported file type: ${s}]` };
1153
+ return { name: r, content: `[Unsupported file type: ${r}]` };
1151
1154
  }), o.handle("markitdown:check", async () => {
1152
1155
  const t = U(R);
1153
1156
  try {
@@ -1167,7 +1170,7 @@ function At(o, r) {
1167
1170
  return { success: !1, error: e instanceof Error ? e.message : String(e) };
1168
1171
  }
1169
1172
  }), o.handle("dialog:selectDirectory", async () => {
1170
- const t = r();
1173
+ const t = s();
1171
1174
  if (!t) return null;
1172
1175
  const e = await Ee.showOpenDialog(t, {
1173
1176
  properties: ["openDirectory"]
@@ -1175,11 +1178,11 @@ function At(o, r) {
1175
1178
  return e.canceled ? null : e.filePaths[0];
1176
1179
  });
1177
1180
  }
1178
- const It = Oe(import.meta.url), J = Ie(It), ve = d(v(), ".ai-council");
1181
+ const Ot = Oe(import.meta.url), J = Ie(Ot), ve = d(v(), ".ai-council");
1179
1182
  Pe(ve, { recursive: !0 });
1180
1183
  const ke = d(ve, "electron-debug.log");
1181
- function $(o, ...r) {
1182
- const t = `[${(/* @__PURE__ */ new Date()).toISOString()}] [${o}] ${r.map((e) => typeof e == "string" ? e : JSON.stringify(e)).join(" ")}
1184
+ function $(o, ...s) {
1185
+ const t = `[${(/* @__PURE__ */ new Date()).toISOString()}] [${o}] ${s.map((e) => typeof e == "string" ? e : JSON.stringify(e)).join(" ")}
1183
1186
  `;
1184
1187
  Ne(ke, t);
1185
1188
  }
@@ -1200,20 +1203,20 @@ function me() {
1200
1203
  nodeIntegration: !1,
1201
1204
  preload: d(J, "preload.mjs")
1202
1205
  }
1203
- }), S.webContents.on("console-message", (r, t, e, s, n) => {
1206
+ }), S.webContents.on("console-message", (s, t, e, r, n) => {
1204
1207
  const a = ["DEBUG", "INFO", "WARN", "ERROR"][t] || "LOG";
1205
- $(`renderer:${a}`, `${e} (${n}:${s})`);
1206
- }), S.webContents.on("render-process-gone", (r, t) => {
1208
+ $(`renderer:${a}`, `${e} (${n}:${r})`);
1209
+ }), S.webContents.on("render-process-gone", (s, t) => {
1207
1210
  $("main:CRASH", "Renderer process gone:", t);
1208
- }), S.webContents.on("did-fail-load", (r, t, e) => {
1211
+ }), S.webContents.on("did-fail-load", (s, t, e) => {
1209
1212
  $("main:LOAD_ERROR", `Failed to load: ${t} ${e}`);
1210
1213
  });
1211
1214
  const o = process.env.VITE_DEV_SERVER_URL;
1212
1215
  if (o)
1213
1216
  $("main", `Loading dev server URL: ${o}`), S.loadURL(o);
1214
1217
  else {
1215
- const r = d(J, "../dist-renderer/index.html");
1216
- $("main", `Loading file: ${r}`), S.loadFile(r);
1218
+ const s = d(J, "../dist-renderer/index.html");
1219
+ $("main", `Loading file: ${s}`), S.loadFile(s);
1217
1220
  }
1218
1221
  process.env.VITE_DEV_SERVER_URL && S.webContents.openDevTools(), S.on("closed", () => {
1219
1222
  S = null;
@@ -1224,7 +1227,7 @@ pe.registerSchemesAsPrivileged([
1224
1227
  ]);
1225
1228
  L.whenReady().then(() => {
1226
1229
  $("main", "App ready, registering IPC handlers");
1227
- const o = "State Change Council", r = [
1230
+ const o = "State Change Council", s = [
1228
1231
  {
1229
1232
  label: o,
1230
1233
  submenu: [
@@ -1244,10 +1247,10 @@ L.whenReady().then(() => {
1244
1247
  { role: "viewMenu" },
1245
1248
  { role: "windowMenu" }
1246
1249
  ];
1247
- ne.setApplicationMenu(ne.buildFromTemplate(r)), pe.handle("council-file", (t) => {
1250
+ ne.setApplicationMenu(ne.buildFromTemplate(s)), pe.handle("council-file", (t) => {
1248
1251
  const e = decodeURIComponent(t.url.replace("council-file://", ""));
1249
1252
  return Se.fetch($e(e).href);
1250
- }), At(Ae, () => S), me(), L.on("activate", () => {
1253
+ }), It(Ae, () => S), me(), L.on("activate", () => {
1251
1254
  fe.getAllWindows().length === 0 && me();
1252
1255
  });
1253
1256
  });