archer-wizard 0.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 (59) hide show
  1. package/.env.example +6 -0
  2. package/README.md +140 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +77 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/ascii.d.ts +14 -0
  8. package/dist/lib/ascii.d.ts.map +1 -0
  9. package/dist/lib/ascii.js +88 -0
  10. package/dist/lib/ascii.js.map +1 -0
  11. package/dist/lib/supabase.d.ts +7 -0
  12. package/dist/lib/supabase.d.ts.map +1 -0
  13. package/dist/lib/supabase.js +54 -0
  14. package/dist/lib/supabase.js.map +1 -0
  15. package/dist/lib/webhook.d.ts +4 -0
  16. package/dist/lib/webhook.d.ts.map +1 -0
  17. package/dist/lib/webhook.js +53 -0
  18. package/dist/lib/webhook.js.map +1 -0
  19. package/dist/tools/watch.d.ts +35 -0
  20. package/dist/tools/watch.d.ts.map +1 -0
  21. package/dist/tools/watch.js +178 -0
  22. package/dist/tools/watch.js.map +1 -0
  23. package/dist/types/index.d.ts +84 -0
  24. package/dist/types/index.d.ts.map +1 -0
  25. package/dist/types/index.js +24 -0
  26. package/dist/types/index.js.map +1 -0
  27. package/dist/wizard/detector.d.ts +5 -0
  28. package/dist/wizard/detector.d.ts.map +1 -0
  29. package/dist/wizard/detector.js +125 -0
  30. package/dist/wizard/detector.js.map +1 -0
  31. package/dist/wizard/index.d.ts +2 -0
  32. package/dist/wizard/index.d.ts.map +1 -0
  33. package/dist/wizard/index.js +50 -0
  34. package/dist/wizard/index.js.map +1 -0
  35. package/dist/wizard/injector.d.ts +3 -0
  36. package/dist/wizard/injector.d.ts.map +1 -0
  37. package/dist/wizard/injector.js +91 -0
  38. package/dist/wizard/injector.js.map +1 -0
  39. package/dist/wizard/rules.d.ts +3 -0
  40. package/dist/wizard/rules.d.ts.map +1 -0
  41. package/dist/wizard/rules.js +94 -0
  42. package/dist/wizard/rules.js.map +1 -0
  43. package/dist/wizard/scanner.d.ts +7 -0
  44. package/dist/wizard/scanner.d.ts.map +1 -0
  45. package/dist/wizard/scanner.js +201 -0
  46. package/dist/wizard/scanner.js.map +1 -0
  47. package/package.json +28 -0
  48. package/src/index.ts +90 -0
  49. package/src/lib/ascii.ts +109 -0
  50. package/src/lib/supabase.ts +78 -0
  51. package/src/lib/webhook.ts +69 -0
  52. package/src/tools/watch.ts +223 -0
  53. package/src/types/index.ts +120 -0
  54. package/src/wizard/detector.ts +151 -0
  55. package/src/wizard/index.ts +69 -0
  56. package/src/wizard/injector.ts +115 -0
  57. package/src/wizard/rules.ts +112 -0
  58. package/src/wizard/scanner.ts +250 -0
  59. package/tsconfig.json +20 -0
