@automatalabs/acp-agents 0.21.2 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/acp-client.d.ts +51 -0
  2. package/dist/acp-client.d.ts.map +1 -1
  3. package/dist/acp-client.js +127 -2
  4. package/dist/auth/auth-profiles.d.ts +63 -0
  5. package/dist/auth/auth-profiles.d.ts.map +1 -0
  6. package/dist/auth/auth-profiles.js +45 -0
  7. package/dist/auth/auth-store.d.ts +112 -0
  8. package/dist/auth/auth-store.d.ts.map +1 -0
  9. package/dist/auth/auth-store.js +186 -0
  10. package/dist/auth/auth-types.d.ts +93 -0
  11. package/dist/auth/auth-types.d.ts.map +1 -0
  12. package/dist/auth/auth-types.js +108 -0
  13. package/dist/backend.d.ts +7 -0
  14. package/dist/backend.d.ts.map +1 -1
  15. package/dist/backends/claude.d.ts +2 -0
  16. package/dist/backends/claude.d.ts.map +1 -1
  17. package/dist/backends/claude.js +3 -0
  18. package/dist/backends/codex.d.ts +3 -0
  19. package/dist/backends/codex.d.ts.map +1 -1
  20. package/dist/backends/codex.js +4 -0
  21. package/dist/backends/opencode.d.ts +2 -0
  22. package/dist/backends/opencode.d.ts.map +1 -1
  23. package/dist/backends/opencode.js +3 -0
  24. package/dist/capabilities.d.ts +7 -1
  25. package/dist/capabilities.d.ts.map +1 -1
  26. package/dist/capabilities.js +17 -0
  27. package/dist/client-handlers.d.ts +9 -0
  28. package/dist/client-handlers.d.ts.map +1 -1
  29. package/dist/client-handlers.js +17 -0
  30. package/dist/errors-map.d.ts.map +1 -1
  31. package/dist/errors-map.js +26 -2
  32. package/dist/index.d.ts +11 -5
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +8 -2
  35. package/dist/permissions.d.ts +27 -0
  36. package/dist/permissions.d.ts.map +1 -1
  37. package/dist/permissions.js +23 -1
  38. package/dist/pool.d.ts +20 -0
  39. package/dist/pool.d.ts.map +1 -1
  40. package/dist/pool.js +58 -16
  41. package/dist/protocol-coverage.d.ts +75 -0
  42. package/dist/protocol-coverage.d.ts.map +1 -1
  43. package/dist/protocol-coverage.js +58 -0
  44. package/dist/runner.d.ts +120 -3
  45. package/dist/runner.d.ts.map +1 -1
  46. package/dist/runner.js +307 -20
  47. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"errors-map.d.ts","sourceRoot":"","sources":["../src/errors-map.ts"],"names":[],"mappings":"AAYA,OAAO,EAA0C,aAAa,EAAqB,MAAM,4BAA4B,CAAC;AACtH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,eAAO,MAAM,4BAA4B,SAAS,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CACrC;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAahD;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,aAAa,CA4BvG"}
1
+ {"version":3,"file":"errors-map.d.ts","sourceRoot":"","sources":["../src/errors-map.ts"],"names":[],"mappings":"AAYA,OAAO,EAA0C,aAAa,EAAqB,MAAM,4BAA4B,CAAC;AAEtH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,eAAO,MAAM,4BAA4B,SAAS,CAAC;AAQnD,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CACrC;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAahD;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,aAAa,CAsCvG"}
@@ -12,6 +12,11 @@
12
12
  // AGENT_EMPTY_OUTPUT) pass through unchanged.
13
13
  import { classifyProviderLimit, isWorkflowError, WorkflowError, WorkflowErrorCode } from "@automatalabs/shared-types";
14
14
  export const ACP_AUTH_REQUIRED_ERROR_CODE = -32000;
15
+ // JSON-RPC codes the SDK reserves for NON-auth failures (jsonrpc.js:764-829). A different reserved
16
+ // code that merely mentions the auth phrase must NEVER mis-route to pause-for-auth. -32000 is
17
+ // deliberately EXCLUDED — it is the primary auth code (reserved exclusively for authRequired,
18
+ // jsonrpc.js:818-823) and is matched code-only above the fallback.
19
+ const OTHER_RESERVED = new Set([-32700, -32600, -32601, -32602, -32603, -32800, -32002]);
15
20
  export function errorText(error) {
16
21
  if (error instanceof Error)
17
22
  return error.message;
@@ -38,9 +43,19 @@ export function mapThrownError(error, labelOrContext) {
38
43
  const context = typeof labelOrContext === "string" ? { label: labelOrContext } : (labelOrContext ?? {});
39
44
  const message = errorText(error);
40
45
  if (isAcpAuthRequired(error, message)) {
46
+ // authContext sources ONLY agent-advertised AuthMethod fields (ids/types/names) — never our
47
+ // sent _meta/env values (Principle 9). This is the machine-readable contract every downstream
48
+ // host reads; the enriched message is human-readable only.
49
+ const methods = (context.authMethods ?? []).map((m) => ({
50
+ id: m.id,
51
+ // AuthMethodAgent carries no `type` field (the SDK treats a missing discriminant as "agent").
52
+ type: ("type" in m ? m.type : undefined) ?? "agent",
53
+ name: m.name,
54
+ }));
41
55
  return new WorkflowError(authRequiredMessage(message, context), WorkflowErrorCode.AUTH_REQUIRED, {
42
56
  recoverable: false,
43
57
  agentLabel: context.label,
58
+ authContext: { backendId: context.backendId, methods },
44
59
  details: error,
45
60
  });
46
61
  }
@@ -55,8 +70,17 @@ export function mapThrownError(error, labelOrContext) {
55
70
  });
56
71
  }
