hippo-memory 1.42.1 → 1.43.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 CHANGED
@@ -633,7 +633,7 @@ hippo watch "npm run build"
633
633
  | `hippo wm read --scope <s>` | Read working memory entries |
634
634
  | `hippo wm clear --scope <s>` | Clear working memory |
635
635
  | `hippo wm flush --scope <s>` | Flush working memory (session end) |
636
- | `hippo dashboard` | Open web dashboard at localhost:3333 |
636
+ | `hippo dashboard` | Open web dashboard at localhost:3333 (memory map and card board) |
637
637
  | `hippo dashboard --port <n>` | Use custom port |
638
638
  | `hippo mcp` | Start MCP server (stdio transport) |
639
639
 
@@ -0,0 +1,14 @@
1
+ import type { Card, CardComment, CardRun } from './card.js';
2
+ import type { SessionHandoff } from './handoff.js';
3
+ import { loadCardDeps } from './store.js';
4
+ /** A card plus everything `hippo card show` prints about it. */
5
+ export interface CardDetail {
6
+ card: Card;
7
+ deps: ReturnType<typeof loadCardDeps>;
8
+ runs: CardRun[];
9
+ comments: CardComment[];
10
+ handoff: SessionHandoff | null;
11
+ }
12
+ /** Loads the detail behind `hippo card show` and `GET /api/cards/:id` (null when the tenant has no such card); five separate reads, so a write landing between them can show a mixed view, as `card show` always could. */
13
+ export declare function loadCardDetail(hippoRoot: string, tenantId: string, id: string): CardDetail | null;
14
+ //# sourceMappingURL=card-detail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-detail.d.ts","sourceRoot":"","sources":["../src/card-detail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAA8B,YAAY,EAA0C,MAAM,YAAY,CAAC;AAE9G,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;IACtC,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;CAChC;AAED,2NAA2N;AAC3N,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAUjG"}
@@ -0,0 +1,15 @@
1
+ import { loadCard, loadCardComments, loadCardDeps, loadCardRuns, loadLatestHandoffForCard } from './store.js';
2
+ /** Loads the detail behind `hippo card show` and `GET /api/cards/:id` (null when the tenant has no such card); five separate reads, so a write landing between them can show a mixed view, as `card show` always could. */
3
+ export function loadCardDetail(hippoRoot, tenantId, id) {
4
+ const card = loadCard(hippoRoot, tenantId, id);
5
+ if (!card)
6
+ return null;
7
+ return {
8
+ card,
9
+ deps: loadCardDeps(hippoRoot, tenantId, id),
10
+ runs: loadCardRuns(hippoRoot, tenantId, id),
11
+ comments: loadCardComments(hippoRoot, tenantId, id),
12
+ handoff: loadLatestHandoffForCard(hippoRoot, tenantId, id),
13
+ };
14
+ }
15
+ //# sourceMappingURL=card-detail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-detail.js","sourceRoot":"","sources":["../src/card-detail.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAW9G,2NAA2N;AAC3N,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,QAAgB,EAAE,EAAU;IAC5E,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC/C,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,YAAY,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC;QAC3C,IAAI,EAAE,YAAY,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC;QAC3C,QAAQ,EAAE,gBAAgB,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC;QACnD,OAAO,EAAE,wBAAwB,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC;KAC3D,CAAC;AACJ,CAAC"}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AA2BH,OAAO,EAWL,WAAW,EAEZ,MAAM,aAAa,CAAC;AA6HrB,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AA4ChC,kFAAkF;AAClF,wBAAgB,8BAA8B,IAAI,IAAI,CAErD;AAuJD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,CAAA;CAAE,CAwCjI;AAqxED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,MAAqB,GAAG,MAAM,CAyF3F;AAyGD;;;GAGG;AACH,oHAAoH;AACpH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAuD/D;AAsgHD,oHAAoH;AACpH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,EACtF,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,MAAkB,GAC1B,IAAI,CA8BN"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AA2BH,OAAO,EAWL,WAAW,EAEZ,MAAM,aAAa,CAAC;AA2HrB,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AA4ChC,kFAAkF;AAClF,wBAAgB,8BAA8B,IAAI,IAAI,CAErD;AAuJD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,CAAA;CAAE,CAwCjI;AAqxED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,MAAqB,GAAG,MAAM,CAyF3F;AAyGD;;;GAGG;AACH,oHAAoH;AACpH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAuD/D;AA6/GD,oHAAoH;AACpH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,EACtF,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,MAAkB,GAC1B,IAAI,CA8BN"}
package/dist/cli.js CHANGED
@@ -38,11 +38,12 @@ import { execFileSync, execSync, spawn } from 'child_process';
38
38
  import { installJsonHooks, uninstallJsonHooks, resolveJsonHookPaths, detectInstalledTools, defaultSleepLogPath, ensureCodexWrapperInstalled, installCodexWrapper, isCodexWrapperInstalled, repairCodexWrapperIfInstalled, uninstallCodexWrapper, resolveCodexSessionTranscript, resolveCodexWrapperPaths, installOpencodePlugin, uninstallOpencodePlugin, resolveOpencodePluginPath, } from './hooks.js';
39
39
  import { createMemory, calculateStrength, calculateRewardFactor, deriveHalfLife, resolveConfidence, confidenceFacets, confidenceLabel, computeSchemaFit, Layer, } from './memory.js';
40
40
  import { detectSecret } from './secret-detect.js';
