suzi-cli 0.1.5 → 0.1.7

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 (76) hide show
  1. package/CLAUDE.md +2 -2
  2. package/README.md +267 -1
  3. package/dist/commands/accounts.d.ts.map +1 -1
  4. package/dist/commands/accounts.js +59 -0
  5. package/dist/commands/accounts.js.map +1 -1
  6. package/dist/commands/agents.d.ts.map +1 -1
  7. package/dist/commands/agents.js +10 -3
  8. package/dist/commands/agents.js.map +1 -1
  9. package/dist/commands/create.d.ts.map +1 -1
  10. package/dist/commands/create.js +147 -40
  11. package/dist/commands/create.js.map +1 -1
  12. package/dist/commands/deploy.d.ts.map +1 -1
  13. package/dist/commands/deploy.js +27 -2
  14. package/dist/commands/deploy.js.map +1 -1
  15. package/dist/commands/init.d.ts +3 -0
  16. package/dist/commands/init.d.ts.map +1 -0
  17. package/dist/commands/init.js +139 -0
  18. package/dist/commands/init.js.map +1 -0
  19. package/dist/commands/install-hooks.d.ts +16 -0
  20. package/dist/commands/install-hooks.d.ts.map +1 -0
  21. package/dist/commands/install-hooks.js +381 -0
  22. package/dist/commands/install-hooks.js.map +1 -0
  23. package/dist/commands/list-triggers.d.ts +3 -0
  24. package/dist/commands/list-triggers.d.ts.map +1 -0
  25. package/dist/commands/list-triggers.js +153 -0
  26. package/dist/commands/list-triggers.js.map +1 -0
  27. package/dist/commands/login.d.ts.map +1 -1
  28. package/dist/commands/login.js +78 -0
  29. package/dist/commands/login.js.map +1 -1
  30. package/dist/commands/memory.d.ts +3 -0
  31. package/dist/commands/memory.d.ts.map +1 -0
  32. package/dist/commands/memory.js +196 -0
  33. package/dist/commands/memory.js.map +1 -0
  34. package/dist/commands/portfolio.d.ts.map +1 -1
  35. package/dist/commands/portfolio.js +5 -8
  36. package/dist/commands/portfolio.js.map +1 -1
  37. package/dist/commands/prompt-suggestions.d.ts.map +1 -1
  38. package/dist/commands/prompt-suggestions.js +8 -14
  39. package/dist/commands/prompt-suggestions.js.map +1 -1
  40. package/dist/commands/share.d.ts.map +1 -1
  41. package/dist/commands/share.js +2 -0
  42. package/dist/commands/share.js.map +1 -1
  43. package/dist/commands/skills.d.ts.map +1 -1
  44. package/dist/commands/skills.js +30 -31
  45. package/dist/commands/skills.js.map +1 -1
  46. package/dist/commands/validate.d.ts +3 -0
  47. package/dist/commands/validate.d.ts.map +1 -0
  48. package/dist/commands/validate.js +165 -0
  49. package/dist/commands/validate.js.map +1 -0
  50. package/dist/index.js +40 -10
  51. package/dist/index.js.map +1 -1
  52. package/dist/lib/config.d.ts +4 -0
  53. package/dist/lib/config.d.ts.map +1 -1
  54. package/dist/lib/config.js +13 -0
  55. package/dist/lib/config.js.map +1 -1
  56. package/dist/lib/memory.d.ts +45 -0
  57. package/dist/lib/memory.d.ts.map +1 -0
  58. package/dist/lib/memory.js +247 -0
  59. package/dist/lib/memory.js.map +1 -0
  60. package/dist/lib/skills.d.ts +20 -0
  61. package/dist/lib/skills.d.ts.map +1 -0
  62. package/dist/lib/skills.js +73 -0
  63. package/dist/lib/skills.js.map +1 -0
  64. package/dist/lib/suzi-guide.d.ts +1 -1
  65. package/dist/lib/suzi-guide.d.ts.map +1 -1
  66. package/dist/lib/suzi-guide.js +154 -37
  67. package/dist/lib/suzi-guide.js.map +1 -1
  68. package/dist/utils/ui.d.ts +3 -1
  69. package/dist/utils/ui.d.ts.map +1 -1
  70. package/dist/utils/ui.js +4 -1
  71. package/dist/utils/ui.js.map +1 -1
  72. package/package.json +1 -1
  73. package/dist/commands/wallet.d.ts +0 -3
  74. package/dist/commands/wallet.d.ts.map +0 -1
  75. package/dist/commands/wallet.js +0 -191
  76. package/dist/commands/wallet.js.map +0 -1
