@vibecodetown/mcp-server 2.1.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 (172) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +269 -0
  3. package/build/auth/gate.js +225 -0
  4. package/build/auth/index.js +55 -0
  5. package/build/auth/public_key.js +27 -0
  6. package/build/auth/token_cache.js +122 -0
  7. package/build/auth/token_verifier.js +103 -0
  8. package/build/bootstrap/doctor.js +115 -0
  9. package/build/bootstrap/installer.js +673 -0
  10. package/build/bootstrap/lock.js +37 -0
  11. package/build/bootstrap/platform.js +26 -0
  12. package/build/bootstrap/registry.js +37 -0
  13. package/build/cache/index.js +147 -0
  14. package/build/cli.js +101 -0
  15. package/build/contracts.js +22 -0
  16. package/build/control_plane/gate.js +161 -0
  17. package/build/control_plane/index.js +6 -0
  18. package/build/dx/activity.js +139 -0
  19. package/build/engine.js +106 -0
  20. package/build/errors.js +171 -0
  21. package/build/generated/activate_input.js +2 -0
  22. package/build/generated/activate_output.js +57 -0
  23. package/build/generated/advisory_review_input.js +2 -0
  24. package/build/generated/advisory_review_output.js +35 -0
  25. package/build/generated/auth_token_file.js +2 -0
  26. package/build/generated/briefing_input.js +2 -0
  27. package/build/generated/briefing_output.js +2 -0
  28. package/build/generated/clinic_bridge_file.js +13 -0
  29. package/build/generated/contracts_bundle_info.js +5 -0
  30. package/build/generated/create_work_order_input.js +2 -0
  31. package/build/generated/create_work_order_output.js +2 -0
  32. package/build/generated/current_work_order_file.js +2 -0
  33. package/build/generated/doctor_input.js +2 -0
  34. package/build/generated/doctor_output.js +24 -0
  35. package/build/generated/execution_result.js +2 -0
  36. package/build/generated/execution_task.js +2 -0
  37. package/build/generated/export_output_input.js +2 -0
  38. package/build/generated/export_output_output.js +2 -0
  39. package/build/generated/finalize_work_input.js +2 -0
  40. package/build/generated/finalize_work_output.js +2 -0
  41. package/build/generated/gate_input.js +2 -0
  42. package/build/generated/gate_output.js +2 -0
  43. package/build/generated/gate_result_v1.js +2 -0
  44. package/build/generated/get_decision_input.js +2 -0
  45. package/build/generated/get_decision_output.js +13 -0
  46. package/build/generated/handoff_to_clinic.js +2 -0
  47. package/build/generated/index.js +75 -0
  48. package/build/generated/inspect_code_input.js +2 -0
  49. package/build/generated/inspect_code_output.js +13 -0
  50. package/build/generated/memory_retrieve_output.js +2 -0
  51. package/build/generated/memory_state_file.js +2 -0
  52. package/build/generated/memory_status_input.js +2 -0
  53. package/build/generated/memory_status_output.js +13 -0
  54. package/build/generated/memory_sync_input.js +2 -0
  55. package/build/generated/memory_sync_output.js +13 -0
  56. package/build/generated/plugin_result.js +2 -0
  57. package/build/generated/react_perf_check_patterns_input.js +2 -0
  58. package/build/generated/react_perf_check_patterns_output.js +2 -0
  59. package/build/generated/react_perf_generate_report_input.js +2 -0
  60. package/build/generated/react_perf_generate_report_output.js +2 -0
  61. package/build/generated/repair_plan_input.js +2 -0
  62. package/build/generated/repair_plan_output.js +2 -0
  63. package/build/generated/run_app_input.js +2 -0
  64. package/build/generated/run_app_output.js +2 -0
  65. package/build/generated/run_state_file.js +13 -0
  66. package/build/generated/scaffold_input.js +2 -0
  67. package/build/generated/scaffold_output.js +2 -0
  68. package/build/generated/search_oss_input.js +2 -0
  69. package/build/generated/search_oss_output.js +2 -0
  70. package/build/generated/selection_validation_result.js +2 -0
  71. package/build/generated/signal_agent_input.js +2 -0
  72. package/build/generated/spec_high_ask_queue_items_file.js +2 -0
  73. package/build/generated/spec_high_clinic_bridge_output.js +2 -0
  74. package/build/generated/spec_high_decision_draft_output.js +2 -0
  75. package/build/generated/spec_high_validate_output.js +2 -0
  76. package/build/generated/status_input.js +2 -0
  77. package/build/generated/status_output.js +2 -0
  78. package/build/generated/submit_decision_input.js +2 -0
  79. package/build/generated/submit_decision_output.js +2 -0
  80. package/build/generated/tool_error_output.js +2 -0
  81. package/build/generated/undo_last_task_input.js +2 -0
  82. package/build/generated/undo_last_task_output.js +2 -0
  83. package/build/generated/update_input.js +2 -0
  84. package/build/generated/update_output.js +2 -0
  85. package/build/generated/vibe_pm_inspection_result.js +2 -0
  86. package/build/generated/vibe_pm_report_markdown.js +2 -0
  87. package/build/generated/vibe_pm_verdict.js +2 -0
  88. package/build/generated/vibe_repo_config.js +2 -0
  89. package/build/generated/vibecoding_helper_answer_output.js +2 -0
  90. package/build/generated/vibecoding_helper_one_loop_selection_output.js +2 -0
  91. package/build/generated/vibecoding_helper_show_ask_queue_output.js +2 -0
  92. package/build/generated/work_order_v1.js +2 -0
  93. package/build/generated/zoekt_evidence_input.js +2 -0
  94. package/build/generated/zoekt_evidence_output.js +2 -0
  95. package/build/index.js +111 -0
  96. package/build/legacy_alias.js +65 -0
  97. package/build/local-mode/bash.js +61 -0
  98. package/build/local-mode/config.js +171 -0
  99. package/build/local-mode/git.js +33 -0
  100. package/build/local-mode/init.js +110 -0
  101. package/build/local-mode/paths.js +24 -0
  102. package/build/local-mode/templates.js +856 -0
  103. package/build/local-mode/work-order.js +41 -0
  104. package/build/resources/index.js +246 -0
  105. package/build/security/input-validator.js +119 -0
  106. package/build/security/path-policy.js +289 -0
  107. package/build/security/sandbox.js +228 -0
  108. package/build/tools/react_perf/check_patterns.js +172 -0
  109. package/build/tools/react_perf/generate_report.js +337 -0
  110. package/build/tools/react_perf/index.js +119 -0
  111. package/build/tools/react_perf/rules/advanced.js +325 -0
  112. package/build/tools/react_perf/rules/async.js +104 -0
  113. package/build/tools/react_perf/rules/bundle.js +101 -0
  114. package/build/tools/react_perf/rules/client.js +186 -0
  115. package/build/tools/react_perf/rules/index.js +74 -0
  116. package/build/tools/react_perf/rules/js.js +148 -0
  117. package/build/tools/react_perf/rules/rendering.js +166 -0
  118. package/build/tools/react_perf/rules/rerender.js +161 -0
  119. package/build/tools/react_perf/rules/server.js +141 -0
  120. package/build/tools/react_perf/types.js +127 -0
  121. package/build/tools/vibe_pm/activate.js +102 -0
  122. package/build/tools/vibe_pm/advisory_review.js +77 -0
  123. package/build/tools/vibe_pm/briefing.js +178 -0
  124. package/build/tools/vibe_pm/context.js +439 -0
  125. package/build/tools/vibe_pm/create_work_order.js +271 -0
  126. package/build/tools/vibe_pm/doc_status_gate.js +370 -0
  127. package/build/tools/vibe_pm/doctor.js +262 -0
  128. package/build/tools/vibe_pm/entity_gate/preflight.js +78 -0
  129. package/build/tools/vibe_pm/export_output.js +135 -0
  130. package/build/tools/vibe_pm/finalize_work.js +393 -0
  131. package/build/tools/vibe_pm/gate.js +33 -0
  132. package/build/tools/vibe_pm/get_decision.js +281 -0
  133. package/build/tools/vibe_pm/index.js +593 -0
  134. package/build/tools/vibe_pm/inspect_code.js +828 -0
  135. package/build/tools/vibe_pm/intent/generator.js +294 -0
  136. package/build/tools/vibe_pm/intent/index.js +5 -0
  137. package/build/tools/vibe_pm/intent/prompt_density.js +227 -0
  138. package/build/tools/vibe_pm/intent/types.js +70 -0
  139. package/build/tools/vibe_pm/intent/verifier.js +237 -0
  140. package/build/tools/vibe_pm/kce/doc_usage.js +51 -0
  141. package/build/tools/vibe_pm/kce/on_finalize.js +11 -0
  142. package/build/tools/vibe_pm/kce/preflight.js +232 -0
  143. package/build/tools/vibe_pm/local_memory.js +26 -0
  144. package/build/tools/vibe_pm/memory_status.js +82 -0
  145. package/build/tools/vibe_pm/memory_sync.js +134 -0
  146. package/build/tools/vibe_pm/modules/decision_snapshot.js +29 -0
  147. package/build/tools/vibe_pm/modules/ensure.js +100 -0
  148. package/build/tools/vibe_pm/modules/fingerprint.js +30 -0
  149. package/build/tools/vibe_pm/modules/fix_dependencies.js +394 -0
  150. package/build/tools/vibe_pm/modules/planning_v1.js +110 -0
  151. package/build/tools/vibe_pm/modules/repo_context.js +56 -0
  152. package/build/tools/vibe_pm/modules/research_v1.js +114 -0
  153. package/build/tools/vibe_pm/modules/skills_v1.js +100 -0
  154. package/build/tools/vibe_pm/pm_language.js +222 -0
  155. package/build/tools/vibe_pm/repair_plan.js +199 -0
  156. package/build/tools/vibe_pm/run_app.js +597 -0
  157. package/build/tools/vibe_pm/run_app_podman.js +64 -0
  158. package/build/tools/vibe_pm/scaffold.js +550 -0
  159. package/build/tools/vibe_pm/search_oss.js +124 -0
  160. package/build/tools/vibe_pm/status.js +153 -0
  161. package/build/tools/vibe_pm/submit_decision.js +87 -0
  162. package/build/tools/vibe_pm/system_design/issue_mapping.js +47 -0
  163. package/build/tools/vibe_pm/system_design/rulebook.js +112 -0
  164. package/build/tools/vibe_pm/system_design/semgrep.js +132 -0
  165. package/build/tools/vibe_pm/types.js +229 -0
  166. package/build/tools/vibe_pm/undo_last_task.js +163 -0
  167. package/build/tools/vibe_pm/update.js +146 -0
  168. package/build/tools/vibe_pm/zoekt_evidence.js +96 -0
  169. package/build/tools.js +269 -0
  170. package/build/version-check.js +239 -0
  171. package/build/vibe-cli.js +631 -0
  172. package/package.json +76 -0
