@livedesk/hub 0.1.35 → 0.1.37

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livedesk/hub",
3
- "version": "0.1.35",
3
+ "version": "0.1.37",
4
4
  "description": "LiveDesk local Hub API and browser frame bridge",
5
5
  "type": "module",
6
6
  "main": "src/server.js",
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@ffmpeg-installer/ffmpeg": "^1.1.0",
19
- "@livedesk/runtime-core": "0.1.4",
19
+ "@livedesk/runtime-core": "0.1.5",
20
20
  "@openai/codex-sdk": "0.145.0",
21
21
  "cors": "^2.8.5",
22
22
  "express": "^4.21.2",
@@ -1,4 +1,4 @@
1
- import { appendFile, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
1
+ import { appendFile, mkdir, readFile, rename, writeFile } from 'node:fs/promises';
2
2
  import crypto from 'node:crypto';
3
3
  import os from 'node:os';
4
4
  import path from 'node:path';
@@ -84,20 +84,10 @@ export function createAgentAuditStore({ dataDir = path.join(os.homedir(), '.live
84
84
  await writeQueue;
85
85
  return record;
86
86
  },
87
- async list({ runId = '', limit = 200 } = {}) {
87
+ async list({ runId = '', limit = 200 } = {}) {
88
88
  const current = await load();
89
89
  const normalizedLimit = Math.max(1, Math.min(500, Number(limit) || 200));
90
- return current.filter(item => !runId || item.runId === String(runId)).slice(-normalizedLimit).reverse();
91
- },
92
- async clear() {
93
- writeQueue = writeQueue.then(async () => {
94
- await rm(filePath, { force: true });
95
- records = [];
96
- fileRecordCount = 0;
97
- rewriteNeeded = false;
98
- });
99
- await writeQueue;
100
- return { ok: true };
101
- }
102
- };
103
- }
90
+ return current.filter(item => !runId || item.runId === String(runId)).slice(-normalizedLimit).reverse();
91
+ }
92
+ };
93
+ }
@@ -42,19 +42,19 @@ const PRESET_CATEGORIES = Object.freeze({
42
42
  ...DEFAULT_CUSTOM_CATEGORIES,
43
43
  userAccount: 'ask'
44
44
  },
45
- 'safe-auto': {
46
- read: 'allow',
47
- processControl: 'allow',
48
- serviceControl: 'allow',
49
- // launch_application accepts an executable path, so allowing it would
50
- // provide a shell-equivalent escape hatch (for example powershell.exe).
51
- applicationControl: 'ask',
52
- fileRead: 'allow',
53
- fileWrite: 'allow',
54
- fileDelete: 'ask',
55
- shell: 'ask',
56
- // A writable script directory must never become an auto-execution path.
57
- script: 'ask',
45
+ 'safe-auto': {
46
+ read: 'allow',
47
+ processControl: 'allow',
48
+ serviceControl: 'allow',
49
+ // launch_application accepts an executable path, so allowing it would
50
+ // provide a shell-equivalent escape hatch (for example powershell.exe).
51
+ applicationControl: 'ask',
52
+ fileRead: 'allow',
53
+ fileWrite: 'allow',
54
+ fileDelete: 'ask',
55
+ shell: 'ask',
56
+ // A writable script directory must never become an auto-execution path.
57
+ script: 'ask',
58
58
  softwareInstall: 'ask',
59
59
  network: 'allow',
60
60
  systemPower: 'ask',
@@ -161,17 +161,17 @@ function isSafeAutoRelativePath(value) {
161
161
  return segments.length > 0 && !segments.includes('..');
162
162
  }
163
163
 
164
- function safeAutoConstraint(tool, args, mode) {
165
- if (mode !== 'safe-auto') return '';
166
- if (tool.category === 'fileWrite' && !isSafeAutoRelativePath(args?.path)) {
167
- return 'Safe Auto file writes are limited to relative paths inside the LiveDesk files directory.';
168
- }
169
- if (tool.category === 'fileWrite') {
170
- const filePath = String(args?.path || '').trim().replaceAll('\\', '/').toLowerCase();
171
- if (filePath === 'scripts' || filePath.startsWith('scripts/')) {
172
- return 'Safe Auto cannot write files inside the script directory.';
173
- }
174
- }
164
+ function safeAutoConstraint(tool, args, mode) {
165
+ if (mode !== 'safe-auto') return '';
166
+ if (tool.category === 'fileWrite' && !isSafeAutoRelativePath(args?.path)) {
167
+ return 'Safe Auto file writes are limited to relative paths inside the LiveDesk files directory.';
168
+ }
169
+ if (tool.category === 'fileWrite') {
170
+ const filePath = String(args?.path || '').trim().replaceAll('\\', '/').toLowerCase();
171
+ if (filePath === 'scripts' || filePath.startsWith('scripts/')) {
172
+ return 'Safe Auto cannot write files inside the script directory.';
173
+ }
174
+ }
175
175
  if (tool.category === 'script') {
176
176
  const scriptPath = String(args?.path || '').trim().toLowerCase();
177
177
  if (!isSafeAutoRelativePath(scriptPath) || !scriptPath.replaceAll('\\', '/').startsWith('scripts/') || !/\.(ps1|psm1|sh|bash|py|js|mjs|cmd|bat)$/.test(scriptPath)) {
@@ -181,15 +181,9 @@ function safeAutoConstraint(tool, args, mode) {
181
181
  return '';
182
182
  }
183
183
 
184
- export function evaluateAgentToolPermission({ policy, toolName, arguments: args = {}, deviceIds = [] } = {}) {
185
- const tool = getAgentToolDefinition(toolName);
186
- if (!tool) return { decision: 'deny', category: 'unknown', risk: 'critical', reason: 'Unknown or unregistered Agent tool.' };
187
- // This is deliberately redundant with the filtered MCP registry. A future
188
- // registry edit must not make an AI mutation executable merely by exposing
189
- // a definition again.
190
- if (tool.mutating === true || tool.readOnly !== true) {
191
- return { decision: 'deny', category: tool.category, risk: 'critical', reason: 'AI mutating tools are disabled in the first public product.' };
192
- }
184
+ export function evaluateAgentToolPermission({ policy, toolName, arguments: args = {}, deviceIds = [] } = {}) {
185
+ const tool = getAgentToolDefinition(toolName);
186
+ if (!tool) return { decision: 'deny', category: 'unknown', risk: 'critical', reason: 'Unknown or unregistered Agent tool.' };
193
187
  const allowed = new Set(normalizeIds(policy?.deviceIds));
194
188
  const requested = targetIdsFromArgs(args, deviceIds);
195
189
  if (requested.some(deviceId => !allowed.has(deviceId))) {