@stackmemoryai/stackmemory 0.5.3 → 0.5.5

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 (37) hide show
  1. package/bin/claude-sm +6 -0
  2. package/bin/claude-smd +6 -0
  3. package/dist/cli/claude-sm-danger.js +20 -0
  4. package/dist/cli/claude-sm-danger.js.map +7 -0
  5. package/dist/cli/commands/api.js +228 -0
  6. package/dist/cli/commands/api.js.map +7 -0
  7. package/dist/cli/commands/cleanup-processes.js +64 -0
  8. package/dist/cli/commands/cleanup-processes.js.map +7 -0
  9. package/dist/cli/commands/hooks.js +294 -0
  10. package/dist/cli/commands/hooks.js.map +7 -0
  11. package/dist/cli/commands/shell.js +248 -0
  12. package/dist/cli/commands/shell.js.map +7 -0
  13. package/dist/cli/commands/sweep.js +173 -5
  14. package/dist/cli/commands/sweep.js.map +3 -3
  15. package/dist/cli/index.js +9 -1
  16. package/dist/cli/index.js.map +2 -2
  17. package/dist/hooks/config.js +146 -0
  18. package/dist/hooks/config.js.map +7 -0
  19. package/dist/hooks/daemon.js +360 -0
  20. package/dist/hooks/daemon.js.map +7 -0
  21. package/dist/hooks/events.js +51 -0
  22. package/dist/hooks/events.js.map +7 -0
  23. package/dist/hooks/index.js +4 -0
  24. package/dist/hooks/index.js.map +7 -0
  25. package/dist/skills/api-discovery.js +349 -0
  26. package/dist/skills/api-discovery.js.map +7 -0
  27. package/dist/skills/api-skill.js +471 -0
  28. package/dist/skills/api-skill.js.map +7 -0
  29. package/dist/skills/claude-skills.js +49 -1
  30. package/dist/skills/claude-skills.js.map +2 -2
  31. package/dist/utils/process-cleanup.js +132 -0
  32. package/dist/utils/process-cleanup.js.map +7 -0
  33. package/package.json +4 -2
  34. package/scripts/install-sweep-hook.sh +89 -0
  35. package/templates/claude-hooks/post-edit-sweep.js +437 -0
  36. package/templates/shell/sweep-complete.zsh +116 -0
  37. package/templates/shell/sweep-suggest.js +161 -0
