farming-code 2.2.28 → 2.2.30

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.
Files changed (83) hide show
  1. package/README.md +27 -90
  2. package/README.zh_cn.md +17 -90
  3. package/THIRD_PARTY_NOTICES.md +25 -6
  4. package/backend/acp/packaged-claude-acp.js +13 -0
  5. package/backend/acp/packaged-codex-acp.js +2 -2
  6. package/backend/acp-runtime.js +38 -17
  7. package/backend/acp-session-state.js +78 -88
  8. package/backend/acp-transcript.js +174 -9
  9. package/backend/agent-manager.js +27 -2
  10. package/backend/agent-session-history.js +45 -12
  11. package/backend/codex-session-history.js +1 -1
  12. package/backend/codex-transcript.js +0 -202
  13. package/backend/config-manager.js +44 -16
  14. package/backend/data/LICENSE.agent-browser +201 -0
  15. package/backend/data/runtime-dependency-manifest.json +199 -0
  16. package/backend/data/runtime-dependency-sources.json +5 -0
  17. package/backend/executable-discovery.js +7 -0
  18. package/backend/farming-agent-bootstrap.zh_cn.md +4 -2
  19. package/backend/farming-app-cli.js +161 -65
  20. package/backend/farming-cli.js +7 -59
  21. package/backend/index-html.js +31 -0
  22. package/backend/main-agent-skills.js +7 -28
  23. package/backend/npm-update-helper.js +43 -6
  24. package/backend/provider-adapters.js +10 -0
  25. package/backend/runtime-dependency-manager.js +759 -0
  26. package/backend/runtime-executable-invocation.js +20 -0
  27. package/backend/server-process-identity.js +47 -0
  28. package/backend/server.js +145 -204
  29. package/backend/slash-command-discovery.js +138 -1
  30. package/backend/storage-layout.js +30 -0
  31. package/backend/update-service.js +60 -914
  32. package/config/farming.deploy.env.example +1 -1
  33. package/config/farming.install.env.example +5 -1
  34. package/dist/acp/LICENSE.claude-agent-acp +191 -0
  35. package/dist/acp/LICENSE.claude-agent-sdk +1 -0
  36. package/dist/acp/claude-agent-acp-0.59.0.mjs +41606 -0
  37. package/dist/acp/{codex-acp-1.1.4.js → codex-acp-1.1.4.mjs} +387 -7
  38. package/dist/assets/{App-CM7Cy-l4.css → App-BKNUILuL.css} +1 -1
  39. package/dist/assets/App-Z1N7T0eM.js +695 -0
  40. package/dist/assets/{FileEditorMarkdownPreview-DYOMm-b1.js → FileEditorMarkdownPreview-Cs9cLv8a.js} +1 -1
  41. package/dist/assets/FileEditorPane-CNtuGjQ3.js +2 -0
  42. package/dist/assets/IconGlyphs-BClgag6E.js +1 -0
  43. package/dist/assets/ProjectFilesSection-K3GHuQ4U.js +12 -0
  44. package/dist/assets/ReviewPage-BRuxFaH5.js +3 -0
  45. package/dist/assets/code-dark-kLsQLvpf.css +1 -0
  46. package/dist/assets/{index-BzQO3pUr.js → index-D-zetSol.js} +2 -2
  47. package/dist/assets/main-DUTz-Rd2.css +1 -0
  48. package/dist/assets/{workspace-editor-monaco-tXA-udGx.js → workspace-editor-monaco-CJNwbpCy.js} +1 -1
  49. package/dist/assets/workspace-editor-monaco-CO9w8YV0.js +1 -0
  50. package/dist/assets/workspace-view-state-BjKPYp0E.js +7 -0
  51. package/dist/index.html +33 -3
  52. package/extensions/browser/backend/agent-browser-runtime.js +1041 -0
  53. package/extensions/browser/backend/browser-mcp-server.js +352 -0
  54. package/extensions/browser/backend/browser-resource-manager.js +921 -114
  55. package/extensions/browser/backend/browser-resource-store.js +47 -6
  56. package/extensions/browser/backend/browser-router.js +15 -2
  57. package/extensions/browser/backend/executable-discovery.js +164 -17
  58. package/extensions/browser/backend/managed-chromium-installer.js +593 -0
  59. package/extensions/browser/bin/farming-browser +384 -30
  60. package/extensions/browser/frontend/BrowserSidebarPortals.tsx +17 -19
  61. package/extensions/browser/frontend/BrowserViewer.tsx +217 -46
  62. package/extensions/browser/frontend/browser.css +68 -17
  63. package/extensions/browser/frontend/types.ts +13 -0
  64. package/extensions/browser/frontend/useBrowserResources.ts +18 -3
  65. package/index.html +32 -2
  66. package/package.json +10 -6
  67. package/shared/backend-connection-status.d.ts +12 -0
  68. package/shared/backend-connection-status.js +35 -4
  69. package/backend/agent-activity.js +0 -35
  70. package/backend/agent-memory-report.js +0 -583
  71. package/backend/bundle-update-helper.js +0 -113
  72. package/backend/codex-rollout-follower.js +0 -326
  73. package/dist/assets/App-CPG4WcjO.js +0 -658
  74. package/dist/assets/FileEditorPane-DXXq82aM.js +0 -2
  75. package/dist/assets/IconGlyphs-DrdPjYXr.js +0 -1
  76. package/dist/assets/ProjectFilesSection-CP66XVPl.js +0 -12
  77. package/dist/assets/ReviewPage-w21MEPD6.js +0 -3
  78. package/dist/assets/code-dark-BDjwj7Um.css +0 -1
  79. package/dist/assets/main-BlVUXfxa.css +0 -1
  80. package/dist/assets/workspace-editor-monaco-CFEfFNcA.js +0 -1
  81. package/dist/assets/workspace-view-state-BS_V8JVs.js +0 -7
  82. package/extensions/browser/backend/cdp-browser-runtime.js +0 -648
  83. package/extensions/browser/backend/cdp-client.js +0 -167
