synomem 0.4.0 → 0.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/CHANGELOG.md +42 -1
- package/README.md +50 -10
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +179 -16
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +2 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +37 -1
- package/dist/client.js.map +1 -1
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +31 -15
- package/dist/configure.js.map +1 -1
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +9 -1
- package/dist/credentials.js.map +1 -1
- package/dist/discover.d.ts +48 -0
- package/dist/discover.d.ts.map +1 -0
- package/dist/discover.js +106 -0
- package/dist/discover.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/projections.d.ts.map +1 -1
- package/dist/projections.js +15 -7
- package/dist/projections.js.map +1 -1
- package/dist/service.d.ts +2 -1
- package/dist/service.d.ts.map +1 -1
- package/dist/storage.d.ts +5 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +6 -0
- package/dist/storage.js.map +1 -1
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/cli.md +67 -3
- package/package.json +1 -1
- package/src/cli.ts +228 -20
- package/src/client.ts +41 -1
- package/src/configure.ts +30 -14
- package/src/credentials.ts +9 -1
- package/src/discover.ts +155 -0
- package/src/index.ts +2 -0
- package/src/projections.ts +17 -7
- package/src/service.ts +8 -0
- package/src/storage.ts +9 -0
- package/src/types.ts +21 -0
package/src/projections.ts
CHANGED
|
@@ -749,6 +749,14 @@ export class ProjectionManager implements ProjectionWriter {
|
|
|
749
749
|
return { generated: generated.sort(), removed: removed.sort() };
|
|
750
750
|
}
|
|
751
751
|
|
|
752
|
+
/*
|
|
753
|
+
* The paths a rebuild would produce, for comparison against the manifest.
|
|
754
|
+
*
|
|
755
|
+
* Directories are named by HANDLE, matching what the writers above create,
|
|
756
|
+
* while the record filters match on the canonical agent ID, which is what
|
|
757
|
+
* stored events carry. Mixing the two up makes the comparison never agree,
|
|
758
|
+
* and `doctor` then reports every workspace's projections as stale forever.
|
|
759
|
+
*/
|
|
752
760
|
expectedPaths(): string[] {
|
|
753
761
|
const profiles = this.storage.listAgents();
|
|
754
762
|
const events = this.storage.getReadableEvents();
|
|
@@ -757,10 +765,12 @@ export class ProjectionManager implements ProjectionWriter {
|
|
|
757
765
|
const tasks = taskRecordsFromEvents(events);
|
|
758
766
|
const paths: string[] = [];
|
|
759
767
|
for (const profile of profiles) {
|
|
760
|
-
paths.push(`${profile.
|
|
761
|
-
if (this.storage.config.projection.writeWinsMarkdown) paths.push(`${profile.
|
|
762
|
-
if (this.storage.config.projection.writeMemoryMarkdown)
|
|
763
|
-
|
|
768
|
+
paths.push(`${profile.handle}/profile.json`);
|
|
769
|
+
if (this.storage.config.projection.writeWinsMarkdown) paths.push(`${profile.handle}/WINS.md`);
|
|
770
|
+
if (this.storage.config.projection.writeMemoryMarkdown)
|
|
771
|
+
paths.push(`${profile.handle}/MEMORY.md`);
|
|
772
|
+
if (this.storage.config.projection.writeTasksMarkdown)
|
|
773
|
+
paths.push(`${profile.handle}/TASKS.md`);
|
|
764
774
|
if (this.storage.config.projection.writeInboxEntries) {
|
|
765
775
|
for (const record of records.filter(
|
|
766
776
|
(item) =>
|
|
@@ -768,19 +778,19 @@ export class ProjectionManager implements ProjectionWriter {
|
|
|
768
778
|
item.status === 'unacknowledged' &&
|
|
769
779
|
item.revocationStatus === 'active',
|
|
770
780
|
)) {
|
|
771
|
-
paths.push(`${profile.
|
|
781
|
+
paths.push(`${profile.handle}/inbox/kudos/${record.event.id}.md`);
|
|
772
782
|
}
|
|
773
783
|
for (const record of memos.filter(
|
|
774
784
|
(item) => item.event.recipientAgentId === profile.id && item.status === 'unread',
|
|
775
785
|
)) {
|
|
776
|
-
paths.push(`${profile.
|
|
786
|
+
paths.push(`${profile.handle}/inbox/memos/${record.event.id}.md`);
|
|
777
787
|
}
|
|
778
788
|
for (const record of tasks.filter(
|
|
779
789
|
(item) =>
|
|
780
790
|
item.event.assigneeAgentId === profile.id &&
|
|
781
791
|
(item.status === 'open' || item.status === 'assigned'),
|
|
782
792
|
)) {
|
|
783
|
-
paths.push(`${profile.
|
|
793
|
+
paths.push(`${profile.handle}/inbox/tasks/${record.event.id}.md`);
|
|
784
794
|
}
|
|
785
795
|
}
|
|
786
796
|
}
|
package/src/service.ts
CHANGED
|
@@ -19,6 +19,7 @@ import type {
|
|
|
19
19
|
CreateTodoResult,
|
|
20
20
|
CreateTaskResult,
|
|
21
21
|
DoctorResult,
|
|
22
|
+
ProjectionStatus,
|
|
22
23
|
GiveKudosInput,
|
|
23
24
|
GiveKudosResult,
|
|
24
25
|
ItemListInput,
|
|
@@ -213,6 +214,13 @@ export interface SynomemService extends SynomemDomainService {
|
|
|
213
214
|
doctor(): Promise<DoctorResult>;
|
|
214
215
|
export(format: 'json' | 'jsonl' | 'markdown'): Promise<string>;
|
|
215
216
|
backup?(destination: string): Promise<string>;
|
|
217
|
+
/*
|
|
218
|
+
* Optional, because only a backend that writes projected files can report on
|
|
219
|
+
* them. The remote backend keeps no filesystem projections at all, and
|
|
220
|
+
* inventing an empty answer there would read as "nothing is stale" rather
|
|
221
|
+
* than "there is nothing to be stale".
|
|
222
|
+
*/
|
|
223
|
+
projectionStatus?(): Promise<ProjectionStatus>;
|
|
216
224
|
rebuild(): Promise<ProjectionRebuildResult>;
|
|
217
225
|
capabilities(): Promise<SynomemServiceCapabilities>;
|
|
218
226
|
info(): Promise<SynomemServiceInfo>;
|
package/src/storage.ts
CHANGED
|
@@ -2041,6 +2041,15 @@ export class SynomemStorage implements SynomemRepository {
|
|
|
2041
2041
|
).map((row) => row.path);
|
|
2042
2042
|
}
|
|
2043
2043
|
|
|
2044
|
+
/** The manifest with the time each path was written, newest first. */
|
|
2045
|
+
projectionManifestEntries(): { path: string; generatedAt: string }[] {
|
|
2046
|
+
return (
|
|
2047
|
+
this.db()
|
|
2048
|
+
.prepare('SELECT path, generated_at FROM projection_manifest ORDER BY generated_at DESC')
|
|
2049
|
+
.all() as unknown as { path: string; generated_at: string }[]
|
|
2050
|
+
).map((row) => ({ path: row.path, generatedAt: row.generated_at }));
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2044
2053
|
integrityCheck(): string[] {
|
|
2045
2054
|
const rows = this.db().prepare('PRAGMA integrity_check').all() as unknown as Record<
|
|
2046
2055
|
string,
|
package/src/types.ts
CHANGED
|
@@ -737,6 +737,27 @@ export interface DoctorResult {
|
|
|
737
737
|
healthy: boolean;
|
|
738
738
|
diagnostics: Diagnostic[];
|
|
739
739
|
}
|
|
740
|
+
/**
|
|
741
|
+
* What the projected files on disk look like next to what they should be.
|
|
742
|
+
*
|
|
743
|
+
* Projections are derived, never canonical, so this reports drift rather than
|
|
744
|
+
* damage: `missing` and `unexpected` are both repaired by a rebuild, and
|
|
745
|
+
* neither means an event was lost.
|
|
746
|
+
*/
|
|
747
|
+
export interface ProjectionStatus {
|
|
748
|
+
/** Where projected files live. Absent on a backend that projects nothing. */
|
|
749
|
+
directory?: string;
|
|
750
|
+
settings: SynomemConfig['projection'];
|
|
751
|
+
/** True when the manifest matches what a rebuild would produce. */
|
|
752
|
+
current: boolean;
|
|
753
|
+
/** Recorded by the manifest, not the filesystem; absent before any rebuild. */
|
|
754
|
+
lastRebuiltAt?: string;
|
|
755
|
+
counts: { expected: number; manifest: number; missing: number; unexpected: number };
|
|
756
|
+
/** Expected but not on disk. Capped, because a large workspace has many. */
|
|
757
|
+
missing: string[];
|
|
758
|
+
/** On disk and in the manifest, but no longer expected. Capped likewise. */
|
|
759
|
+
unexpected: string[];
|
|
760
|
+
}
|
|
740
761
|
|
|
741
762
|
export type SynomemBackendConfig =
|
|
742
763
|
{ kind: 'local' } | { kind: 'remote'; baseUrl: string; workspaceId: string };
|