@oharness/engine 0.1.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.
- package/dist/agent/agent.d.ts +196 -0
- package/dist/agent/agent.js +758 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/compaction.d.ts +68 -0
- package/dist/agent/compaction.js +179 -0
- package/dist/agent/compaction.js.map +1 -0
- package/dist/agent/hooks.d.ts +77 -0
- package/dist/agent/hooks.js +152 -0
- package/dist/agent/hooks.js.map +1 -0
- package/dist/agent/memory.d.ts +45 -0
- package/dist/agent/memory.js +147 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/agent/overflow.d.ts +35 -0
- package/dist/agent/overflow.js +69 -0
- package/dist/agent/overflow.js.map +1 -0
- package/dist/agent/permissions.d.ts +181 -0
- package/dist/agent/permissions.js +289 -0
- package/dist/agent/permissions.js.map +1 -0
- package/dist/agent/prompt.d.ts +25 -0
- package/dist/agent/prompt.js +63 -0
- package/dist/agent/prompt.js.map +1 -0
- package/dist/agent/session.d.ts +108 -0
- package/dist/agent/session.js +231 -0
- package/dist/agent/session.js.map +1 -0
- package/dist/agent/settings.d.ts +37 -0
- package/dist/agent/settings.js +113 -0
- package/dist/agent/settings.js.map +1 -0
- package/dist/agent/skills.d.ts +58 -0
- package/dist/agent/skills.js +225 -0
- package/dist/agent/skills.js.map +1 -0
- package/dist/agent/store.d.ts +308 -0
- package/dist/agent/store.js +596 -0
- package/dist/agent/store.js.map +1 -0
- package/dist/agent/subagent.d.ts +44 -0
- package/dist/agent/subagent.js +138 -0
- package/dist/agent/subagent.js.map +1 -0
- package/dist/agent/titles.d.ts +8 -0
- package/dist/agent/titles.js +23 -0
- package/dist/agent/titles.js.map +1 -0
- package/dist/agent/workspace.d.ts +60 -0
- package/dist/agent/workspace.js +156 -0
- package/dist/agent/workspace.js.map +1 -0
- package/dist/artifacts/publish.d.ts +94 -0
- package/dist/artifacts/publish.js +104 -0
- package/dist/artifacts/publish.js.map +1 -0
- package/dist/artifacts/store.d.ts +324 -0
- package/dist/artifacts/store.js +500 -0
- package/dist/artifacts/store.js.map +1 -0
- package/dist/auth/index.d.ts +13 -0
- package/dist/auth/index.js +10 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/manager.d.ts +83 -0
- package/dist/auth/manager.js +266 -0
- package/dist/auth/manager.js.map +1 -0
- package/dist/auth/oauth.d.ts +83 -0
- package/dist/auth/oauth.js +327 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/auth/providers/account.d.ts +59 -0
- package/dist/auth/providers/account.js +282 -0
- package/dist/auth/providers/account.js.map +1 -0
- package/dist/auth/providers/anthropic.d.ts +24 -0
- package/dist/auth/providers/anthropic.js +209 -0
- package/dist/auth/providers/anthropic.js.map +1 -0
- package/dist/auth/providers/generic.d.ts +57 -0
- package/dist/auth/providers/generic.js +155 -0
- package/dist/auth/providers/generic.js.map +1 -0
- package/dist/auth/providers/official.d.ts +3 -0
- package/dist/auth/providers/official.js +90 -0
- package/dist/auth/providers/official.js.map +1 -0
- package/dist/auth/providers/ottoport.d.ts +3 -0
- package/dist/auth/providers/ottoport.js +60 -0
- package/dist/auth/providers/ottoport.js.map +1 -0
- package/dist/auth/store.d.ts +22 -0
- package/dist/auth/store.js +138 -0
- package/dist/auth/store.js.map +1 -0
- package/dist/auth/types.d.ts +167 -0
- package/dist/auth/types.js +16 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/config.d.ts +197 -0
- package/dist/config.js +195 -0
- package/dist/config.js.map +1 -0
- package/dist/core/errors.d.ts +46 -0
- package/dist/core/errors.js +83 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/tokens.d.ts +12 -0
- package/dist/core/tokens.js +56 -0
- package/dist/core/tokens.js.map +1 -0
- package/dist/core/types.d.ts +91 -0
- package/dist/core/types.js +49 -0
- package/dist/core/types.js.map +1 -0
- package/dist/harness.d.ts +302 -0
- package/dist/harness.js +695 -0
- package/dist/harness.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +55 -0
- package/dist/mcp/client.js +199 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/index.js +8 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/manager.d.ts +77 -0
- package/dist/mcp/manager.js +325 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/mcp/oauth.d.ts +63 -0
- package/dist/mcp/oauth.js +302 -0
- package/dist/mcp/oauth.js.map +1 -0
- package/dist/mcp/protocol.d.ts +130 -0
- package/dist/mcp/protocol.js +14 -0
- package/dist/mcp/protocol.js.map +1 -0
- package/dist/mcp/registry.d.ts +52 -0
- package/dist/mcp/registry.js +100 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/registry.json +293 -0
- package/dist/mcp/secrets.d.ts +20 -0
- package/dist/mcp/secrets.js +75 -0
- package/dist/mcp/secrets.js.map +1 -0
- package/dist/mcp/transport.d.ts +51 -0
- package/dist/mcp/transport.js +158 -0
- package/dist/mcp/transport.js.map +1 -0
- package/dist/paths.d.ts +37 -0
- package/dist/paths.js +63 -0
- package/dist/paths.js.map +1 -0
- package/dist/plugins.d.ts +55 -0
- package/dist/plugins.js +201 -0
- package/dist/plugins.js.map +1 -0
- package/dist/providers/builtin.d.ts +23 -0
- package/dist/providers/builtin.js +141 -0
- package/dist/providers/builtin.js.map +1 -0
- package/dist/providers/catalog.d.ts +129 -0
- package/dist/providers/catalog.js +254 -0
- package/dist/providers/catalog.js.map +1 -0
- package/dist/providers/catalog.json +472 -0
- package/dist/providers/discovery.d.ts +16 -0
- package/dist/providers/discovery.js +161 -0
- package/dist/providers/discovery.js.map +1 -0
- package/dist/providers/http.d.ts +24 -0
- package/dist/providers/http.js +139 -0
- package/dist/providers/http.js.map +1 -0
- package/dist/providers/index.d.ts +10 -0
- package/dist/providers/index.js +8 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/piai.d.ts +124 -0
- package/dist/providers/piai.js +551 -0
- package/dist/providers/piai.js.map +1 -0
- package/dist/providers/registry.d.ts +65 -0
- package/dist/providers/registry.js +195 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/resilient.d.ts +46 -0
- package/dist/providers/resilient.js +117 -0
- package/dist/providers/resilient.js.map +1 -0
- package/dist/providers/types.d.ts +182 -0
- package/dist/providers/types.js +50 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/schedule/cron.d.ts +35 -0
- package/dist/schedule/cron.js +125 -0
- package/dist/schedule/cron.js.map +1 -0
- package/dist/schedule/scheduler.d.ts +87 -0
- package/dist/schedule/scheduler.js +237 -0
- package/dist/schedule/scheduler.js.map +1 -0
- package/dist/storage/kv.d.ts +56 -0
- package/dist/storage/kv.js +173 -0
- package/dist/storage/kv.js.map +1 -0
- package/dist/storage/migrate.d.ts +11 -0
- package/dist/storage/migrate.js +93 -0
- package/dist/storage/migrate.js.map +1 -0
- package/dist/storage/project.d.ts +9 -0
- package/dist/storage/project.js +57 -0
- package/dist/storage/project.js.map +1 -0
- package/dist/storage/records.d.ts +32 -0
- package/dist/storage/records.js +48 -0
- package/dist/storage/records.js.map +1 -0
- package/dist/sync/client.d.ts +79 -0
- package/dist/sync/client.js +118 -0
- package/dist/sync/client.js.map +1 -0
- package/dist/sync/mirror.d.ts +85 -0
- package/dist/sync/mirror.js +389 -0
- package/dist/sync/mirror.js.map +1 -0
- package/dist/sync/protocol.d.ts +67 -0
- package/dist/sync/protocol.js +16 -0
- package/dist/sync/protocol.js.map +1 -0
- package/dist/sync/settings.d.ts +56 -0
- package/dist/sync/settings.js +60 -0
- package/dist/sync/settings.js.map +1 -0
- package/dist/tools/builtin/artifact.d.ts +16 -0
- package/dist/tools/builtin/artifact.js +134 -0
- package/dist/tools/builtin/artifact.js.map +1 -0
- package/dist/tools/builtin/bash.d.ts +3 -0
- package/dist/tools/builtin/bash.js +142 -0
- package/dist/tools/builtin/bash.js.map +1 -0
- package/dist/tools/builtin/fs.d.ts +19 -0
- package/dist/tools/builtin/fs.js +280 -0
- package/dist/tools/builtin/fs.js.map +1 -0
- package/dist/tools/builtin/index.d.ts +22 -0
- package/dist/tools/builtin/index.js +42 -0
- package/dist/tools/builtin/index.js.map +1 -0
- package/dist/tools/builtin/mcp-resource.d.ts +3 -0
- package/dist/tools/builtin/mcp-resource.js +220 -0
- package/dist/tools/builtin/mcp-resource.js.map +1 -0
- package/dist/tools/builtin/memory.d.ts +10 -0
- package/dist/tools/builtin/memory.js +76 -0
- package/dist/tools/builtin/memory.js.map +1 -0
- package/dist/tools/builtin/recall.d.ts +13 -0
- package/dist/tools/builtin/recall.js +163 -0
- package/dist/tools/builtin/recall.js.map +1 -0
- package/dist/tools/builtin/search.d.ts +3 -0
- package/dist/tools/builtin/search.js +240 -0
- package/dist/tools/builtin/search.js.map +1 -0
- package/dist/tools/builtin/skill.d.ts +10 -0
- package/dist/tools/builtin/skill.js +46 -0
- package/dist/tools/builtin/skill.js.map +1 -0
- package/dist/tools/builtin/task.d.ts +9 -0
- package/dist/tools/builtin/task.js +68 -0
- package/dist/tools/builtin/task.js.map +1 -0
- package/dist/tools/builtin/todo.d.ts +20 -0
- package/dist/tools/builtin/todo.js +63 -0
- package/dist/tools/builtin/todo.js.map +1 -0
- package/dist/tools/define.d.ts +19 -0
- package/dist/tools/define.js +39 -0
- package/dist/tools/define.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.js +5 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +39 -0
- package/dist/tools/registry.js +101 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/types.d.ts +112 -0
- package/dist/tools/types.js +22 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/util/id.d.ts +9 -0
- package/dist/util/id.js +19 -0
- package/dist/util/id.js.map +1 -0
- package/dist/util/json.d.ts +25 -0
- package/dist/util/json.js +100 -0
- package/dist/util/json.js.map +1 -0
- package/dist/util/jwt.d.ts +74 -0
- package/dist/util/jwt.js +177 -0
- package/dist/util/jwt.js.map +1 -0
- package/dist/util/logger.d.ts +13 -0
- package/dist/util/logger.js +59 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/queue.d.ts +26 -0
- package/dist/util/queue.js +106 -0
- package/dist/util/queue.js.map +1 -0
- package/dist/util/schema.d.ts +17 -0
- package/dist/util/schema.js +98 -0
- package/dist/util/schema.js.map +1 -0
- package/dist/util/shell.d.ts +20 -0
- package/dist/util/shell.js +24 -0
- package/dist/util/shell.js.map +1 -0
- package/official.json +4 -0
- package/package.json +38 -0
- package/skills/artifact-authoring/SKILL.md +81 -0
- package/skills/canvas/SKILL.md +85 -0
- package/skills/skill-authoring/SKILL.md +85 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication contract.
|
|
3
|
+
*
|
|
4
|
+
* Two things drive the design:
|
|
5
|
+
*
|
|
6
|
+
* 1. Subscription credentials expire. Anything that snapshots a header at
|
|
7
|
+
* construction time breaks an hour later, so credentials are resolved
|
|
8
|
+
* **per request** and the resolver owns refresh.
|
|
9
|
+
* 2. Login flows differ per provider, but a CLI should not need to know that.
|
|
10
|
+
* Providers therefore *describe* their login methods declaratively and the
|
|
11
|
+
* UI renders whatever prompts they declare.
|
|
12
|
+
*/
|
|
13
|
+
export interface ApiCredential {
|
|
14
|
+
type: "api";
|
|
15
|
+
key: string;
|
|
16
|
+
/** Extra non-secret fields a provider needs alongside the key. */
|
|
17
|
+
metadata?: Record<string, string>;
|
|
18
|
+
}
|
|
19
|
+
export interface OAuthCredential {
|
|
20
|
+
type: "oauth";
|
|
21
|
+
access: string;
|
|
22
|
+
refresh: string;
|
|
23
|
+
/** Epoch milliseconds. */
|
|
24
|
+
expires: number;
|
|
25
|
+
/** Provider-specific extras, e.g. an enterprise endpoint or account id. */
|
|
26
|
+
accountId?: string;
|
|
27
|
+
baseUrl?: string;
|
|
28
|
+
metadata?: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
/** A long-lived token paired with a key, for providers that issue both. */
|
|
31
|
+
export interface WellKnownCredential {
|
|
32
|
+
type: "wellknown";
|
|
33
|
+
key: string;
|
|
34
|
+
token: string;
|
|
35
|
+
}
|
|
36
|
+
export type Credential = ApiCredential | OAuthCredential | WellKnownCredential;
|
|
37
|
+
/** Show a prompt only when an earlier answer matches. */
|
|
38
|
+
export interface PromptCondition {
|
|
39
|
+
key: string;
|
|
40
|
+
op: "eq" | "neq";
|
|
41
|
+
value: string;
|
|
42
|
+
}
|
|
43
|
+
export interface TextPrompt {
|
|
44
|
+
type: "text";
|
|
45
|
+
key: string;
|
|
46
|
+
message: string;
|
|
47
|
+
placeholder?: string;
|
|
48
|
+
/** Mask the input (API keys, secrets). */
|
|
49
|
+
secret?: boolean;
|
|
50
|
+
when?: PromptCondition;
|
|
51
|
+
validate?(value: string): string | undefined;
|
|
52
|
+
}
|
|
53
|
+
export interface SelectPrompt {
|
|
54
|
+
type: "select";
|
|
55
|
+
key: string;
|
|
56
|
+
message: string;
|
|
57
|
+
options: Array<{
|
|
58
|
+
label: string;
|
|
59
|
+
value: string;
|
|
60
|
+
hint?: string;
|
|
61
|
+
}>;
|
|
62
|
+
when?: PromptCondition;
|
|
63
|
+
}
|
|
64
|
+
export type Prompt = TextPrompt | SelectPrompt;
|
|
65
|
+
/** What `authorize()` hands back so the UI can walk the user through login. */
|
|
66
|
+
export type AuthorizeResult = {
|
|
67
|
+
/**
|
|
68
|
+
* The page the user has to visit, if there is one. Absent for flows that
|
|
69
|
+
* deliver the code out of band — an emailed one-time code has nothing to
|
|
70
|
+
* open, and sending a browser somewhere anyway invites a second, competing
|
|
71
|
+
* session.
|
|
72
|
+
*/
|
|
73
|
+
url?: string;
|
|
74
|
+
instructions: string;
|
|
75
|
+
} & ({
|
|
76
|
+
/**
|
|
77
|
+
* The flow completes without the user typing anything back — a device
|
|
78
|
+
* code poll, or a loopback redirect we listen for.
|
|
79
|
+
*/
|
|
80
|
+
method: "auto";
|
|
81
|
+
callback(): Promise<CallbackResult>;
|
|
82
|
+
} | {
|
|
83
|
+
/** The user copies a code out of the browser and pastes it back. */
|
|
84
|
+
method: "code";
|
|
85
|
+
callback(code: string): Promise<CallbackResult>;
|
|
86
|
+
});
|
|
87
|
+
export type CallbackResult = ({
|
|
88
|
+
type: "success";
|
|
89
|
+
} & Omit<OAuthCredential, "type">) | ({
|
|
90
|
+
type: "success";
|
|
91
|
+
} & Omit<ApiCredential, "type">) | {
|
|
92
|
+
type: "failed";
|
|
93
|
+
error?: string;
|
|
94
|
+
};
|
|
95
|
+
export interface OAuthMethod {
|
|
96
|
+
type: "oauth";
|
|
97
|
+
label: string;
|
|
98
|
+
prompts?: Prompt[];
|
|
99
|
+
authorize(inputs: Record<string, string>): Promise<AuthorizeResult>;
|
|
100
|
+
}
|
|
101
|
+
export interface ApiKeyMethod {
|
|
102
|
+
type: "api";
|
|
103
|
+
label: string;
|
|
104
|
+
prompts?: Prompt[];
|
|
105
|
+
/**
|
|
106
|
+
* Turn the collected prompt answers into a credential. Defaults to treating
|
|
107
|
+
* the `key` answer as the API key.
|
|
108
|
+
*/
|
|
109
|
+
authorize?(inputs: Record<string, string>): Promise<CallbackResult>;
|
|
110
|
+
}
|
|
111
|
+
export type AuthMethod = OAuthMethod | ApiKeyMethod;
|
|
112
|
+
/** Context a resolver may use to vary headers per request. */
|
|
113
|
+
export interface AuthContext {
|
|
114
|
+
providerId: string;
|
|
115
|
+
/** The request body about to be sent, for providers that inspect it. */
|
|
116
|
+
body?: unknown;
|
|
117
|
+
/** The URL about to be called. */
|
|
118
|
+
url?: string;
|
|
119
|
+
}
|
|
120
|
+
export interface ResolvedAuth {
|
|
121
|
+
headers: Record<string, string>;
|
|
122
|
+
/** Override the endpoint, e.g. an enterprise or regional host. */
|
|
123
|
+
baseUrl?: string;
|
|
124
|
+
/**
|
|
125
|
+
* Headers to strip before sending. Bearer-token auth must remove the
|
|
126
|
+
* `x-api-key` a provider would otherwise set, or the API sees two
|
|
127
|
+
* conflicting credentials and rejects the request.
|
|
128
|
+
*/
|
|
129
|
+
removeHeaders?: string[];
|
|
130
|
+
/** How this credential was obtained, for `/auth` and diagnostics. */
|
|
131
|
+
source?: string;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Resolves credentials at request time. Returning `undefined` means "no
|
|
135
|
+
* credential available" and the provider falls back to its own env lookup.
|
|
136
|
+
*/
|
|
137
|
+
export type AuthResolver = (ctx: AuthContext) => Promise<ResolvedAuth | undefined>;
|
|
138
|
+
/**
|
|
139
|
+
* Everything a provider needs to declare about authentication. `loader` is the
|
|
140
|
+
* counterpart to `methods`: methods obtain a credential, loader turns a stored
|
|
141
|
+
* credential into request headers.
|
|
142
|
+
*/
|
|
143
|
+
export interface AuthProvider {
|
|
144
|
+
/** Must match the id of the model provider it authenticates. */
|
|
145
|
+
id: string;
|
|
146
|
+
label: string;
|
|
147
|
+
methods: AuthMethod[];
|
|
148
|
+
/**
|
|
149
|
+
* Turn a stored credential into request headers. Called on every request,
|
|
150
|
+
* so it is also the place to refresh an expiring token.
|
|
151
|
+
*/
|
|
152
|
+
loader?(credential: Credential | undefined, ctx: AuthContext): Promise<ResolvedAuth | undefined>;
|
|
153
|
+
/**
|
|
154
|
+
* Refresh an OAuth credential. The manager calls this shortly before expiry
|
|
155
|
+
* and persists whatever comes back.
|
|
156
|
+
*/
|
|
157
|
+
refresh?(credential: OAuthCredential): Promise<OAuthCredential | undefined>;
|
|
158
|
+
/**
|
|
159
|
+
* Discover credentials the harness did not store itself — an API key in the
|
|
160
|
+
* environment, or a profile written by a vendor's own CLI.
|
|
161
|
+
*/
|
|
162
|
+
discover?(): Promise<{
|
|
163
|
+
credential: Credential;
|
|
164
|
+
source: string;
|
|
165
|
+
} | undefined>;
|
|
166
|
+
}
|
|
167
|
+
export declare function isExpired(credential: OAuthCredential, skewMs?: number): boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication contract.
|
|
3
|
+
*
|
|
4
|
+
* Two things drive the design:
|
|
5
|
+
*
|
|
6
|
+
* 1. Subscription credentials expire. Anything that snapshots a header at
|
|
7
|
+
* construction time breaks an hour later, so credentials are resolved
|
|
8
|
+
* **per request** and the resolver owns refresh.
|
|
9
|
+
* 2. Login flows differ per provider, but a CLI should not need to know that.
|
|
10
|
+
* Providers therefore *describe* their login methods declaratively and the
|
|
11
|
+
* UI renders whatever prompts they declare.
|
|
12
|
+
*/
|
|
13
|
+
export function isExpired(credential, skewMs = 60_000) {
|
|
14
|
+
return credential.expires > 0 && credential.expires - skewMs <= Date.now();
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAoLH,MAAM,UAAU,SAAS,CAAC,UAA2B,EAAE,MAAM,GAAG,MAAM;IACpE,OAAO,UAAU,CAAC,OAAO,GAAG,CAAC,IAAI,UAAU,CAAC,OAAO,GAAG,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;AAC7E,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import type { McpServerConfig } from "./mcp/client.ts";
|
|
2
|
+
import type { OAuthProviderOptions } from "./auth/providers/generic.ts";
|
|
3
|
+
import type { ModelSpec, ProviderCredentials, ThinkingConfig } from "./providers/types.ts";
|
|
4
|
+
import type { HookConfig } from "./agent/hooks.ts";
|
|
5
|
+
import type { PermissionMode, PermissionRules } from "./agent/permissions.ts";
|
|
6
|
+
import type { WorkspaceMode } from "./agent/workspace.ts";
|
|
7
|
+
import type { SubagentDefinition } from "./agent/subagent.ts";
|
|
8
|
+
import type { ScheduleDefinition } from "./schedule/scheduler.ts";
|
|
9
|
+
import type { ToolFilter } from "./tools/registry.ts";
|
|
10
|
+
import type { LogLevel } from "./util/logger.ts";
|
|
11
|
+
import type { PluginConfig } from "./plugins.ts";
|
|
12
|
+
export interface HarnessConfig {
|
|
13
|
+
/** Default model alias, e.g. "sonnet" or "openai/gpt-4.1". */
|
|
14
|
+
model?: string;
|
|
15
|
+
/** Model used for compaction and cheap subagents. */
|
|
16
|
+
smallModel?: string;
|
|
17
|
+
permissionMode?: PermissionMode;
|
|
18
|
+
permissions?: PermissionRules;
|
|
19
|
+
/**
|
|
20
|
+
* Where writes may land: `read-only`, `workspace-write` (the default — the
|
|
21
|
+
* project directory plus `writableRoots`), or `full-access`. This is a
|
|
22
|
+
* policy gate on tool arguments, not an OS sandbox.
|
|
23
|
+
*/
|
|
24
|
+
workspaceMode?: WorkspaceMode;
|
|
25
|
+
/** Extra directories the agent may write to, beyond the project root. */
|
|
26
|
+
writableRoots?: string[];
|
|
27
|
+
/** Extra directories the agent may read but not write. */
|
|
28
|
+
readableRoots?: string[];
|
|
29
|
+
/**
|
|
30
|
+
* Record every permission decision with the session that made it. On unless
|
|
31
|
+
* set to false — the trail is small, local, and the one thing that can answer
|
|
32
|
+
* afterwards what the agent was allowed to do.
|
|
33
|
+
*/
|
|
34
|
+
audit?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Also append every decision to this file. The session's own trail is kept
|
|
37
|
+
* either way; this is for a run whose record has to end up somewhere a
|
|
38
|
+
* collector can read, e.g. an unattended scheduled one.
|
|
39
|
+
*/
|
|
40
|
+
auditLog?: string;
|
|
41
|
+
maxTurns?: number;
|
|
42
|
+
thinking?: ThinkingConfig;
|
|
43
|
+
cache?: boolean;
|
|
44
|
+
systemPrompt?: string;
|
|
45
|
+
appendSystemPrompt?: string;
|
|
46
|
+
/** Path to a project instructions file, relative to the project root. */
|
|
47
|
+
instructionsFile?: string;
|
|
48
|
+
tools?: ToolFilter;
|
|
49
|
+
mcpServers?: Record<string, McpServerConfig>;
|
|
50
|
+
hooks?: HookConfig;
|
|
51
|
+
subagents?: SubagentDefinition[];
|
|
52
|
+
/** Extra directories to scan for skills, relative to the project root. */
|
|
53
|
+
skillDirs?: string[];
|
|
54
|
+
/** Extra directories to scan for markdown subagent definitions. */
|
|
55
|
+
agentDirs?: string[];
|
|
56
|
+
/** Recurring prompts, run on a cron schedule. */
|
|
57
|
+
schedules?: ScheduleDefinition[];
|
|
58
|
+
/** Where durable notes live; defaults to .oharness/memory. */
|
|
59
|
+
memoryDir?: string;
|
|
60
|
+
/** Declarative plugin bundles to discover and activate. */
|
|
61
|
+
plugins?: PluginConfig;
|
|
62
|
+
/** Extra or overriding model specs, merged over the built-in catalog. */
|
|
63
|
+
models?: ModelSpec[];
|
|
64
|
+
/** Per-provider credentials and endpoints; env vars still apply as fallback. */
|
|
65
|
+
providers?: Record<string, ProviderCredentials>;
|
|
66
|
+
/**
|
|
67
|
+
* Subscription providers authenticated by OAuth. `clientId` is required —
|
|
68
|
+
* see the README on why no client id ships built in.
|
|
69
|
+
*/
|
|
70
|
+
oauthProviders?: OAuthProviderOptions[];
|
|
71
|
+
/**
|
|
72
|
+
* Path to an extra catalog file, merged over the bundled one and the user's.
|
|
73
|
+
* The catalog is where providers and models live — see src/providers/catalog.json.
|
|
74
|
+
*/
|
|
75
|
+
catalog?: string;
|
|
76
|
+
/** OpenAI-compatible vendors to register as their own providers. */
|
|
77
|
+
openAiCompatible?: Array<{
|
|
78
|
+
id: string;
|
|
79
|
+
name?: string;
|
|
80
|
+
baseUrl: string;
|
|
81
|
+
apiKeyEnv?: string;
|
|
82
|
+
includeUsage?: boolean;
|
|
83
|
+
}>;
|
|
84
|
+
logLevel?: LogLevel;
|
|
85
|
+
/**
|
|
86
|
+
* Where sessions, transcripts and project records are kept. Defaults to
|
|
87
|
+
* `storage/` in the user directory; naming one here opts out of importing
|
|
88
|
+
* anything that was recorded under the default.
|
|
89
|
+
*/
|
|
90
|
+
sessionDir?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Reclaim old sessions on startup. Nothing is deleted unless one of these is
|
|
93
|
+
* set — losing a transcript should be opt-in.
|
|
94
|
+
*/
|
|
95
|
+
sessionRetention?: {
|
|
96
|
+
maxAgeDays?: number;
|
|
97
|
+
keep?: number;
|
|
98
|
+
};
|
|
99
|
+
/** Where transcripts are mirrored so a second device can continue them. */
|
|
100
|
+
sync?: SyncConfig;
|
|
101
|
+
/**
|
|
102
|
+
* The account system `auth login official` signs in to.
|
|
103
|
+
*
|
|
104
|
+
* User config only — see `projectSafe`. This is the setting a fork or a
|
|
105
|
+
* self-hosted deployment uses to point the harness at its own Supabase
|
|
106
|
+
* project without rebuilding anything, and it beats the ids a published
|
|
107
|
+
* build was packaged with.
|
|
108
|
+
*/
|
|
109
|
+
account?: AccountConfig;
|
|
110
|
+
}
|
|
111
|
+
export interface AccountConfig {
|
|
112
|
+
/**
|
|
113
|
+
* The Supabase project accounts live in, e.g.
|
|
114
|
+
* `https://<project>.supabase.co`. Set this and `supabaseAnonKey` together;
|
|
115
|
+
* one without the other is treated as neither.
|
|
116
|
+
*/
|
|
117
|
+
supabaseUrl?: string;
|
|
118
|
+
/**
|
|
119
|
+
* The project's anon key. A publishable client credential — it grants
|
|
120
|
+
* nothing beyond what an anonymous visitor has, and row level security is
|
|
121
|
+
* what protects the data — so it is no more sensitive here than in the
|
|
122
|
+
* browser bundle of the site it belongs to.
|
|
123
|
+
*/
|
|
124
|
+
supabaseAnonKey?: string;
|
|
125
|
+
/**
|
|
126
|
+
* The website that owns those accounts, for the browser sign-in handoff.
|
|
127
|
+
* Defaults to the official one.
|
|
128
|
+
*/
|
|
129
|
+
siteUrl?: string;
|
|
130
|
+
}
|
|
131
|
+
export interface SyncConfig {
|
|
132
|
+
/**
|
|
133
|
+
* Defaults to on. Sync still does nothing without a destination and a token,
|
|
134
|
+
* so "on" means "as soon as you are signed in" rather than "immediately" —
|
|
135
|
+
* see `resolveSync`.
|
|
136
|
+
*/
|
|
137
|
+
enabled?: boolean;
|
|
138
|
+
/** Base URL of the sync server. Unset uses the official one. */
|
|
139
|
+
url?: string;
|
|
140
|
+
/**
|
|
141
|
+
* Bearer token. Usually left unset: the official service reads the account
|
|
142
|
+
* credential, and a self-hosted server's token is better placed in the user
|
|
143
|
+
* config than in a repository's.
|
|
144
|
+
*/
|
|
145
|
+
token?: string;
|
|
146
|
+
/**
|
|
147
|
+
* Mirror into a team's shared history rather than your own.
|
|
148
|
+
*
|
|
149
|
+
* Everyone on the team reads and writes one feed per project, which is what
|
|
150
|
+
* lets two people continue each other's sessions. The server checks the
|
|
151
|
+
* account holds the team, so naming one here is a choice about where your
|
|
152
|
+
* own transcripts go, never a way to reach someone else's.
|
|
153
|
+
*/
|
|
154
|
+
team?: string;
|
|
155
|
+
/**
|
|
156
|
+
* Projects never to mirror, by project id or worktree path. For the one repo
|
|
157
|
+
* whose transcripts should not leave the machine, without turning sync off
|
|
158
|
+
* everywhere else.
|
|
159
|
+
*/
|
|
160
|
+
exclude?: string[];
|
|
161
|
+
}
|
|
162
|
+
export declare const CONFIG_FILENAMES: string[];
|
|
163
|
+
/**
|
|
164
|
+
* Load and merge configuration.
|
|
165
|
+
*
|
|
166
|
+
* User config (`~/.oharness/config.json`) is the base; project config
|
|
167
|
+
* overrides it, so a repo can tighten policy for everyone working in it
|
|
168
|
+
* without each person editing their global settings.
|
|
169
|
+
*/
|
|
170
|
+
export declare function loadConfig(cwd?: string): Promise<HarnessConfig>;
|
|
171
|
+
/**
|
|
172
|
+
* The project's own config file, unmerged.
|
|
173
|
+
*
|
|
174
|
+
* Provenance, for the settings a UI offers to change. Once merged there is no
|
|
175
|
+
* way to tell a value the user chose from one the repository imposed, and the
|
|
176
|
+
* difference decides whether a switch works or silently reverts on the next
|
|
177
|
+
* launch — so a control over a setting a project may override has to ask this
|
|
178
|
+
* first.
|
|
179
|
+
*/
|
|
180
|
+
export declare function loadProjectConfig(cwd?: string): Promise<HarnessConfig | undefined>;
|
|
181
|
+
/**
|
|
182
|
+
* Change the user's own config file.
|
|
183
|
+
*
|
|
184
|
+
* The only writer in this module, and deliberately narrow. Config is a file a
|
|
185
|
+
* person edits, so a program that rewrites it wholesale would reformat their
|
|
186
|
+
* comments away and reorder their keys — this reads, applies one change, and
|
|
187
|
+
* writes back, which loses formatting but not content. Reach for it when a
|
|
188
|
+
* setting is toggled from a UI and has to still be true tomorrow; leave
|
|
189
|
+
* everything else to the person and their editor.
|
|
190
|
+
*
|
|
191
|
+
* Never the project config: a preference is about this machine and its owner,
|
|
192
|
+
* and writing it into the repository would commit it to everyone.
|
|
193
|
+
*/
|
|
194
|
+
export declare function updateUserConfig(change: (current: HarnessConfig) => HarnessConfig): Promise<HarnessConfig>;
|
|
195
|
+
export declare function mergeConfig(base: HarnessConfig, override: HarnessConfig): HarnessConfig;
|
|
196
|
+
/** Read the project's instructions file, if one exists. */
|
|
197
|
+
export declare function loadProjectInstructions(cwd: string, configured?: string): Promise<string | undefined>;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { userPath } from "./paths.js";
|
|
2
|
+
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { ConfigError } from "./core/errors.js";
|
|
5
|
+
import { parseJson } from "./util/json.js";
|
|
6
|
+
export const CONFIG_FILENAMES = ["oharness.config.json", ".oharness.json"];
|
|
7
|
+
const DEFAULT_INSTRUCTIONS = ["AGENTS.md", "CLAUDE.md", ".oharness/instructions.md"];
|
|
8
|
+
/**
|
|
9
|
+
* Load and merge configuration.
|
|
10
|
+
*
|
|
11
|
+
* User config (`~/.oharness/config.json`) is the base; project config
|
|
12
|
+
* overrides it, so a repo can tighten policy for everyone working in it
|
|
13
|
+
* without each person editing their global settings.
|
|
14
|
+
*/
|
|
15
|
+
export async function loadConfig(cwd = process.cwd()) {
|
|
16
|
+
const user = await readConfigFile(userPath("config.json"));
|
|
17
|
+
const project = await loadProjectConfig(cwd);
|
|
18
|
+
return mergeConfig(user ?? {}, projectSafe(project ?? {}));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The project's own config file, unmerged.
|
|
22
|
+
*
|
|
23
|
+
* Provenance, for the settings a UI offers to change. Once merged there is no
|
|
24
|
+
* way to tell a value the user chose from one the repository imposed, and the
|
|
25
|
+
* difference decides whether a switch works or silently reverts on the next
|
|
26
|
+
* launch — so a control over a setting a project may override has to ask this
|
|
27
|
+
* first.
|
|
28
|
+
*/
|
|
29
|
+
export async function loadProjectConfig(cwd = process.cwd()) {
|
|
30
|
+
for (const filename of CONFIG_FILENAMES) {
|
|
31
|
+
const found = await readConfigFile(path.join(cwd, filename));
|
|
32
|
+
if (found)
|
|
33
|
+
return found;
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* A project config with the parts a repository may not decide removed.
|
|
39
|
+
*
|
|
40
|
+
* Applied here rather than inside `mergeConfig`, because this is the only
|
|
41
|
+
* place that knows which side is the person and which is the repository —
|
|
42
|
+
* elsewhere the same function merges plugin contributions under a user's own
|
|
43
|
+
* settings, and a rule written as "the base wins" would there mean "discard
|
|
44
|
+
* what the user set", which is how this was wrong the first time.
|
|
45
|
+
*
|
|
46
|
+
* What a project may still do: switch sync off, and add exclusions. Both
|
|
47
|
+
* restrict. What it may not do is switch sync on, choose the server, supply
|
|
48
|
+
* the credential, or name the team — each of which would let a repository you
|
|
49
|
+
* cloned decide where your transcripts go.
|
|
50
|
+
*
|
|
51
|
+
* `account` is removed outright, for a sharper version of the same reason. It
|
|
52
|
+
* names where sign-in sends an email address and a password; a repository that
|
|
53
|
+
* could set it would be a repository that collects them. There is no part of
|
|
54
|
+
* it a project has any business deciding, so unlike sync there is nothing to
|
|
55
|
+
* keep.
|
|
56
|
+
*/
|
|
57
|
+
function projectSafe(project) {
|
|
58
|
+
const { account: _account, ...rest } = project;
|
|
59
|
+
if (!rest.sync)
|
|
60
|
+
return rest;
|
|
61
|
+
const { url: _url, token: _token, team: _team, ...allowed } = rest.sync;
|
|
62
|
+
return { ...rest, sync: allowed };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Change the user's own config file.
|
|
66
|
+
*
|
|
67
|
+
* The only writer in this module, and deliberately narrow. Config is a file a
|
|
68
|
+
* person edits, so a program that rewrites it wholesale would reformat their
|
|
69
|
+
* comments away and reorder their keys — this reads, applies one change, and
|
|
70
|
+
* writes back, which loses formatting but not content. Reach for it when a
|
|
71
|
+
* setting is toggled from a UI and has to still be true tomorrow; leave
|
|
72
|
+
* everything else to the person and their editor.
|
|
73
|
+
*
|
|
74
|
+
* Never the project config: a preference is about this machine and its owner,
|
|
75
|
+
* and writing it into the repository would commit it to everyone.
|
|
76
|
+
*/
|
|
77
|
+
export async function updateUserConfig(change) {
|
|
78
|
+
const file = userPath("config.json");
|
|
79
|
+
const current = (await readConfigFile(file)) ?? {};
|
|
80
|
+
const next = change(current);
|
|
81
|
+
await mkdir(path.dirname(file), { recursive: true });
|
|
82
|
+
const temp = `${file}.${process.pid}.tmp`;
|
|
83
|
+
// Temp plus rename, so an interrupted write cannot leave a config file that
|
|
84
|
+
// fails to parse — which would read as "every setting reverted".
|
|
85
|
+
await writeFile(temp, `${JSON.stringify(next, null, 2)}\n`, "utf8");
|
|
86
|
+
await rename(temp, file);
|
|
87
|
+
return next;
|
|
88
|
+
}
|
|
89
|
+
export function mergeConfig(base, override) {
|
|
90
|
+
return {
|
|
91
|
+
...base,
|
|
92
|
+
...override,
|
|
93
|
+
permissions: mergeRules(base.permissions, override.permissions),
|
|
94
|
+
tools: {
|
|
95
|
+
allow: override.tools?.allow ?? base.tools?.allow,
|
|
96
|
+
deny: [...(base.tools?.deny ?? []), ...(override.tools?.deny ?? [])],
|
|
97
|
+
},
|
|
98
|
+
mcpServers: { ...base.mcpServers, ...override.mcpServers },
|
|
99
|
+
hooks: mergeHooks(base.hooks, override.hooks),
|
|
100
|
+
subagents: [...(base.subagents ?? []), ...(override.subagents ?? [])],
|
|
101
|
+
skillDirs: [...(base.skillDirs ?? []), ...(override.skillDirs ?? [])],
|
|
102
|
+
agentDirs: [...(base.agentDirs ?? []), ...(override.agentDirs ?? [])],
|
|
103
|
+
schedules: [...(base.schedules ?? []), ...(override.schedules ?? [])],
|
|
104
|
+
writableRoots: [...(base.writableRoots ?? []), ...(override.writableRoots ?? [])],
|
|
105
|
+
readableRoots: [...(base.readableRoots ?? []), ...(override.readableRoots ?? [])],
|
|
106
|
+
plugins: mergePlugins(base.plugins, override.plugins),
|
|
107
|
+
models: [...(base.models ?? []), ...(override.models ?? [])],
|
|
108
|
+
providers: { ...base.providers, ...override.providers },
|
|
109
|
+
openAiCompatible: [...(base.openAiCompatible ?? []), ...(override.openAiCompatible ?? [])],
|
|
110
|
+
oauthProviders: [...(base.oauthProviders ?? []), ...(override.oauthProviders ?? [])],
|
|
111
|
+
sync: mergeSync(base.sync, override.sync),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Sync settings.
|
|
116
|
+
*
|
|
117
|
+
* `enabled` is the one field where the later side cannot win outright: off
|
|
118
|
+
* from either is off. Turning sync *on* is a decision about where a
|
|
119
|
+
* transcript goes, so nothing merged in later gets to make it on the user's
|
|
120
|
+
* behalf — not a project, and not a plugin. Exclusions accumulate for the
|
|
121
|
+
* same reason, exactly like `tools.deny`.
|
|
122
|
+
*
|
|
123
|
+
* The destination, credential and team merge normally here. Keeping a
|
|
124
|
+
* repository from setting them is `projectSafe`'s job, one layer up, where it
|
|
125
|
+
* is known which side is the repository.
|
|
126
|
+
*/
|
|
127
|
+
function mergeSync(base, override) {
|
|
128
|
+
if (!base && !override)
|
|
129
|
+
return undefined;
|
|
130
|
+
const enabled = base?.enabled === false || override?.enabled === false
|
|
131
|
+
? false
|
|
132
|
+
: (override?.enabled ?? base?.enabled);
|
|
133
|
+
const url = override?.url ?? base?.url;
|
|
134
|
+
const token = override?.token ?? base?.token;
|
|
135
|
+
const team = override?.team ?? base?.team;
|
|
136
|
+
return {
|
|
137
|
+
...(enabled !== undefined ? { enabled } : {}),
|
|
138
|
+
...(url ? { url } : {}),
|
|
139
|
+
...(token ? { token } : {}),
|
|
140
|
+
...(team ? { team } : {}),
|
|
141
|
+
exclude: [...(base?.exclude ?? []), ...(override?.exclude ?? [])],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function mergePlugins(base, override) {
|
|
145
|
+
return {
|
|
146
|
+
dirs: [...(base?.dirs ?? []), ...(override?.dirs ?? [])],
|
|
147
|
+
enabled: override?.enabled ?? base?.enabled,
|
|
148
|
+
disabled: [...(base?.disabled ?? []), ...(override?.disabled ?? [])],
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/** Read the project's instructions file, if one exists. */
|
|
152
|
+
export async function loadProjectInstructions(cwd, configured) {
|
|
153
|
+
const candidates = configured ? [configured] : DEFAULT_INSTRUCTIONS;
|
|
154
|
+
for (const candidate of candidates) {
|
|
155
|
+
try {
|
|
156
|
+
const body = await readFile(path.resolve(cwd, candidate), "utf8");
|
|
157
|
+
if (body.trim())
|
|
158
|
+
return body;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
async function readConfigFile(file) {
|
|
167
|
+
let raw;
|
|
168
|
+
try {
|
|
169
|
+
raw = await readFile(file, "utf8");
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
const parsed = parseJson(raw);
|
|
175
|
+
if (!parsed.ok) {
|
|
176
|
+
throw new ConfigError(`${file} is not valid JSON: ${parsed.error}`);
|
|
177
|
+
}
|
|
178
|
+
return parsed.value;
|
|
179
|
+
}
|
|
180
|
+
function mergeRules(base, override) {
|
|
181
|
+
return {
|
|
182
|
+
allow: [...(base?.allow ?? []), ...(override?.allow ?? [])],
|
|
183
|
+
// Denials accumulate: a project can add restrictions but not remove them.
|
|
184
|
+
deny: [...(base?.deny ?? []), ...(override?.deny ?? [])],
|
|
185
|
+
ask: [...(base?.ask ?? []), ...(override?.ask ?? [])],
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function mergeHooks(base, override) {
|
|
189
|
+
const merged = { ...base };
|
|
190
|
+
for (const [event, hooks] of Object.entries(override ?? {})) {
|
|
191
|
+
merged[event] = [...(merged[event] ?? []), ...(hooks ?? [])];
|
|
192
|
+
}
|
|
193
|
+
return merged;
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAU/C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA0J3C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,sBAAsB,EAAE,gBAAgB,CAAC,CAAC;AAC3E,MAAM,oBAAoB,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,2BAA2B,CAAC,CAAC;AAErF;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAClD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC7C,OAAO,WAAW,CAAC,IAAI,IAAI,EAAE,EAAE,WAAW,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IACzD,KAAK,MAAM,QAAQ,IAAI,gBAAgB,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC7D,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAS,WAAW,CAAC,OAAsB;IACzC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAC/C,IAAI,CAAC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;IACxE,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACpC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAiD;IAEjD,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACnD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAE7B,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;IAC1C,4EAA4E;IAC5E,iEAAiE;IACjE,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACpE,MAAM,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACzB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAmB,EAAE,QAAuB;IACtE,OAAO;QACL,GAAG,IAAI;QACP,GAAG,QAAQ;QACX,WAAW,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,CAAC;QAC/D,KAAK,EAAE;YACL,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,KAAK;YACjD,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;SACrE;QACD,UAAU,EAAE,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,QAAQ,CAAC,UAAU,EAAE;QAC1D,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;QAC7C,SAAS,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QACrE,SAAS,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QACrE,SAAS,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QACrE,SAAS,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QACrE,aAAa,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QACjF,aAAa,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QACjF,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC;QACrD,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QAC5D,SAAS,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,QAAQ,CAAC,SAAS,EAAE;QACvD,gBAAgB,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;QAC1F,cAAc,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;QACpF,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,SAAS,CAAC,IAAiB,EAAE,QAAqB;IACzD,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,OAAO,GACX,IAAI,EAAE,OAAO,KAAK,KAAK,IAAI,QAAQ,EAAE,OAAO,KAAK,KAAK;QACpD,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,CAAC,QAAQ,EAAE,OAAO,IAAI,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,QAAQ,EAAE,GAAG,IAAI,IAAI,EAAE,GAAG,CAAC;IACvC,MAAM,KAAK,GAAG,QAAQ,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,CAAC;IAC7C,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,CAAC;IAC1C,OAAO;QACL,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvB,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;KAClE,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,IAAmB,EAAE,QAAuB;IAChE,OAAO;QACL,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;QACxD,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,IAAI,EAAE,OAAO;QAC3C,QAAQ,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC;KACrE,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,GAAW,EACX,UAAmB;IAEnB,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC;IACpE,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;YAClE,IAAI,IAAI,CAAC,IAAI,EAAE;gBAAE,OAAO,IAAI,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,IAAY;IACxC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAgB,GAAG,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CAAC,GAAG,IAAI,uBAAuB,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC;AAED,SAAS,UAAU,CACjB,IAAiC,EACjC,QAAqC;IAErC,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC3D,0EAA0E;QAC1E,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;QACxD,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;KACtD,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,IAAiB,EAAE,QAAqB;IAC1D,MAAM,MAAM,GAAe,EAAE,GAAG,IAAI,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC;QAC5D,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export declare class HarnessError extends Error {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
readonly retryable: boolean;
|
|
4
|
+
readonly cause?: unknown;
|
|
5
|
+
constructor(message: string, opts?: {
|
|
6
|
+
code?: string;
|
|
7
|
+
retryable?: boolean;
|
|
8
|
+
cause?: unknown;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export declare class ConfigError extends HarnessError {
|
|
12
|
+
constructor(message: string, cause?: unknown);
|
|
13
|
+
}
|
|
14
|
+
export declare class ProviderError extends HarnessError {
|
|
15
|
+
readonly status?: number;
|
|
16
|
+
readonly provider: string;
|
|
17
|
+
constructor(provider: string, message: string, opts?: {
|
|
18
|
+
status?: number;
|
|
19
|
+
retryable?: boolean;
|
|
20
|
+
cause?: unknown;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export declare class ToolError extends HarnessError {
|
|
24
|
+
readonly toolName: string;
|
|
25
|
+
constructor(toolName: string, message: string, cause?: unknown);
|
|
26
|
+
}
|
|
27
|
+
export declare class PermissionDeniedError extends HarnessError {
|
|
28
|
+
constructor(message: string);
|
|
29
|
+
}
|
|
30
|
+
export declare class McpError extends HarnessError {
|
|
31
|
+
readonly server: string;
|
|
32
|
+
constructor(server: string, message: string, cause?: unknown);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The server answered 401: it has an identity to check and we have not proved
|
|
36
|
+
* one. Distinct from `McpError` because it is not a failure to be reported —
|
|
37
|
+
* it is the start of a login, and the caller needs the challenge to begin it.
|
|
38
|
+
*/
|
|
39
|
+
export declare class McpAuthRequiredError extends McpError {
|
|
40
|
+
/** The `WWW-Authenticate` header, which carries where to go discover auth. */
|
|
41
|
+
readonly challenge?: string;
|
|
42
|
+
readonly url: string;
|
|
43
|
+
constructor(server: string, url: string, challenge?: string);
|
|
44
|
+
}
|
|
45
|
+
export declare function isRetryableStatus(status: number | undefined): boolean;
|
|
46
|
+
export declare function errorMessage(err: unknown): string;
|