@mrpatronz/nexusflow 2.4.1 → 2.5.1

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 (107) hide show
  1. package/dist/commands/finish.d.ts.map +1 -1
  2. package/dist/commands/finish.js +7 -0
  3. package/dist/commands/finish.js.map +1 -1
  4. package/dist/commands/isolate.d.ts +12 -0
  5. package/dist/commands/isolate.d.ts.map +1 -0
  6. package/dist/commands/isolate.js +78 -0
  7. package/dist/commands/isolate.js.map +1 -0
  8. package/dist/commands/isolate.test.d.ts +2 -0
  9. package/dist/commands/isolate.test.d.ts.map +1 -0
  10. package/dist/commands/isolate.test.js +59 -0
  11. package/dist/commands/isolate.test.js.map +1 -0
  12. package/dist/commands/list.d.ts +3 -1
  13. package/dist/commands/list.d.ts.map +1 -1
  14. package/dist/commands/list.js +5 -1
  15. package/dist/commands/list.js.map +1 -1
  16. package/dist/commands/schedule.d.ts.map +1 -1
  17. package/dist/commands/schedule.js +6 -0
  18. package/dist/commands/schedule.js.map +1 -1
  19. package/dist/commands/ui.d.ts +2 -1
  20. package/dist/commands/ui.d.ts.map +1 -1
  21. package/dist/commands/ui.js +27 -7
  22. package/dist/commands/ui.js.map +1 -1
  23. package/dist/core/config-schema.d.ts +17 -0
  24. package/dist/core/config-schema.d.ts.map +1 -0
  25. package/dist/core/config-schema.js +24 -0
  26. package/dist/core/config-schema.js.map +1 -0
  27. package/dist/core/doctor.d.ts.map +1 -1
  28. package/dist/core/doctor.js +43 -5
  29. package/dist/core/doctor.js.map +1 -1
  30. package/dist/core/isolate.d.ts +31 -0
  31. package/dist/core/isolate.d.ts.map +1 -0
  32. package/dist/core/isolate.js +175 -0
  33. package/dist/core/isolate.js.map +1 -0
  34. package/dist/core/isolate.test.d.ts +2 -0
  35. package/dist/core/isolate.test.d.ts.map +1 -0
  36. package/dist/core/isolate.test.js +290 -0
  37. package/dist/core/isolate.test.js.map +1 -0
  38. package/dist/core/refresh.d.ts.map +1 -1
  39. package/dist/core/refresh.js +19 -16
  40. package/dist/core/refresh.js.map +1 -1
  41. package/dist/core/sync.d.ts.map +1 -1
  42. package/dist/core/sync.js +21 -7
  43. package/dist/core/sync.js.map +1 -1
  44. package/dist/core/workspace.d.ts +6 -0
  45. package/dist/core/workspace.d.ts.map +1 -1
  46. package/dist/core/workspace.js +27 -4
  47. package/dist/core/workspace.js.map +1 -1
  48. package/dist/core/worktree.d.ts.map +1 -1
  49. package/dist/core/worktree.js +7 -0
  50. package/dist/core/worktree.js.map +1 -1
  51. package/dist/desktop-server.js +2 -1
  52. package/dist/desktop-server.js.map +1 -1
  53. package/dist/generators/base.d.ts.map +1 -1
  54. package/dist/generators/base.js +13 -5
  55. package/dist/generators/base.js.map +1 -1
  56. package/dist/generators/base.test.js +1 -1
  57. package/dist/generators/base.test.js.map +1 -1
  58. package/dist/gui/assets/{AgentsPage-BNHR9qux.js → AgentsPage-gHbRof2y.js} +1 -1
  59. package/dist/gui/assets/{DashboardPage-BScH3Cxp.js → DashboardPage-CkXIpoFX.js} +1 -1
  60. package/dist/gui/assets/{GettingStartedPage-AWlI-176.js → GettingStartedPage-DRL_nbb6.js} +1 -1
  61. package/dist/gui/assets/{ProjectsPage-Bojj7gxI.js → ProjectsPage-C8XQ9dRr.js} +1 -1
  62. package/dist/gui/assets/{ScaffoldRepoInline-DJMbeHVM.js → ScaffoldRepoInline-ys4l8ho4.js} +1 -1
  63. package/dist/gui/assets/{SettingsPage-BAdXO8X0.js → SettingsPage-CRVDsRwi.js} +1 -1
  64. package/dist/gui/assets/{SkillsPage-CF6Db1FA.js → SkillsPage-BfQu6PT3.js} +1 -1
  65. package/dist/gui/assets/StartWorkPage-BNzeMcFc.js +1 -0
  66. package/dist/gui/assets/{StrategiesPage-nGbR9TAc.js → StrategiesPage-Bh6x7zhl.js} +1 -1
  67. package/dist/gui/assets/{WorkspacesPage-7XRtVJNF.js → WorkspacesPage-DYQt7CQ8.js} +1 -1
  68. package/dist/gui/assets/{alert-dialog-67uzXJi4.js → alert-dialog-D7jNzvYQ.js} +1 -1
  69. package/dist/gui/assets/{index-V1dDX1O_.js → index-C6qbn9Zq.js} +3 -3
  70. package/dist/gui/assets/{vsc-Di05BTNr.js → vsc-CvlJSs-5.js} +1 -1
  71. package/dist/gui/index.html +1 -1
  72. package/dist/index.js +124 -489
  73. package/dist/index.js.map +1 -1
  74. package/dist/mcp/tools.d.ts.map +1 -1
  75. package/dist/mcp/tools.js +47 -1
  76. package/dist/mcp/tools.js.map +1 -1
  77. package/dist/mcp/tools.test.d.ts +2 -0
  78. package/dist/mcp/tools.test.d.ts.map +1 -0
  79. package/dist/mcp/tools.test.js +70 -0
  80. package/dist/mcp/tools.test.js.map +1 -0
  81. package/dist/orchestration/orchestrator.js +2 -2
  82. package/dist/orchestration/orchestrator.js.map +1 -1
  83. package/dist/orchestration/orchestrator.test.js +1 -1
  84. package/dist/orchestration/orchestrator.test.js.map +1 -1
  85. package/dist/orchestration/runner.d.ts +5 -1
  86. package/dist/orchestration/runner.d.ts.map +1 -1
  87. package/dist/orchestration/runner.js +14 -4
  88. package/dist/orchestration/runner.js.map +1 -1
  89. package/dist/orchestration/runner.test.js +22 -16
  90. package/dist/orchestration/runner.test.js.map +1 -1
  91. package/dist/server.d.ts.map +1 -1
  92. package/dist/server.js +110 -11
  93. package/dist/server.js.map +1 -1
  94. package/dist/server.test.js +74 -1
  95. package/dist/server.test.js.map +1 -1
  96. package/dist/types.d.ts +16 -0
  97. package/dist/types.d.ts.map +1 -1
  98. package/dist/utils/feature.d.ts +10 -1
  99. package/dist/utils/feature.d.ts.map +1 -1
  100. package/dist/utils/feature.js +36 -4
  101. package/dist/utils/feature.js.map +1 -1
  102. package/dist/utils/session-finder.d.ts +2 -0
  103. package/dist/utils/session-finder.d.ts.map +1 -1
  104. package/dist/utils/session-finder.js +13 -0
  105. package/dist/utils/session-finder.js.map +1 -1
  106. package/package.json +6 -4
  107. package/dist/gui/assets/StartWorkPage-BQid3uIw.js +0 -1
