@alpacakit/agents 0.1.0-beta.19
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.
- package/LICENSE +21 -0
- package/README.md +224 -0
- package/dist/agents/builtin.d.ts +19 -0
- package/dist/agents/builtin.d.ts.map +1 -0
- package/dist/agents/builtin.js +14 -0
- package/dist/agents/claude.d.ts +20 -0
- package/dist/agents/claude.d.ts.map +1 -0
- package/dist/agents/claude.js +480 -0
- package/dist/agents/codex.d.ts +19 -0
- package/dist/agents/codex.d.ts.map +1 -0
- package/dist/agents/codex.js +355 -0
- package/dist/agents/openai-compatible/config.d.ts +16 -0
- package/dist/agents/openai-compatible/config.d.ts.map +1 -0
- package/dist/agents/openai-compatible/config.js +160 -0
- package/dist/agents/openai-compatible/engine.d.ts +18 -0
- package/dist/agents/openai-compatible/engine.d.ts.map +1 -0
- package/dist/agents/openai-compatible/engine.js +10 -0
- package/dist/agents/openai-compatible/fetch-engine.d.ts +38 -0
- package/dist/agents/openai-compatible/fetch-engine.d.ts.map +1 -0
- package/dist/agents/openai-compatible/fetch-engine.js +216 -0
- package/dist/agents/openai-compatible/pi/engine.d.ts +32 -0
- package/dist/agents/openai-compatible/pi/engine.d.ts.map +1 -0
- package/dist/agents/openai-compatible/pi/engine.js +98 -0
- package/dist/agents/openai-compatible/pi/module.d.ts +87 -0
- package/dist/agents/openai-compatible/pi/module.d.ts.map +1 -0
- package/dist/agents/openai-compatible/pi/module.js +43 -0
- package/dist/agents/openai-compatible/pi/sandbox.d.ts +25 -0
- package/dist/agents/openai-compatible/pi/sandbox.d.ts.map +1 -0
- package/dist/agents/openai-compatible/pi/sandbox.js +69 -0
- package/dist/agents/openai-compatible/pi/session.d.ts +17 -0
- package/dist/agents/openai-compatible/pi/session.d.ts.map +1 -0
- package/dist/agents/openai-compatible/pi/session.js +354 -0
- package/dist/agents/openai-compatible/response.d.ts +19 -0
- package/dist/agents/openai-compatible/response.d.ts.map +1 -0
- package/dist/agents/openai-compatible/response.js +203 -0
- package/dist/agents/openai-compatible/types.d.ts +34 -0
- package/dist/agents/openai-compatible/types.d.ts.map +1 -0
- package/dist/agents/openai-compatible/types.js +1 -0
- package/dist/agents/openai-compatible.d.ts +12 -0
- package/dist/agents/openai-compatible.d.ts.map +1 -0
- package/dist/agents/openai-compatible.js +45 -0
- package/dist/auth/login-probe.d.ts +21 -0
- package/dist/auth/login-probe.d.ts.map +1 -0
- package/dist/auth/login-probe.js +47 -0
- package/dist/auth/login.d.ts +79 -0
- package/dist/auth/login.d.ts.map +1 -0
- package/dist/auth/login.js +9 -0
- package/dist/auth/material.d.ts +87 -0
- package/dist/auth/material.d.ts.map +1 -0
- package/dist/auth/material.js +59 -0
- package/dist/auth/profile-store.d.ts +14 -0
- package/dist/auth/profile-store.d.ts.map +1 -0
- package/dist/auth/profile-store.js +101 -0
- package/dist/auth/secrets.d.ts +14 -0
- package/dist/auth/secrets.d.ts.map +1 -0
- package/dist/auth/secrets.js +40 -0
- package/dist/codex/app-server.d.ts +30 -0
- package/dist/codex/app-server.d.ts.map +1 -0
- package/dist/codex/app-server.js +322 -0
- package/dist/codex/index.d.ts +3 -0
- package/dist/codex/index.d.ts.map +1 -0
- package/dist/codex/index.js +1 -0
- package/dist/codex/protocol.d.ts +124 -0
- package/dist/codex/protocol.d.ts.map +1 -0
- package/dist/codex/protocol.js +283 -0
- package/dist/config/agent-config-validation.d.ts +22 -0
- package/dist/config/agent-config-validation.d.ts.map +1 -0
- package/dist/config/agent-config-validation.js +31 -0
- package/dist/config/agent-configs.d.ts +37 -0
- package/dist/config/agent-configs.d.ts.map +1 -0
- package/dist/config/agent-configs.js +214 -0
- package/dist/config/compose.d.ts +10 -0
- package/dist/config/compose.d.ts.map +1 -0
- package/dist/config/compose.js +89 -0
- package/dist/config/config.d.ts +21 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +33 -0
- package/dist/config/errors.d.ts +45 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/errors.js +37 -0
- package/dist/config/extension.d.ts +3 -0
- package/dist/config/extension.d.ts.map +1 -0
- package/dist/config/extension.js +1 -0
- package/dist/config/ids.d.ts +8 -0
- package/dist/config/ids.d.ts.map +1 -0
- package/dist/config/ids.js +4 -0
- package/dist/config/index.d.ts +12 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/model.d.ts +105 -0
- package/dist/config/model.d.ts.map +1 -0
- package/dist/config/model.js +1 -0
- package/dist/config/paths.d.ts +7 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +10 -0
- package/dist/config/schema.d.ts +59 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +83 -0
- package/dist/config/store.d.ts +34 -0
- package/dist/config/store.d.ts.map +1 -0
- package/dist/config/store.js +420 -0
- package/dist/config/support.d.ts +14 -0
- package/dist/config/support.d.ts.map +1 -0
- package/dist/config/support.js +32 -0
- package/dist/config/values.d.ts +21 -0
- package/dist/config/values.d.ts.map +1 -0
- package/dist/config/values.js +22 -0
- package/dist/config/xdg.d.ts +20 -0
- package/dist/config/xdg.d.ts.map +1 -0
- package/dist/config/xdg.js +23 -0
- package/dist/core/async-queue.d.ts +14 -0
- package/dist/core/async-queue.d.ts.map +1 -0
- package/dist/core/async-queue.js +46 -0
- package/dist/core/env.d.ts +19 -0
- package/dist/core/env.d.ts.map +1 -0
- package/dist/core/env.js +39 -0
- package/dist/core/error.d.ts +121 -0
- package/dist/core/error.d.ts.map +1 -0
- package/dist/core/error.js +88 -0
- package/dist/core/fs.d.ts +16 -0
- package/dist/core/fs.d.ts.map +1 -0
- package/dist/core/fs.js +30 -0
- package/dist/core/json.d.ts +20 -0
- package/dist/core/json.d.ts.map +1 -0
- package/dist/core/json.js +42 -0
- package/dist/core/node-ports.d.ts +9 -0
- package/dist/core/node-ports.d.ts.map +1 -0
- package/dist/core/node-ports.js +135 -0
- package/dist/core/ports.d.ts +71 -0
- package/dist/core/ports.d.ts.map +1 -0
- package/dist/core/ports.js +19 -0
- package/dist/core/redact.d.ts +8 -0
- package/dist/core/redact.d.ts.map +1 -0
- package/dist/core/redact.js +66 -0
- package/dist/core/run.d.ts +125 -0
- package/dist/core/run.d.ts.map +1 -0
- package/dist/core/run.js +27 -0
- package/dist/core/values.d.ts +12 -0
- package/dist/core/values.d.ts.map +1 -0
- package/dist/core/values.js +9 -0
- package/dist/corpus/failure-corpus.d.ts +21 -0
- package/dist/corpus/failure-corpus.d.ts.map +1 -0
- package/dist/corpus/failure-corpus.js +89 -0
- package/dist/fleet/fleet.d.ts +120 -0
- package/dist/fleet/fleet.d.ts.map +1 -0
- package/dist/fleet/fleet.js +409 -0
- package/dist/fleet/policy.d.ts +45 -0
- package/dist/fleet/policy.d.ts.map +1 -0
- package/dist/fleet/policy.js +50 -0
- package/dist/fleet/store.d.ts +28 -0
- package/dist/fleet/store.d.ts.map +1 -0
- package/dist/fleet/store.js +225 -0
- package/dist/host/capabilities.d.ts +146 -0
- package/dist/host/capabilities.d.ts.map +1 -0
- package/dist/host/capabilities.js +59 -0
- package/dist/host/context.d.ts +29 -0
- package/dist/host/context.d.ts.map +1 -0
- package/dist/host/context.js +11 -0
- package/dist/host/github-dir.d.ts +16 -0
- package/dist/host/github-dir.d.ts.map +1 -0
- package/dist/host/github-dir.js +164 -0
- package/dist/host/mcp-list.d.ts +12 -0
- package/dist/host/mcp-list.d.ts.map +1 -0
- package/dist/host/mcp-list.js +122 -0
- package/dist/host/requirement-ref.d.ts +12 -0
- package/dist/host/requirement-ref.d.ts.map +1 -0
- package/dist/host/requirement-ref.js +40 -0
- package/dist/host/run-command.d.ts +27 -0
- package/dist/host/run-command.d.ts.map +1 -0
- package/dist/host/run-command.js +66 -0
- package/dist/host/validate-spec.d.ts +10 -0
- package/dist/host/validate-spec.d.ts.map +1 -0
- package/dist/host/validate-spec.js +69 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/kernel/classify.d.ts +44 -0
- package/dist/kernel/classify.d.ts.map +1 -0
- package/dist/kernel/classify.js +136 -0
- package/dist/kernel/cli-agent.d.ts +62 -0
- package/dist/kernel/cli-agent.d.ts.map +1 -0
- package/dist/kernel/cli-agent.js +281 -0
- package/dist/kernel/cli-login.d.ts +13 -0
- package/dist/kernel/cli-login.d.ts.map +1 -0
- package/dist/kernel/cli-login.js +199 -0
- package/dist/kernel/definition.d.ts +41 -0
- package/dist/kernel/definition.d.ts.map +1 -0
- package/dist/kernel/definition.js +13 -0
- package/dist/kernel/env-template.d.ts +17 -0
- package/dist/kernel/env-template.d.ts.map +1 -0
- package/dist/kernel/env-template.js +78 -0
- package/dist/kernel/facets.d.ts +58 -0
- package/dist/kernel/facets.d.ts.map +1 -0
- package/dist/kernel/facets.js +102 -0
- package/dist/kernel/guard.d.ts +24 -0
- package/dist/kernel/guard.d.ts.map +1 -0
- package/dist/kernel/guard.js +69 -0
- package/dist/kernel/handle.d.ts +29 -0
- package/dist/kernel/handle.d.ts.map +1 -0
- package/dist/kernel/handle.js +97 -0
- package/dist/kernel/keyed.d.ts +19 -0
- package/dist/kernel/keyed.d.ts.map +1 -0
- package/dist/kernel/keyed.js +35 -0
- package/dist/kernel/login.d.ts +20 -0
- package/dist/kernel/login.d.ts.map +1 -0
- package/dist/kernel/login.js +74 -0
- package/dist/kernel/options.d.ts +73 -0
- package/dist/kernel/options.d.ts.map +1 -0
- package/dist/kernel/options.js +41 -0
- package/dist/kernel/run.d.ts +20 -0
- package/dist/kernel/run.d.ts.map +1 -0
- package/dist/kernel/run.js +245 -0
- package/dist/kernel/runtime.d.ts +48 -0
- package/dist/kernel/runtime.d.ts.map +1 -0
- package/dist/kernel/runtime.js +108 -0
- package/dist/keyring/index.d.ts +2 -0
- package/dist/keyring/index.d.ts.map +1 -0
- package/dist/keyring/index.js +1 -0
- package/dist/keyring/resolver.d.ts +9 -0
- package/dist/keyring/resolver.d.ts.map +1 -0
- package/dist/keyring/resolver.js +62 -0
- package/dist/run-agent.d.ts +19 -0
- package/dist/run-agent.d.ts.map +1 -0
- package/dist/run-agent.js +25 -0
- package/dist/structured/extract.d.ts +27 -0
- package/dist/structured/extract.d.ts.map +1 -0
- package/dist/structured/extract.js +188 -0
- package/dist/structured/run-structured.d.ts +83 -0
- package/dist/structured/run-structured.d.ts.map +1 -0
- package/dist/structured/run-structured.js +202 -0
- package/dist/structured/standard-schema.d.ts +34 -0
- package/dist/structured/standard-schema.d.ts.map +1 -0
- package/dist/structured/standard-schema.js +6 -0
- package/dist/testing/fake-agent.d.ts +32 -0
- package/dist/testing/fake-agent.d.ts.map +1 -0
- package/dist/testing/fake-agent.js +43 -0
- package/dist/testing/fake-clock.d.ts +8 -0
- package/dist/testing/fake-clock.d.ts.map +1 -0
- package/dist/testing/fake-clock.js +44 -0
- package/dist/testing/fake-exec.d.ts +26 -0
- package/dist/testing/fake-exec.d.ts.map +1 -0
- package/dist/testing/fake-exec.js +69 -0
- package/dist/testing/fake-secrets.d.ts +3 -0
- package/dist/testing/fake-secrets.d.ts.map +1 -0
- package/dist/testing/fake-secrets.js +5 -0
- package/dist/testing/index.d.ts +10 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +9 -0
- package/package.json +75 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CLI login probe (E12): run an agent's "am I signed in?" subcommand
|
|
3
|
+
* under the candidate's auth env and map its exit code to an `AuthStatus`.
|
|
4
|
+
* Only the exit code matters — output is drained and discarded. A hung probe
|
|
5
|
+
* is killed after the timeout and reported as "unknown"; a hang proves
|
|
6
|
+
* nothing about the credential (probe-owned time mechanics, mirroring the run
|
|
7
|
+
* plane's kill escalation). Home-dir material handlers reuse this so the two
|
|
8
|
+
* built-in agents do not each carry a copy of the probe loop.
|
|
9
|
+
*/
|
|
10
|
+
import type { EnvPatch } from "../core/env.js";
|
|
11
|
+
import type { HostContext } from "../host/context.js";
|
|
12
|
+
import { type AuthStatus } from "./material.js";
|
|
13
|
+
export type CliLoginProbeOptions = {
|
|
14
|
+
readonly command: string;
|
|
15
|
+
readonly args: readonly string[];
|
|
16
|
+
readonly envPatch: EnvPatch;
|
|
17
|
+
readonly ctx: HostContext;
|
|
18
|
+
readonly timeoutMs?: number;
|
|
19
|
+
};
|
|
20
|
+
export declare function cliLoginProbe(options: CliLoginProbeOptions): Promise<AuthStatus>;
|
|
21
|
+
//# sourceMappingURL=login-probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login-probe.d.ts","sourceRoot":"","sources":["../../src/auth/login-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAI7D,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,UAAU,CAAC,CAgCrB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CLI login probe (E12): run an agent's "am I signed in?" subcommand
|
|
3
|
+
* under the candidate's auth env and map its exit code to an `AuthStatus`.
|
|
4
|
+
* Only the exit code matters — output is drained and discarded. A hung probe
|
|
5
|
+
* is killed after the timeout and reported as "unknown"; a hang proves
|
|
6
|
+
* nothing about the credential (probe-owned time mechanics, mirroring the run
|
|
7
|
+
* plane's kill escalation). Home-dir material handlers reuse this so the two
|
|
8
|
+
* built-in agents do not each carry a copy of the probe loop.
|
|
9
|
+
*/
|
|
10
|
+
import { applyEnvPatch } from "../core/env.js";
|
|
11
|
+
import { PROCESS_SIGNAL } from "../core/values.js";
|
|
12
|
+
import { AUTH_STATUS } from "./material.js";
|
|
13
|
+
const DEFAULT_LOGIN_PROBE_TIMEOUT_MS = 30_000;
|
|
14
|
+
export async function cliLoginProbe(options) {
|
|
15
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_LOGIN_PROBE_TIMEOUT_MS;
|
|
16
|
+
const env = applyEnvPatch(options.ctx.env, options.envPatch);
|
|
17
|
+
const command = await options.ctx.exec.which(options.command, env);
|
|
18
|
+
if (command === null) {
|
|
19
|
+
// No binary on PATH: the probe cannot run, so it proves nothing.
|
|
20
|
+
return AUTH_STATUS.unknown;
|
|
21
|
+
}
|
|
22
|
+
const probe = options.ctx.exec.spawn({
|
|
23
|
+
command,
|
|
24
|
+
args: [...options.args],
|
|
25
|
+
cwd: options.ctx.location.homeDir,
|
|
26
|
+
env,
|
|
27
|
+
stdin: null,
|
|
28
|
+
});
|
|
29
|
+
let timedOut = false;
|
|
30
|
+
const cancelTimeout = options.ctx.clock.setTimeout(() => {
|
|
31
|
+
timedOut = true;
|
|
32
|
+
probe.kill(PROCESS_SIGNAL.sigkill);
|
|
33
|
+
}, timeoutMs);
|
|
34
|
+
try {
|
|
35
|
+
for await (const _chunk of probe.chunks) {
|
|
36
|
+
// Drain; only the exit code matters for the login probe.
|
|
37
|
+
}
|
|
38
|
+
const exit = await probe.exit;
|
|
39
|
+
if (timedOut) {
|
|
40
|
+
return AUTH_STATUS.unknown;
|
|
41
|
+
}
|
|
42
|
+
return exit.code === 0 ? AUTH_STATUS.valid : AUTH_STATUS.invalid;
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
cancelTimeout();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Clock, Exec } from "../core/ports.js";
|
|
2
|
+
import type { OutputChannel } from "../core/values.js";
|
|
3
|
+
import type { AuthMaterial, AuthStatus } from "./material.js";
|
|
4
|
+
export declare const LOGIN_METHOD: {
|
|
5
|
+
readonly oauth: "oauth";
|
|
6
|
+
readonly device: "device";
|
|
7
|
+
};
|
|
8
|
+
export type LoginMethod = (typeof LOGIN_METHOD)[keyof typeof LOGIN_METHOD];
|
|
9
|
+
export declare const LOGIN_EVENT_TYPE: {
|
|
10
|
+
readonly openUrl: "open-url";
|
|
11
|
+
readonly deviceCode: "device-code";
|
|
12
|
+
readonly output: "output";
|
|
13
|
+
};
|
|
14
|
+
export type LoginRequest = {
|
|
15
|
+
readonly method: LoginMethod;
|
|
16
|
+
readonly homeDir: string;
|
|
17
|
+
/**
|
|
18
|
+
* Caller cancellation, mirroring `RunOptions.signal`. The login driver
|
|
19
|
+
* funnels it into the `LoginContext` signal the handler drives the CLI
|
|
20
|
+
* with, so a hung device flow aborts instead of waiting out the total
|
|
21
|
+
* timeout. Absent means "no caller cancellation".
|
|
22
|
+
*/
|
|
23
|
+
readonly signal?: AbortSignal;
|
|
24
|
+
};
|
|
25
|
+
export type LoginEvent = {
|
|
26
|
+
readonly type: typeof LOGIN_EVENT_TYPE.openUrl;
|
|
27
|
+
readonly url: string;
|
|
28
|
+
} | {
|
|
29
|
+
readonly type: typeof LOGIN_EVENT_TYPE.deviceCode;
|
|
30
|
+
readonly code: string;
|
|
31
|
+
readonly url: string;
|
|
32
|
+
readonly expiresAt: string | null;
|
|
33
|
+
} | {
|
|
34
|
+
readonly type: typeof LOGIN_EVENT_TYPE.output;
|
|
35
|
+
readonly channel: OutputChannel;
|
|
36
|
+
readonly chunk: string;
|
|
37
|
+
};
|
|
38
|
+
export type LoginOutcome = {
|
|
39
|
+
readonly material: AuthMaterial;
|
|
40
|
+
readonly status: AuthStatus;
|
|
41
|
+
};
|
|
42
|
+
export type LoginRun = AsyncGenerator<LoginEvent, LoginOutcome, void>;
|
|
43
|
+
/**
|
|
44
|
+
* What a login handler drives the CLI with — a first-class login-plane context,
|
|
45
|
+
* a sibling to `RunContext` (not `HostContext` with a bolt-on `signal`). It
|
|
46
|
+
* carries exactly what an Exec-driven login CLI needs: the resolved location for
|
|
47
|
+
* the child's cwd, the ports it spawns and times with, and the ONE stop channel.
|
|
48
|
+
* `signal` is always live — the driver supplies a never-aborting one when the
|
|
49
|
+
* caller passes none — so handlers read `ctx.signal.aborted` unconditionally and
|
|
50
|
+
* escalate SIGTERM→SIGKILL on abort. `http` / `logger` are intentionally absent
|
|
51
|
+
* (the CLI-over-Exec mechanism uses neither); a handler that needs one adds it.
|
|
52
|
+
*/
|
|
53
|
+
export type LoginContext = {
|
|
54
|
+
location: {
|
|
55
|
+
homeDir: string;
|
|
56
|
+
projectDir: string | null;
|
|
57
|
+
};
|
|
58
|
+
signal: AbortSignal;
|
|
59
|
+
env: Record<string, string>;
|
|
60
|
+
exec: Exec;
|
|
61
|
+
clock: Clock;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Cancellation lives on `ctx.signal`, so the handler-facing request drops
|
|
65
|
+
* `signal` via `Omit` (which tracks `LoginRequest`, so no twin can drift) — one
|
|
66
|
+
* cancellation source, the way run adapters see `ResolvedRunOptions` without
|
|
67
|
+
* `RunOptions.signal`.
|
|
68
|
+
*/
|
|
69
|
+
export type LoginHandler = (request: Omit<LoginRequest, "signal">, ctx: LoginContext) => LoginRun;
|
|
70
|
+
export interface LoginCapability {
|
|
71
|
+
readonly methods: {
|
|
72
|
+
readonly [M in LoginMethod]?: LoginHandler;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export type LoginHandle = PromiseLike<LoginOutcome> & {
|
|
76
|
+
readonly events: AsyncIterable<LoginEvent>;
|
|
77
|
+
readonly result: Promise<LoginOutcome>;
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=login.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/auth/login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE9D,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE3E,eAAO,MAAM,gBAAgB;;;;CAInB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,gBAAgB,CAAC,OAAO,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACxE;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,gBAAgB,CAAC,UAAU,CAAC;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,gBAAgB,CAAC,MAAM,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEN,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,cAAc,CAAC,UAAU,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;AAEtE;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACzD,MAAM,EAAE,WAAW,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EACrC,GAAG,EAAE,YAAY,KACd,QAAQ,CAAC;AAEd,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,EAAE,CAAC,IAAI,WAAW,CAAC,CAAC,EAAE,YAAY;KAC3C,CAAC;CACH;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,YAAY,CAAC,GAAG;IACpD,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CACxC,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth model (design "Auth"): two materials, per-kind handler records.
|
|
3
|
+
* Inheriting the base env is the ABSENCE of a profile — there is no
|
|
4
|
+
* "inherit" sentinel. Hard rule A9: no secret value ever appears in a
|
|
5
|
+
* persisted structure; refs, env names, and paths only.
|
|
6
|
+
*/
|
|
7
|
+
import type { SecretRef } from "@alpacakit/core";
|
|
8
|
+
import type { EnvPatch } from "../core/env.js";
|
|
9
|
+
import type { SecretResolvers } from "../core/ports.js";
|
|
10
|
+
import type { HostContext } from "../host/context.js";
|
|
11
|
+
export type { SecretRef } from "@alpacakit/core";
|
|
12
|
+
export declare const AUTH_MATERIAL_KIND: {
|
|
13
|
+
readonly homeDir: "home-dir";
|
|
14
|
+
readonly apiKey: "api-key";
|
|
15
|
+
};
|
|
16
|
+
export type AuthMaterial = {
|
|
17
|
+
kind: typeof AUTH_MATERIAL_KIND.homeDir;
|
|
18
|
+
path: string;
|
|
19
|
+
} | {
|
|
20
|
+
kind: typeof AUTH_MATERIAL_KIND.apiKey;
|
|
21
|
+
secret: SecretRef;
|
|
22
|
+
};
|
|
23
|
+
export type AuthMaterialKind = AuthMaterial["kind"];
|
|
24
|
+
export declare function authMaterialRequiresSecret(kind: AuthMaterialKind): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* What an agent's auth facet reports for one supported material kind, so a
|
|
27
|
+
* consumer can build a sign-in UI without hardcoding which agent takes what:
|
|
28
|
+
* `requiresSecret` distinguishes a `SecretRef` input from a path/login, and
|
|
29
|
+
* `canProbe` says whether `check` can verify the credential.
|
|
30
|
+
*/
|
|
31
|
+
export type AuthMaterialDescriptor = {
|
|
32
|
+
kind: AuthMaterialKind;
|
|
33
|
+
requiresSecret: boolean;
|
|
34
|
+
canProbe: boolean;
|
|
35
|
+
};
|
|
36
|
+
export type AuthProfile<Id extends string = string> = {
|
|
37
|
+
readonly id: string;
|
|
38
|
+
readonly agentId: Id;
|
|
39
|
+
readonly material: AuthMaterial;
|
|
40
|
+
};
|
|
41
|
+
export type HomeDirProfileOptions<Id extends string = string> = {
|
|
42
|
+
readonly id: string;
|
|
43
|
+
readonly agentId: Id;
|
|
44
|
+
readonly path: string;
|
|
45
|
+
};
|
|
46
|
+
export type ApiKeyProfileOptions<Id extends string = string> = {
|
|
47
|
+
readonly id: string;
|
|
48
|
+
readonly agentId: Id;
|
|
49
|
+
readonly secret: SecretRef;
|
|
50
|
+
};
|
|
51
|
+
export declare function createHomeDirProfile<const Id extends string>(options: HomeDirProfileOptions<Id>): AuthProfile<Id>;
|
|
52
|
+
export declare function createApiKeyProfile<const Id extends string>(options: ApiKeyProfileOptions<Id>): AuthProfile<Id>;
|
|
53
|
+
export declare const AUTH_STATUS: {
|
|
54
|
+
readonly valid: "valid";
|
|
55
|
+
readonly invalid: "invalid";
|
|
56
|
+
readonly unknown: "unknown";
|
|
57
|
+
};
|
|
58
|
+
export type AuthStatus = (typeof AUTH_STATUS)[keyof typeof AUTH_STATUS];
|
|
59
|
+
export type MaterialHandler<K extends AuthMaterialKind> = {
|
|
60
|
+
toEnv(material: Extract<AuthMaterial, {
|
|
61
|
+
kind: K;
|
|
62
|
+
}>, secrets: SecretResolvers): Promise<EnvPatch>;
|
|
63
|
+
check?(material: Extract<AuthMaterial, {
|
|
64
|
+
kind: K;
|
|
65
|
+
}>, ctx: HostContext): Promise<AuthStatus>;
|
|
66
|
+
};
|
|
67
|
+
export type EnvVarAuthMaterialOptions<K extends AuthMaterialKind> = {
|
|
68
|
+
readonly set: (material: Extract<AuthMaterial, {
|
|
69
|
+
kind: K;
|
|
70
|
+
}>, secrets: SecretResolvers) => Promise<Record<string, string>> | Record<string, string>;
|
|
71
|
+
readonly unset: readonly string[];
|
|
72
|
+
readonly check?: (material: Extract<AuthMaterial, {
|
|
73
|
+
kind: K;
|
|
74
|
+
}>, ctx: HostContext) => Promise<AuthStatus>;
|
|
75
|
+
};
|
|
76
|
+
export declare function envVarAuthMaterial<K extends AuthMaterialKind>(options: EnvVarAuthMaterialOptions<K>): MaterialHandler<K>;
|
|
77
|
+
/**
|
|
78
|
+
* Keyed handler record (design principle 7): key presence declares
|
|
79
|
+
* support; absence is a typed `invalid_input`, enforced centrally.
|
|
80
|
+
*/
|
|
81
|
+
export type MaterialHandlers = {
|
|
82
|
+
[K in AuthMaterialKind]?: MaterialHandler<K>;
|
|
83
|
+
};
|
|
84
|
+
export interface AuthCapability {
|
|
85
|
+
materials: MaterialHandlers;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=material.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../../src/auth/material.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth model (design "Auth"): two materials, per-kind handler records.
|
|
3
|
+
* Inheriting the base env is the ABSENCE of a profile — there is no
|
|
4
|
+
* "inherit" sentinel. Hard rule A9: no secret value ever appears in a
|
|
5
|
+
* persisted structure; refs, env names, and paths only.
|
|
6
|
+
*/
|
|
7
|
+
export const AUTH_MATERIAL_KIND = {
|
|
8
|
+
homeDir: "home-dir",
|
|
9
|
+
apiKey: "api-key",
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Static per-kind facts for capability introspection (a keyed record, not a
|
|
13
|
+
* branch): `requiresSecret` says whether the material carries a `SecretRef`
|
|
14
|
+
* (api-key) or only a path (home-dir). Adding a kind adds a row.
|
|
15
|
+
*/
|
|
16
|
+
const AUTH_MATERIAL_REQUIRES_SECRET = {
|
|
17
|
+
[AUTH_MATERIAL_KIND.homeDir]: false,
|
|
18
|
+
[AUTH_MATERIAL_KIND.apiKey]: true,
|
|
19
|
+
};
|
|
20
|
+
export function authMaterialRequiresSecret(kind) {
|
|
21
|
+
return AUTH_MATERIAL_REQUIRES_SECRET[kind];
|
|
22
|
+
}
|
|
23
|
+
export function createHomeDirProfile(options) {
|
|
24
|
+
return {
|
|
25
|
+
id: options.id,
|
|
26
|
+
agentId: options.agentId,
|
|
27
|
+
material: {
|
|
28
|
+
kind: AUTH_MATERIAL_KIND.homeDir,
|
|
29
|
+
path: options.path,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function createApiKeyProfile(options) {
|
|
34
|
+
return {
|
|
35
|
+
id: options.id,
|
|
36
|
+
agentId: options.agentId,
|
|
37
|
+
material: {
|
|
38
|
+
kind: AUTH_MATERIAL_KIND.apiKey,
|
|
39
|
+
secret: options.secret,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export const AUTH_STATUS = {
|
|
44
|
+
valid: "valid",
|
|
45
|
+
invalid: "invalid",
|
|
46
|
+
unknown: "unknown",
|
|
47
|
+
};
|
|
48
|
+
export function envVarAuthMaterial(options) {
|
|
49
|
+
const handler = {
|
|
50
|
+
toEnv: async (material, secrets) => ({
|
|
51
|
+
set: await options.set(material, secrets),
|
|
52
|
+
unset: [...options.unset],
|
|
53
|
+
}),
|
|
54
|
+
};
|
|
55
|
+
if (options.check !== undefined) {
|
|
56
|
+
handler.check = options.check;
|
|
57
|
+
}
|
|
58
|
+
return handler;
|
|
59
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal file-backed profile store (A11): rows follow rule 2 and never
|
|
3
|
+
* contain secret values (A9) — materials carry refs and paths only.
|
|
4
|
+
* Profile management UX is consumer territory. Unlike fleet state, this
|
|
5
|
+
* is durable user data: malformed or unknown-version files are typed
|
|
6
|
+
* errors, never silent resets.
|
|
7
|
+
*/
|
|
8
|
+
import { type AuthProfile } from "./material.js";
|
|
9
|
+
export interface ProfileStore {
|
|
10
|
+
list(): Promise<AuthProfile[]>;
|
|
11
|
+
save(profiles: AuthProfile[]): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare function fileProfileStore(filePath: string): ProfileStore;
|
|
14
|
+
//# sourceMappingURL=profile-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-store.d.ts","sourceRoot":"","sources":["../../src/auth/profile-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAcrE,MAAM,WAAW,YAAY;IAC3B,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/B,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AA6FD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAE/D"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal file-backed profile store (A11): rows follow rule 2 and never
|
|
3
|
+
* contain secret values (A9) — materials carry refs and paths only.
|
|
4
|
+
* Profile management UX is consumer territory. Unlike fleet state, this
|
|
5
|
+
* is durable user data: malformed or unknown-version files are typed
|
|
6
|
+
* errors, never silent resets.
|
|
7
|
+
*/
|
|
8
|
+
import { readFile } from "node:fs/promises";
|
|
9
|
+
import { AGENT_ERROR_CODE, AgentError } from "../core/error.js";
|
|
10
|
+
import { isErrnoCode, writeFileAtomically } from "../core/fs.js";
|
|
11
|
+
import { readUnknownRecord } from "../core/json.js";
|
|
12
|
+
import { TEXT_ENCODING } from "../core/values.js";
|
|
13
|
+
import { AUTH_MATERIAL_KIND } from "./material.js";
|
|
14
|
+
const PROFILE_FILE_VERSION = 1;
|
|
15
|
+
const PROFILE_STORE_ERROR_REASON = {
|
|
16
|
+
unreadable: "unreadable file",
|
|
17
|
+
malformedJson: "malformed JSON",
|
|
18
|
+
rootMustBeObject: "root must be an object",
|
|
19
|
+
unsupportedVersion: "unsupported version",
|
|
20
|
+
invalidProfiles: "profiles must be auth profile records",
|
|
21
|
+
};
|
|
22
|
+
function profileStoreError(reason, cause) {
|
|
23
|
+
return new AgentError({
|
|
24
|
+
code: AGENT_ERROR_CODE.invalidInput,
|
|
25
|
+
message: `Invalid auth profile store: ${reason}`,
|
|
26
|
+
data: { reason },
|
|
27
|
+
...(cause === undefined ? {} : { cause }),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function isSecretRef(value) {
|
|
31
|
+
const record = readUnknownRecord(value);
|
|
32
|
+
if (record === null) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const { resolver, id } = record;
|
|
36
|
+
return typeof resolver === "string" && typeof id === "string";
|
|
37
|
+
}
|
|
38
|
+
function isAuthProfile(value) {
|
|
39
|
+
const record = readUnknownRecord(value);
|
|
40
|
+
if (record === null) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
const { id, agentId, material: materialValue } = record;
|
|
44
|
+
const material = readUnknownRecord(materialValue);
|
|
45
|
+
if (material === null) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const { kind, path, secret } = material;
|
|
49
|
+
const materialValid = (kind === AUTH_MATERIAL_KIND.homeDir && typeof path === "string") ||
|
|
50
|
+
(kind === AUTH_MATERIAL_KIND.apiKey && isSecretRef(secret));
|
|
51
|
+
return typeof id === "string" && typeof agentId === "string" && materialValid;
|
|
52
|
+
}
|
|
53
|
+
function parseProfileFile(raw) {
|
|
54
|
+
let parsed;
|
|
55
|
+
try {
|
|
56
|
+
parsed = JSON.parse(raw);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw profileStoreError(PROFILE_STORE_ERROR_REASON.malformedJson, error);
|
|
60
|
+
}
|
|
61
|
+
const root = readUnknownRecord(parsed);
|
|
62
|
+
if (root === null) {
|
|
63
|
+
throw profileStoreError(PROFILE_STORE_ERROR_REASON.rootMustBeObject);
|
|
64
|
+
}
|
|
65
|
+
const { version, profiles } = root;
|
|
66
|
+
if (version !== PROFILE_FILE_VERSION) {
|
|
67
|
+
throw profileStoreError(PROFILE_STORE_ERROR_REASON.unsupportedVersion);
|
|
68
|
+
}
|
|
69
|
+
if (!Array.isArray(profiles) || !profiles.every(isAuthProfile)) {
|
|
70
|
+
throw profileStoreError(PROFILE_STORE_ERROR_REASON.invalidProfiles);
|
|
71
|
+
}
|
|
72
|
+
return profiles;
|
|
73
|
+
}
|
|
74
|
+
class FileProfileStore {
|
|
75
|
+
filePath;
|
|
76
|
+
constructor(filePath) {
|
|
77
|
+
this.filePath = filePath;
|
|
78
|
+
}
|
|
79
|
+
async list() {
|
|
80
|
+
let raw;
|
|
81
|
+
try {
|
|
82
|
+
raw = await readFile(this.filePath, TEXT_ENCODING);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
// Durable user data: only "not created yet" reads as empty; any
|
|
86
|
+
// other read failure surfaces instead of masking real profiles.
|
|
87
|
+
if (isErrnoCode(error, "ENOENT")) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
throw profileStoreError(PROFILE_STORE_ERROR_REASON.unreadable, error);
|
|
91
|
+
}
|
|
92
|
+
return parseProfileFile(raw);
|
|
93
|
+
}
|
|
94
|
+
async save(profiles) {
|
|
95
|
+
const file = { version: PROFILE_FILE_VERSION, profiles };
|
|
96
|
+
await writeFileAtomically(this.filePath, `${JSON.stringify(file, null, 2)}\n`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export function fileProfileStore(filePath) {
|
|
100
|
+
return new FileProfileStore(filePath);
|
|
101
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SecretResolver, SecretResolvers } from "../core/ports.js";
|
|
2
|
+
import type { SecretRef } from "./material.js";
|
|
3
|
+
/**
|
|
4
|
+
* The only sanctioned way to index the resolver registry: unknown
|
|
5
|
+
* resolver key is a typed `invalid_input`, resolution to null is an
|
|
6
|
+
* `auth` failure. Adapters never index the registry raw.
|
|
7
|
+
*/
|
|
8
|
+
export declare function requireSecret(resolvers: SecretResolvers, ref: SecretRef): Promise<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Built-in "env" resolver: a secret ref id is an environment variable
|
|
11
|
+
* name. Reading `process.env` IS this adapter's job — it is the boundary.
|
|
12
|
+
*/
|
|
13
|
+
export declare function envResolver(): SecretResolver;
|
|
14
|
+
//# sourceMappingURL=secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/auth/secrets.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,eAAe,EAC1B,GAAG,EAAE,SAAS,GACb,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,cAAc,CAS5C"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { AGENT_ERROR_CODE, AgentError, AUTH_FAILURE_REASON, } from "../core/error.js";
|
|
2
|
+
/**
|
|
3
|
+
* The only sanctioned way to index the resolver registry: unknown
|
|
4
|
+
* resolver key is a typed `invalid_input`, resolution to null is an
|
|
5
|
+
* `auth` failure. Adapters never index the registry raw.
|
|
6
|
+
*/
|
|
7
|
+
export async function requireSecret(resolvers, ref) {
|
|
8
|
+
const resolver = resolvers[ref.resolver];
|
|
9
|
+
if (resolver === undefined) {
|
|
10
|
+
throw new AgentError({
|
|
11
|
+
code: AGENT_ERROR_CODE.invalidInput,
|
|
12
|
+
message: `Unknown secret resolver "${ref.resolver}"`,
|
|
13
|
+
data: { reason: `no secret resolver registered for "${ref.resolver}"` },
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const value = await resolver.resolve(ref.id);
|
|
17
|
+
if (value === null || value === "") {
|
|
18
|
+
throw new AgentError({
|
|
19
|
+
code: AGENT_ERROR_CODE.auth,
|
|
20
|
+
message: `Secret "${ref.id}" is not available from resolver "${ref.resolver}"`,
|
|
21
|
+
data: {
|
|
22
|
+
reason: AUTH_FAILURE_REASON.invalidCredentials,
|
|
23
|
+
detail: `secret "${ref.id}" unresolved`,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Built-in "env" resolver: a secret ref id is an environment variable
|
|
31
|
+
* name. Reading `process.env` IS this adapter's job — it is the boundary.
|
|
32
|
+
*/
|
|
33
|
+
export function envResolver() {
|
|
34
|
+
return {
|
|
35
|
+
resolve: (id) => {
|
|
36
|
+
const value = process.env[id];
|
|
37
|
+
return Promise.resolve(value === undefined || value === "" ? null : value);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Clock, Exec } from "../core/ports.js";
|
|
2
|
+
import type { CodexAppServerMethods, CodexMcpServerStatus } from "./protocol.js";
|
|
3
|
+
/**
|
|
4
|
+
* How the client identifies itself to the codex app-server `initialize`
|
|
5
|
+
* handshake. The library default is neutral (see `DEFAULT_APP_SERVER_CLIENT_INFO`);
|
|
6
|
+
* a product may override it to surface its own name in codex logs without
|
|
7
|
+
* that branding being baked into the OSS package.
|
|
8
|
+
*/
|
|
9
|
+
export type AppServerClientInfo = {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly title: string;
|
|
12
|
+
readonly version: string;
|
|
13
|
+
};
|
|
14
|
+
export type CodexAppServerOptions = {
|
|
15
|
+
readonly exec: Exec;
|
|
16
|
+
readonly clock: Clock;
|
|
17
|
+
readonly env: Record<string, string>;
|
|
18
|
+
readonly cwd: string;
|
|
19
|
+
readonly command?: string;
|
|
20
|
+
readonly requestTimeoutMs?: number;
|
|
21
|
+
readonly clientInfo?: AppServerClientInfo;
|
|
22
|
+
};
|
|
23
|
+
export interface CodexAppServer {
|
|
24
|
+
request<M extends keyof CodexAppServerMethods>(method: M, params: CodexAppServerMethods[M]["params"]): Promise<CodexAppServerMethods[M]["result"]>;
|
|
25
|
+
close(): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export declare function createCodexAppServer(options: CodexAppServerOptions): CodexAppServer;
|
|
28
|
+
export declare function withCodexAppServer<T>(options: CodexAppServerOptions, task: (client: CodexAppServer) => Promise<T>): Promise<T>;
|
|
29
|
+
export declare function listAllCodexMcpServerStatuses(client: CodexAppServer): Promise<CodexMcpServerStatus[]>;
|
|
30
|
+
//# sourceMappingURL=app-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-server.d.ts","sourceRoot":"","sources":["../../src/codex/app-server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAA0B,MAAM,kBAAkB,CAAC;AAG5E,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAErB,MAAM,eAAe,CAAC;AAOvB;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAC3C,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,CAAC,SAAS,MAAM,qBAAqB,EAC3C,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GACzC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAwED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,GAC7B,cAAc,CAEhB;AAED,wBAAsB,kBAAkB,CAAC,CAAC,EACxC,OAAO,EAAE,qBAAqB,EAC9B,IAAI,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC,CAOZ;AAED,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAgBjC"}
|