@gmickel/gno 2.10.0 → 2.10.1
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 +1 -1
- package/browser-extension/artifacts/{gno-browser-clipper-v2.10.0.zip → gno-browser-clipper-v2.10.1.zip} +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v2.10.1.zip.sha256 +1 -0
- package/browser-extension/dist/manifest.json +1 -1
- package/bunfig.toml +5 -1
- package/package.json +2 -1
- package/spec/cli.md +32 -10
- package/spec/mcp.md +1 -1
- package/spec/output-schemas/mcp-remove-result.schema.json +2 -2
- package/src/cli/commands/cleanup.ts +9 -1
- package/src/cli/commands/collection/remove.ts +50 -31
- package/src/cli/commands/collection/rename.ts +36 -8
- package/src/cli/program.ts +56 -16
- package/src/mcp/tools/remove-collection.ts +2 -1
- package/src/serve/routes/api.ts +3 -4
- package/src/store/sqlite/adapter.ts +17 -4
- package/browser-extension/artifacts/gno-browser-clipper-v2.10.0.zip.sha256 +0 -1
package/README.md
CHANGED
|
@@ -139,7 +139,7 @@ See the [guide](docs/COMPILED-CONTEXT.md).
|
|
|
139
139
|
|
|
140
140
|
<!-- public-truth:current-version -->
|
|
141
141
|
|
|
142
|
-
> Current source version: **v2.10.
|
|
142
|
+
> Current source version: **v2.10.1**. See [CHANGELOG.md](./CHANGELOG.md).
|
|
143
143
|
|
|
144
144
|
<!-- /public-truth -->
|
|
145
145
|
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
e42897b28d0fc0fca7d1d7aca6ab016255cc3b5bf20d38bcac51535499eb7f25 gno-browser-clipper-v2.10.1.zip
|
package/bunfig.toml
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
plugins = ["bun-plugin-tailwind"]
|
|
3
3
|
|
|
4
4
|
[test]
|
|
5
|
-
preload = [
|
|
5
|
+
preload = [
|
|
6
|
+
"./test/preload/temp-dir.ts",
|
|
7
|
+
"./test/preload/happy-dom.ts",
|
|
8
|
+
"./test/preload/env-guard.ts",
|
|
9
|
+
]
|
|
6
10
|
# Frozen evidence and local experiments are not the executable regression suite.
|
|
7
11
|
pathIgnorePatterns = [".flow/artifacts/**", "notes/**"]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gmickel/gno",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.1",
|
|
4
4
|
"description": "Local semantic search for your documents. Index Markdown, PDF, and Office files with hybrid BM25 + vector search.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"embeddings",
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"test:e2e:install": "bunx playwright install chromium",
|
|
73
73
|
"test:package": "bun scripts/package-smoke.ts",
|
|
74
74
|
"test:package:clipper": "bun scripts/package-smoke-clipper-cli.ts",
|
|
75
|
+
"test:tmp-check": "bun scripts/test-tmp-check.ts",
|
|
75
76
|
"test:watch": "bun test --watch",
|
|
76
77
|
"test:coverage": "bun test --coverage",
|
|
77
78
|
"test:coverage:html": "bun test --coverage --html",
|
package/spec/cli.md
CHANGED
|
@@ -242,8 +242,10 @@ the model with `id`, `model`, `dimensions`, `state` (`active`|`shadow`),
|
|
|
242
242
|
Terminal output prints a `Vector partitions:` block
|
|
243
243
|
unless there is exactly one healthy partition. `collections`, `totalDocuments`
|
|
244
244
|
and `totalChunks` cover configured collections only: a collection removed from
|
|
245
|
-
config
|
|
246
|
-
|
|
245
|
+
config is not reported even while its rows remain in the index until the next
|
|
246
|
+
command that syncs collections (`gno update`, `gno index`, `gno cleanup`). The
|
|
247
|
+
embedding backlog likewise counts chunks of configured collections only.
|
|
248
|
+
`gno collection remove` syncs at once, so no rows remain. `totalChunks` counts the
|
|
247
249
|
distinct chunks of active documents; chunks left by deleted documents do not
|
|
248
250
|
count. Per-collection chunk totals remain deduplicated by canonical chunk;
|
|
249
251
|
embedded counts require matching current inputs for every active owner within
|
|
@@ -1097,12 +1099,12 @@ for `updateCmd`; without it the command is stopped after 10 minutes.
|
|
|
1097
1099
|
|
|
1098
1100
|
### gno collection remove
|
|
1099
1101
|
|
|
1100
|
-
Remove a collection from the index.
|
|
1102
|
+
Remove a collection from the config and the index.
|
|
1101
1103
|
|
|
1102
1104
|
**Synopsis:**
|
|
1103
1105
|
|
|
1104
1106
|
```bash
|
|
1105
|
-
gno collection remove <name>
|
|
1107
|
+
gno collection remove <name> [--lock-wait <duration>] [--no-wait]
|
|
1106
1108
|
```
|
|
1107
1109
|
|
|
1108
1110
|
**Arguments:**
|
|
@@ -1113,12 +1115,19 @@ gno collection remove <name>
|
|
|
1113
1115
|
**Behavior:**
|
|
1114
1116
|
|
|
1115
1117
|
- Removes collection from config
|
|
1116
|
-
-
|
|
1118
|
+
- Syncs the index in the same config write: the collection row and its
|
|
1119
|
+
documents are deleted at once, so status, search and the embedding backlog
|
|
1120
|
+
stop counting them without another command
|
|
1121
|
+
- Content, chunks and vectors no longer referenced by any document stay until
|
|
1122
|
+
`gno cleanup`
|
|
1123
|
+
- Waits for the index write lease (`--lock-wait`, default 120s; `--no-wait`
|
|
1124
|
+
fails at once)
|
|
1117
1125
|
|
|
1118
1126
|
**Exit Codes:**
|
|
1119
1127
|
|
|
1120
1128
|
- 0: Success
|
|
1121
|
-
- 1: Collection not found
|
|
1129
|
+
- 1: Collection not found or referenced by contexts
|
|
1130
|
+
- 2: Config save or index sync failure, or write lease busy
|
|
1122
1131
|
|
|
1123
1132
|
---
|
|
1124
1133
|
|
|
@@ -1129,7 +1138,7 @@ Rename a collection.
|
|
|
1129
1138
|
**Synopsis:**
|
|
1130
1139
|
|
|
1131
1140
|
```bash
|
|
1132
|
-
gno collection rename <old> <new>
|
|
1141
|
+
gno collection rename <old> <new> [--lock-wait <duration>] [--no-wait]
|
|
1133
1142
|
```
|
|
1134
1143
|
|
|
1135
1144
|
**Arguments:**
|
|
@@ -1138,10 +1147,22 @@ gno collection rename <old> <new>
|
|
|
1138
1147
|
| `<old>` | string | Current collection name |
|
|
1139
1148
|
| `<new>` | string | New collection name |
|
|
1140
1149
|
|
|
1150
|
+
**Behavior:**
|
|
1151
|
+
|
|
1152
|
+
- Renames the collection in config and rewrites contexts scoped to it
|
|
1153
|
+
- Syncs the index in the same config write. Documents are keyed by collection
|
|
1154
|
+
name, so the old name's documents are deleted at once and the collection is
|
|
1155
|
+
empty until the next `gno update` (or `gno index`) indexes its files under
|
|
1156
|
+
the new name; content and vectors not yet removed by `gno cleanup` are reused
|
|
1157
|
+
- Prints `Run: gno update to index it under the new name`
|
|
1158
|
+
- Waits for the index write lease (`--lock-wait`, default 120s; `--no-wait`
|
|
1159
|
+
fails at once)
|
|
1160
|
+
|
|
1141
1161
|
**Exit Codes:**
|
|
1142
1162
|
|
|
1143
1163
|
- 0: Success
|
|
1144
|
-
- 1: Old name not found
|
|
1164
|
+
- 1: Old name not found, new name already exists, or new name invalid
|
|
1165
|
+
- 2: Config save or index sync failure, or write lease busy
|
|
1145
1166
|
|
|
1146
1167
|
---
|
|
1147
1168
|
|
|
@@ -2944,12 +2965,13 @@ included, is refused. JSON output is
|
|
|
2944
2965
|
|
|
2945
2966
|
### gno cleanup
|
|
2946
2967
|
|
|
2947
|
-
Remove
|
|
2968
|
+
Remove documents of collections no longer in the config, then orphaned
|
|
2969
|
+
content, chunks, and vectors not referenced by active documents.
|
|
2948
2970
|
|
|
2949
2971
|
**Synopsis:**
|
|
2950
2972
|
|
|
2951
2973
|
```bash
|
|
2952
|
-
gno cleanup
|
|
2974
|
+
gno cleanup [--lock-wait <duration>] [--no-wait]
|
|
2953
2975
|
```
|
|
2954
2976
|
|
|
2955
2977
|
**Exit Codes:**
|
package/spec/mcp.md
CHANGED
|
@@ -2830,7 +2830,7 @@ Full index: sync files + generate embeddings (write-enabled). Runs as background
|
|
|
2830
2830
|
|
|
2831
2831
|
### gno_remove_collection
|
|
2832
2832
|
|
|
2833
|
-
Remove a collection from config (write-enabled).
|
|
2833
|
+
Remove a collection from config and delete its documents from the index (write-enabled). Content, chunks and vectors stay until `gno cleanup`; `indexedDataRetained` is always `true` for that reason.
|
|
2834
2834
|
|
|
2835
2835
|
**Input Schema:**
|
|
2836
2836
|
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
},
|
|
29
29
|
"indexedDataRetained": {
|
|
30
30
|
"type": "boolean",
|
|
31
|
-
"description": "
|
|
31
|
+
"description": "Always true: the collection's documents are deleted, but content, chunks and vectors stay in the index until gno cleanup",
|
|
32
32
|
"const": true
|
|
33
33
|
},
|
|
34
34
|
"note": {
|
|
35
35
|
"type": "string",
|
|
36
|
-
"description": "
|
|
36
|
+
"description": "What was deleted and what stays until gno cleanup"
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* gno cleanup command implementation.
|
|
3
|
-
* Remove
|
|
3
|
+
* Remove documents of collections no longer configured, then orphaned
|
|
4
|
+
* content, chunks and vectors not referenced by active documents.
|
|
4
5
|
*
|
|
5
6
|
* @module src/cli/commands/cleanup
|
|
6
7
|
*/
|
|
@@ -61,6 +62,13 @@ export async function cleanup(
|
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
try {
|
|
65
|
+
// Drop collections no longer in the config first (their documents follow
|
|
66
|
+
// by cascade), so their content, chunks and vectors count as orphans.
|
|
67
|
+
const syncResult = await store.syncCollections(config.collections);
|
|
68
|
+
if (!syncResult.ok) {
|
|
69
|
+
return { success: false, error: syncResult.error.message };
|
|
70
|
+
}
|
|
71
|
+
|
|
64
72
|
const cleanupResult = await store.cleanupOrphans();
|
|
65
73
|
if (!cleanupResult.ok) {
|
|
66
74
|
return { success: false, error: cleanupResult.error.message };
|
|
@@ -3,43 +3,62 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { removeCollection } from "../../../collection";
|
|
6
|
-
import {
|
|
6
|
+
import { applyConfigChange } from "../../../core/config-mutation";
|
|
7
7
|
import { CliError } from "../../errors";
|
|
8
|
+
import { initStore } from "../shared";
|
|
8
9
|
|
|
9
10
|
export async function collectionRemove(
|
|
10
11
|
name: string,
|
|
11
|
-
options: { configPath?: string } = {}
|
|
12
|
+
options: { configPath?: string; indexName?: string } = {}
|
|
12
13
|
): Promise<void> {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
14
|
+
// Open the index so the removal reaches the store in the same locked
|
|
15
|
+
// boundary: syncing collections deletes the collection row, and its
|
|
16
|
+
// documents follow by cascade. A config-only edit left them active (and
|
|
17
|
+
// counted in the embedding backlog) until some later command synced.
|
|
18
|
+
const initialized = await initStore({
|
|
19
|
+
configPath: options.configPath,
|
|
20
|
+
indexName: options.indexName,
|
|
21
|
+
syncConfig: false,
|
|
22
|
+
allowEmptyCollections: true,
|
|
23
|
+
});
|
|
24
|
+
if (!initialized.ok) {
|
|
25
|
+
throw new CliError("RUNTIME", initialized.error);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const mutation = await applyConfigChange(
|
|
30
|
+
{ store: initialized.store, configPath: initialized.actualConfigPath },
|
|
31
|
+
(config) => {
|
|
32
|
+
const result = removeCollection(config, { name });
|
|
33
|
+
return result.ok
|
|
34
|
+
? {
|
|
35
|
+
ok: true as const,
|
|
36
|
+
config: result.config,
|
|
37
|
+
value: result.collection,
|
|
38
|
+
}
|
|
39
|
+
: {
|
|
40
|
+
ok: false as const,
|
|
41
|
+
error: result.message,
|
|
42
|
+
code: result.code,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
if (!mutation.ok) {
|
|
48
|
+
// Map collection error codes to CLI error codes
|
|
49
|
+
const cliCode =
|
|
50
|
+
mutation.code === "VALIDATION" ||
|
|
51
|
+
mutation.code === "NOT_FOUND" ||
|
|
52
|
+
mutation.code === "HAS_REFERENCES"
|
|
53
|
+
? "VALIDATION"
|
|
54
|
+
: "RUNTIME";
|
|
55
|
+
throw new CliError(cliCode, mutation.error);
|
|
28
56
|
}
|
|
29
|
-
);
|
|
30
57
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
mutation.code === "HAS_REFERENCES"
|
|
37
|
-
? "VALIDATION"
|
|
38
|
-
: "RUNTIME";
|
|
39
|
-
throw new CliError(cliCode, mutation.error);
|
|
58
|
+
process.stdout.write(
|
|
59
|
+
`Collection "${mutation.value?.name}" removed successfully\n`
|
|
60
|
+
);
|
|
61
|
+
} finally {
|
|
62
|
+
await initialized.store.close();
|
|
40
63
|
}
|
|
41
|
-
|
|
42
|
-
process.stdout.write(
|
|
43
|
-
`Collection "${mutation.value?.name}" removed successfully\n`
|
|
44
|
-
);
|
|
45
64
|
}
|
|
@@ -3,19 +3,51 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { CollectionSchema, getCollectionFromScope } from "../../../config";
|
|
6
|
-
import {
|
|
6
|
+
import { applyConfigChange } from "../../../core/config-mutation";
|
|
7
7
|
import { CliError } from "../../errors";
|
|
8
|
+
import { initStore, type InitStoreResult } from "../shared";
|
|
8
9
|
|
|
9
10
|
export async function collectionRename(
|
|
10
11
|
oldName: string,
|
|
11
12
|
newName: string,
|
|
12
|
-
options: { configPath?: string } = {}
|
|
13
|
+
options: { configPath?: string; indexName?: string } = {}
|
|
13
14
|
): Promise<void> {
|
|
14
15
|
const oldCollectionName = oldName.toLowerCase();
|
|
15
16
|
const newCollectionName = newName.toLowerCase();
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
// Documents are keyed by collection name (URIs, FTS paths, links), so the
|
|
19
|
+
// index cannot rename them in place. Sync in the same locked boundary: the
|
|
20
|
+
// old name's documents go now instead of at some later sync, and the next
|
|
21
|
+
// update indexes the files under the new name.
|
|
22
|
+
const initialized = await initStore({
|
|
23
|
+
configPath: options.configPath,
|
|
24
|
+
indexName: options.indexName,
|
|
25
|
+
syncConfig: false,
|
|
26
|
+
allowEmptyCollections: true,
|
|
27
|
+
});
|
|
28
|
+
if (!initialized.ok) {
|
|
29
|
+
throw new CliError("RUNTIME", initialized.error);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
await renameAndSync(initialized, oldCollectionName, newCollectionName);
|
|
34
|
+
} finally {
|
|
35
|
+
await initialized.store.close();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
process.stdout.write(
|
|
39
|
+
`Collection "${oldCollectionName}" renamed to "${newCollectionName}"\n` +
|
|
40
|
+
"Run: gno update to index it under the new name\n"
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function renameAndSync(
|
|
45
|
+
initialized: Extract<InitStoreResult, { ok: true }>,
|
|
46
|
+
oldCollectionName: string,
|
|
47
|
+
newCollectionName: string
|
|
48
|
+
): Promise<void> {
|
|
49
|
+
const mutation = await applyConfigChange(
|
|
50
|
+
{ store: initialized.store, configPath: initialized.actualConfigPath },
|
|
19
51
|
(config) => {
|
|
20
52
|
const collection = config.collections.find(
|
|
21
53
|
(item) => item.name === oldCollectionName
|
|
@@ -70,8 +102,4 @@ export async function collectionRename(
|
|
|
70
102
|
mutation.error
|
|
71
103
|
);
|
|
72
104
|
}
|
|
73
|
-
|
|
74
|
-
process.stdout.write(
|
|
75
|
-
`Collection "${oldCollectionName}" renamed to "${newCollectionName}"\n`
|
|
76
|
-
);
|
|
77
105
|
}
|
package/src/cli/program.ts
CHANGED
|
@@ -2870,23 +2870,59 @@ function wireManagementCommands(program: Command): void {
|
|
|
2870
2870
|
});
|
|
2871
2871
|
});
|
|
2872
2872
|
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2873
|
+
addWriteLeaseFlags(
|
|
2874
|
+
collectionCmd
|
|
2875
|
+
.command("remove <name>")
|
|
2876
|
+
.description("Remove a collection and its indexed documents")
|
|
2877
|
+
).action(async (name: string, cmdOpts: Record<string, unknown>) => {
|
|
2878
|
+
const { collectionRemove } = await import("./commands/collection");
|
|
2879
|
+
const lease = parseWriteLeaseFlags(cmdOpts);
|
|
2880
|
+
const result = await withCliWriteLease(
|
|
2881
|
+
{
|
|
2882
|
+
indexName: getGlobals().index,
|
|
2883
|
+
lockWaitMs: lease.lockWaitMs,
|
|
2884
|
+
noWait: lease.noWait,
|
|
2885
|
+
},
|
|
2886
|
+
async () => {
|
|
2887
|
+
await collectionRemove(name, {
|
|
2888
|
+
configPath: getGlobals().config,
|
|
2889
|
+
indexName: getGlobals().index,
|
|
2890
|
+
});
|
|
2891
|
+
return { success: true as const };
|
|
2892
|
+
}
|
|
2893
|
+
);
|
|
2894
|
+
throwIfWriteLeaseBusy(result, false);
|
|
2895
|
+
});
|
|
2880
2896
|
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2897
|
+
addWriteLeaseFlags(
|
|
2898
|
+
collectionCmd
|
|
2899
|
+
.command("rename <old> <new>")
|
|
2900
|
+
.description("Rename a collection (run gno update afterwards)")
|
|
2901
|
+
).action(
|
|
2902
|
+
async (
|
|
2903
|
+
oldName: string,
|
|
2904
|
+
newName: string,
|
|
2905
|
+
cmdOpts: Record<string, unknown>
|
|
2906
|
+
) => {
|
|
2885
2907
|
const { collectionRename } = await import("./commands/collection");
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2908
|
+
const lease = parseWriteLeaseFlags(cmdOpts);
|
|
2909
|
+
const result = await withCliWriteLease(
|
|
2910
|
+
{
|
|
2911
|
+
indexName: getGlobals().index,
|
|
2912
|
+
lockWaitMs: lease.lockWaitMs,
|
|
2913
|
+
noWait: lease.noWait,
|
|
2914
|
+
},
|
|
2915
|
+
async () => {
|
|
2916
|
+
await collectionRename(oldName, newName, {
|
|
2917
|
+
configPath: getGlobals().config,
|
|
2918
|
+
indexName: getGlobals().index,
|
|
2919
|
+
});
|
|
2920
|
+
return { success: true as const };
|
|
2921
|
+
}
|
|
2922
|
+
);
|
|
2923
|
+
throwIfWriteLeaseBusy(result, false);
|
|
2924
|
+
}
|
|
2925
|
+
);
|
|
2890
2926
|
|
|
2891
2927
|
addWriteLeaseFlags(
|
|
2892
2928
|
collectionCmd
|
|
@@ -3620,7 +3656,11 @@ function wireManagementCommands(program: Command): void {
|
|
|
3620
3656
|
lockWaitMs: lease.lockWaitMs,
|
|
3621
3657
|
noWait: lease.noWait,
|
|
3622
3658
|
},
|
|
3623
|
-
() =>
|
|
3659
|
+
() =>
|
|
3660
|
+
cleanup({
|
|
3661
|
+
configPath: getGlobals().config,
|
|
3662
|
+
indexName: getGlobals().index,
|
|
3663
|
+
})
|
|
3624
3664
|
);
|
|
3625
3665
|
throwIfWriteLeaseBusy(result, false);
|
|
3626
3666
|
|
|
@@ -21,6 +21,7 @@ interface RemoveCollectionResult {
|
|
|
21
21
|
removed: true;
|
|
22
22
|
collection: string;
|
|
23
23
|
configUpdated: true;
|
|
24
|
+
/** Documents are deleted; content, chunks and vectors stay until cleanup. */
|
|
24
25
|
indexedDataRetained: true;
|
|
25
26
|
note: string;
|
|
26
27
|
}
|
|
@@ -101,7 +102,7 @@ export function handleRemoveCollection(
|
|
|
101
102
|
collection: name,
|
|
102
103
|
configUpdated: true,
|
|
103
104
|
indexedDataRetained: true,
|
|
104
|
-
note: "
|
|
105
|
+
note: "Collection removed from config and its documents deleted from the index. Content, chunks and vectors stay until gno cleanup.",
|
|
105
106
|
};
|
|
106
107
|
|
|
107
108
|
return result;
|
package/src/serve/routes/api.ts
CHANGED
|
@@ -1574,9 +1574,8 @@ export async function handleImportPreview(
|
|
|
1574
1574
|
|
|
1575
1575
|
/**
|
|
1576
1576
|
* DELETE /api/collections/:name
|
|
1577
|
-
* Remove a collection from config.
|
|
1578
|
-
*
|
|
1579
|
-
* or manual cleanup. This preserves data for potential recovery.
|
|
1577
|
+
* Remove a collection from config. The config sync deletes the collection
|
|
1578
|
+
* row and its documents; content, chunks and vectors stay until cleanup.
|
|
1580
1579
|
*/
|
|
1581
1580
|
export async function handleDeleteCollection(
|
|
1582
1581
|
ctxHolder: ContextHolder,
|
|
@@ -1612,7 +1611,7 @@ export async function handleDeleteCollection(
|
|
|
1612
1611
|
return jsonResponse({
|
|
1613
1612
|
success: true,
|
|
1614
1613
|
collection: name,
|
|
1615
|
-
note: "Collection removed from config
|
|
1614
|
+
note: "Collection removed from config and its documents deleted from the index. Content, chunks and vectors stay until gno cleanup.",
|
|
1616
1615
|
});
|
|
1617
1616
|
}
|
|
1618
1617
|
|
|
@@ -6124,18 +6124,25 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
6124
6124
|
)
|
|
6125
6125
|
.get(configuredJson, configuredJson)?.count ?? 0;
|
|
6126
6126
|
|
|
6127
|
-
// Embedding backlog: chunks from active docs
|
|
6128
|
-
//
|
|
6127
|
+
// Embedding backlog: chunks from active docs of configured collections
|
|
6128
|
+
// without vectors. DISTINCT avoids duplicates when docs share mirror_hash.
|
|
6129
6129
|
const backlogRow = db
|
|
6130
6130
|
.query<
|
|
6131
6131
|
{ count: number },
|
|
6132
|
-
[
|
|
6132
|
+
[
|
|
6133
|
+
string | null,
|
|
6134
|
+
string | null,
|
|
6135
|
+
string | null,
|
|
6136
|
+
string | null,
|
|
6137
|
+
string | null,
|
|
6138
|
+
]
|
|
6133
6139
|
>(
|
|
6134
6140
|
`
|
|
6135
6141
|
WITH active_mirrors AS (
|
|
6136
6142
|
SELECT DISTINCT mirror_hash
|
|
6137
6143
|
FROM documents
|
|
6138
6144
|
WHERE active = 1 AND mirror_hash IS NOT NULL
|
|
6145
|
+
AND (? IS NULL OR collection IN (SELECT value FROM json_each(?)))
|
|
6139
6146
|
),
|
|
6140
6147
|
matching_vectors AS (
|
|
6141
6148
|
SELECT mirror_hash, seq, MAX(embedded_at) AS embedded_at
|
|
@@ -6155,7 +6162,13 @@ export class SqliteAdapter implements StorePort, SqliteDbProvider {
|
|
|
6155
6162
|
WHERE mv.mirror_hash IS NULL
|
|
6156
6163
|
`
|
|
6157
6164
|
)
|
|
6158
|
-
.get(
|
|
6165
|
+
.get(
|
|
6166
|
+
configuredJson,
|
|
6167
|
+
configuredJson,
|
|
6168
|
+
embedModel,
|
|
6169
|
+
embedModel,
|
|
6170
|
+
embedFingerprint
|
|
6171
|
+
);
|
|
6159
6172
|
|
|
6160
6173
|
// Recent errors (last 24h)
|
|
6161
6174
|
const recentErrorsRow = db
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
56174f38783259cef05d81ae53adceebc8467799b735c2f3026b928f7070ae76 gno-browser-clipper-v2.10.0.zip
|