@nanonets/graft 0.8.1 → 0.9.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 +80 -38
- package/dist/ai/llm/openai.d.ts +11 -0
- package/dist/ai/llm/openai.d.ts.map +1 -1
- package/dist/ai/llm/openai.js +33 -1
- package/dist/ai/llm/openai.js.map +1 -1
- package/dist/ask/ask.d.ts.map +1 -1
- package/dist/ask/ask.js +23 -16
- package/dist/ask/ask.js.map +1 -1
- package/dist/ask/fuse.d.ts +4 -0
- package/dist/ask/fuse.d.ts.map +1 -1
- package/dist/ask/fuse.js +2 -1
- package/dist/ask/fuse.js.map +1 -1
- package/dist/ask/index-file.d.ts +1 -0
- package/dist/ask/index-file.d.ts.map +1 -1
- package/dist/ask/index-file.js +1 -1
- package/dist/ask/index-file.js.map +1 -1
- package/dist/claude/format.d.ts +40 -13
- package/dist/claude/format.d.ts.map +1 -1
- package/dist/claude/format.js +54 -15
- package/dist/claude/format.js.map +1 -1
- package/dist/claude/init.d.ts.map +1 -1
- package/dist/claude/init.js +3 -3
- package/dist/claude/init.js.map +1 -1
- package/dist/claude/settings-merge.d.ts.map +1 -1
- package/dist/claude/settings-merge.js +10 -1
- package/dist/claude/settings-merge.js.map +1 -1
- package/dist/claude/skill-template.js +2 -2
- package/dist/claude/state.d.ts +3 -0
- package/dist/claude/state.d.ts.map +1 -1
- package/dist/claude/state.js +1 -1
- package/dist/claude/state.js.map +1 -1
- package/dist/cli-meta.d.ts +6 -1
- package/dist/cli-meta.d.ts.map +1 -1
- package/dist/cli-meta.js +8 -2
- package/dist/cli-meta.js.map +1 -1
- package/dist/cli-picker.d.ts.map +1 -1
- package/dist/cli-picker.js +3 -1
- package/dist/cli-picker.js.map +1 -1
- package/dist/cli.js +32 -4
- package/dist/cli.js.map +1 -1
- package/dist/context/build.d.ts.map +1 -1
- package/dist/context/build.js +13 -4
- package/dist/context/build.js.map +1 -1
- package/dist/context/check.d.ts.map +1 -1
- package/dist/context/check.js +14 -5
- package/dist/context/check.js.map +1 -1
- package/dist/context/node-file.d.ts +21 -0
- package/dist/context/node-file.d.ts.map +1 -1
- package/dist/context/node-file.js +51 -3
- package/dist/context/node-file.js.map +1 -1
- package/dist/graph/build.d.ts +3 -0
- package/dist/graph/build.d.ts.map +1 -1
- package/dist/graph/build.js +46 -13
- package/dist/graph/build.js.map +1 -1
- package/dist/graph/cards.d.ts.map +1 -1
- package/dist/graph/cards.js +11 -2
- package/dist/graph/cards.js.map +1 -1
- package/dist/graph/check.d.ts.map +1 -1
- package/dist/graph/check.js +7 -4
- package/dist/graph/check.js.map +1 -1
- package/dist/graph/extract-cache.d.ts +1 -0
- package/dist/graph/extract-cache.d.ts.map +1 -1
- package/dist/graph/extract-cache.js +1 -1
- package/dist/graph/extract-cache.js.map +1 -1
- package/dist/graph/extract.d.ts +17 -0
- package/dist/graph/extract.d.ts.map +1 -1
- package/dist/graph/extract.js +188 -17
- package/dist/graph/extract.js.map +1 -1
- package/dist/graph/fingerprint.d.ts +1 -0
- package/dist/graph/fingerprint.d.ts.map +1 -1
- package/dist/graph/fingerprint.js +15 -6
- package/dist/graph/fingerprint.js.map +1 -1
- package/dist/graph/map.d.ts.map +1 -1
- package/dist/graph/map.js +6 -4
- package/dist/graph/map.js.map +1 -1
- package/dist/graph/refresh.d.ts.map +1 -1
- package/dist/graph/refresh.js +61 -13
- package/dist/graph/refresh.js.map +1 -1
- package/dist/graph/resolve.d.ts.map +1 -1
- package/dist/graph/resolve.js +36 -43
- package/dist/graph/resolve.js.map +1 -1
- package/dist/graph/scopes.d.ts +14 -2
- package/dist/graph/scopes.d.ts.map +1 -1
- package/dist/graph/scopes.js +51 -81
- package/dist/graph/scopes.js.map +1 -1
- package/dist/graph/seed.d.ts +38 -0
- package/dist/graph/seed.d.ts.map +1 -0
- package/dist/graph/seed.js +226 -0
- package/dist/graph/seed.js.map +1 -0
- package/dist/graph/source-files.d.ts +13 -5
- package/dist/graph/source-files.d.ts.map +1 -1
- package/dist/graph/source-files.js +16 -7
- package/dist/graph/source-files.js.map +1 -1
- package/dist/graph/traverse-cli.d.ts +9 -3
- package/dist/graph/traverse-cli.d.ts.map +1 -1
- package/dist/graph/traverse-cli.js +28 -8
- package/dist/graph/traverse-cli.js.map +1 -1
- package/dist/graph/traverse.d.ts +5 -3
- package/dist/graph/traverse.d.ts.map +1 -1
- package/dist/graph/traverse.js +23 -4
- package/dist/graph/traverse.js.map +1 -1
- package/dist/graph/types.d.ts +1 -0
- package/dist/graph/types.d.ts.map +1 -1
- package/dist/graph/workspace-cli.d.ts +5 -0
- package/dist/graph/workspace-cli.d.ts.map +1 -1
- package/dist/graph/workspace-cli.js +7 -0
- package/dist/graph/workspace-cli.js.map +1 -1
- package/dist/graph/workspace.js +1 -1
- package/dist/graph/workspace.js.map +1 -1
- package/dist/hosts/mcp-config.d.ts +11 -1
- package/dist/hosts/mcp-config.d.ts.map +1 -1
- package/dist/hosts/mcp-config.js +50 -7
- package/dist/hosts/mcp-config.js.map +1 -1
- package/dist/ingest/fs.d.ts +30 -2
- package/dist/ingest/fs.d.ts.map +1 -1
- package/dist/ingest/fs.js +84 -8
- package/dist/ingest/fs.js.map +1 -1
- package/dist/mcp/instructions.d.ts +29 -0
- package/dist/mcp/instructions.d.ts.map +1 -0
- package/dist/mcp/instructions.js +55 -0
- package/dist/mcp/instructions.js.map +1 -0
- package/dist/mcp/server.d.ts +6 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +10 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +3 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +54 -30
- package/dist/mcp/tools.js.map +1 -1
- package/dist/search/grep-cli.d.ts.map +1 -1
- package/dist/search/grep-cli.js +5 -2
- package/dist/search/grep-cli.js.map +1 -1
- package/dist/search/grep.d.ts +2 -1
- package/dist/search/grep.d.ts.map +1 -1
- package/dist/search/grep.js +17 -4
- package/dist/search/grep.js.map +1 -1
- package/dist/util/paths.d.ts +29 -0
- package/dist/util/paths.d.ts.map +1 -0
- package/dist/util/paths.js +71 -0
- package/dist/util/paths.js.map +1 -0
- package/dist/util/source.d.ts +4 -0
- package/dist/util/source.d.ts.map +1 -0
- package/dist/util/source.js +12 -0
- package/dist/util/source.js.map +1 -0
- package/dist/util/state.d.ts +25 -0
- package/dist/util/state.d.ts.map +1 -1
- package/dist/util/state.js +41 -0
- package/dist/util/state.js.map +1 -1
- package/package.json +2 -2
- package/scripts/run-tests.mjs +43 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repo-relative paths, always posix.
|
|
3
|
+
*
|
|
4
|
+
* Every path graft stores — node ids, `node.path`, extract-cache keys, the
|
|
5
|
+
* freshness fingerprint, the card manifest — is repo-relative and separated by
|
|
6
|
+
* `/` on every platform. That is not cosmetic: the query layer parses these
|
|
7
|
+
* strings with `/` as the separator, and does it by hand rather than through
|
|
8
|
+
* `node:path`. `pathUnderPrefix` (`--in` scoping) tests
|
|
9
|
+
* `startsWith(`${prefix}/`)`, `map`'s `dirKey` splits on `/` to cluster by
|
|
10
|
+
* directory, `resolveSymbol` matches a filename query with
|
|
11
|
+
* `endsWith("/" + query)`. Hand any of them a `src\gate.ts` and none of them
|
|
12
|
+
* error — they match nothing, silently. On Windows that made every `--in`
|
|
13
|
+
* report "nothing indexed under …" and made `map` emit one single-file
|
|
14
|
+
* "directory" per file.
|
|
15
|
+
*
|
|
16
|
+
* So normalize once, here, where a path is *created*, instead of defensively at
|
|
17
|
+
* each consumer — a consumer that forgets is a silent wrong answer, and there
|
|
18
|
+
* are more consumers than producers.
|
|
19
|
+
*
|
|
20
|
+
* {@link toPosixPath} splits on the platform `sep`, never a literal `\`: a
|
|
21
|
+
* posix filename may legitimately contain a backslash, and splitting on `"\\"`
|
|
22
|
+
* would corrupt it. That also makes this module provably the identity function
|
|
23
|
+
* on posix, which is what guarantees an existing Mac/Linux graph is byte-identical
|
|
24
|
+
* across this change.
|
|
25
|
+
*/
|
|
26
|
+
import { relative, sep } from "node:path";
|
|
27
|
+
/** Platform separators → `/`. Identity on posix. */
|
|
28
|
+
export function toPosixPath(p) {
|
|
29
|
+
return sep === "/" ? p : p.split(sep).join("/");
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* `relative(from, to)`, normalized to posix — the canonical form of every path
|
|
33
|
+
* graft stores. Use this rather than bare `relative` for anything that lands in
|
|
34
|
+
* the graph, a cache key, or a manifest. Bare `relative` is still right for
|
|
35
|
+
* text shown in the terminal, where a native separator is what the platform's
|
|
36
|
+
* users expect.
|
|
37
|
+
*/
|
|
38
|
+
export function relPosix(from, to) {
|
|
39
|
+
return toPosixPath(relative(from, to));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Trailing `/` off a repo-relative path, in linear time.
|
|
43
|
+
*
|
|
44
|
+
* The obvious `replace(/\/+$/, "")` is a polynomial-ReDoS shape — `\/+$` can begin
|
|
45
|
+
* matching at any point inside a run of slashes, so a path ending in many slashes
|
|
46
|
+
* and then anything else costs O(n²). CodeQL flags it (`js/polynomial-redos`), and
|
|
47
|
+
* rightly: these inputs are a `--dir` or `--in` value rather than anything
|
|
48
|
+
* attacker-controlled, but the ambiguity buys nothing and a loop is both faster
|
|
49
|
+
* and plainer.
|
|
50
|
+
*/
|
|
51
|
+
export function stripTrailingSlashes(path) {
|
|
52
|
+
let end = path.length;
|
|
53
|
+
while (end > 0 && path[end - 1] === "/")
|
|
54
|
+
end--;
|
|
55
|
+
return path.slice(0, end);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Normalize a user-supplied path prefix (`--in`) so it can be compared against
|
|
59
|
+
* a stored `node.path`: posix separators, no leading `./`, no trailing
|
|
60
|
+
* separator. Windows users type — and their shell's tab-completion produces —
|
|
61
|
+
* `--in server\src\gpu`, so both separators have to reduce to the same prefix.
|
|
62
|
+
*/
|
|
63
|
+
export function normalizePathPrefix(p) {
|
|
64
|
+
let out = toPosixPath(p);
|
|
65
|
+
while (out.startsWith("./"))
|
|
66
|
+
out = out.slice(2);
|
|
67
|
+
// Trailing separators only; a bare "/" normalizes to "" (match everything),
|
|
68
|
+
// which is exactly how `pathUnderPrefix` reads an empty prefix.
|
|
69
|
+
return stripTrailingSlashes(out);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/util/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAE1C,oDAAoD;AACpD,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,EAAU;IAC/C,OAAO,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;IACtB,OAAO,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG;QAAE,GAAG,EAAE,CAAC;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,CAAS;IAC3C,IAAI,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IACzB,OAAO,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAChD,4EAA4E;IAC5E,gEAAgE;IAChE,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Read source text, decoding Windows tooling's common UTF-16LE output. UTF-16BE
|
|
2
|
+
* is rare and unsupported by Node's built-in decoders, so callers silently skip it. */
|
|
3
|
+
export declare function readSourceFile(path: string): string | null;
|
|
4
|
+
//# sourceMappingURL=source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/util/source.ts"],"names":[],"mappings":"AAEA;uFACuF;AACvF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK1D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
/** Read source text, decoding Windows tooling's common UTF-16LE output. UTF-16BE
|
|
3
|
+
* is rare and unsupported by Node's built-in decoders, so callers silently skip it. */
|
|
4
|
+
export function readSourceFile(path) {
|
|
5
|
+
const bytes = readFileSync(path);
|
|
6
|
+
if (bytes[0] === 0xfe && bytes[1] === 0xff)
|
|
7
|
+
return null;
|
|
8
|
+
if (bytes[0] === 0xff && bytes[1] === 0xfe)
|
|
9
|
+
return bytes.subarray(2).toString("utf16le");
|
|
10
|
+
return bytes.toString("utf8");
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/util/source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC;uFACuF;AACvF,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACxD,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACzF,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC"}
|
package/dist/util/state.d.ts
CHANGED
|
@@ -31,6 +31,31 @@ export declare function readJson<T>(p: string): T | null;
|
|
|
31
31
|
export declare function writeJsonAtomic(p: string, value: unknown, compact?: boolean): void;
|
|
32
32
|
export declare function readStats(d: string): Stats | null;
|
|
33
33
|
export declare function writeStats(d: string, s: Stats): void;
|
|
34
|
+
/**
|
|
35
|
+
* Persisted per-repo build configuration — currently just `graft build
|
|
36
|
+
* --include-dir`'s override. An explicit input like the graph itself: absent
|
|
37
|
+
* or empty `includeDirs` means today's default (every `SKIP_DIRS` name stays
|
|
38
|
+
* skipped), so a repo that never used the flag is entirely unaffected.
|
|
39
|
+
*/
|
|
40
|
+
export interface BuildConfig {
|
|
41
|
+
/** SKIP_DIRS names to include in this repo's walks, persisted so a LATER
|
|
42
|
+
* no-flag build — and the fingerprint/refresh path, which never sees CLI
|
|
43
|
+
* flags at all — behave identically to the invocation that set it. */
|
|
44
|
+
includeDirs?: string[];
|
|
45
|
+
}
|
|
46
|
+
/** Local, Git-ignored repository configuration. Kept outside generated
|
|
47
|
+
* `graft/` output so deleting/replacing that cache, workspace federation, and
|
|
48
|
+
* custom `--dir` builds cannot erase or redirect the persisted choice. */
|
|
49
|
+
export declare const BUILD_CONFIG_DIR = ".graft";
|
|
50
|
+
export declare function buildConfigPath(d: string): string;
|
|
51
|
+
export declare function readBuildConfig(d: string): BuildConfig | null;
|
|
52
|
+
export declare function writeBuildConfig(d: string, c: BuildConfig): void;
|
|
53
|
+
/** The persisted `--include-dir` override for repo `d`, as a Set — `undefined`
|
|
54
|
+
* when nothing was ever persisted (or the persisted list is empty), which every
|
|
55
|
+
* `shouldSkipDir`/`walkDir` caller treats as "today's default behavior". Shared
|
|
56
|
+
* by every walkDir-driven entry point (source-files.ts, scopes.ts) so a build,
|
|
57
|
+
* a later no-flag rebuild, and the hooks/refresh path all agree. */
|
|
58
|
+
export declare function readIncludeDirs(d: string): Set<string> | undefined;
|
|
34
59
|
export declare function patchStats(d: string, patch: Partial<Stats>): Stats;
|
|
35
60
|
export declare function acquireLock(d: string): boolean;
|
|
36
61
|
export declare function releaseLock(d: string): void;
|
package/dist/util/state.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/util/state.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAC1D,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IACrD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClD;AAED,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC,wBAAgB,UAAU,IAAI,KAAK,CAGlC;AAID,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAgD;AAGpG,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAE/C;AACD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,UAAQ,GAAG,IAAI,CAUhF;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAA0C;AAC5F,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,CAAsC;
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/util/state.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAC1D,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IACrD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClD;AAED,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC,wBAAgB,UAAU,IAAI,KAAK,CAGlC;AAID,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAgD;AAGpG,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAE/C;AACD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,UAAQ,GAAG,IAAI,CAUhF;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAA0C;AAC5F,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,CAAsC;AAE3F;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B;;0EAEsE;IACtE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;0EAE0E;AAC1E,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAEzC,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAqD;AAkBvG,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAsD;AACpH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,GAAG,IAAI,CAGhE;AAED;;;;oEAIoE;AACpE,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAGlE;AAGD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAIlE;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE9C;AACD,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAgBpD;AACD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEjD"}
|
package/dist/util/state.js
CHANGED
|
@@ -58,6 +58,47 @@ export function writeJsonAtomic(p, value, compact = false) {
|
|
|
58
58
|
}
|
|
59
59
|
export function readStats(d) { return readJson(statsPath(d)); }
|
|
60
60
|
export function writeStats(d, s) { writeJsonAtomic(statsPath(d), s); }
|
|
61
|
+
/** Local, Git-ignored repository configuration. Kept outside generated
|
|
62
|
+
* `graft/` output so deleting/replacing that cache, workspace federation, and
|
|
63
|
+
* custom `--dir` builds cannot erase or redirect the persisted choice. */
|
|
64
|
+
export const BUILD_CONFIG_DIR = '.graft';
|
|
65
|
+
export function buildConfigPath(d) { return join(d, BUILD_CONFIG_DIR, 'config.json'); }
|
|
66
|
+
/** Keep local build configuration out of Git without coupling it to the
|
|
67
|
+
* generated graph directory. Best-effort, matching graph-cache ignore setup. */
|
|
68
|
+
function ensureBuildConfigIgnored(d) {
|
|
69
|
+
const path = join(d, '.gitignore');
|
|
70
|
+
let current = '';
|
|
71
|
+
try {
|
|
72
|
+
current = readFileSync(path, 'utf8');
|
|
73
|
+
}
|
|
74
|
+
catch { /* no .gitignore yet */ }
|
|
75
|
+
const present = current.split('\n').some((line) => {
|
|
76
|
+
const value = line.trim();
|
|
77
|
+
return value === BUILD_CONFIG_DIR || value === `${BUILD_CONFIG_DIR}/` || value === `/${BUILD_CONFIG_DIR}/`;
|
|
78
|
+
});
|
|
79
|
+
if (present)
|
|
80
|
+
return;
|
|
81
|
+
const gap = current === '' ? '' : current.endsWith('\n') ? '\n' : '\n\n';
|
|
82
|
+
const block = `${gap}# graft's local repository settings — not committed.\n/${BUILD_CONFIG_DIR}/\n`;
|
|
83
|
+
try {
|
|
84
|
+
writeFileSync(path, current + block);
|
|
85
|
+
}
|
|
86
|
+
catch { /* best-effort */ }
|
|
87
|
+
}
|
|
88
|
+
export function readBuildConfig(d) { return readJson(buildConfigPath(d)); }
|
|
89
|
+
export function writeBuildConfig(d, c) {
|
|
90
|
+
ensureBuildConfigIgnored(d);
|
|
91
|
+
writeJsonAtomic(buildConfigPath(d), c);
|
|
92
|
+
}
|
|
93
|
+
/** The persisted `--include-dir` override for repo `d`, as a Set — `undefined`
|
|
94
|
+
* when nothing was ever persisted (or the persisted list is empty), which every
|
|
95
|
+
* `shouldSkipDir`/`walkDir` caller treats as "today's default behavior". Shared
|
|
96
|
+
* by every walkDir-driven entry point (source-files.ts, scopes.ts) so a build,
|
|
97
|
+
* a later no-flag rebuild, and the hooks/refresh path all agree. */
|
|
98
|
+
export function readIncludeDirs(d) {
|
|
99
|
+
const dirs = readBuildConfig(d)?.includeDirs;
|
|
100
|
+
return dirs && dirs.length ? new Set(dirs) : undefined;
|
|
101
|
+
}
|
|
61
102
|
// Best-effort read-modify-write; not atomic across concurrent processes, but acceptable
|
|
62
103
|
// for episodic hook writes (worst case is a lost update, not corruption).
|
|
63
104
|
export function patchStats(d, patch) {
|
package/dist/util/state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/util/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/F,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAS1C,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC;AAEpC,MAAM,UAAU,UAAU;IACxB,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC;QAC9E,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAClF,CAAC;AAED,MAAM,SAAS,GAAG,YAAY,CAAC;AAE/B,MAAM,UAAU,QAAQ,CAAC,UAAkB,IAAY,OAAO,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;AACpG,SAAS,SAAS,CAAC,CAAS,IAAY,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;AAEjF,MAAM,UAAU,QAAQ,CAAI,CAAS;IACnC,IAAI,CAAC;QAAC,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAM,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AACjF,CAAC;AACD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,eAAe,CAAC,CAAS,EAAE,KAAc,EAAE,OAAO,GAAG,KAAK;IACxE,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;IACtC,IAAI,CAAC;QACH,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACrF,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC;YAAC,MAAM,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,4BAA4B,CAAC,CAAC;QAC5E,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,CAAS,IAAkB,OAAO,QAAQ,CAAQ,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5F,MAAM,UAAU,UAAU,CAAC,CAAS,EAAE,CAAQ,IAAU,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/util/state.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nanonets/graft",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Build a repo's context graph as a folder of linked markdown files that live in the repo and stay in sync with the code through git.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"build": "tsc -p tsconfig.json && tsc -p viewer/tsconfig.json && node scripts/build-viewer.mjs",
|
|
47
47
|
"dev": "tsc -p tsconfig.json --watch",
|
|
48
48
|
"cli": "tsx src/cli.ts",
|
|
49
|
-
"test": "node
|
|
49
|
+
"test": "node scripts/run-tests.mjs",
|
|
50
50
|
"prepare": "npm run build",
|
|
51
51
|
"prepublishOnly": "npm run build",
|
|
52
52
|
"postinstall": "node scripts/postinstall.mjs"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs the test suite without depending on shell glob expansion.
|
|
3
|
+
*
|
|
4
|
+
* `node --test test/*.test.ts` needs the *shell* to expand that glob, and on
|
|
5
|
+
* Windows nothing does: npm runs scripts through `cmd.exe` regardless of the
|
|
6
|
+
* shell that invoked npm, and Node's `--test` only accepts glob patterns itself
|
|
7
|
+
* from Node 21 (this package supports >=20). The literal pattern reaches Node as
|
|
8
|
+
* a filename and it exits with `Could not find '…\test\*.test.ts'` — so the
|
|
9
|
+
* Windows CI leg reported failure while actually running zero tests.
|
|
10
|
+
*
|
|
11
|
+
* Enumerating the files here instead means `npm test` behaves identically in
|
|
12
|
+
* cmd.exe, PowerShell, bash and CI, on any supported Node.
|
|
13
|
+
*/
|
|
14
|
+
import { readdirSync } from "node:fs";
|
|
15
|
+
import { spawnSync } from "node:child_process";
|
|
16
|
+
import { dirname, join, resolve } from "node:path";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
|
|
19
|
+
const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
20
|
+
const testDir = join(repoRoot, "test");
|
|
21
|
+
|
|
22
|
+
// Sorted so a failure is reported in the same order on every platform and run.
|
|
23
|
+
const files = readdirSync(testDir)
|
|
24
|
+
.filter((f) => f.endsWith(".test.ts"))
|
|
25
|
+
.sort()
|
|
26
|
+
.map((f) => join(testDir, f));
|
|
27
|
+
|
|
28
|
+
if (files.length === 0) {
|
|
29
|
+
console.error(`✗ no test files found in ${testDir}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const result = spawnSync(process.execPath, ["--import", "tsx", "--test", ...files], {
|
|
34
|
+
cwd: repoRoot,
|
|
35
|
+
stdio: "inherit",
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (result.error) {
|
|
39
|
+
console.error(`✗ could not start the test runner: ${result.error.message}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
// A signal-killed run reports null status; treat anything non-zero as failure.
|
|
43
|
+
process.exit(result.status ?? 1);
|