aura-code 0.3.7 → 0.6.3

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 (160) hide show
  1. package/README.md +56 -4
  2. package/dist/agent/compactor.d.ts +26 -0
  3. package/dist/agent/compactor.js +156 -0
  4. package/dist/agent/compactor.js.map +1 -0
  5. package/dist/agent/context.d.ts +4 -0
  6. package/dist/agent/context.js +38 -0
  7. package/dist/agent/context.js.map +1 -1
  8. package/dist/agent/design.d.ts +17 -0
  9. package/dist/agent/design.js +175 -0
  10. package/dist/agent/design.js.map +1 -0
  11. package/dist/agent/loop.js +24 -1
  12. package/dist/agent/loop.js.map +1 -1
  13. package/dist/agent/system-prompt.d.ts +1 -1
  14. package/dist/agent/system-prompt.js +14 -3
  15. package/dist/agent/system-prompt.js.map +1 -1
  16. package/dist/cli/display.js +46 -5
  17. package/dist/cli/display.js.map +1 -1
  18. package/dist/cli/index.js +323 -46
  19. package/dist/cli/index.js.map +1 -1
  20. package/dist/config/defaults.js +8 -1
  21. package/dist/config/defaults.js.map +1 -1
  22. package/dist/config/project-config.d.ts +6 -0
  23. package/dist/config/project-config.js +2 -0
  24. package/dist/config/project-config.js.map +1 -1
  25. package/dist/dream/dream.d.ts +71 -0
  26. package/dist/dream/dream.js +217 -0
  27. package/dist/dream/dream.js.map +1 -0
  28. package/dist/dream/okf.d.ts +10 -0
  29. package/dist/dream/okf.js +280 -0
  30. package/dist/dream/okf.js.map +1 -0
  31. package/dist/dream/parser.d.ts +60 -0
  32. package/dist/dream/parser.js +176 -0
  33. package/dist/dream/parser.js.map +1 -0
  34. package/dist/dream/reconcile.d.ts +69 -0
  35. package/dist/dream/reconcile.js +303 -0
  36. package/dist/dream/reconcile.js.map +1 -0
  37. package/dist/kanban/index.d.ts +5 -0
  38. package/dist/kanban/index.js +11 -0
  39. package/dist/kanban/index.js.map +1 -0
  40. package/dist/kanban/pipeline.d.ts +16 -0
  41. package/dist/kanban/pipeline.js +910 -0
  42. package/dist/kanban/pipeline.js.map +1 -0
  43. package/dist/kanban/server.d.ts +5 -0
  44. package/dist/kanban/server.js +820 -0
  45. package/dist/kanban/server.js.map +1 -0
  46. package/dist/kanban/types.d.ts +75 -0
  47. package/dist/kanban/types.js +6 -0
  48. package/dist/kanban/types.js.map +1 -0
  49. package/dist/learnlight/driven.d.ts +2 -0
  50. package/dist/learnlight/driven.js +109 -0
  51. package/dist/learnlight/driven.js.map +1 -0
  52. package/dist/learnlight/index.d.ts +4 -0
  53. package/dist/learnlight/index.js +32 -0
  54. package/dist/learnlight/index.js.map +1 -0
  55. package/dist/learnlight/lesson-prep.d.ts +36 -0
  56. package/dist/learnlight/lesson-prep.js +224 -0
  57. package/dist/learnlight/lesson-prep.js.map +1 -0
  58. package/dist/learnlight/report.d.ts +2 -0
  59. package/dist/learnlight/report.js +37 -0
  60. package/dist/learnlight/report.js.map +1 -0
  61. package/dist/learnlight/types.d.ts +72 -0
  62. package/dist/learnlight/types.js +6 -0
  63. package/dist/learnlight/types.js.map +1 -0
  64. package/dist/machina/index.d.ts +16 -0
  65. package/dist/machina/index.js +61 -0
  66. package/dist/machina/index.js.map +1 -0
  67. package/dist/machina/render-html.d.ts +2 -0
  68. package/dist/machina/render-html.js +189 -0
  69. package/dist/machina/render-html.js.map +1 -0
  70. package/dist/machina/render-terminal.d.ts +2 -0
  71. package/dist/machina/render-terminal.js +92 -0
  72. package/dist/machina/render-terminal.js.map +1 -0
  73. package/dist/machina/spec.d.ts +61 -0
  74. package/dist/machina/spec.js +124 -0
  75. package/dist/machina/spec.js.map +1 -0
  76. package/dist/machina/verify.d.ts +27 -0
  77. package/dist/machina/verify.js +85 -0
  78. package/dist/machina/verify.js.map +1 -0
  79. package/dist/perception/graph-store.d.ts +11 -0
  80. package/dist/perception/graph-store.js +33 -0
  81. package/dist/perception/graph-store.js.map +1 -1
  82. package/dist/perception/index.d.ts +1 -1
  83. package/dist/perception/index.js +2 -1
  84. package/dist/perception/index.js.map +1 -1
  85. package/dist/providers/anthropic.js +1 -1
  86. package/dist/providers/anthropic.js.map +1 -1
  87. package/dist/providers/factory.d.ts +49 -0
  88. package/dist/providers/factory.js +99 -0
  89. package/dist/providers/factory.js.map +1 -1
  90. package/dist/providers/google.js +1 -1
  91. package/dist/providers/google.js.map +1 -1
  92. package/dist/providers/openai-compatible.js +81 -50
  93. package/dist/providers/openai-compatible.js.map +1 -1
  94. package/dist/rem/graph.d.ts +72 -0
  95. package/dist/rem/graph.js +139 -0
  96. package/dist/rem/graph.js.map +1 -0
  97. package/dist/rem/index.d.ts +16 -0
  98. package/dist/rem/index.js +60 -0
  99. package/dist/rem/index.js.map +1 -0
  100. package/dist/rem/render-html.d.ts +2 -0
  101. package/dist/rem/render-html.js +189 -0
  102. package/dist/rem/render-html.js.map +1 -0
  103. package/dist/rem/render-terminal.d.ts +4 -0
  104. package/dist/rem/render-terminal.js +94 -0
  105. package/dist/rem/render-terminal.js.map +1 -0
  106. package/dist/research/council.d.ts +27 -0
  107. package/dist/research/council.js +263 -0
  108. package/dist/research/council.js.map +1 -0
  109. package/dist/research/research.d.ts +24 -0
  110. package/dist/research/research.js +116 -0
  111. package/dist/research/research.js.map +1 -0
  112. package/dist/ruby/alternator.d.ts +36 -1
  113. package/dist/ruby/alternator.js +40 -31
  114. package/dist/ruby/alternator.js.map +1 -1
  115. package/dist/ruby/stats.js +10 -11
  116. package/dist/ruby/stats.js.map +1 -1
  117. package/dist/ruby/types.js +1 -1
  118. package/dist/ruby/types.js.map +1 -1
  119. package/dist/safety/permissions.d.ts +8 -0
  120. package/dist/safety/permissions.js +12 -0
  121. package/dist/safety/permissions.js.map +1 -1
  122. package/dist/setup/provider-registry.js +14 -0
  123. package/dist/setup/provider-registry.js.map +1 -1
  124. package/dist/setup/provider-test.js +24 -2
  125. package/dist/setup/provider-test.js.map +1 -1
  126. package/dist/setup/telegram-wizard.d.ts +57 -0
  127. package/dist/setup/telegram-wizard.js +343 -0
  128. package/dist/setup/telegram-wizard.js.map +1 -0
  129. package/dist/tools/audio-transcribe.d.ts +20 -0
  130. package/dist/tools/audio-transcribe.js +39 -28
  131. package/dist/tools/audio-transcribe.js.map +1 -1
  132. package/dist/tools/browser.js +8 -10
  133. package/dist/tools/browser.js.map +1 -1
  134. package/dist/tools/gmail-tool.d.ts +15 -0
  135. package/dist/tools/gmail-tool.js +361 -0
  136. package/dist/tools/gmail-tool.js.map +1 -0
  137. package/dist/tools/read-file.js +13 -0
  138. package/dist/tools/read-file.js.map +1 -1
  139. package/dist/tools/telegram-bot.js +103 -20
  140. package/dist/tools/telegram-bot.js.map +1 -1
  141. package/dist/tools/telegram-voice.d.ts +22 -0
  142. package/dist/tools/telegram-voice.js +203 -0
  143. package/dist/tools/telegram-voice.js.map +1 -0
  144. package/dist/tools/telegram.d.ts +6 -1
  145. package/dist/tools/telegram.js +115 -5
  146. package/dist/tools/telegram.js.map +1 -1
  147. package/dist/tools/video-render.d.ts +11 -0
  148. package/dist/tools/video-render.js +189 -0
  149. package/dist/tools/video-render.js.map +1 -0
  150. package/dist/tools/web-search.d.ts +20 -0
  151. package/dist/tools/web-search.js +134 -38
  152. package/dist/tools/web-search.js.map +1 -1
  153. package/dist/util/errors.js +6 -0
  154. package/dist/util/errors.js.map +1 -1
  155. package/dist/viz/index.js +816 -30
  156. package/dist/viz/index.js.map +1 -1
  157. package/dist/viz/reader.d.ts +33 -0
  158. package/dist/viz/reader.js +343 -0
  159. package/dist/viz/reader.js.map +1 -0
  160. package/package.json +3 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rem/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,wBAcC;AAhCD,uCAAyB;AACzB,2CAA6B;AAC7B,yCAAyD;AACzD,6DAAyD;AACzD,qDAA+C;AAQ/C;;;;;GAKG;AACH,SAAgB,MAAM,CAAC,IAAkD;IACvE,MAAM,KAAK,GAAG,IAAA,uBAAY,EAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7C,MAAM,cAAc,GAAG,IAAA,sCAAiB,EAAC,KAAK,CAAC,CAAC;IAEhD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACpB,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;IACnC,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC5C,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAA,4BAAW,EAAC,KAAK,CAAC,CAAC,CAAC;IAE/C,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { RemGraph } from './graph.js';