@@ -0,0 +1,294 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import ora from "ora";
4
+ import { existsSync, readFileSync, unlinkSync } from "fs";
5
+ import { spawn } from "child_process";
6
+ import {
7
+ loadConfig,
8
+ saveConfig,
9
+ initConfig,
10
+ getConfigPath
11
+ } from "../../hooks/config.js";
12
+ import {
13
+ startDaemon,
14
+ stopDaemon,
15
+ getDaemonStatus
16
+ } from "../../hooks/daemon.js";
17
+ function createHooksCommand() {
18
+ const cmd = new Command("hooks").description(
19
+ "Manage StackMemory hook daemon for suggestions and automation"
20
+ ).addHelpText(
21
+ "after",
22
+ `
23
+ Examples:
24
+ stackmemory hooks init Initialize hook configuration
25
+ stackmemory hooks start Start the hook daemon
26
+ stackmemory hooks stop Stop the hook daemon
27
+ stackmemory hooks status Check daemon status
28
+ stackmemory hooks logs View recent hook logs
29
+ stackmemory hooks config Show current configuration
30
+
31
+ The hook daemon watches for file changes and provides:
32
+ - Sweep AI predictions for next edits
33
+ - Context tracking across sessions
34
+ - Custom automation hooks
35
+ `
36
+ );
37
+ cmd.command("init").description("Initialize hook configuration").action(() => {
38
+ const configPath = getConfigPath();
39
+ if (existsSync(configPath)) {
40
+ console.log(chalk.yellow("Config already exists at:"), configPath);
41
+ console.log(chalk.gray("Use --force to overwrite"));
42
+ return;
43
+ }
44
+ initConfig();
45
+ console.log(chalk.green("Hook configuration initialized"));
46
+ console.log(chalk.gray(`Config: ${configPath}`));
47
+ console.log("");
48
+ console.log(chalk.bold("Next steps:"));
49
+ console.log(" stackmemory hooks start Start the daemon");
50
+ console.log(" stackmemory hooks config View configuration");
51
+ });
52
+ cmd.command("start").description("Start the hook daemon").option("--foreground", "Run in foreground (for debugging)").action(async (options) => {
53
+ const status = getDaemonStatus();
54
+ if (status.running) {
55
+ console.log(
56
+ chalk.yellow("Daemon already running"),
57
+ chalk.gray(`(pid: ${status.pid})`)
58
+ );
59
+ return;
60
+ }
61
+ const spinner = ora("Starting hook daemon...").start();
62
+ try {
63
+ await startDaemon({ foreground: options.foreground });
64
+ if (!options.foreground) {
65
+ await new Promise((r) => setTimeout(r, 500));
66
+ const newStatus = getDaemonStatus();
67
+ if (newStatus.running) {
68
+ spinner.succeed(chalk.green("Hook daemon started"));
69
+ console.log(chalk.gray(`PID: ${newStatus.pid}`));
70
+ } else {
71
+ spinner.fail(chalk.red("Failed to start daemon"));
72
+ console.log(chalk.gray("Check logs: stackmemory hooks logs"));
73
+ }
74
+ }
75
+ } catch (error) {
76
+ spinner.fail(chalk.red("Failed to start daemon"));
77
+ console.log(chalk.gray(error.message));
78
+ }
79
+ });
80
+ cmd.command("stop").description("Stop the hook daemon").action(() => {
81
+ const status = getDaemonStatus();
82
+ if (!status.running) {
83
+ console.log(chalk.yellow("Daemon not running"));
84
+ return;
85
+ }
86
+ stopDaemon();
87
+ console.log(chalk.green("Hook daemon stopped"));
88
+ });
89
+ cmd.command("restart").description("Restart the hook daemon").action(async () => {
90
+ const status = getDaemonStatus();
91
+ if (status.running) {
92
+ stopDaemon();
93
+ await new Promise((r) => setTimeout(r, 500));
94
+ }
95
+ await startDaemon();
96
+ await new Promise((r) => setTimeout(r, 500));
97
+ const newStatus = getDaemonStatus();
98
+ if (newStatus.running) {
99
+ console.log(
100
+ chalk.green("Hook daemon restarted"),
101
+ chalk.gray(`(pid: ${newStatus.pid})`)
102
+ );
103
+ } else {
104
+ console.log(chalk.red("Failed to restart daemon"));
105
+ }
106
+ });
107
+ cmd.command("status").description("Check hook daemon status").action(() => {
108
+ const status = getDaemonStatus();
109
+ const config = loadConfig();
110
+ console.log(chalk.bold("\nStackMemory Hook Daemon Status\n"));
111
+ console.log(
112
+ `Daemon: ${status.running ? chalk.green("Running") : chalk.yellow("Stopped")}`
113
+ );
114
+ if (status.running) {
115
+ console.log(chalk.gray(` PID: ${status.pid}`));
116
+ if (status.uptime) {
117
+ const uptime = Math.round(status.uptime / 1e3);
118
+ const mins = Math.floor(uptime / 60);
119
+ const secs = uptime % 60;
120
+ console.log(chalk.gray(` Uptime: ${mins}m ${secs}s`));
121
+ }
122
+ if (status.eventsProcessed) {
123
+ console.log(
124
+ chalk.gray(` Events processed: ${status.eventsProcessed}`)
125
+ );
126
+ }
127
+ }
128
+ console.log("");
129
+ console.log(chalk.bold("Configuration:"));
130
+ console.log(
131
+ ` File watch: ${config.file_watch.enabled ? chalk.green("Enabled") : chalk.yellow("Disabled")}`
132
+ );
133
+ console.log(
134
+ ` Extensions: ${chalk.gray(config.file_watch.extensions.join(", "))}`
135
+ );
136
+ console.log("");
137
+ console.log(chalk.bold("Active hooks:"));
138
+ for (const [event, hookConfig] of Object.entries(config.hooks)) {
139
+ if (hookConfig?.enabled) {
140
+ console.log(
141
+ ` ${event}: ${chalk.green(hookConfig.handler)} -> ${hookConfig.output}`
142
+ );
143
+ }
144
+ }
145
+ if (!status.running) {
146
+ console.log("");
147
+ console.log(chalk.bold("To start: stackmemory hooks start"));
148
+ }
149
+ });
150
+ cmd.command("logs").description("View hook daemon logs").option("-n, --lines <number>", "Number of lines to show", "50").option("-f, --follow", "Follow log output").action((options) => {
151
+ const config = loadConfig();
152
+ const logFile = config.daemon.log_file;
153
+ if (!existsSync(logFile)) {
154
+ console.log(chalk.yellow("No log file found"));
155
+ console.log(
156
+ chalk.gray("Start the daemon first: stackmemory hooks start")
157
+ );
158
+ return;
159
+ }
160
+ if (options.follow) {
161
+ const tail = spawn("tail", ["-f", logFile], { stdio: "inherit" });
162
+ tail.on("error", () => {
163
+ console.log(chalk.red("Could not follow logs"));
164
+ });
165
+ return;
166
+ }
167
+ const content = readFileSync(logFile, "utf-8");
168
+ const lines = content.trim().split("\n");
169
+ const count = parseInt(options.lines, 10);
170
+ const recent = lines.slice(-count);
171
+ console.log(chalk.bold(`
172
+ Recent logs (${recent.length} lines):
173
+ `));
174
+ for (const line of recent) {
175
+ try {
176
+ if (line.includes("[ERROR]")) {
177
+ console.log(chalk.red(line));
178
+ } else if (line.includes("[WARN]")) {
179
+ console.log(chalk.yellow(line));
180
+ } else if (line.includes("[DEBUG]")) {
181
+ console.log(chalk.gray(line));
182
+ } else {
183
+ console.log(line);
184
+ }
185
+ } catch {
186
+ console.log(line);
187
+ }
188
+ }
189
+ });
190
+ cmd.command("config").description("Show or edit hook configuration").option("--edit", "Open config in editor").option("--reset", "Reset to default configuration").action((options) => {
191
+ const configPath = getConfigPath();
192
+ if (options.reset) {
193
+ if (existsSync(configPath)) {
194
+ unlinkSync(configPath);
195
+ }
196
+ initConfig();
197
+ console.log(chalk.green("Configuration reset to defaults"));
198
+ return;
199
+ }
200
+ if (options.edit) {
201
+ const editor = process.env.EDITOR || "vim";
202
+ spawn(editor, [configPath], { stdio: "inherit" });
203
+ return;
204
+ }
205
+ const config = loadConfig();
206
+ console.log(chalk.bold("\nHook Configuration\n"));
207
+ console.log(chalk.gray(`File: ${configPath}`));
208
+ console.log("");
209
+ console.log(chalk.bold("Daemon:"));
210
+ console.log(` Enabled: ${config.daemon.enabled}`);
211
+ console.log(` Log level: ${config.daemon.log_level}`);
212
+ console.log(` PID file: ${chalk.gray(config.daemon.pid_file)}`);
213
+ console.log(` Log file: ${chalk.gray(config.daemon.log_file)}`);
214
+ console.log("");
215
+ console.log(chalk.bold("File Watch:"));
216
+ console.log(` Enabled: ${config.file_watch.enabled}`);
217
+ console.log(` Paths: ${config.file_watch.paths.join(", ")}`);
218
+ console.log(` Extensions: ${config.file_watch.extensions.join(", ")}`);
219
+ console.log(` Ignore: ${config.file_watch.ignore.join(", ")}`);
220
+ console.log("");
221
+ console.log(chalk.bold("Hooks:"));
222
+ for (const [event, hookConfig] of Object.entries(config.hooks)) {
223
+ console.log(` ${event}:`);
224
+ console.log(` Enabled: ${hookConfig?.enabled}`);
225
+ console.log(` Handler: ${hookConfig?.handler}`);
226
+ console.log(` Output: ${hookConfig?.output}`);
227
+ if (hookConfig?.debounce_ms) {
228
+ console.log(` Debounce: ${hookConfig.debounce_ms}ms`);
229
+ }
230
+ if (hookConfig?.cooldown_ms) {
231
+ console.log(` Cooldown: ${hookConfig.cooldown_ms}ms`);
232
+ }
233
+ }
234
+ });
235
+ cmd.command("add <handler>").description("Add a hook handler").option("-e, --event <type>", "Event type to hook", "file_change").option(
236
+ "-o, --output <type>",
237
+ "Output type (overlay|notification|log)",
238
+ "log"
239
+ ).action((handler, options) => {
240
+ const config = loadConfig();
241
+ const event = options.event;
242
+ config.hooks[event] = {
243
+ enabled: true,
244
+ handler,
245
+ output: options.output,
246
+ debounce_ms: 2e3,
247
+ cooldown_ms: 1e4
248
+ };
249
+ saveConfig(config);
250
+ console.log(chalk.green(`Added ${handler} hook for ${event} events`));
251
+ console.log(
252
+ chalk.gray("Restart daemon to apply: stackmemory hooks restart")
253
+ );
254
+ });
255
+ cmd.command("remove <event>").description("Remove a hook by event type").action((event) => {
256
+ const config = loadConfig();
257
+ if (!config.hooks[event]) {
258
+ console.log(chalk.yellow(`No hook found for ${event}`));
259
+ return;
260
+ }
261
+ delete config.hooks[event];
262
+ saveConfig(config);
263
+ console.log(chalk.green(`Removed hook for ${event}`));
264
+ console.log(
265
+ chalk.gray("Restart daemon to apply: stackmemory hooks restart")
266
+ );
267
+ });
268
+ cmd.action(() => {
269
+ const status = getDaemonStatus();
270
+ console.log(chalk.bold("\nStackMemory Hooks\n"));
271
+ console.log(
272
+ `Daemon: ${status.running ? chalk.green("Running") : chalk.yellow("Stopped")}`
273
+ );
274
+ if (!status.running) {
275
+ console.log("");
276
+ console.log(chalk.bold("Quick start:"));
277
+ console.log(" stackmemory hooks init Initialize configuration");
278
+ console.log(" stackmemory hooks start Start the daemon");
279
+ } else {
280
+ console.log("");
281
+ console.log(chalk.bold("Commands:"));
282
+ console.log(" stackmemory hooks status View detailed status");
283
+ console.log(" stackmemory hooks logs View daemon logs");
284
+ console.log(" stackmemory hooks stop Stop the daemon");
285
+ }
286
+ });
287
+ return cmd;
288
+ }
289
+ var hooks_default = createHooksCommand();
290
+ export {
291
+ createHooksCommand,
292
+ hooks_default as default
293
+ };
294
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/cli/commands/hooks.ts"],
4
+ "sourcesContent": ["/**\n * Hooks CLI Command\n * Manage StackMemory hook daemon and configuration\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { existsSync, readFileSync, unlinkSync } from 'fs';\nimport { spawn } from 'child_process';\nimport {\n loadConfig,\n saveConfig,\n initConfig,\n getConfigPath,\n} from '../../hooks/config.js';\nimport {\n startDaemon,\n stopDaemon,\n getDaemonStatus,\n} from '../../hooks/daemon.js';\n\nexport function createHooksCommand(): Command {\n const cmd = new Command('hooks')\n .description(\n 'Manage StackMemory hook daemon for suggestions and automation'\n )\n .addHelpText(\n 'after',\n `\nExamples:\n stackmemory hooks init Initialize hook configuration\n stackmemory hooks start Start the hook daemon\n stackmemory hooks stop Stop the hook daemon\n stackmemory hooks status Check daemon status\n stackmemory hooks logs View recent hook logs\n stackmemory hooks config Show current configuration\n\nThe hook daemon watches for file changes and provides:\n - Sweep AI predictions for next edits\n - Context tracking across sessions\n - Custom automation hooks\n`\n );\n\n cmd\n .command('init')\n .description('Initialize hook configuration')\n .action(() => {\n const configPath = getConfigPath();\n\n if (existsSync(configPath)) {\n console.log(chalk.yellow('Config already exists at:'), configPath);\n console.log(chalk.gray('Use --force to overwrite'));\n return;\n }\n\n initConfig();\n console.log(chalk.green('Hook configuration initialized'));\n console.log(chalk.gray(`Config: ${configPath}`));\n console.log('');\n console.log(chalk.bold('Next steps:'));\n console.log(' stackmemory hooks start Start the daemon');\n console.log(' stackmemory hooks config View configuration');\n });\n\n cmd\n .command('start')\n .description('Start the hook daemon')\n .option('--foreground', 'Run in foreground (for debugging)')\n .action(async (options) => {\n const status = getDaemonStatus();\n\n if (status.running) {\n console.log(\n chalk.yellow('Daemon already running'),\n chalk.gray(`(pid: ${status.pid})`)\n );\n return;\n }\n\n const spinner = ora('Starting hook daemon...').start();\n\n try {\n await startDaemon({ foreground: options.foreground });\n\n if (!options.foreground) {\n await new Promise((r) => setTimeout(r, 500));\n const newStatus = getDaemonStatus();\n\n if (newStatus.running) {\n spinner.succeed(chalk.green('Hook daemon started'));\n console.log(chalk.gray(`PID: ${newStatus.pid}`));\n } else {\n spinner.fail(chalk.red('Failed to start daemon'));\n console.log(chalk.gray('Check logs: stackmemory hooks logs'));\n }\n }\n } catch (error) {\n spinner.fail(chalk.red('Failed to start daemon'));\n console.log(chalk.gray((error as Error).message));\n }\n });\n\n cmd\n .command('stop')\n .description('Stop the hook daemon')\n .action(() => {\n const status = getDaemonStatus();\n\n if (!status.running) {\n console.log(chalk.yellow('Daemon not running'));\n return;\n }\n\n stopDaemon();\n console.log(chalk.green('Hook daemon stopped'));\n });\n\n cmd\n .command('restart')\n .description('Restart the hook daemon')\n .action(async () => {\n const status = getDaemonStatus();\n\n if (status.running) {\n stopDaemon();\n await new Promise((r) => setTimeout(r, 500));\n }\n\n await startDaemon();\n await new Promise((r) => setTimeout(r, 500));\n\n const newStatus = getDaemonStatus();\n if (newStatus.running) {\n console.log(\n chalk.green('Hook daemon restarted'),\n chalk.gray(`(pid: ${newStatus.pid})`)\n );\n } else {\n console.log(chalk.red('Failed to restart daemon'));\n }\n });\n\n cmd\n .command('status')\n .description('Check hook daemon status')\n .action(() => {\n const status = getDaemonStatus();\n const config = loadConfig();\n\n console.log(chalk.bold('\\nStackMemory Hook Daemon Status\\n'));\n\n console.log(\n `Daemon: ${status.running ? chalk.green('Running') : chalk.yellow('Stopped')}`\n );\n\n if (status.running) {\n console.log(chalk.gray(` PID: ${status.pid}`));\n if (status.uptime) {\n const uptime = Math.round(status.uptime / 1000);\n const mins = Math.floor(uptime / 60);\n const secs = uptime % 60;\n console.log(chalk.gray(` Uptime: ${mins}m ${secs}s`));\n }\n if (status.eventsProcessed) {\n console.log(\n chalk.gray(` Events processed: ${status.eventsProcessed}`)\n );\n }\n }\n\n console.log('');\n console.log(chalk.bold('Configuration:'));\n console.log(\n ` File watch: ${config.file_watch.enabled ? chalk.green('Enabled') : chalk.yellow('Disabled')}`\n );\n console.log(\n ` Extensions: ${chalk.gray(config.file_watch.extensions.join(', '))}`\n );\n\n console.log('');\n console.log(chalk.bold('Active hooks:'));\n for (const [event, hookConfig] of Object.entries(config.hooks)) {\n if (hookConfig?.enabled) {\n console.log(\n ` ${event}: ${chalk.green(hookConfig.handler)} -> ${hookConfig.output}`\n );\n }\n }\n\n if (!status.running) {\n console.log('');\n console.log(chalk.bold('To start: stackmemory hooks start'));\n }\n });\n\n cmd\n .command('logs')\n .description('View hook daemon logs')\n .option('-n, --lines <number>', 'Number of lines to show', '50')\n .option('-f, --follow', 'Follow log output')\n .action((options) => {\n const config = loadConfig();\n const logFile = config.daemon.log_file;\n\n if (!existsSync(logFile)) {\n console.log(chalk.yellow('No log file found'));\n console.log(\n chalk.gray('Start the daemon first: stackmemory hooks start')\n );\n return;\n }\n\n if (options.follow) {\n const tail = spawn('tail', ['-f', logFile], { stdio: 'inherit' });\n tail.on('error', () => {\n console.log(chalk.red('Could not follow logs'));\n });\n return;\n }\n\n const content = readFileSync(logFile, 'utf-8');\n const lines = content.trim().split('\\n');\n const count = parseInt(options.lines, 10);\n const recent = lines.slice(-count);\n\n console.log(chalk.bold(`\\nRecent logs (${recent.length} lines):\\n`));\n for (const line of recent) {\n try {\n if (line.includes('[ERROR]')) {\n console.log(chalk.red(line));\n } else if (line.includes('[WARN]')) {\n console.log(chalk.yellow(line));\n } else if (line.includes('[DEBUG]')) {\n console.log(chalk.gray(line));\n } else {\n console.log(line);\n }\n } catch {\n console.log(line);\n }\n }\n });\n\n cmd\n .command('config')\n .description('Show or edit hook configuration')\n .option('--edit', 'Open config in editor')\n .option('--reset', 'Reset to default configuration')\n .action((options) => {\n const configPath = getConfigPath();\n\n if (options.reset) {\n if (existsSync(configPath)) {\n unlinkSync(configPath);\n }\n initConfig();\n console.log(chalk.green('Configuration reset to defaults'));\n return;\n }\n\n if (options.edit) {\n const editor = process.env.EDITOR || 'vim';\n spawn(editor, [configPath], { stdio: 'inherit' });\n return;\n }\n\n const config = loadConfig();\n\n console.log(chalk.bold('\\nHook Configuration\\n'));\n console.log(chalk.gray(`File: ${configPath}`));\n console.log('');\n console.log(chalk.bold('Daemon:'));\n console.log(` Enabled: ${config.daemon.enabled}`);\n console.log(` Log level: ${config.daemon.log_level}`);\n console.log(` PID file: ${chalk.gray(config.daemon.pid_file)}`);\n console.log(` Log file: ${chalk.gray(config.daemon.log_file)}`);\n\n console.log('');\n console.log(chalk.bold('File Watch:'));\n console.log(` Enabled: ${config.file_watch.enabled}`);\n console.log(` Paths: ${config.file_watch.paths.join(', ')}`);\n console.log(` Extensions: ${config.file_watch.extensions.join(', ')}`);\n console.log(` Ignore: ${config.file_watch.ignore.join(', ')}`);\n\n console.log('');\n console.log(chalk.bold('Hooks:'));\n for (const [event, hookConfig] of Object.entries(config.hooks)) {\n console.log(` ${event}:`);\n console.log(` Enabled: ${hookConfig?.enabled}`);\n console.log(` Handler: ${hookConfig?.handler}`);\n console.log(` Output: ${hookConfig?.output}`);\n if (hookConfig?.debounce_ms) {\n console.log(` Debounce: ${hookConfig.debounce_ms}ms`);\n }\n if (hookConfig?.cooldown_ms) {\n console.log(` Cooldown: ${hookConfig.cooldown_ms}ms`);\n }\n }\n });\n\n cmd\n .command('add <handler>')\n .description('Add a hook handler')\n .option('-e, --event <type>', 'Event type to hook', 'file_change')\n .option(\n '-o, --output <type>',\n 'Output type (overlay|notification|log)',\n 'log'\n )\n .action((handler, options) => {\n const config = loadConfig();\n const event = options.event as keyof typeof config.hooks;\n\n config.hooks[event] = {\n enabled: true,\n handler,\n output: options.output,\n debounce_ms: 2000,\n cooldown_ms: 10000,\n };\n\n saveConfig(config);\n console.log(chalk.green(`Added ${handler} hook for ${event} events`));\n console.log(\n chalk.gray('Restart daemon to apply: stackmemory hooks restart')\n );\n });\n\n cmd\n .command('remove <event>')\n .description('Remove a hook by event type')\n .action((event) => {\n const config = loadConfig();\n\n if (!config.hooks[event as keyof typeof config.hooks]) {\n console.log(chalk.yellow(`No hook found for ${event}`));\n return;\n }\n\n delete config.hooks[event as keyof typeof config.hooks];\n saveConfig(config);\n console.log(chalk.green(`Removed hook for ${event}`));\n console.log(\n chalk.gray('Restart daemon to apply: stackmemory hooks restart')\n );\n });\n\n cmd.action(() => {\n const status = getDaemonStatus();\n\n console.log(chalk.bold('\\nStackMemory Hooks\\n'));\n console.log(\n `Daemon: ${status.running ? chalk.green('Running') : chalk.yellow('Stopped')}`\n );\n\n if (!status.running) {\n console.log('');\n console.log(chalk.bold('Quick start:'));\n console.log(' stackmemory hooks init Initialize configuration');\n console.log(' stackmemory hooks start Start the daemon');\n } else {\n console.log('');\n console.log(chalk.bold('Commands:'));\n console.log(' stackmemory hooks status View detailed status');\n console.log(' stackmemory hooks logs View daemon logs');\n console.log(' stackmemory hooks stop Stop the daemon');\n }\n });\n\n return cmd;\n}\n\nexport default createHooksCommand();\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,248 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import ora from "ora";
4
+ import {
5
+ existsSync,
6
+ readFileSync,
7
+ writeFileSync,
8
+ mkdirSync,
9
+ copyFileSync,
10
+ chmodSync,
11
+ appendFileSync
12
+ } from "fs";
13
+ import { join, dirname } from "path";
14
+ import { fileURLToPath } from "url";
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = dirname(__filename);
17
+ function getShellType() {
18
+ const shell = process.env.SHELL || "";
19
+ if (shell.includes("zsh")) return "zsh";
20
+ if (shell.includes("bash")) return "bash";
21
+ return "unknown";
22
+ }
23
+ function getShellRcFile() {
24
+ const home = process.env.HOME || "";
25
+ const shell = getShellType();
26
+ if (shell === "zsh") {
27
+ return join(home, ".zshrc");
28
+ } else if (shell === "bash") {
29
+ const bashrc = join(home, ".bashrc");
30
+ const profile = join(home, ".bash_profile");
31
+ return existsSync(bashrc) ? bashrc : profile;
32
+ }
33
+ return join(home, ".profile");
34
+ }
35
+ function findTemplateFile(filename) {
36
+ const locations = [
37
+ join(process.cwd(), "templates", "shell", filename),
38
+ join(
39
+ process.cwd(),
40
+ "node_modules",
41
+ "@stackmemoryai",
42
+ "stackmemory",
43
+ "templates",
44
+ "shell",
45
+ filename
46
+ ),
47
+ join(dirname(dirname(dirname(__dirname))), "templates", "shell", filename)
48
+ ];
49
+ for (const loc of locations) {
50
+ if (existsSync(loc)) {
51
+ return loc;
52
+ }
53
+ }
54
+ return null;
55
+ }
56
+ function createShellCommand() {
57
+ const cmd = new Command("shell").description("Shell integration for Sweep-powered completions").addHelpText(
58
+ "after",
59
+ `
60
+ Examples:
61
+ stackmemory shell install Install shell completions
62
+ stackmemory shell status Check installation status
63
+ stackmemory shell uninstall Remove shell integration
64
+
65
+ After installation:
66
+ - Ctrl+] Request suggestion
67
+ - Shift+Tab Accept suggestion
68
+ - sweep_status Check status
69
+ - sweep_toggle Enable/disable
70
+ `
71
+ );
72
+ cmd.command("install").description("Install Sweep-powered shell completions").option("--shell <type>", "Shell type (zsh or bash)", getShellType()).action(async (options) => {
73
+ const spinner = ora("Installing shell integration...").start();
74
+ const home = process.env.HOME || "";
75
+ const shellDir = join(home, ".stackmemory", "shell");
76
+ const shell = options.shell;
77
+ if (shell === "unknown") {
78
+ spinner.fail(chalk.red("Could not detect shell type"));
79
+ console.log(chalk.gray("Use --shell zsh or --shell bash"));
80
+ process.exit(1);
81
+ }
82
+ try {
83
+ mkdirSync(shellDir, { recursive: true });
84
+ const zshSource = findTemplateFile("sweep-complete.zsh");
85
+ const suggestSource = findTemplateFile("sweep-suggest.js");
86
+ if (!zshSource || !suggestSource) {
87
+ spinner.fail(chalk.red("Template files not found"));
88
+ console.log(chalk.gray("Ensure stackmemory is installed correctly"));
89
+ process.exit(1);
90
+ }
91
+ const zshDest = join(shellDir, "sweep-complete.zsh");
92
+ const suggestDest = join(shellDir, "sweep-suggest.js");
93
+ copyFileSync(zshSource, zshDest);
94
+ copyFileSync(suggestSource, suggestDest);
95
+ chmodSync(suggestDest, "755");
96
+ spinner.text = "Updating shell configuration...";
97
+ const rcFile = getShellRcFile();
98
+ const sourceCmd = shell === "zsh" ? `source "${zshDest}"` : `source "${shellDir}/sweep-complete.bash"`;
99
+ const marker = "# StackMemory Sweep Completion";
100
+ if (existsSync(rcFile)) {
101
+ const content = readFileSync(rcFile, "utf-8");
102
+ if (content.includes(marker)) {
103
+ spinner.succeed(chalk.green("Shell integration already installed"));
104
+ console.log(
105
+ chalk.gray("Restart your shell or run: source " + rcFile)
106
+ );
107
+ return;
108
+ }
109
+ const addition = `
110
+ ${marker}
111
+ if [[ -f "${zshDest}" ]]; then
112
+ ${sourceCmd}
113
+ fi
114
+ `;
115
+ appendFileSync(rcFile, addition);
116
+ } else {
117
+ writeFileSync(
118
+ rcFile,
119
+ `${marker}
120
+ if [[ -f "${zshDest}" ]]; then
121
+ ${sourceCmd}
122
+ fi
123
+ `
124
+ );
125
+ }
126
+ spinner.succeed(chalk.green("Shell integration installed"));
127
+ console.log("");
128
+ console.log(chalk.bold("Files installed:"));
129
+ console.log(chalk.gray(` ${zshDest}`));
130
+ console.log(chalk.gray(` ${suggestDest}`));
131
+ console.log("");
132
+ console.log(chalk.bold("To activate:"));
133
+ console.log(` source ${rcFile}`);
134
+ console.log(" OR restart your terminal");
135
+ console.log("");
136
+ console.log(chalk.bold("Usage:"));
137
+ console.log(" Ctrl+] Request suggestion");
138
+ console.log(" Shift+Tab Accept suggestion");
139
+ console.log(" sweep_status Check status");
140
+ console.log(" sweep_toggle Enable/disable");
141
+ } catch (error) {
142
+ spinner.fail(chalk.red("Installation failed"));
143
+ console.log(chalk.gray(error.message));
144
+ process.exit(1);
145
+ }
146
+ });
147
+ cmd.command("status").description("Check shell integration status").action(() => {
148
+ const home = process.env.HOME || "";
149
+ const shellDir = join(home, ".stackmemory", "shell");
150
+ const zshFile = join(shellDir, "sweep-complete.zsh");
151
+ const suggestFile = join(shellDir, "sweep-suggest.js");
152
+ const rcFile = getShellRcFile();
153
+ console.log(chalk.bold("\nShell Integration Status\n"));
154
+ console.log(`Shell: ${chalk.cyan(getShellType())}`);
155
+ console.log(`RC file: ${chalk.gray(rcFile)}`);
156
+ console.log("");
157
+ const zshInstalled = existsSync(zshFile);
158
+ const suggestInstalled = existsSync(suggestFile);
159
+ console.log(
160
+ `Completion script: ${zshInstalled ? chalk.green("Installed") : chalk.yellow("Not installed")}`
161
+ );
162
+ console.log(
163
+ `Suggest script: ${suggestInstalled ? chalk.green("Installed") : chalk.yellow("Not installed")}`
164
+ );
165
+ if (existsSync(rcFile)) {
166
+ const content = readFileSync(rcFile, "utf-8");
167
+ const configured = content.includes("StackMemory Sweep Completion");
168
+ console.log(
169
+ `RC configured: ${configured ? chalk.green("Yes") : chalk.yellow("No")}`
170
+ );
171
+ } else {
172
+ console.log(`RC configured: ${chalk.yellow("No RC file")}`);
173
+ }
174
+ const sweepState = join(home, ".stackmemory", "sweep-state.json");
175
+ if (existsSync(sweepState)) {
176
+ try {
177
+ const state = JSON.parse(readFileSync(sweepState, "utf-8"));
178
+ console.log("");
179
+ console.log(chalk.bold("Sweep Context:"));
180
+ console.log(
181
+ chalk.gray(` Recent diffs: ${state.recentDiffs?.length || 0}`)
182
+ );
183
+ if (state.lastPrediction) {
184
+ const age = Date.now() - state.lastPrediction.timestamp;
185
+ const ageStr = age < 6e4 ? `${Math.round(age / 1e3)}s ago` : `${Math.round(age / 6e4)}m ago`;
186
+ console.log(chalk.gray(` Last prediction: ${ageStr}`));
187
+ }
188
+ } catch {
189
+ }
190
+ }
191
+ if (!zshInstalled || !suggestInstalled) {
192
+ console.log("");
193
+ console.log(chalk.bold("To install: stackmemory shell install"));
194
+ }
195
+ });
196
+ cmd.command("uninstall").description("Remove shell integration").action(() => {
197
+ const rcFile = getShellRcFile();
198
+ if (existsSync(rcFile)) {
199
+ let content = readFileSync(rcFile, "utf-8");
200
+ const marker = "# StackMemory Sweep Completion";
201
+ const markerIndex = content.indexOf(marker);
202
+ if (markerIndex !== -1) {
203
+ const endPattern = /\nfi\n/;
204
+ const afterMarker = content.slice(markerIndex);
205
+ const endMatch = afterMarker.match(endPattern);
206
+ if (endMatch && endMatch.index !== void 0) {
207
+ const endIndex = markerIndex + endMatch.index + endMatch[0].length;
208
+ content = content.slice(0, markerIndex) + content.slice(endIndex);
209
+ writeFileSync(rcFile, content);
210
+ console.log(
211
+ chalk.green("Shell integration removed from " + rcFile)
212
+ );
213
+ }
214
+ } else {
215
+ console.log(chalk.yellow("No shell integration found in " + rcFile));
216
+ }
217
+ }
218
+ console.log(
219
+ chalk.gray("\nRestart your shell to complete uninstallation")
220
+ );
221
+ });
222
+ cmd.action(() => {
223
+ const home = process.env.HOME || "";
224
+ const zshFile = join(home, ".stackmemory", "shell", "sweep-complete.zsh");
225
+ const installed = existsSync(zshFile);
226
+ console.log(chalk.bold("\nStackMemory Shell Integration\n"));
227
+ console.log(
228
+ `Status: ${installed ? chalk.green("Installed") : chalk.yellow("Not installed")}`
229
+ );
230
+ if (!installed) {
231
+ console.log("");
232
+ console.log(chalk.bold("Install with:"));
233
+ console.log(" stackmemory shell install");
234
+ } else {
235
+ console.log("");
236
+ console.log(chalk.bold("Commands:"));
237
+ console.log(" stackmemory shell status Check status");
238
+ console.log(" stackmemory shell uninstall Remove integration");
239
+ }
240
+ });
241
+ return cmd;
242
+ }
243
+ var shell_default = createShellCommand();
244
+ export {
245
+ createShellCommand,
246
+ shell_default as default
247
+ };
248
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/cli/commands/shell.ts"],
4
+ "sourcesContent": ["/**\n * Shell Integration CLI Command\n * Install Sweep-powered completions for zsh/bash\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n copyFileSync,\n chmodSync,\n appendFileSync,\n} from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nfunction getShellType(): 'zsh' | 'bash' | 'unknown' {\n const shell = process.env.SHELL || '';\n if (shell.includes('zsh')) return 'zsh';\n if (shell.includes('bash')) return 'bash';\n return 'unknown';\n}\n\nfunction getShellRcFile(): string {\n const home = process.env.HOME || '';\n const shell = getShellType();\n\n if (shell === 'zsh') {\n return join(home, '.zshrc');\n } else if (shell === 'bash') {\n const bashrc = join(home, '.bashrc');\n const profile = join(home, '.bash_profile');\n return existsSync(bashrc) ? bashrc : profile;\n }\n\n return join(home, '.profile');\n}\n\nfunction findTemplateFile(filename: string): string | null {\n const locations = [\n join(process.cwd(), 'templates', 'shell', filename),\n join(\n process.cwd(),\n 'node_modules',\n '@stackmemoryai',\n 'stackmemory',\n 'templates',\n 'shell',\n filename\n ),\n join(dirname(dirname(dirname(__dirname))), 'templates', 'shell', filename),\n ];\n\n for (const loc of locations) {\n if (existsSync(loc)) {\n return loc;\n }\n }\n return null;\n}\n\nexport function createShellCommand(): Command {\n const cmd = new Command('shell')\n .description('Shell integration for Sweep-powered completions')\n .addHelpText(\n 'after',\n `\nExamples:\n stackmemory shell install Install shell completions\n stackmemory shell status Check installation status\n stackmemory shell uninstall Remove shell integration\n\nAfter installation:\n - Ctrl+] Request suggestion\n - Shift+Tab Accept suggestion\n - sweep_status Check status\n - sweep_toggle Enable/disable\n`\n );\n\n cmd\n .command('install')\n .description('Install Sweep-powered shell completions')\n .option('--shell <type>', 'Shell type (zsh or bash)', getShellType())\n .action(async (options) => {\n const spinner = ora('Installing shell integration...').start();\n\n const home = process.env.HOME || '';\n const shellDir = join(home, '.stackmemory', 'shell');\n const shell = options.shell as 'zsh' | 'bash';\n\n if (shell === 'unknown') {\n spinner.fail(chalk.red('Could not detect shell type'));\n console.log(chalk.gray('Use --shell zsh or --shell bash'));\n process.exit(1);\n }\n\n try {\n mkdirSync(shellDir, { recursive: true });\n\n const zshSource = findTemplateFile('sweep-complete.zsh');\n const suggestSource = findTemplateFile('sweep-suggest.js');\n\n if (!zshSource || !suggestSource) {\n spinner.fail(chalk.red('Template files not found'));\n console.log(chalk.gray('Ensure stackmemory is installed correctly'));\n process.exit(1);\n }\n\n const zshDest = join(shellDir, 'sweep-complete.zsh');\n const suggestDest = join(shellDir, 'sweep-suggest.js');\n\n copyFileSync(zshSource, zshDest);\n copyFileSync(suggestSource, suggestDest);\n chmodSync(suggestDest, '755');\n\n spinner.text = 'Updating shell configuration...';\n\n const rcFile = getShellRcFile();\n const sourceCmd =\n shell === 'zsh'\n ? `source \"${zshDest}\"`\n : `source \"${shellDir}/sweep-complete.bash\"`;\n\n const marker = '# StackMemory Sweep Completion';\n\n if (existsSync(rcFile)) {\n const content = readFileSync(rcFile, 'utf-8');\n\n if (content.includes(marker)) {\n spinner.succeed(chalk.green('Shell integration already installed'));\n console.log(\n chalk.gray('Restart your shell or run: source ' + rcFile)\n );\n return;\n }\n\n const addition = `\n${marker}\nif [[ -f \"${zshDest}\" ]]; then\n ${sourceCmd}\nfi\n`;\n appendFileSync(rcFile, addition);\n } else {\n writeFileSync(\n rcFile,\n `${marker}\\nif [[ -f \"${zshDest}\" ]]; then\\n ${sourceCmd}\\nfi\\n`\n );\n }\n\n spinner.succeed(chalk.green('Shell integration installed'));\n console.log('');\n console.log(chalk.bold('Files installed:'));\n console.log(chalk.gray(` ${zshDest}`));\n console.log(chalk.gray(` ${suggestDest}`));\n console.log('');\n console.log(chalk.bold('To activate:'));\n console.log(` source ${rcFile}`);\n console.log(' OR restart your terminal');\n console.log('');\n console.log(chalk.bold('Usage:'));\n console.log(' Ctrl+] Request suggestion');\n console.log(' Shift+Tab Accept suggestion');\n console.log(' sweep_status Check status');\n console.log(' sweep_toggle Enable/disable');\n } catch (error) {\n spinner.fail(chalk.red('Installation failed'));\n console.log(chalk.gray((error as Error).message));\n process.exit(1);\n }\n });\n\n cmd\n .command('status')\n .description('Check shell integration status')\n .action(() => {\n const home = process.env.HOME || '';\n const shellDir = join(home, '.stackmemory', 'shell');\n const zshFile = join(shellDir, 'sweep-complete.zsh');\n const suggestFile = join(shellDir, 'sweep-suggest.js');\n const rcFile = getShellRcFile();\n\n console.log(chalk.bold('\\nShell Integration Status\\n'));\n\n console.log(`Shell: ${chalk.cyan(getShellType())}`);\n console.log(`RC file: ${chalk.gray(rcFile)}`);\n console.log('');\n\n const zshInstalled = existsSync(zshFile);\n const suggestInstalled = existsSync(suggestFile);\n\n console.log(\n `Completion script: ${zshInstalled ? chalk.green('Installed') : chalk.yellow('Not installed')}`\n );\n console.log(\n `Suggest script: ${suggestInstalled ? chalk.green('Installed') : chalk.yellow('Not installed')}`\n );\n\n if (existsSync(rcFile)) {\n const content = readFileSync(rcFile, 'utf-8');\n const configured = content.includes('StackMemory Sweep Completion');\n console.log(\n `RC configured: ${configured ? chalk.green('Yes') : chalk.yellow('No')}`\n );\n } else {\n console.log(`RC configured: ${chalk.yellow('No RC file')}`);\n }\n\n const sweepState = join(home, '.stackmemory', 'sweep-state.json');\n if (existsSync(sweepState)) {\n try {\n const state = JSON.parse(readFileSync(sweepState, 'utf-8'));\n console.log('');\n console.log(chalk.bold('Sweep Context:'));\n console.log(\n chalk.gray(` Recent diffs: ${state.recentDiffs?.length || 0}`)\n );\n if (state.lastPrediction) {\n const age = Date.now() - state.lastPrediction.timestamp;\n const ageStr =\n age < 60000\n ? `${Math.round(age / 1000)}s ago`\n : `${Math.round(age / 60000)}m ago`;\n console.log(chalk.gray(` Last prediction: ${ageStr}`));\n }\n } catch {\n // Ignore\n }\n }\n\n if (!zshInstalled || !suggestInstalled) {\n console.log('');\n console.log(chalk.bold('To install: stackmemory shell install'));\n }\n });\n\n cmd\n .command('uninstall')\n .description('Remove shell integration')\n .action(() => {\n const rcFile = getShellRcFile();\n\n if (existsSync(rcFile)) {\n let content = readFileSync(rcFile, 'utf-8');\n\n const marker = '# StackMemory Sweep Completion';\n const markerIndex = content.indexOf(marker);\n\n if (markerIndex !== -1) {\n const endPattern = /\\nfi\\n/;\n const afterMarker = content.slice(markerIndex);\n const endMatch = afterMarker.match(endPattern);\n\n if (endMatch && endMatch.index !== undefined) {\n const endIndex = markerIndex + endMatch.index + endMatch[0].length;\n content = content.slice(0, markerIndex) + content.slice(endIndex);\n writeFileSync(rcFile, content);\n console.log(\n chalk.green('Shell integration removed from ' + rcFile)\n );\n }\n } else {\n console.log(chalk.yellow('No shell integration found in ' + rcFile));\n }\n }\n\n console.log(\n chalk.gray('\\nRestart your shell to complete uninstallation')\n );\n });\n\n cmd.action(() => {\n const home = process.env.HOME || '';\n const zshFile = join(home, '.stackmemory', 'shell', 'sweep-complete.zsh');\n const installed = existsSync(zshFile);\n\n console.log(chalk.bold('\\nStackMemory Shell Integration\\n'));\n console.log(\n `Status: ${installed ? chalk.green('Installed') : chalk.yellow('Not installed')}`\n );\n\n if (!installed) {\n console.log('');\n console.log(chalk.bold('Install with:'));\n console.log(' stackmemory shell install');\n } else {\n console.log('');\n console.log(chalk.bold('Commands:'));\n console.log(' stackmemory shell status Check status');\n console.log(' stackmemory shell uninstall Remove integration');\n }\n });\n\n return cmd;\n}\n\nexport default createShellCommand();\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }