opencode-diane 0.0.5
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 +180 -0
- package/LICENSE +21 -0
- package/README.md +206 -0
- package/WIKI.md +1430 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +1632 -0
- package/dist/ingest/adaptive.d.ts +47 -0
- package/dist/ingest/adaptive.js +182 -0
- package/dist/ingest/code-health.d.ts +58 -0
- package/dist/ingest/code-health.js +202 -0
- package/dist/ingest/code-map.d.ts +71 -0
- package/dist/ingest/code-map.js +670 -0
- package/dist/ingest/cross-refs.d.ts +59 -0
- package/dist/ingest/cross-refs.js +1207 -0
- package/dist/ingest/docs.d.ts +49 -0
- package/dist/ingest/docs.js +325 -0
- package/dist/ingest/git.d.ts +77 -0
- package/dist/ingest/git.js +390 -0
- package/dist/ingest/live-session.d.ts +101 -0
- package/dist/ingest/live-session.js +173 -0
- package/dist/ingest/project-notes.d.ts +28 -0
- package/dist/ingest/project-notes.js +102 -0
- package/dist/ingest/project.d.ts +35 -0
- package/dist/ingest/project.js +430 -0
- package/dist/ingest/session-snapshot.d.ts +63 -0
- package/dist/ingest/session-snapshot.js +94 -0
- package/dist/ingest/sessions.d.ts +29 -0
- package/dist/ingest/sessions.js +164 -0
- package/dist/ingest/tables.d.ts +52 -0
- package/dist/ingest/tables.js +360 -0
- package/dist/mining/skill-miner.d.ts +53 -0
- package/dist/mining/skill-miner.js +234 -0
- package/dist/search/bm25.d.ts +81 -0
- package/dist/search/bm25.js +334 -0
- package/dist/search/e5-embedder.d.ts +30 -0
- package/dist/search/e5-embedder.js +91 -0
- package/dist/search/embed-pass.d.ts +26 -0
- package/dist/search/embed-pass.js +43 -0
- package/dist/search/embedder.d.ts +58 -0
- package/dist/search/embedder.js +85 -0
- package/dist/search/inverted-index.d.ts +51 -0
- package/dist/search/inverted-index.js +139 -0
- package/dist/search/ppr.d.ts +44 -0
- package/dist/search/ppr.js +118 -0
- package/dist/search/tokenize.d.ts +26 -0
- package/dist/search/tokenize.js +98 -0
- package/dist/store/eviction.d.ts +16 -0
- package/dist/store/eviction.js +37 -0
- package/dist/store/repository.d.ts +222 -0
- package/dist/store/repository.js +420 -0
- package/dist/store/sqlite-store.d.ts +89 -0
- package/dist/store/sqlite-store.js +252 -0
- package/dist/store/vector-store.d.ts +66 -0
- package/dist/store/vector-store.js +160 -0
- package/dist/types.d.ts +385 -0
- package/dist/types.js +9 -0
- package/dist/utils/file-log.d.ts +87 -0
- package/dist/utils/file-log.js +215 -0
- package/dist/utils/peer-detection.d.ts +45 -0
- package/dist/utils/peer-detection.js +90 -0
- package/dist/utils/shell.d.ts +43 -0
- package/dist/utils/shell.js +110 -0
- package/dist/utils/usage-skill.d.ts +42 -0
- package/dist/utils/usage-skill.js +129 -0
- package/dist/utils/xlsx.d.ts +36 -0
- package/dist/utils/xlsx.js +270 -0
- package/grammars/tree-sitter-c.wasm +0 -0
- package/grammars/tree-sitter-c_sharp.wasm +0 -0
- package/grammars/tree-sitter-cpp.wasm +0 -0
- package/grammars/tree-sitter-css.wasm +0 -0
- package/grammars/tree-sitter-go.wasm +0 -0
- package/grammars/tree-sitter-html.wasm +0 -0
- package/grammars/tree-sitter-java.wasm +0 -0
- package/grammars/tree-sitter-javascript.wasm +0 -0
- package/grammars/tree-sitter-json.wasm +0 -0
- package/grammars/tree-sitter-php.wasm +0 -0
- package/grammars/tree-sitter-python.wasm +0 -0
- package/grammars/tree-sitter-rust.wasm +0 -0
- package/grammars/tree-sitter-typescript.wasm +0 -0
- package/package.json +80 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* xlsx.ts — minimal XLSX reader, header-row only.
|
|
3
|
+
*
|
|
4
|
+
* XLSX is a ZIP archive of XML files. We need exactly two of them:
|
|
5
|
+
* - `xl/worksheets/sheet1.xml` — cell data
|
|
6
|
+
* - `xl/sharedStrings.xml` — string table (cells of type "s" are
|
|
7
|
+
* indices into this; not all sheets
|
|
8
|
+
* use it, so it's optional)
|
|
9
|
+
*
|
|
10
|
+
* This file implements the smallest possible code path to extract the
|
|
11
|
+
* first row's cell values:
|
|
12
|
+
*
|
|
13
|
+
* 1. Find the End-of-Central-Directory record at the file tail.
|
|
14
|
+
* 2. Read the Central Directory entries to locate our two files.
|
|
15
|
+
* 3. For each, seek to the local file header, read the compressed
|
|
16
|
+
* data, and `inflateRaw` it to text.
|
|
17
|
+
* 4. Pull the first `<row>` from the sheet XML, walk its `<c>`
|
|
18
|
+
* cells, resolving shared-string indices against the table.
|
|
19
|
+
*
|
|
20
|
+
* **Deliberately limited scope.** Standard PKZIP layout only — no
|
|
21
|
+
* ZIP64 (sheets >4 GiB), no encryption, no compression method other
|
|
22
|
+
* than `stored` (0) or `deflated` (8). Spreadsheets violating any of
|
|
23
|
+
* those return `null` and the caller skips the file. Failing closed
|
|
24
|
+
* is correct here: we promise header discoverability, not row data.
|
|
25
|
+
*
|
|
26
|
+
* **No external dependencies.** This module uses only `node:fs/promises`
|
|
27
|
+
* and `node:zlib`. SheetJS/exceljs would handle every edge case but
|
|
28
|
+
* add 1-2 MB of dependency weight for what is a niche feature in a
|
|
29
|
+
* source-code-indexer. The trade is intentional and documented.
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Public entry point. Returns the first row's cell values, or null
|
|
33
|
+
* if the file isn't a readable XLSX, the sheet is empty, or anything
|
|
34
|
+
* about the structure trips the limits above. Never throws.
|
|
35
|
+
*/
|
|
36
|
+
export declare function readXlsxFirstRow(absPath: string): Promise<string[] | null>;
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* xlsx.ts — minimal XLSX reader, header-row only.
|
|
3
|
+
*
|
|
4
|
+
* XLSX is a ZIP archive of XML files. We need exactly two of them:
|
|
5
|
+
* - `xl/worksheets/sheet1.xml` — cell data
|
|
6
|
+
* - `xl/sharedStrings.xml` — string table (cells of type "s" are
|
|
7
|
+
* indices into this; not all sheets
|
|
8
|
+
* use it, so it's optional)
|
|
9
|
+
*
|
|
10
|
+
* This file implements the smallest possible code path to extract the
|
|
11
|
+
* first row's cell values:
|
|
12
|
+
*
|
|
13
|
+
* 1. Find the End-of-Central-Directory record at the file tail.
|
|
14
|
+
* 2. Read the Central Directory entries to locate our two files.
|
|
15
|
+
* 3. For each, seek to the local file header, read the compressed
|
|
16
|
+
* data, and `inflateRaw` it to text.
|
|
17
|
+
* 4. Pull the first `<row>` from the sheet XML, walk its `<c>`
|
|
18
|
+
* cells, resolving shared-string indices against the table.
|
|
19
|
+
*
|
|
20
|
+
* **Deliberately limited scope.** Standard PKZIP layout only — no
|
|
21
|
+
* ZIP64 (sheets >4 GiB), no encryption, no compression method other
|
|
22
|
+
* than `stored` (0) or `deflated` (8). Spreadsheets violating any of
|
|
23
|
+
* those return `null` and the caller skips the file. Failing closed
|
|
24
|
+
* is correct here: we promise header discoverability, not row data.
|
|
25
|
+
*
|
|
26
|
+
* **No external dependencies.** This module uses only `node:fs/promises`
|
|
27
|
+
* and `node:zlib`. SheetJS/exceljs would handle every edge case but
|
|
28
|
+
* add 1-2 MB of dependency weight for what is a niche feature in a
|
|
29
|
+
* source-code-indexer. The trade is intentional and documented.
|
|
30
|
+
*/
|
|
31
|
+
import { open } from "node:fs/promises";
|
|
32
|
+
import { inflateRawSync } from "node:zlib";
|
|
33
|
+
// ── PKZIP wire-format constants ────────────────────────────────────
|
|
34
|
+
const SIG_LOCAL_FILE_HEADER = 0x04034b50;
|
|
35
|
+
const SIG_CENTRAL_DIRECTORY = 0x02014b50;
|
|
36
|
+
const SIG_END_OF_CENTRAL_DIR = 0x06054b50;
|
|
37
|
+
// End-of-Central-Directory record is 22 bytes plus a variable-length
|
|
38
|
+
// comment up to 65535 bytes. We scan the last 64 KiB which covers any
|
|
39
|
+
// realistic case (XLSX files don't carry archive comments).
|
|
40
|
+
const EOCD_SCAN_BYTES = 65_557;
|
|
41
|
+
// Hard ceilings — bounded work per file even on malicious input.
|
|
42
|
+
const MAX_FILE_BYTES = 200 * 1024 * 1024; // 200 MB compressed
|
|
43
|
+
const MAX_UNCOMPRESSED_BYTES = 80 * 1024 * 1024; // 80 MB inflated
|
|
44
|
+
const MAX_COLUMNS = 256;
|
|
45
|
+
/**
|
|
46
|
+
* Public entry point. Returns the first row's cell values, or null
|
|
47
|
+
* if the file isn't a readable XLSX, the sheet is empty, or anything
|
|
48
|
+
* about the structure trips the limits above. Never throws.
|
|
49
|
+
*/
|
|
50
|
+
export async function readXlsxFirstRow(absPath) {
|
|
51
|
+
let handle = null;
|
|
52
|
+
try {
|
|
53
|
+
handle = await open(absPath, "r");
|
|
54
|
+
const stat = await handle.stat();
|
|
55
|
+
if (!stat.isFile() || stat.size < 22 || stat.size > MAX_FILE_BYTES)
|
|
56
|
+
return null;
|
|
57
|
+
const entries = await readCentralDirectory(handle, stat.size);
|
|
58
|
+
if (!entries)
|
|
59
|
+
return null;
|
|
60
|
+
// We need sheet1.xml; sharedStrings.xml is optional.
|
|
61
|
+
const sheet = entries.find((e) => e.name === "xl/worksheets/sheet1.xml");
|
|
62
|
+
if (!sheet)
|
|
63
|
+
return null;
|
|
64
|
+
const sharedEntry = entries.find((e) => e.name === "xl/sharedStrings.xml") ?? null;
|
|
65
|
+
const sheetXml = await extractEntryAsText(handle, sheet);
|
|
66
|
+
if (sheetXml === null)
|
|
67
|
+
return null;
|
|
68
|
+
const sharedXml = sharedEntry ? await extractEntryAsText(handle, sharedEntry) : null;
|
|
69
|
+
const sharedStrings = sharedXml ? parseSharedStrings(sharedXml) : [];
|
|
70
|
+
return parseFirstRow(sheetXml, sharedStrings);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
if (handle)
|
|
77
|
+
await handle.close().catch(() => undefined);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Locate the End-of-Central-Directory record near the end of the
|
|
82
|
+
* file, then walk the Central Directory entries. Returns null on any
|
|
83
|
+
* structural problem.
|
|
84
|
+
*/
|
|
85
|
+
async function readCentralDirectory(handle, fileSize) {
|
|
86
|
+
const tailSize = Math.min(EOCD_SCAN_BYTES, fileSize);
|
|
87
|
+
const tail = Buffer.alloc(tailSize);
|
|
88
|
+
await handle.read(tail, 0, tailSize, fileSize - tailSize);
|
|
89
|
+
// Scan backwards for the EOCD signature.
|
|
90
|
+
let eocdOffset = -1;
|
|
91
|
+
for (let i = tail.length - 22; i >= 0; i--) {
|
|
92
|
+
if (tail.readUInt32LE(i) === SIG_END_OF_CENTRAL_DIR) {
|
|
93
|
+
eocdOffset = i;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (eocdOffset < 0)
|
|
98
|
+
return null;
|
|
99
|
+
const totalEntries = tail.readUInt16LE(eocdOffset + 10);
|
|
100
|
+
const cdSize = tail.readUInt32LE(eocdOffset + 12);
|
|
101
|
+
const cdOffset = tail.readUInt32LE(eocdOffset + 16);
|
|
102
|
+
// ZIP64 sentinel — out of scope.
|
|
103
|
+
if (cdOffset === 0xffffffff || cdSize === 0xffffffff || totalEntries === 0xffff)
|
|
104
|
+
return null;
|
|
105
|
+
// Read the Central Directory itself.
|
|
106
|
+
const cd = Buffer.alloc(cdSize);
|
|
107
|
+
await handle.read(cd, 0, cdSize, cdOffset);
|
|
108
|
+
const entries = [];
|
|
109
|
+
let p = 0;
|
|
110
|
+
for (let i = 0; i < totalEntries; i++) {
|
|
111
|
+
if (p + 46 > cd.length)
|
|
112
|
+
return null;
|
|
113
|
+
if (cd.readUInt32LE(p) !== SIG_CENTRAL_DIRECTORY)
|
|
114
|
+
return null;
|
|
115
|
+
const compressionMethod = cd.readUInt16LE(p + 10);
|
|
116
|
+
const compressedSize = cd.readUInt32LE(p + 20);
|
|
117
|
+
const uncompressedSize = cd.readUInt32LE(p + 24);
|
|
118
|
+
const nameLen = cd.readUInt16LE(p + 28);
|
|
119
|
+
const extraLen = cd.readUInt16LE(p + 30);
|
|
120
|
+
const commentLen = cd.readUInt16LE(p + 32);
|
|
121
|
+
const localHeaderOffset = cd.readUInt32LE(p + 42);
|
|
122
|
+
if (compressedSize === 0xffffffff || uncompressedSize === 0xffffffff || localHeaderOffset === 0xffffffff)
|
|
123
|
+
return null;
|
|
124
|
+
const name = cd.subarray(p + 46, p + 46 + nameLen).toString("utf-8");
|
|
125
|
+
entries.push({ name, localHeaderOffset, compressionMethod, compressedSize, uncompressedSize });
|
|
126
|
+
p += 46 + nameLen + extraLen + commentLen;
|
|
127
|
+
}
|
|
128
|
+
return entries;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Read one entry from the ZIP: seek to its local file header, skip
|
|
132
|
+
* the variable-length name+extra fields, read the compressed payload,
|
|
133
|
+
* and inflate it. Returns null if the entry is too big, uses an
|
|
134
|
+
* unsupported compression method, or fails to decompress.
|
|
135
|
+
*/
|
|
136
|
+
async function extractEntryAsText(handle, entry) {
|
|
137
|
+
if (entry.uncompressedSize > MAX_UNCOMPRESSED_BYTES)
|
|
138
|
+
return null;
|
|
139
|
+
if (entry.compressionMethod !== 0 && entry.compressionMethod !== 8)
|
|
140
|
+
return null; // stored or deflated only
|
|
141
|
+
// Read the local file header to learn the name+extra lengths there
|
|
142
|
+
// (they can differ from the central-directory copy in theory).
|
|
143
|
+
const lfh = Buffer.alloc(30);
|
|
144
|
+
await handle.read(lfh, 0, 30, entry.localHeaderOffset);
|
|
145
|
+
if (lfh.readUInt32LE(0) !== SIG_LOCAL_FILE_HEADER)
|
|
146
|
+
return null;
|
|
147
|
+
const lfhNameLen = lfh.readUInt16LE(26);
|
|
148
|
+
const lfhExtraLen = lfh.readUInt16LE(28);
|
|
149
|
+
const dataOffset = entry.localHeaderOffset + 30 + lfhNameLen + lfhExtraLen;
|
|
150
|
+
const compressed = Buffer.alloc(entry.compressedSize);
|
|
151
|
+
if (entry.compressedSize > 0) {
|
|
152
|
+
await handle.read(compressed, 0, entry.compressedSize, dataOffset);
|
|
153
|
+
}
|
|
154
|
+
let raw;
|
|
155
|
+
if (entry.compressionMethod === 0) {
|
|
156
|
+
raw = compressed;
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
try {
|
|
160
|
+
raw = inflateRawSync(compressed, { maxOutputLength: MAX_UNCOMPRESSED_BYTES });
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return raw.toString("utf-8");
|
|
167
|
+
}
|
|
168
|
+
// ── Tiny XML extraction (regex; we don't need a real parser) ───────
|
|
169
|
+
//
|
|
170
|
+
// We avoid pulling in an XML library. Two operations are all we need:
|
|
171
|
+
// - From sharedStrings.xml, the ordered sequence of `<t>…</t>` (and
|
|
172
|
+
// `<t xml:space="preserve">…</t>`) under each `<si>`.
|
|
173
|
+
// - From sheet1.xml, the first `<row>…</row>`, and within it each
|
|
174
|
+
// `<c r="A1" t="s">…</c>` cell. The cell value is either a
|
|
175
|
+
// numeric `<v>N</v>` index into the shared-string table (when
|
|
176
|
+
// `t="s"`) or an inline string in `<is><t>…</t></is>`.
|
|
177
|
+
//
|
|
178
|
+
// XLSX cells use a tightly constrained subset of XML — the writers
|
|
179
|
+
// emit predictable shapes. Regex parsing is brittle in general but
|
|
180
|
+
// adequate here, especially since we never write XML out.
|
|
181
|
+
/**
|
|
182
|
+
* Parse the shared-strings table to an indexable array. Each `<si>`
|
|
183
|
+
* element contributes one entry; the entry is the concatenation of
|
|
184
|
+
* its `<t>` children (rich text broken into runs still flattens to
|
|
185
|
+
* a single string, which is what we want for a header label).
|
|
186
|
+
*/
|
|
187
|
+
function parseSharedStrings(xml) {
|
|
188
|
+
const result = [];
|
|
189
|
+
// Walk <si>…</si> blocks; inside each, gather all <t>…</t> text.
|
|
190
|
+
const siRe = /<si\b[^>]*>([\s\S]*?)<\/si>/g;
|
|
191
|
+
const tRe = /<t\b[^>]*>([\s\S]*?)<\/t>/g;
|
|
192
|
+
let m;
|
|
193
|
+
while ((m = siRe.exec(xml)) !== null) {
|
|
194
|
+
const inner = m[1];
|
|
195
|
+
let combined = "";
|
|
196
|
+
let tm;
|
|
197
|
+
tRe.lastIndex = 0;
|
|
198
|
+
while ((tm = tRe.exec(inner)) !== null) {
|
|
199
|
+
combined += decodeXmlEntities(tm[1]);
|
|
200
|
+
}
|
|
201
|
+
result.push(combined);
|
|
202
|
+
if (result.length > 100_000)
|
|
203
|
+
break; // sanity ceiling
|
|
204
|
+
}
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Extract the first row's cell values from a sheet XML, resolving
|
|
209
|
+
* shared-string indices against the supplied table. Returns null if
|
|
210
|
+
* no row is found, an empty array if the row had no cells.
|
|
211
|
+
*/
|
|
212
|
+
function parseFirstRow(xml, shared) {
|
|
213
|
+
const rowMatch = /<row\b[^>]*>([\s\S]*?)<\/row>/.exec(xml);
|
|
214
|
+
if (!rowMatch)
|
|
215
|
+
return null;
|
|
216
|
+
const rowInner = rowMatch[1];
|
|
217
|
+
// Each <c r="REF" t="TYPE">…</c>. t may be: "s" (shared string),
|
|
218
|
+
// "str" (formula string), "inlineStr" (inline string), absent
|
|
219
|
+
// (number), "b" (boolean). We only render textually.
|
|
220
|
+
const cellRe = /<c\b([^>]*)>([\s\S]*?)<\/c>/g;
|
|
221
|
+
const cells = [];
|
|
222
|
+
let m;
|
|
223
|
+
while ((m = cellRe.exec(rowInner)) !== null) {
|
|
224
|
+
const attrs = m[1];
|
|
225
|
+
const inner = m[2];
|
|
226
|
+
const tMatch = /\bt="([^"]+)"/.exec(attrs);
|
|
227
|
+
const type = tMatch ? tMatch[1] : null;
|
|
228
|
+
const value = extractCellValue(type, inner, shared);
|
|
229
|
+
cells.push(value);
|
|
230
|
+
if (cells.length > MAX_COLUMNS)
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
return cells;
|
|
234
|
+
}
|
|
235
|
+
function extractCellValue(type, inner, shared) {
|
|
236
|
+
if (type === "s") {
|
|
237
|
+
const v = /<v>([\s\S]*?)<\/v>/.exec(inner);
|
|
238
|
+
if (!v)
|
|
239
|
+
return "";
|
|
240
|
+
const idx = Number.parseInt(v[1].trim(), 10);
|
|
241
|
+
if (!Number.isFinite(idx) || idx < 0 || idx >= shared.length)
|
|
242
|
+
return "";
|
|
243
|
+
return shared[idx];
|
|
244
|
+
}
|
|
245
|
+
if (type === "inlineStr") {
|
|
246
|
+
const ts = [];
|
|
247
|
+
const tRe = /<t\b[^>]*>([\s\S]*?)<\/t>/g;
|
|
248
|
+
let m;
|
|
249
|
+
while ((m = tRe.exec(inner)) !== null)
|
|
250
|
+
ts.push(decodeXmlEntities(m[1]));
|
|
251
|
+
return ts.join("");
|
|
252
|
+
}
|
|
253
|
+
// Number, formula result, boolean, or untyped — fall through to <v>.
|
|
254
|
+
const v = /<v>([\s\S]*?)<\/v>/.exec(inner);
|
|
255
|
+
return v ? decodeXmlEntities(v[1].trim()) : "";
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Decode the five XML predefined entities. We don't see numeric
|
|
259
|
+
* character references in XLSX cell text in practice; if a writer
|
|
260
|
+
* does emit them, they pass through literally — acceptable for header
|
|
261
|
+
* labels.
|
|
262
|
+
*/
|
|
263
|
+
function decodeXmlEntities(s) {
|
|
264
|
+
return s
|
|
265
|
+
.replace(/</g, "<")
|
|
266
|
+
.replace(/>/g, ">")
|
|
267
|
+
.replace(/"/g, '"')
|
|
268
|
+
.replace(/'/g, "'")
|
|
269
|
+
.replace(/&/g, "&");
|
|
270
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "opencode-diane",
|
|
3
|
+
"version": "0.0.5",
|
|
4
|
+
"description": "OpenCode plugin: hierarchical, token-efficient memory for any git repository. Convention-free — pre-fills from git diff-structure and project files, no LLM at the core, no commit-message parsing. Optional cross-lingual semantic search; skill mining.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"opencode",
|
|
7
|
+
"opencode-plugin",
|
|
8
|
+
"memory",
|
|
9
|
+
"experience-reuse",
|
|
10
|
+
"token-saving",
|
|
11
|
+
"bm25",
|
|
12
|
+
"language-agnostic",
|
|
13
|
+
"agents.md"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/two-coats-guaranteed/opencode-diane.git"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/two-coats-guaranteed/opencode-diane/issues"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/two-coats-guaranteed/opencode-diane#readme",
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"grammars",
|
|
36
|
+
"README.md",
|
|
37
|
+
"WIKI.md",
|
|
38
|
+
"CHANGELOG.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc -p tsconfig.json",
|
|
43
|
+
"lint": "eslint src tests",
|
|
44
|
+
"clean": "rm -rf dist coverage",
|
|
45
|
+
"prepublishOnly": "bun run clean && bun run build",
|
|
46
|
+
"test": "bun scripts/run-tests.mjs",
|
|
47
|
+
"smoke": "bun scripts/smoke.mjs",
|
|
48
|
+
"check:size": "bun scripts/check-size.mjs",
|
|
49
|
+
"test:coverage": "bun test --coverage",
|
|
50
|
+
"coverage:check": "bun scripts/coverage-check.mjs",
|
|
51
|
+
"verify:semantic": "bun scripts/verify-semantic.mjs",
|
|
52
|
+
"test:analyzer": "python3 tests/test_analyze_logs.py",
|
|
53
|
+
"test:coverage-parser": "node --test scripts/lib/coverage-parser-tests.mjs",
|
|
54
|
+
"typecheck": "tsc --noEmit"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@opencode-ai/plugin": ">=1.14.0",
|
|
58
|
+
"web-tree-sitter": "0.25.10",
|
|
59
|
+
"xlsx": "^0.18.5"
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"@huggingface/transformers": "^4.2.0"
|
|
63
|
+
},
|
|
64
|
+
"peerDependenciesMeta": {
|
|
65
|
+
"@huggingface/transformers": {
|
|
66
|
+
"optional": true
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@eslint/js": "^9.39.4",
|
|
71
|
+
"@types/bun": "^1.1.14",
|
|
72
|
+
"@types/node": "^22.10.0",
|
|
73
|
+
"eslint": "^9.39.4",
|
|
74
|
+
"typescript": "^5.6.3",
|
|
75
|
+
"typescript-eslint": "^8.59.3"
|
|
76
|
+
},
|
|
77
|
+
"engines": {
|
|
78
|
+
"bun": ">=1.1.0"
|
|
79
|
+
}
|
|
80
|
+
}
|