@pasko70/pibo 2.2.4 → 2.3.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/agent-runtime/capabilities.js +9 -1
- package/dist/agent-runtime/context-build.js +5 -2
- package/dist/agent-runtimes/codex-native/adapter.js +5 -0
- package/dist/agent-runtimes/omp/adapter.js +5 -0
- package/dist/agent-runtimes/omp/turn.js +2 -0
- package/dist/agent-runtimes/pi/adapter.js +28 -7
- package/dist/agent-runtimes/pi/intent-tracing.js +120 -0
- package/dist/agent-runtimes/pi/routed-session.js +25 -8
- package/dist/agent-runtimes/pi/runtime.js +28 -16
- package/dist/apps/chat/chat-settings-routes.js +44 -3
- package/dist/apps/chat/chat-transcription.js +85 -0
- package/dist/apps/chat/data/chat-data-mappers.js +4 -4
- package/dist/apps/chat/stream.js +23 -9
- package/dist/apps/chat/trace-v2.js +1 -0
- package/dist/apps/chat/web-app.js +49 -0
- package/dist/apps/chat-ui/assets/{dist-luJVFsmq.js → dist-Byygd1lH.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-ltfz1vFX.js → dist-C9BrS7sL.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-rf4HYdoa.js → dist-CUcAofmV.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CImWCF2M.js → dist-D4RU6xu3.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BFwTuvyi.js → dist-DusFwy0L.js} +1 -1
- package/dist/apps/chat-ui/assets/{index-nZQXUpxE.css → index-BJ56TREg.css} +1 -1
- package/dist/apps/chat-ui/assets/index-Bifi_kjN.js +228 -0
- package/dist/apps/chat-ui/index.html +2 -2
- package/dist/apps/chat-vscode-web/assets/index-WsLm1mo3.js +43 -0
- package/dist/apps/chat-vscode-web/index.html +1 -1
- package/dist/apps/vscode-artifacts/latest.vsix +0 -0
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-2.3.0.vsix +0 -0
- package/dist/core/codex-compat.js +1 -3
- package/dist/core/context-build.js +16 -7
- package/dist/core/gateway-resource-guard.js +35 -14
- package/dist/core/gateway-settings.js +64 -0
- package/dist/core/session-router.js +226 -46
- package/dist/core/user-settings.js +20 -0
- package/dist/data/ingest-service.js +14 -2
- package/dist/debug/agents.js +391 -0
- package/dist/debug/index.js +14 -2
- package/dist/gateway/server.js +2 -0
- package/dist/index.js +6 -1
- package/dist/plugins/builtin.js +4 -2
- package/dist/plugins/openai-chatgpt-transcription.js +12 -0
- package/dist/plugins/openai-transcription.js +12 -0
- package/dist/plugins/registry.js +23 -0
- package/dist/session-ui/delegation.js +4 -2
- package/dist/session-ui/terminalRows.js +51 -1
- package/dist/shared/trace-async-agent-runs.js +4 -2
- package/dist/shared/trace-event-projection.js +12 -2
- package/dist/shared/trace-live-reducer.js +4 -0
- package/dist/shared/trace-patch-nodes.js +1 -0
- package/dist/shared/trace-subagent-links.js +19 -6
- package/dist/subagents/observations.js +149 -0
- package/dist/subagents/tool.js +177 -46
- package/dist/tools/session-service.js +1 -0
- package/dist/tools/session-tool-set.js +9 -5
- package/dist/transcription/openai-chatgpt.js +148 -0
- package/dist/transcription/openai.js +72 -0
- package/dist/transcription/types.js +8 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/dist/apps/chat-ui/assets/index-D2Maa2v1.js +0 -226
- package/dist/apps/chat-vscode-web/assets/index-BpurWVnX.js +0 -41
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-2.2.4.vsix +0 -0
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<meta name="theme-color" content="#101d22" />
|
|
7
7
|
<title>Pibo</title>
|
|
8
|
-
<script type="module" crossorigin src="/apps/chat-vscode/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/apps/chat-vscode/assets/index-WsLm1mo3.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/apps/chat-vscode/assets/index-CF1-9PKU.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const CODEX_COMPAT_SUBAGENTS = ["default", "explorer", "worker"];
|
|
2
1
|
function currentDate() {
|
|
3
2
|
return new Date().toISOString().slice(0, 10);
|
|
4
3
|
}
|
|
@@ -15,7 +14,7 @@ export function buildCodexCompatSystemPrompt(options) {
|
|
|
15
14
|
const compatibilityInstructions = [
|
|
16
15
|
"# Codex-Compatible Runtime",
|
|
17
16
|
"You are running in Pibo through the codex-compat profile. Match Codex-style tool use where the exposed Pibo tools support it, while staying truthful about implemented behavior.",
|
|
18
|
-
"Use Pibo's pibo_run_*
|
|
17
|
+
"Use Pibo's pibo_run_* and pibo_agents_* tools for parallel work, yielded runs, and delegated-agent lifecycle management.",
|
|
19
18
|
"Use direct execution for normal coding tasks. If a structured planning or user-input tool is not present, ask concise questions in normal chat.",
|
|
20
19
|
"When web_search is selected by the profile, use it for current or externally sourced information.",
|
|
21
20
|
childInstructions,
|
|
@@ -24,7 +23,6 @@ export function buildCodexCompatSystemPrompt(options) {
|
|
|
24
23
|
` <shell>${options.shell}</shell>`,
|
|
25
24
|
` <current_date>${options.currentDate ?? currentDate()}</current_date>`,
|
|
26
25
|
` <timezone>${options.timezone ?? currentTimezone()}</timezone>`,
|
|
27
|
-
` <subagents>${CODEX_COMPAT_SUBAGENTS.join(", ")}</subagents>`,
|
|
28
26
|
"</environment_context>",
|
|
29
27
|
options.baseSystemPrompt,
|
|
30
28
|
];
|
|
@@ -139,11 +139,20 @@ function sanitizeNode(input, parentId, order = 0) {
|
|
|
139
139
|
function countNodes(nodes) {
|
|
140
140
|
return nodes.reduce((count, node) => count + 1 + countNodes(node.children ?? []), 0);
|
|
141
141
|
}
|
|
142
|
-
function
|
|
142
|
+
function inspectionAgentsController() {
|
|
143
|
+
const fail = () => {
|
|
144
|
+
throw new Error("Context build inspection cannot execute delegated-agent tools");
|
|
145
|
+
};
|
|
143
146
|
return {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
sendMessage: fail,
|
|
148
|
+
listAgents: () => [],
|
|
149
|
+
observe: (input) => ({
|
|
150
|
+
filters: input,
|
|
151
|
+
observations: [],
|
|
152
|
+
nextAfterSequence: input.afterSequence ?? 0,
|
|
153
|
+
truncated: false,
|
|
154
|
+
}),
|
|
155
|
+
killAgent: fail,
|
|
147
156
|
};
|
|
148
157
|
}
|
|
149
158
|
function inspectionRunToolController() {
|
|
@@ -196,8 +205,8 @@ function toolDefinitionSchema(definition, toolInfo) {
|
|
|
196
205
|
function generatedOriginForTool(name, profile) {
|
|
197
206
|
if (name === "runtime")
|
|
198
207
|
return "Generated Pibo runtime tool selected by the profile.";
|
|
199
|
-
if (name.startsWith("
|
|
200
|
-
return "Generated
|
|
208
|
+
if (name.startsWith("pibo_agents_"))
|
|
209
|
+
return "Generated shared agent-management tool from the profile's delegated-agent list.";
|
|
201
210
|
if (name.startsWith("pibo_run_"))
|
|
202
211
|
return "Generated run-control tool from the pibo-run-control capability package.";
|
|
203
212
|
if (PIBO_GOAL_TOOL_NAMES.includes(name))
|
|
@@ -298,7 +307,7 @@ export async function inspectPiboContextBuild(options = {}) {
|
|
|
298
307
|
profile: inspectionProfile,
|
|
299
308
|
activeModel: undefined,
|
|
300
309
|
persistSession: false,
|
|
301
|
-
|
|
310
|
+
agentsController: options.agentsController ?? (hasEnabledSubagents ? inspectionAgentsController() : undefined),
|
|
302
311
|
runToolController: options.runToolController ?? (hasYieldableTools ? inspectionRunToolController() : undefined),
|
|
303
312
|
});
|
|
304
313
|
try {
|
|
@@ -3,6 +3,7 @@ import { freemem, totalmem } from "node:os";
|
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
4
|
import { getHeapStatistics } from "node:v8";
|
|
5
5
|
import { collectYieldedRunHostResourceSnapshot } from "../runs/resource-isolation.js";
|
|
6
|
+
import { DEFAULT_GATEWAY_CONCURRENT_YIELDED_RUNS, DEFAULT_SESSION_CONCURRENT_YIELDED_RUNS, resolvePiboGatewaySettings, } from "./gateway-settings.js";
|
|
6
7
|
const execFileAsync = promisify(execFile);
|
|
7
8
|
const DEFAULT_POLICY = Object.freeze({
|
|
8
9
|
mode: "block",
|
|
@@ -10,17 +11,19 @@ const DEFAULT_POLICY = Object.freeze({
|
|
|
10
11
|
minHeapAvailableBytes: 64 * 1024 * 1024,
|
|
11
12
|
maxRssBytes: 1536 * 1024 * 1024,
|
|
12
13
|
knownDaemonWarningRssBytes: 2 * 1024 * 1024 * 1024,
|
|
13
|
-
maxConcurrentYieldedRuns:
|
|
14
|
+
maxConcurrentYieldedRuns: DEFAULT_GATEWAY_CONCURRENT_YIELDED_RUNS,
|
|
15
|
+
sessionConcurrentYieldedRuns: DEFAULT_SESSION_CONCURRENT_YIELDED_RUNS,
|
|
14
16
|
yieldedRunMemoryReservationBytes: 2 * 1024 * 1024 * 1024,
|
|
15
17
|
});
|
|
16
|
-
export function resolveGatewayResourceGuardPolicy(env = process.env) {
|
|
18
|
+
export function resolveGatewayResourceGuardPolicy(env = process.env, gatewaySettings = resolvePiboGatewaySettings(env)) {
|
|
17
19
|
return {
|
|
18
20
|
mode: parseMode(env.PIBO_GATEWAY_RESOURCE_GUARD, DEFAULT_POLICY.mode),
|
|
19
21
|
minFreeMemoryBytes: parseByteThreshold(env.PIBO_GATEWAY_MIN_FREE_MEMORY_BYTES, DEFAULT_POLICY.minFreeMemoryBytes),
|
|
20
22
|
minHeapAvailableBytes: parseByteThreshold(env.PIBO_GATEWAY_MIN_HEAP_AVAILABLE_BYTES, DEFAULT_POLICY.minHeapAvailableBytes),
|
|
21
23
|
maxRssBytes: parseByteThreshold(env.PIBO_GATEWAY_MAX_RSS_BYTES, DEFAULT_POLICY.maxRssBytes),
|
|
22
24
|
knownDaemonWarningRssBytes: parseByteThreshold(env.PIBO_GATEWAY_KNOWN_DAEMON_WARNING_RSS_BYTES, DEFAULT_POLICY.knownDaemonWarningRssBytes),
|
|
23
|
-
maxConcurrentYieldedRuns:
|
|
25
|
+
maxConcurrentYieldedRuns: gatewaySettings.maxConcurrentYieldedRuns,
|
|
26
|
+
sessionConcurrentYieldedRuns: gatewaySettings.sessionConcurrentYieldedRuns,
|
|
24
27
|
yieldedRunMemoryReservationBytes: parseByteThreshold(env.PIBO_GATEWAY_YIELDED_RUN_MEMORY_RESERVATION_BYTES, DEFAULT_POLICY.yieldedRunMemoryReservationBytes),
|
|
25
28
|
};
|
|
26
29
|
}
|
|
@@ -39,7 +42,7 @@ export function collectGatewayProcessMemory() {
|
|
|
39
42
|
};
|
|
40
43
|
}
|
|
41
44
|
export function buildGatewayResourceSnapshot(options = {}) {
|
|
42
|
-
const policy = resolveGatewayResourceGuardPolicy(options.env);
|
|
45
|
+
const policy = resolveGatewayResourceGuardPolicy(options.env, options.gatewaySettings);
|
|
43
46
|
const gateway = collectGatewayProcessMemory();
|
|
44
47
|
const hostResources = options.hostResourceSnapshot ?? collectYieldedRunHostResourceSnapshot({ now: options.now });
|
|
45
48
|
const host = { freeBytes: hostResources.memoryFreeBytes || freemem(), availableBytes: hostResources.memoryAvailableBytes || freemem(), totalBytes: totalmem() };
|
|
@@ -91,15 +94,30 @@ export function assertGatewayResourceAvailableForWork(workLabel, env = process.e
|
|
|
91
94
|
}
|
|
92
95
|
export class GatewayWorkAdmissionController {
|
|
93
96
|
activeReservations = new Set();
|
|
94
|
-
|
|
95
|
-
|
|
97
|
+
activeSessionReservations = new Map();
|
|
98
|
+
reserve(workLabel, options = {}) {
|
|
99
|
+
const snapshot = buildGatewayResourceSnapshot({
|
|
100
|
+
env: options.env,
|
|
101
|
+
gatewaySettings: options.gatewaySettings,
|
|
102
|
+
includeProcesses: false,
|
|
103
|
+
});
|
|
96
104
|
const policy = snapshot.policy;
|
|
97
105
|
if (snapshot.guardAction === "block") {
|
|
98
106
|
throwGatewayResourceBlock(workLabel, snapshot.checks.filter((check) => check.severity === "critical").map((check) => check.message));
|
|
99
107
|
}
|
|
100
108
|
if (policy.mode === "block" && this.activeReservations.size >= policy.maxConcurrentYieldedRuns) {
|
|
101
109
|
throwGatewayResourceBlock(workLabel, [
|
|
102
|
-
`Active yielded runs ${this.activeReservations.size} reached the configured limit ${policy.maxConcurrentYieldedRuns}. Wait for an active run to settle or raise PIBO_GATEWAY_MAX_CONCURRENT_YIELDED_RUNS
|
|
110
|
+
`Active yielded runs ${this.activeReservations.size} reached the configured gateway limit ${policy.maxConcurrentYieldedRuns}. Wait for an active run to settle or raise PIBO_GATEWAY_MAX_CONCURRENT_YIELDED_RUNS in Settings or the gateway environment.`,
|
|
111
|
+
]);
|
|
112
|
+
}
|
|
113
|
+
const activeForSession = options.sessionId
|
|
114
|
+
? this.activeSessionReservations.get(options.sessionId) ?? 0
|
|
115
|
+
: 0;
|
|
116
|
+
if (policy.mode === "block"
|
|
117
|
+
&& options.sessionId
|
|
118
|
+
&& activeForSession >= policy.sessionConcurrentYieldedRuns) {
|
|
119
|
+
throwGatewayResourceBlock(workLabel, [
|
|
120
|
+
`Session ${options.sessionId} has ${activeForSession} active yielded runs and reached the configured session limit ${policy.sessionConcurrentYieldedRuns}. Wait for an active run to settle or raise PIBO_SESSION_CONCURRENT_YIELDED_RUNS in Settings or the gateway environment.`,
|
|
103
121
|
]);
|
|
104
122
|
}
|
|
105
123
|
if (policy.mode === "block" &&
|
|
@@ -110,6 +128,8 @@ export class GatewayWorkAdmissionController {
|
|
|
110
128
|
}
|
|
111
129
|
const reservation = Symbol(workLabel);
|
|
112
130
|
this.activeReservations.add(reservation);
|
|
131
|
+
if (options.sessionId)
|
|
132
|
+
this.activeSessionReservations.set(options.sessionId, activeForSession + 1);
|
|
113
133
|
let released = false;
|
|
114
134
|
return {
|
|
115
135
|
admission: collectYieldedRunHostResourceSnapshot(),
|
|
@@ -118,6 +138,13 @@ export class GatewayWorkAdmissionController {
|
|
|
118
138
|
return;
|
|
119
139
|
released = true;
|
|
120
140
|
this.activeReservations.delete(reservation);
|
|
141
|
+
if (!options.sessionId)
|
|
142
|
+
return;
|
|
143
|
+
const nextSessionCount = (this.activeSessionReservations.get(options.sessionId) ?? 1) - 1;
|
|
144
|
+
if (nextSessionCount > 0)
|
|
145
|
+
this.activeSessionReservations.set(options.sessionId, nextSessionCount);
|
|
146
|
+
else
|
|
147
|
+
this.activeSessionReservations.delete(options.sessionId);
|
|
121
148
|
},
|
|
122
149
|
};
|
|
123
150
|
}
|
|
@@ -157,7 +184,7 @@ export function renderGatewayResourceSnapshotText(snapshot) {
|
|
|
157
184
|
lines.push(`Gateway PID: ${snapshot.gateway.pid}`);
|
|
158
185
|
lines.push(`Gateway memory: rss=${snapshot.gateway.rssBytes} heapUsed=${snapshot.gateway.heapUsedBytes} heapAvailable=${snapshot.gateway.heapAvailableBytes} heapLimit=${snapshot.gateway.heapLimitBytes}`);
|
|
159
186
|
lines.push(`Host memory: free=${snapshot.host.freeBytes} available=${snapshot.host.availableBytes} total=${snapshot.host.totalBytes}`);
|
|
160
|
-
lines.push(`Thresholds: minFree=${snapshot.policy.minFreeMemoryBytes} minHeapAvailable=${snapshot.policy.minHeapAvailableBytes} maxRss=${snapshot.policy.maxRssBytes} daemonWarnRss=${snapshot.policy.knownDaemonWarningRssBytes} maxYieldedRuns=${snapshot.policy.maxConcurrentYieldedRuns} yieldedRunReservation=${snapshot.policy.yieldedRunMemoryReservationBytes}`);
|
|
187
|
+
lines.push(`Thresholds: minFree=${snapshot.policy.minFreeMemoryBytes} minHeapAvailable=${snapshot.policy.minHeapAvailableBytes} maxRss=${snapshot.policy.maxRssBytes} daemonWarnRss=${snapshot.policy.knownDaemonWarningRssBytes} maxYieldedRuns=${snapshot.policy.maxConcurrentYieldedRuns} sessionYieldedRuns=${snapshot.policy.sessionConcurrentYieldedRuns} yieldedRunReservation=${snapshot.policy.yieldedRunMemoryReservationBytes}`);
|
|
161
188
|
lines.push(`Related processes: children=${snapshot.processes.children.length} knownDaemons=${snapshot.processes.knownDaemons.length} processList=${snapshot.processes.available ? "available" : "unavailable"}`);
|
|
162
189
|
lines.push(`Yielded-run cgroups: units=${snapshot.yieldedRunUnits.units.length} systemdList=${snapshot.yieldedRunUnits.available ? "available" : "unavailable"}`);
|
|
163
190
|
if (snapshot.processes.error)
|
|
@@ -242,12 +269,6 @@ function parseByteThreshold(value, fallback) {
|
|
|
242
269
|
const parsed = Number(value);
|
|
243
270
|
return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : fallback;
|
|
244
271
|
}
|
|
245
|
-
function parsePositiveInteger(value, fallback) {
|
|
246
|
-
if (value === undefined || value.trim() === "")
|
|
247
|
-
return fallback;
|
|
248
|
-
const parsed = Number(value);
|
|
249
|
-
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
250
|
-
}
|
|
251
272
|
function throwGatewayResourceBlock(workLabel, reasons) {
|
|
252
273
|
throw new Error(`Gateway resource guard blocked ${workLabel} before starting: ${reasons.join("; ")}`);
|
|
253
274
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { piboHomePath } from "./pibo-home.js";
|
|
4
|
+
export const DEFAULT_GATEWAY_CONCURRENT_YIELDED_RUNS = 50;
|
|
5
|
+
export const DEFAULT_SESSION_CONCURRENT_YIELDED_RUNS = 10;
|
|
6
|
+
export const DEFAULT_PIBO_GATEWAY_SETTINGS_PATH = "gateway-settings.json";
|
|
7
|
+
export function loadPiboGatewaySettings(env = process.env) {
|
|
8
|
+
return sanitizePiboGatewaySettings(readState().settings, env);
|
|
9
|
+
}
|
|
10
|
+
export function updatePiboGatewaySettings(patch, env = process.env) {
|
|
11
|
+
const state = readState();
|
|
12
|
+
const current = sanitizePiboGatewaySettings(state.settings, env);
|
|
13
|
+
const next = sanitizePiboGatewaySettings({ ...current, ...patch }, env);
|
|
14
|
+
state.settings = next;
|
|
15
|
+
writeState(state);
|
|
16
|
+
return next;
|
|
17
|
+
}
|
|
18
|
+
export function resolvePiboGatewaySettings(env = process.env) {
|
|
19
|
+
return {
|
|
20
|
+
maxConcurrentYieldedRuns: parsePositiveInteger(env.PIBO_GATEWAY_MAX_CONCURRENT_YIELDED_RUNS, DEFAULT_GATEWAY_CONCURRENT_YIELDED_RUNS),
|
|
21
|
+
sessionConcurrentYieldedRuns: parsePositiveInteger(env.PIBO_SESSION_CONCURRENT_YIELDED_RUNS, DEFAULT_SESSION_CONCURRENT_YIELDED_RUNS),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function sanitizePiboGatewaySettings(value, env = process.env) {
|
|
25
|
+
const raw = value && typeof value === "object" && !Array.isArray(value)
|
|
26
|
+
? value
|
|
27
|
+
: {};
|
|
28
|
+
const defaults = resolvePiboGatewaySettings(env);
|
|
29
|
+
return {
|
|
30
|
+
maxConcurrentYieldedRuns: sanitizeConcurrentYieldedRuns(raw.maxConcurrentYieldedRuns)
|
|
31
|
+
?? defaults.maxConcurrentYieldedRuns,
|
|
32
|
+
sessionConcurrentYieldedRuns: sanitizeConcurrentYieldedRuns(raw.sessionConcurrentYieldedRuns)
|
|
33
|
+
?? defaults.sessionConcurrentYieldedRuns,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function sanitizeConcurrentYieldedRuns(value) {
|
|
37
|
+
if (typeof value !== "number" && typeof value !== "string")
|
|
38
|
+
return undefined;
|
|
39
|
+
const parsed = typeof value === "number" ? value : Number(value.trim());
|
|
40
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined;
|
|
41
|
+
}
|
|
42
|
+
function parsePositiveInteger(value, fallback) {
|
|
43
|
+
return sanitizeConcurrentYieldedRuns(value) ?? fallback;
|
|
44
|
+
}
|
|
45
|
+
function readState() {
|
|
46
|
+
const path = piboHomePath(DEFAULT_PIBO_GATEWAY_SETTINGS_PATH);
|
|
47
|
+
if (!existsSync(path))
|
|
48
|
+
return {};
|
|
49
|
+
try {
|
|
50
|
+
const parsed = JSON.parse(readFileSync(path, "utf-8"));
|
|
51
|
+
const raw = parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
52
|
+
? parsed
|
|
53
|
+
: {};
|
|
54
|
+
return { settings: raw.settings };
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return {};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function writeState(state) {
|
|
61
|
+
const path = piboHomePath(DEFAULT_PIBO_GATEWAY_SETTINGS_PATH);
|
|
62
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
63
|
+
writeFileSync(path, `${JSON.stringify(state, null, 2)}\n`);
|
|
64
|
+
}
|