@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":"openai-agents.js","sourceRoot":"","sources":["../../src/detect/openai-agents.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,YAAY;AACZ,gDAAgD;AAChD,oEAAoE;AACpE,EAAE;AACF,2EAA2E;AAC3E,sEAAsE;AAOtE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhE,MAAM,kBAAkB,GAAG,CAAC,gBAAgB,EAAE,eAAe,CAAU,CAAC;AAExE,MAAM,CAAC,MAAM,oBAAoB,GAAoB;IACnD,EAAE,EAAE,eAAe;IACnB,KAAK,EAAE,mBAAmB;IAE1B,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,36 @@
1
+ export interface DetectionContext {
2
+ /** Absolute path to the user project being installed into. */
3
+ cwd: string;
4
+ /** Absolute path to the user's home dir. */
5
+ home: string;
6
+ /** Node's `process.platform` — one of "win32" | "darwin" | "linux" | others. */
7
+ platform: NodeJS.Platform;
8
+ /** Environment snapshot — tests inject a fake one, runtime passes process.env. */
9
+ env: NodeJS.ProcessEnv;
10
+ }
11
+ export interface DetectionResult {
12
+ /** Stable harness id, e.g. "claude-code", "langgraph". */
13
+ harness: string;
14
+ /** Human-readable label for UI. */
15
+ label: string;
16
+ /** Whether the detector found evidence of the harness. */
17
+ detected: boolean;
18
+ /** If detected: where evidence was found (e.g. a config file path). */
19
+ evidence?: string[];
20
+ /** If not detected: one-line explanation. Never leaks secrets. */
21
+ reason?: string;
22
+ /**
23
+ * Config file(s) the installer would modify. May be present even when
24
+ * `detected` is false (e.g. "I could create this file if the user opts in").
25
+ */
26
+ configTargets?: string[];
27
+ }
28
+ export interface HarnessDetector {
29
+ /** Stable id used across commands and reports. */
30
+ readonly id: string;
31
+ /** UI label. */
32
+ readonly label: string;
33
+ /** Run the detection. Must be side-effect-free except for reads. */
34
+ detect(ctx: DetectionContext): Promise<DetectionResult>;
35
+ }
36
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/detect/types.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,GAAG,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,kFAAkF;IAClF,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,QAAQ,EAAE,OAAO,CAAC;IAClB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,kDAAkD;IAClD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,gBAAgB;IAChB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,oEAAoE;IACpE,MAAM,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACzD"}
@@ -0,0 +1,8 @@
1
+ // Shared types for harness detectors.
2
+ //
3
+ // Each detector is a pure function that inspects the filesystem (and optionally
4
+ // the current working directory) and reports whether it believes its harness
5
+ // is installed. Detectors must NOT mutate state and must NOT throw — any error
6
+ // becomes `{ detected: false, reason: "<error message>" }`.
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/detect/types.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,gFAAgF;AAChF,6EAA6E;AAC7E,+EAA+E;AAC/E,4DAA4D"}
@@ -0,0 +1,22 @@
1
+ export declare const IDENTITY_FORMAT: "ed25519-b64url";
2
+ export interface StoredIdentity {
3
+ format: typeof IDENTITY_FORMAT;
4
+ publicKey: string;
5
+ secretKey: string;
6
+ createdAt: string;
7
+ }
8
+ export declare function generateKeyPair(): StoredIdentity;
9
+ export declare function loadIdentity(): Promise<StoredIdentity | null>;
10
+ export declare function saveIdentity(identity: StoredIdentity): Promise<void>;
11
+ /** Load the stored identity or generate + persist a new one. */
12
+ export declare function loadOrCreateIdentity(): Promise<StoredIdentity>;
13
+ /**
14
+ * Returns a base64url-encoded detached Ed25519 signature over `message`.
15
+ * Used by the MCP client's challenge-response loop: the message format is
16
+ * `${agentId}:${action}:${timestamp}` — the server echoes that envelope and
17
+ * verifies with the stored public key it saw at acp_register time.
18
+ */
19
+ export declare function signMessage(message: string, identity: StoredIdentity): string;
20
+ /** For tests — verify a signature round-tripped by this module. */
21
+ export declare function verifySignature(message: string, signature: string, publicKey: string): boolean;
22
+ //# sourceMappingURL=keypair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keypair.d.ts","sourceRoot":"","sources":["../../src/identity/keypair.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,eAAe,EAAG,gBAAyB,CAAC;AAEzD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,eAAe,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAeD,wBAAgB,eAAe,IAAI,cAAc,CAQhD;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAUnE;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E;AAED,gEAAgE;AAChE,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,cAAc,CAAC,CAMpE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,CAK7E;AAED,mEAAmE;AACnE,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAST"}
@@ -0,0 +1,85 @@
1
+ // Local Ed25519 identity for challenge-response auto-signing.
2
+ //
3
+ // Implementation choice: tweetnacl + tweetnacl-util.
4
+ // Rationale: Ed25519 has been in Node's native `crypto` since v16, but the
5
+ // KeyObject-based API is awkward for signing raw bytes and returning a
6
+ // base64url-encoded signature. tweetnacl gives us a single-call
7
+ // `nacl.sign.detached(msg, secretKey)` that matches the server's verifier
8
+ // (which uses `nacl-verify` from the same family). If we ever need FIPS
9
+ // compliance we swap to the node crypto path — isolated behind signMessage.
10
+ import { promises as fs } from "node:fs";
11
+ import nacl from "tweetnacl";
12
+ import naclUtil from "tweetnacl-util";
13
+ import { identityFilePath, writeSecureJson } from "../auth/paths.js";
14
+ export const IDENTITY_FORMAT = "ed25519-b64url";
15
+ function b64urlEncode(bytes) {
16
+ // tweetnacl-util gives standard base64; convert to base64url.
17
+ const b64 = naclUtil.encodeBase64(bytes);
18
+ return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
19
+ }
20
+ function b64urlDecode(s) {
21
+ const padded = s.replace(/-/g, "+").replace(/_/g, "/");
22
+ const rem = padded.length % 4;
23
+ const full = rem ? padded + "=".repeat(4 - rem) : padded;
24
+ return naclUtil.decodeBase64(full);
25
+ }
26
+ export function generateKeyPair() {
27
+ const kp = nacl.sign.keyPair();
28
+ return {
29
+ format: IDENTITY_FORMAT,
30
+ publicKey: b64urlEncode(kp.publicKey),
31
+ secretKey: b64urlEncode(kp.secretKey),
32
+ createdAt: new Date().toISOString(),
33
+ };
34
+ }
35
+ export async function loadIdentity() {
36
+ try {
37
+ const raw = await fs.readFile(identityFilePath(), "utf8");
38
+ const parsed = JSON.parse(raw);
39
+ if (parsed.format !== IDENTITY_FORMAT)
40
+ return null;
41
+ if (!parsed.publicKey || !parsed.secretKey)
42
+ return null;
43
+ return parsed;
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ }
49
+ export async function saveIdentity(identity) {
50
+ await writeSecureJson(identityFilePath(), identity);
51
+ }
52
+ /** Load the stored identity or generate + persist a new one. */
53
+ export async function loadOrCreateIdentity() {
54
+ const existing = await loadIdentity();
55
+ if (existing)
56
+ return existing;
57
+ const fresh = generateKeyPair();
58
+ await saveIdentity(fresh);
59
+ return fresh;
60
+ }
61
+ /**
62
+ * Returns a base64url-encoded detached Ed25519 signature over `message`.
63
+ * Used by the MCP client's challenge-response loop: the message format is
64
+ * `${agentId}:${action}:${timestamp}` — the server echoes that envelope and
65
+ * verifies with the stored public key it saw at acp_register time.
66
+ */
67
+ export function signMessage(message, identity) {
68
+ const msgBytes = naclUtil.decodeUTF8(message);
69
+ const secret = b64urlDecode(identity.secretKey);
70
+ const sig = nacl.sign.detached(msgBytes, secret);
71
+ return b64urlEncode(sig);
72
+ }
73
+ /** For tests — verify a signature round-tripped by this module. */
74
+ export function verifySignature(message, signature, publicKey) {
75
+ try {
76
+ const msgBytes = naclUtil.decodeUTF8(message);
77
+ const sigBytes = b64urlDecode(signature);
78
+ const pkBytes = b64urlDecode(publicKey);
79
+ return nacl.sign.detached.verify(msgBytes, sigBytes, pkBytes);
80
+ }
81
+ catch {
82
+ return false;
83
+ }
84
+ }
85
+ //# sourceMappingURL=keypair.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keypair.js","sourceRoot":"","sources":["../../src/identity/keypair.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+ // @acprompt/join — CLI entry.
3
+ //
4
+ // Sub-commands:
5
+ // install interactive: detect -> auth -> write config -> verify
6
+ // detect print the harness detection report
7
+ // verify ping the MCP endpoint with the stored token
8
+ // whoami show the stored owner + identity public key
9
+ import { Command } from "commander";
10
+ import { runDetect } from "./commands/detect.js";
11
+ import { runInstall } from "./commands/install.js";
12
+ import { runVerify } from "./commands/verify.js";
13
+ import { runWhoami } from "./commands/whoami.js";
14
+ const program = new Command();
15
+ program
16
+ .name("acprompt-join")
17
+ .description("Smart installer for ACPrompt — wire any agent harness into the ACPrompt network via MCP.")
18
+ .version("0.0.1");
19
+ program
20
+ .command("install")
21
+ .description("Interactive: detect harness, mint token, write config, verify.")
22
+ .action(async () => {
23
+ await runInstall();
24
+ });
25
+ program
26
+ .command("detect")
27
+ .description("Print the harness detection report for the current project.")
28
+ .action(async () => {
29
+ await runDetect();
30
+ });
31
+ program
32
+ .command("verify")
33
+ .description("Ping the ACPrompt MCP endpoint with the stored token.")
34
+ .action(async () => {
35
+ await runVerify();
36
+ });
37
+ program
38
+ .command("whoami")
39
+ .description("Show the stored owner + local identity public key.")
40
+ .action(async () => {
41
+ await runWhoami();
42
+ });
43
+ // Default to `install` when no sub-command is passed.
44
+ if (process.argv.length <= 2) {
45
+ runInstall().catch((err) => {
46
+ console.error(err.message);
47
+ process.exit(1);
48
+ });
49
+ }
50
+ else {
51
+ program.parseAsync(process.argv).catch((err) => {
52
+ console.error(err.message);
53
+ process.exit(1);
54
+ });
55
+ }
56
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,8BAA8B;AAC9B,EAAE;AACF,gBAAgB;AAChB,mEAAmE;AACnE,gDAAgD;AAChD,yDAAyD;AACzD,yDAAyD;AAEzD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,eAAe,CAAC;KACrB,WAAW,CAAC,0FAA0F,CAAC;KACvG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,gEAAgE,CAAC;KAC7E,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,UAAU,EAAE,CAAC;AACrB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,6DAA6D,CAAC;KAC1E,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,SAAS,EAAE,CAAC;AACpB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,SAAS,EAAE,CAAC;AACpB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,oDAAoD,CAAC;KACjE,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,SAAS,EAAE,CAAC;AACpB,CAAC,CAAC,CAAC;AAEL,sDAAsD;AACtD,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;IAC7B,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;QAChC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;QACpD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,18 @@
1
+ export interface CallToolOptions {
2
+ /** Timeout for the tool call in ms. Default 30s. */
3
+ timeoutMs?: number;
4
+ /** Whether to retry with a signature on needs_signature=true. Default true. */
5
+ autoSign?: boolean;
6
+ }
7
+ export interface ToolCallResult {
8
+ content: unknown;
9
+ isError: boolean;
10
+ }
11
+ export declare function callTool(name: string, args?: Record<string, unknown>, opts?: CallToolOptions): Promise<ToolCallResult>;
12
+ /** Calls acp_register. Returns whatever the server hands back (agent row). */
13
+ export declare function register(args: {
14
+ name: string;
15
+ kind?: string;
16
+ public_key?: string;
17
+ }): Promise<ToolCallResult>;
18
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AA0CD,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAClC,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,cAAc,CAAC,CAwCzB;AAED,8EAA8E;AAC9E,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,cAAc,CAAC,CAE1B"}
@@ -0,0 +1,95 @@
1
+ // Thin MCP client wrapper for the ACPrompt endpoint.
2
+ //
3
+ // Responsibilities:
4
+ // - Auto-attach the stored owner token as a Bearer header.
5
+ // - Run the challenge-response loop: if a tool response comes back with
6
+ // `needs_signature: true`, auto-sign `${agentId}:${action}:${timestamp}`
7
+ // with the local identity and retry ONCE with the signature in the
8
+ // envelope.
9
+ // - Hand back JSON-parsed tool output.
10
+ //
11
+ // Uses the streamable-HTTP transport in stateless mode — every call is a
12
+ // fresh session, matching the ACPrompt server's expectation.
13
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
14
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
15
+ import { getToken } from "../auth/token-store.js";
16
+ import { loadOrCreateIdentity, signMessage } from "../identity/keypair.js";
17
+ const CLIENT_INFO = {
18
+ name: "acprompt-join",
19
+ version: "0.0.1",
20
+ };
21
+ function extractChallenge(content) {
22
+ // MCP returns `content: [{type:"text", text:"..."}, ...]`. The server
23
+ // serializes challenges as JSON text. We try the first text block.
24
+ if (!Array.isArray(content) || content.length === 0)
25
+ return null;
26
+ const first = content[0];
27
+ if (first?.type !== "text" || typeof first.text !== "string")
28
+ return null;
29
+ try {
30
+ const parsed = JSON.parse(first.text);
31
+ if (parsed && parsed.needs_signature === true)
32
+ return parsed;
33
+ return null;
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ async function connect() {
40
+ const stored = await getToken();
41
+ if (!stored) {
42
+ throw new Error("No ACPrompt token found. Run `acprompt-join install` first.");
43
+ }
44
+ const headers = {
45
+ Authorization: `Bearer ${stored.token}`,
46
+ };
47
+ const transport = new StreamableHTTPClientTransport(new URL(stored.mcpUrl), {
48
+ requestInit: { headers },
49
+ });
50
+ const client = new Client(CLIENT_INFO, { capabilities: {} });
51
+ await client.connect(transport);
52
+ return client;
53
+ }
54
+ export async function callTool(name, args = {}, opts = {}) {
55
+ const autoSign = opts.autoSign ?? true;
56
+ const client = await connect();
57
+ try {
58
+ const first = await client.callTool({ name, arguments: args });
59
+ const challenge = extractChallenge(first.content);
60
+ if (!challenge || !autoSign) {
61
+ return { content: first.content, isError: Boolean(first.isError) };
62
+ }
63
+ const { agent_id, action, timestamp } = challenge;
64
+ if (!agent_id || !action || timestamp === undefined) {
65
+ return { content: first.content, isError: Boolean(first.isError) };
66
+ }
67
+ const identity = await loadOrCreateIdentity();
68
+ const envelope = `${agent_id}:${action}:${timestamp}`;
69
+ const signature = signMessage(envelope, identity);
70
+ const retry = await client.callTool({
71
+ name,
72
+ arguments: {
73
+ ...args,
74
+ _sig: {
75
+ agent_id,
76
+ action,
77
+ timestamp,
78
+ signature,
79
+ public_key: identity.publicKey,
80
+ },
81
+ },
82
+ });
83
+ return { content: retry.content, isError: Boolean(retry.isError) };
84
+ }
85
+ finally {
86
+ await client.close().catch(() => {
87
+ // transport close errors are harmless
88
+ });
89
+ }
90
+ }
91
+ /** Calls acp_register. Returns whatever the server hands back (agent row). */
92
+ export async function register(args) {
93
+ return callTool("acp_register", args);
94
+ }
95
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@acprompt/join",
3
+ "version": "0.0.1",
4
+ "description": "Smart installer for ACPrompt — one-shot MCP config for any agent harness.",
5
+ "keywords": [
6
+ "acprompt",
7
+ "acp",
8
+ "mcp",
9
+ "agent",
10
+ "cli",
11
+ "installer"
12
+ ],
13
+ "homepage": "https://acprompt.com",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/ffffj-ai/acprompt-join.git"
17
+ },
18
+ "bugs": {
19
+ "url": "https://github.com/ffffj-ai/acprompt-join/issues"
20
+ },
21
+ "license": "MIT",
22
+ "author": "ACPrompt (https://acprompt.com)",
23
+ "type": "module",
24
+ "bin": {
25
+ "acprompt-join": "dist/index.js"
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "engines": {
33
+ "node": ">=20"
34
+ },
35
+ "scripts": {
36
+ "build": "tsc -p tsconfig.json",
37
+ "dev": "tsc -p tsconfig.json --watch",
38
+ "test": "vitest run",
39
+ "test:watch": "vitest",
40
+ "typecheck": "tsc -p tsconfig.json --noEmit",
41
+ "prepublishOnly": "npm run build"
42
+ },
43
+ "dependencies": {
44
+ "@inquirer/prompts": "^7.0.0",
45
+ "@modelcontextprotocol/sdk": "^1.0.0",
46
+ "commander": "^12.0.0",
47
+ "open": "^10.0.0",
48
+ "picocolors": "^1.0.0",
49
+ "tweetnacl": "^1.0.3",
50
+ "tweetnacl-util": "^0.15.1"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^22.0.0",
54
+ "typescript": "^5.6.0",
55
+ "vitest": "^2.1.0"
56
+ }
57
+ }