@@ -2,7 +2,7 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
2
  import * as fs from 'node:fs/promises';
3
3
  import { execa } from 'execa';
4
4
  import * as path from 'node:path';
5
- import { getPm2List, loadRunningState, parsePm2Json, pm2AppName, serviceLogFile, startService, stopService, stopServices, } from './runner.js';
5
+ import { getPm2List, loadRunningState, parsePm2Json, pm2AppName, pm2Prefix, serviceLogFile, startService, stopService, stopServices, } from './runner.js';
6
6
  vi.mock('node:fs/promises');
7
7
  vi.mock('execa');
8
8
  function service(name, cwd) {
@@ -59,8 +59,8 @@ describe('orchestration runner PM2 state handling', () => {
59
59
  };
60
60
  vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify(state));
61
61
  const runningState = await loadRunningState(workspacePath, [
62
- { name: 'nexusflow-feature-a-api', pid: 333, pm2_env: { status: 'online' } },
63
- { name: 'nexusflow-feature-a-web', pid: 444, pm2_env: { status: 'stopped' } },
62
+ { name: pm2AppName(workspacePath, 'api'), pid: 333, pm2_env: { status: 'online' } },
63
+ { name: pm2AppName(workspacePath, 'web'), pid: 444, pm2_env: { status: 'stopped' } },
64
64
  ]);
65
65
  expect(runningState?.services).toHaveLength(1);
66
66
  expect(runningState?.services[0]?.name).toBe('api');
@@ -104,11 +104,12 @@ describe('orchestration runner PM2 state handling', () => {
104
104
  describe('per-service lifecycle', () => {
105
105
  it('pm2AppName and serviceLogFile derive workspace-scoped names', () => {
106
106
  const ws = path.join(process.cwd(), 'my-ws');
107
- expect(pm2AppName(ws, 'api')).toBe('nexusflow-my-ws-api');
107
+ expect(pm2AppName(ws, 'api')).toMatch(/^nexusflow-my-ws-[0-9a-f]{8}-api$/);
108
108
  expect(serviceLogFile('/logs', 'api')).toBe(path.join('/logs', 'api.log'));
109
109
  });
110
110
  it('startService deletes any existing app, starts PM2, resolves the PID and upserts state', async () => {
111
111
  const ws = path.join(process.cwd(), 'my-ws');
112
+ const expectedApp = pm2AppName(ws, 'api');
112
113
  // fs: mkdir (log dir), then mutateRunningState reads (ENOENT) + writes.
113
114
  vi.mocked(fs.mkdir).mockResolvedValue(undefined);
114
115
  vi.mocked(fs.readFile).mockRejectedValue(new Error('ENOENT'));
@@ -116,13 +117,13 @@ describe('orchestration runner PM2 state handling', () => {
116
117
  vi.mocked(execa)
117
118
  .mockResolvedValueOnce({ stdout: '' }) // pm2 delete
118
119
  .mockResolvedValueOnce({ stdout: '' }) // pm2 start
119
- .mockResolvedValueOnce({ stdout: '[{"name":"nexusflow-my-ws-api","pid":4321}]' }); // pm2 jlist
120
+ .mockResolvedValueOnce({ stdout: JSON.stringify([{ name: expectedApp, pid: 4321 }]) }); // pm2 jlist
120
121
  const running = await startService(service('api', ws), ws, '/logs');
121
122
  expect(running?.pid).toBe(4321);
122
123
  const calls = vi.mocked(execa).mock.calls;
123
- expect(calls[0]).toEqual(['npx', ['pm2', 'delete', 'nexusflow-my-ws-api'], { reject: false }]);
124
+ expect(calls[0]).toEqual(['npx', ['pm2', 'delete', expectedApp], { reject: false }]);
124
125
  expect(calls[1]?.[1]).toContain('start');
125
- expect(calls[1]?.[1]).toContain('nexusflow-my-ws-api');
126
+ expect(calls[1]?.[1]).toContain(expectedApp);
126
127
  // State written with the running service.
127
128
  const written = JSON.parse(vi.mocked(fs.writeFile).mock.calls.at(-1)?.[1]);
128
129
  expect(written.services.map((s) => s.name)).toEqual(['api']);
@@ -138,18 +139,19 @@ describe('orchestration runner PM2 state handling', () => {
138
139
  });
139
140
  it('stopService deletes the PM2 app and removes it from state', async () => {
140
141
  const ws = path.join(process.cwd(), 'my-ws');
142
+ const expectedApp = pm2AppName(ws, 'api');
141
143
  const state = {
142
144
  workspacePath: ws,
143
145
  services: [{ name: 'api', pid: 1, config: service('api', ws), startedAt: 'x' }],
144
146
  updatedAt: 'x',
145
147
  };
146
148
  vi.mocked(execa)
147
- .mockResolvedValueOnce({ stdout: '[{"name":"nexusflow-my-ws-api"}]' }) // jlist
149
+ .mockResolvedValueOnce({ stdout: JSON.stringify([{ name: expectedApp }]) }) // jlist
148
150
  .mockResolvedValueOnce({ stdout: '' }); // pm2 delete
149
151
  vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify(state));
150
152
  vi.mocked(fs.unlink).mockResolvedValue(undefined);
151
153
  expect(await stopService(ws, 'api')).toBe(true);
152
- expect(vi.mocked(execa).mock.calls[1]).toEqual(['npx', ['pm2', 'delete', 'nexusflow-my-ws-api'], { reject: false }]);
154
+ expect(vi.mocked(execa).mock.calls[1]).toEqual(['npx', ['pm2', 'delete', expectedApp], { reject: false }]);
153
155
  // Services now empty → state file removed.
154
156
  expect(fs.unlink).toHaveBeenCalled();
155
157
  });
@@ -157,11 +159,15 @@ describe('orchestration runner PM2 state handling', () => {
157
159
  describe('stop-all carve-out', () => {
158
160
  it('stops orch-* named services but excludes recorded orchestrator apps', async () => {
159
161
  const ws = path.join(process.cwd(), 'my-ws');
162
+ const prefix = pm2Prefix(ws);
163
+ const orchApp = `${prefix}orch-tilt-tiltfile`;
164
+ const workerApp = `${prefix}orch-worker`;
165
+ const apiApp = `${prefix}api`;
160
166
  const state = {
161
167
  workspacePath: ws,
162
168
  services: [],
163
169
  orchestrators: [
164
- { id: 'tilt:Tiltfile', tool: 'tilt', configPath: 'Tiltfile', mode: 'pm2', pm2Name: 'nexusflow-my-ws-orch-tilt-tiltfile', logName: 'orch-tilt-tiltfile', startedAt: 'x' },
170
+ { id: 'tilt:Tiltfile', tool: 'tilt', configPath: 'Tiltfile', mode: 'pm2', pm2Name: orchApp, logName: 'orch-tilt-tiltfile', startedAt: 'x' },
165
171
  ],
166
172
  updatedAt: 'x',
167
173
  };
@@ -174,9 +180,9 @@ describe('orchestration runner PM2 state handling', () => {
174
180
  // orch-worker, and a plain service.
175
181
  .mockResolvedValueOnce({
176
182
  stdout: JSON.stringify([
177
- { name: 'nexusflow-my-ws-orch-tilt-tiltfile' },
178
- { name: 'nexusflow-my-ws-orch-worker' },
179
- { name: 'nexusflow-my-ws-api' },
183
+ { name: orchApp },
184
+ { name: workerApp },
185
+ { name: apiApp },
180
186
  ]),
181
187
  })
182
188
  .mockResolvedValue({ stdout: '' }); // subsequent pm2 delete calls
@@ -185,10 +191,10 @@ describe('orchestration runner PM2 state handling', () => {
185
191
  .filter((c) => c[1]?.[1] === 'delete')
186
192
  .map((c) => c[1][2]);
187
193
  // The orch-* SERVICE and the plain service are stopped...
188
- expect(deleted).toContain('nexusflow-my-ws-orch-worker');
189
- expect(deleted).toContain('nexusflow-my-ws-api');
194
+ expect(deleted).toContain(workerApp);
195
+ expect(deleted).toContain(apiApp);
190
196
  // ...but the recorded orchestrator app is left running.
191
- expect(deleted).not.toContain('nexusflow-my-ws-orch-tilt-tiltfile');
197
+ expect(deleted).not.toContain(orchApp);
192
198
  });
193
199
  });
194
200
  });
@@ -1 +1 @@
1
- {"version":3,"file":"runner.test.js","sourceRoot":"","sources":["../../src/orchestration/runner.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.test.js","sourceRoot":"","sources":["../../src/orchestration/runner.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AA4C5B,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA4EjF,eAAO,MAAM,GAAG,4EAAa,CAAC;AAc9B,mGAAmG;AACnG,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,GACvD,MAAM,GAAG,IAAI,CAUf;AAED,gFAAgF;AAChF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;IAEhB,QAAQ,IAAI,OAAO;IAMnB,MAAM,IAAI,IAAI;IAId,QAAQ,IAAI,OAAO;CAG3B;AAuKD,yEAAyE;AACzE,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,SAA2B;CAI/C;AAcD,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE9E;AAID;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,YAAY,GAAE,MAAM,CAAC,YAA2B,EAChD,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,eAAe,GAAE,MAAM,OAMtB,GACA,OAAO,CAeT;AA8BD,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/E;AAsDD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAc7D;AAmnED,wBAAgB,WAAW,CACzB,IAAI,SAAO,EACX,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GAClC,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,CAAC,CA0BxC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AA+C5B,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA4EjF,eAAO,MAAM,GAAG,4EAAa,CAAC;AAc9B,mGAAmG;AACnG,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,GACvD,MAAM,GAAG,IAAI,CAUf;AAED,gFAAgF;AAChF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;IAEhB,QAAQ,IAAI,OAAO;IAMnB,MAAM,IAAI,IAAI;IAId,QAAQ,IAAI,OAAO;CAG3B;AAkLD,yEAAyE;AACzE,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,SAA2B;CAI/C;AAcD,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE9E;AAID;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,YAAY,GAAE,MAAM,CAAC,YAA2B,EAChD,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,eAAe,GAAE,MAAM,OAMtB,GACA,OAAO,CAeT;AA8BD,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/E;AAsDD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAc7D;AA8sED,wBAAgB,WAAW,CACzB,IAAI,SAAO,EACX,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GAClC,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE,CAAC,CA0BxC"}
package/dist/server.js CHANGED
@@ -14,16 +14,19 @@ import * as path from 'node:path';
14
14
  import { fileURLToPath } from 'node:url';
15
15
  import { execa } from 'execa';
16
16
  import * as os from 'node:os';
17
+ import { createHash } from 'node:crypto';
18
+ import { Readable } from 'node:stream';
17
19
  import { pipeline } from 'node:stream/promises';
18
20
  import { spawn } from 'node:child_process';
19
21
  import { loadConfig, saveConfig, getConfigDir } from './core/config.js';
22
+ import { configPatchSchema } from './core/config-schema.js';
20
23
  import { listStorageProviders } from './core/adapters/registry.js';
21
24
  import { scanForRepos } from './core/scanner.js';
22
- import { createNewRepo } from './core/new-repo.js';
25
+ import { createNewRepo, isValidProjectName } from './core/new-repo.js';
23
26
  import { loadProjects, createProject, updateProject, removeProject, slugifyProjectName } from './core/projects.js';
24
27
  import { getSessionCwd, isInPlace, resolveFeatureRepoPath } from './utils/feature.js';
25
28
  import { listBranches } from './utils/git.js';
26
- import { createWorkspace, listWorkspaces, loadFeatureConfig, loadWorkspaceManifest, deleteWorkspace, addRepoToWorkspace } from './core/workspace.js';
29
+ import { createWorkspace, listWorkspaces, loadFeatureConfig, loadWorkspaceManifest, deleteWorkspace, addRepoToWorkspace, isolateWorkspaceRepo } from './core/workspace.js';
27
30
  import { loadWorkspaceState } from './core/workspace-state.js';
28
31
  import { analyzeAllRepos } from './analyzers/index.js';
29
32
  import { generateContextFiles } from './generators/index.js';
@@ -123,7 +126,7 @@ app.get('/ws', async (c, next) => {
123
126
  let activeProvider = null;
124
127
  const turnGate = new AgentTurnGate();
125
128
  return {
126
- onMessage(event, ws) {
129
+ async onMessage(event, ws) {
127
130
  if (typeof event.data === 'string') {
128
131
  if (event.data === 'ping') {
129
132
  ws.send(JSON.stringify({ type: 'pong' }));
@@ -147,6 +150,16 @@ app.get('/ws', async (c, next) => {
147
150
  ws.send(JSON.stringify({ type: 'error', message: `No provider found for ${payload.command}. Please create a dedicated adapter.` }));
148
151
  return;
149
152
  }
153
+ const config = await loadConfig();
154
+ if (typeof payload.cwd !== 'string' || !payload.cwd.trim()) {
155
+ ws.send(JSON.stringify({ type: 'error', message: 'Workspace directory cwd is required.' }));
156
+ return;
157
+ }
158
+ const safeCwd = await resolveExactLaunchWorkspace(config.workspacesDir, payload.cwd);
159
+ if (!safeCwd) {
160
+ ws.send(JSON.stringify({ type: 'error', message: 'Invalid or uncontained workspace directory.' }));
161
+ return;
162
+ }
150
163
  let session;
151
164
  if (payload.sessionId !== undefined && payload.sessionId !== null) {
152
165
  if (!isValidSessionUuid(payload.sessionId)) {
@@ -195,7 +208,7 @@ app.get('/ws', async (c, next) => {
195
208
  return;
196
209
  ws.send(JSON.stringify({ type: 'error', message: error?.message ?? String(error) }));
197
210
  });
198
- startedAgent.start(payload.cwd, session);
211
+ startedAgent.start(safeCwd, session);
199
212
  }
200
213
  else if (payload.type === 'input') {
201
214
  if (agent && activeProvider) {
@@ -435,6 +448,22 @@ app.use('/api/*', cors({
435
448
  }
436
449
  },
437
450
  }));
451
+ // --- host guard: DNS rebinding protection ---
452
+ function isAllowedHost(hostHeader) {
453
+ if (!hostHeader)
454
+ return true; // Internal Hono programmatic invocations / test requests
455
+ const hostname = hostHeader.startsWith('[')
456
+ ? hostHeader.slice(1, hostHeader.indexOf(']'))
457
+ : hostHeader.split(':')[0]?.toLowerCase() ?? '';
458
+ return ['localhost', '127.0.0.1', '::1'].includes(hostname);
459
+ }
460
+ app.use('*', async (c, next) => {
461
+ const host = c.req.header('host');
462
+ if (!isAllowedHost(host)) {
463
+ return c.text('Forbidden: invalid Host header', 403);
464
+ }
465
+ await next();
466
+ });
438
467
  // Enforce trusted local origin on all mutating HTTP methods across /api/* to defend against
439
468
  // cross-site request forgery and browser form posts from untrusted web pages.
440
469
  app.use('/api/*', async (c, next) => {
@@ -500,9 +529,15 @@ app.get('/api/adapters', async (c) => {
500
529
  // 2. Save configuration
501
530
  app.post('/api/config', async (c) => {
502
531
  try {
503
- const newConfig = await c.req.json();
504
- await saveConfig(newConfig);
505
- return c.json({ success: true, config: newConfig });
532
+ const body = await c.req.json().catch(() => null);
533
+ const parsed = configPatchSchema.safeParse(body);
534
+ if (!parsed.success) {
535
+ return c.json({ error: 'Invalid config payload', issues: parsed.error.flatten() }, 400);
536
+ }
537
+ const current = await loadConfig();
538
+ const next = { ...current, ...parsed.data };
539
+ await saveConfig(next);
540
+ return c.json({ success: true, config: next });
506
541
  }
507
542
  catch (error) {
508
543
  return errorResponse(c, error);
@@ -883,6 +918,21 @@ app.post('/api/workspace', async (c) => {
883
918
  return c.json({ error: 'Missing "branchName" in request body' }, 400);
884
919
  }
885
920
  const config = await loadConfig();
921
+ const devDir = config.devDir || path.join(os.homedir(), 'dev');
922
+ // Validate repo names and paths synchronously before starting the job.
923
+ for (const r of body.repos || []) {
924
+ if (inPlace) {
925
+ if (!r.path) {
926
+ return c.json({ error: 'Repository path is required for in-place mode.' }, 400);
927
+ }
928
+ assertWithin(devDir, path.resolve(r.path));
929
+ }
930
+ else {
931
+ if (r.name && !isValidProjectName(r.name)) {
932
+ return c.json({ error: `Invalid repository name: ${JSON.stringify(r.name)}` }, 400);
933
+ }
934
+ }
935
+ }
886
936
  // The job id doubles as the workspace directory name.
887
937
  const jobId = inPlace ? slugifyProjectName(body.name) : body.branchName;
888
938
  if (!jobId) {
@@ -1010,6 +1060,8 @@ app.post('/api/workspace/:id/repo', async (c) => {
1010
1060
  const id = decodeURIComponent(c.req.param('id'));
1011
1061
  const { repoPath } = await c.req.json();
1012
1062
  const config = await loadConfig();
1063
+ const devDir = config.devDir || path.join(os.homedir(), 'dev');
1064
+ assertWithin(devDir, path.resolve(repoPath));
1013
1065
  const workspacePath = resolveWorkspacePath(config.workspacesDir, id);
1014
1066
  await addRepoToWorkspace(workspacePath, repoPath);
1015
1067
  return c.json({ success: true });
@@ -1018,6 +1070,29 @@ app.post('/api/workspace/:id/repo', async (c) => {
1018
1070
  return errorResponse(c, error);
1019
1071
  }
1020
1072
  });
1073
+ // 7.7b. Isolate repo in in-place workspace
1074
+ app.post('/api/workspace/:id/isolate', async (c) => {
1075
+ try {
1076
+ const id = decodeURIComponent(c.req.param('id'));
1077
+ const body = await c.req.json().catch(() => ({}));
1078
+ const repo = typeof body.repo === 'string' ? body.repo.trim() : '';
1079
+ if (!repo) {
1080
+ return c.json({ error: 'Missing "repo" parameter in request body' }, 400);
1081
+ }
1082
+ const branchName = typeof body.branchName === 'string' && body.branchName.trim() ? body.branchName.trim() : undefined;
1083
+ const baseBranch = typeof body.baseBranch === 'string' && body.baseBranch.trim() ? body.baseBranch.trim() : undefined;
1084
+ const config = await loadConfig();
1085
+ const workspacePath = resolveWorkspacePath(config.workspacesDir, id);
1086
+ const result = await isolateWorkspaceRepo(workspacePath, repo, {
1087
+ branchName,
1088
+ baseBranch,
1089
+ });
1090
+ return c.json({ success: true, ...result });
1091
+ }
1092
+ catch (error) {
1093
+ return errorResponse(c, error);
1094
+ }
1095
+ });
1021
1096
  // 7.8. Suggest workflow strategy based on feature description & selected repos
1022
1097
  app.post('/api/workspace/suggest-workflow', async (c) => {
1023
1098
  try {
@@ -1907,15 +1982,39 @@ app.post('/api/updates/download', async (c) => {
1907
1982
  if (!response.ok) {
1908
1983
  throw new Error(`HTTP error ${response.status}`);
1909
1984
  }
1910
- // Node fetch body stream download
1985
+ // Node fetch body stream download and SHA-256 computation
1986
+ const hash = createHash('sha256');
1911
1987
  const fileStream = createWriteStream(targetPath);
1912
1988
  if (!response.body) {
1913
1989
  throw new Error('Response body is null');
1914
1990
  }
1915
- // Convert ReadableStream to Node stream
1916
- await pipeline(response.body, fileStream);
1991
+ const nodeStream = Readable.fromWeb(response.body);
1992
+ nodeStream.on('data', (chunk) => hash.update(chunk));
1993
+ await pipeline(nodeStream, fileStream);
1994
+ const computedHash = hash.digest('hex').toLowerCase();
1995
+ // Verify SHA-256 against release checksum file if published
1996
+ try {
1997
+ const shaUrl = `${downloadUrl}.sha256`;
1998
+ if (isAllowedUpdateUrl(shaUrl)) {
1999
+ const shaRes = await fetch(shaUrl);
2000
+ if (shaRes.ok) {
2001
+ const shaText = await shaRes.text();
2002
+ const expectedHash = shaText.trim().split(/\s+/)[0]?.toLowerCase();
2003
+ if (expectedHash && expectedHash.length === 64 && expectedHash !== computedHash) {
2004
+ await fs.unlink(targetPath).catch(() => { });
2005
+ throw new Error(`SHA-256 checksum mismatch (expected ${expectedHash}, got ${computedHash})`);
2006
+ }
2007
+ }
2008
+ }
2009
+ }
2010
+ catch (shaErr) {
2011
+ if (shaErr instanceof Error && shaErr.message.includes('SHA-256 checksum mismatch')) {
2012
+ throw shaErr;
2013
+ }
2014
+ // Non-fatal if sha256 sidecar does not exist on older releases
2015
+ }
1917
2016
  downloadedInstallerPath = targetPath;
1918
- return c.json({ success: true, path: targetPath });
2017
+ return c.json({ success: true, path: targetPath, sha256: computedHash });
1919
2018
  }
1920
2019
  catch (error) {
1921
2020
  const msg = error instanceof Error ? error.message : String(error);