@mmnto/totem 0.9.0 → 0.9.2
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/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/ingest/file-resolver.d.ts +6 -1
- package/dist/ingest/file-resolver.d.ts.map +1 -1
- package/dist/ingest/file-resolver.js +50 -7
- package/dist/ingest/file-resolver.js.map +1 -1
- package/dist/ingest/file-resolver.test.d.ts +2 -0
- package/dist/ingest/file-resolver.test.d.ts.map +1 -0
- package/dist/ingest/file-resolver.test.js +84 -0
- package/dist/ingest/file-resolver.test.js.map +1 -0
- package/dist/ingest/pipeline.d.ts.map +1 -1
- package/dist/ingest/pipeline.js +64 -3
- package/dist/ingest/pipeline.js.map +1 -1
- package/dist/ingest/pipeline.test.d.ts +2 -0
- package/dist/ingest/pipeline.test.d.ts.map +1 -0
- package/dist/ingest/pipeline.test.js +79 -0
- package/dist/ingest/pipeline.test.js.map +1 -0
- package/dist/ingest/sync.d.ts +1 -1
- package/dist/ingest/sync.d.ts.map +1 -1
- package/dist/ingest/sync.js +1 -1
- package/dist/ingest/sync.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/xml-format.d.ts +13 -0
- package/dist/xml-format.d.ts.map +1 -0
- package/dist/xml-format.js +17 -0
- package/dist/xml-format.js.map +1 -0
- package/dist/xml-format.test.d.ts +2 -0
- package/dist/xml-format.test.d.ts.map +1 -0
- package/dist/xml-format.test.js +39 -0
- package/dist/xml-format.test.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { ChunkStrategy, ContentType, EmbeddingProvider, IngestTarget, Orchestrator, TotemConfig, } from './config-schema.js';
|
|
2
2
|
export { ChunkStrategySchema, ContentTypeSchema, DEFAULT_IGNORE_PATTERNS, EmbeddingProviderSchema, IngestTargetSchema, OllamaProviderSchema, OpenAIProviderSchema, OrchestratorSchema, ShellOrchestratorSchema, TotemConfigSchema, } from './config-schema.js';
|
|
3
|
-
export type { Chunk, SearchOptions, SearchResult, StoredChunk, SyncOptions } from './types.js';
|
|
3
|
+
export type { Chunk, SearchOptions, SearchResult, StoredChunk, SyncOptions, SyncState, } from './types.js';
|
|
4
4
|
export type { Chunker } from './chunkers/chunker.js';
|
|
5
5
|
export { createChunker } from './chunkers/chunker.js';
|
|
6
6
|
export type { Embedder } from './embedders/embedder.js';
|
|
@@ -8,5 +8,6 @@ export { createEmbedder } from './embedders/embedder.js';
|
|
|
8
8
|
export { TOTEM_TABLE_NAME } from './store/lance-schema.js';
|
|
9
9
|
export { LanceStore } from './store/lance-store.js';
|
|
10
10
|
export type { ResolvedFile } from './ingest/sync.js';
|
|
11
|
-
export { getChangedFiles, resolveFiles, runSync } from './ingest/sync.js';
|
|
11
|
+
export { getChangedFiles, getHeadSha, resolveFiles, runSync } from './ingest/sync.js';
|
|
12
|
+
export { wrapXml } from './xml-format.js';
|
|
12
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EACV,KAAK,EACL,aAAa,EACb,YAAY,EACZ,WAAW,EACX,WAAW,EACX,SAAS,GACV,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,YAAY,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAGtF,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,5 +4,7 @@ export { createEmbedder } from './embedders/embedder.js';
|
|
|
4
4
|
// Store
|
|
5
5
|
export { TOTEM_TABLE_NAME } from './store/lance-schema.js';
|
|
6
6
|
export { LanceStore } from './store/lance-store.js';
|
|
7
|
-
export { getChangedFiles, resolveFiles, runSync } from './ingest/sync.js';
|
|
7
|
+
export { getChangedFiles, getHeadSha, resolveFiles, runSync } from './ingest/sync.js';
|
|
8
|
+
// Utilities
|
|
9
|
+
export { wrapXml } from './xml-format.js';
|
|
8
10
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAc5B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAItD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,QAAQ;AACR,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIpD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEtF,YAAY;AACZ,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -8,7 +8,12 @@ export interface ResolvedFile {
|
|
|
8
8
|
export declare function resolveFiles(targets: IngestTarget[], projectRoot: string, ignorePatterns?: string[], onWarn?: (msg: string) => void): ResolvedFile[];
|
|
9
9
|
/**
|
|
10
10
|
* Get files changed since a given git ref (e.g., HEAD~1 or a commit SHA).
|
|
11
|
-
*
|
|
11
|
+
* Also includes untracked files so new files are picked up on incremental sync.
|
|
12
|
+
* Uses -z for null-delimited output consistent with getGitNonIgnoredFiles.
|
|
12
13
|
*/
|
|
13
14
|
export declare function getChangedFiles(projectRoot: string, sinceRef?: string, onWarn?: (msg: string) => void): string[] | null;
|
|
15
|
+
/**
|
|
16
|
+
* Get the current HEAD SHA for sync state tracking.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getHeadSha(projectRoot: string, onWarn?: (msg: string) => void): string | null;
|
|
14
19
|
//# sourceMappingURL=file-resolver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-resolver.d.ts","sourceRoot":"","sources":["../../src/ingest/file-resolver.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;CACtB;AAwCD,sEAAsE;AACtE,wBAAgB,YAAY,CAC1B,OAAO,EAAE,YAAY,EAAE,EACvB,WAAW,EAAE,MAAM,EACnB,cAAc,GAAE,MAAM,EAA4B,EAClD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC7B,YAAY,EAAE,CA2BhB;
|
|
1
|
+
{"version":3,"file":"file-resolver.d.ts","sourceRoot":"","sources":["../../src/ingest/file-resolver.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;CACtB;AAwCD,sEAAsE;AACtE,wBAAgB,YAAY,CAC1B,OAAO,EAAE,YAAY,EAAE,EACvB,WAAW,EAAE,MAAM,EACnB,cAAc,GAAE,MAAM,EAA4B,EAClD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC7B,YAAY,EAAE,CA2BhB;AAKD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,QAAQ,GAAE,MAAiB,EAC3B,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC7B,MAAM,EAAE,GAAG,IAAI,CA8CjB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,GAAG,IAAI,CAa7F"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { execFileSync
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import { globSync } from 'glob';
|
|
4
4
|
import { DEFAULT_IGNORE_PATTERNS } from '../config-schema.js';
|
|
@@ -57,20 +57,45 @@ export function resolveFiles(targets, projectRoot, ignorePatterns = DEFAULT_IGNO
|
|
|
57
57
|
}
|
|
58
58
|
return results;
|
|
59
59
|
}
|
|
60
|
+
/** Validate that a git ref is safe (hex SHA, HEAD~N, branch name — no shell metacharacters). */
|
|
61
|
+
const SAFE_GIT_REF = /^[a-zA-Z0-9_./:~^{}\-]+$/;
|
|
60
62
|
/**
|
|
61
63
|
* Get files changed since a given git ref (e.g., HEAD~1 or a commit SHA).
|
|
62
|
-
*
|
|
64
|
+
* Also includes untracked files so new files are picked up on incremental sync.
|
|
65
|
+
* Uses -z for null-delimited output consistent with getGitNonIgnoredFiles.
|
|
63
66
|
*/
|
|
64
67
|
export function getChangedFiles(projectRoot, sinceRef = 'HEAD~1', onWarn) {
|
|
68
|
+
if (!SAFE_GIT_REF.test(sinceRef)) {
|
|
69
|
+
if (onWarn) {
|
|
70
|
+
onWarn(`Invalid git ref "${sinceRef}" — falling back to full sync.`);
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
65
74
|
try {
|
|
66
|
-
const
|
|
75
|
+
const diffOutput = execFileSync('git', ['diff', '-z', '--name-only', sinceRef], {
|
|
67
76
|
cwd: projectRoot,
|
|
68
77
|
encoding: 'utf-8',
|
|
78
|
+
shell: process.platform === 'win32',
|
|
69
79
|
});
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
// Also pick up untracked files (new files not yet committed)
|
|
81
|
+
let untrackedOutput = '';
|
|
82
|
+
try {
|
|
83
|
+
untrackedOutput = execFileSync('git', ['ls-files', '-z', '--others', '--exclude-standard'], {
|
|
84
|
+
cwd: projectRoot,
|
|
85
|
+
encoding: 'utf-8',
|
|
86
|
+
shell: process.platform === 'win32',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
if (onWarn) {
|
|
91
|
+
onWarn(`Failed to list untracked files: ${err instanceof Error ? err.message : String(err)}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const paths = new Set((diffOutput + untrackedOutput)
|
|
95
|
+
.split('\0')
|
|
96
|
+
.map((p) => p.replace(/\\/g, '/'))
|
|
97
|
+
.filter(Boolean));
|
|
98
|
+
return [...paths];
|
|
74
99
|
}
|
|
75
100
|
catch (err) {
|
|
76
101
|
const msg = `Failed to get changed files from git. Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
@@ -80,4 +105,22 @@ export function getChangedFiles(projectRoot, sinceRef = 'HEAD~1', onWarn) {
|
|
|
80
105
|
return null;
|
|
81
106
|
}
|
|
82
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Get the current HEAD SHA for sync state tracking.
|
|
110
|
+
*/
|
|
111
|
+
export function getHeadSha(projectRoot, onWarn) {
|
|
112
|
+
try {
|
|
113
|
+
return execFileSync('git', ['rev-parse', 'HEAD'], {
|
|
114
|
+
cwd: projectRoot,
|
|
115
|
+
encoding: 'utf-8',
|
|
116
|
+
shell: process.platform === 'win32',
|
|
117
|
+
}).trim();
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
if (onWarn) {
|
|
121
|
+
onWarn(`Failed to read HEAD SHA: ${err instanceof Error ? err.message : String(err)}`);
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
83
126
|
//# sourceMappingURL=file-resolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-resolver.js","sourceRoot":"","sources":["../../src/ingest/file-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"file-resolver.js","sourceRoot":"","sources":["../../src/ingest/file-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAGhC,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAQ9D;;;GAGG;AACH,SAAS,qBAAqB,CAC5B,WAAmB,EACnB,MAA8B;IAE9B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CACzB,KAAK,EACL,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB,CAAC,EAChE;YACE,GAAG,EAAE,WAAW;YAChB,QAAQ,EAAE,OAAO;YACjB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;YAC3B,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;SACpC,CACF,CAAC;QACF,OAAO,IAAI,GAAG,CACZ,MAAM;aACH,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CACrC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,QAAQ,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClE,MAAM,GAAG,GACP,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC;YAC3D,CAAC,CAAC,oGAAoG;YACtG,CAAC,CAAC,kGAAkG,QAAQ,EAAE,CAAC;QACnH,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,YAAY,CAC1B,OAAuB,EACvB,WAAmB,EACnB,iBAA2B,uBAAuB,EAClD,MAA8B;IAE9B,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,UAAU,GAAG,qBAAqB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAE9D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE;YACpC,GAAG,EAAE,WAAW;YAChB,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,cAAc;SACvB,CAAC,CAAC;QAEH,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACjD,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC;gBAAE,SAAS;YACrC,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC;gBAAE,SAAS;YAC1D,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAEvB,OAAO,CAAC,IAAI,CAAC;gBACX,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC;gBAC7C,YAAY;gBACZ,MAAM;aACP,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,gGAAgG;AAChG,MAAM,YAAY,GAAG,0BAA0B,CAAC;AAEhD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,WAAmB,EACnB,WAAmB,QAAQ,EAC3B,MAA8B;IAE9B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,oBAAoB,QAAQ,gCAAgC,CAAC,CAAC;QACvE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE;YAC9E,GAAG,EAAE,WAAW;YAChB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;SACpC,CAAC,CAAC;QAEH,6DAA6D;QAC7D,IAAI,eAAe,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,eAAe,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,oBAAoB,CAAC,EAAE;gBAC1F,GAAG,EAAE,WAAW;gBAChB,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;aACpC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CACJ,mCAAmC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACtF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,GAAG,CACnB,CAAC,UAAU,GAAG,eAAe,CAAC;aAC3B,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;aACjC,MAAM,CAAC,OAAO,CAAC,CACnB,CAAC;QAEF,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;IACpB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,gDAAgD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/G,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,WAAmB,EAAE,MAA8B;IAC5E,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE;YAChD,GAAG,EAAE,WAAW;YAChB,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;SACpC,CAAC,CAAC,IAAI,EAAE,CAAC;IACZ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,4BAA4B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzF,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-resolver.test.d.ts","sourceRoot":"","sources":["../../src/ingest/file-resolver.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import * as childProcess from 'node:child_process';
|
|
2
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { getChangedFiles, getHeadSha } from './file-resolver.js';
|
|
4
|
+
vi.mock('node:child_process', () => ({
|
|
5
|
+
execFileSync: vi.fn(),
|
|
6
|
+
}));
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
vi.restoreAllMocks();
|
|
9
|
+
});
|
|
10
|
+
describe('getHeadSha', () => {
|
|
11
|
+
it('returns trimmed SHA on success', () => {
|
|
12
|
+
vi.mocked(childProcess.execFileSync).mockReturnValue('abc123def456\n');
|
|
13
|
+
expect(getHeadSha('/project')).toBe('abc123def456');
|
|
14
|
+
});
|
|
15
|
+
it('returns null when git fails', () => {
|
|
16
|
+
vi.mocked(childProcess.execFileSync).mockImplementation(() => {
|
|
17
|
+
throw new Error('not a git repo');
|
|
18
|
+
});
|
|
19
|
+
expect(getHeadSha('/project')).toBeNull();
|
|
20
|
+
});
|
|
21
|
+
it('calls onWarn when git fails', () => {
|
|
22
|
+
vi.mocked(childProcess.execFileSync).mockImplementation(() => {
|
|
23
|
+
throw new Error('not a git repo');
|
|
24
|
+
});
|
|
25
|
+
const warn = vi.fn();
|
|
26
|
+
getHeadSha('/project', warn);
|
|
27
|
+
expect(warn).toHaveBeenCalledWith(expect.stringContaining('not a git repo'));
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe('getChangedFiles', () => {
|
|
31
|
+
it('returns deduplicated paths from diff and untracked (null-delimited)', () => {
|
|
32
|
+
vi.mocked(childProcess.execFileSync).mockImplementation((_cmd, args) => {
|
|
33
|
+
if (args && args.includes('diff'))
|
|
34
|
+
return 'src/a.ts\0src/b.ts\0';
|
|
35
|
+
if (args && args.includes('ls-files'))
|
|
36
|
+
return 'src/b.ts\0src/new.ts\0';
|
|
37
|
+
return '';
|
|
38
|
+
});
|
|
39
|
+
const result = getChangedFiles('/project', 'HEAD~1');
|
|
40
|
+
expect(result).toEqual(expect.arrayContaining(['src/a.ts', 'src/b.ts', 'src/new.ts']));
|
|
41
|
+
expect(result).toHaveLength(3);
|
|
42
|
+
});
|
|
43
|
+
it('returns null and warns when git diff fails', () => {
|
|
44
|
+
vi.mocked(childProcess.execFileSync).mockImplementation(() => {
|
|
45
|
+
throw new Error('bad ref');
|
|
46
|
+
});
|
|
47
|
+
const warn = vi.fn();
|
|
48
|
+
const result = getChangedFiles('/project', 'HEAD~1', warn);
|
|
49
|
+
expect(result).toBeNull();
|
|
50
|
+
expect(warn).toHaveBeenCalledWith(expect.stringContaining('bad ref'));
|
|
51
|
+
});
|
|
52
|
+
it('still returns diff results when untracked listing fails', () => {
|
|
53
|
+
vi.mocked(childProcess.execFileSync).mockImplementation((_cmd, args) => {
|
|
54
|
+
if (args && args.includes('diff'))
|
|
55
|
+
return 'src/a.ts\0';
|
|
56
|
+
throw new Error('ls-files failed');
|
|
57
|
+
});
|
|
58
|
+
const warn = vi.fn();
|
|
59
|
+
const result = getChangedFiles('/project', 'HEAD~1', warn);
|
|
60
|
+
expect(result).toEqual(['src/a.ts']);
|
|
61
|
+
expect(warn).toHaveBeenCalledWith(expect.stringContaining('untracked'));
|
|
62
|
+
});
|
|
63
|
+
it('normalizes backslashes to forward slashes', () => {
|
|
64
|
+
vi.mocked(childProcess.execFileSync).mockImplementation((_cmd, args) => {
|
|
65
|
+
if (args && args.includes('diff'))
|
|
66
|
+
return 'src\\foo\\bar.ts\0';
|
|
67
|
+
return '';
|
|
68
|
+
});
|
|
69
|
+
const result = getChangedFiles('/project');
|
|
70
|
+
expect(result).toEqual(['src/foo/bar.ts']);
|
|
71
|
+
});
|
|
72
|
+
it('rejects sinceRef with shell metacharacters', () => {
|
|
73
|
+
const warn = vi.fn();
|
|
74
|
+
const result = getChangedFiles('/project', 'HEAD; rm -rf /', warn);
|
|
75
|
+
expect(result).toBeNull();
|
|
76
|
+
expect(warn).toHaveBeenCalledWith(expect.stringContaining('Invalid git ref'));
|
|
77
|
+
});
|
|
78
|
+
it('accepts valid hex SHA as sinceRef', () => {
|
|
79
|
+
vi.mocked(childProcess.execFileSync).mockReturnValue('');
|
|
80
|
+
const result = getChangedFiles('/project', 'abc123def456');
|
|
81
|
+
expect(result).toEqual([]);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=file-resolver.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-resolver.test.js","sourceRoot":"","sources":["../../src/ingest/file-resolver.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/ingest/pipeline.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,OAAO,KAAK,EAAS,WAAW,
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/ingest/pipeline.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,OAAO,KAAK,EAAS,WAAW,EAAa,MAAM,aAAa,CAAC;AAwCjE,wBAAsB,OAAO,CAC3B,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC,CA4I9D"}
|
package/dist/ingest/pipeline.js
CHANGED
|
@@ -3,12 +3,43 @@ import * as path from 'node:path';
|
|
|
3
3
|
import { createChunker } from '../chunkers/chunker.js';
|
|
4
4
|
import { createEmbedder } from '../embedders/embedder.js';
|
|
5
5
|
import { LanceStore } from '../store/lance-store.js';
|
|
6
|
-
import { getChangedFiles, resolveFiles } from './file-resolver.js';
|
|
6
|
+
import { getChangedFiles, getHeadSha, resolveFiles } from './file-resolver.js';
|
|
7
7
|
const EMBED_BATCH_SIZE = 100;
|
|
8
|
+
const SYNC_STATE_FILE = 'cache/sync-state.json';
|
|
9
|
+
function readSyncState(totemDir, onProgress) {
|
|
10
|
+
const statePath = path.join(totemDir, SYNC_STATE_FILE);
|
|
11
|
+
try {
|
|
12
|
+
const raw = fs.readFileSync(statePath, 'utf-8');
|
|
13
|
+
const parsed = JSON.parse(raw);
|
|
14
|
+
if (typeof parsed.lastSyncSha === 'string' &&
|
|
15
|
+
parsed.lastSyncSha &&
|
|
16
|
+
typeof parsed.timestamp === 'number') {
|
|
17
|
+
return parsed;
|
|
18
|
+
}
|
|
19
|
+
onProgress?.(`Warning: Ignoring malformed sync state file at ${statePath}.`);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
// ENOENT is expected on first run — don't warn
|
|
24
|
+
if (err instanceof Error && err.code === 'ENOENT') {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
onProgress?.(`Warning: Failed to read sync state: ${err instanceof Error ? err.message : String(err)}`);
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function writeSyncState(totemDir, state) {
|
|
32
|
+
const statePath = path.join(totemDir, SYNC_STATE_FILE);
|
|
33
|
+
const dir = path.dirname(statePath);
|
|
34
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
35
|
+
fs.writeFileSync(statePath, JSON.stringify(state, null, 2) + '\n', 'utf-8');
|
|
36
|
+
}
|
|
8
37
|
export async function runSync(config, options) {
|
|
9
38
|
const { projectRoot, onProgress } = options;
|
|
10
39
|
let incremental = options.incremental;
|
|
11
40
|
const log = onProgress ?? (() => { });
|
|
41
|
+
// 0. Capture HEAD SHA early — before any async work that might race with new commits
|
|
42
|
+
const headSha = getHeadSha(projectRoot, log);
|
|
12
43
|
// 1. Create embedder
|
|
13
44
|
log('Initializing embedding provider...');
|
|
14
45
|
const embedder = createEmbedder(config.embedding);
|
|
@@ -22,10 +53,21 @@ export async function runSync(config, options) {
|
|
|
22
53
|
incremental = false;
|
|
23
54
|
}
|
|
24
55
|
// 3. Resolve files to process
|
|
56
|
+
const totemDir = path.join(projectRoot, config.totemDir);
|
|
25
57
|
const allFiles = resolveFiles(config.targets, projectRoot, config.ignorePatterns, log);
|
|
26
58
|
let filesToProcess;
|
|
59
|
+
let deletedPaths = [];
|
|
27
60
|
if (incremental) {
|
|
28
|
-
|
|
61
|
+
// Determine the ref to diff against: saved sync state > fallback HEAD~1
|
|
62
|
+
let sinceRef = 'HEAD~1';
|
|
63
|
+
if (!options.changedFiles) {
|
|
64
|
+
const syncState = readSyncState(totemDir, log);
|
|
65
|
+
if (syncState) {
|
|
66
|
+
sinceRef = syncState.lastSyncSha;
|
|
67
|
+
log(`Resuming from last sync at ${sinceRef.slice(0, 8)}...`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const changedPaths = options.changedFiles ?? getChangedFiles(projectRoot, sinceRef, log);
|
|
29
71
|
if (changedPaths === null) {
|
|
30
72
|
log('Git diff failed, falling back to full sync...');
|
|
31
73
|
await store.reset();
|
|
@@ -34,8 +76,13 @@ export async function runSync(config, options) {
|
|
|
34
76
|
}
|
|
35
77
|
else {
|
|
36
78
|
const changedSet = new Set(changedPaths);
|
|
79
|
+
const allFileSet = new Set(allFiles.map((f) => f.relativePath));
|
|
80
|
+
// Partition: files that still exist get re-indexed, missing files get deleted
|
|
37
81
|
filesToProcess = allFiles.filter((f) => changedSet.has(f.relativePath));
|
|
38
|
-
|
|
82
|
+
deletedPaths = changedPaths.filter((p) => !allFileSet.has(p));
|
|
83
|
+
log(`Incremental sync: ${filesToProcess.length} changed files` +
|
|
84
|
+
(deletedPaths.length > 0 ? `, ${deletedPaths.length} deleted` : '') +
|
|
85
|
+
` (of ${allFiles.length} total)`);
|
|
39
86
|
}
|
|
40
87
|
}
|
|
41
88
|
else {
|
|
@@ -44,6 +91,16 @@ export async function runSync(config, options) {
|
|
|
44
91
|
filesToProcess = allFiles;
|
|
45
92
|
log(`Full sync: ${filesToProcess.length} files to process`);
|
|
46
93
|
}
|
|
94
|
+
// 3b. Purge chunks from deleted files before ingesting new ones
|
|
95
|
+
for (const deletedPath of deletedPaths) {
|
|
96
|
+
try {
|
|
97
|
+
await store.deleteByFile(deletedPath);
|
|
98
|
+
log(` Purged chunks for deleted file: ${deletedPath}`);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
log(` Warning: failed to purge ${deletedPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
47
104
|
// 4. Chunk files and stream to LanceDB in batches (bounded memory)
|
|
48
105
|
let totalChunks = 0;
|
|
49
106
|
let buffer = [];
|
|
@@ -85,6 +142,10 @@ export async function runSync(config, options) {
|
|
|
85
142
|
// Flush remaining chunks
|
|
86
143
|
await flushBuffer();
|
|
87
144
|
log(`Sync complete: ${totalChunks} chunks from ${filesToProcess.length} files`);
|
|
145
|
+
// Persist sync state so next incremental sync knows where to diff from
|
|
146
|
+
if (headSha) {
|
|
147
|
+
writeSyncState(totemDir, { lastSyncSha: headSha, timestamp: Date.now() });
|
|
148
|
+
}
|
|
88
149
|
return {
|
|
89
150
|
chunksProcessed: totalChunks,
|
|
90
151
|
filesProcessed: filesToProcess.length,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/ingest/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAGrD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/ingest/pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.test.d.ts","sourceRoot":"","sources":["../../src/ingest/pipeline.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
+
// Import the internal helpers via a workaround — we test the state file contract
|
|
6
|
+
// since readSyncState/writeSyncState are not exported directly.
|
|
7
|
+
const SYNC_STATE_FILE = 'cache/sync-state.json';
|
|
8
|
+
describe('sync state persistence', () => {
|
|
9
|
+
let tmpDir;
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'totem-sync-state-'));
|
|
12
|
+
});
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
15
|
+
});
|
|
16
|
+
it('creates cache directory and writes valid JSON', () => {
|
|
17
|
+
const statePath = path.join(tmpDir, SYNC_STATE_FILE);
|
|
18
|
+
const dir = path.dirname(statePath);
|
|
19
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
20
|
+
const state = { lastSyncSha: 'abc123def456', timestamp: Date.now() };
|
|
21
|
+
fs.writeFileSync(statePath, JSON.stringify(state, null, 2) + '\n', 'utf-8');
|
|
22
|
+
const raw = fs.readFileSync(statePath, 'utf-8');
|
|
23
|
+
const parsed = JSON.parse(raw);
|
|
24
|
+
expect(parsed.lastSyncSha).toBe('abc123def456');
|
|
25
|
+
expect(typeof parsed.timestamp).toBe('number');
|
|
26
|
+
});
|
|
27
|
+
it('reads back a previously written state', () => {
|
|
28
|
+
const statePath = path.join(tmpDir, SYNC_STATE_FILE);
|
|
29
|
+
const dir = path.dirname(statePath);
|
|
30
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
31
|
+
const state = { lastSyncSha: 'deadbeef', timestamp: 1234567890 };
|
|
32
|
+
fs.writeFileSync(statePath, JSON.stringify(state), 'utf-8');
|
|
33
|
+
const raw = fs.readFileSync(statePath, 'utf-8');
|
|
34
|
+
const parsed = JSON.parse(raw);
|
|
35
|
+
expect(parsed.lastSyncSha).toBe('deadbeef');
|
|
36
|
+
expect(parsed.timestamp).toBe(1234567890);
|
|
37
|
+
});
|
|
38
|
+
it('returns null-equivalent for missing state file', () => {
|
|
39
|
+
const statePath = path.join(tmpDir, SYNC_STATE_FILE);
|
|
40
|
+
expect(fs.existsSync(statePath)).toBe(false);
|
|
41
|
+
});
|
|
42
|
+
it('returns null-equivalent for corrupted state file', () => {
|
|
43
|
+
const statePath = path.join(tmpDir, SYNC_STATE_FILE);
|
|
44
|
+
const dir = path.dirname(statePath);
|
|
45
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
46
|
+
fs.writeFileSync(statePath, '{ broken json!!!', 'utf-8');
|
|
47
|
+
let parsed = null;
|
|
48
|
+
try {
|
|
49
|
+
parsed = JSON.parse(fs.readFileSync(statePath, 'utf-8'));
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Expected
|
|
53
|
+
}
|
|
54
|
+
expect(parsed).toBeNull();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
describe('deleted file partitioning', () => {
|
|
58
|
+
it('identifies files in changedPaths but missing from allFiles as deleted', () => {
|
|
59
|
+
const changedPaths = ['src/a.ts', 'src/b.ts', 'src/deleted.ts'];
|
|
60
|
+
const allFileSet = new Set(['src/a.ts', 'src/b.ts']);
|
|
61
|
+
const deletedPaths = changedPaths.filter((p) => !allFileSet.has(p));
|
|
62
|
+
expect(deletedPaths).toEqual(['src/deleted.ts']);
|
|
63
|
+
});
|
|
64
|
+
it('returns empty when all changed files still exist', () => {
|
|
65
|
+
const changedPaths = ['src/a.ts'];
|
|
66
|
+
const allFileSet = new Set(['src/a.ts', 'src/b.ts']);
|
|
67
|
+
const deletedPaths = changedPaths.filter((p) => !allFileSet.has(p));
|
|
68
|
+
expect(deletedPaths).toEqual([]);
|
|
69
|
+
});
|
|
70
|
+
it('handles renamed files (old path deleted, new path exists)', () => {
|
|
71
|
+
const changedPaths = ['src/old-name.ts', 'src/new-name.ts'];
|
|
72
|
+
const allFileSet = new Set(['src/new-name.ts']);
|
|
73
|
+
const filesToProcess = changedPaths.filter((p) => allFileSet.has(p));
|
|
74
|
+
const deletedPaths = changedPaths.filter((p) => !allFileSet.has(p));
|
|
75
|
+
expect(filesToProcess).toEqual(['src/new-name.ts']);
|
|
76
|
+
expect(deletedPaths).toEqual(['src/old-name.ts']);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
//# sourceMappingURL=pipeline.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.test.js","sourceRoot":"","sources":["../../src/ingest/pipeline.test.ts"],"names":[],"mappings":"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"}
|
package/dist/ingest/sync.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export type { ResolvedFile } from './file-resolver.js';
|
|
2
|
-
export { getChangedFiles, resolveFiles } from './file-resolver.js';
|
|
2
|
+
export { getChangedFiles, getHeadSha, resolveFiles } from './file-resolver.js';
|
|
3
3
|
export { runSync } from './pipeline.js';
|
|
4
4
|
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/ingest/sync.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/ingest/sync.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/ingest/sync.js
CHANGED
package/dist/ingest/sync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/ingest/sync.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/ingest/sync.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -64,6 +64,13 @@ export interface SyncOptions {
|
|
|
64
64
|
/** Callback for progress reporting */
|
|
65
65
|
onProgress?: (message: string) => void;
|
|
66
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Persisted state for incremental sync tracking.
|
|
69
|
+
*/
|
|
70
|
+
export interface SyncState {
|
|
71
|
+
lastSyncSha: string;
|
|
72
|
+
timestamp: number;
|
|
73
|
+
}
|
|
67
74
|
/**
|
|
68
75
|
* Options for search queries.
|
|
69
76
|
*/
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAErE;;;GAGG;AACH,MAAM,WAAW,KAAK;IACpB,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAEhB,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IAEtB,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IAEjB,0CAA0C;IAC1C,IAAI,EAAE,WAAW,CAAC;IAElB,iDAAiD;IACjD,QAAQ,EAAE,aAAa,CAAC;IAExB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IAEd,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAElB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAEhB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;IAEpB,0DAA0D;IAC1D,WAAW,EAAE,OAAO,CAAC;IAErB,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB,sCAAsC;IACtC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAErE;;;GAGG;AACH,MAAM,WAAW,KAAK;IACpB,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAEhB,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IAEtB,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IAEjB,0CAA0C;IAC1C,IAAI,EAAE,WAAW,CAAC;IAElB,iDAAiD;IACjD,QAAQ,EAAE,aAAa,CAAC;IAExB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IAEd,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAElB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAEhB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;IAEpB,0DAA0D;IAC1D,WAAW,EAAE,OAAO,CAAC;IAErB,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB,sCAAsC;IACtC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrap external/user-supplied content in XML tags to create a clear boundary
|
|
3
|
+
* between system instructions and passive data. Escapes matching closing tags
|
|
4
|
+
* in the content using backslash escaping to prevent breakout.
|
|
5
|
+
*
|
|
6
|
+
* Backslash escaping is preferred over HTML entities for LLM consumption —
|
|
7
|
+
* it prevents tag interpretation while maintaining readability.
|
|
8
|
+
*
|
|
9
|
+
* @see https://github.com/mmnto-ai/totem/issues/149
|
|
10
|
+
* @see https://github.com/mmnto-ai/totem/issues/158
|
|
11
|
+
*/
|
|
12
|
+
export declare function wrapXml(tag: string, content: string): string;
|
|
13
|
+
//# sourceMappingURL=xml-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-format.d.ts","sourceRoot":"","sources":["../src/xml-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAO5D"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrap external/user-supplied content in XML tags to create a clear boundary
|
|
3
|
+
* between system instructions and passive data. Escapes matching closing tags
|
|
4
|
+
* in the content using backslash escaping to prevent breakout.
|
|
5
|
+
*
|
|
6
|
+
* Backslash escaping is preferred over HTML entities for LLM consumption —
|
|
7
|
+
* it prevents tag interpretation while maintaining readability.
|
|
8
|
+
*
|
|
9
|
+
* @see https://github.com/mmnto-ai/totem/issues/149
|
|
10
|
+
* @see https://github.com/mmnto-ai/totem/issues/158
|
|
11
|
+
*/
|
|
12
|
+
export function wrapXml(tag, content) {
|
|
13
|
+
const safeTag = tag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
14
|
+
const escaped = content.replace(new RegExp(`</\\s*${safeTag}\\s*>`, 'gi'), (match) => `<\\/${match.slice(2)}`);
|
|
15
|
+
return `<${tag}>\n${escaped}\n</${tag}>`;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=xml-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-format.js","sourceRoot":"","sources":["../src/xml-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,OAAO,CAAC,GAAW,EAAE,OAAe;IAClD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAC7B,IAAI,MAAM,CAAC,SAAS,OAAO,OAAO,EAAE,IAAI,CAAC,EACzC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CACnC,CAAC;IACF,OAAO,IAAI,GAAG,MAAM,OAAO,OAAO,GAAG,GAAG,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-format.test.d.ts","sourceRoot":"","sources":["../src/xml-format.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { wrapXml } from './xml-format.js';
|
|
3
|
+
describe('wrapXml', () => {
|
|
4
|
+
it('wraps content in XML tags', () => {
|
|
5
|
+
expect(wrapXml('knowledge', 'Hello world')).toBe('<knowledge>\nHello world\n</knowledge>');
|
|
6
|
+
});
|
|
7
|
+
it('escapes exact lowercase closing tags in content', () => {
|
|
8
|
+
const result = wrapXml('knowledge', 'payload </knowledge> injection');
|
|
9
|
+
expect(result).toBe('<knowledge>\npayload <\\/knowledge> injection\n</knowledge>');
|
|
10
|
+
});
|
|
11
|
+
it('escapes mixed-case closing tags (case-insensitive)', () => {
|
|
12
|
+
const result = wrapXml('knowledge', 'try </KNOWLEDGE> or </Knowledge>');
|
|
13
|
+
expect(result).toBe('<knowledge>\ntry <\\/KNOWLEDGE> or <\\/Knowledge>\n</knowledge>');
|
|
14
|
+
});
|
|
15
|
+
it('escapes multiple instances of the closing tag', () => {
|
|
16
|
+
const result = wrapXml('knowledge', '</knowledge> and </knowledge>');
|
|
17
|
+
expect(result).toBe('<knowledge>\n<\\/knowledge> and <\\/knowledge>\n</knowledge>');
|
|
18
|
+
});
|
|
19
|
+
it('wraps empty content', () => {
|
|
20
|
+
expect(wrapXml('git_diff', '')).toBe('<git_diff>\n\n</git_diff>');
|
|
21
|
+
});
|
|
22
|
+
it('works with different tag names', () => {
|
|
23
|
+
const result = wrapXml('lesson_added', 'Saved. </lesson_added> test');
|
|
24
|
+
expect(result).toBe('<lesson_added>\nSaved. <\\/lesson_added> test\n</lesson_added>');
|
|
25
|
+
});
|
|
26
|
+
it('escapes closing tags with internal whitespace', () => {
|
|
27
|
+
const result = wrapXml('knowledge', 'try </ knowledge> or </knowledge >');
|
|
28
|
+
expect(result).toBe('<knowledge>\ntry <\\/ knowledge> or <\\/knowledge >\n</knowledge>');
|
|
29
|
+
});
|
|
30
|
+
it('does not escape non-matching closing tags', () => {
|
|
31
|
+
const content = 'contains </other_tag> but not the target';
|
|
32
|
+
expect(wrapXml('issue_body', content)).toBe('<issue_body>\ncontains </other_tag> but not the target\n</issue_body>');
|
|
33
|
+
});
|
|
34
|
+
it('preserves multiline content', () => {
|
|
35
|
+
const content = 'line 1\nline 2\nline 3';
|
|
36
|
+
expect(wrapXml('git_status', content)).toBe('<git_status>\nline 1\nline 2\nline 3\n</git_status>');
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=xml-format.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-format.test.js","sourceRoot":"","sources":["../src/xml-format.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,gCAAgC,CAAC,CAAC;QACtE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,kCAAkC,CAAC,CAAC;QACxE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,+BAA+B,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,6BAA6B,CAAC,CAAC;QACtE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,oCAAoC,CAAC,CAAC;QAC1E,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,OAAO,GAAG,0CAA0C,CAAC;QAC3D,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CACzC,uEAAuE,CACxE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,OAAO,GAAG,wBAAwB,CAAC;QACzC,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CACzC,qDAAqD,CACtD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|