@livedesk/hub 0.1.45 → 0.1.47

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.45",
3
+ "version": "0.1.47",
4
4
  "description": "LiveDesk local Hub API and browser frame bridge",
5
5
  "type": "module",
6
6
  "main": "src/server.js",
@@ -1,66 +1,66 @@
1
- const DEFAULT_MAX_STATUS_AGE_MS = 30_000;
2
-
3
- function asRecord(value) {
4
- return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
5
- }
6
-
7
- function cpuUsageRatio(value) {
8
- return typeof value === 'number' && Number.isFinite(value) && value >= 0 && value <= 1
9
- ? value
10
- : null;
11
- }
12
-
13
- function positiveInteger(value) {
14
- const number = Number(value);
15
- return Number.isSafeInteger(number) && number > 0 ? number : null;
16
- }
17
-
18
- function statusAgeMs(device, now) {
19
- const sampledAt = Date.parse(String(device?.lastStatusAt || ''));
20
- return Number.isFinite(sampledAt) ? Math.max(0, now - sampledAt) : null;
21
- }
22
-
23
- export function enrichAgentTaskResults({
24
- operation,
25
- results,
26
- devices,
27
- now = Date.now(),
28
- maxStatusAgeMs = DEFAULT_MAX_STATUS_AGE_MS
29
- } = {}) {
30
- const sourceResults = Array.isArray(results) ? results : [];
31
- if (operation !== 'system.health') return sourceResults;
32
-
33
- const devicesById = new Map(
34
- (Array.isArray(devices) ? devices : []).map(device => [String(device?.deviceId || ''), device])
35
- );
36
-
37
- return sourceResults.map(result => {
38
- if (!result || result.status !== 'completed') return result;
39
- const data = asRecord(result.data);
40
- const device = devicesById.get(String(result.deviceId || ''));
41
- const status = asRecord(device?.status);
42
- const statusCpu = asRecord(status.cpu);
43
- const directRatio = cpuUsageRatio(data.cpuUsageRatio);
44
- const latestRatio = cpuUsageRatio(statusCpu.usageRatio);
45
- const latestAgeMs = statusAgeMs(device, now);
46
- const useLatestStatus = directRatio === null
47
- && latestRatio !== null
48
- && latestAgeMs !== null
49
- && latestAgeMs <= Math.max(0, Number(maxStatusAgeMs) || DEFAULT_MAX_STATUS_AGE_MS);
50
- const cores = positiveInteger(data.cores) || positiveInteger(statusCpu.cores);
51
- const nextData = { ...data };
52
-
53
- if (cores !== null) nextData.cores = cores;
54
- if (directRatio !== null) {
55
- nextData.cpuUsageRatio = directRatio;
56
- nextData.cpuUsageSource = 'system-health-task';
57
- } else if (useLatestStatus) {
58
- nextData.cpuUsageRatio = latestRatio;
59
- nextData.cpuUsageSource = 'latest-client-status';
60
- nextData.cpuUsageSampleAgeMs = latestAgeMs;
61
- nextData.cpuUsageSampledAt = String(device.lastStatusAt);
62
- }
63
-
64
- return { ...result, data: nextData };
65
- });
66
- }
1
+ const DEFAULT_MAX_STATUS_AGE_MS = 30_000;
2
+
3
+ function asRecord(value) {
4
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
5
+ }
6
+
7
+ function cpuUsageRatio(value) {
8
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0 && value <= 1
9
+ ? value
10
+ : null;
11
+ }
12
+
13
+ function positiveInteger(value) {
14
+ const number = Number(value);
15
+ return Number.isSafeInteger(number) && number > 0 ? number : null;
16
+ }
17
+
18
+ function statusAgeMs(device, now) {
19
+ const sampledAt = Date.parse(String(device?.lastStatusAt || ''));
20
+ return Number.isFinite(sampledAt) ? Math.max(0, now - sampledAt) : null;
21
+ }
22
+
23
+ export function enrichAgentTaskResults({
24
+ operation,
25
+ results,
26
+ devices,
27
+ now = Date.now(),
28
+ maxStatusAgeMs = DEFAULT_MAX_STATUS_AGE_MS
29
+ } = {}) {
30
+ const sourceResults = Array.isArray(results) ? results : [];
31
+ if (operation !== 'system.health') return sourceResults;
32
+
33
+ const devicesById = new Map(
34
+ (Array.isArray(devices) ? devices : []).map(device => [String(device?.deviceId || ''), device])
35
+ );
36
+
37
+ return sourceResults.map(result => {
38
+ if (!result || result.status !== 'completed') return result;
39
+ const data = asRecord(result.data);
40
+ const device = devicesById.get(String(result.deviceId || ''));
41
+ const status = asRecord(device?.status);
42
+ const statusCpu = asRecord(status.cpu);
43
+ const directRatio = cpuUsageRatio(data.cpuUsageRatio);
44
+ const latestRatio = cpuUsageRatio(statusCpu.usageRatio);
45
+ const latestAgeMs = statusAgeMs(device, now);
46
+ const useLatestStatus = directRatio === null
47
+ && latestRatio !== null
48
+ && latestAgeMs !== null
49
+ && latestAgeMs <= Math.max(0, Number(maxStatusAgeMs) || DEFAULT_MAX_STATUS_AGE_MS);
50
+ const cores = positiveInteger(data.cores) || positiveInteger(statusCpu.cores);
51
+ const nextData = { ...data };
52
+
53
+ if (cores !== null) nextData.cores = cores;
54
+ if (directRatio !== null) {
55
+ nextData.cpuUsageRatio = directRatio;
56
+ nextData.cpuUsageSource = 'system-health-task';
57
+ } else if (useLatestStatus) {
58
+ nextData.cpuUsageRatio = latestRatio;
59
+ nextData.cpuUsageSource = 'latest-client-status';
60
+ nextData.cpuUsageSampleAgeMs = latestAgeMs;
61
+ nextData.cpuUsageSampledAt = String(device.lastStatusAt);
62
+ }
63
+
64
+ return { ...result, data: nextData };
65
+ });
66
+ }
@@ -728,10 +728,10 @@ export function createCodexAgentRuntime({
728
728
  'Never use arbitrary MCP servers, change permissions, forge approvals, request credentials, or invent a tool result.',
729
729
  `The Hub has fixed this run to permission mode ${permissionPolicy?.mode || 'ask'} and enforces the policy independently of your instructions.`,
730
730
  'Use only the selected connected device IDs below. If the Hub asks for user approval, wait for that approval result and do not work around it.',
731
- 'You may perform multiple safe read-only checks when the request requires a sequence. For example, find Clients missing a named process, then check a related service only on those Clients.',
732
- 'If one read-only result omits a fact the user requested, do not treat that missing field as proof that the fact is unavailable. Try another applicable registered LiveDesk read-only tool.',
733
- 'If only a high-risk registered tool such as livedesk.run_command can obtain the missing fact, use it only when necessary, one selected device per call, and let the Hub approval policy ask the user. If approval is denied or no applicable tool exists, explain that exact limit.',
734
- `Selected device IDs: ${JSON.stringify(deviceIds)}`,
731
+ 'You may perform multiple safe read-only checks when the request requires a sequence. For example, find Clients missing a named process, then check a related service only on those Clients.',
732
+ 'If one read-only result omits a fact the user requested, do not treat that missing field as proof that the fact is unavailable. Try another applicable registered LiveDesk read-only tool.',
733
+ 'If only a high-risk registered tool such as livedesk.run_command can obtain the missing fact, use it only when necessary, one selected device per call, and let the Hub approval policy ask the user. If approval is denied or no applicable tool exists, explain that exact limit.',
734
+ `Selected device IDs: ${JSON.stringify(deviceIds)}`,
735
735
  'Return a concise Korean or English summary grounded only in tool results. Do not invent results.',
736
736
  `User request: ${safeText(instruction, 4000)}`
737
737
  ].join('\n');