@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.
- package/bin/claude-sm +6 -0
- package/bin/claude-smd +6 -0
- package/dist/cli/claude-sm-danger.js +20 -0
- package/dist/cli/claude-sm-danger.js.map +7 -0
- package/dist/cli/commands/api.js +228 -0
- package/dist/cli/commands/api.js.map +7 -0
- package/dist/cli/commands/cleanup-processes.js +64 -0
- package/dist/cli/commands/cleanup-processes.js.map +7 -0
- package/dist/cli/commands/hooks.js +294 -0
- package/dist/cli/commands/hooks.js.map +7 -0
- package/dist/cli/commands/shell.js +248 -0
- package/dist/cli/commands/shell.js.map +7 -0
- package/dist/cli/commands/sweep.js +173 -5
- package/dist/cli/commands/sweep.js.map +3 -3
- package/dist/cli/index.js +9 -1
- package/dist/cli/index.js.map +2 -2
- package/dist/hooks/config.js +146 -0
- package/dist/hooks/config.js.map +7 -0
- package/dist/hooks/daemon.js +360 -0
- package/dist/hooks/daemon.js.map +7 -0
- package/dist/hooks/events.js +51 -0
- package/dist/hooks/events.js.map +7 -0
- package/dist/hooks/index.js +4 -0
- package/dist/hooks/index.js.map +7 -0
- package/dist/skills/api-discovery.js +349 -0
- package/dist/skills/api-discovery.js.map +7 -0
- package/dist/skills/api-skill.js +471 -0
- package/dist/skills/api-skill.js.map +7 -0
- package/dist/skills/claude-skills.js +49 -1
- package/dist/skills/claude-skills.js.map +2 -2
- package/dist/utils/process-cleanup.js +132 -0
- package/dist/utils/process-cleanup.js.map +7 -0
- package/package.json +4 -2
- package/scripts/install-sweep-hook.sh +89 -0
- package/templates/claude-hooks/post-edit-sweep.js +437 -0
- package/templates/shell/sweep-complete.zsh +116 -0
- package/templates/shell/sweep-suggest.js +161 -0
package/bin/claude-sm
ADDED
package/bin/claude-smd
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
const claudeSmPath = path.join(__dirname, "claude-sm.js");
|
|
8
|
+
const args = ["--dangerously-skip-permissions", ...process.argv.slice(2)];
|
|
9
|
+
const child = spawn("node", [claudeSmPath, ...args], {
|
|
10
|
+
stdio: "inherit",
|
|
11
|
+
env: process.env
|
|
12
|
+
});
|
|
13
|
+
child.on("exit", (code) => {
|
|
14
|
+
process.exit(code || 0);
|
|
15
|
+
});
|
|
16
|
+
child.on("error", (err) => {
|
|
17
|
+
console.error("Failed to launch claude-sm:", err.message);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
});
|
|
20
|
+
//# sourceMappingURL=claude-sm-danger.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/cli/claude-sm-danger.ts"],
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\n/**\n * claude-sm-danger: Claude-SM wrapper with --dangerously-skip-permissions\n * Shorthand for: claude-sm --dangerously-skip-permissions [args]\n */\n\nimport { spawn } from 'child_process';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Get the claude-sm script path\nconst claudeSmPath = path.join(__dirname, 'claude-sm.js');\n\n// Prepend the danger flag to all args\nconst args = ['--dangerously-skip-permissions', ...process.argv.slice(2)];\n\n// Spawn claude-sm with the danger flag\nconst child = spawn('node', [claudeSmPath, ...args], {\n stdio: 'inherit',\n env: process.env,\n});\n\nchild.on('exit', (code) => {\n process.exit(code || 0);\n});\n\nchild.on('error', (err) => {\n console.error('Failed to launch claude-sm:', err.message);\n process.exit(1);\n});\n"],
|
|
5
|
+
"mappings": ";AAOA,SAAS,aAAa;AACtB,YAAY,UAAU;AACtB,SAAS,qBAAqB;AAE9B,MAAM,aAAa,cAAc,YAAY,GAAG;AAChD,MAAM,YAAY,KAAK,QAAQ,UAAU;AAGzC,MAAM,eAAe,KAAK,KAAK,WAAW,cAAc;AAGxD,MAAM,OAAO,CAAC,kCAAkC,GAAG,QAAQ,KAAK,MAAM,CAAC,CAAC;AAGxE,MAAM,QAAQ,MAAM,QAAQ,CAAC,cAAc,GAAG,IAAI,GAAG;AAAA,EACnD,OAAO;AAAA,EACP,KAAK,QAAQ;AACf,CAAC;AAED,MAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,UAAQ,KAAK,QAAQ,CAAC;AACxB,CAAC;AAED,MAAM,GAAG,SAAS,CAAC,QAAQ;AACzB,UAAQ,MAAM,+BAA+B,IAAI,OAAO;AACxD,UAAQ,KAAK,CAAC;AAChB,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { getAPISkill } from "../../skills/api-skill.js";
|
|
3
|
+
import { getAPIDiscovery } from "../../skills/api-discovery.js";
|
|
4
|
+
function createAPICommand() {
|
|
5
|
+
const api = new Command("api");
|
|
6
|
+
api.description("OpenAPI-based API access via Restish");
|
|
7
|
+
api.command("add <name> <url>").description("Register a new API").option("--spec <url>", "OpenAPI spec URL").option(
|
|
8
|
+
"--auth-type <type>",
|
|
9
|
+
"Authentication type (none|api-key|oauth2|basic)",
|
|
10
|
+
"none"
|
|
11
|
+
).option("--header-name <name>", "Auth header name", "Authorization").option("--env-var <name>", "Environment variable for auth token").action(async (name, url, options) => {
|
|
12
|
+
const skill = getAPISkill();
|
|
13
|
+
const result = await skill.add(name, url, {
|
|
14
|
+
spec: options.spec,
|
|
15
|
+
authType: options.authType,
|
|
16
|
+
headerName: options.headerName,
|
|
17
|
+
envVar: options.envVar
|
|
18
|
+
});
|
|
19
|
+
if (result.success) {
|
|
20
|
+
console.log(`API '${name}' registered`);
|
|
21
|
+
if (result.data) {
|
|
22
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
23
|
+
}
|
|
24
|
+
} else {
|
|
25
|
+
console.error(`Error: ${result.message}`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
api.command("list").description("List all registered APIs").action(async () => {
|
|
30
|
+
const skill = getAPISkill();
|
|
31
|
+
const result = await skill.list();
|
|
32
|
+
if (result.success) {
|
|
33
|
+
if (Array.isArray(result.data) && result.data.length === 0) {
|
|
34
|
+
console.log(
|
|
35
|
+
"No APIs registered. Use: stackmemory api add <name> <url>"
|
|
36
|
+
);
|
|
37
|
+
} else {
|
|
38
|
+
console.log("Registered APIs:");
|
|
39
|
+
for (const api2 of result.data) {
|
|
40
|
+
console.log(` ${api2.name}`);
|
|
41
|
+
console.log(` URL: ${api2.baseUrl}`);
|
|
42
|
+
console.log(` Auth: ${api2.authType}`);
|
|
43
|
+
console.log(` Operations: ${api2.operations}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
console.error(`Error: ${result.message}`);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
api.command("describe <name> [operation]").description("Show API details or specific operation").action(async (name, operation) => {
|
|
52
|
+
const skill = getAPISkill();
|
|
53
|
+
const result = await skill.describe(name, operation);
|
|
54
|
+
if (result.success) {
|
|
55
|
+
console.log(result.message);
|
|
56
|
+
if (result.data) {
|
|
57
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
console.error(`Error: ${result.message}`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
api.command("exec <name> <operation>").description("Execute an API operation").option("--raw", "Output raw response").option("--filter <query>", "Filter/project response using shorthand query").option("-H, --header <header...>", "Add custom headers (key:value)").allowUnknownOption(true).action(async (name, operation, options, command) => {
|
|
65
|
+
const skill = getAPISkill();
|
|
66
|
+
const params = {};
|
|
67
|
+
const args = command.args.slice(2);
|
|
68
|
+
for (let i = 0; i < args.length; i++) {
|
|
69
|
+
const arg = args[i];
|
|
70
|
+
if (arg.startsWith("--")) {
|
|
71
|
+
const key = arg.slice(2);
|
|
72
|
+
const nextArg = args[i + 1];
|
|
73
|
+
if (nextArg && !nextArg.startsWith("--")) {
|
|
74
|
+
params[key] = nextArg;
|
|
75
|
+
i++;
|
|
76
|
+
} else {
|
|
77
|
+
params[key] = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const headers = {};
|
|
82
|
+
if (options.header) {
|
|
83
|
+
for (const h of options.header) {
|
|
84
|
+
const [key, ...valueParts] = h.split(":");
|
|
85
|
+
headers[key] = valueParts.join(":").trim();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const result = await skill.exec(name, operation, params, {
|
|
89
|
+
raw: options.raw,
|
|
90
|
+
filter: options.filter,
|
|
91
|
+
headers
|
|
92
|
+
});
|
|
93
|
+
if (result.success) {
|
|
94
|
+
if (typeof result.data === "string") {
|
|
95
|
+
console.log(result.data);
|
|
96
|
+
} else {
|
|
97
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
console.error(`Error: ${result.message}`);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
api.command("auth <name>").description("Configure API authentication").option("--token <token>", "API token/key").option("--env-var <name>", "Environment variable name for token").option("--oauth", "Use OAuth2 flow").option("--scopes <scopes>", "OAuth2 scopes (comma-separated)").action(async (name, options) => {
|
|
105
|
+
const skill = getAPISkill();
|
|
106
|
+
const result = await skill.auth(name, {
|
|
107
|
+
token: options.token,
|
|
108
|
+
envVar: options.envVar,
|
|
109
|
+
oauth: options.oauth,
|
|
110
|
+
scopes: options.scopes?.split(",")
|
|
111
|
+
});
|
|
112
|
+
if (result.success) {
|
|
113
|
+
console.log(result.message);
|
|
114
|
+
} else {
|
|
115
|
+
console.error(`Error: ${result.message}`);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
api.command("sync <name>").description("Refresh API operations from spec").action(async (name) => {
|
|
120
|
+
const skill = getAPISkill();
|
|
121
|
+
const result = await skill.sync(name);
|
|
122
|
+
if (result.success) {
|
|
123
|
+
console.log(result.message);
|
|
124
|
+
if (result.data?.operations) {
|
|
125
|
+
console.log(
|
|
126
|
+
`Operations: ${result.data.operations.join(", ")}`
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
console.error(`Error: ${result.message}`);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
api.command("remove <name>").description("Remove a registered API").action(async (name) => {
|
|
135
|
+
const skill = getAPISkill();
|
|
136
|
+
const result = await skill.remove(name);
|
|
137
|
+
if (result.success) {
|
|
138
|
+
console.log(result.message);
|
|
139
|
+
} else {
|
|
140
|
+
console.error(`Error: ${result.message}`);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
api.command("discover <url>").description("Analyze a URL and discover API endpoints").option("--register", "Auto-register if API is discovered").action(async (url, options) => {
|
|
145
|
+
const discovery = getAPIDiscovery();
|
|
146
|
+
const result = discovery.analyzeUrl(url);
|
|
147
|
+
if (result) {
|
|
148
|
+
console.log(`Discovered API: ${result.name}`);
|
|
149
|
+
console.log(` Base URL: ${result.baseUrl}`);
|
|
150
|
+
console.log(` Spec URL: ${result.specUrl || "not found"}`);
|
|
151
|
+
console.log(` Type: ${result.apiType || "rest"}`);
|
|
152
|
+
console.log(` Source: ${result.source}`);
|
|
153
|
+
console.log(` Confidence: ${(result.confidence * 100).toFixed(0)}%`);
|
|
154
|
+
if (result.apiType === "graphql") {
|
|
155
|
+
console.log(
|
|
156
|
+
`
|
|
157
|
+
Note: This is a GraphQL API. Use a GraphQL client for queries.`
|
|
158
|
+
);
|
|
159
|
+
} else if (result.apiType === "google-discovery") {
|
|
160
|
+
console.log(
|
|
161
|
+
`
|
|
162
|
+
Note: This uses Google Discovery format. Auth via gcloud CLI.`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
if (options.register) {
|
|
166
|
+
await discovery.registerAPI(result);
|
|
167
|
+
console.log(
|
|
168
|
+
`
|
|
169
|
+
API registered. Use: stackmemory api exec ${result.name} <path>`
|
|
170
|
+
);
|
|
171
|
+
} else {
|
|
172
|
+
console.log(
|
|
173
|
+
`
|
|
174
|
+
To register: stackmemory api add ${result.name} ${result.baseUrl}`
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
console.log("No API detected in this URL");
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
api.command("discovered").description("List all auto-discovered APIs").action(() => {
|
|
182
|
+
const discovery = getAPIDiscovery();
|
|
183
|
+
const discovered = discovery.getDiscoveredAPIs();
|
|
184
|
+
if (discovered.length === 0) {
|
|
185
|
+
console.log("No APIs discovered yet.");
|
|
186
|
+
console.log(
|
|
187
|
+
"Browse API documentation or use: stackmemory api discover <url>"
|
|
188
|
+
);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
console.log("Discovered APIs:");
|
|
192
|
+
for (const api2 of discovered) {
|
|
193
|
+
console.log(` ${api2.name}`);
|
|
194
|
+
console.log(` Base: ${api2.baseUrl}`);
|
|
195
|
+
console.log(` Spec: ${api2.specUrl || "none"}`);
|
|
196
|
+
console.log(` Confidence: ${(api2.confidence * 100).toFixed(0)}%`);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
api.command("register-discovered").description("Register all discovered APIs").action(async () => {
|
|
200
|
+
const discovery = getAPIDiscovery();
|
|
201
|
+
const discovered = discovery.getDiscoveredAPIs();
|
|
202
|
+
if (discovered.length === 0) {
|
|
203
|
+
console.log("No APIs to register. Use: stackmemory api discover <url>");
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
let registered = 0;
|
|
207
|
+
for (const api2 of discovered) {
|
|
208
|
+
if (await discovery.registerAPI(api2)) {
|
|
209
|
+
console.log(`Registered: ${api2.name}`);
|
|
210
|
+
registered++;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
console.log(`
|
|
214
|
+
Registered ${registered}/${discovered.length} APIs`);
|
|
215
|
+
});
|
|
216
|
+
api.command("help").description("Show API skill help").action(() => {
|
|
217
|
+
const skill = getAPISkill();
|
|
218
|
+
const discovery = getAPIDiscovery();
|
|
219
|
+
console.log(skill.getHelp());
|
|
220
|
+
console.log("\n---\n");
|
|
221
|
+
console.log(discovery.getHelp());
|
|
222
|
+
});
|
|
223
|
+
return api;
|
|
224
|
+
}
|
|
225
|
+
export {
|
|
226
|
+
createAPICommand
|
|
227
|
+
};
|
|
228
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/cli/commands/api.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * CLI Commands for API Skill\n *\n * Provides command-line interface for managing and executing APIs\n * via the Restish-based API skill.\n */\n\nimport { Command } from 'commander';\nimport { getAPISkill } from '../../skills/api-skill.js';\nimport { getAPIDiscovery } from '../../skills/api-discovery.js';\n\nexport function createAPICommand(): Command {\n const api = new Command('api');\n api.description('OpenAPI-based API access via Restish');\n\n // Add API\n api\n .command('add <name> <url>')\n .description('Register a new API')\n .option('--spec <url>', 'OpenAPI spec URL')\n .option(\n '--auth-type <type>',\n 'Authentication type (none|api-key|oauth2|basic)',\n 'none'\n )\n .option('--header-name <name>', 'Auth header name', 'Authorization')\n .option('--env-var <name>', 'Environment variable for auth token')\n .action(async (name: string, url: string, options) => {\n const skill = getAPISkill();\n const result = await skill.add(name, url, {\n spec: options.spec,\n authType: options.authType,\n headerName: options.headerName,\n envVar: options.envVar,\n });\n\n if (result.success) {\n console.log(`API '${name}' registered`);\n if (result.data) {\n console.log(JSON.stringify(result.data, null, 2));\n }\n } else {\n console.error(`Error: ${result.message}`);\n process.exit(1);\n }\n });\n\n // List APIs\n api\n .command('list')\n .description('List all registered APIs')\n .action(async () => {\n const skill = getAPISkill();\n const result = await skill.list();\n\n if (result.success) {\n if (Array.isArray(result.data) && result.data.length === 0) {\n console.log(\n 'No APIs registered. Use: stackmemory api add <name> <url>'\n );\n } else {\n console.log('Registered APIs:');\n for (const api of result.data as Array<{\n name: string;\n baseUrl: string;\n authType: string;\n operations: number | string;\n }>) {\n console.log(` ${api.name}`);\n console.log(` URL: ${api.baseUrl}`);\n console.log(` Auth: ${api.authType}`);\n console.log(` Operations: ${api.operations}`);\n }\n }\n } else {\n console.error(`Error: ${result.message}`);\n process.exit(1);\n }\n });\n\n // Describe API\n api\n .command('describe <name> [operation]')\n .description('Show API details or specific operation')\n .action(async (name: string, operation?: string) => {\n const skill = getAPISkill();\n const result = await skill.describe(name, operation);\n\n if (result.success) {\n console.log(result.message);\n if (result.data) {\n console.log(JSON.stringify(result.data, null, 2));\n }\n } else {\n console.error(`Error: ${result.message}`);\n process.exit(1);\n }\n });\n\n // Execute API operation\n api\n .command('exec <name> <operation>')\n .description('Execute an API operation')\n .option('--raw', 'Output raw response')\n .option('--filter <query>', 'Filter/project response using shorthand query')\n .option('-H, --header <header...>', 'Add custom headers (key:value)')\n .allowUnknownOption(true)\n .action(async (name: string, operation: string, options, command) => {\n const skill = getAPISkill();\n\n // Parse unknown options as API parameters\n const params: Record<string, unknown> = {};\n const args = command.args.slice(2); // Skip name and operation\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg.startsWith('--')) {\n const key = arg.slice(2);\n const nextArg = args[i + 1];\n if (nextArg && !nextArg.startsWith('--')) {\n params[key] = nextArg;\n i++;\n } else {\n params[key] = true;\n }\n }\n }\n\n // Parse headers\n const headers: Record<string, string> = {};\n if (options.header) {\n for (const h of options.header) {\n const [key, ...valueParts] = h.split(':');\n headers[key] = valueParts.join(':').trim();\n }\n }\n\n const result = await skill.exec(name, operation, params, {\n raw: options.raw,\n filter: options.filter,\n headers,\n });\n\n if (result.success) {\n if (typeof result.data === 'string') {\n console.log(result.data);\n } else {\n console.log(JSON.stringify(result.data, null, 2));\n }\n } else {\n console.error(`Error: ${result.message}`);\n process.exit(1);\n }\n });\n\n // Configure auth\n api\n .command('auth <name>')\n .description('Configure API authentication')\n .option('--token <token>', 'API token/key')\n .option('--env-var <name>', 'Environment variable name for token')\n .option('--oauth', 'Use OAuth2 flow')\n .option('--scopes <scopes>', 'OAuth2 scopes (comma-separated)')\n .action(async (name: string, options) => {\n const skill = getAPISkill();\n\n const result = await skill.auth(name, {\n token: options.token,\n envVar: options.envVar,\n oauth: options.oauth,\n scopes: options.scopes?.split(','),\n });\n\n if (result.success) {\n console.log(result.message);\n } else {\n console.error(`Error: ${result.message}`);\n process.exit(1);\n }\n });\n\n // Sync API\n api\n .command('sync <name>')\n .description('Refresh API operations from spec')\n .action(async (name: string) => {\n const skill = getAPISkill();\n const result = await skill.sync(name);\n\n if (result.success) {\n console.log(result.message);\n if (result.data?.operations) {\n console.log(\n `Operations: ${(result.data.operations as string[]).join(', ')}`\n );\n }\n } else {\n console.error(`Error: ${result.message}`);\n process.exit(1);\n }\n });\n\n // Remove API\n api\n .command('remove <name>')\n .description('Remove a registered API')\n .action(async (name: string) => {\n const skill = getAPISkill();\n const result = await skill.remove(name);\n\n if (result.success) {\n console.log(result.message);\n } else {\n console.error(`Error: ${result.message}`);\n process.exit(1);\n }\n });\n\n // Discover API from URL\n api\n .command('discover <url>')\n .description('Analyze a URL and discover API endpoints')\n .option('--register', 'Auto-register if API is discovered')\n .action(async (url: string, options) => {\n const discovery = getAPIDiscovery();\n\n // Use analyzeUrl directly for quick response (no network probing)\n const result = discovery.analyzeUrl(url);\n\n if (result) {\n console.log(`Discovered API: ${result.name}`);\n console.log(` Base URL: ${result.baseUrl}`);\n console.log(` Spec URL: ${result.specUrl || 'not found'}`);\n console.log(` Type: ${result.apiType || 'rest'}`);\n console.log(` Source: ${result.source}`);\n console.log(` Confidence: ${(result.confidence * 100).toFixed(0)}%`);\n\n if (result.apiType === 'graphql') {\n console.log(\n `\\nNote: This is a GraphQL API. Use a GraphQL client for queries.`\n );\n } else if (result.apiType === 'google-discovery') {\n console.log(\n `\\nNote: This uses Google Discovery format. Auth via gcloud CLI.`\n );\n }\n\n if (options.register) {\n await discovery.registerAPI(result);\n console.log(\n `\\nAPI registered. Use: stackmemory api exec ${result.name} <path>`\n );\n } else {\n console.log(\n `\\nTo register: stackmemory api add ${result.name} ${result.baseUrl}`\n );\n }\n } else {\n console.log('No API detected in this URL');\n }\n });\n\n // List discovered APIs\n api\n .command('discovered')\n .description('List all auto-discovered APIs')\n .action(() => {\n const discovery = getAPIDiscovery();\n const discovered = discovery.getDiscoveredAPIs();\n\n if (discovered.length === 0) {\n console.log('No APIs discovered yet.');\n console.log(\n 'Browse API documentation or use: stackmemory api discover <url>'\n );\n return;\n }\n\n console.log('Discovered APIs:');\n for (const api of discovered) {\n console.log(` ${api.name}`);\n console.log(` Base: ${api.baseUrl}`);\n console.log(` Spec: ${api.specUrl || 'none'}`);\n console.log(` Confidence: ${(api.confidence * 100).toFixed(0)}%`);\n }\n });\n\n // Register all discovered APIs\n api\n .command('register-discovered')\n .description('Register all discovered APIs')\n .action(async () => {\n const discovery = getAPIDiscovery();\n const discovered = discovery.getDiscoveredAPIs();\n\n if (discovered.length === 0) {\n console.log('No APIs to register. Use: stackmemory api discover <url>');\n return;\n }\n\n let registered = 0;\n for (const api of discovered) {\n if (await discovery.registerAPI(api)) {\n console.log(`Registered: ${api.name}`);\n registered++;\n }\n }\n\n console.log(`\\nRegistered ${registered}/${discovered.length} APIs`);\n });\n\n // Help\n api\n .command('help')\n .description('Show API skill help')\n .action(() => {\n const skill = getAPISkill();\n const discovery = getAPIDiscovery();\n console.log(skill.getHelp());\n console.log('\\n---\\n');\n console.log(discovery.getHelp());\n });\n\n return api;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["api"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import {
|
|
3
|
+
cleanupStaleProcesses,
|
|
4
|
+
findStaleProcesses,
|
|
5
|
+
getStackmemoryProcesses
|
|
6
|
+
} from "../../utils/process-cleanup.js";
|
|
7
|
+
function createCleanupProcessesCommand() {
|
|
8
|
+
const cmd = new Command("cleanup-processes");
|
|
9
|
+
cmd.description("Clean up stale stackmemory processes");
|
|
10
|
+
cmd.option("--max-age <hours>", "Max process age in hours (default: 24)", "24").option("--dry-run", "Show what would be killed without actually killing").option("--all", "Show all stackmemory processes (not just stale)").option("--force", "Kill without checking log activity").action((options) => {
|
|
11
|
+
const maxAgeHours = parseInt(options.maxAge, 10);
|
|
12
|
+
if (options.all) {
|
|
13
|
+
const processes = getStackmemoryProcesses();
|
|
14
|
+
if (processes.length === 0) {
|
|
15
|
+
console.log("No stackmemory processes running");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
console.log(`Found ${processes.length} stackmemory process(es):
|
|
19
|
+
`);
|
|
20
|
+
for (const proc of processes) {
|
|
21
|
+
const age = proc.ageHours < 1 ? `${Math.round(proc.ageHours * 60)}m` : `${Math.round(proc.ageHours)}h`;
|
|
22
|
+
console.log(` PID ${proc.pid} (${age} old)`);
|
|
23
|
+
console.log(` ${proc.command}`);
|
|
24
|
+
}
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const staleProcesses = options.force ? getStackmemoryProcesses().filter((p) => p.ageHours >= maxAgeHours) : findStaleProcesses(maxAgeHours);
|
|
28
|
+
if (staleProcesses.length === 0) {
|
|
29
|
+
console.log(`No stale processes older than ${maxAgeHours}h found`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
console.log(
|
|
33
|
+
`Found ${staleProcesses.length} stale process(es) older than ${maxAgeHours}h:
|
|
34
|
+
`
|
|
35
|
+
);
|
|
36
|
+
for (const proc of staleProcesses) {
|
|
37
|
+
const age = `${Math.round(proc.ageHours)}h`;
|
|
38
|
+
console.log(` PID ${proc.pid} (${age} old)`);
|
|
39
|
+
console.log(` ${proc.command}`);
|
|
40
|
+
if (proc.lastLogActivity) {
|
|
41
|
+
console.log(` Last log: ${proc.lastLogActivity.toISOString()}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (options.dryRun) {
|
|
45
|
+
console.log("\n[DRY RUN] No processes killed");
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
console.log("\nKilling stale processes...");
|
|
49
|
+
const result = cleanupStaleProcesses({ maxAgeHours, dryRun: false });
|
|
50
|
+
console.log(`
|
|
51
|
+
Killed: ${result.killed.length}`);
|
|
52
|
+
if (result.errors.length > 0) {
|
|
53
|
+
console.log(`Errors: ${result.errors.length}`);
|
|
54
|
+
for (const err of result.errors) {
|
|
55
|
+
console.log(` PID ${err.pid}: ${err.error}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return cmd;
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
createCleanupProcessesCommand
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=cleanup-processes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/cli/commands/cleanup-processes.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * CLI Command for Process Cleanup\n */\n\nimport { Command } from 'commander';\nimport {\n cleanupStaleProcesses,\n findStaleProcesses,\n getStackmemoryProcesses,\n} from '../../utils/process-cleanup.js';\n\nexport function createCleanupProcessesCommand(): Command {\n const cmd = new Command('cleanup-processes');\n cmd.description('Clean up stale stackmemory processes');\n\n cmd\n .option('--max-age <hours>', 'Max process age in hours (default: 24)', '24')\n .option('--dry-run', 'Show what would be killed without actually killing')\n .option('--all', 'Show all stackmemory processes (not just stale)')\n .option('--force', 'Kill without checking log activity')\n .action((options) => {\n const maxAgeHours = parseInt(options.maxAge, 10);\n\n if (options.all) {\n // Just list all processes\n const processes = getStackmemoryProcesses();\n\n if (processes.length === 0) {\n console.log('No stackmemory processes running');\n return;\n }\n\n console.log(`Found ${processes.length} stackmemory process(es):\\n`);\n for (const proc of processes) {\n const age =\n proc.ageHours < 1\n ? `${Math.round(proc.ageHours * 60)}m`\n : `${Math.round(proc.ageHours)}h`;\n console.log(` PID ${proc.pid} (${age} old)`);\n console.log(` ${proc.command}`);\n }\n return;\n }\n\n // Find and optionally kill stale processes\n const staleProcesses = options.force\n ? getStackmemoryProcesses().filter((p) => p.ageHours >= maxAgeHours)\n : findStaleProcesses(maxAgeHours);\n\n if (staleProcesses.length === 0) {\n console.log(`No stale processes older than ${maxAgeHours}h found`);\n return;\n }\n\n console.log(\n `Found ${staleProcesses.length} stale process(es) older than ${maxAgeHours}h:\\n`\n );\n\n for (const proc of staleProcesses) {\n const age = `${Math.round(proc.ageHours)}h`;\n console.log(` PID ${proc.pid} (${age} old)`);\n console.log(` ${proc.command}`);\n if (proc.lastLogActivity) {\n console.log(` Last log: ${proc.lastLogActivity.toISOString()}`);\n }\n }\n\n if (options.dryRun) {\n console.log('\\n[DRY RUN] No processes killed');\n return;\n }\n\n console.log('\\nKilling stale processes...');\n const result = cleanupStaleProcesses({ maxAgeHours, dryRun: false });\n\n console.log(`\\nKilled: ${result.killed.length}`);\n if (result.errors.length > 0) {\n console.log(`Errors: ${result.errors.length}`);\n for (const err of result.errors) {\n console.log(` PID ${err.pid}: ${err.error}`);\n }\n }\n });\n\n return cmd;\n}\n"],
|
|
5
|
+
"mappings": "AAIA,SAAS,eAAe;AACxB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,SAAS,gCAAyC;AACvD,QAAM,MAAM,IAAI,QAAQ,mBAAmB;AAC3C,MAAI,YAAY,sCAAsC;AAEtD,MACG,OAAO,qBAAqB,0CAA0C,IAAI,EAC1E,OAAO,aAAa,oDAAoD,EACxE,OAAO,SAAS,iDAAiD,EACjE,OAAO,WAAW,oCAAoC,EACtD,OAAO,CAAC,YAAY;AACnB,UAAM,cAAc,SAAS,QAAQ,QAAQ,EAAE;AAE/C,QAAI,QAAQ,KAAK;AAEf,YAAM,YAAY,wBAAwB;AAE1C,UAAI,UAAU,WAAW,GAAG;AAC1B,gBAAQ,IAAI,kCAAkC;AAC9C;AAAA,MACF;AAEA,cAAQ,IAAI,SAAS,UAAU,MAAM;AAAA,CAA6B;AAClE,iBAAW,QAAQ,WAAW;AAC5B,cAAM,MACJ,KAAK,WAAW,IACZ,GAAG,KAAK,MAAM,KAAK,WAAW,EAAE,CAAC,MACjC,GAAG,KAAK,MAAM,KAAK,QAAQ,CAAC;AAClC,gBAAQ,IAAI,SAAS,KAAK,GAAG,KAAK,GAAG,OAAO;AAC5C,gBAAQ,IAAI,OAAO,KAAK,OAAO,EAAE;AAAA,MACnC;AACA;AAAA,IACF;AAGA,UAAM,iBAAiB,QAAQ,QAC3B,wBAAwB,EAAE,OAAO,CAAC,MAAM,EAAE,YAAY,WAAW,IACjE,mBAAmB,WAAW;AAElC,QAAI,eAAe,WAAW,GAAG;AAC/B,cAAQ,IAAI,iCAAiC,WAAW,SAAS;AACjE;AAAA,IACF;AAEA,YAAQ;AAAA,MACN,SAAS,eAAe,MAAM,iCAAiC,WAAW;AAAA;AAAA,IAC5E;AAEA,eAAW,QAAQ,gBAAgB;AACjC,YAAM,MAAM,GAAG,KAAK,MAAM,KAAK,QAAQ,CAAC;AACxC,cAAQ,IAAI,SAAS,KAAK,GAAG,KAAK,GAAG,OAAO;AAC5C,cAAQ,IAAI,OAAO,KAAK,OAAO,EAAE;AACjC,UAAI,KAAK,iBAAiB;AACxB,gBAAQ,IAAI,iBAAiB,KAAK,gBAAgB,YAAY,CAAC,EAAE;AAAA,MACnE;AAAA,IACF;AAEA,QAAI,QAAQ,QAAQ;AAClB,cAAQ,IAAI,iCAAiC;AAC7C;AAAA,IACF;AAEA,YAAQ,IAAI,8BAA8B;AAC1C,UAAM,SAAS,sBAAsB,EAAE,aAAa,QAAQ,MAAM,CAAC;AAEnE,YAAQ,IAAI;AAAA,UAAa,OAAO,OAAO,MAAM,EAAE;AAC/C,QAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,cAAQ,IAAI,WAAW,OAAO,OAAO,MAAM,EAAE;AAC7C,iBAAW,OAAO,OAAO,QAAQ;AAC/B,gBAAQ,IAAI,SAAS,IAAI,GAAG,KAAK,IAAI,KAAK,EAAE;AAAA,MAC9C;AAAA,IACF;AAAA,EACF,CAAC;AAEH,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|