aismemory 0.2.0 → 0.4.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.
Files changed (72) hide show
  1. package/dist/__tests__/cli-review.test.d.ts +1 -0
  2. package/dist/__tests__/cli-review.test.js +26 -0
  3. package/dist/__tests__/cli-review.test.js.map +1 -0
  4. package/dist/__tests__/config.test.d.ts +1 -0
  5. package/dist/__tests__/config.test.js +54 -0
  6. package/dist/__tests__/config.test.js.map +1 -0
  7. package/dist/__tests__/local-claude-source.test.d.ts +1 -0
  8. package/dist/__tests__/local-claude-source.test.js +97 -0
  9. package/dist/__tests__/local-claude-source.test.js.map +1 -0
  10. package/dist/__tests__/local-mirror.test.d.ts +1 -0
  11. package/dist/__tests__/local-mirror.test.js +95 -0
  12. package/dist/__tests__/local-mirror.test.js.map +1 -0
  13. package/dist/__tests__/mcp-init-no-auth.test.d.ts +1 -0
  14. package/dist/__tests__/mcp-init-no-auth.test.js +75 -0
  15. package/dist/__tests__/mcp-init-no-auth.test.js.map +1 -0
  16. package/dist/__tests__/pipeline-ingestion.test.d.ts +1 -0
  17. package/dist/__tests__/pipeline-ingestion.test.js +161 -0
  18. package/dist/__tests__/pipeline-ingestion.test.js.map +1 -0
  19. package/dist/__tests__/pipeline-scope-resolver.test.d.ts +1 -0
  20. package/dist/__tests__/pipeline-scope-resolver.test.js +51 -0
  21. package/dist/__tests__/pipeline-scope-resolver.test.js.map +1 -0
  22. package/dist/__tests__/pipeline-trust-tagger.test.d.ts +1 -0
  23. package/dist/__tests__/pipeline-trust-tagger.test.js +24 -0
  24. package/dist/__tests__/pipeline-trust-tagger.test.js.map +1 -0
  25. package/dist/__tests__/read-claude-memory-tree.test.d.ts +1 -0
  26. package/dist/__tests__/read-claude-memory-tree.test.js +37 -0
  27. package/dist/__tests__/read-claude-memory-tree.test.js.map +1 -0
  28. package/dist/__tests__/trust-ledger.test.d.ts +1 -0
  29. package/dist/__tests__/trust-ledger.test.js +55 -0
  30. package/dist/__tests__/trust-ledger.test.js.map +1 -0
  31. package/dist/cli/read-claude-memory-tree.d.ts +7 -0
  32. package/dist/cli/read-claude-memory-tree.js +65 -0
  33. package/dist/cli/read-claude-memory-tree.js.map +1 -0
  34. package/dist/cli/sync-memory.d.ts +2 -0
  35. package/dist/cli/sync-memory.js +155 -0
  36. package/dist/cli/sync-memory.js.map +1 -0
  37. package/dist/config.d.ts +11 -0
  38. package/dist/config.js +51 -0
  39. package/dist/config.js.map +1 -0
  40. package/dist/index.js +154 -54
  41. package/dist/index.js.map +1 -1
  42. package/dist/local-mirror.d.ts +15 -0
  43. package/dist/local-mirror.js +56 -0
  44. package/dist/local-mirror.js.map +1 -0
  45. package/dist/pipeline/dedupe.d.ts +11 -0
  46. package/dist/pipeline/dedupe.js +21 -0
  47. package/dist/pipeline/dedupe.js.map +1 -0
  48. package/dist/pipeline/ingestion.d.ts +56 -0
  49. package/dist/pipeline/ingestion.js +86 -0
  50. package/dist/pipeline/ingestion.js.map +1 -0
  51. package/dist/pipeline/scope-resolver.d.ts +15 -0
  52. package/dist/pipeline/scope-resolver.js +28 -0
  53. package/dist/pipeline/scope-resolver.js.map +1 -0
  54. package/dist/pipeline/trust-tagger.d.ts +10 -0
  55. package/dist/pipeline/trust-tagger.js +12 -0
  56. package/dist/pipeline/trust-tagger.js.map +1 -0
  57. package/dist/pipeline/types.d.ts +41 -0
  58. package/dist/pipeline/types.js +6 -0
  59. package/dist/pipeline/types.js.map +1 -0
  60. package/dist/review/cli-review.d.ts +10 -0
  61. package/dist/review/cli-review.js +47 -0
  62. package/dist/review/cli-review.js.map +1 -0
  63. package/dist/sources/local-claude.d.ts +11 -0
  64. package/dist/sources/local-claude.js +137 -0
  65. package/dist/sources/local-claude.js.map +1 -0
  66. package/dist/sources/types.d.ts +53 -0
  67. package/dist/sources/types.js +9 -0
  68. package/dist/sources/types.js.map +1 -0
  69. package/dist/trust-ledger.d.ts +8 -0
  70. package/dist/trust-ledger.js +61 -0
  71. package/dist/trust-ledger.js.map +1 -0
  72. package/package.json +1 -1
@@ -0,0 +1,28 @@
1
+ export async function resolveScope(options) {
2
+ const { config, projectPath, activeGoal, sessionTopic, confirmer, saveAsDefault = false } = options;
3
+ if (projectPath) {
4
+ const saved = config.scopePreference(projectPath);
5
+ if (saved)
6
+ return saved;
7
+ }
8
+ let proposed;
9
+ if (activeGoal) {
10
+ proposed = { kind: 'goal', label: activeGoal.description, goalId: activeGoal.id };
11
+ }
12
+ else if (projectPath) {
13
+ const label = projectPath.split('/').filter(Boolean).pop() ?? 'project';
14
+ proposed = { kind: 'project', label, projectPath };
15
+ }
16
+ else if (sessionTopic) {
17
+ proposed = { kind: 'session', label: sessionTopic, topicSummary: sessionTopic };
18
+ }
19
+ else {
20
+ proposed = { kind: 'user-named', label: 'untitled' };
21
+ }
22
+ const confirmed = await confirmer(proposed);
23
+ if (saveAsDefault && projectPath) {
24
+ config.saveScopePreference(projectPath, confirmed);
25
+ }
26
+ return confirmed;
27
+ }
28
+ //# sourceMappingURL=scope-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-resolver.js","sourceRoot":"","sources":["../../src/pipeline/scope-resolver.ts"],"names":[],"mappings":"AAiBA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA6B;IAC9D,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAEpG,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QAClD,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IAED,IAAI,QAAmB,CAAC;IACxB,IAAI,UAAU,EAAE,CAAC;QACf,QAAQ,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC;IACpF,CAAC;SAAM,IAAI,WAAW,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,SAAS,CAAC;QACxE,QAAQ,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IACrD,CAAC;SAAM,IAAI,YAAY,EAAE,CAAC;QACxB,QAAQ,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;IAClF,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IACvD,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;IAE5C,IAAI,aAAa,IAAI,WAAW,EAAE,CAAC;QACjC,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { AisMemoryDraft } from './types.js';
2
+ export interface TrustTagOptions {
3
+ defaultTrustScore: number;
4
+ }
5
+ /**
6
+ * Fills in default trust scores for drafts left at 0 by the adapter.
7
+ * Adapters may optionally pre-set trust (e.g., if they have provider-level
8
+ * confidence signals). This stage is a safety net, not a mandatory rewrite.
9
+ */
10
+ export declare function applyTrustTags(drafts: AisMemoryDraft[], options: TrustTagOptions): AisMemoryDraft[];
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Fills in default trust scores for drafts left at 0 by the adapter.
3
+ * Adapters may optionally pre-set trust (e.g., if they have provider-level
4
+ * confidence signals). This stage is a safety net, not a mandatory rewrite.
5
+ */
6
+ export function applyTrustTags(drafts, options) {
7
+ return drafts.map((d) => ({
8
+ ...d,
9
+ trustScore: d.trustScore === 0 ? options.defaultTrustScore : d.trustScore,
10
+ }));
11
+ }
12
+ //# sourceMappingURL=trust-tagger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust-tagger.js","sourceRoot":"","sources":["../../src/pipeline/trust-tagger.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAwB,EAAE,OAAwB;IAC/E,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxB,GAAG,CAAC;QACJ,UAAU,EAAE,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU;KAC1E,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Core pipeline types used across scope resolution, dedupe, trust tagging,
3
+ * and ingestion.
4
+ */
5
+ export type ScopeKind = 'goal' | 'project' | 'session' | 'user-named' | 'all';
6
+ export interface SyncScope {
7
+ readonly kind: ScopeKind;
8
+ readonly label: string;
9
+ readonly goalId?: string;
10
+ readonly projectPath?: string;
11
+ readonly topicSummary?: string;
12
+ }
13
+ export type AisMemoryType = 'fact' | 'event' | 'lesson' | 'context' | 'goal' | 'task';
14
+ export interface AisMemoryDraft {
15
+ content: string;
16
+ type: AisMemoryType;
17
+ importance: number;
18
+ trustScore: number;
19
+ provenance: ImportProvenance;
20
+ }
21
+ export interface ImportProvenance {
22
+ source: string;
23
+ sourceCategory?: string;
24
+ sourceDate?: string | null;
25
+ sourceHash: string;
26
+ importedAt: string;
27
+ importedBy: string;
28
+ sourceScope: SyncScope;
29
+ sourcePrompt: string;
30
+ }
31
+ export interface SyncResult {
32
+ imported: number;
33
+ skippedExactDupes: number;
34
+ skippedByUser: number;
35
+ warnings: string[];
36
+ memoryIds: string[];
37
+ failed: Array<{
38
+ index: number;
39
+ error: string;
40
+ }>;
41
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Core pipeline types used across scope resolution, dedupe, trust tagging,
3
+ * and ingestion.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,10 @@
1
+ import type { AisMemoryDraft } from '../pipeline/types.js';
2
+ export declare function bulkSelectAll(drafts: readonly AisMemoryDraft[]): AisMemoryDraft[];
3
+ export declare function bulkDeselectAll(_drafts: readonly AisMemoryDraft[]): AisMemoryDraft[];
4
+ export declare function filterByImportance(drafts: readonly AisMemoryDraft[], minImportance: number): AisMemoryDraft[];
5
+ export interface InteractiveReviewOptions {
6
+ sourceId: string;
7
+ scopeLabel: string;
8
+ firstSyncForScope: boolean;
9
+ }
10
+ export declare function interactiveReview(drafts: AisMemoryDraft[], options: InteractiveReviewOptions): Promise<AisMemoryDraft[]>;
@@ -0,0 +1,47 @@
1
+ import { createInterface } from 'node:readline/promises';
2
+ import { stdin, stdout } from 'node:process';
3
+ export function bulkSelectAll(drafts) {
4
+ return [...drafts];
5
+ }
6
+ export function bulkDeselectAll(_drafts) {
7
+ return [];
8
+ }
9
+ export function filterByImportance(drafts, minImportance) {
10
+ return drafts.filter((d) => d.importance >= minImportance);
11
+ }
12
+ export async function interactiveReview(drafts, options) {
13
+ if (drafts.length === 0)
14
+ return [];
15
+ const rl = createInterface({ input: stdin, output: stdout });
16
+ try {
17
+ stdout.write(`\n=== Review candidates from ${options.sourceId} for scope "${options.scopeLabel}" ===\n`);
18
+ stdout.write(options.firstSyncForScope
19
+ ? `(First sync for this scope — please review each memory)\n\n`
20
+ : `(Trusted scope — preview and confirm)\n\n`);
21
+ drafts.forEach((d, i) => {
22
+ const preview = d.content.length > 100 ? `${d.content.slice(0, 100)}…` : d.content;
23
+ stdout.write(`[${i + 1}] (${d.type}, imp ${d.importance.toFixed(2)}) ${preview}\n`);
24
+ });
25
+ stdout.write(`\nActions:\n`);
26
+ stdout.write(` a = accept all\n`);
27
+ stdout.write(` n = reject all\n`);
28
+ stdout.write(` h = accept only importance >= 0.7\n`);
29
+ stdout.write(` <indices> = accept listed (e.g., "1,3,5")\n`);
30
+ const answer = (await rl.question('Choice: ')).trim().toLowerCase();
31
+ if (answer === 'a')
32
+ return bulkSelectAll(drafts);
33
+ if (answer === 'n')
34
+ return bulkDeselectAll(drafts);
35
+ if (answer === 'h')
36
+ return filterByImportance(drafts, 0.7);
37
+ const indices = answer
38
+ .split(',')
39
+ .map((s) => parseInt(s.trim(), 10) - 1)
40
+ .filter((n) => Number.isInteger(n) && n >= 0 && n < drafts.length);
41
+ return indices.map((i) => drafts[i]).filter((d) => Boolean(d));
42
+ }
43
+ finally {
44
+ rl.close();
45
+ }
46
+ }
47
+ //# sourceMappingURL=cli-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-review.js","sourceRoot":"","sources":["../../src/review/cli-review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { AisMemoryDraft, SyncScope } from '../pipeline/types.js';
2
+ import type { FilesystemResult, ParseResult, SourceAdapter, SourceMemory } from './types.js';
3
+ export declare class LocalClaudeSource implements SourceAdapter {
4
+ readonly id = "claude-local";
5
+ readonly displayName = "Claude local files";
6
+ readonly kind: "filesystem";
7
+ extractionPrompt(_scope: SyncScope): string;
8
+ parseResponse(raw: string | FilesystemResult): ParseResult;
9
+ mapToAis(src: SourceMemory, scope: SyncScope, agentId: string): AisMemoryDraft;
10
+ dedupeKey(src: SourceMemory): string;
11
+ }
@@ -0,0 +1,137 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { basename } from 'node:path';
3
+ const SOURCE_ID = 'claude-local';
4
+ function normalizeContent(raw) {
5
+ // Strip BOM if present, then normalize CRLF/CR to LF.
6
+ const noBom = raw.startsWith('\uFEFF') ? raw.slice(1) : raw;
7
+ return noBom.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
8
+ }
9
+ function categoryForFile(path) {
10
+ const name = basename(path).toLowerCase();
11
+ if (name === 'memory.md')
12
+ return 'memory-index';
13
+ if (name.startsWith('feedback_'))
14
+ return 'feedback';
15
+ if (name.startsWith('agent_') || name.startsWith('user_'))
16
+ return 'agent';
17
+ if (name.startsWith('project_') ||
18
+ name.startsWith('session_') ||
19
+ name.startsWith('swarm_')) {
20
+ return 'project-event';
21
+ }
22
+ return 'other';
23
+ }
24
+ function typeForCategory(category) {
25
+ switch (category) {
26
+ case 'feedback':
27
+ return 'lesson';
28
+ case 'agent':
29
+ return 'fact';
30
+ case 'project-event':
31
+ return 'event';
32
+ case 'memory-index':
33
+ case 'other':
34
+ default:
35
+ return 'context';
36
+ }
37
+ }
38
+ function importanceFor(category, bulletPosition) {
39
+ if (category === 'feedback')
40
+ return 0.8;
41
+ if (category === 'agent')
42
+ return 0.75;
43
+ if (category === 'memory-index') {
44
+ return Math.max(0.5, 0.9 - 0.02 * bulletPosition);
45
+ }
46
+ return 0.6;
47
+ }
48
+ function extractMemoryIndexBullets(content) {
49
+ const bullets = [];
50
+ for (const rawLine of content.split('\n')) {
51
+ // Only top-level bullets (no leading whitespace). Nested bullets are skipped;
52
+ // their content is typically elaboration of the parent and would lose context
53
+ // if imported separately.
54
+ if (rawLine.startsWith('- ') && rawLine.length > 2) {
55
+ bullets.push(rawLine.slice(2).trim());
56
+ }
57
+ }
58
+ return bullets;
59
+ }
60
+ function extractBodyAfterFrontmatter(content) {
61
+ const match = /^---\n[\s\S]*?\n---\n+([\s\S]*)$/.exec(content);
62
+ return match?.[1]?.trim() ?? content.trim();
63
+ }
64
+ export class LocalClaudeSource {
65
+ id = SOURCE_ID;
66
+ displayName = 'Claude local files';
67
+ kind = 'filesystem';
68
+ extractionPrompt(_scope) {
69
+ return '';
70
+ }
71
+ parseResponse(raw) {
72
+ if (typeof raw === 'string') {
73
+ return { memories: [], warnings: ['LocalClaudeSource requires FilesystemResult, got string'] };
74
+ }
75
+ const memories = [];
76
+ const warnings = [];
77
+ for (const file of raw.files) {
78
+ const category = categoryForFile(file.path);
79
+ const content = normalizeContent(file.content);
80
+ if (category === 'memory-index') {
81
+ const bullets = extractMemoryIndexBullets(content);
82
+ bullets.forEach((b, i) => {
83
+ memories.push({
84
+ content: b,
85
+ sourceCategory: 'memory-index',
86
+ sourceMetadata: { sourceFile: file.path, bulletIndex: i },
87
+ });
88
+ });
89
+ }
90
+ else if (category === 'other') {
91
+ // Skip unclassified files silently.
92
+ }
93
+ else {
94
+ const body = extractBodyAfterFrontmatter(content);
95
+ if (body.length === 0) {
96
+ warnings.push(`empty body after frontmatter: ${file.path}`);
97
+ continue;
98
+ }
99
+ memories.push({
100
+ content: body,
101
+ sourceCategory: category,
102
+ sourceMetadata: { sourceFile: file.path },
103
+ });
104
+ }
105
+ }
106
+ return { memories, warnings };
107
+ }
108
+ mapToAis(src, scope, agentId) {
109
+ const category = src.sourceCategory ?? 'other';
110
+ const bulletIndex = typeof src.sourceMetadata?.['bulletIndex'] === 'number'
111
+ ? src.sourceMetadata['bulletIndex']
112
+ : 0;
113
+ const provenance = {
114
+ source: SOURCE_ID,
115
+ sourceCategory: category,
116
+ sourceDate: null,
117
+ sourceHash: this.dedupeKey(src),
118
+ importedAt: new Date().toISOString(),
119
+ importedBy: agentId,
120
+ sourceScope: scope,
121
+ sourcePrompt: '',
122
+ };
123
+ return {
124
+ content: src.content,
125
+ type: typeForCategory(category),
126
+ importance: importanceFor(category, bulletIndex),
127
+ trustScore: 0,
128
+ provenance,
129
+ };
130
+ }
131
+ dedupeKey(src) {
132
+ return createHash('sha256')
133
+ .update(`${src.content}\x00${SOURCE_ID}\x00${src.sourceCategory ?? ''}`)
134
+ .digest('hex');
135
+ }
136
+ }
137
+ //# sourceMappingURL=local-claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-claude.js","sourceRoot":"","sources":["../../src/sources/local-claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Source Adapter interface — the plug-in contract for each memory provider.
3
+ *
4
+ * Each memory source (Claude local files, Claude.ai paste, ChatGPT paste, etc.)
5
+ * implements this interface in a self-contained file. Adapters PARSE and NORMALIZE;
6
+ * they never write to AIS directly. The ingestion pipeline does all writes.
7
+ */
8
+ import type { SyncScope, AisMemoryDraft } from '../pipeline/types.js';
9
+ export type SourceKind = 'filesystem' | 'paste' | 'api';
10
+ export interface SourceAdapter {
11
+ readonly id: string;
12
+ readonly displayName: string;
13
+ readonly kind: SourceKind;
14
+ readonly icon?: string;
15
+ /**
16
+ * Return the prompt the human should paste into the source provider, or an
17
+ * empty string for filesystem-kind adapters.
18
+ */
19
+ extractionPrompt(scope: SyncScope): string;
20
+ /**
21
+ * Parse whatever the provider returned. MUST NOT throw on partial/malformed
22
+ * data — return what can be parsed in `memories`, surface problems in
23
+ * `warnings`. `raw` is string for paste, FilesystemResult for filesystem.
24
+ */
25
+ parseResponse(raw: string | FilesystemResult): ParseResult;
26
+ /**
27
+ * Map a SourceMemory to an AIS memory draft. Applies provider-specific
28
+ * category→type mapping. Does NOT set trust/provenance — the trust-tagger
29
+ * stage does that.
30
+ */
31
+ mapToAis(src: SourceMemory, scope: SyncScope, agentId: string): AisMemoryDraft;
32
+ /**
33
+ * Deterministic dedupe key for this memory. Default: sha256(content + source + sourceCategory).
34
+ */
35
+ dedupeKey(src: SourceMemory): string;
36
+ }
37
+ export interface SourceMemory {
38
+ content: string;
39
+ sourceCategory?: string;
40
+ sourceDate?: string | null;
41
+ sourceMetadata?: Record<string, unknown>;
42
+ }
43
+ export interface ParseResult {
44
+ memories: SourceMemory[];
45
+ warnings: string[];
46
+ }
47
+ export interface FilesystemResult {
48
+ rootPath: string;
49
+ files: Array<{
50
+ path: string;
51
+ content: string;
52
+ }>;
53
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Source Adapter interface — the plug-in contract for each memory provider.
3
+ *
4
+ * Each memory source (Claude local files, Claude.ai paste, ChatGPT paste, etc.)
5
+ * implements this interface in a self-contained file. Adapters PARSE and NORMALIZE;
6
+ * they never write to AIS directly. The ingestion pipeline does all writes.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sources/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,8 @@
1
+ export declare class TrustLedger {
2
+ private readonly filePath;
3
+ private data;
4
+ constructor(home?: string);
5
+ isTrusted(agentId: string, sourceId: string, scopeKey: string): boolean;
6
+ recordSync(agentId: string, sourceId: string, scopeKey: string): void;
7
+ private persist;
8
+ }
@@ -0,0 +1,61 @@
1
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ const TRUST_AFTER_SYNCS = 2;
5
+ export class TrustLedger {
6
+ filePath;
7
+ data;
8
+ constructor(home = homedir()) {
9
+ const dir = join(home, '.aismemory');
10
+ this.filePath = join(dir, 'trust-ledger.json');
11
+ if (!existsSync(dir)) {
12
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
13
+ }
14
+ if (existsSync(this.filePath)) {
15
+ try {
16
+ this.data = JSON.parse(readFileSync(this.filePath, 'utf8'));
17
+ }
18
+ catch {
19
+ const backup = `${this.filePath}.corrupt-${Date.now()}`;
20
+ try {
21
+ renameSync(this.filePath, backup);
22
+ console.warn(`[TrustLedger] Corrupt ledger file renamed to ${backup}; starting fresh.`);
23
+ }
24
+ catch {
25
+ console.warn(`[TrustLedger] Corrupt ledger file could not be backed up; starting fresh.`);
26
+ }
27
+ this.data = {};
28
+ }
29
+ }
30
+ else {
31
+ this.data = {};
32
+ }
33
+ }
34
+ isTrusted(agentId, sourceId, scopeKey) {
35
+ return this.data[agentId]?.[sourceId]?.[scopeKey]?.trusted === true;
36
+ }
37
+ recordSync(agentId, sourceId, scopeKey) {
38
+ const now = new Date().toISOString();
39
+ const agent = this.data[agentId] ?? {};
40
+ const source = agent[sourceId] ?? {};
41
+ const existing = source[scopeKey];
42
+ const entry = existing
43
+ ? {
44
+ firstSyncAt: existing.firstSyncAt,
45
+ lastSyncAt: now,
46
+ syncCount: existing.syncCount + 1,
47
+ trusted: existing.syncCount + 1 >= TRUST_AFTER_SYNCS,
48
+ }
49
+ : { firstSyncAt: now, lastSyncAt: now, syncCount: 1, trusted: false };
50
+ source[scopeKey] = entry;
51
+ agent[sourceId] = source;
52
+ this.data[agentId] = agent;
53
+ this.persist();
54
+ }
55
+ persist() {
56
+ const tmp = `${this.filePath}.tmp`;
57
+ writeFileSync(tmp, JSON.stringify(this.data, null, 2), { mode: 0o600 });
58
+ renameSync(tmp, this.filePath);
59
+ }
60
+ }
61
+ //# sourceMappingURL=trust-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust-ledger.js","sourceRoot":"","sources":["../src/trust-ledger.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aismemory",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Persistent memory for AI agents. MCP server that connects to Agent Identity Service.",
5
5
  "type": "module",
6
6
  "bin": "dist/index.js",