hippo-memory 1.56.0 → 1.57.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/dist/api.d.ts +16 -9
- package/dist/api.js +57 -24
- package/dist/card-detail.d.ts +1 -1
- package/dist/card-detail.js +1 -1
- package/dist/cli/shared.d.ts +137 -0
- package/dist/cli/shared.js +830 -0
- package/dist/cli/sleep.d.ts +10 -0
- package/dist/cli/sleep.js +171 -0
- package/dist/cli.d.ts +0 -7
- package/dist/cli.js +223 -1789
- package/dist/connectors/github/webhook.d.ts +19 -0
- package/dist/connectors/github/webhook.js +313 -0
- package/dist/connectors/slack/webhook.d.ts +22 -0
- package/dist/connectors/slack/webhook.js +203 -0
- package/dist/consolidate.js +3 -2
- package/dist/context-auto.d.ts +3 -0
- package/dist/context-auto.js +34 -0
- package/dist/customer-notes.js +2 -1
- package/dist/dashboard.js +2 -1
- package/dist/decisions.js +2 -1
- package/dist/eval-stats.d.ts +58 -0
- package/dist/eval-stats.js +111 -0
- package/dist/goals.d.ts +49 -25
- package/dist/goals.js +39 -22
- package/dist/graph-extract.js +1 -1
- package/dist/graph-recall.d.ts +1 -1
- package/dist/graph-recall.js +1 -1
- package/dist/graph.js +1 -1
- package/dist/hooks.d.ts +1 -3
- package/dist/hooks.js +2 -4
- package/dist/http-util.d.ts +31 -0
- package/dist/http-util.js +46 -0
- package/dist/incidents.js +2 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +5 -2
- package/dist/mcp/server.js +173 -285
- package/dist/memory.d.ts +19 -0
- package/dist/memory.js +38 -0
- package/dist/policies.js +2 -1
- package/dist/predictions.js +2 -1
- package/dist/processes.js +2 -1
- package/dist/project-briefs.js +3 -1
- package/dist/prompt-recall.js +1 -1
- package/dist/recall-history.d.ts +5 -0
- package/dist/recall-history.js +9 -0
- package/dist/recall-pipeline.d.ts +101 -0
- package/dist/recall-pipeline.js +313 -0
- package/dist/recall-scope.d.ts +22 -0
- package/dist/recall-scope.js +27 -1
- package/dist/search.d.ts +0 -20
- package/dist/search.js +2 -49
- package/dist/server.js +1901 -2384
- package/dist/skills.js +2 -1
- package/dist/store-cards.d.ts +53 -0
- package/dist/store-cards.js +512 -0
- package/dist/store.d.ts +2 -89
- package/dist/store.js +6 -562
- package/dist/tenant.d.ts +22 -0
- package/dist/tenant.js +26 -0
- package/dist/tokenize.d.ts +2 -0
- package/dist/tokenize.js +8 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { auditMemories, type AuditEvent, type AuditOp } from './audit.js';
|
|
|
19
19
|
import { autoShare } from './shared.js';
|
|
20
20
|
import type { DeliveryObserver } from './delivery-recorder.js';
|
|
21
21
|
import { type ApiKeyListItem } from './auth.js';
|
|
22
|
-
import { type RerankStep } from './search.js';
|
|
22
|
+
import { type RerankStep, type SearchResult } from './search.js';
|
|
23
23
|
import { consolidate } from './consolidate.js';
|
|
24
24
|
import { loadConfig } from './config.js';
|
|
25
25
|
import { deduplicateStore } from './dedupe.js';
|
|
@@ -92,9 +92,8 @@ export type { TokenSummary, TokenSurface, TokenSurfaceSummary } from './token-le
|
|
|
92
92
|
export type { FailureSummary } from './failure-log.js';
|
|
93
93
|
export { classifyOriginProject } from './project-identity.js';
|
|
94
94
|
/**
|
|
95
|
-
* v39 S4: the secret half of the ambient policy on its own, for
|
|
96
|
-
*
|
|
97
|
-
* exact-match). A flagged row is only admitted inside its owning project;
|
|
95
|
+
* v39 S4: the secret half of the ambient policy on its own, for callers
|
|
96
|
+
* that apply their own scope rule. A flagged row is only admitted inside its owning project;
|
|
98
97
|
* flagged rows with no project origin never ambient-inject.
|
|
99
98
|
*/
|
|
100
99
|
export declare function ambientSecretAdmit(e: MemoryEntry, currentProjectName: string): boolean;
|
|
@@ -270,16 +269,22 @@ export interface RecallOpts {
|
|
|
270
269
|
* Mirrors `suppressAvailabilityHint`'s pattern: callers that run their OWN
|
|
271
270
|
* tracing over a DIFFERENT result set must suppress api.recall's copy so
|
|
272
271
|
* the training corpus doesn't get a trace mislabeled as 'api' pipeline
|
|
273
|
-
* when the caller's actual user-visible results came from elsewhere.
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
* tracing is the reserved 'mcp' pipeline, a follow-up). HTTP / direct SDK
|
|
277
|
-
* callers leave this unset and get the trace.
|
|
272
|
+
* when the caller's actual user-visible results came from elsewhere. Under
|
|
273
|
+
* `showRanked` it also drops the 'mcp' trace of the shown list. HTTP /
|
|
274
|
+
* direct SDK callers leave this unset and get the trace.
|
|
278
275
|
*/
|
|
279
276
|
suppressRecallTrace?: boolean;
|
|
280
277
|
/** Set only by the MCP recall tool, which ranks with its own scorer and drops copies from its own final list: this call
|
|
281
278
|
* then keeps a memory that a merged row in the same result holds word for word. Other callers leave it unset. */
|
|
282
279
|
keepHeldCopies?: boolean;
|
|
280
|
+
/** MCP recall only: `retrieve` ranks the whole scoped store and strengthens and traces (pipeline 'mcp') just the ids this returns; `results` stays the window band. */
|
|
281
|
+
showRanked?: (ranking: StoreRanking, result: RecallResult) => readonly string[];
|
|
282
|
+
}
|
|
283
|
+
/** `ranked`: every scored row, best first, goal boost applied, entries as loaded; `pool`: the store after the scope filter. */
|
|
284
|
+
export interface StoreRanking {
|
|
285
|
+
ranked: SearchResult[];
|
|
286
|
+
pool: MemoryEntry[];
|
|
287
|
+
droppedByScope: number;
|
|
283
288
|
}
|
|
284
289
|
export interface ContinuityBlock {
|
|
285
290
|
activeSnapshot: TaskSnapshot | null;
|
|
@@ -946,6 +951,8 @@ export interface ContextOpts {
|
|
|
946
951
|
limit?: number;
|
|
947
952
|
pinnedOnly?: boolean;
|
|
948
953
|
scope?: string;
|
|
954
|
+
/** Envelope scope to match exactly, as in `recall`: admits that scope even when private, after the actor's scope check. */
|
|
955
|
+
exactScope?: string;
|
|
949
956
|
/** With `pinnedOnly`, also inject the N most recent writes that pass the
|
|
950
957
|
* quality floor (`isContentWorthStoring`, DF3). Filtering happens BEFORE
|
|
951
958
|
* the take-N, so a caller asking for 5 gets 5 qualifying entries rather
|
package/dist/api.js
CHANGED
|
@@ -16,7 +16,7 @@ import { detectInstruction } from './instruction-detect.js';
|
|
|
16
16
|
import { quarantineScopeFor, recordQuarantine, getQuarantineRow, listQuarantineRows, approveQuarantineRow, rejectQuarantineRow, } from './quarantine.js';
|
|
17
17
|
import { summarizeFailures } from './failure-log.js';
|
|
18
18
|
import { formatHandoffEvidenceLine } from './handoff.js';
|
|
19
|
-
import { createMemory, createSuccessor, applyOutcome, calculateStrength, CHURN_STALE_TAG, COMPACTION_MEMORY_TAG, } from './memory.js';
|
|
19
|
+
import { createMemory, createSuccessor, applyOutcome, calculateStrength, markRetrieved, CHURN_STALE_TAG, COMPACTION_MEMORY_TAG, } from './memory.js';
|
|
20
20
|
import { appendAuditEvent, auditQueryFields, queryAuditEvents, auditMemories, isContentWorthStoring, } from './audit.js';
|
|
21
21
|
import { promoteToGlobal, getGlobalRoot, autoShare, searchBothHybrid } from './shared.js';
|
|
22
22
|
import { writeRecallTrace, writeRecallTraceAtRoot, recordTraceOutcome } from './recall-trace.js';
|
|
@@ -24,7 +24,7 @@ import { evalNow } from './ablation.js';
|
|
|
24
24
|
import { archiveRawMemory } from './raw-archive.js';
|
|
25
25
|
import { createApiKey, listApiKeys, revokeApiKey, grantScope, ungrantScope, } from './auth.js';
|
|
26
26
|
import { applyGoalStackBoost } from './goals.js';
|
|
27
|
-
import {
|
|
27
|
+
import { estimateTokens, hybridSearch, physicsSearch, churnStaleFactor } from './search.js';
|
|
28
28
|
import { compareEntryIdentity, compareScoredResults } from './compare.js';
|
|
29
29
|
import { dropHeldCopies, duplicateKey, storedTextKeys } from './same-text.js';
|
|
30
30
|
import { scopeMatch } from './scope.js';
|
|
@@ -39,7 +39,7 @@ import { computeAmbientState } from './ambient.js';
|
|
|
39
39
|
import { loadPendingExtractionTenants, markPendingProcessedUpTo } from './graph.js';
|
|
40
40
|
import { extractGraph } from './graph-extract.js';
|
|
41
41
|
import { computePlanningFallacyOutput, } from './predictions.js';
|
|
42
|
-
import { detectAnchoring, hashQueryText, } from './recall-history.js';
|
|
42
|
+
import { detectAnchoring, hashQueryText, biasHintEnabled, } from './recall-history.js';
|
|
43
43
|
import { detectAvailabilityBias } from './availability.js';
|
|
44
44
|
/**
|
|
45
45
|
* Helper for building process-local (admin-by-default) Actor values. v1.12.0
|
|
@@ -107,23 +107,22 @@ export { classifyOriginProject } from './project-identity.js';
|
|
|
107
107
|
* injects inside its owning project; flagged rows with no project origin
|
|
108
108
|
* (''/null) never ambient-inject at all. Explicit recall is unaffected -
|
|
109
109
|
* recalling a secret is a deliberate act.
|
|
110
|
-
* - S2 envelope parity: private scopes
|
|
110
|
+
* - S2 envelope parity: private/quarantine scopes never inject unless `exactScope` names one.
|
|
111
111
|
* - S3 origin partition: other-project rows are excluded unless
|
|
112
112
|
* `includeCrossProject`.
|
|
113
113
|
*/
|
|
114
|
-
function ambientAdmitEntry(e, currentProjectName, includeCrossProject) {
|
|
114
|
+
function ambientAdmitEntry(e, currentProjectName, includeCrossProject, exactScope) {
|
|
115
115
|
if (!ambientSecretAdmit(e, currentProjectName))
|
|
116
116
|
return false;
|
|
117
|
-
if (!passesScopeFilterForRecall(e.scope ?? null,
|
|
117
|
+
if (!passesScopeFilterForRecall(e.scope ?? null, exactScope))
|
|
118
118
|
return false;
|
|
119
119
|
if (includeCrossProject)
|
|
120
120
|
return true;
|
|
121
121
|
return classifyOriginProject(e.origin_project, currentProjectName) !== 'cross-project';
|
|
122
122
|
}
|
|
123
123
|
/**
|
|
124
|
-
* v39 S4: the secret half of the ambient policy on its own, for
|
|
125
|
-
*
|
|
126
|
-
* exact-match). A flagged row is only admitted inside its owning project;
|
|
124
|
+
* v39 S4: the secret half of the ambient policy on its own, for callers
|
|
125
|
+
* that apply their own scope rule. A flagged row is only admitted inside its owning project;
|
|
127
126
|
* flagged rows with no project origin never ambient-inject.
|
|
128
127
|
*/
|
|
129
128
|
export function ambientSecretAdmit(e, currentProjectName) {
|
|
@@ -244,6 +243,8 @@ export function recall(ctx, opts) {
|
|
|
244
243
|
export async function retrieve(ctx, opts) {
|
|
245
244
|
assertScopeRequestAllowed(ctx.actor, opts.scope);
|
|
246
245
|
const windowSize = recallWindowSize(opts);
|
|
246
|
+
if (opts.showRanked)
|
|
247
|
+
return retrieveFromStore(ctx, opts, windowSize, opts.showRanked);
|
|
247
248
|
let candidates = loadRecallSearchEntries(ctx.hippoRoot, opts.query, windowSize, ctx.tenantId, opts.scope, 'exact', false);
|
|
248
249
|
if (opts.mode === 'hybrid' || opts.mode === 'physics') {
|
|
249
250
|
const searchOpts = { budget: Infinity, hippoRoot: ctx.hippoRoot, scope: opts.scope ?? null };
|
|
@@ -257,6 +258,40 @@ export async function retrieve(ctx, opts) {
|
|
|
257
258
|
strengthenRetrieved(ctx.hippoRoot, result.results.map((r) => r.id), ctx.tenantId);
|
|
258
259
|
return result;
|
|
259
260
|
}
|
|
261
|
+
/** `retrieve` under `showRanked`: physics when `mode` says so, hybrid otherwise, over every admitted row. */
|
|
262
|
+
async function retrieveFromStore(ctx, opts, windowSize, show) {
|
|
263
|
+
const store = loadAllEntries(ctx.hippoRoot, ctx.tenantId);
|
|
264
|
+
const pool = store.filter((e) => passesScopeFilterForRecall(e.scope ?? null, opts.scope));
|
|
265
|
+
// No scope option: the scope boost follows HIPPO_SCOPE and the skill env, as MCP recall always ranked.
|
|
266
|
+
const searchOpts = { budget: Infinity, hippoRoot: ctx.hippoRoot };
|
|
267
|
+
let ranked = opts.mode === 'physics'
|
|
268
|
+
? await physicsSearch(opts.query, pool, { ...searchOpts, physicsConfig: loadConfig(ctx.hippoRoot).physics })
|
|
269
|
+
: await hybridSearch(opts.query, pool, searchOpts);
|
|
270
|
+
if (opts.sessionId && !opts.goalTag) {
|
|
271
|
+
const db = openHippoDb(ctx.hippoRoot);
|
|
272
|
+
try {
|
|
273
|
+
ranked = applyGoalStackBoost(db, ranked, { sessionId: opts.sessionId, tenantId: ctx.tenantId, limit: ranked.length });
|
|
274
|
+
}
|
|
275
|
+
finally {
|
|
276
|
+
closeHippoDb(db);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
const window = ranked.slice(0, windowSize).map((r) => r.entry);
|
|
280
|
+
const result = recallFrom(ctx, { ...opts, suppressRecallTrace: true }, windowSize, window);
|
|
281
|
+
const shown = show({ ranked, pool, droppedByScope: store.length - pool.length }, result);
|
|
282
|
+
strengthenRetrieved(ctx.hippoRoot, shown, ctx.tenantId);
|
|
283
|
+
if (!opts.suppressRecallTrace) {
|
|
284
|
+
const scores = new Map(ranked.map((r) => [r.entry.id, r.score]));
|
|
285
|
+
writeRecallTraceAtRoot(ctx.hippoRoot, {
|
|
286
|
+
tenantId: ctx.tenantId,
|
|
287
|
+
sessionId: opts.sessionId ?? null,
|
|
288
|
+
pipeline: 'mcp',
|
|
289
|
+
query: opts.query,
|
|
290
|
+
results: shown.map((id) => ({ memoryId: id, score: scores.get(id) ?? 0 })),
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
return result;
|
|
294
|
+
}
|
|
260
295
|
/** Contract preflight: throws before any store-touching work. */
|
|
261
296
|
function recallWindowSize(opts) {
|
|
262
297
|
// F5 (v1.6.5) preflight — codex P1: original guard fired AFTER
|
|
@@ -564,9 +599,9 @@ function recallFrom(ctx, opts, windowSize, all) {
|
|
|
564
599
|
// handle. v1.11.5 contract lock holds — api.recall does NOT write
|
|
565
600
|
// last_trace_id (tests/api-recall-no-side-effects.test.ts); a trace INSERT
|
|
566
601
|
// is the same observability class as the audit row it sits beside, not
|
|
567
|
-
// retrieval state. F2 fix: suppressed when the caller
|
|
568
|
-
//
|
|
569
|
-
//
|
|
602
|
+
// retrieval state. F2 fix: suppressed when the caller traces its own,
|
|
603
|
+
// different result set (retrieve under showRanked traces the shown list as
|
|
604
|
+
// 'mcp'). Fail-soft internally; never throws.
|
|
570
605
|
if (!opts.suppressRecallTrace) {
|
|
571
606
|
writeRecallTrace(db, {
|
|
572
607
|
tenantId: ctx.tenantId,
|
|
@@ -656,7 +691,7 @@ function recallFrom(ctx, opts, windowSize, all) {
|
|
|
656
691
|
// detect call returns null and api.recall's anchoringHint stays absent.
|
|
657
692
|
let anchoringHint = null;
|
|
658
693
|
let suppressedByInterferenceCount = 0;
|
|
659
|
-
if (
|
|
694
|
+
if (biasHintEnabled('anchoring') && opts.recallHistory) {
|
|
660
695
|
const queryHash = hashQueryText(opts.query);
|
|
661
696
|
const topMemoryId = rankedOut[0]?.id ?? null;
|
|
662
697
|
anchoringHint = detectAnchoring(opts.recallHistory, queryHash, topMemoryId);
|
|
@@ -709,7 +744,7 @@ function recallFrom(ctx, opts, windowSize, all) {
|
|
|
709
744
|
// opts.recallHistory gate above so we never double-emit the audit op. Audit
|
|
710
745
|
// emission is pipeline-local, mirroring the J1 block above.
|
|
711
746
|
let availabilityHint = null;
|
|
712
|
-
if (
|
|
747
|
+
if (biasHintEnabled('availability') && !opts.suppressAvailabilityHint) {
|
|
713
748
|
availabilityHint = detectAvailabilityBias({
|
|
714
749
|
topK: baseSlice.map((e) => ({ id: e.id, created: e.created })),
|
|
715
750
|
pool: entries.map((e) => ({ id: e.id, created: e.created })),
|
|
@@ -1551,6 +1586,8 @@ export async function getContext(ctx, opts = {}) {
|
|
|
1551
1586
|
const limit = opts.limit ?? Number.POSITIVE_INFINITY;
|
|
1552
1587
|
const includeRecent = opts.includeRecent ?? 0;
|
|
1553
1588
|
const activeScope = opts.scope ?? '';
|
|
1589
|
+
assertScopeRequestAllowed(ctx.actor, opts.exactScope);
|
|
1590
|
+
const exactScope = opts.exactScope || undefined;
|
|
1554
1591
|
if (budget <= 0) {
|
|
1555
1592
|
return { entries: [], tokens: 0 };
|
|
1556
1593
|
}
|
|
@@ -1562,10 +1599,7 @@ export async function getContext(ctx, opts = {}) {
|
|
|
1562
1599
|
const primaryIsGlobal = isGlobalStoreRoot(ctx.hippoRoot);
|
|
1563
1600
|
const hasLocalTaskState = hasLocal && !primaryIsGlobal;
|
|
1564
1601
|
// v39 memory scope isolation (docs/plans/2026-07-01-memory-scope-isolation.md).
|
|
1565
|
-
// S2: envelope-filter parity with api.recall
|
|
1566
|
-
// scopes and quarantine buckets never inject. `requested` is deliberately
|
|
1567
|
-
// undefined: opts.scope is the scope-TAG boost input here, not an
|
|
1568
|
-
// envelope-scope request (api.recall's exact-match semantics don't apply).
|
|
1602
|
+
// S2: envelope-filter parity with api.recall; opts.scope is only the tag boost, opts.exactScope the envelope request.
|
|
1569
1603
|
// S3: origin partition - other-project memories are excluded unless the
|
|
1570
1604
|
// caller explicitly asks for them (crossProject) or isolation is disabled.
|
|
1571
1605
|
const config = loadConfig(ctx.hippoRoot);
|
|
@@ -1612,9 +1646,8 @@ export async function getContext(ctx, opts = {}) {
|
|
|
1612
1646
|
sessionId: opts.currentSessionId,
|
|
1613
1647
|
})
|
|
1614
1648
|
: null;
|
|
1615
|
-
// W1:
|
|
1616
|
-
|
|
1617
|
-
const activeSnapshot = rawActiveSnapshot && passesScopeFilterForRecall(rowScope(rawActiveSnapshot), undefined)
|
|
1649
|
+
// W1: the same envelope rule ambientAdmitEntry applies to memory rows.
|
|
1650
|
+
const activeSnapshot = rawActiveSnapshot && passesScopeFilterForRecall(rowScope(rawActiveSnapshot), exactScope)
|
|
1618
1651
|
? rawActiveSnapshot
|
|
1619
1652
|
: null;
|
|
1620
1653
|
// Key on the RAW snapshot: a scope-hidden active session must not fall through to another session's ambient handoff.
|
|
@@ -1628,7 +1661,7 @@ export async function getContext(ctx, opts = {}) {
|
|
|
1628
1661
|
// codex P2: admit scope in SQL so a newer denied row can't hide an older eligible one before LIMIT 1.
|
|
1629
1662
|
scopeFilter: 'default-deny',
|
|
1630
1663
|
});
|
|
1631
|
-
const sessionHandoff = rawSessionHandoff && passesScopeFilterForRecall(rowScope(rawSessionHandoff),
|
|
1664
|
+
const sessionHandoff = rawSessionHandoff && passesScopeFilterForRecall(rowScope(rawSessionHandoff), exactScope)
|
|
1632
1665
|
? rawSessionHandoff
|
|
1633
1666
|
: null;
|
|
1634
1667
|
// Raw session id here too: each event is admitted on its own scope, same as recall and the CLI.
|
|
@@ -1636,7 +1669,7 @@ export async function getContext(ctx, opts = {}) {
|
|
|
1636
1669
|
? listSessionEvents(ctx.hippoRoot, ctx.tenantId, {
|
|
1637
1670
|
session_id: rawActiveSnapshot.session_id,
|
|
1638
1671
|
limit: 5,
|
|
1639
|
-
}).filter((e) => passesScopeFilterForRecall(rowScope(e),
|
|
1672
|
+
}).filter((e) => passesScopeFilterForRecall(rowScope(e), exactScope))
|
|
1640
1673
|
: [];
|
|
1641
1674
|
const shownSnapshot = activeSnapshot && (!cost || pays(cost.snapshot(activeSnapshot))) ? activeSnapshot : null;
|
|
1642
1675
|
const shownHandoff = sessionHandoff && (!cost || pays(cost.handoff(sessionHandoff))) ? sessionHandoff : null;
|
|
@@ -1650,7 +1683,7 @@ export async function getContext(ctx, opts = {}) {
|
|
|
1650
1683
|
digestHiddenForHandoff = true;
|
|
1651
1684
|
return false;
|
|
1652
1685
|
}
|
|
1653
|
-
return ambientAdmitEntry(e, currentProjectName, includeCrossProject);
|
|
1686
|
+
return ambientAdmitEntry(e, currentProjectName, includeCrossProject, exactScope);
|
|
1654
1687
|
};
|
|
1655
1688
|
const ownSessionId = opts.currentSessionId || '';
|
|
1656
1689
|
// Inside admit, not after the load, so the loader's window widens past a session's own items.
|
package/dist/card-detail.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Card, CardComment, CardRun } from './card.js';
|
|
2
2
|
import type { SessionHandoff } from './handoff.js';
|
|
3
|
-
import { loadCardDeps } from './store.js';
|
|
3
|
+
import { loadCardDeps } from './store-cards.js';
|
|
4
4
|
/** A card plus everything `hippo card show` prints about it. */
|
|
5
5
|
export interface CardDetail {
|
|
6
6
|
card: Card;
|
package/dist/card-detail.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadCard, loadCardComments, loadCardDeps, loadCardRuns, loadLatestHandoffForCard } from './store.js';
|
|
1
|
+
import { loadCard, loadCardComments, loadCardDeps, loadCardRuns, loadLatestHandoffForCard } from './store-cards.js';
|
|
2
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
3
|
export function loadCardDetail(hippoRoot, tenantId, id) {
|
|
4
4
|
const card = loadCard(hippoRoot, tenantId, id);
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { TaskSnapshot, SessionEvent } from '../store.js';
|
|
2
|
+
import type { HandoffEvidence, SessionHandoff } from '../handoff.js';
|
|
3
|
+
import { type SearchResult } from '../search.js';
|
|
4
|
+
import { type HippoConfig } from '../config.js';
|
|
5
|
+
import { openHippoDb } from '../db.js';
|
|
6
|
+
import { type ImportReport } from '../agent-memories/report.js';
|
|
7
|
+
import { type ChurnStaleResult } from '../invalidation.js';
|
|
8
|
+
import { type AuditOp } from '../audit.js';
|
|
9
|
+
import { type ServerInfo } from '../server-detect.js';
|
|
10
|
+
import type { RecallSearchOpts } from '../recall-pipeline.js';
|
|
11
|
+
export declare function parseLimitFlag(value: string | boolean | string[] | undefined): number;
|
|
12
|
+
export declare function parseCountFlag(value: string | boolean | string[] | undefined): number;
|
|
13
|
+
export declare function parseBudgetFlag(value: string | boolean | string[] | undefined, fallback: number): number;
|
|
14
|
+
/**
|
|
15
|
+
* Emit an audit event against `hippoRoot`'s db. Opens its own short-lived
|
|
16
|
+
* connection so callers don't have to thread a db handle. Swallows all errors
|
|
17
|
+
* — audit must never crash a CLI command.
|
|
18
|
+
*/
|
|
19
|
+
export declare function emitCliAudit(hippoRoot: string, op: AuditOp, targetId?: string, metadata?: Record<string, unknown>): void;
|
|
20
|
+
export declare function requireInit(hippoRoot: string): void;
|
|
21
|
+
/** Runs detectChurnStale against every store this repo's memories can live in. */
|
|
22
|
+
export declare function runChurnStaleForRepo(hippoRoot: string, dryRun: boolean): {
|
|
23
|
+
root: string;
|
|
24
|
+
result: ChurnStaleResult;
|
|
25
|
+
}[];
|
|
26
|
+
/**
|
|
27
|
+
* Run an HTTP-routed command if a `hippo serve` instance is detected for
|
|
28
|
+
* `hippoRoot`. Returns:
|
|
29
|
+
* - true if the HTTP path ran (success OR a structured server error that
|
|
30
|
+
* was already surfaced to stdout/stderr by `httpFn`),
|
|
31
|
+
* - false if no server was detected, or if the detected pidfile turned out
|
|
32
|
+
* to be stale (connection refused). On stale, the pidfile is removed
|
|
33
|
+
* if it still names that dead server (a newer one may have replaced
|
|
34
|
+
* it) and the caller should fall back to the direct path.
|
|
35
|
+
*
|
|
36
|
+
* Stale pidfiles must self-heal, not crash.
|
|
37
|
+
* When HIPPO_REQUIRE_SERVER is set, both fallback paths throw instead of
|
|
38
|
+
* returning false, so a missing server fails loudly rather than silently
|
|
39
|
+
* degrading to direct mode.
|
|
40
|
+
*/
|
|
41
|
+
export declare function runViaServerIfAvailable(hippoRoot: string, httpFn: (info: ServerInfo, apiKey: string | undefined) => Promise<void>): Promise<boolean>;
|
|
42
|
+
export declare function fmt(n: number, digits?: number): string;
|
|
43
|
+
export declare function recallEntryText(r: SearchResult, query: string, showWhy: boolean, isGlobal: boolean): string;
|
|
44
|
+
export declare function recallHeading(entries: number, tokens: number, query: string): string;
|
|
45
|
+
/** One line when an agent memory import moved anything; its warnings go to stderr. */
|
|
46
|
+
export declare function printAgentImport(report: ImportReport, indent?: string): void;
|
|
47
|
+
/** The first hippo block in `text` and the agent whose current or shipped text it is; `owner` is undefined for an edited block. */
|
|
48
|
+
export declare function hippoBlock(text: string): {
|
|
49
|
+
start: number;
|
|
50
|
+
end: number;
|
|
51
|
+
eol: string;
|
|
52
|
+
inner: string;
|
|
53
|
+
owner?: string;
|
|
54
|
+
} | null;
|
|
55
|
+
/** Adds hippo's two Codex hooks and says what changed; each install ends on the trust reminder, since Codex skips an untrusted hook. */
|
|
56
|
+
export declare function installCodexMemoryHooks(indent: string): void;
|
|
57
|
+
/**
|
|
58
|
+
* Set up a machine-level daily runner that sweeps all registered Hippo
|
|
59
|
+
* workspaces.
|
|
60
|
+
* Linux/macOS: writes to user crontab.
|
|
61
|
+
* Windows: creates a scheduled task.
|
|
62
|
+
* Skips if already installed.
|
|
63
|
+
*/
|
|
64
|
+
export declare function setupDailySchedule(globalRoot: string): void;
|
|
65
|
+
export type CliFlags = Record<string, string | boolean | string[]>;
|
|
66
|
+
export type EngineFlags = Pick<RecallSearchOpts, 'usePhysics' | 'physicsConfig' | 'mmr' | 'mmrLambda' | 'localBump'>;
|
|
67
|
+
export declare function parseAsOfFlag(flags: CliFlags): string | undefined;
|
|
68
|
+
/** --physics forces physics, --classic forces BM25+cosine, else physics unless the config turns it off. */
|
|
69
|
+
export declare function engineFlags(flags: CliFlags, config: HippoConfig): EngineFlags;
|
|
70
|
+
/**
|
|
71
|
+
* Detached worker that counts re-reads, runs sleep, then capture. Invoked via the internal
|
|
72
|
+
* `__session-end-worker` subcommand (not user-facing). Failures in one stage
|
|
73
|
+
* do not block the other.
|
|
74
|
+
*/
|
|
75
|
+
export declare function collectHandoffEvidence(cwd: string, testStatus: HandoffEvidence['testStatus']): HandoffEvidence;
|
|
76
|
+
/** A folder without its own store never sleeps at session end, so its project's agent notes go to the global store here. */
|
|
77
|
+
export declare function logSessionEndImport(logFile: string | null, transcriptPath: string | undefined): void;
|
|
78
|
+
/**
|
|
79
|
+
* Best-effort log line for the snapshot-close step in
|
|
80
|
+
* `cmdSessionEndWorker`. `cmdSleep`/`cmdCapture` each tee console output to
|
|
81
|
+
* `logFile` only for their own duration (the tee is restored before this
|
|
82
|
+
* runs), so a plain `console.log` here would be silently discarded under
|
|
83
|
+
* the detached worker's `stdio: 'ignore'` — write straight to the file
|
|
84
|
+
* instead, matching capture.ts's `appendPreCompactLog` convention.
|
|
85
|
+
*/
|
|
86
|
+
export declare function appendSessionEndCloseLog(logFile: string | null, message: string, opts?: {
|
|
87
|
+
startFresh?: boolean;
|
|
88
|
+
}): void;
|
|
89
|
+
export declare function printActiveTaskSnapshot(snapshot: TaskSnapshot): void;
|
|
90
|
+
export declare function printSessionEvents(events: SessionEvent[]): void;
|
|
91
|
+
export declare function printHandoff(handoff: SessionHandoff): void;
|
|
92
|
+
export declare function cardStringFlag(flags: Record<string, string | boolean | string[]>, key: string): string | undefined;
|
|
93
|
+
export declare function hostSessionId(): string | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Compaction drops the pinned blocks the per-prompt hook injected
|
|
96
|
+
* earlier, so record a `reset` for the payload's session and the next prompt
|
|
97
|
+
* injects again even if nothing changed. `requiredSource` limits it to hook
|
|
98
|
+
* payloads with that `source` (SessionStart fires for other reasons too).
|
|
99
|
+
* Best-effort and silent: a malformed payload records nothing.
|
|
100
|
+
*/
|
|
101
|
+
export declare function resetHookInjection(hippoRoot: string, stdinText: string | undefined, requiredSource: string | null): void;
|
|
102
|
+
/**
|
|
103
|
+
* Run `fn` with console.log captured; returns the captured lines joined by
|
|
104
|
+
* newlines (what the same calls would have printed, minus the final newline).
|
|
105
|
+
*/
|
|
106
|
+
export declare function captureConsole(fn: () => void): string;
|
|
107
|
+
/**
|
|
108
|
+
* The store a Claude Code hook writes to: the project store when there is
|
|
109
|
+
* one, else an existing global store, else the project path (which the hook
|
|
110
|
+
* then skips, since hooks fire in every directory and must not create one).
|
|
111
|
+
* Pre-compact and compact-resume must agree, or a snapshot saved to one store
|
|
112
|
+
* is looked for in the other.
|
|
113
|
+
*/
|
|
114
|
+
export declare function hookStoreRoot(hippoRoot: string): string;
|
|
115
|
+
/**
|
|
116
|
+
* Run `fn` against the token ledger's store: the local store when it is
|
|
117
|
+
* initialized, else the global one (the per-prompt hook runs in directories
|
|
118
|
+
* without a local store). Best-effort: returns undefined and never throws,
|
|
119
|
+
* because a ledger failure must not break context or recall.
|
|
120
|
+
*/
|
|
121
|
+
export declare function withLedgerDb<T>(hippoRoot: string, fn: (db: ReturnType<typeof openHippoDb>) => T): T | undefined;
|
|
122
|
+
export declare function learnFromRepo(hippoRoot: string, repoPath: string, days: number, label?: string): {
|
|
123
|
+
added: number;
|
|
124
|
+
skipped: number;
|
|
125
|
+
lowInfo: number;
|
|
126
|
+
};
|
|
127
|
+
export declare const HOOK_MARKERS: {
|
|
128
|
+
start: string;
|
|
129
|
+
end: string;
|
|
130
|
+
};
|
|
131
|
+
export declare const HOOKS: Record<string, {
|
|
132
|
+
file: string;
|
|
133
|
+
content: string;
|
|
134
|
+
description: string;
|
|
135
|
+
}>;
|
|
136
|
+
export declare function resolveAuthRoot(hippoRoot: string, flags: Record<string, string | boolean | string[]>): string;
|
|
137
|
+
//# sourceMappingURL=shared.d.ts.map
|