dsh-gitnexus-plus 0.0.0-stage → 0.1.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.
Files changed (90) hide show
  1. package/LICENSE +38 -0
  2. package/README.md +631 -2
  3. package/cordis.patch.yml +18 -0
  4. package/lib/bin/gitnexus-coverage.d.ts +14 -0
  5. package/lib/bin/gitnexus-coverage.d.ts.map +1 -0
  6. package/lib/bin/gitnexus-coverage.js +171 -0
  7. package/lib/bin/gitnexus-coverage.js.map +1 -0
  8. package/lib/bin/search-helper.d.ts +22 -0
  9. package/lib/bin/search-helper.d.ts.map +1 -0
  10. package/lib/bin/search-helper.js +57 -0
  11. package/lib/bin/search-helper.js.map +1 -0
  12. package/lib/client.js +2131 -0
  13. package/lib/gitnexus/analyze.d.ts +173 -0
  14. package/lib/gitnexus/analyze.d.ts.map +1 -0
  15. package/lib/gitnexus/analyze.js +308 -0
  16. package/lib/gitnexus/analyze.js.map +1 -0
  17. package/lib/gitnexus/commands.d.ts +129 -0
  18. package/lib/gitnexus/commands.d.ts.map +1 -0
  19. package/lib/gitnexus/commands.js +185 -0
  20. package/lib/gitnexus/commands.js.map +1 -0
  21. package/lib/gitnexus/coverage.d.ts +340 -0
  22. package/lib/gitnexus/coverage.d.ts.map +1 -0
  23. package/lib/gitnexus/coverage.js +554 -0
  24. package/lib/gitnexus/coverage.js.map +1 -0
  25. package/lib/gitnexus/format.d.ts +16 -0
  26. package/lib/gitnexus/format.d.ts.map +1 -0
  27. package/lib/gitnexus/format.js +178 -0
  28. package/lib/gitnexus/format.js.map +1 -0
  29. package/lib/gitnexus/git-activity.d.ts +136 -0
  30. package/lib/gitnexus/git-activity.d.ts.map +1 -0
  31. package/lib/gitnexus/git-activity.js +345 -0
  32. package/lib/gitnexus/git-activity.js.map +1 -0
  33. package/lib/gitnexus/git.d.ts +70 -0
  34. package/lib/gitnexus/git.d.ts.map +1 -0
  35. package/lib/gitnexus/git.js +121 -0
  36. package/lib/gitnexus/git.js.map +1 -0
  37. package/lib/gitnexus/index-meta.d.ts +160 -0
  38. package/lib/gitnexus/index-meta.d.ts.map +1 -0
  39. package/lib/gitnexus/index-meta.js +176 -0
  40. package/lib/gitnexus/index-meta.js.map +1 -0
  41. package/lib/gitnexus/install.d.ts +97 -0
  42. package/lib/gitnexus/install.d.ts.map +1 -0
  43. package/lib/gitnexus/install.js +228 -0
  44. package/lib/gitnexus/install.js.map +1 -0
  45. package/lib/gitnexus/languages.d.ts +80 -0
  46. package/lib/gitnexus/languages.d.ts.map +1 -0
  47. package/lib/gitnexus/languages.js +297 -0
  48. package/lib/gitnexus/languages.js.map +1 -0
  49. package/lib/gitnexus/root.d.ts +74 -0
  50. package/lib/gitnexus/root.d.ts.map +1 -0
  51. package/lib/gitnexus/root.js +168 -0
  52. package/lib/gitnexus/root.js.map +1 -0
  53. package/lib/gitnexus/scan.d.ts +68 -0
  54. package/lib/gitnexus/scan.d.ts.map +1 -0
  55. package/lib/gitnexus/scan.js +249 -0
  56. package/lib/gitnexus/scan.js.map +1 -0
  57. package/lib/gitnexus/search.d.ts +167 -0
  58. package/lib/gitnexus/search.d.ts.map +1 -0
  59. package/lib/gitnexus/search.js +517 -0
  60. package/lib/gitnexus/search.js.map +1 -0
  61. package/lib/gitnexus/toolchain.d.ts +136 -0
  62. package/lib/gitnexus/toolchain.d.ts.map +1 -0
  63. package/lib/gitnexus/toolchain.js +251 -0
  64. package/lib/gitnexus/toolchain.js.map +1 -0
  65. package/lib/index.d.ts +98 -0
  66. package/lib/index.d.ts.map +1 -0
  67. package/lib/index.js +252 -0
  68. package/lib/index.js.map +1 -0
  69. package/lib/routes/analyze.d.ts +41 -0
  70. package/lib/routes/analyze.d.ts.map +1 -0
  71. package/lib/routes/analyze.js +75 -0
  72. package/lib/routes/analyze.js.map +1 -0
  73. package/lib/routes/coverage.d.ts +52 -0
  74. package/lib/routes/coverage.d.ts.map +1 -0
  75. package/lib/routes/coverage.js +81 -0
  76. package/lib/routes/coverage.js.map +1 -0
  77. package/lib/routes/guard.d.ts +92 -0
  78. package/lib/routes/guard.d.ts.map +1 -0
  79. package/lib/routes/guard.js +187 -0
  80. package/lib/routes/guard.js.map +1 -0
  81. package/lib/routes/install.d.ts +27 -0
  82. package/lib/routes/install.d.ts.map +1 -0
  83. package/lib/routes/install.js +46 -0
  84. package/lib/routes/install.js.map +1 -0
  85. package/lib/routes/search.d.ts +27 -0
  86. package/lib/routes/search.d.ts.map +1 -0
  87. package/lib/routes/search.js +77 -0
  88. package/lib/routes/search.js.map +1 -0
  89. package/package.json +87 -4
  90. package/scripts/link-runtime.mjs +146 -0
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Read the on-disk GitNexus index metadata.
3
+ *
4
+ * `.gitnexus/gitnexus.json` is the only fully machine-readable artifact GitNexus
5
+ * writes: the graph itself lives in a single LadybugDB file (`lbug`) and there is
6
+ * no persisted graph JSON/CSV. Everything this plugin shows about an index that
7
+ * is not the graph comes from here or from `~/.gitnexus/registry.json`.
8
+ */
9
+ /** Directory GitNexus keeps its global state in, honouring `GITNEXUS_HOME`. */
10
+ export declare function globalDir(env?: NodeJS.ProcessEnv): string;
11
+ /** The environment a caller may thread through instead of the real one. */
12
+ export interface RegistryOptions {
13
+ env?: NodeJS.ProcessEnv;
14
+ }
15
+ /** The counters every manifest and registry entry carries. */
16
+ export interface IndexStats {
17
+ files: number;
18
+ nodes: number;
19
+ edges: number;
20
+ communities: number;
21
+ processes: number;
22
+ embeddings: number;
23
+ }
24
+ export interface RegistryEntry {
25
+ name: string;
26
+ path: string;
27
+ storagePath: string;
28
+ indexedAt: string;
29
+ lastCommit: string;
30
+ remoteUrl?: string;
31
+ branch?: string;
32
+ stats: IndexStats;
33
+ }
34
+ /**
35
+ * Read the global registry. Never throws: an absent or malformed registry yields
36
+ * an empty list, because "GitNexus has never run here" is a normal state.
37
+ *
38
+ * The registry is written by GitNexus, not by this plugin, so entries are taken
39
+ * as written: the guard checks the one field a lookup needs (`path`) and nothing
40
+ * else, exactly as the untyped revision did.
41
+ */
42
+ export declare function readRegistry(options?: RegistryOptions): Promise<RegistryEntry[]>;
43
+ /**
44
+ * Normalize a path for comparison.
45
+ *
46
+ * Windows paths in the registry are not case-stable in practice — this machine's
47
+ * registry holds both `D:\Project\...` and `D:\project\...` for the same tree.
48
+ * Comparing raw strings would treat one repository as two.
49
+ */
50
+ export declare function normalizePathKey(p: string): string;
51
+ /**
52
+ * Find the registry entry for a repository path or alias.
53
+ *
54
+ * @param target absolute path or registry alias
55
+ */
56
+ export declare function findRegistryEntry(target: string, options?: RegistryOptions): Promise<RegistryEntry | null>;
57
+ /**
58
+ * Whether a directory holds a GitNexus index.
59
+ *
60
+ * The panel shows the project the user is *in*, which need not appear in the global
61
+ * registry at all — and a plugin that refused to describe the user's own working
62
+ * directory because a global file elsewhere had not heard of it would be wrong.
63
+ * This is not by itself the route bound any more: a git project with no index still
64
+ * has a readable working tree, so the routes use {@link isProjectRoot}, which
65
+ * accepts either an index or a `.git` marker.
66
+ */
67
+ export declare function hasIndex(repoPath: string): Promise<boolean>;
68
+ /**
69
+ * Whether a directory is a project the routes may describe.
70
+ *
71
+ * Deliberately wider than {@link hasIndex}: a git repository with no index still has
72
+ * a readable working tree, and both the scan-only coverage report and the initialize
73
+ * action are for exactly that state. A directory with neither an index nor a `.git`
74
+ * marker is refused, which is what keeps these routes from becoming a filesystem
75
+ * probe. `.git` may be a directory or a file (worktrees and submodules), so this
76
+ * checks existence rather than type.
77
+ */
78
+ export declare function isProjectRoot(repoPath: string): Promise<boolean>;
79
+ /** `indexCoverage` as the `analyze` that produced the index wrote it. */
80
+ export interface RawIndexCoverage {
81
+ maxFileSizeBytes?: unknown;
82
+ dirtyPaths?: unknown;
83
+ [key: string]: unknown;
84
+ }
85
+ /** `runnerIdentity`, the analyzer-provenance receipt (schema v4). */
86
+ export interface RunnerIdentity {
87
+ cliVersion?: string;
88
+ [key: string]: unknown;
89
+ }
90
+ /**
91
+ * The parsed manifest, as far as this plugin reads it.
92
+ *
93
+ * Named fields are the ones read here or in the report built from them; the index
94
+ * signature carries the rest of a manifest GitNexus is free to extend, so a newer
95
+ * manifest stays readable without a change here. Nothing in this file validates
96
+ * the manifest — a field of the wrong type is reported as absent, not repaired.
97
+ */
98
+ export interface RawIndexManifest {
99
+ storagePath?: unknown;
100
+ repoPath?: unknown;
101
+ indexedAt?: unknown;
102
+ lastCommit?: unknown;
103
+ branch?: unknown;
104
+ stats?: IndexStats;
105
+ fileHashes?: Record<string, unknown> | null;
106
+ indexCoverage?: RawIndexCoverage | null;
107
+ capabilities?: Record<string, unknown>;
108
+ schemaFingerprint?: unknown;
109
+ runnerIdentity?: RunnerIdentity;
110
+ remoteUrl?: string;
111
+ contentRetention?: string | null;
112
+ ftsProfile?: string | null;
113
+ analysisFeatures?: Record<string, number>;
114
+ crossLanguageProperties?: unknown[];
115
+ unresolvedReceiverMembers?: unknown;
116
+ [key: string]: unknown;
117
+ }
118
+ export interface IndexMeta {
119
+ /** which of the two manifest names the values came from */
120
+ metaFile: string | null;
121
+ storagePath: string;
122
+ repoPath: string;
123
+ indexedAt: string;
124
+ lastCommit: string;
125
+ branch?: string;
126
+ stats: IndexStats;
127
+ /** repo-relative path -> sha256 */
128
+ fileHashes: Record<string, string>;
129
+ /** size cap in force when the index was written */
130
+ coverageMaxFileSizeBytes: number | null;
131
+ /** files that were dirty vs HEAD when indexed */
132
+ dirtyPaths: string[];
133
+ capabilities: Record<string, unknown>;
134
+ schemaFingerprint?: string;
135
+ runnerIdentity?: RunnerIdentity;
136
+ /** the full parsed manifest */
137
+ raw: RawIndexManifest;
138
+ }
139
+ /**
140
+ * Read the index manifest for a repository.
141
+ *
142
+ * Two file names exist in the wild and both must be honoured:
143
+ *
144
+ * `gitnexus.json` — current format, written by the `analyze` that produced the
145
+ * index. Carries `indexCoverage`, `storagePath`, `branch`,
146
+ * `runnerIdentity` on top of the shared fields.
147
+ * `meta.json` — the older name, still present on indexes built by earlier
148
+ * releases. Observed on this machine holding a 28 536-entry
149
+ * `fileHashes` with **no** `indexCoverage` at all.
150
+ *
151
+ * Reading only `gitnexus.json` makes the tool report a perfectly good 28k-file
152
+ * index as "not indexed" — which is how this fallback came to exist. Absent
153
+ * coverage fields are reported as absent (`null`), never defaulted: claiming a cap
154
+ * the index never recorded would misattribute files as "skipped".
155
+ *
156
+ * @param repoPath absolute repository root
157
+ * @returns `null` when the repository is not indexed.
158
+ */
159
+ export declare function readIndexMeta(repoPath: string): Promise<IndexMeta | null>;
160
+ //# sourceMappingURL=index-meta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-meta.d.ts","sourceRoot":"","sources":["../../src/gitnexus/index-meta.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Read the on-disk GitNexus index metadata.
3
+ *
4
+ * `.gitnexus/gitnexus.json` is the only fully machine-readable artifact GitNexus
5
+ * writes: the graph itself lives in a single LadybugDB file (`lbug`) and there is
6
+ * no persisted graph JSON/CSV. Everything this plugin shows about an index that
7
+ * is not the graph comes from here or from `~/.gitnexus/registry.json`.
8
+ */
9
+ import { existsSync } from 'node:fs';
10
+ import fs from 'node:fs/promises';
11
+ import path from 'node:path';
12
+ import os from 'node:os';
13
+ /** Directory GitNexus keeps its global state in, honouring `GITNEXUS_HOME`. */
14
+ export function globalDir(env = process.env) {
15
+ return env.GITNEXUS_HOME && env.GITNEXUS_HOME.trim() !== ''
16
+ ? path.resolve(env.GITNEXUS_HOME)
17
+ : path.join(os.homedir(), '.gitnexus');
18
+ }
19
+ /**
20
+ * Read the global registry. Never throws: an absent or malformed registry yields
21
+ * an empty list, because "GitNexus has never run here" is a normal state.
22
+ *
23
+ * The registry is written by GitNexus, not by this plugin, so entries are taken
24
+ * as written: the guard checks the one field a lookup needs (`path`) and nothing
25
+ * else, exactly as the untyped revision did.
26
+ */
27
+ export async function readRegistry(options = {}) {
28
+ const file = path.join(globalDir(options.env ?? process.env), 'registry.json');
29
+ try {
30
+ const parsed = JSON.parse(await fs.readFile(file, 'utf8'));
31
+ return Array.isArray(parsed)
32
+ ? parsed.filter((entry) => Boolean(entry) && typeof entry.path === 'string')
33
+ : [];
34
+ }
35
+ catch {
36
+ return [];
37
+ }
38
+ }
39
+ /**
40
+ * Normalize a path for comparison.
41
+ *
42
+ * Windows paths in the registry are not case-stable in practice — this machine's
43
+ * registry holds both `D:\Project\...` and `D:\project\...` for the same tree.
44
+ * Comparing raw strings would treat one repository as two.
45
+ */
46
+ export function normalizePathKey(p) {
47
+ const resolved = path.resolve(p).replace(/\\/g, '/').replace(/\/+$/, '');
48
+ return process.platform === 'win32' ? resolved.toLowerCase() : resolved;
49
+ }
50
+ /**
51
+ * Find the registry entry for a repository path or alias.
52
+ *
53
+ * @param target absolute path or registry alias
54
+ */
55
+ export async function findRegistryEntry(target, options = {}) {
56
+ const entries = await readRegistry(options);
57
+ const wanted = normalizePathKey(target);
58
+ const byPath = entries.find((e) => {
59
+ try {
60
+ return normalizePathKey(e.path) === wanted;
61
+ }
62
+ catch {
63
+ return false;
64
+ }
65
+ });
66
+ if (byPath)
67
+ return byPath;
68
+ return entries.find((e) => e.name === target) ?? null;
69
+ }
70
+ /**
71
+ * Whether a directory holds a GitNexus index.
72
+ *
73
+ * The panel shows the project the user is *in*, which need not appear in the global
74
+ * registry at all — and a plugin that refused to describe the user's own working
75
+ * directory because a global file elsewhere had not heard of it would be wrong.
76
+ * This is not by itself the route bound any more: a git project with no index still
77
+ * has a readable working tree, so the routes use {@link isProjectRoot}, which
78
+ * accepts either an index or a `.git` marker.
79
+ */
80
+ export async function hasIndex(repoPath) {
81
+ const dir = path.join(repoPath, '.gitnexus');
82
+ for (const name of ['gitnexus.json', 'meta.json']) {
83
+ try {
84
+ await fs.access(path.join(dir, name));
85
+ return true;
86
+ }
87
+ catch {
88
+ /* try the next name */
89
+ }
90
+ }
91
+ return false;
92
+ }
93
+ /**
94
+ * Whether a directory is a project the routes may describe.
95
+ *
96
+ * Deliberately wider than {@link hasIndex}: a git repository with no index still has
97
+ * a readable working tree, and both the scan-only coverage report and the initialize
98
+ * action are for exactly that state. A directory with neither an index nor a `.git`
99
+ * marker is refused, which is what keeps these routes from becoming a filesystem
100
+ * probe. `.git` may be a directory or a file (worktrees and submodules), so this
101
+ * checks existence rather than type.
102
+ */
103
+ export async function isProjectRoot(repoPath) {
104
+ if (await hasIndex(repoPath))
105
+ return true;
106
+ try {
107
+ return existsSync(path.join(repoPath, '.git'));
108
+ }
109
+ catch {
110
+ return false;
111
+ }
112
+ }
113
+ /**
114
+ * Read the index manifest for a repository.
115
+ *
116
+ * Two file names exist in the wild and both must be honoured:
117
+ *
118
+ * `gitnexus.json` — current format, written by the `analyze` that produced the
119
+ * index. Carries `indexCoverage`, `storagePath`, `branch`,
120
+ * `runnerIdentity` on top of the shared fields.
121
+ * `meta.json` — the older name, still present on indexes built by earlier
122
+ * releases. Observed on this machine holding a 28 536-entry
123
+ * `fileHashes` with **no** `indexCoverage` at all.
124
+ *
125
+ * Reading only `gitnexus.json` makes the tool report a perfectly good 28k-file
126
+ * index as "not indexed" — which is how this fallback came to exist. Absent
127
+ * coverage fields are reported as absent (`null`), never defaulted: claiming a cap
128
+ * the index never recorded would misattribute files as "skipped".
129
+ *
130
+ * @param repoPath absolute repository root
131
+ * @returns `null` when the repository is not indexed.
132
+ */
133
+ export async function readIndexMeta(repoPath) {
134
+ const dir = path.join(repoPath, '.gitnexus');
135
+ let raw = null;
136
+ let source = null;
137
+ for (const name of ['gitnexus.json', 'meta.json']) {
138
+ try {
139
+ raw = JSON.parse(await fs.readFile(path.join(dir, name), 'utf8'));
140
+ source = name;
141
+ break;
142
+ }
143
+ catch {
144
+ /* try the next name */
145
+ }
146
+ }
147
+ if (raw === null)
148
+ return null;
149
+ const fileHashes = {};
150
+ if (raw.fileHashes && typeof raw.fileHashes === 'object') {
151
+ for (const [key, value] of Object.entries(raw.fileHashes)) {
152
+ if (typeof value === 'string')
153
+ fileHashes[key.replace(/\\/g, '/')] = value;
154
+ }
155
+ }
156
+ const coverage = raw.indexCoverage;
157
+ return {
158
+ metaFile: source,
159
+ storagePath: typeof raw.storagePath === 'string' ? raw.storagePath : path.join(repoPath, '.gitnexus'),
160
+ repoPath: typeof raw.repoPath === 'string' ? raw.repoPath : repoPath,
161
+ indexedAt: typeof raw.indexedAt === 'string' ? raw.indexedAt : '',
162
+ lastCommit: typeof raw.lastCommit === 'string' ? raw.lastCommit : '',
163
+ branch: typeof raw.branch === 'string' ? raw.branch : undefined,
164
+ stats: raw.stats ?? { files: 0, nodes: 0, edges: 0, communities: 0, processes: 0, embeddings: 0 },
165
+ fileHashes,
166
+ // Absent on indexes written before this field existed — callers must not
167
+ // invent a cap when it is missing.
168
+ coverageMaxFileSizeBytes: coverage && typeof coverage.maxFileSizeBytes === 'number' ? coverage.maxFileSizeBytes : null,
169
+ dirtyPaths: Array.isArray(coverage?.dirtyPaths) ? coverage.dirtyPaths : [],
170
+ capabilities: raw.capabilities ?? {},
171
+ schemaFingerprint: typeof raw.schemaFingerprint === 'string' ? raw.schemaFingerprint : undefined,
172
+ runnerIdentity: raw.runnerIdentity,
173
+ raw,
174
+ };
175
+ }
176
+ //# sourceMappingURL=index-meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-meta.js","sourceRoot":"","sources":["../../src/gitnexus/index-meta.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Install GitNexus on this machine, on the operator's explicit instruction.
3
+ *
4
+ * WHY THE PLUGIN DOES THIS ITSELF
5
+ * -------------------------------
6
+ * The plugin reads `.gitnexus/gitnexus.json` — a file that only GitNexus can produce,
7
+ * containing every function definition, symbol relationship and execution flow. Without
8
+ * it there is nothing to display, and no amount of scanning the working tree substitutes
9
+ * for it. So "the user has no GitNexus" is not a degraded state to design around; it is
10
+ * a missing prerequisite, and the most useful thing the plugin can do about it is offer
11
+ * to satisfy it.
12
+ *
13
+ * WHAT IT DOES NOT DO
14
+ * -------------------
15
+ * It does not download anything itself, and it does not pick a registry. It runs `npm
16
+ * install` and lets npm use whatever registry the machine is already configured for —
17
+ * a mirror, a corporate feed, a local Verdaccio. Hardcoding one would break exactly the
18
+ * users whose network is the reason they need this path, and the operator's `.npmrc` is
19
+ * the only authority on where their packages come from.
20
+ *
21
+ * It also does not build anything itself. npm runs the dependency install scripts that
22
+ * GitNexus needs (`@ladybugdb/core`, `tree-sitter`, its own grammar build) — which is
23
+ * why this uses npm rather than pnpm, whose ≥10 line refuses dependency build scripts by
24
+ * default and would fail the install in a way the operator could not act on.
25
+ *
26
+ * INSTALL LOCATION
27
+ * ----------------
28
+ * A directory the plugin owns (`$DSH_HOME/gitnexus-plus/gitnexus`), never the global
29
+ * prefix. A global install needs elevation on Windows and would collide with a GitNexus
30
+ * the operator already has. A plugin-owned copy is removable, self-describing, and does
31
+ * not make the plugin responsible for someone else's global state.
32
+ *
33
+ * The cost is real and the confirmation must state it: roughly 500 MB to 1 GB, several
34
+ * minutes, network access, and the package's build scripts running on this machine.
35
+ */
36
+ import type { ShellLike } from './analyze.js';
37
+ export type InstallState = 'running' | 'done' | 'failed' | 'timed-out' | 'cancelled'
38
+ /** The sandbox refused a write. Reported, never retried wider. */
39
+ | 'denied'
40
+ /** No shell executor in this deployment, so nothing can be installed. */
41
+ | 'unavailable';
42
+ export interface InstallStatus {
43
+ state: InstallState;
44
+ /** The command as run, so a failure can be reproduced by hand. */
45
+ command: string;
46
+ /** Where it installs to. */
47
+ prefix: string;
48
+ startedAt: number;
49
+ finishedAt: number | null;
50
+ exitCode: number | null;
51
+ message: string | null;
52
+ output: string;
53
+ }
54
+ /** The version range this plugin is known to work against. */
55
+ export declare const GITNEXUS_RANGE = "^1.6.12";
56
+ export interface InstallRunnerOptions {
57
+ shell: ShellLike | null;
58
+ /** Install target. Defaults to `$DSH_HOME/gitnexus-plus/gitnexus`. */
59
+ prefix?: string;
60
+ /** Version spec passed to npm. */
61
+ spec?: string;
62
+ timeoutMs?: number;
63
+ outputLimit?: number;
64
+ tailLimit?: number;
65
+ /** How long to wait for the completion notice, for tests. */
66
+ now?: () => number;
67
+ /** Platform whose shell syntax applies. */
68
+ platform?: NodeJS.Platform;
69
+ }
70
+ export interface InstallRunner {
71
+ start(): InstallStatus;
72
+ status(): InstallStatus | null;
73
+ cancel(): boolean;
74
+ /** Where a successful install puts the CLI. */
75
+ cliPath(): string;
76
+ dispose(): void;
77
+ }
78
+ /**
79
+ * The default install target.
80
+ *
81
+ * Under `DSH_HOME` rather than under the plugin, because a profile-installed plugin
82
+ * lives inside `node_modules` and writing a 500 MB tree there would be lost on the next
83
+ * install and would confuse the package manager's own bookkeeping.
84
+ */
85
+ export declare function defaultInstallPrefix(env?: NodeJS.ProcessEnv): string;
86
+ /**
87
+ * The `npm install` line, as the shell will read it.
88
+ *
89
+ * `--prefix` rather than `cd`: the working directory stays wherever the executor put it,
90
+ * so a failed install cannot leave a half-written tree in the operator's project. No
91
+ * `--registry` on purpose — see the module comment.
92
+ */
93
+ export declare function installCommandLine(prefix: string, spec: string, options?: {
94
+ platform?: NodeJS.Platform;
95
+ }): string;
96
+ export declare function createInstallRunner(options: InstallRunnerOptions): InstallRunner;
97
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/gitnexus/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,MAAM,GACN,QAAQ,GACR,WAAW,GACX,WAAW;AACb,kEAAkE;GAChE,QAAQ;AACV,yEAAyE;GACvE,aAAa,CAAC;AAElB,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,YAAY,CAAC;IACpB,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,8DAA8D;AAC9D,eAAO,MAAM,cAAc,YAAY,CAAC;AAMxC,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,IAAI,aAAa,CAAC;IACvB,MAAM,IAAI,aAAa,GAAG,IAAI,CAAC;IAC/B,MAAM,IAAI,OAAO,CAAC;IAClB,+CAA+C;IAC/C,OAAO,IAAI,MAAM,CAAC;IAClB,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAGjF;AAOD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAA;CAAO,GAC3C,MAAM,CAIR;AAcD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAwJhF"}