@alpacakit/agents-conventions 0.1.0-beta.36 → 0.1.0-beta.37

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/README.md CHANGED
@@ -1,12 +1,119 @@
1
1
  # @alpacakit/agents-conventions
2
2
 
3
- AlpacaLoop-family conventions for [`@alpacakit/agents`](../agents) machine-local
4
- config: the `ALPACA_AGENTS_HOME` / `~/.alpaca/agents` config root, the
5
- `alpacaloop.agents-home` keyring service, and the managed-home layout shared
6
- by AlpacaLoop-family products (the CLI, promptopt, codehint).
7
-
8
- This package is published with the other `@alpacakit/*` libraries. It is a
9
- plain consumer of the neutral `@alpacakit/agents` public API — the same shape
10
- any third party would write for their own convention. The general library
11
- ships a convention-neutral `@alpacakit/agents/config/xdg` preset; this package
12
- provides the AlpacaLoop-specific instance.
3
+ The AlpacaKit family's **shared agents home**: where it lives, how an agent is
4
+ registered into it, and the `agent` command every family product mounts.
5
+
6
+ This lives outside the neutral [`@alpacakit/agents`](../agents) package on
7
+ purpose. It encodes the family's `ALPACA_AGENTS_HOME` / `~/.alpaca/agents`
8
+ config root, the `alpaca.agents` keychain service, the managed-home layout, and
9
+ the part that matters most — the **order and failure policy** of registering
10
+ a credential. It is a plain consumer of the agents package's public API: the
11
+ same shape any third party would write for their own convention. The general
12
+ library ships a convention-neutral `@alpacakit/agents/config/xdg` preset; this
13
+ package is the AlpacaKit-specific instance.
14
+
15
+ ## Procedures
16
+
17
+ Every procedure takes `{ homeDir, env }` and opens the same shared home.
18
+ `ports` and `keyring` are injectable so tests drive the real path without a
19
+ subprocess or a real keychain. Expected outcomes come back as a result type
20
+ with a `kind`; only faults throw.
21
+
22
+ | Procedure | Result kinds |
23
+ |---|---|
24
+ | `listAgentsHome` | `{ agentsHome, entries }` — every candidate with its readiness |
25
+ | `loginManagedHome` | `registered` / `profile_exists` / `unknown_agent` / `unsupported` / `login_failed` |
26
+ | `addApiKeyProfile` | `registered` / `profile_exists` / `empty_key` |
27
+ | `addAgentConfig` | `added` / `exists` |
28
+ | `removeAgentsHomeEntry` | `removed_profile` / `removed_agent_config` / `not_found` |
29
+
30
+ Every procedure that takes a record name can also answer `invalid_name`
31
+ (carrying the `rule` in words, so a product need not restate the grammar).
32
+
33
+ The policies these procedures own, so no product re-decides them:
34
+
35
+ - **`listAgentsHome`** probes a profile-backed candidate with that profile's
36
+ environment applied — the same `auth.toEnv` patch a run gets — so it can
37
+ never report the ambient login for a profile that has its own credential. An
38
+ agent that declares no availability probe reports `null`, not a guess.
39
+ - **`loginManagedHome`** writes no profile when the sign-in fails, but keeps
40
+ the managed home so a retry resumes from it. A sign-in that succeeds and then
41
+ cannot be recorded is a **fault**, not a result: discarding a completed
42
+ browser flow would leave a live credential nobody knows about. An id this
43
+ home does not have (`unknown_agent`) is kept apart from a method the agent
44
+ does not offer (`unsupported`) — the two have different fixes.
45
+ - **`addApiKeyProfile`** rejects a blank key (`empty_key`) before touching the
46
+ keychain, stores the key trimmed so a piped newline never reaches the
47
+ provider, then references it — and removes the stored key again if the
48
+ reference cannot be written.
49
+ - **`addAgentConfig`** dispatches on `input.kind`, the same discriminator
50
+ `agent add --kind` carries, so the CLI projection is the input verbatim.
51
+ - **Record names** (profile ids, agent config ids) match
52
+ `^[a-z0-9][a-z0-9._-]{0,63}$`. A name is not free text: it becomes a path
53
+ segment under `managed-homes/` and a segment of a keychain account, so an
54
+ unconstrained one would decide where this package writes and what it deletes.
55
+ `/cli` rejects it at the codec and the procedures repeat the check for
56
+ callers that skip the CLI; `resolveManagedHomePath` throws rather than build
57
+ a path outside the shared home.
58
+ - **`removeAgentsHomeEntry`** removes the record first, then only the artifacts
59
+ this package created. A home the operator pointed at themselves, and a secret
60
+ behind someone else's resolver, are left alone.
61
+
62
+ ```ts
63
+ import { loginManagedHome } from "@alpacakit/agents-conventions";
64
+
65
+ const result = await loginManagedHome({
66
+ homeDir: os.homedir(),
67
+ env: process.env,
68
+ profileId: "judge-codex",
69
+ agentId: "codex",
70
+ method: "oauth",
71
+ onEvent: (event) => render(event),
72
+ });
73
+ ```
74
+
75
+ ## `@alpacakit/agents-conventions/cli`
76
+
77
+ The `agent` command surface, as **data** — no `bin`, no handler, no I/O. It
78
+ owns the command paths, the flags, the projection into a procedure input, and
79
+ the JSON each result must be, so `alpacaloop agent login` and
80
+ `promptopt agent login` are the same command.
81
+
82
+ ```
83
+ agent list
84
+ agent login <PROFILE> --agent <claude|codex> [--method oauth|device]
85
+ agent credential add <PROFILE> --agent <ID> --stdin (--stdin is required)
86
+ agent add <ID> --kind openai-compatible --base-url <URL> --model <M>
87
+ [--api-key-env <VAR>] [--engine fetch|pi]
88
+ agent remove <NAME>
89
+ ```
90
+
91
+ Mount the node in the product's tree and bind a handler per endpoint — call the
92
+ procedure, render the result:
93
+
94
+ ```ts
95
+ import { AGENT_CLI_SURFACE } from "@alpacakit/agents-conventions/cli";
96
+ import { loginManagedHome } from "@alpacakit/agents-conventions";
97
+ import { handleCliEndpoint } from "@alpacakit/channels/cli";
98
+
99
+ // 1. mount: put AGENT_CLI_SURFACE.node among the product root's children.
100
+ // 2. bind:
101
+ handleCliEndpoint(AGENT_CLI_SURFACE.endpoints.login, async ({ projection }) =>
102
+ render(await loginManagedHome({ ...projection, homeDir, env })),
103
+ );
104
+ ```
105
+
106
+ Each endpoint's projection is the matching procedure's input verbatim, so the
107
+ handler never re-maps fields: `endpoints.add` projects `{ kind, id, baseUrl,
108
+ model, apiKeyEnv?, engine? }` straight into `addAgentConfig`. Optional flags
109
+ stay absent when unset — `--engine` is defaulted once, by the agent-config
110
+ payload that persists it, never a second time by the command surface. The addable kinds
111
+ (`AGENT_ADD_KIND`) live on the root export, next to the procedure that acts on
112
+ them — `/cli` only spells them as a flag.
113
+
114
+ `AGENT_CLI_SURFACE.outputs` carries the same contracts for products that emit
115
+ machine-readable output.
116
+
117
+ `@alpacakit/channels` and `zod` are **peer** dependencies of this package: they
118
+ are needed only by `/cli`, so importing the procedures never drags a CLI
119
+ framework in.
@@ -0,0 +1,209 @@
1
+ /**
2
+ * The JSON shape of every `agent` command result. These are the CONTRACT, not
3
+ * a convenience: an app may render the result any way it likes, but what it
4
+ * emits as data is fixed here so `alpacaloop agent list --json` and
5
+ * `promptopt agent list --json` are the same document.
6
+ */
7
+ import { z } from "zod";
8
+ export declare const profileSchema: z.ZodObject<{
9
+ id: z.ZodString;
10
+ agentId: z.ZodString;
11
+ material: z.ZodDiscriminatedUnion<[z.ZodObject<{
12
+ kind: z.ZodLiteral<"home-dir">;
13
+ path: z.ZodString;
14
+ }, z.core.$strict>, z.ZodObject<{
15
+ kind: z.ZodLiteral<"api-key">;
16
+ secret: z.ZodObject<{
17
+ resolver: z.ZodString;
18
+ id: z.ZodString;
19
+ }, z.core.$strict>;
20
+ }, z.core.$strict>], "kind">;
21
+ }, z.core.$strict>;
22
+ export declare const agentConfigSchema: z.ZodObject<{
23
+ id: z.ZodString;
24
+ kind: z.ZodString;
25
+ enabled: z.ZodBoolean;
26
+ payload: z.ZodRecord<z.ZodString, z.ZodType<import("@alpacakit/agents").JsonValue, unknown, z.core.$ZodTypeInternals<import("@alpacakit/agents").JsonValue, unknown>>>;
27
+ }, z.core.$strict>;
28
+ /** `null` when the agent declares no availability probe at all. */
29
+ export declare const availabilitySchema: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
30
+ status: z.ZodLiteral<"runnable">;
31
+ }, z.core.$strict>, z.ZodObject<{
32
+ status: z.ZodLiteral<"unavailable">;
33
+ reason: z.ZodEnum<{
34
+ command_missing: "command_missing";
35
+ authentication_required: "authentication_required";
36
+ }>;
37
+ remediation: z.ZodNullable<z.ZodObject<{
38
+ detail: z.ZodString;
39
+ command: z.ZodNullable<z.ZodObject<{
40
+ executable: z.ZodString;
41
+ args: z.ZodArray<z.ZodString>;
42
+ }, z.core.$strict>>;
43
+ }, z.core.$strict>>;
44
+ }, z.core.$strict>, z.ZodObject<{
45
+ status: z.ZodLiteral<"indeterminate">;
46
+ reason: z.ZodEnum<{
47
+ probe_timeout: "probe_timeout";
48
+ probe_fault: "probe_fault";
49
+ }>;
50
+ detail: z.ZodString;
51
+ }, z.core.$strict>], "status">>;
52
+ export declare const agentListOutputSchema: z.ZodObject<{
53
+ agentsHome: z.ZodString;
54
+ entries: z.ZodArray<z.ZodObject<{
55
+ agentId: z.ZodString;
56
+ agentConfigId: z.ZodString;
57
+ kind: z.ZodString;
58
+ source: z.ZodEnum<{
59
+ profile: "profile";
60
+ ambient: "ambient";
61
+ configured: "configured";
62
+ }>;
63
+ profileId: z.ZodNullable<z.ZodString>;
64
+ availability: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
65
+ status: z.ZodLiteral<"runnable">;
66
+ }, z.core.$strict>, z.ZodObject<{
67
+ status: z.ZodLiteral<"unavailable">;
68
+ reason: z.ZodEnum<{
69
+ command_missing: "command_missing";
70
+ authentication_required: "authentication_required";
71
+ }>;
72
+ remediation: z.ZodNullable<z.ZodObject<{
73
+ detail: z.ZodString;
74
+ command: z.ZodNullable<z.ZodObject<{
75
+ executable: z.ZodString;
76
+ args: z.ZodArray<z.ZodString>;
77
+ }, z.core.$strict>>;
78
+ }, z.core.$strict>>;
79
+ }, z.core.$strict>, z.ZodObject<{
80
+ status: z.ZodLiteral<"indeterminate">;
81
+ reason: z.ZodEnum<{
82
+ probe_timeout: "probe_timeout";
83
+ probe_fault: "probe_fault";
84
+ }>;
85
+ detail: z.ZodString;
86
+ }, z.core.$strict>], "status">>;
87
+ }, z.core.$strict>>;
88
+ }, z.core.$strict>;
89
+ export declare const agentLoginOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
90
+ kind: z.ZodLiteral<"registered">;
91
+ profile: z.ZodObject<{
92
+ id: z.ZodString;
93
+ agentId: z.ZodString;
94
+ material: z.ZodDiscriminatedUnion<[z.ZodObject<{
95
+ kind: z.ZodLiteral<"home-dir">;
96
+ path: z.ZodString;
97
+ }, z.core.$strict>, z.ZodObject<{
98
+ kind: z.ZodLiteral<"api-key">;
99
+ secret: z.ZodObject<{
100
+ resolver: z.ZodString;
101
+ id: z.ZodString;
102
+ }, z.core.$strict>;
103
+ }, z.core.$strict>], "kind">;
104
+ }, z.core.$strict>;
105
+ managedHome: z.ZodString;
106
+ }, z.core.$strict>, z.ZodObject<{
107
+ kind: z.ZodLiteral<"profile_exists">;
108
+ profileId: z.ZodString;
109
+ }, z.core.$strict>, z.ZodObject<{
110
+ kind: z.ZodLiteral<"unknown_agent">;
111
+ agentId: z.ZodString;
112
+ known: z.ZodArray<z.ZodString>;
113
+ }, z.core.$strict>, z.ZodObject<{
114
+ kind: z.ZodLiteral<"unsupported">;
115
+ agentId: z.ZodString;
116
+ method: z.ZodString;
117
+ supported: z.ZodArray<z.ZodString>;
118
+ }, z.core.$strict>, z.ZodObject<{
119
+ kind: z.ZodLiteral<"login_failed">;
120
+ detail: z.ZodString;
121
+ managedHome: z.ZodString;
122
+ }, z.core.$strict>, z.ZodObject<{
123
+ kind: z.ZodLiteral<"invalid_name">;
124
+ name: z.ZodString;
125
+ rule: z.ZodString;
126
+ }, z.core.$strict>], "kind">;
127
+ export declare const agentCredentialAddOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
128
+ kind: z.ZodLiteral<"registered">;
129
+ profile: z.ZodObject<{
130
+ id: z.ZodString;
131
+ agentId: z.ZodString;
132
+ material: z.ZodDiscriminatedUnion<[z.ZodObject<{
133
+ kind: z.ZodLiteral<"home-dir">;
134
+ path: z.ZodString;
135
+ }, z.core.$strict>, z.ZodObject<{
136
+ kind: z.ZodLiteral<"api-key">;
137
+ secret: z.ZodObject<{
138
+ resolver: z.ZodString;
139
+ id: z.ZodString;
140
+ }, z.core.$strict>;
141
+ }, z.core.$strict>], "kind">;
142
+ }, z.core.$strict>;
143
+ }, z.core.$strict>, z.ZodObject<{
144
+ kind: z.ZodLiteral<"profile_exists">;
145
+ profileId: z.ZodString;
146
+ }, z.core.$strict>, z.ZodObject<{
147
+ kind: z.ZodLiteral<"empty_key">;
148
+ profileId: z.ZodString;
149
+ }, z.core.$strict>, z.ZodObject<{
150
+ kind: z.ZodLiteral<"invalid_name">;
151
+ name: z.ZodString;
152
+ rule: z.ZodString;
153
+ }, z.core.$strict>], "kind">;
154
+ export declare const agentAddOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
155
+ kind: z.ZodLiteral<"added">;
156
+ agentConfig: z.ZodObject<{
157
+ id: z.ZodString;
158
+ kind: z.ZodString;
159
+ enabled: z.ZodBoolean;
160
+ payload: z.ZodRecord<z.ZodString, z.ZodType<import("@alpacakit/agents").JsonValue, unknown, z.core.$ZodTypeInternals<import("@alpacakit/agents").JsonValue, unknown>>>;
161
+ }, z.core.$strict>;
162
+ }, z.core.$strict>, z.ZodObject<{
163
+ kind: z.ZodLiteral<"exists">;
164
+ id: z.ZodString;
165
+ }, z.core.$strict>, z.ZodObject<{
166
+ kind: z.ZodLiteral<"invalid_name">;
167
+ name: z.ZodString;
168
+ rule: z.ZodString;
169
+ }, z.core.$strict>], "kind">;
170
+ export declare const agentRemoveOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
171
+ kind: z.ZodLiteral<"removed_profile">;
172
+ profile: z.ZodObject<{
173
+ id: z.ZodString;
174
+ agentId: z.ZodString;
175
+ material: z.ZodDiscriminatedUnion<[z.ZodObject<{
176
+ kind: z.ZodLiteral<"home-dir">;
177
+ path: z.ZodString;
178
+ }, z.core.$strict>, z.ZodObject<{
179
+ kind: z.ZodLiteral<"api-key">;
180
+ secret: z.ZodObject<{
181
+ resolver: z.ZodString;
182
+ id: z.ZodString;
183
+ }, z.core.$strict>;
184
+ }, z.core.$strict>], "kind">;
185
+ }, z.core.$strict>;
186
+ removedManagedHome: z.ZodNullable<z.ZodString>;
187
+ removedSecret: z.ZodBoolean;
188
+ }, z.core.$strict>, z.ZodObject<{
189
+ kind: z.ZodLiteral<"removed_agent_config">;
190
+ agentConfig: z.ZodObject<{
191
+ id: z.ZodString;
192
+ kind: z.ZodString;
193
+ enabled: z.ZodBoolean;
194
+ payload: z.ZodRecord<z.ZodString, z.ZodType<import("@alpacakit/agents").JsonValue, unknown, z.core.$ZodTypeInternals<import("@alpacakit/agents").JsonValue, unknown>>>;
195
+ }, z.core.$strict>;
196
+ }, z.core.$strict>, z.ZodObject<{
197
+ kind: z.ZodLiteral<"not_found">;
198
+ name: z.ZodString;
199
+ }, z.core.$strict>, z.ZodObject<{
200
+ kind: z.ZodLiteral<"invalid_name">;
201
+ name: z.ZodString;
202
+ rule: z.ZodString;
203
+ }, z.core.$strict>], "kind">;
204
+ export type AgentListOutput = z.infer<typeof agentListOutputSchema>;
205
+ export type AgentLoginOutput = z.infer<typeof agentLoginOutputSchema>;
206
+ export type AgentCredentialAddOutput = z.infer<typeof agentCredentialAddOutputSchema>;
207
+ export type AgentAddOutput = z.infer<typeof agentAddOutputSchema>;
208
+ export type AgentRemoveOutput = z.infer<typeof agentRemoveOutputSchema>;
209
+ //# sourceMappingURL=cli-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-output.d.ts","sourceRoot":"","sources":["../src/cli-output.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA+BxB,eAAO,MAAM,aAAa;;;;;;;;;;;;;kBAMf,CAAC;AAEZ,eAAO,MAAM,iBAAiB;;;;;kBAOnB,CAAC;AAYZ,mEAAmE;AACnE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;+BA0BlB,CAAC;AAWd,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoBvB,CAAC;AAEZ,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAwClC,CAAC;AAEF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;4BAuB1C,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;4BAc/B,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAyBnC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACpE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAC5C,OAAO,8BAA8B,CACtC,CAAC;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
@@ -0,0 +1,208 @@
1
+ /**
2
+ * The JSON shape of every `agent` command result. These are the CONTRACT, not
3
+ * a convenience: an app may render the result any way it likes, but what it
4
+ * emits as data is fixed here so `alpacaloop agent list --json` and
5
+ * `promptopt agent list --json` are the same document.
6
+ */
7
+ import { AGENT_AVAILABILITY_STATUS, AGENT_INDETERMINATE_REASON, AGENT_UNAVAILABLE_REASON, AUTH_MATERIAL_KIND, } from "@alpacakit/agents";
8
+ import { CANDIDATE_SOURCE_KIND } from "@alpacakit/agents/config";
9
+ import { jsonValueSchema } from "@alpacakit/core";
10
+ import { z } from "zod";
11
+ import { ADD_AGENT_CONFIG_RESULT, ADD_API_KEY_PROFILE_RESULT, LOGIN_MANAGED_HOME_RESULT, } from "./register.js";
12
+ import { INVALID_NAME_RESULT_KIND } from "./names.js";
13
+ import { REMOVE_AGENTS_HOME_ENTRY_RESULT } from "./remove.js";
14
+ const RESULT_DISCRIMINATOR = "kind";
15
+ const AVAILABILITY_DISCRIMINATOR = "status";
16
+ const secretRefSchema = z
17
+ .object({ resolver: z.string(), id: z.string() })
18
+ .strict();
19
+ const authMaterialSchema = z.discriminatedUnion(RESULT_DISCRIMINATOR, [
20
+ z
21
+ .object({
22
+ kind: z.literal(AUTH_MATERIAL_KIND.homeDir),
23
+ path: z.string(),
24
+ })
25
+ .strict(),
26
+ z
27
+ .object({
28
+ kind: z.literal(AUTH_MATERIAL_KIND.apiKey),
29
+ secret: secretRefSchema,
30
+ })
31
+ .strict(),
32
+ ]);
33
+ export const profileSchema = z
34
+ .object({
35
+ id: z.string(),
36
+ agentId: z.string(),
37
+ material: authMaterialSchema,
38
+ })
39
+ .strict();
40
+ export const agentConfigSchema = z
41
+ .object({
42
+ id: z.string(),
43
+ kind: z.string(),
44
+ enabled: z.boolean(),
45
+ payload: z.record(z.string(), jsonValueSchema),
46
+ })
47
+ .strict();
48
+ const remediationSchema = z
49
+ .object({
50
+ detail: z.string(),
51
+ command: z
52
+ .object({ executable: z.string(), args: z.array(z.string()) })
53
+ .strict()
54
+ .nullable(),
55
+ })
56
+ .strict();
57
+ /** `null` when the agent declares no availability probe at all. */
58
+ export const availabilitySchema = z
59
+ .discriminatedUnion(AVAILABILITY_DISCRIMINATOR, [
60
+ z
61
+ .object({ status: z.literal(AGENT_AVAILABILITY_STATUS.runnable) })
62
+ .strict(),
63
+ z
64
+ .object({
65
+ status: z.literal(AGENT_AVAILABILITY_STATUS.unavailable),
66
+ reason: z.enum([
67
+ AGENT_UNAVAILABLE_REASON.commandMissing,
68
+ AGENT_UNAVAILABLE_REASON.authenticationRequired,
69
+ ]),
70
+ remediation: remediationSchema.nullable(),
71
+ })
72
+ .strict(),
73
+ z
74
+ .object({
75
+ status: z.literal(AGENT_AVAILABILITY_STATUS.indeterminate),
76
+ reason: z.enum([
77
+ AGENT_INDETERMINATE_REASON.probeTimeout,
78
+ AGENT_INDETERMINATE_REASON.probeFault,
79
+ ]),
80
+ detail: z.string(),
81
+ })
82
+ .strict(),
83
+ ])
84
+ .nullable();
85
+ /** The rejection every name-taking command shares (`InvalidNameResult`). */
86
+ const invalidNameSchema = z
87
+ .object({
88
+ kind: z.literal(INVALID_NAME_RESULT_KIND),
89
+ name: z.string(),
90
+ rule: z.string(),
91
+ })
92
+ .strict();
93
+ export const agentListOutputSchema = z
94
+ .object({
95
+ agentsHome: z.string(),
96
+ entries: z.array(z
97
+ .object({
98
+ agentId: z.string(),
99
+ agentConfigId: z.string(),
100
+ kind: z.string(),
101
+ source: z.enum([
102
+ CANDIDATE_SOURCE_KIND.profile,
103
+ CANDIDATE_SOURCE_KIND.ambient,
104
+ CANDIDATE_SOURCE_KIND.configured,
105
+ ]),
106
+ profileId: z.string().nullable(),
107
+ availability: availabilitySchema,
108
+ })
109
+ .strict()),
110
+ })
111
+ .strict();
112
+ export const agentLoginOutputSchema = z.discriminatedUnion(RESULT_DISCRIMINATOR, [
113
+ z
114
+ .object({
115
+ kind: z.literal(LOGIN_MANAGED_HOME_RESULT.registered),
116
+ profile: profileSchema,
117
+ managedHome: z.string(),
118
+ })
119
+ .strict(),
120
+ z
121
+ .object({
122
+ kind: z.literal(LOGIN_MANAGED_HOME_RESULT.profileExists),
123
+ profileId: z.string(),
124
+ })
125
+ .strict(),
126
+ z
127
+ .object({
128
+ kind: z.literal(LOGIN_MANAGED_HOME_RESULT.unknownAgent),
129
+ agentId: z.string(),
130
+ known: z.array(z.string()),
131
+ })
132
+ .strict(),
133
+ z
134
+ .object({
135
+ kind: z.literal(LOGIN_MANAGED_HOME_RESULT.unsupported),
136
+ agentId: z.string(),
137
+ method: z.string(),
138
+ supported: z.array(z.string()),
139
+ })
140
+ .strict(),
141
+ z
142
+ .object({
143
+ kind: z.literal(LOGIN_MANAGED_HOME_RESULT.loginFailed),
144
+ detail: z.string(),
145
+ managedHome: z.string(),
146
+ })
147
+ .strict(),
148
+ invalidNameSchema,
149
+ ]);
150
+ export const agentCredentialAddOutputSchema = z.discriminatedUnion(RESULT_DISCRIMINATOR, [
151
+ z
152
+ .object({
153
+ kind: z.literal(ADD_API_KEY_PROFILE_RESULT.registered),
154
+ profile: profileSchema,
155
+ })
156
+ .strict(),
157
+ z
158
+ .object({
159
+ kind: z.literal(ADD_API_KEY_PROFILE_RESULT.profileExists),
160
+ profileId: z.string(),
161
+ })
162
+ .strict(),
163
+ z
164
+ .object({
165
+ kind: z.literal(ADD_API_KEY_PROFILE_RESULT.emptyKey),
166
+ profileId: z.string(),
167
+ })
168
+ .strict(),
169
+ invalidNameSchema,
170
+ ]);
171
+ export const agentAddOutputSchema = z.discriminatedUnion(RESULT_DISCRIMINATOR, [
172
+ z
173
+ .object({
174
+ kind: z.literal(ADD_AGENT_CONFIG_RESULT.added),
175
+ agentConfig: agentConfigSchema,
176
+ })
177
+ .strict(),
178
+ z
179
+ .object({
180
+ kind: z.literal(ADD_AGENT_CONFIG_RESULT.exists),
181
+ id: z.string(),
182
+ })
183
+ .strict(),
184
+ invalidNameSchema,
185
+ ]);
186
+ export const agentRemoveOutputSchema = z.discriminatedUnion(RESULT_DISCRIMINATOR, [
187
+ z
188
+ .object({
189
+ kind: z.literal(REMOVE_AGENTS_HOME_ENTRY_RESULT.removedProfile),
190
+ profile: profileSchema,
191
+ removedManagedHome: z.string().nullable(),
192
+ removedSecret: z.boolean(),
193
+ })
194
+ .strict(),
195
+ z
196
+ .object({
197
+ kind: z.literal(REMOVE_AGENTS_HOME_ENTRY_RESULT.removedAgentConfig),
198
+ agentConfig: agentConfigSchema,
199
+ })
200
+ .strict(),
201
+ z
202
+ .object({
203
+ kind: z.literal(REMOVE_AGENTS_HOME_ENTRY_RESULT.notFound),
204
+ name: z.string(),
205
+ })
206
+ .strict(),
207
+ invalidNameSchema,
208
+ ]);