@mengzf/skillflow-mcp 0.0.0-stage → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +279 -2
  3. package/dist/adapters/claude-code.adapter.d.ts +10 -0
  4. package/dist/adapters/claude-code.adapter.d.ts.map +1 -0
  5. package/dist/adapters/claude-code.adapter.js +166 -0
  6. package/dist/adapters/claude-code.adapter.js.map +1 -0
  7. package/dist/adapters/codex.adapter.d.ts +10 -0
  8. package/dist/adapters/codex.adapter.d.ts.map +1 -0
  9. package/dist/adapters/codex.adapter.js +109 -0
  10. package/dist/adapters/codex.adapter.js.map +1 -0
  11. package/dist/adapters/dsh.adapter.d.ts +7 -0
  12. package/dist/adapters/dsh.adapter.d.ts.map +1 -0
  13. package/dist/adapters/dsh.adapter.js +60 -0
  14. package/dist/adapters/dsh.adapter.js.map +1 -0
  15. package/dist/adapters/qoder.adapter.d.ts +10 -0
  16. package/dist/adapters/qoder.adapter.d.ts.map +1 -0
  17. package/dist/adapters/qoder.adapter.js +119 -0
  18. package/dist/adapters/qoder.adapter.js.map +1 -0
  19. package/dist/adapters/trae.adapter.d.ts +8 -0
  20. package/dist/adapters/trae.adapter.d.ts.map +1 -0
  21. package/dist/adapters/trae.adapter.js +104 -0
  22. package/dist/adapters/trae.adapter.js.map +1 -0
  23. package/dist/adapters/types.d.ts +25 -0
  24. package/dist/adapters/types.d.ts.map +1 -0
  25. package/dist/adapters/types.js +2 -0
  26. package/dist/adapters/types.js.map +1 -0
  27. package/dist/adapters/universal.sync.d.ts +22 -0
  28. package/dist/adapters/universal.sync.d.ts.map +1 -0
  29. package/dist/adapters/universal.sync.js +140 -0
  30. package/dist/adapters/universal.sync.js.map +1 -0
  31. package/dist/adapters/workbuddy.sniffer.d.ts +22 -0
  32. package/dist/adapters/workbuddy.sniffer.d.ts.map +1 -0
  33. package/dist/adapters/workbuddy.sniffer.js +148 -0
  34. package/dist/adapters/workbuddy.sniffer.js.map +1 -0
  35. package/dist/config.d.ts +9 -0
  36. package/dist/config.d.ts.map +1 -0
  37. package/dist/config.js +33 -0
  38. package/dist/config.js.map +1 -0
  39. package/dist/db/index.d.ts +4 -0
  40. package/dist/db/index.d.ts.map +1 -0
  41. package/dist/db/index.js +39 -0
  42. package/dist/db/index.js.map +1 -0
  43. package/dist/db/invocation-filter.d.ts +29 -0
  44. package/dist/db/invocation-filter.d.ts.map +1 -0
  45. package/dist/db/invocation-filter.js +78 -0
  46. package/dist/db/invocation-filter.js.map +1 -0
  47. package/dist/db/schema.d.ts +3 -0
  48. package/dist/db/schema.d.ts.map +1 -0
  49. package/dist/db/schema.js +129 -0
  50. package/dist/db/schema.js.map +1 -0
  51. package/dist/db/seed.d.ts +15 -0
  52. package/dist/db/seed.d.ts.map +1 -0
  53. package/dist/db/seed.js +128 -0
  54. package/dist/db/seed.js.map +1 -0
  55. package/dist/index.d.ts +3 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +51 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/server.d.ts +7 -0
  60. package/dist/server.d.ts.map +1 -0
  61. package/dist/server.js +372 -0
  62. package/dist/server.js.map +1 -0
  63. package/dist/services/benchmark.service.d.ts +27 -0
  64. package/dist/services/benchmark.service.d.ts.map +1 -0
  65. package/dist/services/benchmark.service.js +94 -0
  66. package/dist/services/benchmark.service.js.map +1 -0
  67. package/dist/services/dashboard.service.d.ts +14 -0
  68. package/dist/services/dashboard.service.d.ts.map +1 -0
  69. package/dist/services/dashboard.service.js +296 -0
  70. package/dist/services/dashboard.service.js.map +1 -0
  71. package/dist/services/filter.service.d.ts +26 -0
  72. package/dist/services/filter.service.d.ts.map +1 -0
  73. package/dist/services/filter.service.js +103 -0
  74. package/dist/services/filter.service.js.map +1 -0
  75. package/dist/services/impact.service.d.ts +20 -0
  76. package/dist/services/impact.service.d.ts.map +1 -0
  77. package/dist/services/impact.service.js +114 -0
  78. package/dist/services/impact.service.js.map +1 -0
  79. package/dist/services/telemetry.service.d.ts +41 -0
  80. package/dist/services/telemetry.service.d.ts.map +1 -0
  81. package/dist/services/telemetry.service.js +244 -0
  82. package/dist/services/telemetry.service.js.map +1 -0
  83. package/dist/types/index.d.ts +3 -0
  84. package/dist/types/index.d.ts.map +1 -0
  85. package/dist/types/index.js +3 -0
  86. package/dist/types/index.js.map +1 -0
  87. package/dist/types/models.d.ts +73 -0
  88. package/dist/types/models.d.ts.map +1 -0
  89. package/dist/types/models.js +2 -0
  90. package/dist/types/models.js.map +1 -0
  91. package/dist/types/tools.d.ts +173 -0
  92. package/dist/types/tools.d.ts.map +1 -0
  93. package/dist/types/tools.js +195 -0
  94. package/dist/types/tools.js.map +1 -0
  95. package/dist/utils/ascii-chart.d.ts +9 -0
  96. package/dist/utils/ascii-chart.d.ts.map +1 -0
  97. package/dist/utils/ascii-chart.js +29 -0
  98. package/dist/utils/ascii-chart.js.map +1 -0
  99. package/dist/utils/formatter.d.ts +6 -0
  100. package/dist/utils/formatter.d.ts.map +1 -0
  101. package/dist/utils/formatter.js +29 -0
  102. package/dist/utils/formatter.js.map +1 -0
  103. package/dist/utils/governance.d.ts +25 -0
  104. package/dist/utils/governance.d.ts.map +1 -0
  105. package/dist/utils/governance.js +70 -0
  106. package/dist/utils/governance.js.map +1 -0
  107. package/dist/utils/hours.d.ts +3 -0
  108. package/dist/utils/hours.d.ts.map +1 -0
  109. package/dist/utils/hours.js +15 -0
  110. package/dist/utils/hours.js.map +1 -0
  111. package/dist/utils/pricing.d.ts +19 -0
  112. package/dist/utils/pricing.d.ts.map +1 -0
  113. package/dist/utils/pricing.js +96 -0
  114. package/dist/utils/pricing.js.map +1 -0
  115. package/dist/utils/quality.d.ts +15 -0
  116. package/dist/utils/quality.d.ts.map +1 -0
  117. package/dist/utils/quality.js +47 -0
  118. package/dist/utils/quality.js.map +1 -0
  119. package/dist/web/render.d.ts +2 -0
  120. package/dist/web/render.d.ts.map +1 -0
  121. package/dist/web/render.js +1919 -0
  122. package/dist/web/render.js.map +1 -0
  123. package/dist/web/server.d.ts +10 -0
  124. package/dist/web/server.d.ts.map +1 -0
  125. package/dist/web/server.js +160 -0
  126. package/dist/web/server.js.map +1 -0
  127. package/package.json +51 -4