@@ -0,0 +1,122 @@
1
+ import { homedir } from 'os';
2
+ import { join } from 'path';
3
+ import { readFile, writeFile, mkdir } from 'fs/promises';
4
+ import { existsSync } from 'fs';
5
+ import { AuthTokenFileSchema } from '../generated/auth_token_file.js';
6
+ const CONFIG_DIR = join(homedir(), '.vibe-pm');
7
+ const DEFAULT_TOKEN_FILE = join(CONFIG_DIR, 'auth-token.json');
8
+ export class TokenCache {
9
+ memoryCache = null;
10
+ resolveTokenFilePath() {
11
+ const override = (process.env.VIBECODE_AUTH_TOKEN_FILE || '').trim();
12
+ return override || DEFAULT_TOKEN_FILE;
13
+ }
14
+ /**
15
+ * Get the cached token if it exists and is not expired
16
+ */
17
+ async get() {
18
+ // Check memory cache first
19
+ if (this.memoryCache) {
20
+ if (this.isValid(this.memoryCache)) {
21
+ return this.memoryCache;
22
+ }
23
+ this.memoryCache = null;
24
+ }
25
+ // Try to load from disk
26
+ const diskCache = await this.loadFromDisk();
27
+ if (diskCache && this.isValid(diskCache)) {
28
+ this.memoryCache = diskCache;
29
+ return diskCache;
30
+ }
31
+ return null;
32
+ }
33
+ /**
34
+ * Save a token to the cache
35
+ */
36
+ async set(cached) {
37
+ this.memoryCache = cached;
38
+ await this.saveToDisk(cached);
39
+ }
40
+ /**
41
+ * Clear the cached token
42
+ */
43
+ async clear() {
44
+ this.memoryCache = null;
45
+ await this.deleteFromDisk();
46
+ }
47
+ /**
48
+ * Check if a cached token is still valid (not expired)
49
+ */
50
+ isValid(cached) {
51
+ const now = Math.floor(Date.now() / 1000);
52
+ // Consider expired 60 seconds early to avoid edge cases
53
+ return cached.expiresAt > now + 60;
54
+ }
55
+ /**
56
+ * Check if the token needs refresh (expired or will expire soon)
57
+ */
58
+ needsRefresh(cached, bufferSeconds = 300) {
59
+ const now = Math.floor(Date.now() / 1000);
60
+ return cached.expiresAt < now + bufferSeconds;
61
+ }
62
+ /**
63
+ * Load token from disk
64
+ */
65
+ async loadFromDisk() {
66
+ try {
67
+ const tokenFile = this.resolveTokenFilePath();
68
+ if (!existsSync(tokenFile)) {
69
+ return null;
70
+ }
71
+ const data = await readFile(tokenFile, 'utf-8');
72
+ const raw = JSON.parse(data);
73
+ const validated = AuthTokenFileSchema.safeParse(raw);
74
+ if (!validated.success) {
75
+ return null;
76
+ }
77
+ return validated.data;
78
+ }
79
+ catch {
80
+ return null;
81
+ }
82
+ }
83
+ /**
84
+ * Save token to disk
85
+ */
86
+ async saveToDisk(cached) {
87
+ try {
88
+ // Ensure config directory exists
89
+ if (!existsSync(CONFIG_DIR)) {
90
+ await mkdir(CONFIG_DIR, { recursive: true, mode: 0o700 });
91
+ }
92
+ // Write with restricted permissions
93
+ const sealed = AuthTokenFileSchema.parse(cached);
94
+ const data = JSON.stringify(sealed, null, 2);
95
+ await writeFile(this.resolveTokenFilePath(), data, { mode: 0o600 });
96
+ }
97
+ catch (error) {
98
+ console.error('Failed to save token to disk:', error);
99
+ }
100
+ }
101
+ /**
102
+ * Delete token from disk
103
+ */
104
+ async deleteFromDisk() {
105
+ try {
106
+ const tokenFile = this.resolveTokenFilePath();
107
+ if (existsSync(tokenFile)) {
108
+ const { unlink } = await import('fs/promises');
109
+ await unlink(tokenFile);
110
+ }
111
+ }
112
+ catch {
113
+ // Ignore errors when deleting
114
+ }
115
+ }
116
+ /**
117
+ * Get the token file path (for debugging)
118
+ */
119
+ getTokenFilePath() {
120
+ return this.resolveTokenFilePath();
121
+ }
122
+ }
@@ -0,0 +1,103 @@
1
+ import * as jose from 'jose';
2
+ import { PUBLIC_KEY, JWT_ISSUER, JWT_AUDIENCE } from './public_key.js';
3
+ export class TokenVerifier {
4
+ publicKey = null;
5
+ /**
6
+ * Initialize the public key
7
+ */
8
+ async getPublicKey() {
9
+ if (this.publicKey) {
10
+ return this.publicKey;
11
+ }
12
+ this.publicKey = await jose.importSPKI(PUBLIC_KEY, 'ES256');
13
+ return this.publicKey;
14
+ }
15
+ /**
16
+ * Verify a JWT token offline using the embedded public key
17
+ */
18
+ async verify(token) {
19
+ try {
20
+ const key = await this.getPublicKey();
21
+ const { payload } = await jose.jwtVerify(token, key, {
22
+ issuer: JWT_ISSUER,
23
+ audience: JWT_AUDIENCE,
24
+ });
25
+ // Extract and validate claims
26
+ if (!payload.sub || !payload.ent || !payload.pol) {
27
+ return { success: false, error: 'invalid_token' };
28
+ }
29
+ const verified = {
30
+ subjectId: payload.sub,
31
+ entitlements: payload.ent,
32
+ policy: payload.pol,
33
+ issuedAt: payload.iat || 0,
34
+ expiresAt: payload.exp || 0,
35
+ };
36
+ return { success: true, token: verified };
37
+ }
38
+ catch (error) {
39
+ // Map jose errors to our error types
40
+ if (error instanceof jose.errors.JWTExpired) {
41
+ return { success: false, error: 'expired_token' };
42
+ }
43
+ if (error instanceof jose.errors.JWSSignatureVerificationFailed) {
44
+ return { success: false, error: 'invalid_signature' };
45
+ }
46
+ if (error instanceof jose.errors.JWTClaimValidationFailed) {
47
+ const message = error.message || '';
48
+ if (message.includes('iss')) {
49
+ return { success: false, error: 'invalid_issuer' };
50
+ }
51
+ if (message.includes('aud')) {
52
+ return { success: false, error: 'invalid_audience' };
53
+ }
54
+ }
55
+ return { success: false, error: 'invalid_token' };
56
+ }
57
+ }
58
+ /**
59
+ * Quick check if a token is expired without full verification
60
+ */
61
+ isExpired(token) {
62
+ try {
63
+ const decoded = jose.decodeJwt(token);
64
+ if (!decoded.exp) {
65
+ return true;
66
+ }
67
+ const now = Math.floor(Date.now() / 1000);
68
+ return decoded.exp < now;
69
+ }
70
+ catch {
71
+ return true;
72
+ }
73
+ }
74
+ /**
75
+ * Get the time until token expires (in seconds)
76
+ * Returns 0 if expired or invalid
77
+ */
78
+ getTimeUntilExpiry(token) {
79
+ try {
80
+ const decoded = jose.decodeJwt(token);
81
+ if (!decoded.exp) {
82
+ return 0;
83
+ }
84
+ const now = Math.floor(Date.now() / 1000);
85
+ const remaining = decoded.exp - now;
86
+ return Math.max(0, remaining);
87
+ }
88
+ catch {
89
+ return 0;
90
+ }
91
+ }
92
+ /**
93
+ * Decode token without verification (for debugging)
94
+ */
95
+ decode(token) {
96
+ try {
97
+ return jose.decodeJwt(token);
98
+ }
99
+ catch {
100
+ return null;
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,115 @@
1
+ // adapters/mcp-ts/src/bootstrap/doctor.ts
2
+ // Health check tool for installation status
3
+ import { ensureEngines, getEngineHealth, checkUpdates, validateCache } from "./installer.js";
4
+ import { ENGINE_SPECS } from "./registry.js";
5
+ /**
6
+ * Check engine installation status and return detailed health info
7
+ * Triggers installation if engines are missing or outdated
8
+ */
9
+ export async function doctor() {
10
+ try {
11
+ // First, get current health status
12
+ const healthBefore = await getEngineHealth();
13
+ // Count issues
14
+ const summary = {
15
+ total: healthBefore.length,
16
+ ok: healthBefore.filter((h) => h.status === "ok").length,
17
+ needsUpdate: healthBefore.filter((h) => h.status === "needs_update").length,
18
+ missing: healthBefore.filter((h) => h.status === "missing").length,
19
+ corrupted: healthBefore.filter((h) => h.status === "corrupted").length
20
+ };
21
+ // If anything needs attention, trigger installation
22
+ if (summary.ok < summary.total) {
23
+ await ensureEngines();
24
+ }
25
+ // Get updated health status
26
+ const healthAfter = await getEngineHealth();
27
+ // Build result
28
+ const engines = {};
29
+ for (const h of healthAfter) {
30
+ engines[h.name] = {
31
+ version: h.version,
32
+ currentVersion: h.currentVersion,
33
+ path: h.path,
34
+ status: h.status
35
+ };
36
+ }
37
+ // Update summary
38
+ const summaryAfter = {
39
+ total: healthAfter.length,
40
+ ok: healthAfter.filter((h) => h.status === "ok").length,
41
+ needsUpdate: healthAfter.filter((h) => h.status === "needs_update").length,
42
+ missing: healthAfter.filter((h) => h.status === "missing").length,
43
+ corrupted: healthAfter.filter((h) => h.status === "corrupted").length
44
+ };
45
+ // Determine overall status
46
+ let status = "OK";
47
+ if (summaryAfter.missing > 0 || summaryAfter.corrupted > 0) {
48
+ status = "ERROR";
49
+ }
50
+ else if (summaryAfter.needsUpdate > 0) {
51
+ status = "NEEDS_UPDATE";
52
+ }
53
+ return {
54
+ status,
55
+ engines,
56
+ summary: summaryAfter
57
+ };
58
+ }
59
+ catch (e) {
60
+ return {
61
+ status: "ERROR",
62
+ engines: {},
63
+ summary: {
64
+ total: Object.keys(ENGINE_SPECS).length,
65
+ ok: 0,
66
+ needsUpdate: 0,
67
+ missing: Object.keys(ENGINE_SPECS).length,
68
+ corrupted: 0
69
+ },
70
+ error: e instanceof Error ? e.message : String(e)
71
+ };
72
+ }
73
+ }
74
+ /**
75
+ * Quick health check without triggering installation
76
+ */
77
+ export async function healthCheck() {
78
+ const health = await getEngineHealth();
79
+ const allOk = health.every((h) => h.status === "ok");
80
+ return {
81
+ status: allOk ? "OK" : "NEEDS_ATTENTION",
82
+ engines: health
83
+ };
84
+ }
85
+ /**
86
+ * Check for available updates
87
+ */
88
+ export async function checkForUpdates() {
89
+ const updates = await checkUpdates();
90
+ const hasUpdates = Object.values(updates).some((u) => u.needsUpdate);
91
+ const result = {};
92
+ for (const [name, info] of Object.entries(updates)) {
93
+ if (info.needsUpdate) {
94
+ result[name] = {
95
+ current: info.current,
96
+ required: info.required
97
+ };
98
+ }
99
+ }
100
+ return {
101
+ hasUpdates,
102
+ updates: result
103
+ };
104
+ }
105
+ /**
106
+ * Validate cache integrity
107
+ */
108
+ export async function validateCacheIntegrity() {
109
+ const cacheStatus = await validateCache();
110
+ const valid = Object.values(cacheStatus).every((c) => c.valid);
111
+ return {
112
+ valid,
113
+ engines: cacheStatus
114
+ };
115
+ }