proteum 2.3.0 → 2.4.2

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 (56) hide show
  1. package/AGENTS.md +8 -3
  2. package/README.md +20 -15
  3. package/agents/project/AGENTS.md +16 -10
  4. package/agents/project/DOCUMENTATION.md +1326 -0
  5. package/agents/project/app-root/AGENTS.md +2 -2
  6. package/agents/project/diagnostics.md +10 -9
  7. package/agents/project/optimizations.md +1 -1
  8. package/agents/project/root/AGENTS.md +15 -8
  9. package/agents/project/server/services/AGENTS.md +1 -0
  10. package/agents/project/tests/AGENTS.md +1 -0
  11. package/cli/commands/db.ts +160 -0
  12. package/cli/commands/dev.ts +148 -25
  13. package/cli/commands/diagnose.ts +2 -0
  14. package/cli/commands/explain.ts +38 -9
  15. package/cli/commands/mcp.ts +126 -9
  16. package/cli/commands/orient.ts +44 -17
  17. package/cli/commands/runtime.ts +100 -17
  18. package/cli/mcp/router.ts +1028 -0
  19. package/cli/presentation/commands.ts +56 -25
  20. package/cli/presentation/help.ts +1 -1
  21. package/cli/runtime/commands.ts +163 -21
  22. package/cli/runtime/devSessions.ts +328 -2
  23. package/cli/runtime/mcpDaemon.ts +288 -0
  24. package/cli/runtime/ports.ts +151 -0
  25. package/cli/utils/agents.ts +94 -17
  26. package/cli/utils/appRoots.ts +232 -0
  27. package/common/dev/database.ts +226 -0
  28. package/common/dev/diagnostics.ts +1 -1
  29. package/common/dev/inspection.ts +8 -1
  30. package/common/dev/mcpPayloads.ts +456 -17
  31. package/common/dev/mcpServer.ts +51 -0
  32. package/docs/agent-routing.md +32 -21
  33. package/docs/dev-commands.md +1 -1
  34. package/docs/dev-sessions.md +3 -1
  35. package/docs/diagnostics.md +21 -20
  36. package/docs/mcp.md +114 -50
  37. package/docs/migrate-from-2.1.3.md +3 -5
  38. package/docs/request-tracing.md +3 -3
  39. package/package.json +10 -3
  40. package/server/app/devDiagnostics.ts +92 -0
  41. package/server/app/devMcp.ts +55 -0
  42. package/server/services/prisma/mariadb.ts +7 -3
  43. package/server/services/router/http/index.ts +25 -0
  44. package/server/services/router/request/ip.test.cjs +0 -1
  45. package/tests/agents-utils.test.cjs +58 -3
  46. package/tests/cli-mcp-command.test.cjs +327 -0
  47. package/tests/codex-mcp-usage.test.cjs +307 -0
  48. package/tests/dev-sessions.test.cjs +113 -0
  49. package/tests/dev-transpile-watch.test.cjs +0 -1
  50. package/tests/eslint-rules.test.cjs +0 -1
  51. package/tests/inspection.test.cjs +0 -1
  52. package/tests/mcp.test.cjs +769 -2
  53. package/tests/router-cache-config.test.cjs +0 -1
  54. package/vitest.config.mjs +9 -0
  55. package/cli/mcp/provider.ts +0 -365
  56. package/cli/mcp/stdio.ts +0 -16
