@programinglive/dev-workflow-mcp-server 1.8.0 → 1.9.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 (106) hide show
  1. package/.env.example +21 -1
  2. package/AGENTS.md +25 -0
  3. package/README.md +257 -664
  4. package/index.js +5 -4
  5. package/package.json +11 -6
  6. package/scripts/bootstrap-unix.sh +55 -0
  7. package/scripts/bootstrap-windows.ps1 +75 -0
  8. package/scripts/install-husky.js +43 -0
  9. package/scripts/setup-stack.js +436 -0
  10. package/tools/definitions.js +19 -0
  11. package/tools/handler-modules/commit-handlers.js +2 -1
  12. package/tools/handler-modules/index.js +13 -7
  13. package/tools/handler-modules/shared.js +7 -41
  14. package/tools/handler-modules/status-handlers.js +3 -1
  15. package/tools/handler-modules/workflow-handlers.js +26 -8
  16. package/workflow-state.js +10 -0
  17. package/.agent/workflows/dev-workflow-bugfix.md +0 -250
  18. package/.agent/workflows/dev-workflow-feature.md +0 -201
  19. package/.agent/workflows/dev-workflow-full-cycle.md +0 -400
  20. package/.agent/workflows/dev-workflow-refactor.md +0 -238
  21. package/.env.production +0 -16
  22. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -34
  23. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -25
  24. package/.github/pull_request_template.md +0 -22
  25. package/.github/workflows/github-release.yml +0 -131
  26. package/.husky/commit-msg +0 -3
  27. package/.husky/pre-commit +0 -2
  28. package/CHANGELOG.md +0 -1137
  29. package/docs/GCP_DEPLOYMENT.md +0 -298
  30. package/docs/NETLIFY_DEPLOYMENT.md +0 -125
  31. package/docs/PLESK_DEPLOYMENT.md +0 -170
  32. package/docs/PRD.md +0 -83
  33. package/docs/WORKFLOW-BEST-PRACTICES.md +0 -58
  34. package/docs/antigravity/EXAMPLES.md +0 -535
  35. package/docs/antigravity/GETTING-STARTED.md +0 -292
  36. package/docs/antigravity/TROUBLESHOOTING.md +0 -742
  37. package/docs/antigravity/WALKTHROUGH.md +0 -25
  38. package/docs/antigravity/WORKFLOW-TEMPLATES.md +0 -670
  39. package/docs/release-notes/RELEASE_NOTES.md +0 -516
  40. package/docs/web-dashboard.md +0 -175
  41. package/tailwind.config.js +0 -8
  42. package/tests/build.test.js +0 -74
  43. package/tests/db-adapters.test.js +0 -108
  44. package/tests/env-support.test.js +0 -46
  45. package/tests/exec.test.js +0 -35
  46. package/tests/handlers-commit.test.js +0 -174
  47. package/tests/handlers-release.test.js +0 -212
  48. package/tests/handlers-workflow.test.js +0 -68
  49. package/tests/handlers.test.js +0 -1142
  50. package/tests/hello-world.test.js +0 -13
  51. package/tests/mcpRegistry.test.js +0 -65
  52. package/tests/patch-release.test.js +0 -7
  53. package/tests/release-wrapper.test.js +0 -107
  54. package/tests/startup-resilience.test.js +0 -73
  55. package/tests/test-helpers.js +0 -50
  56. package/tests/workflowState.test.js +0 -520
  57. package/web/Dockerfile.api +0 -25
  58. package/web/README.md +0 -133
  59. package/web/__tests__/api/workflow-history.test.js +0 -63
  60. package/web/api-server.js +0 -211
  61. package/web/app/docs/page.tsx +0 -202
  62. package/web/app/favicon.ico +0 -0
  63. package/web/app/globals.css +0 -91
  64. package/web/app/history/page.tsx +0 -220
  65. package/web/app/layout.tsx +0 -39
  66. package/web/app/login/page.tsx +0 -142
  67. package/web/app/page.tsx +0 -13
  68. package/web/components/ApiReference.tsx +0 -20
  69. package/web/components/Features.tsx +0 -61
  70. package/web/components/Footer.tsx +0 -9
  71. package/web/components/Hero.tsx +0 -96
  72. package/web/components/History.tsx +0 -175
  73. package/web/components/Navbar.tsx +0 -208
  74. package/web/components/Terminal.tsx +0 -114
  75. package/web/components/ThemeProvider.tsx +0 -58
  76. package/web/eslint.config.mjs +0 -18
  77. package/web/lib/api-client.ts +0 -123
  78. package/web/lib/auth.js +0 -75
  79. package/web/lib/db.js +0 -131
  80. package/web/lib/docs.js +0 -73
  81. package/web/middleware/auth.js +0 -26
  82. package/web/netlify.toml +0 -8
  83. package/web/next.config.ts +0 -19
  84. package/web/package-lock.json +0 -10911
  85. package/web/package.json +0 -42
  86. package/web/postcss.config.mjs +0 -9
  87. package/web/public/assets/android-chrome-192x192.png +0 -0
  88. package/web/public/assets/android-chrome-512x512.png +0 -0
  89. package/web/public/assets/apple-touch-icon.png +0 -0
  90. package/web/public/assets/favicon-16x16.png +0 -0
  91. package/web/public/assets/favicon-32x32.png +0 -0
  92. package/web/public/assets/favicon.ico +0 -0
  93. package/web/public/assets/favicon.png +0 -0
  94. package/web/public/assets/logo.png +0 -0
  95. package/web/public/assets/og-preview.png +0 -0
  96. package/web/public/assets/site.webmanifest +0 -1
  97. package/web/public/file.svg +0 -1
  98. package/web/public/globe.svg +0 -1
  99. package/web/public/next.svg +0 -1
  100. package/web/public/vercel.svg +0 -1
  101. package/web/public/window.svg +0 -1
  102. package/web/scripts/db-query-history.js +0 -120
  103. package/web/scripts/smoke-test.js +0 -30
  104. package/web/server.js +0 -184
  105. package/web/tailwind.config.ts +0 -20
  106. package/web/tsconfig.json +0 -42
