@stackmemoryai/stackmemory 0.3.6 → 0.3.8
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/agents/core/agent-task-manager.js +5 -5
- package/dist/agents/core/agent-task-manager.js.map +2 -2
- package/dist/agents/verifiers/base-verifier.js +2 -2
- package/dist/agents/verifiers/base-verifier.js.map +2 -2
- package/dist/agents/verifiers/formatter-verifier.js.map +2 -2
- package/dist/agents/verifiers/llm-judge.js.map +2 -2
- package/dist/cli/claude-sm.js +13 -13
- package/dist/cli/claude-sm.js.map +2 -2
- package/dist/cli/codex-sm.js +13 -13
- package/dist/cli/codex-sm.js.map +2 -2
- package/dist/cli/commands/agent.js.map +2 -2
- package/dist/cli/commands/chromadb.js +261 -46
- package/dist/cli/commands/chromadb.js.map +2 -2
- package/dist/cli/commands/clear.js +10 -3
- package/dist/cli/commands/clear.js.map +2 -2
- package/dist/cli/commands/config.js +43 -33
- package/dist/cli/commands/config.js.map +2 -2
- package/dist/cli/commands/context.js +13 -2
- package/dist/cli/commands/context.js.map +2 -2
- package/dist/cli/commands/dashboard.js +41 -13
- package/dist/cli/commands/dashboard.js.map +2 -2
- package/dist/cli/commands/gc.js +251 -0
- package/dist/cli/commands/gc.js.map +7 -0
- package/dist/cli/commands/handoff.js +12 -1
- package/dist/cli/commands/handoff.js.map +2 -2
- package/dist/cli/commands/infinite-storage.js +92 -40
- package/dist/cli/commands/infinite-storage.js.map +2 -2
- package/dist/cli/commands/linear-create.js +49 -10
- package/dist/cli/commands/linear-create.js.map +2 -2
- package/dist/cli/commands/linear-list.js +45 -11
- package/dist/cli/commands/linear-list.js.map +2 -2
- package/dist/cli/commands/linear-migrate.js +29 -5
- package/dist/cli/commands/linear-migrate.js.map +2 -2
- package/dist/cli/commands/linear-test.js +26 -7
- package/dist/cli/commands/linear-test.js.map +2 -2
- package/dist/cli/commands/linear-unified.js +350 -0
- package/dist/cli/commands/linear-unified.js.map +7 -0
- package/dist/cli/commands/linear.js +17 -6
- package/dist/cli/commands/linear.js.map +2 -2
- package/dist/cli/commands/monitor.js.map +2 -2
- package/dist/cli/commands/onboard.js +35 -8
- package/dist/cli/commands/onboard.js.map +2 -2
- package/dist/cli/commands/quality.js +2 -7
- package/dist/cli/commands/quality.js.map +2 -2
- package/dist/cli/commands/search.js.map +2 -2
- package/dist/cli/commands/session.js +23 -6
- package/dist/cli/commands/session.js.map +2 -2
- package/dist/cli/commands/skills.js +84 -28
- package/dist/cli/commands/skills.js.map +2 -2
- package/dist/cli/commands/storage.js +119 -38
- package/dist/cli/commands/storage.js.map +2 -2
- package/dist/cli/commands/tasks.js.map +2 -2
- package/dist/cli/commands/tui.js +13 -2
- package/dist/cli/commands/tui.js.map +2 -2
- package/dist/cli/commands/webhook.js +71 -21
- package/dist/cli/commands/webhook.js.map +2 -2
- package/dist/cli/commands/workflow.js +11 -7
- package/dist/cli/commands/workflow.js.map +2 -2
- package/dist/cli/commands/worktree.js +34 -13
- package/dist/cli/commands/worktree.js.map +2 -2
- package/dist/cli/index.js +7 -5
- package/dist/cli/index.js.map +2 -2
- package/dist/core/config/config-manager.js.map +2 -2
- package/dist/core/config/types.js.map +1 -1
- package/dist/core/context/auto-context.js +10 -6
- package/dist/core/context/auto-context.js.map +2 -2
- package/dist/core/context/compaction-handler.js.map +2 -2
- package/dist/core/context/context-bridge.js.map +2 -2
- package/dist/core/context/dual-stack-manager.js.map +2 -2
- package/dist/core/context/frame-database.js +13 -3
- package/dist/core/context/frame-database.js.map +2 -2
- package/dist/core/context/frame-digest.js +7 -5
- package/dist/core/context/frame-digest.js.map +2 -2
- package/dist/core/context/frame-handoff-manager.js.map +2 -2
- package/dist/core/context/frame-manager.js +12 -1
- package/dist/core/context/frame-manager.js.map +2 -2
- package/dist/core/context/frame-stack.js +16 -5
- package/dist/core/context/frame-stack.js.map +2 -2
- package/dist/core/context/incremental-gc.js +286 -0
- package/dist/core/context/incremental-gc.js.map +7 -0
- package/dist/core/context/index.js.map +1 -1
- package/dist/core/context/permission-manager.js +12 -1
- package/dist/core/context/permission-manager.js.map +2 -2
- package/dist/core/context/refactored-frame-manager.js +12 -3
- package/dist/core/context/refactored-frame-manager.js.map +2 -2
- package/dist/core/context/shared-context-layer.js +16 -3
- package/dist/core/context/shared-context-layer.js.map +2 -2
- package/dist/core/context/stack-merge-resolver.js.map +2 -2
- package/dist/core/context/validation.js.map +2 -2
- package/dist/core/database/batch-operations.js +112 -86
- package/dist/core/database/batch-operations.js.map +2 -2
- package/dist/core/database/connection-pool.js.map +2 -2
- package/dist/core/database/migration-manager.js.map +2 -2
- package/dist/core/database/paradedb-adapter.js.map +2 -2
- package/dist/core/database/query-cache.js +19 -9
- package/dist/core/database/query-cache.js.map +2 -2
- package/dist/core/database/query-router.js.map +2 -2
- package/dist/core/database/sqlite-adapter.js +1 -1
- package/dist/core/database/sqlite-adapter.js.map +2 -2
- package/dist/core/digest/enhanced-hybrid-digest.js +8 -2
- package/dist/core/digest/enhanced-hybrid-digest.js.map +2 -2
- package/dist/core/errors/recovery.js +9 -2
- package/dist/core/errors/recovery.js.map +2 -2
- package/dist/core/frame/workflow-templates-stub.js.map +1 -1
- package/dist/core/frame/workflow-templates.js +40 -1
- package/dist/core/frame/workflow-templates.js.map +2 -2
- package/dist/core/merge/resolution-engine.js.map +2 -2
- package/dist/core/monitoring/error-handler.js.map +2 -2
- package/dist/core/monitoring/logger.js +19 -3
- package/dist/core/monitoring/logger.js.map +2 -2
- package/dist/core/monitoring/metrics.js +13 -2
- package/dist/core/monitoring/metrics.js.map +2 -2
- package/dist/core/monitoring/progress-tracker.js +12 -1
- package/dist/core/monitoring/progress-tracker.js.map +2 -2
- package/dist/core/monitoring/session-monitor.js.map +2 -2
- package/dist/core/performance/context-cache.js.map +2 -2
- package/dist/core/performance/lazy-context-loader.js +24 -20
- package/dist/core/performance/lazy-context-loader.js.map +2 -2
- package/dist/core/performance/monitor.js.map +2 -2
- package/dist/core/performance/optimized-frame-context.js +27 -12
- package/dist/core/performance/optimized-frame-context.js.map +2 -2
- package/dist/core/performance/performance-benchmark.js +10 -6
- package/dist/core/performance/performance-benchmark.js.map +2 -2
- package/dist/core/performance/performance-profiler.js +63 -15
- package/dist/core/performance/performance-profiler.js.map +2 -2
- package/dist/core/performance/streaming-jsonl-parser.js +5 -1
- package/dist/core/performance/streaming-jsonl-parser.js.map +2 -2
- package/dist/core/persistence/postgres-adapter.js.map +2 -2
- package/dist/core/projects/project-manager.js +14 -20
- package/dist/core/projects/project-manager.js.map +2 -2
- package/dist/core/retrieval/context-retriever.js.map +2 -2
- package/dist/core/retrieval/graph-retrieval.js.map +2 -2
- package/dist/core/retrieval/llm-context-retrieval.js.map +2 -2
- package/dist/core/retrieval/retrieval-benchmarks.js.map +2 -2
- package/dist/core/retrieval/summary-generator.js.map +2 -2
- package/dist/core/session/clear-survival-stub.js +5 -1
- package/dist/core/session/clear-survival-stub.js.map +2 -2
- package/dist/core/session/clear-survival.js +35 -0
- package/dist/core/session/clear-survival.js.map +2 -2
- package/dist/core/session/handoff-generator.js.map +2 -2
- package/dist/core/session/index.js.map +1 -1
- package/dist/core/session/session-manager.js +16 -5
- package/dist/core/session/session-manager.js.map +2 -2
- package/dist/core/skills/skill-storage.js +13 -2
- package/dist/core/skills/skill-storage.js.map +2 -2
- package/dist/core/storage/chromadb-adapter.js +6 -2
- package/dist/core/storage/chromadb-adapter.js.map +2 -2
- package/dist/core/storage/chromadb-simple.js +17 -5
- package/dist/core/storage/chromadb-simple.js.map +2 -2
- package/dist/core/storage/infinite-storage.js +109 -46
- package/dist/core/storage/infinite-storage.js.map +2 -2
- package/dist/core/storage/railway-optimized-storage.js +67 -30
- package/dist/core/storage/railway-optimized-storage.js.map +2 -2
- package/dist/core/storage/remote-storage.js +53 -24
- package/dist/core/storage/remote-storage.js.map +2 -2
- package/dist/core/trace/cli-trace-wrapper.js +25 -7
- package/dist/core/trace/cli-trace-wrapper.js.map +2 -2
- package/dist/core/trace/db-trace-wrapper.js +96 -68
- package/dist/core/trace/db-trace-wrapper.js.map +2 -2
- package/dist/core/trace/debug-trace.js +44 -16
- package/dist/core/trace/debug-trace.js.map +2 -2
- package/dist/core/trace/index.js +50 -35
- package/dist/core/trace/index.js.map +2 -2
- package/dist/core/trace/linear-api-wrapper.js +10 -5
- package/dist/core/trace/linear-api-wrapper.js.map +2 -2
- package/dist/core/trace/trace-demo.js +26 -11
- package/dist/core/trace/trace-demo.js.map +2 -2
- package/dist/core/trace/trace-detector.js +9 -2
- package/dist/core/trace/trace-detector.js.map +2 -2
- package/dist/core/trace/trace-store.js.map +2 -2
- package/dist/core/trace/types.js.map +1 -1
- package/dist/core/utils/compression.js.map +1 -1
- package/dist/core/utils/update-checker.js.map +2 -2
- package/dist/core/worktree/worktree-manager.js +18 -7
- package/dist/core/worktree/worktree-manager.js.map +2 -2
- package/dist/features/analytics/api/analytics-api.js.map +2 -2
- package/dist/features/analytics/core/analytics-service.js +12 -1
- package/dist/features/analytics/core/analytics-service.js.map +2 -2
- package/dist/features/analytics/queries/metrics-queries.js +1 -1
- package/dist/features/analytics/queries/metrics-queries.js.map +2 -2
- package/dist/features/tasks/pebbles-task-store.js.map +2 -2
- package/dist/features/tui/components/analytics-panel.js +36 -15
- package/dist/features/tui/components/analytics-panel.js.map +2 -2
- package/dist/features/tui/components/pr-tracker.js +19 -7
- package/dist/features/tui/components/pr-tracker.js.map +2 -2
- package/dist/features/tui/components/session-monitor.js +22 -9
- package/dist/features/tui/components/session-monitor.js.map +2 -2
- package/dist/features/tui/components/subagent-fleet.js +20 -13
- package/dist/features/tui/components/subagent-fleet.js.map +2 -2
- package/dist/features/tui/components/task-board.js +666 -2
- package/dist/features/tui/components/task-board.js.map +2 -2
- package/dist/features/tui/index.js +16 -5
- package/dist/features/tui/index.js.map +2 -2
- package/dist/features/tui/services/data-service.js +30 -15
- package/dist/features/tui/services/data-service.js.map +2 -2
- package/dist/features/tui/services/linear-task-reader.js +3 -1
- package/dist/features/tui/services/linear-task-reader.js.map +2 -2
- package/dist/features/tui/services/websocket-client.js +16 -3
- package/dist/features/tui/services/websocket-client.js.map +2 -2
- package/dist/features/tui/terminal-compat.js +33 -18
- package/dist/features/tui/terminal-compat.js.map +2 -2
- package/dist/features/web/client/stores/task-store.js.map +2 -2
- package/dist/features/web/server/index.js +31 -12
- package/dist/features/web/server/index.js.map +2 -2
- package/dist/integrations/claude-code/enhanced-pre-clear-hooks.js.map +2 -2
- package/dist/integrations/claude-code/lifecycle-hooks.js.map +2 -2
- package/dist/integrations/claude-code/post-task-hooks.js.map +2 -2
- package/dist/integrations/linear/auth.js +17 -6
- package/dist/integrations/linear/auth.js.map +2 -2
- package/dist/integrations/linear/auto-sync.js.map +2 -2
- package/dist/integrations/linear/client.js.map +2 -2
- package/dist/integrations/linear/config.js.map +2 -2
- package/dist/integrations/linear/migration.js.map +2 -2
- package/dist/integrations/linear/oauth-server.js +13 -2
- package/dist/integrations/linear/oauth-server.js.map +2 -2
- package/dist/integrations/linear/rest-client.js.map +2 -2
- package/dist/integrations/linear/sync-enhanced.js +202 -0
- package/dist/integrations/linear/sync-enhanced.js.map +7 -0
- package/dist/integrations/linear/sync-manager.js.map +2 -2
- package/dist/integrations/linear/sync-service.js +24 -14
- package/dist/integrations/linear/sync-service.js.map +2 -2
- package/dist/integrations/linear/sync.js +196 -3
- package/dist/integrations/linear/sync.js.map +2 -2
- package/dist/integrations/linear/unified-sync.js +560 -0
- package/dist/integrations/linear/unified-sync.js.map +7 -0
- package/dist/integrations/linear/webhook-handler.js +12 -1
- package/dist/integrations/linear/webhook-handler.js.map +2 -2
- package/dist/integrations/linear/webhook-server.js +29 -19
- package/dist/integrations/linear/webhook-server.js.map +2 -2
- package/dist/integrations/linear/webhook.js +12 -1
- package/dist/integrations/linear/webhook.js.map +2 -2
- package/dist/integrations/mcp/handlers/context-handlers.js.map +2 -2
- package/dist/integrations/mcp/handlers/linear-handlers.js.map +2 -2
- package/dist/integrations/mcp/handlers/skill-handlers.js +13 -2
- package/dist/integrations/mcp/handlers/skill-handlers.js.map +2 -2
- package/dist/integrations/mcp/handlers/task-handlers.js.map +2 -2
- package/dist/integrations/mcp/handlers/trace-handlers.js.map +2 -2
- package/dist/integrations/mcp/middleware/tool-scoring.js.map +2 -2
- package/dist/integrations/mcp/refactored-server.js +15 -4
- package/dist/integrations/mcp/refactored-server.js.map +2 -2
- package/dist/integrations/mcp/server.js +12 -1
- package/dist/integrations/mcp/server.js.map +2 -2
- package/dist/integrations/mcp/tool-definitions.js.map +2 -2
- package/dist/integrations/pg-aiguide/embedding-provider.js +13 -2
- package/dist/integrations/pg-aiguide/embedding-provider.js.map +2 -2
- package/dist/integrations/pg-aiguide/semantic-search.js.map +2 -2
- package/dist/mcp/stackmemory-mcp-server.js +1 -1
- package/dist/mcp/stackmemory-mcp-server.js.map +2 -2
- package/dist/middleware/exponential-rate-limiter.js.map +2 -2
- package/dist/servers/production/auth-middleware.js +13 -2
- package/dist/servers/production/auth-middleware.js.map +2 -2
- package/dist/servers/railway/index.js +22 -11
- package/dist/servers/railway/index.js.map +2 -2
- package/dist/services/config-service.js +6 -7
- package/dist/services/config-service.js.map +2 -2
- package/dist/services/context-service.js +11 -12
- package/dist/services/context-service.js.map +2 -2
- package/dist/skills/claude-skills.js +108 -3
- package/dist/skills/claude-skills.js.map +2 -2
- package/dist/skills/dashboard-launcher.js.map +2 -2
- package/dist/skills/repo-ingestion-skill.js +561 -0
- package/dist/skills/repo-ingestion-skill.js.map +7 -0
- package/dist/utils/env.js +46 -0
- package/dist/utils/env.js.map +7 -0
- package/dist/utils/logger.js +1 -1
- package/dist/utils/logger.js.map +2 -2
- package/package.json +5 -1
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import ora from "ora";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ClaudeSkillsManager
|
|
7
|
+
} from "../../skills/claude-skills.js";
|
|
6
8
|
import { DualStackManager } from "../../core/context/dual-stack-manager.js";
|
|
7
9
|
import { FrameHandoffManager } from "../../core/context/frame-handoff-manager.js";
|
|
8
10
|
import { ContextRetriever } from "../../core/retrieval/context-retriever.js";
|
|
@@ -10,10 +12,21 @@ import { SQLiteAdapter } from "../../core/database/sqlite-adapter.js";
|
|
|
10
12
|
import { ConfigManager } from "../../core/config/config-manager.js";
|
|
11
13
|
import * as path from "path";
|
|
12
14
|
import * as os from "os";
|
|
15
|
+
function getEnv(key, defaultValue) {
|
|
16
|
+
const value = process.env[key];
|
|
17
|
+
if (value === void 0) {
|
|
18
|
+
if (defaultValue !== void 0) return defaultValue;
|
|
19
|
+
throw new Error(`Environment variable ${key} is required`);
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function getOptionalEnv(key) {
|
|
24
|
+
return process.env[key];
|
|
25
|
+
}
|
|
13
26
|
async function initializeSkillContext() {
|
|
14
27
|
const config = ConfigManager.getInstance();
|
|
15
28
|
const projectId = config.get("project.id");
|
|
16
|
-
const userId = config.get("user.id") || process.env
|
|
29
|
+
const userId = config.get("user.id") || process.env["USER"] || "default";
|
|
17
30
|
const dbPath = path.join(
|
|
18
31
|
os.homedir(),
|
|
19
32
|
".stackmemory",
|
|
@@ -36,17 +49,27 @@ async function initializeSkillContext() {
|
|
|
36
49
|
};
|
|
37
50
|
}
|
|
38
51
|
function createSkillsCommand() {
|
|
39
|
-
const skillsCmd = new Command("skills").description(
|
|
40
|
-
|
|
52
|
+
const skillsCmd = new Command("skills").description(
|
|
53
|
+
"Execute Claude skills for enhanced workflow"
|
|
54
|
+
);
|
|
55
|
+
skillsCmd.command("handoff <targetUser> <message>").description("Streamline frame handoffs between team members").option(
|
|
56
|
+
"-p, --priority <level>",
|
|
57
|
+
"Set priority (low, medium, high, critical)",
|
|
58
|
+
"medium"
|
|
59
|
+
).option("-f, --frames <frames...>", "Specific frames to handoff").option("--no-auto-detect", "Disable auto-detection of frames").action(async (targetUser, message, options) => {
|
|
41
60
|
const spinner = ora("Initiating handoff...").start();
|
|
42
61
|
try {
|
|
43
62
|
const context = await initializeSkillContext();
|
|
44
63
|
const skillsManager = new ClaudeSkillsManager(context);
|
|
45
|
-
const result = await skillsManager.executeSkill(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
64
|
+
const result = await skillsManager.executeSkill(
|
|
65
|
+
"handoff",
|
|
66
|
+
[targetUser, message],
|
|
67
|
+
{
|
|
68
|
+
priority: options.priority,
|
|
69
|
+
frames: options.frames,
|
|
70
|
+
autoDetect: options.autoDetect !== false
|
|
71
|
+
}
|
|
72
|
+
);
|
|
50
73
|
spinner.stop();
|
|
51
74
|
if (result.success) {
|
|
52
75
|
console.log(chalk.green("\u2713"), result.message);
|
|
@@ -78,10 +101,14 @@ function createSkillsCommand() {
|
|
|
78
101
|
try {
|
|
79
102
|
const context = await initializeSkillContext();
|
|
80
103
|
const skillsManager = new ClaudeSkillsManager(context);
|
|
81
|
-
const result = await skillsManager.executeSkill(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
104
|
+
const result = await skillsManager.executeSkill(
|
|
105
|
+
"checkpoint",
|
|
106
|
+
["create", description],
|
|
107
|
+
{
|
|
108
|
+
includeFiles: options.files,
|
|
109
|
+
autoDetectRisky: options.autoDetectRisky
|
|
110
|
+
}
|
|
111
|
+
);
|
|
85
112
|
spinner.stop();
|
|
86
113
|
if (result.success) {
|
|
87
114
|
console.log(chalk.green("\u2713"), result.message);
|
|
@@ -106,7 +133,10 @@ function createSkillsCommand() {
|
|
|
106
133
|
try {
|
|
107
134
|
const context = await initializeSkillContext();
|
|
108
135
|
const skillsManager = new ClaudeSkillsManager(context);
|
|
109
|
-
const result = await skillsManager.executeSkill("checkpoint", [
|
|
136
|
+
const result = await skillsManager.executeSkill("checkpoint", [
|
|
137
|
+
"restore",
|
|
138
|
+
checkpointId
|
|
139
|
+
]);
|
|
110
140
|
spinner.stop();
|
|
111
141
|
if (result.success) {
|
|
112
142
|
console.log(chalk.green("\u2713"), result.message);
|
|
@@ -130,10 +160,14 @@ function createSkillsCommand() {
|
|
|
130
160
|
try {
|
|
131
161
|
const context = await initializeSkillContext();
|
|
132
162
|
const skillsManager = new ClaudeSkillsManager(context);
|
|
133
|
-
const result = await skillsManager.executeSkill(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
163
|
+
const result = await skillsManager.executeSkill(
|
|
164
|
+
"checkpoint",
|
|
165
|
+
["list"],
|
|
166
|
+
{
|
|
167
|
+
limit: parseInt(options.limit),
|
|
168
|
+
since: options.since ? new Date(options.since) : void 0
|
|
169
|
+
}
|
|
170
|
+
);
|
|
137
171
|
spinner.stop();
|
|
138
172
|
if (result.success) {
|
|
139
173
|
console.log(chalk.cyan("Available Checkpoints:\n"));
|
|
@@ -142,8 +176,10 @@ function createSkillsCommand() {
|
|
|
142
176
|
const riskIndicator = cp.risky ? chalk.yellow(" [RISKY]") : "";
|
|
143
177
|
console.log(`${chalk.bold(cp.id)}${riskIndicator}`);
|
|
144
178
|
console.log(` ${cp.description}`);
|
|
145
|
-
console.log(
|
|
146
|
-
`)
|
|
179
|
+
console.log(
|
|
180
|
+
chalk.gray(` ${cp.timestamp} (${cp.frameCount} frames)
|
|
181
|
+
`)
|
|
182
|
+
);
|
|
147
183
|
});
|
|
148
184
|
} else {
|
|
149
185
|
console.log(chalk.gray("No checkpoints found"));
|
|
@@ -163,7 +199,11 @@ function createSkillsCommand() {
|
|
|
163
199
|
try {
|
|
164
200
|
const context = await initializeSkillContext();
|
|
165
201
|
const skillsManager = new ClaudeSkillsManager(context);
|
|
166
|
-
const result = await skillsManager.executeSkill("checkpoint", [
|
|
202
|
+
const result = await skillsManager.executeSkill("checkpoint", [
|
|
203
|
+
"diff",
|
|
204
|
+
checkpoint1,
|
|
205
|
+
checkpoint2
|
|
206
|
+
]);
|
|
167
207
|
spinner.stop();
|
|
168
208
|
if (result.success) {
|
|
169
209
|
console.log(chalk.cyan("Checkpoint Diff:\n"));
|
|
@@ -184,7 +224,11 @@ function createSkillsCommand() {
|
|
|
184
224
|
process.exit(1);
|
|
185
225
|
}
|
|
186
226
|
});
|
|
187
|
-
skillsCmd.command("dig <query>").description("Deep historical context retrieval").option(
|
|
227
|
+
skillsCmd.command("dig <query>").description("Deep historical context retrieval").option(
|
|
228
|
+
"-d, --depth <depth>",
|
|
229
|
+
"Search depth (e.g., 30days, 6months, all)",
|
|
230
|
+
"30days"
|
|
231
|
+
).option("--patterns", "Extract patterns from results").option("--decisions", "Extract key decisions").option("--timeline", "Generate activity timeline").action(async (query, options) => {
|
|
188
232
|
const spinner = ora("Digging through context...").start();
|
|
189
233
|
try {
|
|
190
234
|
const context = await initializeSkillContext();
|
|
@@ -199,15 +243,21 @@ function createSkillsCommand() {
|
|
|
199
243
|
if (result.success) {
|
|
200
244
|
console.log(chalk.green("\u2713"), result.message);
|
|
201
245
|
if (result.data) {
|
|
202
|
-
console.log(
|
|
203
|
-
|
|
246
|
+
console.log(
|
|
247
|
+
chalk.cyan(
|
|
248
|
+
`
|
|
249
|
+
Searched ${result.data.timeRange.from} to ${result.data.timeRange.to}`
|
|
250
|
+
)
|
|
251
|
+
);
|
|
204
252
|
if (result.data.summary) {
|
|
205
253
|
console.log("\n" + result.data.summary);
|
|
206
254
|
} else {
|
|
207
255
|
if (result.data.topResults?.length > 0) {
|
|
208
256
|
console.log(chalk.cyan("\nTop Results:"));
|
|
209
257
|
result.data.topResults.forEach((r) => {
|
|
210
|
-
console.log(
|
|
258
|
+
console.log(
|
|
259
|
+
` ${chalk.yellow(`[${r.score.toFixed(2)}]`)} ${r.summary}`
|
|
260
|
+
);
|
|
211
261
|
});
|
|
212
262
|
}
|
|
213
263
|
if (result.data.patterns?.length > 0) {
|
|
@@ -219,7 +269,9 @@ Searched ${result.data.timeRange.from} to ${result.data.timeRange.to}`));
|
|
|
219
269
|
if (result.data.decisions?.length > 0) {
|
|
220
270
|
console.log(chalk.cyan("\nKey Decisions:"));
|
|
221
271
|
result.data.decisions.slice(0, 5).forEach((d) => {
|
|
222
|
-
console.log(
|
|
272
|
+
console.log(
|
|
273
|
+
` ${chalk.gray(new Date(d.timestamp).toLocaleDateString())}: ${d.decision}`
|
|
274
|
+
);
|
|
223
275
|
});
|
|
224
276
|
}
|
|
225
277
|
if (result.data.timeline?.length > 0) {
|
|
@@ -247,10 +299,14 @@ Searched ${result.data.timeRange.from} to ${result.data.timeRange.to}`));
|
|
|
247
299
|
console.log(skillsManager.getSkillHelp(skill));
|
|
248
300
|
} else {
|
|
249
301
|
console.log(chalk.cyan("Available Claude Skills:\n"));
|
|
250
|
-
console.log(
|
|
302
|
+
console.log(
|
|
303
|
+
" handoff - Streamline frame handoffs between team members"
|
|
304
|
+
);
|
|
251
305
|
console.log(" checkpoint - Create and manage recovery points");
|
|
252
306
|
console.log(" dig - Deep historical context retrieval\n");
|
|
253
|
-
console.log(
|
|
307
|
+
console.log(
|
|
308
|
+
'Use "stackmemory skills help <skill>" for detailed help on each skill'
|
|
309
|
+
);
|
|
254
310
|
}
|
|
255
311
|
await context.database.disconnect();
|
|
256
312
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/cli/commands/skills.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n/**\n * Claude Skills CLI Commands\n * Integrates Claude skills into the stackmemory CLI\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { ClaudeSkillsManager, type SkillContext } from '../../skills/claude-skills.js';\nimport { DualStackManager } from '../../core/context/dual-stack-manager.js';\nimport { FrameHandoffManager } from '../../core/context/frame-handoff-manager.js';\nimport { ContextRetriever } from '../../core/retrieval/context-retriever.js';\nimport { SQLiteAdapter } from '../../core/database/sqlite-adapter.js';\nimport { ConfigManager } from '../../core/config/config-manager.js';\nimport * as path from 'path';\nimport * as os from 'os';\n\nasync function initializeSkillContext(): Promise<SkillContext> {\n const config = ConfigManager.getInstance();\n const projectId = config.get('project.id');\n const userId = config.get('user.id') || process.env.USER || 'default';\n \n const dbPath = path.join(\n os.homedir(),\n '.stackmemory',\n 'data',\n projectId,\n 'stackmemory.db'\n );\n\n const database = new SQLiteAdapter(projectId, { dbPath });\n await database.connect();\n\n const dualStackManager = new DualStackManager(database, projectId, userId);\n const handoffManager = new FrameHandoffManager(dualStackManager);\n const contextRetriever = new ContextRetriever(database);\n\n return {\n projectId,\n userId,\n dualStackManager,\n handoffManager,\n contextRetriever,\n database,\n };\n}\n\nexport function createSkillsCommand(): Command {\n const skillsCmd = new Command('skills')\n .description('Execute Claude skills for enhanced workflow');\n\n // Handoff skill command\n skillsCmd\n .command('handoff <targetUser> <message>')\n .description('Streamline frame handoffs between team members')\n .option('-p, --priority <level>', 'Set priority (low, medium, high, critical)', 'medium')\n .option('-f, --frames <frames...>', 'Specific frames to handoff')\n .option('--no-auto-detect', 'Disable auto-detection of frames')\n .action(async (targetUser, message, options) => {\n const spinner = ora('Initiating handoff...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('handoff', [targetUser, message], {\n priority: options.priority,\n frames: options.frames,\n autoDetect: options.autoDetect !== false,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n if (result.data) {\n console.log(chalk.cyan('\\nHandoff Details:'));\n console.log(` ID: ${result.data.handoffId}`);\n console.log(` Frames: ${result.data.frameCount}`);\n console.log(` Priority: ${result.data.priority}`);\n if (result.data.actionItems?.length > 0) {\n console.log(chalk.yellow('\\n Action Items:'));\n result.data.actionItems.forEach(item => {\n console.log(` \u2022 ${item}`);\n });\n }\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n // Checkpoint skill commands\n const checkpointCmd = skillsCmd.command('checkpoint')\n .description('Create and manage recovery points');\n\n checkpointCmd\n .command('create <description>')\n .description('Create a new checkpoint')\n .option('--files <files...>', 'Include specific files in checkpoint')\n .option('--auto-detect-risky', 'Auto-detect risky operations')\n .action(async (description, options) => {\n const spinner = ora('Creating checkpoint...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('checkpoint', ['create', description], {\n includeFiles: options.files,\n autoDetectRisky: options.autoDetectRisky,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n if (result.data) {\n console.log(chalk.cyan('\\nCheckpoint Info:'));\n console.log(` ID: ${result.data.checkpointId}`);\n console.log(` Time: ${result.data.timestamp}`);\n console.log(` Frames: ${result.data.frameCount}`);\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n checkpointCmd\n .command('restore <checkpointId>')\n .description('Restore from a checkpoint')\n .action(async (checkpointId) => {\n const spinner = ora('Restoring checkpoint...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('checkpoint', ['restore', checkpointId]);\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n if (result.data) {\n console.log(chalk.cyan('\\nRestored:'));\n console.log(` Frames: ${result.data.frameCount}`);\n console.log(` Files: ${result.data.filesRestored}`);\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n checkpointCmd\n .command('list')\n .description('List available checkpoints')\n .option('-l, --limit <number>', 'Limit number of results', '10')\n .option('-s, --since <date>', 'Show checkpoints since date')\n .action(async (options) => {\n const spinner = ora('Loading checkpoints...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('checkpoint', ['list'], {\n limit: parseInt(options.limit),\n since: options.since ? new Date(options.since) : undefined,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.cyan('Available Checkpoints:\\n'));\n if (result.data && result.data.length > 0) {\n result.data.forEach((cp: any) => {\n const riskIndicator = cp.risky ? chalk.yellow(' [RISKY]') : '';\n console.log(`${chalk.bold(cp.id)}${riskIndicator}`);\n console.log(` ${cp.description}`);\n console.log(chalk.gray(` ${cp.timestamp} (${cp.frameCount} frames)\\n`));\n });\n } else {\n console.log(chalk.gray('No checkpoints found'));\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n checkpointCmd\n .command('diff <checkpoint1> <checkpoint2>')\n .description('Show differences between two checkpoints')\n .action(async (checkpoint1, checkpoint2) => {\n const spinner = ora('Comparing checkpoints...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('checkpoint', ['diff', checkpoint1, checkpoint2]);\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.cyan('Checkpoint Diff:\\n'));\n if (result.data) {\n console.log(` Time difference: ${result.data.timeDiff}`);\n console.log(` Frame difference: ${result.data.framesDiff}`);\n console.log(` New frames: ${result.data.newFrames}`);\n console.log(` Removed frames: ${result.data.removedFrames}`);\n console.log(` Modified frames: ${result.data.modifiedFrames}`);\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n // Context Archaeologist skill command\n skillsCmd\n .command('dig <query>')\n .description('Deep historical context retrieval')\n .option('-d, --depth <depth>', 'Search depth (e.g., 30days, 6months, all)', '30days')\n .option('--patterns', 'Extract patterns from results')\n .option('--decisions', 'Extract key decisions')\n .option('--timeline', 'Generate activity timeline')\n .action(async (query, options) => {\n const spinner = ora('Digging through context...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('dig', [query], {\n depth: options.depth,\n patterns: options.patterns,\n decisions: options.decisions,\n timeline: options.timeline,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n \n if (result.data) {\n console.log(chalk.cyan(`\\nSearched ${result.data.timeRange.from} to ${result.data.timeRange.to}`));\n \n if (result.data.summary) {\n console.log('\\n' + result.data.summary);\n } else {\n // Display top results\n if (result.data.topResults?.length > 0) {\n console.log(chalk.cyan('\\nTop Results:'));\n result.data.topResults.forEach((r: any) => {\n console.log(` ${chalk.yellow(`[${r.score.toFixed(2)}]`)} ${r.summary}`);\n });\n }\n\n // Display patterns if found\n if (result.data.patterns?.length > 0) {\n console.log(chalk.cyan('\\nDetected Patterns:'));\n result.data.patterns.forEach((p: any) => {\n console.log(` ${p.name}: ${p.count} occurrences`);\n });\n }\n\n // Display decisions if found\n if (result.data.decisions?.length > 0) {\n console.log(chalk.cyan('\\nKey Decisions:'));\n result.data.decisions.slice(0, 5).forEach((d: any) => {\n console.log(` ${chalk.gray(new Date(d.timestamp).toLocaleDateString())}: ${d.decision}`);\n });\n }\n\n // Display timeline if generated\n if (result.data.timeline?.length > 0) {\n console.log(chalk.cyan('\\nActivity Timeline:'));\n result.data.timeline.slice(0, 5).forEach((t: any) => {\n console.log(` ${t.date}: ${t.itemCount} activities`);\n });\n }\n }\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n // Help command for skills\n skillsCmd\n .command('help [skill]')\n .description('Show help for a specific skill')\n .action(async (skill) => {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n if (skill) {\n console.log(skillsManager.getSkillHelp(skill));\n } else {\n console.log(chalk.cyan('Available Claude Skills:\\n'));\n console.log(' handoff - Streamline frame handoffs between team members');\n console.log(' checkpoint - Create and manage recovery points');\n console.log(' dig - Deep historical context retrieval\\n');\n console.log('Use \"stackmemory skills help <skill>\" for detailed help on each skill');\n }\n \n await context.database.disconnect();\n });\n\n return skillsCmd;\n}"],
|
|
5
|
-
"mappings": ";AAMA,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,OAAO,SAAS;AAChB,
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n/**\n * Claude Skills CLI Commands\n * Integrates Claude skills into the stackmemory CLI\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport {\n ClaudeSkillsManager,\n type SkillContext,\n} from '../../skills/claude-skills.js';\nimport { DualStackManager } from '../../core/context/dual-stack-manager.js';\nimport { FrameHandoffManager } from '../../core/context/frame-handoff-manager.js';\nimport { ContextRetriever } from '../../core/retrieval/context-retriever.js';\nimport { SQLiteAdapter } from '../../core/database/sqlite-adapter.js';\nimport { ConfigManager } from '../../core/config/config-manager.js';\nimport * as path from 'path';\nimport * as os from 'os';\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\nasync function initializeSkillContext(): Promise<SkillContext> {\n const config = ConfigManager.getInstance();\n const projectId = config.get('project.id');\n const userId = config.get('user.id') || process.env['USER'] || 'default';\n\n const dbPath = path.join(\n os.homedir(),\n '.stackmemory',\n 'data',\n projectId,\n 'stackmemory.db'\n );\n\n const database = new SQLiteAdapter(projectId, { dbPath });\n await database.connect();\n\n const dualStackManager = new DualStackManager(database, projectId, userId);\n const handoffManager = new FrameHandoffManager(dualStackManager);\n const contextRetriever = new ContextRetriever(database);\n\n return {\n projectId,\n userId,\n dualStackManager,\n handoffManager,\n contextRetriever,\n database,\n };\n}\n\nexport function createSkillsCommand(): Command {\n const skillsCmd = new Command('skills').description(\n 'Execute Claude skills for enhanced workflow'\n );\n\n // Handoff skill command\n skillsCmd\n .command('handoff <targetUser> <message>')\n .description('Streamline frame handoffs between team members')\n .option(\n '-p, --priority <level>',\n 'Set priority (low, medium, high, critical)',\n 'medium'\n )\n .option('-f, --frames <frames...>', 'Specific frames to handoff')\n .option('--no-auto-detect', 'Disable auto-detection of frames')\n .action(async (targetUser, message, options) => {\n const spinner = ora('Initiating handoff...').start();\n\n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n\n const result = await skillsManager.executeSkill(\n 'handoff',\n [targetUser, message],\n {\n priority: options.priority,\n frames: options.frames,\n autoDetect: options.autoDetect !== false,\n }\n );\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n if (result.data) {\n console.log(chalk.cyan('\\nHandoff Details:'));\n console.log(` ID: ${result.data.handoffId}`);\n console.log(` Frames: ${result.data.frameCount}`);\n console.log(` Priority: ${result.data.priority}`);\n if (result.data.actionItems?.length > 0) {\n console.log(chalk.yellow('\\n Action Items:'));\n result.data.actionItems.forEach((item) => {\n console.log(` \u2022 ${item}`);\n });\n }\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error: unknown) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n // Checkpoint skill commands\n const checkpointCmd = skillsCmd\n .command('checkpoint')\n .description('Create and manage recovery points');\n\n checkpointCmd\n .command('create <description>')\n .description('Create a new checkpoint')\n .option('--files <files...>', 'Include specific files in checkpoint')\n .option('--auto-detect-risky', 'Auto-detect risky operations')\n .action(async (description, options) => {\n const spinner = ora('Creating checkpoint...').start();\n\n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n\n const result = await skillsManager.executeSkill(\n 'checkpoint',\n ['create', description],\n {\n includeFiles: options.files,\n autoDetectRisky: options.autoDetectRisky,\n }\n );\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n if (result.data) {\n console.log(chalk.cyan('\\nCheckpoint Info:'));\n console.log(` ID: ${result.data.checkpointId}`);\n console.log(` Time: ${result.data.timestamp}`);\n console.log(` Frames: ${result.data.frameCount}`);\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error: unknown) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n checkpointCmd\n .command('restore <checkpointId>')\n .description('Restore from a checkpoint')\n .action(async (checkpointId) => {\n const spinner = ora('Restoring checkpoint...').start();\n\n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n\n const result = await skillsManager.executeSkill('checkpoint', [\n 'restore',\n checkpointId,\n ]);\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n if (result.data) {\n console.log(chalk.cyan('\\nRestored:'));\n console.log(` Frames: ${result.data.frameCount}`);\n console.log(` Files: ${result.data.filesRestored}`);\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error: unknown) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n checkpointCmd\n .command('list')\n .description('List available checkpoints')\n .option('-l, --limit <number>', 'Limit number of results', '10')\n .option('-s, --since <date>', 'Show checkpoints since date')\n .action(async (options) => {\n const spinner = ora('Loading checkpoints...').start();\n\n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n\n const result = await skillsManager.executeSkill(\n 'checkpoint',\n ['list'],\n {\n limit: parseInt(options.limit),\n since: options.since ? new Date(options.since) : undefined,\n }\n );\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.cyan('Available Checkpoints:\\n'));\n if (result.data && result.data.length > 0) {\n result.data.forEach((cp: any) => {\n const riskIndicator = cp.risky ? chalk.yellow(' [RISKY]') : '';\n console.log(`${chalk.bold(cp.id)}${riskIndicator}`);\n console.log(` ${cp.description}`);\n console.log(\n chalk.gray(` ${cp.timestamp} (${cp.frameCount} frames)\\n`)\n );\n });\n } else {\n console.log(chalk.gray('No checkpoints found'));\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error: unknown) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n checkpointCmd\n .command('diff <checkpoint1> <checkpoint2>')\n .description('Show differences between two checkpoints')\n .action(async (checkpoint1, checkpoint2) => {\n const spinner = ora('Comparing checkpoints...').start();\n\n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n\n const result = await skillsManager.executeSkill('checkpoint', [\n 'diff',\n checkpoint1,\n checkpoint2,\n ]);\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.cyan('Checkpoint Diff:\\n'));\n if (result.data) {\n console.log(` Time difference: ${result.data.timeDiff}`);\n console.log(` Frame difference: ${result.data.framesDiff}`);\n console.log(` New frames: ${result.data.newFrames}`);\n console.log(` Removed frames: ${result.data.removedFrames}`);\n console.log(` Modified frames: ${result.data.modifiedFrames}`);\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error: unknown) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n // Context Archaeologist skill command\n skillsCmd\n .command('dig <query>')\n .description('Deep historical context retrieval')\n .option(\n '-d, --depth <depth>',\n 'Search depth (e.g., 30days, 6months, all)',\n '30days'\n )\n .option('--patterns', 'Extract patterns from results')\n .option('--decisions', 'Extract key decisions')\n .option('--timeline', 'Generate activity timeline')\n .action(async (query, options) => {\n const spinner = ora('Digging through context...').start();\n\n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n\n const result = await skillsManager.executeSkill('dig', [query], {\n depth: options.depth,\n patterns: options.patterns,\n decisions: options.decisions,\n timeline: options.timeline,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n\n if (result.data) {\n console.log(\n chalk.cyan(\n `\\nSearched ${result.data.timeRange.from} to ${result.data.timeRange.to}`\n )\n );\n\n if (result.data.summary) {\n console.log('\\n' + result.data.summary);\n } else {\n // Display top results\n if (result.data.topResults?.length > 0) {\n console.log(chalk.cyan('\\nTop Results:'));\n result.data.topResults.forEach((r: any) => {\n console.log(\n ` ${chalk.yellow(`[${r.score.toFixed(2)}]`)} ${r.summary}`\n );\n });\n }\n\n // Display patterns if found\n if (result.data.patterns?.length > 0) {\n console.log(chalk.cyan('\\nDetected Patterns:'));\n result.data.patterns.forEach((p: any) => {\n console.log(` ${p.name}: ${p.count} occurrences`);\n });\n }\n\n // Display decisions if found\n if (result.data.decisions?.length > 0) {\n console.log(chalk.cyan('\\nKey Decisions:'));\n result.data.decisions.slice(0, 5).forEach((d: any) => {\n console.log(\n ` ${chalk.gray(new Date(d.timestamp).toLocaleDateString())}: ${d.decision}`\n );\n });\n }\n\n // Display timeline if generated\n if (result.data.timeline?.length > 0) {\n console.log(chalk.cyan('\\nActivity Timeline:'));\n result.data.timeline.slice(0, 5).forEach((t: any) => {\n console.log(` ${t.date}: ${t.itemCount} activities`);\n });\n }\n }\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error: unknown) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n // Help command for skills\n skillsCmd\n .command('help [skill]')\n .description('Show help for a specific skill')\n .action(async (skill) => {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n\n if (skill) {\n console.log(skillsManager.getSkillHelp(skill));\n } else {\n console.log(chalk.cyan('Available Claude Skills:\\n'));\n console.log(\n ' handoff - Streamline frame handoffs between team members'\n );\n console.log(' checkpoint - Create and manage recovery points');\n console.log(' dig - Deep historical context retrieval\\n');\n console.log(\n 'Use \"stackmemory skills help <skill>\" for detailed help on each skill'\n );\n }\n\n await context.database.disconnect();\n });\n\n return skillsCmd;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -7,6 +7,17 @@ import { existsSync } from "fs";
|
|
|
7
7
|
import { RailwayOptimizedStorage } from "../../core/storage/railway-optimized-storage.js";
|
|
8
8
|
import { ConfigManager } from "../../core/config/config-manager.js";
|
|
9
9
|
import { formatBytes, formatDuration } from "../../utils/formatting.js";
|
|
10
|
+
function getEnv(key, defaultValue) {
|
|
11
|
+
const value = process.env[key];
|
|
12
|
+
if (value === void 0) {
|
|
13
|
+
if (defaultValue !== void 0) return defaultValue;
|
|
14
|
+
throw new Error(`Environment variable ${key} is required`);
|
|
15
|
+
}
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
function getOptionalEnv(key) {
|
|
19
|
+
return process.env[key];
|
|
20
|
+
}
|
|
10
21
|
function createStorageCommand() {
|
|
11
22
|
const storage = new Command("storage").description(
|
|
12
23
|
"Manage 3-tier storage system (Redis/Railway/GCS)"
|
|
@@ -32,46 +43,70 @@ function createStorageCommand() {
|
|
|
32
43
|
console.log(`
|
|
33
44
|
${icon} ${color(tier.tier.toUpperCase())} Tier:`);
|
|
34
45
|
console.log(` Traces: ${chalk.white(tier.count)}`);
|
|
35
|
-
console.log(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
console.log(
|
|
46
|
+
console.log(
|
|
47
|
+
` Original Size: ${chalk.white(formatBytes(tier.total_original || 0))}`
|
|
48
|
+
);
|
|
49
|
+
console.log(
|
|
50
|
+
` Compressed Size: ${chalk.white(formatBytes(tier.total_compressed || 0))}`
|
|
51
|
+
);
|
|
52
|
+
console.log(
|
|
53
|
+
` Compression Ratio: ${chalk.green((tier.avg_compression * 100).toFixed(1) + "%")}`
|
|
54
|
+
);
|
|
55
|
+
console.log(
|
|
56
|
+
` Avg Access Count: ${chalk.white(tier.avg_access?.toFixed(1) || "0")}`
|
|
57
|
+
);
|
|
39
58
|
}
|
|
40
59
|
console.log(chalk.blue("\n\u{1F4C5} Age Distribution:"));
|
|
41
60
|
console.log(chalk.gray("\u2501".repeat(50)));
|
|
42
61
|
for (const age of stats.byAge) {
|
|
43
62
|
const percent = (age.count / stats.totalTraces * 100).toFixed(1);
|
|
44
63
|
const bar = "\u2588".repeat(Math.floor(percent / 2));
|
|
45
|
-
console.log(
|
|
64
|
+
console.log(
|
|
65
|
+
` ${age.age_group.padEnd(10)} ${bar} ${percent}% (${age.count})`
|
|
66
|
+
);
|
|
46
67
|
}
|
|
47
68
|
console.log(chalk.blue("\n\u{1F4C8} Summary:"));
|
|
48
69
|
console.log(chalk.gray("\u2501".repeat(50)));
|
|
49
70
|
console.log(` Total Traces: ${chalk.white(stats.totalTraces)}`);
|
|
50
|
-
console.log(
|
|
51
|
-
|
|
71
|
+
console.log(
|
|
72
|
+
` Total Size: ${chalk.white(formatBytes(stats.totalSize))}`
|
|
73
|
+
);
|
|
74
|
+
console.log(
|
|
75
|
+
` Compressed Size: ${chalk.white(formatBytes(stats.compressedSize))}`
|
|
76
|
+
);
|
|
52
77
|
const compressionRatio = ((1 - stats.compressedSize / stats.totalSize) * 100).toFixed(1);
|
|
53
|
-
console.log(
|
|
78
|
+
console.log(
|
|
79
|
+
` Overall Compression: ${chalk.green(compressionRatio + "%")}`
|
|
80
|
+
);
|
|
54
81
|
const costEstimate = calculateStorageCost(stats);
|
|
55
82
|
console.log(chalk.blue("\n\u{1F4B0} Estimated Monthly Cost:"));
|
|
56
83
|
console.log(chalk.gray("\u2501".repeat(50)));
|
|
57
|
-
console.log(
|
|
58
|
-
|
|
84
|
+
console.log(
|
|
85
|
+
` Redis (Hot): ${chalk.green("$0.00")} (included with Railway)`
|
|
86
|
+
);
|
|
87
|
+
console.log(
|
|
88
|
+
` Railway Buckets (Warm): ${chalk.yellow(costEstimate.railway)}`
|
|
89
|
+
);
|
|
59
90
|
console.log(` GCS Coldline (Cold): ${chalk.cyan(costEstimate.gcs)}`);
|
|
60
91
|
console.log(` Total: ${chalk.white(costEstimate.total)}`);
|
|
61
92
|
if (options.verbose) {
|
|
62
|
-
const recentMigrations = db.prepare(
|
|
93
|
+
const recentMigrations = db.prepare(
|
|
94
|
+
`
|
|
63
95
|
SELECT trace_id, tier, migrated_at, score
|
|
64
96
|
FROM storage_tiers
|
|
65
97
|
WHERE migrated_at > ?
|
|
66
98
|
ORDER BY migrated_at DESC
|
|
67
99
|
LIMIT 10
|
|
68
|
-
`
|
|
100
|
+
`
|
|
101
|
+
).all(Date.now() - 24 * 60 * 60 * 1e3);
|
|
69
102
|
if (recentMigrations.length > 0) {
|
|
70
103
|
console.log(chalk.blue("\n\u{1F504} Recent Migrations (last 24h):"));
|
|
71
104
|
console.log(chalk.gray("\u2501".repeat(50)));
|
|
72
105
|
for (const m of recentMigrations) {
|
|
73
106
|
const time = new Date(m.migrated_at).toLocaleTimeString();
|
|
74
|
-
console.log(
|
|
107
|
+
console.log(
|
|
108
|
+
` ${time} - ${m.trace_id.substring(0, 8)}... \u2192 ${m.tier} (score: ${m.score.toFixed(2)})`
|
|
109
|
+
);
|
|
75
110
|
}
|
|
76
111
|
}
|
|
77
112
|
}
|
|
@@ -90,13 +125,15 @@ ${icon} ${color(tier.tier.toUpperCase())} Tier:`);
|
|
|
90
125
|
const configManager = new ConfigManager();
|
|
91
126
|
const storage2 = new RailwayOptimizedStorage(db, configManager);
|
|
92
127
|
if (options.dryRun) {
|
|
93
|
-
const candidates = db.prepare(
|
|
128
|
+
const candidates = db.prepare(
|
|
129
|
+
`
|
|
94
130
|
SELECT trace_id, tier, created_at, score,
|
|
95
131
|
(? - created_at) / 3600000 as age_hours
|
|
96
132
|
FROM storage_tiers
|
|
97
133
|
WHERE tier != 'cold'
|
|
98
134
|
ORDER BY created_at ASC
|
|
99
|
-
`
|
|
135
|
+
`
|
|
136
|
+
).all(Date.now());
|
|
100
137
|
const toMigrate = {
|
|
101
138
|
hotToWarm: candidates.filter(
|
|
102
139
|
(c) => c.tier === "hot" && c.age_hours > 24
|
|
@@ -109,21 +146,33 @@ ${icon} ${color(tier.tier.toUpperCase())} Tier:`);
|
|
|
109
146
|
console.log(chalk.blue("\n\u{1F504} Migration Plan:"));
|
|
110
147
|
console.log(chalk.gray("\u2501".repeat(50)));
|
|
111
148
|
if (toMigrate.hotToWarm.length > 0) {
|
|
112
|
-
console.log(
|
|
113
|
-
|
|
149
|
+
console.log(
|
|
150
|
+
chalk.red(
|
|
151
|
+
`
|
|
152
|
+
\u{1F525} \u2192 \u2601\uFE0F Hot to Warm: ${toMigrate.hotToWarm.length} traces`
|
|
153
|
+
)
|
|
154
|
+
);
|
|
114
155
|
for (const t of toMigrate.hotToWarm.slice(0, 5)) {
|
|
115
|
-
console.log(
|
|
156
|
+
console.log(
|
|
157
|
+
` \u2022 ${t.trace_id.substring(0, 8)}... (${t.age_hours.toFixed(0)}h old, score: ${t.score.toFixed(2)})`
|
|
158
|
+
);
|
|
116
159
|
}
|
|
117
160
|
if (toMigrate.hotToWarm.length > 5) {
|
|
118
161
|
console.log(` ... and ${toMigrate.hotToWarm.length - 5} more`);
|
|
119
162
|
}
|
|
120
163
|
}
|
|
121
164
|
if (toMigrate.warmToCold.length > 0) {
|
|
122
|
-
console.log(
|
|
123
|
-
|
|
165
|
+
console.log(
|
|
166
|
+
chalk.yellow(
|
|
167
|
+
`
|
|
168
|
+
\u2601\uFE0F \u2192 \u2744\uFE0F Warm to Cold: ${toMigrate.warmToCold.length} traces`
|
|
169
|
+
)
|
|
170
|
+
);
|
|
124
171
|
for (const t of toMigrate.warmToCold.slice(0, 5)) {
|
|
125
172
|
const ageDays = Math.floor(t.age_hours / 24);
|
|
126
|
-
console.log(
|
|
173
|
+
console.log(
|
|
174
|
+
` \u2022 ${t.trace_id.substring(0, 8)}... (${ageDays}d old, score: ${t.score.toFixed(2)})`
|
|
175
|
+
);
|
|
127
176
|
}
|
|
128
177
|
if (toMigrate.warmToCold.length > 5) {
|
|
129
178
|
console.log(` ... and ${toMigrate.warmToCold.length - 5} more`);
|
|
@@ -138,8 +187,12 @@ ${icon} ${color(tier.tier.toUpperCase())} Tier:`);
|
|
|
138
187
|
spinner.succeed("Migration completed");
|
|
139
188
|
console.log(chalk.blue("\n\u2705 Migration Results:"));
|
|
140
189
|
console.log(chalk.gray("\u2501".repeat(50)));
|
|
141
|
-
console.log(
|
|
142
|
-
|
|
190
|
+
console.log(
|
|
191
|
+
` Hot \u2192 Warm: ${chalk.yellow(results.hotToWarm)} traces`
|
|
192
|
+
);
|
|
193
|
+
console.log(
|
|
194
|
+
` Warm \u2192 Cold: ${chalk.cyan(results.warmToCold)} traces`
|
|
195
|
+
);
|
|
143
196
|
if (results.errors.length > 0) {
|
|
144
197
|
console.log(chalk.red(`
|
|
145
198
|
\u274C Errors (${results.errors.length}):`));
|
|
@@ -164,16 +217,20 @@ ${icon} ${color(tier.tier.toUpperCase())} Tier:`);
|
|
|
164
217
|
const storage2 = new RailwayOptimizedStorage(db, configManager);
|
|
165
218
|
const cutoff = Date.now() - options.days * 24 * 60 * 60 * 1e3;
|
|
166
219
|
if (options.dryRun) {
|
|
167
|
-
const toRemove = db.prepare(
|
|
220
|
+
const toRemove = db.prepare(
|
|
221
|
+
`
|
|
168
222
|
SELECT COUNT(*) as count, SUM(compressed_size) as size
|
|
169
223
|
FROM storage_tiers
|
|
170
224
|
WHERE tier = 'cold' AND created_at < ? AND access_count = 0
|
|
171
|
-
`
|
|
225
|
+
`
|
|
226
|
+
).get(cutoff);
|
|
172
227
|
spinner.info("Dry run - no traces will be removed");
|
|
173
228
|
console.log(chalk.blue("\n\u{1F9F9} Cleanup Analysis:"));
|
|
174
229
|
console.log(chalk.gray("\u2501".repeat(50)));
|
|
175
230
|
console.log(` Traces to remove: ${chalk.red(toRemove.count || 0)}`);
|
|
176
|
-
console.log(
|
|
231
|
+
console.log(
|
|
232
|
+
` Space to free: ${chalk.yellow(formatBytes(toRemove.size || 0))}`
|
|
233
|
+
);
|
|
177
234
|
console.log(` Criteria: > ${options.days} days old with 0 access`);
|
|
178
235
|
} else {
|
|
179
236
|
const removed = await storage2.cleanup();
|
|
@@ -205,14 +262,24 @@ ${icon} ${color(tier.tier.toUpperCase())} Tier:`);
|
|
|
205
262
|
console.log(` Type: ${chalk.yellow(trace.type)}`);
|
|
206
263
|
console.log(` Score: ${chalk.green(trace.score.toFixed(3))}`);
|
|
207
264
|
console.log(` Summary: ${trace.summary}`);
|
|
208
|
-
console.log(
|
|
265
|
+
console.log(
|
|
266
|
+
` Tools: ${trace.tools?.length || trace.toolSummary?.count || 0}`
|
|
267
|
+
);
|
|
209
268
|
const metadata = trace.metadata;
|
|
210
269
|
if (metadata) {
|
|
211
270
|
console.log(chalk.blue("\n\u{1F4CB} Metadata:"));
|
|
212
|
-
console.log(
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
console.log(
|
|
271
|
+
console.log(
|
|
272
|
+
` Start: ${new Date(metadata.startTime).toLocaleString()}`
|
|
273
|
+
);
|
|
274
|
+
console.log(
|
|
275
|
+
` Duration: ${formatDuration(metadata.endTime - metadata.startTime)}`
|
|
276
|
+
);
|
|
277
|
+
console.log(
|
|
278
|
+
` Files: ${metadata.filesModified?.length || metadata.filesModified || 0}`
|
|
279
|
+
);
|
|
280
|
+
console.log(
|
|
281
|
+
` Errors: ${metadata.errorsEncountered?.length || metadata.errorsCount || 0}`
|
|
282
|
+
);
|
|
216
283
|
}
|
|
217
284
|
const location = db.prepare(
|
|
218
285
|
"SELECT tier, location, access_count FROM storage_tiers WHERE trace_id = ?"
|
|
@@ -234,18 +301,32 @@ ${icon} ${color(tier.tier.toUpperCase())} Tier:`);
|
|
|
234
301
|
console.log(chalk.blue("\n\u2699\uFE0F Storage Configuration:"));
|
|
235
302
|
console.log(chalk.gray("\u2501".repeat(50)));
|
|
236
303
|
console.log(chalk.red("\n\u{1F525} Hot Tier (Redis):"));
|
|
237
|
-
console.log(
|
|
304
|
+
console.log(
|
|
305
|
+
` URL: ${process.env["REDIS_URL"] ? chalk.green("Configured") : chalk.yellow("Not configured")}`
|
|
306
|
+
);
|
|
238
307
|
console.log(` TTL: 24 hours`);
|
|
239
308
|
console.log(` Max Memory: 100MB`);
|
|
240
309
|
console.log(chalk.yellow("\n\u2601\uFE0F Warm Tier (Railway Buckets):"));
|
|
241
|
-
console.log(
|
|
242
|
-
|
|
243
|
-
|
|
310
|
+
console.log(
|
|
311
|
+
` Endpoint: ${process.env["RAILWAY_BUCKET_ENDPOINT"] || "Not configured"}`
|
|
312
|
+
);
|
|
313
|
+
console.log(
|
|
314
|
+
` Bucket: ${process.env["RAILWAY_BUCKET_NAME"] || "stackmemory-warm"}`
|
|
315
|
+
);
|
|
316
|
+
console.log(
|
|
317
|
+
` Access Key: ${process.env["RAILWAY_BUCKET_ACCESS_KEY"] ? chalk.green("Set") : chalk.yellow("Not set")}`
|
|
318
|
+
);
|
|
244
319
|
console.log(` Retention: 30 days`);
|
|
245
320
|
console.log(chalk.cyan("\n\u2744\uFE0F Cold Tier (GCS):"));
|
|
246
|
-
console.log(
|
|
247
|
-
|
|
248
|
-
|
|
321
|
+
console.log(
|
|
322
|
+
` Project: ${process.env["GCP_PROJECT_ID"] || "Not configured"}`
|
|
323
|
+
);
|
|
324
|
+
console.log(
|
|
325
|
+
` Bucket: ${process.env["GCS_BUCKET"] || "stackmemory-cold"}`
|
|
326
|
+
);
|
|
327
|
+
console.log(
|
|
328
|
+
` Key File: ${process.env["GCP_KEY_FILE"] ? chalk.green("Set") : chalk.yellow("Not set")}`
|
|
329
|
+
);
|
|
249
330
|
console.log(` Storage Class: Coldline`);
|
|
250
331
|
console.log(` Retention: Infinite`);
|
|
251
332
|
console.log(chalk.blue("\n\u{1F4CA} Migration Thresholds:"));
|