@acprompt/join 0.0.1

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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/auth/browser-flow.d.ts +25 -0
  4. package/dist/auth/browser-flow.d.ts.map +1 -0
  5. package/dist/auth/browser-flow.js +113 -0
  6. package/dist/auth/browser-flow.js.map +1 -0
  7. package/dist/auth/paths.d.ts +13 -0
  8. package/dist/auth/paths.d.ts.map +1 -0
  9. package/dist/auth/paths.js +47 -0
  10. package/dist/auth/paths.js.map +1 -0
  11. package/dist/auth/token-store.d.ts +18 -0
  12. package/dist/auth/token-store.d.ts.map +1 -0
  13. package/dist/auth/token-store.js +51 -0
  14. package/dist/auth/token-store.js.map +1 -0
  15. package/dist/commands/detect.d.ts +2 -0
  16. package/dist/commands/detect.d.ts.map +1 -0
  17. package/dist/commands/detect.js +31 -0
  18. package/dist/commands/detect.js.map +1 -0
  19. package/dist/commands/install.d.ts +2 -0
  20. package/dist/commands/install.d.ts.map +1 -0
  21. package/dist/commands/install.js +92 -0
  22. package/dist/commands/install.js.map +1 -0
  23. package/dist/commands/verify.d.ts +2 -0
  24. package/dist/commands/verify.d.ts.map +1 -0
  25. package/dist/commands/verify.js +41 -0
  26. package/dist/commands/verify.js.map +1 -0
  27. package/dist/commands/whoami.d.ts +2 -0
  28. package/dist/commands/whoami.d.ts.map +1 -0
  29. package/dist/commands/whoami.js +34 -0
  30. package/dist/commands/whoami.js.map +1 -0
  31. package/dist/detect/anthropic-sdk.d.ts +3 -0
  32. package/dist/detect/anthropic-sdk.d.ts.map +1 -0
  33. package/dist/detect/anthropic-sdk.js +49 -0
  34. package/dist/detect/anthropic-sdk.js.map +1 -0
  35. package/dist/detect/claude-code.d.ts +4 -0
  36. package/dist/detect/claude-code.d.ts.map +1 -0
  37. package/dist/detect/claude-code.js +86 -0
  38. package/dist/detect/claude-code.js.map +1 -0
  39. package/dist/detect/crewai.d.ts +3 -0
  40. package/dist/detect/crewai.d.ts.map +1 -0
  41. package/dist/detect/crewai.js +42 -0
  42. package/dist/detect/crewai.js.map +1 -0
  43. package/dist/detect/deps.d.ts +10 -0
  44. package/dist/detect/deps.d.ts.map +1 -0
  45. package/dist/detect/deps.js +107 -0
  46. package/dist/detect/deps.js.map +1 -0
  47. package/dist/detect/generic.d.ts +3 -0
  48. package/dist/detect/generic.d.ts.map +1 -0
  49. package/dist/detect/generic.js +24 -0
  50. package/dist/detect/generic.js.map +1 -0
  51. package/dist/detect/index.d.ts +5 -0
  52. package/dist/detect/index.d.ts.map +1 -0
  53. package/dist/detect/index.js +27 -0
  54. package/dist/detect/index.js.map +1 -0
  55. package/dist/detect/langgraph.d.ts +3 -0
  56. package/dist/detect/langgraph.d.ts.map +1 -0
  57. package/dist/detect/langgraph.js +43 -0
  58. package/dist/detect/langgraph.js.map +1 -0
  59. package/dist/detect/letta.d.ts +5 -0
  60. package/dist/detect/letta.d.ts.map +1 -0
  61. package/dist/detect/letta.js +73 -0
  62. package/dist/detect/letta.js.map +1 -0
  63. package/dist/detect/openai-agents.d.ts +3 -0
  64. package/dist/detect/openai-agents.d.ts.map +1 -0
  65. package/dist/detect/openai-agents.js +42 -0
  66. package/dist/detect/openai-agents.js.map +1 -0
  67. package/dist/detect/types.d.ts +36 -0
  68. package/dist/detect/types.d.ts.map +1 -0
  69. package/dist/detect/types.js +8 -0
  70. package/dist/detect/types.js.map +1 -0
  71. package/dist/identity/keypair.d.ts +22 -0
  72. package/dist/identity/keypair.d.ts.map +1 -0
  73. package/dist/identity/keypair.js +85 -0
  74. package/dist/identity/keypair.js.map +1 -0
  75. package/dist/index.d.ts +3 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +56 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/mcp/client.d.ts +18 -0
  80. package/dist/mcp/client.d.ts.map +1 -0
  81. package/dist/mcp/client.js +95 -0
  82. package/dist/mcp/client.js.map +1 -0
  83. package/package.json +57 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,6CAA6C;AAE7C,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpE,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;IAExE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,eAAe,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,eAAe,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,+CAA+C,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,eAAe,gBAAgB,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,8DAA8D,CAAC,CAAC,CAAC;IACzF,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { HarnessDetector } from "./types.js";
