crewx 0.8.3-rc.4 → 0.8.3-rc.6

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/bin/crewx-ui.js CHANGED
File without changes
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ // @vitest-environment node
7
+ const vitest_1 = require("vitest");
8
+ const testing_1 = require("@nestjs/testing");
9
+ const common_1 = require("@nestjs/common");
10
+ const express_1 = __importDefault(require("express"));
11
+ const supertest_1 = __importDefault(require("supertest"));
12
+ const fs_1 = require("fs");
13
+ const path_1 = require("path");
14
+ const os_1 = require("os");
15
+ const app_module_js_1 = require("../../app.module.js");
16
+ const VALID_PATH = 'docs/test-save.md';
17
+ const VALID_CONTENT = '# Hello World';
18
+ let testWorkspace;
19
+ function makeTempWorkspace() {
20
+ const dir = (0, path_1.join)((0, os_1.tmpdir)(), `doc-e2e-${Date.now()}-${Math.random().toString(36).slice(2)}`);
21
+ (0, fs_1.mkdirSync)(dir, { recursive: true });
22
+ (0, fs_1.mkdirSync)((0, path_1.join)(dir, 'docs'), { recursive: true });
23
+ (0, fs_1.mkdirSync)((0, path_1.join)(dir, 'skills'), { recursive: true });
24
+ return dir;
25
+ }
26
+ (0, vitest_1.describe)('DOC.SAVE (PUT /api/v1/docs/content) e2e', () => {
27
+ let app;
28
+ (0, vitest_1.beforeAll)(async () => {
29
+ testWorkspace = makeTempWorkspace();
30
+ process.env.CREWX_WORKSPACE = testWorkspace;
31
+ const module = await testing_1.Test.createTestingModule({ imports: [app_module_js_1.AppModule] }).compile();
32
+ app = module.createNestApplication();
33
+ app.use((req, res, next) => {
34
+ if (req.url.startsWith('/adapters/')) {
35
+ return next();
36
+ }
37
+ return express_1.default.json({ limit: '5mb' })(req, res, next);
38
+ });
39
+ app.useGlobalPipes(new common_1.ValidationPipe({ whitelist: true, transform: true }));
40
+ app.setGlobalPrefix('api/v1', { exclude: ['mcp', 'mcp/health'] });
41
+ await app.init();
42
+ });
43
+ (0, vitest_1.afterAll)(async () => {
44
+ await app.close();
45
+ delete process.env.CREWX_WORKSPACE;
46
+ if ((0, fs_1.existsSync)(testWorkspace)) {
47
+ (0, fs_1.rmSync)(testWorkspace, { recursive: true, force: true });
48
+ }
49
+ });
50
+ (0, vitest_1.beforeEach)(() => {
51
+ const filePath = (0, path_1.join)(testWorkspace, VALID_PATH);
52
+ (0, fs_1.mkdirSync)((0, path_1.join)(testWorkspace, 'docs'), { recursive: true });
53
+ (0, fs_1.writeFileSync)(filePath, VALID_CONTENT, 'utf-8');
54
+ });
55
+ (0, vitest_1.afterEach)(() => {
56
+ const filePath = (0, path_1.join)(testWorkspace, VALID_PATH);
57
+ if ((0, fs_1.existsSync)(filePath)) {
58
+ (0, fs_1.rmSync)(filePath, { force: true });
59
+ }
60
+ });
61
+ (0, vitest_1.it)('returns 200 on successful save', async () => {
62
+ const filePath = (0, path_1.join)(testWorkspace, VALID_PATH);
63
+ const mtime = (0, fs_1.statSync)(filePath).mtimeMs;
64
+ const res = await (0, supertest_1.default)(app.getHttpServer())
65
+ .put('/api/v1/docs/content')
66
+ .send({ path: VALID_PATH, content: '# Updated', mtime });
67
+ (0, vitest_1.expect)(res.status).toBe(200);
68
+ (0, vitest_1.expect)(res.body.success).toBe(true);
69
+ (0, vitest_1.expect)(res.body.data.path).toBe(VALID_PATH);
70
+ (0, vitest_1.expect)(typeof res.body.data.mtime).toBe('number');
71
+ });
72
+ (0, vitest_1.it)('returns 409 on mtime mismatch', async () => {
73
+ const staleMtime = 0;
74
+ const res = await (0, supertest_1.default)(app.getHttpServer())
75
+ .put('/api/v1/docs/content')
76
+ .send({ path: VALID_PATH, content: '# Conflict', mtime: staleMtime });
77
+ (0, vitest_1.expect)(res.status).toBe(409);
78
+ (0, vitest_1.expect)(res.body.error).toBe('CONFLICT');
79
+ });
80
+ (0, vitest_1.it)('returns 400 on path traversal', async () => {
81
+ const res = await (0, supertest_1.default)(app.getHttpServer())
82
+ .put('/api/v1/docs/content')
83
+ .send({ path: '../../etc/passwd', content: 'hacked', mtime: 0 });
84
+ (0, vitest_1.expect)(res.status).toBe(400);
85
+ (0, vitest_1.expect)(res.body.message).toContain('Path traversal');
86
+ });
87
+ (0, vitest_1.it)('returns 400 on .ts extension', async () => {
88
+ const tsPath = (0, path_1.join)(testWorkspace, 'src', 'index.ts');
89
+ (0, fs_1.mkdirSync)((0, path_1.join)(testWorkspace, 'src'), { recursive: true });
90
+ (0, fs_1.writeFileSync)(tsPath, 'console.log("hi")', 'utf-8');
91
+ const res = await (0, supertest_1.default)(app.getHttpServer())
92
+ .put('/api/v1/docs/content')
93
+ .send({ path: 'src/index.ts', content: 'new code', mtime: 0 });
94
+ (0, vitest_1.expect)(res.status).toBe(400);
95
+ (0, vitest_1.expect)(res.body.message).toContain('.md');
96
+ (0, fs_1.rmSync)(tsPath, { force: true });
97
+ });
98
+ (0, vitest_1.it)('returns 400 on content exceeding 2MB', async () => {
99
+ const filePath = (0, path_1.join)(testWorkspace, VALID_PATH);
100
+ const mtime = (0, fs_1.statSync)(filePath).mtimeMs;
101
+ const bigContent = 'x'.repeat(2 * 1024 * 1024 + 1);
102
+ const res = await (0, supertest_1.default)(app.getHttpServer())
103
+ .put('/api/v1/docs/content')
104
+ .send({ path: VALID_PATH, content: bigContent, mtime });
105
+ (0, vitest_1.expect)(res.status).toBe(400);
106
+ (0, vitest_1.expect)(res.body.message).toContain('2MB');
107
+ });
108
+ (0, vitest_1.it)('returns 400 on empty content', async () => {
109
+ const filePath = (0, path_1.join)(testWorkspace, VALID_PATH);
110
+ const mtime = (0, fs_1.statSync)(filePath).mtimeMs;
111
+ const res = await (0, supertest_1.default)(app.getHttpServer())
112
+ .put('/api/v1/docs/content')
113
+ .send({ path: VALID_PATH, content: '', mtime });
114
+ (0, vitest_1.expect)(res.status).toBe(400);
115
+ (0, vitest_1.expect)(res.body.message).toContain('Empty content');
116
+ });
117
+ (0, vitest_1.it)('returns 400 when body is missing (DTO empty)', async () => {
118
+ const res = await (0, supertest_1.default)(app.getHttpServer())
119
+ .put('/api/v1/docs/content')
120
+ .send({})
121
+ .set('Content-Type', 'application/json');
122
+ (0, vitest_1.expect)(res.status).toBe(400);
123
+ });
124
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crewx",
3
- "version": "0.8.3-rc.4",
3
+ "version": "0.8.3-rc.6",
4
4
  "description": "CrewX — AI agent team dashboard with Electron UI and CLI (Web + Electron + Global CLI)",
5
5
  "main": "server.js",
6
6
  "bin": {
@@ -24,8 +24,49 @@
24
24
  "email": "doha.park@sowonlabs.com"
25
25
  },
26
26
  "license": "UNLICENSED",
27
+ "packageManager": "pnpm@9.15.0",
28
+ "scripts": {
29
+ "dev": "pm2 start ecosystem.dev.config.cjs",
30
+ "dev:stop": "pm2 stop crewx-server crewx-ui",
31
+ "dev:restart": "pm2 restart crewx-server crewx-ui",
32
+ "dev:logs": "pm2 logs crewx-server crewx-ui",
33
+ "dev:status": "pm2 list | grep crewx",
34
+ "dev:server": "nest start --watch",
35
+ "dev:ui": "vite",
36
+ "dev:electron": "ELECTRON=true vite",
37
+ "build:sdk": "pnpm -F @crewx/sdk run build",
38
+ "db:generate": "pnpm -F @crewx/sdk run db:generate",
39
+ "db:check": "pnpm -F @crewx/sdk run db:check",
40
+ "build:built-in": "pnpm -r --filter './packages/built-in/*' run build",
41
+ "build": "pnpm run build:sdk && pnpm run build:built-in && pnpm run build:cli && pnpm run build:server && pnpm run build:ui",
42
+ "build:cli": "cd packages/cli && npm run build",
43
+ "build:server": "tsc -p tsconfig.server.json && node scripts/emit-dist-server-package-json.mjs",
44
+ "build:ui": "vite build",
45
+ "build:web": "npm run build",
46
+ "build:electron": "ELECTRON=true vite build && npm run build:server && electron-builder",
47
+ "preview": "vite preview",
48
+ "lint": "eslint src --ext .ts,.tsx",
49
+ "test": "vitest run --config vitest.packages.config.ts && vitest run --config vitest.server.config.ts",
50
+ "test:all": "vitest run && vitest run --config vitest.server.config.ts",
51
+ "test:watch": "vitest",
52
+ "test:ui": "vitest run",
53
+ "test:server": "vitest run --config vitest.server.config.ts",
54
+ "type-check": "tsc --noEmit",
55
+ "build:manual": "node scripts/build-manual.mjs"
56
+ },
27
57
  "dependencies": {
28
58
  "@ccusage/codex": "^0.0.1",
59
+ "@crewx/cli": "workspace:*",
60
+ "@crewx/cron": "workspace:*",
61
+ "@crewx/doc": "workspace:*",
62
+ "@crewx/knowledge-core": "workspace:*",
63
+ "@crewx/memory": "workspace:*",
64
+ "@crewx/sdk": "workspace:*",
65
+ "@crewx/search": "workspace:*",
66
+ "@crewx/shared": "workspace:*",
67
+ "@crewx/skill": "workspace:*",
68
+ "@crewx/wbs": "workspace:*",
69
+ "@crewx/workflow": "workspace:*",
29
70
  "@modelcontextprotocol/sdk": "^1.0.0",
30
71
  "@nestjs/common": "^11.0.0",
31
72
  "@nestjs/config": "^4.0.3",
@@ -94,18 +135,7 @@
94
135
  "wink-nlp-utils": "^2.1.0",
95
136
  "yargs": "^17.7.0",
96
137
  "zod": "^3.22.0",
97
- "zustand": "^4.5.0",
98
- "@crewx/cli": "0.8.3-rc.4",
99
- "@crewx/cron": "0.1.7",
100
- "@crewx/knowledge-core": "0.1.5",
101
- "@crewx/doc": "0.1.7",
102
- "@crewx/sdk": "0.8.3-rc.1",
103
- "@crewx/memory": "0.1.9",
104
- "@crewx/search": "0.1.8",
105
- "@crewx/shared": "0.0.4",
106
- "@crewx/skill": "0.1.7",
107
- "@crewx/workflow": "0.3.13",
108
- "@crewx/wbs": "0.1.8"
138
+ "zustand": "^4.5.0"
109
139
  },
110
140
  "devDependencies": {
111
141
  "@nestjs/cli": "^11.0.16",
@@ -183,34 +213,5 @@
183
213
  "portable"
184
214
  ]
185
215
  }
186
- },
187
- "scripts": {
188
- "dev": "pm2 start ecosystem.dev.config.cjs",
189
- "dev:stop": "pm2 stop crewx-server crewx-ui",
190
- "dev:restart": "pm2 restart crewx-server crewx-ui",
191
- "dev:logs": "pm2 logs crewx-server crewx-ui",
192
- "dev:status": "pm2 list | grep crewx",
193
- "dev:server": "nest start --watch",
194
- "dev:ui": "vite",
195
- "dev:electron": "ELECTRON=true vite",
196
- "build:sdk": "pnpm -F @crewx/sdk run build",
197
- "db:generate": "pnpm -F @crewx/sdk run db:generate",
198
- "db:check": "pnpm -F @crewx/sdk run db:check",
199
- "build:built-in": "pnpm -r --filter './packages/built-in/*' run build",
200
- "build": "pnpm run build:sdk && pnpm run build:built-in && pnpm run build:cli && pnpm run build:server && pnpm run build:ui",
201
- "build:cli": "cd packages/cli && npm run build",
202
- "build:server": "tsc -p tsconfig.server.json && node scripts/emit-dist-server-package-json.mjs",
203
- "build:ui": "vite build",
204
- "build:web": "npm run build",
205
- "build:electron": "ELECTRON=true vite build && npm run build:server && electron-builder",
206
- "preview": "vite preview",
207
- "lint": "eslint src --ext .ts,.tsx",
208
- "test": "vitest run --config vitest.packages.config.ts && vitest run --config vitest.server.config.ts",
209
- "test:all": "vitest run && vitest run --config vitest.server.config.ts",
210
- "test:watch": "vitest",
211
- "test:ui": "vitest run",
212
- "test:server": "vitest run --config vitest.server.config.ts",
213
- "type-check": "tsc --noEmit",
214
- "build:manual": "node scripts/build-manual.mjs"
215
216
  }
216
- }
217
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewx/cli",
3
- "version": "0.8.3-rc.4",
3
+ "version": "0.8.3-rc.6",
4
4
  "license": "UNLICENSED",
5
5
  "engines": {
6
6
  "node": ">=20.19.0"