@stackmemoryai/stackmemory 0.5.22 → 0.5.24
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/dist/cli/claude-sm.js +2 -0
- package/dist/cli/claude-sm.js.map +2 -2
- package/dist/cli/commands/discovery.js +279 -0
- package/dist/cli/commands/discovery.js.map +7 -0
- package/dist/cli/commands/retrieval.js +248 -0
- package/dist/cli/commands/retrieval.js.map +7 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +2 -2
- package/dist/core/retrieval/llm-context-retrieval.js +33 -1
- package/dist/core/retrieval/llm-context-retrieval.js.map +2 -2
- package/dist/core/retrieval/llm-provider.js +128 -0
- package/dist/core/retrieval/llm-provider.js.map +7 -0
- package/dist/core/retrieval/retrieval-audit.js +236 -0
- package/dist/core/retrieval/retrieval-audit.js.map +7 -0
- package/dist/integrations/linear/client.js +125 -0
- package/dist/integrations/linear/client.js.map +2 -2
- package/dist/integrations/mcp/handlers/discovery-handlers.js +497 -0
- package/dist/integrations/mcp/handlers/discovery-handlers.js.map +7 -0
- package/dist/integrations/mcp/handlers/index.js +40 -12
- package/dist/integrations/mcp/handlers/index.js.map +2 -2
- package/dist/integrations/mcp/server.js +270 -0
- package/dist/integrations/mcp/server.js.map +2 -2
- package/dist/integrations/mcp/tool-definitions.js +141 -5
- package/dist/integrations/mcp/tool-definitions.js.map +2 -2
- package/package.json +1 -1
- package/dist/cli/commands/agent.js +0 -286
- package/dist/cli/commands/agent.js.map +0 -7
- package/dist/cli/commands/chromadb.js +0 -482
- package/dist/cli/commands/chromadb.js.map +0 -7
- package/dist/cli/commands/gc.js +0 -251
- package/dist/cli/commands/gc.js.map +0 -7
- package/dist/cli/commands/infinite-storage.js +0 -292
- package/dist/cli/commands/infinite-storage.js.map +0 -7
- package/dist/cli/commands/linear-create.js +0 -171
- package/dist/cli/commands/linear-create.js.map +0 -7
- package/dist/cli/commands/linear-list.js +0 -103
- package/dist/cli/commands/linear-list.js.map +0 -7
- package/dist/cli/commands/linear-migrate.js +0 -64
- package/dist/cli/commands/linear-migrate.js.map +0 -7
- package/dist/cli/commands/linear-test.js +0 -134
- package/dist/cli/commands/linear-test.js.map +0 -7
- package/dist/cli/commands/tui.js +0 -77
- package/dist/cli/commands/tui.js.map +0 -7
- package/dist/cli/commands/webhook.js +0 -181
- package/dist/cli/commands/webhook.js.map +0 -7
- package/dist/cli/streamlined-cli.js +0 -144
- package/dist/cli/streamlined-cli.js.map +0 -7
- package/dist/core/events/event-bus.js +0 -110
- package/dist/core/events/event-bus.js.map +0 -7
- package/dist/core/frame/workflow-templates-stub.js +0 -42
- package/dist/core/frame/workflow-templates-stub.js.map +0 -7
- package/dist/core/plugins/plugin-interface.js +0 -87
- package/dist/core/plugins/plugin-interface.js.map +0 -7
- package/dist/core/session/clear-survival-stub.js +0 -53
- package/dist/core/session/clear-survival-stub.js.map +0 -7
- package/dist/core/storage/chromadb-simple.js +0 -172
- package/dist/core/storage/chromadb-simple.js.map +0 -7
- package/dist/core/storage/simplified-storage.js +0 -328
- package/dist/core/storage/simplified-storage.js.map +0 -7
- package/dist/features/tasks/pebbles-task-store.js +0 -647
- package/dist/features/tasks/pebbles-task-store.js.map +0 -7
- package/dist/integrations/linear/sync-enhanced.js +0 -202
- package/dist/integrations/linear/sync-enhanced.js.map +0 -7
- package/dist/plugins/linear/index.js +0 -166
- package/dist/plugins/linear/index.js.map +0 -7
- package/dist/plugins/loader.js +0 -57
- package/dist/plugins/loader.js.map +0 -7
- package/dist/plugins/plugin-interface.js +0 -67
- package/dist/plugins/plugin-interface.js.map +0 -7
- package/dist/plugins/ralph/simple-ralph-plugin.js +0 -305
- package/dist/plugins/ralph/simple-ralph-plugin.js.map +0 -7
- package/dist/plugins/ralph/use-cases/code-generator.js +0 -151
- package/dist/plugins/ralph/use-cases/code-generator.js.map +0 -7
- package/dist/plugins/ralph/use-cases/test-generator.js +0 -201
- package/dist/plugins/ralph/use-cases/test-generator.js.map +0 -7
- package/dist/utils/logger.js +0 -52
- package/dist/utils/logger.js.map +0 -7
package/dist/cli/commands/gc.js
DELETED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import chalk from "chalk";
|
|
3
|
-
import ora from "ora";
|
|
4
|
-
import Table from "cli-table3";
|
|
5
|
-
import { IncrementalGarbageCollector } from "../../core/context/incremental-gc.js";
|
|
6
|
-
import { FrameManager } from "../../core/context/frame-manager.js";
|
|
7
|
-
import { Logger } from "../../core/monitoring/logger.js";
|
|
8
|
-
const logger = new Logger("GC-CLI");
|
|
9
|
-
function createGCCommand() {
|
|
10
|
-
const gc = new Command("gc").description("Manage incremental garbage collection system").alias("garbage-collect");
|
|
11
|
-
gc.command("status").description("Show garbage collection statistics").action(async () => {
|
|
12
|
-
const spinner = ora("Getting GC status...").start();
|
|
13
|
-
try {
|
|
14
|
-
const frameManager = new FrameManager();
|
|
15
|
-
const collector = new IncrementalGarbageCollector(frameManager);
|
|
16
|
-
const stats = collector.getStats();
|
|
17
|
-
spinner.stop();
|
|
18
|
-
console.log(
|
|
19
|
-
chalk.cyan("\n\u{1F5D1}\uFE0F Incremental Garbage Collection Status\n")
|
|
20
|
-
);
|
|
21
|
-
const table = new Table({
|
|
22
|
-
head: ["Metric", "Value"],
|
|
23
|
-
colWidths: [25, 20]
|
|
24
|
-
});
|
|
25
|
-
table.push(
|
|
26
|
-
["Total Frames", stats.totalFrames.toString()],
|
|
27
|
-
["Collected Frames", stats.collectedFrames.toString()],
|
|
28
|
-
["Collection Cycles", stats.cycleCount.toString()],
|
|
29
|
-
["Avg Cycle Time", `${stats.avgCycleTime.toFixed(2)}ms`],
|
|
30
|
-
["Protected Frames", stats.protectedFrames.toString()],
|
|
31
|
-
[
|
|
32
|
-
"Last Run",
|
|
33
|
-
stats.lastRunTime ? new Date(stats.lastRunTime).toLocaleString() : "Never"
|
|
34
|
-
]
|
|
35
|
-
);
|
|
36
|
-
console.log(table.toString());
|
|
37
|
-
if (stats.totalFrames > 0) {
|
|
38
|
-
const collectionRate = (stats.collectedFrames / stats.totalFrames * 100).toFixed(1);
|
|
39
|
-
const protectionRate = (stats.protectedFrames / stats.totalFrames * 100).toFixed(1);
|
|
40
|
-
console.log("\n\u{1F4CA} Collection Efficiency:");
|
|
41
|
-
console.log(` Collection Rate: ${collectionRate}%`);
|
|
42
|
-
console.log(` Protection Rate: ${protectionRate}%`);
|
|
43
|
-
}
|
|
44
|
-
} catch (error) {
|
|
45
|
-
spinner.fail("Failed to get GC status");
|
|
46
|
-
logger.error("GC status error", error);
|
|
47
|
-
console.error(
|
|
48
|
-
chalk.red(error instanceof Error ? error.message : "Unknown error")
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
gc.command("collect").description("Run manual garbage collection cycle").option(
|
|
53
|
-
"--dry-run",
|
|
54
|
-
"Show what would be collected without actually collecting"
|
|
55
|
-
).action(async (options) => {
|
|
56
|
-
const spinner = ora("Running garbage collection...").start();
|
|
57
|
-
try {
|
|
58
|
-
const frameManager = new FrameManager();
|
|
59
|
-
const collector = new IncrementalGarbageCollector(frameManager);
|
|
60
|
-
if (options.dryRun) {
|
|
61
|
-
spinner.text = "Analyzing collection candidates (dry run)...";
|
|
62
|
-
spinner.succeed("Dry run completed - check logs for details");
|
|
63
|
-
} else {
|
|
64
|
-
await collector.forceCollection();
|
|
65
|
-
const stats = collector.getStats();
|
|
66
|
-
spinner.succeed(
|
|
67
|
-
`Collection completed - collected ${stats.collectedFrames} frames`
|
|
68
|
-
);
|
|
69
|
-
console.log(chalk.green("\n\u2705 Manual collection completed"));
|
|
70
|
-
console.log(` Processed: ${stats.totalFrames} frames`);
|
|
71
|
-
console.log(` Collected: ${stats.collectedFrames} frames`);
|
|
72
|
-
console.log(` Protected: ${stats.protectedFrames} frames`);
|
|
73
|
-
}
|
|
74
|
-
} catch (error) {
|
|
75
|
-
spinner.fail("Collection failed");
|
|
76
|
-
logger.error("GC collection error", error);
|
|
77
|
-
console.error(
|
|
78
|
-
chalk.red(error instanceof Error ? error.message : "Unknown error")
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
gc.command("start").description("Start incremental GC daemon").option("--interval <seconds>", "Collection interval in seconds", "60").option("--frames-per-cycle <number>", "Frames to process per cycle", "100").action(async (options) => {
|
|
83
|
-
const spinner = ora("Starting GC daemon...").start();
|
|
84
|
-
try {
|
|
85
|
-
const frameManager = new FrameManager();
|
|
86
|
-
const collector = new IncrementalGarbageCollector(frameManager, {
|
|
87
|
-
cycleInterval: parseInt(options.interval) * 1e3,
|
|
88
|
-
framesPerCycle: parseInt(options.framesPerCycle)
|
|
89
|
-
});
|
|
90
|
-
collector.start();
|
|
91
|
-
spinner.succeed("GC daemon started");
|
|
92
|
-
console.log(chalk.green("\n\u{1F680} Incremental GC daemon is running"));
|
|
93
|
-
console.log(` Interval: ${options.interval}s`);
|
|
94
|
-
console.log(` Frames per cycle: ${options.framesPerCycle}`);
|
|
95
|
-
console.log("\nPress Ctrl+C to stop");
|
|
96
|
-
process.on("SIGINT", () => {
|
|
97
|
-
console.log("\n\u23F9\uFE0F Stopping GC daemon...");
|
|
98
|
-
collector.stop();
|
|
99
|
-
process.exit(0);
|
|
100
|
-
});
|
|
101
|
-
await new Promise(() => {
|
|
102
|
-
});
|
|
103
|
-
} catch (error) {
|
|
104
|
-
spinner.fail("Failed to start GC daemon");
|
|
105
|
-
logger.error("GC start error", error);
|
|
106
|
-
console.error(
|
|
107
|
-
chalk.red(error instanceof Error ? error.message : "Unknown error")
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
gc.command("config").description("View or update GC configuration").option("--set-interval <seconds>", "Set collection interval").option("--set-frames-per-cycle <number>", "Set frames per cycle").option("--set-max-age <days>", "Set max frame age before collection").action(async (options) => {
|
|
112
|
-
try {
|
|
113
|
-
const frameManager = new FrameManager();
|
|
114
|
-
const collector = new IncrementalGarbageCollector(frameManager);
|
|
115
|
-
if (options.setInterval || options.setFramesPerCycle || options.setMaxAge) {
|
|
116
|
-
const newConfig = {};
|
|
117
|
-
if (options.setInterval)
|
|
118
|
-
newConfig.cycleInterval = parseInt(options.setInterval) * 1e3;
|
|
119
|
-
if (options.setFramesPerCycle)
|
|
120
|
-
newConfig.framesPerCycle = parseInt(options.setFramesPerCycle);
|
|
121
|
-
if (options.setMaxAge)
|
|
122
|
-
newConfig.maxAge = parseInt(options.setMaxAge) * 24 * 60 * 60 * 1e3;
|
|
123
|
-
collector.updateConfig(newConfig);
|
|
124
|
-
console.log(chalk.green("\u2705 Configuration updated"));
|
|
125
|
-
}
|
|
126
|
-
console.log(chalk.cyan("\n\u2699\uFE0F Current GC Configuration\n"));
|
|
127
|
-
console.log("Cycle Interval: 60s");
|
|
128
|
-
console.log("Frames per Cycle: 100");
|
|
129
|
-
console.log("Max Age: 30 days");
|
|
130
|
-
console.log("\nGenerations:");
|
|
131
|
-
console.log(" Young: < 1 day");
|
|
132
|
-
console.log(" Mature: 1-7 days");
|
|
133
|
-
console.log(" Old: 7-30 days");
|
|
134
|
-
} catch (error) {
|
|
135
|
-
logger.error("GC config error", error);
|
|
136
|
-
console.error(
|
|
137
|
-
chalk.red(error instanceof Error ? error.message : "Unknown error")
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
gc.command("analyze").description("Analyze frame distribution and collection opportunities").action(async () => {
|
|
142
|
-
const spinner = ora("Analyzing frames...").start();
|
|
143
|
-
try {
|
|
144
|
-
const frameManager = new FrameManager();
|
|
145
|
-
const allFrames = await frameManager.getAllFrames();
|
|
146
|
-
if (allFrames.length === 0) {
|
|
147
|
-
spinner.succeed("No frames to analyze");
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
const now = Date.now();
|
|
151
|
-
const analysis = {
|
|
152
|
-
total: allFrames.length,
|
|
153
|
-
active: 0,
|
|
154
|
-
closed: 0,
|
|
155
|
-
young: 0,
|
|
156
|
-
mature: 0,
|
|
157
|
-
old: 0,
|
|
158
|
-
withOutputs: 0,
|
|
159
|
-
withoutOutputs: 0,
|
|
160
|
-
rootFrames: 0,
|
|
161
|
-
leafFrames: 0
|
|
162
|
-
};
|
|
163
|
-
for (const frame of allFrames) {
|
|
164
|
-
const age = now - frame.created_at;
|
|
165
|
-
if (frame.state === "active") analysis.active++;
|
|
166
|
-
else analysis.closed++;
|
|
167
|
-
if (age < 24 * 60 * 60 * 1e3) analysis.young++;
|
|
168
|
-
else if (age < 7 * 24 * 60 * 60 * 1e3) analysis.mature++;
|
|
169
|
-
else analysis.old++;
|
|
170
|
-
if (frame.outputs && Object.keys(frame.outputs).length > 0) {
|
|
171
|
-
analysis.withOutputs++;
|
|
172
|
-
} else {
|
|
173
|
-
analysis.withoutOutputs++;
|
|
174
|
-
}
|
|
175
|
-
if (frame.depth === 0) analysis.rootFrames++;
|
|
176
|
-
if (!allFrames.some((f) => f.parent_frame_id === frame.frame_id)) {
|
|
177
|
-
analysis.leafFrames++;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
spinner.stop();
|
|
181
|
-
console.log(chalk.cyan("\n\u{1F4CA} Frame Distribution Analysis\n"));
|
|
182
|
-
const stateTable = new Table({
|
|
183
|
-
head: ["Category", "Count", "Percentage"],
|
|
184
|
-
colWidths: [20, 10, 15]
|
|
185
|
-
});
|
|
186
|
-
const pct = (count) => `${(count / analysis.total * 100).toFixed(1)}%`;
|
|
187
|
-
stateTable.push(
|
|
188
|
-
["Active Frames", analysis.active.toString(), pct(analysis.active)],
|
|
189
|
-
["Closed Frames", analysis.closed.toString(), pct(analysis.closed)],
|
|
190
|
-
["", "", ""],
|
|
191
|
-
["Young (< 1 day)", analysis.young.toString(), pct(analysis.young)],
|
|
192
|
-
[
|
|
193
|
-
"Mature (1-7 days)",
|
|
194
|
-
analysis.mature.toString(),
|
|
195
|
-
pct(analysis.mature)
|
|
196
|
-
],
|
|
197
|
-
["Old (> 7 days)", analysis.old.toString(), pct(analysis.old)],
|
|
198
|
-
["", "", ""],
|
|
199
|
-
[
|
|
200
|
-
"With Outputs",
|
|
201
|
-
analysis.withOutputs.toString(),
|
|
202
|
-
pct(analysis.withOutputs)
|
|
203
|
-
],
|
|
204
|
-
[
|
|
205
|
-
"Without Outputs",
|
|
206
|
-
analysis.withoutOutputs.toString(),
|
|
207
|
-
pct(analysis.withoutOutputs)
|
|
208
|
-
],
|
|
209
|
-
["", "", ""],
|
|
210
|
-
[
|
|
211
|
-
"Root Frames",
|
|
212
|
-
analysis.rootFrames.toString(),
|
|
213
|
-
pct(analysis.rootFrames)
|
|
214
|
-
],
|
|
215
|
-
[
|
|
216
|
-
"Leaf Frames",
|
|
217
|
-
analysis.leafFrames.toString(),
|
|
218
|
-
pct(analysis.leafFrames)
|
|
219
|
-
]
|
|
220
|
-
);
|
|
221
|
-
console.log(stateTable.toString());
|
|
222
|
-
console.log(chalk.yellow("\n\u{1F4A1} Collection Recommendations:\n"));
|
|
223
|
-
const candidatesForCollection = analysis.closed + analysis.withoutOutputs;
|
|
224
|
-
console.log(
|
|
225
|
-
`\u2022 Potential collection candidates: ${candidatesForCollection} frames`
|
|
226
|
-
);
|
|
227
|
-
console.log(
|
|
228
|
-
`\u2022 Estimated space savings: ${(candidatesForCollection / analysis.total * 100).toFixed(1)}%`
|
|
229
|
-
);
|
|
230
|
-
if (analysis.old > 0) {
|
|
231
|
-
console.log(`\u2022 ${analysis.old} old frames ready for collection`);
|
|
232
|
-
}
|
|
233
|
-
if (analysis.withoutOutputs > 0) {
|
|
234
|
-
console.log(
|
|
235
|
-
`\u2022 ${analysis.withoutOutputs} frames without outputs can be collected`
|
|
236
|
-
);
|
|
237
|
-
}
|
|
238
|
-
} catch (error) {
|
|
239
|
-
spinner.fail("Analysis failed");
|
|
240
|
-
logger.error("GC analysis error", error);
|
|
241
|
-
console.error(
|
|
242
|
-
chalk.red(error instanceof Error ? error.message : "Unknown error")
|
|
243
|
-
);
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
return gc;
|
|
247
|
-
}
|
|
248
|
-
export {
|
|
249
|
-
createGCCommand
|
|
250
|
-
};
|
|
251
|
-
//# sourceMappingURL=gc.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/cli/commands/gc.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * CLI commands for Incremental Garbage Collection management\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport Table from 'cli-table3';\nimport { IncrementalGarbageCollector } from '../../core/context/incremental-gc.js';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport { Logger } from '../../core/monitoring/logger.js';\n\nconst logger = new Logger('GC-CLI');\n\nexport function createGCCommand(): Command {\n const gc = new Command('gc')\n .description('Manage incremental garbage collection system')\n .alias('garbage-collect');\n\n // Status command\n gc.command('status')\n .description('Show garbage collection statistics')\n .action(async () => {\n const spinner = ora('Getting GC status...').start();\n\n try {\n const frameManager = new FrameManager();\n const collector = new IncrementalGarbageCollector(frameManager);\n\n const stats = collector.getStats();\n spinner.stop();\n\n console.log(\n chalk.cyan('\\n\uD83D\uDDD1\uFE0F Incremental Garbage Collection Status\\n')\n );\n\n const table = new Table({\n head: ['Metric', 'Value'],\n colWidths: [25, 20],\n });\n\n table.push(\n ['Total Frames', stats.totalFrames.toString()],\n ['Collected Frames', stats.collectedFrames.toString()],\n ['Collection Cycles', stats.cycleCount.toString()],\n ['Avg Cycle Time', `${stats.avgCycleTime.toFixed(2)}ms`],\n ['Protected Frames', stats.protectedFrames.toString()],\n [\n 'Last Run',\n stats.lastRunTime\n ? new Date(stats.lastRunTime).toLocaleString()\n : 'Never',\n ]\n );\n\n console.log(table.toString());\n\n // Show efficiency metrics\n if (stats.totalFrames > 0) {\n const collectionRate = (\n (stats.collectedFrames / stats.totalFrames) *\n 100\n ).toFixed(1);\n const protectionRate = (\n (stats.protectedFrames / stats.totalFrames) *\n 100\n ).toFixed(1);\n\n console.log('\\n\uD83D\uDCCA Collection Efficiency:');\n console.log(` Collection Rate: ${collectionRate}%`);\n console.log(` Protection Rate: ${protectionRate}%`);\n }\n } catch (error: unknown) {\n spinner.fail('Failed to get GC status');\n logger.error('GC status error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Manual collection command\n gc.command('collect')\n .description('Run manual garbage collection cycle')\n .option(\n '--dry-run',\n 'Show what would be collected without actually collecting'\n )\n .action(async (options) => {\n const spinner = ora('Running garbage collection...').start();\n\n try {\n const frameManager = new FrameManager();\n const collector = new IncrementalGarbageCollector(frameManager);\n\n if (options.dryRun) {\n spinner.text = 'Analyzing collection candidates (dry run)...';\n // TODO: Implement dry run mode\n spinner.succeed('Dry run completed - check logs for details');\n } else {\n await collector.forceCollection();\n const stats = collector.getStats();\n\n spinner.succeed(\n `Collection completed - collected ${stats.collectedFrames} frames`\n );\n\n console.log(chalk.green('\\n\u2705 Manual collection completed'));\n console.log(` Processed: ${stats.totalFrames} frames`);\n console.log(` Collected: ${stats.collectedFrames} frames`);\n console.log(` Protected: ${stats.protectedFrames} frames`);\n }\n } catch (error: unknown) {\n spinner.fail('Collection failed');\n logger.error('GC collection error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Start/stop daemon commands\n gc.command('start')\n .description('Start incremental GC daemon')\n .option('--interval <seconds>', 'Collection interval in seconds', '60')\n .option('--frames-per-cycle <number>', 'Frames to process per cycle', '100')\n .action(async (options) => {\n const spinner = ora('Starting GC daemon...').start();\n\n try {\n const frameManager = new FrameManager();\n const collector = new IncrementalGarbageCollector(frameManager, {\n cycleInterval: parseInt(options.interval) * 1000,\n framesPerCycle: parseInt(options.framesPerCycle),\n });\n\n collector.start();\n\n spinner.succeed('GC daemon started');\n console.log(chalk.green('\\n\uD83D\uDE80 Incremental GC daemon is running'));\n console.log(` Interval: ${options.interval}s`);\n console.log(` Frames per cycle: ${options.framesPerCycle}`);\n console.log('\\nPress Ctrl+C to stop');\n\n // Keep process alive\n process.on('SIGINT', () => {\n console.log('\\n\u23F9\uFE0F Stopping GC daemon...');\n collector.stop();\n process.exit(0);\n });\n\n // Keep the process running\n await new Promise(() => {}); // Run forever\n } catch (error: unknown) {\n spinner.fail('Failed to start GC daemon');\n logger.error('GC start error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Configuration command\n gc.command('config')\n .description('View or update GC configuration')\n .option('--set-interval <seconds>', 'Set collection interval')\n .option('--set-frames-per-cycle <number>', 'Set frames per cycle')\n .option('--set-max-age <days>', 'Set max frame age before collection')\n .action(async (options) => {\n try {\n const frameManager = new FrameManager();\n const collector = new IncrementalGarbageCollector(frameManager);\n\n if (\n options.setInterval ||\n options.setFramesPerCycle ||\n options.setMaxAge\n ) {\n // Update configuration\n const newConfig: any = {};\n if (options.setInterval)\n newConfig.cycleInterval = parseInt(options.setInterval) * 1000;\n if (options.setFramesPerCycle)\n newConfig.framesPerCycle = parseInt(options.setFramesPerCycle);\n if (options.setMaxAge)\n newConfig.maxAge =\n parseInt(options.setMaxAge) * 24 * 60 * 60 * 1000;\n\n collector.updateConfig(newConfig);\n console.log(chalk.green('\u2705 Configuration updated'));\n }\n\n // Show current config\n console.log(chalk.cyan('\\n\u2699\uFE0F Current GC Configuration\\n'));\n console.log('Cycle Interval: 60s');\n console.log('Frames per Cycle: 100');\n console.log('Max Age: 30 days');\n console.log('\\nGenerations:');\n console.log(' Young: < 1 day');\n console.log(' Mature: 1-7 days');\n console.log(' Old: 7-30 days');\n } catch (error: unknown) {\n logger.error('GC config error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Analysis command\n gc.command('analyze')\n .description('Analyze frame distribution and collection opportunities')\n .action(async () => {\n const spinner = ora('Analyzing frames...').start();\n\n try {\n const frameManager = new FrameManager();\n const allFrames = await frameManager.getAllFrames();\n\n if (allFrames.length === 0) {\n spinner.succeed('No frames to analyze');\n return;\n }\n\n // Analyze frame distribution\n const now = Date.now();\n const analysis = {\n total: allFrames.length,\n active: 0,\n closed: 0,\n young: 0,\n mature: 0,\n old: 0,\n withOutputs: 0,\n withoutOutputs: 0,\n rootFrames: 0,\n leafFrames: 0,\n };\n\n for (const frame of allFrames) {\n const age = now - frame.created_at;\n\n // State analysis\n if (frame.state === 'active') analysis.active++;\n else analysis.closed++;\n\n // Age analysis\n if (age < 24 * 60 * 60 * 1000) analysis.young++;\n else if (age < 7 * 24 * 60 * 60 * 1000) analysis.mature++;\n else analysis.old++;\n\n // Output analysis\n if (frame.outputs && Object.keys(frame.outputs).length > 0) {\n analysis.withOutputs++;\n } else {\n analysis.withoutOutputs++;\n }\n\n // Hierarchy analysis\n if (frame.depth === 0) analysis.rootFrames++;\n if (!allFrames.some((f) => f.parent_frame_id === frame.frame_id)) {\n analysis.leafFrames++;\n }\n }\n\n spinner.stop();\n\n console.log(chalk.cyan('\\n\uD83D\uDCCA Frame Distribution Analysis\\n'));\n\n const stateTable = new Table({\n head: ['Category', 'Count', 'Percentage'],\n colWidths: [20, 10, 15],\n });\n\n const pct = (count: number) =>\n `${((count / analysis.total) * 100).toFixed(1)}%`;\n\n stateTable.push(\n ['Active Frames', analysis.active.toString(), pct(analysis.active)],\n ['Closed Frames', analysis.closed.toString(), pct(analysis.closed)],\n ['', '', ''],\n ['Young (< 1 day)', analysis.young.toString(), pct(analysis.young)],\n [\n 'Mature (1-7 days)',\n analysis.mature.toString(),\n pct(analysis.mature),\n ],\n ['Old (> 7 days)', analysis.old.toString(), pct(analysis.old)],\n ['', '', ''],\n [\n 'With Outputs',\n analysis.withOutputs.toString(),\n pct(analysis.withOutputs),\n ],\n [\n 'Without Outputs',\n analysis.withoutOutputs.toString(),\n pct(analysis.withoutOutputs),\n ],\n ['', '', ''],\n [\n 'Root Frames',\n analysis.rootFrames.toString(),\n pct(analysis.rootFrames),\n ],\n [\n 'Leaf Frames',\n analysis.leafFrames.toString(),\n pct(analysis.leafFrames),\n ]\n );\n\n console.log(stateTable.toString());\n\n // Collection recommendations\n console.log(chalk.yellow('\\n\uD83D\uDCA1 Collection Recommendations:\\n'));\n const candidatesForCollection =\n analysis.closed + analysis.withoutOutputs;\n console.log(\n `\u2022 Potential collection candidates: ${candidatesForCollection} frames`\n );\n console.log(\n `\u2022 Estimated space savings: ${((candidatesForCollection / analysis.total) * 100).toFixed(1)}%`\n );\n\n if (analysis.old > 0) {\n console.log(`\u2022 ${analysis.old} old frames ready for collection`);\n }\n if (analysis.withoutOutputs > 0) {\n console.log(\n `\u2022 ${analysis.withoutOutputs} frames without outputs can be collected`\n );\n }\n } catch (error: unknown) {\n spinner.fail('Analysis failed');\n logger.error('GC analysis error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n return gc;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import chalk from "chalk";
|
|
3
|
-
import ora from "ora";
|
|
4
|
-
import Table from "cli-table3";
|
|
5
|
-
import {
|
|
6
|
-
InfiniteStorageSystem
|
|
7
|
-
} from "../../core/storage/infinite-storage.js";
|
|
8
|
-
import { FrameManager } from "../../core/context/frame-manager.js";
|
|
9
|
-
import { Logger } from "../../core/monitoring/logger.js";
|
|
10
|
-
import dotenv from "dotenv";
|
|
11
|
-
import path from "path";
|
|
12
|
-
import { fileURLToPath } from "url";
|
|
13
|
-
function getEnv(key, defaultValue) {
|
|
14
|
-
const value = process.env[key];
|
|
15
|
-
if (value === void 0) {
|
|
16
|
-
if (defaultValue !== void 0) return defaultValue;
|
|
17
|
-
throw new Error(`Environment variable ${key} is required`);
|
|
18
|
-
}
|
|
19
|
-
return value;
|
|
20
|
-
}
|
|
21
|
-
function getOptionalEnv(key) {
|
|
22
|
-
return process.env[key];
|
|
23
|
-
}
|
|
24
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
25
|
-
dotenv.config({
|
|
26
|
-
path: path.join(__dirname, "../../../.env"),
|
|
27
|
-
override: true,
|
|
28
|
-
silent: true
|
|
29
|
-
});
|
|
30
|
-
const logger = new Logger("InfiniteStorage-CLI");
|
|
31
|
-
function createInfiniteStorageCommand() {
|
|
32
|
-
const storage = new Command("infinite-storage").description("Manage infinite storage system with tiered storage").alias("storage");
|
|
33
|
-
storage.command("init").description("Initialize infinite storage system").option("--redis-url <url>", "Redis connection URL").option("--timeseries-url <url>", "TimeSeries DB connection URL").option("--s3-bucket <bucket>", "S3 bucket name").option("--s3-region <region>", "S3 region", "us-east-1").action(async (options) => {
|
|
34
|
-
const spinner = ora("Initializing infinite storage...").start();
|
|
35
|
-
try {
|
|
36
|
-
const config = {
|
|
37
|
-
redis: {
|
|
38
|
-
url: options.redisUrl || process.env["REDIS_URL"] || "redis://localhost:6379",
|
|
39
|
-
ttlSeconds: 3600,
|
|
40
|
-
maxMemoryMB: parseInt(process.env["REDIS_MAX_MEMORY_MB"] || "512")
|
|
41
|
-
},
|
|
42
|
-
timeseries: {
|
|
43
|
-
connectionString: options.timeseriesUrl || process.env["TIMESERIES_URL"] || "",
|
|
44
|
-
retentionDays: 30
|
|
45
|
-
},
|
|
46
|
-
s3: {
|
|
47
|
-
bucket: options.s3Bucket || process.env["S3_BUCKET"] || "",
|
|
48
|
-
region: options.s3Region || process.env["AWS_REGION"] || "us-east-1",
|
|
49
|
-
accessKeyId: process.env["AWS_ACCESS_KEY_ID"],
|
|
50
|
-
secretAccessKey: process.env["AWS_SECRET_ACCESS_KEY"]
|
|
51
|
-
},
|
|
52
|
-
tiers: []
|
|
53
|
-
};
|
|
54
|
-
const storage2 = new InfiniteStorageSystem(config);
|
|
55
|
-
await storage2.initialize();
|
|
56
|
-
spinner.succeed("Infinite storage initialized");
|
|
57
|
-
console.log(chalk.green("\n\u2705 Storage Tiers Configured:"));
|
|
58
|
-
console.log(" Hot (Redis): < 1 hour, 5ms latency");
|
|
59
|
-
console.log(" Warm (TimeSeries): 1h - 7 days, 50ms latency");
|
|
60
|
-
console.log(" Cold (S3): 7 - 30 days, 100ms latency");
|
|
61
|
-
console.log(" Archive (Glacier): > 30 days, 1h latency");
|
|
62
|
-
const envPath = path.join(__dirname, "../../../.env");
|
|
63
|
-
const updates = [];
|
|
64
|
-
if (!process.env["REDIS_URL"] && options.redisUrl) {
|
|
65
|
-
updates.push(`REDIS_URL=${options.redisUrl}`);
|
|
66
|
-
}
|
|
67
|
-
if (!process.env["TIMESERIES_URL"] && options.timeseriesUrl) {
|
|
68
|
-
updates.push(`TIMESERIES_URL=${options.timeseriesUrl}`);
|
|
69
|
-
}
|
|
70
|
-
if (!process.env["S3_BUCKET"] && options.s3Bucket) {
|
|
71
|
-
updates.push(`S3_BUCKET=${options.s3Bucket}`);
|
|
72
|
-
}
|
|
73
|
-
if (updates.length > 0) {
|
|
74
|
-
const fs = await import("fs");
|
|
75
|
-
fs.appendFileSync(
|
|
76
|
-
envPath,
|
|
77
|
-
"\n# Infinite Storage Configuration\n" + updates.join("\n") + "\n"
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
} catch (error) {
|
|
81
|
-
spinner.fail("Failed to initialize storage");
|
|
82
|
-
logger.error("Initialization error", error);
|
|
83
|
-
console.error(
|
|
84
|
-
chalk.red(error instanceof Error ? error.message : "Unknown error")
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
storage.command("store").description("Store current frames in infinite storage").option("--project <name>", "Project name").option("--user <id>", "User ID").action(async (options) => {
|
|
89
|
-
const spinner = ora("Storing frames...").start();
|
|
90
|
-
try {
|
|
91
|
-
const config = getStorageConfig();
|
|
92
|
-
const storage2 = new InfiniteStorageSystem(config);
|
|
93
|
-
await storage2.initialize();
|
|
94
|
-
const frameManager = new FrameManager();
|
|
95
|
-
const frames = frameManager.getAllFrames();
|
|
96
|
-
const userId = options.user || process.env["USER"] || "default";
|
|
97
|
-
for (const frame of frames) {
|
|
98
|
-
await storage2.storeFrame(frame, userId);
|
|
99
|
-
}
|
|
100
|
-
spinner.succeed(`Stored ${frames.length} frames`);
|
|
101
|
-
} catch (error) {
|
|
102
|
-
spinner.fail("Failed to store frames");
|
|
103
|
-
logger.error("Store error", error);
|
|
104
|
-
console.error(
|
|
105
|
-
chalk.red(error instanceof Error ? error.message : "Unknown error")
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
storage.command("retrieve <frameId>").description("Retrieve a frame from storage").option("--user <id>", "User ID").action(async (frameId, options) => {
|
|
110
|
-
const spinner = ora("Retrieving frame...").start();
|
|
111
|
-
try {
|
|
112
|
-
const config = getStorageConfig();
|
|
113
|
-
const storage2 = new InfiniteStorageSystem(config);
|
|
114
|
-
await storage2.initialize();
|
|
115
|
-
const userId = options.user || process.env["USER"] || "default";
|
|
116
|
-
const frame = await storage2.retrieveFrame(frameId, userId);
|
|
117
|
-
spinner.stop();
|
|
118
|
-
if (frame) {
|
|
119
|
-
console.log(chalk.green("\n\u2705 Frame Retrieved:"));
|
|
120
|
-
console.log(JSON.stringify(frame, null, 2));
|
|
121
|
-
} else {
|
|
122
|
-
console.log(chalk.yellow("Frame not found"));
|
|
123
|
-
}
|
|
124
|
-
} catch (error) {
|
|
125
|
-
spinner.fail("Failed to retrieve frame");
|
|
126
|
-
logger.error("Retrieve error", error);
|
|
127
|
-
console.error(
|
|
128
|
-
chalk.red(error instanceof Error ? error.message : "Unknown error")
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
storage.command("metrics").description("Show storage system metrics").action(async () => {
|
|
133
|
-
const spinner = ora("Fetching metrics...").start();
|
|
134
|
-
try {
|
|
135
|
-
const config = getStorageConfig();
|
|
136
|
-
const storage2 = new InfiniteStorageSystem(config);
|
|
137
|
-
await storage2.initialize();
|
|
138
|
-
const metrics = await storage2.getMetrics();
|
|
139
|
-
spinner.stop();
|
|
140
|
-
console.log(chalk.cyan("\n\u{1F4CA} Infinite Storage Metrics\n"));
|
|
141
|
-
const table = new Table({
|
|
142
|
-
head: ["Metric", "Value"],
|
|
143
|
-
colWidths: [30, 40]
|
|
144
|
-
});
|
|
145
|
-
table.push(
|
|
146
|
-
["Total Objects", metrics.totalObjects.toString()],
|
|
147
|
-
["Storage Size", formatBytes(metrics.storageBytes)],
|
|
148
|
-
["Avg Latency", `${metrics.avgLatencyMs.toFixed(2)}ms`],
|
|
149
|
-
["P50 Latency", `${metrics.p50LatencyMs}ms`],
|
|
150
|
-
["P99 Latency", `${metrics.p99LatencyMs}ms`]
|
|
151
|
-
);
|
|
152
|
-
console.log(table.toString());
|
|
153
|
-
if (Object.keys(metrics.tierDistribution).length > 0) {
|
|
154
|
-
console.log("\nTier Distribution:");
|
|
155
|
-
for (const [tier, count] of Object.entries(
|
|
156
|
-
metrics.tierDistribution
|
|
157
|
-
)) {
|
|
158
|
-
const percentage = (count / metrics.totalObjects * 100).toFixed(
|
|
159
|
-
1
|
|
160
|
-
);
|
|
161
|
-
console.log(` ${tier}: ${count} objects (${percentage}%)`);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
console.log(chalk.cyan("\n\u{1F3AF} STA-287 Performance Targets:"));
|
|
165
|
-
const p50Target = metrics.p50LatencyMs <= 50;
|
|
166
|
-
const p99Target = metrics.p99LatencyMs <= 500;
|
|
167
|
-
console.log(
|
|
168
|
-
` P50 \u2264 50ms: ${p50Target ? chalk.green("\u2705 PASS") : chalk.red("\u274C FAIL")} (${metrics.p50LatencyMs}ms)`
|
|
169
|
-
);
|
|
170
|
-
console.log(
|
|
171
|
-
` P99 \u2264 500ms: ${p99Target ? chalk.green("\u2705 PASS") : chalk.red("\u274C FAIL")} (${metrics.p99LatencyMs}ms)`
|
|
172
|
-
);
|
|
173
|
-
} catch (error) {
|
|
174
|
-
spinner.fail("Failed to get metrics");
|
|
175
|
-
logger.error("Metrics error", error);
|
|
176
|
-
console.error(
|
|
177
|
-
chalk.red(error instanceof Error ? error.message : "Unknown error")
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
storage.command("migrate").description("Manually trigger tier migration").action(async () => {
|
|
182
|
-
const spinner = ora("Running migration...").start();
|
|
183
|
-
try {
|
|
184
|
-
const config = getStorageConfig();
|
|
185
|
-
const storage2 = new InfiniteStorageSystem(config);
|
|
186
|
-
await storage2.initialize();
|
|
187
|
-
await storage2.migrateAgedData();
|
|
188
|
-
spinner.succeed("Migration completed");
|
|
189
|
-
} catch (error) {
|
|
190
|
-
spinner.fail("Migration failed");
|
|
191
|
-
logger.error("Migration error", error);
|
|
192
|
-
console.error(
|
|
193
|
-
chalk.red(error instanceof Error ? error.message : "Unknown error")
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
storage.command("status").description("Check storage system status").action(async () => {
|
|
198
|
-
const spinner = ora("Checking status...").start();
|
|
199
|
-
try {
|
|
200
|
-
const config = getStorageConfig();
|
|
201
|
-
spinner.stop();
|
|
202
|
-
console.log(chalk.cyan("\n\u{1F4E6} Storage System Status\n"));
|
|
203
|
-
if (config.redis?.url) {
|
|
204
|
-
try {
|
|
205
|
-
const { createClient } = await import("redis");
|
|
206
|
-
const client = createClient({ url: config.redis.url });
|
|
207
|
-
await client.connect();
|
|
208
|
-
await client.ping();
|
|
209
|
-
await client.quit();
|
|
210
|
-
console.log("Redis (Hot Tier): " + chalk.green("\u2705 Connected"));
|
|
211
|
-
} catch {
|
|
212
|
-
console.log("Redis (Hot Tier): " + chalk.red("\u274C Not connected"));
|
|
213
|
-
}
|
|
214
|
-
} else {
|
|
215
|
-
console.log("Redis (Hot Tier): " + chalk.yellow("\u26A0\uFE0F Not configured"));
|
|
216
|
-
}
|
|
217
|
-
if (config.timeseries?.connectionString) {
|
|
218
|
-
try {
|
|
219
|
-
const { Pool } = await import("pg");
|
|
220
|
-
const pool = new Pool({
|
|
221
|
-
connectionString: config.timeseries.connectionString
|
|
222
|
-
});
|
|
223
|
-
await pool.query("SELECT 1");
|
|
224
|
-
await pool.end();
|
|
225
|
-
console.log(
|
|
226
|
-
"TimeSeries DB (Warm Tier): " + chalk.green("\u2705 Connected")
|
|
227
|
-
);
|
|
228
|
-
} catch {
|
|
229
|
-
console.log(
|
|
230
|
-
"TimeSeries DB (Warm Tier): " + chalk.red("\u274C Not connected")
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
} else {
|
|
234
|
-
console.log(
|
|
235
|
-
"TimeSeries DB (Warm Tier): " + chalk.yellow("\u26A0\uFE0F Not configured")
|
|
236
|
-
);
|
|
237
|
-
}
|
|
238
|
-
if (config.s3?.bucket) {
|
|
239
|
-
console.log(
|
|
240
|
-
`S3 (Cold/Archive Tier): ${chalk.green("\u2705")} Bucket: ${config.s3.bucket}`
|
|
241
|
-
);
|
|
242
|
-
} else {
|
|
243
|
-
console.log(
|
|
244
|
-
"S3 (Cold/Archive Tier): " + chalk.yellow("\u26A0\uFE0F Not configured")
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
console.log(
|
|
248
|
-
"\n" + chalk.gray(
|
|
249
|
-
"Configure missing tiers with: stackmemory infinite-storage init"
|
|
250
|
-
)
|
|
251
|
-
);
|
|
252
|
-
} catch (error) {
|
|
253
|
-
spinner.fail("Failed to check status");
|
|
254
|
-
logger.error("Status error", error);
|
|
255
|
-
console.error(
|
|
256
|
-
chalk.red(error instanceof Error ? error.message : "Unknown error")
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
return storage;
|
|
261
|
-
}
|
|
262
|
-
function getStorageConfig() {
|
|
263
|
-
return {
|
|
264
|
-
redis: {
|
|
265
|
-
url: process.env["REDIS_URL"] || "redis://localhost:6379",
|
|
266
|
-
ttlSeconds: parseInt(process.env["REDIS_TTL"] || "3600"),
|
|
267
|
-
maxMemoryMB: parseInt(process.env["REDIS_MAX_MEMORY_MB"] || "512")
|
|
268
|
-
},
|
|
269
|
-
timeseries: {
|
|
270
|
-
connectionString: process.env["TIMESERIES_URL"] || "",
|
|
271
|
-
retentionDays: parseInt(process.env["TIMESERIES_RETENTION_DAYS"] || "30")
|
|
272
|
-
},
|
|
273
|
-
s3: {
|
|
274
|
-
bucket: process.env["S3_BUCKET"] || "",
|
|
275
|
-
region: process.env["AWS_REGION"] || "us-east-1",
|
|
276
|
-
accessKeyId: process.env["AWS_ACCESS_KEY_ID"],
|
|
277
|
-
secretAccessKey: process.env["AWS_SECRET_ACCESS_KEY"]
|
|
278
|
-
},
|
|
279
|
-
tiers: []
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
function formatBytes(bytes) {
|
|
283
|
-
if (bytes === 0) return "0 Bytes";
|
|
284
|
-
const k = 1024;
|
|
285
|
-
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
|
|
286
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
287
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
|
|
288
|
-
}
|
|
289
|
-
export {
|
|
290
|
-
createInfiniteStorageCommand
|
|
291
|
-
};
|
|
292
|
-
//# sourceMappingURL=infinite-storage.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/cli/commands/infinite-storage.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * CLI commands for Infinite Storage System management\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport Table from 'cli-table3';\nimport {\n InfiniteStorageSystem,\n StorageConfig,\n} from '../../core/storage/infinite-storage.js';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport { Logger } from '../../core/monitoring/logger.js';\nimport dotenv from 'dotenv';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n// Type-safe environment variable access\nfunction getEnv(key: string, defaultValue?: string): string {\n const value = process.env[key];\n if (value === undefined) {\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${key} is required`);\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// Load environment variables\ndotenv.config({\n path: path.join(__dirname, '../../../.env'),\n override: true,\n silent: true,\n});\n\nconst logger = new Logger('InfiniteStorage-CLI');\n\nexport function createInfiniteStorageCommand(): Command {\n const storage = new Command('infinite-storage')\n .description('Manage infinite storage system with tiered storage')\n .alias('storage');\n\n // Initialize storage system\n storage\n .command('init')\n .description('Initialize infinite storage system')\n .option('--redis-url <url>', 'Redis connection URL')\n .option('--timeseries-url <url>', 'TimeSeries DB connection URL')\n .option('--s3-bucket <bucket>', 'S3 bucket name')\n .option('--s3-region <region>', 'S3 region', 'us-east-1')\n .action(async (options) => {\n const spinner = ora('Initializing infinite storage...').start();\n\n try {\n const config: StorageConfig = {\n redis: {\n url:\n options.redisUrl ||\n process.env['REDIS_URL'] ||\n 'redis://localhost:6379',\n ttlSeconds: 3600,\n maxMemoryMB: parseInt(process.env['REDIS_MAX_MEMORY_MB'] || '512'),\n },\n timeseries: {\n connectionString:\n options.timeseriesUrl || process.env['TIMESERIES_URL'] || '',\n retentionDays: 30,\n },\n s3: {\n bucket: options.s3Bucket || process.env['S3_BUCKET'] || '',\n region:\n options.s3Region || process.env['AWS_REGION'] || 'us-east-1',\n accessKeyId: process.env['AWS_ACCESS_KEY_ID'],\n secretAccessKey: process.env['AWS_SECRET_ACCESS_KEY'],\n },\n tiers: [],\n };\n\n const storage = new InfiniteStorageSystem(config);\n await storage.initialize();\n\n spinner.succeed('Infinite storage initialized');\n\n console.log(chalk.green('\\n\u2705 Storage Tiers Configured:'));\n console.log(' Hot (Redis): < 1 hour, 5ms latency');\n console.log(' Warm (TimeSeries): 1h - 7 days, 50ms latency');\n console.log(' Cold (S3): 7 - 30 days, 100ms latency');\n console.log(' Archive (Glacier): > 30 days, 1h latency');\n\n // Save config to env\n const envPath = path.join(__dirname, '../../../.env');\n const updates: string[] = [];\n\n if (!process.env['REDIS_URL'] && options.redisUrl) {\n updates.push(`REDIS_URL=${options.redisUrl}`);\n }\n if (!process.env['TIMESERIES_URL'] && options.timeseriesUrl) {\n updates.push(`TIMESERIES_URL=${options.timeseriesUrl}`);\n }\n if (!process.env['S3_BUCKET'] && options.s3Bucket) {\n updates.push(`S3_BUCKET=${options.s3Bucket}`);\n }\n\n if (updates.length > 0) {\n const fs = await import('fs');\n fs.appendFileSync(\n envPath,\n '\\n# Infinite Storage Configuration\\n' + updates.join('\\n') + '\\n'\n );\n }\n } catch (error: unknown) {\n spinner.fail('Failed to initialize storage');\n logger.error('Initialization error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Store frames\n storage\n .command('store')\n .description('Store current frames in infinite storage')\n .option('--project <name>', 'Project name')\n .option('--user <id>', 'User ID')\n .action(async (options) => {\n const spinner = ora('Storing frames...').start();\n\n try {\n const config = getStorageConfig();\n const storage = new InfiniteStorageSystem(config);\n await storage.initialize();\n\n const frameManager = new FrameManager();\n const frames = frameManager.getAllFrames();\n const userId = options.user || process.env['USER'] || 'default';\n\n for (const frame of frames) {\n await storage.storeFrame(frame, userId);\n }\n\n spinner.succeed(`Stored ${frames.length} frames`);\n } catch (error: unknown) {\n spinner.fail('Failed to store frames');\n logger.error('Store error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Retrieve frame\n storage\n .command('retrieve <frameId>')\n .description('Retrieve a frame from storage')\n .option('--user <id>', 'User ID')\n .action(async (frameId, options) => {\n const spinner = ora('Retrieving frame...').start();\n\n try {\n const config = getStorageConfig();\n const storage = new InfiniteStorageSystem(config);\n await storage.initialize();\n\n const userId = options.user || process.env['USER'] || 'default';\n const frame = await storage.retrieveFrame(frameId, userId);\n\n spinner.stop();\n\n if (frame) {\n console.log(chalk.green('\\n\u2705 Frame Retrieved:'));\n console.log(JSON.stringify(frame, null, 2));\n } else {\n console.log(chalk.yellow('Frame not found'));\n }\n } catch (error: unknown) {\n spinner.fail('Failed to retrieve frame');\n logger.error('Retrieve error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Show metrics\n storage\n .command('metrics')\n .description('Show storage system metrics')\n .action(async () => {\n const spinner = ora('Fetching metrics...').start();\n\n try {\n const config = getStorageConfig();\n const storage = new InfiniteStorageSystem(config);\n await storage.initialize();\n\n const metrics = await storage.getMetrics();\n\n spinner.stop();\n\n console.log(chalk.cyan('\\n\uD83D\uDCCA Infinite Storage Metrics\\n'));\n\n const table = new Table({\n head: ['Metric', 'Value'],\n colWidths: [30, 40],\n });\n\n table.push(\n ['Total Objects', metrics.totalObjects.toString()],\n ['Storage Size', formatBytes(metrics.storageBytes)],\n ['Avg Latency', `${metrics.avgLatencyMs.toFixed(2)}ms`],\n ['P50 Latency', `${metrics.p50LatencyMs}ms`],\n ['P99 Latency', `${metrics.p99LatencyMs}ms`]\n );\n\n console.log(table.toString());\n\n if (Object.keys(metrics.tierDistribution).length > 0) {\n console.log('\\nTier Distribution:');\n for (const [tier, count] of Object.entries(\n metrics.tierDistribution\n )) {\n const percentage = ((count / metrics.totalObjects) * 100).toFixed(\n 1\n );\n console.log(` ${tier}: ${count} objects (${percentage}%)`);\n }\n }\n\n // Check if meeting STA-287 targets\n console.log(chalk.cyan('\\n\uD83C\uDFAF STA-287 Performance Targets:'));\n const p50Target = metrics.p50LatencyMs <= 50;\n const p99Target = metrics.p99LatencyMs <= 500;\n\n console.log(\n ` P50 \u2264 50ms: ${p50Target ? chalk.green('\u2705 PASS') : chalk.red('\u274C FAIL')} (${metrics.p50LatencyMs}ms)`\n );\n console.log(\n ` P99 \u2264 500ms: ${p99Target ? chalk.green('\u2705 PASS') : chalk.red('\u274C FAIL')} (${metrics.p99LatencyMs}ms)`\n );\n } catch (error: unknown) {\n spinner.fail('Failed to get metrics');\n logger.error('Metrics error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Migrate data\n storage\n .command('migrate')\n .description('Manually trigger tier migration')\n .action(async () => {\n const spinner = ora('Running migration...').start();\n\n try {\n const config = getStorageConfig();\n const storage = new InfiniteStorageSystem(config);\n await storage.initialize();\n\n // Trigger migration (this would normally run automatically)\n // @ts-ignore - accessing private method for manual trigger\n await storage.migrateAgedData();\n\n spinner.succeed('Migration completed');\n } catch (error: unknown) {\n spinner.fail('Migration failed');\n logger.error('Migration error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Status command\n storage\n .command('status')\n .description('Check storage system status')\n .action(async () => {\n const spinner = ora('Checking status...').start();\n\n try {\n const config = getStorageConfig();\n\n spinner.stop();\n\n console.log(chalk.cyan('\\n\uD83D\uDCE6 Storage System Status\\n'));\n\n // Check Redis\n if (config.redis?.url) {\n try {\n const { createClient } = await import('redis');\n const client = createClient({ url: config.redis.url });\n await client.connect();\n await client.ping();\n await client.quit();\n console.log('Redis (Hot Tier): ' + chalk.green('\u2705 Connected'));\n } catch {\n console.log('Redis (Hot Tier): ' + chalk.red('\u274C Not connected'));\n }\n } else {\n console.log('Redis (Hot Tier): ' + chalk.yellow('\u26A0\uFE0F Not configured'));\n }\n\n // Check TimeSeries DB\n if (config.timeseries?.connectionString) {\n try {\n const { Pool } = await import('pg');\n const pool = new Pool({\n connectionString: config.timeseries.connectionString,\n });\n await pool.query('SELECT 1');\n await pool.end();\n console.log(\n 'TimeSeries DB (Warm Tier): ' + chalk.green('\u2705 Connected')\n );\n } catch {\n console.log(\n 'TimeSeries DB (Warm Tier): ' + chalk.red('\u274C Not connected')\n );\n }\n } else {\n console.log(\n 'TimeSeries DB (Warm Tier): ' + chalk.yellow('\u26A0\uFE0F Not configured')\n );\n }\n\n // Check S3\n if (config.s3?.bucket) {\n console.log(\n `S3 (Cold/Archive Tier): ${chalk.green('\u2705')} Bucket: ${config.s3.bucket}`\n );\n } else {\n console.log(\n 'S3 (Cold/Archive Tier): ' + chalk.yellow('\u26A0\uFE0F Not configured')\n );\n }\n\n console.log(\n '\\n' +\n chalk.gray(\n 'Configure missing tiers with: stackmemory infinite-storage init'\n )\n );\n } catch (error: unknown) {\n spinner.fail('Failed to check status');\n logger.error('Status error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n return storage;\n}\n\nfunction getStorageConfig(): StorageConfig {\n return {\n redis: {\n url: process.env['REDIS_URL'] || 'redis://localhost:6379',\n ttlSeconds: parseInt(process.env['REDIS_TTL'] || '3600'),\n maxMemoryMB: parseInt(process.env['REDIS_MAX_MEMORY_MB'] || '512'),\n },\n timeseries: {\n connectionString: process.env['TIMESERIES_URL'] || '',\n retentionDays: parseInt(process.env['TIMESERIES_RETENTION_DAYS'] || '30'),\n },\n s3: {\n bucket: process.env['S3_BUCKET'] || '',\n region: process.env['AWS_REGION'] || 'us-east-1',\n accessKeyId: process.env['AWS_ACCESS_KEY_ID'],\n secretAccessKey: process.env['AWS_SECRET_ACCESS_KEY'],\n },\n tiers: [],\n };\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["storage"]
|
|
7
|
-
}
|