@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.
- package/README.md +0 -0
- package/bin/aiflow.js +55 -2
- package/bin/ak.js +0 -0
- package/custom/mcp-presets/README.md +204 -204
- package/custom/mcp-presets/backlog.json +0 -0
- package/custom/mcp-presets/figma-desktop.json +0 -0
- package/custom/mcp-presets/figma.json +0 -0
- package/custom/mcp-presets/gitnexus.json +0 -0
- package/custom/mcp-presets/google-sheets.json +0 -0
- package/custom/mcp-presets/jira.json +0 -0
- package/custom/prompts/bug-fix.md +0 -0
- package/custom/prompts/feature.md +0 -0
- package/custom/prompts/investigation.md +0 -0
- package/custom/rules/code-style.md +0 -0
- package/custom/rules/java/code-style.md +0 -0
- package/custom/rules/java/naming.md +0 -0
- package/custom/rules/java/review-checklist.md +0 -0
- package/custom/rules/java/spring-boot-examples.md +0 -0
- package/custom/rules/javascript/code-style.md +0 -0
- package/custom/rules/javascript/naming.md +0 -0
- package/custom/rules/ml-conventions.md +88 -0
- package/custom/rules/ml-review-checklist.md +14 -0
- package/custom/rules/naming.md +0 -0
- package/custom/rules/php/code-style.md +0 -0
- package/custom/rules/php/naming.md +0 -0
- package/custom/rules/project-conventions.md +0 -0
- package/custom/rules/review-checklist.md +0 -0
- package/custom/skills/deploy-model/SKILL.md +90 -0
- package/custom/skills/design-experiment/SKILL.md +88 -0
- package/custom/skills/evaluate-model/SKILL.md +93 -0
- package/custom/skills/explore-data/SKILL.md +87 -0
- package/custom/skills/figma-to-component/SKILL.md +164 -59
- package/custom/skills/frame-ml-problem/SKILL.md +88 -0
- package/custom/skills/generate-spec/SKILL.md +0 -0
- package/custom/skills/impact-analysis/SKILL.md +0 -0
- package/custom/skills/improve-algorithm/SKILL.md +74 -0
- package/custom/skills/investigate-bug/SKILL.md +0 -0
- package/custom/skills/read-study-requirement/SKILL.md +0 -0
- package/custom/skills/report-customer/SKILL.md +0 -0
- package/custom/skills/review-plan/SKILL.md +0 -0
- package/custom/skills/train-model/SKILL.md +78 -0
- package/custom/templates/laravel.md +0 -0
- package/custom/templates/nestjs.md +0 -0
- package/custom/templates/nextjs.md +0 -0
- package/custom/templates/nodejs-express.md +0 -0
- package/custom/templates/php-plain.md +0 -0
- package/custom/templates/php.md +0 -0
- package/custom/templates/python-django.md +0 -0
- package/custom/templates/python-fastapi.md +0 -0
- package/custom/templates/python-ml.md +273 -0
- package/custom/templates/python.md +0 -0
- package/custom/templates/reactjs.md +0 -0
- package/custom/templates/shared/gate-workflow.md +0 -0
- package/custom/templates/shared/ml-gate-workflow.md +103 -0
- package/custom/templates/spring-boot.md +0 -0
- package/custom/templates/tools/claude.md +0 -0
- package/custom/templates/tools/copilot.md +0 -0
- package/custom/templates/tools/cursor.md +0 -0
- package/custom/templates/tools/gemini.md +0 -0
- package/custom/templates/tools/generic.md +0 -0
- package/custom/templates/vue-nuxt.md +0 -0
- package/docs/common/AIFLOW.md +512 -512
- package/docs/common/CHANGELOG.md +16 -0
- package/docs/common/QUICK_START.md +0 -0
- package/docs/common/ai-integration.md +0 -0
- package/docs/common/cli-reference.md +0 -0
- package/docs/common/configuration.md +0 -0
- package/docs/common/getting-started.md +0 -0
- package/docs/common/troubleshooting.md +0 -0
- package/docs/common/workflows/bug-fix.md +0 -0
- package/docs/common/workflows/feature.md +0 -0
- package/docs/common/workflows/figma.md +0 -0
- package/docs/common/workflows/impact-analysis.md +0 -0
- package/docs/common/workflows/investigation.md +0 -0
- package/docs/common/workflows/refactor.md +0 -0
- package/docs/project/ARCHITECTURE.md +0 -0
- package/index.js +0 -0
- package/package.json +2 -2
- package/scripts/checkpoint.js +0 -0
- package/scripts/config.js +0 -0
- package/scripts/context.js +0 -0
- package/scripts/create-score-excel.js +0 -0
- package/scripts/detect.js +239 -239
- package/scripts/doctor.js +192 -218
- package/scripts/gitnexus-worker.js +0 -0
- package/scripts/guide.js +0 -0
- package/scripts/hooks/block-git-write.js +0 -0
- package/scripts/hooks/session-start.js +0 -0
- package/scripts/hooks/session-stop.js +0 -0
- package/scripts/init.js +1112 -1009
- package/scripts/link-resolver.js +0 -0
- package/scripts/memory.js +0 -0
- package/scripts/prompt.js +538 -538
- package/scripts/remove.js +0 -0
- package/scripts/task.js +546 -546
- package/scripts/telemetry/cli.js +0 -0
- package/scripts/telemetry/config.js +0 -0
- package/scripts/telemetry/crypto.js +0 -0
- package/scripts/telemetry/flush.js +0 -0
- package/scripts/telemetry/record.js +0 -0
- package/scripts/update.js +10 -7
- package/scripts/use.js +33 -12
- package/scripts/validate.js +0 -0
- package/upstream/.claude-plugin/marketplace.json +0 -0
- package/upstream/.claude-plugin/plugin.json +0 -0
- package/upstream/.codex/INSTALL.md +0 -0
- package/upstream/.cursor-plugin/plugin.json +0 -0
- package/upstream/.gitattributes +0 -0
- package/upstream/.github/FUNDING.yml +0 -0
- package/upstream/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- package/upstream/.github/ISSUE_TEMPLATE/config.yml +0 -0
- package/upstream/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- package/upstream/.github/ISSUE_TEMPLATE/platform_support.md +0 -0
- package/upstream/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- package/upstream/.opencode/INSTALL.md +0 -0
- package/upstream/.opencode/plugins/superpowers.js +0 -0
- package/upstream/.version-bump.json +0 -0
- package/upstream/AGENTS.md +0 -0
- package/upstream/CHANGELOG.md +0 -0
- package/upstream/CLAUDE.md +0 -0
- package/upstream/CODE_OF_CONDUCT.md +0 -0
- package/upstream/GEMINI.md +0 -0
- package/upstream/LICENSE +0 -0
- package/upstream/README.md +0 -0
- package/upstream/RELEASE-NOTES.md +0 -0
- package/upstream/agents/code-reviewer.md +0 -0
- package/upstream/commands/brainstorm.md +0 -0
- package/upstream/commands/execute-plan.md +0 -0
- package/upstream/commands/write-plan.md +0 -0
- package/upstream/docs/README.codex.md +0 -0
- package/upstream/docs/README.opencode.md +0 -0
- package/upstream/docs/plans/2025-11-22-opencode-support-design.md +0 -0
- package/upstream/docs/plans/2025-11-22-opencode-support-implementation.md +0 -0
- package/upstream/docs/plans/2025-11-28-skills-improvements-from-user-feedback.md +0 -0
- package/upstream/docs/plans/2026-01-17-visual-brainstorming.md +0 -0
- package/upstream/docs/superpowers/plans/2026-01-22-document-review-system.md +0 -0
- package/upstream/docs/superpowers/plans/2026-02-19-visual-brainstorming-refactor.md +0 -0
- package/upstream/docs/superpowers/plans/2026-03-11-zero-dep-brainstorm-server.md +0 -0
- package/upstream/docs/superpowers/plans/2026-03-23-codex-app-compatibility.md +0 -0
- package/upstream/docs/superpowers/specs/2026-01-22-document-review-system-design.md +0 -0
- package/upstream/docs/superpowers/specs/2026-02-19-visual-brainstorming-refactor-design.md +0 -0
- package/upstream/docs/superpowers/specs/2026-03-11-zero-dep-brainstorm-server-design.md +0 -0
- package/upstream/docs/superpowers/specs/2026-03-23-codex-app-compatibility-design.md +0 -0
- package/upstream/docs/testing.md +0 -0
- package/upstream/docs/windows/polyglot-hooks.md +0 -0
- package/upstream/gemini-extension.json +0 -0
- package/upstream/hooks/hooks-cursor.json +0 -0
- package/upstream/hooks/hooks.json +0 -0
- package/upstream/hooks/run-hook.cmd +0 -0
- package/upstream/hooks/session-start +0 -0
- package/upstream/package.json +0 -0
- package/upstream/scripts/bump-version.sh +0 -0
- package/upstream/skills/brainstorming/SKILL.md +0 -0
- package/upstream/skills/brainstorming/scripts/frame-template.html +0 -0
- package/upstream/skills/brainstorming/scripts/helper.js +0 -0
- package/upstream/skills/brainstorming/scripts/server.cjs +0 -0
- package/upstream/skills/brainstorming/scripts/start-server.sh +0 -0
- package/upstream/skills/brainstorming/scripts/stop-server.sh +0 -0
- package/upstream/skills/brainstorming/spec-document-reviewer-prompt.md +0 -0
- package/upstream/skills/brainstorming/visual-companion.md +0 -0
- package/upstream/skills/dispatching-parallel-agents/SKILL.md +0 -0
- package/upstream/skills/executing-plans/SKILL.md +0 -0
- package/upstream/skills/finishing-a-development-branch/SKILL.md +0 -0
- package/upstream/skills/receiving-code-review/SKILL.md +0 -0
- package/upstream/skills/requesting-code-review/SKILL.md +0 -0
- package/upstream/skills/requesting-code-review/code-reviewer.md +0 -0
- package/upstream/skills/subagent-driven-development/SKILL.md +0 -0
- package/upstream/skills/subagent-driven-development/code-quality-reviewer-prompt.md +0 -0
- package/upstream/skills/subagent-driven-development/implementer-prompt.md +0 -0
- package/upstream/skills/subagent-driven-development/spec-reviewer-prompt.md +0 -0
- package/upstream/skills/systematic-debugging/CREATION-LOG.md +0 -0
- package/upstream/skills/systematic-debugging/SKILL.md +0 -0
- package/upstream/skills/systematic-debugging/condition-based-waiting-example.ts +0 -0
- package/upstream/skills/systematic-debugging/condition-based-waiting.md +0 -0
- package/upstream/skills/systematic-debugging/defense-in-depth.md +0 -0
- package/upstream/skills/systematic-debugging/find-polluter.sh +0 -0
- package/upstream/skills/systematic-debugging/root-cause-tracing.md +0 -0
- package/upstream/skills/systematic-debugging/test-academic.md +0 -0
- package/upstream/skills/systematic-debugging/test-pressure-1.md +0 -0
- package/upstream/skills/systematic-debugging/test-pressure-2.md +0 -0
- package/upstream/skills/systematic-debugging/test-pressure-3.md +0 -0
- package/upstream/skills/tdd-lean/SKILL.md +0 -0
- package/upstream/skills/test-driven-development/SKILL.md +0 -0
- package/upstream/skills/test-driven-development/testing-anti-patterns.md +0 -0
- package/upstream/skills/using-git-worktrees/SKILL.md +0 -0
- package/upstream/skills/using-superpowers/SKILL.md +0 -0
- package/upstream/skills/using-superpowers/references/codex-tools.md +0 -0
- package/upstream/skills/using-superpowers/references/copilot-tools.md +0 -0
- package/upstream/skills/using-superpowers/references/gemini-tools.md +0 -0
- package/upstream/skills/verification-before-completion/SKILL.md +0 -0
- package/upstream/skills/writing-plans/SKILL.md +0 -0
- package/upstream/skills/writing-plans/plan-document-reviewer-prompt.md +0 -0
- package/upstream/skills/writing-skills/SKILL.md +0 -0
- package/upstream/skills/writing-skills/anthropic-best-practices.md +0 -0
- package/upstream/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -0
- package/upstream/skills/writing-skills/graphviz-conventions.dot +0 -0
- package/upstream/skills/writing-skills/persuasion-principles.md +0 -0
- package/upstream/skills/writing-skills/render-graphs.js +0 -0
- package/upstream/skills/writing-skills/testing-skills-with-subagents.md +0 -0
- package/upstream/tests/brainstorm-server/package-lock.json +0 -0
- package/upstream/tests/brainstorm-server/package.json +0 -0
- package/upstream/tests/brainstorm-server/server.test.js +0 -0
- package/upstream/tests/brainstorm-server/windows-lifecycle.test.sh +0 -0
- package/upstream/tests/brainstorm-server/ws-protocol.test.js +0 -0
- package/upstream/tests/claude-code/README.md +0 -0
- package/upstream/tests/claude-code/analyze-token-usage.py +0 -0
- package/upstream/tests/claude-code/run-skill-tests.sh +0 -0
- package/upstream/tests/claude-code/test-document-review-system.sh +0 -0
- package/upstream/tests/claude-code/test-helpers.sh +0 -0
- package/upstream/tests/claude-code/test-subagent-driven-development-integration.sh +0 -0
- package/upstream/tests/claude-code/test-subagent-driven-development.sh +0 -0
- package/upstream/tests/explicit-skill-requests/prompts/action-oriented.txt +0 -0
- package/upstream/tests/explicit-skill-requests/prompts/after-planning-flow.txt +0 -0
- package/upstream/tests/explicit-skill-requests/prompts/claude-suggested-it.txt +0 -0
- package/upstream/tests/explicit-skill-requests/prompts/i-know-what-sdd-means.txt +0 -0
- package/upstream/tests/explicit-skill-requests/prompts/mid-conversation-execute-plan.txt +0 -0
- package/upstream/tests/explicit-skill-requests/prompts/please-use-brainstorming.txt +0 -0
- package/upstream/tests/explicit-skill-requests/prompts/skip-formalities.txt +0 -0
- package/upstream/tests/explicit-skill-requests/prompts/subagent-driven-development-please.txt +0 -0
- package/upstream/tests/explicit-skill-requests/prompts/use-systematic-debugging.txt +0 -0
- package/upstream/tests/explicit-skill-requests/run-all.sh +0 -0
- package/upstream/tests/explicit-skill-requests/run-claude-describes-sdd.sh +0 -0
- package/upstream/tests/explicit-skill-requests/run-extended-multiturn-test.sh +0 -0
- package/upstream/tests/explicit-skill-requests/run-haiku-test.sh +0 -0
- package/upstream/tests/explicit-skill-requests/run-multiturn-test.sh +0 -0
- package/upstream/tests/explicit-skill-requests/run-test.sh +0 -0
- package/upstream/tests/opencode/run-tests.sh +0 -0
- package/upstream/tests/opencode/setup.sh +0 -0
- package/upstream/tests/opencode/test-plugin-loading.sh +0 -0
- package/upstream/tests/opencode/test-priority.sh +0 -0
- package/upstream/tests/opencode/test-tools.sh +0 -0
- package/upstream/tests/skill-triggering/prompts/dispatching-parallel-agents.txt +0 -0
- package/upstream/tests/skill-triggering/prompts/executing-plans.txt +0 -0
- package/upstream/tests/skill-triggering/prompts/requesting-code-review.txt +0 -0
- package/upstream/tests/skill-triggering/prompts/systematic-debugging.txt +0 -0
- package/upstream/tests/skill-triggering/prompts/test-driven-development.txt +0 -0
- package/upstream/tests/skill-triggering/prompts/writing-plans.txt +0 -0
- package/upstream/tests/skill-triggering/run-all.sh +0 -0
- package/upstream/tests/skill-triggering/run-test.sh +0 -0
- package/upstream/tests/subagent-driven-dev/go-fractals/design.md +0 -0
- package/upstream/tests/subagent-driven-dev/go-fractals/plan.md +0 -0
- package/upstream/tests/subagent-driven-dev/go-fractals/scaffold.sh +0 -0
- package/upstream/tests/subagent-driven-dev/run-test.sh +0 -0
- package/upstream/tests/subagent-driven-dev/svelte-todo/design.md +0 -0
- package/upstream/tests/subagent-driven-dev/svelte-todo/plan.md +0 -0
- package/upstream/tests/subagent-driven-dev/svelte-todo/scaffold.sh +0 -0
- package/scripts/score_members.js +0 -320
package/scripts/score_members.js
DELETED
|
@@ -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
|
-
});
|