level-up-mcp-server-cn 0.4.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 (137) hide show
  1. package/.claude/projects/c--Users-klexi-OneDrive-Desktop-Levelup-level-up-mcp-server/memory/project_testing_service.md +11 -0
  2. package/.claude/settings.local.json +10 -0
  3. package/.env.example +19 -0
  4. package/CLAUDE.md +222 -0
  5. package/CODE_REVIEW.md +282 -0
  6. package/LICENSE +64 -0
  7. package/README.md +198 -0
  8. package/dist/constants.d.ts +33 -0
  9. package/dist/constants.js +78 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/data/quest-seeds.d.ts +18 -0
  12. package/dist/data/quest-seeds.js +380 -0
  13. package/dist/data/quest-seeds.js.map +1 -0
  14. package/dist/index.d.ts +3 -0
  15. package/dist/index.js +260 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/schemas/common.d.ts +33 -0
  18. package/dist/schemas/common.js +96 -0
  19. package/dist/schemas/common.js.map +1 -0
  20. package/dist/services/dispatcher.d.ts +27 -0
  21. package/dist/services/dispatcher.js +47 -0
  22. package/dist/services/dispatcher.js.map +1 -0
  23. package/dist/services/errors.d.ts +56 -0
  24. package/dist/services/errors.js +99 -0
  25. package/dist/services/errors.js.map +1 -0
  26. package/dist/services/format.d.ts +74 -0
  27. package/dist/services/format.js +144 -0
  28. package/dist/services/format.js.map +1 -0
  29. package/dist/services/ownership.d.ts +19 -0
  30. package/dist/services/ownership.js +79 -0
  31. package/dist/services/ownership.js.map +1 -0
  32. package/dist/services/quality-gate.d.ts +45 -0
  33. package/dist/services/quality-gate.js +131 -0
  34. package/dist/services/quality-gate.js.map +1 -0
  35. package/dist/services/rate-limit.d.ts +12 -0
  36. package/dist/services/rate-limit.js +49 -0
  37. package/dist/services/rate-limit.js.map +1 -0
  38. package/dist/services/register.d.ts +49 -0
  39. package/dist/services/register.js +63 -0
  40. package/dist/services/register.js.map +1 -0
  41. package/dist/services/supabase.d.ts +10 -0
  42. package/dist/services/supabase.js +79 -0
  43. package/dist/services/supabase.js.map +1 -0
  44. package/dist/tools/achievements.d.ts +6 -0
  45. package/dist/tools/achievements.js +242 -0
  46. package/dist/tools/achievements.js.map +1 -0
  47. package/dist/tools/admin.d.ts +16 -0
  48. package/dist/tools/admin.js +328 -0
  49. package/dist/tools/admin.js.map +1 -0
  50. package/dist/tools/agents.d.ts +3 -0
  51. package/dist/tools/agents.js +400 -0
  52. package/dist/tools/agents.js.map +1 -0
  53. package/dist/tools/bootstrap.d.ts +17 -0
  54. package/dist/tools/bootstrap.js +565 -0
  55. package/dist/tools/bootstrap.js.map +1 -0
  56. package/dist/tools/dispatchers/admin.d.ts +3 -0
  57. package/dist/tools/dispatchers/admin.js +50 -0
  58. package/dist/tools/dispatchers/admin.js.map +1 -0
  59. package/dist/tools/dispatchers/eval.d.ts +3 -0
  60. package/dist/tools/dispatchers/eval.js +40 -0
  61. package/dist/tools/dispatchers/eval.js.map +1 -0
  62. package/dist/tools/dispatchers/quests.d.ts +3 -0
  63. package/dist/tools/dispatchers/quests.js +60 -0
  64. package/dist/tools/dispatchers/quests.js.map +1 -0
  65. package/dist/tools/dispatchers/session.d.ts +3 -0
  66. package/dist/tools/dispatchers/session.js +38 -0
  67. package/dist/tools/dispatchers/session.js.map +1 -0
  68. package/dist/tools/dispatchers/skills.d.ts +3 -0
  69. package/dist/tools/dispatchers/skills.js +49 -0
  70. package/dist/tools/dispatchers/skills.js.map +1 -0
  71. package/dist/tools/dispatchers/tasks.d.ts +3 -0
  72. package/dist/tools/dispatchers/tasks.js +53 -0
  73. package/dist/tools/dispatchers/tasks.js.map +1 -0
  74. package/dist/tools/dispatchers/users.d.ts +3 -0
  75. package/dist/tools/dispatchers/users.js +65 -0
  76. package/dist/tools/dispatchers/users.js.map +1 -0
  77. package/dist/tools/dispatchers/xp.d.ts +3 -0
  78. package/dist/tools/dispatchers/xp.js +51 -0
  79. package/dist/tools/dispatchers/xp.js.map +1 -0
  80. package/dist/tools/growth-plan.d.ts +5 -0
  81. package/dist/tools/growth-plan.js +791 -0
  82. package/dist/tools/growth-plan.js.map +1 -0
  83. package/dist/tools/leaderboards.d.ts +10 -0
  84. package/dist/tools/leaderboards.js +279 -0
  85. package/dist/tools/leaderboards.js.map +1 -0
  86. package/dist/tools/leveling.d.ts +24 -0
  87. package/dist/tools/leveling.js +356 -0
  88. package/dist/tools/leveling.js.map +1 -0
  89. package/dist/tools/metrics.d.ts +3 -0
  90. package/dist/tools/metrics.js +247 -0
  91. package/dist/tools/metrics.js.map +1 -0
  92. package/dist/tools/quests.d.ts +5 -0
  93. package/dist/tools/quests.js +586 -0
  94. package/dist/tools/quests.js.map +1 -0
  95. package/dist/tools/ratings.d.ts +11 -0
  96. package/dist/tools/ratings.js +564 -0
  97. package/dist/tools/ratings.js.map +1 -0
  98. package/dist/tools/skills.d.ts +66 -0
  99. package/dist/tools/skills.js +1112 -0
  100. package/dist/tools/skills.js.map +1 -0
  101. package/dist/tools/system.d.ts +31 -0
  102. package/dist/tools/system.js +605 -0
  103. package/dist/tools/system.js.map +1 -0
  104. package/dist/tools/tasks.d.ts +73 -0
  105. package/dist/tools/tasks.js +1572 -0
  106. package/dist/tools/tasks.js.map +1 -0
  107. package/dist/tools/users.d.ts +97 -0
  108. package/dist/tools/users.js +1306 -0
  109. package/dist/tools/users.js.map +1 -0
  110. package/dist/tools/xp.d.ts +38 -0
  111. package/dist/tools/xp.js +670 -0
  112. package/dist/tools/xp.js.map +1 -0
  113. package/dist/types.d.ts +178 -0
  114. package/dist/types.js +12 -0
  115. package/dist/types.js.map +1 -0
  116. package/docs/recommended-skillsets.md +622 -0
  117. package/docs/skills-and-abilities-review.md +672 -0
  118. package/docs/v0.3-roadmap.md +191 -0
  119. package/package.json +35 -0
  120. package/sql/agent_pending_installs.sql +28 -0
  121. package/sql/award_class_xp.sql +81 -0
  122. package/supabase/.temp/cli-latest +1 -0
  123. package/supabase/.temp/gotrue-version +1 -0
  124. package/supabase/.temp/pooler-url +1 -0
  125. package/supabase/.temp/postgres-version +1 -0
  126. package/supabase/.temp/project-ref +1 -0
  127. package/supabase/.temp/rest-version +1 -0
  128. package/supabase/.temp/storage-migration +1 -0
  129. package/supabase/.temp/storage-version +1 -0
  130. package/supabase/migrations/20260314000000_anon_rls_policies.sql +311 -0
  131. package/supabase/migrations/20260314000001_ownership_rpcs.sql +382 -0
  132. package/supabase/migrations/20260314000002_evidence_and_growth_plan.sql +97 -0
  133. package/supabase/migrations/20260317000000_seed_quests.sql +62 -0
  134. package/supabase/migrations/20260317000001_star_cooldown_and_fixes.sql +16 -0
  135. package/supabase/migrations/20260318000000_restore_rank_names.sql +25 -0
  136. package/supabase/migrations/20260320000000_chinese_rank_names.sql +24 -0
  137. package/vitest.config.ts +11 -0
