perchai-cli 2.4.12 → 2.4.13
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/perch.mjs +150 -70
- package/package.json +1 -1
package/dist/perch.mjs
CHANGED
|
@@ -75566,7 +75566,6 @@ var init_payroll = __esm({
|
|
|
75566
75566
|
// lib/perchBusinessTools/index.ts
|
|
75567
75567
|
var init_perchBusinessTools = __esm({
|
|
75568
75568
|
"lib/perchBusinessTools/index.ts"() {
|
|
75569
|
-
"use strict";
|
|
75570
75569
|
init_generateAPAuditPacket();
|
|
75571
75570
|
init_inventoryFolder();
|
|
75572
75571
|
init_loadBusinessTables();
|
|
@@ -80628,13 +80627,13 @@ function buildDesktopContextSection(input) {
|
|
|
80628
80627
|
label: "CLI workspace",
|
|
80629
80628
|
content: [
|
|
80630
80629
|
"## CLI local workspace",
|
|
80631
|
-
"Perch is running from a terminal. Local filesystem, shell, sandbox-code, and AP evidence tools are available through the CLI local
|
|
80630
|
+
"Perch is running from a terminal. Local filesystem, shell, sandbox-code, and AP evidence tools are available through the CLI local runtime.",
|
|
80632
80631
|
input.activeRootPath?.trim() ? `Workspace root: ${input.activeRootPath}. Treat relative paths as relative to this root.` : "Workspace root: current terminal directory.",
|
|
80633
|
-
"
|
|
80632
|
+
"GUI-only services are not connected here: embedded browser, Google/Gmail/Calendar delivery, Desktop RAG indexing, MCP Desktop servers, and project memory writes are unavailable unless the desktop app is running.",
|
|
80634
80633
|
localReadTools.length > 0 ? `Read tools: ${localReadTools.join(", ")}.` : "Read tools: none exposed for this turn.",
|
|
80635
80634
|
localWriteTools.length > 0 ? `Write/command tools: ${localWriteTools.join(", ")}. These are governed by the selected permission mode and command policy.` : "Write/command tools: none exposed for this turn."
|
|
80636
80635
|
].join("\n"),
|
|
80637
|
-
reason: "Terminal local
|
|
80636
|
+
reason: "Terminal local runtime state and CLI tool availability for this turn.",
|
|
80638
80637
|
sourcePath: input.activeRootPath,
|
|
80639
80638
|
metadata: {
|
|
80640
80639
|
desktopConnected: false,
|
|
@@ -80649,7 +80648,7 @@ function buildDesktopContextSection(input) {
|
|
|
80649
80648
|
lane: "desktop",
|
|
80650
80649
|
label: "Desktop workspace",
|
|
80651
80650
|
content: "",
|
|
80652
|
-
reason: "
|
|
80651
|
+
reason: "Local workspace runtime is unavailable in browser mode.",
|
|
80653
80652
|
sourcePath: input.activeRootPath,
|
|
80654
80653
|
skipped: true,
|
|
80655
80654
|
metadata: { desktopConnected: false }
|
|
@@ -80736,7 +80735,7 @@ function buildDesktopContextSection(input) {
|
|
|
80736
80735
|
label: "Desktop workspace",
|
|
80737
80736
|
content: [
|
|
80738
80737
|
"## Desktop environment",
|
|
80739
|
-
"Desktop
|
|
80738
|
+
"Desktop local runtime is connected. Local filesystem tools are available to the operator runtime.",
|
|
80740
80739
|
input.activeRootPath?.trim() ? `Optional folder scope: ${input.activeRootPath} (you are NOT limited to it \u2014 absolute paths anywhere in the user's home work directly).` : "No folder scope is selected, and none is needed. When the user gives a file path, USE IT DIRECTLY \u2014 call readLocalFile / glob / grep / visionInspect with the absolute path (e.g. /Users/you/Desktop/shot.png). Full-access policy already allows any path in the user's home. NEVER tell the user to select or approve a folder, and NEVER refuse a file because no folder is selected.",
|
|
80741
80740
|
`Visible local sources: ${totalVisibleFiles}`,
|
|
80742
80741
|
input.localSourcesMeta?.refreshedAt ? `Local source snapshot refreshed: ${input.localSourcesMeta.refreshedAt}` : null,
|
|
@@ -80754,7 +80753,7 @@ function buildDesktopContextSection(input) {
|
|
|
80754
80753
|
availableReadTools.length > 0 ? `Read tools: ${availableReadTools.join(", ")}.` : "Read tools: none exposed for this turn.",
|
|
80755
80754
|
availableWriteTools.length > 0 ? `Write/command tools: ${availableWriteTools.join(", ")}. These are governed by the selected permission mode and command policy.` : "Write/command tools: none exposed for this turn."
|
|
80756
80755
|
].filter(Boolean).join("\n"),
|
|
80757
|
-
reason: "
|
|
80756
|
+
reason: "Local runtime state, optional folder scope, and tool availability for this turn.",
|
|
80758
80757
|
sourcePath: input.activeRootPath,
|
|
80759
80758
|
metadata: {
|
|
80760
80759
|
desktopConnected: true,
|
|
@@ -82928,7 +82927,6 @@ function truncateHistoryLine(value, max2) {
|
|
|
82928
82927
|
}
|
|
82929
82928
|
var init_operatorTruth = __esm({
|
|
82930
82929
|
"features/perchTerminal/runtime/operatorTruth.ts"() {
|
|
82931
|
-
"use strict";
|
|
82932
82930
|
}
|
|
82933
82931
|
});
|
|
82934
82932
|
|
|
@@ -91830,7 +91828,7 @@ function assembleContext(input) {
|
|
|
91830
91828
|
);
|
|
91831
91829
|
if (!input.desktopConnected && input.cliLocalTools !== true) {
|
|
91832
91830
|
warnings.push(
|
|
91833
|
-
"
|
|
91831
|
+
"Local workspace runtime is not connected. Local workspace tools are unavailable in browser mode."
|
|
91834
91832
|
);
|
|
91835
91833
|
}
|
|
91836
91834
|
return {
|
|
@@ -133572,7 +133570,7 @@ function validateToolCallPolicy(input) {
|
|
|
133572
133570
|
return {
|
|
133573
133571
|
ok: false,
|
|
133574
133572
|
code: "tool_desktop_required",
|
|
133575
|
-
message: "
|
|
133573
|
+
message: "This tool requires a local runtime. Filesystem access is validated per path by the current permission mode.",
|
|
133576
133574
|
riskLevel: classified.riskLevel,
|
|
133577
133575
|
desktopRequired: true
|
|
133578
133576
|
};
|
|
@@ -136033,7 +136031,7 @@ function getNativeToolDefinitions() {
|
|
|
136033
136031
|
type: "function",
|
|
136034
136032
|
function: {
|
|
136035
136033
|
name: TOOL_NAMES.configInspect,
|
|
136036
|
-
description: "Inspect the Perch Terminal runtime configuration: execution host,
|
|
136034
|
+
description: "Inspect the Perch Terminal runtime configuration: execution host, local runtime status, optional folder scope, permission mode, and capabilities.",
|
|
136037
136035
|
parameters: {
|
|
136038
136036
|
type: "object",
|
|
136039
136037
|
properties: {},
|
|
@@ -136936,7 +136934,7 @@ function notifyApprovedRootsChanged() {
|
|
|
136936
136934
|
}
|
|
136937
136935
|
async function pickFolder(request) {
|
|
136938
136936
|
const bridge = getDesktopBridge();
|
|
136939
|
-
if (!bridge) return { ok: false, error: "
|
|
136937
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
136940
136938
|
const result2 = await bridge.pickFolder({
|
|
136941
136939
|
permissionMode: currentPermissionMode(),
|
|
136942
136940
|
defaultPath: request?.defaultPath ?? null,
|
|
@@ -136949,7 +136947,7 @@ async function pickFolder(request) {
|
|
|
136949
136947
|
}
|
|
136950
136948
|
async function approveFolderAccess(path14, options) {
|
|
136951
136949
|
const bridge = getDesktopBridge();
|
|
136952
|
-
if (!bridge) return { ok: false, error: "
|
|
136950
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
136953
136951
|
const result2 = await bridge.approveFolderAccess({
|
|
136954
136952
|
path: path14,
|
|
136955
136953
|
permissionMode: currentPermissionMode(),
|
|
@@ -136963,7 +136961,7 @@ async function checkFsAccess(request) {
|
|
|
136963
136961
|
if (!bridge) {
|
|
136964
136962
|
return {
|
|
136965
136963
|
decision: "block",
|
|
136966
|
-
reason: "
|
|
136964
|
+
reason: "Local runtime not available",
|
|
136967
136965
|
absolutePath: request.absolutePath,
|
|
136968
136966
|
approvalPath: request.absolutePath
|
|
136969
136967
|
};
|
|
@@ -136982,7 +136980,7 @@ async function checkFullDiskAccess() {
|
|
|
136982
136980
|
}
|
|
136983
136981
|
async function resolveDefaultSavePath(request) {
|
|
136984
136982
|
const bridge = getDesktopBridge();
|
|
136985
|
-
if (!bridge) return { ok: false, error: "
|
|
136983
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
136986
136984
|
return bridge.resolveDefaultSavePath(request);
|
|
136987
136985
|
}
|
|
136988
136986
|
async function getApprovedRoots() {
|
|
@@ -136992,17 +136990,17 @@ async function getApprovedRoots() {
|
|
|
136992
136990
|
}
|
|
136993
136991
|
async function removeRoot(rootId) {
|
|
136994
136992
|
const bridge = getDesktopBridge();
|
|
136995
|
-
if (!bridge) return { ok: false, error: "
|
|
136993
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
136996
136994
|
return bridge.removeRoot(rootId);
|
|
136997
136995
|
}
|
|
136998
136996
|
async function listFiles(rootId, relativePath, depth) {
|
|
136999
136997
|
const bridge = getDesktopBridge();
|
|
137000
|
-
if (!bridge) return { ok: false, rootId, basePath: "", entries: [], truncated: false, error: "
|
|
136998
|
+
if (!bridge) return { ok: false, rootId, basePath: "", entries: [], truncated: false, error: "Local runtime not available" };
|
|
137001
136999
|
return bridge.listFiles(withPermissionMode({ rootId, relativePath, depth }));
|
|
137002
137000
|
}
|
|
137003
137001
|
async function readFile2(rootId, relativePath) {
|
|
137004
137002
|
const bridge = getDesktopBridge();
|
|
137005
|
-
if (!bridge) return { ok: false, error: "
|
|
137003
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137006
137004
|
return bridge.readFile(withPermissionMode({ rootId, relativePath }));
|
|
137007
137005
|
}
|
|
137008
137006
|
function normalizeLegacyListResult(result2, request) {
|
|
@@ -137038,7 +137036,7 @@ async function listLocalSourcesDetailed(request) {
|
|
|
137038
137036
|
query: typeof request === "object" && request ? request.query ?? null : null,
|
|
137039
137037
|
refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
137040
137038
|
maxSources: 0,
|
|
137041
|
-
warning: "
|
|
137039
|
+
warning: "Local runtime not available"
|
|
137042
137040
|
};
|
|
137043
137041
|
}
|
|
137044
137042
|
const raw = await bridge.listLocalSources(request);
|
|
@@ -137046,7 +137044,7 @@ async function listLocalSourcesDetailed(request) {
|
|
|
137046
137044
|
}
|
|
137047
137045
|
async function readLocalSourceFile(localSourceId) {
|
|
137048
137046
|
const bridge = getDesktopBridge();
|
|
137049
|
-
if (!bridge) return { ok: false, error: "
|
|
137047
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137050
137048
|
return bridge.readLocalFile(localSourceId, { permissionMode: currentPermissionMode() });
|
|
137051
137049
|
}
|
|
137052
137050
|
async function getProjectRules(rootId) {
|
|
@@ -137056,37 +137054,37 @@ async function getProjectRules(rootId) {
|
|
|
137056
137054
|
}
|
|
137057
137055
|
async function readProjectMemory(rootId) {
|
|
137058
137056
|
const bridge = getDesktopBridge();
|
|
137059
|
-
if (!bridge) return { ok: false, error: "
|
|
137057
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137060
137058
|
return bridge.readProjectMemory({ rootId });
|
|
137061
137059
|
}
|
|
137062
137060
|
async function writeProjectMemory(rootId, meta) {
|
|
137063
137061
|
const bridge = getDesktopBridge();
|
|
137064
|
-
if (!bridge) return { ok: false, error: "
|
|
137062
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137065
137063
|
return bridge.writeProjectMemory({ rootId, meta });
|
|
137066
137064
|
}
|
|
137067
137065
|
async function writeMemoryFile(rootId, request) {
|
|
137068
137066
|
const bridge = getDesktopBridge();
|
|
137069
|
-
if (!bridge) return { ok: false, error: "
|
|
137067
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137070
137068
|
return bridge.writeMemoryFile({ rootId, ...request });
|
|
137071
137069
|
}
|
|
137072
137070
|
async function writeRule(rootId, request) {
|
|
137073
137071
|
const bridge = getDesktopBridge();
|
|
137074
|
-
if (!bridge) return { ok: false, error: "
|
|
137072
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137075
137073
|
return bridge.writeRule({ rootId, ...request });
|
|
137076
137074
|
}
|
|
137077
137075
|
async function writePerchMd(rootId, request) {
|
|
137078
137076
|
const bridge = getDesktopBridge();
|
|
137079
|
-
if (!bridge) return { ok: false, error: "
|
|
137077
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137080
137078
|
return bridge.writePerchMd({ rootId, ...request });
|
|
137081
137079
|
}
|
|
137082
137080
|
async function readGlobalPerchMd() {
|
|
137083
137081
|
const bridge = getDesktopBridge();
|
|
137084
|
-
if (!bridge) return { ok: false, error: "
|
|
137082
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137085
137083
|
return bridge.readGlobalPerchMd();
|
|
137086
137084
|
}
|
|
137087
137085
|
async function writeGlobalPerchMd(content) {
|
|
137088
137086
|
const bridge = getDesktopBridge();
|
|
137089
|
-
if (!bridge) return { ok: false, error: "
|
|
137087
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137090
137088
|
return bridge.writeGlobalPerchMd({ content });
|
|
137091
137089
|
}
|
|
137092
137090
|
async function getMcpStatus() {
|
|
@@ -137101,12 +137099,12 @@ async function listMcpTools() {
|
|
|
137101
137099
|
}
|
|
137102
137100
|
async function callMcpTool(request) {
|
|
137103
137101
|
const bridge = getDesktopBridge();
|
|
137104
|
-
if (!bridge) return { ok: false, error: "
|
|
137102
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137105
137103
|
return bridge.callMcpTool(request);
|
|
137106
137104
|
}
|
|
137107
137105
|
async function callEmbeddedBrowserTool(request) {
|
|
137108
137106
|
const bridge = getDesktopBridge();
|
|
137109
|
-
if (!bridge) return { ok: false, error: "
|
|
137107
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137110
137108
|
if (typeof bridge.callEmbeddedBrowserTool !== "function") {
|
|
137111
137109
|
return { ok: false, error: "Embedded browser bridge not available in this desktop build" };
|
|
137112
137110
|
}
|
|
@@ -137114,7 +137112,7 @@ async function callEmbeddedBrowserTool(request) {
|
|
|
137114
137112
|
}
|
|
137115
137113
|
async function setEmbeddedBrowserVisible(open) {
|
|
137116
137114
|
const bridge = getDesktopBridge();
|
|
137117
|
-
if (!bridge) return { ok: false, error: "
|
|
137115
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137118
137116
|
if (typeof bridge.setEmbeddedBrowserVisible !== "function") {
|
|
137119
137117
|
return { ok: false, error: "Embedded browser bridge not available in this desktop build" };
|
|
137120
137118
|
}
|
|
@@ -137137,7 +137135,7 @@ function onEmbeddedBrowserState(handler) {
|
|
|
137137
137135
|
}
|
|
137138
137136
|
async function reconnectMcp() {
|
|
137139
137137
|
const bridge = getDesktopBridge();
|
|
137140
|
-
if (!bridge) return { ok: false, error: "
|
|
137138
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137141
137139
|
return bridge.reconnectMcp();
|
|
137142
137140
|
}
|
|
137143
137141
|
async function getOrStartBashTerminal(request) {
|
|
@@ -137182,37 +137180,37 @@ async function runLocalBash(request) {
|
|
|
137182
137180
|
}
|
|
137183
137181
|
async function readWorkspaceFile(request) {
|
|
137184
137182
|
const bridge = getDesktopBridge();
|
|
137185
|
-
if (!bridge) return { ok: false, error: "
|
|
137183
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137186
137184
|
return bridge.readWorkspaceFile(withPermissionMode(request, request));
|
|
137187
137185
|
}
|
|
137188
137186
|
async function writeWorkspaceFile(request) {
|
|
137189
137187
|
const bridge = getDesktopBridge();
|
|
137190
|
-
if (!bridge) return { ok: false, error: "
|
|
137188
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137191
137189
|
return bridge.writeWorkspaceFile(withPermissionMode(request, request));
|
|
137192
137190
|
}
|
|
137193
137191
|
async function moveLocalFile(request) {
|
|
137194
137192
|
const bridge = getDesktopBridge();
|
|
137195
|
-
if (!bridge) return { ok: false, error: "
|
|
137193
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137196
137194
|
return bridge.moveLocalFile(withPermissionMode(request, request));
|
|
137197
137195
|
}
|
|
137198
137196
|
async function copyLocalFile(request) {
|
|
137199
137197
|
const bridge = getDesktopBridge();
|
|
137200
|
-
if (!bridge) return { ok: false, error: "
|
|
137198
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137201
137199
|
return bridge.copyLocalFile(withPermissionMode(request, request));
|
|
137202
137200
|
}
|
|
137203
137201
|
async function createDirectory(request) {
|
|
137204
137202
|
const bridge = getDesktopBridge();
|
|
137205
|
-
if (!bridge) return { ok: false, error: "
|
|
137203
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137206
137204
|
return bridge.createDirectory(withPermissionMode(request, request));
|
|
137207
137205
|
}
|
|
137208
137206
|
async function deleteLocalFile(request) {
|
|
137209
137207
|
const bridge = getDesktopBridge();
|
|
137210
|
-
if (!bridge) return { ok: false, error: "
|
|
137208
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137211
137209
|
return bridge.deleteLocalFile(withPermissionMode(request, request));
|
|
137212
137210
|
}
|
|
137213
137211
|
async function printFile(request) {
|
|
137214
137212
|
const bridge = getDesktopBridge();
|
|
137215
|
-
if (!bridge) return { ok: false, error: "
|
|
137213
|
+
if (!bridge) return { ok: false, error: "Local runtime not available" };
|
|
137216
137214
|
return bridge.printFile(withPermissionMode(request, request));
|
|
137217
137215
|
}
|
|
137218
137216
|
async function listWorkspaceFilesGlob(request) {
|
|
@@ -137271,7 +137269,7 @@ async function runLocalAPAuditPacket(request) {
|
|
|
137271
137269
|
if (!bridge) {
|
|
137272
137270
|
return {
|
|
137273
137271
|
ok: false,
|
|
137274
|
-
error: "
|
|
137272
|
+
error: "Local runtime not available",
|
|
137275
137273
|
errorCode: "desktop_bridge_unavailable",
|
|
137276
137274
|
executionHost: "electron_desktop",
|
|
137277
137275
|
durationMs: 0
|
|
@@ -137284,7 +137282,7 @@ async function runLocalPrepareAPEvidence(request) {
|
|
|
137284
137282
|
if (!bridge?.runLocalPrepareAPEvidence) {
|
|
137285
137283
|
return {
|
|
137286
137284
|
ok: false,
|
|
137287
|
-
error: "
|
|
137285
|
+
error: "AP evidence tool not available in local runtime",
|
|
137288
137286
|
errorCode: bridge ? "missing_dependency" : "desktop_bridge_unavailable",
|
|
137289
137287
|
executionHost: "electron_desktop",
|
|
137290
137288
|
durationMs: 0
|
|
@@ -137297,7 +137295,7 @@ async function runLocalQueryAPCases(request) {
|
|
|
137297
137295
|
if (!bridge?.runLocalQueryAPCases) {
|
|
137298
137296
|
return {
|
|
137299
137297
|
ok: false,
|
|
137300
|
-
error: "
|
|
137298
|
+
error: "AP case query tool not available in local runtime",
|
|
137301
137299
|
errorCode: bridge ? "missing_dependency" : "desktop_bridge_unavailable",
|
|
137302
137300
|
executionHost: "electron_desktop",
|
|
137303
137301
|
durationMs: 0
|
|
@@ -137310,7 +137308,7 @@ async function runLocalRenderAPControlGraph(request) {
|
|
|
137310
137308
|
if (!bridge?.runLocalRenderAPControlGraph) {
|
|
137311
137309
|
return {
|
|
137312
137310
|
ok: false,
|
|
137313
|
-
error: "
|
|
137311
|
+
error: "AP control graph tool not available in local runtime",
|
|
137314
137312
|
errorCode: bridge ? "missing_dependency" : "desktop_bridge_unavailable",
|
|
137315
137313
|
executionHost: "electron_desktop",
|
|
137316
137314
|
durationMs: 0
|
|
@@ -137323,7 +137321,7 @@ async function runLocalPayrollRunArtifact(request) {
|
|
|
137323
137321
|
if (!bridge) {
|
|
137324
137322
|
return {
|
|
137325
137323
|
ok: false,
|
|
137326
|
-
error: "
|
|
137324
|
+
error: "Local runtime not available",
|
|
137327
137325
|
errorCode: "desktop_bridge_unavailable",
|
|
137328
137326
|
executionHost: "electron_desktop",
|
|
137329
137327
|
durationMs: 0
|
|
@@ -137338,7 +137336,7 @@ function desktopGLReconcileAvailable() {
|
|
|
137338
137336
|
async function runLocalGLReconcileArtifact(folderPath) {
|
|
137339
137337
|
const bridge = getDesktopBridge();
|
|
137340
137338
|
if (!bridge?.runLocalGLReconcileArtifact) {
|
|
137341
|
-
return { ok: false, error: "
|
|
137339
|
+
return { ok: false, error: "Local runtime unavailable", errorCode: "desktop_bridge_unavailable", executionHost: "electron_desktop", durationMs: 0 };
|
|
137342
137340
|
}
|
|
137343
137341
|
return bridge.runLocalGLReconcileArtifact({ folderPath });
|
|
137344
137342
|
}
|
|
@@ -137349,7 +137347,7 @@ function desktopStatementAuditAvailable() {
|
|
|
137349
137347
|
async function runLocalStatementAuditArtifact(folderPath) {
|
|
137350
137348
|
const bridge = getDesktopBridge();
|
|
137351
137349
|
if (!bridge?.runLocalStatementAuditArtifact) {
|
|
137352
|
-
return { ok: false, error: "
|
|
137350
|
+
return { ok: false, error: "Local runtime unavailable", errorCode: "desktop_bridge_unavailable", executionHost: "electron_desktop", durationMs: 0 };
|
|
137353
137351
|
}
|
|
137354
137352
|
return bridge.runLocalStatementAuditArtifact({ folderPath });
|
|
137355
137353
|
}
|
|
@@ -137374,7 +137372,7 @@ async function runSandboxCodeJob(request) {
|
|
|
137374
137372
|
kind: "blocked",
|
|
137375
137373
|
error: bridge ? "capability_unavailable" : "not_desktop",
|
|
137376
137374
|
executionHost: "electron-main",
|
|
137377
|
-
message: bridge ? "This Perch
|
|
137375
|
+
message: bridge ? "This Perch build does not expose runSandboxCodeJob." : "Local runtime is unavailable."
|
|
137378
137376
|
};
|
|
137379
137377
|
}
|
|
137380
137378
|
return bridge.runSandboxCodeJob(request);
|
|
@@ -198170,8 +198168,8 @@ async function resolvePlaybookInputs(args) {
|
|
|
198170
198168
|
return {
|
|
198171
198169
|
ok: false,
|
|
198172
198170
|
status: "blocked",
|
|
198173
|
-
errorCode: "
|
|
198174
|
-
message: "Managed playbooks require the
|
|
198171
|
+
errorCode: "local_runtime_unavailable",
|
|
198172
|
+
message: "Managed playbooks require the local runtime for source discovery and file reads.",
|
|
198175
198173
|
folderPath: rawFolderPath,
|
|
198176
198174
|
warnings: []
|
|
198177
198175
|
};
|
|
@@ -199532,7 +199530,6 @@ function containsBrowserDeliveryTask(tasks) {
|
|
|
199532
199530
|
var BROWSER_DELIVERY_ROLE_IDS;
|
|
199533
199531
|
var init_browserDeliveryLock = __esm({
|
|
199534
199532
|
"features/perchTerminal/agentPlatform/browserDeliveryLock.ts"() {
|
|
199535
|
-
"use strict";
|
|
199536
199533
|
BROWSER_DELIVERY_ROLE_IDS = /* @__PURE__ */ new Set([
|
|
199537
199534
|
"doc_writer",
|
|
199538
199535
|
"email_sender",
|
|
@@ -199903,6 +199900,30 @@ function abortRuntimeRun(runId, reason = "Run cancelled.") {
|
|
|
199903
199900
|
cleanupRun(record);
|
|
199904
199901
|
return true;
|
|
199905
199902
|
}
|
|
199903
|
+
function submitRuntimeSteer(input) {
|
|
199904
|
+
const runId = input.runId?.trim();
|
|
199905
|
+
if (!runId) return { ok: false, error: "No active turn to steer." };
|
|
199906
|
+
if (input.expectedRunId && input.expectedRunId !== runId) {
|
|
199907
|
+
return { ok: false, error: `Expected active turn ${input.expectedRunId}, found ${runId}.` };
|
|
199908
|
+
}
|
|
199909
|
+
const record = getRuntimeRun(runId);
|
|
199910
|
+
if (!record || record.status !== "running" || record.controller.signal.aborted) {
|
|
199911
|
+
return { ok: false, error: "No active turn to steer." };
|
|
199912
|
+
}
|
|
199913
|
+
if (input.threadId && record.threadId && input.threadId !== record.threadId) {
|
|
199914
|
+
return { ok: false, error: "Active turn belongs to a different thread." };
|
|
199915
|
+
}
|
|
199916
|
+
const text = input.text.trim();
|
|
199917
|
+
if (!text) return { ok: false, error: "Steer input cannot be empty." };
|
|
199918
|
+
record.steerQueue.push({
|
|
199919
|
+
text,
|
|
199920
|
+
mode: input.mode ?? "append",
|
|
199921
|
+
clientMessageId: input.clientMessageId ?? null,
|
|
199922
|
+
submittedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
199923
|
+
});
|
|
199924
|
+
record.updatedAt = nowMs();
|
|
199925
|
+
return { ok: true, turnId: runId };
|
|
199926
|
+
}
|
|
199906
199927
|
function consumeRuntimeSteers(runId) {
|
|
199907
199928
|
const record = getRuntimeRun(runId);
|
|
199908
199929
|
if (!record || record.status !== "running" || record.controller.signal.aborted) return [];
|
|
@@ -205951,14 +205972,14 @@ async function runAPAuditPacketAdapter(args) {
|
|
|
205951
205972
|
const folderPath = (args.folderPath ?? "").trim();
|
|
205952
205973
|
if (!isDesktopAvailable()) {
|
|
205953
205974
|
return blockedEnvelope({
|
|
205954
|
-
reason: "AP audit packet requires the
|
|
205955
|
-
errorCode: "
|
|
205975
|
+
reason: "AP audit packet requires the local runtime for filesystem access. The browser cannot read the user's filesystem.",
|
|
205976
|
+
errorCode: "local_runtime_unavailable",
|
|
205956
205977
|
folderPath: folderPath || null
|
|
205957
205978
|
});
|
|
205958
205979
|
}
|
|
205959
205980
|
if (!desktopAPAuditAvailable()) {
|
|
205960
205981
|
return blockedEnvelope({
|
|
205961
|
-
reason: "This Perch
|
|
205982
|
+
reason: "This Perch build does not expose runLocalAPAuditPacket. Update Perch CLI or rebuild the app package.",
|
|
205962
205983
|
errorCode: "capability_unavailable",
|
|
205963
205984
|
folderPath: folderPath || null
|
|
205964
205985
|
});
|
|
@@ -206181,14 +206202,14 @@ function preflight(toolName) {
|
|
|
206181
206202
|
if (!isDesktopAvailable()) {
|
|
206182
206203
|
return blocked({
|
|
206183
206204
|
toolName,
|
|
206184
|
-
reason: "AP evidence tools require the
|
|
206185
|
-
errorCode: "
|
|
206205
|
+
reason: "AP evidence tools require the local runtime for filesystem access.",
|
|
206206
|
+
errorCode: "local_runtime_unavailable"
|
|
206186
206207
|
});
|
|
206187
206208
|
}
|
|
206188
206209
|
if (!desktopAPEvidenceAvailable()) {
|
|
206189
206210
|
return blocked({
|
|
206190
206211
|
toolName,
|
|
206191
|
-
reason: "This Perch
|
|
206212
|
+
reason: "This Perch build does not expose AP evidence tools. Update Perch CLI or rebuild the app package.",
|
|
206192
206213
|
errorCode: "capability_unavailable"
|
|
206193
206214
|
});
|
|
206194
206215
|
}
|
|
@@ -206939,13 +206960,13 @@ function blocked2(reason, errorCode) {
|
|
|
206939
206960
|
async function runSandboxAnalysisAdapter(args, opts) {
|
|
206940
206961
|
if (!isDesktopAvailable()) {
|
|
206941
206962
|
return blocked2(
|
|
206942
|
-
"runSandboxAnalysis requires the
|
|
206943
|
-
"
|
|
206963
|
+
"runSandboxAnalysis requires the local runtime. The browser cannot execute sandbox jobs against local sources.",
|
|
206964
|
+
"local_runtime_unavailable"
|
|
206944
206965
|
);
|
|
206945
206966
|
}
|
|
206946
206967
|
if (!desktopSandboxAnalysisAvailable()) {
|
|
206947
206968
|
return blocked2(
|
|
206948
|
-
"This Perch
|
|
206969
|
+
"This Perch build does not expose runSandboxAnalysisJob. Update Perch CLI or rebuild the app package.",
|
|
206949
206970
|
"capability_unavailable"
|
|
206950
206971
|
);
|
|
206951
206972
|
}
|
|
@@ -210448,7 +210469,7 @@ function validateSuitePlan(plan, opts) {
|
|
|
210448
210469
|
};
|
|
210449
210470
|
}
|
|
210450
210471
|
if (opts?.desktopConnected === false) {
|
|
210451
|
-
return { valid: false, reason: "
|
|
210472
|
+
return { valid: false, reason: "Local runtime required for workflow tools." };
|
|
210452
210473
|
}
|
|
210453
210474
|
return { valid: true };
|
|
210454
210475
|
}
|
|
@@ -213140,7 +213161,7 @@ var init_config2 = __esm({
|
|
|
213140
213161
|
ok: true,
|
|
213141
213162
|
configured: false,
|
|
213142
213163
|
servers: [],
|
|
213143
|
-
note: "
|
|
213164
|
+
note: "MCP servers are not connected in this runtime."
|
|
213144
213165
|
};
|
|
213145
213166
|
}
|
|
213146
213167
|
const { getMcpStatus: getMcpStatus2 } = await Promise.resolve().then(() => (init_bridge(), bridge_exports));
|
|
@@ -213975,7 +213996,7 @@ async function executeToolCall(call, opts) {
|
|
|
213975
213996
|
startMs,
|
|
213976
213997
|
startedAt,
|
|
213977
213998
|
code: "tool_desktop_required",
|
|
213978
|
-
message: "
|
|
213999
|
+
message: "Local runtime not available. Local tools require Perch Desktop or CLI local mode.",
|
|
213979
214000
|
riskLevel: policy.riskLevel,
|
|
213980
214001
|
desktopRequired: true
|
|
213981
214002
|
});
|
|
@@ -224069,13 +224090,13 @@ function createCliNodeLocalBridge(input) {
|
|
|
224069
224090
|
};
|
|
224070
224091
|
},
|
|
224071
224092
|
getProjectRules: async () => [],
|
|
224072
|
-
readProjectMemory: async () => ({ ok: false, error: "Project memory is
|
|
224073
|
-
writeProjectMemory: async () => ({ ok: false, error: "Project memory
|
|
224074
|
-
writeMemoryFile: async () => ({ ok: false, error: "Project memory
|
|
224075
|
-
writeRule: async () => ({ ok: false, error: "Project
|
|
224076
|
-
writePerchMd: async () => ({ ok: false, error: "PERCH.md writes are
|
|
224077
|
-
readGlobalPerchMd: async () => ({ ok: false, error: "Global PERCH.md is
|
|
224078
|
-
writeGlobalPerchMd: async () => ({ ok: false, error: "Global PERCH.md
|
|
224093
|
+
readProjectMemory: async () => ({ ok: false, error: "Project memory is not available in this CLI package yet." }),
|
|
224094
|
+
writeProjectMemory: async () => ({ ok: false, error: "Project memory writes are not available in this CLI package yet." }),
|
|
224095
|
+
writeMemoryFile: async () => ({ ok: false, error: "Project memory files are not available in this CLI package yet." }),
|
|
224096
|
+
writeRule: async () => ({ ok: false, error: "Project rule writes are not available in this CLI package yet." }),
|
|
224097
|
+
writePerchMd: async () => ({ ok: false, error: "PERCH.md writes are not available in this CLI package yet." }),
|
|
224098
|
+
readGlobalPerchMd: async () => ({ ok: false, error: "Global PERCH.md is not available in this CLI package yet." }),
|
|
224099
|
+
writeGlobalPerchMd: async () => ({ ok: false, error: "Global PERCH.md writes are not available in this CLI package yet." }),
|
|
224079
224100
|
getMcpStatus: async () => [],
|
|
224080
224101
|
listMcpTools: async () => [],
|
|
224081
224102
|
callMcpTool: async () => ({ ok: false, error: "MCP tools are not available in CLI local mode." }),
|
|
@@ -224631,6 +224652,7 @@ function buildCliTurnInput(input, resolved) {
|
|
|
224631
224652
|
const userId = input.userId ?? null;
|
|
224632
224653
|
return {
|
|
224633
224654
|
trimmedInput: resolved.prompt,
|
|
224655
|
+
clientRunId: input.clientRunId ?? null,
|
|
224634
224656
|
chatMode: input.chatMode ?? "agents",
|
|
224635
224657
|
threadId: resolved.threadId,
|
|
224636
224658
|
personaId: input.personaId ?? DEFAULT_PERSONA_ID,
|
|
@@ -280080,6 +280102,7 @@ async function runInkInteractivePerchCli(writer, deps, options) {
|
|
|
280080
280102
|
const [pulse, setPulse] = React11.useState(0);
|
|
280081
280103
|
const [, refresh] = React11.useState(0);
|
|
280082
280104
|
const liveTextRef = React11.useRef("");
|
|
280105
|
+
const activeRunRef = React11.useRef(null);
|
|
280083
280106
|
React11.useEffect(() => {
|
|
280084
280107
|
if (!working) return void 0;
|
|
280085
280108
|
const timer = setInterval(() => setPulse((value) => value + 1), 120);
|
|
@@ -280148,6 +280171,15 @@ async function runInkInteractivePerchCli(writer, deps, options) {
|
|
|
280148
280171
|
setLiveText("");
|
|
280149
280172
|
liveTextRef.current = "";
|
|
280150
280173
|
const toolNamesById = /* @__PURE__ */ new Map();
|
|
280174
|
+
const clientRunId = createCliRunId();
|
|
280175
|
+
const externalController = new AbortController();
|
|
280176
|
+
const runtimeRun = registerRuntimeRun({
|
|
280177
|
+
runId: clientRunId,
|
|
280178
|
+
kind: "turn",
|
|
280179
|
+
threadId: state.threadId,
|
|
280180
|
+
parentSignal: externalController.signal
|
|
280181
|
+
});
|
|
280182
|
+
activeRunRef.current = { runId: clientRunId, threadId: state.threadId };
|
|
280151
280183
|
try {
|
|
280152
280184
|
if (!isCliModelConnectionReady(connection)) {
|
|
280153
280185
|
addItem({
|
|
@@ -280173,8 +280205,10 @@ async function runInkInteractivePerchCli(writer, deps, options) {
|
|
|
280173
280205
|
workspaceId: hostedContext.workspaceId,
|
|
280174
280206
|
permanentMemories: hostedContext.permanentMemories,
|
|
280175
280207
|
founderModelSelection: connection.founderModelSelection,
|
|
280208
|
+
clientRunId,
|
|
280176
280209
|
desktopConnected: state.desktopConnected,
|
|
280177
280210
|
cliLocalTools: state.cliLocalTools,
|
|
280211
|
+
signal: runtimeRun.controller.signal,
|
|
280178
280212
|
onEvent: (event) => {
|
|
280179
280213
|
switch (event.type) {
|
|
280180
280214
|
case "content_delta":
|
|
@@ -280268,6 +280302,11 @@ async function runInkInteractivePerchCli(writer, deps, options) {
|
|
|
280268
280302
|
} catch (error) {
|
|
280269
280303
|
addItem({ label: "stop", text: humanizeCliError(errorMessage(error)), tone: "danger" });
|
|
280270
280304
|
} finally {
|
|
280305
|
+
finishRuntimeRun(clientRunId, runtimeRun.controller.signal.aborted ? "cancelled" : "completed");
|
|
280306
|
+
externalController.abort();
|
|
280307
|
+
if (activeRunRef.current?.runId === clientRunId) {
|
|
280308
|
+
activeRunRef.current = null;
|
|
280309
|
+
}
|
|
280271
280310
|
setWorking(false);
|
|
280272
280311
|
setWorkingText("ready");
|
|
280273
280312
|
setLiveText("");
|
|
@@ -280275,7 +280314,44 @@ async function runInkInteractivePerchCli(writer, deps, options) {
|
|
|
280275
280314
|
}
|
|
280276
280315
|
}, [addItem, app, reconnect, runTurn, updateToolItem, working]);
|
|
280277
280316
|
Ink2.useInput((input, key) => {
|
|
280278
|
-
if (working)
|
|
280317
|
+
if (working) {
|
|
280318
|
+
if (key.ctrl && input === "c") {
|
|
280319
|
+
const active = activeRunRef.current;
|
|
280320
|
+
if (active && abortRuntimeRun(active.runId, "Stopped from CLI.")) {
|
|
280321
|
+
addItem({ label: "stop", text: "stop requested", tone: "danger" });
|
|
280322
|
+
setWorkingText("stopping");
|
|
280323
|
+
}
|
|
280324
|
+
return;
|
|
280325
|
+
}
|
|
280326
|
+
if (key.return) {
|
|
280327
|
+
const steerText = draft.trim();
|
|
280328
|
+
const active = activeRunRef.current;
|
|
280329
|
+
if (steerText && active) {
|
|
280330
|
+
const result2 = submitRuntimeSteer({
|
|
280331
|
+
runId: active.runId,
|
|
280332
|
+
expectedRunId: active.runId,
|
|
280333
|
+
threadId: active.threadId,
|
|
280334
|
+
text: steerText,
|
|
280335
|
+
mode: "append",
|
|
280336
|
+
clientMessageId: `cli-steer-${Date.now()}`
|
|
280337
|
+
});
|
|
280338
|
+
if (result2.ok) {
|
|
280339
|
+
addItem({ label: "you", text: steerText, tone: "touch" });
|
|
280340
|
+
addItem({ label: "system", text: "steer queued", tone: "muted" });
|
|
280341
|
+
setDraft("");
|
|
280342
|
+
} else {
|
|
280343
|
+
addItem({ label: "need", text: result2.error, tone: "danger" });
|
|
280344
|
+
}
|
|
280345
|
+
}
|
|
280346
|
+
return;
|
|
280347
|
+
}
|
|
280348
|
+
if (key.backspace || key.delete) {
|
|
280349
|
+
setDraft((value) => value.slice(0, -1));
|
|
280350
|
+
return;
|
|
280351
|
+
}
|
|
280352
|
+
if (input && !key.escape) setDraft((value) => value + input);
|
|
280353
|
+
return;
|
|
280354
|
+
}
|
|
280279
280355
|
if (key.return) {
|
|
280280
280356
|
void submitPrompt(draft);
|
|
280281
280357
|
return;
|
|
@@ -280422,7 +280498,7 @@ async function runInkInteractivePerchCli(writer, deps, options) {
|
|
|
280422
280498
|
)
|
|
280423
280499
|
);
|
|
280424
280500
|
}),
|
|
280425
|
-
{ exitOnCtrlC:
|
|
280501
|
+
{ exitOnCtrlC: false }
|
|
280426
280502
|
);
|
|
280427
280503
|
await instance.waitUntilExit();
|
|
280428
280504
|
connection.restore();
|
|
@@ -280950,6 +281026,9 @@ function trimRecentMessages(messages) {
|
|
|
280950
281026
|
messages.splice(0, messages.length - 30);
|
|
280951
281027
|
}
|
|
280952
281028
|
}
|
|
281029
|
+
function createCliRunId() {
|
|
281030
|
+
return `cli-turn-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
281031
|
+
}
|
|
280953
281032
|
async function runAuthCommand(parsed, writer) {
|
|
280954
281033
|
if (parsed.action === "logout") {
|
|
280955
281034
|
await clearStoredCliAuthSession();
|
|
@@ -281220,6 +281299,7 @@ var init_perch_cli = __esm({
|
|
|
281220
281299
|
init_cliStandaloneOAuth();
|
|
281221
281300
|
init_contextMeterDisplay();
|
|
281222
281301
|
init_threadSession();
|
|
281302
|
+
init_runRegistry();
|
|
281223
281303
|
execFileAsync3 = promisify3(execFile3);
|
|
281224
281304
|
DEFAULT_CLI_LOGIN_APP_URL = "https://app.perchai.app";
|
|
281225
281305
|
CLI_PACKAGE_VERSION = readCliPackageVersion();
|