package/web/package.json DELETED
@@ -1,42 +0,0 @@
1
- {
2
- "name": "web",
3
- "version": "1.7.15",
4
- "private": true,
5
- "type": "module",
6
- "scripts": {
7
- "dev": "node server.js",
8
- "build": "next build",
9
- "start": "cross-env NODE_ENV=production node server.js",
10
- "lint": "next lint"
11
- },
12
- "dependencies": {
13
- "bcrypt": "^6.0.0",
14
- "connect-pg-simple": "^10.0.0",
15
- "cors": "^2.8.5",
16
- "dotenv": "^17.2.3",
17
- "express": "^5.2.1",
18
- "express-session": "^1.18.2",
19
- "jsonwebtoken": "^9.0.3",
20
- "lucide-react": "^0.555.0",
21
- "next": "^16.0.10",
22
- "pg": "^8.16.3",
23
- "react": "19.2.0",
24
- "react-dom": "19.2.0"
25
- },
26
- "devDependencies": {
27
- "@netlify/plugin-nextjs": "^5.15.2",
28
- "@types/node": "^20",
29
- "@types/pg": "^8.16.0",
30
- "@types/react": "^19",
31
- "@types/react-dom": "^19",
32
- "autoprefixer": "^10.4.22",
33
- "cross-env": "^10.1.0",
34
- "eslint": "^9",
35
- "eslint-config-next": "16.0.4",
36
- "jest": "^30.2.0",
37
- "postcss": "^8.5.6",
38
- "supertest": "^7.1.4",
39
- "tailwindcss": "^3.4.18",
40
- "typescript": "^5"
41
- }
42
- }
@@ -1,9 +0,0 @@
1
- /** @type {import('postcss-load-config').Config} */
2
- const config = {
3
- plugins: {
4
- tailwindcss: {},
5
- autoprefixer: {},
6
- },
7
- };
8
-
9
- export default config;
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1 +0,0 @@
1
- {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
@@ -1 +0,0 @@
1
- <svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
@@ -1 +0,0 @@
1
- <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
@@ -1 +0,0 @@
1
- <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
@@ -1 +0,0 @@
1
- <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
@@ -1,120 +0,0 @@
1
- import pg from 'pg';
2
- import path from 'path';
3
- import fs from 'fs';
4
- import { fileURLToPath } from 'url';
5
- import dotenv from 'dotenv';
6
- import { createRequire } from 'module';
7
-
8
- const require = createRequire(import.meta.url);
9
- const { Pool } = pg;
10
-
11
- const __filename = fileURLToPath(import.meta.url);
12
- const __dirname = path.dirname(__filename);
13
-
14
- // Silence stdout during dotenv loading to prevent noise in API output
15
- const originalWrite = process.stdout.write;
16
- process.stdout.write = () => true; // No-op
17
-
18
- try {
19
- // Try web/.env
20
- dotenv.config({ path: path.join(__dirname, '../.env') });
21
- // Try root .env
22
- dotenv.config({ path: path.join(__dirname, '../../.env') });
23
- } catch (e) {
24
- // dotenv might not be available
25
- } finally {
26
- // Restore stdout
27
- process.stdout.write = originalWrite;
28
- }
29
-
30
- const defaultUrl = 'postgres://devworkflow:devworkflow_secure_password_change_me@localhost:5432/devworkflow';
31
- const connectionString = process.env.DEV_WORKFLOW_DB_URL || defaultUrl;
32
- const rawSid = process.argv[2]; // Passed from API
33
-
34
- // DEBUG: output connection details to stderr (so it doesn't break JSON on stdout)
35
- try {
36
- const urlStr = connectionString.startsWith('postgres') ? connectionString : `postgres://${connectionString}`; // handle simpler strings if needed
37
- // Simple heuristic parsing or URL object
38
- const u = new URL(urlStr);
39
- console.error(`DEBUG: Connecting to Host: ${u.hostname}, Port: ${u.port}, User: ${u.username}`);
40
- } catch (err) {
41
- console.error('DEBUG: Could not parse connection string for logging');
42
- }
43
-
44
- if (!connectionString) {
45
- // Should be unreachable with defaultUrl, but good for safety
46
- console.error(JSON.stringify({ error: 'Database configuration missing' }));
47
- process.exit(1);
48
- }
49
-
50
- const pool = new Pool({ connectionString });
51
-
52
- async function run() {
53
- try {
54
- let userId = null;
55
-
56
- // 1. Validate Session if provided
57
- if (rawSid) {
58
- // Parse 's:session_id.signature' -> 'session_id'
59
- // Simplified logic: between 's:' and '.'
60
- let sid = rawSid;
61
- if (rawSid.startsWith('s:')) {
62
- sid = rawSid.slice(2, rawSid.lastIndexOf('.'));
63
- } else if (rawSid.includes('.')) {
64
- // heuristic for signed cookie without s: prefix?
65
- sid = rawSid.slice(0, rawSid.lastIndexOf('.'));
66
- }
67
-
68
- // Try lookup
69
- const sessionRes = await pool.query("SELECT sess FROM session WHERE sid = $1", [sid]);
70
- if (sessionRes.rows.length > 0) {
71
- const sessionData = sessionRes.rows[0].sess;
72
- if (sessionData && sessionData.userId) {
73
- userId = sessionData.userId;
74
- }
75
- }
76
- }
77
-
78
- // 2. Fallback if no valid session found (for dev/recovery comfort)
79
- if (!userId) {
80
- // Try admin
81
- const userRes = await pool.query("SELECT id FROM users WHERE LOWER(username) = 'admin'");
82
- if (userRes.rows.length > 0) {
83
- userId = userRes.rows[0].id;
84
- } else {
85
- const anyUser = await pool.query("SELECT id FROM users LIMIT 1");
86
- if (anyUser.rows.length > 0) {
87
- userId = anyUser.rows[0].id;
88
- } else {
89
- throw new Error('No user found');
90
- }
91
- }
92
- }
93
-
94
- // 3. (Self-healing removed as it was causing schema errors)
95
-
96
- const result = await pool.query(`
97
- SELECT
98
- id,
99
- task_type,
100
- description,
101
- commit_message,
102
- completed_at,
103
- tests_passed,
104
- documentation_type
105
- FROM workflow_history
106
- WHERE user_id = $1
107
- ORDER BY completed_at DESC LIMIT 100
108
- `, [userId]);
109
-
110
- console.log(JSON.stringify({ history: result.rows }));
111
-
112
- } catch (error) {
113
- console.error(JSON.stringify({ error: error.message, stack: error.stack }));
114
- process.exit(1);
115
- } finally {
116
- await pool.end();
117
- }
118
- }
119
-
120
- run();
@@ -1,30 +0,0 @@
1
- import fs from 'fs';
2
- import { execSync } from 'child_process';
3
- import path from 'path';
4
- import { fileURLToPath } from 'url';
5
-
6
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
- const rootDir = path.join(__dirname, '..');
8
-
9
- console.log('Running smoke tests...');
10
-
11
- try {
12
- // 1. Verify package.json type: module
13
- const packageJsonPath = path.join(rootDir, 'package.json');
14
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
15
- if (packageJson.type !== 'module') {
16
- throw new Error('FAIL: package.json must have "type": "module"');
17
- }
18
- console.log('✅ package.json has "type": "module"');
19
-
20
- // 2. Syntax check server.js
21
- const serverJsPath = path.join(rootDir, 'server.js');
22
- execSync(`node -c "${serverJsPath}"`, { stdio: 'inherit' });
23
- console.log('✅ server.js syntax check passed');
24
-
25
- console.log('All smoke tests passed!');
26
- process.exit(0);
27
- } catch (error) {
28
- console.error('❌ Smoke test failed:', error.message);
29
- process.exit(1);
30
- }
package/web/server.js DELETED
@@ -1,184 +0,0 @@
1
- import { createServer } from 'http';
2
- import { parse } from 'url';
3
- import next from 'next';
4
- import express from 'express';
5
- import session from 'express-session';
6
- import connectPgSimple from 'connect-pg-simple';
7
- import pg from 'pg';
8
- import dotenv from 'dotenv';
9
- import path from 'path';
10
- import { fileURLToPath } from 'url';
11
-
12
- const __filename = fileURLToPath(import.meta.url);
13
- const __dirname = path.dirname(__filename);
14
-
15
- // Load env from root
16
- dotenv.config({ path: path.resolve(__dirname, '../.env') });
17
-
18
- const pgSession = connectPgSimple(session);
19
- const { Pool } = pg;
20
-
21
- const dev = process.env.NODE_ENV !== 'production';
22
- const hostname = 'localhost';
23
- const port = process.env.PORT || 3000;
24
-
25
- // Initialize PostgreSQL pool for sessions
26
- const dbUrl = process.env.DEV_WORKFLOW_DB_URL;
27
- const pool = dbUrl ? new Pool({ connectionString: dbUrl }) : null;
28
-
29
- // Initialize Next.js app
30
- const app = next({ dev, hostname, port });
31
- const handle = app.getRequestHandler();
32
-
33
- // Import auth utilities
34
- let authenticateUser, getUserById;
35
- if (pool) {
36
- import('./lib/auth.js').then(module => {
37
- authenticateUser = module.authenticateUser;
38
- getUserById = module.getUserById;
39
- });
40
- }
41
-
42
- app.prepare().then(() => {
43
- const server = express();
44
-
45
- server.use(express.json());
46
- server.use(express.urlencoded({ extended: true }));
47
-
48
- // Session middleware
49
- if (pool) {
50
- server.use(
51
- session({
52
- store: new pgSession({
53
- pool,
54
- tableName: 'session'
55
- }),
56
- secret: process.env.SESSION_SECRET || 'dev-workflow-secret-change-in-production',
57
- resave: false,
58
- saveUninitialized: false,
59
- cookie: {
60
- maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
61
- httpOnly: true,
62
- secure: process.env.NODE_ENV === 'production'
63
- }
64
- })
65
- );
66
- }
67
-
68
- // Auth API routes
69
- server.post('/api/auth/login', async (req, res) => {
70
- if (!pool || !authenticateUser) {
71
- return res.status(500).json({ error: 'Database not configured' });
72
- }
73
-
74
- const { username, password } = req.body;
75
-
76
- if (!username || !password) {
77
- return res.status(400).json({ error: 'Username and password required' });
78
- }
79
-
80
- try {
81
- const user = await authenticateUser(pool, username, password);
82
-
83
- if (!user) {
84
- return res.status(401).json({ error: 'Invalid credentials' });
85
- }
86
-
87
- req.session.userId = user.id;
88
- req.session.username = user.username;
89
-
90
- res.json({ success: true, user: { username: user.username, email: user.email } });
91
- } catch (error) {
92
- console.error('Login error:', error);
93
- res.status(500).json({ error: 'Internal server error' });
94
- }
95
- });
96
-
97
- server.post('/api/auth/logout', (req, res) => {
98
- req.session.destroy((err) => {
99
- if (err) {
100
- return res.status(500).json({ error: 'Logout failed' });
101
- }
102
- res.json({ success: true });
103
- });
104
- });
105
-
106
- server.get('/api/auth/me', async (req, res) => {
107
- if (!req.session || !req.session.userId) {
108
- return res.status(401).json({ error: 'Not authenticated' });
109
- }
110
-
111
- if (!pool || !getUserById) {
112
- return res.status(500).json({ error: 'Database not configured' });
113
- }
114
-
115
- try {
116
- const user = await getUserById(pool, req.session.userId);
117
-
118
- if (!user) {
119
- return res.status(404).json({ error: 'User not found' });
120
- }
121
-
122
- res.json({ user: { username: user.username, email: user.email } });
123
- } catch (error) {
124
- console.error('Get user error:', error);
125
- res.status(500).json({ error: 'Internal server error' });
126
- }
127
- });
128
-
129
- // Get workflow history
130
- server.get('/api/workflow/history', async (req, res) => {
131
- if (!req.session || !req.session.userId) {
132
- return res.status(401).json({ error: 'Not authenticated' });
133
- }
134
-
135
- if (!pool) {
136
- return res.status(500).json({ error: 'Database not configured' });
137
- }
138
-
139
- try {
140
- // Get user details to filter history
141
- // We assume workflow_history.user_id stores the username (based on schema)
142
- // We use userId (integer) to query the foreign key column
143
- const userId = req.session.userId;
144
-
145
- let query = `
146
- SELECT
147
- id,
148
- task_type,
149
- task_description as description,
150
- commit_message,
151
- timestamp as completed_at,
152
- tests_passed,
153
- documentation_type
154
- FROM workflow_history
155
- `;
156
-
157
- const params = [];
158
-
159
- if (userId) {
160
- query += ` WHERE user_id = $1 `;
161
- params.push(userId);
162
- }
163
-
164
- query += ` ORDER BY timestamp DESC LIMIT 100`;
165
-
166
- const result = await pool.query(query, params);
167
-
168
- res.json({ history: result.rows });
169
- } catch (error) {
170
- console.error('Get history error:', error);
171
- res.status(500).json({ error: 'Internal server error' });
172
- }
173
- });
174
-
175
- // Next.js handler for all other routes
176
- server.all('*', (req, res) => {
177
- return handle(req, res);
178
- });
179
-
180
- server.listen(port, (err) => {
181
- if (err) throw err;
182
- console.log(`> Ready on http://${hostname}:${port}`);
183
- });
184
- });
@@ -1,20 +0,0 @@
1
- import type { Config } from "tailwindcss";
2
-
3
- const config: Config = {
4
- content: [
5
- "./pages/**/*.{js,ts,jsx,tsx,mdx}",
6
- "./components/**/*.{js,ts,jsx,tsx,mdx}",
7
- "./app/**/*.{js,ts,jsx,tsx,mdx}",
8
- ],
9
- darkMode: "class",
10
- theme: {
11
- extend: {
12
- colors: {
13
- background: "var(--background)",
14
- foreground: "var(--foreground)",
15
- },
16
- },
17
- },
18
- plugins: [],
19
- };
20
- export default config;
package/web/tsconfig.json DELETED
@@ -1,42 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2017",
4
- "lib": [
5
- "dom",
6
- "dom.iterable",
7
- "esnext"
8
- ],
9
- "allowJs": true,
10
- "skipLibCheck": true,
11
- "strict": true,
12
- "noEmit": true,
13
- "esModuleInterop": true,
14
- "module": "esnext",
15
- "moduleResolution": "bundler",
16
- "resolveJsonModule": true,
17
- "isolatedModules": true,
18
- "jsx": "react-jsx",
19
- "incremental": true,
20
- "plugins": [
21
- {
22
- "name": "next"
23
- }
24
- ],
25
- "paths": {
26
- "@/*": [
27
- "./*"
28
- ]
29
- }
30
- },
31
- "include": [
32
- "next-env.d.ts",
33
- "**/*.ts",
34
- "**/*.tsx",
35
- ".next/types/**/*.ts",
36
- ".next/dev/types/**/*.ts",
37
- "**/*.mts"
38
- ],
39
- "exclude": [
40
- "node_modules"
41
- ]
42
- }