@@ -0,0 +1,191 @@
1
+ # v0.3 Roadmap
2
+
3
+ ## Release Theme: Bootstrap, Quests & UX
4
+
5
+ Target: After v0.2.x feedback incorporated
6
+
7
+ ---
8
+
9
+ ## v0.2.x Review Summary (2026-03-17)
10
+
11
+ Two reviews received — Claude (technical) and OpenClaw/Maine (user testing on Ken's account).
12
+
13
+ **Key findings:**
14
+ - User XP too low (2-6 XP per task due to 60/40 agent split) — users feel unrewarded
15
+ - Class tracks (Trainer/Orchestrator/Partner) completely unused — 0 XP across all users
16
+ - Output type rarely set (90% null), evidence rarely attached
17
+ - Orphaned tasks — 2 tasks stuck in_progress with no recovery mechanism
18
+ - No onboarding guidance — users don't know what to do next
19
+ - 15+ tool calls needed for full onboarding — too much friction
20
+ - Rating: 6/10 — good foundation, needs better UX
21
+
22
+ ---
23
+
24
+ ## v0.3 Build Order (by impact × feasibility)
25
+
26
+ ### Phase 1: CRITICAL — Unblock adoption
27
+
28
+ #### 1. Session Bootstrap (`levelup_bootstrap`)
29
+ Single tool call returns complete session state for stateless agents.
30
+
31
+ ```
32
+ levelup_bootstrap(user_id?, agent_id?, platform?)
33
+ → Returns: user profile, agent profile, orphaned tasks, recent tasks,
34
+ active quests, coaching nudge, recovery actions
35
+ ```
36
+
37
+ **Solves:** 3 sequential tool calls → 1. Orphaned task recovery. Works across fresh chats.
38
+
39
+ #### 2. Setup Wizard (`levelup_setup_wizard`)
40
+ One-call onboarding that auto-maps installed MCPs to skills.
41
+
42
+ ```
43
+ levelup_setup_wizard(agent_id, installed_mcps?: string[], auto_register_skills?: true)
44
+ → Returns: skills_registered, skills_already_had, suggested_mcps, suggested_skills
45
+ ```
46
+
47
+ **Solves:** 15+ tool calls → 1 for skill registration. MCP-to-skill lookup table built in.
48
+
49
+ #### 3. Quest / Challenge System
50
+ Directed learning through onboarding, skill, and weekly quests.
51
+
52
+ **Onboarding quests:** "Register profile" → "Add 3 skills" → "Complete first task" → "Install 3 MCPs" → "Quality score > 3.5"
53
+ **Skill quests:** "Use GitHub MCP to create a PR" → "Set up automated workflow with 2+ MCPs"
54
+ **Weekly challenges:** "Complete 5 tasks" → "Increase skill proficiency" → "5-day streak"
55
+
56
+ Tools: `levelup_get_active_quests`, `levelup_start_quest`, `levelup_check_quest_progress`
57
+ Note: 12 quest tools already exist in quests.ts but are not active.
58
+
59
+ ### Phase 2: HIGH — Drive engagement
60
+
61
+ #### 4. Fix Growth Plan Quality
62
+ - Deduplicate MCP install suggestions (group skills-per-MCP)
63
+ - Mix action types — max 3 installs before suggesting a task
64
+ - Filter by already-installed MCPs
65
+ - Differentiate priorities (critical/recommended/optional)
66
+ - Respect 3/day install cooldown — spread across days
67
+
68
+ #### 5. Contextual Coaching (`levelup_get_coaching_suggestions`)
69
+ Analyzes task history, tool usage, automation ratio, skill gaps, unused MCPs.
70
+
71
+ ```
72
+ levelup_get_coaching_suggestions(user_id, agent_id?, focus?)
73
+ → Returns: suggestions with evidence, impact, pre-filled action params
74
+ ```
75
+
76
+ Example: "You've done 8 email drafts manually. Gmail MCP is installed but unused in tasks."
77
+
78
+ #### 6. Workflow Templates (`levelup_browse_workflows`)
79
+ Multi-step recipes using multiple MCPs. Shows which MCPs user has vs needs.
80
+
81
+ Seed workflows: Bug fix pipeline, Feature sprint, Blog post pipeline, Meeting automation, etc.
82
+
83
+ ### Phase 3: MEDIUM — Polish & consolidate
84
+
85
+ #### 7. Consolidated Dashboard (`levelup_dashboard`)
86
+ One tool replaces 6+: user profile + progress + achievements + recap + agents + quests.
87
+
88
+ #### 8. Idempotent Task Tracking (`levelup_resume_or_start`)
89
+ Checks for in-progress task with similar title before creating new one. Auto-fail tasks orphaned 24h+.
90
+
91
+ #### 9. Progressive Tool Disclosure
92
+ Level 1-3: ~15 tools (basics). Level 4-7: +12 tools (intermediate). Level 8+: all tools (admin/power).
93
+
94
+ #### 10. Achievement System Seeding
95
+ Seed 30-50 achievements: First Steps, Century (100 XP), Rank Up, On a Roll (3-day streak), Craftsman (4.5+ quality), Night Owl, Speed Demon, Polyglot.
96
+
97
+ ### Phase 4: LOW — Future infrastructure
98
+
99
+ #### 11. Webhook / Push Notifications
100
+ Platforms subscribe to events: level_up, achievement_earned, quest_available, weekly_recap.
101
+
102
+ #### 12. Testing Service (separate repo: level-up-test-service)
103
+ See testing service architecture below.
104
+
105
+ ---
106
+
107
+ ## User XP Balance Fix
108
+
109
+ **Problem:** Users get 40% of XP in user_with_agent tasks (60% to agent). Users earn 2-6 XP per task, feels unrewarding.
110
+
111
+ **Options:**
112
+ - A) Adjust default split to 50/50
113
+ - B) Add user-only XP bonuses (evidence bonus, streak bonus, quest completion)
114
+ - C) Both — rebalance split AND add user bonuses
115
+ - D) Keep split but add class track XP (Trainer/Orchestrator/Partner earn separately)
116
+
117
+ **Decision needed before v0.3.**
118
+
119
+ ---
120
+
121
+ ## Feature: Testing Service (deferred to v0.4+)
122
+
123
+ ### Architecture
124
+
125
+ ```
126
+ Agent <-> Level-Up MCP <-> Testing Service (HTTP API)
127
+ |
128
+ Supabase DB
129
+ ```
130
+
131
+ ### Test Types
132
+
133
+ | Type | Trigger | Purpose |
134
+ |------|---------|---------|
135
+ | Skill verification | Agent claims skill proficiency | Prove agent can actually use a skill |
136
+ | Rank advancement | Agent at level 10 (D) -> 11 (C) | Gate or bonus for rank-up milestones |
137
+ | Periodic re-test | Configurable interval | Prevent skill decay / stale claims |
138
+
139
+ ### Open Design Questions
140
+
141
+ 1. Gated vs optional — Must agents test to rank up, or just bonus XP?
142
+ 2. Evaluation method — LLM judge vs rubric checklist vs hybrid
143
+ 3. Challenge source — Fixed bank vs LLM-generated per attempt
144
+ 4. Cheating prevention — Time limits, unique challenges, cooldown, max attempts
145
+ 5. Deployment — Separate Railway service vs serverless
146
+
147
+ ---
148
+
149
+ ## Other Ideas (backlog)
150
+
151
+ - [ ] MCP discovery tool — search Docker MCP registry / awesome-mcp-servers
152
+ - [ ] Allow agents to install any MCP and map to closest ability category
153
+ - [ ] Frontend experiment using Google Flow
154
+ - [ ] Testing module experiment using Mirro (simulated AI reviewers)
155
+ - [ ] `npx level-up-mcp-server --setup` auto-config command
156
+ - [ ] Blockchain integration — on-chain XP/achievement verification, portable agent credentials
157
+ - [ ] Class track activation (Trainer/Orchestrator/Partner)
158
+ - [ ] User preference snippet generator for persistent identity
159
+ - [ ] MCP-level session identity (requires MCP spec changes)
160
+ - [ ] Auto-prompt users after tasks for output_type and evidence
161
+
162
+ ---
163
+
164
+ ## Completed (v0.2.x)
165
+
166
+ - [x] Agents not earning XP — fixed agent_id flow (v0.2.2)
167
+ - [x] Stars displayed in rank responses (v0.2.2)
168
+ - [x] register_user/register_agent → RPC with fallback (v0.2.4)
169
+ - [x] Achievement auto-triggers (v0.2.2)
170
+ - [x] Skill discount passed to level-up RPC (v0.2.2)
171
+ - [x] Tool installation XP +20 (v0.2.2)
172
+ - [x] Whoami auto-detection (v0.2.5)
173
+ - [x] Growth plan level-gating (v0.2.5)
174
+ - [x] Evidence requirements per tier (v0.2.4)
175
+ - [x] Browse skillsets — 18 categories (v0.2.4)
176
+ - [x] check_level_up RPC fix (v0.2.6)
177
+ - [x] Evidence sanitization pipeline (v0.2.1)
178
+ - [x] Tier override + auto-downgrade (v0.2.1)
179
+ - [x] Anti-gaming: quality gate, rate limiting, duration floors (v0.2.0)
180
+
181
+ ---
182
+
183
+ ## Versioning Plan
184
+
185
+ | Version | Scope |
186
+ |---------|-------|
187
+ | 0.2.0-0.2.6 | Foundation — anti-gaming, evidence, growth plans, whoami, skillsets |
188
+ | 0.3.0 | Bootstrap + setup wizard + quest system + growth plan fixes |
189
+ | 0.3.x | Coaching, workflows, dashboard consolidation, achievements |
190
+ | 0.4.0 | Testing service + progressive disclosure + webhooks |
191
+ | 1.0.0 | Blockchain integration + stable API |
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "level-up-mcp-server-cn",
3
+ "version": "0.4.0",
4
+ "description": "Level-Up 游戏化MCP服务器 — 为人类和AI智能体追踪经验值、等级、技能和任务",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "level-up-mcp-server-cn": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/index.js",
13
+ "dev": "tsc --watch",
14
+ "start:http": "TRANSPORT=http node dist/index.js",
15
+ "pretest": "rm -rf node_modules/.vite node_modules/.experimental-vitest-cache",
16
+ "test": "vitest run --pool forks",
17
+ "test:watch": "vitest"
18
+ },
19
+ "dependencies": {
20
+ "@modelcontextprotocol/sdk": "^1.27.1",
21
+ "@supabase/supabase-js": "^2.49.0",
22
+ "express": "^5.0.1",
23
+ "zod": "^3.25.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/express": "^5.0.0",
27
+ "@types/node": "^22.0.0",
28
+ "typescript": "^5.7.0",
29
+ "vitest": "^4.1.0"
30
+ },
31
+ "engines": {
32
+ "node": ">=18.0.0"
33
+ },
34
+ "license": "BUSL-1.1"
35
+ }
@@ -0,0 +1,28 @@
1
+ -- agent_pending_installs: tracks frontend install requests before agent confirmation
2
+ -- Flow: frontend INSERT (pending) → agent reads → agent installs → agent UPDATE (confirmed)
3
+
4
+ CREATE TABLE IF NOT EXISTS agent_pending_installs (
5
+ id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
6
+ agent_id uuid NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
7
+ item_type text NOT NULL CHECK (item_type IN ('mcp', 'skill')),
8
+ item_name text NOT NULL,
9
+ status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'confirmed', 'cancelled')),
10
+ created_at timestamptz DEFAULT now(),
11
+ confirmed_at timestamptz
12
+ );
13
+
14
+ -- Index for fast lookup by agent
15
+ CREATE INDEX IF NOT EXISTS idx_pending_installs_agent
16
+ ON agent_pending_installs(agent_id, status);
17
+
18
+ -- RLS: allow anon read/write for now (frontend uses anon key)
19
+ ALTER TABLE agent_pending_installs ENABLE ROW LEVEL SECURITY;
20
+
21
+ CREATE POLICY "anon_read_pending_installs" ON agent_pending_installs
22
+ FOR SELECT TO anon USING (true);
23
+
24
+ CREATE POLICY "anon_insert_pending_installs" ON agent_pending_installs
25
+ FOR INSERT TO anon WITH CHECK (true);
26
+
27
+ CREATE POLICY "anon_update_pending_installs" ON agent_pending_installs
28
+ FOR UPDATE TO anon USING (true) WITH CHECK (true);
@@ -0,0 +1,81 @@
1
+ -- ============================================================
2
+ -- RPC: award_class_xp
3
+ -- Awards class XP to a user's class track (trainer/partner/orchestrator).
4
+ -- Updates user_class_progress and records the XP in xp_ledger
5
+ -- with the class name as xp_type.
6
+ -- ============================================================
7
+ CREATE OR REPLACE FUNCTION award_class_xp(
8
+ p_user_id UUID,
9
+ p_class_name TEXT,
10
+ p_amount INTEGER,
11
+ p_source_type TEXT,
12
+ p_description TEXT,
13
+ p_source_id UUID DEFAULT NULL
14
+ ) RETURNS JSONB AS $$
15
+ DECLARE
16
+ v_class_row RECORD;
17
+ v_running_total BIGINT;
18
+ BEGIN
19
+ -- Validate user exists
20
+ IF NOT EXISTS (SELECT 1 FROM users WHERE id = p_user_id) THEN
21
+ RETURN jsonb_build_object('success', false, 'error', 'User not found');
22
+ END IF;
23
+
24
+ -- Validate class name
25
+ IF p_class_name NOT IN ('trainer', 'partner', 'orchestrator') THEN
26
+ RETURN jsonb_build_object('success', false, 'error', 'Invalid class_name');
27
+ END IF;
28
+
29
+ -- Validate amount is positive
30
+ IF p_amount <= 0 THEN
31
+ RETURN jsonb_build_object('success', false, 'error', 'Amount must be positive');
32
+ END IF;
33
+
34
+ -- Get the class progress row
35
+ SELECT id, class_xp INTO v_class_row
36
+ FROM user_class_progress
37
+ WHERE user_id = p_user_id AND class_name = p_class_name;
38
+
39
+ IF NOT FOUND THEN
40
+ RETURN jsonb_build_object('success', false, 'error', 'Class progress row not found');
41
+ END IF;
42
+
43
+ -- Update class XP
44
+ UPDATE user_class_progress
45
+ SET class_xp = v_class_row.class_xp + p_amount
46
+ WHERE id = v_class_row.id;
47
+
48
+ -- Get running total for xp_ledger
49
+ SELECT COALESCE(running_total, 0) INTO v_running_total
50
+ FROM xp_ledger
51
+ WHERE entity_type = 'user' AND entity_id = p_user_id
52
+ ORDER BY created_at DESC
53
+ LIMIT 1;
54
+
55
+ IF NOT FOUND THEN
56
+ v_running_total := 0;
57
+ END IF;
58
+
59
+ -- Note: class XP is tracked separately; running_total here is for audit trail only
60
+ -- and does NOT get added to main_xp (class XP is a parallel track)
61
+
62
+ -- Insert ledger entry with class name as xp_type
63
+ INSERT INTO xp_ledger (
64
+ entity_type, entity_id, xp_type, amount,
65
+ source_type, source_id, description, running_total
66
+ ) VALUES (
67
+ 'user', p_user_id, p_class_name, p_amount,
68
+ p_source_type, p_source_id, p_description, v_running_total
69
+ );
70
+
71
+ RETURN jsonb_build_object(
72
+ 'success', true,
73
+ 'class_name', p_class_name,
74
+ 'new_class_xp', v_class_row.class_xp + p_amount,
75
+ 'amount', p_amount
76
+ );
77
+ END;
78
+ $$ LANGUAGE plpgsql SECURITY DEFINER;
79
+
80
+ -- Grant access to anon role
81
+ GRANT EXECUTE ON FUNCTION award_class_xp(UUID, TEXT, INTEGER, TEXT, TEXT, UUID) TO anon;
@@ -0,0 +1 @@
1
+ v2.78.1
@@ -0,0 +1 @@
1
+ v2.187.0
@@ -0,0 +1 @@
1
+ postgresql://postgres.pxanrmpwptinbtwigqdt@aws-1-ap-southeast-1.pooler.supabase.com:5432/postgres
@@ -0,0 +1 @@
1
+ 17.6.1.084
@@ -0,0 +1 @@
1
+ pxanrmpwptinbtwigqdt
@@ -0,0 +1 @@
1
+ v14.4
@@ -0,0 +1 @@
1
+ fix-optimized-search-function
@@ -0,0 +1 @@
1
+ v1.37.7
@@ -0,0 +1,311 @@
1
+ -- ============================================================
2
+ -- Migration: Add anon role RLS policies for MCP server
3
+ -- ============================================================
4
+ -- The MCP server connects with the anon key (no auth.uid()).
5
+ -- These policies allow the MCP tools to perform core operations
6
+ -- while keeping XP/level columns locked to SECURITY DEFINER RPCs.
7
+ --
8
+ -- EXISTING anon policies (already in place, DO NOT re-create):
9
+ -- anon SELECT on: users, user_identities, user_class_progress,
10
+ -- user_achievements, user_level_requirements, agents, agent_skills,
11
+ -- agent_tool_installations, agent_skill_snapshots, agent_transfers,
12
+ -- agent_integrity_log, agent_cross_ratings, skills, tasks,
13
+ -- weekly_bonus_criteria, achievement_definitions, verification_rules,
14
+ -- + all reference tables (level_curves, rank_definitions, xp_config, etc.)
15
+ -- anon INSERT on: user_identities, agent_skills, agent_skill_snapshots,
16
+ -- agent_transfers, agent_integrity_log, agent_cross_ratings, skills,
17
+ -- agent_tool_installations, user_level_requirements
18
+ -- anon UPDATE on: user_identities, user_level_requirements, agent_skills
19
+ --
20
+ -- STRATEGY:
21
+ -- - XP/level writes → only via SECURITY DEFINER RPCs (locked)
22
+ -- - Task/agent/user creation → anon INSERT allowed (MCP tools enforce rules)
23
+ -- - Config/rule tables → read-only for anon (admin via service_role)
24
+ -- ============================================================
25
+
26
+ -- ============================================================
27
+ -- 1. USERS: Allow registration and safe profile updates
28
+ -- ============================================================
29
+
30
+ -- Anon can register new users
31
+ CREATE POLICY "anon_insert_users" ON users
32
+ FOR INSERT TO anon
33
+ WITH CHECK (true);
34
+
35
+ -- NO anon UPDATE on users — all updates go through RPCs:
36
+ -- update_user_profile() for safe fields
37
+ -- merge_user_profiles() for profile merges
38
+ -- award_task_xp() for XP (existing)
39
+ -- check_and_apply_level_up() for levels (existing)
40
+
41
+ -- ============================================================
42
+ -- 2. USER_CLASS_PROGRESS: Allow creation during registration
43
+ -- ============================================================
44
+
45
+ CREATE POLICY "anon_insert_user_class_progress" ON user_class_progress
46
+ FOR INSERT TO anon
47
+ WITH CHECK (true);
48
+
49
+ -- NO anon UPDATE on user_class_progress — updates via RPCs only
50
+
51
+ -- ============================================================
52
+ -- 3. AGENTS: Allow registration, safe updates only
53
+ -- ============================================================
54
+
55
+ -- Anon can register agents
56
+ CREATE POLICY "anon_insert_agents" ON agents
57
+ FOR INSERT TO anon
58
+ WITH CHECK (true);
59
+
60
+ -- NO anon UPDATE on agents — all updates go through RPCs:
61
+ -- update_agent_profile() for safe fields (with ownership check)
62
+ -- update_integrity_score() for integrity
63
+ -- record_level_up_timestamp() for level-up timestamps
64
+ -- award_task_xp() for XP (existing)
65
+ -- check_and_apply_level_up() for levels (existing)
66
+
67
+ -- ============================================================
68
+ -- 4. TASKS: Allow create and update (MCP enforces min duration,
69
+ -- rate limits, cooldowns)
70
+ -- ============================================================
71
+
72
+ CREATE POLICY "anon_insert_tasks" ON tasks
73
+ FOR INSERT TO anon
74
+ WITH CHECK (
75
+ status = 'in_progress' -- Can only create tasks as in_progress
76
+ );
77
+
78
+ -- NO anon UPDATE on tasks — all updates go through update_task_status() RPC
79
+ -- which verifies the caller owns the task
80
+
81
+ -- ============================================================
82
+ -- 5. TASK SUPPORT TABLES: Ratings, expectations, evaluations, TDI
83
+ -- ============================================================
84
+
85
+ CREATE POLICY "anon_insert_task_ratings" ON task_ratings
86
+ FOR INSERT TO anon
87
+ WITH CHECK (true);
88
+
89
+ CREATE POLICY "anon_insert_task_expectations" ON task_expectations
90
+ FOR INSERT TO anon
91
+ WITH CHECK (true);
92
+
93
+ CREATE POLICY "anon_read_task_evaluations" ON task_evaluations
94
+ FOR SELECT TO anon
95
+ USING (true);
96
+
97
+ CREATE POLICY "anon_insert_task_evaluations" ON task_evaluations
98
+ FOR INSERT TO anon
99
+ WITH CHECK (true);
100
+
101
+ CREATE POLICY "anon_read_task_milestones" ON task_milestones
102
+ FOR SELECT TO anon
103
+ USING (true);
104
+
105
+ CREATE POLICY "anon_insert_task_milestones" ON task_milestones
106
+ FOR INSERT TO anon
107
+ WITH CHECK (true);
108
+
109
+ CREATE POLICY "anon_update_task_milestones" ON task_milestones
110
+ FOR UPDATE TO anon
111
+ USING (true)
112
+ WITH CHECK (true);
113
+
114
+ -- TDI: Allow MCP to upsert difficulty index entries
115
+ CREATE POLICY "anon_insert_task_difficulty_index" ON task_difficulty_index
116
+ FOR INSERT TO anon
117
+ WITH CHECK (true);
118
+
119
+ CREATE POLICY "anon_update_task_difficulty_index" ON task_difficulty_index
120
+ FOR UPDATE TO anon
121
+ USING (true)
122
+ WITH CHECK (true);
123
+
124
+ -- Task XP awards: read-only for anon (written by award_task_xp RPC)
125
+ CREATE POLICY "anon_read_task_xp_awards" ON task_xp_awards
126
+ FOR SELECT TO anon
127
+ USING (true);
128
+
129
+ -- ============================================================
130
+ -- 6. QUESTS: Allow create, join, progress, complete
131
+ -- ============================================================
132
+
133
+ CREATE POLICY "anon_read_quests" ON quests
134
+ FOR SELECT TO anon
135
+ USING (true);
136
+
137
+ CREATE POLICY "anon_insert_quests" ON quests
138
+ FOR INSERT TO anon
139
+ WITH CHECK (true);
140
+
141
+ CREATE POLICY "anon_update_quests" ON quests
142
+ FOR UPDATE TO anon
143
+ USING (true)
144
+ WITH CHECK (true);
145
+
146
+ CREATE POLICY "anon_read_quest_participants" ON quest_participants
147
+ FOR SELECT TO anon
148
+ USING (true);
149
+
150
+ CREATE POLICY "anon_insert_quest_participants" ON quest_participants
151
+ FOR INSERT TO anon
152
+ WITH CHECK (true);
153
+
154
+ CREATE POLICY "anon_read_quest_completions" ON quest_completions
155
+ FOR SELECT TO anon
156
+ USING (true);
157
+
158
+ CREATE POLICY "anon_insert_quest_completions" ON quest_completions
159
+ FOR INSERT TO anon
160
+ WITH CHECK (true);
161
+
162
+ -- ============================================================
163
+ -- 7. LINK CODES & OTP: Allow MCP to create codes
164
+ -- ============================================================
165
+
166
+ CREATE POLICY "anon_read_link_codes" ON link_codes
167
+ FOR SELECT TO anon
168
+ USING (true);
169
+
170
+ CREATE POLICY "anon_insert_link_codes" ON link_codes
171
+ FOR INSERT TO anon
172
+ WITH CHECK (true);
173
+
174
+ CREATE POLICY "anon_update_link_codes" ON link_codes
175
+ FOR UPDATE TO anon
176
+ USING (true)
177
+ WITH CHECK (true);
178
+
179
+ -- OTP codes (if table exists with RLS enabled)
180
+ DO $$
181
+ BEGIN
182
+ IF EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'public' AND tablename = 'otp_codes') THEN
183
+ EXECUTE 'CREATE POLICY "anon_read_otp_codes" ON otp_codes FOR SELECT TO anon USING (true)';
184
+ EXECUTE 'CREATE POLICY "anon_insert_otp_codes" ON otp_codes FOR INSERT TO anon WITH CHECK (true)';
185
+ EXECUTE 'CREATE POLICY "anon_update_otp_codes" ON otp_codes FOR UPDATE TO anon USING (true) WITH CHECK (true)';
186
+ EXECUTE 'CREATE POLICY "anon_delete_otp_codes" ON otp_codes FOR DELETE TO anon USING (true)';
187
+ END IF;
188
+ END $$;
189
+
190
+ -- ============================================================
191
+ -- 8. METRICS: Allow reporting and processing
192
+ -- ============================================================
193
+
194
+ CREATE POLICY "anon_read_metrics_log" ON metrics_log
195
+ FOR SELECT TO anon
196
+ USING (true);
197
+
198
+ CREATE POLICY "anon_insert_metrics_log" ON metrics_log
199
+ FOR INSERT TO anon
200
+ WITH CHECK (true);
201
+
202
+ CREATE POLICY "anon_update_metrics_log" ON metrics_log
203
+ FOR UPDATE TO anon
204
+ USING (true)
205
+ WITH CHECK (true);
206
+
207
+ -- ============================================================
208
+ -- 9. WEEKLY BONUSES: Allow processing
209
+ -- ============================================================
210
+
211
+ CREATE POLICY "anon_read_weekly_bonus_awards" ON weekly_bonus_awards
212
+ FOR SELECT TO anon
213
+ USING (true);
214
+
215
+ CREATE POLICY "anon_insert_weekly_bonus_awards" ON weekly_bonus_awards
216
+ FOR INSERT TO anon
217
+ WITH CHECK (true);
218
+
219
+ -- Weekly bonus progress (if exists)
220
+ DO $$
221
+ BEGIN
222
+ IF EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'public' AND tablename = 'weekly_bonus_progress') THEN
223
+ EXECUTE 'CREATE POLICY "anon_read_weekly_bonus_progress" ON weekly_bonus_progress FOR SELECT TO anon USING (true)';
224
+ EXECUTE 'CREATE POLICY "anon_insert_weekly_bonus_progress" ON weekly_bonus_progress FOR INSERT TO anon WITH CHECK (true)';
225
+ EXECUTE 'CREATE POLICY "anon_update_weekly_bonus_progress" ON weekly_bonus_progress FOR UPDATE TO anon USING (true) WITH CHECK (true)';
226
+ END IF;
227
+ END $$;
228
+
229
+ -- ============================================================
230
+ -- 10. XP LEDGER: READ-ONLY for anon (LOCKED)
231
+ -- ============================================================
232
+ -- xp_ledger has NO anon insert/update policy — this is correct.
233
+ -- All XP writes go through SECURITY DEFINER RPCs:
234
+ -- - award_task_xp (task completion)
235
+ -- - check_and_apply_level_up (level progression)
236
+ --
237
+ -- The awardXpWithLock() function in quests.ts writes directly
238
+ -- to xp_ledger — this will FAIL with anon key. It must be
239
+ -- migrated to a SECURITY DEFINER RPC. See migration note below.
240
+
241
+ CREATE POLICY "anon_read_xp_ledger" ON xp_ledger
242
+ FOR SELECT TO anon
243
+ USING (true);
244
+
245
+ -- ============================================================
246
+ -- 11. ADMIN-ONLY TABLES: No anon write (use service_role key)
247
+ -- ============================================================
248
+ -- These tables have anon SELECT but intentionally NO anon write:
249
+ -- - task_types (create_task_type is admin-only)
250
+ -- - xp_config (set_xp_config is admin-only)
251
+ -- - xp_split_rules / xp_split_rule_entries (create_split_rule is admin-only)
252
+ -- - level_curves, rank_definitions, completion_curves
253
+ -- - skill_categories, skill_leveling_rules, skill_tool_mappings
254
+ -- - achievement_definitions, community_expectations
255
+ --
256
+ -- Admin tools (Section 12) must use service_role key to write to these.
257
+
258
+ -- ============================================================
259
+ -- 12. ENSURE RPCs ARE SECURITY DEFINER
260
+ -- ============================================================
261
+ -- These functions must bypass RLS to update locked XP/level columns.
262
+ -- Run these ALTER statements to confirm they're SECURITY DEFINER:
263
+
264
+ ALTER FUNCTION award_task_xp(uuid) SECURITY DEFINER;
265
+ ALTER FUNCTION check_and_apply_level_up(text, uuid) SECURITY DEFINER;
266
+
267
+ -- ============================================================
268
+ -- MIGRATION NOTE: awardXpWithLock() needs an RPC
269
+ -- ============================================================
270
+ -- The quest/weekly-bonus XP path in the MCP server currently
271
+ -- writes directly to xp_ledger and updates users.main_xp / agents.xp.
272
+ -- With these RLS policies, that path will fail for anon.
273
+ --
274
+ -- TODO: Create a new SECURITY DEFINER RPC:
275
+ --
276
+ -- CREATE OR REPLACE FUNCTION award_xp_direct(
277
+ -- p_entity_type TEXT,
278
+ -- p_entity_id UUID,
279
+ -- p_amount INTEGER,
280
+ -- p_source_type TEXT,
281
+ -- p_description TEXT,
282
+ -- p_source_id UUID DEFAULT NULL
283
+ -- ) RETURNS JSONB AS $$
284
+ -- DECLARE
285
+ -- v_running_total BIGINT;
286
+ -- BEGIN
287
+ -- SELECT COALESCE(running_total, 0) INTO v_running_total
288
+ -- FROM xp_ledger
289
+ -- WHERE entity_type = p_entity_type AND entity_id = p_entity_id
290
+ -- ORDER BY created_at DESC LIMIT 1;
291
+ --
292
+ -- v_running_total := v_running_total + p_amount;
293
+ --
294
+ -- INSERT INTO xp_ledger (entity_type, entity_id, xp_type, amount,
295
+ -- source_type, source_id, description, running_total)
296
+ -- VALUES (p_entity_type, p_entity_id, 'main', p_amount,
297
+ -- p_source_type, p_source_id, p_description, v_running_total);
298
+ --
299
+ -- IF p_entity_type = 'user' THEN
300
+ -- UPDATE users SET main_xp = v_running_total WHERE id = p_entity_id;
301
+ -- ELSE
302
+ -- UPDATE agents SET xp = v_running_total WHERE id = p_entity_id;
303
+ -- END IF;
304
+ --
305
+ -- RETURN jsonb_build_object('success', true, 'running_total', v_running_total);
306
+ -- END;
307
+ -- $$ LANGUAGE plpgsql SECURITY DEFINER;
308
+ --
309
+ -- Then update quests.ts awardXpWithLock() to call this RPC instead
310
+ -- of writing directly to xp_ledger.
311
+ -- ============================================================