@@ -0,0 +1,178 @@
1
+ import crypto from 'node:crypto';
2
+ import { WatchInputSchema } from '../types/index.js';
3
+ import { createAuthChannel, createTableChannel } from '../lib/supabase.js';
4
+ import { fireWebhook, buildWebhookPayload } from '../lib/webhook.js';
5
+ import { stderrAction, stderrSuccess, stderrError } from '../lib/ascii.js';
6
+ const activeWatches = new Map();
7
+ // ─── Condition Evaluator ────────────────────────────────────
8
+ function evaluateCondition(data, condition) {
9
+ // Parse: "field operator value"
10
+ // Supported: "ends with", "starts with", "contains", "equals"
11
+ const operators = ['ends with', 'starts with', 'contains', 'equals'];
12
+ const conditionLower = condition.toLowerCase();
13
+ let matchedOperator = null;
14
+ let splitIndex = -1;
15
+ for (const op of operators) {
16
+ const idx = conditionLower.indexOf(op);
17
+ if (idx !== -1) {
18
+ matchedOperator = op;
19
+ splitIndex = idx;
20
+ break;
21
+ }
22
+ }
23
+ if (!matchedOperator || splitIndex === -1) {
24
+ stderrError(`unknown condition format: "${condition}"`);
25
+ return true; // Pass through if condition can't be parsed
26
+ }
27
+ const field = condition.slice(0, splitIndex).trim();
28
+ const value = condition.slice(splitIndex + matchedOperator.length).trim();
29
+ const fieldValue = String(data[field] ?? '');
30
+ switch (matchedOperator) {
31
+ case 'ends with':
32
+ return fieldValue.endsWith(value);
33
+ case 'starts with':
34
+ return fieldValue.startsWith(value);
35
+ case 'contains':
36
+ return fieldValue.includes(value);
37
+ case 'equals':
38
+ return fieldValue === value;
39
+ default:
40
+ return true;
41
+ }
42
+ }
43
+ // ─── Map Event To Postgres Event ────────────────────────────
44
+ function toPostgresEvent(event) {
45
+ switch (event) {
46
+ case 'table.insert': return 'INSERT';
47
+ case 'table.update': return 'UPDATE';
48
+ case 'table.delete': return 'DELETE';
49
+ default: return 'INSERT';
50
+ }
51
+ }
52
+ // ─── Event Handler ──────────────────────────────────────────
53
+ function createEventHandler(watch) {
54
+ return async (data) => {
55
+ stderrAction(`event received → ${watch.event}${watch.table ? ` on ${watch.table}` : ''}`);
56
+ // Apply condition filter
57
+ if (watch.condition && !evaluateCondition(data, watch.condition)) {
58
+ stderrAction(`condition not met → "${watch.condition}", skipping`);
59
+ return;
60
+ }
61
+ // Build and fire webhook
62
+ const payload = buildWebhookPayload(watch.watchId, watch.event, data);
63
+ await fireWebhook({
64
+ url: watch.webhookUrl,
65
+ payload,
66
+ event: watch.event,
67
+ });
68
+ };
69
+ }
70
+ // ─── Main Watch Implementation ──────────────────────────────
71
+ export function executeWatch(rawInput) {
72
+ // Validate input
73
+ const parseResult = WatchInputSchema.safeParse(rawInput);
74
+ if (!parseResult.success) {
75
+ const errors = parseResult.error.issues.map((e) => e.message).join(', ');
76
+ return {
77
+ success: false,
78
+ watchId: '',
79
+ message: `validation failed: ${errors}`,
80
+ condition: null,
81
+ };
82
+ }
83
+ const input = parseResult.data;
84
+ const watchId = `watch_${crypto.randomUUID().slice(0, 8)}`;
85
+ stderrAction(`creating watch ${watchId} for ${input.event}`);
86
+ try {
87
+ let channel;
88
+ if (input.event === 'auth.signup') {
89
+ // Auth signup → watch auth.users table
90
+ const handler = createEventHandler({
91
+ watchId,
92
+ channel: null,
93
+ event: input.event,
94
+ condition: input.condition,
95
+ webhookUrl: input.webhookUrl,
96
+ });
97
+ channel = createAuthChannel(watchId, handler);
98
+ }
99
+ else {
100
+ // Table events → watch specific table
101
+ const table = input.table;
102
+ const pgEvent = toPostgresEvent(input.event);
103
+ const handler = createEventHandler({
104
+ watchId,
105
+ channel: null,
106
+ event: input.event,
107
+ table,
108
+ condition: input.condition,
109
+ webhookUrl: input.webhookUrl,
110
+ });
111
+ channel = createTableChannel(watchId, table, pgEvent, handler);
112
+ }
113
+ // Store active watch
114
+ const watch = {
115
+ watchId,
116
+ channel,
117
+ event: input.event,
118
+ table: input.table,
119
+ condition: input.condition,
120
+ webhookUrl: input.webhookUrl,
121
+ };
122
+ activeWatches.set(watchId, watch);
123
+ const tableInfo = input.table ? ` on table "${input.table}"` : '';
124
+ const conditionInfo = input.condition ? ` where ${input.condition}` : '';
125
+ const message = `watching ${input.event}${tableInfo}${conditionInfo} → ${input.webhookUrl}`;
126
+ stderrSuccess(message);
127
+ return {
128
+ success: true,
129
+ watchId,
130
+ message,
131
+ condition: input.condition ?? null,
132
+ };
133
+ }
134
+ catch (err) {
135
+ const message = err instanceof Error ? err.message : String(err);
136
+ stderrError(`watch failed: ${message}`);
137
+ return {
138
+ success: false,
139
+ watchId,
140
+ message: `watch failed: ${message}`,
141
+ condition: input.condition ?? null,
142
+ };
143
+ }
144
+ }
145
+ // ─── Tool Schema (for MCP registration) ─────────────────────
146
+ export const WATCH_TOOL_SCHEMA = {
147
+ name: 'archer_watch',
148
+ description: 'Watch real-time events from Supabase. Monitors auth signups, table inserts, updates, and deletes. Fires a webhook when conditions are met.',
149
+ inputSchema: {
150
+ type: 'object',
151
+ properties: {
152
+ source: {
153
+ type: 'string',
154
+ enum: ['supabase'],
155
+ description: 'Event source (currently only "supabase")',
156
+ },
157
+ event: {
158
+ type: 'string',
159
+ enum: ['auth.signup', 'table.insert', 'table.update', 'table.delete'],
160
+ description: 'Event type to watch for',
161
+ },
162
+ table: {
163
+ type: 'string',
164
+ description: 'Table name (required for table.* events)',
165
+ },
166
+ condition: {
167
+ type: 'string',
168
+ description: 'Optional filter like "email ends with @gmail.com". Supports: ends with, starts with, contains, equals',
169
+ },
170
+ webhookUrl: {
171
+ type: 'string',
172
+ description: 'URL to receive POST notifications when events match',
173
+ },
174
+ },
175
+ required: ['source', 'event', 'webhookUrl'],
176
+ },
177
+ };
178
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/tools/watch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import { z } from 'zod';
2
+ export type Framework = 'nextjs' | 'vite' | 'unknown';
3
+ export interface ScanResult {
4
+ supabaseUrl: string | null;
5
+ serviceRoleKey: string | null;
6
+ anonKey: string | null;
7
+ framework: Framework;
8
+ hasSupabaseInstalled: boolean;
9
+ foundInFile: string | null;
10
+ }
11
+ export interface ValidatedCredentials {
12
+ supabaseUrl: string;
13
+ serviceRoleKey: string;
14
+ anonKey: string | null;
15
+ }
16
+ export interface AgentInfo {
17
+ name: string;
18
+ installed: boolean;
19
+ configPath: string;
20
+ configExists: boolean;
21
+ }
22
+ export type AgentName = 'cursor' | 'claude-code' | 'opencode' | 'antigravity' | 'windsurf';
23
+ export interface AgentConfigFormat {
24
+ name: AgentName;
25
+ displayName: string;
26
+ configKey: 'mcpServers' | 'mcp';
27
+ rulesPath: (cwd: string) => string;
28
+ }
29
+ export declare const WatchEventSchema: z.ZodEnum<{
30
+ "auth.signup": "auth.signup";
31
+ "table.insert": "table.insert";
32
+ "table.update": "table.update";
33
+ "table.delete": "table.delete";
34
+ }>;
35
+ export type WatchEvent = z.infer<typeof WatchEventSchema>;
36
+ export declare const WatchInputSchema: z.ZodObject<{
37
+ source: z.ZodLiteral<"supabase">;
38
+ event: z.ZodEnum<{
39
+ "auth.signup": "auth.signup";
40
+ "table.insert": "table.insert";
41
+ "table.update": "table.update";
42
+ "table.delete": "table.delete";
43
+ }>;
44
+ table: z.ZodOptional<z.ZodString>;
45
+ condition: z.ZodOptional<z.ZodString>;
46
+ webhookUrl: z.ZodString;
47
+ }, z.core.$strip>;
48
+ export type WatchInput = z.infer<typeof WatchInputSchema>;
49
+ export interface WatchResult {
50
+ success: boolean;
51
+ watchId: string;
52
+ message: string;
53
+ condition: string | null;
54
+ }
55
+ export interface WebhookPayload {
56
+ archer: {
57
+ watchId: string;
58
+ event: string;
59
+ source: 'supabase';
60
+ firedAt: string;
61
+ };
62
+ data: Record<string, unknown>;
63
+ }
64
+ export interface WebhookOptions {
65
+ url: string;
66
+ payload: WebhookPayload;
67
+ event: string;
68
+ }
69
+ export type PostgresEvent = 'INSERT' | 'UPDATE' | 'DELETE';
70
+ export interface RealtimeChannelConfig {
71
+ table: string;
72
+ event: PostgresEvent;
73
+ }
74
+ export interface InjectionResult {
75
+ agent: string;
76
+ success: boolean;
77
+ error?: string;
78
+ }
79
+ export interface McpServerEntry {
80
+ command: string;
81
+ args: string[];
82
+ env: Record<string, string>;
83
+ }
84
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAItD,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,SAAS,CAAC;IACrB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAID,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,aAAa,GAAG,UAAU,GAAG,aAAa,GAAG,UAAU,CAAC;AAE3F,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,YAAY,GAAG,KAAK,CAAC;IAChC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;CACpC;AAID,eAAO,MAAM,gBAAgB;;;;;EAK3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,gBAAgB;;;;;;;;;;;iBAiB5B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAID,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,UAAU,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAID,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,CAAC;CACtB;AAID,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B"}
@@ -0,0 +1,24 @@
1
+ import { z } from 'zod';
2
+ // ─── Watch Tool Types ───────────────────────────────────────
3
+ export const WatchEventSchema = z.enum([
4
+ 'auth.signup',
5
+ 'table.insert',
6
+ 'table.update',
7
+ 'table.delete',
8
+ ]);
9
+ export const WatchInputSchema = z.object({
10
+ source: z.literal('supabase'),
11
+ event: WatchEventSchema,
12
+ table: z.string().optional(),
13
+ condition: z.string().optional(),
14
+ webhookUrl: z.string().url('webhookUrl must be a valid URL'),
15
+ }).refine((data) => {
16
+ if (data.event !== 'auth.signup' && !data.table) {
17
+ return false;
18
+ }
19
+ return true;
20
+ }, {
21
+ message: 'table is required when event is not auth.signup',
22
+ path: ['table'],
23
+ });
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAyCxB,+DAA+D;AAE/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC;IACrC,aAAa;IACb,cAAc;IACd,cAAc;IACd,cAAc;CACf,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;IAC7B,KAAK,EAAE,gBAAgB;IACvB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,gCAAgC,CAAC;CAC7D,CAAC,CAAC,MAAM,CACP,CAAC,IAAI,EAAE,EAAE;IACP,IAAI,IAAI,CAAC,KAAK,KAAK,aAAa,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,EACD;IACE,OAAO,EAAE,iDAAiD;IAC1D,IAAI,EAAE,CAAC,OAAO,CAAC;CAChB,CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { AgentInfo } from '../types/index.js';
2
+ export declare function detectAgents(): AgentInfo[];
3
+ export declare function getConfigKey(agentName: string): 'mcpServers' | 'mcp';
4
+ export declare function getRulesPath(agentName: string, cwd: string): string;
5
+ //# sourceMappingURL=detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/wizard/detector.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAiGnD,wBAAgB,YAAY,IAAI,SAAS,EAAE,CAqB1C;AAID,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,KAAK,CAMpE;AAID,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAenE"}
@@ -0,0 +1,125 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ const AGENTS = [
5
+ {
6
+ name: 'cursor',
7
+ paths: {
8
+ darwin: path.join(os.homedir(), '.cursor', 'mcp.json'),
9
+ linux: path.join(os.homedir(), '.cursor', 'mcp.json'),
10
+ win32: path.join(process.env['APPDATA'] ?? os.homedir(), 'Cursor', 'mcp.json'),
11
+ },
12
+ },
13
+ {
14
+ name: 'claude-code',
15
+ paths: {
16
+ darwin: path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
17
+ linux: path.join(os.homedir(), '.config', 'claude', 'claude_desktop_config.json'),
18
+ win32: path.join(process.env['APPDATA'] ?? os.homedir(), 'Claude', 'claude_desktop_config.json'),
19
+ },
20
+ },
21
+ {
22
+ name: 'opencode',
23
+ paths: {
24
+ darwin: path.join(os.homedir(), '.config', 'opencode', 'config.json'),
25
+ linux: path.join(os.homedir(), '.config', 'opencode', 'config.json'),
26
+ win32: path.join(process.env['APPDATA'] ?? os.homedir(), 'opencode', 'config.json'),
27
+ },
28
+ },
29
+ {
30
+ name: 'antigravity',
31
+ paths: {
32
+ darwin: path.join(os.homedir(), '.config', 'antigravity', 'config.json'),
33
+ linux: path.join(os.homedir(), '.config', 'antigravity', 'config.json'),
34
+ win32: path.join(process.env['APPDATA'] ?? os.homedir(), 'Antigravity', 'config.json'),
35
+ },
36
+ },
37
+ {
38
+ name: 'windsurf',
39
+ paths: {
40
+ darwin: path.join(os.homedir(), '.codeium', 'windsurf', 'mcp_config.json'),
41
+ linux: path.join(os.homedir(), '.codeium', 'windsurf', 'mcp_config.json'),
42
+ win32: path.join(process.env['APPDATA'] ?? os.homedir(), 'Windsurf', 'mcp_config.json'),
43
+ },
44
+ },
45
+ ];
46
+ // ─── Platform Detection ─────────────────────────────────────
47
+ function getPlatform() {
48
+ const platform = os.platform();
49
+ if (platform === 'darwin' || platform === 'linux' || platform === 'win32') {
50
+ return platform;
51
+ }
52
+ // Default to linux for other Unix-like systems
53
+ return 'linux';
54
+ }
55
+ // ─── Get Config Path For Agent ──────────────────────────────
56
+ function getConfigPath(agent) {
57
+ const platform = getPlatform();
58
+ return agent.paths[platform];
59
+ }
60
+ // ─── Check If Path Exists ───────────────────────────────────
61
+ function fileExists(filePath) {
62
+ try {
63
+ // Check if the file itself OR its parent directory exists
64
+ // The config file might not exist yet, but the parent app directory should
65
+ return fs.existsSync(filePath);
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ }
71
+ function parentDirExists(filePath) {
72
+ try {
73
+ const dir = path.dirname(filePath);
74
+ return fs.existsSync(dir);
75
+ }
76
+ catch {
77
+ return false;
78
+ }
79
+ }
80
+ // ─── Detect Installed Agents ────────────────────────────────
81
+ export function detectAgents() {
82
+ const detected = [];
83
+ for (const agent of AGENTS) {
84
+ const configPath = getConfigPath(agent);
85
+ const configExists = fileExists(configPath);
86
+ const dirExists = parentDirExists(configPath);
87
+ // Agent is "installed" if its parent directory exists
88
+ // (the config file might not exist yet)
89
+ if (dirExists) {
90
+ detected.push({
91
+ name: agent.name,
92
+ installed: true,
93
+ configPath,
94
+ configExists,
95
+ });
96
+ }
97
+ }
98
+ return detected;
99
+ }
100
+ // ─── Get Config Key For Agent ───────────────────────────────
101
+ export function getConfigKey(agentName) {
102
+ if (agentName === 'opencode') {
103
+ return 'mcp';
104
+ }
105
+ // cursor, claude-code, antigravity, windsurf all use mcpServers
106
+ return 'mcpServers';
107
+ }
108
+ // ─── Get Rules Path For Agent ───────────────────────────────
109
+ export function getRulesPath(agentName, cwd) {
110
+ switch (agentName) {
111
+ case 'cursor':
112
+ return path.join(cwd, '.cursor', 'rules', 'archer.mdc');
113
+ case 'claude-code':
114
+ return path.join(cwd, 'CLAUDE.md');
115
+ case 'opencode':
116
+ return path.join(cwd, '.opencode', 'rules.md');
117
+ case 'antigravity':
118
+ return path.join(cwd, '.antigravity', 'rules.md');
119
+ case 'windsurf':
120
+ return path.join(cwd, '.windsurf', 'rules.md');
121
+ default:
122
+ return path.join(cwd, '.archer', 'rules.md');
123
+ }
124
+ }
125
+ //# sourceMappingURL=detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/wizard/detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runWizard(): Promise<void>;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/wizard/index.ts"],"names":[],"mappings":"AAUA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CA0D/C"}
@@ -0,0 +1,50 @@
1
+ import * as clack from '@clack/prompts';
2
+ import pc from 'picocolors';
3
+ import { showAsciiArt, logAction, logSuccess, showSuccessBox } from '../lib/ascii.js';
4
+ import { scanProject, promptForMissing } from './scanner.js';
5
+ import { detectAgents } from './detector.js';
6
+ import { injectIntoAgents } from './injector.js';
7
+ import { injectRules } from './rules.js';
8
+ // ─── Wizard Sequence ────────────────────────────────────────
9
+ export async function runWizard() {
10
+ const cwd = process.cwd();
11
+ // ─ Step 1: ASCII Art ─
12
+ showAsciiArt();
13
+ // ─ Step 2: Start clack ─
14
+ clack.intro(pc.bgGreen(pc.black(' archer setup ')));
15
+ // ─ Step 3: Scanning ─
16
+ logAction('scanning project for Supabase credentials...');
17
+ console.log();
18
+ // ─ Step 4-6: Scan env files ─
19
+ const scan = await scanProject(cwd);
20
+ console.log();
21
+ // ─ Step 7: Framework detection ─
22
+ if (scan.framework !== 'unknown') {
23
+ logSuccess(`detected ${pc.bold(scan.framework)} project`);
24
+ }
25
+ if (scan.hasSupabaseInstalled) {
26
+ logSuccess('found @supabase/supabase-js');
27
+ }
28
+ // ─ Step 8: Prompt for missing credentials ─
29
+ const credentials = await promptForMissing(scan);
30
+ console.log();
31
+ // ─ Step 9: Detect agents ─
32
+ logAction('detecting AI agents...');
33
+ const agents = detectAgents();
34
+ console.log();
35
+ // ─ Step 10-11: Inject into agents ─
36
+ const injectionResults = await injectIntoAgents(agents, credentials.supabaseUrl, credentials.serviceRoleKey);
37
+ console.log();
38
+ // ─ Step 12: Filter successful injections ─
39
+ const successfulAgents = agents.filter((a) => injectionResults.some((r) => r.agent === a.name && r.success));
40
+ // ─ Step 13: Inject rules ─
41
+ if (successfulAgents.length > 0) {
42
+ logAction('writing agent rules...');
43
+ injectRules(successfulAgents, cwd);
44
+ console.log();
45
+ }
46
+ // ─ Step 14: Success ─
47
+ showSuccessBox(successfulAgents.length);
48
+ clack.outro(pc.dim('docs → github.com/archer-mcp'));
49
+ }
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/wizard/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,+DAA+D;AAE/D,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,wBAAwB;IACxB,YAAY,EAAE,CAAC;IAEf,0BAA0B;IAC1B,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAEpD,uBAAuB;IACvB,SAAS,CAAC,8CAA8C,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,+BAA+B;IAC/B,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,kCAAkC;IAClC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACjC,UAAU,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC9B,UAAU,CAAC,6BAA6B,CAAC,CAAC;IAC5C,CAAC;IAED,6CAA6C;IAC7C,MAAM,WAAW,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,4BAA4B;IAC5B,SAAS,CAAC,wBAAwB,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,qCAAqC;IACrC,MAAM,gBAAgB,GAAG,MAAM,gBAAgB,CAC7C,MAAM,EACN,WAAW,CAAC,WAAW,EACvB,WAAW,CAAC,cAAc,CAC3B,CAAC;IACF,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,4CAA4C;IAC5C,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3C,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,CAC9D,CAAC;IAEF,4BAA4B;IAC5B,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,SAAS,CAAC,wBAAwB,CAAC,CAAC;QACpC,WAAW,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,uBAAuB;IACvB,cAAc,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAExC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { AgentInfo, InjectionResult } from '../types/index.js';
2
+ export declare function injectIntoAgents(agents: AgentInfo[], supabaseUrl: string, serviceRoleKey: string): Promise<InjectionResult[]>;
3
+ //# sourceMappingURL=injector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injector.d.ts","sourceRoot":"","sources":["../../src/wizard/injector.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAkB,MAAM,mBAAmB,CAAC;AAuEpF,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,EAAE,EACnB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,eAAe,EAAE,CAAC,CAiC5B"}
@@ -0,0 +1,91 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import * as clack from '@clack/prompts';
4
+ import pc from 'picocolors';
5
+ import { logSuccess, logError, logAction } from '../lib/ascii.js';
6
+ import { getConfigKey } from './detector.js';
7
+ // ─── Archer MCP Entry ───────────────────────────────────────
8
+ function buildArcherEntry(supabaseUrl, serviceRoleKey) {
9
+ return {
10
+ command: 'npx',
11
+ args: ['-y', 'archer', '--mcp'],
12
+ env: {
13
+ SUPABASE_URL: supabaseUrl,
14
+ SUPABASE_SERVICE_ROLE_KEY: serviceRoleKey,
15
+ },
16
+ };
17
+ }
18
+ // ─── Read or Create Config ──────────────────────────────────
19
+ function readConfig(configPath) {
20
+ try {
21
+ if (fs.existsSync(configPath)) {
22
+ const content = fs.readFileSync(configPath, 'utf-8');
23
+ return JSON.parse(content);
24
+ }
25
+ }
26
+ catch {
27
+ // Parse error or read error — start fresh
28
+ }
29
+ return {};
30
+ }
31
+ function writeConfig(configPath, config) {
32
+ const dir = path.dirname(configPath);
33
+ if (!fs.existsSync(dir)) {
34
+ fs.mkdirSync(dir, { recursive: true });
35
+ }
36
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
37
+ }
38
+ // ─── Inject Into Single Agent ───────────────────────────────
39
+ function injectIntoAgent(agent, supabaseUrl, serviceRoleKey) {
40
+ try {
41
+ const configKey = getConfigKey(agent.name);
42
+ const config = readConfig(agent.configPath);
43
+ const archerEntry = buildArcherEntry(supabaseUrl, serviceRoleKey);
44
+ // Ensure the config key object exists
45
+ if (!config[configKey] || typeof config[configKey] !== 'object') {
46
+ config[configKey] = {};
47
+ }
48
+ // Inject archer entry without overwriting other servers
49
+ const servers = config[configKey];
50
+ servers['archer'] = archerEntry;
51
+ writeConfig(agent.configPath, config);
52
+ logSuccess(`injected into ${pc.bold(agent.name)} → ${agent.configPath}`);
53
+ return { agent: agent.name, success: true };
54
+ }
55
+ catch (err) {
56
+ const message = err instanceof Error ? err.message : String(err);
57
+ logError(`failed to inject into ${agent.name}: ${message}`);
58
+ return { agent: agent.name, success: false, error: message };
59
+ }
60
+ }
61
+ // ─── Main Injector ──────────────────────────────────────────
62
+ export async function injectIntoAgents(agents, supabaseUrl, serviceRoleKey) {
63
+ if (agents.length === 0) {
64
+ logError('no AI agents detected on this system');
65
+ return [];
66
+ }
67
+ // Display found agents
68
+ console.log();
69
+ logAction('detected agents:');
70
+ for (const agent of agents) {
71
+ console.log(` ${pc.dim('·')} ${pc.bold(agent.name)}`);
72
+ }
73
+ console.log();
74
+ // Single confirmation
75
+ const shouldInject = await clack.confirm({
76
+ message: `inject archer into ${agents.length} agent${agents.length !== 1 ? 's' : ''}?`,
77
+ initialValue: true,
78
+ });
79
+ if (clack.isCancel(shouldInject) || !shouldInject) {
80
+ logAction('skipped injection');
81
+ return [];
82
+ }
83
+ // Inject into all confirmed agents
84
+ const results = [];
85
+ for (const agent of agents) {
86
+ const result = injectIntoAgent(agent, supabaseUrl, serviceRoleKey);
87
+ results.push(result);
88
+ }
89
+ return results;
90
+ }
91
+ //# sourceMappingURL=injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injector.js","sourceRoot":"","sources":["../../src/wizard/injector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { AgentInfo } from '../types/index.js';
2
+ export declare function injectRules(agents: AgentInfo[], cwd: string): void;
3
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/wizard/rules.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAuGnD,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAIlE"}