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
package/dist/cli/index.js
CHANGED
|
@@ -66,6 +66,8 @@ const diamond_js_1 = require("./diamond.js");
|
|
|
66
66
|
const episode_capture_js_1 = require("../ruby/episode-capture.js");
|
|
67
67
|
const model_selector_js_1 = require("../ruby/model-selector.js");
|
|
68
68
|
const stats_js_1 = require("../ruby/stats.js");
|
|
69
|
+
const alternator_js_1 = require("../ruby/alternator.js");
|
|
70
|
+
const types_js_1 = require("../ruby/types.js");
|
|
69
71
|
const load_env_js_1 = require("../util/load-env.js");
|
|
70
72
|
const factory_js_2 = require("../providers/factory.js");
|
|
71
73
|
// Load API keys from ~/.hermes/.env, ~/.config/aura-code/.env, and project .env
|
|
@@ -783,6 +785,9 @@ async function main() {
|
|
|
783
785
|
if (!perception || (0, index_js_4.isStale)(perception)) {
|
|
784
786
|
display.agentThinking();
|
|
785
787
|
perception = await (0, index_js_4.extractPerception)(ctx.root);
|
|
788
|
+
// Persist so the viz dashboard and context summary stay populated
|
|
789
|
+
(0, index_js_4.savePerception)(perception).catch(() => { });
|
|
790
|
+
(0, index_js_4.saveGraphForViz)(perception).catch(() => { });
|
|
786
791
|
}
|
|
787
792
|
const decision = await (0, index_js_3.routeTask)({ provider, context: ctx, task, perception: perception ?? undefined });
|
|
788
793
|
if (decision.shouldDecompose && decision.confidence > 0.8) {
|
|
@@ -795,7 +800,11 @@ async function main() {
|
|
|
795
800
|
catch {
|
|
796
801
|
// Router failed — fall through to single agent
|
|
797
802
|
}
|
|
798
|
-
// ──
|
|
803
|
+
// ── Competence-based model selection ───────────────────────────────────────
|
|
804
|
+
// Picks the best-performing model among already-configured, same-family
|
|
805
|
+
// options based on task similarity to past episodes. Distinct from
|
|
806
|
+
// RubyAlternator below — this only chooses among models you've already
|
|
807
|
+
// set up; it never tries a free local model first.
|
|
799
808
|
// Only when the user has NOT explicitly specified --model or :model
|
|
800
809
|
if (!userSetModel && !globalCfg?.defaultModel) {
|
|
801
810
|
try {
|
|
@@ -818,9 +827,13 @@ async function main() {
|
|
|
818
827
|
}
|
|
819
828
|
}
|
|
820
829
|
const doVerify = cliVerify || !!fileConfig.verify;
|
|
830
|
+
const rubyConfig = { ...types_js_1.DEFAULT_RUBY_CONFIG, ...fileConfig.ruby };
|
|
821
831
|
const episodeStart = Date.now();
|
|
822
832
|
let result;
|
|
833
|
+
let alternatorHandledEpisode = false;
|
|
823
834
|
if (doVerify) {
|
|
835
|
+
// Ruby-alternation doesn't support the verification wrapper yet —
|
|
836
|
+
// a verified task always runs directly against the selected model.
|
|
824
837
|
const { runWithVerification } = await Promise.resolve().then(() => __importStar(require('../verify/index.js')));
|
|
825
838
|
const maxRetries = cliMaxVerifyRetries ?? fileConfig.maxVerifyRetries ?? defaults_js_1.DEFAULTS.maxVerifyRetries;
|
|
826
839
|
const testCommand = cliTestCommand ?? fileConfig.testCommand;
|
|
@@ -841,6 +854,20 @@ async function main() {
|
|
|
841
854
|
});
|
|
842
855
|
result = wrapperResult.loopResult;
|
|
843
856
|
}
|
|
857
|
+
else if (rubyConfig.enabled) {
|
|
858
|
+
const alternator = new alternator_js_1.RubyAlternator({
|
|
859
|
+
rubyConfig,
|
|
860
|
+
largeModelProvider: provider,
|
|
861
|
+
projectRoot: ctx.root,
|
|
862
|
+
context: ctx,
|
|
863
|
+
display,
|
|
864
|
+
permissions,
|
|
865
|
+
initialHistory: activeChatHistory,
|
|
866
|
+
});
|
|
867
|
+
const altResult = await alternator.run(task);
|
|
868
|
+
result = altResult.loopResult;
|
|
869
|
+
alternatorHandledEpisode = true; // alternator.run() already saved its own episode
|
|
870
|
+
}
|
|
844
871
|
else {
|
|
845
872
|
result = await (0, loop_js_1.runAgentLoop)({
|
|
846
873
|
provider, task, context: ctx, permissions, display,
|
|
@@ -853,26 +880,30 @@ async function main() {
|
|
|
853
880
|
sessionPath,
|
|
854
881
|
});
|
|
855
882
|
}
|
|
856
|
-
// Persist episode for Ruby Principle training data
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
883
|
+
// Persist episode for Ruby Principle training data — skip when
|
|
884
|
+
// RubyAlternator already saved its own (richer) episode above, to
|
|
885
|
+
// avoid double-counting every task in the stats/dashboard.
|
|
886
|
+
if (!alternatorHandledEpisode) {
|
|
887
|
+
try {
|
|
888
|
+
const { randomBytes } = await Promise.resolve().then(() => __importStar(require('crypto')));
|
|
889
|
+
await (0, episode_capture_js_1.saveEpisode)(ctx.root, {
|
|
890
|
+
id: randomBytes(4).toString('hex') + '-' + Date.now().toString(36),
|
|
891
|
+
timestamp: Date.now(),
|
|
892
|
+
task,
|
|
893
|
+
projectRoot: ctx.root,
|
|
894
|
+
rubyAttempted: false,
|
|
895
|
+
rubySucceeded: false,
|
|
896
|
+
largeModelUsed: runtimeConfig.model,
|
|
897
|
+
largeModelOutput: result.summary,
|
|
898
|
+
reviewerApproved: result.success,
|
|
899
|
+
tokensUsed: { largeModel: result.usage.totalTokens },
|
|
900
|
+
durationMs: Date.now() - episodeStart,
|
|
901
|
+
taskCategory: 'other',
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
catch {
|
|
905
|
+
// Episode recording is best-effort; never block the user
|
|
906
|
+
}
|
|
876
907
|
}
|
|
877
908
|
// Update history so REPL continues the conversation
|
|
878
909
|
activeChatHistory = result.history;
|
|
@@ -920,6 +951,7 @@ async function main() {
|
|
|
920
951
|
permissions, cumulative,
|
|
921
952
|
chatState: { projectRoot, activeChatId, activeChatHistory, activeChatTitle, noSession },
|
|
922
953
|
rl,
|
|
954
|
+
rubyEnabled: { ...types_js_1.DEFAULT_RUBY_CONFIG, ...fileConfig.ruby }.enabled,
|
|
923
955
|
};
|
|
924
956
|
const cmdResult = await handleReplCommand(input, replCtx);
|
|
925
957
|
if (cmdResult.handled) {
|
|
@@ -930,11 +962,19 @@ async function main() {
|
|
|
930
962
|
activeChatHistory = cmdResult.newHistory;
|
|
931
963
|
if (cmdResult.newTitle !== undefined)
|
|
932
964
|
activeChatTitle = cmdResult.newTitle;
|
|
965
|
+
// :ruby on/off persists by mutating the loaded config the gate reads.
|
|
966
|
+
if (cmdResult.rubyEnabled !== undefined) {
|
|
967
|
+
fileConfig.ruby = { ...fileConfig.ruby, enabled: cmdResult.rubyEnabled };
|
|
968
|
+
}
|
|
933
969
|
ask();
|
|
934
970
|
return;
|
|
935
971
|
}
|
|
936
972
|
// Run task — pass current conversation history for stay-active mode
|
|
937
|
-
// ──
|
|
973
|
+
// ── Competence-based model selection ───────────────────────────────
|
|
974
|
+
// Picks the best-performing model among already-configured, same-family
|
|
975
|
+
// options based on task similarity to past episodes. Distinct from
|
|
976
|
+
// RubyAlternator below — this only chooses among models you've already
|
|
977
|
+
// set up; it never tries a free local model first.
|
|
938
978
|
// Only when the user has NOT set a model explicitly via --model or :model
|
|
939
979
|
if (!userSetModel && !globalCfg?.defaultModel) {
|
|
940
980
|
try {
|
|
@@ -957,8 +997,16 @@ async function main() {
|
|
|
957
997
|
let result;
|
|
958
998
|
try {
|
|
959
999
|
const currentProvider = buildProvider(display);
|
|
1000
|
+
const replConfirmFn = async (msg) => new Promise(res => {
|
|
1001
|
+
rl.question(`\n⚠️ ${msg} [y/N] `, a => {
|
|
1002
|
+
res(a.trim().toLowerCase() === 'y' || a.trim().toLowerCase() === 'yes');
|
|
1003
|
+
});
|
|
1004
|
+
});
|
|
960
1005
|
const doVerify = argv.verify === true || !!fileConfig.verify;
|
|
1006
|
+
const rubyConfig = { ...types_js_1.DEFAULT_RUBY_CONFIG, ...fileConfig.ruby };
|
|
961
1007
|
if (doVerify) {
|
|
1008
|
+
// Ruby-alternation doesn't support the verification wrapper yet —
|
|
1009
|
+
// a verified task always runs directly against the selected model.
|
|
962
1010
|
const { runWithVerification } = await Promise.resolve().then(() => __importStar(require('../verify/index.js')));
|
|
963
1011
|
const maxRetries = cliMaxVerifyRetries ?? fileConfig.maxVerifyRetries ?? defaults_js_1.DEFAULTS.maxVerifyRetries;
|
|
964
1012
|
const testCommand = cliTestCommand ?? fileConfig.testCommand;
|
|
@@ -968,11 +1016,7 @@ async function main() {
|
|
|
968
1016
|
context: ctx, permissions, display,
|
|
969
1017
|
initialHistory: activeChatHistory,
|
|
970
1018
|
maxTurns: resolved.maxTurns,
|
|
971
|
-
confirmFn:
|
|
972
|
-
rl.question(`\\n⚠️ ${msg} [y/N] `, a => {
|
|
973
|
-
res(a.trim().toLowerCase() === 'y' || a.trim().toLowerCase() === 'yes');
|
|
974
|
-
});
|
|
975
|
-
}),
|
|
1019
|
+
confirmFn: replConfirmFn,
|
|
976
1020
|
spawnConfig: {
|
|
977
1021
|
apiKey: runtimeConfig.apiKey,
|
|
978
1022
|
baseUrl: runtimeConfig.baseUrl ?? undefined,
|
|
@@ -985,17 +1029,27 @@ async function main() {
|
|
|
985
1029
|
});
|
|
986
1030
|
result = wrapperResult.loopResult;
|
|
987
1031
|
}
|
|
1032
|
+
else if (rubyConfig.enabled) {
|
|
1033
|
+
const alternator = new alternator_js_1.RubyAlternator({
|
|
1034
|
+
rubyConfig,
|
|
1035
|
+
largeModelProvider: currentProvider,
|
|
1036
|
+
projectRoot: ctx.root,
|
|
1037
|
+
context: ctx,
|
|
1038
|
+
display,
|
|
1039
|
+
permissions,
|
|
1040
|
+
confirmFn: replConfirmFn,
|
|
1041
|
+
initialHistory: activeChatHistory,
|
|
1042
|
+
});
|
|
1043
|
+
const altResult = await alternator.run(input);
|
|
1044
|
+
result = altResult.loopResult;
|
|
1045
|
+
}
|
|
988
1046
|
else {
|
|
989
1047
|
result = await (0, loop_js_1.runAgentLoop)({
|
|
990
1048
|
provider: currentProvider, task: input,
|
|
991
1049
|
context: ctx, permissions, display,
|
|
992
1050
|
initialHistory: activeChatHistory,
|
|
993
1051
|
maxTurns: resolved.maxTurns,
|
|
994
|
-
confirmFn:
|
|
995
|
-
rl.question(`\\n⚠️ ${msg} [y/N] `, a => {
|
|
996
|
-
res(a.trim().toLowerCase() === 'y' || a.trim().toLowerCase() === 'yes');
|
|
997
|
-
});
|
|
998
|
-
}),
|
|
1052
|
+
confirmFn: replConfirmFn,
|
|
999
1053
|
spawnConfig: {
|
|
1000
1054
|
apiKey: runtimeConfig.apiKey,
|
|
1001
1055
|
baseUrl: runtimeConfig.baseUrl ?? undefined,
|
|
@@ -1165,15 +1219,30 @@ async function handleReplCommand(input, c) {
|
|
|
1165
1219
|
' ── Context / Stats ──────────────────────────────',
|
|
1166
1220
|
' :context Show loaded project context',
|
|
1167
1221
|
' :graph Show codebase knowledge graph summary',
|
|
1168
|
-
' :graph refresh
|
|
1222
|
+
' :graph refresh Extract + persist codebase graph',
|
|
1223
|
+
' :stats Show episode-level stats (completion rate, models, tokens)',
|
|
1169
1224
|
' :plans List saved execution plans',
|
|
1170
1225
|
' :viz, :dashboard Generate and open the memory dashboard',
|
|
1171
|
-
'
|
|
1226
|
+
' :dream [experimental] Consolidate today\'s episodes into a dated dream (dreams/*.md)',
|
|
1227
|
+
' :dream full [experimental] Consolidate ALL episodes, ignoring the last-dream cutoff',
|
|
1228
|
+
' :rem [experimental] List dream files and open the most recent one',
|
|
1229
|
+
' :research <topic> Multi-step research pass, saved to research/*.md (inspired by DeerFlow)',
|
|
1230
|
+
' :council <topic> Ecclesia — 5 independent agents research the topic, synthesized into one verdict (council/*.md)',
|
|
1231
|
+
' :ruby [on|off] Toggle the Ruby Principle (default: off)',
|
|
1232
|
+
' ⚠ :machina The Abstract Agent Machine — formal model, verified against this source tree',
|
|
1233
|
+
' ⚠ :machina --html Also write the full writeup + diagram to docs/machina.html',
|
|
1234
|
+
' :design [slug|list|off] Set/list the design system auto-applied to UI builds',
|
|
1235
|
+
' /stats, /usage, :usage Show token + cost usage this session',
|
|
1172
1236
|
' /clear, /reset Reset cumulative usage stats',
|
|
1173
1237
|
'',
|
|
1174
1238
|
' ── General ──────────────────────────────────────',
|
|
1239
|
+
' :approve all Auto-approve all tool calls (no confirmations)',
|
|
1240
|
+
' :approve normal Require confirmation for destructive ops',
|
|
1241
|
+
' :approve read-only Block all write operations',
|
|
1175
1242
|
' :quit, :q, /exit Exit',
|
|
1176
1243
|
'',
|
|
1244
|
+
' ⚠ = extremely high token usage — reads multiple source files and writes a careful long-form result',
|
|
1245
|
+
'',
|
|
1177
1246
|
].join('\n')));
|
|
1178
1247
|
return { handled: true };
|
|
1179
1248
|
}
|
|
@@ -1301,6 +1370,180 @@ async function handleReplCommand(input, c) {
|
|
|
1301
1370
|
}
|
|
1302
1371
|
return { handled: true };
|
|
1303
1372
|
}
|
|
1373
|
+
if (input === ':dream' || input === ':dream full') {
|
|
1374
|
+
const full = input === ':dream full';
|
|
1375
|
+
console.log(chalk_1.default.hex('#8a7768')('\n Dreaming — consolidating episodes…\n'));
|
|
1376
|
+
try {
|
|
1377
|
+
const { runDream } = await Promise.resolve().then(() => __importStar(require('../dream/dream.js')));
|
|
1378
|
+
const { createResilientProvider } = await Promise.resolve().then(() => __importStar(require('../providers/resilient-factory.js')));
|
|
1379
|
+
const provider = createResilientProvider({ model: c.providerConfig.model, apiKey: c.providerConfig.apiKey, baseUrl: c.providerConfig.baseUrl }, {}, c.display);
|
|
1380
|
+
const res = await runDream({ projectRoot: c.ctx.root, provider, full });
|
|
1381
|
+
if (res.skipped) {
|
|
1382
|
+
console.log(chalk_1.default.hex('#cc9e5c')(` ⤳ Nothing to dream about — ${res.reason}.\n`));
|
|
1383
|
+
}
|
|
1384
|
+
else {
|
|
1385
|
+
console.log(chalk_1.default.hex('#5a9e6e')(` ✓ Dream written: ${res.path}`));
|
|
1386
|
+
console.log(chalk_1.default.hex('#8a7768')(` Consolidated ${res.episodeCount} episode(s).\n`));
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
catch (e) {
|
|
1390
|
+
console.log(chalk_1.default.hex('#b15439')(` ✗ ${String(e)}\n`));
|
|
1391
|
+
}
|
|
1392
|
+
return { handled: true };
|
|
1393
|
+
}
|
|
1394
|
+
if (input.startsWith(':research ')) {
|
|
1395
|
+
const topic = input.slice(':research '.length).trim();
|
|
1396
|
+
if (!topic) {
|
|
1397
|
+
console.log(chalk_1.default.hex('#b15439')('\n Usage: :research <topic>\n'));
|
|
1398
|
+
return { handled: true };
|
|
1399
|
+
}
|
|
1400
|
+
console.log(chalk_1.default.hex('#8a7768')(`\n Researching "${topic}"…\n`));
|
|
1401
|
+
try {
|
|
1402
|
+
const { runResearch } = await Promise.resolve().then(() => __importStar(require('../research/research.js')));
|
|
1403
|
+
const { createResilientProvider } = await Promise.resolve().then(() => __importStar(require('../providers/resilient-factory.js')));
|
|
1404
|
+
const provider = createResilientProvider({ model: c.providerConfig.model, apiKey: c.providerConfig.apiKey, baseUrl: c.providerConfig.baseUrl }, {}, c.display);
|
|
1405
|
+
const res = await runResearch({
|
|
1406
|
+
projectRoot: c.ctx.root,
|
|
1407
|
+
topic,
|
|
1408
|
+
provider,
|
|
1409
|
+
context: c.ctx,
|
|
1410
|
+
permissions: c.permissions,
|
|
1411
|
+
display: c.display,
|
|
1412
|
+
});
|
|
1413
|
+
console.log(chalk_1.default.hex('#5a9e6e')(` ✓ Research written: ${res.path}`));
|
|
1414
|
+
console.log(chalk_1.default.hex('#8a7768')(` ${res.turns} turn(s) · ${res.toolCalls} tool call(s).\n`));
|
|
1415
|
+
}
|
|
1416
|
+
catch (e) {
|
|
1417
|
+
console.log(chalk_1.default.hex('#b15439')(` ✗ ${String(e)}\n`));
|
|
1418
|
+
}
|
|
1419
|
+
return { handled: true };
|
|
1420
|
+
}
|
|
1421
|
+
if (input.startsWith(':council ')) {
|
|
1422
|
+
let rest = input.slice(':council '.length).trim();
|
|
1423
|
+
const wantsReader = /(^|\s)--reader(\s|$)/.test(rest);
|
|
1424
|
+
rest = rest.replace(/(^|\s)--reader(\s|$)/g, ' ').trim();
|
|
1425
|
+
const stray = rest.match(/(^|\s)(--\S+)/);
|
|
1426
|
+
if (stray) {
|
|
1427
|
+
console.log(chalk_1.default.hex('#b15439')(`\n ✗ Unknown flag: ${stray[2]}. Did you mean --reader?\n`));
|
|
1428
|
+
return { handled: true };
|
|
1429
|
+
}
|
|
1430
|
+
const topic = rest;
|
|
1431
|
+
if (!topic) {
|
|
1432
|
+
console.log(chalk_1.default.hex('#b15439')('\n Usage: :council <topic> [--reader]\n'));
|
|
1433
|
+
return { handled: true };
|
|
1434
|
+
}
|
|
1435
|
+
console.log(chalk_1.default.hex('#8a7768')(`\n Convening Ecclesia on "${topic}" — 5 independent agents…\n`));
|
|
1436
|
+
try {
|
|
1437
|
+
const { runCouncil } = await Promise.resolve().then(() => __importStar(require('../research/council.js')));
|
|
1438
|
+
const { createResilientProvider } = await Promise.resolve().then(() => __importStar(require('../providers/resilient-factory.js')));
|
|
1439
|
+
const synthesisProvider = createResilientProvider({ model: c.providerConfig.model, apiKey: c.providerConfig.apiKey, baseUrl: c.providerConfig.baseUrl }, {}, c.display);
|
|
1440
|
+
const res = await runCouncil({
|
|
1441
|
+
projectRoot: c.ctx.root,
|
|
1442
|
+
topic,
|
|
1443
|
+
synthesisProvider,
|
|
1444
|
+
context: c.ctx,
|
|
1445
|
+
permissions: c.permissions,
|
|
1446
|
+
display: c.display,
|
|
1447
|
+
});
|
|
1448
|
+
console.log(chalk_1.default.hex('#5a9e6e')(` ✓ Ecclesia verdict: ${res.path}`));
|
|
1449
|
+
console.log(chalk_1.default.hex('#8a7768')(` ${res.panelSize} agents` + (res.agentFailures > 0 ? `, ${res.agentFailures} failed` : '') + `.\n`));
|
|
1450
|
+
if (wantsReader) {
|
|
1451
|
+
const { renderReaderFromMarkdown } = await Promise.resolve().then(() => __importStar(require('../viz/reader.js')));
|
|
1452
|
+
const readerPath = renderReaderFromMarkdown(res.path);
|
|
1453
|
+
console.log(chalk_1.default.hex('#5a9e6e')(` ✓ Reader: ${readerPath}`));
|
|
1454
|
+
console.log(chalk_1.default.hex('#8a7768')(' Opening in browser…\n'));
|
|
1455
|
+
(0, index_js_1.openDashboard)(readerPath);
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
catch (e) {
|
|
1459
|
+
console.log(chalk_1.default.hex('#b15439')(` ✗ ${String(e)}\n`));
|
|
1460
|
+
}
|
|
1461
|
+
return { handled: true };
|
|
1462
|
+
}
|
|
1463
|
+
if (input === ':rem') {
|
|
1464
|
+
const dir = path.join(c.ctx.root, 'dreams');
|
|
1465
|
+
let files = [];
|
|
1466
|
+
try {
|
|
1467
|
+
files = fs.readdirSync(dir).filter(f => f.endsWith('.md') && !f.startsWith('.')).sort().reverse();
|
|
1468
|
+
}
|
|
1469
|
+
catch { /* no dreams dir */ }
|
|
1470
|
+
if (files.length === 0) {
|
|
1471
|
+
console.log(chalk_1.default.hex('#8a7768')('\n No dreams yet. Run :dream after some work.\n'));
|
|
1472
|
+
}
|
|
1473
|
+
else {
|
|
1474
|
+
console.log(chalk_1.default.hex('#cc785c').bold('\n Dreams\n'));
|
|
1475
|
+
for (const f of files.slice(0, 20))
|
|
1476
|
+
console.log(chalk_1.default.hex('#ede0cc')(` ${f}`));
|
|
1477
|
+
// Prefer reconciled view if it exists
|
|
1478
|
+
const reconciledPath = path.join(dir, '.reconciled.md');
|
|
1479
|
+
const hasReconciled = fs.existsSync(reconciledPath);
|
|
1480
|
+
if (hasReconciled) {
|
|
1481
|
+
console.log(chalk_1.default.hex('#5a9e6e')(`\n ✓ Reconciled memory (${files.length} dreams → projection):\n`));
|
|
1482
|
+
console.log(chalk_1.default.hex('#ede0cc')(fs.readFileSync(reconciledPath, 'utf8')));
|
|
1483
|
+
}
|
|
1484
|
+
else {
|
|
1485
|
+
const latest = path.join(dir, files[0]);
|
|
1486
|
+
console.log(chalk_1.default.hex('#8a7768')(`\n Most recent: ${latest}\n`));
|
|
1487
|
+
console.log(chalk_1.default.hex('#4e3d30')(fs.readFileSync(latest, 'utf8')));
|
|
1488
|
+
if (files.length >= 3) {
|
|
1489
|
+
console.log(chalk_1.default.hex('#8a7768')(' 💡 Run :dream to trigger memory reconciliation (≥3 dreams).\n'));
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
return { handled: true };
|
|
1494
|
+
}
|
|
1495
|
+
if (input === ':ruby' || input === ':ruby on' || input === ':ruby off') {
|
|
1496
|
+
if (input === ':ruby') {
|
|
1497
|
+
const state = c.rubyEnabled ? chalk_1.default.hex('#5a9e6e')('ON') : chalk_1.default.hex('#b15439')('OFF');
|
|
1498
|
+
console.log(chalk_1.default.hex('#8a7768')(`\n Ruby Principle is ${state}. Use :ruby on / :ruby off to change.\n`));
|
|
1499
|
+
return { handled: true };
|
|
1500
|
+
}
|
|
1501
|
+
const on = input === ':ruby on';
|
|
1502
|
+
c.rubyEnabled = on;
|
|
1503
|
+
const state = on ? chalk_1.default.hex('#5a9e6e')('ON') : chalk_1.default.hex('#b15439')('OFF');
|
|
1504
|
+
console.log(chalk_1.default.hex('#8a7768')(`\n Ruby Principle is now ${state} for this session.\n`));
|
|
1505
|
+
return { handled: true, rubyEnabled: on };
|
|
1506
|
+
}
|
|
1507
|
+
if (input === ':machina' || input === ':machina --html' || input === ':machina -html') {
|
|
1508
|
+
const wantsHtml = input !== ':machina';
|
|
1509
|
+
console.log(chalk_1.default.hex('#b15439')('\n ⚠ :machina reads several source files and writes a careful long-form result — extremely high token usage.\n'));
|
|
1510
|
+
const { runMachina } = await Promise.resolve().then(() => __importStar(require('../machina/index.js')));
|
|
1511
|
+
const res = runMachina({ outputRoot: c.ctx.root, writeHtml: wantsHtml });
|
|
1512
|
+
console.log(res.terminalOutput);
|
|
1513
|
+
if (res.htmlPath) {
|
|
1514
|
+
console.log(chalk_1.default.hex('#5a9e6e')(` ✓ Written: ${res.htmlPath}\n`));
|
|
1515
|
+
}
|
|
1516
|
+
return { handled: true };
|
|
1517
|
+
}
|
|
1518
|
+
if (input === ':design' || input.startsWith(':design ')) {
|
|
1519
|
+
const { listDesignSlugs } = await Promise.resolve().then(() => __importStar(require('../agent/design.js')));
|
|
1520
|
+
const slugs = listDesignSlugs(c.ctx.root);
|
|
1521
|
+
const arg = input.slice(':design'.length).trim();
|
|
1522
|
+
if (slugs.length === 0) {
|
|
1523
|
+
console.log(chalk_1.default.hex('#b15439')('\n No design-systems/ folder found in this project.\n'));
|
|
1524
|
+
return { handled: true };
|
|
1525
|
+
}
|
|
1526
|
+
if (arg === '' || arg === 'list') {
|
|
1527
|
+
const current = process.env.AURA_DESIGN || 'terracotta';
|
|
1528
|
+
console.log(chalk_1.default.hex('#cc785c').bold(`\n Design systems (${slugs.length}) — default: ${current}\n`));
|
|
1529
|
+
console.log(chalk_1.default.hex('#ede0cc')(' ' + slugs.join(' ')));
|
|
1530
|
+
console.log(chalk_1.default.hex('#8a7768')('\n :design <slug> sets the default · auto-applies on website/UI tasks.\n'));
|
|
1531
|
+
return { handled: true };
|
|
1532
|
+
}
|
|
1533
|
+
if (arg === 'off') {
|
|
1534
|
+
process.env.AURA_DESIGN = '__none__';
|
|
1535
|
+
console.log(chalk_1.default.hex('#8a7768')('\n Design auto-injection disabled for this session.\n'));
|
|
1536
|
+
return { handled: true };
|
|
1537
|
+
}
|
|
1538
|
+
if (slugs.includes(arg)) {
|
|
1539
|
+
process.env.AURA_DESIGN = arg;
|
|
1540
|
+
console.log(chalk_1.default.hex('#5a9e6e')(`\n Default design set to "${arg}" for this session.\n`));
|
|
1541
|
+
}
|
|
1542
|
+
else {
|
|
1543
|
+
console.log(chalk_1.default.hex('#b15439')(`\n Unknown design "${arg}". Run :design to list available slugs.\n`));
|
|
1544
|
+
}
|
|
1545
|
+
return { handled: true };
|
|
1546
|
+
}
|
|
1304
1547
|
if (input === ':plans') {
|
|
1305
1548
|
const { planStore } = await Promise.resolve().then(() => __importStar(require('../orchestration/plan-store.js')));
|
|
1306
1549
|
const plans = await planStore.list();
|
|
@@ -1323,24 +1566,25 @@ async function handleReplCommand(input, c) {
|
|
|
1323
1566
|
return { handled: true };
|
|
1324
1567
|
}
|
|
1325
1568
|
if (input === ':graph refresh') {
|
|
1326
|
-
console.log(chalk_1.default.hex('#8a7768')('\n
|
|
1327
|
-
const { execFileSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
|
|
1569
|
+
console.log(chalk_1.default.hex('#8a7768')('\n Extracting codebase graph...\n'));
|
|
1328
1570
|
try {
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
}
|
|
1336
|
-
catch {
|
|
1571
|
+
const perception = await (0, index_js_4.extractPerception)(c.ctx.root);
|
|
1572
|
+
await (0, index_js_4.savePerception)(perception);
|
|
1573
|
+
await (0, index_js_4.saveGraphForViz)(perception);
|
|
1574
|
+
const nodeCount = perception.nodes.length;
|
|
1575
|
+
const edgeCount = perception.edges.length;
|
|
1576
|
+
console.log(chalk_1.default.hex('#5a9e6e')(` ✓ Extracted ${nodeCount} nodes, ${edgeCount} edges.\n`));
|
|
1577
|
+
}
|
|
1578
|
+
catch (err) {
|
|
1579
|
+
console.log(chalk_1.default.hex('#f85149')(` ✗ Extraction failed: ${err instanceof Error ? err.message : String(err)}\n`));
|
|
1580
|
+
}
|
|
1337
1581
|
// Reload context graph
|
|
1338
1582
|
c.ctx.graphSummary = (0, context_js_1.loadGraphSummary)(c.ctx.root);
|
|
1339
1583
|
if (c.ctx.graphSummary) {
|
|
1340
1584
|
console.log(chalk_1.default.hex('#5a9e6e')(' ✓ Graph loaded and injected into context.\n'));
|
|
1341
1585
|
}
|
|
1342
1586
|
else {
|
|
1343
|
-
console.log(chalk_1.default.hex('#8a7768')(' No graph.json found after refresh
|
|
1587
|
+
console.log(chalk_1.default.hex('#8a7768')(' No graph.json found after refresh.\n'));
|
|
1344
1588
|
}
|
|
1345
1589
|
return { handled: true };
|
|
1346
1590
|
}
|
|
@@ -1406,7 +1650,39 @@ async function handleReplCommand(input, c) {
|
|
|
1406
1650
|
console.log(chalk_1.default.hex('#5a9e6e')(' ✓ Session stats reset'));
|
|
1407
1651
|
return { handled: true };
|
|
1408
1652
|
}
|
|
1409
|
-
|
|
1653
|
+
// ── Permission commands ──────────────────────────────────────────────────
|
|
1654
|
+
if (input.startsWith(':approve ')) {
|
|
1655
|
+
const raw = input.slice(':approve '.length).trim();
|
|
1656
|
+
const mapped = raw === 'all' ? 'auto' : raw;
|
|
1657
|
+
if (mapped !== 'auto' && mapped !== 'normal' && mapped !== 'read-only') {
|
|
1658
|
+
console.log(chalk_1.default.hex('#b15439')(' ✗ Usage: :approve all | :approve normal | :approve read-only'));
|
|
1659
|
+
return { handled: true };
|
|
1660
|
+
}
|
|
1661
|
+
c.permissions.setLevel(mapped);
|
|
1662
|
+
console.log(chalk_1.default.hex('#5a9e6e')(` ✓ Permission level set to ${mapped}`));
|
|
1663
|
+
return { handled: true };
|
|
1664
|
+
}
|
|
1665
|
+
if (input === ':stats') {
|
|
1666
|
+
// Episode-level stats (same as --stats CLI flag)
|
|
1667
|
+
const episodes = await (0, episode_capture_js_1.loadEpisodes)(c.chatState.projectRoot);
|
|
1668
|
+
const output = (0, stats_js_1.formatStats)(episodes);
|
|
1669
|
+
for (const line of output.split('\n')) {
|
|
1670
|
+
if (line.trim() === 'Aura Stats') {
|
|
1671
|
+
console.log(chalk_1.default.hex('#cc785c').bold(line));
|
|
1672
|
+
}
|
|
1673
|
+
else if (line.includes(':')) {
|
|
1674
|
+
const colonIdx = line.indexOf(':');
|
|
1675
|
+
const label = line.slice(0, colonIdx + 1);
|
|
1676
|
+
const value = line.slice(colonIdx + 1);
|
|
1677
|
+
console.log(chalk_1.default.hex('#8a7768')(label) + chalk_1.default.hex('#ede0cc')(value));
|
|
1678
|
+
}
|
|
1679
|
+
else {
|
|
1680
|
+
console.log(line);
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
return { handled: true };
|
|
1684
|
+
}
|
|
1685
|
+
if (input === '/stats' || input === '/usage' || input === ':usage') {
|
|
1410
1686
|
const u = c.cumulative;
|
|
1411
1687
|
const total = u.inputTokens + u.outputTokens;
|
|
1412
1688
|
console.log(chalk_1.default.hex('#8a7768')([
|
|
@@ -1790,6 +2066,7 @@ ${chalk_1.default.hex('#cc785c').bold(' aura')} ${chalk_1.default.hex('#8a7768'
|
|
|
1790
2066
|
--test-command <cmd> Shell command run as part of verification (e.g. "npm test")
|
|
1791
2067
|
--max-turns <n> Max agent loop turns before stopping (default: 150)
|
|
1792
2068
|
--analyze Mine session history for weakness patterns; save report
|
|
2069
|
+
--stats Show episode stats — completion rate, avg duration, top model, tokens
|
|
1793
2070
|
--propose-harness Generate system-prompt patches from weakness report
|
|
1794
2071
|
--apply-harness <id> Apply a proposal patch; reverts if tests fail
|
|
1795
2072
|
--workflow <name> ... Create and run a sequential workflow with named steps
|