@relipa/ai-flow-kit 0.1.1-beta.0 → 0.1.2-beta.0

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 (247) hide show
  1. package/README.md +0 -0
  2. package/bin/aiflow.js +55 -2
  3. package/bin/ak.js +0 -0
  4. package/custom/mcp-presets/README.md +204 -204
  5. package/custom/mcp-presets/backlog.json +0 -0
  6. package/custom/mcp-presets/figma-desktop.json +0 -0
  7. package/custom/mcp-presets/figma.json +0 -0
  8. package/custom/mcp-presets/gitnexus.json +0 -0
  9. package/custom/mcp-presets/google-sheets.json +0 -0
  10. package/custom/mcp-presets/jira.json +0 -0
  11. package/custom/prompts/bug-fix.md +0 -0
  12. package/custom/prompts/feature.md +0 -0
  13. package/custom/prompts/investigation.md +0 -0
  14. package/custom/rules/code-style.md +0 -0
  15. package/custom/rules/java/code-style.md +0 -0
  16. package/custom/rules/java/naming.md +0 -0
  17. package/custom/rules/java/review-checklist.md +0 -0
  18. package/custom/rules/java/spring-boot-examples.md +0 -0
  19. package/custom/rules/javascript/code-style.md +0 -0
  20. package/custom/rules/javascript/naming.md +0 -0
  21. package/custom/rules/ml-conventions.md +88 -0
  22. package/custom/rules/ml-review-checklist.md +14 -0
  23. package/custom/rules/naming.md +0 -0
  24. package/custom/rules/php/code-style.md +0 -0
  25. package/custom/rules/php/naming.md +0 -0
  26. package/custom/rules/project-conventions.md +0 -0
  27. package/custom/rules/review-checklist.md +0 -0
  28. package/custom/skills/deploy-model/SKILL.md +90 -0
  29. package/custom/skills/design-experiment/SKILL.md +88 -0
  30. package/custom/skills/evaluate-model/SKILL.md +93 -0
  31. package/custom/skills/explore-data/SKILL.md +87 -0
  32. package/custom/skills/figma-to-component/SKILL.md +164 -59
  33. package/custom/skills/frame-ml-problem/SKILL.md +88 -0
  34. package/custom/skills/generate-spec/SKILL.md +0 -0
  35. package/custom/skills/impact-analysis/SKILL.md +0 -0
  36. package/custom/skills/improve-algorithm/SKILL.md +74 -0
  37. package/custom/skills/investigate-bug/SKILL.md +0 -0
  38. package/custom/skills/read-study-requirement/SKILL.md +0 -0
  39. package/custom/skills/report-customer/SKILL.md +0 -0
  40. package/custom/skills/review-plan/SKILL.md +0 -0
  41. package/custom/skills/train-model/SKILL.md +78 -0
  42. package/custom/templates/laravel.md +0 -0
  43. package/custom/templates/nestjs.md +0 -0
  44. package/custom/templates/nextjs.md +0 -0
  45. package/custom/templates/nodejs-express.md +0 -0
  46. package/custom/templates/php-plain.md +0 -0
  47. package/custom/templates/php.md +0 -0
  48. package/custom/templates/python-django.md +0 -0
  49. package/custom/templates/python-fastapi.md +0 -0
  50. package/custom/templates/python-ml.md +273 -0
  51. package/custom/templates/python.md +0 -0
  52. package/custom/templates/reactjs.md +0 -0
  53. package/custom/templates/shared/gate-workflow.md +0 -0
  54. package/custom/templates/shared/ml-gate-workflow.md +103 -0
  55. package/custom/templates/spring-boot.md +0 -0
  56. package/custom/templates/tools/claude.md +0 -0
  57. package/custom/templates/tools/copilot.md +0 -0
  58. package/custom/templates/tools/cursor.md +0 -0
  59. package/custom/templates/tools/gemini.md +0 -0
  60. package/custom/templates/tools/generic.md +0 -0
  61. package/custom/templates/vue-nuxt.md +0 -0
  62. package/docs/common/AIFLOW.md +512 -512
  63. package/docs/common/CHANGELOG.md +16 -0
  64. package/docs/common/QUICK_START.md +0 -0
  65. package/docs/common/ai-integration.md +0 -0
  66. package/docs/common/cli-reference.md +0 -0
  67. package/docs/common/configuration.md +0 -0
  68. package/docs/common/getting-started.md +0 -0
  69. package/docs/common/troubleshooting.md +0 -0
  70. package/docs/common/workflows/bug-fix.md +0 -0
  71. package/docs/common/workflows/feature.md +0 -0
  72. package/docs/common/workflows/figma.md +0 -0
  73. package/docs/common/workflows/impact-analysis.md +0 -0
  74. package/docs/common/workflows/investigation.md +0 -0
  75. package/docs/common/workflows/refactor.md +0 -0
  76. package/docs/project/ARCHITECTURE.md +0 -0
  77. package/index.js +0 -0
  78. package/package.json +2 -2
  79. package/scripts/checkpoint.js +0 -0
  80. package/scripts/config.js +0 -0
  81. package/scripts/context.js +0 -0
  82. package/scripts/create-score-excel.js +0 -0
  83. package/scripts/detect.js +239 -239
  84. package/scripts/doctor.js +192 -218
  85. package/scripts/gitnexus-worker.js +0 -0
  86. package/scripts/guide.js +0 -0
  87. package/scripts/hooks/block-git-write.js +0 -0
  88. package/scripts/hooks/session-start.js +0 -0
  89. package/scripts/hooks/session-stop.js +0 -0
  90. package/scripts/init.js +1112 -1009
  91. package/scripts/link-resolver.js +0 -0
  92. package/scripts/memory.js +0 -0
  93. package/scripts/prompt.js +538 -538
  94. package/scripts/remove.js +0 -0
  95. package/scripts/task.js +546 -546
  96. package/scripts/telemetry/cli.js +0 -0
  97. package/scripts/telemetry/config.js +0 -0
  98. package/scripts/telemetry/crypto.js +0 -0
  99. package/scripts/telemetry/flush.js +0 -0
  100. package/scripts/telemetry/record.js +0 -0
  101. package/scripts/update.js +10 -7
  102. package/scripts/use.js +33 -12
  103. package/scripts/validate.js +0 -0
  104. package/upstream/.claude-plugin/marketplace.json +0 -0
  105. package/upstream/.claude-plugin/plugin.json +0 -0
  106. package/upstream/.codex/INSTALL.md +0 -0
  107. package/upstream/.cursor-plugin/plugin.json +0 -0
  108. package/upstream/.gitattributes +0 -0
  109. package/upstream/.github/FUNDING.yml +0 -0
  110. package/upstream/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  111. package/upstream/.github/ISSUE_TEMPLATE/config.yml +0 -0
  112. package/upstream/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  113. package/upstream/.github/ISSUE_TEMPLATE/platform_support.md +0 -0
  114. package/upstream/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  115. package/upstream/.opencode/INSTALL.md +0 -0
  116. package/upstream/.opencode/plugins/superpowers.js +0 -0
  117. package/upstream/.version-bump.json +0 -0
  118. package/upstream/AGENTS.md +0 -0
  119. package/upstream/CHANGELOG.md +0 -0
  120. package/upstream/CLAUDE.md +0 -0
  121. package/upstream/CODE_OF_CONDUCT.md +0 -0
  122. package/upstream/GEMINI.md +0 -0
  123. package/upstream/LICENSE +0 -0
  124. package/upstream/README.md +0 -0
  125. package/upstream/RELEASE-NOTES.md +0 -0
  126. package/upstream/agents/code-reviewer.md +0 -0
  127. package/upstream/commands/brainstorm.md +0 -0
  128. package/upstream/commands/execute-plan.md +0 -0
  129. package/upstream/commands/write-plan.md +0 -0
  130. package/upstream/docs/README.codex.md +0 -0
  131. package/upstream/docs/README.opencode.md +0 -0
  132. package/upstream/docs/plans/2025-11-22-opencode-support-design.md +0 -0
  133. package/upstream/docs/plans/2025-11-22-opencode-support-implementation.md +0 -0
  134. package/upstream/docs/plans/2025-11-28-skills-improvements-from-user-feedback.md +0 -0
  135. package/upstream/docs/plans/2026-01-17-visual-brainstorming.md +0 -0
  136. package/upstream/docs/superpowers/plans/2026-01-22-document-review-system.md +0 -0
  137. package/upstream/docs/superpowers/plans/2026-02-19-visual-brainstorming-refactor.md +0 -0
  138. package/upstream/docs/superpowers/plans/2026-03-11-zero-dep-brainstorm-server.md +0 -0
  139. package/upstream/docs/superpowers/plans/2026-03-23-codex-app-compatibility.md +0 -0
  140. package/upstream/docs/superpowers/specs/2026-01-22-document-review-system-design.md +0 -0
  141. package/upstream/docs/superpowers/specs/2026-02-19-visual-brainstorming-refactor-design.md +0 -0
  142. package/upstream/docs/superpowers/specs/2026-03-11-zero-dep-brainstorm-server-design.md +0 -0
  143. package/upstream/docs/superpowers/specs/2026-03-23-codex-app-compatibility-design.md +0 -0
  144. package/upstream/docs/testing.md +0 -0
  145. package/upstream/docs/windows/polyglot-hooks.md +0 -0
  146. package/upstream/gemini-extension.json +0 -0
  147. package/upstream/hooks/hooks-cursor.json +0 -0
  148. package/upstream/hooks/hooks.json +0 -0
  149. package/upstream/hooks/run-hook.cmd +0 -0
  150. package/upstream/hooks/session-start +0 -0
  151. package/upstream/package.json +0 -0
  152. package/upstream/scripts/bump-version.sh +0 -0
  153. package/upstream/skills/brainstorming/SKILL.md +0 -0
  154. package/upstream/skills/brainstorming/scripts/frame-template.html +0 -0
  155. package/upstream/skills/brainstorming/scripts/helper.js +0 -0
  156. package/upstream/skills/brainstorming/scripts/server.cjs +0 -0
  157. package/upstream/skills/brainstorming/scripts/start-server.sh +0 -0
  158. package/upstream/skills/brainstorming/scripts/stop-server.sh +0 -0
  159. package/upstream/skills/brainstorming/spec-document-reviewer-prompt.md +0 -0
  160. package/upstream/skills/brainstorming/visual-companion.md +0 -0
  161. package/upstream/skills/dispatching-parallel-agents/SKILL.md +0 -0
  162. package/upstream/skills/executing-plans/SKILL.md +0 -0
  163. package/upstream/skills/finishing-a-development-branch/SKILL.md +0 -0
  164. package/upstream/skills/receiving-code-review/SKILL.md +0 -0
  165. package/upstream/skills/requesting-code-review/SKILL.md +0 -0
  166. package/upstream/skills/requesting-code-review/code-reviewer.md +0 -0
  167. package/upstream/skills/subagent-driven-development/SKILL.md +0 -0
  168. package/upstream/skills/subagent-driven-development/code-quality-reviewer-prompt.md +0 -0
  169. package/upstream/skills/subagent-driven-development/implementer-prompt.md +0 -0
  170. package/upstream/skills/subagent-driven-development/spec-reviewer-prompt.md +0 -0
  171. package/upstream/skills/systematic-debugging/CREATION-LOG.md +0 -0
  172. package/upstream/skills/systematic-debugging/SKILL.md +0 -0
  173. package/upstream/skills/systematic-debugging/condition-based-waiting-example.ts +0 -0
  174. package/upstream/skills/systematic-debugging/condition-based-waiting.md +0 -0
  175. package/upstream/skills/systematic-debugging/defense-in-depth.md +0 -0
  176. package/upstream/skills/systematic-debugging/find-polluter.sh +0 -0
  177. package/upstream/skills/systematic-debugging/root-cause-tracing.md +0 -0
  178. package/upstream/skills/systematic-debugging/test-academic.md +0 -0
  179. package/upstream/skills/systematic-debugging/test-pressure-1.md +0 -0
  180. package/upstream/skills/systematic-debugging/test-pressure-2.md +0 -0
  181. package/upstream/skills/systematic-debugging/test-pressure-3.md +0 -0
  182. package/upstream/skills/tdd-lean/SKILL.md +0 -0
  183. package/upstream/skills/test-driven-development/SKILL.md +0 -0
  184. package/upstream/skills/test-driven-development/testing-anti-patterns.md +0 -0
  185. package/upstream/skills/using-git-worktrees/SKILL.md +0 -0
  186. package/upstream/skills/using-superpowers/SKILL.md +0 -0
  187. package/upstream/skills/using-superpowers/references/codex-tools.md +0 -0
  188. package/upstream/skills/using-superpowers/references/copilot-tools.md +0 -0
  189. package/upstream/skills/using-superpowers/references/gemini-tools.md +0 -0
  190. package/upstream/skills/verification-before-completion/SKILL.md +0 -0
  191. package/upstream/skills/writing-plans/SKILL.md +0 -0
  192. package/upstream/skills/writing-plans/plan-document-reviewer-prompt.md +0 -0
  193. package/upstream/skills/writing-skills/SKILL.md +0 -0
  194. package/upstream/skills/writing-skills/anthropic-best-practices.md +0 -0
  195. package/upstream/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -0
  196. package/upstream/skills/writing-skills/graphviz-conventions.dot +0 -0
  197. package/upstream/skills/writing-skills/persuasion-principles.md +0 -0
  198. package/upstream/skills/writing-skills/render-graphs.js +0 -0
  199. package/upstream/skills/writing-skills/testing-skills-with-subagents.md +0 -0
  200. package/upstream/tests/brainstorm-server/package-lock.json +0 -0
  201. package/upstream/tests/brainstorm-server/package.json +0 -0
  202. package/upstream/tests/brainstorm-server/server.test.js +0 -0
  203. package/upstream/tests/brainstorm-server/windows-lifecycle.test.sh +0 -0
  204. package/upstream/tests/brainstorm-server/ws-protocol.test.js +0 -0
  205. package/upstream/tests/claude-code/README.md +0 -0
  206. package/upstream/tests/claude-code/analyze-token-usage.py +0 -0
  207. package/upstream/tests/claude-code/run-skill-tests.sh +0 -0
  208. package/upstream/tests/claude-code/test-document-review-system.sh +0 -0
  209. package/upstream/tests/claude-code/test-helpers.sh +0 -0
  210. package/upstream/tests/claude-code/test-subagent-driven-development-integration.sh +0 -0
  211. package/upstream/tests/claude-code/test-subagent-driven-development.sh +0 -0
  212. package/upstream/tests/explicit-skill-requests/prompts/action-oriented.txt +0 -0
  213. package/upstream/tests/explicit-skill-requests/prompts/after-planning-flow.txt +0 -0
  214. package/upstream/tests/explicit-skill-requests/prompts/claude-suggested-it.txt +0 -0
  215. package/upstream/tests/explicit-skill-requests/prompts/i-know-what-sdd-means.txt +0 -0
  216. package/upstream/tests/explicit-skill-requests/prompts/mid-conversation-execute-plan.txt +0 -0
  217. package/upstream/tests/explicit-skill-requests/prompts/please-use-brainstorming.txt +0 -0
  218. package/upstream/tests/explicit-skill-requests/prompts/skip-formalities.txt +0 -0
  219. package/upstream/tests/explicit-skill-requests/prompts/subagent-driven-development-please.txt +0 -0
  220. package/upstream/tests/explicit-skill-requests/prompts/use-systematic-debugging.txt +0 -0
  221. package/upstream/tests/explicit-skill-requests/run-all.sh +0 -0
  222. package/upstream/tests/explicit-skill-requests/run-claude-describes-sdd.sh +0 -0
  223. package/upstream/tests/explicit-skill-requests/run-extended-multiturn-test.sh +0 -0
  224. package/upstream/tests/explicit-skill-requests/run-haiku-test.sh +0 -0
  225. package/upstream/tests/explicit-skill-requests/run-multiturn-test.sh +0 -0
  226. package/upstream/tests/explicit-skill-requests/run-test.sh +0 -0
  227. package/upstream/tests/opencode/run-tests.sh +0 -0
  228. package/upstream/tests/opencode/setup.sh +0 -0
  229. package/upstream/tests/opencode/test-plugin-loading.sh +0 -0
  230. package/upstream/tests/opencode/test-priority.sh +0 -0
  231. package/upstream/tests/opencode/test-tools.sh +0 -0
  232. package/upstream/tests/skill-triggering/prompts/dispatching-parallel-agents.txt +0 -0
  233. package/upstream/tests/skill-triggering/prompts/executing-plans.txt +0 -0
  234. package/upstream/tests/skill-triggering/prompts/requesting-code-review.txt +0 -0
  235. package/upstream/tests/skill-triggering/prompts/systematic-debugging.txt +0 -0
  236. package/upstream/tests/skill-triggering/prompts/test-driven-development.txt +0 -0
  237. package/upstream/tests/skill-triggering/prompts/writing-plans.txt +0 -0
  238. package/upstream/tests/skill-triggering/run-all.sh +0 -0
  239. package/upstream/tests/skill-triggering/run-test.sh +0 -0
  240. package/upstream/tests/subagent-driven-dev/go-fractals/design.md +0 -0
  241. package/upstream/tests/subagent-driven-dev/go-fractals/plan.md +0 -0
  242. package/upstream/tests/subagent-driven-dev/go-fractals/scaffold.sh +0 -0
  243. package/upstream/tests/subagent-driven-dev/run-test.sh +0 -0
  244. package/upstream/tests/subagent-driven-dev/svelte-todo/design.md +0 -0
  245. package/upstream/tests/subagent-driven-dev/svelte-todo/plan.md +0 -0
  246. package/upstream/tests/subagent-driven-dev/svelte-todo/scaffold.sh +0 -0
  247. package/scripts/score_members.js +0 -320
