subagent-extension-for-codex 0.1.1 → 0.2.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 +11 -8
- package/assets/icons/archive-view.svg +16 -0
- package/assets/icons/git-commit-off.svg +15 -0
- package/assets/icons/git-off.svg +17 -0
- package/dist/THIRD_PARTY_LICENSES.txt +1 -1
- package/dist/app.html +254 -146
- package/dist/bundle/chunks/{chunk-LZFYKJ4Y.js → chunk-DGCGXY3T.js} +81 -165
- package/dist/bundle/chunks/chunk-DGCGXY3T.js.map +6 -0
- package/dist/bundle/chunks/{chunk-KFBRPWLR.js → chunk-MOWBM7MZ.js} +6830 -7889
- package/dist/bundle/chunks/chunk-MOWBM7MZ.js.map +6 -0
- package/dist/bundle/chunks/chunk-ZSLXLKU2.js +1702 -0
- package/dist/bundle/chunks/chunk-ZSLXLKU2.js.map +6 -0
- package/dist/bundle/main.js +17321 -15989
- package/dist/bundle/main.js.map +2 -2
- package/dist/bundle/projects-cli.js +7 -7
- package/dist/bundle/projects-cli.js.map +1 -1
- package/dist/bundle/stdio.js +2 -2
- package/package.json +13 -1
- package/plugin.json +1 -1
- package/dist/bundle/chunks/chunk-KFBRPWLR.js.map +0 -6
- package/dist/bundle/chunks/chunk-L3PORPD3.js +0 -450
- package/dist/bundle/chunks/chunk-L3PORPD3.js.map +0 -6
- package/dist/bundle/chunks/chunk-LZFYKJ4Y.js.map +0 -6
|
@@ -3,11 +3,14 @@ import {
|
|
|
3
3
|
JsonlWriter,
|
|
4
4
|
approvalDeciderSchema,
|
|
5
5
|
approvalModeSchema,
|
|
6
|
+
assertPlainFolderAllowed,
|
|
6
7
|
budgetRaiseSchema,
|
|
7
8
|
dataDirectory,
|
|
8
9
|
deliveries,
|
|
9
10
|
errorCategory,
|
|
10
11
|
gitRepositoryRoot,
|
|
12
|
+
gitState,
|
|
13
|
+
gitWorkTreeRoot,
|
|
11
14
|
installRoot,
|
|
12
15
|
logCorrelation,
|
|
13
16
|
logError,
|
|
@@ -19,8 +22,9 @@ import {
|
|
|
19
22
|
reasoningSchema,
|
|
20
23
|
roles,
|
|
21
24
|
startSchema,
|
|
22
|
-
withLogContext
|
|
23
|
-
|
|
25
|
+
withLogContext,
|
|
26
|
+
within
|
|
27
|
+
} from "./chunk-MOWBM7MZ.js";
|
|
24
28
|
import {
|
|
25
29
|
$ZodObject,
|
|
26
30
|
$ZodType,
|
|
@@ -63,6 +67,7 @@ import {
|
|
|
63
67
|
} from "./chunk-5TX3SEV2.js";
|
|
64
68
|
|
|
65
69
|
// src/service/platform/panel/host-context.ts
|
|
70
|
+
import { realpath } from "node:fs/promises";
|
|
66
71
|
import { isAbsolute } from "node:path";
|
|
67
72
|
import { fileURLToPath } from "node:url";
|
|
68
73
|
var codexContextCapability = {
|
|
@@ -74,21 +79,45 @@ async function withHostRepository(c, args, meta2) {
|
|
|
74
79
|
const directory = args.host_directory ?? state?.sandboxCwd;
|
|
75
80
|
if (typeof directory !== "string" || directory.length > 4096) return args;
|
|
76
81
|
try {
|
|
77
|
-
const
|
|
78
|
-
if (!
|
|
79
|
-
const
|
|
80
|
-
const repository = c.projects ? await c.projects.resolve(root) : await c.workspaces.repository(root);
|
|
82
|
+
const candidate = await hostProjectCandidate(c, directory);
|
|
83
|
+
if (!candidate) return args;
|
|
84
|
+
const repository = c.projects ? await c.projects.resolve(candidate.repository) : await c.workspaces.repository(candidate.repository);
|
|
81
85
|
return { ...args, repository };
|
|
82
86
|
} catch {
|
|
83
87
|
return args;
|
|
84
88
|
}
|
|
85
89
|
}
|
|
86
|
-
|
|
90
|
+
var isGitRoot = (candidate) => candidate.git === "ready" || candidate.git === "no_commits";
|
|
91
|
+
var permissionDenied = (error) => /Operation not permitted|Permission denied/.test(
|
|
92
|
+
String(error.stderr)
|
|
93
|
+
);
|
|
94
|
+
async function hostProjectCandidate(c, directory) {
|
|
87
95
|
if (!directory) return void 0;
|
|
88
96
|
try {
|
|
89
97
|
const cwd = fileURLToPath(directory);
|
|
90
98
|
if (!isAbsolute(cwd)) return void 0;
|
|
91
|
-
|
|
99
|
+
let root;
|
|
100
|
+
try {
|
|
101
|
+
root = await gitWorkTreeRoot(cwd);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
if (permissionDenied(error)) return { repository: cwd };
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
if (root) {
|
|
107
|
+
return {
|
|
108
|
+
repository: root,
|
|
109
|
+
...await gitState(root).then(
|
|
110
|
+
(git) => ({ git }),
|
|
111
|
+
() => ({})
|
|
112
|
+
)
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const actual = await realpath(cwd);
|
|
116
|
+
const registered = c.projects?.list().filter(
|
|
117
|
+
(project) => project.kind === "repository" && within(project.repository, actual)
|
|
118
|
+
).map((project) => project.repository).sort((a, b) => b.length - a.length)[0];
|
|
119
|
+
if (!registered) await assertPlainFolderAllowed(actual);
|
|
120
|
+
return { repository: registered ?? actual, git: "none" };
|
|
92
121
|
} catch {
|
|
93
122
|
return void 0;
|
|
94
123
|
}
|
|
@@ -8160,6 +8189,7 @@ var panelOutputSchema = external_exports.object({
|
|
|
8160
8189
|
}),
|
|
8161
8190
|
panel_project_candidate: external_exports.object({
|
|
8162
8191
|
repository: external_exports.string(),
|
|
8192
|
+
git: external_exports.union([external_exports.literal("ready"), external_exports.literal("no_commits"), external_exports.literal("none")]).optional(),
|
|
8163
8193
|
auto_register: external_exports.boolean()
|
|
8164
8194
|
}).optional(),
|
|
8165
8195
|
panel_selection: external_exports.object({
|
|
@@ -8684,13 +8714,13 @@ async function resolvePanelContext(c, owner, args) {
|
|
|
8684
8714
|
if (target && args.revision && args.revision !== target.revision) {
|
|
8685
8715
|
throw new Error("Task uses a different revision");
|
|
8686
8716
|
}
|
|
8687
|
-
const candidate = !args.repository && !target && args.conversation_id !== null ? await hostProjectCandidate(args.host_directory) : void 0;
|
|
8717
|
+
const candidate = !args.repository && !target && args.conversation_id !== null ? await hostProjectCandidate(c, args.host_directory) : void 0;
|
|
8688
8718
|
return {
|
|
8689
|
-
...candidate && candidate !== repository ? {
|
|
8719
|
+
...candidate && candidate.repository !== repository ? {
|
|
8690
8720
|
panel_project_candidate: {
|
|
8691
|
-
|
|
8721
|
+
...candidate,
|
|
8692
8722
|
// New task may offer it; starting that task adds it with the user's choice.
|
|
8693
|
-
auto_register: !!c.projects && c.settings.values(owner).projects.auto_register_chat
|
|
8723
|
+
auto_register: isGitRoot(candidate) && !!c.projects && c.settings.values(owner).projects.auto_register_chat
|
|
8694
8724
|
}
|
|
8695
8725
|
} : {},
|
|
8696
8726
|
panel_scope: {
|
|
@@ -8847,7 +8877,7 @@ function delegationPanel(htmlPath, initialTasks, context) {
|
|
|
8847
8877
|
var SERVER_INSTRUCTIONS = `Delegate work to background workers.
|
|
8848
8878
|
1. Resolve the repository with get_current_project or list_projects and pass it to start_task as an explicit absolute path. Never guess a path. Tool arguments never grant access. For an unregistered project, follow next_step.
|
|
8849
8879
|
2. Call list_workers. If a provider is not ready, report readiness.message to the user instead of retrying. Use the reviewer profile for review requests.
|
|
8850
|
-
3. Call start_task with the user's full request in description. Tasks use the current checkout by default, including uncommitted changes. Use workspace_strategy worktree for isolated or parallel edits from a committed revision.
|
|
8880
|
+
3. Call start_task with the user's full request in description. Tasks use the current checkout by default, including uncommitted changes. Use workspace_strategy worktree for isolated or parallel edits from a committed revision, only on a project whose git is ready.
|
|
8851
8881
|
4. Supervise with list_messages as its description explains. Read what the worker changed with get_changes, never from its own reply.
|
|
8852
8882
|
5. A finished task stays open. Continue it with send_message. Reopen its panel with open_subagent_extension_for_codex(task_id), never another start_task.`;
|
|
8853
8883
|
|
|
@@ -9967,8 +9997,12 @@ async function autoRegisterChatProject(c, owner, meta2, repository) {
|
|
|
9967
9997
|
if (!c.projects || !c.settings.values(owner).projects.auto_register_chat) {
|
|
9968
9998
|
return void 0;
|
|
9969
9999
|
}
|
|
9970
|
-
const
|
|
9971
|
-
|
|
10000
|
+
const candidate = await hostProjectCandidate(
|
|
10001
|
+
c,
|
|
10002
|
+
hostDirectoryFromMeta(meta2)
|
|
10003
|
+
);
|
|
10004
|
+
if (!candidate || !isGitRoot(candidate)) return void 0;
|
|
10005
|
+
const root = candidate.repository;
|
|
9972
10006
|
if (repository !== void 0 && (!isAbsolute2(repository) || await gitRoot(repository) !== root)) {
|
|
9973
10007
|
return void 0;
|
|
9974
10008
|
}
|
|
@@ -9979,21 +10013,23 @@ async function autoRegisterChatProject(c, owner, meta2, repository) {
|
|
|
9979
10013
|
}
|
|
9980
10014
|
}
|
|
9981
10015
|
async function currentChatProject(c, owner, meta2) {
|
|
9982
|
-
const
|
|
9983
|
-
if (!
|
|
10016
|
+
const candidate = await hostProjectCandidate(c, hostDirectoryFromMeta(meta2));
|
|
10017
|
+
if (!candidate) {
|
|
9984
10018
|
throw new Error(
|
|
9985
10019
|
"The host supplied no usable local project directory. Use the actual absolute repository from the task context, and ask the user to use Add project in the panel if it is not registered."
|
|
9986
10020
|
);
|
|
9987
10021
|
}
|
|
10022
|
+
const { repository: root, git } = candidate;
|
|
9988
10023
|
const registered = await isApproved(c, root);
|
|
9989
|
-
const auto = !!c.projects && c.settings.values(owner).projects.auto_register_chat;
|
|
10024
|
+
const auto = isGitRoot(candidate) && !!c.projects && c.settings.values(owner).projects.auto_register_chat;
|
|
9990
10025
|
return {
|
|
9991
10026
|
repository: root,
|
|
10027
|
+
...git ? { git } : {},
|
|
9992
10028
|
registered,
|
|
9993
10029
|
auto_register_on_task_start: auto,
|
|
9994
10030
|
// Read-only callers never register; they hand the decision to the user.
|
|
9995
10031
|
...registered ? {} : {
|
|
9996
|
-
next_step: auto ? "Starting a task for this repository from this chat adds it automatically. Otherwise ask the user to use
|
|
10032
|
+
next_step: auto ? "Starting a task for this repository from this chat adds it automatically. Otherwise ask the user to use Allow tasks here in the panel." : "Ask the user to use Allow tasks here in the panel before delegating to this project."
|
|
9997
10033
|
}
|
|
9998
10034
|
};
|
|
9999
10035
|
}
|
|
@@ -10468,7 +10504,10 @@ var settingsSchema = external_exports.strictObject({
|
|
|
10468
10504
|
// enabled provider, and reads replace one that's no longer enabled.
|
|
10469
10505
|
provider: external_exports.string().meta({ title: "Provider" }),
|
|
10470
10506
|
worker_profile: external_exports.enum(roles).meta({ title: "Worker profile" }).default("reviewer"),
|
|
10471
|
-
workspace_strategy: external_exports.enum(["worktree", "current_repo"]).meta({
|
|
10507
|
+
workspace_strategy: external_exports.enum(["worktree", "current_repo"]).meta({
|
|
10508
|
+
title: "Workspace",
|
|
10509
|
+
description: "A project with no Git commit always uses the project folder, because worktrees need a commit."
|
|
10510
|
+
}).default("current_repo"),
|
|
10472
10511
|
// Git checks the whole name when a worktree is created.
|
|
10473
10512
|
worktree_branch_prefix: external_exports.string().max(100).regex(
|
|
10474
10513
|
new RegExp(`^${branchPrefixPattern}$`),
|
|
@@ -10723,7 +10762,7 @@ function settingsSections(input) {
|
|
|
10723
10762
|
kind: "select",
|
|
10724
10763
|
...described("task.workspace_strategy"),
|
|
10725
10764
|
options: options2({
|
|
10726
|
-
current_repo: "
|
|
10765
|
+
current_repo: "Project folder",
|
|
10727
10766
|
worktree: "Isolated worktree"
|
|
10728
10767
|
})
|
|
10729
10768
|
},
|
|
@@ -10910,19 +10949,19 @@ function agentTools({ c, owner, authority, hostMeta }) {
|
|
|
10910
10949
|
get_panel_context: tool({
|
|
10911
10950
|
readOnly: true,
|
|
10912
10951
|
conversation: "panel",
|
|
10913
|
-
description: "Resolve panel defaults for repository, revision and conversation from explicit arguments, host_directory or this conversation's latest task. task_id selects an owned task. null conversation_id means all conversations. Never registers a project or starts work. For a returned panel_project_candidate, ask the user to use
|
|
10952
|
+
description: "Resolve panel defaults for repository, revision and conversation from explicit arguments, host_directory or this conversation's latest task. task_id selects an owned task. null conversation_id means all conversations. Never registers a project or starts work. For a returned panel_project_candidate, ask the user to use Allow tasks here in the panel.",
|
|
10914
10953
|
schema: panelContextInput,
|
|
10915
10954
|
run: (a) => resolvePanelContext(c, owner, a)
|
|
10916
10955
|
}),
|
|
10917
10956
|
list_projects: tool({
|
|
10918
10957
|
readOnly: true,
|
|
10919
|
-
description: "List registered project roots. Pass one to start_task as the explicit absolute repository. Never registers. If the chat's project is missing, ask the user to use Add project in the panel.",
|
|
10958
|
+
description: "List registered project roots. Pass one to start_task as the explicit absolute repository. git is ready, no_commits or none when known, and only ready supports worktrees. Never registers. If the chat's project is missing, ask the user to use Allow tasks here or Add project in the panel.",
|
|
10920
10959
|
schema: external_exports.strictObject({}),
|
|
10921
|
-
run: () => c.projects?.
|
|
10960
|
+
run: () => c.projects?.listWithGit() ?? []
|
|
10922
10961
|
}),
|
|
10923
10962
|
get_current_project: tool({
|
|
10924
10963
|
readOnly: true,
|
|
10925
|
-
description: "Find the current chat's
|
|
10964
|
+
description: "Find the current chat's project from host directory metadata: its Git root, a registered folder containing it, or the directory itself. Reports whether it is registered and its Git state. Never registers. For an unregistered project, follow next_step.",
|
|
10926
10965
|
schema: external_exports.strictObject({}),
|
|
10927
10966
|
run: () => currentChatProject(c, owner, hostMeta)
|
|
10928
10967
|
}),
|
|
@@ -10943,7 +10982,7 @@ function agentTools({ c, owner, authority, hostMeta }) {
|
|
|
10943
10982
|
openWorld: true,
|
|
10944
10983
|
panel: true,
|
|
10945
10984
|
conversation: "chat",
|
|
10946
|
-
description: "Start asynchronous work on the full request in description. The service generates the title. Work runs in the current checkout by default, including uncommitted changes. Reopen existing work with open_subagent_extension_for_codex(task_id), never another start_task.",
|
|
10985
|
+
description: "Start asynchronous work on the full request in description. The service generates the title. Work runs in the current checkout by default, including uncommitted changes. If the result has workspace_fallback, tell the user the task isn't isolated in a worktree and edits apply directly to the project folder. Reopen existing work with open_subagent_extension_for_codex(task_id), never another start_task.",
|
|
10947
10986
|
schema: startSchema.extend({
|
|
10948
10987
|
conversation_id: startSchema.shape.conversation_id.nullable(),
|
|
10949
10988
|
provider: startSchema.shape.provider.unwrap().optional(),
|
|
@@ -11091,7 +11130,7 @@ function agentTools({ c, owner, authority, hostMeta }) {
|
|
|
11091
11130
|
}),
|
|
11092
11131
|
get_changes: tool({
|
|
11093
11132
|
readOnly: true,
|
|
11094
|
-
description: "Read the worker's recorded edits for the whole task or the latest turn as a unified diff with per-file stats. Prefer this to the worker's own account of its changes. Every page lists every file. Pass next_cursor to read more diffs. Incomplete files have no diff, and unrecorded_commands means a command changed files without recorded edits. Inspect those files directly. Commits and worktree removal leave these diffs unchanged. Worktree commits are on task.branch.",
|
|
11133
|
+
description: "Read the worker's recorded edits for the whole task or the latest turn as a unified diff with per-file stats. Prefer this to the worker's own account of its changes. Every page lists every file. Pass next_cursor to read more diffs. Incomplete files have no diff, and unrecorded_commands means a command changed or, in a folder without Git, may have changed files without recorded edits. Inspect those files directly. Commits and worktree removal leave these diffs unchanged. Worktree commits are on task.branch.",
|
|
11095
11134
|
schema: taskId.extend({
|
|
11096
11135
|
scope: external_exports.enum(["task", "turn"]).default("task"),
|
|
11097
11136
|
cursor: external_exports.string().max(300).optional()
|
|
@@ -11561,7 +11600,7 @@ import { execFile } from "node:child_process";
|
|
|
11561
11600
|
import { promisify } from "node:util";
|
|
11562
11601
|
var execute = promisify(execFile);
|
|
11563
11602
|
var script = `try
|
|
11564
|
-
set selectedFolder to choose folder with prompt "Choose a
|
|
11603
|
+
set selectedFolder to choose folder with prompt "Choose a folder to add to Delegated Work"
|
|
11565
11604
|
return POSIX path of selectedFolder
|
|
11566
11605
|
on error number -128
|
|
11567
11606
|
return ""
|
|
@@ -11570,7 +11609,7 @@ var pending = false;
|
|
|
11570
11609
|
async function browseProject(options3 = { platform: process.platform, execute }) {
|
|
11571
11610
|
if (options3.platform !== "darwin") {
|
|
11572
11611
|
throw new Error(
|
|
11573
|
-
"Folder browsing is available on macOS. Enter an absolute
|
|
11612
|
+
"Folder browsing is available on macOS. Enter an absolute folder path instead."
|
|
11574
11613
|
);
|
|
11575
11614
|
}
|
|
11576
11615
|
if (pending) {
|
|
@@ -11597,7 +11636,7 @@ async function browseProject(options3 = { platform: process.platform, execute })
|
|
|
11597
11636
|
function projectTools(c, owner) {
|
|
11598
11637
|
return {
|
|
11599
11638
|
app_register_project: tool({
|
|
11600
|
-
description: "User interface only: approve and persist a
|
|
11639
|
+
description: "User interface only: approve and persist a folder selected by the user, with or without Git. Does not approve its parent or nested repositories.",
|
|
11601
11640
|
schema: external_exports.strictObject({ repository: external_exports.string().min(1).max(4096) }),
|
|
11602
11641
|
run: async (a) => {
|
|
11603
11642
|
if (!c.projects) {
|
|
@@ -11695,127 +11734,9 @@ function queueTools(c, owner) {
|
|
|
11695
11734
|
}
|
|
11696
11735
|
|
|
11697
11736
|
// src/service/features/settings/settings-file.ts
|
|
11698
|
-
import {
|
|
11699
|
-
import { mkdir as mkdir2, writeFile } from "node:fs/promises";
|
|
11700
|
-
import { join as join3 } from "node:path";
|
|
11701
|
-
|
|
11702
|
-
// src/service/features/settings/downloads-directory.ts
|
|
11703
|
-
import { execFile as execFile2 } from "node:child_process";
|
|
11704
|
-
import { readFile as readFile2 } from "node:fs/promises";
|
|
11737
|
+
import { writeFile } from "node:fs/promises";
|
|
11705
11738
|
import { homedir } from "node:os";
|
|
11706
|
-
import {
|
|
11707
|
-
import { promisify as promisify2 } from "node:util";
|
|
11708
|
-
var executeFile = promisify2(execFile2);
|
|
11709
|
-
var windowsDownloads = `
|
|
11710
|
-
$ErrorActionPreference = 'Stop'
|
|
11711
|
-
[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding
|
|
11712
|
-
Add-Type @'
|
|
11713
|
-
using System;
|
|
11714
|
-
using System.Runtime.InteropServices;
|
|
11715
|
-
public static class DownloadsFolder {
|
|
11716
|
-
[DllImport("shell32.dll")]
|
|
11717
|
-
public static extern int SHGetKnownFolderPath(
|
|
11718
|
-
[MarshalAs(UnmanagedType.LPStruct)] Guid id, uint flags,
|
|
11719
|
-
IntPtr token, out IntPtr path);
|
|
11720
|
-
}
|
|
11721
|
-
'@
|
|
11722
|
-
$path = [IntPtr]::Zero
|
|
11723
|
-
try {
|
|
11724
|
-
# KF_FLAG_DONT_VERIFY returns the configured path even before the folder exists.
|
|
11725
|
-
$result = [DownloadsFolder]::SHGetKnownFolderPath(
|
|
11726
|
-
[Guid]'374DE290-123F-4565-9164-39C4925E467B', 0x4000, [IntPtr]::Zero, [ref]$path)
|
|
11727
|
-
[Runtime.InteropServices.Marshal]::ThrowExceptionForHR($result)
|
|
11728
|
-
[Runtime.InteropServices.Marshal]::PtrToStringUni($path)
|
|
11729
|
-
} finally {
|
|
11730
|
-
[Runtime.InteropServices.Marshal]::FreeCoTaskMem($path)
|
|
11731
|
-
}
|
|
11732
|
-
`;
|
|
11733
|
-
async function execute2(command, args) {
|
|
11734
|
-
try {
|
|
11735
|
-
const { stdout } = await executeFile(command, args, {
|
|
11736
|
-
encoding: "utf8",
|
|
11737
|
-
timeout: 1e4,
|
|
11738
|
-
maxBuffer: 16384,
|
|
11739
|
-
windowsHide: true
|
|
11740
|
-
});
|
|
11741
|
-
return stdout;
|
|
11742
|
-
} catch (error) {
|
|
11743
|
-
throw new Error("The system couldn't locate the Downloads folder.", {
|
|
11744
|
-
cause: error
|
|
11745
|
-
});
|
|
11746
|
-
}
|
|
11747
|
-
}
|
|
11748
|
-
function xdgDownloadPath(text, home) {
|
|
11749
|
-
const entry = text.split(/\r?\n/).findLast((line) => /^\s*XDG_DOWNLOAD_DIR\s*=/.test(line));
|
|
11750
|
-
if (entry === void 0) return join2(home, "Downloads");
|
|
11751
|
-
const match = /^\s*XDG_DOWNLOAD_DIR="((?:\\.|[^"\\])*)"\s*(?:#.*)?$/.exec(
|
|
11752
|
-
entry
|
|
11753
|
-
);
|
|
11754
|
-
if (!match) throw new Error("The Downloads folder setting is invalid.");
|
|
11755
|
-
let raw = match[1], path = "";
|
|
11756
|
-
if (raw === "$HOME" || raw.startsWith("$HOME/")) {
|
|
11757
|
-
path = home;
|
|
11758
|
-
raw = raw.slice(5);
|
|
11759
|
-
}
|
|
11760
|
-
for (let index = 0; index < raw.length; index++) {
|
|
11761
|
-
const character = raw[index];
|
|
11762
|
-
if (character === "\\" && /[\\"$`]/.test(raw[index + 1] ?? "")) {
|
|
11763
|
-
path += raw[++index];
|
|
11764
|
-
} else if (character === "$" || character === "`") {
|
|
11765
|
-
throw new Error(
|
|
11766
|
-
"The Downloads folder setting uses an unsupported variable or command."
|
|
11767
|
-
);
|
|
11768
|
-
} else {
|
|
11769
|
-
path += character;
|
|
11770
|
-
}
|
|
11771
|
-
}
|
|
11772
|
-
return path;
|
|
11773
|
-
}
|
|
11774
|
-
async function downloadsDirectory(options3 = {}) {
|
|
11775
|
-
const {
|
|
11776
|
-
platform = process.platform,
|
|
11777
|
-
home = homedir(),
|
|
11778
|
-
env = process.env,
|
|
11779
|
-
execute: run2 = execute2
|
|
11780
|
-
} = options3;
|
|
11781
|
-
let path;
|
|
11782
|
-
if (platform === "darwin") {
|
|
11783
|
-
path = await run2("/usr/bin/osascript", [
|
|
11784
|
-
"-e",
|
|
11785
|
-
"POSIX path of (path to downloads folder)"
|
|
11786
|
-
]);
|
|
11787
|
-
} else if (platform === "win32") {
|
|
11788
|
-
path = await run2(
|
|
11789
|
-
win32.join(
|
|
11790
|
-
env.SystemRoot ?? "C:\\Windows",
|
|
11791
|
-
"System32",
|
|
11792
|
-
"WindowsPowerShell",
|
|
11793
|
-
"v1.0",
|
|
11794
|
-
"powershell.exe"
|
|
11795
|
-
),
|
|
11796
|
-
["-NoProfile", "-NonInteractive", "-Command", windowsDownloads]
|
|
11797
|
-
);
|
|
11798
|
-
} else if (platform === "linux") {
|
|
11799
|
-
const config = env.XDG_CONFIG_HOME && isAbsolute3(env.XDG_CONFIG_HOME) ? env.XDG_CONFIG_HOME : join2(home, ".config");
|
|
11800
|
-
let text = "";
|
|
11801
|
-
try {
|
|
11802
|
-
text = await readFile2(join2(config, "user-dirs.dirs"), "utf8");
|
|
11803
|
-
} catch (error) {
|
|
11804
|
-
if (error.code !== "ENOENT") throw error;
|
|
11805
|
-
}
|
|
11806
|
-
path = xdgDownloadPath(text, home);
|
|
11807
|
-
} else {
|
|
11808
|
-
throw new Error(
|
|
11809
|
-
"Saving settings files is unavailable on this operating system."
|
|
11810
|
-
);
|
|
11811
|
-
}
|
|
11812
|
-
if (platform !== "linux") path = path.replace(/\r?\n$/, "");
|
|
11813
|
-
const absolute = platform === "win32" ? /^(?:[a-z]:[\\/]|[\\/]{2}[^\\/]+[\\/][^\\/]+)/i.test(path) : isAbsolute3(path);
|
|
11814
|
-
if (!absolute) {
|
|
11815
|
-
throw new Error("Downloads must be an absolute folder path.");
|
|
11816
|
-
}
|
|
11817
|
-
return path;
|
|
11818
|
-
}
|
|
11739
|
+
import { join as join2 } from "node:path";
|
|
11819
11740
|
|
|
11820
11741
|
// src/service/features/settings/settings-transfer.ts
|
|
11821
11742
|
var SETTINGS_FORMAT = 2;
|
|
@@ -11883,15 +11804,10 @@ function importSettings(settings, owner, input) {
|
|
|
11883
11804
|
|
|
11884
11805
|
// src/service/features/settings/settings-file.ts
|
|
11885
11806
|
var settingsFileOutputSchema = external_exports.object({ path: external_exports.string() });
|
|
11886
|
-
async function saveSettingsFile(settings, owner
|
|
11807
|
+
async function saveSettingsFile(settings, owner) {
|
|
11887
11808
|
const { document: document2 } = exportSettings(settings, owner);
|
|
11888
|
-
const
|
|
11889
|
-
|
|
11890
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
11891
|
-
const path = join3(
|
|
11892
|
-
folder,
|
|
11893
|
-
`delegated-work-settings-${timestamp}-${randomUUID()}.json`
|
|
11894
|
-
);
|
|
11809
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 19).replace(/:/g, "-");
|
|
11810
|
+
const path = join2(homedir(), `delegated-work-settings-${timestamp}Z.json`);
|
|
11895
11811
|
await writeFile(path, `${document2}
|
|
11896
11812
|
`, {
|
|
11897
11813
|
encoding: "utf8",
|
|
@@ -11918,7 +11834,7 @@ function settingsTransferTools(settings, owner) {
|
|
|
11918
11834
|
run: (a) => importSettings(settings, owner, a)
|
|
11919
11835
|
}),
|
|
11920
11836
|
app_save_settings_file: tool({
|
|
11921
|
-
description: "User interface only: save the user's defaults as a new JSON file in
|
|
11837
|
+
description: "User interface only: save the user's defaults as a new JSON file in the home folder on the service computer and return its path.",
|
|
11922
11838
|
schema: external_exports.strictObject({}),
|
|
11923
11839
|
outputSchema: settingsFileOutputSchema,
|
|
11924
11840
|
run: () => saveSettingsFile(settings, owner)
|
|
@@ -12189,7 +12105,7 @@ async function callTool(c, owner, name, args, authority = "parent", hostMeta) {
|
|
|
12189
12105
|
// src/service/platform/service/process-info.ts
|
|
12190
12106
|
import { execFileSync } from "node:child_process";
|
|
12191
12107
|
import { readFileSync as readFileSync2, readlinkSync } from "node:fs";
|
|
12192
|
-
import { basename, dirname, join as
|
|
12108
|
+
import { basename, dirname, join as join3 } from "node:path";
|
|
12193
12109
|
function inspectProcess(pid) {
|
|
12194
12110
|
try {
|
|
12195
12111
|
if (process.platform === "linux") return inspectLinuxProcess(pid);
|
|
@@ -12219,13 +12135,13 @@ function inspectProcessIdentity(pid) {
|
|
|
12219
12135
|
return void 0;
|
|
12220
12136
|
}
|
|
12221
12137
|
function isProcessRunning(pid) {
|
|
12222
|
-
let
|
|
12138
|
+
let permissionDenied2 = false;
|
|
12223
12139
|
try {
|
|
12224
12140
|
process.kill(pid, 0);
|
|
12225
12141
|
} catch (error) {
|
|
12226
12142
|
const code = error.code;
|
|
12227
12143
|
if (code === "ESRCH") return false;
|
|
12228
|
-
if (code === "EPERM")
|
|
12144
|
+
if (code === "EPERM") permissionDenied2 = true;
|
|
12229
12145
|
else return true;
|
|
12230
12146
|
}
|
|
12231
12147
|
if (process.platform === "linux") {
|
|
@@ -12234,7 +12150,7 @@ function isProcessRunning(pid) {
|
|
|
12234
12150
|
return state !== "Z" && state !== "X";
|
|
12235
12151
|
} catch (error) {
|
|
12236
12152
|
if (error.code === "ENOENT") {
|
|
12237
|
-
return
|
|
12153
|
+
return permissionDenied2;
|
|
12238
12154
|
}
|
|
12239
12155
|
}
|
|
12240
12156
|
}
|
|
@@ -12250,7 +12166,7 @@ function isExtensionService(owner, lockFile) {
|
|
|
12250
12166
|
let metadata;
|
|
12251
12167
|
try {
|
|
12252
12168
|
metadata = JSON.parse(
|
|
12253
|
-
readFileSync2(
|
|
12169
|
+
readFileSync2(join3(dirname(lockFile), "service.json"), "utf8")
|
|
12254
12170
|
);
|
|
12255
12171
|
} catch {
|
|
12256
12172
|
return false;
|
|
@@ -12777,4 +12693,4 @@ export {
|
|
|
12777
12693
|
toolStructuredContent,
|
|
12778
12694
|
callTool
|
|
12779
12695
|
};
|
|
12780
|
-
//# sourceMappingURL=chunk-
|
|
12696
|
+
//# sourceMappingURL=chunk-DGCGXY3T.js.map
|