@@ -0,0 +1,381 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.installHooksGlobal = installHooksGlobal;
7
+ exports.registerInstallHooksCommand = registerInstallHooksCommand;
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const os_1 = __importDefault(require("os"));
12
+ const ui_1 = require("../utils/ui");
13
+ const memory_1 = require("../lib/memory");
14
+ // ── Hook Script Sources (embedded — single source of truth) ────────
15
+ const HOOK_SCRIPTS = [
16
+ {
17
+ name: 'Session Start',
18
+ file: 'suzi-session-start.sh',
19
+ content: `#!/bin/bash
20
+ # Claude Code SessionStart hook
21
+ # Injects Suzi learnings, preferences, and context into Claude's context window.
22
+ # Triggered on: startup, resume, compact
23
+
24
+ SUZI_DIR="$HOME/.suzi"
25
+ OUTPUT=""
26
+
27
+ # User preferences (trading style, conventions)
28
+ if [ -f "$SUZI_DIR/preferences.md" ]; then
29
+ OUTPUT+="=== Suzi User Preferences ===
30
+ "
31
+ OUTPUT+="$(cat "$SUZI_DIR/preferences.md")
32
+
33
+ "
34
+ fi
35
+
36
+ # Recent learnings (last 50 lines to stay within context budget)
37
+ if [ -f "$SUZI_DIR/memory/LEARNINGS.md" ]; then
38
+ CONTENT="$(tail -50 "$SUZI_DIR/memory/LEARNINGS.md")"
39
+ if [ -n "$CONTENT" ]; then
40
+ OUTPUT+="=== Suzi Learnings (Recent) ===
41
+ "
42
+ OUTPUT+="$CONTENT
43
+
44
+ "
45
+ fi
46
+ fi
47
+
48
+ # Active context (recent agents, wallet state)
49
+ if [ -f "$SUZI_DIR/memory/context.md" ]; then
50
+ OUTPUT+="=== Suzi Active Context ===
51
+ "
52
+ OUTPUT+="$(cat "$SUZI_DIR/memory/context.md")
53
+
54
+ "
55
+ fi
56
+
57
+ # Project-level SUZI.md
58
+ PROJECT_SUZI="\${CLAUDE_PROJECT_DIR:-$(pwd)}/SUZI.md"
59
+ if [ -f "$PROJECT_SUZI" ]; then
60
+ OUTPUT+="=== Project Suzi Config ===
61
+ "
62
+ OUTPUT+="$(cat "$PROJECT_SUZI")
63
+
64
+ "
65
+ fi
66
+
67
+ if [ -n "$OUTPUT" ]; then
68
+ echo "$OUTPUT"
69
+ fi
70
+ `,
71
+ },
72
+ {
73
+ name: 'CLI Capture',
74
+ file: 'suzi-capture-cli.sh',
75
+ content: `#!/bin/bash
76
+ # Claude Code PostToolUse hook (async)
77
+ # Captures suzi CLI command outcomes to daily log and learnings.
78
+ # Only processes commands containing "suzi ".
79
+
80
+ MAX_LEARNINGS=500
81
+ LOCK_TIMEOUT=5
82
+
83
+ INPUT=$(cat)
84
+ CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
85
+
86
+ # Only process suzi commands
87
+ [[ "$CMD" != *"suzi "* ]] && exit 0
88
+
89
+ # Redact sensitive flags and JWT tokens from the command before logging
90
+ SAFE_CMD=$(echo "$CMD" | sed -E \\
91
+ -e 's/(--)(token|key|secret|password|auth|credential|private[-_]?[a-zA-Z]*)[= ][^ ]*/\\1\\2 <REDACTED>/gi' \\
92
+ -e 's/eyJ[A-Za-z0-9_-]+\\.eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+/<TOKEN>/g')
93
+
94
+ RESULT=$(echo "$INPUT" | jq -r '.tool_result // empty' 2>/dev/null)
95
+ DATE=$(date +%Y-%m-%d)
96
+ TIME=$(date +%H:%M)
97
+ MEMORY_DIR="$HOME/.suzi/memory"
98
+ DAILY_DIR="$MEMORY_DIR/daily"
99
+ DAILY="$DAILY_DIR/$DATE.md"
100
+ LEARNINGS="$MEMORY_DIR/LEARNINGS.md"
101
+ LOCKDIR="$LEARNINGS.lock"
102
+
103
+ mkdir -p "$DAILY_DIR"
104
+
105
+ # Log sanitized command to daily activity
106
+ if [ ! -f "$DAILY" ]; then
107
+ echo "# $DATE" > "$DAILY"
108
+ echo "" >> "$DAILY"
109
+ fi
110
+ echo "- [$TIME] \\\`$SAFE_CMD\\\`" >> "$DAILY"
111
+
112
+ # Capture errors as learnings (only the error message, not full output)
113
+ if echo "$RESULT" | grep -qiE "error|failed|exception|ENOENT|timeout"; then
114
+ ERROR_LINE=$(echo "$RESULT" | grep -iE "error|failed|exception" | head -1 | cut -c1-200)
115
+ # Redact any secrets that might appear in error output
116
+ SAFE_ERROR=$(echo "$ERROR_LINE" | sed -E \\
117
+ -e 's/eyJ[A-Za-z0-9_-]+\\.eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+/<TOKEN>/g' \\
118
+ -e 's/(0x)?[0-9a-fA-F]{64}/<KEY>/g')
119
+
120
+ if [ -n "$SAFE_ERROR" ]; then
121
+ NEW_LINE="- **$DATE**: \\\`error\\\` — $SAFE_ERROR (cmd: \\\`$SAFE_CMD\\\`)"
122
+
123
+ # Acquire lock (mkdir is atomic on all POSIX systems)
124
+ TRIES=0
125
+ while ! mkdir "$LOCKDIR" 2>/dev/null; do
126
+ TRIES=$((TRIES + 1))
127
+ if [ "$TRIES" -ge "$LOCK_TIMEOUT" ]; then
128
+ # Stale lock — force remove and retry once
129
+ rmdir "$LOCKDIR" 2>/dev/null
130
+ mkdir "$LOCKDIR" 2>/dev/null && break
131
+ exit 0
132
+ fi
133
+ sleep 1
134
+ done
135
+
136
+ # Ensure lock is released on exit or failure
137
+ trap 'rmdir "$LOCKDIR" 2>/dev/null' EXIT
138
+
139
+ # Dedup: skip if identical message already in last 20 lines
140
+ if [ -f "$LEARNINGS" ]; then
141
+ if tail -20 "$LEARNINGS" | grep -qF "$SAFE_ERROR"; then
142
+ exit 0
143
+ fi
144
+ fi
145
+
146
+ echo "$NEW_LINE" >> "$LEARNINGS"
147
+
148
+ # Trim to max lines (keep newest) using unique temp file
149
+ if [ -f "$LEARNINGS" ]; then
150
+ LINE_COUNT=$(wc -l < "$LEARNINGS")
151
+ if [ "$LINE_COUNT" -gt "$MAX_LEARNINGS" ]; then
152
+ TMPFILE=$(mktemp "$LEARNINGS.XXXXXX")
153
+ tail -n "$MAX_LEARNINGS" "$LEARNINGS" > "$TMPFILE" && mv "$TMPFILE" "$LEARNINGS"
154
+ fi
155
+ fi
156
+ fi
157
+ fi
158
+ `,
159
+ },
160
+ {
161
+ name: 'Pre-Compact',
162
+ file: 'suzi-pre-compact.sh',
163
+ content: `#!/bin/bash
164
+ # Claude Code PreCompact hook
165
+ # Saves Suzi-related state before context window compression.
166
+
167
+ CONTEXT="$HOME/.suzi/memory/context.md"
168
+ MEMORY_DIR="$HOME/.suzi/memory"
169
+
170
+ mkdir -p "$MEMORY_DIR"
171
+
172
+ echo "## Active Context" > "$CONTEXT"
173
+ echo "" >> "$CONTEXT"
174
+ echo "_Auto-saved before compaction: $(date -Iseconds)_" >> "$CONTEXT"
175
+ echo "" >> "$CONTEXT"
176
+
177
+ # Save today's activity log summary if it exists
178
+ DATE=$(date +%Y-%m-%d)
179
+ DAILY="$MEMORY_DIR/daily/$DATE.md"
180
+ if [ -f "$DAILY" ]; then
181
+ echo "### Today's Activity" >> "$CONTEXT"
182
+ tail -20 "$DAILY" >> "$CONTEXT"
183
+ echo "" >> "$CONTEXT"
184
+ fi
185
+ `,
186
+ },
187
+ ];
188
+ const PREFERENCES_TEMPLATE = `# Suzi Preferences
189
+
190
+ ## Trading Style
191
+ <!-- Define your risk preferences -->
192
+ <!-- Example:
193
+ - Conservative: max 5% per position
194
+ - Prefer high-liquidity markets
195
+ - Always set stop-losses
196
+ -->
197
+
198
+ ## Protocol Preferences
199
+ <!-- Which protocols and chains do you prefer? -->
200
+ <!-- Example:
201
+ - Primary: Polymarket
202
+ - Chain: EVM
203
+ -->
204
+
205
+ ## Agent Conventions
206
+ <!-- Any patterns you want all your agents to follow -->
207
+ <!-- Example:
208
+ - Always log on activate/deactivate
209
+ - Include a kill switch for drawdown > 10%
210
+ - Use 5-minute cron intervals minimum
211
+ -->
212
+ `;
213
+ const HOOK_CONFIG = {
214
+ hooks: {
215
+ SessionStart: [
216
+ {
217
+ matcher: 'startup|resume|compact',
218
+ hooks: [
219
+ {
220
+ type: 'command',
221
+ command: '$HOME/.claude/hooks/suzi-session-start.sh',
222
+ },
223
+ ],
224
+ },
225
+ ],
226
+ PostToolUse: [
227
+ {
228
+ matcher: 'Bash',
229
+ hooks: [
230
+ {
231
+ type: 'command',
232
+ command: '$HOME/.claude/hooks/suzi-capture-cli.sh',
233
+ async: true,
234
+ },
235
+ ],
236
+ },
237
+ ],
238
+ PreCompact: [
239
+ {
240
+ hooks: [
241
+ {
242
+ type: 'command',
243
+ command: '$HOME/.claude/hooks/suzi-pre-compact.sh',
244
+ },
245
+ ],
246
+ },
247
+ ],
248
+ },
249
+ };
250
+ // ── Core Logic (reusable) ─────────────────────────────────────────
251
+ function writeScript(filePath, content) {
252
+ const dir = path_1.default.dirname(filePath);
253
+ if (!fs_1.default.existsSync(dir)) {
254
+ fs_1.default.mkdirSync(dir, { recursive: true });
255
+ }
256
+ if (fs_1.default.existsSync(filePath)) {
257
+ const existing = fs_1.default.readFileSync(filePath, 'utf-8');
258
+ if (existing === content)
259
+ return 'unchanged';
260
+ fs_1.default.writeFileSync(filePath, content, { mode: 0o755 });
261
+ return 'updated';
262
+ }
263
+ fs_1.default.writeFileSync(filePath, content, { mode: 0o755 });
264
+ return 'installed';
265
+ }
266
+ function mergeSettings(settingsPath, hookConfig) {
267
+ let existing = {};
268
+ if (fs_1.default.existsSync(settingsPath)) {
269
+ try {
270
+ existing = JSON.parse(fs_1.default.readFileSync(settingsPath, 'utf-8'));
271
+ }
272
+ catch {
273
+ existing = {};
274
+ }
275
+ }
276
+ // Merge hooks — preserve existing hooks, add Suzi ones
277
+ if (!existing.hooks) {
278
+ existing.hooks = {};
279
+ }
280
+ for (const [event, entries] of Object.entries(hookConfig.hooks)) {
281
+ if (!existing.hooks[event]) {
282
+ existing.hooks[event] = entries;
283
+ }
284
+ else {
285
+ // Check if suzi hooks already present
286
+ const existingCommands = existing.hooks[event]
287
+ .flatMap((e) => (e.hooks || []).map((h) => h.command));
288
+ for (const entry of entries) {
289
+ const newCommands = entry.hooks.map((h) => h.command);
290
+ const alreadyPresent = newCommands.every((cmd) => existingCommands.includes(cmd));
291
+ if (!alreadyPresent) {
292
+ existing.hooks[event].push(entry);
293
+ }
294
+ }
295
+ }
296
+ }
297
+ const dir = path_1.default.dirname(settingsPath);
298
+ if (!fs_1.default.existsSync(dir)) {
299
+ fs_1.default.mkdirSync(dir, { recursive: true });
300
+ }
301
+ fs_1.default.writeFileSync(settingsPath, JSON.stringify(existing, null, 2));
302
+ }
303
+ /**
304
+ * Install Suzi hooks globally to ~/.claude/.
305
+ * Can be called programmatically (e.g. during login onboarding) or via the CLI command.
306
+ */
307
+ function installHooksGlobal() {
308
+ const home = os_1.default.homedir();
309
+ const hooksDir = path_1.default.join(home, '.claude', 'hooks');
310
+ // 1. Write hook scripts
311
+ const scripts = HOOK_SCRIPTS.map((script) => {
312
+ const filePath = path_1.default.join(hooksDir, script.file);
313
+ const state = writeScript(filePath, script.content);
314
+ return { name: script.name, state };
315
+ });
316
+ // 2. Merge settings
317
+ const settingsPath = path_1.default.join(home, '.claude', 'settings.json');
318
+ mergeSettings(settingsPath, HOOK_CONFIG);
319
+ // 3. Ensure memory directories
320
+ const memoryDir = (0, memory_1.getMemoryDir)();
321
+ const dailyDir = path_1.default.join(memoryDir, 'daily');
322
+ let memoryCreated = false;
323
+ if (!fs_1.default.existsSync(dailyDir)) {
324
+ fs_1.default.mkdirSync(dailyDir, { recursive: true });
325
+ memoryCreated = true;
326
+ }
327
+ return { scripts, settingsMerged: true, memoryCreated };
328
+ }
329
+ // ── CLI Command ───────────────────────────────────────────────────
330
+ function registerInstallHooksCommand(program) {
331
+ program
332
+ .command('install-hooks')
333
+ .description('Install Claude Code hooks for auto-context injection')
334
+ .option('--preferences', 'Also create a starter preferences.md file')
335
+ .action((opts) => {
336
+ (0, ui_1.header)('Install Suzi Hooks (Global)');
337
+ console.log();
338
+ const result = installHooksGlobal();
339
+ const lines = [];
340
+ for (const s of result.scripts) {
341
+ const icon = s.state === 'installed' ? chalk_1.default.green('✓') : s.state === 'updated' ? chalk_1.default.yellow('↑') : chalk_1.default.gray('–');
342
+ lines.push(` ${icon} ${s.name} hook: ${s.state}`);
343
+ }
344
+ lines.push(` ${chalk_1.default.green('✓')} ~/.claude/settings.json: hooks configured`);
345
+ if (result.memoryCreated) {
346
+ lines.push(` ${chalk_1.default.green('✓')} ~/.suzi/memory/daily/: created`);
347
+ }
348
+ else {
349
+ lines.push(` ${chalk_1.default.gray('–')} ~/.suzi/memory/: already exists`);
350
+ }
351
+ // Optionally create preferences.md
352
+ if (opts.preferences) {
353
+ const prefsPath = path_1.default.join(os_1.default.homedir(), '.suzi', 'preferences.md');
354
+ if (!fs_1.default.existsSync(prefsPath)) {
355
+ fs_1.default.writeFileSync(prefsPath, PREFERENCES_TEMPLATE);
356
+ lines.push(` ${chalk_1.default.green('✓')} ~/.suzi/preferences.md: created`);
357
+ }
358
+ else {
359
+ lines.push(` ${chalk_1.default.gray('–')} ~/.suzi/preferences.md: already exists`);
360
+ }
361
+ }
362
+ for (const line of lines) {
363
+ console.log(line);
364
+ }
365
+ console.log();
366
+ (0, ui_1.divider)();
367
+ console.log();
368
+ (0, ui_1.success)('Global hooks installed!');
369
+ console.log();
370
+ (0, ui_1.info)('Hooks installed to ~/.claude/hooks/ — active in all projects.');
371
+ (0, ui_1.info)('Claude Code will now auto-inject Suzi context on session start.');
372
+ (0, ui_1.info)('CLI command outcomes will be captured to learnings (async).');
373
+ (0, ui_1.info)('Context will be preserved before compaction.');
374
+ if (!opts.preferences) {
375
+ console.log();
376
+ (0, ui_1.info)(`Tip: Run ${chalk_1.default.cyan('suzi install-hooks --preferences')} to create a preferences file.`);
377
+ }
378
+ console.log();
379
+ });
380
+ }
381
+ //# sourceMappingURL=install-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-hooks.js","sourceRoot":"","sources":["../../src/commands/install-hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerListTriggersCommand(program: Command): void;
3
+ //# sourceMappingURL=list-triggers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-triggers.d.ts","sourceRoot":"","sources":["../../src/commands/list-triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwCpC,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8IlE"}
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerListTriggersCommand = registerListTriggersCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const ui_1 = require("../utils/ui");
10
+ const api_1 = require("../lib/api");
11
+ function groupByProtocol(triggers) {
12
+ const groups = new Map();
13
+ for (const trigger of triggers) {
14
+ const group = groups.get(trigger.protocol) ?? [];
15
+ group.push(trigger);
16
+ groups.set(trigger.protocol, group);
17
+ }
18
+ return groups;
19
+ }
20
+ function formatConfigFields(schema) {
21
+ const properties = (schema?.properties ?? {});
22
+ const required = (schema?.required ?? []);
23
+ const lines = [];
24
+ for (const [name, prop] of Object.entries(properties)) {
25
+ const type = prop.type ?? 'unknown';
26
+ const isRequired = required.includes(name);
27
+ const tag = isRequired ? chalk_1.default.yellow('required') : ui_1.colors.muted('optional');
28
+ const desc = prop.description ? ` ${ui_1.colors.muted(prop.description)}` : '';
29
+ lines.push(` ${ui_1.colors.highlight(name)} ${ui_1.colors.muted(`(${type})`)} [${tag}]${desc}`);
30
+ }
31
+ return lines;
32
+ }
33
+ function registerListTriggersCommand(program) {
34
+ program
35
+ .command('list-triggers')
36
+ .alias('triggers')
37
+ .description('List all available triggers')
38
+ .option('--protocol <name>', 'Filter by protocol name')
39
+ .option('--verbose', 'Show config fields for each trigger')
40
+ .option('--schema <trigger>', 'Show JSON schema for a specific trigger (requires --protocol)')
41
+ .action(async (opts) => {
42
+ if (!(0, ui_1.requireAuth)())
43
+ return;
44
+ const spinner = (0, ora_1.default)('Fetching triggers...').start();
45
+ try {
46
+ const queryParams = opts.protocol ? `?protocol=${encodeURIComponent(opts.protocol)}` : '';
47
+ const res = await (0, api_1.get)(`/api/triggers${queryParams}`);
48
+ if (!res.ok || !res.data?.ok) {
49
+ spinner.fail('Failed to fetch triggers');
50
+ (0, ui_1.error)(res.data?.error ?? `API returned status ${res.status}`);
51
+ return;
52
+ }
53
+ const triggers = res.data.triggers;
54
+ const grouped = groupByProtocol(triggers);
55
+ if (opts.protocol && !grouped.has(opts.protocol)) {
56
+ // Fetch unfiltered list to show available protocols
57
+ const allRes = await (0, api_1.get)('/api/triggers');
58
+ const allProtocols = allRes.ok && allRes.data?.triggers
59
+ ? Array.from(groupByProtocol(allRes.data.triggers).keys())
60
+ : [];
61
+ spinner.fail(`Protocol "${opts.protocol}" not found`);
62
+ process.exitCode = 1;
63
+ if (allProtocols.length > 0) {
64
+ (0, ui_1.info)(`Available: ${allProtocols.join(', ')}`);
65
+ }
66
+ return;
67
+ }
68
+ // --schema: dump raw JSON schema for a single trigger
69
+ if (opts.schema) {
70
+ if (!opts.protocol) {
71
+ spinner.fail('Missing --protocol');
72
+ (0, ui_1.error)('--schema requires --protocol. Example: suzi list-triggers --protocol polymarket --schema price_change');
73
+ return;
74
+ }
75
+ const protocolTriggers = grouped.get(opts.protocol);
76
+ if (!protocolTriggers) {
77
+ spinner.fail(`Protocol "${opts.protocol}" not found.`);
78
+ process.exitCode = 1;
79
+ (0, ui_1.info)(`Available: ${Array.from(grouped.keys()).join(', ')}`);
80
+ return;
81
+ }
82
+ const fullName = `${opts.protocol}.${opts.schema}`;
83
+ const match = protocolTriggers.find((t) => t.name === fullName);
84
+ if (!match) {
85
+ spinner.fail(`Trigger "${opts.schema}" not found in ${opts.protocol}.`);
86
+ process.exitCode = 1;
87
+ (0, ui_1.info)('Available triggers:');
88
+ for (const t of protocolTriggers) {
89
+ const short = t.name.includes('.') ? t.name.split('.')[1] : t.name;
90
+ console.log(` ${ui_1.colors.highlight(short)} ${ui_1.colors.muted(t.description)}`);
91
+ }
92
+ return;
93
+ }
94
+ spinner.succeed(`Schema for ${opts.protocol}.${opts.schema}`);
95
+ console.log(JSON.stringify(match.configSchema, null, 2));
96
+ return;
97
+ }
98
+ // Default: list protocols and triggers
99
+ spinner.succeed('Triggers loaded');
100
+ console.log();
101
+ (0, ui_1.header)('Available Triggers');
102
+ console.log();
103
+ const showDetails = opts.verbose || opts.protocol;
104
+ const protocols = opts.protocol
105
+ ? [[opts.protocol, grouped.get(opts.protocol)]]
106
+ : Array.from(grouped.entries());
107
+ for (const [protocol, protocolTriggers] of protocols) {
108
+ if (!protocolTriggers)
109
+ continue;
110
+ console.log(` ${ui_1.colors.highlight(protocol)}`);
111
+ console.log();
112
+ for (const trigger of protocolTriggers) {
113
+ const shortName = trigger.name.includes('.') ? trigger.name.split('.')[1] : trigger.name;
114
+ console.log(` ${ui_1.colors.highlight(shortName)} ${ui_1.colors.muted(trigger.description)}`);
115
+ if (showDetails) {
116
+ const fieldLines = formatConfigFields(trigger.configSchema);
117
+ if (fieldLines.length > 0) {
118
+ console.log(` ${chalk_1.default.cyan('Config:')}`);
119
+ for (const line of fieldLines) {
120
+ console.log(line);
121
+ }
122
+ }
123
+ if (trigger.example) {
124
+ console.log(` ${chalk_1.default.cyan('Example:')}`);
125
+ for (const line of trigger.example.split('\n')) {
126
+ console.log(` ${ui_1.colors.muted(line)}`);
127
+ }
128
+ }
129
+ console.log();
130
+ }
131
+ }
132
+ if (!showDetails) {
133
+ console.log();
134
+ }
135
+ }
136
+ (0, ui_1.divider)();
137
+ (0, ui_1.info)(`${grouped.size} protocols, ${triggers.length} total triggers`);
138
+ if (!opts.verbose && !opts.protocol) {
139
+ (0, ui_1.info)('Use --verbose or --protocol <name> for details.');
140
+ }
141
+ (0, ui_1.info)(`Use ${chalk_1.default.cyan('suzi list-triggers --protocol <name> --schema <trigger>')} to view schema.`);
142
+ console.log();
143
+ (0, ui_1.info)('Usage in agent code:');
144
+ console.log(` ${ui_1.colors.muted('on.<protocol>.<trigger>(handler)')}`);
145
+ console.log(` ${ui_1.colors.muted('on.<protocol>.<trigger>(config, handler)')}`);
146
+ }
147
+ catch (err) {
148
+ spinner.fail();
149
+ (0, ui_1.error)(`Failed to fetch triggers: ${err.message}`);
150
+ }
151
+ });
152
+ }
153
+ //# sourceMappingURL=list-triggers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-triggers.js","sourceRoot":"","sources":["../../src/commands/list-triggers.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyI3D"}
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6I3D"}
@@ -9,7 +9,11 @@ const ora_1 = __importDefault(require("ora"));
9
9
  const open_1 = __importDefault(require("open"));
