crewx 0.8.7-rc.17 → 0.8.7-rc.18
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/dist-server/adapters/adapter.module.js +35 -0
- package/dist-server/adapters/adapter.service.js +79 -0
- package/dist-server/adapters/http-router.service.js +91 -0
- package/dist-server/app.module.js +111 -0
- package/dist-server/bootstrap/crewx-server.js +80 -0
- package/dist-server/bootstrap/tls.js +138 -0
- package/dist-server/common/analytics.client.js +180 -0
- package/dist-server/common/analytics.module.js +21 -0
- package/dist-server/common/cors.js +15 -0
- package/dist-server/common/decorators/project.decorator.js +21 -0
- package/dist-server/common/decorators/workspace.decorator.js +24 -0
- package/dist-server/common/device-id.js +33 -0
- package/dist-server/common/interceptor/api-id-header.interceptor.js +53 -0
- package/dist-server/common/interceptor/http-logging.interceptor.js +124 -0
- package/dist-server/common/limits/defaults.js +13 -0
- package/dist-server/common/limits/limits-provider.js +6 -0
- package/dist-server/common/limits/limits.controller.js +38 -0
- package/dist-server/common/limits/limits.module.js +24 -0
- package/dist-server/common/limits/local-limits.provider.js +27 -0
- package/dist-server/common/middleware/workspace.middleware.js +210 -0
- package/dist-server/common/repository.exception-filter.js +48 -0
- package/dist-server/common/workspace-context.store.js +25 -0
- package/dist-server/domain/agent/agent.controller.js +96 -0
- package/dist-server/domain/agent/agent.module.js +27 -0
- package/dist-server/domain/agent/agent.service.js +335 -0
- package/dist-server/domain/agent/agent.types.js +3 -0
- package/dist-server/domain/agent/dto/create-agent.dto.js +80 -0
- package/dist-server/domain/agent/dto/preview-prompt.dto.js +77 -0
- package/dist-server/domain/agent/dto/provider-meta.dto.js +2 -0
- package/dist-server/domain/agent/dto/update-agent.dto.js +92 -0
- package/dist-server/domain/agent/provider.controller.js +38 -0
- package/dist-server/domain/agent/template-processor.service.js +71 -0
- package/dist-server/domain/auth/auth.constants.js +4 -0
- package/dist-server/domain/auth/auth.controller.js +123 -0
- package/dist-server/domain/auth/auth.module.js +47 -0
- package/dist-server/domain/auth/decorators/public.decorator.js +7 -0
- package/dist-server/domain/auth/guards/base-auth.guard.js +66 -0
- package/dist-server/domain/auth/session-store.js +26 -0
- package/dist-server/domain/auth/utils/ip.utils.js +31 -0
- package/dist-server/domain/box/box.controller.js +77 -0
- package/dist-server/domain/box/box.module.js +21 -0
- package/dist-server/domain/box/box.service.js +97 -0
- package/dist-server/domain/box/dto/create-box.dto.js +74 -0
- package/dist-server/domain/cli/cli.controller.js +136 -0
- package/dist-server/domain/cli/cli.module.js +21 -0
- package/dist-server/domain/cli/cli.service.js +598 -0
- package/dist-server/domain/cli/dto/login-cli.dto.js +25 -0
- package/dist-server/domain/cli/dto/update-cli.dto.js +31 -0
- package/dist-server/domain/doc/doc.controller.js +95 -0
- package/dist-server/domain/doc/doc.module.js +21 -0
- package/dist-server/domain/doc/doc.service.js +368 -0
- package/dist-server/domain/doc/dto/doc.dto.js +64 -0
- package/dist-server/domain/document/document.controller.js +57 -0
- package/dist-server/domain/document/document.module.js +22 -0
- package/dist-server/domain/document/document.service.js +274 -0
- package/dist-server/domain/document/dto/register-document.dto.js +24 -0
- package/dist-server/domain/fs/dto/mkdir-request.dto.js +47 -0
- package/dist-server/domain/fs/dto/mkdir-response.dto.js +2 -0
- package/dist-server/domain/fs/dto/quick-access.dto.js +2 -0
- package/dist-server/domain/fs/dto/tree-node.dto.js +2 -0
- package/dist-server/domain/fs/dto/tree-query.dto.js +35 -0
- package/dist-server/domain/fs/fs.controller.js +63 -0
- package/dist-server/domain/fs/fs.module.js +22 -0
- package/dist-server/domain/fs/fs.service.js +303 -0
- package/dist-server/domain/git/git.module.js +20 -0
- package/dist-server/domain/git/git.service.js +222 -0
- package/dist-server/domain/goal/dto/goal.dto.js +49 -0
- package/dist-server/domain/goal/goal.controller.js +86 -0
- package/dist-server/domain/goal/goal.module.js +22 -0
- package/dist-server/domain/goal/goal.service.js +197 -0
- package/dist-server/domain/goal/parser/goal-md-parser.js +166 -0
- package/dist-server/domain/goal/parser/goal-md-serializer.js +110 -0
- package/dist-server/domain/health/health.controller.js +57 -0
- package/dist-server/domain/health/health.module.js +19 -0
- package/dist-server/domain/knowledge/dto/graph-knowledge.dto.js +27 -0
- package/dist-server/domain/knowledge/dto/knowledge.dto.js +71 -0
- package/dist-server/domain/knowledge/knowledge.controller.js +122 -0
- package/dist-server/domain/knowledge/knowledge.module.js +21 -0
- package/dist-server/domain/knowledge/knowledge.service.js +538 -0
- package/dist-server/domain/market/dto/add-registry.dto.js +32 -0
- package/dist-server/domain/market/dto/install-market.dto.js +30 -0
- package/dist-server/domain/market/market.controller.js +163 -0
- package/dist-server/domain/market/market.module.js +22 -0
- package/dist-server/domain/market/market.service.js +1447 -0
- package/dist-server/domain/mcp/browser-session.store.js +247 -0
- package/dist-server/domain/mcp/crewx-tool.factory.js +119 -0
- package/dist-server/domain/mcp/mcp-auth.guard.js +61 -0
- package/dist-server/domain/mcp/mcp.constants.js +4 -0
- package/dist-server/domain/mcp/mcp.controller.js +125 -0
- package/dist-server/domain/mcp/mcp.dto.js +12 -0
- package/dist-server/domain/mcp/mcp.module.js +49 -0
- package/dist-server/domain/mcp/mcp.service.js +684 -0
- package/dist-server/domain/mcp/tool-router.service.js +120 -0
- package/dist-server/domain/message/dto/list-messages.dto.js +57 -0
- package/dist-server/domain/message/dto/send-message.dto.js +45 -0
- package/dist-server/domain/message/message.controller.js +73 -0
- package/dist-server/domain/message/message.module.js +25 -0
- package/dist-server/domain/message/message.service.js +160 -0
- package/dist-server/domain/onboarding/onboarding.controller.js +97 -0
- package/dist-server/domain/onboarding/onboarding.module.js +23 -0
- package/dist-server/domain/onboarding/onboarding.service.js +106 -0
- package/dist-server/domain/onboarding/onboarding.types.js +2 -0
- package/dist-server/domain/onboarding/presets/custom.js +10 -0
- package/dist-server/domain/onboarding/presets/dev-team.js +41 -0
- package/dist-server/domain/onboarding/presets/index.js +15 -0
- package/dist-server/domain/onboarding/presets/marketing-team.js +29 -0
- package/dist-server/domain/onboarding/presets/planning-team.js +29 -0
- package/dist-server/domain/onboarding/presets/solo.js +17 -0
- package/dist-server/domain/planner/dto/planner.dto.js +58 -0
- package/dist-server/domain/planner/planner.controller.js +74 -0
- package/dist-server/domain/planner/planner.module.js +22 -0
- package/dist-server/domain/planner/planner.service.js +269 -0
- package/dist-server/domain/project/dto/create-project.dto.js +46 -0
- package/dist-server/domain/project/dto/update-project.dto.js +60 -0
- package/dist-server/domain/project/project.controller.js +129 -0
- package/dist-server/domain/project/project.module.js +22 -0
- package/dist-server/domain/project/project.service.js +173 -0
- package/dist-server/domain/settings/settings.controller.js +52 -0
- package/dist-server/domain/settings/settings.module.js +22 -0
- package/dist-server/domain/settings/settings.service.js +105 -0
- package/dist-server/domain/task/dto/all-tasks.dto.js +55 -0
- package/dist-server/domain/task/dto/list-tasks.dto.js +69 -0
- package/dist-server/domain/task/dto/search-tasks.dto.js +66 -0
- package/dist-server/domain/task/dto/send-message.dto.js +31 -0
- package/dist-server/domain/task/dto/task-status.dto.js +34 -0
- package/dist-server/domain/task/dto/workspace-usage.dto.js +38 -0
- package/dist-server/domain/task/task.constants.js +5 -0
- package/dist-server/domain/task/task.controller.js +169 -0
- package/dist-server/domain/task/task.module.js +23 -0
- package/dist-server/domain/task/task.service.js +755 -0
- package/dist-server/domain/thread/dto/build-context.dto.js +42 -0
- package/dist-server/domain/thread/dto/list-messages.dto.js +49 -0
- package/dist-server/domain/thread/dto/list-threads.dto.js +70 -0
- package/dist-server/domain/thread/dto/search-threads.dto.js +13 -0
- package/dist-server/domain/thread/dto/update-thread.dto.js +23 -0
- package/dist-server/domain/thread/thread.controller.js +160 -0
- package/dist-server/domain/thread/thread.module.js +23 -0
- package/dist-server/domain/thread/thread.service.js +419 -0
- package/dist-server/domain/usage/usage.controller.js +118 -0
- package/dist-server/domain/usage/usage.module.js +21 -0
- package/dist-server/domain/usage/usage.service.js +358 -0
- package/dist-server/domain/usage/usage.types.js +4 -0
- package/dist-server/domain/wbs/wbs.controller.js +51 -0
- package/dist-server/domain/wbs/wbs.module.js +21 -0
- package/dist-server/domain/wbs/wbs.service.js +94 -0
- package/dist-server/domain/workflow/workflow.controller.js +53 -0
- package/dist-server/domain/workflow/workflow.module.js +21 -0
- package/dist-server/domain/workflow/workflow.service.js +209 -0
- package/dist-server/domain/workspace/dto/create-workspace.dto.js +45 -0
- package/dist-server/domain/workspace/dto/switch-workspace.dto.js +32 -0
- package/dist-server/domain/workspace/dto/workspace-info.dto.js +2 -0
- package/dist-server/domain/workspace/workspace.controller.js +98 -0
- package/dist-server/domain/workspace/workspace.module.js +22 -0
- package/dist-server/domain/workspace/workspace.service.js +198 -0
- package/dist-server/main.js +203 -0
- package/dist-server/modules/crewx-pool.service.js +75 -0
- package/dist-server/modules/crewx.module.js +47 -0
- package/dist-server/repository/base-sqlite.repository.js +18 -0
- package/dist-server/repository/box.repository.js +99 -0
- package/dist-server/repository/message.repository.js +22 -0
- package/dist-server/repository/project.repository.js +51 -0
- package/dist-server/repository/repository.module.js +34 -0
- package/dist-server/repository/request-log.repository.js +96 -0
- package/dist-server/repository/task.repository.js +101 -0
- package/dist-server/repository/thread.repository.js +165 -0
- package/dist-server/shared/crewx-home.js +58 -0
- package/dist-server/shared/crewx-state.js +66 -0
- package/dist-server/test-utils/compat-database.js +30 -0
- package/dist-server/utils/tokenizer.js +8 -0
- package/package.json +9 -9
- package/packages/cli/package.json +1 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AdapterModule — NestJS module for adapter lifecycle management.
|
|
4
|
+
*
|
|
5
|
+
* Implements OnApplicationBootstrap (start adapters from yaml)
|
|
6
|
+
* and OnApplicationShutdown (stop all adapters with timeout).
|
|
7
|
+
*/
|
|
8
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
9
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
10
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
11
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
12
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
13
|
+
};
|
|
14
|
+
var AdapterModule_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.AdapterModule = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const adapter_service_js_1 = require("./adapter.service.js");
|
|
19
|
+
const http_router_service_js_1 = require("./http-router.service.js");
|
|
20
|
+
let AdapterModule = AdapterModule_1 = class AdapterModule {
|
|
21
|
+
logger = new common_1.Logger(AdapterModule_1.name);
|
|
22
|
+
onApplicationBootstrap() {
|
|
23
|
+
this.logger.log('AdapterModule bootstrap — adapters will be loaded lazily via AdapterService');
|
|
24
|
+
}
|
|
25
|
+
async onApplicationShutdown() {
|
|
26
|
+
this.logger.log('AdapterModule shutdown — stopping all adapters');
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
exports.AdapterModule = AdapterModule;
|
|
30
|
+
exports.AdapterModule = AdapterModule = AdapterModule_1 = __decorate([
|
|
31
|
+
(0, common_1.Module)({
|
|
32
|
+
providers: [adapter_service_js_1.AdapterService, http_router_service_js_1.AdapterHttpRouterService],
|
|
33
|
+
exports: [adapter_service_js_1.AdapterService, http_router_service_js_1.AdapterHttpRouterService],
|
|
34
|
+
})
|
|
35
|
+
], AdapterModule);
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AdapterService — loads adapter configs from crewx.yaml and registers them.
|
|
4
|
+
*
|
|
5
|
+
* V1: yaml auto-load model. Reads `adapters:` section from crewx config.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
24
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
25
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
26
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
27
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
28
|
+
};
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
var AdapterService_1;
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.AdapterService = void 0;
|
|
49
|
+
const common_1 = require("@nestjs/common");
|
|
50
|
+
let AdapterService = AdapterService_1 = class AdapterService {
|
|
51
|
+
logger = new common_1.Logger(AdapterService_1.name);
|
|
52
|
+
async loadFromYaml(crewx, adapters) {
|
|
53
|
+
for (const adapterConf of adapters) {
|
|
54
|
+
try {
|
|
55
|
+
const instanceId = adapterConf.instanceId ?? adapterConf.id;
|
|
56
|
+
this.logger.log(`Loading adapter: ${adapterConf.id} (instance: ${instanceId})`);
|
|
57
|
+
const adapterModule = await Promise.resolve(`${adapterConf.module}`).then(s => __importStar(require(s)));
|
|
58
|
+
const adapter = adapterModule.default ?? adapterModule.adapter;
|
|
59
|
+
if (!adapter) {
|
|
60
|
+
this.logger.error(`Adapter module ${adapterConf.module} has no default export`);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
await crewx.registerChannelAdapter({
|
|
64
|
+
adapter,
|
|
65
|
+
instanceId,
|
|
66
|
+
config: adapterConf.config ?? {},
|
|
67
|
+
});
|
|
68
|
+
this.logger.log(`Adapter ${adapterConf.id} started successfully`);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
this.logger.error(`Failed to load adapter ${adapterConf.id}: ${err instanceof Error ? err.message : String(err)}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
exports.AdapterService = AdapterService;
|
|
77
|
+
exports.AdapterService = AdapterService = AdapterService_1 = __decorate([
|
|
78
|
+
(0, common_1.Injectable)()
|
|
79
|
+
], AdapterService);
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AdapterHttpRouterService — implements HttpRouter.registerRoute for NestJS.
|
|
4
|
+
*
|
|
5
|
+
* M2: raw body handling with bodyParser:false,
|
|
6
|
+
* requireSignature for webhook signature verification,
|
|
7
|
+
* rateLimit per route, timeout handling.
|
|
8
|
+
*
|
|
9
|
+
* Route prefix: /adapters/:adapterId/* (enforced)
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.AdapterHttpRouterService = void 0;
|
|
13
|
+
class AdapterHttpRouterService {
|
|
14
|
+
routes = [];
|
|
15
|
+
rateLimitCounters = new Map();
|
|
16
|
+
registerRoute(adapterId, path, handler, opts) {
|
|
17
|
+
const fullPath = `/adapters/${adapterId}${path}`;
|
|
18
|
+
this.routes.push({ adapterId, path, fullPath, handler, opts });
|
|
19
|
+
}
|
|
20
|
+
getRoutes() {
|
|
21
|
+
return this.routes;
|
|
22
|
+
}
|
|
23
|
+
findRoute(_method, url) {
|
|
24
|
+
for (const route of this.routes) {
|
|
25
|
+
if (url === route.fullPath || url.startsWith(route.fullPath)) {
|
|
26
|
+
return route;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
clearRoutes() {
|
|
32
|
+
this.routes.length = 0;
|
|
33
|
+
this.rateLimitCounters.clear();
|
|
34
|
+
}
|
|
35
|
+
async handleRequest(route, req, res) {
|
|
36
|
+
if (!req.url.startsWith('/adapters/')) {
|
|
37
|
+
res.status(403).json({ error: 'route_prefix_violation' });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (route.opts?.requireSignature) {
|
|
41
|
+
const sig = req.headers[route.opts.requireSignature.headerName];
|
|
42
|
+
const sigStr = Array.isArray(sig) ? sig[0] : sig;
|
|
43
|
+
if (!sigStr || !route.opts.requireSignature.verify(req.body, sigStr)) {
|
|
44
|
+
res.status(401).json({ error: 'invalid_signature' });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (route.opts?.rateLimit) {
|
|
49
|
+
const key = `${route.adapterId}:${route.path}`;
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
const entry = this.rateLimitCounters.get(key);
|
|
52
|
+
const windowMs = 60_000;
|
|
53
|
+
if (!entry || now >= entry.resetAt) {
|
|
54
|
+
this.rateLimitCounters.set(key, { count: 1, resetAt: now + windowMs });
|
|
55
|
+
}
|
|
56
|
+
else if (entry.count >= route.opts.rateLimit.requestsPerMin) {
|
|
57
|
+
res.status(429).json({ error: 'rate_limit_exceeded' });
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
entry.count++;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const timeoutMs = route.opts?.timeoutMs ?? 30_000;
|
|
65
|
+
let settled = false;
|
|
66
|
+
const timeout = setTimeout(() => {
|
|
67
|
+
if (!settled) {
|
|
68
|
+
settled = true;
|
|
69
|
+
res.status(504).json({ error: 'timeout' });
|
|
70
|
+
}
|
|
71
|
+
}, timeoutMs);
|
|
72
|
+
try {
|
|
73
|
+
await route.handler(req, res);
|
|
74
|
+
if (!settled) {
|
|
75
|
+
settled = true;
|
|
76
|
+
clearTimeout(timeout);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
if (!settled) {
|
|
81
|
+
settled = true;
|
|
82
|
+
clearTimeout(timeout);
|
|
83
|
+
res.status(500).json({
|
|
84
|
+
error: 'handler_error',
|
|
85
|
+
message: err instanceof Error ? err.message : String(err),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.AdapterHttpRouterService = AdapterHttpRouterService;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.AppModule = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const core_1 = require("@nestjs/core");
|
|
12
|
+
const throttler_1 = require("@nestjs/throttler");
|
|
13
|
+
const repository_exception_filter_js_1 = require("./common/repository.exception-filter.js");
|
|
14
|
+
const workspace_middleware_js_1 = require("./common/middleware/workspace.middleware.js");
|
|
15
|
+
const config_1 = require("@nestjs/config");
|
|
16
|
+
const cli_module_js_1 = require("./domain/cli/cli.module.js");
|
|
17
|
+
const usage_module_js_1 = require("./domain/usage/usage.module.js");
|
|
18
|
+
const task_module_js_1 = require("./domain/task/task.module.js");
|
|
19
|
+
const mcp_module_js_1 = require("./domain/mcp/mcp.module.js");
|
|
20
|
+
const agent_module_js_1 = require("./domain/agent/agent.module.js");
|
|
21
|
+
const git_module_js_1 = require("./domain/git/git.module.js");
|
|
22
|
+
const knowledge_module_js_1 = require("./domain/knowledge/knowledge.module.js");
|
|
23
|
+
const wbs_module_js_1 = require("./domain/wbs/wbs.module.js");
|
|
24
|
+
const thread_module_js_1 = require("./domain/thread/thread.module.js");
|
|
25
|
+
const doc_module_js_1 = require("./domain/doc/doc.module.js");
|
|
26
|
+
const document_module_js_1 = require("./domain/document/document.module.js");
|
|
27
|
+
const project_module_js_1 = require("./domain/project/project.module.js");
|
|
28
|
+
const onboarding_module_js_1 = require("./domain/onboarding/onboarding.module.js");
|
|
29
|
+
const box_module_js_1 = require("./domain/box/box.module.js");
|
|
30
|
+
const message_module_js_1 = require("./domain/message/message.module.js");
|
|
31
|
+
const market_module_js_1 = require("./domain/market/market.module.js");
|
|
32
|
+
const workflow_module_js_1 = require("./domain/workflow/workflow.module.js");
|
|
33
|
+
const planner_module_js_1 = require("./domain/planner/planner.module.js");
|
|
34
|
+
const goal_module_js_1 = require("./domain/goal/goal.module.js");
|
|
35
|
+
const workspace_module_js_1 = require("./domain/workspace/workspace.module.js");
|
|
36
|
+
const health_module_js_1 = require("./domain/health/health.module.js");
|
|
37
|
+
const http_logging_interceptor_js_1 = require("./common/interceptor/http-logging.interceptor.js");
|
|
38
|
+
const api_id_header_interceptor_js_1 = require("./common/interceptor/api-id-header.interceptor.js");
|
|
39
|
+
const repository_module_js_1 = require("./repository/repository.module.js");
|
|
40
|
+
const crewx_module_js_1 = require("./modules/crewx.module.js");
|
|
41
|
+
const analytics_module_js_1 = require("./common/analytics.module.js");
|
|
42
|
+
const limits_module_js_1 = require("./common/limits/limits.module.js");
|
|
43
|
+
const fs_module_js_1 = require("./domain/fs/fs.module.js");
|
|
44
|
+
const auth_module_js_1 = require("./domain/auth/auth.module.js");
|
|
45
|
+
const settings_module_js_1 = require("./domain/settings/settings.module.js");
|
|
46
|
+
let AppModule = class AppModule {
|
|
47
|
+
configure(consumer) {
|
|
48
|
+
consumer
|
|
49
|
+
.apply(workspace_middleware_js_1.WorkspaceMiddleware)
|
|
50
|
+
.forRoutes({ path: 'ws/:slug/(.*)', method: common_1.RequestMethod.ALL });
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
exports.AppModule = AppModule;
|
|
54
|
+
exports.AppModule = AppModule = __decorate([
|
|
55
|
+
(0, common_1.Module)({
|
|
56
|
+
imports: [
|
|
57
|
+
config_1.ConfigModule.forRoot({ isGlobal: true }),
|
|
58
|
+
throttler_1.ThrottlerModule.forRoot([{ ttl: 60000, limit: 100 }]),
|
|
59
|
+
repository_module_js_1.RepositoryModule,
|
|
60
|
+
analytics_module_js_1.AnalyticsModule,
|
|
61
|
+
crewx_module_js_1.CrewxModule,
|
|
62
|
+
// Workspace-scoped modules (controllers use ws/:slug/* prefix directly)
|
|
63
|
+
thread_module_js_1.ThreadModule,
|
|
64
|
+
message_module_js_1.MessageModule,
|
|
65
|
+
task_module_js_1.TaskModule,
|
|
66
|
+
agent_module_js_1.AgentModule,
|
|
67
|
+
usage_module_js_1.UsageModule,
|
|
68
|
+
document_module_js_1.DocumentModule,
|
|
69
|
+
doc_module_js_1.DocModule,
|
|
70
|
+
knowledge_module_js_1.KnowledgeModule,
|
|
71
|
+
onboarding_module_js_1.OnboardingModule,
|
|
72
|
+
project_module_js_1.ProjectModule,
|
|
73
|
+
market_module_js_1.MarketModule,
|
|
74
|
+
wbs_module_js_1.WbsModule,
|
|
75
|
+
workflow_module_js_1.WorkflowModule,
|
|
76
|
+
planner_module_js_1.PlannerModule,
|
|
77
|
+
goal_module_js_1.GoalModule,
|
|
78
|
+
limits_module_js_1.LimitsModule,
|
|
79
|
+
// Global modules (no workspace prefix)
|
|
80
|
+
cli_module_js_1.CliModule,
|
|
81
|
+
mcp_module_js_1.McpModule,
|
|
82
|
+
auth_module_js_1.AuthModule,
|
|
83
|
+
git_module_js_1.GitModule,
|
|
84
|
+
box_module_js_1.BoxModule,
|
|
85
|
+
fs_module_js_1.FsModule,
|
|
86
|
+
workspace_module_js_1.WorkspaceModule,
|
|
87
|
+
health_module_js_1.HealthModule,
|
|
88
|
+
settings_module_js_1.SettingsModule,
|
|
89
|
+
],
|
|
90
|
+
controllers: [],
|
|
91
|
+
providers: [
|
|
92
|
+
core_1.Reflector,
|
|
93
|
+
{
|
|
94
|
+
provide: core_1.APP_FILTER,
|
|
95
|
+
useClass: repository_exception_filter_js_1.RepositoryExceptionFilter,
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
provide: core_1.APP_GUARD,
|
|
99
|
+
useClass: throttler_1.ThrottlerGuard,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
provide: core_1.APP_INTERCEPTOR,
|
|
103
|
+
useClass: api_id_header_interceptor_js_1.ApiIdHeaderInterceptor,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
provide: core_1.APP_INTERCEPTOR,
|
|
107
|
+
useClass: http_logging_interceptor_js_1.HttpLoggingInterceptor,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
})
|
|
111
|
+
], AppModule);
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createServerCrewx = createServerCrewx;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const os_1 = require("os");
|
|
7
|
+
const sdk_1 = require("@crewx/sdk");
|
|
8
|
+
const plugins_1 = require("@crewx/sdk/plugins");
|
|
9
|
+
const repository_1 = require("@crewx/sdk/repository");
|
|
10
|
+
const node_1 = require("@crewx/sdk/tools/node");
|
|
11
|
+
const SERVER_VERSION = (() => {
|
|
12
|
+
try {
|
|
13
|
+
const pkg = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../package.json'), 'utf8'));
|
|
14
|
+
return pkg.version ?? '0.0.0';
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return '0.0.0';
|
|
18
|
+
}
|
|
19
|
+
})();
|
|
20
|
+
/**
|
|
21
|
+
* Build a Crewx instance for the NestJS server with standard plugins
|
|
22
|
+
* (FileLogger + SqliteTracing) plus built-in node tools registration.
|
|
23
|
+
* Passes itself as remoteFactory so that file:// remote agent delegation
|
|
24
|
+
* inherits the same plugin/tool environment in the target Crewx instance
|
|
25
|
+
* (identical semantics to CLI's createCliCrewx).
|
|
26
|
+
*
|
|
27
|
+
* Behavior mirrors createCliCrewx:
|
|
28
|
+
* - If configPath resolves to an existing file → load it (with built-ins merged)
|
|
29
|
+
* - If configPath is NOT set via CREWX_CONFIG env AND the file doesn't exist →
|
|
30
|
+
* fall back to built-in-only mode so `crewx` can launch from any cwd
|
|
31
|
+
* - If CREWX_CONFIG is explicitly set AND the file doesn't exist → throw
|
|
32
|
+
*
|
|
33
|
+
* workspaceRoot used by FileLoggerPlugin: directory of the yaml when present,
|
|
34
|
+
* otherwise process.cwd() so logs land in the launch directory.
|
|
35
|
+
*/
|
|
36
|
+
async function createServerCrewx(configPath) {
|
|
37
|
+
let yamlPath;
|
|
38
|
+
let workspaceRoot;
|
|
39
|
+
if (configPath !== undefined) {
|
|
40
|
+
// Caller explicitly provided a path — trust it directly without existsSync
|
|
41
|
+
const absConfigPath = (0, path_1.resolve)(configPath);
|
|
42
|
+
yamlPath = absConfigPath;
|
|
43
|
+
workspaceRoot = (0, path_1.dirname)(absConfigPath);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// No explicit path — use env/default with existsSync fallback
|
|
47
|
+
const defaultPath = (0, path_1.resolve)(process.env.CREWX_CONFIG ?? 'crewx.yaml');
|
|
48
|
+
const isExplicitConfig = Boolean(process.env.CREWX_CONFIG);
|
|
49
|
+
const fileExists = (0, fs_1.existsSync)(defaultPath);
|
|
50
|
+
if (fileExists) {
|
|
51
|
+
yamlPath = defaultPath;
|
|
52
|
+
workspaceRoot = (0, path_1.dirname)(defaultPath);
|
|
53
|
+
}
|
|
54
|
+
else if (isExplicitConfig) {
|
|
55
|
+
throw new Error(`[crewx] Config file not found: ${defaultPath} (set via CREWX_CONFIG)`);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
yamlPath = undefined;
|
|
59
|
+
workspaceRoot = process.cwd();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const dbDir = (0, path_1.join)((0, os_1.homedir)(), '.crewx');
|
|
63
|
+
(0, fs_1.mkdirSync)(dbDir, { recursive: true });
|
|
64
|
+
const dbPath = (0, path_1.join)(dbDir, 'crewx.db');
|
|
65
|
+
const handle = (0, repository_1.openDrizzleDb)(dbPath);
|
|
66
|
+
try {
|
|
67
|
+
(0, repository_1.runMigrations)(handle.db);
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
handle.close();
|
|
71
|
+
}
|
|
72
|
+
const crewx = await sdk_1.Crewx.loadYaml(yamlPath, {
|
|
73
|
+
remoteFactory: createServerCrewx,
|
|
74
|
+
});
|
|
75
|
+
(0, node_1.registerBuiltinTools)(crewx);
|
|
76
|
+
await crewx.use(new plugins_1.FileLoggerPlugin({ workspaceRoot, version: SERVER_VERSION }));
|
|
77
|
+
await crewx.use(new plugins_1.SqliteTracingPlugin({ version: SERVER_VERSION }));
|
|
78
|
+
await crewx.use(new plugins_1.ConversationPlugin());
|
|
79
|
+
return crewx;
|
|
80
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
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
|
+
exports.CERT_PATH = void 0;
|
|
7
|
+
exports.resolveHttpsOptions = resolveHttpsOptions;
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
const os_1 = require("os");
|
|
11
|
+
const child_process_1 = require("child_process");
|
|
12
|
+
const node_forge_1 = __importDefault(require("node-forge"));
|
|
13
|
+
const TLS_DIR = (0, path_1.join)((0, os_1.homedir)(), '.crewx', 'tls');
|
|
14
|
+
const CA_CERT_PATH = (0, path_1.join)(TLS_DIR, 'ca.pem');
|
|
15
|
+
const CA_KEY_PATH = (0, path_1.join)(TLS_DIR, 'ca-key.pem');
|
|
16
|
+
const CERT_PATH = (0, path_1.join)(TLS_DIR, 'cert.pem');
|
|
17
|
+
exports.CERT_PATH = CERT_PATH;
|
|
18
|
+
const KEY_PATH = (0, path_1.join)(TLS_DIR, 'key.pem');
|
|
19
|
+
async function resolveHttpsOptions() {
|
|
20
|
+
if (process.env.CREWX_HTTPS !== 'true') {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
if (process.env.TLS_CERT && process.env.TLS_KEY) {
|
|
24
|
+
return {
|
|
25
|
+
cert: (0, fs_1.readFileSync)(process.env.TLS_CERT),
|
|
26
|
+
key: (0, fs_1.readFileSync)(process.env.TLS_KEY),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if ((0, fs_1.existsSync)(CA_CERT_PATH) && (0, fs_1.existsSync)(CERT_PATH) && (0, fs_1.existsSync)(KEY_PATH)) {
|
|
30
|
+
return {
|
|
31
|
+
cert: (0, fs_1.readFileSync)(CERT_PATH),
|
|
32
|
+
key: (0, fs_1.readFileSync)(KEY_PATH),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// Generate CA (or reuse existing) + server cert signed by CA
|
|
36
|
+
const ca = ensureCACert();
|
|
37
|
+
const server = generateServerCert(ca.cert, ca.key);
|
|
38
|
+
(0, fs_1.writeFileSync)(CERT_PATH, server.certPem, { mode: 0o644 });
|
|
39
|
+
(0, fs_1.writeFileSync)(KEY_PATH, server.keyPem, { mode: 0o600 });
|
|
40
|
+
if (ca.isNew && process.env.CREWX_TRUST_CA === 'true') {
|
|
41
|
+
installCA(CA_CERT_PATH);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
cert: Buffer.from(server.certPem),
|
|
45
|
+
key: Buffer.from(server.keyPem),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function ensureCACert() {
|
|
49
|
+
if ((0, fs_1.existsSync)(CA_CERT_PATH) && (0, fs_1.existsSync)(CA_KEY_PATH)) {
|
|
50
|
+
return {
|
|
51
|
+
cert: node_forge_1.default.pki.certificateFromPem((0, fs_1.readFileSync)(CA_CERT_PATH, 'utf8')),
|
|
52
|
+
key: node_forge_1.default.pki.privateKeyFromPem((0, fs_1.readFileSync)(CA_KEY_PATH, 'utf8')),
|
|
53
|
+
isNew: false,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const keys = node_forge_1.default.pki.rsa.generateKeyPair(2048);
|
|
57
|
+
const cert = node_forge_1.default.pki.createCertificate();
|
|
58
|
+
cert.publicKey = keys.publicKey;
|
|
59
|
+
cert.serialNumber = randomSerialNumber();
|
|
60
|
+
cert.validity.notBefore = new Date();
|
|
61
|
+
cert.validity.notAfter = new Date();
|
|
62
|
+
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 10);
|
|
63
|
+
const attrs = [
|
|
64
|
+
{ name: 'commonName', value: 'SowonLabs CrewX Local CA' },
|
|
65
|
+
{ name: 'organizationName', value: 'SowonLabs' },
|
|
66
|
+
];
|
|
67
|
+
cert.setSubject(attrs);
|
|
68
|
+
cert.setIssuer(attrs);
|
|
69
|
+
cert.setExtensions([
|
|
70
|
+
{ name: 'basicConstraints', cA: true },
|
|
71
|
+
{ name: 'keyUsage', keyCertSign: true, cRLSign: true },
|
|
72
|
+
]);
|
|
73
|
+
cert.sign(keys.privateKey, node_forge_1.default.md.sha256.create());
|
|
74
|
+
(0, fs_1.mkdirSync)(TLS_DIR, { recursive: true });
|
|
75
|
+
(0, fs_1.writeFileSync)(CA_CERT_PATH, node_forge_1.default.pki.certificateToPem(cert), { mode: 0o644 });
|
|
76
|
+
(0, fs_1.writeFileSync)(CA_KEY_PATH, node_forge_1.default.pki.privateKeyToPem(keys.privateKey), {
|
|
77
|
+
mode: 0o600,
|
|
78
|
+
});
|
|
79
|
+
console.log('🏛️ SowonLabs CrewX Local CA created: ~/.crewx/tls/ca.pem');
|
|
80
|
+
return { cert, key: keys.privateKey, isNew: true };
|
|
81
|
+
}
|
|
82
|
+
function generateServerCert(caCert, caKey) {
|
|
83
|
+
const host = (0, os_1.hostname)();
|
|
84
|
+
const keys = node_forge_1.default.pki.rsa.generateKeyPair(2048);
|
|
85
|
+
const cert = node_forge_1.default.pki.createCertificate();
|
|
86
|
+
cert.publicKey = keys.publicKey;
|
|
87
|
+
cert.serialNumber = randomSerialNumber();
|
|
88
|
+
cert.validity.notBefore = new Date();
|
|
89
|
+
cert.validity.notAfter = new Date();
|
|
90
|
+
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);
|
|
91
|
+
cert.setSubject([{ name: 'commonName', value: host }]);
|
|
92
|
+
cert.setIssuer(caCert.subject.attributes);
|
|
93
|
+
cert.setExtensions([
|
|
94
|
+
{
|
|
95
|
+
name: 'subjectAltName',
|
|
96
|
+
altNames: [
|
|
97
|
+
{ type: 2, value: 'localhost' },
|
|
98
|
+
{ type: 2, value: host },
|
|
99
|
+
{ type: 7, ip: '127.0.0.1' },
|
|
100
|
+
{ type: 7, ip: '::1' },
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
]);
|
|
104
|
+
cert.sign(caKey, node_forge_1.default.md.sha256.create());
|
|
105
|
+
console.log('🔒 Server certificate issued by SowonLabs CA: ~/.crewx/tls/cert.pem');
|
|
106
|
+
return {
|
|
107
|
+
certPem: node_forge_1.default.pki.certificateToPem(cert),
|
|
108
|
+
keyPem: node_forge_1.default.pki.privateKeyToPem(keys.privateKey),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function installCA(caCertPath) {
|
|
112
|
+
const platform = process.platform;
|
|
113
|
+
console.log('');
|
|
114
|
+
console.log('🔐 Installing CA certificate to system trust store...');
|
|
115
|
+
console.log('');
|
|
116
|
+
try {
|
|
117
|
+
if (platform === 'win32') {
|
|
118
|
+
(0, child_process_1.execSync)(`powershell -Command "Import-Certificate -FilePath '${caCertPath}' -CertStoreLocation Cert:\\CurrentUser\\Root"`, { stdio: 'inherit' });
|
|
119
|
+
}
|
|
120
|
+
else if (platform === 'darwin') {
|
|
121
|
+
(0, child_process_1.execSync)(`security add-trusted-cert -r trustRoot -k ~/Library/Keychains/login.keychain-db "${caCertPath}"`, { stdio: 'inherit' });
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
console.log(' Manual installation required on Linux:');
|
|
125
|
+
console.log(` sudo cp ${caCertPath} /usr/local/share/ca-certificates/crewx-ca.crt`);
|
|
126
|
+
console.log(' sudo update-ca-certificates');
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
console.log('✅ SowonLabs CA installed. HTTPS will work without browser warnings.');
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
console.log('⚠️ CA installation failed. HTTPS still works, but browser will show a warning.');
|
|
133
|
+
console.log(` Manual install: ${caCertPath}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function randomSerialNumber() {
|
|
137
|
+
return node_forge_1.default.util.bytesToHex(node_forge_1.default.random.getBytesSync(16));
|
|
138
|
+
}
|