@@ -0,0 +1,60 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ export class DshAdapter {
5
+ agentName = 'DSH';
6
+ findSessionsDir() {
7
+ const defaultDir = path.join(os.homedir(), '.dsh', 'sessions');
8
+ if (fs.existsSync(defaultDir)) {
9
+ return defaultDir;
10
+ }
11
+ return null;
12
+ }
13
+ scan() {
14
+ const dir = this.findSessionsDir();
15
+ if (!dir)
16
+ return [];
17
+ const invocations = [];
18
+ try {
19
+ const projectDirs = fs.readdirSync(dir, { withFileTypes: true });
20
+ for (const pDir of projectDirs) {
21
+ if (!pDir.isDirectory())
22
+ continue;
23
+ const fullPDir = path.join(dir, pDir.name);
24
+ try {
25
+ const sessions = fs.readdirSync(fullPDir, { withFileTypes: true });
26
+ for (const s of sessions) {
27
+ if (s.name.startsWith('session-') || s.name.length > 20) {
28
+ const sessionId = s.name.replace(/^session-/, '');
29
+ const sPath = path.join(fullPDir, s.name);
30
+ const stat = fs.statSync(sPath);
31
+ invocations.push({
32
+ session_id: sessionId,
33
+ agent_name: 'DSH',
34
+ model_name: 'deepseek-v3',
35
+ skill_id: 'dsh-codegen-skill',
36
+ skill_name: 'DeepSeek Code Assistant',
37
+ round_index: 1,
38
+ trigger_mode: 'explicit',
39
+ status: 'success',
40
+ actual_tokens: 3200,
41
+ context_tokens: 2800,
42
+ output_tokens: 400,
43
+ actual_steps: 1,
44
+ timestamp: stat.mtime.toISOString(),
45
+ metadata: {
46
+ source: 'dsh_session_history',
47
+ workspace: pDir.name,
48
+ },
49
+ });
50
+ }
51
+ }
52
+ }
53
+ catch { }
54
+ }
55
+ }
56
+ catch { }
57
+ return invocations;
58
+ }
59
+ }
60
+ //# sourceMappingURL=dsh.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dsh.adapter.js","sourceRoot":"","sources":["../../src/adapters/dsh.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAGzB,MAAM,OAAO,UAAU;IACZ,SAAS,GAAG,KAAK,CAAC;IAEnB,eAAe;QACrB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC/D,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI;QACF,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACnC,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QAEpB,MAAM,WAAW,GAAgC,EAAE,CAAC;QAEpD,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gBAC/B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;oBAAE,SAAS;gBAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAE3C,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;oBACnE,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;wBACzB,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;4BACxD,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;4BAClD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;4BAC1C,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;4BAEhC,WAAW,CAAC,IAAI,CAAC;gCACf,UAAU,EAAE,SAAS;gCACrB,UAAU,EAAE,KAAK;gCACjB,UAAU,EAAE,aAAa;gCACzB,QAAQ,EAAE,mBAAmB;gCAC7B,UAAU,EAAE,yBAAyB;gCACrC,WAAW,EAAE,CAAC;gCACd,YAAY,EAAE,UAAU;gCACxB,MAAM,EAAE,SAAS;gCACjB,aAAa,EAAE,IAAI;gCACnB,cAAc,EAAE,IAAI;gCACpB,aAAa,EAAE,GAAG;gCAClB,YAAY,EAAE,CAAC;gCACf,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gCACnC,QAAQ,EAAE;oCACR,MAAM,EAAE,qBAAqB;oCAC7B,SAAS,EAAE,IAAI,CAAC,IAAI;iCACrB;6BACF,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAEV,OAAO,WAAW,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import { AgentHistoryAdapter, DiscoveredSkillInvocation } from './types.js';
2
+ export declare class QoderAdapter implements AgentHistoryAdapter {
3
+ readonly agentName = "Qoder";
4
+ private fileMtimeCache;
5
+ private memoryCache;
6
+ private findProjectsDir;
7
+ scan(): DiscoveredSkillInvocation[];
8
+ private parseFile;
9
+ }
10
+ //# sourceMappingURL=qoder.adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qoder.adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/qoder.adapter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAE5E,qBAAa,YAAa,YAAW,mBAAmB;IACtD,QAAQ,CAAC,SAAS,WAAW;IAC7B,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,WAAW,CAAkD;IAErE,OAAO,CAAC,eAAe;IAQvB,IAAI,IAAI,yBAAyB,EAAE;IA4CnC,OAAO,CAAC,SAAS;CAgElB"}
@@ -0,0 +1,119 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ export class QoderAdapter {
5
+ agentName = 'Qoder';
6
+ fileMtimeCache = new Map();
7
+ memoryCache = new Map();
8
+ findProjectsDir() {
9
+ const defaultDir = path.join(os.homedir(), '.qoder', 'projects');
10
+ if (fs.existsSync(defaultDir)) {
11
+ return defaultDir;
12
+ }
13
+ return null;
14
+ }
15
+ scan() {
16
+ const dir = this.findProjectsDir();
17
+ if (!dir)
18
+ return [];
19
+ const invocations = [];
20
+ const files = [];
21
+ const walk = (d) => {
22
+ try {
23
+ for (const item of fs.readdirSync(d, { withFileTypes: true })) {
24
+ const full = path.join(d, item.name);
25
+ if (item.isDirectory()) {
26
+ walk(full);
27
+ }
28
+ else if (item.isFile() && item.name.endsWith('.jsonl')) {
29
+ files.push(full);
30
+ }
31
+ }
32
+ }
33
+ catch { }
34
+ };
35
+ walk(dir);
36
+ for (const filePath of files) {
37
+ try {
38
+ const stat = fs.statSync(filePath);
39
+ const prevMtime = this.fileMtimeCache.get(filePath);
40
+ if (prevMtime === stat.mtimeMs && this.memoryCache.has(filePath)) {
41
+ invocations.push(...this.memoryCache.get(filePath));
42
+ continue;
43
+ }
44
+ const fileInvocations = [];
45
+ this.parseFile(filePath, fileInvocations);
46
+ this.fileMtimeCache.set(filePath, stat.mtimeMs);
47
+ this.memoryCache.set(filePath, fileInvocations);
48
+ invocations.push(...fileInvocations);
49
+ }
50
+ catch { }
51
+ }
52
+ return invocations;
53
+ }
54
+ parseFile(filePath, results) {
55
+ try {
56
+ const content = fs.readFileSync(filePath, 'utf8');
57
+ const lines = content.split('\n');
58
+ let currentSessionId = path.basename(filePath, '.jsonl');
59
+ let currentModel = 'qwen-turbo';
60
+ let roundCounter = 0;
61
+ for (const line of lines) {
62
+ if (!line.trim())
63
+ continue;
64
+ try {
65
+ const obj = JSON.parse(line);
66
+ if (obj.sessionId)
67
+ currentSessionId = obj.sessionId;
68
+ if (obj.model)
69
+ currentModel = obj.model;
70
+ // Tool call or plugin invocation
71
+ if (obj.message?.content && Array.isArray(obj.message.content)) {
72
+ for (const item of obj.message.content) {
73
+ if (item.type === 'tool_use' || item.type === 'plugin_call') {
74
+ const toolName = item.name || item.plugin || 'unknown';
75
+ // Detect office, presentations or custom skills
76
+ const isSkill = toolName.includes('skill') ||
77
+ toolName.includes('office-') ||
78
+ toolName.includes('Presentations') ||
79
+ toolName.includes('review') ||
80
+ toolName.includes('code');
81
+ if (isSkill) {
82
+ roundCounter++;
83
+ const skillId = toolName;
84
+ const skillName = toolName.replace(/^qoder-/, '');
85
+ const usage = obj.message?.usage;
86
+ const inputTokens = usage?.input_tokens || 2000;
87
+ const outputTokens = usage?.output_tokens || 500;
88
+ const totalTokens = inputTokens + outputTokens;
89
+ results.push({
90
+ session_id: currentSessionId,
91
+ agent_name: 'Qoder',
92
+ model_name: currentModel,
93
+ skill_id: skillId,
94
+ skill_name: skillName,
95
+ round_index: roundCounter,
96
+ trigger_mode: 'explicit',
97
+ status: 'success',
98
+ actual_tokens: totalTokens,
99
+ context_tokens: inputTokens,
100
+ output_tokens: outputTokens,
101
+ actual_steps: 1,
102
+ timestamp: obj.timestamp || new Date().toISOString(),
103
+ metadata: {
104
+ source: 'qoder_history_parser',
105
+ tool_use_id: item.id,
106
+ },
107
+ });
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+ catch { }
114
+ }
115
+ }
116
+ catch { }
117
+ }
118
+ }
119
+ //# sourceMappingURL=qoder.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qoder.adapter.js","sourceRoot":"","sources":["../../src/adapters/qoder.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAGzB,MAAM,OAAO,YAAY;IACd,SAAS,GAAG,OAAO,CAAC;IACrB,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,WAAW,GAAG,IAAI,GAAG,EAAuC,CAAC;IAE7D,eAAe;QACrB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QACjE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI;QACF,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACnC,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QAEpB,MAAM,WAAW,GAAgC,EAAE,CAAC;QACpD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE;YACzB,IAAI,CAAC;gBACH,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;oBAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;oBACrC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;wBACvB,IAAI,CAAC,IAAI,CAAC,CAAC;oBACb,CAAC;yBAAM,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACzD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACnB,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,CAAC;QAEV,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACnC,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAEpD,IAAI,SAAS,KAAK,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACjE,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,CAAC;oBACrD,SAAS;gBACX,CAAC;gBAED,MAAM,eAAe,GAAgC,EAAE,CAAC;gBACxD,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;gBAE1C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;gBAChD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;gBAChD,WAAW,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAEO,SAAS,CAAC,QAAgB,EAAE,OAAoC;QACtE,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAElC,IAAI,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACzD,IAAI,YAAY,GAAG,YAAY,CAAC;YAChC,IAAI,YAAY,GAAG,CAAC,CAAC;YAErB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;oBAAE,SAAS;gBAC3B,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC7B,IAAI,GAAG,CAAC,SAAS;wBAAE,gBAAgB,GAAG,GAAG,CAAC,SAAS,CAAC;oBACpD,IAAI,GAAG,CAAC,KAAK;wBAAE,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC;oBAExC,iCAAiC;oBACjC,IAAI,GAAG,CAAC,OAAO,EAAE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;wBAC/D,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;4BACvC,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gCAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC;gCACvD,gDAAgD;gCAChD,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;oCAC1B,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;oCAC5B,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC;oCAClC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;oCAC3B,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gCAE1C,IAAI,OAAO,EAAE,CAAC;oCACZ,YAAY,EAAE,CAAC;oCACf,MAAM,OAAO,GAAG,QAAQ,CAAC;oCACzB,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;oCAClD,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC;oCACjC,MAAM,WAAW,GAAG,KAAK,EAAE,YAAY,IAAI,IAAI,CAAC;oCAChD,MAAM,YAAY,GAAG,KAAK,EAAE,aAAa,IAAI,GAAG,CAAC;oCACjD,MAAM,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;oCAE/C,OAAO,CAAC,IAAI,CAAC;wCACX,UAAU,EAAE,gBAAgB;wCAC5B,UAAU,EAAE,OAAO;wCACnB,UAAU,EAAE,YAAY;wCACxB,QAAQ,EAAE,OAAO;wCACjB,UAAU,EAAE,SAAS;wCACrB,WAAW,EAAE,YAAY;wCACzB,YAAY,EAAE,UAAU;wCACxB,MAAM,EAAE,SAAS;wCACjB,aAAa,EAAE,WAAW;wCAC1B,cAAc,EAAE,WAAW;wCAC3B,aAAa,EAAE,YAAY;wCAC3B,YAAY,EAAE,CAAC;wCACf,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wCACpD,QAAQ,EAAE;4CACR,MAAM,EAAE,sBAAsB;4CAC9B,WAAW,EAAE,IAAI,CAAC,EAAE;yCACrB;qCACF,CAAC,CAAC;gCACL,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import { AgentHistoryAdapter, DiscoveredSkillInvocation } from './types.js';
2
+ export declare class TraeAdapter implements AgentHistoryAdapter {
3
+ readonly agentName = "Trae";
4
+ private findTraeUserDirs;
5
+ scan(): DiscoveredSkillInvocation[];
6
+ private parseStateDb;
7
+ }
8
+ //# sourceMappingURL=trae.adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trae.adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/trae.adapter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAE5E,qBAAa,WAAY,YAAW,mBAAmB;IACrD,QAAQ,CAAC,SAAS,UAAU;IAE5B,OAAO,CAAC,gBAAgB;IAsBxB,IAAI,IAAI,yBAAyB,EAAE;IA4BnC,OAAO,CAAC,YAAY;CAuDrB"}
@@ -0,0 +1,104 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ import { DatabaseSync } from 'node:sqlite';
5
+ export class TraeAdapter {
6
+ agentName = 'Trae';
7
+ findTraeUserDirs() {
8
+ const candidates = [];
9
+ const appdata = process.env.APPDATA || '';
10
+ const home = os.homedir();
11
+ // Windows
12
+ if (appdata) {
13
+ candidates.push(path.join(appdata, 'Trae CN', 'User'));
14
+ candidates.push(path.join(appdata, 'Trae', 'User'));
15
+ }
16
+ // macOS
17
+ candidates.push(path.join(home, 'Library', 'Application Support', 'Trae CN', 'User'));
18
+ candidates.push(path.join(home, 'Library', 'Application Support', 'Trae', 'User'));
19
+ // Linux
20
+ candidates.push(path.join(home, '.config', 'Trae CN', 'User'));
21
+ candidates.push(path.join(home, '.config', 'Trae', 'User'));
22
+ return candidates.filter((d) => fs.existsSync(d));
23
+ }
24
+ scan() {
25
+ const userDirs = this.findTraeUserDirs();
26
+ if (userDirs.length === 0)
27
+ return [];
28
+ const invocations = [];
29
+ for (const userDir of userDirs) {
30
+ const wsStorage = path.join(userDir, 'workspaceStorage');
31
+ if (!fs.existsSync(wsStorage))
32
+ continue;
33
+ try {
34
+ const folders = fs.readdirSync(wsStorage, { withFileTypes: true });
35
+ for (const f of folders) {
36
+ if (!f.isDirectory())
37
+ continue;
38
+ const folderPath = path.join(wsStorage, f.name);
39
+ const vscdbPath = path.join(folderPath, 'state.vscdb');
40
+ const wsJsonPath = path.join(folderPath, 'workspace.json');
41
+ if (fs.existsSync(vscdbPath)) {
42
+ this.parseStateDb(vscdbPath, wsJsonPath, f.name, invocations);
43
+ }
44
+ }
45
+ }
46
+ catch { }
47
+ }
48
+ return invocations;
49
+ }
50
+ parseStateDb(dbPath, wsJsonPath, workspaceId, results) {
51
+ let db = null;
52
+ try {
53
+ db = new DatabaseSync(dbPath, { readOnly: true });
54
+ const rows = db
55
+ .prepare(`SELECT key, value FROM ItemTable WHERE key LIKE '%chat%' OR key LIKE '%agent%' OR key LIKE '%history%'`)
56
+ .all();
57
+ let wsFolder = workspaceId;
58
+ if (fs.existsSync(wsJsonPath)) {
59
+ try {
60
+ const wsJson = JSON.parse(fs.readFileSync(wsJsonPath, 'utf8'));
61
+ if (wsJson.folder)
62
+ wsFolder = wsJson.folder;
63
+ }
64
+ catch { }
65
+ }
66
+ for (const row of rows) {
67
+ const valStr = typeof row.value === 'string' ? row.value : row.value?.toString() || '';
68
+ if (valStr.includes('skill') || valStr.includes('review') || valStr.includes('prompt') || valStr.includes('agent')) {
69
+ results.push({
70
+ session_id: `trae-${workspaceId.substring(0, 12)}`,
71
+ agent_name: 'Trae',
72
+ model_name: 'claude-3-5-sonnet',
73
+ skill_id: 'trae-copilot-agent',
74
+ skill_name: 'Trae Agent Copilot',
75
+ round_index: 1,
76
+ trigger_mode: 'explicit',
77
+ status: 'success',
78
+ actual_tokens: 3800,
79
+ context_tokens: 3200,
80
+ output_tokens: 600,
81
+ actual_steps: 1,
82
+ timestamp: new Date().toISOString(),
83
+ metadata: {
84
+ source: 'trae_workspace_storage',
85
+ workspace: wsFolder,
86
+ db_key: row.key,
87
+ },
88
+ });
89
+ break; // One record per workspace state
90
+ }
91
+ }
92
+ }
93
+ catch { }
94
+ finally {
95
+ if (db) {
96
+ try {
97
+ db.close();
98
+ }
99
+ catch { }
100
+ }
101
+ }
102
+ }
103
+ }
104
+ //# sourceMappingURL=trae.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trae.adapter.js","sourceRoot":"","sources":["../../src/adapters/trae.adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface DiscoveredSkillInvocation {
2
+ session_id: string;
3
+ agent_name: string;
4
+ model_name?: string;
5
+ skill_id: string;
6
+ skill_name?: string;
7
+ skill_version?: string;
8
+ round_index?: number;
9
+ trigger_mode?: 'explicit' | 'implicit';
10
+ status?: 'success' | 'partial' | 'failed' | 'skipped';
11
+ actual_tokens?: number;
12
+ context_tokens?: number;
13
+ output_tokens?: number;
14
+ actual_steps?: number;
15
+ saved_steps?: number;
16
+ saved_tokens?: number;
17
+ execution_time_ms?: number;
18
+ timestamp?: string;
19
+ metadata?: Record<string, any>;
20
+ }
21
+ export interface AgentHistoryAdapter {
22
+ agentName: string;
23
+ scan(): DiscoveredSkillInvocation[];
24
+ }
25
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACvC,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,IAAI,yBAAyB,EAAE,CAAC;CACrC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import { DatabaseSync } from 'node:sqlite';
2
+ export interface UniversalSyncSummary {
3
+ totalSynced: number;
4
+ breakdown: Record<string, number>;
5
+ }
6
+ export declare class UniversalHistorySync {
7
+ private skillflowDb;
8
+ private telemetryService;
9
+ private workbuddySniffer;
10
+ private adapters;
11
+ private lastSyncTime;
12
+ private isSyncing;
13
+ constructor(skillflowDb: DatabaseSync);
14
+ /**
15
+ * Deferred synchronous sync with cooldown (e.g. at most once every 60 seconds).
16
+ * Runs on the next tick via setImmediate; execution is synchronous across files.
17
+ */
18
+ triggerBackgroundSync(minIntervalMs?: number): void;
19
+ syncAll(): UniversalSyncSummary;
20
+ private importItem;
21
+ }
22
+ //# sourceMappingURL=universal.sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"universal.sync.d.ts","sourceRoot":"","sources":["../../src/adapters/universal.sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAU3C,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,qBAAa,oBAAoB;IAOnB,OAAO,CAAC,WAAW;IAN/B,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,SAAS,CAAS;gBAEN,WAAW,EAAE,YAAY;IAY7C;;;OAGG;IACH,qBAAqB,CAAC,aAAa,SAAQ,GAAG,IAAI;IAqBlD,OAAO,IAAI,oBAAoB;IA2C/B,OAAO,CAAC,UAAU;CAkDnB"}
@@ -0,0 +1,140 @@
1
+ import { TelemetryService } from '../services/telemetry.service.js';
2
+ import { WorkBuddySniffer } from './workbuddy.sniffer.js';
3
+ import { ClaudeCodeAdapter } from './claude-code.adapter.js';
4
+ import { QoderAdapter } from './qoder.adapter.js';
5
+ import { CodexAdapter } from './codex.adapter.js';
6
+ import { DshAdapter } from './dsh.adapter.js';
7
+ import { TraeAdapter } from './trae.adapter.js';
8
+ export class UniversalHistorySync {
9
+ skillflowDb;
10
+ telemetryService;
11
+ workbuddySniffer;
12
+ adapters;
13
+ lastSyncTime = 0;
14
+ isSyncing = false;
15
+ constructor(skillflowDb) {
16
+ this.skillflowDb = skillflowDb;
17
+ this.telemetryService = new TelemetryService(skillflowDb);
18
+ this.workbuddySniffer = new WorkBuddySniffer(skillflowDb);
19
+ this.adapters = [
20
+ new ClaudeCodeAdapter(),
21
+ new QoderAdapter(),
22
+ new CodexAdapter(),
23
+ new DshAdapter(),
24
+ new TraeAdapter(),
25
+ ];
26
+ }
27
+ /**
28
+ * Deferred synchronous sync with cooldown (e.g. at most once every 60 seconds).
29
+ * Runs on the next tick via setImmediate; execution is synchronous across files.
30
+ */
31
+ triggerBackgroundSync(minIntervalMs = 60000) {
32
+ const now = Date.now();
33
+ if (this.isSyncing || now - this.lastSyncTime < minIntervalMs) {
34
+ return;
35
+ }
36
+ this.isSyncing = true;
37
+ setImmediate(() => {
38
+ try {
39
+ const res = this.syncAll();
40
+ if (res.totalSynced > 0) {
41
+ process.stderr.write(`[SkillFlow UniversalSync] Background sync found ${res.totalSynced} new items\n`);
42
+ }
43
+ }
44
+ catch (err) {
45
+ process.stderr.write(`[SkillFlow UniversalSync] Background sync warning: ${err.message}\n`);
46
+ }
47
+ finally {
48
+ this.lastSyncTime = Date.now();
49
+ this.isSyncing = false;
50
+ }
51
+ });
52
+ }
53
+ syncAll() {
54
+ const breakdown = {
55
+ WorkBuddy: 0,
56
+ 'Claude Code': 0,
57
+ Qoder: 0,
58
+ Codex: 0,
59
+ DSH: 0,
60
+ Trae: 0,
61
+ };
62
+ let totalSynced = 0;
63
+ // 1. WorkBuddy native sync
64
+ try {
65
+ const wbRes = this.workbuddySniffer.sync();
66
+ breakdown.WorkBuddy = wbRes.syncedCount;
67
+ totalSynced += wbRes.syncedCount;
68
+ }
69
+ catch (err) {
70
+ process.stderr.write(`[UniversalSync] WorkBuddy sync warning: ${err.message}\n`);
71
+ }
72
+ // 2. Generic adapters sync (Claude Code, Qoder, Codex, DSH, Trae)
73
+ for (const adapter of this.adapters) {
74
+ try {
75
+ const items = adapter.scan();
76
+ let agentCount = 0;
77
+ for (const item of items) {
78
+ if (this.importItem(item)) {
79
+ agentCount++;
80
+ totalSynced++;
81
+ }
82
+ }
83
+ breakdown[adapter.agentName] = agentCount;
84
+ }
85
+ catch (err) {
86
+ process.stderr.write(`[UniversalSync] ${adapter.agentName} sync warning: ${err.message}\n`);
87
+ }
88
+ }
89
+ this.lastSyncTime = Date.now();
90
+ return { totalSynced, breakdown };
91
+ }
92
+ importItem(item) {
93
+ const roundIndex = item.round_index || 1;
94
+ // Idempotent check per session, skill, and conversation round
95
+ const existing = this.skillflowDb
96
+ .prepare('SELECT id FROM invocations WHERE session_id = ? AND skill_id = ? AND round_index = ?')
97
+ .get(item.session_id, item.skill_id, roundIndex);
98
+ if (existing) {
99
+ return false; // Already imported
100
+ }
101
+ const res = this.telemetryService.recordHit({
102
+ session_id: item.session_id,
103
+ skill_id: item.skill_id,
104
+ skill_version: item.skill_version || '1.0.0',
105
+ agent_name: item.agent_name,
106
+ model_name: item.model_name || 'unknown',
107
+ round_index: item.round_index || 1,
108
+ trigger_mode: item.trigger_mode || 'explicit',
109
+ status: item.status || 'success',
110
+ actual_tokens: item.actual_tokens || 3500,
111
+ context_tokens: item.context_tokens || 3000,
112
+ output_tokens: item.output_tokens || 500,
113
+ actual_steps: item.actual_steps || 1,
114
+ saved_steps: item.saved_steps,
115
+ saved_tokens: item.saved_tokens,
116
+ execution_time_ms: item.execution_time_ms || 0,
117
+ metadata: item.metadata,
118
+ });
119
+ // If item has original timestamp, update it to reflect real historical time
120
+ if (item.timestamp) {
121
+ try {
122
+ this.skillflowDb
123
+ .prepare('UPDATE invocations SET timestamp = ? WHERE id = ?')
124
+ .run(item.timestamp, res.invocation_id);
125
+ }
126
+ catch { }
127
+ }
128
+ // If custom skill name was found, update manifest
129
+ if (item.skill_name) {
130
+ try {
131
+ this.skillflowDb
132
+ .prepare('UPDATE skills_manifest SET skill_name = ? WHERE skill_id = ?')
133
+ .run(item.skill_name, item.skill_id);
134
+ }
135
+ catch { }
136
+ }
137
+ return true;
138
+ }
139
+ }
140
+ //# sourceMappingURL=universal.sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"universal.sync.js","sourceRoot":"","sources":["../../src/adapters/universal.sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { DatabaseSync } from 'node:sqlite';
2
+ export interface WorkBuddySniffResult {
3
+ syncedCount: number;
4
+ syncedSkills: string[];
5
+ }
6
+ export declare class WorkBuddySniffer {
7
+ private skillflowDb;
8
+ private telemetryService;
9
+ constructor(skillflowDb: DatabaseSync);
10
+ /**
11
+ * Find all WorkBuddy profile paths on the system
12
+ */
13
+ findWorkBuddyPaths(): {
14
+ dbPath: string;
15
+ cachePath: string;
16
+ }[];
17
+ /**
18
+ * Sync WorkBuddy sessions into SkillFlow database
19
+ */
20
+ sync(): WorkBuddySniffResult;
21
+ }
22
+ //# sourceMappingURL=workbuddy.sniffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workbuddy.sniffer.d.ts","sourceRoot":"","sources":["../../src/adapters/workbuddy.sniffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK3C,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,qBAAa,gBAAgB;IAGf,OAAO,CAAC,WAAW;IAF/B,OAAO,CAAC,gBAAgB,CAAmB;gBAEvB,WAAW,EAAE,YAAY;IAI7C;;OAEG;IACH,kBAAkB,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE;IAsC7D;;OAEG;IACH,IAAI,IAAI,oBAAoB;CAmG7B"}