2
+ export declare const anthropicSdkDetector: HarnessDetector;
3
+ //# sourceMappingURL=anthropic-sdk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-sdk.d.ts","sourceRoot":"","sources":["../../src/detect/anthropic-sdk.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,YAAY,CAAC;AAKpB,eAAO,MAAM,oBAAoB,EAAE,eA8BlC,CAAC"}
@@ -0,0 +1,49 @@
1
+ // Anthropic SDK harness detector.
2
+ //
3
+ // Coverage:
4
+ // * JS/TS: `@anthropic-ai/sdk` in package.json
5
+ // * Python: `anthropic` in pyproject.toml / requirements.txt
6
+ //
7
+ // Note the ordering constraint: the Claude Code / Desktop detector runs
8
+ // first in the registry. That detector fires when a native app is present
9
+ // OR the `claude` CLI is on PATH — but it does NOT inspect Python/Node
10
+ // manifests. So a user who only has the raw `anthropic` SDK in their repo
11
+ // will fall through to this detector, which is the intended behavior.
12
+ //
13
+ // Config surface: in-code. The SDK's MCP integration (`mcp_servers`
14
+ // parameter on `messages.create` + the MCP connector) is wired in code, not
15
+ // through a central config file, so the installer emits a snippet.
16
+ import { findDependency, evidenceFromMatches } from "./deps.js";
17
+ const ANTHROPIC_SDK_DEPS = ["@anthropic-ai/sdk", "anthropic"];
18
+ export const anthropicSdkDetector = {
19
+ id: "anthropic-sdk",
20
+ label: "Anthropic SDK",
21
+ async detect(ctx) {
22
+ try {
23
+ const matches = await findDependency(ctx, ANTHROPIC_SDK_DEPS);
24
+ if (matches.length === 0) {
25
+ return {
26
+ harness: this.id,
27
+ label: this.label,
28
+ detected: false,
29
+ reason: "No anthropic SDK dependency in package.json / pyproject.toml / requirements.txt.",
30
+ };
31
+ }
32
+ return {
33
+ harness: this.id,
34
+ label: this.label,
35
+ detected: true,
36
+ evidence: evidenceFromMatches(matches),
37
+ };
38
+ }
39
+ catch (e) {
40
+ return {
41
+ harness: this.id,
42
+ label: this.label,
43
+ detected: false,
44
+ reason: e.message,
45
+ };
46
+ }
47
+ },
48
+ };
49
+ //# sourceMappingURL=anthropic-sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-sdk.js","sourceRoot":"","sources":["../../src/detect/anthropic-sdk.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,EAAE;AACF,YAAY;AACZ,mDAAmD;AACnD,gEAAgE;AAChE,EAAE;AACF,wEAAwE;AACxE,0EAA0E;AAC1E,uEAAuE;AACvE,0EAA0E;AAC1E,sEAAsE;AACtE,EAAE;AACF,oEAAoE;AACpE,4EAA4E;AAC5E,mEAAmE;AAOnE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhE,MAAM,kBAAkB,GAAG,CAAC,mBAAmB,EAAE,WAAW,CAAU,CAAC;AAEvE,MAAM,CAAC,MAAM,oBAAoB,GAAoB;IACnD,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,eAAe;IAEtB,KAAK,CAAC,MAAM,CAAC,GAAqB;QAChC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;YAC9D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO;oBACL,OAAO,EAAE,IAAI,CAAC,EAAE;oBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,QAAQ,EAAE,KAAK;oBACf,MAAM,EAAE,kFAAkF;iBAC3F,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,OAAO,EAAE,IAAI,CAAC,EAAE;gBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,IAAI;gBACd,QAAQ,EAAE,mBAAmB,CAAC,OAAO,CAAC;aACvC,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,IAAI,CAAC,EAAE;gBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAG,CAAW,CAAC,OAAO;aAC7B,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { DetectionContext, HarnessDetector } from "./types.js";
2
+ export declare function claudeDesktopConfigPath(ctx: DetectionContext): string;
3
+ export declare const claudeCodeDetector: HarnessDetector;
4
+ //# sourceMappingURL=claude-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/detect/claude-code.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,gBAAgB,EAEhB,eAAe,EAChB,MAAM,YAAY,CAAC;AAIpB,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,CAiBrE;AAuBD,eAAO,MAAM,kBAAkB,EAAE,eAkChC,CAAC"}
@@ -0,0 +1,86 @@
1
+ // Claude Code / Claude Desktop harness detector.
2
+ //
3
+ // This detector covers two related-but-distinct targets:
4
+ // 1. Claude Desktop — the native app. Config at:
5
+ // win32: %APPDATA%\Claude\claude_desktop_config.json
6
+ // darwin: ~/Library/Application Support/Claude/claude_desktop_config.json
7
+ // linux: ~/.config/Claude/claude_desktop_config.json
8
+ // 2. Claude Code CLI — the terminal tool. Detected by presence of `claude`
9
+ // on PATH. Its MCP config lives under ~/.claude/ but the user-facing
10
+ // install flow uses `claude mcp add ...`, so we just need to know the
11
+ // CLI exists; we don't write its config directly.
12
+ //
13
+ // If either is present, we report `detected: true`. The `configTargets`
14
+ // array is set so the install command knows where to write for the desktop
15
+ // variant; the CLI variant's hint is surfaced separately as a shell command.
16
+ import { promises as fs } from "node:fs";
17
+ import path from "node:path";
18
+ import { execFile } from "node:child_process";
19
+ import { promisify } from "node:util";
20
+ const execFileAsync = promisify(execFile);
21
+ export function claudeDesktopConfigPath(ctx) {
22
+ if (ctx.platform === "win32") {
23
+ const appData = ctx.env.APPDATA ?? path.join(ctx.home, "AppData", "Roaming");
24
+ return path.join(appData, "Claude", "claude_desktop_config.json");
25
+ }
26
+ if (ctx.platform === "darwin") {
27
+ return path.join(ctx.home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
28
+ }
29
+ // linux + everything else
30
+ const xdgConfig = ctx.env.XDG_CONFIG_HOME ?? path.join(ctx.home, ".config");
31
+ return path.join(xdgConfig, "Claude", "claude_desktop_config.json");
32
+ }
33
+ async function fileExists(p) {
34
+ try {
35
+ await fs.access(p);
36
+ return true;
37
+ }
38
+ catch {
39
+ return false;
40
+ }
41
+ }
42
+ async function claudeCliOnPath(ctx) {
43
+ // `claude --version` is the cheapest way to confirm the CLI exists.
44
+ // Swallow every error — if it's not installed, the CLI simply isn't there.
45
+ const probe = ctx.platform === "win32" ? "claude.cmd" : "claude";
46
+ try {
47
+ await execFileAsync(probe, ["--version"], { timeout: 3000 });
48
+ return true;
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }
54
+ export const claudeCodeDetector = {
55
+ id: "claude-code",
56
+ label: "Claude Code / Claude Desktop",
57
+ async detect(ctx) {
58
+ const desktopConfig = claudeDesktopConfigPath(ctx);
59
+ const [desktopPresent, cliPresent] = await Promise.all([
60
+ fileExists(desktopConfig),
61
+ claudeCliOnPath(ctx),
62
+ ]);
63
+ const evidence = [];
64
+ if (desktopPresent)
65
+ evidence.push(`Claude Desktop config: ${desktopConfig}`);
66
+ if (cliPresent)
67
+ evidence.push("Claude Code CLI on PATH");
68
+ if (evidence.length === 0) {
69
+ return {
70
+ harness: this.id,
71
+ label: this.label,
72
+ detected: false,
73
+ reason: "No Claude Desktop config file found and `claude` CLI not on PATH.",
74
+ configTargets: [desktopConfig],
75
+ };
76
+ }
77
+ return {
78
+ harness: this.id,
79
+ label: this.label,
80
+ detected: true,
81
+ evidence,
82
+ configTargets: [desktopConfig],
83
+ };
84
+ },
85
+ };
86
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/detect/claude-code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { HarnessDetector } from "./types.js";
2
+ export declare const crewaiDetector: HarnessDetector;
3
+ //# sourceMappingURL=crewai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crewai.d.ts","sourceRoot":"","sources":["../../src/detect/crewai.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,YAAY,CAAC;AAKpB,eAAO,MAAM,cAAc,EAAE,eA8B5B,CAAC"}
@@ -0,0 +1,42 @@
1
+ // CrewAI harness detector.
2
+ //
3
+ // CrewAI is Python-only (as of 2026-04). We scan pyproject.toml / requirements.txt
4
+ // for `crewai` or the adjacent `crewai-tools` extension package — the latter
5
+ // is often the manifest line that actually declares the MCP-capable extras.
6
+ //
7
+ // Config surface: in-code. CrewAI doesn't have a central MCP registry;
8
+ // installer output is a snippet to paste into the Crew / Agent constructor.
9
+ import { findDependency, evidenceFromMatches } from "./deps.js";
10
+ const CREWAI_DEPS = ["crewai", "crewai-tools"];
11
+ export const crewaiDetector = {
12
+ id: "crewai",
13
+ label: "CrewAI",
14
+ async detect(ctx) {
15
+ try {
16
+ const matches = await findDependency(ctx, CREWAI_DEPS);
17
+ if (matches.length === 0) {
18
+ return {
19
+ harness: this.id,
20
+ label: this.label,
21
+ detected: false,
22
+ reason: "No crewai dependency in pyproject.toml / requirements.txt.",
23
+ };
24
+ }
25
+ return {
26
+ harness: this.id,
27
+ label: this.label,
28
+ detected: true,
29
+ evidence: evidenceFromMatches(matches),
30
+ };
31
+ }
32
+ catch (e) {
33
+ return {
34
+ harness: this.id,
35
+ label: this.label,
36
+ detected: false,
37
+ reason: e.message,
38
+ };
39
+ }
40
+ },
41
+ };
42
+ //# sourceMappingURL=crewai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crewai.js","sourceRoot":"","sources":["../../src/detect/crewai.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,EAAE;AACF,mFAAmF;AACnF,6EAA6E;AAC7E,4EAA4E;AAC5E,EAAE;AACF,uEAAuE;AACvE,4EAA4E;AAO5E,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhE,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,cAAc,CAAU,CAAC;AAExD,MAAM,CAAC,MAAM,cAAc,GAAoB;IAC7C,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,QAAQ;IAEf,KAAK,CAAC,MAAM,CAAC,GAAqB;QAChC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;YACvD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO;oBACL,OAAO,EAAE,IAAI,CAAC,EAAE;oBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,QAAQ,EAAE,KAAK;oBACf,MAAM,EAAE,4DAA4D;iBACrE,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,OAAO,EAAE,IAAI,CAAC,EAAE;gBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,IAAI;gBACd,QAAQ,EAAE,mBAAmB,CAAC,OAAO,CAAC;aACvC,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,IAAI,CAAC,EAAE;gBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAG,CAAW,CAAC,OAAO;aAC7B,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { DetectionContext } from "./types.js";
2
+ export interface DepMatch {
3
+ /** Path (relative to cwd) of the manifest that contained the match. */
4
+ file: string;
5
+ /** Which candidate name matched. */
6
+ name: string;
7
+ }
8
+ export declare function findDependency(ctx: DetectionContext, names: readonly string[]): Promise<DepMatch[]>;
9
+ export declare function evidenceFromMatches(matches: readonly DepMatch[]): string[];
10
+ //# sourceMappingURL=deps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../../src/detect/deps.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,QAAQ;IACvB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd;AAgGD,wBAAsB,cAAc,CAClC,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAOrB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,EAAE,CAE1E"}
@@ -0,0 +1,107 @@
1
+ // Shared dependency scanner used by language-framework detectors
2
+ // (LangGraph, CrewAI, OpenAI Agents SDK, Anthropic SDK, Letta).
3
+ //
4
+ // Scans the three manifest files commonly found at a project root:
5
+ // - package.json (Node/TS projects; dependencies + devDependencies +
6
+ // peerDependencies + optionalDependencies)
7
+ // - pyproject.toml (PEP 621 and Poetry-style Python projects, scanned
8
+ // textually so we don't pull in a TOML parser)
9
+ // - requirements.txt (pip-style Python projects)
10
+ //
11
+ // The scan is deliberately lenient. Over-detecting is cheap: the installer
12
+ // asks the user to confirm before writing any config. Under-detecting means
13
+ // a real user's harness slips through to the generic fallback, which is
14
+ // worse UX.
15
+ import { promises as fs } from "node:fs";
16
+ import path from "node:path";
17
+ async function readFileIfExists(p) {
18
+ try {
19
+ return await fs.readFile(p, "utf8");
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
25
+ function escapeRegex(s) {
26
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
27
+ }
28
+ async function scanPackageJson(cwd, names) {
29
+ const raw = await readFileIfExists(path.join(cwd, "package.json"));
30
+ if (!raw)
31
+ return [];
32
+ let parsed;
33
+ try {
34
+ parsed = JSON.parse(raw);
35
+ }
36
+ catch {
37
+ return [];
38
+ }
39
+ const buckets = [
40
+ "dependencies",
41
+ "devDependencies",
42
+ "peerDependencies",
43
+ "optionalDependencies",
44
+ ];
45
+ const all = {};
46
+ for (const k of buckets) {
47
+ const v = parsed[k];
48
+ if (v && typeof v === "object") {
49
+ Object.assign(all, v);
50
+ }
51
+ }
52
+ const matches = [];
53
+ for (const n of names) {
54
+ if (Object.prototype.hasOwnProperty.call(all, n)) {
55
+ matches.push({ file: "package.json", name: n });
56
+ }
57
+ }
58
+ return matches;
59
+ }
60
+ async function scanPyproject(cwd, names) {
61
+ const raw = await readFileIfExists(path.join(cwd, "pyproject.toml"));
62
+ if (!raw)
63
+ return [];
64
+ const matches = [];
65
+ for (const n of names) {
66
+ // Accept the package name when it appears:
67
+ // * as a bare TOML key: name = "..."
68
+ // * inside a quoted PEP 508 spec: "name", "name>=1", "name ; python_version"
69
+ // Prefix char: start-of-line, whitespace, or a quote/bracket/comma/equals.
70
+ // Suffix char: version operator, quote, comma, or bracket — NOT a raw
71
+ // space or letter (that ruled out false positives like "a langgraph tool").
72
+ const re = new RegExp(`(^|[\\s"'\\[,=])${escapeRegex(n)}(\\s*[=<>~!^]|["',\\]])`, "m");
73
+ if (re.test(raw)) {
74
+ matches.push({ file: "pyproject.toml", name: n });
75
+ }
76
+ }
77
+ return matches;
78
+ }
79
+ async function scanRequirementsTxt(cwd, names) {
80
+ const raw = await readFileIfExists(path.join(cwd, "requirements.txt"));
81
+ if (!raw)
82
+ return [];
83
+ const lines = raw
84
+ .split(/\r?\n/)
85
+ .map((l) => (l.split("#")[0] ?? "").trim())
86
+ .filter((l) => l.length > 0);
87
+ const matches = [];
88
+ for (const n of names) {
89
+ const re = new RegExp(`^${escapeRegex(n)}(\\s*[\\[=<>~!]|\\s*$)`, "i");
90
+ if (lines.some((l) => re.test(l))) {
91
+ matches.push({ file: "requirements.txt", name: n });
92
+ }
93
+ }
94
+ return matches;
95
+ }
96
+ export async function findDependency(ctx, names) {
97
+ const [pkg, py, req] = await Promise.all([
98
+ scanPackageJson(ctx.cwd, names),
99
+ scanPyproject(ctx.cwd, names),
100
+ scanRequirementsTxt(ctx.cwd, names),
101
+ ]);
102
+ return [...pkg, ...py, ...req];
103
+ }
104
+ export function evidenceFromMatches(matches) {
105
+ return matches.map((m) => `${m.file}: ${m.name}`);
106
+ }
107
+ //# sourceMappingURL=deps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deps.js","sourceRoot":"","sources":["../../src/detect/deps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { HarnessDetector } from "./types.js";
2
+ export declare const genericDetector: HarnessDetector;
3
+ //# sourceMappingURL=generic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../src/detect/generic.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,eAAe,EAAE,eAY7B,CAAC"}
@@ -0,0 +1,24 @@
1
+ // Generic fallback detector.
2
+ //
3
+ // ALWAYS reports detected. The registry in `src/detect/index.ts` puts this
4
+ // detector last; callers that use `detections.find((d) => d.detected)` will
5
+ // only land on this one if every specific detector missed, in which case
6
+ // the installer prints the manual MCP snippet (URL + bearer header) for the
7
+ // user to wire in themselves.
8
+ //
9
+ // There is no `configTargets` — the user pastes the snippet wherever their
10
+ // harness expects MCP server configuration. `evidence` flags that no other
11
+ // harness matched, so this is a last-resort match rather than a confident one.
12
+ export const genericDetector = {
13
+ id: "generic",
14
+ label: "Generic (manual MCP config)",
15
+ async detect(_ctx) {
16
+ return {
17
+ harness: this.id,
18
+ label: this.label,
19
+ detected: true,
20
+ evidence: ["No specific harness matched — manual MCP snippet will be printed."],
21
+ };
22
+ },
23
+ };
24
+ //# sourceMappingURL=generic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/detect/generic.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,yEAAyE;AACzE,4EAA4E;AAC5E,8BAA8B;AAC9B,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,+EAA+E;AAQ/E,MAAM,CAAC,MAAM,eAAe,GAAoB;IAC9C,EAAE,EAAE,SAAS;IACb,KAAK,EAAE,6BAA6B;IAEpC,KAAK,CAAC,MAAM,CAAC,IAAsB;QACjC,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,EAAE;YAChB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,CAAC,mEAAmE,CAAC;SAChF,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { DetectionContext, HarnessDetector } from "./types.js";
2
+ export declare const ALL_DETECTORS: readonly HarnessDetector[];
3
+ export declare function currentContext(): DetectionContext;
4
+ export type { DetectionContext, DetectionResult, HarnessDetector } from "./types.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/detect/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AASpE,eAAO,MAAM,aAAa,EAAE,SAAS,eAAe,EAQnD,CAAC;AAEF,wBAAgB,cAAc,IAAI,gBAAgB,CAOjD;AAED,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,27 @@
1
+ // Detector registry. Order matters: more specific first, `generic` last.
2
+ import os from "node:os";
3
+ import { claudeCodeDetector } from "./claude-code.js";
4
+ import { langgraphDetector } from "./langgraph.js";
5
+ import { crewaiDetector } from "./crewai.js";
6
+ import { openaiAgentsDetector } from "./openai-agents.js";
7
+ import { anthropicSdkDetector } from "./anthropic-sdk.js";
8
+ import { lettaDetector } from "./letta.js";
9
+ import { genericDetector } from "./generic.js";
10
+ export const ALL_DETECTORS = [
11
+ claudeCodeDetector,
12
+ langgraphDetector,
13
+ crewaiDetector,
14
+ openaiAgentsDetector,
15
+ anthropicSdkDetector,
16
+ lettaDetector,
17
+ genericDetector,
18
+ ];
19
+ export function currentContext() {
20
+ return {
21
+ cwd: process.cwd(),
22
+ home: os.homedir(),
23
+ platform: process.platform,
24
+ env: process.env,
25
+ };
26
+ }
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/detect/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AAEzE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,MAAM,aAAa,GAA+B;IACvD,kBAAkB;IAClB,iBAAiB;IACjB,cAAc;IACd,oBAAoB;IACpB,oBAAoB;IACpB,aAAa;IACb,eAAe;CAChB,CAAC;AAEF,MAAM,UAAU,cAAc;IAC5B,OAAO;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE;QAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { HarnessDetector } from "./types.js";
2
+ export declare const langgraphDetector: HarnessDetector;
3
+ //# sourceMappingURL=langgraph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"langgraph.d.ts","sourceRoot":"","sources":["../../src/detect/langgraph.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,YAAY,CAAC;AAKpB,eAAO,MAAM,iBAAiB,EAAE,eA8B/B,CAAC"}
@@ -0,0 +1,43 @@
1
+ // LangGraph harness detector.
2
+ //
3
+ // Coverage:
4
+ // * Python: `langgraph` in pyproject.toml or requirements.txt
5
+ // * JS/TS: `@langchain/langgraph` in package.json
6
+ //
7
+ // Config surface: ambient — LangGraph has no central MCP config file, so the
8
+ // installer prints a code snippet for the user to paste into their graph
9
+ // builder (Week 3 work). We only populate `evidence` here.
10
+ import { findDependency, evidenceFromMatches } from "./deps.js";
11
+ const LANGGRAPH_DEPS = ["langgraph", "@langchain/langgraph"];
12
+ export const langgraphDetector = {
13
+ id: "langgraph",
14
+ label: "LangGraph",
15
+ async detect(ctx) {
16
+ try {
17
+ const matches = await findDependency(ctx, LANGGRAPH_DEPS);
18
+ if (matches.length === 0) {
19
+ return {
20
+ harness: this.id,
21
+ label: this.label,
22
+ detected: false,
23
+ reason: "No langgraph dependency in package.json / pyproject.toml / requirements.txt.",
24
+ };
25
+ }
26
+ return {
27
+ harness: this.id,
28
+ label: this.label,
29
+ detected: true,
30
+ evidence: evidenceFromMatches(matches),
31
+ };
32
+ }
33
+ catch (e) {
34
+ return {
35
+ harness: this.id,
36
+ label: this.label,
37
+ detected: false,
38
+ reason: e.message,
39
+ };
40
+ }
41
+ },
42
+ };
43
+ //# sourceMappingURL=langgraph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"langgraph.js","sourceRoot":"","sources":["../../src/detect/langgraph.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,YAAY;AACZ,kEAAkE;AAClE,uDAAuD;AACvD,EAAE;AACF,6EAA6E;AAC7E,yEAAyE;AACzE,2DAA2D;AAO3D,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhE,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,sBAAsB,CAAU,CAAC;AAEtE,MAAM,CAAC,MAAM,iBAAiB,GAAoB;IAChD,EAAE,EAAE,WAAW;IACf,KAAK,EAAE,WAAW;IAElB,KAAK,CAAC,MAAM,CAAC,GAAqB;QAChC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YAC1D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO;oBACL,OAAO,EAAE,IAAI,CAAC,EAAE;oBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,QAAQ,EAAE,KAAK;oBACf,MAAM,EAAE,8EAA8E;iBACvF,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,OAAO,EAAE,IAAI,CAAC,EAAE;gBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,IAAI;gBACd,QAAQ,EAAE,mBAAmB,CAAC,OAAO,CAAC;aACvC,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,IAAI,CAAC,EAAE;gBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAG,CAAW,CAAC,OAAO;aAC7B,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { DetectionContext, HarnessDetector } from "./types.js";
2
+ export declare function lettaHomeDir(ctx: DetectionContext): string;
3
+ export declare function lettaMcpConfigPath(ctx: DetectionContext): string;
4
+ export declare const lettaDetector: HarnessDetector;
5
+ //# sourceMappingURL=letta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"letta.d.ts","sourceRoot":"","sources":["../../src/detect/letta.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,gBAAgB,EAEhB,eAAe,EAChB,MAAM,YAAY,CAAC;AAKpB,wBAAgB,YAAY,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,CAE1D;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,CAEhE;AAWD,eAAO,MAAM,aAAa,EAAE,eA0C3B,CAAC"}
@@ -0,0 +1,73 @@
1
+ // Letta harness detector.
2
+ //
3
+ // Letta is a Python-based stateful-agent platform. Two independent evidence
4
+ // sources:
5
+ // 1. `letta` dependency in pyproject.toml / requirements.txt (the user is
6
+ // building WITH Letta).
7
+ // 2. `~/.letta/` directory present (the user has already run the Letta
8
+ // server at least once, which creates this dir with config + state).
9
+ //
10
+ // Either signal is enough to report detected. The configTarget points at
11
+ // `~/.letta/mcp_config.json` — Letta's MCP-server registry file. Writing
12
+ // that file is Week-3 work; for now we only expose the path.
13
+ import { promises as fs } from "node:fs";
14
+ import path from "node:path";
15
+ import { findDependency, evidenceFromMatches } from "./deps.js";
16
+ const LETTA_DEPS = ["letta", "pyletta"];
17
+ export function lettaHomeDir(ctx) {
18
+ return path.join(ctx.home, ".letta");
19
+ }
20
+ export function lettaMcpConfigPath(ctx) {
21
+ return path.join(lettaHomeDir(ctx), "mcp_config.json");
22
+ }
23
+ async function dirExists(p) {
24
+ try {
25
+ const s = await fs.stat(p);
26
+ return s.isDirectory();
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ export const lettaDetector = {
33
+ id: "letta",
34
+ label: "Letta",
35
+ async detect(ctx) {
36
+ const configTarget = lettaMcpConfigPath(ctx);
37
+ try {
38
+ const [depMatches, homePresent] = await Promise.all([
39
+ findDependency(ctx, LETTA_DEPS),
40
+ dirExists(lettaHomeDir(ctx)),
41
+ ]);
42
+ const evidence = evidenceFromMatches(depMatches);
43
+ if (homePresent)
44
+ evidence.push(`Letta home dir: ${lettaHomeDir(ctx)}`);
45
+ if (evidence.length === 0) {
46
+ return {
47
+ harness: this.id,
48
+ label: this.label,
49
+ detected: false,
50
+ reason: "No letta dependency and no ~/.letta/ directory.",
51
+ configTargets: [configTarget],
52
+ };
53
+ }
54
+ return {
55
+ harness: this.id,
56
+ label: this.label,
57
+ detected: true,
58
+ evidence,
59
+ configTargets: [configTarget],
60
+ };
61
+ }
62
+ catch (e) {
63
+ return {
64
+ harness: this.id,
65
+ label: this.label,
66
+ detected: false,
67
+ reason: e.message,
68
+ configTargets: [configTarget],
69
+ };
70
+ }
71
+ },
72
+ };
73
+ //# sourceMappingURL=letta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"letta.js","sourceRoot":"","sources":["../../src/detect/letta.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,EAAE;AACF,4EAA4E;AAC5E,WAAW;AACX,4EAA4E;AAC5E,6BAA6B;AAC7B,yEAAyE;AACzE,0EAA0E;AAC1E,EAAE;AACF,yEAAyE;AACzE,yEAAyE;AACzE,6DAA6D;AAE7D,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAM7B,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhE,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,SAAS,CAAU,CAAC;AAEjD,MAAM,UAAU,YAAY,CAAC,GAAqB;IAChD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAqB;IACtD,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,iBAAiB,CAAC,CAAC;AACzD,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,CAAS;IAChC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAoB;IAC5C,EAAE,EAAE,OAAO;IACX,KAAK,EAAE,OAAO;IAEd,KAAK,CAAC,MAAM,CAAC,GAAqB;QAChC,MAAM,YAAY,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAClD,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC;gBAC/B,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;aAC7B,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;YACjD,IAAI,WAAW;gBAAE,QAAQ,CAAC,IAAI,CAAC,mBAAmB,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEvE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO;oBACL,OAAO,EAAE,IAAI,CAAC,EAAE;oBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,QAAQ,EAAE,KAAK;oBACf,MAAM,EAAE,iDAAiD;oBACzD,aAAa,EAAE,CAAC,YAAY,CAAC;iBAC9B,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,IAAI,CAAC,EAAE;gBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,IAAI;gBACd,QAAQ;gBACR,aAAa,EAAE,CAAC,YAAY,CAAC;aAC9B,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,IAAI,CAAC,EAAE;gBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAG,CAAW,CAAC,OAAO;gBAC5B,aAAa,EAAE,CAAC,YAAY,CAAC;aAC9B,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { HarnessDetector } from "./types.js";
2
+ export declare const openaiAgentsDetector: HarnessDetector;
3
+ //# sourceMappingURL=openai-agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-agents.d.ts","sourceRoot":"","sources":["../../src/detect/openai-agents.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,YAAY,CAAC;AAKpB,eAAO,MAAM,oBAAoB,EAAE,eA8BlC,CAAC"}
@@ -0,0 +1,42 @@
1
+ // OpenAI Agents SDK harness detector.
2
+ //
3
+ // Coverage:
4
+ // * JS/TS: `@openai/agents` in package.json
5
+ // * Python: `openai-agents` in pyproject.toml / requirements.txt
6
+ //
7
+ // Config surface: in-code (`new Agent({ tools: [...] })`). Installer emits
8
+ // a snippet that registers the ACPrompt MCP server against the agent.
9
+ import { findDependency, evidenceFromMatches } from "./deps.js";
10
+ const OPENAI_AGENTS_DEPS = ["@openai/agents", "openai-agents"];
11
+ export const openaiAgentsDetector = {
12
+ id: "openai-agents",
13
+ label: "OpenAI Agents SDK",
14
+ async detect(ctx) {
15
+ try {
16
+ const matches = await findDependency(ctx, OPENAI_AGENTS_DEPS);
17
+ if (matches.length === 0) {
18
+ return {
19
+ harness: this.id,
20
+ label: this.label,
21
+ detected: false,
22
+ reason: "No openai-agents dependency in package.json / pyproject.toml / requirements.txt.",
23
+ };
24
+ }
25
+ return {
26
+ harness: this.id,
27
+ label: this.label,
28
+ detected: true,
29
+ evidence: evidenceFromMatches(matches),
30
+ };
31
+ }
32
+ catch (e) {
33
+ return {
34
+ harness: this.id,
35
+ label: this.label,
36
+ detected: false,
37
+ reason: e.message,
38
+ };
39
+ }
40
+ },
41
+ };
42
+ //# sourceMappingURL=openai-agents.js.map