@agenthifive/openclaw 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/README.md +124 -0
- package/dist/client.d.ts +27 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +136 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt-utils.d.ts +29 -0
- package/dist/jwt-utils.d.ts.map +1 -0
- package/dist/jwt-utils.js +55 -0
- package/dist/jwt-utils.js.map +1 -0
- package/dist/patch-verify.d.ts +28 -0
- package/dist/patch-verify.d.ts.map +1 -0
- package/dist/patch-verify.js +72 -0
- package/dist/patch-verify.js.map +1 -0
- package/dist/pending-approvals.d.ts +55 -0
- package/dist/pending-approvals.d.ts.map +1 -0
- package/dist/pending-approvals.js +95 -0
- package/dist/pending-approvals.js.map +1 -0
- package/dist/prompt-reference.d.ts +51 -0
- package/dist/prompt-reference.d.ts.map +1 -0
- package/dist/prompt-reference.js +645 -0
- package/dist/prompt-reference.js.map +1 -0
- package/dist/register.d.ts +20 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +551 -0
- package/dist/register.js.map +1 -0
- package/dist/runtime.d.ts +66 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +87 -0
- package/dist/runtime.js.map +1 -0
- package/dist/session-context.d.ts +39 -0
- package/dist/session-context.d.ts.map +1 -0
- package/dist/session-context.js +58 -0
- package/dist/session-context.js.map +1 -0
- package/dist/setup-wizard.d.ts +28 -0
- package/dist/setup-wizard.d.ts.map +1 -0
- package/dist/setup-wizard.js +303 -0
- package/dist/setup-wizard.js.map +1 -0
- package/dist/tools.d.ts +27 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +128 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +93 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/vault-action-proxy.d.ts +75 -0
- package/dist/vault-action-proxy.d.ts.map +1 -0
- package/dist/vault-action-proxy.js +152 -0
- package/dist/vault-action-proxy.js.map +1 -0
- package/dist/vault-provider.d.ts +52 -0
- package/dist/vault-provider.d.ts.map +1 -0
- package/dist/vault-provider.js +37 -0
- package/dist/vault-provider.js.map +1 -0
- package/dist/vault-token-manager.d.ts +42 -0
- package/dist/vault-token-manager.d.ts.map +1 -0
- package/dist/vault-token-manager.js +124 -0
- package/dist/vault-token-manager.js.map +1 -0
- package/openclaw.plugin.json +59 -0
- package/package.json +58 -0
- package/patches/README.md +85 -0
- package/patches/model-auth.patch +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# @agenthifive/openclaw
|
|
2
|
+
|
|
3
|
+
OpenClaw plugin for [AgentHiFive](https://agenthifive.com) vault integration. Gives AI agents secure, policy-governed access to user accounts through vault-managed credentials and a brokered API proxy.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
- **5 agent tools** for executing API calls through the vault (Model B brokered proxy)
|
|
8
|
+
- **Step-up approval flow** for sensitive actions (user approves via dashboard)
|
|
9
|
+
- **Prompt injection** with chunked API reference docs for connected services
|
|
10
|
+
- **ES256 JWT auth** with automatic background token refresh
|
|
11
|
+
- **Setup wizard** (`openclaw setup-vault`) for bootstrapping agent auth
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
openclaw plugins install @agenthifive/openclaw
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or add to your OpenClaw config manually:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"plugins": {
|
|
26
|
+
"load": { "paths": ["@agenthifive/openclaw"] },
|
|
27
|
+
"entries": {
|
|
28
|
+
"agenthifive": {
|
|
29
|
+
"enabled": true,
|
|
30
|
+
"hooks": { "allowPromptInjection": true },
|
|
31
|
+
"config": { ... }
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. Setup
|
|
39
|
+
|
|
40
|
+
Run the setup wizard to bootstrap agent auth and discover connected services:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
openclaw setup-vault
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or non-interactively:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
openclaw setup-vault --base-url https://app.agenthifive.com --bootstrap-secret ah5b_...
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The wizard generates a JSON config block to paste into `~/.openclaw/openclaw.json`.
|
|
53
|
+
|
|
54
|
+
### 3. Connect Services
|
|
55
|
+
|
|
56
|
+
Add OAuth connections (Google, Microsoft, Slack, Telegram, etc.) and configure policies in the [AgentHiFive dashboard](https://app.agenthifive.com).
|
|
57
|
+
|
|
58
|
+
## Tools
|
|
59
|
+
|
|
60
|
+
| Tool | Description |
|
|
61
|
+
|------|-------------|
|
|
62
|
+
| `agenthifive_execute` | Execute an HTTP request through the vault proxy (Model B) |
|
|
63
|
+
| `agenthifive_approval_request` | Create a step-up approval request for sensitive actions |
|
|
64
|
+
| `agenthifive_approval_commit` | Wait for an approval to be resolved |
|
|
65
|
+
| `agenthifive_connections_list` | List available connections and their status |
|
|
66
|
+
| `agenthifive_connection_revoke` | Revoke a connection immediately |
|
|
67
|
+
|
|
68
|
+
## Configuration
|
|
69
|
+
|
|
70
|
+
Plugin config goes in `plugins.entries.agenthifive.config` in your `openclaw.json`:
|
|
71
|
+
|
|
72
|
+
| Key | Type | Description |
|
|
73
|
+
|-----|------|-------------|
|
|
74
|
+
| `baseUrl` | string | AgentHiFive API base URL |
|
|
75
|
+
| `auth.mode` | `"agent"` \| `"bearer"` | Authentication mode |
|
|
76
|
+
| `auth.agentId` | string | Agent ID (agent mode) |
|
|
77
|
+
| `auth.privateKey` | string | Base64-encoded ES256 JWK (agent mode) |
|
|
78
|
+
| `auth.token` | string | Bearer token (bearer mode) |
|
|
79
|
+
| `auth.tokenAudience` | string | Token audience override (optional) |
|
|
80
|
+
| `connectedProviders` | string[] | Provider names for prompt injection |
|
|
81
|
+
| `proxiedProviders` | string[] | Providers using vault LLM proxy |
|
|
82
|
+
| `pollTimeoutMs` | number | Approval poll timeout (default: 300000) |
|
|
83
|
+
| `pollIntervalMs` | number | Approval poll interval (default: 3000) |
|
|
84
|
+
|
|
85
|
+
## LLM Credential Proxying (Optional Patch)
|
|
86
|
+
|
|
87
|
+
To route LLM API calls through the vault (so agents don't need local API keys), apply the included patch:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pnpm patch openclaw
|
|
91
|
+
cd <temp-directory>
|
|
92
|
+
patch -p1 < node_modules/@agenthifive/openclaw/patches/model-auth.patch
|
|
93
|
+
pnpm patch-commit <temp-directory>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This adds vault credential resolution (Tier 0 + Tier 0.5) to OpenClaw's `resolveApiKeyForProvider()`. The patch uses dynamic imports and is a no-op when the plugin is not installed.
|
|
97
|
+
|
|
98
|
+
See [`patches/README.md`](patches/README.md) for details.
|
|
99
|
+
|
|
100
|
+
## Programmatic Usage
|
|
101
|
+
|
|
102
|
+
The package also exports classes for use outside the plugin system:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { VaultClient, VaultTokenManager, VaultActionProxy } from "@agenthifive/openclaw";
|
|
106
|
+
|
|
107
|
+
// Direct API client
|
|
108
|
+
const client = new VaultClient({
|
|
109
|
+
baseUrl: "https://app.agenthifive.com",
|
|
110
|
+
auth: { mode: "bearer", token: "ah5t_..." },
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// ES256 JWT token management
|
|
114
|
+
const tokenManager = new VaultTokenManager({
|
|
115
|
+
baseUrl: "https://app.agenthifive.com",
|
|
116
|
+
agentId: "agent_...",
|
|
117
|
+
privateKey: jwk,
|
|
118
|
+
});
|
|
119
|
+
await tokenManager.init();
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { OpenClawPluginConfig } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Lightweight HTTP client for communicating with the AgentHiFive Vault API.
|
|
4
|
+
* Supports agent auth (private_key_jwt with auto token refresh) and direct bearer tokens.
|
|
5
|
+
*/
|
|
6
|
+
export declare class VaultClient {
|
|
7
|
+
private readonly baseUrl;
|
|
8
|
+
private directBearerToken;
|
|
9
|
+
private privateKeyJWK;
|
|
10
|
+
private privateKeyObj;
|
|
11
|
+
private agentId;
|
|
12
|
+
private tokenAudience;
|
|
13
|
+
private accessToken;
|
|
14
|
+
private tokenExpiresAt;
|
|
15
|
+
constructor(config: OpenClawPluginConfig);
|
|
16
|
+
private getAuthHeader;
|
|
17
|
+
private refreshToken;
|
|
18
|
+
get<T>(path: string): Promise<T>;
|
|
19
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
20
|
+
put<T>(path: string, body?: unknown): Promise<T>;
|
|
21
|
+
private handleResponse;
|
|
22
|
+
}
|
|
23
|
+
export declare class VaultApiError extends Error {
|
|
24
|
+
readonly statusCode: number;
|
|
25
|
+
constructor(message: string, statusCode: number);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGvD;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAGjC,OAAO,CAAC,iBAAiB,CAAgB;IAGzC,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,aAAa,CAAS;IAG9B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,cAAc,CAAa;gBAEvB,MAAM,EAAE,oBAAoB;YAkB1B,aAAa;YAYb,YAAY;IAyBpB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAYhC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAgBjD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;YAgBxC,cAAc;CAiB7B;AAED,qBAAa,aAAc,SAAQ,KAAK;aAGpB,UAAU,EAAE,MAAM;gBADlC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM;CAKrC"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { importES256Key, exchangeToken, TokenExchangeError } from "./jwt-utils.js";
|
|
2
|
+
/**
|
|
3
|
+
* Lightweight HTTP client for communicating with the AgentHiFive Vault API.
|
|
4
|
+
* Supports agent auth (private_key_jwt with auto token refresh) and direct bearer tokens.
|
|
5
|
+
*/
|
|
6
|
+
export class VaultClient {
|
|
7
|
+
baseUrl;
|
|
8
|
+
// Direct bearer mode
|
|
9
|
+
directBearerToken;
|
|
10
|
+
// Agent auth mode
|
|
11
|
+
privateKeyJWK;
|
|
12
|
+
privateKeyObj = null;
|
|
13
|
+
agentId;
|
|
14
|
+
tokenAudience;
|
|
15
|
+
// Token cache
|
|
16
|
+
accessToken = null;
|
|
17
|
+
tokenExpiresAt = 0; // epoch ms
|
|
18
|
+
constructor(config) {
|
|
19
|
+
// Strip trailing slash
|
|
20
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
21
|
+
if (config.auth.mode === "bearer") {
|
|
22
|
+
this.directBearerToken = config.auth.token;
|
|
23
|
+
this.privateKeyJWK = null;
|
|
24
|
+
this.agentId = null;
|
|
25
|
+
this.tokenAudience = "";
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// agent mode
|
|
29
|
+
this.directBearerToken = null;
|
|
30
|
+
this.privateKeyJWK = config.auth.privateKey;
|
|
31
|
+
this.agentId = config.auth.agentId;
|
|
32
|
+
this.tokenAudience = config.auth.tokenAudience ?? this.baseUrl;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async getAuthHeader() {
|
|
36
|
+
if (this.directBearerToken) {
|
|
37
|
+
return `Bearer ${this.directBearerToken}`;
|
|
38
|
+
}
|
|
39
|
+
// Refresh token if expired or expiring within 30s
|
|
40
|
+
if (!this.accessToken || Date.now() >= this.tokenExpiresAt - 30_000) {
|
|
41
|
+
await this.refreshToken();
|
|
42
|
+
}
|
|
43
|
+
return `Bearer ${this.accessToken}`;
|
|
44
|
+
}
|
|
45
|
+
async refreshToken() {
|
|
46
|
+
if (!this.privateKeyJWK || !this.agentId) {
|
|
47
|
+
throw new Error("Cannot refresh token without privateKey and agentId");
|
|
48
|
+
}
|
|
49
|
+
if (!this.privateKeyObj) {
|
|
50
|
+
this.privateKeyObj = await importES256Key(this.privateKeyJWK);
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const result = await exchangeToken(this.privateKeyObj, {
|
|
54
|
+
baseUrl: this.baseUrl,
|
|
55
|
+
agentId: this.agentId,
|
|
56
|
+
tokenAudience: this.tokenAudience,
|
|
57
|
+
});
|
|
58
|
+
this.accessToken = result.accessToken;
|
|
59
|
+
this.tokenExpiresAt = Date.now() + result.expiresIn * 1000;
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
if (err instanceof TokenExchangeError) {
|
|
63
|
+
throw new VaultApiError(err.message, err.statusCode);
|
|
64
|
+
}
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async get(path) {
|
|
69
|
+
const authHeader = await this.getAuthHeader();
|
|
70
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
71
|
+
method: "GET",
|
|
72
|
+
headers: {
|
|
73
|
+
Authorization: authHeader,
|
|
74
|
+
Accept: "application/json",
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
return this.handleResponse(response);
|
|
78
|
+
}
|
|
79
|
+
async post(path, body) {
|
|
80
|
+
const authHeader = await this.getAuthHeader();
|
|
81
|
+
const headers = {
|
|
82
|
+
Authorization: authHeader,
|
|
83
|
+
Accept: "application/json",
|
|
84
|
+
};
|
|
85
|
+
const init = { method: "POST", headers };
|
|
86
|
+
if (body !== undefined) {
|
|
87
|
+
headers["Content-Type"] = "application/json";
|
|
88
|
+
init.body = JSON.stringify(body);
|
|
89
|
+
}
|
|
90
|
+
const response = await fetch(`${this.baseUrl}${path}`, init);
|
|
91
|
+
return this.handleResponse(response);
|
|
92
|
+
}
|
|
93
|
+
async put(path, body) {
|
|
94
|
+
const authHeader = await this.getAuthHeader();
|
|
95
|
+
const headers = {
|
|
96
|
+
Authorization: authHeader,
|
|
97
|
+
Accept: "application/json",
|
|
98
|
+
};
|
|
99
|
+
const init = { method: "PUT", headers };
|
|
100
|
+
if (body !== undefined) {
|
|
101
|
+
headers["Content-Type"] = "application/json";
|
|
102
|
+
init.body = JSON.stringify(body);
|
|
103
|
+
}
|
|
104
|
+
const response = await fetch(`${this.baseUrl}${path}`, init);
|
|
105
|
+
return this.handleResponse(response);
|
|
106
|
+
}
|
|
107
|
+
async handleResponse(response) {
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
const text = await response.text().catch(() => "");
|
|
110
|
+
let message = `Vault API error: ${response.status} ${response.statusText}`;
|
|
111
|
+
if (text) {
|
|
112
|
+
try {
|
|
113
|
+
const parsed = JSON.parse(text);
|
|
114
|
+
if (parsed.error)
|
|
115
|
+
message = parsed.error;
|
|
116
|
+
else if (parsed.message)
|
|
117
|
+
message = parsed.message;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
message = text;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
throw new VaultApiError(message, response.status);
|
|
124
|
+
}
|
|
125
|
+
return (await response.json());
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export class VaultApiError extends Error {
|
|
129
|
+
statusCode;
|
|
130
|
+
constructor(message, statusCode) {
|
|
131
|
+
super(message);
|
|
132
|
+
this.statusCode = statusCode;
|
|
133
|
+
this.name = "VaultApiError";
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { default as plugin } from "./register.js";
|
|
2
|
+
export { API_REFERENCE_PROMPT, API_REFERENCE_SECTIONS, CHUNKED_API_SECTIONS, buildApiReferencePrompt, writeReferenceFiles, buildChunkedPrompt, } from "./prompt-reference.js";
|
|
3
|
+
export { VaultClient, VaultApiError } from "./client.js";
|
|
4
|
+
export { importES256Key, exchangeToken, TokenExchangeError } from "./jwt-utils.js";
|
|
5
|
+
export { VaultTokenManager } from "./vault-token-manager.js";
|
|
6
|
+
export { VaultActionProxy } from "./vault-action-proxy.js";
|
|
7
|
+
export { VaultCredentialProvider } from "./vault-provider.js";
|
|
8
|
+
export { verifyPatches } from "./patch-verify.js";
|
|
9
|
+
export type { PatchStatus } from "./patch-verify.js";
|
|
10
|
+
export { runSetupWizard, parseSetupArgs, buildConfigOutput } from "./setup-wizard.js";
|
|
11
|
+
export type { SetupOptions } from "./setup-wizard.js";
|
|
12
|
+
export { setCurrentSessionContext, getCurrentSessionContext, parseSessionKey, } from "./session-context.js";
|
|
13
|
+
export { initPendingApprovals, addPendingApproval, loadPendingApprovals, savePendingApprovals, loadFallbackNotifications, saveFallbackNotifications, } from "./pending-approvals.js";
|
|
14
|
+
export type { OpenClawPluginConfig, OpenClawAuthConfig, ExecuteInput, ExecuteOutput, ExecuteApprovalOutput, ApprovalRequestInput, ApprovalRequestOutput, ApprovalCommitInput, ApprovalCommitOutput, ConnectionListItem, ConnectionsListOutput, ConnectionRevokeInput, ConnectionRevokeOutput, ActionProxy, ProxyRequest, ProxyResponse, CredentialProvider, CredentialQuery, CredentialResult, VaultProviderConfig, VaultTokenManagerConfig, SessionContext, PendingApproval, FallbackNotification, PluginLogger, } from "./types.js";
|
|
15
|
+
export { execute, approvalRequest, approvalCommit, connectionsList, connectionRevoke, } from "./tools.js";
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtF,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EAEtB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,OAAO,EACP,eAAe,EACf,cAAc,EACd,eAAe,EACf,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// OpenClaw plugin entry (register-based API for OpenClaw's plugin loader)
|
|
2
|
+
export { default as plugin } from "./register.js";
|
|
3
|
+
// Prompt reference (for LLM-as-integration-layer)
|
|
4
|
+
export { API_REFERENCE_PROMPT, API_REFERENCE_SECTIONS, CHUNKED_API_SECTIONS, buildApiReferencePrompt, writeReferenceFiles, buildChunkedPrompt, } from "./prompt-reference.js";
|
|
5
|
+
// Client
|
|
6
|
+
export { VaultClient, VaultApiError } from "./client.js";
|
|
7
|
+
// JWT utilities
|
|
8
|
+
export { importES256Key, exchangeToken, TokenExchangeError } from "./jwt-utils.js";
|
|
9
|
+
// Vault auth & runtime (M2 extractions)
|
|
10
|
+
export { VaultTokenManager } from "./vault-token-manager.js";
|
|
11
|
+
export { VaultActionProxy } from "./vault-action-proxy.js";
|
|
12
|
+
export { VaultCredentialProvider } from "./vault-provider.js";
|
|
13
|
+
// Patch runtime (separate entry point at @agenthifive/openclaw/runtime)
|
|
14
|
+
export { verifyPatches } from "./patch-verify.js";
|
|
15
|
+
// Setup wizard
|
|
16
|
+
export { runSetupWizard, parseSetupArgs, buildConfigOutput } from "./setup-wizard.js";
|
|
17
|
+
// Session context
|
|
18
|
+
export { setCurrentSessionContext, getCurrentSessionContext, parseSessionKey, } from "./session-context.js";
|
|
19
|
+
// Pending approvals
|
|
20
|
+
export { initPendingApprovals, addPendingApproval, loadPendingApprovals, savePendingApprovals, loadFallbackNotifications, saveFallbackNotifications, } from "./pending-approvals.js";
|
|
21
|
+
// Individual tool functions (for advanced usage)
|
|
22
|
+
export { execute, approvalRequest, approvalCommit, connectionsList, connectionRevoke, } from "./tools.js";
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,eAAe,CAAC;AAElD,kDAAkD;AAClD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,SAAS;AACT,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEzD,gBAAgB;AAChB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEnF,wCAAwC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,wEAAwE;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,eAAe;AACf,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtF,kBAAkB;AAClB,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAE9B,oBAAoB;AACpB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAgChC,iDAAiD;AACjD,OAAO,EACL,OAAO,EACP,eAAe,EACf,cAAc,EACd,eAAe,EACf,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared JWT utilities for ES256 client assertion auth.
|
|
3
|
+
*
|
|
4
|
+
* Used by both VaultClient (on-demand token refresh) and
|
|
5
|
+
* VaultTokenManager (background token refresh).
|
|
6
|
+
*/
|
|
7
|
+
import { type KeyLike } from "jose";
|
|
8
|
+
export type TokenExchangeConfig = {
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
agentId: string;
|
|
11
|
+
tokenAudience: string;
|
|
12
|
+
};
|
|
13
|
+
export type TokenExchangeResult = {
|
|
14
|
+
accessToken: string;
|
|
15
|
+
expiresIn: number;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Import a JWK as a KeyLike object for ES256 signing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function importES256Key(jwk: JsonWebKey): Promise<KeyLike>;
|
|
21
|
+
/**
|
|
22
|
+
* Sign an ES256 client assertion JWT and exchange it for an access token.
|
|
23
|
+
*/
|
|
24
|
+
export declare function exchangeToken(privateKey: KeyLike, config: TokenExchangeConfig): Promise<TokenExchangeResult>;
|
|
25
|
+
export declare class TokenExchangeError extends Error {
|
|
26
|
+
readonly statusCode: number;
|
|
27
|
+
constructor(message: string, statusCode: number);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=jwt-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt-utils.d.ts","sourceRoot":"","sources":["../src/jwt-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAsB,KAAK,OAAO,EAAY,MAAM,MAAM,CAAC;AAElE,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAEtE;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAuC9B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;aAGzB,UAAU,EAAE,MAAM;gBADlC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM;CAKrC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared JWT utilities for ES256 client assertion auth.
|
|
3
|
+
*
|
|
4
|
+
* Used by both VaultClient (on-demand token refresh) and
|
|
5
|
+
* VaultTokenManager (background token refresh).
|
|
6
|
+
*/
|
|
7
|
+
import { SignJWT, importJWK } from "jose";
|
|
8
|
+
/**
|
|
9
|
+
* Import a JWK as a KeyLike object for ES256 signing.
|
|
10
|
+
*/
|
|
11
|
+
export async function importES256Key(jwk) {
|
|
12
|
+
return (await importJWK(jwk, "ES256"));
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Sign an ES256 client assertion JWT and exchange it for an access token.
|
|
16
|
+
*/
|
|
17
|
+
export async function exchangeToken(privateKey, config) {
|
|
18
|
+
const now = Math.floor(Date.now() / 1000);
|
|
19
|
+
const assertion = await new SignJWT({})
|
|
20
|
+
.setProtectedHeader({ alg: "ES256" })
|
|
21
|
+
.setIssuer(config.agentId)
|
|
22
|
+
.setSubject(config.agentId)
|
|
23
|
+
.setAudience(config.tokenAudience)
|
|
24
|
+
.setIssuedAt(now)
|
|
25
|
+
.setExpirationTime(now + 30)
|
|
26
|
+
.setJti(crypto.randomUUID())
|
|
27
|
+
.sign(privateKey);
|
|
28
|
+
const response = await fetch(`${config.baseUrl}/v1/agents/token`, {
|
|
29
|
+
method: "POST",
|
|
30
|
+
headers: { "Content-Type": "application/json" },
|
|
31
|
+
body: JSON.stringify({
|
|
32
|
+
grant_type: "client_assertion",
|
|
33
|
+
client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
|
|
34
|
+
client_assertion: assertion,
|
|
35
|
+
}),
|
|
36
|
+
});
|
|
37
|
+
if (!response.ok) {
|
|
38
|
+
const text = await response.text().catch(() => "");
|
|
39
|
+
throw new TokenExchangeError(`Token exchange failed: ${response.status} ${text}`, response.status);
|
|
40
|
+
}
|
|
41
|
+
const result = (await response.json());
|
|
42
|
+
return {
|
|
43
|
+
accessToken: result.access_token,
|
|
44
|
+
expiresIn: result.expires_in,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export class TokenExchangeError extends Error {
|
|
48
|
+
statusCode;
|
|
49
|
+
constructor(message, statusCode) {
|
|
50
|
+
super(message);
|
|
51
|
+
this.statusCode = statusCode;
|
|
52
|
+
this.name = "TokenExchangeError";
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=jwt-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt-utils.js","sourceRoot":"","sources":["../src/jwt-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,SAAS,EAA0B,MAAM,MAAM,CAAC;AAalE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAe;IAClD,OAAO,CAAC,MAAM,SAAS,CAAC,GAAU,EAAE,OAAO,CAAC,CAAY,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAmB,EACnB,MAA2B;IAE3B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,MAAM,IAAI,OAAO,CAAC,EAAE,CAAC;SACpC,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;SACpC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC;SACzB,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC;SAC1B,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC;SACjC,WAAW,CAAC,GAAG,CAAC;SAChB,iBAAiB,CAAC,GAAG,GAAG,EAAE,CAAC;SAC3B,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;SAC3B,IAAI,CAAC,UAAU,CAAC,CAAC;IAEpB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,kBAAkB,EAAE;QAChE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,UAAU,EAAE,kBAAkB;YAC9B,qBAAqB,EAAE,wDAAwD;YAC/E,gBAAgB,EAAE,SAAS;SAC5B,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,MAAM,IAAI,kBAAkB,CAC1B,0BAA0B,QAAQ,CAAC,MAAM,IAAI,IAAI,EAAE,EACnD,QAAQ,CAAC,MAAM,CAChB,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAGpC,CAAC;IAEF,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,YAAY;QAChC,SAAS,EAAE,MAAM,CAAC,UAAU;KAC7B,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAGzB;IAFlB,YACE,OAAe,EACC,UAAkB;QAElC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,eAAU,GAAV,UAAU,CAAQ;QAGlC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime verification of whether OpenClaw core patches are applied.
|
|
3
|
+
*
|
|
4
|
+
* Called during plugin registration to inform the user whether credential
|
|
5
|
+
* proxying features are available. The plugin works fully (tools, hooks,
|
|
6
|
+
* prompt injection) WITHOUT patches — they only enable LLM credential
|
|
7
|
+
* proxying via model-auth.ts.
|
|
8
|
+
*/
|
|
9
|
+
import type { PluginLogger } from "./pending-approvals.js";
|
|
10
|
+
export type PatchStatus = {
|
|
11
|
+
/** Whether the model-auth.ts patch is applied (Tier 0 + Tier 0.5) */
|
|
12
|
+
modelAuth: boolean;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Probe whether the model-auth patch is applied by checking if OpenClaw's
|
|
16
|
+
* resolveApiKeyForProvider function consults our runtime module.
|
|
17
|
+
*
|
|
18
|
+
* Strategy: We check if the patched module can be resolved. The patch adds
|
|
19
|
+
* a dynamic import of "@agenthifive/openclaw/runtime" — if the import path
|
|
20
|
+
* resolves, the module exists. The actual behavior test would require calling
|
|
21
|
+
* resolveApiKeyForProvider which is too invasive for a startup check.
|
|
22
|
+
*
|
|
23
|
+
* Instead, we do a simpler check: look for our credential resolution code
|
|
24
|
+
* in the model-auth module by attempting to import it and checking for the
|
|
25
|
+
* patched function signature.
|
|
26
|
+
*/
|
|
27
|
+
export declare function verifyPatches(logger: PluginLogger): Promise<PatchStatus>;
|
|
28
|
+
//# sourceMappingURL=patch-verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch-verify.d.ts","sourceRoot":"","sources":["../src/patch-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,MAAM,MAAM,WAAW,GAAG;IACxB,qEAAqE;IACrE,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAiC9E"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime verification of whether OpenClaw core patches are applied.
|
|
3
|
+
*
|
|
4
|
+
* Called during plugin registration to inform the user whether credential
|
|
5
|
+
* proxying features are available. The plugin works fully (tools, hooks,
|
|
6
|
+
* prompt injection) WITHOUT patches — they only enable LLM credential
|
|
7
|
+
* proxying via model-auth.ts.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Probe whether the model-auth patch is applied by checking if OpenClaw's
|
|
11
|
+
* resolveApiKeyForProvider function consults our runtime module.
|
|
12
|
+
*
|
|
13
|
+
* Strategy: We check if the patched module can be resolved. The patch adds
|
|
14
|
+
* a dynamic import of "@agenthifive/openclaw/runtime" — if the import path
|
|
15
|
+
* resolves, the module exists. The actual behavior test would require calling
|
|
16
|
+
* resolveApiKeyForProvider which is too invasive for a startup check.
|
|
17
|
+
*
|
|
18
|
+
* Instead, we do a simpler check: look for our credential resolution code
|
|
19
|
+
* in the model-auth module by attempting to import it and checking for the
|
|
20
|
+
* patched function signature.
|
|
21
|
+
*/
|
|
22
|
+
export async function verifyPatches(logger) {
|
|
23
|
+
const status = { modelAuth: false };
|
|
24
|
+
try {
|
|
25
|
+
// Try to import model-auth and check if it has vault awareness
|
|
26
|
+
// The patched version exports a marker or has vault-related code paths.
|
|
27
|
+
// We check by looking for the `resolveApiKeyForProvider` and testing
|
|
28
|
+
// whether it consults our runtime module.
|
|
29
|
+
//
|
|
30
|
+
// Simplest reliable approach: check if the source contains our patch
|
|
31
|
+
// marker comment that we add in the patch file.
|
|
32
|
+
const modelAuthPath = await findModuleFile("../agents/model-auth.js");
|
|
33
|
+
if (modelAuthPath) {
|
|
34
|
+
const { readFileSync } = await import("node:fs");
|
|
35
|
+
const source = readFileSync(modelAuthPath, "utf-8");
|
|
36
|
+
status.modelAuth = source.includes("@agenthifive/openclaw/runtime");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// Module not found or read failed — patches not applied
|
|
41
|
+
}
|
|
42
|
+
if (!status.modelAuth) {
|
|
43
|
+
logger.warn?.("AgentHiFive: model-auth patch not detected. LLM credential proxying is unavailable. " +
|
|
44
|
+
"Tools, prompt injection, and approval flow work normally. " +
|
|
45
|
+
"To enable credential proxying, apply the patch: " +
|
|
46
|
+
"see @agenthifive/openclaw/patches/README.md");
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
logger.info?.("AgentHiFive: model-auth patch detected — credential proxying enabled");
|
|
50
|
+
}
|
|
51
|
+
return status;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Attempt to find the filesystem path of a module relative to openclaw's location.
|
|
55
|
+
* Returns null if the module cannot be found.
|
|
56
|
+
*/
|
|
57
|
+
async function findModuleFile(specifier) {
|
|
58
|
+
try {
|
|
59
|
+
// Use import.meta.resolve to find the module path
|
|
60
|
+
const resolved = import.meta.resolve(specifier);
|
|
61
|
+
// Convert file:// URL to path
|
|
62
|
+
if (resolved.startsWith("file://")) {
|
|
63
|
+
const { fileURLToPath } = await import("node:url");
|
|
64
|
+
return fileURLToPath(resolved);
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=patch-verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch-verify.js","sourceRoot":"","sources":["../src/patch-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAoB;IACtD,MAAM,MAAM,GAAgB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAEjD,IAAI,CAAC;QACH,+DAA+D;QAC/D,wEAAwE;QACxE,qEAAqE;QACrE,0CAA0C;QAC1C,EAAE;QACF,qEAAqE;QACrE,gDAAgD;QAChD,MAAM,aAAa,GAAG,MAAM,cAAc,CAAC,yBAAyB,CAAC,CAAC;QACtE,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YACpD,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,+BAA+B,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;IAC1D,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,EAAE,CACX,sFAAsF;YACpF,4DAA4D;YAC5D,kDAAkD;YAClD,6CAA6C,CAChD,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,EAAE,CAAC,sEAAsE,CAAC,CAAC;IACxF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,cAAc,CAAC,SAAiB;IAC7C,IAAI,CAAC;QACH,kDAAkD;QAClD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChD,8BAA8B;QAC9B,IAAI,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACnC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State file for tracking pending vault step-up approvals.
|
|
3
|
+
*
|
|
4
|
+
* When the vault_execute agent tool gets a 202 (approval required), it writes
|
|
5
|
+
* the pending approval to {stateDir}/vault-pending-approvals.json.
|
|
6
|
+
*
|
|
7
|
+
* The before_agent_start hook reads this file on each turn, polls the AH5 API
|
|
8
|
+
* for resolved approvals, and injects notifications into the agent's context
|
|
9
|
+
* so it can re-submit approved requests and continue multi-step plans.
|
|
10
|
+
*
|
|
11
|
+
* Unlike the fork version, this module accepts `stateDir` as a parameter
|
|
12
|
+
* instead of importing from OpenClaw's config/paths.
|
|
13
|
+
*/
|
|
14
|
+
export type PendingApproval = {
|
|
15
|
+
approvalRequestId: string;
|
|
16
|
+
service?: string;
|
|
17
|
+
connectionId?: string;
|
|
18
|
+
method: string;
|
|
19
|
+
url: string;
|
|
20
|
+
/** Human-readable summary of what the request does */
|
|
21
|
+
summary: string;
|
|
22
|
+
createdAt: string;
|
|
23
|
+
expiresAt?: string;
|
|
24
|
+
/** Routing info for auto-triggering the agent when the approval resolves */
|
|
25
|
+
sessionKey?: string;
|
|
26
|
+
channel?: string;
|
|
27
|
+
peerId?: string;
|
|
28
|
+
peerKind?: string;
|
|
29
|
+
threadId?: string;
|
|
30
|
+
};
|
|
31
|
+
export type FallbackNotification = {
|
|
32
|
+
approvalRequestId: string;
|
|
33
|
+
notificationText: string;
|
|
34
|
+
createdAt: string;
|
|
35
|
+
};
|
|
36
|
+
export interface PluginLogger {
|
|
37
|
+
info?: (...args: unknown[]) => void;
|
|
38
|
+
warn?: (...args: unknown[]) => void;
|
|
39
|
+
error?: (...args: unknown[]) => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Initialize the pending approvals module with a state directory and logger.
|
|
43
|
+
* Must be called before any other function in this module.
|
|
44
|
+
*/
|
|
45
|
+
export declare function initPendingApprovals(stateDir: string, logger?: PluginLogger): void;
|
|
46
|
+
/**
|
|
47
|
+
* Add a pending approval to the state file.
|
|
48
|
+
* Called by the vault_execute tool when it receives a 202.
|
|
49
|
+
*/
|
|
50
|
+
export declare function addPendingApproval(approval: PendingApproval): void;
|
|
51
|
+
export declare function loadPendingApprovals(): PendingApproval[];
|
|
52
|
+
export declare function savePendingApprovals(approvals: PendingApproval[]): void;
|
|
53
|
+
export declare function loadFallbackNotifications(): FallbackNotification[];
|
|
54
|
+
export declare function saveFallbackNotifications(notifications: FallbackNotification[]): void;
|
|
55
|
+
//# sourceMappingURL=pending-approvals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-approvals.d.ts","sourceRoot":"","sources":["../src/pending-approvals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,MAAM,MAAM,eAAe,GAAG;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAMF,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACtC;AAKD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CAGlF;AASD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAYlE;AAED,wBAAgB,oBAAoB,IAAI,eAAe,EAAE,CAWxD;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,IAAI,CAMvE;AAED,wBAAgB,yBAAyB,IAAI,oBAAoB,EAAE,CAWlE;AAED,wBAAgB,yBAAyB,CAAC,aAAa,EAAE,oBAAoB,EAAE,GAAG,IAAI,CAMrF"}
|