@agenthifive/openclaw-setup 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/auto-patch.d.ts +56 -0
- package/dist/auto-patch.d.ts.map +1 -0
- package/dist/auto-patch.js +422 -0
- package/dist/auto-patch.js.map +1 -0
- package/dist/cli.d.ts +18 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +51 -0
- package/dist/cli.js.map +1 -0
- package/dist/config-discovery.d.ts +41 -0
- package/dist/config-discovery.d.ts.map +1 -0
- package/dist/config-discovery.js +161 -0
- package/dist/config-discovery.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/setup-wizard.d.ts +34 -0
- package/dist/setup-wizard.d.ts.map +1 -0
- package/dist/setup-wizard.js +515 -0
- package/dist/setup-wizard.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/package.json +40 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { importES256Key, exchangeToken } from "./jwt-utils.js";
|
|
2
|
+
export class VaultTokenManager {
|
|
3
|
+
baseUrl;
|
|
4
|
+
agentId;
|
|
5
|
+
privateKeyJWK;
|
|
6
|
+
tokenAudience;
|
|
7
|
+
privateKeyObj = null;
|
|
8
|
+
accessToken = null;
|
|
9
|
+
tokenExpiresAt = 0; // epoch ms
|
|
10
|
+
refreshTimer = null;
|
|
11
|
+
refreshInFlight = null;
|
|
12
|
+
/** Called after every successful token refresh with the new token. */
|
|
13
|
+
onRefresh = null;
|
|
14
|
+
/** Called when token refresh fails with 401 — indicates the agent's key is no longer valid. */
|
|
15
|
+
onAuthFailure = null;
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
18
|
+
this.agentId = config.agentId;
|
|
19
|
+
this.privateKeyJWK = config.privateKey;
|
|
20
|
+
this.tokenAudience = (config.tokenAudience ?? this.baseUrl).replace(/\/+$/, "");
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Perform the initial token exchange and start the background refresh timer.
|
|
24
|
+
* Must be called (and awaited) before getToken().
|
|
25
|
+
*/
|
|
26
|
+
async init() {
|
|
27
|
+
// Import the JWK once
|
|
28
|
+
this.privateKeyObj = await importES256Key(this.privateKeyJWK);
|
|
29
|
+
// Initial token exchange
|
|
30
|
+
await this.refreshToken();
|
|
31
|
+
// Schedule background refresh — check every 30s, refresh when near expiry
|
|
32
|
+
this.refreshTimer = setInterval(() => {
|
|
33
|
+
if (Date.now() >= this.tokenExpiresAt - 60_000) {
|
|
34
|
+
this.refreshToken().catch((err) => {
|
|
35
|
+
const ttlLeft = Math.max(0, Math.round((this.tokenExpiresAt - Date.now()) / 1000));
|
|
36
|
+
console.error(`[vault-token-manager] refresh failed (current token expires in ${ttlLeft}s, ` +
|
|
37
|
+
`prefix: ${this.accessToken?.slice(0, 4) ?? "none"}): ${err instanceof Error ? err.message : String(err)}`);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}, 30_000);
|
|
41
|
+
// Don't keep the process alive just for token refresh
|
|
42
|
+
if (this.refreshTimer &&
|
|
43
|
+
typeof this.refreshTimer === "object" &&
|
|
44
|
+
"unref" in this.refreshTimer) {
|
|
45
|
+
this.refreshTimer.unref();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get the current bearer token. Synchronous — relies on background refresh.
|
|
50
|
+
* Throws if init() hasn't been called.
|
|
51
|
+
*/
|
|
52
|
+
getToken() {
|
|
53
|
+
if (!this.accessToken) {
|
|
54
|
+
throw new Error("VaultTokenManager not initialized — call init() first");
|
|
55
|
+
}
|
|
56
|
+
return this.accessToken;
|
|
57
|
+
}
|
|
58
|
+
/** Stop the background refresh timer. */
|
|
59
|
+
stop() {
|
|
60
|
+
if (this.refreshTimer) {
|
|
61
|
+
clearInterval(this.refreshTimer);
|
|
62
|
+
this.refreshTimer = null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Force an immediate token refresh. Called on-demand when a 401 is received.
|
|
67
|
+
* Coalesces concurrent requests — if a refresh is already in flight, callers
|
|
68
|
+
* wait for the same promise instead of hammering the token endpoint.
|
|
69
|
+
*/
|
|
70
|
+
async forceRefresh() {
|
|
71
|
+
if (this.refreshInFlight) {
|
|
72
|
+
try {
|
|
73
|
+
await this.refreshInFlight;
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const attempt = this.refreshToken();
|
|
81
|
+
this.refreshInFlight = attempt;
|
|
82
|
+
try {
|
|
83
|
+
await attempt;
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
this.refreshInFlight = null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async refreshToken() {
|
|
94
|
+
if (!this.privateKeyObj) {
|
|
95
|
+
throw new Error("Private key not imported — call init() first");
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const result = await exchangeToken(this.privateKeyObj, {
|
|
99
|
+
baseUrl: this.baseUrl,
|
|
100
|
+
agentId: this.agentId,
|
|
101
|
+
tokenAudience: this.tokenAudience,
|
|
102
|
+
});
|
|
103
|
+
const previousToken = this.accessToken;
|
|
104
|
+
this.accessToken = result.accessToken;
|
|
105
|
+
this.tokenExpiresAt = Date.now() + result.expiresIn * 1000;
|
|
106
|
+
console.log(`[vault-token-manager] Token refreshed (prefix: ${this.accessToken.slice(0, 4)}..., ` +
|
|
107
|
+
`ttl: ${result.expiresIn}s, previous: ${previousToken ? previousToken.slice(0, 4) + "..." : "none"})`);
|
|
108
|
+
// Notify listener (register.ts uses this to update the shared mutable auth object)
|
|
109
|
+
this.onRefresh?.(this.accessToken);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
// Check for 401 specifically
|
|
113
|
+
if (err instanceof Error && err.message.includes("401")) {
|
|
114
|
+
console.error("[vault-token-manager] Token exchange rejected (401). " +
|
|
115
|
+
"The agent's key pair is no longer valid — agent may have been disabled or key rotated. " +
|
|
116
|
+
"Generate a bootstrap secret from the AgentHiFive dashboard (Agents → Bootstrap Secret), " +
|
|
117
|
+
"then run `openclaw configure` to reconnect.");
|
|
118
|
+
this.onAuthFailure?.();
|
|
119
|
+
}
|
|
120
|
+
throw err;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=vault-token-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault-token-manager.js","sourceRoot":"","sources":["../src/vault-token-manager.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agenthifive/openclaw-setup",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": {
|
|
6
|
+
"ah5-setup": "dist/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc -p tsconfig.json",
|
|
13
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
14
|
+
"lint": "echo Lint: OK"
|
|
15
|
+
},
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/supersantux/AgentH5.git",
|
|
20
|
+
"directory": "packages/openclaw-setup"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"openclaw",
|
|
24
|
+
"agenthifive",
|
|
25
|
+
"vault",
|
|
26
|
+
"ai-agent",
|
|
27
|
+
"setup",
|
|
28
|
+
"cli"
|
|
29
|
+
],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"jose": "^5.9.3"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^20.0.0",
|
|
38
|
+
"typescript": "^5.6.0"
|
|
39
|
+
}
|
|
40
|
+
}
|