archer-wizard 0.2.0 → 0.2.2
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/ARCHITECTURE.md +378 -0
- package/README.md +72 -46
- package/dist/lib/ascii.js +1 -1
- package/dist/lib/ascii.js.map +1 -1
- package/dist/types/index.d.ts +1 -5
- package/dist/types/index.d.ts.map +1 -1
- package/dist/wizard/detector.js +3 -3
- package/dist/wizard/detector.js.map +1 -1
- package/dist/wizard/index.d.ts.map +1 -1
- package/dist/wizard/index.js +57 -23
- package/dist/wizard/index.js.map +1 -1
- package/dist/wizard/injector.d.ts.map +1 -1
- package/dist/wizard/injector.js +17 -7
- package/dist/wizard/injector.js.map +1 -1
- package/dist/wizard/rules.d.ts.map +1 -1
- package/dist/wizard/rules.js +50 -28
- package/dist/wizard/rules.js.map +1 -1
- package/dist/wizard/scanner.d.ts.map +1 -1
- package/dist/wizard/scanner.js +0 -23
- package/dist/wizard/scanner.js.map +1 -1
- package/package.json +1 -1
- package/src/lib/ascii.ts +1 -1
- package/src/types/index.ts +1 -5
- package/src/wizard/detector.ts +3 -3
- package/src/wizard/index.ts +54 -24
- package/src/wizard/injector.ts +23 -7
- package/src/wizard/rules.ts +50 -28
- package/src/wizard/scanner.ts +0 -23
package/src/wizard/injector.ts
CHANGED
|
@@ -6,16 +6,32 @@ import { logSuccess, logError, logAction } from '../lib/ascii.js';
|
|
|
6
6
|
import { getConfigKey } from './detector.js';
|
|
7
7
|
import type { AgentInfo, InjectionResult, McpServerEntry } from '../types/index.js';
|
|
8
8
|
|
|
9
|
-
// ─── Archer MCP Entry
|
|
9
|
+
// ─── Archer MCP Entry (agent-aware) ─────────────────────────
|
|
10
10
|
|
|
11
|
-
function buildArcherEntry(
|
|
11
|
+
function buildArcherEntry(
|
|
12
|
+
agentName: string,
|
|
13
|
+
supabaseUrl: string,
|
|
14
|
+
serviceRoleKey: string,
|
|
15
|
+
): McpServerEntry {
|
|
16
|
+
const envVars = {
|
|
17
|
+
SUPABASE_URL: supabaseUrl,
|
|
18
|
+
SUPABASE_SERVICE_ROLE_KEY: serviceRoleKey,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// opencode uses { type, command[], environment }
|
|
22
|
+
if (agentName === 'opencode') {
|
|
23
|
+
return {
|
|
24
|
+
type: 'local',
|
|
25
|
+
command: ['npx', '-y', 'archer-wizard@latest', '--mcp'],
|
|
26
|
+
environment: envVars,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// cursor, claude-code, windsurf, antigravity use { command, args, env }
|
|
12
31
|
return {
|
|
13
32
|
command: 'npx',
|
|
14
33
|
args: ['-y', 'archer-wizard@latest', '--mcp'],
|
|
15
|
-
env:
|
|
16
|
-
SUPABASE_URL: supabaseUrl,
|
|
17
|
-
SUPABASE_SERVICE_ROLE_KEY: serviceRoleKey,
|
|
18
|
-
},
|
|
34
|
+
env: envVars,
|
|
19
35
|
};
|
|
20
36
|
}
|
|
21
37
|
|
|
@@ -51,7 +67,7 @@ function injectIntoAgent(
|
|
|
51
67
|
try {
|
|
52
68
|
const configKey = getConfigKey(agent.name);
|
|
53
69
|
const config = readConfig(agent.configPath);
|
|
54
|
-
const archerEntry = buildArcherEntry(supabaseUrl, serviceRoleKey);
|
|
70
|
+
const archerEntry = buildArcherEntry(agent.name, supabaseUrl, serviceRoleKey);
|
|
55
71
|
|
|
56
72
|
// Ensure the config key object exists
|
|
57
73
|
if (!config[configKey] || typeof config[configKey] !== 'object') {
|
package/src/wizard/rules.ts
CHANGED
|
@@ -9,53 +9,75 @@ import type { AgentInfo } from '../types/index.js';
|
|
|
9
9
|
const RULE_CONTENT = `
|
|
10
10
|
# Archer — Event Intelligence for AI Agents
|
|
11
11
|
|
|
12
|
-
Archer is the event intelligence layer for AI agents. It
|
|
12
|
+
Archer is the universal event intelligence layer for AI agents. It watches your data sources in real time, detects changes the moment they happen, and delivers full context to your webhook — so your agent can react instantly, without polling.
|
|
13
13
|
|
|
14
|
-
## Available
|
|
14
|
+
## Available MCP Tools
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
### archer_watch
|
|
17
|
+
Create a persistent real-time watch on a data source. Watches survive agent session restarts.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
**Parameters:**
|
|
20
|
+
- **table** *(required)* — name of the table or resource to watch
|
|
21
|
+
- **event** — type of change: \`INSERT\`, \`UPDATE\`, \`DELETE\`, or \`*\` (all). Default: \`*\`
|
|
22
|
+
- **filter** — optional filter expression, e.g. \`"status=eq.active"\` or \`"amount=gt.1000"\`
|
|
23
|
+
- **webhookUrl** — URL to receive a POST with full event payload when a match fires
|
|
19
24
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- Watch for new user signups
|
|
23
|
-
- React to events in external services
|
|
24
|
-
- Automate responses to data changes
|
|
25
|
-
- Set up real-time notifications
|
|
25
|
+
### archer_unwatch
|
|
26
|
+
Remove an active watch by its ID. Stops listening and cleans up.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
**Parameters:**
|
|
29
|
+
- **watchId** *(required)* — the watch ID returned by \`archer_watch\`
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- **table**: the table name (required for table events)
|
|
32
|
-
- **condition**: optional filter like \`"email ends with @gmail.com"\`
|
|
33
|
-
- **webhookUrl**: URL to receive POST notifications when events match
|
|
31
|
+
### archer_watches
|
|
32
|
+
List all active watches — their IDs, tables, events, filters, and webhook URLs.
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
## When to Use Archer
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
Use Archer any time the user wants to:
|
|
37
|
+
- **Monitor data changes** — new rows, updates, deletions in any table
|
|
38
|
+
- **React to events** — trigger automations when conditions are met
|
|
39
|
+
- **Set up alerts** — notify on signups, new orders, status changes, threshold breaches
|
|
40
|
+
- **Build event-driven workflows** — chain watches with webhooks for real-time pipelines
|
|
41
|
+
- **Track activity** — audit logs, user actions, system events
|
|
42
|
+
|
|
43
|
+
## Examples
|
|
44
|
+
|
|
45
|
+
1. Watch for new rows in a table:
|
|
46
|
+
\`\`\`
|
|
47
|
+
archer_watch({ table: "users", event: "INSERT", webhookUrl: "https://hooks.example.com/new-users" })
|
|
48
|
+
\`\`\`
|
|
49
|
+
|
|
50
|
+
2. Watch for updates with a filter:
|
|
38
51
|
\`\`\`
|
|
39
|
-
|
|
52
|
+
archer_watch({ table: "orders", event: "UPDATE", filter: "status=eq.shipped", webhookUrl: "https://hooks.example.com/shipped" })
|
|
40
53
|
\`\`\`
|
|
41
54
|
|
|
42
|
-
|
|
55
|
+
3. Watch all changes on a table:
|
|
43
56
|
\`\`\`
|
|
44
|
-
|
|
57
|
+
archer_watch({ table: "payments", webhookUrl: "https://hooks.example.com/payments" })
|
|
45
58
|
\`\`\`
|
|
46
59
|
|
|
47
|
-
|
|
60
|
+
4. List active watches:
|
|
48
61
|
\`\`\`
|
|
49
|
-
|
|
62
|
+
archer_watches()
|
|
50
63
|
\`\`\`
|
|
51
64
|
|
|
52
|
-
|
|
65
|
+
5. Stop a watch:
|
|
66
|
+
\`\`\`
|
|
67
|
+
archer_unwatch({ watchId: "abc-123" })
|
|
68
|
+
\`\`\`
|
|
69
|
+
|
|
70
|
+
## Best Practices
|
|
71
|
+
|
|
72
|
+
- Add filters to reduce noise — only fire on events that matter
|
|
73
|
+
- Use descriptive webhook URLs that map to specific actions
|
|
74
|
+
- Chain multiple watches for complex event-driven workflows
|
|
75
|
+
- Use \`archer_watches\` to inspect and manage active watchers
|
|
76
|
+
- Clean up watches you no longer need with \`archer_unwatch\`
|
|
53
77
|
|
|
54
|
-
|
|
55
|
-
- Add conditions to filter events and reduce noise
|
|
56
|
-
- Combine with your existing workflows for maximum impact
|
|
78
|
+
## Trigger Words
|
|
57
79
|
|
|
58
|
-
When the user
|
|
80
|
+
When the user says **"watch"**, **"monitor"**, **"notify me"**, **"alert me"**, **"track"**, **"listen for"**, or **"fire when"** — use Archer.
|
|
59
81
|
`.trim();
|
|
60
82
|
|
|
61
83
|
// ─── Archer Block Markers ───────────────────────────────────
|
package/src/wizard/scanner.ts
CHANGED
|
@@ -2,7 +2,6 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import * as clack from '@clack/prompts';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
import { logSuccess, logError, maskCredential } from '../lib/ascii.js';
|
|
6
5
|
import type { ScanResult, Framework } from '../types/index.js';
|
|
7
6
|
|
|
8
7
|
// Helper to search for keys in files
|
|
@@ -236,28 +235,6 @@ export async function scanProject(cwd: string): Promise<ScanResult> {
|
|
|
236
235
|
|
|
237
236
|
const { framework, hasSupabaseInstalled } = detectFramework(cwd);
|
|
238
237
|
|
|
239
|
-
// Log found credentials
|
|
240
|
-
if (supabaseUrl) {
|
|
241
|
-
logSuccess(`SUPABASE_URL = ${maskCredential(supabaseUrl)}`);
|
|
242
|
-
} else {
|
|
243
|
-
logError('missing SUPABASE_URL');
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
if (serviceRoleKey) {
|
|
247
|
-
logSuccess(`SUPABASE_SERVICE_ROLE_KEY = ${maskCredential(serviceRoleKey)}`);
|
|
248
|
-
} else {
|
|
249
|
-
logError('missing SUPABASE_SERVICE_ROLE_KEY');
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (anonKey) {
|
|
253
|
-
logSuccess(`SUPABASE_ANON_KEY = ${maskCredential(anonKey)}`);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
if (foundInFile) {
|
|
257
|
-
logSuccess(`found credentials in ${foundInFile}`);
|
|
258
|
-
} else if (codebaseResults.size > 0) {
|
|
259
|
-
logSuccess(`found credentials in codebase`);
|
|
260
|
-
}
|
|
261
238
|
|
|
262
239
|
return {
|
|
263
240
|
supabaseUrl,
|