lavs-runtime 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 +75 -0
- package/dist/function-executor.d.ts +26 -0
- package/dist/function-executor.d.ts.map +1 -0
- package/dist/function-executor.js +116 -0
- package/dist/function-executor.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/loader.d.ts +37 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +187 -0
- package/dist/loader.js.map +1 -0
- package/dist/permission-checker.d.ts +86 -0
- package/dist/permission-checker.d.ts.map +1 -0
- package/dist/permission-checker.js +172 -0
- package/dist/permission-checker.js.map +1 -0
- package/dist/rate-limiter.d.ts +57 -0
- package/dist/rate-limiter.d.ts.map +1 -0
- package/dist/rate-limiter.js +84 -0
- package/dist/rate-limiter.js.map +1 -0
- package/dist/script-executor.d.ts +70 -0
- package/dist/script-executor.d.ts.map +1 -0
- package/dist/script-executor.js +314 -0
- package/dist/script-executor.js.map +1 -0
- package/dist/subscription-manager.d.ts +106 -0
- package/dist/subscription-manager.d.ts.map +1 -0
- package/dist/subscription-manager.js +257 -0
- package/dist/subscription-manager.js.map +1 -0
- package/dist/tool-generator.d.ts +51 -0
- package/dist/tool-generator.d.ts.map +1 -0
- package/dist/tool-generator.js +147 -0
- package/dist/tool-generator.js.map +1 -0
- package/dist/types.d.ts +171 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +38 -0
- package/dist/types.js.map +1 -0
- package/dist/validator.d.ts +94 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +187 -0
- package/dist/validator.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# lavs-runtime
|
|
2
|
+
|
|
3
|
+
Server-side runtime for the **LAVS (Local Agent View Service)** protocol.
|
|
4
|
+
|
|
5
|
+
Provides manifest loading, JSON Schema validation, handler execution (script & function), permission checking, rate limiting, subscription management, and AI tool generation.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install lavs-runtime
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import {
|
|
17
|
+
ManifestLoader,
|
|
18
|
+
LAVSValidator,
|
|
19
|
+
ScriptExecutor,
|
|
20
|
+
PermissionChecker,
|
|
21
|
+
LAVSToolGenerator,
|
|
22
|
+
} from 'lavs-runtime';
|
|
23
|
+
|
|
24
|
+
// Load and validate a LAVS manifest
|
|
25
|
+
const loader = new ManifestLoader();
|
|
26
|
+
const manifest = await loader.load('./lavs.json');
|
|
27
|
+
|
|
28
|
+
const validator = new LAVSValidator();
|
|
29
|
+
const result = validator.validateManifest(manifest);
|
|
30
|
+
|
|
31
|
+
if (result.valid) {
|
|
32
|
+
// Execute a script handler
|
|
33
|
+
const executor = new ScriptExecutor();
|
|
34
|
+
const output = await executor.execute(manifest.endpoints[0].handler, {
|
|
35
|
+
endpointId: 'getData',
|
|
36
|
+
agentId: 'my-agent',
|
|
37
|
+
workdir: process.cwd(),
|
|
38
|
+
permissions: manifest.permissions ?? {},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Generate AI Tools from Manifest
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
const generator = new LAVSToolGenerator();
|
|
47
|
+
const tools = generator.generate(manifest);
|
|
48
|
+
|
|
49
|
+
// tools can be passed to Claude or other LLM APIs
|
|
50
|
+
for (const tool of tools) {
|
|
51
|
+
console.log(tool.name, tool.description);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Core Modules
|
|
56
|
+
|
|
57
|
+
| Module | Description |
|
|
58
|
+
|--------|-------------|
|
|
59
|
+
| `ManifestLoader` | Load and parse `lavs.json` manifests |
|
|
60
|
+
| `LAVSValidator` | Validate manifests and endpoint I/O against JSON Schema |
|
|
61
|
+
| `ScriptExecutor` | Execute script handlers (node, python, etc.) |
|
|
62
|
+
| `FunctionExecutor` | Execute JS/TS function handlers |
|
|
63
|
+
| `PermissionChecker` | Enforce file access and execution permissions |
|
|
64
|
+
| `LAVSRateLimiter` | Rate limiting for endpoint calls |
|
|
65
|
+
| `SubscriptionManager` | SSE-based real-time subscriptions |
|
|
66
|
+
| `LAVSToolGenerator` | Generate Claude-compatible tool definitions |
|
|
67
|
+
|
|
68
|
+
## Related Packages
|
|
69
|
+
|
|
70
|
+
- [`lavs-types`](https://www.npmjs.com/package/lavs-types) — Protocol type definitions
|
|
71
|
+
- [`lavs-client`](https://www.npmjs.com/package/lavs-client) — Client SDK for frontend applications
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
MIT
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LAVS Function Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes function handlers by dynamically importing JS/TS modules
|
|
5
|
+
* and calling exported functions.
|
|
6
|
+
*/
|
|
7
|
+
import { FunctionHandler, ExecutionContext } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* LAVS Function Executor - executes function handlers from JS modules
|
|
10
|
+
*/
|
|
11
|
+
export declare class FunctionExecutor {
|
|
12
|
+
/**
|
|
13
|
+
* Execute a function handler
|
|
14
|
+
*
|
|
15
|
+
* @param handler - Function handler configuration (module path + function name)
|
|
16
|
+
* @param input - Input data to pass to the function
|
|
17
|
+
* @param context - Execution context with permissions
|
|
18
|
+
* @returns Function return value
|
|
19
|
+
*/
|
|
20
|
+
execute(handler: FunctionHandler, input: unknown, context: ExecutionContext): Promise<unknown>;
|
|
21
|
+
/**
|
|
22
|
+
* Execute a function with a timeout
|
|
23
|
+
*/
|
|
24
|
+
private executeWithTimeout;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=function-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function-executor.d.ts","sourceRoot":"","sources":["../src/function-executor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,eAAe,EACf,gBAAgB,EAGjB,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,qBAAa,gBAAgB;IAC3B;;;;;;;OAOG;IACG,OAAO,CACX,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,OAAO,CAAC;IA0DnB;;OAEG;YACW,kBAAkB;CA0BjC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LAVS Function Executor
|
|
4
|
+
*
|
|
5
|
+
* Executes function handlers by dynamically importing JS/TS modules
|
|
6
|
+
* and calling exported functions.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.FunctionExecutor = void 0;
|
|
43
|
+
const types_1 = require("./types");
|
|
44
|
+
/**
|
|
45
|
+
* LAVS Function Executor - executes function handlers from JS modules
|
|
46
|
+
*/
|
|
47
|
+
class FunctionExecutor {
|
|
48
|
+
/**
|
|
49
|
+
* Execute a function handler
|
|
50
|
+
*
|
|
51
|
+
* @param handler - Function handler configuration (module path + function name)
|
|
52
|
+
* @param input - Input data to pass to the function
|
|
53
|
+
* @param context - Execution context with permissions
|
|
54
|
+
* @returns Function return value
|
|
55
|
+
*/
|
|
56
|
+
async execute(handler, input, context) {
|
|
57
|
+
const startTime = Date.now();
|
|
58
|
+
console.log(`[LAVS] Executing function for ${context.endpointId}`, {
|
|
59
|
+
module: handler.module,
|
|
60
|
+
function: handler.function,
|
|
61
|
+
});
|
|
62
|
+
try {
|
|
63
|
+
// 1. Dynamically import the module
|
|
64
|
+
let mod;
|
|
65
|
+
try {
|
|
66
|
+
mod = await Promise.resolve(`${handler.module}`).then(s => __importStar(require(s)));
|
|
67
|
+
}
|
|
68
|
+
catch (importError) {
|
|
69
|
+
const message = importError instanceof Error ? importError.message : String(importError);
|
|
70
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.HandlerError, `Failed to import module '${handler.module}': ${message}`);
|
|
71
|
+
}
|
|
72
|
+
// 2. Find the function
|
|
73
|
+
const fn = mod[handler.function];
|
|
74
|
+
if (typeof fn !== 'function') {
|
|
75
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.HandlerError, `Function '${handler.function}' not found or not a function in module '${handler.module}'`);
|
|
76
|
+
}
|
|
77
|
+
// 3. Execute with timeout
|
|
78
|
+
const timeout = context.timeout || context.permissions.maxExecutionTime || 30000;
|
|
79
|
+
const result = await this.executeWithTimeout(fn, input, context, timeout);
|
|
80
|
+
const duration = Date.now() - startTime;
|
|
81
|
+
console.log(`[LAVS] Function completed in ${duration}ms`, {
|
|
82
|
+
endpointId: context.endpointId,
|
|
83
|
+
});
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
if (error instanceof types_1.LAVSError) {
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
91
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.HandlerError, `Function execution failed: ${message}`, { cause: error });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Execute a function with a timeout
|
|
96
|
+
*/
|
|
97
|
+
async executeWithTimeout(fn, input, context, timeout) {
|
|
98
|
+
return new Promise((resolve, reject) => {
|
|
99
|
+
const timer = setTimeout(() => {
|
|
100
|
+
reject(new types_1.LAVSError(types_1.LAVSErrorCode.Timeout, `Function execution timeout after ${timeout}ms`));
|
|
101
|
+
}, timeout);
|
|
102
|
+
// Call the function - pass both input and context
|
|
103
|
+
Promise.resolve(fn(input, context))
|
|
104
|
+
.then((result) => {
|
|
105
|
+
clearTimeout(timer);
|
|
106
|
+
resolve(result);
|
|
107
|
+
})
|
|
108
|
+
.catch((error) => {
|
|
109
|
+
clearTimeout(timer);
|
|
110
|
+
reject(error);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.FunctionExecutor = FunctionExecutor;
|
|
116
|
+
//# sourceMappingURL=function-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function-executor.js","sourceRoot":"","sources":["../src/function-executor.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,mCAKiB;AAEjB;;GAEG;AACH,MAAa,gBAAgB;IAC3B;;;;;;;OAOG;IACH,KAAK,CAAC,OAAO,CACX,OAAwB,EACxB,KAAc,EACd,OAAyB;QAEzB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,iCAAiC,OAAO,CAAC,UAAU,EAAE,EAAE;YACjE,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,mCAAmC;YACnC,IAAI,GAA4B,CAAC;YACjC,IAAI,CAAC;gBACH,GAAG,GAAG,yBAAa,OAAO,CAAC,MAAM,uCAAC,CAAC;YACrC,CAAC;YAAC,OAAO,WAAoB,EAAE,CAAC;gBAC9B,MAAM,OAAO,GAAG,WAAW,YAAY,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBACzF,MAAM,IAAI,iBAAS,CACjB,qBAAa,CAAC,YAAY,EAC1B,4BAA4B,OAAO,CAAC,MAAM,MAAM,OAAO,EAAE,CAC1D,CAAC;YACJ,CAAC;YAED,uBAAuB;YACvB,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACjC,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;gBAC7B,MAAM,IAAI,iBAAS,CACjB,qBAAa,CAAC,YAAY,EAC1B,aAAa,OAAO,CAAC,QAAQ,4CAA4C,OAAO,CAAC,MAAM,GAAG,CAC3F,CAAC;YACJ,CAAC;YAED,0BAA0B;YAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC,gBAAgB,IAAI,KAAK,CAAC;YACjF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAC1C,EAAqE,EACrE,KAAK,EACL,OAAO,EACP,OAAO,CACR,CAAC;YAEF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,gCAAgC,QAAQ,IAAI,EAAE;gBACxD,UAAU,EAAE,OAAO,CAAC,UAAU;aAC/B,CAAC,CAAC;YAEH,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAI,KAAK,YAAY,iBAAS,EAAE,CAAC;gBAC/B,MAAM,KAAK,CAAC;YACd,CAAC;YAED,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,MAAM,IAAI,iBAAS,CACjB,qBAAa,CAAC,YAAY,EAC1B,8BAA8B,OAAO,EAAE,EACvC,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,kBAAkB,CAC9B,EAAmE,EACnE,KAAc,EACd,OAAyB,EACzB,OAAe;QAEf,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC9C,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,MAAM,CAAC,IAAI,iBAAS,CAClB,qBAAa,CAAC,OAAO,EACrB,oCAAoC,OAAO,IAAI,CAChD,CAAC,CAAC;YACL,CAAC,EAAE,OAAO,CAAC,CAAC;YAEZ,kDAAkD;YAClD,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;iBAChC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;gBACf,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACf,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AApGD,4CAoGC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LAVS Runtime - Server-side SDK
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all core runtime modules for convenient importing.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { ManifestLoader, LAVSValidator, ScriptExecutor } from '@lavs/runtime';
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export type { LAVSManifest, Endpoint, Handler, ScriptHandler, FunctionHandler, HTTPHandler, MCPHandler, Schema, JSONSchema, TypeDefinitions, ViewConfig, ComponentSource, Permissions, ExecutionContext, } from './types';
|
|
12
|
+
export { LAVSError, LAVSErrorCode } from './types';
|
|
13
|
+
export { ManifestLoader } from './loader';
|
|
14
|
+
export { LAVSValidator } from './validator';
|
|
15
|
+
export type { ValidationResult, ValidationError } from './validator';
|
|
16
|
+
export { ScriptExecutor } from './script-executor';
|
|
17
|
+
export { FunctionExecutor } from './function-executor';
|
|
18
|
+
export { PermissionChecker } from './permission-checker';
|
|
19
|
+
export { LAVSRateLimiter } from './rate-limiter';
|
|
20
|
+
export type { RateLimitConfig, RateLimitResult } from './rate-limiter';
|
|
21
|
+
export { SubscriptionManager, subscriptionManager } from './subscription-manager';
|
|
22
|
+
export type { SubscriptionEvent, SSEResponse } from './subscription-manager';
|
|
23
|
+
export { LAVSToolGenerator } from './tool-generator';
|
|
24
|
+
export type { ClaudeTool, ToolExecutor, GeneratedTool } from './tool-generator';
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EACV,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,aAAa,EACb,eAAe,EACf,WAAW,EACX,UAAU,EACV,MAAM,EACN,UAAU,EACV,eAAe,EACf,UAAU,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,GACjB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGnD,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClF,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LAVS Runtime - Server-side SDK
|
|
4
|
+
*
|
|
5
|
+
* Re-exports all core runtime modules for convenient importing.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { ManifestLoader, LAVSValidator, ScriptExecutor } from '@lavs/runtime';
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.LAVSToolGenerator = exports.subscriptionManager = exports.SubscriptionManager = exports.LAVSRateLimiter = exports.PermissionChecker = exports.FunctionExecutor = exports.ScriptExecutor = exports.LAVSValidator = exports.ManifestLoader = exports.LAVSErrorCode = exports.LAVSError = void 0;
|
|
14
|
+
var types_1 = require("./types");
|
|
15
|
+
Object.defineProperty(exports, "LAVSError", { enumerable: true, get: function () { return types_1.LAVSError; } });
|
|
16
|
+
Object.defineProperty(exports, "LAVSErrorCode", { enumerable: true, get: function () { return types_1.LAVSErrorCode; } });
|
|
17
|
+
// Core modules
|
|
18
|
+
var loader_1 = require("./loader");
|
|
19
|
+
Object.defineProperty(exports, "ManifestLoader", { enumerable: true, get: function () { return loader_1.ManifestLoader; } });
|
|
20
|
+
var validator_1 = require("./validator");
|
|
21
|
+
Object.defineProperty(exports, "LAVSValidator", { enumerable: true, get: function () { return validator_1.LAVSValidator; } });
|
|
22
|
+
var script_executor_1 = require("./script-executor");
|
|
23
|
+
Object.defineProperty(exports, "ScriptExecutor", { enumerable: true, get: function () { return script_executor_1.ScriptExecutor; } });
|
|
24
|
+
var function_executor_1 = require("./function-executor");
|
|
25
|
+
Object.defineProperty(exports, "FunctionExecutor", { enumerable: true, get: function () { return function_executor_1.FunctionExecutor; } });
|
|
26
|
+
var permission_checker_1 = require("./permission-checker");
|
|
27
|
+
Object.defineProperty(exports, "PermissionChecker", { enumerable: true, get: function () { return permission_checker_1.PermissionChecker; } });
|
|
28
|
+
var rate_limiter_1 = require("./rate-limiter");
|
|
29
|
+
Object.defineProperty(exports, "LAVSRateLimiter", { enumerable: true, get: function () { return rate_limiter_1.LAVSRateLimiter; } });
|
|
30
|
+
var subscription_manager_1 = require("./subscription-manager");
|
|
31
|
+
Object.defineProperty(exports, "SubscriptionManager", { enumerable: true, get: function () { return subscription_manager_1.SubscriptionManager; } });
|
|
32
|
+
Object.defineProperty(exports, "subscriptionManager", { enumerable: true, get: function () { return subscription_manager_1.subscriptionManager; } });
|
|
33
|
+
var tool_generator_1 = require("./tool-generator");
|
|
34
|
+
Object.defineProperty(exports, "LAVSToolGenerator", { enumerable: true, get: function () { return tool_generator_1.LAVSToolGenerator; } });
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAmBH,iCAAmD;AAA1C,kGAAA,SAAS,OAAA;AAAE,sGAAA,aAAa,OAAA;AAEjC,eAAe;AACf,mCAA0C;AAAjC,wGAAA,cAAc,OAAA;AACvB,yCAA4C;AAAnC,0GAAA,aAAa,OAAA;AAEtB,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,yDAAuD;AAA9C,qHAAA,gBAAgB,OAAA;AACzB,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,+CAAiD;AAAxC,+GAAA,eAAe,OAAA;AAExB,+DAAkF;AAAzE,2HAAA,mBAAmB,OAAA;AAAE,2HAAA,mBAAmB,OAAA;AAEjD,mDAAqD;AAA5C,mHAAA,iBAAiB,OAAA"}
|
package/dist/loader.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LAVS Manifest Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads and validates lavs.json configuration files.
|
|
5
|
+
*/
|
|
6
|
+
import { LAVSManifest } from './types';
|
|
7
|
+
export declare class ManifestLoader {
|
|
8
|
+
/**
|
|
9
|
+
* Load LAVS manifest from file
|
|
10
|
+
* @param manifestPath - Path to lavs.json
|
|
11
|
+
* @returns Parsed and validated manifest with resolved paths
|
|
12
|
+
*/
|
|
13
|
+
load(manifestPath: string): Promise<LAVSManifest>;
|
|
14
|
+
/**
|
|
15
|
+
* Validate manifest structure and required fields
|
|
16
|
+
*/
|
|
17
|
+
private validateManifest;
|
|
18
|
+
/**
|
|
19
|
+
* Validate individual endpoint definition
|
|
20
|
+
*/
|
|
21
|
+
private validateEndpoint;
|
|
22
|
+
/**
|
|
23
|
+
* Validate handler configuration
|
|
24
|
+
*/
|
|
25
|
+
private validateHandler;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve relative paths in manifest to absolute paths
|
|
28
|
+
* This makes the manifest portable and allows scripts to use relative paths
|
|
29
|
+
*/
|
|
30
|
+
private resolvePaths;
|
|
31
|
+
/**
|
|
32
|
+
* Check if a command looks like a relative script path
|
|
33
|
+
* e.g., "scripts/handler.js", "./handler.py", "handler.sh"
|
|
34
|
+
*/
|
|
35
|
+
private isRelativeScriptPath;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,YAAY,EAA4D,MAAM,SAAS,CAAC;AAEjG,qBAAa,cAAc;IACzB;;;;OAIG;IACG,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IA+CvD;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA4CxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAyBxB;;OAEG;IACH,OAAO,CAAC,eAAe;IA6DvB;;;OAGG;IACH,OAAO,CAAC,YAAY;IA2CpB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;CAa7B"}
|
package/dist/loader.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LAVS Manifest Loader
|
|
4
|
+
*
|
|
5
|
+
* Loads and validates lavs.json configuration files.
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.ManifestLoader = void 0;
|
|
12
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
const types_1 = require("./types");
|
|
15
|
+
class ManifestLoader {
|
|
16
|
+
/**
|
|
17
|
+
* Load LAVS manifest from file
|
|
18
|
+
* @param manifestPath - Path to lavs.json
|
|
19
|
+
* @returns Parsed and validated manifest with resolved paths
|
|
20
|
+
*/
|
|
21
|
+
async load(manifestPath) {
|
|
22
|
+
try {
|
|
23
|
+
// 1. Check if file exists
|
|
24
|
+
const exists = await promises_1.default.access(manifestPath).then(() => true).catch(() => false);
|
|
25
|
+
if (!exists) {
|
|
26
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, `Manifest file not found: ${manifestPath}`);
|
|
27
|
+
}
|
|
28
|
+
// 2. Read file
|
|
29
|
+
const content = await promises_1.default.readFile(manifestPath, 'utf-8');
|
|
30
|
+
// 3. Parse JSON
|
|
31
|
+
let parsed;
|
|
32
|
+
try {
|
|
33
|
+
parsed = JSON.parse(content);
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
37
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.ParseError, `Invalid JSON in manifest: ${message}`, { cause: e });
|
|
38
|
+
}
|
|
39
|
+
// 4. Basic validation
|
|
40
|
+
this.validateManifest(parsed);
|
|
41
|
+
// 5. Resolve relative paths
|
|
42
|
+
const manifest = this.resolvePaths(parsed, manifestPath);
|
|
43
|
+
return manifest;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (error instanceof types_1.LAVSError) {
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
50
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InternalError, `Failed to load manifest: ${message}`, { cause: error });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Validate manifest structure and required fields
|
|
55
|
+
*/
|
|
56
|
+
validateManifest(manifest) {
|
|
57
|
+
// Check required top-level fields
|
|
58
|
+
if (!manifest.lavs) {
|
|
59
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, 'Missing required field: lavs');
|
|
60
|
+
}
|
|
61
|
+
if (!manifest.name) {
|
|
62
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, 'Missing required field: name');
|
|
63
|
+
}
|
|
64
|
+
if (!manifest.version) {
|
|
65
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, 'Missing required field: version');
|
|
66
|
+
}
|
|
67
|
+
if (!Array.isArray(manifest.endpoints)) {
|
|
68
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, 'Missing or invalid field: endpoints (must be array)');
|
|
69
|
+
}
|
|
70
|
+
// Validate each endpoint + uniqueness check
|
|
71
|
+
const seenIds = new Set();
|
|
72
|
+
for (const endpoint of manifest.endpoints) {
|
|
73
|
+
this.validateEndpoint(endpoint);
|
|
74
|
+
if (seenIds.has(endpoint.id)) {
|
|
75
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, `Duplicate endpoint ID: '${endpoint.id}'. Endpoint IDs must be unique.`);
|
|
76
|
+
}
|
|
77
|
+
seenIds.add(endpoint.id);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Validate individual endpoint definition
|
|
82
|
+
*/
|
|
83
|
+
validateEndpoint(endpoint) {
|
|
84
|
+
if (!endpoint.id) {
|
|
85
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, 'Endpoint missing required field: id');
|
|
86
|
+
}
|
|
87
|
+
if (!endpoint.method || !['query', 'mutation', 'subscription'].includes(endpoint.method)) {
|
|
88
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, `Invalid endpoint method: ${endpoint.method} (must be query, mutation, or subscription)`);
|
|
89
|
+
}
|
|
90
|
+
if (!endpoint.handler) {
|
|
91
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, `Endpoint ${endpoint.id} missing required field: handler`);
|
|
92
|
+
}
|
|
93
|
+
this.validateHandler(endpoint.handler, endpoint.id);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Validate handler configuration
|
|
97
|
+
*/
|
|
98
|
+
validateHandler(handler, endpointId) {
|
|
99
|
+
if (!handler.type) {
|
|
100
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, `Handler for ${endpointId} missing required field: type`);
|
|
101
|
+
}
|
|
102
|
+
const validTypes = ['script', 'function', 'http', 'mcp'];
|
|
103
|
+
if (!validTypes.includes(handler.type)) {
|
|
104
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, `Invalid handler type: ${handler.type} (must be one of: ${validTypes.join(', ')})`);
|
|
105
|
+
}
|
|
106
|
+
// Type-specific validation
|
|
107
|
+
if (handler.type === 'script') {
|
|
108
|
+
if (!handler.command) {
|
|
109
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, `Script handler for ${endpointId} missing required field: command`);
|
|
110
|
+
}
|
|
111
|
+
if (handler.input && !['args', 'stdin', 'env'].includes(handler.input)) {
|
|
112
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, `Invalid script input mode: ${handler.input} (must be args, stdin, or env)`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (handler.type === 'function') {
|
|
116
|
+
if (!handler.module || !handler.function) {
|
|
117
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, `Function handler for ${endpointId} missing required fields: module, function`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (handler.type === 'http') {
|
|
121
|
+
if (!handler.url || !handler.method) {
|
|
122
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, `HTTP handler for ${endpointId} missing required fields: url, method`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (handler.type === 'mcp') {
|
|
126
|
+
if (!handler.server || !handler.tool) {
|
|
127
|
+
throw new types_1.LAVSError(types_1.LAVSErrorCode.InvalidRequest, `MCP handler for ${endpointId} missing required fields: server, tool`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Resolve relative paths in manifest to absolute paths
|
|
133
|
+
* This makes the manifest portable and allows scripts to use relative paths
|
|
134
|
+
*/
|
|
135
|
+
resolvePaths(manifest, manifestPath) {
|
|
136
|
+
const basedir = path_1.default.dirname(manifestPath);
|
|
137
|
+
// Clone to avoid mutations
|
|
138
|
+
const resolved = JSON.parse(JSON.stringify(manifest));
|
|
139
|
+
// Resolve endpoint handlers
|
|
140
|
+
for (const endpoint of resolved.endpoints) {
|
|
141
|
+
const handler = endpoint.handler;
|
|
142
|
+
if (handler.type === 'script') {
|
|
143
|
+
// Resolve script command path if it looks like a relative file path
|
|
144
|
+
// (has .js, .py, etc. extension and doesn't start with /)
|
|
145
|
+
const cmd = handler.command;
|
|
146
|
+
if (this.isRelativeScriptPath(cmd)) {
|
|
147
|
+
handler.command = path_1.default.resolve(basedir, cmd);
|
|
148
|
+
}
|
|
149
|
+
// Resolve cwd if specified
|
|
150
|
+
if (handler.cwd && !path_1.default.isAbsolute(handler.cwd)) {
|
|
151
|
+
handler.cwd = path_1.default.resolve(basedir, handler.cwd);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (handler.type === 'function') {
|
|
155
|
+
// Resolve module path
|
|
156
|
+
if (!path_1.default.isAbsolute(handler.module)) {
|
|
157
|
+
handler.module = path_1.default.resolve(basedir, handler.module);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Resolve view component paths
|
|
162
|
+
if (resolved.view?.component?.type === 'local') {
|
|
163
|
+
const comp = resolved.view.component;
|
|
164
|
+
if (!path_1.default.isAbsolute(comp.path)) {
|
|
165
|
+
comp.path = path_1.default.resolve(basedir, comp.path);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return resolved;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Check if a command looks like a relative script path
|
|
172
|
+
* e.g., "scripts/handler.js", "./handler.py", "handler.sh"
|
|
173
|
+
*/
|
|
174
|
+
isRelativeScriptPath(cmd) {
|
|
175
|
+
// If starts with ./ or ../, definitely relative
|
|
176
|
+
if (cmd.startsWith('./') || cmd.startsWith('../')) {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
// If has path separators and common script extensions
|
|
180
|
+
const scriptExtensions = ['.js', '.ts', '.py', '.sh', '.rb', '.php'];
|
|
181
|
+
const hasExtension = scriptExtensions.some(ext => cmd.endsWith(ext));
|
|
182
|
+
const hasPathSep = cmd.includes('/');
|
|
183
|
+
return hasExtension && (hasPathSep || !cmd.includes(' '));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
exports.ManifestLoader = ManifestLoader;
|
|
187
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LAVS Permission Checker
|
|
3
|
+
*
|
|
4
|
+
* Enforces permission constraints declared in LAVS manifests.
|
|
5
|
+
*
|
|
6
|
+
* ## Enforcement Model
|
|
7
|
+
*
|
|
8
|
+
* LAVS permissions have two enforcement levels:
|
|
9
|
+
*
|
|
10
|
+
* | Permission | Level | What is checked |
|
|
11
|
+
* |-----------------|----------|------------------------------------------------|
|
|
12
|
+
* | Path traversal | ENFORCED | Handler cwd and command paths are validated |
|
|
13
|
+
* | fileAccess | ADVISORY | Glob pattern matching at dispatch time; |
|
|
14
|
+
* | | | NOT intercepted at OS/syscall level during |
|
|
15
|
+
* | | | script execution. Scripts can still access |
|
|
16
|
+
* | | | files the process has OS-level permission for. |
|
|
17
|
+
* | networkAccess | ADVISORY | Declared for auditing; not enforced at runtime. |
|
|
18
|
+
* | | | Use OS-level isolation (nsjail, Docker) for |
|
|
19
|
+
* | | | strict enforcement. |
|
|
20
|
+
* | maxExecTime | ENFORCED | Handler killed via SIGTERM/SIGKILL on timeout. |
|
|
21
|
+
* | maxMemory | ADVISORY | Not enforced in current runtime. |
|
|
22
|
+
*
|
|
23
|
+
* Future: Consider OS-level sandboxing for fileAccess and networkAccess.
|
|
24
|
+
*/
|
|
25
|
+
import { Permissions, ScriptHandler } from './types';
|
|
26
|
+
/**
|
|
27
|
+
* LAVS Permission Checker - enforces manifest-declared security constraints
|
|
28
|
+
*/
|
|
29
|
+
export declare class PermissionChecker {
|
|
30
|
+
/**
|
|
31
|
+
* Merge manifest-level and endpoint-level permissions.
|
|
32
|
+
* Endpoint-level permissions take precedence over manifest-level.
|
|
33
|
+
*
|
|
34
|
+
* @param manifestPermissions - Manifest-level permissions (defaults)
|
|
35
|
+
* @param endpointPermissions - Endpoint-level permissions (overrides)
|
|
36
|
+
* @returns Merged permissions object
|
|
37
|
+
*/
|
|
38
|
+
mergePermissions(manifestPermissions?: Permissions, endpointPermissions?: Permissions): Permissions;
|
|
39
|
+
/**
|
|
40
|
+
* Check if a target path is within the allowed base directory.
|
|
41
|
+
* Prevents path traversal attacks (e.g., ../../etc/passwd).
|
|
42
|
+
*
|
|
43
|
+
* @param targetPath - The path to check (absolute or relative)
|
|
44
|
+
* @param allowedBase - The allowed base directory (absolute)
|
|
45
|
+
* @throws LAVSError with code PermissionDenied if path is outside allowed base
|
|
46
|
+
*/
|
|
47
|
+
checkPathTraversal(targetPath: string, allowedBase: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* Check if a handler's working directory is within the allowed base.
|
|
50
|
+
*
|
|
51
|
+
* @param handler - Script handler with optional cwd
|
|
52
|
+
* @param agentDir - Agent directory (the allowed base)
|
|
53
|
+
* @throws LAVSError with code PermissionDenied if cwd is outside agent directory
|
|
54
|
+
*/
|
|
55
|
+
checkHandlerCwd(handler: ScriptHandler, agentDir: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Check if file access patterns allow a given path.
|
|
58
|
+
* Uses glob matching against permissions.fileAccess patterns.
|
|
59
|
+
*
|
|
60
|
+
* @param filePath - The file path to check (relative to agent dir)
|
|
61
|
+
* @param permissions - Permission constraints including fileAccess patterns
|
|
62
|
+
* @returns true if access is allowed, false otherwise
|
|
63
|
+
*/
|
|
64
|
+
checkFileAccess(filePath: string, permissions: Permissions): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Get the effective execution timeout for a handler.
|
|
67
|
+
* Priority: handler.timeout > permissions.maxExecutionTime > default (30000ms)
|
|
68
|
+
*
|
|
69
|
+
* @param handler - Script handler with optional timeout
|
|
70
|
+
* @param permissions - Permission constraints with optional maxExecutionTime
|
|
71
|
+
* @param defaultTimeout - Default timeout in milliseconds (default: 30000)
|
|
72
|
+
* @returns Effective timeout in milliseconds
|
|
73
|
+
*/
|
|
74
|
+
getEffectiveTimeout(handler: ScriptHandler, permissions: Permissions, defaultTimeout?: number): number;
|
|
75
|
+
/**
|
|
76
|
+
* Run all permission checks for a script handler execution.
|
|
77
|
+
* This is a convenience method that combines multiple checks.
|
|
78
|
+
*
|
|
79
|
+
* @param handler - Script handler configuration
|
|
80
|
+
* @param permissions - Merged permissions
|
|
81
|
+
* @param agentDir - Agent base directory
|
|
82
|
+
* @throws LAVSError if any permission check fails
|
|
83
|
+
*/
|
|
84
|
+
assertAllowed(handler: ScriptHandler, permissions: Permissions, agentDir: string): void;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=permission-checker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-checker.d.ts","sourceRoot":"","sources":["../src/permission-checker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,OAAO,EACL,WAAW,EACX,aAAa,EAGd,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,qBAAa,iBAAiB;IAC5B;;;;;;;OAOG;IACH,gBAAgB,CACd,mBAAmB,CAAC,EAAE,WAAW,EACjC,mBAAmB,CAAC,EAAE,WAAW,GAChC,WAAW;IAmBd;;;;;;;OAOG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAcjE;;;;;;OAMG;IACH,eAAe,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAQ/D;;;;;;;OAOG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO;IA+BpE;;;;;;;;OAQG;IACH,mBAAmB,CACjB,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,WAAW,EACxB,cAAc,GAAE,MAAc,GAC7B,MAAM;IAkBT;;;;;;;;OAQG;IACH,aAAa,CACX,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,MAAM,GACf,IAAI;CAYR"}
|