10
10
  const express_1 = __importDefault(require("express"));
11
11
  const qrcode_terminal_1 = __importDefault(require("qrcode-terminal"));
12
+ const inquirer_1 = __importDefault(require("inquirer"));
12
13
  const config_1 = require("../lib/config");
14
+ const suzi_guide_1 = require("../lib/suzi-guide");
15
+ const skills_1 = require("../lib/skills");
16
+ const install_hooks_1 = require("./install-hooks");
13
17
  const api_1 = require("../lib/api");
14
18
  const ui_1 = require("../utils/ui");
15
19
  /**
@@ -80,6 +84,9 @@ function registerLoginCommand(program) {
80
84
  }
81
85
  (0, ui_1.divider)();
82
86
  console.log();
87
+ await maybePromptForDefaultAi();
88
+ installSuziSkillForAllClients();
89
+ installSuziHooksGlobal();
83
90
  // Onboarding: show wallet QR and wait for deposit
84
91
  if (activeAcc?.svmWalletAddress) {
85
92
  await onboardNewUser(activeAcc.svmWalletAddress);
@@ -147,6 +154,77 @@ function generateQR(text) {
147
154
  });
148
155
  });
149
156
  }
157
+ async function maybePromptForDefaultAi() {
158
+ if ((0, config_1.getDefaultAi)())
159
+ return;
160
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
161
+ (0, config_1.setDefaultAi)('claude');
162
+ (0, ui_1.info)('Default AI set to Claude Code (non-interactive session).');
163
+ return;
164
+ }
165
+ const { defaultAi } = await inquirer_1.default.prompt([
166
+ {
167
+ type: 'list',
168
+ name: 'defaultAi',
169
+ message: 'Choose your default AI for `suzi create`:',
170
+ default: 'claude',
171
+ choices: [
172
+ { name: 'Claude Code', value: 'claude' },
173
+ { name: 'Codex', value: 'codex' },
174
+ ],
175
+ },
176
+ ]);
177
+ (0, config_1.setDefaultAi)(defaultAi);
178
+ const labelText = defaultAi === 'claude' ? 'Claude Code' : 'Codex';
179
+ (0, ui_1.success)(`Default AI set to ${chalk_1.default.bold(labelText)}.`);
180
+ (0, ui_1.info)('Change this anytime with `suzi create --set-default claude|codex`.');
181
+ console.log();
182
+ }
183
+ function installSuziSkillForAllClients() {
184
+ const targets = (0, skills_1.getDefaultSkillTargets)();
185
+ const outcomes = [];
186
+ for (const target of targets) {
187
+ try {
188
+ const result = (0, skills_1.installSkillToTarget)(target, 'suzi-guide', suzi_guide_1.SUZI_GUIDE_CONTENT, 'missing-only');
189
+ if (result.state === 'installed') {
190
+ outcomes.push(`${target.label}: installed`);
191
+ }
192
+ else if (result.state === 'skipped-existing') {
193
+ outcomes.push(`${target.label}: skipped existing`);
194
+ }
195
+ else {
196
+ outcomes.push(`${target.label}: ${result.state}`);
197
+ }
198
+ }
199
+ catch (err) {
200
+ (0, ui_1.warn)(`Could not install suzi-guide for ${target.label}: ${err?.message || 'Unknown error'}`);
201
+ }
202
+ }
203
+ if (outcomes.length > 0) {
204
+ (0, ui_1.info)(`Suzi skill sync complete (${outcomes.join(', ')}).`);
205
+ }
206
+ }
207
+ function installSuziHooksGlobal() {
208
+ try {
209
+ const result = (0, install_hooks_1.installHooksGlobal)();
210
+ const installed = result.scripts.filter((s) => s.state === 'installed').length;
211
+ const updated = result.scripts.filter((s) => s.state === 'updated').length;
212
+ if (installed > 0 || updated > 0) {
213
+ const parts = [];
214
+ if (installed > 0)
215
+ parts.push(`${installed} installed`);
216
+ if (updated > 0)
217
+ parts.push(`${updated} updated`);
218
+ (0, ui_1.info)(`Suzi hooks: ${parts.join(', ')} → ~/.claude/hooks/`);
219
+ }
220
+ else {
221
+ (0, ui_1.info)('Suzi hooks: up to date.');
222
+ }
223
+ }
224
+ catch (err) {
225
+ (0, ui_1.warn)(`Could not install hooks: ${err?.message || 'Unknown error'}`);
226
+ }
227
+ }
150
228
  async function onboardNewUser(walletAddress) {
151
229
  console.log(ui_1.colors.primary.bold(' Fund your wallet to get started'));
152
230
  console.log();