@@ -0,0 +1,113 @@
1
+ const assert = require('node:assert/strict');
2
+ const { spawn } = require('node:child_process');
3
+ const fs = require('node:fs');
4
+ const os = require('node:os');
5
+ const path = require('node:path');
6
+
7
+ const coreRoot = path.resolve(__dirname, '..');
8
+ process.env.TS_NODE_PROJECT = path.join(coreRoot, 'cli', 'tsconfig.json');
9
+ process.env.TS_NODE_TRANSPILE_ONLY = '1';
10
+ require('ts-node/register/transpile-only');
11
+ require('../cli/context.ts');
12
+
13
+ const {
14
+ createDevSessionRecord,
15
+ prepareDevSessionStart,
16
+ resolveDevSessionFilePath,
17
+ writeDevSessionRecord,
18
+ } = require('../cli/runtime/devSessions.ts');
19
+
20
+ const createTempAppRoot = () => fs.mkdtempSync(path.join(os.tmpdir(), 'proteum-dev-session-app-'));
21
+
22
+ const createSessionRecord = ({ appRoot, pid = process.pid, port = 3101, sessionFilePath }) => ({
23
+ ...createDevSessionRecord({ appRoot, port, sessionFilePath }),
24
+ pid,
25
+ publicUrl: `http://localhost:${port}`,
26
+ state: 'ready',
27
+ });
28
+
29
+ test('prepareDevSessionStart cleans stale and invalid same-worktree sessions', async () => {
30
+ const appRoot = createTempAppRoot();
31
+ const staleSessionFilePath = resolveDevSessionFilePath({ appRoot, port: 3101 });
32
+ const invalidSessionFilePath = resolveDevSessionFilePath({ appRoot, port: 3102 });
33
+ const requestedSessionFilePath = resolveDevSessionFilePath({ appRoot, port: 3103 });
34
+
35
+ await writeDevSessionRecord(
36
+ createSessionRecord({
37
+ appRoot,
38
+ pid: 999999,
39
+ port: 3101,
40
+ sessionFilePath: staleSessionFilePath,
41
+ }),
42
+ );
43
+ fs.mkdirSync(path.dirname(invalidSessionFilePath), { recursive: true });
44
+ fs.writeFileSync(invalidSessionFilePath, '{ invalid json');
45
+
46
+ const result = await prepareDevSessionStart({
47
+ appRoot,
48
+ replaceExisting: false,
49
+ sessionFilePath: requestedSessionFilePath,
50
+ });
51
+
52
+ assert.equal(result.blocking.length, 0);
53
+ assert.equal(result.cleaned.length, 2);
54
+ assert.equal(fs.existsSync(staleSessionFilePath), false);
55
+ assert.equal(fs.existsSync(invalidSessionFilePath), false);
56
+ });
57
+
58
+ test('prepareDevSessionStart blocks another live same-worktree session', async () => {
59
+ const appRoot = createTempAppRoot();
60
+ const blockingSessionFilePath = resolveDevSessionFilePath({ appRoot, port: 3101 });
61
+ const requestedSessionFilePath = resolveDevSessionFilePath({ appRoot, port: 3102 });
62
+
63
+ await writeDevSessionRecord(
64
+ createSessionRecord({
65
+ appRoot,
66
+ pid: process.pid,
67
+ port: 3101,
68
+ sessionFilePath: blockingSessionFilePath,
69
+ }),
70
+ );
71
+
72
+ const result = await prepareDevSessionStart({
73
+ appRoot,
74
+ currentPid: process.pid + 1,
75
+ replaceExisting: false,
76
+ sessionFilePath: requestedSessionFilePath,
77
+ });
78
+
79
+ assert.equal(result.blocking.length, 1);
80
+ assert.equal(result.blocking[0].sessionFilePath, blockingSessionFilePath);
81
+ assert.equal(fs.existsSync(blockingSessionFilePath), true);
82
+ });
83
+
84
+ test('prepareDevSessionStart replaces the exact requested session file only with replaceExisting', async () => {
85
+ const appRoot = createTempAppRoot();
86
+ const requestedSessionFilePath = resolveDevSessionFilePath({ appRoot, port: 3101 });
87
+ const child = spawn(process.execPath, ['-e', 'setInterval(() => {}, 1000)'], {
88
+ stdio: 'ignore',
89
+ });
90
+
91
+ try {
92
+ await writeDevSessionRecord(
93
+ createSessionRecord({
94
+ appRoot,
95
+ pid: child.pid,
96
+ port: 3101,
97
+ sessionFilePath: requestedSessionFilePath,
98
+ }),
99
+ );
100
+
101
+ const result = await prepareDevSessionStart({
102
+ appRoot,
103
+ replaceExisting: true,
104
+ sessionFilePath: requestedSessionFilePath,
105
+ });
106
+
107
+ assert.equal(result.blocking.length, 0);
108
+ assert.equal(result.replaced?.stopped, true);
109
+ assert.equal(fs.existsSync(requestedSessionFilePath), false);
110
+ } finally {
111
+ if (child.exitCode === null && child.signalCode === null) child.kill('SIGKILL');
112
+ }
113
+ });
@@ -5,7 +5,6 @@ const net = require('node:net');
5
5
  const os = require('node:os');
6
6
  const path = require('node:path');
7
7
  const { spawn } = require('node:child_process');
8
- const test = require('node:test');
9
8
 
10
9
  const coreRoot = path.resolve(__dirname, '..');
11
10
  const cliBin = path.join(coreRoot, 'cli', 'bin.js');
@@ -1,5 +1,4 @@
1
1
  const assert = require('node:assert/strict');
2
- const test = require('node:test');
3
2
  const { Linter } = require('eslint');
4
3
 
5
4
  const { createProteumEslintConfig } = require('../eslint.js');
@@ -1,6 +1,5 @@
1
1
  const assert = require('node:assert/strict');
2
2
  const path = require('node:path');
3
- const test = require('node:test');
4
3
 
5
4
  const coreRoot = path.resolve(__dirname, '..');
6
5
  process.env.TS_NODE_PROJECT = path.join(coreRoot, 'cli', 'tsconfig.json');