doc-detective 4.0.2-dev.1 → 4.0.2-dev.11

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 (97) hide show
  1. package/dist/agents/adapters/claude-code.d.ts +77 -0
  2. package/dist/agents/adapters/claude-code.d.ts.map +1 -0
  3. package/dist/agents/adapters/claude-code.js +461 -0
  4. package/dist/agents/adapters/claude-code.js.map +1 -0
  5. package/dist/agents/adapters/codex.d.ts +64 -0
  6. package/dist/agents/adapters/codex.d.ts.map +1 -0
  7. package/dist/agents/adapters/codex.js +299 -0
  8. package/dist/agents/adapters/codex.js.map +1 -0
  9. package/dist/agents/adapters/copilot-cli.d.ts +29 -0
  10. package/dist/agents/adapters/copilot-cli.d.ts.map +1 -0
  11. package/dist/agents/adapters/copilot-cli.js +195 -0
  12. package/dist/agents/adapters/copilot-cli.js.map +1 -0
  13. package/dist/agents/adapters/gemini-cli.d.ts +29 -0
  14. package/dist/agents/adapters/gemini-cli.d.ts.map +1 -0
  15. package/dist/agents/adapters/gemini-cli.js +207 -0
  16. package/dist/agents/adapters/gemini-cli.js.map +1 -0
  17. package/dist/agents/adapters/opencode.d.ts +67 -0
  18. package/dist/agents/adapters/opencode.d.ts.map +1 -0
  19. package/dist/agents/adapters/opencode.js +341 -0
  20. package/dist/agents/adapters/opencode.js.map +1 -0
  21. package/dist/agents/adapters/qwen-code.d.ts +30 -0
  22. package/dist/agents/adapters/qwen-code.d.ts.map +1 -0
  23. package/dist/agents/adapters/qwen-code.js +212 -0
  24. package/dist/agents/adapters/qwen-code.js.map +1 -0
  25. package/dist/agents/command.d.ts +11 -0
  26. package/dist/agents/command.d.ts.map +1 -0
  27. package/dist/agents/command.js +41 -0
  28. package/dist/agents/command.js.map +1 -0
  29. package/dist/agents/fetcher.d.ts +30 -0
  30. package/dist/agents/fetcher.d.ts.map +1 -0
  31. package/dist/agents/fetcher.js +112 -0
  32. package/dist/agents/fetcher.js.map +1 -0
  33. package/dist/agents/prompts.d.ts +24 -0
  34. package/dist/agents/prompts.d.ts.map +1 -0
  35. package/dist/agents/prompts.js +74 -0
  36. package/dist/agents/prompts.js.map +1 -0
  37. package/dist/agents/registry.d.ts +4 -0
  38. package/dist/agents/registry.d.ts.map +1 -0
  39. package/dist/agents/registry.js +25 -0
  40. package/dist/agents/registry.js.map +1 -0
  41. package/dist/agents/runner.d.ts +13 -0
  42. package/dist/agents/runner.d.ts.map +1 -0
  43. package/dist/agents/runner.js +155 -0
  44. package/dist/agents/runner.js.map +1 -0
  45. package/dist/agents/spawn-helper.d.ts +33 -0
  46. package/dist/agents/spawn-helper.d.ts.map +1 -0
  47. package/dist/agents/spawn-helper.js +98 -0
  48. package/dist/agents/spawn-helper.js.map +1 -0
  49. package/dist/agents/types.d.ts +41 -0
  50. package/dist/agents/types.d.ts.map +1 -0
  51. package/dist/agents/types.js +2 -0
  52. package/dist/agents/types.js.map +1 -0
  53. package/dist/cli.js +42 -10
  54. package/dist/cli.js.map +1 -1
  55. package/dist/common/src/detectTests.d.ts.map +1 -1
  56. package/dist/common/src/detectTests.js +43 -12
  57. package/dist/common/src/detectTests.js.map +1 -1
  58. package/dist/common/src/fileTypes.d.ts.map +1 -1
  59. package/dist/common/src/fileTypes.js +10 -0
  60. package/dist/common/src/fileTypes.js.map +1 -1
  61. package/dist/common/src/schemas/schemas.json +594 -0
  62. package/dist/common/src/types/generated/checkLink_v3.d.ts +15 -0
  63. package/dist/common/src/types/generated/checkLink_v3.d.ts.map +1 -1
  64. package/dist/common/src/types/generated/config_v3.d.ts +4 -0
  65. package/dist/common/src/types/generated/config_v3.d.ts.map +1 -1
  66. package/dist/common/src/types/generated/resolvedTests_v3.d.ts +4 -0
  67. package/dist/common/src/types/generated/resolvedTests_v3.d.ts.map +1 -1
  68. package/dist/common/src/types/generated/step_v3.d.ts +15 -0
  69. package/dist/common/src/types/generated/step_v3.d.ts.map +1 -1
  70. package/dist/common/src/types/generated/test_v3.d.ts +30 -0
  71. package/dist/common/src/types/generated/test_v3.d.ts.map +1 -1
  72. package/dist/core/config.d.ts.map +1 -1
  73. package/dist/core/config.js +10 -0
  74. package/dist/core/config.js.map +1 -1
  75. package/dist/core/integrations/heretto.d.ts.map +1 -1
  76. package/dist/core/integrations/heretto.js +11 -3
  77. package/dist/core/integrations/heretto.js.map +1 -1
  78. package/dist/core/tests/checkLink.d.ts.map +1 -1
  79. package/dist/core/tests/checkLink.js +136 -29
  80. package/dist/core/tests/checkLink.js.map +1 -1
  81. package/dist/core/tests/loadCookie.d.ts.map +1 -1
  82. package/dist/core/tests/loadCookie.js +12 -2
  83. package/dist/core/tests/loadCookie.js.map +1 -1
  84. package/dist/core/tests/saveScreenshot.d.ts +15 -1
  85. package/dist/core/tests/saveScreenshot.d.ts.map +1 -1
  86. package/dist/core/tests/saveScreenshot.js +41 -17
  87. package/dist/core/tests/saveScreenshot.js.map +1 -1
  88. package/dist/index.cjs +816 -59
  89. package/dist/reporters/htmlReporter.d.ts +2 -0
  90. package/dist/reporters/htmlReporter.d.ts.map +1 -0
  91. package/dist/reporters/htmlReporter.js +1589 -0
  92. package/dist/reporters/htmlReporter.js.map +1 -0
  93. package/dist/utils.d.ts +2 -1
  94. package/dist/utils.d.ts.map +1 -1
  95. package/dist/utils.js +43 -10
  96. package/dist/utils.js.map +1 -1
  97. package/package.json +3 -1