@@ -1,320 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- const fs = require('fs');
5
- const path = require('path');
6
- const XLSX = require('xlsx');
7
-
8
- const LOG_FILE = path.resolve(__dirname, '../tellog/log_25-05-2026_31-05-2026');
9
- const OUTPUT_FILE = path.resolve(__dirname, '../tellog/log_25-05-2026_31-05-2026.xlsx');
10
-
11
- const MEMBERS = [
12
- 'anhtt@relipasoft.com',
13
- 'hoangdv@relipasoft.com',
14
- 'chinhtt@relipasoft.com',
15
- 'phongnx@relipasoft.com',
16
- 'dungha@relipasoft.com',
17
- 'thangnv@relipasoft.com',
18
- 'nguyenlt@relipasoft.com',
19
- 'thuongvv@relipasoft.com',
20
- 'yenvtb@relipasoft.com',
21
- 'tructh@relipasoft.com',
22
- 'thainq@relipasoft.com',
23
- 'tuoittx@relipasoft.com',
24
- 'hungdv@relipasoft.com',
25
- 'hiepnk@relipasoft.com',
26
- 'khoihn@relipasoft.com',
27
- 'huynq@relipasoft.com',
28
- 'thinhvq@relipasoft.com',
29
- 'banv@relipasoft.com',
30
- 'duongnt1@relipasoft.com',
31
- 'anhnt@relipasoft.com',
32
- 'khanhdd@relipasoft.com',
33
- 'hieunv@relipasoft.com',
34
- ];
35
-
36
- const EXPLORE_COMMANDS = new Set(['init', 'update', 'version', 'help', 'init.help', 'unknown_flag']);
37
- const USE_COMMANDS = new Set(['use', 'prompt', 'guide', 'guideline', 'guiline', 'guide?']);
38
-
39
- // Tickets that are clearly not real work (test, demo, throwaway)
40
- const FAKE_TICKET_PATTERNS = /^(test|test-direct|demo|investigation|sample|trial|dummy)(-.*)?$/i;
41
-
42
- function isRealTicket(ticket) {
43
- if (!ticket || ticket === '-' || ticket.length < 3) return false;
44
- if (FAKE_TICKET_PATTERNS.test(ticket)) return false;
45
- // Real tickets typically follow PROJECT-ID pattern with uppercase prefix
46
- return true;
47
- }
48
-
49
- function parseLog() {
50
- const content = fs.readFileSync(LOG_FILE, 'utf8');
51
- const lines = content.split('\n');
52
-
53
- // Skip header (line 0)
54
- const events = [];
55
- for (let i = 1; i < lines.length; i++) {
56
- const line = lines[i].trim();
57
- if (!line) continue;
58
-
59
- // TSV format: columns separated by tabs
60
- const cols = line.split('\t');
61
- if (cols.length < 7) continue;
62
-
63
- const timestamp = cols[0];
64
- const repo = cols[1];
65
- const user = cols[2];
66
- const command = (cols[6] || '').trim();
67
- const gate = (cols[8] || '').trim();
68
- const ticket = (cols[9] || '').trim();
69
-
70
- if (!timestamp || !user) continue;
71
-
72
- // Parse date from "DD/MM/YYYY HH:MM" format
73
- const dateMatch = timestamp.match(/^(\d{2})\/(\d{2})\/(\d{4})/);
74
- if (!dateMatch) continue;
75
- const dateStr = `${dateMatch[3]}-${dateMatch[2]}-${dateMatch[1]}`;
76
-
77
- events.push({ timestamp, dateStr, repo, user, command, gate, ticket });
78
- }
79
- return events;
80
- }
81
-
82
- function detectSessions(userEvents) {
83
- // A new session = gap of more than 30 minutes between consecutive events
84
- // or a new day; simplified: count distinct hour blocks per day
85
- const sessionKeys = new Set();
86
- for (const e of userEvents) {
87
- const hourMatch = e.timestamp.match(/(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):/);
88
- if (hourMatch) {
89
- sessionKeys.add(`${hourMatch[3]}-${hourMatch[2]}-${hourMatch[1]}-${hourMatch[4]}`);
90
- }
91
- }
92
- return sessionKeys.size;
93
- }
94
-
95
- function score(stats) {
96
- const { totalEvents, activeDays, sessions, gateStarts, gateApproveds, ticketsProcessed,
97
- ticketsInWeek, hasUseOrPrompt, hasGateStartWithTicket, hasGate3to5Approved } = stats;
98
-
99
- if (totalEvents === 0) return { depth: 0, depthLabel: 'Không hoạt động' };
100
-
101
- const hasOnlyExplore = stats.onlyExploreCommands;
102
-
103
- // Score 5: Gate 3-5 approved + >= 3 real tickets active in week
104
- if (hasGate3to5Approved && ticketsInWeek >= 3) {
105
- return { depth: 5, depthLabel: 'Sử dụng thường xuyên workflow' };
106
- }
107
-
108
- // Score 4: gate.approved >= 1 + >= 1 ticket processed to end
109
- if (gateApproveds >= 1 && ticketsProcessed >= 1) {
110
- return { depth: 4, depthLabel: 'Hoàn thành workflow' };
111
- }
112
-
113
- // Score 3: gate.start with real ticket + >= 3 sessions
114
- if (hasGateStartWithTicket && sessions >= 3) {
115
- return { depth: 3, depthLabel: 'Dùng có workflow' };
116
- }
117
-
118
- // Score 2: has use/prompt/guideline OR >= 2 sessions
119
- if (hasUseOrPrompt || sessions >= 2) {
120
- return { depth: 2, depthLabel: 'Bắt đầu dùng' };
121
- }
122
-
123
- // Score 1: only explore commands
124
- if (hasOnlyExplore) {
125
- return { depth: 1, depthLabel: 'Mới khám phá' };
126
- }
127
-
128
- return { depth: 1, depthLabel: 'Mới khám phá' };
129
- }
130
-
131
- function computeImpactScore(stats) {
132
- // Impact: based on tickets processed and gate depth
133
- const { ticketsProcessed, gateApproveds, hasGate3to5Approved } = stats;
134
- if (ticketsProcessed >= 3 && hasGate3to5Approved) return { impact: 5, impactLabel: 'Rất cao' };
135
- if (ticketsProcessed >= 2 && gateApproveds >= 2) return { impact: 4, impactLabel: 'Cao' };
136
- if (ticketsProcessed >= 1 && gateApproveds >= 1) return { impact: 3, impactLabel: 'Trung bình' };
137
- if (stats.gateStarts >= 1) return { impact: 2, impactLabel: 'Thấp' };
138
- if (stats.totalEvents > 0) return { impact: 1, impactLabel: 'Rất thấp' };
139
- return { impact: 0, impactLabel: 'Không có' };
140
- }
141
-
142
- function buildNotes(stats) {
143
- const parts = [];
144
- if (stats.hasGate3to5Approved) parts.push('Gate 3-5 approved');
145
- if (stats.ticketsProcessed > 0) parts.push(`${stats.ticketsProcessed} ticket(s) hoàn thành`);
146
- if (stats.ticketsInWeek > stats.ticketsProcessed) parts.push(`${stats.ticketsInWeek} ticket(s) trong tuần`);
147
- if (stats.gateStarts > 0 && stats.ticketsProcessed === 0) parts.push('Có gate.start nhưng chưa hoàn thành ticket');
148
- if (stats.onlyExploreCommands && stats.totalEvents > 0) parts.push('Chỉ dùng lệnh khám phá');
149
- if (stats.totalEvents === 0) parts.push('Không có hoạt động');
150
- return parts.join('; ');
151
- }
152
-
153
- function analyzeMembers(events) {
154
- const results = [];
155
-
156
- for (const email of MEMBERS) {
157
- const userEvents = events.filter(e => e.user === email);
158
- const totalEvents = userEvents.length;
159
-
160
- const activeDaysSet = new Set(userEvents.map(e => e.dateStr));
161
- const activeDays = activeDaysSet.size;
162
-
163
- const sessions = detectSessions(userEvents);
164
-
165
- // Collect unique commands (non-empty, non-dash)
166
- const commandSet = new Set(
167
- userEvents.map(e => e.command).filter(c => c && c !== '-')
168
- );
169
- const keyCommands = [...commandSet].join(', ');
170
-
171
- // Gate starts (gate1.start, gate2.start, ...)
172
- const gateStartEvents = userEvents.filter(e => e.command && e.command.match(/^gate\d+\.start$/));
173
- const gateStarts = gateStartEvents.length;
174
-
175
- // Gate approved
176
- const gateApprovedEvents = userEvents.filter(e => e.command && e.command.match(/^gate\d+\.approved$/));
177
- const gateApproveds = gateApprovedEvents.length;
178
-
179
- // Tickets processed to end (reached gate4.approved or gate5.start) - real tickets only
180
- const completedTicketEvents = userEvents.filter(e =>
181
- e.command && (e.command === 'gate4.approved' || e.command === 'gate5.start') && isRealTicket(e.ticket)
182
- );
183
- const ticketsProcessedSet = new Set(completedTicketEvents.map(e => e.ticket));
184
- const ticketsProcessed = ticketsProcessedSet.size;
185
-
186
- // Tickets active in week (any gate event with real ticket)
187
- const ticketsInWeekSet = new Set(
188
- userEvents
189
- .filter(e => e.command && e.command.match(/^gate\d+\.(start|approved)$/) && isRealTicket(e.ticket))
190
- .map(e => e.ticket)
191
- );
192
- const ticketsInWeek = ticketsInWeekSet.size;
193
-
194
- const hasUseOrPrompt = userEvents.some(e =>
195
- e.command && (USE_COMMANDS.has(e.command) || e.command.startsWith('guide'))
196
- );
197
-
198
- const hasGateStartWithRealTicket = gateStartEvents.some(e => isRealTicket(e.ticket));
199
-
200
- // Gate 3-5 approved
201
- const hasGate3to5Approved = userEvents.some(e =>
202
- e.command && e.command.match(/^gate[345]\.approved$/)
203
- );
204
-
205
- const nonExploreCommands = userEvents.filter(e =>
206
- e.command && e.command !== '-' && !EXPLORE_COMMANDS.has(e.command)
207
- );
208
- const onlyExploreCommands = totalEvents > 0 && nonExploreCommands.length === 0;
209
-
210
- const stats = {
211
- totalEvents, activeDays, sessions, gateStarts, gateApproveds,
212
- ticketsProcessed, ticketsInWeek, hasUseOrPrompt, hasGateStartWithTicket: hasGateStartWithRealTicket,
213
- hasGate3to5Approved, onlyExploreCommands
214
- };
215
-
216
- const { depth, depthLabel } = score(stats);
217
- const { impact, impactLabel } = computeImpactScore(stats);
218
- const totalScore = depth + impact;
219
- const notes = buildNotes(stats);
220
-
221
- results.push({
222
- email, totalEvents, activeDays, keyCommands,
223
- gateStarts, gateApproveds, ticketsProcessed,
224
- depth, depthLabel, impact, impactLabel, totalScore, notes
225
- });
226
- }
227
-
228
- return results;
229
- }
230
-
231
- function buildExcel(results) {
232
- const wb = XLSX.utils.book_new();
233
-
234
- const headers = [
235
- '#', 'Email', 'Events', 'Active\nDays', 'Key Commands',
236
- 'Gate Start', 'Gate Approved', 'Tickets Processed',
237
- 'Depth\nScore', 'Depth Label',
238
- 'Impact\nScore', 'Impact Label',
239
- 'Total\nScore', 'Notes'
240
- ];
241
-
242
- const rows = [headers];
243
- results.forEach((r, i) => {
244
- rows.push([
245
- i + 1,
246
- r.email,
247
- r.totalEvents,
248
- r.activeDays,
249
- r.keyCommands,
250
- r.gateStarts,
251
- r.gateApproveds,
252
- r.ticketsProcessed,
253
- r.depth,
254
- r.depthLabel,
255
- r.impact,
256
- r.impactLabel,
257
- r.totalScore,
258
- r.notes
259
- ]);
260
- });
261
-
262
- const ws = XLSX.utils.aoa_to_sheet(rows);
263
-
264
- // Column widths
265
- ws['!cols'] = [
266
- { wch: 4 }, // #
267
- { wch: 32 }, // Email
268
- { wch: 8 }, // Events
269
- { wch: 8 }, // Active Days
270
- { wch: 50 }, // Key Commands
271
- { wch: 10 }, // Gate Start
272
- { wch: 13 }, // Gate Approved
273
- { wch: 16 }, // Tickets Processed
274
- { wch: 8 }, // Depth Score
275
- { wch: 28 }, // Depth Label
276
- { wch: 8 }, // Impact Score
277
- { wch: 14 }, // Impact Label
278
- { wch: 8 }, // Total Score
279
- { wch: 50 }, // Notes
280
- ];
281
-
282
- XLSX.utils.book_append_sheet(wb, ws, 'Scoring');
283
- XLSX.writeFile(wb, OUTPUT_FILE);
284
- console.log(`✅ Excel saved to: ${OUTPUT_FILE}`);
285
- }
286
-
287
- const events = parseLog();
288
- console.log(`Parsed ${events.length} events`);
289
-
290
- const results = analyzeMembers(events);
291
- buildExcel(results);
292
-
293
- // Print summary
294
- console.log('\n=== SCORING SUMMARY ===');
295
- console.log(
296
- '#'.padEnd(3),
297
- 'Email'.padEnd(34),
298
- 'Events'.padEnd(7),
299
- 'Days'.padEnd(5),
300
- 'GS'.padEnd(4),
301
- 'GA'.padEnd(4),
302
- 'TP'.padEnd(4),
303
- 'Depth'.padEnd(6),
304
- 'Impact'.padEnd(7),
305
- 'Total'
306
- );
307
- results.forEach((r, i) => {
308
- console.log(
309
- String(i + 1).padEnd(3),
310
- r.email.padEnd(34),
311
- String(r.totalEvents).padEnd(7),
312
- String(r.activeDays).padEnd(5),
313
- String(r.gateStarts).padEnd(4),
314
- String(r.gateApproveds).padEnd(4),
315
- String(r.ticketsProcessed).padEnd(4),
316
- `${r.depth}(${r.depthLabel.slice(0, 4)})`.padEnd(6),
317
- String(r.impact).padEnd(7),
318
- r.totalScore
319
- );
320
- });