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.
- package/README.md +56 -4
- package/dist/agent/compactor.d.ts +26 -0
- package/dist/agent/compactor.js +156 -0
- package/dist/agent/compactor.js.map +1 -0
- package/dist/agent/context.d.ts +4 -0
- package/dist/agent/context.js +38 -0
- package/dist/agent/context.js.map +1 -1
- package/dist/agent/design.d.ts +17 -0
- package/dist/agent/design.js +175 -0
- package/dist/agent/design.js.map +1 -0
- package/dist/agent/loop.js +24 -1
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/system-prompt.d.ts +1 -1
- package/dist/agent/system-prompt.js +14 -3
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/cli/display.js +46 -5
- package/dist/cli/display.js.map +1 -1
- package/dist/cli/index.js +323 -46
- package/dist/cli/index.js.map +1 -1
- package/dist/config/defaults.js +8 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/project-config.d.ts +6 -0
- package/dist/config/project-config.js +2 -0
- package/dist/config/project-config.js.map +1 -1
- package/dist/dream/dream.d.ts +71 -0
- package/dist/dream/dream.js +217 -0
- package/dist/dream/dream.js.map +1 -0
- package/dist/dream/okf.d.ts +10 -0
- package/dist/dream/okf.js +280 -0
- package/dist/dream/okf.js.map +1 -0
- package/dist/dream/parser.d.ts +60 -0
- package/dist/dream/parser.js +176 -0
- package/dist/dream/parser.js.map +1 -0
- package/dist/dream/reconcile.d.ts +69 -0
- package/dist/dream/reconcile.js +303 -0
- package/dist/dream/reconcile.js.map +1 -0
- package/dist/kanban/index.d.ts +5 -0
- package/dist/kanban/index.js +11 -0
- package/dist/kanban/index.js.map +1 -0
- package/dist/kanban/pipeline.d.ts +16 -0
- package/dist/kanban/pipeline.js +910 -0
- package/dist/kanban/pipeline.js.map +1 -0
- package/dist/kanban/server.d.ts +5 -0
- package/dist/kanban/server.js +820 -0
- package/dist/kanban/server.js.map +1 -0
- package/dist/kanban/types.d.ts +75 -0
- package/dist/kanban/types.js +6 -0
- package/dist/kanban/types.js.map +1 -0
- package/dist/learnlight/driven.d.ts +2 -0
- package/dist/learnlight/driven.js +109 -0
- package/dist/learnlight/driven.js.map +1 -0
- package/dist/learnlight/index.d.ts +4 -0
- package/dist/learnlight/index.js +32 -0
- package/dist/learnlight/index.js.map +1 -0
- package/dist/learnlight/lesson-prep.d.ts +36 -0
- package/dist/learnlight/lesson-prep.js +224 -0
- package/dist/learnlight/lesson-prep.js.map +1 -0
- package/dist/learnlight/report.d.ts +2 -0
- package/dist/learnlight/report.js +37 -0
- package/dist/learnlight/report.js.map +1 -0
- package/dist/learnlight/types.d.ts +72 -0
- package/dist/learnlight/types.js +6 -0
- package/dist/learnlight/types.js.map +1 -0
- package/dist/machina/index.d.ts +16 -0
- package/dist/machina/index.js +61 -0
- package/dist/machina/index.js.map +1 -0
- package/dist/machina/render-html.d.ts +2 -0
- package/dist/machina/render-html.js +189 -0
- package/dist/machina/render-html.js.map +1 -0
- package/dist/machina/render-terminal.d.ts +2 -0
- package/dist/machina/render-terminal.js +92 -0
- package/dist/machina/render-terminal.js.map +1 -0
- package/dist/machina/spec.d.ts +61 -0
- package/dist/machina/spec.js +124 -0
- package/dist/machina/spec.js.map +1 -0
- package/dist/machina/verify.d.ts +27 -0
- package/dist/machina/verify.js +85 -0
- package/dist/machina/verify.js.map +1 -0
- package/dist/perception/graph-store.d.ts +11 -0
- package/dist/perception/graph-store.js +33 -0
- package/dist/perception/graph-store.js.map +1 -1
- package/dist/perception/index.d.ts +1 -1
- package/dist/perception/index.js +2 -1
- package/dist/perception/index.js.map +1 -1
- package/dist/providers/anthropic.js +1 -1
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/factory.d.ts +49 -0
- package/dist/providers/factory.js +99 -0
- package/dist/providers/factory.js.map +1 -1
- package/dist/providers/google.js +1 -1
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/openai-compatible.js +81 -50
- package/dist/providers/openai-compatible.js.map +1 -1
- package/dist/rem/graph.d.ts +72 -0
- package/dist/rem/graph.js +139 -0
- package/dist/rem/graph.js.map +1 -0
- package/dist/rem/index.d.ts +16 -0
- package/dist/rem/index.js +60 -0
- package/dist/rem/index.js.map +1 -0
- package/dist/rem/render-html.d.ts +2 -0
- package/dist/rem/render-html.js +189 -0
- package/dist/rem/render-html.js.map +1 -0
- package/dist/rem/render-terminal.d.ts +4 -0
- package/dist/rem/render-terminal.js +94 -0
- package/dist/rem/render-terminal.js.map +1 -0
- package/dist/research/council.d.ts +27 -0
- package/dist/research/council.js +263 -0
- package/dist/research/council.js.map +1 -0
- package/dist/research/research.d.ts +24 -0
- package/dist/research/research.js +116 -0
- package/dist/research/research.js.map +1 -0
- package/dist/ruby/alternator.d.ts +36 -1
- package/dist/ruby/alternator.js +40 -31
- package/dist/ruby/alternator.js.map +1 -1
- package/dist/ruby/stats.js +10 -11
- package/dist/ruby/stats.js.map +1 -1
- package/dist/ruby/types.js +1 -1
- package/dist/ruby/types.js.map +1 -1
- package/dist/safety/permissions.d.ts +8 -0
- package/dist/safety/permissions.js +12 -0
- package/dist/safety/permissions.js.map +1 -1
- package/dist/setup/provider-registry.js +14 -0
- package/dist/setup/provider-registry.js.map +1 -1
- package/dist/setup/provider-test.js +24 -2
- package/dist/setup/provider-test.js.map +1 -1
- package/dist/setup/telegram-wizard.d.ts +57 -0
- package/dist/setup/telegram-wizard.js +343 -0
- package/dist/setup/telegram-wizard.js.map +1 -0
- package/dist/tools/audio-transcribe.d.ts +20 -0
- package/dist/tools/audio-transcribe.js +39 -28
- package/dist/tools/audio-transcribe.js.map +1 -1
- package/dist/tools/browser.js +8 -10
- package/dist/tools/browser.js.map +1 -1
- package/dist/tools/gmail-tool.d.ts +15 -0
- package/dist/tools/gmail-tool.js +361 -0
- package/dist/tools/gmail-tool.js.map +1 -0
- package/dist/tools/read-file.js +13 -0
- package/dist/tools/read-file.js.map +1 -1
- package/dist/tools/telegram-bot.js +103 -20
- package/dist/tools/telegram-bot.js.map +1 -1
- package/dist/tools/telegram-voice.d.ts +22 -0
- package/dist/tools/telegram-voice.js +203 -0
- package/dist/tools/telegram-voice.js.map +1 -0
- package/dist/tools/telegram.d.ts +6 -1
- package/dist/tools/telegram.js +115 -5
- package/dist/tools/telegram.js.map +1 -1
- package/dist/tools/video-render.d.ts +11 -0
- package/dist/tools/video-render.js +189 -0
- package/dist/tools/video-render.js.map +1 -0
- package/dist/tools/web-search.d.ts +20 -0
- package/dist/tools/web-search.js +134 -38
- package/dist/tools/web-search.js.map +1 -1
- package/dist/util/errors.js +6 -0
- package/dist/util/errors.js.map +1 -1
- package/dist/viz/index.js +816 -30
- package/dist/viz/index.js.map +1 -1
- package/dist/viz/reader.d.ts +33 -0
- package/dist/viz/reader.js +343 -0
- package/dist/viz/reader.js.map +1 -0
- 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,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, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
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 · Rem</div>
|
|
168
|
+
<h1>Dream Relations Graph</h1>
|
|
169
|
+
<div class="meta">${esc(dateRange)} · ${graph.nights.length} night(s) · ${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 · 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 · :rem · 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,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":";;;;;AAuCA,8CA6DC;AApGD,kDAA0B;AAG1B;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,CAAC,GAAG;IACR,OAAO,EAAE,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI;IAClC,IAAI,EAAE,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC;IAC1B,KAAK,EAAE,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC;IAC3B,GAAG,EAAE,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC;IACzB,IAAI,EAAE,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC;IAC1B,IAAI,EAAE,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,QAAQ,GAAG,GAAG,CAAC;AACrB,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB,SAAS,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,KAAK,GAAG,SAAS;IACxD,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;IAC9D,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,SAAgB,iBAAiB,CAAC,KAAe,EAAE,OAAkC,EAAE;IACrF,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,KAAK,CAAC,MAAM,CAAC,MAAM,cAAc,KAAK,CAAC,OAAO,CAAC,MAAM,mBAAmB,CAAC,CAAC,CAAC;IAC3G,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,0EAA0E;IAC1E,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;IAClC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1E,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QACjE,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI;YAC/E,CAAC,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,YAAY,SAAS,QAAQ,SAAS,CAAC,CACzD,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,0EAA0E;IAC1E,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IAC9C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtC,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,GAAG;YAC1D,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,MAAM,WAAW,CAAC,CACnD,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,0EAA0E;IAC1E,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,yBAAyB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC/D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzC,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,6BAA6B,CAAC,EAAE,CAAC,CAAC;YAC5D,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;QAC1C,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACpC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAChD,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/E,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -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, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
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 · ${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 · Ecclesia · 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>;
|