toc-ocra 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/LICENSE +21 -0
- package/README.md +70 -0
- package/assets/icon.svg +1 -0
- package/dist/plugin/renderer.css +2 -0
- package/dist/plugin/renderer.css.map +7 -0
- package/dist/plugin/renderer.js +2 -0
- package/dist/plugin/renderer.js.map +7 -0
- package/dist/src/config.d.ts +66 -0
- package/dist/src/config.js +173 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/control/pairing.d.ts +44 -0
- package/dist/src/control/pairing.js +99 -0
- package/dist/src/control/pairing.js.map +1 -0
- package/dist/src/exec/script-runner.d.ts +9 -0
- package/dist/src/exec/script-runner.js +110 -0
- package/dist/src/exec/script-runner.js.map +1 -0
- package/dist/src/health/server.d.ts +74 -0
- package/dist/src/health/server.js +248 -0
- package/dist/src/health/server.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +173 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/logging/diagnostic-log.d.ts +16 -0
- package/dist/src/logging/diagnostic-log.js +128 -0
- package/dist/src/logging/diagnostic-log.js.map +1 -0
- package/dist/src/providers/cli/claude.d.ts +2 -0
- package/dist/src/providers/cli/claude.js +48 -0
- package/dist/src/providers/cli/claude.js.map +1 -0
- package/dist/src/providers/cli/codex.d.ts +2 -0
- package/dist/src/providers/cli/codex.js +67 -0
- package/dist/src/providers/cli/codex.js.map +1 -0
- package/dist/src/providers/cli/gemini.d.ts +2 -0
- package/dist/src/providers/cli/gemini.js +30 -0
- package/dist/src/providers/cli/gemini.js.map +1 -0
- package/dist/src/providers/cli/grok.d.ts +2 -0
- package/dist/src/providers/cli/grok.js +29 -0
- package/dist/src/providers/cli/grok.js.map +1 -0
- package/dist/src/providers/cli/opencode.d.ts +2 -0
- package/dist/src/providers/cli/opencode.js +29 -0
- package/dist/src/providers/cli/opencode.js.map +1 -0
- package/dist/src/providers/detection.d.ts +11 -0
- package/dist/src/providers/detection.js +96 -0
- package/dist/src/providers/detection.js.map +1 -0
- package/dist/src/providers/model-catalog-collector.d.ts +22 -0
- package/dist/src/providers/model-catalog-collector.js +66 -0
- package/dist/src/providers/model-catalog-collector.js.map +1 -0
- package/dist/src/providers/model-catalog.d.ts +45 -0
- package/dist/src/providers/model-catalog.js +382 -0
- package/dist/src/providers/model-catalog.js.map +1 -0
- package/dist/src/providers/provider.d.ts +49 -0
- package/dist/src/providers/provider.js +63 -0
- package/dist/src/providers/provider.js.map +1 -0
- package/dist/src/providers/registry.d.ts +31 -0
- package/dist/src/providers/registry.js +60 -0
- package/dist/src/providers/registry.js.map +1 -0
- package/dist/src/runs/orphan-registry.d.ts +24 -0
- package/dist/src/runs/orphan-registry.js +63 -0
- package/dist/src/runs/orphan-registry.js.map +1 -0
- package/dist/src/runs/process-tree.d.ts +21 -0
- package/dist/src/runs/process-tree.js +95 -0
- package/dist/src/runs/process-tree.js.map +1 -0
- package/dist/src/runs/run-supervisor.d.ts +63 -0
- package/dist/src/runs/run-supervisor.js +285 -0
- package/dist/src/runs/run-supervisor.js.map +1 -0
- package/dist/src/runtime/agent-runtime.d.ts +68 -0
- package/dist/src/runtime/agent-runtime.js +340 -0
- package/dist/src/runtime/agent-runtime.js.map +1 -0
- package/dist/src/runtime/agent-service.d.ts +33 -0
- package/dist/src/runtime/agent-service.js +181 -0
- package/dist/src/runtime/agent-service.js.map +1 -0
- package/dist/src/runtime/cli/hydrate-shell-path.d.ts +33 -0
- package/dist/src/runtime/cli/hydrate-shell-path.js +173 -0
- package/dist/src/runtime/cli/hydrate-shell-path.js.map +1 -0
- package/dist/src/session/terminal-line-sanitizer.d.ts +7 -0
- package/dist/src/session/terminal-line-sanitizer.js +21 -0
- package/dist/src/session/terminal-line-sanitizer.js.map +1 -0
- package/dist/src/session/terminal-tail-buffer.d.ts +70 -0
- package/dist/src/session/terminal-tail-buffer.js +149 -0
- package/dist/src/session/terminal-tail-buffer.js.map +1 -0
- package/dist/src/shared/cli-detection-types.d.ts +19 -0
- package/dist/src/shared/cli-detection-types.js +2 -0
- package/dist/src/shared/cli-detection-types.js.map +1 -0
- package/dist/src/shared/node-cli-command-resolution.d.ts +19 -0
- package/dist/src/shared/node-cli-command-resolution.js +173 -0
- package/dist/src/shared/node-cli-command-resolution.js.map +1 -0
- package/dist/src/transport/gateway-client.d.ts +38 -0
- package/dist/src/transport/gateway-client.js +73 -0
- package/dist/src/transport/gateway-client.js.map +1 -0
- package/dist/src/types/protocol.d.ts +172 -0
- package/dist/src/types/protocol.js +55 -0
- package/dist/src/types/protocol.js.map +1 -0
- package/dist/src/workspace/directory-browser.d.ts +17 -0
- package/dist/src/workspace/directory-browser.js +47 -0
- package/dist/src/workspace/directory-browser.js.map +1 -0
- package/dist/src/workspace/workspace-manager.d.ts +41 -0
- package/dist/src/workspace/workspace-manager.js +436 -0
- package/dist/src/workspace/workspace-manager.js.map +1 -0
- package/locales/en.json +66 -0
- package/locales/zh-CN.json +66 -0
- package/package.json +90 -0
- package/scripts/service.mjs +174 -0
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { chmod, mkdir, mkdtemp, opendir, realpath, rm, stat, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { homedir, tmpdir } from 'node:os';
|
|
4
|
+
import { isAbsolute, join, relative, resolve } from 'node:path';
|
|
5
|
+
import { addAllowedRoot } from '../config.js';
|
|
6
|
+
const MAX_NODES = 2_000;
|
|
7
|
+
const MAX_DIRECTORY_ENTRIES = 12_000;
|
|
8
|
+
const IGNORED_DIRECTORIES = new Set([
|
|
9
|
+
'.git',
|
|
10
|
+
'node_modules',
|
|
11
|
+
'.next',
|
|
12
|
+
'.nuxt',
|
|
13
|
+
'.cache',
|
|
14
|
+
'dist',
|
|
15
|
+
'build',
|
|
16
|
+
'coverage',
|
|
17
|
+
'target',
|
|
18
|
+
'vendor'
|
|
19
|
+
]);
|
|
20
|
+
export class WorkspaceManager {
|
|
21
|
+
config;
|
|
22
|
+
logger;
|
|
23
|
+
constructor(config, logger) {
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.logger = logger;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Reads folders and Git repositories below the root. The root becomes an
|
|
29
|
+
* allowed CLI work directory: the user chose it for this device.
|
|
30
|
+
*/
|
|
31
|
+
async scan(request) {
|
|
32
|
+
const startedAt = Date.now();
|
|
33
|
+
const rootPath = this.validateRootPath(request.root_path);
|
|
34
|
+
await addAllowedRoot(this.config, rootPath);
|
|
35
|
+
const nodes = await this.scanTree(rootPath, request.max_depth, request.scan_roots);
|
|
36
|
+
return { root_path: rootPath, nodes, truncated: nodes.length >= MAX_NODES, duration_ms: Date.now() - startedAt };
|
|
37
|
+
}
|
|
38
|
+
/** Creates missing folders, clones missing repos, fast-forwards clean ones. */
|
|
39
|
+
async sync(request) {
|
|
40
|
+
const startedAt = Date.now();
|
|
41
|
+
const rootPath = this.validateRootPath(request.root_path);
|
|
42
|
+
const results = await this.syncTree(rootPath, request);
|
|
43
|
+
const failed = results.some((result) => result.status === 'failed');
|
|
44
|
+
return {
|
|
45
|
+
root_path: rootPath,
|
|
46
|
+
results,
|
|
47
|
+
...(failed ? { error: '部分目录或仓库同步失败' } : {}),
|
|
48
|
+
duration_ms: Date.now() - startedAt
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
validateRootPath(value) {
|
|
52
|
+
const raw = value.trim().replace(/^~(?=$|[\\/])/, homedir());
|
|
53
|
+
const root = resolve(raw);
|
|
54
|
+
if (!isAbsolute(raw))
|
|
55
|
+
throw new Error('根目录必须是绝对路径');
|
|
56
|
+
if (relative(root, resolve(root, '..')) === '')
|
|
57
|
+
throw new Error('不能把文件系统根目录作为目录根');
|
|
58
|
+
return root;
|
|
59
|
+
}
|
|
60
|
+
async syncTree(rootPath, request) {
|
|
61
|
+
await mkdir(rootPath, { recursive: true });
|
|
62
|
+
await addAllowedRoot(this.config, rootPath);
|
|
63
|
+
const results = [];
|
|
64
|
+
const requestedPaths = new Set();
|
|
65
|
+
for (const directory of request.directories) {
|
|
66
|
+
const relativePath = this.cleanRelativePath(directory);
|
|
67
|
+
if (requestedPaths.has(relativePath))
|
|
68
|
+
continue;
|
|
69
|
+
requestedPaths.add(relativePath);
|
|
70
|
+
const target = this.resolveWithinRoot(rootPath, relativePath);
|
|
71
|
+
try {
|
|
72
|
+
const metadata = await stat(target).catch(() => undefined);
|
|
73
|
+
if (metadata) {
|
|
74
|
+
if (!metadata.isDirectory()) {
|
|
75
|
+
throw new Error('The existing workspace path is not a directory');
|
|
76
|
+
}
|
|
77
|
+
results.push({
|
|
78
|
+
relative_path: relativePath,
|
|
79
|
+
status: 'skipped',
|
|
80
|
+
kind: 'directory',
|
|
81
|
+
action: 'skip',
|
|
82
|
+
message: '目录已存在'
|
|
83
|
+
});
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
await mkdir(target, { recursive: true });
|
|
87
|
+
results.push({
|
|
88
|
+
relative_path: relativePath,
|
|
89
|
+
status: 'created',
|
|
90
|
+
kind: 'directory',
|
|
91
|
+
action: 'mkdir',
|
|
92
|
+
message: '目录已创建'
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
results.push({
|
|
97
|
+
relative_path: relativePath,
|
|
98
|
+
status: 'failed',
|
|
99
|
+
kind: 'directory',
|
|
100
|
+
action: 'mkdir',
|
|
101
|
+
error: this.message(error)
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const authEnvironment = await this.createGitAuthEnvironment(request.git_auth);
|
|
106
|
+
try {
|
|
107
|
+
for (const repo of request.repos) {
|
|
108
|
+
const relativePath = this.cleanRelativePath(repo.relative_path);
|
|
109
|
+
try {
|
|
110
|
+
results.push(await this.syncRepository(rootPath, relativePath, repo.git_url?.trim() || undefined, repo.branch?.trim() || undefined, request.timeout_s, authEnvironment?.env));
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
results.push({
|
|
114
|
+
relative_path: relativePath,
|
|
115
|
+
status: 'failed',
|
|
116
|
+
kind: 'repo',
|
|
117
|
+
action: 'sync',
|
|
118
|
+
error: this.message(error)
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
await authEnvironment?.cleanup();
|
|
125
|
+
}
|
|
126
|
+
return results;
|
|
127
|
+
}
|
|
128
|
+
async syncRepository(rootPath, relativePath, gitUrl, branch, timeoutSeconds, gitEnvironment) {
|
|
129
|
+
const target = this.resolveWithinRoot(rootPath, relativePath);
|
|
130
|
+
let created = false;
|
|
131
|
+
let metadata;
|
|
132
|
+
try {
|
|
133
|
+
metadata = await stat(target);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// A missing target is the normal clone case.
|
|
137
|
+
}
|
|
138
|
+
if (!metadata) {
|
|
139
|
+
if (!gitUrl)
|
|
140
|
+
throw new Error('A missing repository needs a Git remote URL');
|
|
141
|
+
await mkdir(resolve(target, '..'), { recursive: true });
|
|
142
|
+
const cloneArgs = branch
|
|
143
|
+
? ['clone', '--branch', branch, '--single-branch', gitUrl, target]
|
|
144
|
+
: ['clone', gitUrl, target];
|
|
145
|
+
await this.runGit(cloneArgs, rootPath, timeoutSeconds, false, gitEnvironment);
|
|
146
|
+
created = true;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
if (!metadata.isDirectory())
|
|
150
|
+
throw new Error('The repository path is not a directory');
|
|
151
|
+
if (!(await this.isGitRepository(target, timeoutSeconds))) {
|
|
152
|
+
throw new Error('The existing directory is not a Git repository');
|
|
153
|
+
}
|
|
154
|
+
if (gitUrl) {
|
|
155
|
+
const currentOrigin = (await this.runGit(['config', '--get', 'remote.origin.url'], target, timeoutSeconds, true)).stdout.trim();
|
|
156
|
+
if (currentOrigin && currentOrigin !== gitUrl) {
|
|
157
|
+
throw new Error('The existing repository origin does not match the configured Git URL');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const worktree = await this.runGit(['status', '--porcelain'], target, timeoutSeconds);
|
|
161
|
+
if (worktree.stdout.trim()) {
|
|
162
|
+
return {
|
|
163
|
+
relative_path: relativePath,
|
|
164
|
+
status: 'skipped',
|
|
165
|
+
kind: 'repo',
|
|
166
|
+
action: 'skip',
|
|
167
|
+
message: '仓库存在未提交的本地修改'
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (branch) {
|
|
171
|
+
const currentBranch = await this.runGit(['branch', '--show-current'], target, timeoutSeconds);
|
|
172
|
+
if (currentBranch.stdout.trim() !== branch) {
|
|
173
|
+
return {
|
|
174
|
+
relative_path: relativePath,
|
|
175
|
+
status: 'skipped',
|
|
176
|
+
kind: 'repo',
|
|
177
|
+
action: 'skip',
|
|
178
|
+
message: `当前分支 ${currentBranch.stdout.trim() || '(detached)'} 与目标分支 ${branch} 不一致`
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
await this.runGit(['fetch', '--prune', 'origin'], target, timeoutSeconds, false, gitEnvironment);
|
|
184
|
+
if (branch) {
|
|
185
|
+
const remoteBranch = await this.runGit(['show-ref', '--verify', '--quiet', `refs/remotes/origin/${branch}`], target, timeoutSeconds, true);
|
|
186
|
+
if (remoteBranch.exitCode !== 0) {
|
|
187
|
+
return {
|
|
188
|
+
relative_path: relativePath,
|
|
189
|
+
status: 'skipped',
|
|
190
|
+
kind: 'repo',
|
|
191
|
+
action: 'skip',
|
|
192
|
+
message: `远端分支 origin/${branch} 不存在`
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if (!created) {
|
|
196
|
+
const currentCommit = await this.runGit(['rev-parse', 'HEAD'], target, timeoutSeconds);
|
|
197
|
+
const remoteCommit = await this.runGit(['rev-parse', `origin/${branch}`], target, timeoutSeconds);
|
|
198
|
+
if (currentCommit.stdout.trim() === remoteCommit.stdout.trim()) {
|
|
199
|
+
return {
|
|
200
|
+
relative_path: relativePath,
|
|
201
|
+
status: 'skipped',
|
|
202
|
+
kind: 'repo',
|
|
203
|
+
action: 'skip',
|
|
204
|
+
message: '仓库已是最新'
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
const fastForward = await this.runGit(['merge-base', '--is-ancestor', 'HEAD', `origin/${branch}`], target, timeoutSeconds, true);
|
|
208
|
+
if (fastForward.exitCode !== 0) {
|
|
209
|
+
return {
|
|
210
|
+
relative_path: relativePath,
|
|
211
|
+
status: 'skipped',
|
|
212
|
+
kind: 'repo',
|
|
213
|
+
action: 'skip',
|
|
214
|
+
message: '本地提交无法快进到远端分支'
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
await this.runGit(['pull', '--ff-only', 'origin', branch], target, timeoutSeconds, false, gitEnvironment);
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
relative_path: relativePath,
|
|
222
|
+
status: created ? 'created' : 'updated',
|
|
223
|
+
kind: 'repo',
|
|
224
|
+
action: created ? 'clone' : 'pull',
|
|
225
|
+
message: created ? '仓库已克隆' : '仓库已快进更新'
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
async scanTree(rootPath, maxDepth, scanRoots) {
|
|
229
|
+
const resolvedRoot = await realpath(rootPath);
|
|
230
|
+
const rootMetadata = await stat(resolvedRoot);
|
|
231
|
+
if (!rootMetadata.isDirectory())
|
|
232
|
+
throw new Error('The workspace root is not a directory');
|
|
233
|
+
const nodes = [];
|
|
234
|
+
let entriesRead = 0;
|
|
235
|
+
const appendNode = async (target) => {
|
|
236
|
+
const relativePath = relative(resolvedRoot, target).replaceAll('\\', '/');
|
|
237
|
+
if (!relativePath || !this.isSafeRelativePath(relativePath))
|
|
238
|
+
return undefined;
|
|
239
|
+
const git = await this.readGitMetadata(target);
|
|
240
|
+
if (git) {
|
|
241
|
+
nodes.push({
|
|
242
|
+
relative_path: relativePath,
|
|
243
|
+
node_type: 'repo',
|
|
244
|
+
git_url: git.gitUrl,
|
|
245
|
+
branch: git.branch,
|
|
246
|
+
commit_hash: git.commitHash
|
|
247
|
+
});
|
|
248
|
+
return 'repo';
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
nodes.push({ relative_path: relativePath, node_type: 'folder' });
|
|
252
|
+
return 'folder';
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
const visit = async (directory, remainingDepth) => {
|
|
256
|
+
if (nodes.length >= MAX_NODES || entriesRead >= MAX_DIRECTORY_ENTRIES)
|
|
257
|
+
return;
|
|
258
|
+
let entries;
|
|
259
|
+
try {
|
|
260
|
+
entries = await opendir(directory);
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
this.logger.warn('workspace-scan-directory-failed', { directory, error: this.message(error) });
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
for await (const entry of entries) {
|
|
267
|
+
if (nodes.length >= MAX_NODES || entriesRead++ >= MAX_DIRECTORY_ENTRIES)
|
|
268
|
+
return;
|
|
269
|
+
if (!entry.isDirectory() || IGNORED_DIRECTORIES.has(entry.name))
|
|
270
|
+
continue;
|
|
271
|
+
const target = resolve(directory, entry.name);
|
|
272
|
+
const nodeType = await appendNode(target);
|
|
273
|
+
if (!nodeType || nodeType === 'repo')
|
|
274
|
+
continue;
|
|
275
|
+
if (remainingDepth === undefined || remainingDepth > 1) {
|
|
276
|
+
await visit(target, remainingDepth === undefined ? undefined : remainingDepth - 1);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
if (!scanRoots?.length) {
|
|
281
|
+
await visit(resolvedRoot, maxDepth);
|
|
282
|
+
return nodes;
|
|
283
|
+
}
|
|
284
|
+
const requestedPaths = new Set();
|
|
285
|
+
for (const item of scanRoots) {
|
|
286
|
+
if (nodes.length >= MAX_NODES || entriesRead >= MAX_DIRECTORY_ENTRIES)
|
|
287
|
+
break;
|
|
288
|
+
const relativePath = this.cleanRelativePath(item.relative_path);
|
|
289
|
+
if (requestedPaths.has(relativePath))
|
|
290
|
+
continue;
|
|
291
|
+
requestedPaths.add(relativePath);
|
|
292
|
+
const target = this.resolveWithinRoot(resolvedRoot, relativePath);
|
|
293
|
+
let metadata;
|
|
294
|
+
try {
|
|
295
|
+
metadata = await stat(target);
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
this.logger.warn('workspace-scan-root-missing', {
|
|
299
|
+
rootPath: target,
|
|
300
|
+
error: this.message(error)
|
|
301
|
+
});
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (!metadata.isDirectory())
|
|
305
|
+
continue;
|
|
306
|
+
const nodeType = await appendNode(target);
|
|
307
|
+
if (!nodeType || nodeType === 'repo')
|
|
308
|
+
continue;
|
|
309
|
+
await visit(target, item.max_depth);
|
|
310
|
+
}
|
|
311
|
+
return nodes;
|
|
312
|
+
}
|
|
313
|
+
async readGitMetadata(directory) {
|
|
314
|
+
if (!(await this.isGitRepository(directory)))
|
|
315
|
+
return undefined;
|
|
316
|
+
const [origin, branch, commit] = await Promise.all([
|
|
317
|
+
this.runGit(['config', '--get', 'remote.origin.url'], directory, undefined, true),
|
|
318
|
+
this.runGit(['rev-parse', '--abbrev-ref', 'HEAD'], directory, undefined, true),
|
|
319
|
+
this.runGit(['rev-parse', 'HEAD'], directory, undefined, true)
|
|
320
|
+
]);
|
|
321
|
+
return {
|
|
322
|
+
gitUrl: origin.exitCode === 0 ? origin.stdout.trim() || null : null,
|
|
323
|
+
branch: branch.exitCode === 0 ? branch.stdout.trim() || null : null,
|
|
324
|
+
commitHash: commit.exitCode === 0 ? commit.stdout.trim() || null : null
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
async isGitRepository(directory, timeoutSeconds) {
|
|
328
|
+
const result = await this.runGit(['rev-parse', '--show-toplevel'], directory, timeoutSeconds, true);
|
|
329
|
+
const topLevel = result.stdout.trim();
|
|
330
|
+
if (result.exitCode !== 0 || !topLevel)
|
|
331
|
+
return false;
|
|
332
|
+
try {
|
|
333
|
+
const [resolvedDirectory, resolvedTopLevel] = await Promise.all([
|
|
334
|
+
realpath(directory),
|
|
335
|
+
realpath(topLevel)
|
|
336
|
+
]);
|
|
337
|
+
return resolvedDirectory === resolvedTopLevel;
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
cleanRelativePath(value) {
|
|
344
|
+
const normalized = value.trim().replaceAll('\\', '/').replace(/^\/+|\/+$/g, '');
|
|
345
|
+
if (!normalized || !this.isSafeRelativePath(normalized)) {
|
|
346
|
+
throw new Error('A workspace path must remain under the configured workspace root');
|
|
347
|
+
}
|
|
348
|
+
return normalized;
|
|
349
|
+
}
|
|
350
|
+
isSafeRelativePath(value) {
|
|
351
|
+
const parts = value.split('/');
|
|
352
|
+
return !value.startsWith('/') && !parts.some((part) => !part || part === '.' || part === '..' || part.includes(':'));
|
|
353
|
+
}
|
|
354
|
+
resolveWithinRoot(rootPath, relativePath) {
|
|
355
|
+
const target = resolve(rootPath, relativePath);
|
|
356
|
+
const relativeToRoot = relative(rootPath, target);
|
|
357
|
+
if (relativeToRoot.startsWith('..') || isAbsolute(relativeToRoot)) {
|
|
358
|
+
throw new Error('A workspace path must remain under the configured workspace root');
|
|
359
|
+
}
|
|
360
|
+
return target;
|
|
361
|
+
}
|
|
362
|
+
runGit(args, cwd, timeoutSeconds, allowFailure = false, environment) {
|
|
363
|
+
return new Promise((resolveCommand, rejectCommand) => {
|
|
364
|
+
const child = spawn('git', args, {
|
|
365
|
+
cwd,
|
|
366
|
+
env: environment ?? process.env,
|
|
367
|
+
shell: false,
|
|
368
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
369
|
+
});
|
|
370
|
+
const stdout = [];
|
|
371
|
+
const stderr = [];
|
|
372
|
+
const timeout = setTimeout(() => {
|
|
373
|
+
child.kill('SIGKILL');
|
|
374
|
+
}, Math.max(10, timeoutSeconds ?? 120) * 1_000);
|
|
375
|
+
child.stdout.on('data', (chunk) => stdout.push(Buffer.from(chunk)));
|
|
376
|
+
child.stderr.on('data', (chunk) => stderr.push(Buffer.from(chunk)));
|
|
377
|
+
child.once('error', (error) => {
|
|
378
|
+
clearTimeout(timeout);
|
|
379
|
+
rejectCommand(error);
|
|
380
|
+
});
|
|
381
|
+
child.once('close', (exitCode) => {
|
|
382
|
+
clearTimeout(timeout);
|
|
383
|
+
const result = {
|
|
384
|
+
exitCode: exitCode ?? -1,
|
|
385
|
+
stdout: Buffer.concat(stdout).toString('utf8'),
|
|
386
|
+
stderr: Buffer.concat(stderr).toString('utf8')
|
|
387
|
+
};
|
|
388
|
+
if (result.exitCode !== 0 && !allowFailure) {
|
|
389
|
+
rejectCommand(new Error(gitErrorSummary(result.stderr) || `git ${args[0] ?? 'command'} 失败`));
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
resolveCommand(result);
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
async createGitAuthEnvironment(auth) {
|
|
397
|
+
if (!auth)
|
|
398
|
+
return undefined;
|
|
399
|
+
const directory = await mkdtemp(join(tmpdir(), 'toc-ocra-git-auth-'));
|
|
400
|
+
const isWindows = process.platform === 'win32';
|
|
401
|
+
const scriptPath = join(directory, isWindows ? 'askpass.cmd' : 'askpass.sh');
|
|
402
|
+
let script;
|
|
403
|
+
if (isWindows) {
|
|
404
|
+
const helperPath = join(directory, 'askpass.cjs');
|
|
405
|
+
await writeFile(helperPath, 'const prompt = process.argv.slice(2).join(" ");\nprocess.stdout.write(/username/i.test(prompt) ? process.env.ECHO_GIT_USERNAME ?? "" : process.env.ECHO_GIT_PASSWORD ?? "");\n', { mode: 0o700 });
|
|
406
|
+
script = '@echo off\r\n"%ECHO_NODE_PATH%" "%~dp0askpass.cjs" "%~1"\r\n';
|
|
407
|
+
}
|
|
408
|
+
else {
|
|
409
|
+
script = '#!/bin/sh\ncase "$1" in *Username*|*username*) printf "%s\\n" "$ECHO_GIT_USERNAME" ;; *) printf "%s\\n" "$ECHO_GIT_PASSWORD" ;; esac\n';
|
|
410
|
+
}
|
|
411
|
+
await writeFile(scriptPath, script, { mode: 0o700 });
|
|
412
|
+
if (!isWindows)
|
|
413
|
+
await chmod(scriptPath, 0o700);
|
|
414
|
+
return {
|
|
415
|
+
env: {
|
|
416
|
+
...process.env,
|
|
417
|
+
GIT_ASKPASS: scriptPath,
|
|
418
|
+
GIT_TERMINAL_PROMPT: '0',
|
|
419
|
+
ECHO_NODE_PATH: process.execPath,
|
|
420
|
+
ECHO_GIT_USERNAME: auth.username,
|
|
421
|
+
ECHO_GIT_PASSWORD: auth.password
|
|
422
|
+
},
|
|
423
|
+
cleanup: () => rm(directory, { recursive: true, force: true })
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
message(error) {
|
|
427
|
+
return error instanceof Error ? error.message : String(error);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
/** Keeps the lines that explain a git failure, dropping progress noise. */
|
|
431
|
+
export function gitErrorSummary(stderr) {
|
|
432
|
+
const lines = stderr.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
433
|
+
const useful = lines.filter((line) => /^(fatal|error|remote):/i.test(line));
|
|
434
|
+
return (useful.length ? useful : lines.filter((line) => !/^Cloning into/i.test(line))).slice(-3).join(' ');
|
|
435
|
+
}
|
|
436
|
+
//# sourceMappingURL=workspace-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-manager.js","sourceRoot":"","sources":["../../../src/workspace/workspace-manager.ts"],"names":[],"mappings":"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"}
|
package/locales/en.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"nav": { "title": "Device agent" },
|
|
3
|
+
"page": {
|
|
4
|
+
"title": "Device agent",
|
|
5
|
+
"subtitle": "Let this computer take tasks from task chains and run CLIs such as Codex and Claude locally."
|
|
6
|
+
},
|
|
7
|
+
"common": { "copy": "Copy", "copied": "Copied", "checking": "Checking the local service…" },
|
|
8
|
+
"error": { "offline": "Can't reach the local service. Make sure toc-ocra is running." },
|
|
9
|
+
"health": {
|
|
10
|
+
"online": "Online: {{name}}",
|
|
11
|
+
"disconnected": "Bound, but the server is not reachable right now",
|
|
12
|
+
"unpaired": "Local service running, not bound to a server yet",
|
|
13
|
+
"offline": "Local service not running"
|
|
14
|
+
},
|
|
15
|
+
"offline": {
|
|
16
|
+
"title": "Local service not running",
|
|
17
|
+
"body": "The plugin talks to the local toc-ocra service at {{url}}. Start it in a terminal; the plugin never launches programs for you.",
|
|
18
|
+
"once": "Run once (stops when the terminal closes)",
|
|
19
|
+
"service": "For everyday use: install it as a background service that starts at login",
|
|
20
|
+
"node": "Requires Node.js 20 or newer. This page refreshes on its own once the service is up."
|
|
21
|
+
},
|
|
22
|
+
"pair": {
|
|
23
|
+
"title": "Connect to the local service",
|
|
24
|
+
"body": "The local service shows a 6-digit connection code when it starts. You can also print it with this command.",
|
|
25
|
+
"placeholder": "6-digit code",
|
|
26
|
+
"submit": "Connect",
|
|
27
|
+
"wrong": "Wrong code. Check it again (a code changes after it is used).",
|
|
28
|
+
"locked": "Too many wrong codes. Try again with the new code in 30 seconds."
|
|
29
|
+
},
|
|
30
|
+
"status": {
|
|
31
|
+
"title": "This computer",
|
|
32
|
+
"service": "Local service",
|
|
33
|
+
"binding": "Binding",
|
|
34
|
+
"device": "Device",
|
|
35
|
+
"server": "Server",
|
|
36
|
+
"runs": "Running tasks",
|
|
37
|
+
"lastError": "Last error: {{error}}",
|
|
38
|
+
"tokenFromEnv": "The device token comes from the TOC_OCRA_TOKEN environment variable, so binding can't be changed here.",
|
|
39
|
+
"unpair": "Unbind"
|
|
40
|
+
},
|
|
41
|
+
"binding": { "unpaired": "Not bound", "revoked": "Credentials revoked", "online": "Online", "connecting": "Connecting" },
|
|
42
|
+
"bind": {
|
|
43
|
+
"title": "Bind to the current server",
|
|
44
|
+
"rebindTitle": "Bind again",
|
|
45
|
+
"revoked": "The server no longer accepts this computer's credentials (it may have been unpaired on the Devices page). Bind it again.",
|
|
46
|
+
"elsewhere": "This computer is bound to {{bound}}, but you are using {{current}}. Binding again switches it to the current server.",
|
|
47
|
+
"body": "Once bound, tasks sent to this device in \"{{workspace}}\" run on this computer (server: {{server}}).",
|
|
48
|
+
"server": "Server address",
|
|
49
|
+
"device": "Device",
|
|
50
|
+
"newDevice": "Create a new device",
|
|
51
|
+
"replaces": "replaces its current binding",
|
|
52
|
+
"name": "Device name",
|
|
53
|
+
"submit": "Bind",
|
|
54
|
+
"working": "Binding…",
|
|
55
|
+
"noWorkspace": "Select a workspace first.",
|
|
56
|
+
"noServer": "The server address is missing.",
|
|
57
|
+
"done": "This computer is now bound to {{server}}"
|
|
58
|
+
},
|
|
59
|
+
"cli": {
|
|
60
|
+
"title": "CLIs on this computer",
|
|
61
|
+
"runnable": "Runnable",
|
|
62
|
+
"detectOnly": "Detected only",
|
|
63
|
+
"none": "No usable CLI detected.",
|
|
64
|
+
"redetect": "Detect again"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"nav": { "title": "设备代理" },
|
|
3
|
+
"page": {
|
|
4
|
+
"title": "设备代理",
|
|
5
|
+
"subtitle": "让这台电脑接收任务链派发的任务,并在本机运行 Codex、Claude 等 CLI。"
|
|
6
|
+
},
|
|
7
|
+
"common": { "copy": "复制", "copied": "已复制", "checking": "正在检查本机服务…" },
|
|
8
|
+
"error": { "offline": "连不上本机服务,请确认 toc-ocra 正在运行。" },
|
|
9
|
+
"health": {
|
|
10
|
+
"online": "已在线:{{name}}",
|
|
11
|
+
"disconnected": "已绑定,但暂时连不上服务器",
|
|
12
|
+
"unpaired": "本机服务已运行,尚未绑定服务器",
|
|
13
|
+
"offline": "本机服务未运行"
|
|
14
|
+
},
|
|
15
|
+
"offline": {
|
|
16
|
+
"title": "本机服务未运行",
|
|
17
|
+
"body": "插件通过 {{url}} 连接本机的 toc-ocra 服务。请在终端启动它(需要你亲自运行一次,插件不会替你启动程序)。",
|
|
18
|
+
"once": "临时运行(关闭终端即停止)",
|
|
19
|
+
"service": "长期使用:安装为后台服务,开机自动启动",
|
|
20
|
+
"node": "需要 Node.js 20 或以上。启动后本页会自动刷新。"
|
|
21
|
+
},
|
|
22
|
+
"pair": {
|
|
23
|
+
"title": "连接本机服务",
|
|
24
|
+
"body": "本机服务启动时会显示 6 位连接码,也可以在终端运行下面的命令查看。",
|
|
25
|
+
"placeholder": "6 位连接码",
|
|
26
|
+
"submit": "连接",
|
|
27
|
+
"wrong": "连接码不正确,请重新查看(连接码使用后会更换)。",
|
|
28
|
+
"locked": "错误次数过多,请 30 秒后用新的连接码重试。"
|
|
29
|
+
},
|
|
30
|
+
"status": {
|
|
31
|
+
"title": "本机状态",
|
|
32
|
+
"service": "本机服务",
|
|
33
|
+
"binding": "绑定状态",
|
|
34
|
+
"device": "设备",
|
|
35
|
+
"server": "服务器",
|
|
36
|
+
"runs": "运行中的任务",
|
|
37
|
+
"lastError": "最近错误:{{error}}",
|
|
38
|
+
"tokenFromEnv": "设备令牌来自环境变量 TOC_OCRA_TOKEN,不能在这里绑定或解绑。",
|
|
39
|
+
"unpair": "解除绑定"
|
|
40
|
+
},
|
|
41
|
+
"binding": { "unpaired": "未绑定", "revoked": "凭据已失效", "online": "在线", "connecting": "连接中" },
|
|
42
|
+
"bind": {
|
|
43
|
+
"title": "绑定到当前服务器",
|
|
44
|
+
"rebindTitle": "重新绑定",
|
|
45
|
+
"revoked": "服务器已不再接受这台电脑的凭据(可能在设备页解除了配对),请重新绑定。",
|
|
46
|
+
"elsewhere": "这台电脑当前绑定的是 {{bound}},而你正在使用 {{current}}。重新绑定后将改为接收当前服务器的任务。",
|
|
47
|
+
"body": "绑定后,「{{workspace}}」里派发给这台设备的任务会在本机执行(服务器:{{server}})。",
|
|
48
|
+
"server": "服务器地址",
|
|
49
|
+
"device": "设备",
|
|
50
|
+
"newDevice": "新建一台设备",
|
|
51
|
+
"replaces": "将替换原来的绑定",
|
|
52
|
+
"name": "设备名称",
|
|
53
|
+
"submit": "绑定",
|
|
54
|
+
"working": "正在绑定…",
|
|
55
|
+
"noWorkspace": "请先选择一个工作空间。",
|
|
56
|
+
"noServer": "缺少服务器地址。",
|
|
57
|
+
"done": "这台电脑已绑定到 {{server}}"
|
|
58
|
+
},
|
|
59
|
+
"cli": {
|
|
60
|
+
"title": "本机 CLI",
|
|
61
|
+
"runnable": "可执行",
|
|
62
|
+
"detectOnly": "仅检测到",
|
|
63
|
+
"none": "没有检测到可用的 CLI。",
|
|
64
|
+
"redetect": "重新检测"
|
|
65
|
+
}
|
|
66
|
+
}
|