@ataraxy-labs/sem 0.5.5 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -4
- package/package.json +2 -2
- package/scripts/postinstall.mjs +15 -3
- package/scripts/verify-checksum.mjs +27 -11
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
<img src="https://img.shields.io/badge/rust-stable-orange" alt="Rust">
|
|
25
25
|
<img src="https://img.shields.io/badge/tests-133_passing-brightgreen" alt="Tests">
|
|
26
26
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-yellow" alt="License"></a>
|
|
27
|
-
<img src="https://img.shields.io/badge/languages-
|
|
27
|
+
<img src="https://img.shields.io/badge/languages-28-blue" alt="Languages">
|
|
28
28
|
</p>
|
|
29
29
|
|
|
30
30
|
sem is a semantic version control tool that works on top of Git. It parses your code with tree-sitter, extracts every function, class, and method as an entity, and diffs at the entity level instead of lines. This means you see "function `blahh` was modified" instead of "lines x-y changed."
|
|
@@ -92,6 +92,8 @@ If you installed via npm/bun, the binary lives in `node_modules/.bin/sem` and is
|
|
|
92
92
|
|
|
93
93
|
Works in any Git repo. No setup required. Also works outside Git for arbitrary file comparison.
|
|
94
94
|
|
|
95
|
+
sem stores its SQLite entity cache outside the repository, under the OS cache directory by default. Set `SEM_CACHE_DIR=/path/to/cache` to override the cache root; repo-local overrides are ignored so cache files do not dirty the working tree.
|
|
96
|
+
|
|
95
97
|
### sem diff
|
|
96
98
|
|
|
97
99
|
Entity-level diff with rename detection, structural hashing, and word-level inline highlights.
|
|
@@ -154,6 +156,9 @@ sem impact authenticateUser --json
|
|
|
154
156
|
|
|
155
157
|
# Disambiguate by file
|
|
156
158
|
sem impact authenticateUser --file src/auth.ts
|
|
159
|
+
|
|
160
|
+
# Include generated/build directories that repo-wide scans skip by default
|
|
161
|
+
sem impact authenticateUser --no-default-excludes
|
|
157
162
|
```
|
|
158
163
|
|
|
159
164
|
### sem blame
|
|
@@ -198,11 +203,15 @@ sem entities src/auth.ts
|
|
|
198
203
|
# JSON output
|
|
199
204
|
sem entities --json
|
|
200
205
|
sem entities src/auth.ts --json
|
|
206
|
+
|
|
207
|
+
# Include generated/build directories that repo-wide scans skip by default
|
|
208
|
+
sem entities --no-default-excludes
|
|
201
209
|
```
|
|
202
210
|
|
|
203
211
|
### sem context
|
|
204
212
|
|
|
205
|
-
Token-budgeted context for LLMs: the entity, its dependencies, and its dependents, fitted to a token budget.
|
|
213
|
+
Token-budgeted context for LLMs: the entity, its dependencies, and its dependents, fitted to a strict content token budget.
|
|
214
|
+
When the target signature itself does not fit, JSON output reports `target_omitted: true`.
|
|
206
215
|
|
|
207
216
|
```bash
|
|
208
217
|
sem context authenticateUser
|
|
@@ -212,6 +221,9 @@ sem context authenticateUser --budget 4000
|
|
|
212
221
|
|
|
213
222
|
# JSON output
|
|
214
223
|
sem context authenticateUser --json
|
|
224
|
+
|
|
225
|
+
# Include generated/build directories that repo-wide scans skip by default
|
|
226
|
+
sem context authenticateUser --no-default-excludes
|
|
215
227
|
```
|
|
216
228
|
|
|
217
229
|
## Use as default Git diff
|
|
@@ -232,7 +244,7 @@ sem unsetup
|
|
|
232
244
|
|
|
233
245
|
## What it parses
|
|
234
246
|
|
|
235
|
-
|
|
247
|
+
28 programming languages with full entity extraction via tree-sitter:
|
|
236
248
|
|
|
237
249
|
| Language | Extensions | Entities |
|
|
238
250
|
|----------|-----------|----------|
|
|
@@ -261,6 +273,8 @@ sem unsetup
|
|
|
261
273
|
| Dart | `.dart` | classes, mixins, extensions, enums, type aliases, functions |
|
|
262
274
|
| OCaml | `.ml` `.mli` | values, modules, types, classes, externals |
|
|
263
275
|
| Scala | `.scala` `.sc` `.sbt` | classes, objects, traits, enums, functions, vals, extensions |
|
|
276
|
+
| Nix | `.nix` | bindings, inherit declarations |
|
|
277
|
+
| Haskell | `.hs` | functions, signatures, data types, newtypes, classes, instances, type synonyms |
|
|
264
278
|
| Zig | `.zig` | functions, tests, variables |
|
|
265
279
|
|
|
266
280
|
Plus structured data formats:
|
|
@@ -333,6 +347,11 @@ sem diff --format json
|
|
|
333
347
|
"added": 1,
|
|
334
348
|
"modified": 1,
|
|
335
349
|
"deleted": 1,
|
|
350
|
+
"moved": 0,
|
|
351
|
+
"renamed": 0,
|
|
352
|
+
"reordered": 0,
|
|
353
|
+
"binary": 0,
|
|
354
|
+
"orphan": 0,
|
|
336
355
|
"total": 3
|
|
337
356
|
},
|
|
338
357
|
"changes": [
|
|
@@ -341,12 +360,19 @@ sem diff --format json
|
|
|
341
360
|
"changeType": "added",
|
|
342
361
|
"entityType": "function",
|
|
343
362
|
"entityName": "validateToken",
|
|
363
|
+
"startLine": 12,
|
|
364
|
+
"endLine": 18,
|
|
365
|
+
"oldStartLine": null,
|
|
366
|
+
"oldEndLine": null,
|
|
344
367
|
"filePath": "src/auth.ts"
|
|
345
368
|
}
|
|
346
|
-
]
|
|
369
|
+
],
|
|
370
|
+
"binaryChanges": []
|
|
347
371
|
}
|
|
348
372
|
```
|
|
349
373
|
|
|
374
|
+
The named change-type buckets (`added`, `modified`, `deleted`, `moved`, `renamed`, `reordered`) always sum to `total`. `orphan` is a cross-cutting metadata count for module-level changes, and those changes are already included in the named change-type buckets.
|
|
375
|
+
|
|
350
376
|
## As a library
|
|
351
377
|
|
|
352
378
|
sem-core can be used as a Rust library dependency:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ataraxy-labs/sem",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "npm wrapper for the sem CLI. Downloads the matching release binary and exposes the sem command in node_modules/.bin.",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -42,6 +42,6 @@
|
|
|
42
42
|
"scripts": {
|
|
43
43
|
"postinstall": "node ./scripts/postinstall.mjs",
|
|
44
44
|
"prepack": "node ./scripts/sync-package-version.mjs",
|
|
45
|
-
"test": "node
|
|
45
|
+
"test": "node --test"
|
|
46
46
|
}
|
|
47
47
|
}
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -38,9 +38,21 @@ async function downloadFile(url, destinationPath) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function extractArchive(archivePath, outputDirectory) {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
const args = ['-xzf', archivePath, '-C', outputDirectory];
|
|
42
|
+
let result = spawnSync('tar', args, { stdio: 'pipe' });
|
|
43
|
+
|
|
44
|
+
// On Windows, GNU tar (from Git for Windows / MSYS2) interprets colons in
|
|
45
|
+
// paths as remote host separators (host:path). If extraction fails with a
|
|
46
|
+
// colon-related error, retry with --force-local which disables this behavior.
|
|
47
|
+
// We don't add it unconditionally because the Windows built-in bsdtar doesn't
|
|
48
|
+
// recognize the flag.
|
|
49
|
+
if (
|
|
50
|
+
process.platform === 'win32' &&
|
|
51
|
+
result.status !== 0 &&
|
|
52
|
+
result.stderr?.toString('utf8').includes('Cannot connect to')
|
|
53
|
+
) {
|
|
54
|
+
result = spawnSync('tar', [...args, '--force-local'], { stdio: 'pipe' });
|
|
55
|
+
}
|
|
44
56
|
|
|
45
57
|
if (result.error) {
|
|
46
58
|
throw new Error(`Failed to extract archive: ${result.error.message}`);
|
|
@@ -5,19 +5,36 @@ import fs from 'node:fs/promises';
|
|
|
5
5
|
* Downloads checksums.txt from the release, verifies the archive matches.
|
|
6
6
|
* Returns silently on success, throws on mismatch or missing checksum.
|
|
7
7
|
*/
|
|
8
|
-
export async function verifyChecksum(
|
|
8
|
+
export async function verifyChecksum(
|
|
9
|
+
archivePath,
|
|
10
|
+
archiveName,
|
|
11
|
+
releaseBaseUrl,
|
|
12
|
+
{ env = process.env, fetchFn = fetch } = {},
|
|
13
|
+
) {
|
|
14
|
+
if (env.SEM_SKIP_CHECKSUM === '1') {
|
|
15
|
+
console.warn('Skipping checksum verification because SEM_SKIP_CHECKSUM=1.');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
9
19
|
const checksumsUrl = `${releaseBaseUrl}/checksums.txt`;
|
|
10
20
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
let response;
|
|
22
|
+
try {
|
|
23
|
+
response = await fetchFn(checksumsUrl, {
|
|
24
|
+
headers: { 'user-agent': '@ataraxy-labs/sem npm installer' },
|
|
25
|
+
redirect: 'follow',
|
|
26
|
+
});
|
|
27
|
+
} catch (error) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
`Failed to fetch checksum metadata from ${checksumsUrl}: ${error.message}`,
|
|
30
|
+
);
|
|
31
|
+
}
|
|
15
32
|
|
|
16
33
|
if (!response.ok) {
|
|
17
|
-
|
|
18
|
-
`
|
|
34
|
+
throw new Error(
|
|
35
|
+
`Failed to fetch checksum metadata from ${checksumsUrl}: ` +
|
|
36
|
+
`${response.status} ${response.statusText}`,
|
|
19
37
|
);
|
|
20
|
-
return;
|
|
21
38
|
}
|
|
22
39
|
|
|
23
40
|
const checksumsText = await response.text();
|
|
@@ -33,10 +50,9 @@ export async function verifyChecksum(archivePath, archiveName, releaseBaseUrl) {
|
|
|
33
50
|
}
|
|
34
51
|
|
|
35
52
|
if (!expectedHash) {
|
|
36
|
-
|
|
37
|
-
`No checksum found for ${archiveName} in
|
|
53
|
+
throw new Error(
|
|
54
|
+
`No checksum found for ${archiveName} in checksum metadata from ${checksumsUrl}.`,
|
|
38
55
|
);
|
|
39
|
-
return;
|
|
40
56
|
}
|
|
41
57
|
|
|
42
58
|
const fileBuffer = await fs.readFile(archivePath);
|