@devflow-tools/devflow 0.8.8 → 0.8.9

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 (30) hide show
  1. package/dist/hooks/pre-tool-use.js +2 -2
  2. package/package.json +13 -13
  3. package/dist/cli.js +0 -46
  4. package/dist/dashboard-standalone.tar.gz +0 -0
  5. package/dist/fallback.html +0 -106
  6. package/dist/mcp-server.js +0 -2
  7. package/dist/plugin/hooks.json +0 -40
  8. package/dist/plugin/skills/devflow/SKILL.md +0 -20
  9. package/dist/plugin/skills/devflow:animation/SKILL.md +0 -39
  10. package/dist/plugin/skills/devflow:context/SKILL.md +0 -44
  11. package/dist/plugin/skills/devflow:css/SKILL.md +0 -39
  12. package/dist/plugin/skills/devflow:docker/SKILL.md +0 -62
  13. package/dist/plugin/skills/devflow:doctor/SKILL.md +0 -17
  14. package/dist/plugin/skills/devflow:electron/SKILL.md +0 -62
  15. package/dist/plugin/skills/devflow:git/SKILL.md +0 -43
  16. package/dist/plugin/skills/devflow:graph/SKILL.md +0 -37
  17. package/dist/plugin/skills/devflow:graphql/SKILL.md +0 -63
  18. package/dist/plugin/skills/devflow:knowledge/SKILL.md +0 -37
  19. package/dist/plugin/skills/devflow:memory/SKILL.md +0 -36
  20. package/dist/plugin/skills/devflow:nest/SKILL.md +0 -63
  21. package/dist/plugin/skills/devflow:nextjs/SKILL.md +0 -60
  22. package/dist/plugin/skills/devflow:performance/SKILL.md +0 -62
  23. package/dist/plugin/skills/devflow:react/SKILL.md +0 -80
  24. package/dist/plugin/skills/devflow:start/SKILL.md +0 -54
  25. package/dist/plugin/skills/devflow:tailwind/SKILL.md +0 -58
  26. package/dist/plugin/skills/devflow:taro/SKILL.md +0 -61
  27. package/dist/plugin/skills/devflow:ui-layout/SKILL.md +0 -39
  28. package/dist/plugin/skills/devflow:vue/SKILL.md +0 -69
  29. package/dist/plugin/skills/devflow:workflow/SKILL.md +0 -37
  30. package/dist/server.js +0 -10