@@ -0,0 +1,207 @@
1
+ import path from "node:path";
2
+ import os from "node:os";
3
+ import fs from "node:fs";
4
+ import axios from "axios";
5
+ import { safeSpawn } from "../spawn-helper.js";
6
+ const EXTENSION_NAME = "doc-detective";
7
+ const GIT_SOURCE = "https://github.com/doc-detective/agent-tools.git";
8
+ const LATEST_MANIFEST_URL = "https://raw.githubusercontent.com/doc-detective/agent-tools/main/gemini-extension.json";
9
+ export function defaultGeminiCliDeps() {
10
+ return {
11
+ run: (cmd, args) => safeSpawn(cmd, args),
12
+ existsSync: fs.existsSync,
13
+ readFileSync: (p, enc = "utf8") => fs.readFileSync(p, enc),
14
+ homedir: os.homedir,
15
+ fetchLatestVersion: async () => {
16
+ const response = await axios.get(LATEST_MANIFEST_URL, {
17
+ timeout: 5000,
18
+ responseType: "json",
19
+ });
20
+ const version = response?.data?.version;
21
+ return typeof version === "string" ? version : undefined;
22
+ },
23
+ };
24
+ }
25
+ export class GeminiCliAdapter {
26
+ id = "gemini";
27
+ displayName = "Gemini CLI";
28
+ deps;
29
+ constructor(deps = defaultGeminiCliDeps()) {
30
+ this.deps = deps;
31
+ }
32
+ supportsScopes() {
33
+ // Gemini's `extensions install` has no --scope flag; extensions live in ~/.gemini.
34
+ return ["global"];
35
+ }
36
+ async detect() {
37
+ const geminiHome = path.join(this.deps.homedir(), ".gemini");
38
+ let onPath = false;
39
+ let version;
40
+ try {
41
+ const result = await this.deps.run("gemini", ["--version"]);
42
+ if (result.exitCode === 0 && result.stdout.trim()) {
43
+ onPath = true;
44
+ version = result.stdout.trim();
45
+ }
46
+ }
47
+ catch {
48
+ // Binary absent — silent.
49
+ }
50
+ const configPaths = {};
51
+ if (this.deps.existsSync(geminiHome))
52
+ configPaths.global = geminiHome;
53
+ const present = onPath || !!configPaths.global;
54
+ const notes = [];
55
+ if (!onPath && configPaths.global) {
56
+ notes.push("`gemini` not on PATH; install requires the binary — see https://github.com/google-gemini/gemini-cli for install options.");
57
+ }
58
+ return {
59
+ present,
60
+ onPath,
61
+ version,
62
+ configPaths,
63
+ notes: notes.length ? notes : undefined,
64
+ };
65
+ }
66
+ async getInstallState(_scope) {
67
+ const base = await this.queryLocalInstallState();
68
+ if (!base.installed)
69
+ return base;
70
+ return this.enrichWithLatest(base);
71
+ }
72
+ manifestPath() {
73
+ return path.join(this.deps.homedir(), ".gemini", "extensions", EXTENSION_NAME, "gemini-extension.json");
74
+ }
75
+ async queryLocalInstallState() {
76
+ // Preferred: `gemini extensions list --output-format json`
77
+ try {
78
+ const result = await this.deps.run("gemini", ["extensions", "list", "--output-format", "json"]);
79
+ if (result.exitCode === 0 && result.stdout.trim()) {
80
+ try {
81
+ const parsed = JSON.parse(result.stdout);
82
+ if (Array.isArray(parsed)) {
83
+ const entry = parsed.find((e) => e && typeof e === "object" && e.name === EXTENSION_NAME);
84
+ if (entry) {
85
+ const version = typeof entry.version === "string" ? entry.version : undefined;
86
+ return { installed: true, installedVersion: version };
87
+ }
88
+ return { installed: false };
89
+ }
90
+ // Non-array (e.g. error object) — fall through to the filesystem fallback.
91
+ }
92
+ catch {
93
+ // Unparseable JSON — fall through.
94
+ }
95
+ }
96
+ }
97
+ catch {
98
+ // CLI not available — fall through.
99
+ }
100
+ // Fallback: read the extension manifest directly.
101
+ const manifestPath = this.manifestPath();
102
+ if (!this.deps.existsSync(manifestPath))
103
+ return { installed: false };
104
+ try {
105
+ const parsed = JSON.parse(this.deps.readFileSync(manifestPath, "utf8"));
106
+ return {
107
+ installed: true,
108
+ installedVersion: typeof parsed?.version === "string" ? parsed.version : undefined,
109
+ };
110
+ }
111
+ catch {
112
+ return { installed: false };
113
+ }
114
+ }
115
+ async enrichWithLatest(state) {
116
+ let latestVersion;
117
+ try {
118
+ latestVersion = await this.deps.fetchLatestVersion();
119
+ }
120
+ catch {
121
+ latestVersion = undefined;
122
+ }
123
+ if (!latestVersion) {
124
+ return { ...state, latestVersion: undefined, upToDate: undefined };
125
+ }
126
+ const upToDate = state.installedVersion !== undefined
127
+ ? state.installedVersion === latestVersion
128
+ : undefined;
129
+ return { ...state, latestVersion, upToDate };
130
+ }
131
+ async install(opts) {
132
+ const base = await this.queryLocalInstallState();
133
+ const enriched = base.installed ? await this.enrichWithLatest(base) : base;
134
+ const isInstalled = enriched.installed;
135
+ const isUpToDate = enriched.upToDate === true;
136
+ if (isInstalled && isUpToDate && !opts.force) {
137
+ return {
138
+ adapterId: this.id,
139
+ scope: opts.scope,
140
+ action: "already-up-to-date",
141
+ installedVersion: enriched.installedVersion,
142
+ };
143
+ }
144
+ const commands = isInstalled
145
+ ? [["gemini", "extensions", "update", EXTENSION_NAME]]
146
+ : [
147
+ [
148
+ "gemini", "extensions", "install", GIT_SOURCE,
149
+ "--auto-update", "--consent", "--skip-settings",
150
+ ],
151
+ ];
152
+ if (opts.dryRun) {
153
+ for (const cmd of commands) {
154
+ opts.logger(`[dry-run] would run: ${cmd.join(" ")}`, "info");
155
+ }
156
+ return {
157
+ adapterId: this.id,
158
+ scope: opts.scope,
159
+ action: "dry-run",
160
+ installedVersion: enriched.installedVersion,
161
+ };
162
+ }
163
+ for (const [cmd, ...args] of commands) {
164
+ opts.logger(`Running: ${cmd} ${args.join(" ")}`, "debug");
165
+ let result;
166
+ try {
167
+ result = await this.deps.run(cmd, args);
168
+ }
169
+ catch (err) {
170
+ const code = err?.code;
171
+ if (code === "ENOENT") {
172
+ throw new Error("Gemini CLI is not installed or not on PATH. Run `npm install -g @google/gemini-cli` and re-run install-agents.");
173
+ }
174
+ throw err;
175
+ }
176
+ if (result.stdout)
177
+ opts.logger(result.stdout, "debug");
178
+ if (result.exitCode !== 0) {
179
+ throw new Error(`\`${cmd} ${args.join(" ")}\` exited with code ${result.exitCode}` +
180
+ (result.stderr ? `: ${result.stderr}` : ""));
181
+ }
182
+ }
183
+ // Re-read on-disk state post-install so the report reflects reality even
184
+ // when the network probe failed or this was a fresh install (where
185
+ // `enriched` was never enriched with latestVersion). Same pattern used by
186
+ // the Qwen and Copilot adapters.
187
+ const postInstall = await this.queryLocalInstallState();
188
+ const installedVersion = enriched.latestVersion ??
189
+ postInstall.installedVersion ??
190
+ enriched.installedVersion;
191
+ let action;
192
+ if (opts.force && isInstalled && isUpToDate)
193
+ action = "forced";
194
+ else if (isInstalled)
195
+ action = "updated";
196
+ else
197
+ action = "installed";
198
+ return {
199
+ adapterId: this.id,
200
+ scope: opts.scope,
201
+ action,
202
+ installedVersion,
203
+ };
204
+ }
205
+ }
206
+ export const geminiCliAdapter = new GeminiCliAdapter();
207
+ //# sourceMappingURL=gemini-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-cli.js","sourceRoot":"","sources":["../../../src/agents/adapters/gemini-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import type { AgentAdapter, DetectionResult, InstallOptions, InstallReport, InstallState, Scope } from "../types.js";
2
+ export interface RunResult {
3
+ stdout: string;
4
+ stderr: string;
5
+ exitCode: number;
6
+ }
7
+ export interface OpenCodeDeps {
8
+ run: (cmd: string, args: string[]) => Promise<RunResult>;
9
+ existsSync: (p: string) => boolean;
10
+ readFileSync: (p: string, encoding?: BufferEncoding) => string;
11
+ readdirSync?: (p: string) => string[];
12
+ mkdirSync?: (p: string, opts?: {
13
+ recursive?: boolean;
14
+ }) => void;
15
+ writeFileSync?: (p: string, data: string | Buffer) => void;
16
+ rmSync?: (p: string, opts?: {
17
+ recursive?: boolean;
18
+ force?: boolean;
19
+ }) => void;
20
+ homedir: () => string;
21
+ cwd: () => string;
22
+ fetchLatestVersion: () => Promise<string | undefined>;
23
+ fetchZip: (ref: string) => Promise<{
24
+ tempDir: string;
25
+ ref: string;
26
+ owned?: boolean;
27
+ }>;
28
+ }
29
+ export declare function defaultOpenCodeDeps(): OpenCodeDeps;
30
+ export declare class OpenCodeAdapter implements AgentAdapter {
31
+ readonly id = "opencode";
32
+ readonly displayName = "OpenCode";
33
+ private deps;
34
+ constructor(deps?: OpenCodeDeps);
35
+ supportsScopes(): Scope[];
36
+ detect(): Promise<DetectionResult>;
37
+ getInstallState(scope: Scope): Promise<InstallState>;
38
+ /**
39
+ * Resolve the scope root. Global scope prefers the XDG-style config dir
40
+ * (~/.config/opencode/) that OpenCode documents as primary. Project scope
41
+ * uses ./.opencode/ for committed, team-shared skills.
42
+ */
43
+ private scopeRoot;
44
+ private canonicalSkillPath;
45
+ private queryLocalInstallState;
46
+ private enrichWithLatest;
47
+ install(opts: InstallOptions): Promise<InstallReport>;
48
+ private mkdirp;
49
+ /**
50
+ * Walk a directory tree and remove any file or directory whose basename
51
+ * starts with "doc-detective". Used before re-copying hooks/ or agents/ so
52
+ * we prune our own stale artifacts (files/dirs renamed or removed
53
+ * upstream) without touching unrelated user content living in the same
54
+ * directory.
55
+ */
56
+ private pruneDocDetectiveFiles;
57
+ /**
58
+ * Recursive directory copy. Uses `this.deps.readdirSync` and
59
+ * `this.deps.writeFileSync` where the injected signatures match, but falls
60
+ * back to `fs.statSync` and buffer-returning `fs.readFileSync` directly —
61
+ * the `OpenCodeDeps.readFileSync` signature returns a string, so we can't
62
+ * use it here without losing binary content.
63
+ */
64
+ private copyDir;
65
+ }
66
+ export declare const opencodeAdapter: AgentAdapter;
67
+ //# sourceMappingURL=opencode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../../src/agents/adapters/opencode.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,cAAc,EACd,aAAa,EACb,YAAY,EACZ,KAAK,EACN,MAAM,aAAa,CAAC;AAKrB,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IACzD,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IACnC,YAAY,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,KAAK,MAAM,CAAC;IAC/D,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IACtC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAChE,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IAC3D,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9E,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACtD,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACvF;AAMD,wBAAgB,mBAAmB,IAAI,YAAY,CAqBlD;AAED,qBAAa,eAAgB,YAAW,YAAY;IAClD,QAAQ,CAAC,EAAE,cAAc;IACzB,QAAQ,CAAC,WAAW,cAAc;IAClC,OAAO,CAAC,IAAI,CAAe;gBAEf,IAAI,GAAE,YAAoC;IAItD,cAAc,IAAI,KAAK,EAAE;IAInB,MAAM,IAAI,OAAO,CAAC,eAAe,CAAC;IAsClC,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC;IAM1D;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,sBAAsB;YAWhB,gBAAgB;IAiBxB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAuK3D,OAAO,CAAC,MAAM;IAKd;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAmB9B;;;;;;OAMG;IACH,OAAO,CAAC,OAAO;CAmBhB;AAED,eAAO,MAAM,eAAe,EAAE,YAAoC,CAAC"}
@@ -0,0 +1,341 @@
1
+ import path from "node:path";
2
+ import os from "node:os";
3
+ import fs from "node:fs";
4
+ import axios from "axios";
5
+ import { safeSpawn } from "../spawn-helper.js";
6
+ import { fetchAgentToolsZip } from "../fetcher.js";
7
+ import { parseMetadataVersion } from "./codex.js";
8
+ const CANONICAL_SKILL = "doc-detective-init";
9
+ const LATEST_SKILL_URL = "https://raw.githubusercontent.com/doc-detective/agent-tools/main/skills/doc-detective-init/SKILL.md";
10
+ export function defaultOpenCodeDeps() {
11
+ return {
12
+ run: (cmd, args) => safeSpawn(cmd, args),
13
+ existsSync: fs.existsSync,
14
+ readFileSync: (p, enc = "utf8") => fs.readFileSync(p, enc),
15
+ readdirSync: (p) => fs.readdirSync(p),
16
+ mkdirSync: (p, opts) => { fs.mkdirSync(p, opts); },
17
+ writeFileSync: (p, data) => fs.writeFileSync(p, typeof data === "string" ? data : Buffer.from(data)),
18
+ rmSync: (p, opts) => { fs.rmSync(p, opts); },
19
+ homedir: os.homedir,
20
+ cwd: () => process.cwd(),
21
+ fetchLatestVersion: async () => {
22
+ const response = await axios.get(LATEST_SKILL_URL, {
23
+ timeout: 5000,
24
+ responseType: "text",
25
+ });
26
+ return parseMetadataVersion(String(response?.data ?? ""));
27
+ },
28
+ fetchZip: (ref) => fetchAgentToolsZip(ref),
29
+ };
30
+ }
31
+ export class OpenCodeAdapter {
32
+ id = "opencode";
33
+ displayName = "OpenCode";
34
+ deps;
35
+ constructor(deps = defaultOpenCodeDeps()) {
36
+ this.deps = deps;
37
+ }
38
+ supportsScopes() {
39
+ return ["global", "project"];
40
+ }
41
+ async detect() {
42
+ const configDir = path.join(this.deps.homedir(), ".config", "opencode");
43
+ const installDir = path.join(this.deps.homedir(), ".opencode");
44
+ const projectDir = path.join(this.deps.cwd(), ".opencode");
45
+ let onPath = false;
46
+ let version;
47
+ try {
48
+ const result = await this.deps.run("opencode", ["--version"]);
49
+ if (result.exitCode === 0 && result.stdout.trim()) {
50
+ onPath = true;
51
+ version = result.stdout.trim();
52
+ }
53
+ }
54
+ catch {
55
+ // Binary absent — silent.
56
+ }
57
+ const configPaths = {};
58
+ if (this.deps.existsSync(configDir))
59
+ configPaths.global = configDir;
60
+ else if (this.deps.existsSync(installDir))
61
+ configPaths.global = installDir;
62
+ if (this.deps.existsSync(projectDir))
63
+ configPaths.project = projectDir;
64
+ const present = onPath || !!configPaths.global || !!configPaths.project;
65
+ const notes = [];
66
+ if (!onPath && (configPaths.global || configPaths.project)) {
67
+ notes.push("`opencode` not on PATH; skills will be written to <scope>/skills/ and auto-discovered on next OpenCode launch.");
68
+ }
69
+ return {
70
+ present,
71
+ onPath,
72
+ version,
73
+ configPaths,
74
+ notes: notes.length ? notes : undefined,
75
+ };
76
+ }
77
+ async getInstallState(scope) {
78
+ const base = this.queryLocalInstallState(scope);
79
+ if (!base.installed)
80
+ return base;
81
+ return this.enrichWithLatest(base);
82
+ }
83
+ /**
84
+ * Resolve the scope root. Global scope prefers the XDG-style config dir
85
+ * (~/.config/opencode/) that OpenCode documents as primary. Project scope
86
+ * uses ./.opencode/ for committed, team-shared skills.
87
+ */
88
+ scopeRoot(scope) {
89
+ return scope === "global"
90
+ ? path.join(this.deps.homedir(), ".config", "opencode")
91
+ : path.join(this.deps.cwd(), ".opencode");
92
+ }
93
+ canonicalSkillPath(scope) {
94
+ return path.join(this.scopeRoot(scope), "skills", CANONICAL_SKILL, "SKILL.md");
95
+ }
96
+ queryLocalInstallState(scope) {
97
+ const canonical = this.canonicalSkillPath(scope);
98
+ if (!this.deps.existsSync(canonical))
99
+ return { installed: false };
100
+ try {
101
+ const raw = this.deps.readFileSync(canonical, "utf8");
102
+ return { installed: true, installedVersion: parseMetadataVersion(raw) };
103
+ }
104
+ catch {
105
+ return { installed: false };
106
+ }
107
+ }
108
+ async enrichWithLatest(state) {
109
+ let latestVersion;
110
+ try {
111
+ latestVersion = await this.deps.fetchLatestVersion();
112
+ }
113
+ catch {
114
+ latestVersion = undefined;
115
+ }
116
+ if (!latestVersion) {
117
+ return { ...state, latestVersion: undefined, upToDate: undefined };
118
+ }
119
+ const upToDate = state.installedVersion !== undefined
120
+ ? state.installedVersion === latestVersion
121
+ : undefined;
122
+ return { ...state, latestVersion, upToDate };
123
+ }
124
+ async install(opts) {
125
+ const local = this.queryLocalInstallState(opts.scope);
126
+ const enriched = local.installed ? await this.enrichWithLatest(local) : local;
127
+ const isInstalled = enriched.installed;
128
+ const isUpToDate = enriched.upToDate === true;
129
+ // `upToDate === undefined` means the latest-version probe failed
130
+ // (offline, GitHub rate limit, etc.). Treat that as "keep what's on
131
+ // disk" instead of re-fetching and re-copying the entire zip every
132
+ // run. `--force` still works for explicit refresh.
133
+ const latestUnknown = isInstalled && enriched.upToDate === undefined;
134
+ if (isInstalled && !opts.force && (isUpToDate || latestUnknown)) {
135
+ if (latestUnknown) {
136
+ opts.logger("OpenCode is already installed, but the latest-version check failed; skipping reinstall. Use --force to reinstall anyway.", "info");
137
+ }
138
+ return {
139
+ adapterId: this.id,
140
+ scope: opts.scope,
141
+ action: "already-up-to-date",
142
+ installedVersion: enriched.installedVersion,
143
+ };
144
+ }
145
+ const root = this.scopeRoot(opts.scope);
146
+ if (opts.dryRun) {
147
+ opts.logger(`[dry-run] would fetch doc-detective/agent-tools and copy into ${root}: ` +
148
+ `skills/doc-detective-*, plugins/opencode-plugin.mjs, hooks/, agents/`, "info");
149
+ return {
150
+ adapterId: this.id,
151
+ scope: opts.scope,
152
+ action: "dry-run",
153
+ installedVersion: enriched.installedVersion,
154
+ };
155
+ }
156
+ const fetched = await this.deps.fetchZip("main");
157
+ try {
158
+ const pluginSrc = path.join(fetched.tempDir, "plugins", "doc-detective");
159
+ if (!this.deps.existsSync(pluginSrc)) {
160
+ throw new Error(`Fetched agent-tools archive has no plugins/doc-detective/ directory at ${pluginSrc}.`);
161
+ }
162
+ // Fall back to module-level fs.rmSync when no rmSync is injected —
163
+ // required for the atomic rename below to succeed when `dst` exists.
164
+ const rmSync = this.deps.rmSync ??
165
+ ((p, opts) => fs.rmSync(p, opts));
166
+ // 1. Skills (doc-detective-* only) — fail loudly if missing, then
167
+ // atomic-overwrite each skill (copy to a tmp sibling, swap in).
168
+ const skillsSrc = path.join(pluginSrc, "skills");
169
+ const skillsDst = path.join(root, "skills");
170
+ if (!this.deps.existsSync(skillsSrc)) {
171
+ throw new Error(`Fetched agent-tools archive has no plugins/doc-detective/skills/ directory at ${skillsSrc}.`);
172
+ }
173
+ const names = (this.deps.readdirSync?.(skillsSrc) ?? []).filter((n) => n.startsWith("doc-detective-"));
174
+ if (names.length === 0) {
175
+ throw new Error("Fetched agent-tools archive has no OpenCode doc-detective-* skills to install.");
176
+ }
177
+ this.mkdirp(skillsDst);
178
+ for (const name of names) {
179
+ const src = path.join(skillsSrc, name);
180
+ const dst = path.join(skillsDst, name);
181
+ const tmpDst = `${dst}.install.tmp.${process.pid}.${Date.now()}`;
182
+ if (this.deps.existsSync(tmpDst)) {
183
+ rmSync(tmpDst, { recursive: true, force: true });
184
+ }
185
+ try {
186
+ this.copyDir(src, tmpDst);
187
+ }
188
+ catch (err) {
189
+ try {
190
+ rmSync(tmpDst, { recursive: true, force: true });
191
+ }
192
+ catch { }
193
+ throw err;
194
+ }
195
+ if (this.deps.existsSync(dst)) {
196
+ rmSync(dst, { recursive: true, force: true });
197
+ }
198
+ fs.renameSync(tmpDst, dst);
199
+ opts.logger(`Copied skill: ${name}`, "debug");
200
+ }
201
+ // 2. Plugin file — also required for OpenCode integration to work.
202
+ const pluginFileSrc = path.join(pluginSrc, "opencode-plugin.mjs");
203
+ if (!this.deps.existsSync(pluginFileSrc)) {
204
+ throw new Error(`Fetched agent-tools archive has no OpenCode plugin file at ${pluginFileSrc}.`);
205
+ }
206
+ const pluginFileDst = path.join(root, "plugins", "opencode-plugin.mjs");
207
+ this.mkdirp(path.dirname(pluginFileDst));
208
+ const buf = fs.readFileSync(pluginFileSrc);
209
+ if (this.deps.writeFileSync)
210
+ this.deps.writeFileSync(pluginFileDst, buf);
211
+ else
212
+ fs.writeFileSync(pluginFileDst, buf);
213
+ opts.logger("Copied plugin: opencode-plugin.mjs", "debug");
214
+ // 3. Hooks dir — copy additively. We can't safely wipe the whole dir
215
+ // because OpenCode users may keep their own hooks alongside ours.
216
+ // We prune only doc-detective-owned files: anything whose basename
217
+ // starts with "doc-detective" and lives under hooks/ gets removed
218
+ // first, so files renamed/removed upstream don't linger. Unrelated
219
+ // user content is preserved.
220
+ const hooksSrc = path.join(pluginSrc, "hooks");
221
+ const hooksDst = path.join(root, "hooks");
222
+ if (this.deps.existsSync(hooksSrc)) {
223
+ if (this.deps.existsSync(hooksDst)) {
224
+ this.pruneDocDetectiveFiles(hooksDst);
225
+ }
226
+ this.copyDir(hooksSrc, hooksDst);
227
+ opts.logger("Copied hooks/", "debug");
228
+ }
229
+ // 4. Agents dir — same additive-copy + targeted-prune pattern as hooks.
230
+ const agentsSrc = path.join(pluginSrc, "agents");
231
+ const agentsDst = path.join(root, "agents");
232
+ if (this.deps.existsSync(agentsSrc)) {
233
+ if (this.deps.existsSync(agentsDst)) {
234
+ this.pruneDocDetectiveFiles(agentsDst);
235
+ }
236
+ this.copyDir(agentsSrc, agentsDst);
237
+ opts.logger("Copied agents/", "debug");
238
+ }
239
+ const installedVersion = this.queryLocalInstallState(opts.scope).installedVersion ??
240
+ enriched.latestVersion;
241
+ let action;
242
+ if (opts.force && isInstalled && isUpToDate)
243
+ action = "forced";
244
+ else if (isInstalled)
245
+ action = "updated";
246
+ else
247
+ action = "installed";
248
+ return {
249
+ adapterId: this.id,
250
+ scope: opts.scope,
251
+ action,
252
+ installedVersion,
253
+ notes: [
254
+ "OpenCode auto-discovers skills and plugins at startup — restart OpenCode if it's currently running.",
255
+ ],
256
+ };
257
+ }
258
+ catch (err) {
259
+ const reason = err instanceof Error ? err.message : String(err);
260
+ throw new Error(`Failed to install OpenCode tools from GitHub: ${reason}`);
261
+ }
262
+ finally {
263
+ // Only clean up the fetched tempDir when the fetcher reports ownership.
264
+ // Tests that inject a pre-populated source tree set `owned: false`.
265
+ if (fetched.owned) {
266
+ try {
267
+ this.deps.rmSync?.(fetched.tempDir, { recursive: true, force: true });
268
+ }
269
+ catch { }
270
+ }
271
+ }
272
+ }
273
+ mkdirp(p) {
274
+ if (this.deps.mkdirSync)
275
+ this.deps.mkdirSync(p, { recursive: true });
276
+ else
277
+ fs.mkdirSync(p, { recursive: true });
278
+ }
279
+ /**
280
+ * Walk a directory tree and remove any file or directory whose basename
281
+ * starts with "doc-detective". Used before re-copying hooks/ or agents/ so
282
+ * we prune our own stale artifacts (files/dirs renamed or removed
283
+ * upstream) without touching unrelated user content living in the same
284
+ * directory.
285
+ */
286
+ pruneDocDetectiveFiles(dir) {
287
+ const rmSync = this.deps.rmSync ??
288
+ ((p, opts) => fs.rmSync(p, opts));
289
+ const entries = this.deps.readdirSync?.(dir) ?? [];
290
+ for (const name of entries) {
291
+ const full = path.join(dir, name);
292
+ if (name.startsWith("doc-detective")) {
293
+ rmSync(full, { recursive: true, force: true });
294
+ continue;
295
+ }
296
+ // Recurse into subdirectories to catch nested doc-detective-* files
297
+ // (e.g., hooks/scripts/doc-detective-before.js).
298
+ let isDir = false;
299
+ try {
300
+ isDir = fs.statSync(full).isDirectory();
301
+ }
302
+ catch { }
303
+ if (isDir)
304
+ this.pruneDocDetectiveFiles(full);
305
+ }
306
+ }
307
+ /**
308
+ * Recursive directory copy. Uses `this.deps.readdirSync` and
309
+ * `this.deps.writeFileSync` where the injected signatures match, but falls
310
+ * back to `fs.statSync` and buffer-returning `fs.readFileSync` directly —
311
+ * the `OpenCodeDeps.readFileSync` signature returns a string, so we can't
312
+ * use it here without losing binary content.
313
+ */
314
+ copyDir(src, dst) {
315
+ this.mkdirp(dst);
316
+ const entries = this.deps.readdirSync?.(src) ?? [];
317
+ for (const entry of entries) {
318
+ const from = path.join(src, entry);
319
+ const to = path.join(dst, entry);
320
+ const stat = fs.statSync(from);
321
+ if (stat.isDirectory()) {
322
+ this.copyDir(from, to);
323
+ }
324
+ else {
325
+ const buf = fs.readFileSync(from);
326
+ if (this.deps.writeFileSync)
327
+ this.deps.writeFileSync(to, buf);
328
+ else
329
+ fs.writeFileSync(to, buf);
330
+ // Preserve executable bits from the source so shell-script hooks
331
+ // keep working after install.
332
+ try {
333
+ fs.chmodSync(to, stat.mode);
334
+ }
335
+ catch { }
336
+ }
337
+ }
338
+ }
339
+ }
340
+ export const opencodeAdapter = new OpenCodeAdapter();
341
+ //# sourceMappingURL=opencode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../../src/agents/adapters/opencode.ts"],"names":[],"mappings":"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"}