41
- import { getHippoRoot, isInitialized, initStore, writeEntry, readEntry, deleteEntry, loadAllEntries, loadSearchEntries, loadRecallSearchEntries, loadIndex, saveIndex, loadStats, updateStats, saveActiveTaskSnapshot, loadActiveTaskSnapshot, closeTaskSnapshotsForSession, clearActiveTaskSnapshot, appendSessionEvent, listSessionEvents, listMemoryConflicts, resolveConflict, saveSessionHandoff, loadLatestHandoff, loadHandoffById, stampHandoffOutcome, writeSessionEndHandoff, createCard, loadCard, listCards, loadCardDeps, loadCardRuns, loadCardComments, claimCard, heartbeatCard, blockCard, reviewCard, completeCard, reclaimExpiredCards, addCardComment, loadLatestHandoffForCard, } from './store.js';
41
+ import { getHippoRoot, isInitialized, initStore, writeEntry, readEntry, deleteEntry, loadAllEntries, loadSearchEntries, loadRecallSearchEntries, loadIndex, saveIndex, loadStats, updateStats, saveActiveTaskSnapshot, loadActiveTaskSnapshot, closeTaskSnapshotsForSession, clearActiveTaskSnapshot, appendSessionEvent, listSessionEvents, listMemoryConflicts, resolveConflict, saveSessionHandoff, loadLatestHandoff, loadHandoffById, stampHandoffOutcome, writeSessionEndHandoff, createCard, loadCard, listCards, loadCardRuns, claimCard, heartbeatCard, blockCard, reviewCard, completeCard, reclaimExpiredCards, addCardComment, } from './store.js';
42
42
  import { rejectValue, unrejectValue, listRejectionsForTenant } from './reject-flow.js';
43
43
  import { RejectedValueError } from './rejection.js';
44
44
  import { isHandoffOutcome, formatHandoffEvidenceLine } from './handoff.js';
45
45
  import { isCardStatus } from './card.js';
46
+ import { loadCardDetail } from './card-detail.js';
46
47
  import { passesScopeFilterForRecall } from './recall-scope.js';
47
48
  import { markRetrieved, hybridSearch, physicsSearch, explainMatch, textOverlap, tokenize as tokenizeQuery } from './search.js';
48
49
  import { compareEntryIdentity } from './compare.js';
@@ -4029,7 +4030,8 @@ function cmdHandoff(hippoRoot, args, flags) {
4029
4030
  }
4030
4031
  // Mirrors ARCHIVE_REASON_REQUIRED so the block message can't drift from its usage line.
4031
4032
  const CARD_BLOCK_REASON_REQUIRED = 'hippo card block <id> requires --reason "<why>" (recorded as a comment).';
4032
- function printCard(hippoRoot, tenantId, card) {
4033
+ function printCard(detail) {
4034
+ const { card, deps, runs, comments, handoff } = detail;
4033
4035
  console.log(`## Card ${card.id}\n`);
4034
4036
  console.log(`- Title: ${card.title}`);
4035
4037
  console.log(`- Status: ${card.status}`);
@@ -4046,26 +4048,22 @@ function printCard(hippoRoot, tenantId, card) {
4046
4048
  if (card.budget !== null)
4047
4049
  console.log(`- Budget: ${card.budget}`);
4048
4050
  console.log(`- Updated: ${card.updatedAt}`);
4049
- const deps = loadCardDeps(hippoRoot, tenantId, card.id);
4050
4051
  if (deps.parents.length > 0)
4051
4052
  console.log(`- Parents: ${deps.parents.join(', ')}`);
4052
4053
  if (deps.children.length > 0)
4053
4054
  console.log(`- Children: ${deps.children.join(', ')}`);
4054
- const runs = loadCardRuns(hippoRoot, tenantId, card.id);
4055
4055
  if (runs.length > 0) {
4056
4056
  console.log('\n### Runs');
4057
4057
  for (const run of runs) {
4058
4058
  console.log(`- run ${run.id}: ${run.runtime} started ${run.started}${run.ended ? ` ended ${run.ended} (${run.outcome})` : ' (open)'}`);
4059
4059
  }
4060
4060
  }
4061
- const comments = loadCardComments(hippoRoot, tenantId, card.id);
4062
4061
  if (comments.length > 0) {
4063
4062
  console.log('\n### Comments');
4064
4063
  for (const comment of comments) {
4065
4064
  console.log(`- [${comment.createdAt}] ${comment.author}: ${comment.body}`);
4066
4065
  }
4067
4066
  }
4068
- const handoff = loadLatestHandoffForCard(hippoRoot, tenantId, card.id);
4069
4067
  if (handoff) {
4070
4068
  console.log('\n### Latest handoff');
4071
4069
  console.log(`- Session: ${handoff.sessionId}, updated ${handoff.updatedAt}`);
@@ -4172,22 +4170,16 @@ function cmdCard(hippoRoot, args, flags) {
4172
4170
  console.error('Usage: hippo card show <id> [--json]');
4173
4171
  process.exit(1);
4174
4172
  }
4175
- const card = loadCard(hippoRoot, tenantId, id);
4176
- if (!card) {
4173
+ const detail = loadCardDetail(hippoRoot, tenantId, id);
4174
+ if (!detail) {
4177
4175
  console.error(`No card found with id ${id}.`);
4178
4176
  process.exit(1);
4179
4177
  }
4180
4178
  if (flags['json']) {
4181
- console.log(JSON.stringify({
4182
- card,
4183
- deps: loadCardDeps(hippoRoot, tenantId, id),
4184
- runs: loadCardRuns(hippoRoot, tenantId, id),
4185
- comments: loadCardComments(hippoRoot, tenantId, id),
4186
- handoff: loadLatestHandoffForCard(hippoRoot, tenantId, id),
4187
- }, null, 2));
4179
+ console.log(JSON.stringify(detail, null, 2));
4188
4180
  return;
4189
4181
  }
4190
- printCard(hippoRoot, tenantId, card);
4182
+ printCard(detail);
4191
4183
  return;
4192
4184
  }
4193
4185
  if (subcommand === 'list') {