@@ -1,54 +0,0 @@
1
- ---
2
- name: devflow:start
3
- description: 启动 DevFlow 开发服务器(服务端 + 前端),显示访问信息
4
- required_mcp_tools: []
5
- ---
6
-
7
- # DevFlow Start
8
-
9
- 启动 DevFlow 开发环境,包括服务端和前端。使用 `npx devflow start` 命令,无论在哪个目录下调用都能正确启动 DevFlow 服务。
10
-
11
- ## 执行步骤
12
-
13
- 1. **使用 npx devflow start 启动**
14
- ```bash
15
- npx devflow start
16
- ```
17
-
18
- 这会自动启动:
19
- - DevFlow REST 服务端(默认端口 13337)
20
- - DevFlow Dashboard(默认端口 17788)
21
-
22
- 2. **显示启动信息**
23
- 服务启动后,显示以下信息:
24
-
25
- ```
26
- ╔═══════════════════════════════════════════════════════════╗
27
- ║ 🚀 DevFlow Started! ║
28
- ╠═══════════════════════════════════════════════════════════╣
29
- ║ ║
30
- ║ 🖥️ Server: http://localhost:13337 ║
31
- ║ 🎨 Dashboard: http://localhost:17788 ║
32
- ║ ║
33
- ║ Press Ctrl+C to stop all services ║
34
- ╚═══════════════════════════════════════════════════════════╝
35
- ```
36
-
37
- 3. **保持运行**
38
- - `devflow start` 会持续运行直到 Ctrl+C
39
- - 服务端和 Dashboard 由 CLI 统一管理生命周期
40
-
41
- ## 注意事项
42
-
43
- - 端口 13337:服务端(NestJS)
44
- - 端口 17788:前端(Next.js Dashboard)
45
- - 使用 `npx devflow start` 从任意目录启动,不依赖当前工作目录
46
- - 如果端口被占用,提示用户 `lsof -i :13337` 或 `lsof -i :17788` 检查
47
-
48
- ## 故障排除
49
-
50
- 如果启动失败:
51
- 1. 检查端口是否被占用:`lsof -i :13337` 和 `lsof -i :17788`
52
- 2. 确认 devflow 已安装:`npx devflow --version`
53
- 3. 如需后台运行:`npx devflow start -d`
54
- 4. 仅启动服务端(不要 Dashboard):`npx devflow start --no-dashboard`
@@ -1,58 +0,0 @@
1
- ---
2
- name: devflow:tailwind
3
- description: Tailwind 专家 — 响应式设计、主题定制、Purge 检查、Utility 审查
4
- required_mcp_tools:
5
- - tailwind_new_component
6
- ---
7
- ## MANDATORY FIRST STEP - Skill Registration
8
-
9
- > **IMPORTANT: Before ANY other action, execute the registration command below. This is NON-NEGOTIABLE.**
10
-
11
- ```bash
12
- mkdir -p ~/.devflow && echo '{"name":"devflow:tailwind","required_mcp_tools":["tailwind_new_component"],"description":"devflow:tailwind skill","registeredAt":'"$(date +%s)000"'}' > ~/.devflow/current-skill.json
13
- ```
14
-
15
- After registration, you **MUST** use ONLY these MCP tools for all work in this skill:
16
- - `mcp__devflow__tailwind_new_component`
17
-
18
- **Never use direct tools** (Read, Write, Edit, Bash, Grep, etc.) for tasks that can be handled by the MCP tools above.
19
-
20
- When the skill execution is complete, clean up:
21
- ```bash
22
- rm -f ~/.devflow/current-skill.json ~/.devflow/current-execution-id
23
- ```
24
-
25
-
26
- # 🌊 TAILWIND
27
-
28
- 你是一个 Tailwind CSS 专家。使用 utility-first 方法构建界面。遇到问题先查 Tailwind 官方文档。
29
-
30
- ## 适用场景
31
-
32
- **新建 Tailwind 组件:语义结构 → 样式 → 响应式 → 暗色模式**
33
-
34
- **Utility 审查:清除自定义 CSS → 统一为 Tailwind utility**
35
-
36
- **主题迁移:分析现有设计 → 提取 Design Token → 生成配置**
37
-
38
- ## 核心规则
39
-
40
- - 优先使用 Tailwind utility classes,避免自定义 CSS
41
- - 使用 Tailwind 响应式断点(sm/md/lg/xl/2xl)
42
- - 颜色和间距从 theme 配置中引用
43
- - 复杂样式使用 @apply 抽取
44
- - 使用 class 策略实现暗色模式
45
- - 避免内联 style 和自定义 CSS
46
- - 不确定 class 名称时先查 Tailwind 官方文档
47
-
48
- ## 当前版本
49
-
50
- - tailwind-docs: 3.4.0 — https://tailwindcss.com/docs
51
-
52
- ## 工作流
53
-
54
- | 场景 | 触发方式 |
55
- |------|----------|
56
- | 新建 Tailwind 组件:语义结构 → 样式 → 响应式 → 暗色模式 | 调用 MCP 工具 `tailwind_new_component` |
57
- | Utility 审查:清除自定义 CSS → 统一为 Tailwind utility | 调用 MCP 工具 `tailwind_audit:utility` |
58
- | 主题迁移:分析现有设计 → 提取 Design Token → 生成配置 | 调用 MCP 工具 `tailwind_migrate:theme` |
@@ -1,61 +0,0 @@
1
- ---
2
- name: devflow:taro
3
- description: Taro 跨端专家 — 多端适配、小程序调试、性能优化、兼容方案
4
- required_mcp_tools:
5
- - taro_new_page
6
- ---
7
- ## MANDATORY FIRST STEP - Skill Registration
8
-
9
- > **IMPORTANT: Before ANY other action, execute the registration command below. This is NON-NEGOTIABLE.**
10
-
11
- ```bash
12
- mkdir -p ~/.devflow && echo '{"name":"devflow:taro","required_mcp_tools":["taro_new_page"],"description":"devflow:taro skill","registeredAt":'"$(date +%s)000"'}' > ~/.devflow/current-skill.json
13
- ```
14
-
15
- After registration, you **MUST** use ONLY these MCP tools for all work in this skill:
16
- - `mcp__devflow__taro_new_page`
17
-
18
- **Never use direct tools** (Read, Write, Edit, Bash, Grep, etc.) for tasks that can be handled by the MCP tools above.
19
-
20
- When the skill execution is complete, clean up:
21
- ```bash
22
- rm -f ~/.devflow/current-skill.json ~/.devflow/current-execution-id
23
- ```
24
-
25
-
26
- # 🛠️ TARO
27
-
28
- 你是一个 Taro 跨端开发专家。使用 Taro 内置组件和 API,确保多端兼容。遇到小程序问题先查文档,不凭经验猜测。
29
-
30
- ## 适用场景
31
-
32
- **新建页面:** Taro 跨端页面 → 生成页面组件(兼容 H5/微信小程序),配置路由和导航栏。
33
-
34
- **跨端兼容检查:扫描平台 API → 识别风险点 → 建议兼容方案**
35
-
36
- **小程序调试:错误排查 → 包体积分析 → 性能检测**
37
-
38
- **小程序性能优化:包体积 → 渲染优化 → 加载速度**
39
-
40
- ## 核心规则
41
-
42
- - 使用 Taro 内置组件(View、Text、Image)替代 HTML 元素
43
- - 使用 Taro API 替代浏览器 API
44
- - 避免使用 window/document 等 DOM API
45
- - 使用条件编译处理平台差异(process.env.TARO_ENV)
46
- - 样式使用 px 单位(Taro 自动转换)
47
- - 合理使用分包加载减少首屏体积
48
- - 不确定跨端兼容性时先查 Taro 文档确认
49
-
50
- ## 当前版本
51
-
52
- - taro-docs: 3.6.0 — https://docs.taro.zone/docs/
53
-
54
- ## 工作流
55
-
56
- | 场景 | 触发方式 |
57
- |------|----------|
58
- | 新建页面: | 调用 MCP 工具 `taro_new_page` |
59
- | 跨端兼容检查:扫描平台 API → 识别风险点 → 建议兼容方案 | 调用 MCP 工具 `taro_check:cross-platform` |
60
- | 小程序调试:错误排查 → 包体积分析 → 性能检测 | 调用 MCP 工具 `taro_debug:miniapp` |
61
- | 小程序性能优化:包体积 → 渲染优化 → 加载速度 | 调用 MCP 工具 `taro_optimize:performance` |
@@ -1,39 +0,0 @@
1
- ---
2
- name: devflow:ui-layout
3
- description: UI Layout 专家 — 布局模式、组件组合、响应式架构、设计系统
4
- required_mcp_tools: []
5
- ---
6
-
7
- # 📐 UI-LAYOUT
8
-
9
- 你是一个 UI Layout 专家。精通 CSS Grid、Flexbox 和响应式设计。使用 Design Token 体系管理样式变量。
10
-
11
- ## 适用场景
12
-
13
- **布局审计:一致性检查 → 响应式问题 → 可访问性评估**
14
-
15
- **响应式改造:断点分析 → 移动适配 → Container Queries**
16
-
17
- **Design Token 体系建设:提取 → 分层 → 代码化**
18
-
19
- ## 核心规则
20
-
21
- - 优先使用 CSS Grid 做页面布局,Flexbox 做组件内排列
22
- - 使用容器查询实现组件级响应式
23
- - 间距遵循 4px 倍数的 Scale 体系
24
- - 使用语义化 HTML(header/nav/main/aside/footer)
25
- - 移动优先设计,渐进增强
26
- - 使用 CSS 变量管理 Design Token
27
- - 确保触控目标 ≥ 44×44px,对比度 ≥ 4.5:1
28
-
29
- ## 当前版本
30
-
31
- - web-dev-layout: 2024 — https://web.dev/learn/design/
32
-
33
- ## 工作流
34
-
35
- | 场景 | 触发方式 |
36
- |------|----------|
37
- | 布局审计:一致性检查 → 响应式问题 → 可访问性评估 | 调用 MCP 工具 `ui-layout_audit:layout` |
38
- | 响应式改造:断点分析 → 移动适配 → Container Queries | 调用 MCP 工具 `ui-layout_design:responsive` |
39
- | Design Token 体系建设:提取 → 分层 → 代码化 | 调用 MCP 工具 `ui-layout_setup:design-tokens` |
@@ -1,69 +0,0 @@
1
- ---
2
- name: devflow:vue
3
- description: Vue 3 专家 — Bug 诊断、Composition API、响应式调试、组件重构
4
- required_mcp_tools:
5
- - vue_diagnose_bug
6
- - vue_new_component
7
- - vue_debug_reactivity
8
- ---
9
- ## MANDATORY FIRST STEP - Skill Registration
10
-
11
- > **IMPORTANT: Before ANY other action, execute the registration command below. This is NON-NEGOTIABLE.**
12
-
13
- ```bash
14
- mkdir -p ~/.devflow && echo '{"name":"devflow:vue","required_mcp_tools":["vue_diagnose_bug","vue_new_component","vue_debug_reactivity"],"description":"devflow:vue skill","registeredAt":'"$(date +%s)000"'}' > ~/.devflow/current-skill.json
15
- ```
16
-
17
- After registration, you **MUST** use ONLY these MCP tools for all work in this skill:
18
- - `mcp__devflow__vue_diagnose_bug`
19
- - `mcp__devflow__vue_new_component`
20
- - `mcp__devflow__vue_debug_reactivity`
21
-
22
- **Never use direct tools** (Read, Write, Edit, Bash, Grep, etc.) for tasks that can be handled by the MCP tools above.
23
-
24
- When the skill execution is complete, clean up:
25
- ```bash
26
- rm -f ~/.devflow/current-skill.json ~/.devflow/current-execution-id
27
- ```
28
-
29
-
30
- # 💚 VUE
31
-
32
- 你是一个 Vue 3 专家。使用 Composition API、<script setup> 和 TypeScript。遇到问题先查文档再给方案,不凭空猜测。
33
-
34
- ## 适用场景
35
-
36
- **Bug 排查:** 组件渲染异常、响应式数据不同步 → 定位源码,检查 computed/watch 逻辑,搜索 Vue 官方文档验证 API 用法。
37
-
38
- **新建组件:** 按照项目 SFC 规范生成组件(template + script setup + style scoped),附带 Props/Emits/Slots 类型定义。
39
-
40
- **响应式调试:追踪数据流 → 定位问题 → 修复**
41
-
42
- **提取 Composable:识别重复逻辑 → 抽取 → 替换引用**
43
-
44
- **Pinia Store 重构:结构审查 → 拆分/合并 → 类型安全**
45
-
46
- ## 核心规则
47
-
48
- - 使用 <script setup lang="ts"> 语法糖
49
- - 使用 Composition API(ref、reactive、computed、watch)
50
- - 状态管理使用 Pinia
51
- - 可复用逻辑抽取为 composables
52
- - 遇到不确定的 API 时先查 Vue 官方文档再回答
53
- - 修复 Bug 前先排查响应式数据流
54
- - 生成代码后必须通过 vue-tsc 类型检查
55
- - 不能凭记忆猜测 API 行为,必须基于当前项目版本
56
-
57
- ## 当前版本
58
-
59
- - vue-docs: 3.4.0 — https://vuejs.org/guide/introduction.html
60
-
61
- ## 工作流
62
-
63
- | 场景 | 触发方式 |
64
- |------|----------|
65
- | Bug 排查: | 调用 MCP 工具 `vue_diagnose_bug` |
66
- | 新建组件: | 调用 MCP 工具 `vue_new_component` |
67
- | 响应式调试:追踪数据流 → 定位问题 → 修复 | 调用 MCP 工具 `vue_debug_reactivity` |
68
- | 提取 Composable:识别重复逻辑 → 抽取 → 替换引用 | 调用 MCP 工具 `vue_extract:composable` |
69
- | Pinia Store 重构:结构审查 → 拆分/合并 → 类型安全 | 调用 MCP 工具 `vue_refactor:pinia` |
@@ -1,37 +0,0 @@
1
- ---
2
- name: devflow:workflow
3
- description: 执行标准化开发工作流 — Bug 修复、功能开发、代码审查
4
- required_mcp_tools:
5
- - run_workflow
6
- ---
7
- ## MANDATORY FIRST STEP - Skill Registration
8
-
9
- > **IMPORTANT: Before ANY other action, execute the registration command below. This is NON-NEGOTIABLE.**
10
-
11
- ```bash
12
- mkdir -p ~/.devflow && echo '{"name":"devflow:workflow","required_mcp_tools":["run_workflow"],"description":"devflow:workflow skill","registeredAt":'"$(date +%s)000"'}' > ~/.devflow/current-skill.json
13
- ```
14
-
15
- After registration, you **MUST** use ONLY these MCP tools for all work in this skill:
16
- - `mcp__devflow__run_workflow`
17
-
18
- **Never use direct tools** (Read, Write, Edit, Bash, Grep, etc.) for tasks that can be handled by the MCP tools above.
19
-
20
- When the skill execution is complete, clean up:
21
- ```bash
22
- rm -f ~/.devflow/current-skill.json ~/.devflow/current-execution-id
23
- ```
24
-
25
-
26
- # /devflow:workflow
27
-
28
- ## 执行
29
-
30
- 调用 `run_workflow` MCP 工具:
31
-
32
- ```
33
- type = "bugfix" | "feature" | "review"
34
- input = 用户的查询内容
35
- ```
36
-
37
- MCP 工具提供标准化的 DAG 步骤编排、人工确认节点、执行追踪和遥测记录。工作流执行过程中,MCP 工具会返回需要你介入的步骤,此时才根据步骤指引执行具体操作。
package/dist/server.js DELETED
@@ -1,10 +0,0 @@
1
- import'reflect-metadata';import {Reflector,APP_GUARD,APP_INTERCEPTOR,NestFactory}from'@nestjs/core';import {FastifyAdapter}from'@nestjs/platform-fastify';import {Injectable,Inject,Global,Module,Optional,Get,Query,Param,Post,Body,Delete,Controller,Headers,Put,forwardRef,Res,Catch,UnauthorizedException,NotFoundException,BadRequestException,SetMetadata,Logger,HttpException,HttpStatus}from'@nestjs/common';import {existsSync,readFileSync}from'fs';import {join}from'path';import {createEngines}from'@devflow-tools/context-engine';import {TelemetryEngine}from'@devflow-tools/telemetry';import {MemoryEngine,checkOllama,getOllamaInfoMessage}from'@devflow-tools/memory-engine';import {WorkflowEngine}from'@devflow-tools/workflow-engine';import {loadPlugins}from'@devflow-tools/sdk';import {Subject}from'rxjs';import {KnowledgeEngine}from'@devflow-tools/knowledge-engine';import {BenchmarkEngine}from'@devflow-tools/benchmark';import {DevFlowDatabase}from'@devflow-tools/database';import {map}from'rxjs/operators';var xe=Object.defineProperty;var Ee=Object.getOwnPropertyDescriptor;var i=(c,t,e,s)=>{for(var r=s>1?void 0:s?Ee(t,e):t,o=c.length-1,a;o>=0;o--)(a=c[o])&&(r=(s?a(t,e,r):a(r))||r);return s&&r&&xe(t,e,r),r},n=(c,t)=>(e,s)=>t(e,s,c);var Nt="isPublic",Zt=()=>SetMetadata(Nt,true);var Ot={MISSING_API_KEY:"AUTH_MISSING_API_KEY",INVALID_API_KEY:"AUTH_INVALID_API_KEY"};var Ne=(process.env.DEVFLOW_API_KEYS??"dev-key-000000").split(",").map(c=>c.trim()).filter(Boolean),X=class{constructor(t){this.reflector=t;}canActivate(t){if(this.reflector.getAllAndOverride(Nt,[t.getHandler(),t.getClass()]))return true;let r=t.switchToHttp().getRequest().headers["x-api-key"];if(!r)throw new UnauthorizedException({error:{code:Ot.MISSING_API_KEY,message:"X-API-Key header is required",details:{}}});if(!Ne.includes(r))throw new UnauthorizedException({error:{code:Ot.INVALID_API_KEY,message:"Invalid API key",details:{}}});return true}};X=i([Injectable(),n(0,Inject(Reflector))],X);var st=class{};st=i([Global(),Module({providers:[X,{provide:APP_GUARD,useClass:X}]})],st);var g={WORKFLOW_NOT_FOUND:"WORKFLOW_NOT_FOUND",RUN_NOT_FOUND:"RUN_NOT_FOUND",PROJECT_NOT_FOUND:"PROJECT_NOT_FOUND",NODE_NOT_FOUND:"NODE_NOT_FOUND",PLUGIN_NOT_FOUND:"PLUGIN_NOT_FOUND",BAD_REQUEST:"BAD_REQUEST",VALIDATION_ERROR:"VALIDATION_ERROR",INTERNAL_ERROR:"INTERNAL_ERROR"};var v=class{constructor(t){this.database=t;this.projects=new Map;this.activeProjectRoot=process.env.DEVFLOW_PROJECT_ROOT??null;}onModuleInit(){if(!process.env.DEVFLOW_PROJECT_ROOT&&this.database){let t=this.database.getSetting("activeProjectRoot");t&&(this.activeProjectRoot=t);}}setActiveProject(t){this.activeProjectRoot=t,this.database&&this.database.setSetting("activeProjectRoot",t);}disconnectProject(){this.activeProjectRoot=null,this.database&&this.database.deleteSetting("activeProjectRoot");}getActiveProjectRoot(){return this.activeProjectRoot}async list(){return Array.from(this.projects.values())}async getById(t){let e=this.projects.get(t);if(!e)throw new NotFoundException({error:{code:g.PROJECT_NOT_FOUND,message:`Project "${t}" not found`,details:{}}});return e}async create(t){let e=`proj_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,s={id:e,name:t.name,rootPath:t.rootPath,stack:t.stack,createdAt:Date.now()};return this.projects.set(e,s),this.activeProjectRoot||this.setActiveProject(t.rootPath),s}async delete(t){if(!this.projects.has(t))throw new NotFoundException({error:{code:g.PROJECT_NOT_FOUND,message:`Project "${t}" not found`,details:{}}});this.projects.delete(t);}async getOnboardingPack(t){let e=join(t,".devflow","onboarding-pack.json");if(!existsSync(e))throw new NotFoundException({error:{code:g.PROJECT_NOT_FOUND,message:"Onboarding pack not found. Run `devflow init` first.",details:{}}});return JSON.parse(readFileSync(e,"utf-8"))}async getOnboardingPackByRoot(t){let e=join(t,".devflow","onboarding-pack.json");try{return existsSync(e)?JSON.parse(readFileSync(e,"utf-8")):null}catch{return null}}};v=i([Injectable(),n(0,Optional()),n(0,Inject("DATABASE"))],v);var P=class{constructor(t){this.service=t;}async list(){return this.service.list()}async getOnboardingPackByRoot(t){if(!t)throw new BadRequestException({error:{code:g.BAD_REQUEST,message:"rootPath is required",details:{}}});return this.service.getOnboardingPackByRoot(t)}async getById(t){return this.service.getById(t)}async getOnboardingPack(t){let e=await this.service.getById(t);return this.service.getOnboardingPack(e.rootPath)}async create(t){return this.service.create(t)}async connect(t){return this.service.setActiveProject(t.rootPath),{rootPath:t.rootPath}}async switchProject(t){return this.service.setActiveProject(t.rootPath),{rootPath:t.rootPath}}async getActive(){return {rootPath:this.service.getActiveProjectRoot()}}async disconnect(){return this.service.disconnectProject(),{ok:true}}async delete(t){return this.service.delete(t)}};i([Get()],P.prototype,"list",1),i([Get("onboarding-pack"),n(0,Query("rootPath"))],P.prototype,"getOnboardingPackByRoot",1),i([Get(":id"),n(0,Param("id"))],P.prototype,"getById",1),i([Get(":id/onboarding-pack"),n(0,Param("id"))],P.prototype,"getOnboardingPack",1),i([Post(),n(0,Body())],P.prototype,"create",1),i([Post("connect"),n(0,Body())],P.prototype,"connect",1),i([Post("switch"),n(0,Body())],P.prototype,"switchProject",1),i([Get("active")],P.prototype,"getActive",1),i([Delete("active")],P.prototype,"disconnect",1),i([Delete(":id"),n(0,Param("id"))],P.prototype,"delete",1),P=i([Controller("projects"),n(0,Inject(v))],P);var w=class{};w=i([Module({controllers:[P],providers:[v],exports:[v]})],w);var E=class{constructor(t){this.engine=new TelemetryEngine;this.db=t??null;}async recordEvent(t){await this.engine.recordEvent(t);}async listRuns(t,e,s){let r=Array.from(this.engine.runs.values()),o=r;s&&(o=r.filter(u=>u.meta?.source===s));let a=o.slice(e,e+t).map(u=>({id:u.meta?.runId??"",agent:u.meta?.agent??"",mode:u.meta?.mode??"",source:u.meta?.source??"unknown",status:u.status,startedAt:u.startedAt,tokenUsed:u.tokenUsed}));if(this.db)try{let l=this.db.listSkillExecutions(t,0).map(f=>({id:f.executionId,agent:"claude-code",mode:"hook",source:"hook",status:f.status,startedAt:f.startedAt,tokenUsed:f.totalTokens,skillName:f.skillName,totalToolCalls:f.totalToolCalls,mcpToolCalls:f.mcpToolCalls,mcpComplianceRate:f.mcpComplianceRate})),p=new Set;return [...l,...a].filter(f=>p.has(f.id)?!1:(p.add(f.id),!0)).slice(e,e+t)}catch{}return a}async getRun(t){let e=this.engine.runs.get(t);if(e)return e;if(this.db)try{let s=this.db.getSkillExecution(t);if(s)return {meta:{runId:s.executionId,agent:"claude-code",mode:"hook",source:"hook"},status:s.status,startedAt:s.startedAt,finishedAt:s.finishedAt,tokenUsed:s.totalTokens,steps:[],skillName:s.skillName,totalToolCalls:s.totalToolCalls,mcpToolCalls:s.mcpToolCalls,directToolCalls:s.directToolCalls,mcpComplianceRate:s.mcpComplianceRate}}catch{}throw new NotFoundException({error:{code:g.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}})}async getTimeline(t,e){return Array.from(this.engine.runs.values()).filter(r=>!(t&&r.startedAt<Number(t)||e&&r.startedAt>Number(e))).flatMap(r=>r.steps?.map(o=>({runId:r.meta?.runId,stepId:o.stepId,type:o.type,duration:o.duration,timestamp:o.timestamp}))??[])}async getRunEvents(t){let e=await this.engine.listEvents(t);if(e&&e.length>0)return e;if(this.db)try{let s=this.db.listToolCallEvents(t);if(s&&s.length>0)return s.map(r=>({eventId:r.eventId,runId:t,stepId:r.eventId,type:r.isMcpTool?"mcp_tool":r.toolType==="subagent"?"subagent":"tool_use",timestamp:r.timestamp,duration:r.duration,toolName:r.toolName,toolType:r.toolType,isMcpTool:r.isMcpTool,mcpToolName:r.mcpToolName,mcpEnforced:r.mcpEnforced,mcpFallback:r.mcpFallback,tokensUsed:r.tokensUsed,blocked:r.blocked,blockReason:r.blockReason,error:r.error}))}catch{}return e??[]}async getRunStats(t){let e=await this.engine.getRunStats(t);if(e&&e.totalEvents>0)return e;if(this.db)try{let s=this.db.getSkillExecution(t),r=this.db.listToolCallEvents(t);if(s){let o=r?.reduce((a,u)=>a+(u.tokensUsed??0),0)??0;return {totalEvents:r?.length??0,llmCalls:0,totalTokens:s.totalTokens||o,toolUses:s.totalToolCalls,fileReads:0,fileWrites:0,bashCommands:0,errors:r?.filter(a=>a.error).length??0,totalDuration:s.totalDuration,mcpToolCalls:s.mcpToolCalls,directToolCalls:s.directToolCalls,mcpComplianceRate:s.mcpComplianceRate}}}catch{}return e}async endRun(t,e){await this.engine.endRun(t,e);}async getFeedbackStats(t,e){let s=this.collectAllEvents(),r=e!=null?Date.now()-e*24*60*60*1e3:void 0,o=s.filter(d=>!(d.data?.toolName!=="context_feedback"||t&&d.data?.toolInput?.projectRoot!==t||r!=null&&(d.timestamp??0)<r)),a=o.length,u=o.filter(d=>d.data?.toolInput?.feedback==="hit").length,l=o.filter(d=>d.data?.toolInput?.feedback==="partial").length,p=o.filter(d=>d.data?.toolInput?.feedback==="miss").length;return {total:a,hits:u,partials:l,misses:p,hitRate:a>0?u/a:0,partialRate:a>0?l/a:0,missRate:a>0?p/a:0}}collectAllEvents(){let t=this.engine.events;if(!t)return [];let e=[];for(let s of t.values())Array.isArray(s)&&e.push(...s);return e}async getStats(t=7){let e=Array.from(this.engine.runs.values()),s=Date.now(),r=s-t*24*60*60*1e3,o=e.filter(h=>h.startedAt>=r),a={};for(let h of o){let k=new Date(h.startedAt).toISOString().slice(0,10);a[k]||(a[k]={runs:0,tokens:0}),a[k].runs++,a[k].tokens+=h.tokenUsed??0;}let u=0,l=0,p=0;for(let h of o){let k=this.engine.events.get(h.meta?.runId)??[];u+=h.tokenUsed??0,l+=k.filter(Q=>Q.kind==="llm_call").length,p+=k.filter(Q=>Q.kind==="tool_use").length;}let d=new Date(r).toISOString().slice(0,10),f=new Date(s).toISOString().slice(0,10);return {period:{from:d,to:f},summary:{totalRuns:o.length,completedRuns:o.filter(h=>h.status==="completed").length,failedRuns:o.filter(h=>h.status==="failed").length,totalTokens:u,totalLlmCalls:l,totalToolUses:p,avgRunDuration:o.length>0?Math.round(o.reduce((h,k)=>h+((k.finishedAt??s)-k.startedAt),0)/o.length):0},byDay:Object.entries(a).map(([h,k])=>({date:h,...k})).sort((h,k)=>h.date.localeCompare(k.date)),byWorkflow:this.buildWorkflowBreakdown(o,s),byPlugin:this.buildPluginBreakdown(o)}}buildWorkflowBreakdown(t,e){let s={};for(let r of t){let o=r.workflowName??r.meta?.workflowName??"unknown";s[o]||(s[o]={runs:0,completed:0,failed:0,avgDuration:0}),s[o].runs++,r.status==="completed"?s[o].completed++:s[o].failed++,s[o].avgDuration+=(r.finishedAt??e)-r.startedAt;}for(let r of Object.keys(s))s[r].avgDuration=s[r].runs>0?Math.round(s[r].avgDuration/s[r].runs):0;return Object.entries(s).map(([r,o])=>({name:r,runs:o.runs,successRate:o.runs>0?o.completed/o.runs:0,avgDuration:o.avgDuration}))}buildPluginBreakdown(t){let e={};for(let s of t){let r=s.pluginName??s.meta?.pluginName??"none";e[r]||(e[r]={runs:0,completed:0,failed:0}),e[r].runs++,s.status==="completed"?e[r].completed++:e[r].failed++;}return Object.entries(e).map(([s,r])=>({name:s,runs:r.runs,successRate:r.runs>0?r.completed/r.runs:0}))}async getOpsRoiSummary(){let t=Array.from(this.engine.runs.values()),e=Date.now(),s=t.length,r=t.filter(x=>x.status==="completed").length,o=s>0?r/s:0,a=t.reduce((x,z)=>x+(z.tokenUsed??0),0),u=s>0?a/s:0,l=t.reduce((x,z)=>{let At=z.startedAt??0,jt=z.finishedAt??e;return x+(jt-At)},0),p=s>0?l/s:0,d=t.filter(x=>x.relevanceFeedback==="hit"||x.meta?.relevanceFeedback==="hit").length,f=t.filter(x=>x.relevanceFeedback!==void 0||x.meta?.relevanceFeedback!==void 0).length,h=await this.getFeedbackStats(),k=d+h.hits,Q=f+h.total,wt=Q>0?k/Q:0;return {period:"all-time",totalRuns:s,successfulRuns:r,successRate:o,avgTokenUsage:u,avgDuration:p,feedbackHitRate:wt,trend:"stable"}}async getExperimentalRoiSummary(){return {totalScenarios:0,avgTimeSavedRate:0,avgTokenReductionRate:0,avgFirstPassLift:0,avgReworkReductionRate:0,conclusion:"No experimental data available yet"}}async getRoiSummary(t=7){let e=Array.from(this.engine.runs.values()),s=Date.now(),r=s-t*24*60*60*1e3,o=e.filter(m=>m.startedAt>=r),a=o.length,u=o.filter(m=>m.status==="completed").length,l=o.filter(m=>m.status!=="completed").length,p=a>0?Math.round(o.reduce((m,R)=>m+((R.finishedAt??s)-R.startedAt),0)/a):0,d=a>0?Math.round(o.reduce((m,R)=>m+(R.tokenUsed??0),0)/a):0,f=o.filter(m=>m.firstPassSuccess===true||m.meta?.firstPassSuccess===true).length,h=a>0?f/a:0,k=o.filter(m=>m.relevanceFeedback==="hit"||m.meta?.relevanceFeedback==="hit").length,Q=o.filter(m=>m.relevanceFeedback!==void 0||m.meta?.relevanceFeedback!==void 0).length,wt=await this.getFeedbackStats(void 0,t),x=k+wt.hits,z=Q+wt.total,At=z>0?x/z:0,jt=o.reduce((m,R)=>m+(R.retryCount??R.meta?.retryCount??0),0),we=a>0?jt/a:0,Se=p,ft={context_insufficient:0,knowledge_missing:0,workflow_design_issue:0,tool_error:0,agent_override:0,unknown:0};for(let m of o)if(m.status!=="completed"){let R=m.meta?.runId;if(R)try{let Xt=await this.engine.classifyFailure(R);ft[Xt]=(ft[Xt]??0)+1;}catch{ft.unknown++;}else ft.unknown++;}let et={};for(let m of o){let R=new Date(m.startedAt).toISOString().slice(0,10);et[R]||(et[R]={runs:0,tokens:0,failures:0}),et[R].runs++,et[R].tokens+=m.tokenUsed??0,m.status!=="completed"&&et[R].failures++;}return {period:{from:new Date(r).toISOString().slice(0,10),to:new Date(s).toISOString().slice(0,10)},overview:{totalRuns:a,completedRuns:u,failedRuns:l,avgDuration:p,avgTokens:d,firstPassSuccessRate:h,feedbackHitRate:At},efficiency:{totalTokensSaved:0,avgTimePerTask:Se,avgRetryCount:we},failures:{total:l,breakdown:ft},workflows:this.buildWorkflowBreakdown(o,s),plugins:this.buildPluginBreakdown(o),byDay:Object.entries(et).map(([m,R])=>({date:m,...R})).sort((m,R)=>m.date.localeCompare(R.date))}}async getPluginEffectiveness(t,e){await this.getPluginUsageStats(t);let o=Array.from(this.engine.runs.values()).filter(p=>!((p.pluginName??p.meta?.pluginName)!==t||e&&p.meta?.projectRoot!==e)),a=o.length,u=o.filter(p=>p.status==="completed").length,l=a>0?o.reduce((p,d)=>p+((d.finishedAt??Date.now())-d.startedAt),0)/a:0;return {name:t,installCount:1,activeRate:a>0?1:0,successRate:a>0?u/a:0,avgTokenImpact:-l*.1,lastUsedAt:o.length>0?new Date(Math.max(...o.map(p=>p.startedAt))).toISOString():void 0,recommendation:this.getRecommendation(a>0?u/a:0,a)}}async getPluginUsageStats(t){let s=Array.from(this.engine.runs.values()).filter(d=>(d.pluginName??d.meta?.pluginName)===t),r=s.length,o=s.filter(d=>d.status==="completed").length,a=new Set;for(let d of s){let f=d.meta?.projectRoot;f&&a.add(f);}let u=r>0?s.reduce((d,f)=>d+((f.finishedAt??Date.now())-f.startedAt),0)/r:0,l=s.map(d=>d.startedAt).filter(d=>typeof d=="number"),p=l.length>0?new Date(Math.max(...l)).toISOString():void 0;return {activeProjects:a.size,totalRuns:r,successfulRuns:o,avgTokenImpact:-u*.1,lastUsedAt:p}}getRecommendation(t,e){return e===0?"remove":t>.8?"install":t>.5?"optimize":"remove"}async classifyFailure(t){let e=await this.getRun(t).catch(()=>null);if(!e||e.status!=="failed")return {};let s=e.steps?.find(o=>o.status==="failed");if(!s)return {};let r=s.error?.toLowerCase()??"";return r.includes("context")||r.includes("insufficient")?{failureCategory:"context_insufficient",failureReason:"Context provided was insufficient for the task",suggestedActions:[{action:"Supplement task context",priority:"high"},{action:"View graph roots",priority:"medium"},{action:"Add related memory",priority:"medium"}]}:r.includes("knowledge")||r.includes("docs")?{failureCategory:"knowledge_missing",failureReason:"Required knowledge was not available",suggestedActions:[{action:"Sync knowledge source",priority:"high"},{action:"Add docs source",priority:"medium"}]}:r.includes("workflow")||r.includes("step")?{failureCategory:"workflow_design_issue",failureReason:"Workflow design issue detected",suggestedActions:[{action:"Adjust specific step",priority:"high"},{action:"Split workflow",priority:"medium"}]}:r.includes("tool")||r.includes("connection")?{failureCategory:"tool_error",failureReason:"Tool execution error",suggestedActions:[{action:"Check tool connectivity",priority:"high"},{action:"Retry or fallback",priority:"medium"}]}:{failureCategory:"agent_override",failureReason:"Agent override detected",suggestedActions:[{action:"Enable/strengthen enforcer",priority:"high"}]}}async cleanup(t){let e=this.engine.runs,s=Date.now()-t*24*60*60*1e3,r=0;for(let[o,a]of e)a.startedAt&&a.startedAt<s&&(e.delete(o),r++);return r}async recordExecutionStart(t){this.db&&this.db.insertSkillExecution({executionId:t.executionId,skillName:t.skillName,startedAt:t.startedAt,status:"running"});}async recordToolCall(t){if(!this.db)return;this.db.getSkillExecution(t.executionId)||this.db.insertSkillExecution({executionId:t.executionId,skillName:t.mcpToolName??t.toolName,startedAt:t.timestamp,status:"running"}),this.db.insertToolCallEvent({eventId:t.eventId,executionId:t.executionId,timestamp:t.timestamp,toolName:t.toolName,toolType:t.toolType,isMcpTool:t.isMcpTool,mcpToolName:t.mcpToolName,mcpEnforced:t.mcpEnforced,mcpFallback:t.mcpFallback,input:t.input,tokensUsed:t.tokensUsed,duration:t.duration,parentToolCallId:t.parentToolCallId,subagentId:t.subagentId,error:t.error,blocked:t.blocked,blockReason:t.blockReason});}async recordExecutionComplete(t){this.db&&this.db.updateSkillExecution(t.executionId,{status:t.status,finishedAt:t.finishedAt,totalDuration:t.summary.totalDuration,totalTokens:t.summary.totalTokens,mcpComplianceRate:t.summary.mcpComplianceRate});}async getExecutions(t,e){return this.db?this.db.listSkillExecutions(t,e):[]}async getExecutionEvents(t){return this.db?this.db.listToolCallEvents(t):[]}async getMcpCompliance(){return this.db?this.db.getMcpCompliance():{overall:0,bySkill:{},missedTools:[]}}};E=i([Injectable(),n(0,Optional()),n(0,Inject("DATABASE"))],E);var O=class{constructor(t,e){this.telemetryService=t;this.database=e;this.projectStats=new Map;this.benchmarkResults=[];}async recordTelemetryEvent(t){let e=`evt_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,s=t.toolName?"tool_use":"step_end",r={id:e,runId:t.metadata?.runId??`event_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,stepId:e,kind:s,timestamp:Date.now(),duration:t.durationMs,data:{toolName:t.toolName,toolInput:t.args,errorMessage:t.error},metadata:{source:"claude-code"}};return await this.telemetryService.recordEvent(r),{eventId:e}}async getProjectStats(t){return this.database?this.database.getProjectStats(t):this.projectStats.get(t)??null}async updateProjectStats(t,e){if(this.database){let a={...await this.getProjectStats(t)??{projectRoot:t,totalRuns:0,successfulRuns:0,totalTokens:0,lastActiveAt:Date.now(),topTools:[]},...e,lastActiveAt:Date.now()};return await this.database.upsertProjectStats(a),a}let r={...this.projectStats.get(t)??{projectRoot:t,totalRuns:0,successfulRuns:0,totalTokens:0,lastActiveAt:Date.now(),topTools:[]},...e,lastActiveAt:Date.now()};return this.projectStats.set(t,r),r}recordBenchmarkResult(t){this.benchmarkResults.push(t);}getBenchmarkResults(t){return t?this.benchmarkResults.filter(e=>this.projectStats.get(e.scenarioId)?.projectRoot===t):this.benchmarkResults}async getPluginEffectiveness(t){return []}};O=i([Injectable(),n(0,Inject(E)),n(1,Optional()),n(1,Inject("DATABASE"))],O);var C=class{constructor(t){this.dataService=t;this.feedbackEntries=[];}async indexProject(t){let{context:e,codegraph:s}=await createEngines(t);await e.index(t);let r=s.getStats();return {totalFiles:r.fileCount,totalSymbols:r.nodeCount,lastIndexTime:r.lastUpdated,indexing:s.isIndexing()}}async getStatus(t){try{let{codegraph:e}=await createEngines(t),s=e.getStats();return {totalFiles:s.fileCount,totalSymbols:s.nodeCount,lastIndexTime:s.lastUpdated,indexing:e.isIndexing()}}catch{return {totalFiles:0,totalSymbols:0,lastIndexTime:0,indexing:false}}}async buildContext(t,e,s,r){let{context:o}=await createEngines(t);return o.build({query:e,mode:s,maxTokens:r??8e3,includeGraph:s==="deep"})}async buildTaskContext(t,e,s,r){let{context:o}=await createEngines(t);return o.buildTaskContext(e,{mode:s,maxTokens:r??8e3})}async findSymbol(t,e){let{indexer:s}=await createEngines(t);return s.findSymbol(e)}async recordFeedback(t,e,s,r){let o={query:e,feedback:s,timestamp:Date.now(),projectRoot:t};return this.feedbackEntries.push(o),this.dataService&&await this.dataService.recordTelemetryEvent({toolName:"context_feedback",args:{query:e,feedback:s,taskType:r?.taskType,contextMode:r?.contextMode,projectRoot:t},durationMs:0,success:true,metadata:{projectRoot:t,query:e,taskType:r?.taskType}}),o}async getFeedbackSummaries(){let t=this.feedbackEntries.length,e=this.feedbackEntries.filter(o=>o.feedback==="hit").length,s=this.feedbackEntries.filter(o=>o.feedback==="partial").length,r=this.feedbackEntries.filter(o=>o.feedback==="miss").length;return {total:t,hits:e,partials:s,misses:r,hitRate:t>0?e/t:0}}};C=i([Injectable(),n(0,Optional()),n(0,Inject(O))],C);var I=class{constructor(t,e){this.service=t;this.projects=e;}resolveRootPath(t,e){let s=t??e??this.projects.getActiveProjectRoot();if(!s)throw new BadRequestException("rootPath is required \u2014 no active project connected");return s}async status(t,e){let s=t??e??this.projects.getActiveProjectRoot();return s?this.service.getStatus(s):null}async index(t,e){return this.service.indexProject(this.resolveRootPath(t.rootPath,e))}async build(t,e){return this.service.buildContext(this.resolveRootPath(t.rootPath,e),t.query,t.mode??"fast",t.maxTokens)}async buildTask(t,e){return this.service.buildTaskContext(this.resolveRootPath(t.rootPath,e),t.query,t.mode??"fast",t.maxTokens)}async feedback(t,e){return this.service.recordFeedback(this.resolveRootPath(t.rootPath,e),t.query,t.feedback,{taskType:t.taskType,contextMode:t.contextMode,runId:t.runId,tokenCount:t.tokenCount})}async feedbackSummary(){return this.service.getFeedbackSummaries()}async findSymbol(t,e,s){return this.service.findSymbol(this.resolveRootPath(e,s),t)}};i([Get("status"),n(0,Query("rootPath")),n(1,Headers("x-devflow-project"))],I.prototype,"status",1),i([Post("index"),n(0,Body()),n(1,Headers("x-devflow-project"))],I.prototype,"index",1),i([Post("build"),n(0,Body()),n(1,Headers("x-devflow-project"))],I.prototype,"build",1),i([Post("build-task"),n(0,Body()),n(1,Headers("x-devflow-project"))],I.prototype,"buildTask",1),i([Post("feedback"),n(0,Body()),n(1,Headers("x-devflow-project"))],I.prototype,"feedback",1),i([Get("feedback-summary")],I.prototype,"feedbackSummary",1),i([Get("symbol/:name"),n(0,Param("name")),n(1,Query("rootPath")),n(2,Headers("x-devflow-project"))],I.prototype,"findSymbol",1),I=i([Controller("context"),n(0,Inject(C)),n(1,Inject(v))],I);var _=class{constructor(t){this.dataService=t;}async recordTelemetryEvent(t){return {success:true,...await this.dataService.recordTelemetryEvent(t)}}async getProjectStats(t){return this.dataService.getProjectStats(t)}async updateProjectStats(t){return this.dataService.updateProjectStats(t.projectRoot,t.stats)}recordBenchmarkResult(t){return this.dataService.recordBenchmarkResult(t),{success:true}}getBenchmarkResults(t){return this.dataService.getBenchmarkResults(t)}};i([Post("telemetry/event"),n(0,Body())],_.prototype,"recordTelemetryEvent",1),i([Get("project/stats"),n(0,Query("rootPath"))],_.prototype,"getProjectStats",1),i([Post("project/stats"),n(0,Body())],_.prototype,"updateProjectStats",1),i([Post("benchmark/result"),n(0,Body())],_.prototype,"recordBenchmarkResult",1),i([Get("benchmark/results"),n(0,Query("projectRoot"))],_.prototype,"getBenchmarkResults",1),_=i([Controller("data"),n(0,Inject(O))],_);var D=class{constructor(){this.engines=new Map;}getEngine(t){return this.engines.has(t)||this.engines.set(t,new MemoryEngine(t)),this.engines.get(t)}async getAll(t){let e=this.getEngine(t),[s,r]=await Promise.all([e.listMemories(),checkOllama()]);return {memories:s.map(o=>({id:o.id,category:o.category,content:o.content,originalText:o.originalText,source:o.source,status:o.status,confidence:o.confidence,scope:o.scope,createdAt:o.createdAt,approvedAt:o.approvedAt})),ollama:{installed:r.installed,running:r.running,modelAvailable:r.modelAvailable,modelName:r.modelName,infoMessage:getOllamaInfoMessage(r)}}}async add(t,e){return this.getEngine(t).addMemory({category:e.category,content:e.content,source:"manual",confidence:1,scope:e.scope??""})}async update(t,e,s){await this.getEngine(t).updateMemory(e,s);}async delete(t,e){await this.getEngine(t).deleteMemory(e);}async getCandidates(t){return this.getEngine(t).getPendingMemories()}async approveCandidate(t,e){await this.getEngine(t).approveMemory(e);}async rejectCandidate(t,e){await this.getEngine(t).rejectMemory(e);}async search(t,e,s){return (await this.getEngine(t).search(e,s)).map(o=>o.entry)}async extract(t,e){return this.getEngine(t).extractMemories(e)}async getOllamaStatus(){let t=await checkOllama();return {...t,infoMessage:getOllamaInfoMessage(t)}}async updateLegacy(t,e,s,r){e!=="user"&&await this.getEngine(t).addMemory({category:"project_knowledge",content:`${s}: ${JSON.stringify(r)}`,source:"manual",confidence:1,scope:s});}async recordEvent(t,e){let s=this.getEngine(t);return await s.recordEvent({id:e.id,sessionId:e.sessionId,tool:e.tool,command:e.command,exitCode:e.exitCode,stderr:e.stderr,durationMs:e.durationMs,createdAt:Date.now()}),{acknowledged:true,extracted:(await s.extractFromEventsRealtime([{tool:e.tool,command:e.command,exitCode:e.exitCode,stderr:e.stderr}])).length}}async processSessionEvents(t){return this.getEngine(t).processSessionEvents()}};D=i([Injectable()],D);var y=class{constructor(t,e,s){this.service=t;this.memoryService=e;this.projectsService=s;}async listRuns(t,e,s){return this.service.listRuns(Number(t)||20,Number(e)||0,s)}async getRun(t){let e=await this.service.getRun(t),s=await this.service.classifyFailure(t);return {...e,...s}}async getTimeline(t,e){return this.service.getTimeline(t,e)}async getRunEvents(t){return this.service.getRunEvents(t)}async getRunStats(t){return this.service.getRunStats(t)}async completeRun(t){await this.service.endRun(t,{status:"success",tokenUsed:0});let e=await this.service.getRunEvents(t),s=this.projectsService.getActiveProjectRoot(),r=await this.memoryService.extract(s??"",e);return {ok:true,extracted:Array.isArray(r)?r.length:0}}async getStats(t){return this.service.getStats(Number(t)||7)}async getRoiSummary(t){return this.service.getRoiSummary(Number(t)||7)}async cleanup(t){return {ok:true,data:{removedRuns:await this.service.cleanup(t.olderThanDays??30)}}}async startSkillExecution(t){return await this.service.recordExecutionStart(t),{executionId:t.executionId}}async recordToolCall(t){return await this.service.recordToolCall(t),{eventId:t.eventId}}async completeSkillExecution(t){return await this.service.recordExecutionComplete(t),{}}async getExecutions(t,e){return {data:await this.service.getExecutions(Number(t)||20,e)}}async getExecutionEvents(t){return {data:await this.service.getExecutionEvents(t)}}async getMcpCompliance(){return await this.service.getMcpCompliance()}};i([Get("runs"),n(0,Query("limit")),n(1,Query("offset")),n(2,Query("source"))],y.prototype,"listRuns",1),i([Get("runs/:id"),n(0,Param("id"))],y.prototype,"getRun",1),i([Get("timeline"),n(0,Query("from")),n(1,Query("to"))],y.prototype,"getTimeline",1),i([Get("runs/:runId/events"),n(0,Param("runId"))],y.prototype,"getRunEvents",1),i([Get("runs/:runId/stats"),n(0,Param("runId"))],y.prototype,"getRunStats",1),i([Post("runs/:id/complete"),n(0,Param("id"))],y.prototype,"completeRun",1),i([Get("stats"),n(0,Query("days"))],y.prototype,"getStats",1),i([Get("roi-summary"),n(0,Query("days"))],y.prototype,"getRoiSummary",1),i([Post("cleanup"),n(0,Body())],y.prototype,"cleanup",1),i([Post("skill-execution/start"),n(0,Body())],y.prototype,"startSkillExecution",1),i([Post("tool-call"),n(0,Body())],y.prototype,"recordToolCall",1),i([Post("skill-execution/complete"),n(0,Body())],y.prototype,"completeSkillExecution",1),i([Get("executions"),n(0,Query("limit")),n(1,Query("skillName"))],y.prototype,"getExecutions",1),i([Get("executions/:id/events"),n(0,Param("id"))],y.prototype,"getExecutionEvents",1),i([Get("mcp-compliance")],y.prototype,"getMcpCompliance",1),y=i([Controller("telemetry"),n(0,Inject(E)),n(1,Inject(D)),n(2,Inject(v))],y);var b=class{constructor(t,e){this.service=t;this.projects=e;}resolveRootPath(t,e){let s=t??e??this.projects.getActiveProjectRoot();if(!s)throw new BadRequestException({error:{code:g.BAD_REQUEST,message:"rootPath is required \u2014 no active project connected",details:{}}});return s}async getAll(t,e){return this.service.getAll(this.resolveRootPath(t,e))}async add(t,e,s){return this.service.add(this.resolveRootPath(t,s),e)}async update(t,e,s,r){return await this.service.update(this.resolveRootPath(t,r),e,s),{ok:true}}async delete(t,e,s){return await this.service.delete(this.resolveRootPath(t,s),e),{ok:true}}async getCandidates(t,e){return this.service.getCandidates(this.resolveRootPath(t,e))}async approve(t,e,s){return await this.service.approveCandidate(this.resolveRootPath(t,s),e),{approved:true}}async reject(t,e,s){return await this.service.rejectCandidate(this.resolveRootPath(t,s),e),{rejected:true}}async search(t,e,s){return this.service.search(this.resolveRootPath(t,s),e.query,{limit:e.limit,categories:e.categories})}async extract(t,e,s){return this.service.extract(this.resolveRootPath(t,s),e.events)}async ollamaStatus(){return this.service.getOllamaStatus()}async updateLegacy(t,e,s,r,o){return await this.service.updateLegacy(this.resolveRootPath(t,o),e,s,r.value),{ok:true}}async recordEvent(t,e,s){return this.service.recordEvent(this.resolveRootPath(t,s),e)}async processEvents(t,e){return this.service.processSessionEvents(this.resolveRootPath(t,e))}};i([Get(),n(0,Query("rootPath")),n(1,Headers("x-devflow-project"))],b.prototype,"getAll",1),i([Post(),n(0,Query("rootPath")),n(1,Body()),n(2,Headers("x-devflow-project"))],b.prototype,"add",1),i([Put(":id"),n(0,Query("rootPath")),n(1,Param("id")),n(2,Body()),n(3,Headers("x-devflow-project"))],b.prototype,"update",1),i([Delete(":id"),n(0,Query("rootPath")),n(1,Param("id")),n(2,Headers("x-devflow-project"))],b.prototype,"delete",1),i([Get("candidates"),n(0,Query("rootPath")),n(1,Headers("x-devflow-project"))],b.prototype,"getCandidates",1),i([Post("candidates/:id/approve"),n(0,Query("rootPath")),n(1,Param("id")),n(2,Headers("x-devflow-project"))],b.prototype,"approve",1),i([Post("candidates/:id/reject"),n(0,Query("rootPath")),n(1,Param("id")),n(2,Headers("x-devflow-project"))],b.prototype,"reject",1),i([Post("search"),n(0,Query("rootPath")),n(1,Body()),n(2,Headers("x-devflow-project"))],b.prototype,"search",1),i([Post("extract"),n(0,Query("rootPath")),n(1,Body()),n(2,Headers("x-devflow-project"))],b.prototype,"extract",1),i([Get("ollama/status")],b.prototype,"ollamaStatus",1),i([Put(":layer/:key"),n(0,Query("rootPath")),n(1,Param("layer")),n(2,Param("key")),n(3,Body()),n(4,Headers("x-devflow-project"))],b.prototype,"updateLegacy",1),i([Post("events"),n(0,Query("rootPath")),n(1,Body()),n(2,Headers("x-devflow-project"))],b.prototype,"recordEvent",1),i([Post("process"),n(0,Query("rootPath")),n(1,Headers("x-devflow-project"))],b.prototype,"processEvents",1),b=i([Controller("memory"),n(0,Inject(D)),n(1,Inject(v))],b);var Y=class{};Y=i([Module({imports:[forwardRef(()=>j),w],controllers:[b],providers:[D],exports:[D]})],Y);var M=class{};M=i([Module({imports:[Y,w],controllers:[y],providers:[E],exports:[E]})],M);var J=class{};J=i([Module({imports:[M],controllers:[_],providers:[O],exports:[O]})],J);var j=class{};j=i([Module({imports:[w,J],controllers:[I],providers:[C],exports:[C]})],j);var L=class{async getFullGraph(t){let{graph:e}=await createEngines(t);return e.export()}async getLayeredGraph(t){let{graph:e}=await createEngines(t);return e.getLayeredGraph()}async getNode(t,e){let{codegraph:s}=await createEngines(t),r=s.getNode(e);if(!r)throw new NotFoundException({error:{code:g.NODE_NOT_FOUND,message:`Node "${e}" not found`,details:{}}});return r}async expandNode(t,e,s,r){let{graph:o}=await createEngines(t),a=o.expand([e],{depth:s,direction:r});return {node:a.nodes.find(u=>u.id===e),subGraph:a}}};L=i([Injectable()],L);var q=class{constructor(t,e){this.service=t;this.projects=e;}resolveRootPath(t,e){let s=t??e??this.projects.getActiveProjectRoot();if(!s)throw new BadRequestException({error:{code:g.BAD_REQUEST,message:"rootPath is required \u2014 no active project connected",details:{}}});return s}async getFullGraph(t,e,s){return e==="layered"?this.service.getLayeredGraph(this.resolveRootPath(t,s)):this.service.getFullGraph(this.resolveRootPath(t,s))}async getNode(t,e,s){return this.service.getNode(this.resolveRootPath(t,s),e)}async expandNode(t,e,s,r,o){return this.service.expandNode(this.resolveRootPath(t,o),e,Number(s)||2,r||"both")}};i([Get(),n(0,Query("rootPath")),n(1,Query("view")),n(2,Headers("x-devflow-project"))],q.prototype,"getFullGraph",1),i([Get(":nodeId"),n(0,Query("rootPath")),n(1,Param("nodeId")),n(2,Headers("x-devflow-project"))],q.prototype,"getNode",1),i([Get(":nodeId/expand"),n(0,Query("rootPath")),n(1,Param("nodeId")),n(2,Query("depth")),n(3,Query("direction")),n(4,Headers("x-devflow-project"))],q.prototype,"expandNode",1),q=i([Controller("graph"),n(0,Inject(L)),n(1,Inject(v))],q);var at=class{};at=i([Module({imports:[j,w],controllers:[q],providers:[L],exports:[L]})],at);var $=class{constructor(){this.engine=new WorkflowEngine;this.events=new Map;this.engineRunIds=new Map;}async onModuleInit(){try{let t=await loadPlugins(),e=Array.from(t.values());for(let r of e)for(let o of r.workflow?.templates??[])this.engine.register(o);let s=await this.engine.list();console.log(`[WorkflowService] Loaded ${e.length} plugins with ${s.length} workflows`);}catch(t){console.error("[WorkflowService] Failed to load plugins:",t);}}async list(){return this.engine.list()}async run(t,e){if(!(await this.engine.list()).find(a=>a.name===t))throw new NotFoundException({error:{code:g.WORKFLOW_NOT_FOUND,message:`Workflow "${t}" not found`,details:{}}});let r=`run_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,o=new Subject;return this.events.set(r,o),this.engine.run(t,e).then(a=>{this.engineRunIds.set(r,a.runId);let u=this.engine.getRun(a.runId);if(u){for(let l of u.steps)o.next({runId:r,stepId:l.stepId,status:l.status==="success"?"completed":l.status==="failed"?"failed":"started",output:l.output,error:l.error,timestamp:Date.now()});a.status!=="running"&&o.complete();}a.status==="running"&&this.engine.onEvent(a.runId,l=>{o.next({runId:r,stepId:l.stepId,status:l.type==="step-done"?"completed":l.type==="step-error"?"failed":"started",output:"output"in l?l.output:void 0,error:"error"in l?l.error:void 0,timestamp:Date.now()});});}).catch(a=>{o.next({runId:r,stepId:"engine",status:"failed",error:a.message,timestamp:Date.now()}),o.complete();}),{runId:r}}async listRuns(t,e){return (await this.engine.listRuns()).map(o=>({runId:Array.from(this.engineRunIds.entries()).find(([,u])=>u===o.runId)?.[0]??o.runId,workflowName:o.type,status:o.status,steps:o.steps.map(u=>({stepId:u.stepId,status:u.status,output:u.output,error:u.error,startedAt:0})),startedAt:o.startedAt,finishedAt:o.finishedAt})).slice(e,e+t)}async getRun(t){let e=this.engineRunIds.get(t)??t,s=this.engine.getRun(e);if(!s)throw new NotFoundException({error:{code:g.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});return {runId:t,workflowName:s.type,status:s.status,steps:s.steps.map(r=>({stepId:r.stepId,status:r.status,output:r.output,error:r.error})),startedAt:s.startedAt,finishedAt:s.finishedAt}}streamRun(t){let e=this.events.get(t);if(!e)throw new NotFoundException({error:{code:g.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});return e}async approveRun(t){let e=this.engineRunIds.get(t)??t,s=this.engine.getRun(e);if(!s)throw new NotFoundException({error:{code:g.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});let r=s.steps.find(o=>o.status==="awaiting_approval");r&&await this.engine.approve(e,r.stepId);}async rejectRun(t,e){let s=this.engineRunIds.get(t)??t,r=this.engine.getRun(s);if(!r)throw new NotFoundException({error:{code:g.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});let o=r.steps.find(a=>a.status==="awaiting_approval");o&&await this.engine.reject(s,o.stepId,e??"Rejected");}async getNextStep(t){if(!t){(await this.engine.list())[0];return null}let e=this.engineRunIds.get(t)??t,s=this.engine.getRun(e);return s?(Array.isArray(s.steps)?s.steps:[]).find(o=>o.status==="pending")??null:null}};$=i([Injectable()],$);var S=class{constructor(t){this.service=t;}async list(){return this.service.list()}async run(t,e){return this.service.run(t,e.input??{})}async listRuns(t,e){return this.service.listRuns(Number(t)||20,Number(e)||0)}async getRun(t){return this.service.getRun(t)}async stream(t,e){e.raw.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let r=this.service.streamRun(t).subscribe({next:o=>{e.raw.write(`event: step-${o.status}
2
- data: ${JSON.stringify(o)}
3
-
4
- `);},error:o=>{e.raw.write(`event: error
5
- data: ${JSON.stringify({error:o.message})}
6
-
7
- `),e.raw.end();},complete:()=>{e.raw.write(`event: done
8
- data: {}
9
-
10
- `),e.raw.end();}});e.raw.on("close",()=>r.unsubscribe());}async approve(t){return await this.service.approveRun(t),{approved:true}}async reject(t,e){return await this.service.rejectRun(t,e.reason),{rejected:true}}async nextStep(t){return this.service.getNextStep(t)}};i([Get()],S.prototype,"list",1),i([Post(":type/run"),n(0,Param("type")),n(1,Body())],S.prototype,"run",1),i([Get("runs"),n(0,Query("limit")),n(1,Query("offset"))],S.prototype,"listRuns",1),i([Get("runs/:id"),n(0,Param("id"))],S.prototype,"getRun",1),i([Get("runs/:id/stream"),n(0,Param("id")),n(1,Res())],S.prototype,"stream",1),i([Post("runs/:id/approve"),n(0,Param("id"))],S.prototype,"approve",1),i([Post("runs/:id/reject"),n(0,Param("id")),n(1,Body())],S.prototype,"reject",1),i([Get("next-step"),n(0,Query("runId"))],S.prototype,"nextStep",1),S=i([Controller("workflows"),n(0,Inject($))],S);var ct=class{};ct=i([Module({controllers:[S],providers:[$],exports:[$]})],ct);var G=class{constructor(t){this.projectsService=t;}getEngine(t){return new KnowledgeEngine({projectRoot:t})}async onModuleInit(){let t=this.projectsService.getActiveProjectRoot()??process.env.DEVFLOW_PROJECT_ROOT??process.cwd();try{let e=this.getEngine(t),s=await e.getSources(),r=Date.now()-10080*60*1e3;for(let o of s)(!o.lastSyncTime||o.lastSyncTime<r)&&await e.syncDocs(o.source.name);}catch{}}async search(t,e,s){return this.getEngine(t).search(e,{sources:s&&s!=="all"?[s]:void 0})}async sync(t,e){return this.getEngine(t).syncDocs(e??"")}async getSources(t){return this.getEngine(t).getSources()}};G=i([Injectable(),n(0,Inject(v))],G);var H=class{constructor(t,e){this.service=t;this.projects=e;}resolveRootPath(t,e){let s=t??e??this.projects.getActiveProjectRoot();if(!s)throw new BadRequestException("rootPath is required \u2014 no active project connected");return s}async search(t,e,s,r){return this.service.search(this.resolveRootPath(t,r),e??"",s)}async sync(t,e){return this.service.sync(this.resolveRootPath(t.rootPath,e),t.pluginName)}async getSources(t,e){return {ok:true,data:await this.service.getSources(this.resolveRootPath(t,e))}}};i([Get("search"),n(0,Query("rootPath")),n(1,Query("q")),n(2,Query("scope")),n(3,Headers("x-devflow-project"))],H.prototype,"search",1),i([Post("sync"),n(0,Body()),n(1,Headers("x-devflow-project"))],H.prototype,"sync",1),i([Get("sources"),n(0,Query("rootPath")),n(1,Headers("x-devflow-project"))],H.prototype,"getSources",1),H=i([Controller("knowledge"),n(0,Inject(G)),n(1,Inject(v))],H);var ut=class{};ut=i([Module({imports:[j,w],controllers:[H],providers:[G],exports:[G]})],ut);var K=class{constructor(){this.results=[];this.scenarioIds=[];this.engine=new BenchmarkEngine,this.registerDefaultScenarios();}registerDefaultScenarios(){let t=[{id:"understand-codebase",category:"understand",desc:"\u7406\u89E3\u4EE3\u7801\u5E93\u67B6\u6784",expectedFiles:2},{id:"modify-component",category:"modify",desc:"\u4FEE\u6539 React \u7EC4\u4EF6",expectedFiles:1,expectedComponents:1},{id:"review-code",category:"review",desc:"\u4EE3\u7801\u5BA1\u67E5",expectedIssues:2}];for(let e of t)this.engine.registerScenario(e),this.scenarioIds.push(e.id);}async runScenarioSet(t){let e=async a=>({prepTimeMs:1e3+Math.random()*500,tokenCount:500+Math.floor(Math.random()*200),firstPassSuccess:Math.random()>.5,reworkCount:Math.floor(Math.random()*3),durationMs:5e3+Math.random()*3e3}),s=async a=>({prepTimeMs:500+Math.random()*300,tokenCount:300+Math.floor(Math.random()*100),firstPassSuccess:Math.random()>.2,reworkCount:Math.floor(Math.random()*2),durationMs:3e3+Math.random()*2e3}),r=t??this.scenarioIds,o=await this.engine.runScenarioBatch(r,e,s);return this.results=o,o}async getScenarioResults(){return this.results.length===0&&await this.runScenarioSet(),this.results}async getComparisonSummary(){let t=await this.getScenarioResults(),e=t.length;return {totalScenarios:e,avgTimeSavedRate:t.reduce((s,r)=>s+r.comparison.timeSavedRate,0)/e,avgTokenReductionRate:t.reduce((s,r)=>s+r.comparison.tokenReductionRate,0)/e,avgFirstPassLift:t.reduce((s,r)=>s+r.comparison.firstPassLift,0)/e,avgReworkReductionRate:t.reduce((s,r)=>s+r.comparison.reworkReductionRate,0)/e}}async getExperimentalRoiSummary(){let t=await this.getComparisonSummary();return {totalScenarios:t.totalScenarios,avgTimeSavedRate:t.avgTimeSavedRate,avgTokenReductionRate:t.avgTokenReductionRate,avgFirstPassLift:t.avgFirstPassLift,avgReworkReductionRate:t.avgReworkReductionRate,conclusion:"DevFlow shows significant improvement in all metrics"}}};K=i([Injectable()],K);var U=class{constructor(t){this.service=t;}async run(t){return this.service.runScenarioSet(t.scenarioIds)}async getResults(){return this.service.getScenarioResults()}async getComparisonSummary(){return this.service.getComparisonSummary()}async getExperimentalRoiSummary(){return this.service.getExperimentalRoiSummary()}};i([Post("run"),n(0,Body())],U.prototype,"run",1),i([Get("results")],U.prototype,"getResults",1),i([Get("summary")],U.prototype,"getComparisonSummary",1),i([Get("roi-summary")],U.prototype,"getExperimentalRoiSummary",1),U=i([Controller("benchmark"),n(0,Inject(K))],U);var lt=class{};lt=i([Module({controllers:[U],providers:[K],exports:[K]})],lt);var W=class{constructor(t){this.telemetryService=t;this.plugins=new Map;this.installRecords=[];}async list(t,e){let s=Array.from(this.plugins.values());if(t){let r=t.toLowerCase();s=s.filter(o=>o.name.toLowerCase().includes(r)||o.description.toLowerCase().includes(r));}return e&&(s=s.filter(r=>r.tags.includes(e))),s}async getByName(t){let e=this.plugins.get(t);if(!e)throw new NotFoundException({error:{code:g.PLUGIN_NOT_FOUND,message:`Plugin "${t}" not found`,details:{}}});return e}async publish(t){let e=t.npmPackage.replace(/^@devflow-tools\/plugin-/,""),s={name:e,npmPackage:t.npmPackage,version:t.version,description:t.description,tags:t.tags??[],createdAt:Date.now()};return this.plugins.set(e,s),s}async install(t,e){let s=t.startsWith("@devflow-tools/plugin-")?t:`@devflow-tools/plugin-${t}`,r=t.replace(/^@devflow-tools\/plugin-/,"");return this.plugins.set(r,{name:r,npmPackage:s,version:"0.1.0",description:"Installed plugin",tags:[],createdAt:Date.now()}),e&&await this.recordPluginInstall(r,e),{ok:true,name:r}}async uninstall(t,e){let s=t.replace(/^@devflow-tools\/plugin-/,"");return this.plugins.delete(s),e&&await this.recordPluginUninstall(s,e),{ok:true,name:s}}async recordPluginInstall(t,e){let s=this.installRecords.find(r=>r.pluginName===t&&r.projectRoot===e);s?s.uninstalledAt=void 0:this.installRecords.push({pluginName:t,projectRoot:e,installedAt:Date.now()});}async recordPluginUninstall(t,e){let s=this.installRecords.find(r=>r.pluginName===t&&r.projectRoot===e);s&&(s.uninstalledAt=Date.now());}async listInstalledProjects(t){return this.installRecords.filter(e=>e.pluginName===t&&!e.uninstalledAt).map(e=>e.projectRoot)}async buildPluginEffectiveness(t){let s=(await this.listInstalledProjects(t)).length,r=await this.telemetryService.getPluginUsageStats(t),o=s>0?r.activeProjects/s:0,a=r.totalRuns>0?r.successfulRuns/r.totalRuns:0,u="optimize";return o>.7&&a>.8?u="install":(o<.3||a<.5)&&(u="remove"),{name:t,installCount:s,usageCount:r.totalRuns,activeRate:o,successRate:a,avgTokenImpact:r.avgTokenImpact,lastUsedAt:r.lastUsedAt,recommendation:u}}async getPluginEffectiveness(t){let e=t?this.installRecords.filter(o=>o.projectRoot===t&&!o.uninstalledAt):this.installRecords.filter(o=>!o.uninstalledAt),s=[...new Set(e.map(o=>o.pluginName))],r=[];for(let o of s){let a=await this.buildPluginEffectiveness(o);r.push(a);}return r}};W=i([Injectable(),n(0,Inject(E))],W);var N=class{constructor(t){this.service=t;}async list(t,e){return this.service.list(t,e)}async getPluginEffectiveness(t){return this.service.getPluginEffectiveness(t)}async getByName(t){return this.service.getByName(t)}async publish(t){return this.service.publish(t)}async install(t,e){return this.service.install(t.name,t.rootPath??e)}async uninstall(t,e,s){return this.service.uninstall(t,e.rootPath??s)}};i([Get("plugins"),n(0,Query("search")),n(1,Query("tag"))],N.prototype,"list",1),i([Get("plugins/effectiveness"),n(0,Query("rootPath"))],N.prototype,"getPluginEffectiveness",1),i([Get("plugins/:name"),n(0,Param("name"))],N.prototype,"getByName",1),i([Post("plugins"),n(0,Body())],N.prototype,"publish",1),i([Post("plugins/install"),n(0,Body()),n(1,Headers("x-devflow-project"))],N.prototype,"install",1),i([Post("plugins/:name/uninstall"),n(0,Param("name")),n(1,Body()),n(2,Headers("x-devflow-project"))],N.prototype,"uninstall",1),N=i([Controller("registry"),n(0,Inject(W))],N);var dt=class{};dt=i([Module({imports:[M],controllers:[N],providers:[W],exports:[W]})],dt);var ke={provide:"DATABASE",useFactory:()=>{let c=process.cwd();return new DevFlowDatabase(c)}},mt=class{};mt=i([Global(),Module({providers:[ke],exports:[ke]})],mt);var gt=class{intercept(t,e){return e.handle().pipe(map(s=>s&&typeof s=="object"&&"error"in s?s:{ok:true,data:s??null}))}};gt=i([Injectable()],gt);var tt=class{constructor(){this.startTime=Date.now();}health(){return {version:"0.2.3",uptime:Date.now()-this.startTime}}};i([Zt(),Get("health")],tt.prototype,"health",1),tt=i([Controller()],tt);var pt=class{};pt=i([Module({imports:[mt,st,w,j,at,ct,Y,ut,M,lt,dt,J],controllers:[tt],providers:[{provide:APP_INTERCEPTOR,useClass:gt}]})],pt);function Pe(c){return c===400?g.BAD_REQUEST:c===404?g.PROJECT_NOT_FOUND:c===422?g.VALIDATION_ERROR:g.INTERNAL_ERROR}var V=class{constructor(){this.logger=new Logger(V.name);}catch(t,e){let r=e.switchToHttp().getResponse();if(t instanceof HttpException){let o=t.getStatus(),a=t.getResponse();if(typeof a=="object"&&a!==null&&"error"in a){let l=a.error;if(typeof l=="object"&&l!==null&&"code"in l){r.status(o).send(a);return}let p=typeof a.message=="string"?a.message:"Request failed";r.status(o).send({error:{code:Pe(o),message:p,details:{}}});return}let u=typeof a=="string"?a:a.message??"Request failed";r.status(o).send({error:{code:Pe(o),message:u,details:{}}});return}this.logger.error("Unhandled exception",t instanceof Error?t.stack:String(t)),r.status(HttpStatus.INTERNAL_SERVER_ERROR).send({error:{code:g.INTERNAL_ERROR,message:"Internal server error",details:{}}});}};V=i([Catch()],V);async function lr(){let c=await NestFactory.create(pt,new FastifyAdapter);return c.setGlobalPrefix("api"),c.useGlobalFilters(new V),c.enableCors({origin:true,credentials:true}),await c.listen({port:parseInt(process.env.PORT||"13337",10),host:"0.0.0.0"}),c}(process.argv[1]?.endsWith("main.js")||process.argv[1]?.endsWith("main.ts")||process.argv[1]?.endsWith("server.js"))&&lr();export{lr as bootstrap};