crewx 0.8.5-rc.0 → 0.8.5
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 +0 -0
- 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 +102 -0
- package/dist-server/bootstrap/crewx-server.js +79 -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/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 +26 -0
- package/dist-server/domain/agent/agent.service.js +317 -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 +120 -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 +62 -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 +88 -0
- package/dist-server/domain/cli/cli.module.js +21 -0
- package/dist-server/domain/cli/cli.service.js +435 -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 +271 -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/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/mcp/browser-session.store.js +247 -0
- package/dist-server/domain/mcp/crewx-tool.factory.js +117 -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 +682 -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 +158 -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/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/skill/dto/add-registry.dto.js +23 -0
- package/dist-server/domain/skill/dto/install-skill.dto.js +30 -0
- package/dist-server/domain/skill/skill.controller.js +136 -0
- package/dist-server/domain/skill/skill.module.js +22 -0
- package/dist-server/domain/skill/skill.service.js +632 -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 +722 -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 +132 -0
- package/dist-server/domain/thread/thread.module.js +23 -0
- package/dist-server/domain/thread/thread.service.js +399 -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 +343 -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 +216 -0
- package/dist-server/main.js +175 -0
- package/dist-server/modules/crewx-pool.service.js +70 -0
- package/dist-server/modules/crewx.module.js +47 -0
- package/dist-server/package.json +3 -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 +48 -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 +102 -0
- package/dist-server/repository/thread.repository.js +143 -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 +44 -45
- package/packages/cli/package.json +1 -1
package/bin/crewx-ui.js
CHANGED
|
File without changes
|
|
@@ -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,102 @@
|
|
|
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 skill_module_js_1 = require("./domain/skill/skill.module.js");
|
|
32
|
+
const workflow_module_js_1 = require("./domain/workflow/workflow.module.js");
|
|
33
|
+
const workspace_module_js_1 = require("./domain/workspace/workspace.module.js");
|
|
34
|
+
const health_module_js_1 = require("./domain/health/health.module.js");
|
|
35
|
+
const http_logging_interceptor_js_1 = require("./common/interceptor/http-logging.interceptor.js");
|
|
36
|
+
const api_id_header_interceptor_js_1 = require("./common/interceptor/api-id-header.interceptor.js");
|
|
37
|
+
const repository_module_js_1 = require("./repository/repository.module.js");
|
|
38
|
+
const crewx_module_js_1 = require("./modules/crewx.module.js");
|
|
39
|
+
const limits_module_js_1 = require("./common/limits/limits.module.js");
|
|
40
|
+
const fs_module_js_1 = require("./domain/fs/fs.module.js");
|
|
41
|
+
const auth_module_js_1 = require("./domain/auth/auth.module.js");
|
|
42
|
+
let AppModule = class AppModule {
|
|
43
|
+
configure(consumer) {
|
|
44
|
+
consumer
|
|
45
|
+
.apply(workspace_middleware_js_1.WorkspaceMiddleware)
|
|
46
|
+
.forRoutes({ path: 'ws/:slug/(.*)', method: common_1.RequestMethod.ALL });
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
exports.AppModule = AppModule;
|
|
50
|
+
exports.AppModule = AppModule = __decorate([
|
|
51
|
+
(0, common_1.Module)({
|
|
52
|
+
imports: [
|
|
53
|
+
config_1.ConfigModule.forRoot({ isGlobal: true }),
|
|
54
|
+
throttler_1.ThrottlerModule.forRoot([{ ttl: 60000, limit: 100 }]),
|
|
55
|
+
repository_module_js_1.RepositoryModule,
|
|
56
|
+
crewx_module_js_1.CrewxModule,
|
|
57
|
+
// Workspace-scoped modules (controllers use ws/:slug/* prefix directly)
|
|
58
|
+
thread_module_js_1.ThreadModule,
|
|
59
|
+
message_module_js_1.MessageModule,
|
|
60
|
+
task_module_js_1.TaskModule,
|
|
61
|
+
agent_module_js_1.AgentModule,
|
|
62
|
+
usage_module_js_1.UsageModule,
|
|
63
|
+
document_module_js_1.DocumentModule,
|
|
64
|
+
doc_module_js_1.DocModule,
|
|
65
|
+
knowledge_module_js_1.KnowledgeModule,
|
|
66
|
+
onboarding_module_js_1.OnboardingModule,
|
|
67
|
+
project_module_js_1.ProjectModule,
|
|
68
|
+
fs_module_js_1.FsModule,
|
|
69
|
+
skill_module_js_1.SkillModule,
|
|
70
|
+
wbs_module_js_1.WbsModule,
|
|
71
|
+
workflow_module_js_1.WorkflowModule,
|
|
72
|
+
limits_module_js_1.LimitsModule,
|
|
73
|
+
// Global modules (no workspace prefix)
|
|
74
|
+
cli_module_js_1.CliModule,
|
|
75
|
+
mcp_module_js_1.McpModule,
|
|
76
|
+
auth_module_js_1.AuthModule,
|
|
77
|
+
git_module_js_1.GitModule,
|
|
78
|
+
box_module_js_1.BoxModule,
|
|
79
|
+
workspace_module_js_1.WorkspaceModule,
|
|
80
|
+
health_module_js_1.HealthModule,
|
|
81
|
+
],
|
|
82
|
+
controllers: [],
|
|
83
|
+
providers: [
|
|
84
|
+
{
|
|
85
|
+
provide: core_1.APP_FILTER,
|
|
86
|
+
useClass: repository_exception_filter_js_1.RepositoryExceptionFilter,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
provide: core_1.APP_GUARD,
|
|
90
|
+
useClass: throttler_1.ThrottlerGuard,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
provide: core_1.APP_INTERCEPTOR,
|
|
94
|
+
useClass: api_id_header_interceptor_js_1.ApiIdHeaderInterceptor,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
provide: core_1.APP_INTERCEPTOR,
|
|
98
|
+
useClass: http_logging_interceptor_js_1.HttpLoggingInterceptor,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
})
|
|
102
|
+
], AppModule);
|
|
@@ -0,0 +1,79 @@
|
|
|
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
|
+
return crewx;
|
|
79
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isAllowedOrigin = isAllowedOrigin;
|
|
4
|
+
function isAllowedOrigin(origin, allowedExtensionIds) {
|
|
5
|
+
if (!origin)
|
|
6
|
+
return true;
|
|
7
|
+
if (origin === 'http://localhost:8200')
|
|
8
|
+
return true;
|
|
9
|
+
if (origin.startsWith('chrome-extension://') &&
|
|
10
|
+
(allowedExtensionIds.length === 0 ||
|
|
11
|
+
allowedExtensionIds.some((id) => origin === `chrome-extension://${id}`))) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Project = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
/**
|
|
6
|
+
* Extract project identifier:
|
|
7
|
+
* 1. X-CrewX-Project header
|
|
8
|
+
* 2. ?project query param (backward compat)
|
|
9
|
+
* 3. process.cwd() (server working directory = default project)
|
|
10
|
+
*
|
|
11
|
+
* @deprecated Use `@Workspace()` decorator from `workspace.decorator.ts` instead.
|
|
12
|
+
* This decorator returns a raw string; `@Workspace()` returns a full
|
|
13
|
+
* `WorkspaceContext` ({ id, path, name }) populated by `WorkspaceMiddleware`.
|
|
14
|
+
*/
|
|
15
|
+
exports.Project = (0, common_1.createParamDecorator)((_data, ctx) => {
|
|
16
|
+
const req = ctx.switchToHttp().getRequest();
|
|
17
|
+
const header = req.headers['x-crewx-project'];
|
|
18
|
+
const headerValue = Array.isArray(header) ? header[0] : header;
|
|
19
|
+
const queryValue = req.query['project'];
|
|
20
|
+
return headerValue || queryValue || process.cwd();
|
|
21
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Workspace = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
/**
|
|
6
|
+
* Parameter decorator that extracts `WorkspaceContext` from the current request.
|
|
7
|
+
*
|
|
8
|
+
* The context is populated by `WorkspaceMiddleware` (global) and contains:
|
|
9
|
+
* - `id` — SHA-256 hex (64 chars), used as `workspace_id` in DB queries
|
|
10
|
+
* - `path` — Normalized absolute directory path
|
|
11
|
+
* - `name` — Directory basename (human-readable)
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* @Get()
|
|
16
|
+
* findAll(@Workspace() ws: WorkspaceContext) {
|
|
17
|
+
* return this.service.findAll(ws.id);
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
exports.Workspace = (0, common_1.createParamDecorator)((_data, ctx) => {
|
|
22
|
+
const req = ctx.switchToHttp().getRequest();
|
|
23
|
+
return req.workspace;
|
|
24
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ApiIdHeaderInterceptor = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const core_1 = require("@nestjs/core");
|
|
15
|
+
const HEADER_NAME = 'X-CrewX-ApiId';
|
|
16
|
+
const SWAGGER_API_OPERATION = 'swagger/apiOperation';
|
|
17
|
+
let ApiIdHeaderInterceptor = class ApiIdHeaderInterceptor {
|
|
18
|
+
reflector;
|
|
19
|
+
constructor(reflector) {
|
|
20
|
+
this.reflector = reflector;
|
|
21
|
+
}
|
|
22
|
+
intercept(context, next) {
|
|
23
|
+
// Guard: skip for non-controller contexts (e.g. static file serving)
|
|
24
|
+
if (!this.reflector) {
|
|
25
|
+
return next.handle();
|
|
26
|
+
}
|
|
27
|
+
let handler;
|
|
28
|
+
try {
|
|
29
|
+
handler = context.getHandler();
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return next.handle();
|
|
33
|
+
}
|
|
34
|
+
if (!handler) {
|
|
35
|
+
return next.handle();
|
|
36
|
+
}
|
|
37
|
+
const metadata = this.reflector.get(SWAGGER_API_OPERATION, handler);
|
|
38
|
+
const operationId = metadata?.operationId;
|
|
39
|
+
if (!operationId) {
|
|
40
|
+
return next.handle();
|
|
41
|
+
}
|
|
42
|
+
const res = context.switchToHttp().getResponse();
|
|
43
|
+
if (!res.headersSent) {
|
|
44
|
+
res.setHeader(HEADER_NAME, operationId);
|
|
45
|
+
}
|
|
46
|
+
return next.handle();
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
exports.ApiIdHeaderInterceptor = ApiIdHeaderInterceptor;
|
|
50
|
+
exports.ApiIdHeaderInterceptor = ApiIdHeaderInterceptor = __decorate([
|
|
51
|
+
(0, common_1.Injectable)(),
|
|
52
|
+
__metadata("design:paramtypes", [core_1.Reflector])
|
|
53
|
+
], ApiIdHeaderInterceptor);
|
|
@@ -0,0 +1,124 @@
|
|
|
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
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.HttpLoggingInterceptor = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const rxjs_1 = require("rxjs");
|
|
15
|
+
const crypto_1 = require("crypto");
|
|
16
|
+
const request_log_repository_js_1 = require("../../repository/request-log.repository.js");
|
|
17
|
+
const BATCH_SIZE = 500;
|
|
18
|
+
const FLUSH_INTERVAL_MS = 30_000;
|
|
19
|
+
/** Paths to skip logging (healthcheck endpoints) */
|
|
20
|
+
const SKIP_PATHS = new Set(['/health', '/healthz', '/ready', '/readiness', '/liveness']);
|
|
21
|
+
let HttpLoggingInterceptor = class HttpLoggingInterceptor {
|
|
22
|
+
repo;
|
|
23
|
+
queue = [];
|
|
24
|
+
flushTimer;
|
|
25
|
+
constructor(repo) {
|
|
26
|
+
this.repo = repo;
|
|
27
|
+
this.flushTimer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);
|
|
28
|
+
}
|
|
29
|
+
intercept(context, next) {
|
|
30
|
+
const httpCtx = context.switchToHttp();
|
|
31
|
+
const req = httpCtx.getRequest();
|
|
32
|
+
// Skip healthcheck endpoints
|
|
33
|
+
if (SKIP_PATHS.has(req.path)) {
|
|
34
|
+
return next.handle();
|
|
35
|
+
}
|
|
36
|
+
// Skip if X-Skip-Request-Log header is set
|
|
37
|
+
if (req.headers['x-skip-request-log'] === 'true') {
|
|
38
|
+
return next.handle();
|
|
39
|
+
}
|
|
40
|
+
const startTime = Date.now();
|
|
41
|
+
const res = httpCtx.getResponse();
|
|
42
|
+
// Patch res.json to capture response body for @Res() controllers
|
|
43
|
+
const origJson = res.json.bind(res);
|
|
44
|
+
res.json = (body) => {
|
|
45
|
+
res.__body = body;
|
|
46
|
+
return origJson(body);
|
|
47
|
+
};
|
|
48
|
+
return next.handle().pipe((0, rxjs_1.tap)({
|
|
49
|
+
next: () => this.logRequest(req, res, startTime),
|
|
50
|
+
error: () => this.logRequest(req, res, startTime),
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
logRequest(req, res, startTime) {
|
|
54
|
+
const durationMs = Date.now() - startTime;
|
|
55
|
+
const statusCode = res.statusCode;
|
|
56
|
+
const now = new Date();
|
|
57
|
+
const entry = {
|
|
58
|
+
id: (0, crypto_1.randomUUID)(),
|
|
59
|
+
path: req.path,
|
|
60
|
+
method: req.method,
|
|
61
|
+
status_code: statusCode,
|
|
62
|
+
duration_ms: durationMs,
|
|
63
|
+
ip: req.ip ?? req.socket?.remoteAddress ?? undefined,
|
|
64
|
+
request_headers: this.safeJson(this.filterHeaders(req.headers)),
|
|
65
|
+
response_headers: this.safeJson(this.filterHeaders(res.getHeaders())),
|
|
66
|
+
request_body: req.body ? this.safeJson(req.body) : undefined,
|
|
67
|
+
response_body: undefined,
|
|
68
|
+
query: Object.keys(req.query).length > 0 ? this.safeJson(req.query) : undefined,
|
|
69
|
+
user_id: undefined,
|
|
70
|
+
project_id: this.extractProjectId(req.path),
|
|
71
|
+
partition_key: `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`,
|
|
72
|
+
timestamp: now.toISOString(),
|
|
73
|
+
};
|
|
74
|
+
const resBody = res.__body;
|
|
75
|
+
if (resBody !== undefined) {
|
|
76
|
+
entry.response_body = typeof resBody === 'string' ? resBody : this.safeJson(resBody);
|
|
77
|
+
}
|
|
78
|
+
this.queue.push(entry);
|
|
79
|
+
if (this.queue.length >= BATCH_SIZE) {
|
|
80
|
+
this.flush();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
flush() {
|
|
84
|
+
if (this.queue.length === 0)
|
|
85
|
+
return;
|
|
86
|
+
const batch = this.queue.splice(0);
|
|
87
|
+
this.repo.bulkInsert(batch);
|
|
88
|
+
}
|
|
89
|
+
/** Extract project_id from URL patterns like /api/projects/:id/... */
|
|
90
|
+
extractProjectId(urlPath) {
|
|
91
|
+
const match = urlPath.match(/\/projects\/([^/]+)/);
|
|
92
|
+
return match?.[1];
|
|
93
|
+
}
|
|
94
|
+
/** Filter out sensitive headers */
|
|
95
|
+
filterHeaders(headers) {
|
|
96
|
+
const filtered = {};
|
|
97
|
+
const sensitiveKeys = new Set(['authorization', 'cookie', 'set-cookie', 'x-api-key']);
|
|
98
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
99
|
+
if (!sensitiveKeys.has(key.toLowerCase())) {
|
|
100
|
+
filtered[key] = value;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return filtered;
|
|
104
|
+
}
|
|
105
|
+
safeJson(data) {
|
|
106
|
+
try {
|
|
107
|
+
const json = JSON.stringify(data);
|
|
108
|
+
// Truncate at 512KB to prevent DB bloat
|
|
109
|
+
return json.length > 524288 ? json.slice(0, 524288) : json;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
onModuleDestroy() {
|
|
116
|
+
clearInterval(this.flushTimer);
|
|
117
|
+
this.flush();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
exports.HttpLoggingInterceptor = HttpLoggingInterceptor;
|
|
121
|
+
exports.HttpLoggingInterceptor = HttpLoggingInterceptor = __decorate([
|
|
122
|
+
(0, common_1.Injectable)(),
|
|
123
|
+
__metadata("design:paramtypes", [request_log_repository_js_1.RequestLogRepository])
|
|
124
|
+
], HttpLoggingInterceptor);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UNLIMITED_LIMITS = exports.FREE_TIER_LIMITS = void 0;
|
|
4
|
+
exports.FREE_TIER_LIMITS = {
|
|
5
|
+
tier: 'FREE',
|
|
6
|
+
workspaces: 3,
|
|
7
|
+
agentsPerWorkspace: 10,
|
|
8
|
+
};
|
|
9
|
+
exports.UNLIMITED_LIMITS = {
|
|
10
|
+
tier: 'ENTERPRISE',
|
|
11
|
+
workspaces: -1,
|
|
12
|
+
agentsPerWorkspace: -1,
|
|
13
|
+
};
|