@@ -1,6 +1,10 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { spawn } = require('child_process');
4
+ const {
5
+ matchingProcessIdentity,
6
+ readServerProcessIdentity,
7
+ } = require('./server-process-identity');
4
8
 
5
9
  function writeJsonAtomic(filePath, value) {
6
10
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
@@ -42,18 +46,37 @@ function isProcessRunning(pid) {
42
46
  try {
43
47
  process.kill(pid, 0);
44
48
  return true;
45
- } catch {
49
+ } catch (error) {
50
+ if (error?.code === 'EPERM' || error?.code === 'EACCES') return true;
46
51
  return false;
47
52
  }
48
53
  }
49
54
 
50
- async function stopProcess(pid, timeoutMs = 15_000) {
55
+ async function stopProcess(pid, expectedIdentity, timeoutMs = 15_000) {
51
56
  if (!isProcessRunning(pid)) return;
52
- process.kill(pid, 'SIGTERM');
57
+ const currentIdentity = await readServerProcessIdentity(pid);
58
+ if (!matchingProcessIdentity(expectedIdentity, currentIdentity)) {
59
+ throw new Error(`Refusing to stop Farming server ${pid}: process identity changed`);
60
+ }
61
+ try {
62
+ process.kill(pid, 'SIGKILL');
63
+ } catch (error) {
64
+ if (error?.code === 'EPERM' || error?.code === 'EACCES') {
65
+ throw new Error(
66
+ `Farming cannot stop server ${pid} because the update helper lacks permission. `
67
+ + 'Use the operating-system user that owns this process (or an administrator) to stop and restart Farming, then retry the update.',
68
+ { cause: error },
69
+ );
70
+ }
71
+ if (error?.code !== 'ESRCH') throw error;
72
+ }
53
73
  const startedAt = Date.now();
54
- while (isProcessRunning(pid)) {
74
+ while (matchingProcessIdentity(expectedIdentity, await readServerProcessIdentity(pid))) {
55
75
  if (Date.now() - startedAt >= timeoutMs) {
56
- throw new Error(`Farming server ${pid} did not stop before timeout`);
76
+ throw new Error(
77
+ `Farming server ${pid} did not exit after SIGKILL. `
78
+ + 'Stop and restart Farming manually, then retry the update.',
79
+ );
57
80
  }
58
81
  await new Promise(resolve => setTimeout(resolve, 100));
59
82
  }
@@ -200,9 +223,23 @@ async function prepareNpmUpdate(payload) {
200
223
  fs.mkdirSync(payload.stagingPrefix, { recursive: true });
201
224
  await installPackage(payload, payload.targetVersion, payload.stagingPrefix);
202
225
  verifyInstalledVersion(payload, payload.targetVersion, payload.stagingPackageRoot);
226
+ writeJsonAtomic(payload.stateFile, stateFor(payload, 'preparing-runtimes'));
227
+ appendLog(payload.logPath, `Preparing Farming ${payload.targetVersion} startup dependencies`);
228
+ await runCommand(payload.nodePath, [
229
+ path.join(payload.stagingPackageRoot, 'bin', 'farming'),
230
+ 'runtime',
231
+ 'prepare',
232
+ '--config-dir',
233
+ payload.configDir,
234
+ ], {
235
+ cwd: payload.configDir,
236
+ env: commandEnvironment(),
237
+ logPath: payload.logPath,
238
+ });
203
239
  const preparedAt = new Date().toISOString();
204
240
  writeJsonAtomic(payload.stateFile, stateFor(payload, 'ready-to-restart', {
205
241
  preparedAt,
242
+ runtimePreparedAt: preparedAt,
206
243
  }));
207
244
  appendLog(payload.logPath, `Farming ${payload.targetVersion} is ready to restart`);
208
245
  } catch (error) {
@@ -237,7 +274,7 @@ async function applyNpmUpdate(payload) {
237
274
  preparedAt: payload.preparedAt,
238
275
  }));
239
276
  await new Promise(resolve => setTimeout(resolve, 1_000));
240
- await stopProcess(Number(payload.serverPid));
277
+ await stopProcess(Number(payload.serverPid), payload.serverProcessIdentity);
241
278
  stoppedOldServer = true;
242
279
  fs.renameSync(payload.packageRoot, backupRoot);
243
280
  movedOldPackage = true;
@@ -213,6 +213,14 @@ function codexAcpEnvironment(options = {}) {
213
213
  return env;
214
214
  }
215
215
 
216
+ function claudeAcpEnvironment(options = {}) {
217
+ const env = { ...(options.env || process.env) };
218
+ if (options.executable && !env.CLAUDE_CODE_EXECUTABLE) {
219
+ env.CLAUDE_CODE_EXECUTABLE = options.executable;
220
+ }
221
+ return env;
222
+ }
223
+
216
224
  const PROVIDER_ADAPTERS = Object.freeze([
217
225
  {
218
226
  id: 'codex',
@@ -250,6 +258,7 @@ const PROVIDER_ADAPTERS = Object.freeze([
250
258
  version: '0.59.0',
251
259
  forkMode: 'target-process',
252
260
  },
261
+ prepareAcpEnvironment: claudeAcpEnvironment,
253
262
  capabilities: {
254
263
  runtimeSwitch: true,
255
264
  terminalProfile: false,
@@ -378,6 +387,7 @@ function isFreshAcpSessionSource(provider, source) {
378
387
  }
379
388
 
380
389
  module.exports = {
390
+ claudeAcpEnvironment,
381
391
  getProviderAdapter,
382
392
  applyProviderHomeEnvironment,
383
393
  isFreshAcpSessionSource,