hippo-memory 0.24.1 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -36
- package/dist/audit.d.ts +17 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +107 -0
- package/dist/audit.js.map +1 -0
- package/dist/capture.d.ts.map +1 -1
- package/dist/capture.js +7 -4
- package/dist/capture.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +136 -30
- package/dist/cli.js.map +1 -1
- package/dist/consolidate.d.ts.map +1 -1
- package/dist/consolidate.js +75 -13
- package/dist/consolidate.js.map +1 -1
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/dashboard.js +102 -3
- package/dist/dashboard.js.map +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +12 -1
- package/dist/db.js.map +1 -1
- package/dist/memory.d.ts +2 -0
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +6 -0
- package/dist/memory.js.map +1 -1
- package/dist/scheduler.d.ts +14 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +67 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +14 -4
- package/dist/store.js.map +1 -1
- package/dist-ui/assets/index-CxxqB9Wc.js +4308 -0
- package/dist-ui/index.html +52 -0
- package/extensions/openclaw-plugin/README.md +18 -1
- package/extensions/openclaw-plugin/index.ts +46 -22
- package/extensions/openclaw-plugin/openclaw.plugin.json +2 -2
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +2 -2
- package/package.json +5 -2
package/dist/cli.js
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* hippo embed [--status]
|
|
20
20
|
* hippo watch "<command>"
|
|
21
21
|
* hippo learn --git [--days <n>] [--repos <paths>]
|
|
22
|
+
* hippo daily-runner
|
|
22
23
|
* hippo promote <id>
|
|
23
24
|
* hippo sync
|
|
24
25
|
* hippo decide "<decision>" [--context "<why>"] [--supersedes <id>]
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
import * as path from 'path';
|
|
28
29
|
import * as fs from 'fs';
|
|
29
30
|
import * as os from 'os';
|
|
30
|
-
import { execSync, spawn } from 'child_process';
|
|
31
|
+
import { execFileSync, execSync, spawn } from 'child_process';
|
|
31
32
|
import { installJsonHooks, uninstallJsonHooks, resolveJsonHookPaths, detectInstalledTools, defaultSleepLogPath, ensureCodexWrapperInstalled, installCodexWrapper, uninstallCodexWrapper, resolveCodexSessionTranscript, resolveCodexWrapperPaths, } from './hooks.js';
|
|
32
33
|
import { createMemory, calculateStrength, calculateRewardFactor, deriveHalfLife, resolveConfidence, applyOutcome, computeSchemaFit, Layer, DECISION_HALF_LIFE_DAYS, } from './memory.js';
|
|
33
34
|
import { getHippoRoot, isInitialized, initStore, writeEntry, readEntry, deleteEntry, loadAllEntries, loadSearchEntries, loadIndex, saveIndex, loadStats, updateStats, saveActiveTaskSnapshot, loadActiveTaskSnapshot, clearActiveTaskSnapshot, appendSessionEvent, listSessionEvents, listMemoryConflicts, resolveConflict, saveSessionHandoff, loadLatestHandoff, loadHandoffById, } from './store.js';
|
|
@@ -42,8 +43,10 @@ import { captureError, extractLessons, deduplicateLesson, runWatched, fetchGitLo
|
|
|
42
43
|
import { extractInvalidationTarget, invalidateMatching } from './invalidation.js';
|
|
43
44
|
import { extractPathTags } from './path-context.js';
|
|
44
45
|
import { getGlobalRoot, initGlobal, promoteToGlobal, shareMemory, listPeers, autoShare, transferScore, searchBothHybrid, syncGlobalToLocal, } from './shared.js';
|
|
46
|
+
import { DAILY_TASK_NAME, buildDailyRunnerCommand, listRegisteredWorkspaces, registerWorkspace, runDailyMaintenance, } from './scheduler.js';
|
|
45
47
|
import { importChatGPT, importClaude, importCursor, importGenericFile, importMarkdown, } from './importers.js';
|
|
46
48
|
import { cmdCapture } from './capture.js';
|
|
49
|
+
import { auditMemories } from './audit.js';
|
|
47
50
|
import { wmPush, wmRead, wmClear, wmFlush } from './working-memory.js';
|
|
48
51
|
// ---------------------------------------------------------------------------
|
|
49
52
|
// Helpers
|
|
@@ -160,6 +163,7 @@ function cmdInitScan(scanDir, flags) {
|
|
|
160
163
|
if (!alreadyExists) {
|
|
161
164
|
initStore(repoHippo);
|
|
162
165
|
}
|
|
166
|
+
registerWorkspace(globalRoot, repo);
|
|
163
167
|
// Learn from git history
|
|
164
168
|
let added = 0;
|
|
165
169
|
if (!flags['no-learn'] && isGitRepo(repo)) {
|
|
@@ -173,6 +177,9 @@ function cmdInitScan(scanDir, flags) {
|
|
|
173
177
|
}
|
|
174
178
|
console.log(`\n${repos.length} repositories, ${totalLessons} new lessons learned.`);
|
|
175
179
|
console.log(`Global store: ${globalRoot}`);
|
|
180
|
+
if (!flags['no-schedule']) {
|
|
181
|
+
setupDailySchedule(globalRoot);
|
|
182
|
+
}
|
|
176
183
|
console.log(`\nRun \`hippo sleep\` in any project to consolidate and auto-share to global.`);
|
|
177
184
|
}
|
|
178
185
|
function cmdInit(hippoRoot, flags) {
|
|
@@ -202,13 +209,15 @@ function cmdInit(hippoRoot, flags) {
|
|
|
202
209
|
console.log(' Directories: buffer/ episodic/ semantic/ conflicts/');
|
|
203
210
|
console.log(' Files: hippo.db index.json stats.json');
|
|
204
211
|
}
|
|
212
|
+
const globalRoot = getGlobalRoot();
|
|
213
|
+
registerWorkspace(globalRoot, path.dirname(hippoRoot));
|
|
205
214
|
// Auto-detect and install hooks (unless --no-hooks)
|
|
206
215
|
if (!flags['no-hooks']) {
|
|
207
216
|
autoInstallHooks(alreadyExists);
|
|
208
217
|
}
|
|
209
218
|
// Auto-setup daily schedule (unless --no-schedule)
|
|
210
219
|
if (!flags['no-schedule'] && !flags['global']) {
|
|
211
|
-
setupDailySchedule(
|
|
220
|
+
setupDailySchedule(globalRoot);
|
|
212
221
|
}
|
|
213
222
|
// Seed with git history on first init (unless --no-learn)
|
|
214
223
|
if (!alreadyExists && !flags['no-learn'] && !flags['global']) {
|
|
@@ -301,22 +310,24 @@ function autoInstallHooks(quiet) {
|
|
|
301
310
|
}
|
|
302
311
|
}
|
|
303
312
|
/**
|
|
304
|
-
* Set up a daily
|
|
313
|
+
* Set up a machine-level daily runner that sweeps all registered Hippo
|
|
314
|
+
* workspaces.
|
|
305
315
|
* Linux/macOS: writes to user crontab.
|
|
306
316
|
* Windows: creates a scheduled task.
|
|
307
317
|
* Skips if already installed.
|
|
308
318
|
*/
|
|
309
|
-
function setupDailySchedule(
|
|
310
|
-
const
|
|
319
|
+
function setupDailySchedule(globalRoot) {
|
|
320
|
+
const runnerDir = path.resolve(globalRoot);
|
|
311
321
|
// Reject paths with characters that could break shell/crontab quoting
|
|
312
322
|
// (backslash is normal on Windows, only dangerous in Unix shell/crontab)
|
|
313
323
|
const unsafeChars = process.platform === 'win32' ? /["`$%\n\r]/ : /["`$\n\r\\]/;
|
|
314
|
-
if (unsafeChars.test(
|
|
315
|
-
console.log(` Skipping schedule:
|
|
324
|
+
if (unsafeChars.test(runnerDir)) {
|
|
325
|
+
console.log(` Skipping schedule: runner path contains unsafe characters.`);
|
|
316
326
|
return;
|
|
317
327
|
}
|
|
318
328
|
const isWindows = process.platform === 'win32';
|
|
319
|
-
const taskName =
|
|
329
|
+
const taskName = DAILY_TASK_NAME;
|
|
330
|
+
const cmd = buildDailyRunnerCommand(runnerDir);
|
|
320
331
|
if (isWindows) {
|
|
321
332
|
// Check if task already exists
|
|
322
333
|
try {
|
|
@@ -328,14 +339,13 @@ function setupDailySchedule(hippoRoot) {
|
|
|
328
339
|
catch {
|
|
329
340
|
// Task doesn't exist, create it
|
|
330
341
|
}
|
|
331
|
-
const cmd = `cd /d "${projectDir}" && hippo learn --git --days 1 && hippo sleep`;
|
|
332
342
|
try {
|
|
333
343
|
execSync(`schtasks /create /tn "${taskName}" /tr "cmd /c ${cmd.replace(/"/g, '""')}" /sc daily /st 06:15 /f`, { stdio: 'pipe' });
|
|
334
|
-
console.log(` Scheduled daily
|
|
344
|
+
console.log(` Scheduled machine-level daily runner (6:15am) via Task Scheduler: ${taskName}`);
|
|
335
345
|
}
|
|
336
346
|
catch {
|
|
337
347
|
// No admin rights or schtasks unavailable, fall back to printing instructions
|
|
338
|
-
console.log(` To schedule daily
|
|
348
|
+
console.log(` To schedule the machine-level daily runner, run:`);
|
|
339
349
|
console.log(` schtasks /create /tn "${taskName}" /tr "cmd /c ${cmd}" /sc daily /st 06:15`);
|
|
340
350
|
}
|
|
341
351
|
}
|
|
@@ -347,14 +357,14 @@ function setupDailySchedule(hippoRoot) {
|
|
|
347
357
|
if (existing.includes(marker)) {
|
|
348
358
|
return; // already scheduled
|
|
349
359
|
}
|
|
350
|
-
const cronLine = `15 6 * * *
|
|
360
|
+
const cronLine = `15 6 * * * ${cmd} ${marker}`;
|
|
351
361
|
const newCrontab = existing.trimEnd() + '\n' + cronLine + '\n';
|
|
352
362
|
execSync('crontab -', { input: newCrontab, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
353
|
-
console.log(` Scheduled daily
|
|
363
|
+
console.log(` Scheduled machine-level daily runner (6:15am) via crontab`);
|
|
354
364
|
}
|
|
355
365
|
catch {
|
|
356
|
-
const cronLine = `15 6 * * *
|
|
357
|
-
console.log(` To schedule daily
|
|
366
|
+
const cronLine = `15 6 * * * ${cmd}`;
|
|
367
|
+
console.log(` To schedule the machine-level daily runner, add to crontab (crontab -e):`);
|
|
358
368
|
console.log(` ${cronLine}`);
|
|
359
369
|
}
|
|
360
370
|
}
|
|
@@ -758,6 +768,24 @@ function cmdSleepCore(hippoRoot, flags) {
|
|
|
758
768
|
console.log(`\nDeduped ${dedupResult.removed} duplicates (${parts.join(', ')}). Kept stronger copies.`);
|
|
759
769
|
}
|
|
760
770
|
}
|
|
771
|
+
// Quality audit — remove junk, report warnings
|
|
772
|
+
if (!dryRun) {
|
|
773
|
+
const allEntries = loadAllEntries(hippoRoot);
|
|
774
|
+
const audit = auditMemories(allEntries);
|
|
775
|
+
if (audit.issues.length > 0) {
|
|
776
|
+
const errors = audit.issues.filter(i => i.severity === 'error');
|
|
777
|
+
const warnings = audit.issues.filter(i => i.severity === 'warning');
|
|
778
|
+
if (errors.length > 0) {
|
|
779
|
+
for (const issue of errors) {
|
|
780
|
+
deleteEntry(hippoRoot, issue.memoryId);
|
|
781
|
+
}
|
|
782
|
+
console.log(`\nAudit: removed ${errors.length} junk memories (too short/empty).`);
|
|
783
|
+
}
|
|
784
|
+
if (warnings.length > 0) {
|
|
785
|
+
console.log(`Audit: ${warnings.length} low-quality memories detected (run \`hippo audit\` for details).`);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
761
789
|
// Auto-share high-transfer-score memories to global (unless --no-share or dry-run)
|
|
762
790
|
if (!dryRun && !flags['no-share']) {
|
|
763
791
|
const sleepConfig = loadConfig(hippoRoot);
|
|
@@ -2141,7 +2169,7 @@ hippo capture --stdin <<< '<decisions, errors, lessons — 2-5 bullets>'
|
|
|
2141
2169
|
'codex': {
|
|
2142
2170
|
file: 'AGENTS.md',
|
|
2143
2171
|
description: 'OpenAI Codex',
|
|
2144
|
-
content: `
|
|
2172
|
+
content: `
|
|
2145
2173
|
## Project Memory (Hippo)
|
|
2146
2174
|
|
|
2147
2175
|
At the start of every task, run:
|
|
@@ -2160,8 +2188,8 @@ On task completion:
|
|
|
2160
2188
|
hippo outcome --good
|
|
2161
2189
|
\`\`\`
|
|
2162
2190
|
|
|
2163
|
-
When Hippo's Codex wrapper is installed, session-end capture runs automatically.
|
|
2164
|
-
If the wrapper is not installed, capture a brief summary manually:
|
|
2191
|
+
When Hippo's Codex wrapper is installed, session-end capture runs automatically.
|
|
2192
|
+
If the wrapper is not installed, capture a brief summary manually:
|
|
2165
2193
|
\`\`\`bash
|
|
2166
2194
|
hippo capture --stdin <<< '<decisions, errors, lessons — 2-5 bullets>'
|
|
2167
2195
|
\`\`\`
|
|
@@ -2391,6 +2419,7 @@ function cmdSetup(flags) {
|
|
|
2391
2419
|
const dryRun = Boolean(flags['dry-run']);
|
|
2392
2420
|
const forceAll = Boolean(flags['all']);
|
|
2393
2421
|
const tools = detectInstalledTools();
|
|
2422
|
+
const globalRoot = getGlobalRoot();
|
|
2394
2423
|
console.log('Hippo setup -- configuring SessionEnd + SessionStart hooks');
|
|
2395
2424
|
console.log('');
|
|
2396
2425
|
const jsonTools = tools.filter((t) => t.kind === 'json-hook' && (t.detected || forceAll));
|
|
@@ -2464,9 +2493,46 @@ function cmdSetup(flags) {
|
|
|
2464
2493
|
console.log(` ${tool.name.padEnd(14)} ${tool.notes}`);
|
|
2465
2494
|
}
|
|
2466
2495
|
}
|
|
2496
|
+
if (!flags['no-schedule']) {
|
|
2497
|
+
console.log('');
|
|
2498
|
+
if (dryRun) {
|
|
2499
|
+
console.log(`[dry-run] would install the machine-level daily runner around ${globalRoot}`);
|
|
2500
|
+
}
|
|
2501
|
+
else {
|
|
2502
|
+
setupDailySchedule(globalRoot);
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2467
2505
|
console.log('');
|
|
2468
2506
|
console.log('Done. Restart your AI tool to activate the hooks.');
|
|
2469
2507
|
}
|
|
2508
|
+
function cmdDailyRunner() {
|
|
2509
|
+
const globalRoot = getGlobalRoot();
|
|
2510
|
+
const workspaces = listRegisteredWorkspaces(globalRoot);
|
|
2511
|
+
if (workspaces.length === 0) {
|
|
2512
|
+
console.log('No registered Hippo workspaces found. Run `hippo init` inside a project first.');
|
|
2513
|
+
return;
|
|
2514
|
+
}
|
|
2515
|
+
console.log(`Running daily maintenance across ${workspaces.length} registered workspace${workspaces.length === 1 ? '' : 's'}...`);
|
|
2516
|
+
let processed = 0;
|
|
2517
|
+
let failed = 0;
|
|
2518
|
+
runDailyMaintenance(workspaces, (cwd, args) => {
|
|
2519
|
+
try {
|
|
2520
|
+
execFileSync(process.execPath, [process.argv[1], ...args], {
|
|
2521
|
+
cwd,
|
|
2522
|
+
stdio: 'inherit',
|
|
2523
|
+
windowsHide: true,
|
|
2524
|
+
});
|
|
2525
|
+
if (args[0] === 'sleep')
|
|
2526
|
+
processed++;
|
|
2527
|
+
}
|
|
2528
|
+
catch (err) {
|
|
2529
|
+
failed++;
|
|
2530
|
+
const action = args.join(' ');
|
|
2531
|
+
console.error(`[hippo] daily-runner failed in ${cwd} during \`${action}\`: ${err.message}`);
|
|
2532
|
+
}
|
|
2533
|
+
});
|
|
2534
|
+
console.log(`Daily maintenance complete: ${processed} workspace${processed === 1 ? '' : 's'} processed, ${failed} command failure${failed === 1 ? '' : 's'}.`);
|
|
2535
|
+
}
|
|
2470
2536
|
// JSON-hook install/uninstall lives in ./hooks.ts so tests can import it
|
|
2471
2537
|
// without running the CLI main(). Backwards-compatible wrappers below keep
|
|
2472
2538
|
// older call sites working.
|
|
@@ -2560,7 +2626,7 @@ Commands:
|
|
|
2560
2626
|
--days <n> Days of git history to seed (default: 365 for --scan, 30 for single)
|
|
2561
2627
|
--global Init the global store ($HIPPO_HOME or ~/.hippo/)
|
|
2562
2628
|
--no-hooks Skip auto-detecting and installing agent hooks
|
|
2563
|
-
--no-schedule Skip auto-creating
|
|
2629
|
+
--no-schedule Skip auto-creating the machine-level daily runner
|
|
2564
2630
|
--no-learn Skip seeding memories from git history
|
|
2565
2631
|
remember <text> Store a memory
|
|
2566
2632
|
--tag <tag> Add a tag (repeatable)
|
|
@@ -2583,10 +2649,12 @@ Commands:
|
|
|
2583
2649
|
--dry-run Preview without writing
|
|
2584
2650
|
--no-learn Skip auto git-learn before consolidation
|
|
2585
2651
|
--no-share Skip auto-sharing to global store
|
|
2652
|
+
daily-runner Sweep registered workspaces and run daily learn+sleep
|
|
2586
2653
|
dedup Remove duplicate memories (keeps stronger copy)
|
|
2587
2654
|
--dry-run Preview without removing
|
|
2588
2655
|
--threshold <n> Overlap threshold 0-1 (default: 0.7)
|
|
2589
2656
|
status Show memory health stats
|
|
2657
|
+
audit [--fix] Check memory quality (--fix removes junk)
|
|
2590
2658
|
outcome Apply feedback to last recall
|
|
2591
2659
|
--good Memories were helpful
|
|
2592
2660
|
--bad Memories were irrelevant
|
|
@@ -2679,15 +2747,16 @@ Commands:
|
|
|
2679
2747
|
available SessionEnd+SessionStart hooks
|
|
2680
2748
|
--all Install for every JSON-hook tool, even if not detected
|
|
2681
2749
|
--dry-run Show what would be installed without writing
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
--
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
hook
|
|
2689
|
-
|
|
2690
|
-
|
|
2750
|
+
--no-schedule Skip installing or repairing the daily runner
|
|
2751
|
+
last-sleep Print the last 'hippo sleep --log-file' output and clear it
|
|
2752
|
+
--path <p> Log path (default: ~/.hippo/logs/last-sleep.log)
|
|
2753
|
+
--keep Print without clearing
|
|
2754
|
+
codex-run [-- ...args] Launch real Codex behind Hippo's session-end wrapper
|
|
2755
|
+
hook <sub> [target] Manage framework integrations
|
|
2756
|
+
hook list Show available hooks
|
|
2757
|
+
hook install <target> Install hook (claude-code|codex|cursor|openclaw|opencode|pi)
|
|
2758
|
+
claude-code/opencode install SessionEnd+SessionStart;
|
|
2759
|
+
codex wraps the detected launcher in place
|
|
2691
2760
|
hook uninstall <target> Remove hook
|
|
2692
2761
|
decide "<decision>" Record an architectural decision (90-day half-life)
|
|
2693
2762
|
--context "<why>" Why this decision was made
|
|
@@ -2756,8 +2825,8 @@ async function main() {
|
|
|
2756
2825
|
break;
|
|
2757
2826
|
case 'remember': {
|
|
2758
2827
|
const text = args.join(' ').trim();
|
|
2759
|
-
if (!text) {
|
|
2760
|
-
console.error('
|
|
2828
|
+
if (!text || text.length < 3) {
|
|
2829
|
+
console.error('Memory content too short (minimum 3 characters).');
|
|
2761
2830
|
process.exit(1);
|
|
2762
2831
|
}
|
|
2763
2832
|
cmdRemember(hippoRoot, text, flags);
|
|
@@ -2793,6 +2862,40 @@ async function main() {
|
|
|
2793
2862
|
case 'dedup':
|
|
2794
2863
|
cmdDedup(hippoRoot, flags);
|
|
2795
2864
|
break;
|
|
2865
|
+
case 'audit': {
|
|
2866
|
+
requireInit(hippoRoot);
|
|
2867
|
+
const entries = loadAllEntries(hippoRoot);
|
|
2868
|
+
const result = auditMemories(entries);
|
|
2869
|
+
const shouldFix = Boolean(flags['fix']);
|
|
2870
|
+
if (result.issues.length === 0) {
|
|
2871
|
+
console.log(`All ${result.total} memories passed quality checks.`);
|
|
2872
|
+
}
|
|
2873
|
+
else {
|
|
2874
|
+
console.log(`Audited ${result.total} memories: ${result.clean} clean, ${result.issues.length} issues\n`);
|
|
2875
|
+
for (const issue of result.issues) {
|
|
2876
|
+
const icon = issue.severity === 'error' ? 'ERR' : 'WARN';
|
|
2877
|
+
console.log(` [${icon}] ${issue.memoryId}: ${issue.reason}`);
|
|
2878
|
+
console.log(` "${issue.content.slice(0, 80)}${issue.content.length > 80 ? '...' : ''}"`);
|
|
2879
|
+
}
|
|
2880
|
+
if (shouldFix) {
|
|
2881
|
+
const errorIds = result.issues.filter(i => i.severity === 'error').map(i => i.memoryId);
|
|
2882
|
+
if (errorIds.length > 0) {
|
|
2883
|
+
for (const id of errorIds) {
|
|
2884
|
+
deleteEntry(hippoRoot, id);
|
|
2885
|
+
}
|
|
2886
|
+
console.log(`\nRemoved ${errorIds.length} error-severity memories.`);
|
|
2887
|
+
console.log(`${result.issues.length - errorIds.length} warnings remain (review manually).`);
|
|
2888
|
+
}
|
|
2889
|
+
else {
|
|
2890
|
+
console.log(`\nNo error-severity issues. Warnings require manual review.`);
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
else {
|
|
2894
|
+
console.log(`\nRun with --fix to auto-remove error-severity issues.`);
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
break;
|
|
2898
|
+
}
|
|
2796
2899
|
case 'status':
|
|
2797
2900
|
cmdStatus(hippoRoot);
|
|
2798
2901
|
break;
|
|
@@ -2844,6 +2947,9 @@ async function main() {
|
|
|
2844
2947
|
case 'setup':
|
|
2845
2948
|
cmdSetup(flags);
|
|
2846
2949
|
break;
|
|
2950
|
+
case 'daily-runner':
|
|
2951
|
+
cmdDailyRunner();
|
|
2952
|
+
break;
|
|
2847
2953
|
case 'embed':
|
|
2848
2954
|
await cmdEmbed(hippoRoot, flags);
|
|
2849
2955
|
break;
|