2
+ export declare function wrapRemHtml(graph: RemGraph): string;
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.wrapRemHtml = wrapRemHtml;
4
+ /**
5
+ * Renders a `RemGraph` as a standalone themed HTML file containing a real
6
+ * SVG node-and-edge graph (night nodes in a row, tag nodes arranged around
7
+ * them, edges weighted by occurrence count) plus a ranked tag list below it.
8
+ *
9
+ * Visually matches the warm/cream "Aura" theme used by :research / :council
10
+ * (see src/research/council.ts's wrapHtml) so output feels consistent
11
+ * across the agent's generated docs, with a dark-mode variant via
12
+ * prefers-color-scheme.
13
+ *
14
+ * Layout is a deterministic two-row bipartite layout (nights on top,
15
+ * tags on bottom, both sorted), NOT a physics-simulated force layout —
16
+ * this keeps the SVG static, dependency-free, and stable across renders of
17
+ * the same data (no jitter, no client-side JS layout pass required).
18
+ */
19
+ function esc(s) {
20
+ return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
21
+ }
22
+ const PALETTE = [
23
+ '#cc785c', '#5a9e6e', '#b15439', '#7a8ecc', '#c2a35a', '#9e6ecc', '#5aa3a8',
24
+ ];
25
+ function colorFor(index) {
26
+ return PALETTE[index % PALETTE.length];
27
+ }
28
+ function buildSvg(graph) {
29
+ const nightIds = graph.nights.map(n => n.date);
30
+ const tagIds = graph.topTags.map(t => t.tag);
31
+ const width = Math.max(720, Math.max(nightIds.length, tagIds.length) * 110 + 80);
32
+ const nightY = 90;
33
+ const tagY = 330;
34
+ const height = tagY + 90;
35
+ const nightX = new Map();
36
+ nightIds.forEach((id, i) => {
37
+ const gap = nightIds.length > 1 ? (width - 120) / (nightIds.length - 1) : 0;
38
+ nightX.set(id, 60 + gap * i);
39
+ });
40
+ const tagX = new Map();
41
+ tagIds.forEach((id, i) => {
42
+ const gap = tagIds.length > 1 ? (width - 120) / (tagIds.length - 1) : 0;
43
+ tagX.set(id, 60 + gap * i);
44
+ });
45
+ const maxEpisodes = Math.max(...graph.nights.map(n => n.episodeCount), 1);
46
+ const maxTagCount = graph.topTags[0]?.count ?? 1;
47
+ const maxEdgeWeight = Math.max(...graph.edges.map(e => e.weight), 1);
48
+ const edgeLines = graph.edges.map(e => {
49
+ const x1 = nightX.get(e.night);
50
+ const y1 = nightY;
51
+ const x2 = tagX.get(e.tag);
52
+ const y2 = tagY;
53
+ if (x1 === undefined || x2 === undefined)
54
+ return '';
55
+ const strokeW = 1 + (e.weight / maxEdgeWeight) * 3.5;
56
+ const tagIdx = tagIds.indexOf(e.tag);
57
+ const color = colorFor(tagIdx);
58
+ return `<line x1="${x1}" y1="${y1 + 14}" x2="${x2}" y2="${y2 - 22}" stroke="${color}" stroke-width="${strokeW.toFixed(2)}" stroke-opacity="0.45" />`;
59
+ }).join('\n ');
60
+ const nightNodes = nightIds.map(id => {
61
+ const night = graph.nights.find(n => n.date === id);
62
+ const r = 8 + (night.episodeCount / maxEpisodes) * 14;
63
+ const x = nightX.get(id);
64
+ return `
65
+ <g class="node night-node">
66
+ <circle cx="${x}" cy="${nightY}" r="${r.toFixed(1)}" class="night-circle" />
67
+ <text x="${x}" y="${nightY - r - 8}" class="night-label" text-anchor="middle">${esc(id)}</text>
68
+ <text x="${x}" y="${nightY + r + 16}" class="night-sub" text-anchor="middle">${night.episodeCount} ep</text>
69
+ </g>`;
70
+ }).join('');
71
+ const tagNodes = tagIds.map((id, i) => {
72
+ const t = graph.topTags[i];
73
+ const r = 6 + (t.count / maxTagCount) * 16;
74
+ const x = tagX.get(id);
75
+ const color = colorFor(i);
76
+ return `
77
+ <g class="node tag-node">
78
+ <circle cx="${x}" cy="${tagY}" r="${r.toFixed(1)}" fill="${color}" fill-opacity="0.85" />
79
+ <text x="${x}" y="${tagY + r + 18}" class="tag-label" text-anchor="middle" fill="${color}">[${esc(id)}]</text>
80
+ <text x="${x}" y="${tagY + r + 34}" class="tag-sub" text-anchor="middle">${t.count}×</text>
81
+ </g>`;
82
+ }).join('');
83
+ return `<svg viewBox="0 0 ${width} ${height}" xmlns="http://www.w3.org/2000/svg" class="rem-graph">
84
+ <g class="edges">
85
+ ${edgeLines}
86
+ </g>
87
+ <g class="nights">${nightNodes}
88
+ </g>
89
+ <g class="tags">${tagNodes}
90
+ </g>
91
+ </svg>`;
92
+ }
93
+ function buildTopTagsTable(graph) {
94
+ const rows = graph.topTags.slice(0, 20).map((t, i) => {
95
+ const color = colorFor(i);
96
+ const pct = graph.topTags[0] ? Math.round((t.count / graph.topTags[0].count) * 100) : 0;
97
+ return `<tr>
98
+ <td class="tag-cell"><span class="dot" style="background:${color}"></span>[${esc(t.tag)}]</td>
99
+ <td><div class="bar-track"><div class="bar-fill" style="width:${pct}%;background:${color}"></div></div></td>
100
+ <td class="num-cell">${t.count}</td>
101
+ <td class="num-cell">${t.nights}</td>
102
+ </tr>`;
103
+ }).join('\n');
104
+ return `<table class="tag-table">
105
+ <thead><tr><th>Tag</th><th>Frequency</th><th>Count</th><th>Nights</th></tr></thead>
106
+ <tbody>${rows}</tbody>
107
+ </table>`;
108
+ }
109
+ function wrapRemHtml(graph) {
110
+ const dateRange = graph.nights.length
111
+ ? `${graph.nights[0].date} → ${graph.nights[graph.nights.length - 1].date}`
112
+ : '—';
113
+ return `<!DOCTYPE html>
114
+ <html lang="en">
115
+ <head>
116
+ <meta charset="UTF-8">
117
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
118
+ <title>Rem — Aura Dream Graph</title>
119
+ <style>
120
+ :root {
121
+ --bg: #fdf6f0; --card: #fffaf5; --text: #3e2f24; --muted: #8a7768;
122
+ --accent: #cc785c; --accent-2: #5a9e6e; --border: #e8d5c8;
123
+ --code-bg: #f4ede6; --hr: #e0cebc;
124
+ --shadow: 0 2px 12px rgba(62,47,36,0.06); --radius: 12px;
125
+ --serif: 'Georgia', 'Times New Roman', serif;
126
+ --sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
127
+ --mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
128
+ }
129
+ @media (prefers-color-scheme: dark) {
130
+ :root {
131
+ --bg: #1e1b18; --card: #26221e; --text: #ede0cc; --muted: #9e8e80;
132
+ --accent: #e08a6e; --accent-2: #6db880; --border: #3a322a;
133
+ --code-bg: #2c2722; --hr: #3a322a;
134
+ --shadow: 0 2px 12px rgba(0,0,0,0.25);
135
+ }
136
+ }
137
+ * { box-sizing: border-box; margin: 0; padding: 0; }
138
+ body { background: var(--bg); color: var(--text); font-family: var(--serif); line-height: 1.7; font-size: 17px; }
139
+ .container { max-width: 980px; margin: 0 auto; padding: 3rem 1.5rem 5rem; }
140
+ .hero { text-align: center; padding: 2.5rem 0 2rem; border-bottom: 2px solid var(--border); margin-bottom: 2.5rem; }
141
+ .hero .badge { display: inline-block; background: var(--accent); color: #fff; font-family: var(--sans); font-size: 0.7rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; padding: 0.3em 1em; border-radius: 100px; margin-bottom: 1.25rem; }
142
+ .hero h1 { font-family: var(--sans); font-size: 2.2rem; font-weight: 700; line-height: 1.25; letter-spacing: -0.02em; margin-bottom: 0.5rem; }
143
+ .hero .meta { font-family: var(--sans); font-size: 0.85rem; color: var(--muted); }
144
+ .card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 2rem 2.5rem; margin-bottom: 2rem; }
145
+ @media (max-width: 720px) { .card { padding: 1.25rem; border-radius: 8px; } .hero h1 { font-size: 1.6rem; } .container { padding: 1.5rem 0.75rem 3rem; } }
146
+ .card h2 { font-family: var(--sans); font-size: 1.3rem; color: var(--accent); border-bottom: 2px solid var(--border); padding-bottom: 0.5rem; margin-bottom: 1.25rem; }
147
+ .rem-graph { width: 100%; height: auto; display: block; }
148
+ .night-circle { fill: var(--card); stroke: var(--accent); stroke-width: 2; }
149
+ .night-label { font-family: var(--sans); font-size: 12px; font-weight: 700; fill: var(--text); }
150
+ .night-sub, .tag-sub { font-family: var(--sans); font-size: 10px; fill: var(--muted); }
151
+ .tag-label { font-family: var(--sans); font-size: 11px; font-weight: 600; }
152
+ .tag-table { width: 100%; border-collapse: collapse; font-family: var(--sans); font-size: 0.9rem; }
153
+ .tag-table th { text-align: left; color: var(--muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; padding: 0.5rem 0.75rem; border-bottom: 2px solid var(--border); }
154
+ .tag-table td { padding: 0.55rem 0.75rem; border-bottom: 1px solid var(--hr); vertical-align: middle; }
155
+ .tag-cell { white-space: nowrap; font-weight: 600; }
156
+ .dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 0.5em; }
157
+ .num-cell { text-align: right; color: var(--muted); font-variant-numeric: tabular-nums; }
158
+ .bar-track { background: var(--code-bg); border-radius: 6px; height: 8px; overflow: hidden; min-width: 100px; }
159
+ .bar-fill { height: 100%; border-radius: 6px; }
160
+ .footer { text-align: center; margin-top: 1rem; font-family: var(--sans); font-size: 0.8rem; color: var(--muted); opacity: 0.7; }
161
+ .empty { text-align: center; color: var(--muted); font-family: var(--sans); padding: 3rem 1rem; }
162
+ </style>
163
+ </head>
164
+ <body>
165
+ <div class="container">
166
+ <header class="hero">
167
+ <div class="badge">Aura &middot; Rem</div>
168
+ <h1>Dream Relations Graph</h1>
169
+ <div class="meta">${esc(dateRange)} &middot; ${graph.nights.length} night(s) &middot; ${graph.topTags.length} tag(s)</div>
170
+ </header>
171
+
172
+ ${graph.nights.length === 0
173
+ ? '<div class="card"><p class="empty">No dreams yet. Run :dream after some work, then :rem --html again.</p></div>'
174
+ : `<section class="card">
175
+ <h2>Nights &middot; Tags</h2>
176
+ ${buildSvg(graph)}
177
+ </section>
178
+
179
+ <section class="card">
180
+ <h2>What keeps coming up</h2>
181
+ ${buildTopTagsTable(graph)}
182
+ </section>`}
183
+
184
+ <footer class="footer"><p>Generated by Aura Code &middot; :rem &middot; parsed from dreams/*.md</p></footer>
185
+ </div>
186
+ </body>
187
+ </html>`;
188
+ }
189
+ //# sourceMappingURL=render-html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-html.js","sourceRoot":"","sources":["../../src/rem/render-html.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { RemGraph } from './graph.js';
2
+ export declare function renderRemTerminal(graph: RemGraph, opts?: {
3
+ recentNights?: number;
4
+ }): string;
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.renderRemTerminal = renderRemTerminal;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ /**
9
+ * Renders a `RemGraph` as terminal text using Aura's existing warm palette
10
+ * (the same hex set used throughout src/cli/index.ts) so `:rem` looks native
11
+ * next to `:dream`, `:design`, etc.
12
+ *
13
+ * Layout, top to bottom:
14
+ * 1. A timeline strip — one row per night, oldest→newest, with a small bar
15
+ * sized by episode count.
16
+ * 2. "What keeps coming up" — top tags ranked by total occurrence, with a
17
+ * horizontal bar and the count of distinct nights it appeared in.
18
+ * 3. Per-night detail — for the most recent N nights, which tags fired.
19
+ *
20
+ * Deliberately not a literal node-and-edge ASCII graph (boxes-and-arrows in
21
+ * a terminal degrade badly past ~6 nodes); a ranked/timeline view answers
22
+ * the actual question ("what keeps coming up, and when") more legibly than
23
+ * a force-directed layout would in 80 columns.
24
+ */
25
+ const C = {
26
+ heading: chalk_1.default.hex('#cc785c').bold,
27
+ text: chalk_1.default.hex('#ede0cc'),
28
+ muted: chalk_1.default.hex('#8a7768'),
29
+ dim: chalk_1.default.hex('#4e3d30'),
30
+ good: chalk_1.default.hex('#5a9e6e'),
31
+ warn: chalk_1.default.hex('#b15439'),
32
+ };
33
+ const BAR_CHAR = '█';
34
+ const BAR_WIDTH = 24;
35
+ function bar(value, max, width = BAR_WIDTH) {
36
+ if (max <= 0)
37
+ return '';
38
+ const filled = Math.max(1, Math.round((value / max) * width));
39
+ return BAR_CHAR.repeat(Math.min(filled, width));
40
+ }
41
+ function renderRemTerminal(graph, opts = {}) {
42
+ const recentNights = opts.recentNights ?? 5;
43
+ const lines = [];
44
+ if (graph.nights.length === 0) {
45
+ return C.muted('\n No dreams yet. Run :dream after some work.\n');
46
+ }
47
+ lines.push('');
48
+ lines.push(C.heading(` Rem — ${graph.nights.length} night(s), ${graph.topTags.length} recurring tag(s)`));
49
+ lines.push('');
50
+ // ── 1. Timeline strip ──────────────────────────────────────────────────
51
+ lines.push(C.muted(' Timeline'));
52
+ const maxEpisodes = Math.max(...graph.nights.map(n => n.episodeCount), 1);
53
+ for (const night of graph.nights) {
54
+ const tagCount = new Set(night.occurrences.map(o => o.tag)).size;
55
+ lines.push(` ${C.text(night.date)} ${C.dim(bar(night.episodeCount, maxEpisodes, 16))} ` +
56
+ C.muted(`${night.episodeCount} ep · ${tagCount} tag(s)`));
57
+ }
58
+ lines.push('');
59
+ // ── 2. Top tags ranked by total occurrence ─────────────────────────────
60
+ lines.push(C.muted(' What keeps coming up'));
61
+ const maxCount = graph.topTags[0]?.count ?? 1;
62
+ for (const t of graph.topTags.slice(0, 12)) {
63
+ const label = `[${t.tag}]`.padEnd(20);
64
+ lines.push(` ${C.heading(label)} ${C.text(bar(t.count, maxCount))} ` +
65
+ C.muted(`${t.count}× across ${t.nights} night(s)`));
66
+ }
67
+ lines.push('');
68
+ // ── 3. Per-night detail for the most recent nights ─────────────────────
69
+ const recent = graph.nights.slice(-recentNights).reverse();
70
+ lines.push(C.muted(` Recent detail (last ${recent.length})`));
71
+ for (const night of recent) {
72
+ lines.push(` ${C.heading(night.date)}`);
73
+ if (night.occurrences.length === 0) {
74
+ lines.push(` ${C.muted('(no tagged lessons/threads)')}`);
75
+ continue;
76
+ }
77
+ const byTag = new Map();
78
+ for (const occ of night.occurrences) {
79
+ if (!byTag.has(occ.tag))
80
+ byTag.set(occ.tag, []);
81
+ byTag.get(occ.tag).push(occ.text);
82
+ }
83
+ for (const [tag, texts] of byTag) {
84
+ const sample = texts[0].length > 72 ? texts[0].slice(0, 69) + '...' : texts[0];
85
+ const more = texts.length > 1 ? C.muted(` (+${texts.length - 1} more)`) : '';
86
+ lines.push(` ${C.warn(`[${tag}]`)} ${C.text(sample)}${more}`);
87
+ }
88
+ }
89
+ lines.push('');
90
+ lines.push(C.muted(' :rem --html writes a visual graph to dreams/rem.html'));
91
+ lines.push('');
92
+ return lines.join('\n');
93
+ }
94
+ //# sourceMappingURL=render-terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-terminal.js","sourceRoot":"","sources":["../../src/rem/render-terminal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { LLMProvider } from '../providers/types.js';
2
+ import type { ProjectContext } from '../agent/context.js';
3
+ import type { PermissionSystem } from '../safety/permissions.js';
4
+ import type { Display } from '../cli/display.js';
5
+ export interface CouncilResult {
6
+ path: string;
7
+ htmlPath: string;
8
+ topic: string;
9
+ panelSize: number;
10
+ panelModel: string;
11
+ agentFailures: number;
12
+ }
13
+ /**
14
+ * Run an Ecclesia: `panelSize` independent agents research the topic
15
+ * sequentially, then one synthesis call on the caller's active provider
16
+ * reconciles their findings into a verdict.
17
+ */
18
+ export declare function runCouncil(opts: {
19
+ projectRoot: string;
20
+ topic: string;
21
+ synthesisProvider: LLMProvider;
22
+ context: ProjectContext;
23
+ permissions: PermissionSystem;
24
+ display: Display;
25
+ panelSize?: number;
26
+ panelModel?: string;
27
+ }): Promise<CouncilResult>;
@@ -0,0 +1,263 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runCouncil = runCouncil;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const marked_1 = require("marked");
40
+ const loop_js_1 = require("../agent/loop.js");
41
+ const factory_js_1 = require("../providers/factory.js");
42
+ /**
43
+ * Aura's `:council` ("Ecclesia") — N independent research agents investigate
44
+ * the same topic, then a synthesis pass reconciles their findings into one
45
+ * verdict: what they agreed on, what's contested, and what only a minority
46
+ * caught. Default panel size is 5 — odd, so majority agreement is always
47
+ * decisive (no 2.5/2.5 ties).
48
+ *
49
+ * Cost design, deliberately conservative (see compaction/dream incidents):
50
+ * - The N panel agents run SEQUENTIALLY, each a short findings-only pass
51
+ * (not a full polished report). Local models produce catastrophic factual
52
+ * errors (e.g. hallucinated Djokovic stats), so Ollama is not a
53
+ * supported default.
54
+ * - Only the final synthesis step is reasoning-heavy; it runs as a single
55
+ * call on the caller's active provider.
56
+ * - Per-agent turns are capped well below :research's full budget.
57
+ *
58
+ * Panel model resolution (in priority order):
59
+ * 1. `opts.panelModel` — explicit caller override (CLI: `--panel <model>`).
60
+ * 2. `AURA_PANEL_MODEL` env var — global default for cheap-panel setups.
61
+ * 3. The synthesis provider's own model — the user's already-configured
62
+ * and authenticated model, whatever it is. This works for every user
63
+ * without assuming Xiaomi / OpenAI / any specific provider.
64
+ *
65
+ * Cost note: option 3 means a 5-agent council costs ~5× a single :research
66
+ * pass on whatever the user is paying for. Users who want cheaper runs can
67
+ * set AURA_PANEL_MODEL globally, or pass `--panel <fast-model>` per call.
68
+ *
69
+ * Output: dated `.md` + `.html` under `<projectRoot>/council/`.
70
+ */
71
+ const COUNCIL_DIRNAME = 'council';
72
+ const DEFAULT_PANEL_SIZE = 5;
73
+ const FOOTER = '\n---\n\n*Ecclesia — five voices, one verdict. Inspired by DeerFlow.*\n';
74
+ function councilDir(projectRoot) {
75
+ return path.join(projectRoot, COUNCIL_DIRNAME);
76
+ }
77
+ function slugify(topic) {
78
+ return topic
79
+ .toLowerCase()
80
+ .replace(/[^a-z0-9]+/g, '-')
81
+ .replace(/^-+|-+$/g, '')
82
+ .slice(0, 60) || 'topic';
83
+ }
84
+ function buildPanelTask(topic, seat, panelSize) {
85
+ return (`You are panel seat ${seat} of ${panelSize} in an independent research council on this topic: "${topic}"\n\n` +
86
+ `Research it on your own — search and fetch what you need. Do NOT try to write a polished ` +
87
+ `report. Instead, respond with ONLY a compact findings list:\n\n` +
88
+ `- 4-8 bullet points, each one specific claim or finding, with its source noted in parentheses.\n` +
89
+ `- If something is disputed, speculative, or you're unsure, say so explicitly in that bullet.\n` +
90
+ `- End with one line: "Stance: <your one-sentence bottom-line take>"\n\n` +
91
+ `No preamble, no headers, no questions back. Just the bullets and the stance line.`);
92
+ }
93
+ function buildSynthesisPrompt(topic, findings) {
94
+ const system = 'You are Aura synthesising an Ecclesia — an independent research council. You are given ' +
95
+ `${findings.length} separate agents' findings on the same topic, gathered without them seeing ` +
96
+ 'each other\'s work. Reconcile them into one verdict. Respond in Markdown with EXACTLY these ' +
97
+ 'sections:\n\n' +
98
+ '## Convergent findings\n(claims most or all agents independently arrived at — high confidence)\n\n' +
99
+ '## Contested\n(claims where agents disagreed, or where a majority/minority split exists — name the split, ' +
100
+ 'e.g. "3 of 5 agents..." )\n\n' +
101
+ '## Minority signal\n(something only one or two agents caught that seems worth surfacing anyway, even if unconfirmed)\n\n' +
102
+ '## Verdict\n(the council\'s bottom-line conclusion — what an informed reader should walk away believing, ' +
103
+ 'and how confident that conclusion is)\n\n' +
104
+ '## Sources\n(consolidated list of sources cited across all agents)';
105
+ const user = `Topic: ${topic}\n\n` +
106
+ findings.map((f, i) => `### Agent ${i + 1}\n${f}`).join('\n\n');
107
+ return { system, user };
108
+ }
109
+ function mdToHtml(md) {
110
+ marked_1.marked.setOptions({ gfm: true, breaks: false });
111
+ return marked_1.marked.parse(md);
112
+ }
113
+ function wrapHtml(title, bodyHtml, date, panelSize) {
114
+ const esc = (s) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
115
+ return `<!DOCTYPE html>
116
+ <html lang="en">
117
+ <head>
118
+ <meta charset="UTF-8">
119
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
120
+ <title>${esc(title)} — Ecclesia</title>
121
+ <style>
122
+ :root {
123
+ --bg: #fdf6f0; --card: #fffaf5; --text: #3e2f24; --muted: #8a7768;
124
+ --accent: #cc785c; --accent-2: #5a9e6e; --border: #e8d5c8;
125
+ --code-bg: #f4ede6; --bq: #cc785c; --hr: #e0cebc;
126
+ --shadow: 0 2px 12px rgba(62,47,36,0.06); --radius: 12px;
127
+ --serif: 'Georgia', 'Times New Roman', serif;
128
+ --sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
129
+ --mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
130
+ }
131
+ @media (prefers-color-scheme: dark) {
132
+ :root {
133
+ --bg: #1e1b18; --card: #26221e; --text: #ede0cc; --muted: #9e8e80;
134
+ --accent: #e08a6e; --accent-2: #6db880; --border: #3a322a;
135
+ --code-bg: #2c2722; --bq: #e08a6e; --hr: #3a322a;
136
+ --shadow: 0 2px 12px rgba(0,0,0,0.25);
137
+ }
138
+ }
139
+ * { box-sizing: border-box; margin: 0; padding: 0; }
140
+ body { background: var(--bg); color: var(--text); font-family: var(--serif); line-height: 1.75; font-size: 18px; }
141
+ .container { max-width: 780px; margin: 0 auto; padding: 3rem 1.5rem 5rem; }
142
+ .hero { text-align: center; padding: 3rem 0 2.5rem; border-bottom: 2px solid var(--border); margin-bottom: 2.5rem; }
143
+ .hero .badge { display: inline-block; background: var(--accent); color: #fff; font-family: var(--sans); font-size: 0.7rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; padding: 0.3em 1em; border-radius: 100px; margin-bottom: 1.25rem; }
144
+ .hero h1 { font-family: var(--sans); font-size: 2.4rem; font-weight: 700; line-height: 1.25; letter-spacing: -0.02em; margin-bottom: 0.5rem; }
145
+ .hero .meta { font-family: var(--sans); font-size: 0.85rem; color: var(--muted); }
146
+ .card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 2.5rem 3rem; }
147
+ @media (max-width: 640px) { .card { padding: 1.5rem; border-radius: 8px; } .hero h1 { font-size: 1.7rem; } .container { padding: 1.5rem 0.75rem 3rem; } }
148
+ .card h1, .card h2, .card h3 { font-family: var(--sans); margin: 2rem 0 0.75rem; line-height: 1.3; }
149
+ .card h2:first-child { margin-top: 0; }
150
+ .card h2 { font-size: 1.45rem; color: var(--accent); border-bottom: 2px solid var(--border); padding-bottom: 0.4rem; }
151
+ .card h3 { font-size: 1.1rem; color: var(--accent-2); }
152
+ .card p { margin: 0.85rem 0; }
153
+ .card a { color: var(--accent); text-decoration: none; border-bottom: 1px solid var(--accent); }
154
+ .card ul, .card ol { margin: 0.85rem 0; padding-left: 1.8rem; }
155
+ .card li { margin: 0.4rem 0; }
156
+ .card code { font-family: var(--mono); font-size: 0.88em; background: var(--code-bg); padding: 0.15em 0.4em; border-radius: 4px; border: 1px solid var(--border); }
157
+ .card hr { border: none; border-top: 1px solid var(--hr); margin: 2rem 0; }
158
+ .footer { text-align: center; margin-top: 2.5rem; font-family: var(--sans); font-size: 0.8rem; color: var(--muted); opacity: 0.7; }
159
+ </style>
160
+ </head>
161
+ <body>
162
+ <div class="container">
163
+ <header class="hero">
164
+ <div class="badge">Ecclesia &middot; ${panelSize} agents</div>
165
+ <h1>${esc(title)}</h1>
166
+ <div class="meta">${date}</div>
167
+ </header>
168
+ <article class="card">
169
+ ${bodyHtml}
170
+ </article>
171
+ <footer class="footer"><p>Generated by Aura Code &middot; Ecclesia &middot; Inspired by DeerFlow</p></footer>
172
+ </div>
173
+ </body>
174
+ </html>`;
175
+ }
176
+ /**
177
+ * Pick which model the panel agents run on.
178
+ *
179
+ * Priority:
180
+ * 1. `override` — explicit `opts.panelModel` (set by `--panel <model>`)
181
+ * 2. `AURA_PANEL_MODEL` env var — global default for cheap-panel setups
182
+ * 3. The synthesis provider's `.model` — the user's authenticated, working
183
+ * model. Means the council just works for whoever ran `:provider`,
184
+ * without assuming any specific vendor.
185
+ *
186
+ * If none of these yield a model, throw with a clear message rather than
187
+ * passing `undefined` to `createProvider` (which historically produced
188
+ * opaque "400 Not supported model" errors).
189
+ */
190
+ function resolvePanelModel(synthesisProvider, override) {
191
+ if (override && override.trim())
192
+ return override.trim();
193
+ const env = process.env.AURA_PANEL_MODEL;
194
+ if (env && env.trim())
195
+ return env.trim();
196
+ // LLMProvider.model — the configured model id for that provider instance.
197
+ const fromProvider = synthesisProvider.model;
198
+ if (fromProvider && fromProvider.trim())
199
+ return fromProvider.trim();
200
+ throw new Error('Could not resolve a panel model. Pass --panel <model>, ' +
201
+ 'set AURA_PANEL_MODEL, or configure a provider via :provider first.');
202
+ }
203
+ /**
204
+ * Run an Ecclesia: `panelSize` independent agents research the topic
205
+ * sequentially, then one synthesis call on the caller's active provider
206
+ * reconciles their findings into a verdict.
207
+ */
208
+ async function runCouncil(opts) {
209
+ const { projectRoot, topic, synthesisProvider, context, permissions, display, } = opts;
210
+ const panelSize = Math.max(1, opts.panelSize ?? DEFAULT_PANEL_SIZE);
211
+ const panelModel = resolvePanelModel(synthesisProvider, opts.panelModel);
212
+ const findings = [];
213
+ let agentFailures = 0;
214
+ // Sequential by design — see module doc. Each agent is independent: no
215
+ // agent sees another's findings, so agreement/disagreement is genuine.
216
+ for (let seat = 1; seat <= panelSize; seat++) {
217
+ try {
218
+ const panelProvider = (0, factory_js_1.createProvider)({ model: panelModel });
219
+ const res = await (0, loop_js_1.runAgentLoop)({
220
+ provider: panelProvider,
221
+ task: buildPanelTask(topic, seat, panelSize),
222
+ context,
223
+ permissions,
224
+ display,
225
+ maxTurns: 6,
226
+ disableSpawn: true,
227
+ });
228
+ const text = (res.summary ?? '').trim();
229
+ findings.push(text || `(Agent ${seat} returned no findings.)`);
230
+ }
231
+ catch (err) {
232
+ agentFailures++;
233
+ findings.push(`(Agent ${seat} failed: ${err instanceof Error ? err.message : String(err)})`);
234
+ }
235
+ }
236
+ // Synthesis — one call, on the caller's real provider.
237
+ const { system, user } = buildSynthesisPrompt(topic, findings);
238
+ let verdictBody;
239
+ try {
240
+ const synth = await synthesisProvider.complete(system, [{ role: 'user', content: user }], []);
241
+ verdictBody = (synth.text ?? '').trim();
242
+ }
243
+ catch (err) {
244
+ verdictBody =
245
+ `## Convergent findings\n_Synthesis failed: ${err instanceof Error ? err.message : String(err)}_\n\n` +
246
+ `## Contested\n- none (synthesis did not run)\n\n## Minority signal\n- none\n\n` +
247
+ `## Verdict\nSynthesis could not run, but the ${panelSize} agents' raw findings are preserved below.\n\n## Sources\n- see raw findings`;
248
+ }
249
+ const rawFindingsSection = `\n\n---\n\n## Raw panel findings\n\n` +
250
+ findings.map((f, i) => `### Agent ${i + 1}\n\n${f}`).join('\n\n');
251
+ const md = `# Ecclesia: ${topic}\n\n${verdictBody}${rawFindingsSection}\n${FOOTER}`;
252
+ const dir = councilDir(projectRoot);
253
+ fs.mkdirSync(dir, { recursive: true });
254
+ const date = new Date().toISOString().slice(0, 10);
255
+ const slug = slugify(topic);
256
+ const mdPath = path.join(dir, `${date}-${slug}.md`);
257
+ fs.writeFileSync(mdPath, md);
258
+ const htmlOut = wrapHtml(topic, mdToHtml(`${verdictBody}${rawFindingsSection}`), date, panelSize);
259
+ const htmlPath = path.join(dir, `${date}-${slug}.html`);
260
+ fs.writeFileSync(htmlPath, htmlOut);
261
+ return { path: mdPath, htmlPath, topic, panelSize, panelModel, agentFailures };
262
+ }
263
+ //# sourceMappingURL=council.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"council.js","sourceRoot":"","sources":["../../src/research/council.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { LLMProvider } from '../providers/types.js';
2
+ import type { ProjectContext } from '../agent/context.js';
3
+ import type { PermissionSystem } from '../safety/permissions.js';
4
+ import type { Display } from '../cli/display.js';
5
+ export interface ResearchResult {
6
+ path: string;
7
+ topic: string;
8
+ turns: number;
9
+ toolCalls: number;
10
+ }
11
+ /**
12
+ * Run a research pass and save it to a dated file. Throws if the underlying
13
+ * agent loop fails outright (caller should catch and report — there is no
14
+ * silent error-stub here, unlike :dream, since a failed research run has no
15
+ * partial state worth preserving).
16
+ */
17
+ export declare function runResearch(opts: {
18
+ projectRoot: string;
19
+ topic: string;
20
+ provider: LLMProvider;
21
+ context: ProjectContext;
22
+ permissions: PermissionSystem;
23
+ display: Display;
24
+ }): Promise<ResearchResult>;