sage-mem 0.8.0 → 0.9.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 +28 -0
- package/lib/autodream/config.js +13 -0
- package/lib/autodream/engine.js +78 -1
- package/lib/autodream/report.js +29 -0
- package/lib/autodream/settings.js +2 -0
- package/lib/autodream-audit.js +46 -5
- package/lib/autodream-tools.js +10 -11
- package/lib/client.js +1521 -100
- package/lib/index.js +436 -11
- package/lib/memory/access.js +220 -0
- package/lib/memory/archive.js +91 -0
- package/lib/memory/scan.js +130 -7
- package/lib/typert.host.js +287 -1
- package/package.json +4 -2
package/lib/typert.host.js
CHANGED
|
@@ -25,6 +25,11 @@ const starmapStarSchema = z.object({
|
|
|
25
25
|
'desc': z.string().readonly(),
|
|
26
26
|
'bytes': z.number().readonly(),
|
|
27
27
|
'mtimeMs': z.number().readonly(),
|
|
28
|
+
// 归档星:`archived` 每颗星都有(活动星是 false);两个留痕字段只对归档星出现,
|
|
29
|
+
// 且旧版 autodream 工具归档的文件没有它们 —— 所以 optional,不是 nullable。
|
|
30
|
+
'archived': z.boolean().readonly(),
|
|
31
|
+
'archivedAt': z.string().readonly().optional(),
|
|
32
|
+
'archivedReason': z.string().readonly().optional(),
|
|
28
33
|
}).readonly()
|
|
29
34
|
const starmapListSchema = z.object({
|
|
30
35
|
'count': z.number().readonly(),
|
|
@@ -63,6 +68,152 @@ const deleteResultSchema = z.object({
|
|
|
63
68
|
'error': z.string().readonly().optional(),
|
|
64
69
|
}).readonly()
|
|
65
70
|
|
|
71
|
+
// ── 归档区(v0.9.0 档案馆)─────────────────────────────────────────────────
|
|
72
|
+
// 归档条目的形状 = fileSchema + 两个留痕字段。留痕可能为空串(旧版 autodream 工具
|
|
73
|
+
// 直接移文件、不写留痕),所以是 string 而不是 optional —— 面板永远能拿到一个值。
|
|
74
|
+
const archivedFileSchema = z.object({
|
|
75
|
+
'file': z.string().readonly(),
|
|
76
|
+
'type': z.string().readonly(),
|
|
77
|
+
'description': z.string().readonly(),
|
|
78
|
+
'size': z.number().readonly(),
|
|
79
|
+
'tags': z.array(z.string()).readonly(),
|
|
80
|
+
'archivedAt': z.string().readonly(),
|
|
81
|
+
'archivedReason': z.string().readonly(),
|
|
82
|
+
}).readonly()
|
|
83
|
+
const archivedListSchema = z.object({
|
|
84
|
+
'count': z.number().readonly(),
|
|
85
|
+
'files': z.array(archivedFileSchema).readonly(),
|
|
86
|
+
}).readonly()
|
|
87
|
+
|
|
88
|
+
// 归档缘由:用户输入的一句话。真正的 YAML 转义在 host 侧 yamlScalar(值里的「: 」「 #」),
|
|
89
|
+
// 这里只兜长度 —— 缘由不该长到把 frontmatter 变成正文。
|
|
90
|
+
const archiveReasonSchema = z.string().max(1000).optional()
|
|
91
|
+
// starmap.listStars 的可选开关:不看归档星时行为与从前完全一致。
|
|
92
|
+
const includeArchivedSchema = z.boolean().optional()
|
|
93
|
+
|
|
94
|
+
// 归档 / 恢复的结果:成功 `{ ok: true, file }`,失败 `{ ok: false, error }` —— 失败分支
|
|
95
|
+
// **没有 file**(名字本身可能就是非法的)。所以不能复用 writeResultSchema:那边 `file`
|
|
96
|
+
// 是必填(writeFile 连失败都带着归一后的文件名),strict 校验会把失败分支判成坏结果。
|
|
97
|
+
const archiveResultSchema = z.object({
|
|
98
|
+
'ok': z.boolean().readonly(),
|
|
99
|
+
'file': z.string().readonly().optional(),
|
|
100
|
+
'error': z.string().readonly().optional(),
|
|
101
|
+
}).readonly()
|
|
102
|
+
|
|
103
|
+
// 归档文件的读 / 写(v0.9.0 B1b):归档不是删除,正文要能看能改。三个类型名与活跃记忆
|
|
104
|
+
// 那套(FileName / FileContent / WriteResult)对称,只是作用目录换成 `memory/archive/`。
|
|
105
|
+
// 名字仍受 safeName 约束 —— 调用方不许自己拼路径。
|
|
106
|
+
const archivedReadResultSchema = z.object({
|
|
107
|
+
'name': z.string().readonly(),
|
|
108
|
+
'content': z.string().readonly(),
|
|
109
|
+
}).readonly()
|
|
110
|
+
// 写归档的结果与 writeResultSchema 同形,但**另立一个类型名**:strict 层要能区分
|
|
111
|
+
// 「写活跃记忆」与「写归档记忆」两条路径,将来两者形状分叉时也不必回头改协议。
|
|
112
|
+
const archivedWriteResultSchema = z.object({
|
|
113
|
+
'ok': z.boolean().readonly(),
|
|
114
|
+
'file': z.string().readonly(),
|
|
115
|
+
'error': z.string().readonly().optional(),
|
|
116
|
+
}).readonly()
|
|
117
|
+
|
|
118
|
+
// ── 面板 API(v0.9.0 D1):体检 / 归档候选 / 设置 / 保留名原样读写 ──────────────
|
|
119
|
+
// 审计报告:字段面就是 `auditMemoryDir()` 的返回,逐项在这里钉住 —— strict 会把没声明的
|
|
120
|
+
// 字段剥掉,面板看到的清单必须与模型看到的一致。
|
|
121
|
+
const auditItemSchema = z.object({ 'file': z.string().readonly() }).readonly()
|
|
122
|
+
const auditLinkSchema = z.object({ 'file': z.string().readonly(), 'target': z.string().readonly() }).readonly()
|
|
123
|
+
const auditTypeMismatchSchema = z.object({
|
|
124
|
+
'file': z.string().readonly(),
|
|
125
|
+
'type': z.string().readonly(),
|
|
126
|
+
'prefix': z.string().readonly(),
|
|
127
|
+
'effective': z.string().readonly(),
|
|
128
|
+
}).readonly()
|
|
129
|
+
const auditHazardSchema = z.object({ 'file': z.string().readonly(), 'line': z.string().readonly() }).readonly()
|
|
130
|
+
const auditReportSchema = z.object({
|
|
131
|
+
'dir': z.string().readonly(),
|
|
132
|
+
'fileCount': z.number().readonly(),
|
|
133
|
+
'skipped': z.number().readonly(),
|
|
134
|
+
'archivedCount': z.number().readonly(),
|
|
135
|
+
'indexEntries': z.number().readonly(),
|
|
136
|
+
'dangling': z.array(auditItemSchema).readonly(),
|
|
137
|
+
'unlisted': z.array(auditItemSchema).readonly(),
|
|
138
|
+
'typeMismatch': z.array(auditTypeMismatchSchema).readonly(),
|
|
139
|
+
'crlf': z.array(auditItemSchema).readonly(),
|
|
140
|
+
'brokenLinks': z.array(auditLinkSchema).readonly(),
|
|
141
|
+
'archivedLinks': z.array(auditLinkSchema).readonly(),
|
|
142
|
+
'hashHazards': z.array(auditHazardSchema).readonly(),
|
|
143
|
+
'noFrontmatter': z.array(auditItemSchema).readonly(),
|
|
144
|
+
'unreadable': z.array(auditItemSchema).readonly(),
|
|
145
|
+
'problems': z.number().readonly(),
|
|
146
|
+
}).readonly()
|
|
147
|
+
|
|
148
|
+
const archiveCandidateSchema = z.object({
|
|
149
|
+
'file': z.string().readonly(),
|
|
150
|
+
'type': z.string().readonly(),
|
|
151
|
+
'days': z.number().readonly(),
|
|
152
|
+
'limit': z.number().readonly(),
|
|
153
|
+
'reason': z.string().readonly(),
|
|
154
|
+
}).readonly()
|
|
155
|
+
const archiveCandidatesResultSchema = z.object({
|
|
156
|
+
'count': z.number().readonly(),
|
|
157
|
+
'candidates': z.array(archiveCandidateSchema).readonly(),
|
|
158
|
+
'autoArchive': z.string().readonly(),
|
|
159
|
+
'thresholds': z.object({
|
|
160
|
+
'project': z.number().readonly(),
|
|
161
|
+
'reference': z.number().readonly(),
|
|
162
|
+
'user': z.number().readonly(),
|
|
163
|
+
}).readonly(),
|
|
164
|
+
}).readonly()
|
|
165
|
+
|
|
166
|
+
// 设置:limits = 当前**已生效**的值(模块加载时读的),pendingLimits = 待生效值
|
|
167
|
+
// (settings.json > 环境变量 > 默认)。两个都给,界面才说得清「改了要重启」。
|
|
168
|
+
const settingsLimitsSchema = z.object({
|
|
169
|
+
'maxResults': z.number().readonly(),
|
|
170
|
+
'maxChars': z.number().readonly(),
|
|
171
|
+
'maxBaseline': z.number().readonly(),
|
|
172
|
+
'maxSessionBytes': z.number().readonly(),
|
|
173
|
+
'staleDays': z.number().readonly(),
|
|
174
|
+
}).readonly()
|
|
175
|
+
const settingsSchema = z.object({
|
|
176
|
+
'limits': settingsLimitsSchema,
|
|
177
|
+
'pendingLimits': settingsLimitsSchema,
|
|
178
|
+
'restartRequired': z.boolean().readonly(),
|
|
179
|
+
'reserved': z.array(z.string()).readonly(),
|
|
180
|
+
'reservedExtra': z.array(z.string()).readonly(),
|
|
181
|
+
}).readonly()
|
|
182
|
+
const settingsPatchSchema = z.object({
|
|
183
|
+
'limits': z.object({
|
|
184
|
+
'maxResults': z.number().optional(),
|
|
185
|
+
'maxChars': z.number().optional(),
|
|
186
|
+
'maxBaseline': z.number().optional(),
|
|
187
|
+
'maxSessionBytes': z.number().optional(),
|
|
188
|
+
'staleDays': z.number().optional(),
|
|
189
|
+
}).readonly().optional(),
|
|
190
|
+
'reserved': z.array(z.string()).optional(),
|
|
191
|
+
}).readonly()
|
|
192
|
+
// 成功回 { ok, settings, restartRequired },失败回 { ok:false, error } —— 两条分支并集。
|
|
193
|
+
const settingsResultSchema = z.object({
|
|
194
|
+
'ok': z.boolean().readonly(),
|
|
195
|
+
'error': z.string().readonly().optional(),
|
|
196
|
+
'settings': settingsSchema.optional(),
|
|
197
|
+
'restartRequired': z.boolean().readonly().optional(),
|
|
198
|
+
}).readonly()
|
|
199
|
+
|
|
200
|
+
// 保留名原样读写。读的两条分支(成功 {name,content} / 拒绝 {ok:false,error})用可选字段
|
|
201
|
+
// 的并集接住;写的失败分支可能没有 file,所以 file 也是 optional。
|
|
202
|
+
const rawReadResultSchema = z.object({
|
|
203
|
+
'name': z.string().readonly().optional(),
|
|
204
|
+
'content': z.string().readonly().optional(),
|
|
205
|
+
'ok': z.boolean().readonly().optional(),
|
|
206
|
+
'error': z.string().readonly().optional(),
|
|
207
|
+
}).readonly()
|
|
208
|
+
const rawWriteResultSchema = z.object({
|
|
209
|
+
'ok': z.boolean().readonly(),
|
|
210
|
+
'file': z.string().readonly().optional(),
|
|
211
|
+
'error': z.string().readonly().optional(),
|
|
212
|
+
}).readonly()
|
|
213
|
+
// 保留名的体积上限比单条记忆大得多(session-log.md 天然 > 512 KB)—— 4 MB,独立于
|
|
214
|
+
// fileContentSchema,别把两者混用。
|
|
215
|
+
const rawFileContentSchema = z.string().max(4 * 1024 * 1024)
|
|
216
|
+
|
|
66
217
|
// ── autodream(夜间记忆整理)───────────────────────────────────────────────
|
|
67
218
|
// 配置的每一项都可写;lastResult 是一个「成功/失败两条分支共用」的结构,
|
|
68
219
|
// 所以除了三个必有字段外全是 optional —— 用 strict 校验两种形态的并集,
|
|
@@ -303,13 +454,148 @@ export const TYPERT = {
|
|
|
303
454
|
result: { mode: 'strict', typeSymbol: 'sage-mem/types#DeleteResult', schema: deleteResultSchema, create: () => deleteResultSchema },
|
|
304
455
|
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
305
456
|
},
|
|
457
|
+
{
|
|
458
|
+
id: 'sage-mem#memory/archive',
|
|
459
|
+
service: 'memory',
|
|
460
|
+
namespace: 'memory',
|
|
461
|
+
method: 'archive',
|
|
462
|
+
invocation: { kind: 'direct' },
|
|
463
|
+
parameters: [
|
|
464
|
+
{ name: 'name', wire: 'name', source: 'json', codec: { mode: 'strict', typeSymbol: 'sage-mem/types#FileName', schema: fileNameSchema, create: () => fileNameSchema } },
|
|
465
|
+
{ name: 'reason', wire: 'reason', source: 'json', codec: { mode: 'strict', typeSymbol: 'sage-mem/types#ArchiveReason', schema: archiveReasonSchema, create: () => archiveReasonSchema } },
|
|
466
|
+
],
|
|
467
|
+
// 归档与恢复都回「成不成、动的哪个文件」;失败分支没有 file(名字本身可能就非法),
|
|
468
|
+
// 所以用 ArchiveResult(file / error 都 optional),不能复用 file 必填的 writeResultSchema。
|
|
469
|
+
result: { mode: 'strict', typeSymbol: 'sage-mem/types#ArchiveResult', schema: archiveResultSchema, create: () => archiveResultSchema },
|
|
470
|
+
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
id: 'sage-mem#memory/restore',
|
|
474
|
+
service: 'memory',
|
|
475
|
+
namespace: 'memory',
|
|
476
|
+
method: 'restore',
|
|
477
|
+
invocation: { kind: 'direct' },
|
|
478
|
+
parameters: [
|
|
479
|
+
{ name: 'name', wire: 'name', source: 'json', codec: { mode: 'strict', typeSymbol: 'sage-mem/types#FileName', schema: fileNameSchema, create: () => fileNameSchema } },
|
|
480
|
+
],
|
|
481
|
+
result: { mode: 'strict', typeSymbol: 'sage-mem/types#ArchiveResult', schema: archiveResultSchema, create: () => archiveResultSchema },
|
|
482
|
+
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
id: 'sage-mem#memory/listArchived',
|
|
486
|
+
service: 'memory',
|
|
487
|
+
namespace: 'memory',
|
|
488
|
+
method: 'listArchived',
|
|
489
|
+
invocation: { kind: 'direct' },
|
|
490
|
+
parameters: [],
|
|
491
|
+
result: { mode: 'strict', typeSymbol: 'sage-mem/types#ArchivedList', schema: archivedListSchema, create: () => archivedListSchema },
|
|
492
|
+
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
id: 'sage-mem#memory/readArchived',
|
|
496
|
+
service: 'memory',
|
|
497
|
+
namespace: 'memory',
|
|
498
|
+
method: 'readArchived',
|
|
499
|
+
invocation: { kind: 'direct' },
|
|
500
|
+
parameters: [
|
|
501
|
+
{ name: 'name', wire: 'name', source: 'json', codec: { mode: 'strict', typeSymbol: 'sage-mem/types#ArchivedFileName', schema: fileNameSchema, create: () => fileNameSchema } },
|
|
502
|
+
],
|
|
503
|
+
result: { mode: 'strict', typeSymbol: 'sage-mem/types#ArchivedFileContent', schema: archivedReadResultSchema, create: () => archivedReadResultSchema },
|
|
504
|
+
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
id: 'sage-mem#memory/writeArchived',
|
|
508
|
+
service: 'memory',
|
|
509
|
+
namespace: 'memory',
|
|
510
|
+
method: 'writeArchived',
|
|
511
|
+
invocation: { kind: 'direct' },
|
|
512
|
+
parameters: [
|
|
513
|
+
{ name: 'name', wire: 'name', source: 'json', codec: { mode: 'strict', typeSymbol: 'sage-mem/types#ArchivedFileName', schema: fileNameSchema, create: () => fileNameSchema } },
|
|
514
|
+
// 正文与「写活跃记忆」共用同一个 512 KB 上限 schema;类型名沿用 #ArchivedFileContent
|
|
515
|
+
// 是为了与「读归档」那一侧对称(活跃记忆那套也是 FileContent 一符两用)。
|
|
516
|
+
{ name: 'content', wire: 'content', source: 'json', codec: { mode: 'strict', typeSymbol: 'sage-mem/types#ArchivedFileContent', schema: fileContentSchema, create: () => fileContentSchema } },
|
|
517
|
+
],
|
|
518
|
+
result: { mode: 'strict', typeSymbol: 'sage-mem/types#ArchivedWriteResult', schema: archivedWriteResultSchema, create: () => archivedWriteResultSchema },
|
|
519
|
+
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
id: 'sage-mem#memory/audit',
|
|
523
|
+
service: 'memory',
|
|
524
|
+
namespace: 'memory',
|
|
525
|
+
method: 'audit',
|
|
526
|
+
invocation: { kind: 'direct' },
|
|
527
|
+
parameters: [],
|
|
528
|
+
result: { mode: 'strict', typeSymbol: 'sage-mem/types#AuditReport', schema: auditReportSchema, create: () => auditReportSchema },
|
|
529
|
+
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
id: 'sage-mem#memory/archiveCandidates',
|
|
533
|
+
service: 'memory',
|
|
534
|
+
namespace: 'memory',
|
|
535
|
+
method: 'archiveCandidates',
|
|
536
|
+
invocation: { kind: 'direct' },
|
|
537
|
+
parameters: [],
|
|
538
|
+
result: { mode: 'strict', typeSymbol: 'sage-mem/types#ArchiveCandidates', schema: archiveCandidatesResultSchema, create: () => archiveCandidatesResultSchema },
|
|
539
|
+
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
id: 'sage-mem#memory/getSettings',
|
|
543
|
+
service: 'memory',
|
|
544
|
+
namespace: 'memory',
|
|
545
|
+
method: 'getSettings',
|
|
546
|
+
invocation: { kind: 'direct' },
|
|
547
|
+
parameters: [],
|
|
548
|
+
result: { mode: 'strict', typeSymbol: 'sage-mem/types#MemorySettings', schema: settingsSchema, create: () => settingsSchema },
|
|
549
|
+
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
id: 'sage-mem#memory/setSettings',
|
|
553
|
+
service: 'memory',
|
|
554
|
+
namespace: 'memory',
|
|
555
|
+
method: 'setSettings',
|
|
556
|
+
invocation: { kind: 'direct' },
|
|
557
|
+
parameters: [
|
|
558
|
+
// 补丁式:面板一次只改一项时不该把没碰过的字段用旧值覆盖回去。
|
|
559
|
+
{ name: 'patch', wire: 'patch', source: 'json', codec: { mode: 'strict', typeSymbol: 'sage-mem/types#MemorySettingsPatch', schema: settingsPatchSchema, create: () => settingsPatchSchema } },
|
|
560
|
+
],
|
|
561
|
+
result: { mode: 'strict', typeSymbol: 'sage-mem/types#MemorySettingsResult', schema: settingsResultSchema, create: () => settingsResultSchema },
|
|
562
|
+
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
id: 'sage-mem#memory/readRaw',
|
|
566
|
+
service: 'memory',
|
|
567
|
+
namespace: 'memory',
|
|
568
|
+
method: 'readRaw',
|
|
569
|
+
invocation: { kind: 'direct' },
|
|
570
|
+
parameters: [
|
|
571
|
+
{ name: 'name', wire: 'name', source: 'json', codec: { mode: 'strict', typeSymbol: 'sage-mem/types#ReservedFileName', schema: fileNameSchema, create: () => fileNameSchema } },
|
|
572
|
+
],
|
|
573
|
+
result: { mode: 'strict', typeSymbol: 'sage-mem/types#RawFileContent', schema: rawReadResultSchema, create: () => rawReadResultSchema },
|
|
574
|
+
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
id: 'sage-mem#memory/writeRaw',
|
|
578
|
+
service: 'memory',
|
|
579
|
+
namespace: 'memory',
|
|
580
|
+
method: 'writeRaw',
|
|
581
|
+
invocation: { kind: 'direct' },
|
|
582
|
+
parameters: [
|
|
583
|
+
{ name: 'name', wire: 'name', source: 'json', codec: { mode: 'strict', typeSymbol: 'sage-mem/types#ReservedFileName', schema: fileNameSchema, create: () => fileNameSchema } },
|
|
584
|
+
// 4 MB:与 fileContentSchema(512 KB)**不是同一个上限**,见 rawFileContentSchema 的注释。
|
|
585
|
+
{ name: 'content', wire: 'content', source: 'json', codec: { mode: 'strict', typeSymbol: 'sage-mem/types#RawFileContent', schema: rawFileContentSchema, create: () => rawFileContentSchema } },
|
|
586
|
+
],
|
|
587
|
+
result: { mode: 'strict', typeSymbol: 'sage-mem/types#RawWriteResult', schema: rawWriteResultSchema, create: () => rawWriteResultSchema },
|
|
588
|
+
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
589
|
+
},
|
|
306
590
|
{
|
|
307
591
|
id: 'sage-mem#starmap/listStars',
|
|
308
592
|
service: 'starmap',
|
|
309
593
|
namespace: 'starmap',
|
|
310
594
|
method: 'listStars',
|
|
311
595
|
invocation: { kind: 'direct' },
|
|
312
|
-
parameters: [
|
|
596
|
+
parameters: [
|
|
597
|
+
{ name: 'includeArchived', wire: 'includeArchived', source: 'json', codec: { mode: 'strict', typeSymbol: 'sage-mem/types#StarmapIncludeArchived', schema: includeArchivedSchema, create: () => includeArchivedSchema } },
|
|
598
|
+
],
|
|
313
599
|
result: { mode: 'strict', typeSymbol: 'sage-mem/types#StarmapList', schema: starmapListSchema, create: () => starmapListSchema },
|
|
314
600
|
sourceLocation: { "file": "lib/index.js", "line": 1, "column": 1 },
|
|
315
601
|
},
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sage-mem",
|
|
3
3
|
"description": "File-based memory plugin for DeepSeek Harness (DSH) — cross-session memory in plain markdown files, with a memory star-map view, type/tag filtering, retrieval aliases, and an optional autodream pass that consolidates memories on demand or on a schedule — with per-run rollback points, a per-file change declaration (what changed and why), and a separately selectable model for the consolidation pass",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -87,6 +87,8 @@
|
|
|
87
87
|
"claude-code"
|
|
88
88
|
],
|
|
89
89
|
"scripts": {
|
|
90
|
-
"test": "node test/run.mjs"
|
|
90
|
+
"test": "node test/run.mjs",
|
|
91
|
+
"build:client": "node scripts/build-client.mjs",
|
|
92
|
+
"images": "node scripts/make-readme-images.mjs"
|
|
91
93
|
}
|
|
92
94
|
}
|