somtum 1.3.3 → 1.5.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 +175 -90
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +12 -3
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/forget.d.ts +7 -0
- package/dist/cli/forget.d.ts.map +1 -1
- package/dist/cli/forget.js +44 -0
- package/dist/cli/forget.js.map +1 -1
- package/dist/cli/hook.d.ts.map +1 -1
- package/dist/cli/hook.js +14 -2
- package/dist/cli/hook.js.map +1 -1
- package/dist/cli/index.js +49 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +7 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/list.d.ts +9 -0
- package/dist/cli/list.d.ts.map +1 -0
- package/dist/cli/list.js +54 -0
- package/dist/cli/list.js.map +1 -0
- package/dist/cli/reset.d.ts +7 -0
- package/dist/cli/reset.d.ts.map +1 -0
- package/dist/cli/reset.js +66 -0
- package/dist/cli/reset.js.map +1 -0
- package/dist/cli/suggest_claude_md.d.ts +9 -0
- package/dist/cli/suggest_claude_md.d.ts.map +1 -0
- package/dist/cli/suggest_claude_md.js +106 -0
- package/dist/cli/suggest_claude_md.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -7
- package/dist/config.js.map +1 -1
- package/dist/core/schema.d.ts +51 -0
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +18 -0
- package/dist/core/schema.js.map +1 -1
- package/dist/core/store.d.ts +8 -1
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +61 -6
- package/dist/core/store.js.map +1 -1
- package/dist/dashboard/index.html +49 -6
- package/dist/db/migrations/004_scope_and_staleness.sql +11 -0
- package/dist/hooks/post_session.d.ts.map +1 -1
- package/dist/hooks/post_session.js +50 -2
- package/dist/hooks/post_session.js.map +1 -1
- package/dist/hooks/pre_prompt.d.ts.map +1 -1
- package/dist/hooks/pre_prompt.js +231 -48
- package/dist/hooks/pre_prompt.js.map +1 -1
- package/dist/hooks/pre_read.d.ts.map +1 -1
- package/dist/hooks/pre_read.js +7 -1
- package/dist/hooks/pre_read.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +35 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +33 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +68 -3
- package/dist/mcp/tools.js.map +1 -1
- package/package.json +1 -1
package/dist/core/schema.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare const ObservationKind: z.ZodEnum<["decision", "learning", "bugfix", "file_summary", "command", "other"]>;
|
|
3
3
|
export type ObservationKind = z.infer<typeof ObservationKind>;
|
|
4
|
+
export declare const ObservationScope: z.ZodEnum<["project", "workspace", "global"]>;
|
|
5
|
+
export type ObservationScope = z.infer<typeof ObservationScope>;
|
|
4
6
|
export declare const ObservationSchema: z.ZodObject<{
|
|
5
7
|
id: z.ZodString;
|
|
6
8
|
project_id: z.ZodString;
|
|
@@ -16,6 +18,8 @@ export declare const ObservationSchema: z.ZodObject<{
|
|
|
16
18
|
superseded_by: z.ZodNullable<z.ZodString>;
|
|
17
19
|
embedding: z.ZodNullable<z.ZodType<Buffer<ArrayBufferLike>, z.ZodTypeDef, Buffer<ArrayBufferLike>>>;
|
|
18
20
|
deleted_at: z.ZodNullable<z.ZodNumber>;
|
|
21
|
+
scope: z.ZodDefault<z.ZodEnum<["project", "workspace", "global"]>>;
|
|
22
|
+
last_confirmed_at: z.ZodNullable<z.ZodNumber>;
|
|
19
23
|
}, "strip", z.ZodTypeAny, {
|
|
20
24
|
id: string;
|
|
21
25
|
project_id: string;
|
|
@@ -31,6 +35,8 @@ export declare const ObservationSchema: z.ZodObject<{
|
|
|
31
35
|
superseded_by: string | null;
|
|
32
36
|
embedding: Buffer<ArrayBufferLike> | null;
|
|
33
37
|
deleted_at: number | null;
|
|
38
|
+
scope: "project" | "workspace" | "global";
|
|
39
|
+
last_confirmed_at: number | null;
|
|
34
40
|
}, {
|
|
35
41
|
id: string;
|
|
36
42
|
project_id: string;
|
|
@@ -46,6 +52,8 @@ export declare const ObservationSchema: z.ZodObject<{
|
|
|
46
52
|
superseded_by: string | null;
|
|
47
53
|
embedding: Buffer<ArrayBufferLike> | null;
|
|
48
54
|
deleted_at: number | null;
|
|
55
|
+
last_confirmed_at: number | null;
|
|
56
|
+
scope?: "project" | "workspace" | "global" | undefined;
|
|
49
57
|
}>;
|
|
50
58
|
export type Observation = z.infer<typeof ObservationSchema>;
|
|
51
59
|
export declare const ObservationInputSchema: z.ZodObject<{
|
|
@@ -60,6 +68,7 @@ export declare const ObservationInputSchema: z.ZodObject<{
|
|
|
60
68
|
created_at: z.ZodOptional<z.ZodNumber>;
|
|
61
69
|
tokens_saved: z.ZodDefault<z.ZodNumber>;
|
|
62
70
|
tokens_spent: z.ZodDefault<z.ZodNumber>;
|
|
71
|
+
scope: z.ZodDefault<z.ZodEnum<["project", "workspace", "global"]>>;
|
|
63
72
|
}, "strip", z.ZodTypeAny, {
|
|
64
73
|
project_id: string;
|
|
65
74
|
session_id: string;
|
|
@@ -70,6 +79,7 @@ export declare const ObservationInputSchema: z.ZodObject<{
|
|
|
70
79
|
tags: string[];
|
|
71
80
|
tokens_saved: number;
|
|
72
81
|
tokens_spent: number;
|
|
82
|
+
scope: "project" | "workspace" | "global";
|
|
73
83
|
id?: string | undefined;
|
|
74
84
|
created_at?: number | undefined;
|
|
75
85
|
}, {
|
|
@@ -84,8 +94,26 @@ export declare const ObservationInputSchema: z.ZodObject<{
|
|
|
84
94
|
created_at?: number | undefined;
|
|
85
95
|
tokens_saved?: number | undefined;
|
|
86
96
|
tokens_spent?: number | undefined;
|
|
97
|
+
scope?: "project" | "workspace" | "global" | undefined;
|
|
87
98
|
}>;
|
|
88
99
|
export type ObservationInput = z.input<typeof ObservationInputSchema>;
|
|
100
|
+
export declare const ObservationUpdateSchema: z.ZodObject<{
|
|
101
|
+
title: z.ZodOptional<z.ZodString>;
|
|
102
|
+
body: z.ZodOptional<z.ZodString>;
|
|
103
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
104
|
+
files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
105
|
+
}, "strip", z.ZodTypeAny, {
|
|
106
|
+
title?: string | undefined;
|
|
107
|
+
body?: string | undefined;
|
|
108
|
+
files?: string[] | undefined;
|
|
109
|
+
tags?: string[] | undefined;
|
|
110
|
+
}, {
|
|
111
|
+
title?: string | undefined;
|
|
112
|
+
body?: string | undefined;
|
|
113
|
+
files?: string[] | undefined;
|
|
114
|
+
tags?: string[] | undefined;
|
|
115
|
+
}>;
|
|
116
|
+
export type ObservationUpdate = z.infer<typeof ObservationUpdateSchema>;
|
|
89
117
|
export declare const CacheEntrySchema: z.ZodObject<{
|
|
90
118
|
id: z.ZodString;
|
|
91
119
|
prompt_hash: z.ZodString;
|
|
@@ -376,6 +404,19 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
376
404
|
backend?: string | undefined;
|
|
377
405
|
remote?: string | null | undefined;
|
|
378
406
|
}>>;
|
|
407
|
+
injection: z.ZodDefault<z.ZodObject<{
|
|
408
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
409
|
+
k: z.ZodDefault<z.ZodNumber>;
|
|
410
|
+
max_chars: z.ZodDefault<z.ZodNumber>;
|
|
411
|
+
}, "strip", z.ZodTypeAny, {
|
|
412
|
+
enabled: boolean;
|
|
413
|
+
k: number;
|
|
414
|
+
max_chars: number;
|
|
415
|
+
}, {
|
|
416
|
+
enabled?: boolean | undefined;
|
|
417
|
+
k?: number | undefined;
|
|
418
|
+
max_chars?: number | undefined;
|
|
419
|
+
}>>;
|
|
379
420
|
}, "strip", z.ZodTypeAny, {
|
|
380
421
|
extraction: {
|
|
381
422
|
model: string;
|
|
@@ -420,6 +461,11 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
420
461
|
backend: string;
|
|
421
462
|
remote: string | null;
|
|
422
463
|
};
|
|
464
|
+
injection: {
|
|
465
|
+
enabled: boolean;
|
|
466
|
+
k: number;
|
|
467
|
+
max_chars: number;
|
|
468
|
+
};
|
|
423
469
|
}, {
|
|
424
470
|
extraction?: {
|
|
425
471
|
model?: string | undefined;
|
|
@@ -464,6 +510,11 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
464
510
|
backend?: string | undefined;
|
|
465
511
|
remote?: string | null | undefined;
|
|
466
512
|
} | undefined;
|
|
513
|
+
injection?: {
|
|
514
|
+
enabled?: boolean | undefined;
|
|
515
|
+
k?: number | undefined;
|
|
516
|
+
max_chars?: number | undefined;
|
|
517
|
+
} | undefined;
|
|
467
518
|
}>;
|
|
468
519
|
export type Config = z.infer<typeof ConfigSchema>;
|
|
469
520
|
export type ConfigInput = z.input<typeof ConfigSchema>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,eAAe,mFAO1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,eAAe,mFAO1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,eAAO,MAAM,gBAAgB,+CAA6C,CAAC;AAC3E,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiB5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAajC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;EAKlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAe3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;EAOhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;EAQhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;EAMrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAElC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,iBAAiB,sDAAoD,CAAC;AACnF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6EvB,CAAC;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC"}
|
package/dist/core/schema.js
CHANGED
|
@@ -7,6 +7,7 @@ export const ObservationKind = z.enum([
|
|
|
7
7
|
'command',
|
|
8
8
|
'other',
|
|
9
9
|
]);
|
|
10
|
+
export const ObservationScope = z.enum(['project', 'workspace', 'global']);
|
|
10
11
|
export const ObservationSchema = z.object({
|
|
11
12
|
id: z.string().min(1),
|
|
12
13
|
project_id: z.string().min(1),
|
|
@@ -22,6 +23,8 @@ export const ObservationSchema = z.object({
|
|
|
22
23
|
superseded_by: z.string().nullable(),
|
|
23
24
|
embedding: z.instanceof(Buffer).nullable(),
|
|
24
25
|
deleted_at: z.number().int().nullable(),
|
|
26
|
+
scope: ObservationScope.default('project'),
|
|
27
|
+
last_confirmed_at: z.number().int().nullable(),
|
|
25
28
|
});
|
|
26
29
|
export const ObservationInputSchema = z.object({
|
|
27
30
|
id: z.string().min(1).optional(),
|
|
@@ -35,6 +38,13 @@ export const ObservationInputSchema = z.object({
|
|
|
35
38
|
created_at: z.number().int().nonnegative().optional(),
|
|
36
39
|
tokens_saved: z.number().int().nonnegative().default(0),
|
|
37
40
|
tokens_spent: z.number().int().nonnegative().default(0),
|
|
41
|
+
scope: ObservationScope.default('project'),
|
|
42
|
+
});
|
|
43
|
+
export const ObservationUpdateSchema = z.object({
|
|
44
|
+
title: z.string().min(1).max(80).optional(),
|
|
45
|
+
body: z.string().min(1).optional(),
|
|
46
|
+
tags: z.array(z.string()).optional(),
|
|
47
|
+
files: z.array(z.string()).optional(),
|
|
38
48
|
});
|
|
39
49
|
export const CacheEntrySchema = z.object({
|
|
40
50
|
id: z.string(),
|
|
@@ -149,5 +159,13 @@ export const ConfigSchema = z.object({
|
|
|
149
159
|
remote: z.string().nullable().default(null),
|
|
150
160
|
})
|
|
151
161
|
.default({}),
|
|
162
|
+
injection: z
|
|
163
|
+
.object({
|
|
164
|
+
// Auto-inject top-k relevant memories into every UserPromptSubmit context.
|
|
165
|
+
enabled: z.boolean().default(true),
|
|
166
|
+
k: z.number().int().positive().default(5),
|
|
167
|
+
max_chars: z.number().int().positive().default(3000),
|
|
168
|
+
})
|
|
169
|
+
.default({}),
|
|
152
170
|
});
|
|
153
171
|
//# sourceMappingURL=schema.js.map
|
package/dist/core/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC;IACpC,UAAU;IACV,UAAU;IACV,QAAQ;IACR,cAAc;IACd,SAAS;IACT,OAAO;CACR,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAChC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAC1C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAC5C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAC5C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IAC1C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/core/store.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DB } from './db.js';
|
|
2
|
-
import { type Observation, type ObservationInput, type ObservationKind } from './schema.js';
|
|
2
|
+
import { type Observation, type ObservationInput, type ObservationUpdate, type ObservationKind, type ObservationScope } from './schema.js';
|
|
3
3
|
export interface InsertOptions {
|
|
4
4
|
redactPatterns?: string[];
|
|
5
5
|
}
|
|
@@ -7,6 +7,13 @@ export declare class MemoryStore {
|
|
|
7
7
|
private readonly db;
|
|
8
8
|
constructor(db: DB);
|
|
9
9
|
insert(input: ObservationInput, options?: InsertOptions): Observation;
|
|
10
|
+
update(id: string, patch: ObservationUpdate, options?: InsertOptions): Observation | null;
|
|
11
|
+
confirmRetrieval(id: string, now?: number): void;
|
|
12
|
+
listStale(projectId: string, olderThanDays: number, opts?: {
|
|
13
|
+
limit?: number;
|
|
14
|
+
}): Observation[];
|
|
15
|
+
countStale(projectId: string, olderThanDays: number): number;
|
|
16
|
+
listByScope(scope: ObservationScope, limit?: number): Observation[];
|
|
10
17
|
get(id: string): Observation | null;
|
|
11
18
|
listByProject(projectId: string, options?: {
|
|
12
19
|
includeDeleted?: boolean;
|
package/dist/core/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AA4CrB,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,EAAE;IAEnC,MAAM,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,GAAE,aAAkB,GAAG,WAAW;IAwCzE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,GAAE,aAAkB,GAAG,WAAW,GAAG,IAAI;IA0B7F,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,IAAI;IAO5D,SAAS,CACP,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAC5B,WAAW,EAAE;IAahB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM;IAa5D,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,SAAK,GAAG,WAAW,EAAE;IAW/D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAOnC,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;QAAE,cAAc,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GACzD,WAAW,EAAE;IAWhB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAO/B,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAOzC,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAIjD,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,GAAE,MAAa,GAAG,WAAW,EAAE;IAW7E,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE;IAU1E,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC;IAoB/D,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAU3C,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAY3C,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IAWrD,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,WAAW,EAAE;IAY1E,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,SAAK,GAAG,WAAW,EAAE;IAa/E,iBAAiB,CACf,SAAS,EAAE,MAAM,EACjB,KAAK,SAAK,GACT;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE;CAwBpD"}
|
package/dist/core/store.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ulid } from 'ulid';
|
|
2
|
-
import { ObservationInputSchema, ObservationSchema, } from './schema.js';
|
|
2
|
+
import { ObservationInputSchema, ObservationUpdateSchema, ObservationSchema, } from './schema.js';
|
|
3
3
|
import { redactAll } from './privacy.js';
|
|
4
4
|
function rowToObservation(row) {
|
|
5
5
|
return ObservationSchema.parse({
|
|
@@ -17,6 +17,8 @@ function rowToObservation(row) {
|
|
|
17
17
|
superseded_by: row.superseded_by,
|
|
18
18
|
embedding: row.embedding,
|
|
19
19
|
deleted_at: row.deleted_at,
|
|
20
|
+
scope: row.scope ?? 'project',
|
|
21
|
+
last_confirmed_at: row.last_confirmed_at ?? null,
|
|
20
22
|
});
|
|
21
23
|
}
|
|
22
24
|
export class MemoryStore {
|
|
@@ -31,19 +33,72 @@ export class MemoryStore {
|
|
|
31
33
|
const body = redactAll(parsed.body, patterns);
|
|
32
34
|
const id = parsed.id ?? ulid();
|
|
33
35
|
const created_at = parsed.created_at ?? Date.now();
|
|
34
|
-
|
|
35
|
-
// instead of hanging on the serialization boundary.
|
|
36
|
+
const scope = parsed.scope ?? 'project';
|
|
36
37
|
const txn = this.db.transaction(() => {
|
|
37
38
|
this.db
|
|
38
39
|
.prepare(`INSERT INTO observations
|
|
39
40
|
(id, project_id, session_id, kind, title, body, files, tags,
|
|
40
|
-
created_at, tokens_saved, tokens_spent, superseded_by, embedding, deleted_at
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
created_at, tokens_saved, tokens_spent, superseded_by, embedding, deleted_at,
|
|
42
|
+
scope, last_confirmed_at)
|
|
43
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, NULL, NULL, ?, NULL)`)
|
|
44
|
+
.run(id, parsed.project_id, parsed.session_id, parsed.kind, title, body, JSON.stringify(parsed.files), JSON.stringify(parsed.tags), created_at, parsed.tokens_saved, parsed.tokens_spent, scope);
|
|
43
45
|
});
|
|
44
46
|
txn.immediate();
|
|
45
47
|
return this.get(id);
|
|
46
48
|
}
|
|
49
|
+
update(id, patch, options = {}) {
|
|
50
|
+
const parsed = ObservationUpdateSchema.parse(patch);
|
|
51
|
+
const existing = this.get(id);
|
|
52
|
+
if (!existing || existing.deleted_at !== null)
|
|
53
|
+
return null;
|
|
54
|
+
const patterns = options.redactPatterns ?? [];
|
|
55
|
+
const title = parsed.title !== undefined ? redactAll(parsed.title, patterns) : existing.title;
|
|
56
|
+
const body = parsed.body !== undefined ? redactAll(parsed.body, patterns) : existing.body;
|
|
57
|
+
const files = parsed.files !== undefined ? JSON.stringify(parsed.files) : JSON.stringify(existing.files);
|
|
58
|
+
const tags = parsed.tags !== undefined ? JSON.stringify(parsed.tags) : JSON.stringify(existing.tags);
|
|
59
|
+
const txn = this.db.transaction(() => {
|
|
60
|
+
this.db
|
|
61
|
+
.prepare(`UPDATE observations SET title = ?, body = ?, files = ?, tags = ? WHERE id = ?`)
|
|
62
|
+
.run(title, body, files, tags, id);
|
|
63
|
+
});
|
|
64
|
+
txn.immediate();
|
|
65
|
+
return this.get(id);
|
|
66
|
+
}
|
|
67
|
+
// Bump last_confirmed_at to signal that this memory was retrieved and was useful.
|
|
68
|
+
confirmRetrieval(id, now = Date.now()) {
|
|
69
|
+
this.db
|
|
70
|
+
.prepare(`UPDATE observations SET last_confirmed_at = ? WHERE id = ?`)
|
|
71
|
+
.run(now, id);
|
|
72
|
+
}
|
|
73
|
+
// Observations that have never been confirmed and are older than olderThanDays.
|
|
74
|
+
listStale(projectId, olderThanDays, opts = {}) {
|
|
75
|
+
const cutoff = Date.now() - olderThanDays * 24 * 60 * 60 * 1000;
|
|
76
|
+
const rows = this.db
|
|
77
|
+
.prepare(`SELECT * FROM observations
|
|
78
|
+
WHERE project_id = ? AND deleted_at IS NULL
|
|
79
|
+
AND last_confirmed_at IS NULL AND created_at < ?
|
|
80
|
+
ORDER BY created_at ASC LIMIT ?`)
|
|
81
|
+
.all(projectId, cutoff, Math.floor(opts.limit ?? 100));
|
|
82
|
+
return rows.map(rowToObservation);
|
|
83
|
+
}
|
|
84
|
+
countStale(projectId, olderThanDays) {
|
|
85
|
+
const cutoff = Date.now() - olderThanDays * 24 * 60 * 60 * 1000;
|
|
86
|
+
const row = this.db
|
|
87
|
+
.prepare(`SELECT COUNT(*) AS n FROM observations
|
|
88
|
+
WHERE project_id = ? AND deleted_at IS NULL
|
|
89
|
+
AND last_confirmed_at IS NULL AND created_at < ?`)
|
|
90
|
+
.get(projectId, cutoff);
|
|
91
|
+
return row.n;
|
|
92
|
+
}
|
|
93
|
+
// All non-deleted observations with scope = 'workspace' or 'global' for any project.
|
|
94
|
+
listByScope(scope, limit = 50) {
|
|
95
|
+
const rows = this.db
|
|
96
|
+
.prepare(`SELECT * FROM observations
|
|
97
|
+
WHERE scope = ? AND deleted_at IS NULL
|
|
98
|
+
ORDER BY tokens_saved DESC, created_at DESC LIMIT ?`)
|
|
99
|
+
.all(scope, Math.floor(limit));
|
|
100
|
+
return rows.map(rowToObservation);
|
|
101
|
+
}
|
|
47
102
|
get(id) {
|
|
48
103
|
const row = this.db.prepare(`SELECT * FROM observations WHERE id = ?`).get(id);
|
|
49
104
|
return row ? rowToObservation(row) : null;
|
package/dist/core/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EACL,sBAAsB,EACtB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Somtum — Memory</title>
|
|
6
|
+
<title>Somtum v1.4.0 — Memory</title>
|
|
7
7
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
9
|
<link
|
|
@@ -572,6 +572,22 @@
|
|
|
572
572
|
.kf-file_summary { border-color: rgba(56,189,248,0.3); background: rgba(56,189,248,0.06); color: #38bdf8; }
|
|
573
573
|
.kf-other { border-color: rgba(107,99,80,0.3); background: rgba(107,99,80,0.07); color: #9e9278; }
|
|
574
574
|
.kf-all { border-color: rgba(240,160,48,0.35); background: rgba(240,160,48,0.08); color: #f0a030; }
|
|
575
|
+
|
|
576
|
+
/* Scope badge on memory cards */
|
|
577
|
+
.mc-scope {
|
|
578
|
+
font-size: 8px; font-weight: 700;
|
|
579
|
+
text-transform: uppercase; letter-spacing: 0.08em;
|
|
580
|
+
padding: 1px 5px; border-radius: 3px;
|
|
581
|
+
background: rgba(167,139,250,0.12);
|
|
582
|
+
color: #a78bfa;
|
|
583
|
+
border: 1px solid rgba(167,139,250,0.25);
|
|
584
|
+
flex-shrink: 0;
|
|
585
|
+
}
|
|
586
|
+
.mc-scope.global {
|
|
587
|
+
background: rgba(240,160,48,0.12);
|
|
588
|
+
color: #f0a030;
|
|
589
|
+
border-color: rgba(240,160,48,0.25);
|
|
590
|
+
}
|
|
575
591
|
</style>
|
|
576
592
|
</head>
|
|
577
593
|
<body>
|
|
@@ -764,7 +780,7 @@
|
|
|
764
780
|
// ─── Strategy buttons ─────────────────────────────────────────────────────────
|
|
765
781
|
function buildStrategyBtns() {
|
|
766
782
|
const wrap = document.getElementById('strategy-btns');
|
|
767
|
-
['bm25', 'hybrid', 'embeddings'].forEach((s) => {
|
|
783
|
+
['bm25', 'hybrid', 'embeddings', 'index'].forEach((s) => {
|
|
768
784
|
const btn = h('button', {
|
|
769
785
|
class: 'strat-btn' + (s === S.strategy ? ' active' : ''),
|
|
770
786
|
onclick: () => {
|
|
@@ -860,9 +876,13 @@
|
|
|
860
876
|
);
|
|
861
877
|
const preview = m.body ? h('div', { class: 'mc-body' }, m.body) : null;
|
|
862
878
|
const tags = (m.tags || []).slice(0, 3).map((t) => h('span', { class: 'mc-tag' }, t));
|
|
879
|
+
const scopeBadge = m.scope && m.scope !== 'project'
|
|
880
|
+
? h('span', { class: 'mc-scope' + (m.scope === 'global' ? ' global' : ''), title: m.scope + ' scope' }, m.scope)
|
|
881
|
+
: null;
|
|
863
882
|
const footer = h('div', { class: 'mc-footer' },
|
|
864
883
|
h('span', { class: 'mc-time' }, relTime(m.created_at)),
|
|
865
884
|
h('div', { class: 'mc-tags' }, ...tags),
|
|
885
|
+
scopeBadge,
|
|
866
886
|
);
|
|
867
887
|
card.append(forget, head);
|
|
868
888
|
if (preview) card.append(preview);
|
|
@@ -913,6 +933,8 @@
|
|
|
913
933
|
h('span', {}, relTime(m.created_at)),
|
|
914
934
|
saved ? h('span', { style: 'color:var(--accent-g)' }, saved) : null,
|
|
915
935
|
spent ? h('span', {}, spent) : null,
|
|
936
|
+
m.scope && m.scope !== 'project' ? h('span', { style: 'color:var(--accent-v)' }, 'scope: ' + m.scope) : null,
|
|
937
|
+
m.last_confirmed_at ? h('span', {}, 'confirmed ' + relTime(m.last_confirmed_at)) : null,
|
|
916
938
|
),
|
|
917
939
|
h('div', { class: 'detail-body' }, m.body || ''),
|
|
918
940
|
fileChips.length || tagChips.length
|
|
@@ -1046,10 +1068,11 @@
|
|
|
1046
1068
|
const cc = fs.cache || {};
|
|
1047
1069
|
const cacheCard = card('Cache performance');
|
|
1048
1070
|
[
|
|
1049
|
-
['Hit rate',
|
|
1050
|
-
['Hits',
|
|
1051
|
-
['Misses',
|
|
1052
|
-
['Entries',
|
|
1071
|
+
['Hit rate', cc.hit_rate != null ? (cc.hit_rate * 100).toFixed(1) + '%' : '—', 'var(--accent-g)'],
|
|
1072
|
+
['Hits', cc.hit_count ?? 0, 'var(--accent-g)'],
|
|
1073
|
+
['Misses', cc.miss_count ?? 0, 'var(--muted2)'],
|
|
1074
|
+
['Entries', cc.entry_count ?? 0, 'var(--accent-c)'],
|
|
1075
|
+
['False hits', cc.false_hit_count ?? 0, 'var(--accent-r)'],
|
|
1053
1076
|
].forEach(([lbl, val, color]) => {
|
|
1054
1077
|
cacheCard.append(h('div', { class: 'cache-stat' },
|
|
1055
1078
|
h('span', { class: 'cache-stat-lbl' }, lbl),
|
|
@@ -1085,6 +1108,26 @@
|
|
|
1085
1108
|
});
|
|
1086
1109
|
if (!tf.length) tfCard.append(h('div', { class: 'empty' }, h('div', { class: 'empty-sub' }, 'No file references yet')));
|
|
1087
1110
|
grid.append(wrap(tfCard));
|
|
1111
|
+
|
|
1112
|
+
// 5. Memory health
|
|
1113
|
+
const mems = S.data?.memories ?? [];
|
|
1114
|
+
const staleThreshold = Date.now() - 30 * 24 * 60 * 60 * 1000;
|
|
1115
|
+
const staleCount = mems.filter((m) => !m.last_confirmed_at || new Date(m.last_confirmed_at).getTime() < staleThreshold).length;
|
|
1116
|
+
const workspaceCount = mems.filter((m) => m.scope === 'workspace').length;
|
|
1117
|
+
const globalCount = mems.filter((m) => m.scope === 'global').length;
|
|
1118
|
+
const healthCard = card('Memory health');
|
|
1119
|
+
[
|
|
1120
|
+
['Total', mems.length, 'var(--text)'],
|
|
1121
|
+
['Stale (>30d)', staleCount, 'var(--accent-r)'],
|
|
1122
|
+
['Workspace', workspaceCount, 'var(--accent-v)'],
|
|
1123
|
+
['Global', globalCount, 'var(--accent)'],
|
|
1124
|
+
].forEach(([lbl, val, color]) => {
|
|
1125
|
+
healthCard.append(h('div', { class: 'cache-stat' },
|
|
1126
|
+
h('span', { class: 'cache-stat-lbl' }, lbl),
|
|
1127
|
+
h('span', { class: 'cache-stat-val', style: `color:${color}` }, String(val)),
|
|
1128
|
+
));
|
|
1129
|
+
});
|
|
1130
|
+
grid.append(wrap(healthCard));
|
|
1088
1131
|
}
|
|
1089
1132
|
|
|
1090
1133
|
function card(title) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- 004_scope_and_staleness.sql
|
|
2
|
+
-- Adds observation scope (project/workspace/global) for cross-project memory sharing,
|
|
3
|
+
-- and last_confirmed_at to track staleness (bumped on every successful retrieval).
|
|
4
|
+
|
|
5
|
+
ALTER TABLE observations ADD COLUMN scope TEXT NOT NULL DEFAULT 'project'
|
|
6
|
+
CHECK (scope IN ('project','workspace','global'));
|
|
7
|
+
|
|
8
|
+
ALTER TABLE observations ADD COLUMN last_confirmed_at INTEGER;
|
|
9
|
+
|
|
10
|
+
CREATE INDEX IF NOT EXISTS idx_observations_scope ON observations(scope);
|
|
11
|
+
CREATE INDEX IF NOT EXISTS idx_observations_confirmed ON observations(last_confirmed_at);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post_session.d.ts","sourceRoot":"","sources":["../../src/hooks/post_session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"post_session.d.ts","sourceRoot":"","sources":["../../src/hooks/post_session.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAU,KAAK,EAAE,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAkB9B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAY1B,CAAC;AAEL,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ9E;AAsKD,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,EAAE,CAAC,EAAE,EAAE,CAAC;IACR,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,WAAW,EACpB,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,SAAS,CAAC,CAyIpB;AAYD,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA6B1C"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { readFileSync, appendFileSync } from 'node:fs';
|
|
1
|
+
import { readFileSync, appendFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
2
2
|
import { isAbsolute, join, resolve as resolvePath } from 'node:path';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
|
+
import { createHash } from 'node:crypto';
|
|
4
5
|
import { ulid } from 'ulid';
|
|
5
6
|
import { z } from 'zod';
|
|
6
7
|
import Anthropic from '@anthropic-ai/sdk';
|
|
@@ -12,6 +13,7 @@ import { extract, anthropicCaller, claudeCodeCaller, estimateTokensSaved, } from
|
|
|
12
13
|
import { resolveProjectId, projectNameFromCwd } from '../core/project_id.js';
|
|
13
14
|
import { countTokens } from '../core/tokens.js';
|
|
14
15
|
import { projectDir } from '../config.js';
|
|
16
|
+
import { Bm25Retriever } from '../core/retriever/bm25.js';
|
|
15
17
|
import { parseTranscript, renderTurns, extractPromptResponsePairs } from '../core/transcript.js';
|
|
16
18
|
import { PromptCache, hashPrompt } from '../core/cache.js';
|
|
17
19
|
import { fingerprintFiles } from '../core/fingerprint.js';
|
|
@@ -144,6 +146,38 @@ async function populateFileSummaries(db, turns, opts) {
|
|
|
144
146
|
}
|
|
145
147
|
return generated;
|
|
146
148
|
}
|
|
149
|
+
// Write top-k memories to a warm-start file after PreCompact so the next
|
|
150
|
+
// UserPromptSubmit can restore context into the fresh post-compaction session.
|
|
151
|
+
function writeWarmStart(db, projectId, k = 8) {
|
|
152
|
+
try {
|
|
153
|
+
const retriever = new Bm25Retriever(db);
|
|
154
|
+
// Use a broad "recent" query — we want the most useful memories overall, not
|
|
155
|
+
// query-specific ones, because we don't know what comes next.
|
|
156
|
+
const results = retriever.search('recent decisions learnings bugs commands', {
|
|
157
|
+
k,
|
|
158
|
+
projectId,
|
|
159
|
+
});
|
|
160
|
+
// retriever.search is async but Bm25Retriever is synchronous under the hood;
|
|
161
|
+
// we await-via-then to stay non-blocking.
|
|
162
|
+
void Promise.resolve(results).then((hits) => {
|
|
163
|
+
if (hits.length === 0)
|
|
164
|
+
return;
|
|
165
|
+
const lines = hits
|
|
166
|
+
.map((r) => `[${r.observation.kind}] ${r.observation.title}\n${r.observation.body}`)
|
|
167
|
+
.join('\n---\n');
|
|
168
|
+
const context = `[somtum warm-start — context restored after compaction]\n${lines}\n[/somtum warm-start]`;
|
|
169
|
+
const prefix = createHash('sha1').update(projectId).digest('hex').slice(0, 12);
|
|
170
|
+
const dir = join(homedir(), '.somtum', 'warmstart');
|
|
171
|
+
mkdirSync(dir, { recursive: true });
|
|
172
|
+
// Include a timestamp so concurrent windows on the same project don't clobber each other.
|
|
173
|
+
const path = join(dir, `ws_${prefix}_${Date.now()}.json`);
|
|
174
|
+
writeFileSync(path, JSON.stringify({ project_id: projectId, created_at: Date.now(), context }), 'utf8');
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// Non-fatal: warm-start is a best-effort enhancement.
|
|
179
|
+
}
|
|
180
|
+
}
|
|
147
181
|
export async function runPostSession(payload, opts = {}) {
|
|
148
182
|
const parsed = HookPayloadSchema.parse(payload);
|
|
149
183
|
const cwd = opts.cwd ?? parsed.cwd ?? process.cwd();
|
|
@@ -159,7 +193,18 @@ export async function runPostSession(payload, opts = {}) {
|
|
|
159
193
|
try {
|
|
160
194
|
const store = new MemoryStore(db);
|
|
161
195
|
const resolved = resolveTranscript(parsed);
|
|
162
|
-
|
|
196
|
+
// Cap transcript size to stay within model context limits.
|
|
197
|
+
// At ~4 chars/token, 60k tokens ≈ 240 KB of text. Anything beyond that
|
|
198
|
+
// risks a context-limit error in Haiku; we take the tail (most recent turns).
|
|
199
|
+
const MAX_TRANSCRIPT_TOKENS = 60_000;
|
|
200
|
+
const rawTranscript = resolved.text;
|
|
201
|
+
const transcript = countTokens(rawTranscript) > MAX_TRANSCRIPT_TOKENS
|
|
202
|
+
? (() => {
|
|
203
|
+
const charBudget = MAX_TRANSCRIPT_TOKENS * 4;
|
|
204
|
+
hookLog(`[post_session] WARN: transcript truncated to last ~${charBudget} chars (was ${rawTranscript.length})`);
|
|
205
|
+
return rawTranscript.slice(-charBudget);
|
|
206
|
+
})()
|
|
207
|
+
: rawTranscript;
|
|
163
208
|
const transcriptTokens = countTokens(transcript);
|
|
164
209
|
// Prefer the direct API when a key is present (faster, explicit model choice).
|
|
165
210
|
// Fall back to the claude CLI so Claude Code subscribers need no separate key.
|
|
@@ -232,6 +277,9 @@ export async function runPostSession(payload, opts = {}) {
|
|
|
232
277
|
outputPath: indexPath,
|
|
233
278
|
now: opts.now ?? Date.now(),
|
|
234
279
|
});
|
|
280
|
+
if (parsed.hook_event_name === 'PreCompact') {
|
|
281
|
+
writeWarmStart(db, projectId);
|
|
282
|
+
}
|
|
235
283
|
return {
|
|
236
284
|
projectId,
|
|
237
285
|
inserted,
|