manifest 5.33.16 → 5.33.18
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 +5 -0
- package/dist/backend/config/app.config.js +10 -1
- package/dist/backend/database/database.module.js +7 -0
- package/dist/backend/database/migrations/1774000000000-WidenKeyHashColumn.js +15 -0
- package/dist/backend/entities/agent-api-key.entity.js +1 -1
- package/dist/backend/entities/api-key.entity.js +1 -1
- package/dist/backend/otlp/guards/agent-key-auth.guard.js +24 -0
- package/dist/index.js +7 -7
- package/dist/openclaw.plugin.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -54,6 +54,11 @@ openclaw plugins install manifest
|
|
|
54
54
|
openclaw gateway restart
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
+
> **OpenClaw 2026.3.22+:** If you see `"manifest" is a skill`, install from npm directly:
|
|
58
|
+
> ```bash
|
|
59
|
+
> openclaw plugins install "/tmp/$(npm pack manifest --pack-destination /tmp | tail -1)"
|
|
60
|
+
> ```
|
|
61
|
+
|
|
57
62
|
Dashboard opens at **http://127.0.0.1:2099**. The plugin starts an embedded server, runs the dashboard locally, and registers itself as a provider automatically. No account or API key needed.
|
|
58
63
|
|
|
59
64
|
### Cloud vs local
|
|
@@ -3,11 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.appConfig = void 0;
|
|
4
4
|
const config_1 = require("@nestjs/config");
|
|
5
5
|
const path_1 = require("path");
|
|
6
|
+
const os_1 = require("os");
|
|
6
7
|
function sanitizeDbPath(raw) {
|
|
7
8
|
if (!raw)
|
|
8
9
|
return '';
|
|
9
10
|
return (0, path_1.resolve)(raw);
|
|
10
11
|
}
|
|
12
|
+
function resolveLocalDbPath() {
|
|
13
|
+
const explicit = process.env['MANIFEST_DB_PATH'];
|
|
14
|
+
if (explicit)
|
|
15
|
+
return sanitizeDbPath(explicit);
|
|
16
|
+
if (process.env['MANIFEST_MODE'] !== 'local')
|
|
17
|
+
return '';
|
|
18
|
+
return (0, path_1.join)((0, os_1.homedir)(), '.openclaw', 'manifest', 'manifest.db');
|
|
19
|
+
}
|
|
11
20
|
function resolveDatabaseUrl() {
|
|
12
21
|
const url = process.env['DATABASE_URL'];
|
|
13
22
|
if (url)
|
|
@@ -23,7 +32,7 @@ exports.appConfig = (0, config_1.registerAs)('app', () => ({
|
|
|
23
32
|
nodeEnv: process.env['NODE_ENV'] ?? 'development',
|
|
24
33
|
databaseUrl: resolveDatabaseUrl(),
|
|
25
34
|
manifestMode: process.env['MANIFEST_MODE'] ?? 'cloud',
|
|
26
|
-
dbPath:
|
|
35
|
+
dbPath: resolveLocalDbPath(),
|
|
27
36
|
corsOrigin: process.env['CORS_ORIGIN'] ?? 'http://localhost:3000',
|
|
28
37
|
betterAuthUrl: process.env['BETTER_AUTH_URL'] ?? '',
|
|
29
38
|
throttleTtl: Number(process.env['THROTTLE_TTL'] ?? 60000),
|
|
@@ -11,6 +11,8 @@ const common_1 = require("@nestjs/common");
|
|
|
11
11
|
const typeorm_1 = require("@nestjs/typeorm");
|
|
12
12
|
const schedule_1 = require("@nestjs/schedule");
|
|
13
13
|
const config_1 = require("@nestjs/config");
|
|
14
|
+
const fs_1 = require("fs");
|
|
15
|
+
const path_1 = require("path");
|
|
14
16
|
const agent_message_entity_1 = require("../entities/agent-message.entity");
|
|
15
17
|
const llm_call_entity_1 = require("../entities/llm-call.entity");
|
|
16
18
|
const tool_execution_entity_1 = require("../entities/tool-execution.entity");
|
|
@@ -69,6 +71,7 @@ const _1773650000000_AddProviderRegion_1 = require("./migrations/1773650000000-A
|
|
|
69
71
|
const _1773700000000_DropSecurityEventTable_1 = require("./migrations/1773700000000-DropSecurityEventTable");
|
|
70
72
|
const _1773800000000_FixNegativeCosts_1 = require("./migrations/1773800000000-FixNegativeCosts");
|
|
71
73
|
const _1773900000000_AddKeyPrefixIndex_1 = require("./migrations/1773900000000-AddKeyPrefixIndex");
|
|
74
|
+
const _1774000000000_WidenKeyHashColumn_1 = require("./migrations/1774000000000-WidenKeyHashColumn");
|
|
72
75
|
const entities = [
|
|
73
76
|
agent_message_entity_1.AgentMessage,
|
|
74
77
|
llm_call_entity_1.LlmCall,
|
|
@@ -127,6 +130,7 @@ const migrations = [
|
|
|
127
130
|
_1773700000000_DropSecurityEventTable_1.DropSecurityEventTable1773700000000,
|
|
128
131
|
_1773800000000_FixNegativeCosts_1.FixNegativeCosts1773800000000,
|
|
129
132
|
_1773900000000_AddKeyPrefixIndex_1.AddKeyPrefixIndex1773900000000,
|
|
133
|
+
_1774000000000_WidenKeyHashColumn_1.WidenKeyHashColumn1774000000000,
|
|
130
134
|
];
|
|
131
135
|
const isLocalMode = process.env['MANIFEST_MODE'] === 'local';
|
|
132
136
|
function buildModeServices() {
|
|
@@ -145,6 +149,9 @@ exports.DatabaseModule = DatabaseModule = __decorate([
|
|
|
145
149
|
useFactory: (config) => {
|
|
146
150
|
if (isLocalMode) {
|
|
147
151
|
const dbPath = config.get('app.dbPath') || ':memory:';
|
|
152
|
+
if (dbPath !== ':memory:') {
|
|
153
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(dbPath), { recursive: true, mode: 0o700 });
|
|
154
|
+
}
|
|
148
155
|
return {
|
|
149
156
|
type: 'sqljs',
|
|
150
157
|
location: dbPath === ':memory:' ? undefined : dbPath,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WidenKeyHashColumn1774000000000 = void 0;
|
|
4
|
+
class WidenKeyHashColumn1774000000000 {
|
|
5
|
+
async up(queryRunner) {
|
|
6
|
+
await queryRunner.query(`ALTER TABLE "agent_api_keys" ALTER COLUMN "key_hash" TYPE varchar(128)`);
|
|
7
|
+
await queryRunner.query(`ALTER TABLE "api_keys" ALTER COLUMN "key_hash" TYPE varchar(128)`);
|
|
8
|
+
}
|
|
9
|
+
async down(queryRunner) {
|
|
10
|
+
await queryRunner.query(`ALTER TABLE "agent_api_keys" ALTER COLUMN "key_hash" TYPE varchar(64) USING left("key_hash", 64)`);
|
|
11
|
+
await queryRunner.query(`ALTER TABLE "api_keys" ALTER COLUMN "key_hash" TYPE varchar(64) USING left("key_hash", 64)`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.WidenKeyHashColumn1774000000000 = WidenKeyHashColumn1774000000000;
|
|
15
|
+
//# sourceMappingURL=1774000000000-WidenKeyHashColumn.js.map
|
|
@@ -40,7 +40,7 @@ __decorate([
|
|
|
40
40
|
], AgentApiKey.prototype, "key", void 0);
|
|
41
41
|
__decorate([
|
|
42
42
|
(0, typeorm_1.Index)({ unique: true }),
|
|
43
|
-
(0, typeorm_1.Column)('varchar', { length:
|
|
43
|
+
(0, typeorm_1.Column)('varchar', { length: 128 }),
|
|
44
44
|
__metadata("design:type", String)
|
|
45
45
|
], AgentApiKey.prototype, "key_hash", void 0);
|
|
46
46
|
__decorate([
|
|
@@ -33,7 +33,7 @@ __decorate([
|
|
|
33
33
|
], ApiKey.prototype, "key", void 0);
|
|
34
34
|
__decorate([
|
|
35
35
|
(0, typeorm_1.Index)({ unique: true }),
|
|
36
|
-
(0, typeorm_1.Column)('varchar', { length:
|
|
36
|
+
(0, typeorm_1.Column)('varchar', { length: 128 }),
|
|
37
37
|
__metadata("design:type", String)
|
|
38
38
|
], ApiKey.prototype, "key_hash", void 0);
|
|
39
39
|
__decorate([
|
|
@@ -121,6 +121,30 @@ let AgentKeyAuthGuard = AgentKeyAuthGuard_1 = class AgentKeyAuthGuard {
|
|
|
121
121
|
.getMany();
|
|
122
122
|
const keyRecord = candidates.find((c) => (0, hash_util_1.verifyKey)(token, c.key_hash));
|
|
123
123
|
if (!keyRecord) {
|
|
124
|
+
if (isLocal) {
|
|
125
|
+
if (candidates.length > 0) {
|
|
126
|
+
const best = candidates[0];
|
|
127
|
+
request.ingestionContext = {
|
|
128
|
+
tenantId: best.tenant_id,
|
|
129
|
+
agentId: best.agent_id,
|
|
130
|
+
agentName: best.agent.name,
|
|
131
|
+
userId: best.tenant.name,
|
|
132
|
+
};
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
const fallback = await this.resolveDevContext();
|
|
136
|
+
if (fallback) {
|
|
137
|
+
request.ingestionContext = fallback;
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
request.ingestionContext = {
|
|
141
|
+
tenantId: local_mode_constants_1.LOCAL_TENANT_ID,
|
|
142
|
+
agentId: local_mode_constants_1.LOCAL_AGENT_ID,
|
|
143
|
+
agentName: local_mode_constants_1.LOCAL_AGENT_NAME,
|
|
144
|
+
userId: local_mode_constants_1.LOCAL_USER_ID,
|
|
145
|
+
};
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
124
148
|
this.logger.warn(`Rejected unknown agent key: ${token.substring(0, 8)}...`);
|
|
125
149
|
throw new common_1.UnauthorizedException('Invalid API key');
|
|
126
150
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* manifest-local — OpenClaw Self-Hosted LLM Router */
|
|
2
|
-
"use strict";var f=require("fs"),l=require("path"),
|
|
2
|
+
"use strict";var f=require("fs"),l=require("path"),m=require("os"),u=(0,l.join)((0,m.homedir)(),".openclaw","manifest"),h=3e3;async function d(i,t){try{let e=await fetch(`http://${i}:${t}/api/v1/health`,{signal:AbortSignal.timeout(h)});if(!e.ok)return!1;let n=await e.json();return n!==null&&typeof n=="object"&&"status"in n&&n.status==="healthy"}catch{return!1}}function g(i,t,e,n){(0,f.existsSync)(u)||(0,f.mkdirSync)(u,{recursive:!0,mode:448});let a=(0,l.join)(u,"manifest.db");n.debug("[manifest] Starting embedded server...");let o;try{o=require("./server")}catch(r){let s=r instanceof Error?r.message:String(r);n.error(`[manifest] Failed to load embedded server.
|
|
3
3
|
Error: ${s}
|
|
4
|
-
This is a packaging error \u2014 please reinstall the manifest plugin.`);return}i.registerService({id:"manifest",start:async()=>{if(
|
|
5
|
-
The dashboard may not be accessible at http://${
|
|
4
|
+
This is a packaging error \u2014 please reinstall the manifest plugin.`);return}i.registerService({id:"manifest",start:async()=>{if(n.debug("[manifest] Service start callback invoked"),await d(e,t)){n.info(`[manifest] Reusing existing server at http://${e}:${t}`);return}try{await o.start({port:t,host:e,dbPath:a,quiet:!0}),await d(e,t)?(n.info(`[manifest] Dashboard -> http://${e}:${t}`),n.info(`[manifest] DB: ${a}`)):(n.warn??n.info)(`[manifest] Server started but health check failed.
|
|
5
|
+
The dashboard may not be accessible at http://${e}:${t}`)}catch(s){let c=s instanceof Error?s.message:String(s);c.includes("EADDRINUSE")||c.includes("address already in use")?await d(e,t)?n.info(`[manifest] Reusing existing server at http://${e}:${t}`):n.error(`[manifest] Port ${t} is already in use by another process.
|
|
6
6
|
Change it with: openclaw config set plugins.entries.manifest.config.port ${t+1}
|
|
7
|
-
Then restart the gateway.`):
|
|
7
|
+
Then restart the gateway.`):n.error(`[manifest] Failed to start local server: ${c}
|
|
8
8
|
Try reinstalling: openclaw plugins install manifest
|
|
9
|
-
Then restart: openclaw gateway restart`)}}})}module.exports={id:"manifest",name:"Manifest \u2014 Self-Hosted LLM Router",register(i){let t=i.logger||{info:(...r)=>console.log(...r),debug:()=>{},error:(...r)=>console.error(...r),warn:(...r)=>console.warn(...r)},
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
Then restart: openclaw gateway restart`)}}})}module.exports={id:"manifest",name:"Manifest \u2014 Self-Hosted LLM Router",register(i){let t=i.logger||{info:(...r)=>console.log(...r),debug:()=>{},error:(...r)=>console.error(...r),warn:(...r)=>console.warn(...r)},e=i.pluginConfig||{},n=e&&typeof e=="object"&&"config"in e&&e.config!=null&&typeof e.config=="object"?e.config:e,a=typeof n.port=="number"&&n.port>0?n.port:2099,o=typeof n.host=="string"&&n.host.length>0?n.host:"127.0.0.1";t.info(`[manifest] \u{1F99A} Dashboard: http://${o}:${a}
|
|
10
|
+
[manifest] \u{1F99A} The plugin starts an embedded server.
|
|
11
|
+
[manifest] \u{1F99A} Open the dashboard to connect a provider and start routing.`),g(i,a,o,t)}};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "manifest",
|
|
3
3
|
"name": "Manifest — Self-Hosted LLM Router",
|
|
4
|
-
"version": "5.33.
|
|
4
|
+
"version": "5.33.18",
|
|
5
5
|
"description": "Run the Manifest LLM router locally with SQLite. Zero-config dashboard included.",
|
|
6
6
|
"author": "MNFST Inc.",
|
|
7
7
|
"homepage": "https://manifest.build",
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "manifest",
|
|
3
3
|
"name": "Manifest — Self-Hosted LLM Router",
|
|
4
|
-
"version": "5.33.
|
|
4
|
+
"version": "5.33.18",
|
|
5
5
|
"description": "Run the Manifest LLM router locally with SQLite. Zero-config dashboard included.",
|
|
6
6
|
"author": "MNFST Inc.",
|
|
7
7
|
"homepage": "https://manifest.build",
|