57
72
  function isAcpAuthRequired(error, message) {
58
- return (Boolean(error && typeof error === "object" && error.code === ACP_AUTH_REQUIRED_ERROR_CODE) &&
59
- /^Authentication required\b/i.test(message));
73
+ const code = error?.code;
74
+ // PRIMARY (spec-faithful): -32000 is reserved EXCLUSIVELY for authRequired (jsonrpc.js:818-823;
75
+ // no other constructor in jsonrpc.js:764-829 emits it). Code alone, ANY message — this unblocks
76
+ // conformant agents that localize or rephrase the text.
77
+ if (code === ACP_AUTH_REQUIRED_ERROR_CODE)
78
+ return true;
79
+ // FALLBACK: a non-conformant agent that signals auth in prose without the reserved code. A
80
+ // DIFFERENT reserved code that merely mentions the phrase must NEVER mis-route to pause-for-auth.
81
+ return typeof code === "number"
82
+ ? !OTHER_RESERVED.has(code) && /\bauthentication required\b/i.test(message)
83
+ : /\bauthentication required\b/i.test(message);
60
84
  }
61
85
  function authRequiredMessage(message, context) {
62
86
  const backend = context.backendId ? ` (${context.backendId})` : "";
package/dist/index.d.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  export { AcpAgentRunner, createAcpRunner, selectBackend } from "./runner.js";
2
- export type { AcpRunnerOptions, AuthenticateOptions, AuthMethodsOptions, DisableProviderOptions, DeleteSessionOptions, ListProvidersOptions, ListSessionsOptions, LogoutOptions, ReattachSessionOptions, SetProviderOptions, } from "./runner.js";
2
+ export type { AcpRunnerOptions, AuthenticateOptions, AuthMethodsOptions, AuthCapableRunner, AuthController, AuthOutcome, AuthStatusSnapshot, CompleteAuthOptions, DisableProviderOptions, DeleteSessionOptions, ListProvidersOptions, ListSessionsOptions, LogoutOptions, ReattachSessionOptions, SetProviderOptions, } from "./runner.js";
3
+ export { buildAuthDescriptor, buildAuthDescriptors, isGatewayShapedMeta } from "./auth/auth-types.js";
4
+ export type { AuthContext, AuthMethodDescriptor, AuthResolution, AuthResolver } from "./auth/auth-types.js";
5
+ export { AuthStore, BackendAuthMachine, classifyCredential, redactSecrets, } from "./auth/auth-store.js";
6
+ export type { AuthEvent, AuthIntent, AuthMethodType, BackendAuthState, ConnectionAuthStamp, CredentialClass, RedactedIntent, } from "./auth/auth-store.js";
7
+ export { claudeAuthProfile, codexAuthProfile, opencodeAuthProfile } from "./auth/auth-profiles.js";
8
+ export type { AuthProfile, TerminalLaunch } from "./auth/auth-profiles.js";
3
9
  export { InteractiveSession } from "./interactive.js";
4
10
  export type { InteractiveSessionOptions, InteractiveTurn } from "./interactive.js";
5
11
  export { AGENT_METHODS, CLIENT_METHODS } from "@agentclientprotocol/sdk";
@@ -8,8 +14,8 @@ export { BACKENDS_ENV, registryWithRunBackends, resolveBackendRegistry } from ".
8
14
  export type { BackendRegistry, CustomBackendConfig, RegisteredBackend } from "./registry.js";
9
15
  export { PooledConnection, SessionHandle } from "./acp-client.js";
10
16
  export type { AcpSessionOptions, PooledConnectionDeps } from "./acp-client.js";
11
- export { AGENT_METHOD_COVERAGE, CLIENT_METHOD_COVERAGE } from "./protocol-coverage.js";
12
- export type { AgentMethodCoverage, ClientMethodCoverage } from "./protocol-coverage.js";
17
+ export { AGENT_METHOD_COVERAGE, ACP_AUTH_REQUIRED_CODE_EXCLUSIVE, AUTH_CAPABILITY_KEYS, AUTH_META_CONVENTION_KEYS, AUTH_META_MATRIX, CLIENT_METHOD_COVERAGE, CODEX_SPAWN_AUTH_ENV, HANDLED_AUTH_METHOD_TYPES, assertAuthCapabilityShape, } from "./protocol-coverage.js";
18
+ export type { AgentMethodCoverage, AuthMetaMatrixRow, ClientMethodCoverage } from "./protocol-coverage.js";
13
19
  export { GATED_CUSTOM_META_KEYS, adaptPromptContent, gateCustomMeta, isSupportedProtocolVersion, negotiateCapabilities, unsupportedMcpServer, } from "./capabilities.js";
14
20
  export type { NegotiatedCapabilities } from "./capabilities.js";
15
21
  export { AcpAgentPool, resolvePoolSize } from "./pool.js";
@@ -23,8 +29,8 @@ export { ClaudeBackend } from "./backends/claude.js";
23
29
  export { CodexBackend } from "./backends/codex.js";
24
30
  export { OpenCodeBackend } from "./backends/opencode.js";
25
31
  export { CustomAcpBackend } from "./backends/custom.js";
26
- export { decidePermission } from "./permissions.js";
27
- export type { ElicitationResolver, PermissionResolver, ToolPolicy } from "./permissions.js";
32
+ export { decidePermission, resolvePermission, withPersist } from "./permissions.js";
33
+ export type { ElicitationResolver, PermissionPersist, PermissionResolution, PermissionResolver, ToolPolicy, } from "./permissions.js";
28
34
  export { UsageAccumulator } from "./usage.js";
29
35
  export type { AgentSessionRef, McpAcpServerConfig, McpServerConfig } from "@automatalabs/shared-types";
30
36
  export { toAnthropicJsonSchema, toJsonSchema, toStrictJsonSchema } from "./schema-strict.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7E,YAAY,EACV,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACzE,YAAY,EACV,uBAAuB,EACvB,+BAA+B,EAC/B,qBAAqB,EACrB,kBAAkB,EAClB,0BAA0B,EAC1B,6BAA6B,EAC7B,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,+BAA+B,EAC/B,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,EACvB,2BAA2B,EAC3B,mBAAmB,EACnB,aAAa,EACb,yBAAyB,EACzB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,eAAe,EACf,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC9F,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE7F,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAClE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE/E,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACvF,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAIxF,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,cAAc,EACd,0BAA0B,EAC1B,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAI7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EACV,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,EACd,UAAU,EACV,WAAW,EACX,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAClG,YAAY,EACV,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,2BAA2B,EAC3B,mBAAmB,EACnB,0BAA0B,EAC1B,yBAAyB,EACzB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,OAAO,EACP,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAEvG,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7F,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,uBAAuB,EACvB,aAAa,GACd,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhF,OAAO,EAAE,4BAA4B,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC1F,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7E,YAAY,EACV,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACtG,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC5G,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,GACd,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,SAAS,EACT,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,cAAc,GACf,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnG,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACzE,YAAY,EACV,uBAAuB,EACvB,+BAA+B,EAC/B,qBAAqB,EACrB,kBAAkB,EAClB,0BAA0B,EAC1B,6BAA6B,EAC7B,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,+BAA+B,EAC/B,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,EACvB,2BAA2B,EAC3B,mBAAmB,EACnB,aAAa,EACb,yBAAyB,EACzB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,eAAe,EACf,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC9F,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE7F,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAClE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE/E,OAAO,EACL,qBAAqB,EACrB,gCAAgC,EAChC,oBAAoB,EACpB,yBAAyB,EACzB,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAI3G,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,cAAc,EACd,0BAA0B,EAC1B,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAI7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EACV,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,EACd,UAAU,EACV,WAAW,EACX,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAClG,YAAY,EACV,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,2BAA2B,EAC3B,mBAAmB,EACnB,0BAA0B,EAC1B,yBAAyB,EACzB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,OAAO,EACP,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpF,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,UAAU,GACX,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAEvG,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7F,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,uBAAuB,EACvB,aAAa,GACd,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhF,OAAO,EAAE,4BAA4B,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC1F,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -5,12 +5,18 @@
5
5
  // @automatalabs/workflow-engine; the two siblings meet ONLY at AgentRunner, injected by the
6
6
  // @automatalabs/workflows facade (which mcp-server builds on) via createAcpRunner().
7
7
  export { AcpAgentRunner, createAcpRunner, selectBackend } from "./runner.js";
8
+ // Type-driven auth contracts (§1.3) and the AuthStore lifecycle spine (§2).
9
+ export { buildAuthDescriptor, buildAuthDescriptors, isGatewayShapedMeta } from "./auth/auth-types.js";
10
+ export { AuthStore, BackendAuthMachine, classifyCredential, redactSecrets, } from "./auth/auth-store.js";
11
+ // Per-agent auth profiles (§3): the pure-data adapters wired onto the built-in backends. Custom
12
+ // backends supply none (conformance-by-absence, §3.5).
13
+ export { claudeAuthProfile, codexAuthProfile, opencodeAuthProfile } from "./auth/auth-profiles.js";
8
14
  export { InteractiveSession } from "./interactive.js";
9
15
  export { AGENT_METHODS, CLIENT_METHODS } from "@agentclientprotocol/sdk";
10
16
  // The custom-backend registry: run ANY ACP agent as an agent() target.
11
17
  export { BACKENDS_ENV, registryWithRunBackends, resolveBackendRegistry } from "./registry.js";
12
18
  export { PooledConnection, SessionHandle } from "./acp-client.js";
13
- export { AGENT_METHOD_COVERAGE, CLIENT_METHOD_COVERAGE } from "./protocol-coverage.js";
19
+ export { AGENT_METHOD_COVERAGE, ACP_AUTH_REQUIRED_CODE_EXCLUSIVE, AUTH_CAPABILITY_KEYS, AUTH_META_CONVENTION_KEYS, AUTH_META_MATRIX, CLIENT_METHOD_COVERAGE, CODEX_SPAWN_AUTH_ENV, HANDLED_AUTH_METHOD_TYPES, assertAuthCapabilityShape, } from "./protocol-coverage.js";
14
20
  // ACP capability negotiation: parse/validate the initialize response and gate what the client
15
21
  // sends (custom `_meta` keys, MCP transports) on what the connected agent advertised.
16
22
  export { GATED_CUSTOM_META_KEYS, adaptPromptContent, gateCustomMeta, isSupportedProtocolVersion, negotiateCapabilities, unsupportedMcpServer, } from "./capabilities.js";
@@ -24,7 +30,7 @@ export { ClaudeBackend } from "./backends/claude.js";
24
30
  export { CodexBackend } from "./backends/codex.js";
25
31
  export { OpenCodeBackend } from "./backends/opencode.js";
26
32
  export { CustomAcpBackend } from "./backends/custom.js";
27
- export { decidePermission } from "./permissions.js";
33
+ export { decidePermission, resolvePermission, withPersist } from "./permissions.js";
28
34
  export { UsageAccumulator } from "./usage.js";
29
35
  export { toAnthropicJsonSchema, toJsonSchema, toStrictJsonSchema } from "./schema-strict.js";
30
36
  export { extractValidated, findJsonBlock, parseFinalJson, resolveStructuredOutput, validateValue, } from "./structured-output.js";
@@ -12,6 +12,20 @@ export type PermissionResolver = (params: RequestPermissionRequest, ctx: AcpEven
12
12
  * UNSTABLE/@experimental; this library deliberately exposes the SDK request/response types
13
13
  * directly so regular SDK bumps and wire tests catch drift instead of freezing a local copy. */
14
14
  export type ElicitationResolver = (request: CreateElicitationRequest, context: AcpEventContext) => Promise<CreateElicitationResponse> | CreateElicitationResponse;
15
+ /** Codex tool-approval persistence directive (codex-acp `dist/index.js:23952-23975`, §3.6). A
16
+ * permission decision may ask the agent to REMEMBER the approval for the rest of the session
17
+ * ("session") or permanently ("always"). It is echoed as `_meta.persist` on the RequestPermission
18
+ * response; an agent WITHOUT the capability ignores the extra `_meta` (Principle 3 — no silent
19
+ * unsupported surface). */
20
+ export type PermissionPersist = "session" | "always";
21
+ /** High-level permission decision (§3.6). Mirrors the spec's `PermissionResolution`: a host says
22
+ * allow/deny and, on allow, MAY request persistence. `resolvePermission` maps it onto a concrete ACP
23
+ * `RequestPermissionResponse` (option selection + the `_meta.persist` echo), so a host can drive
24
+ * `onPermissionRequest` at this altitude instead of hand-building the SDK response. */
25
+ export interface PermissionResolution {
26
+ outcome: "allow" | "deny";
27
+ persist?: PermissionPersist;
28
+ }
15
29
  export interface ToolPolicy {
16
30
  /** Allow-list (agentType `tools`). When non-empty, a tool that matches NOTHING is denied. */
17
31
  allow?: string[];
@@ -21,7 +35,20 @@ export interface ToolPolicy {
21
35
  * behavior. Explicit ACP session modes set this to "deny" unless a permission resolver is
22
36
  * present, otherwise read-only/plan confinement can be bypassed by auto-approved escalations. */
23
37
  defaultOutcome?: "allow" | "deny";
38
+ /** Codex tool-approval persistence (§3.6): when the auto-responder ALLOWS a tool, echo this as
39
+ * `_meta.persist` on the response so a capable agent remembers the approval. Ignored on deny and by
40
+ * agents without the capability. */
41
+ persist?: PermissionPersist;
24
42
  }
25
43
  /** Decide the auto-response for one permission request given the tool policy. */
26
44
  export declare function decidePermission(request: RequestPermissionRequest, policy: ToolPolicy): RequestPermissionResponse;
45
+ /** Stamp a persistence directive onto a permission response's top-level `_meta.persist` (§3.6). A
46
+ * cancelled response, or an absent directive, is returned unchanged. Never mutates the input; a
47
+ * non-secret structural echo, so it is safe to emit in events. */
48
+ export declare function withPersist(response: RequestPermissionResponse, persist: PermissionPersist | undefined): RequestPermissionResponse;
49
+ /** Map a high-level `PermissionResolution` (§3.6) onto a concrete ACP `RequestPermissionResponse` for
50
+ * `request`: pick an allow/reject option of the requested polarity and, on allow, echo `_meta.persist`.
51
+ * Falls back to CANCELLING when the agent offers no option of the requested polarity (the only way to
52
+ * refuse a tool with no reject option) — identical to the auto-responder's contract. */
53
+ export declare function resolvePermission(request: RequestPermissionRequest, resolution: PermissionResolution): RequestPermissionResponse;
27
54
  //# sourceMappingURL=permissions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EAGzB,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;wDAMwD;AACxD,MAAM,MAAM,kBAAkB,GAAG,CAC/B,MAAM,EAAE,wBAAwB,EAChC,GAAG,EAAE,eAAe,KACjB,OAAO,CAAC,yBAAyB,CAAC,GAAG,yBAAyB,CAAC;AAEpE;;iGAEiG;AACjG,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE,wBAAwB,EACjC,OAAO,EAAE,eAAe,KACrB,OAAO,CAAC,yBAAyB,CAAC,GAAG,yBAAyB,CAAC;AAEpE,MAAM,WAAW,UAAU;IACzB,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;sGAEkG;IAClG,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACnC;AAKD,iFAAiF;AACjF,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,wBAAwB,EACjC,MAAM,EAAE,UAAU,GACjB,yBAAyB,CAsC3B"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EAGzB,wBAAwB,EACxB,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;wDAMwD;AACxD,MAAM,MAAM,kBAAkB,GAAG,CAC/B,MAAM,EAAE,wBAAwB,EAChC,GAAG,EAAE,eAAe,KACjB,OAAO,CAAC,yBAAyB,CAAC,GAAG,yBAAyB,CAAC;AAEpE;;iGAEiG;AACjG,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE,wBAAwB,EACjC,OAAO,EAAE,eAAe,KACrB,OAAO,CAAC,yBAAyB,CAAC,GAAG,yBAAyB,CAAC;AAEpE;;;;4BAI4B;AAC5B,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAErD;;;wFAGwF;AACxF,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;sGAEkG;IAClG,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAClC;;yCAEqC;IACrC,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAKD,iFAAiF;AACjF,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,wBAAwB,EACjC,MAAM,EAAE,UAAU,GACjB,yBAAyB,CAwC3B;AAED;;mEAEmE;AACnE,wBAAgB,WAAW,CACzB,QAAQ,EAAE,yBAAyB,EACnC,OAAO,EAAE,iBAAiB,GAAG,SAAS,GACrC,yBAAyB,CAG3B;AAED;;;yFAGyF;AACzF,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,wBAAwB,EACjC,UAAU,EAAE,oBAAoB,GAC/B,yBAAyB,CAM3B"}
@@ -35,7 +35,29 @@ export function decidePermission(request, policy) {
35
35
  // remaining way to refuse a tool the server offers no reject option for.
36
36
  return { outcome: { outcome: "cancelled" } };
37
37
  }
38
- return { outcome: { outcome: "selected", optionId: option.optionId } };
38
+ const response = { outcome: { outcome: "selected", optionId: option.optionId } };
39
+ // Echo the persistence directive (§3.6) only when the auto-responder ALLOWS; a denial persists nothing.
40
+ return wantAllow ? withPersist(response, policy.persist) : response;
41
+ }
42
+ /** Stamp a persistence directive onto a permission response's top-level `_meta.persist` (§3.6). A
43
+ * cancelled response, or an absent directive, is returned unchanged. Never mutates the input; a
44
+ * non-secret structural echo, so it is safe to emit in events. */
45
+ export function withPersist(response, persist) {
46
+ if (!persist || response.outcome.outcome !== "selected")
47
+ return response;
48
+ return { ...response, _meta: { ...(response._meta ?? {}), persist } };
49
+ }
50
+ /** Map a high-level `PermissionResolution` (§3.6) onto a concrete ACP `RequestPermissionResponse` for
51
+ * `request`: pick an allow/reject option of the requested polarity and, on allow, echo `_meta.persist`.
52
+ * Falls back to CANCELLING when the agent offers no option of the requested polarity (the only way to
53
+ * refuse a tool with no reject option) — identical to the auto-responder's contract. */
54
+ export function resolvePermission(request, resolution) {
55
+ const wantAllow = resolution.outcome === "allow";
56
+ const option = pickOption(request.options, wantAllow);
57
+ if (!option)
58
+ return { outcome: { outcome: "cancelled" } };
59
+ const response = { outcome: { outcome: "selected", optionId: option.optionId } };
60
+ return wantAllow ? withPersist(response, resolution.persist) : response;
39
61
  }
40
62
  function candidateNames(request) {
41
63
  const decoration = [];
package/dist/pool.d.ts CHANGED
@@ -3,6 +3,7 @@ import { PooledConnection, SessionHandle, type AcpSessionOptions } from "./acp-c
3
3
  import { type ClientHandlers } from "./client-handlers.js";
4
4
  import type { AcpEventSink } from "./events.js";
5
5
  import type { ElicitationResolver, PermissionResolver } from "./permissions.js";
6
+ import type { AuthStore } from "./auth/auth-store.js";
6
7
  export interface AcpPoolOptions {
7
8
  /** Long-lived processes to keep PER backend. Default 1; falls back to AGENTPRISM_ACP_POOL_SIZE. */
8
9
  size?: number;
@@ -16,6 +17,16 @@ export interface AcpPoolDeps {
16
17
  permissionResolver?: PermissionResolver;
17
18
  elicitationResolver?: ElicitationResolver;
18
19
  advertiseElicitation?: boolean;
20
+ /** Initialize-time client auth advertisement (§1.2), forwarded to every PooledConnection.
21
+ * Undefined omits the `auth` capability — the default-OFF baseline. */
22
+ authCapabilities?: {
23
+ terminal?: boolean;
24
+ gateway?: boolean;
25
+ };
26
+ /** The runner's single auth store (§2). When present, connection selection is generation-gated:
27
+ * no session is ever opened on a connection whose applied intent-generation is stale. Undefined
28
+ * => no gating, byte-identical to the pre-auth baseline. */
29
+ authStore?: AuthStore;
19
30
  }
20
31
  /** Resolve the per-backend pool size: explicit option wins, else env, else 1. Clamped to >= 1. */
21
32
  export declare function resolvePoolSize(option?: number): number;
@@ -41,6 +52,15 @@ export declare class AcpAgentPool {
41
52
  * double-book a connection.
42
53
  */
43
54
  private selectConnection;
55
+ /** Reconcile every live connection for a key to the current generation (§2.6). Stale-but-busy
56
+ * connections are DRAINED (recycled on release), not disposed synchronously, so in-flight prompts
57
+ * finish under the auth they started with. Never blocks. */
58
+ private reconcileStale;
59
+ /** Public: reconcile every live connection for a backend to the current generation (§2.6). Called
60
+ * by the runner immediately after a host-completed auth so a subsequent run() lands current. */
61
+ recycle(poolKey: string): void;
62
+ /** Spawn a fresh pooled connection (a fresh process primes the current intent at initialize). */
63
+ private spawn;
44
64
  private connectionsFor;
45
65
  /** Evict a dead connection so it is never handed out again. */
46
66
  private drop;
@@ -1 +1 @@
1
- {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC1F,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAKhF,MAAM,WAAW,cAAc;IAC7B,mGAAmG;IACnG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4FAA4F;IAC5F,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;6FAC6F;AAC7F,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,kGAAkG;AAClG,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED,qBAAa,YAAY;IAUrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IATvB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAC5D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4C;IACtE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA4B;IAC1D,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAS;gBAGvB,OAAO,GAAE,cAAmB,EACX,IAAI,GAAE,WAAgB;IAOzC,8FAA8F;IACxF,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC;IAehF,2FAA2F;IACrF,eAAe,CACnB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,EACzF,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GACrD,OAAO,CAAC,aAAa,CAAC;IAezB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IA4BxB,OAAO,CAAC,cAAc;IAStB,+DAA+D;IAC/D,OAAO,CAAC,IAAI;IAOZ,iEAAiE;IAC3D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,cAAc;IAMtB,gGAAgG;IAChG,OAAO,CAAC,WAAW;CAGpB"}
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC1F,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAsB,MAAM,sBAAsB,CAAC;AAK1E,MAAM,WAAW,cAAc;IAC7B,mGAAmG;IACnG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4FAA4F;IAC5F,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;6FAC6F;AAC7F,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;4EACwE;IACxE,gBAAgB,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC7D;;iEAE6D;IAC7D,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,kGAAkG;AAClG,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED,qBAAa,YAAY;IAUrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IATvB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAC5D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4C;IACtE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA4B;IAC1D,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAS;gBAGvB,OAAO,GAAE,cAAmB,EACX,IAAI,GAAE,WAAgB;IAOzC,8FAA8F;IACxF,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC;IAehF,2FAA2F;IACrF,eAAe,CACnB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,EACzF,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GACrD,OAAO,CAAC,aAAa,CAAC;IAezB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAyBxB;;iEAE6D;IAC7D,OAAO,CAAC,cAAc;IActB;qGACiG;IACjG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAM9B,iGAAiG;IACjG,OAAO,CAAC,KAAK;IAgBb,OAAO,CAAC,cAAc;IAStB,+DAA+D;IAC/D,OAAO,CAAC,IAAI;IAOZ,iEAAiE;IAC3D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,cAAc;IAMtB,gGAAgG;IAChG,OAAO,CAAC,WAAW;CAGpB"}
package/dist/pool.js CHANGED
@@ -75,26 +75,68 @@ export class AcpAgentPool {
75
75
  // Pool identity: poolKey (id + spawn-config hash for custom backends) over bare id, so two
76
76
  // runs declaring the same NAME with different COMMANDS never share a process.
77
77
  const key = backend.poolKey ?? backend.id;
78
+ // Generation-gated selection (§2.6): reuse any idle live connection that is NOT stale,
79
+ // reconciling stale ones first. This is the mechanical proof that no session is served under
80
+ // stale auth. `existing` (not `machineFor`) so the default-OFF path never lazily creates a
81
+ // machine — undefined machine ⇒ nothing is ever stale, byte-identical to the pre-auth baseline.
82
+ const machine = this.deps.authStore?.existing(key);
78
83
  const connections = this.connectionsFor(key);
79
- const live = connections.filter((c) => c.alive);
80
- const idle = live.find((c) => c.activeSessions === 0);
84
+ if (machine)
85
+ this.reconcileStale(key, machine);
86
+ const usable = connections.filter((c) => c.alive && !c.recyclePending && !machine?.isStale(c.authStamp));
87
+ const idle = usable.find((c) => c.activeSessions === 0);
81
88
  if (idle)
82
89
  return idle;
83
- if (live.length < this.size) {
84
- this.installExitHook();
85
- const connection = PooledConnection.create(backend, {
86
- onDead: (dead) => this.drop(key, dead),
87
- onEvent: this.deps.onEvent,
88
- permissionResolver: this.deps.permissionResolver,
89
- elicitationResolver: this.deps.elicitationResolver,
90
- advertiseElicitation: this.deps.advertiseElicitation,
91
- clientHandlers: this.clientHandlers,
92
- });
93
- connections.push(connection);
94
- return connection;
90
+ if (usable.length < this.size)
91
+ return this.spawn(key, backend);
92
+ // At capacity with every usable connection busy: multiplex onto the least-loaded one.
93
+ return usable.length > 0
94
+ ? usable.reduce((least, c) => (c.activeSessions < least.activeSessions ? c : least))
95
+ : this.spawn(key, backend);
96
+ }
97
+ /** Reconcile every live connection for a key to the current generation (§2.6). Stale-but-busy
98
+ * connections are DRAINED (recycled on release), not disposed synchronously, so in-flight prompts
99
+ * finish under the auth they started with. Never blocks. */
100
+ reconcileStale(key, machine) {
101
+ for (const c of this.connectionsFor(key).filter((c) => c.alive)) {
102
+ if (!machine.isStale(c.authStamp))
103
+ continue;
104
+ if (c.canLiveReapply(machine) && c.activeSessions === 0) {
105
+ c.scheduleReapply(machine); // in-process: re-auth the idle connection live
106
+ }
107
+ else if (c.activeSessions === 0) {
108
+ void c.dispose(); // disk/spawn-env: recycle the idle process now
109
+ this.drop(key, c);
110
+ }
111
+ else {
112
+ c.markForRecycleWhenIdle(machine); // BUSY: drain, then recycle on release
113
+ }
95
114
  }
96
- // At capacity with every connection busy: multiplex onto the least-loaded one.
97
- return live.reduce((least, c) => (c.activeSessions < least.activeSessions ? c : least));
115
+ }
116
+ /** Public: reconcile every live connection for a backend to the current generation (§2.6). Called
117
+ * by the runner immediately after a host-completed auth so a subsequent run() lands current. */
118
+ recycle(poolKey) {
119
+ if (this.disposed)
120
+ return;
121
+ const machine = this.deps.authStore?.existing(poolKey);
122
+ if (machine)
123
+ this.reconcileStale(poolKey, machine);
124
+ }
125
+ /** Spawn a fresh pooled connection (a fresh process primes the current intent at initialize). */
126
+ spawn(key, backend) {
127
+ this.installExitHook();
128
+ const connection = PooledConnection.create(backend, {
129
+ onDead: (dead) => this.drop(key, dead),
130
+ onEvent: this.deps.onEvent,
131
+ permissionResolver: this.deps.permissionResolver,
132
+ elicitationResolver: this.deps.elicitationResolver,
133
+ advertiseElicitation: this.deps.advertiseElicitation,
134
+ authCapabilities: this.deps.authCapabilities,
135
+ authStore: this.deps.authStore,
136
+ clientHandlers: this.clientHandlers,
137
+ });
138
+ this.connectionsFor(key).push(connection);
139
+ return connection;
98
140
  }
99
141
  connectionsFor(key) {
100
142
  let arr = this.byBackend.get(key);
@@ -1,4 +1,5 @@
1
1
  import { AGENT_METHODS, CLIENT_METHODS } from "@agentclientprotocol/sdk";
2
+ import type { AuthCapabilities, AuthMethod, AuthMethodAgent, AuthMethodEnvVar, AuthMethodTerminal, ClientCapabilities } from "@agentclientprotocol/sdk";
2
3
  type ValueOf<T> = T[keyof T];
3
4
  type ClientMethod = ValueOf<typeof CLIENT_METHODS>;
4
5
  type AgentMethod = ValueOf<typeof AGENT_METHODS>;
@@ -12,5 +13,79 @@ export type AgentMethodCoverage = "driven" | "passthrough" | "guarded";
12
13
  * and the passthrough remainder is nes/*, document/*, and mcp/message. */
13
14
  export declare const CLIENT_METHOD_COVERAGE: Record<ClientMethod, ClientMethodCoverage>;
14
15
  export declare const AGENT_METHOD_COVERAGE: Record<AgentMethod, AgentMethodCoverage>;
16
+ /** Compile-time assertion primitive: `Expect<T>` only accepts `true`, so a `false` (drifted) SDK
17
+ * shape is a type error at build time. */
18
+ type Expect<T extends true> = T;
19
+ /** `ClientCapabilities.auth` still exists and is typed as `AuthCapabilities` (§1.2 UNSTABLE pin). */
20
+ export type _AuthKeyExists = Expect<"auth" extends keyof ClientCapabilities ? true : false>;
21
+ /** `AuthCapabilities.terminal` is still the typed boolean gate §1.2 assigns to (no `as` cast). */
22
+ export type _AuthTerminalIsBoolean = Expect<AuthCapabilities["terminal"] extends boolean | undefined ? true : false>;
23
+ /** The exact property set SDK 1.2.1 types on `AuthCapabilities` (§1.2). The runtime tripwire below
24
+ * asserts `clientCapabilitiesFor({ auth })` emits ONLY these keys, so a bump that widens/renames
25
+ * the shape trips the coverage suite. */
26
+ export declare const AUTH_CAPABILITY_KEYS: readonly string[];
27
+ /** Runtime drift assertion (§4.6.4 item 1): every key on the advertised `ClientCapabilities.auth`
28
+ * block is a pinned SDK-1.2.1 `AuthCapabilities` key. Throws on drift, tripping the build. A
29
+ * `null`/absent `auth` (the default-OFF baseline) is vacuously conformant. Reads only structural
30
+ * keys — never any advertised value — so it is secret-free. */
31
+ export declare function assertAuthCapabilityShape(auth: ClientCapabilities["auth"]): void;
32
+ /** The three `AuthMethod` variants the base dispatcher handles (`agent`/`terminal`/`env_var`, §1.3).
33
+ * `agent` is the default when `type` is absent (`AuthMethodAgent` carries no `type`). */
34
+ export declare const HANDLED_AUTH_METHOD_TYPES: readonly ["agent", "terminal", "env_var"];
35
+ /** §4.6.4 item 3 — the SDK `AuthMethod` union is EXACTLY the three variants the dispatcher handles;
36
+ * a fourth variant (a widened union) makes this `false` and fails `tsc`. */
37
+ export type _AuthMethodUnionPinned = Expect<[
38
+ AuthMethod
39
+ ] extends [AuthMethodAgent | AuthMethodTerminal | AuthMethodEnvVar] ? true : false>;
40
+ /** The `terminal`/`env_var` discriminants are still the literals the dispatcher branches on: the SDK
41
+ * intersects the bare method type with `{ type: "…" }` in the `AuthMethod` union, so a dropped
42
+ * discriminant makes `Extract` collapse to `never` and fails `tsc`. */
43
+ export type _AuthMethodTerminalDiscriminant = Expect<[
44
+ Extract<AuthMethod, {
45
+ type: "terminal";
46
+ }>
47
+ ] extends [never] ? false : true>;
48
+ export type _AuthMethodEnvVarDiscriminant = Expect<[
49
+ Extract<AuthMethod, {
50
+ type: "env_var";
51
+ }>
52
+ ] extends [never] ? false : true>;
53
+ /** The cross-agent `_meta` key conventions the base layer keys on (§1 intro; recognized by literal
54
+ * name, NOT SDK schema fields). `gateway` ⇒ in-process classification; `terminal-auth` ⇒ terminal
55
+ * launch hint; `api-key` ⇒ codex's disk api-key `_meta`. */
56
+ export declare const AUTH_META_CONVENTION_KEYS: {
57
+ readonly gateway: "gateway";
58
+ readonly terminalAuth: "terminal-auth";
59
+ readonly apiKey: "api-key";
60
+ };
61
+ /** The codex startup pre-auth env channel delivered by `codexAuthProfile.spawnAuthEnv` (§2.8/§3.3). */
62
+ export declare const CODEX_SPAWN_AUTH_ENV: "DEFAULT_AUTH_REQUEST";
63
+ /** JSON-RPC `-32000` is reserved EXCLUSIVELY for `authRequired` (SDK `jsonrpc.js:818-823`) — the
64
+ * guarantee the code-only §1.5 matcher relies on (§4.6.4 item 5). */
65
+ export declare const ACP_AUTH_REQUIRED_CODE_EXCLUSIVE: -32000;
66
+ /** One row of the §3.6 full `_meta` support matrix, landed as executable data (not prose) so an
67
+ * SDK/agent bump that changes a `_meta` surface trips the drift suite (§4.6.4 item 4). */
68
+ export interface AuthMetaMatrixRow {
69
+ readonly agent: "claude" | "codex" | "opencode" | "all";
70
+ /** A stable literal that MUST still be present in the cited artifact/spec — the drift anchor. */
71
+ readonly capability: string;
72
+ /** Wire direction: A→C agent→client, C→A client→agent, C↔A both, — none, agent-internal. */
73
+ readonly direction: "A→C" | "C→A" | "C↔A" | "—" | "agent-internal";
74
+ readonly status: "supported-today" | "work-item";
75
+ /** Owning §/PR for a work item; omitted for supported-today rows. */
76
+ readonly owner?: string;
77
+ /** When set, the literal is asserted present in this backend's INSTALLED dist (claude/codex only;
78
+ * opencode ships a compiled binary with no consumable source — §3.4, grounded by live-e2e). */
79
+ readonly distProbe?: "claude" | "codex";
80
+ }
81
+ /** The §3.6 auth `_meta` matrix as executable rows — the exact surfaces §4.6.4 item 4 enumerates
82
+ * (claude gateway/terminal-auth, codex api-key/gateway/DEFAULT_AUTH_REQUEST, opencode terminal-auth),
83
+ * plus the codex tool-approval `persist` and the cross-agent provider-env passthrough. Each
84
+ * `capability` is a literal that MUST appear in spec §3.6; `docs-drift.test.ts` asserts that lockstep,
85
+ * and (where `distProbe` is set) `protocol-coverage.test.ts` asserts the literal is still present in
86
+ * the installed agent dist — so neither the spec nor an agent bump can silently drift a `_meta`
87
+ * surface. OpenCode ships a compiled binary with no consumable source (§3.4), so its row has no dist
88
+ * probe (grounded instead by the §4.6.3 live-e2e). */
89
+ export declare const AUTH_META_MATRIX: readonly AuthMetaMatrixRow[];
15
90
  export {};
16
91
  //# sourceMappingURL=protocol-coverage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol-coverage.d.ts","sourceRoot":"","sources":["../src/protocol-coverage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAEzE,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7B,KAAK,YAAY,GAAG,OAAO,CAAC,OAAO,cAAc,CAAC,CAAC;AACnD,KAAK,WAAW,GAAG,OAAO,CAAC,OAAO,aAAa,CAAC,CAAC;AAEjD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,SAAS,CAAC;AACxD;kGACkG;AAClG,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,aAAa,GAAG,SAAS,CAAC;AAEvE;;;2EAG2E;AAC3E,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,YAAY,EAAE,oBAAoB,CAe7E,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,WAAW,EAAE,mBAAmB,CA6B1E,CAAC"}
1
+ {"version":3,"file":"protocol-coverage.d.ts","sourceRoot":"","sources":["../src/protocol-coverage.ts"],"names":[],"mappings":"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"}
@@ -49,3 +49,61 @@ export const AGENT_METHOD_COVERAGE = {
49
49
  [AGENT_METHODS.document_did_save]: "passthrough",
50
50
  [AGENT_METHODS.document_did_focus]: "passthrough",
51
51
  };
52
+ /** The exact property set SDK 1.2.1 types on `AuthCapabilities` (§1.2). The runtime tripwire below
53
+ * asserts `clientCapabilitiesFor({ auth })` emits ONLY these keys, so a bump that widens/renames
54
+ * the shape trips the coverage suite. */
55
+ export const AUTH_CAPABILITY_KEYS = ["terminal", "_meta"];
56
+ /** Runtime drift assertion (§4.6.4 item 1): every key on the advertised `ClientCapabilities.auth`
57
+ * block is a pinned SDK-1.2.1 `AuthCapabilities` key. Throws on drift, tripping the build. A
58
+ * `null`/absent `auth` (the default-OFF baseline) is vacuously conformant. Reads only structural
59
+ * keys — never any advertised value — so it is secret-free. */
60
+ export function assertAuthCapabilityShape(auth) {
61
+ if (auth == null)
62
+ return;
63
+ for (const key of Object.keys(auth)) {
64
+ if (!AUTH_CAPABILITY_KEYS.includes(key)) {
65
+ throw new Error(`ClientCapabilities.auth carries unpinned key "${key}" — the SDK AuthCapabilities shape drifted (§1.2/§4.6.4).`);
66
+ }
67
+ }
68
+ }
69
+ // ---------------------------------------------------------------------------------------------
70
+ // Auth `AuthMethod.type` discriminant + cross-agent `_meta` convention drift tripwires
71
+ // (§3.6 / §4.6.4 items 3–5). The base auth flow (§1) dispatches on `AuthMethod.type` plus a small,
72
+ // fixed set of literal cross-agent `_meta` key names — NOT SDK schema fields. Pin both so a
73
+ // `@agentclientprotocol/sdk` bump that widens the method union, or an agent bump that moves a `_meta`
74
+ // surface, fails the build BEFORE release (bump-ACP-deps-every-release), never silently.
75
+ // ---------------------------------------------------------------------------------------------
76
+ /** The three `AuthMethod` variants the base dispatcher handles (`agent`/`terminal`/`env_var`, §1.3).
77
+ * `agent` is the default when `type` is absent (`AuthMethodAgent` carries no `type`). */
78
+ export const HANDLED_AUTH_METHOD_TYPES = ["agent", "terminal", "env_var"];
79
+ /** The cross-agent `_meta` key conventions the base layer keys on (§1 intro; recognized by literal
80
+ * name, NOT SDK schema fields). `gateway` ⇒ in-process classification; `terminal-auth` ⇒ terminal
81
+ * launch hint; `api-key` ⇒ codex's disk api-key `_meta`. */
82
+ export const AUTH_META_CONVENTION_KEYS = {
83
+ gateway: "gateway",
84
+ terminalAuth: "terminal-auth",
85
+ apiKey: "api-key",
86
+ };
87
+ /** The codex startup pre-auth env channel delivered by `codexAuthProfile.spawnAuthEnv` (§2.8/§3.3). */
88
+ export const CODEX_SPAWN_AUTH_ENV = "DEFAULT_AUTH_REQUEST";
89
+ /** JSON-RPC `-32000` is reserved EXCLUSIVELY for `authRequired` (SDK `jsonrpc.js:818-823`) — the
90
+ * guarantee the code-only §1.5 matcher relies on (§4.6.4 item 5). */
91
+ export const ACP_AUTH_REQUIRED_CODE_EXCLUSIVE = -32000;
92
+ /** The §3.6 auth `_meta` matrix as executable rows — the exact surfaces §4.6.4 item 4 enumerates
93
+ * (claude gateway/terminal-auth, codex api-key/gateway/DEFAULT_AUTH_REQUEST, opencode terminal-auth),
94
+ * plus the codex tool-approval `persist` and the cross-agent provider-env passthrough. Each
95
+ * `capability` is a literal that MUST appear in spec §3.6; `docs-drift.test.ts` asserts that lockstep,
96
+ * and (where `distProbe` is set) `protocol-coverage.test.ts` asserts the literal is still present in
97
+ * the installed agent dist — so neither the spec nor an agent bump can silently drift a `_meta`
98
+ * surface. OpenCode ships a compiled binary with no consumable source (§3.4), so its row has no dist
99
+ * probe (grounded instead by the §4.6.3 live-e2e). */
100
+ export const AUTH_META_MATRIX = [
101
+ { agent: "claude", capability: "gateway", direction: "C↔A", status: "work-item", owner: "§1.2-§1.3/PR2-PR3", distProbe: "claude" },
102
+ { agent: "claude", capability: "terminal-auth", direction: "C↔A", status: "work-item", owner: "§1.2-§1.3/PR2-PR3", distProbe: "claude" },
103
+ { agent: "codex", capability: "api-key", direction: "A→C", status: "work-item", owner: "§1.3/PR3", distProbe: "codex" },
104
+ { agent: "codex", capability: "gateway", direction: "C↔A", status: "work-item", owner: "§1.2-§1.3/PR2-PR3", distProbe: "codex" },
105
+ { agent: "codex", capability: "DEFAULT_AUTH_REQUEST", direction: "C→A", status: "work-item", owner: "§3.3/PR7", distProbe: "codex" },
106
+ { agent: "codex", capability: "persist", direction: "C→A", status: "work-item", owner: "§3.6/PR7", distProbe: "codex" },
107
+ { agent: "opencode", capability: "terminal-auth", direction: "C↔A", status: "work-item", owner: "§1.2-§1.3/PR2-PR3" },
108
+ { agent: "all", capability: "provider env keys", direction: "C→A", status: "work-item", owner: "§2.8/§3.4/PR3" },
109
+ ];