@bhimudev/gnanai 0.4.0
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/README.md +270 -0
- package/dist/bin/cli.d.ts +3 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +188 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/commands/cleanup.d.ts +21 -0
- package/dist/commands/cleanup.d.ts.map +1 -0
- package/dist/commands/cleanup.js +380 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/dispatch.d.ts +13 -0
- package/dist/commands/dispatch.d.ts.map +1 -0
- package/dist/commands/dispatch.js +85 -0
- package/dist/commands/dispatch.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +155 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/generate.d.ts +3 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +167 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +711 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/knowledge-sync.d.ts +69 -0
- package/dist/commands/knowledge-sync.d.ts.map +1 -0
- package/dist/commands/knowledge-sync.js +661 -0
- package/dist/commands/knowledge-sync.js.map +1 -0
- package/dist/commands/knowledge.d.ts +35 -0
- package/dist/commands/knowledge.d.ts.map +1 -0
- package/dist/commands/knowledge.js +254 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/rollback.d.ts +13 -0
- package/dist/commands/rollback.d.ts.map +1 -0
- package/dist/commands/rollback.js +186 -0
- package/dist/commands/rollback.js.map +1 -0
- package/dist/commands/setup-config.d.ts +6 -0
- package/dist/commands/setup-config.d.ts.map +1 -0
- package/dist/commands/setup-config.js +663 -0
- package/dist/commands/setup-config.js.map +1 -0
- package/dist/commands/setup-project.d.ts +6 -0
- package/dist/commands/setup-project.d.ts.map +1 -0
- package/dist/commands/setup-project.js +361 -0
- package/dist/commands/setup-project.js.map +1 -0
- package/dist/commands/setup.d.ts +3 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +293 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/status.d.ts +51 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +182 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/uninstall.d.ts +3 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +173 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +10 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +435 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/worktree.d.ts +30 -0
- package/dist/commands/worktree.d.ts.map +1 -0
- package/dist/commands/worktree.js +262 -0
- package/dist/commands/worktree.js.map +1 -0
- package/dist/generator/claude-cli.d.ts +24 -0
- package/dist/generator/claude-cli.d.ts.map +1 -0
- package/dist/generator/claude-cli.js +239 -0
- package/dist/generator/claude-cli.js.map +1 -0
- package/dist/generator/prompt-builder.d.ts +7 -0
- package/dist/generator/prompt-builder.d.ts.map +1 -0
- package/dist/generator/prompt-builder.js +144 -0
- package/dist/generator/prompt-builder.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/embeddings.d.ts +53 -0
- package/dist/mcp/embeddings.d.ts.map +1 -0
- package/dist/mcp/embeddings.js +68 -0
- package/dist/mcp/embeddings.js.map +1 -0
- package/dist/mcp/hybrid-search.d.ts +25 -0
- package/dist/mcp/hybrid-search.d.ts.map +1 -0
- package/dist/mcp/hybrid-search.js +72 -0
- package/dist/mcp/hybrid-search.js.map +1 -0
- package/dist/mcp/knowledge-server.d.ts +4 -0
- package/dist/mcp/knowledge-server.d.ts.map +1 -0
- package/dist/mcp/knowledge-server.js +294 -0
- package/dist/mcp/knowledge-server.js.map +1 -0
- package/dist/mcp/knowledge-utils.d.ts +65 -0
- package/dist/mcp/knowledge-utils.d.ts.map +1 -0
- package/dist/mcp/knowledge-utils.js +207 -0
- package/dist/mcp/knowledge-utils.js.map +1 -0
- package/dist/mcp/search-factory.d.ts +9 -0
- package/dist/mcp/search-factory.d.ts.map +1 -0
- package/dist/mcp/search-factory.js +23 -0
- package/dist/mcp/search-factory.js.map +1 -0
- package/dist/mcp/search-index.d.ts +45 -0
- package/dist/mcp/search-index.d.ts.map +1 -0
- package/dist/mcp/search-index.js +2 -0
- package/dist/mcp/search-index.js.map +1 -0
- package/dist/mcp/search-minisearch.d.ts +46 -0
- package/dist/mcp/search-minisearch.d.ts.map +1 -0
- package/dist/mcp/search-minisearch.js +99 -0
- package/dist/mcp/search-minisearch.js.map +1 -0
- package/dist/mcp/search-sqlite.d.ts +30 -0
- package/dist/mcp/search-sqlite.d.ts.map +1 -0
- package/dist/mcp/search-sqlite.js +188 -0
- package/dist/mcp/search-sqlite.js.map +1 -0
- package/dist/mcp/vector-store.d.ts +52 -0
- package/dist/mcp/vector-store.d.ts.map +1 -0
- package/dist/mcp/vector-store.js +183 -0
- package/dist/mcp/vector-store.js.map +1 -0
- package/dist/scaffold/copy-core-agents.d.ts +2 -0
- package/dist/scaffold/copy-core-agents.d.ts.map +1 -0
- package/dist/scaffold/copy-core-agents.js +90 -0
- package/dist/scaffold/copy-core-agents.js.map +1 -0
- package/dist/scaffold/create-claude-settings.d.ts +40 -0
- package/dist/scaffold/create-claude-settings.d.ts.map +1 -0
- package/dist/scaffold/create-claude-settings.js +422 -0
- package/dist/scaffold/create-claude-settings.js.map +1 -0
- package/dist/scaffold/create-config.d.ts +14 -0
- package/dist/scaffold/create-config.d.ts.map +1 -0
- package/dist/scaffold/create-config.js +199 -0
- package/dist/scaffold/create-config.js.map +1 -0
- package/dist/scaffold/create-project-description.d.ts +12 -0
- package/dist/scaffold/create-project-description.d.ts.map +1 -0
- package/dist/scaffold/create-project-description.js +104 -0
- package/dist/scaffold/create-project-description.js.map +1 -0
- package/dist/scaffold/create-structure.d.ts +2 -0
- package/dist/scaffold/create-structure.d.ts.map +1 -0
- package/dist/scaffold/create-structure.js +146 -0
- package/dist/scaffold/create-structure.js.map +1 -0
- package/dist/types/dependency-analysis.d.ts +11 -0
- package/dist/types/dependency-analysis.d.ts.map +1 -0
- package/dist/types/dependency-analysis.js +2 -0
- package/dist/types/dependency-analysis.js.map +1 -0
- package/dist/types/index.d.ts +526 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/task.d.ts +25 -0
- package/dist/types/task.d.ts.map +1 -0
- package/dist/types/task.js +3 -0
- package/dist/types/task.js.map +1 -0
- package/dist/utils/analyze-files.d.ts +7 -0
- package/dist/utils/analyze-files.d.ts.map +1 -0
- package/dist/utils/analyze-files.js +27 -0
- package/dist/utils/analyze-files.js.map +1 -0
- package/dist/utils/backup.d.ts +102 -0
- package/dist/utils/backup.d.ts.map +1 -0
- package/dist/utils/backup.js +352 -0
- package/dist/utils/backup.js.map +1 -0
- package/dist/utils/ci-provider.d.ts +23 -0
- package/dist/utils/ci-provider.d.ts.map +1 -0
- package/dist/utils/ci-provider.js +525 -0
- package/dist/utils/ci-provider.js.map +1 -0
- package/dist/utils/ci-status.d.ts +57 -0
- package/dist/utils/ci-status.d.ts.map +1 -0
- package/dist/utils/ci-status.js +349 -0
- package/dist/utils/ci-status.js.map +1 -0
- package/dist/utils/dependency-analysis.d.ts +34 -0
- package/dist/utils/dependency-analysis.d.ts.map +1 -0
- package/dist/utils/dependency-analysis.js +298 -0
- package/dist/utils/dependency-analysis.js.map +1 -0
- package/dist/utils/detect-git.d.ts +57 -0
- package/dist/utils/detect-git.d.ts.map +1 -0
- package/dist/utils/detect-git.js +439 -0
- package/dist/utils/detect-git.js.map +1 -0
- package/dist/utils/detect-mcp.d.ts +32 -0
- package/dist/utils/detect-mcp.d.ts.map +1 -0
- package/dist/utils/detect-mcp.js +178 -0
- package/dist/utils/detect-mcp.js.map +1 -0
- package/dist/utils/detect-project.d.ts +3 -0
- package/dist/utils/detect-project.d.ts.map +1 -0
- package/dist/utils/detect-project.js +155 -0
- package/dist/utils/detect-project.js.map +1 -0
- package/dist/utils/file-comparison.d.ts +89 -0
- package/dist/utils/file-comparison.d.ts.map +1 -0
- package/dist/utils/file-comparison.js +301 -0
- package/dist/utils/file-comparison.js.map +1 -0
- package/dist/utils/file-merger.d.ts +74 -0
- package/dist/utils/file-merger.d.ts.map +1 -0
- package/dist/utils/file-merger.js +350 -0
- package/dist/utils/file-merger.js.map +1 -0
- package/dist/utils/logger.d.ts +26 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +72 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/managed-process.d.ts +109 -0
- package/dist/utils/managed-process.d.ts.map +1 -0
- package/dist/utils/managed-process.js +481 -0
- package/dist/utils/managed-process.js.map +1 -0
- package/dist/utils/merge-claude-settings.d.ts +65 -0
- package/dist/utils/merge-claude-settings.d.ts.map +1 -0
- package/dist/utils/merge-claude-settings.js +133 -0
- package/dist/utils/merge-claude-settings.js.map +1 -0
- package/dist/utils/migration.d.ts +74 -0
- package/dist/utils/migration.d.ts.map +1 -0
- package/dist/utils/migration.js +345 -0
- package/dist/utils/migration.js.map +1 -0
- package/dist/utils/process-health.d.ts +51 -0
- package/dist/utils/process-health.d.ts.map +1 -0
- package/dist/utils/process-health.js +123 -0
- package/dist/utils/process-health.js.map +1 -0
- package/dist/utils/process-registry.d.ts +20 -0
- package/dist/utils/process-registry.d.ts.map +1 -0
- package/dist/utils/process-registry.js +151 -0
- package/dist/utils/process-registry.js.map +1 -0
- package/dist/utils/process-tree.d.ts +51 -0
- package/dist/utils/process-tree.d.ts.map +1 -0
- package/dist/utils/process-tree.js +499 -0
- package/dist/utils/process-tree.js.map +1 -0
- package/dist/utils/repair-mcp-config.d.ts +15 -0
- package/dist/utils/repair-mcp-config.d.ts.map +1 -0
- package/dist/utils/repair-mcp-config.js +129 -0
- package/dist/utils/repair-mcp-config.js.map +1 -0
- package/dist/utils/task-lifecycle.d.ts +60 -0
- package/dist/utils/task-lifecycle.d.ts.map +1 -0
- package/dist/utils/task-lifecycle.js +310 -0
- package/dist/utils/task-lifecycle.js.map +1 -0
- package/dist/utils/update-agent-mcp.d.ts +7 -0
- package/dist/utils/update-agent-mcp.d.ts.map +1 -0
- package/dist/utils/update-agent-mcp.js +115 -0
- package/dist/utils/update-agent-mcp.js.map +1 -0
- package/dist/utils/update-agent-templates.d.ts +6 -0
- package/dist/utils/update-agent-templates.d.ts.map +1 -0
- package/dist/utils/update-agent-templates.js +56 -0
- package/dist/utils/update-agent-templates.js.map +1 -0
- package/dist/utils/update-config-ci.d.ts +7 -0
- package/dist/utils/update-config-ci.d.ts.map +1 -0
- package/dist/utils/update-config-ci.js +72 -0
- package/dist/utils/update-config-ci.js.map +1 -0
- package/dist/utils/update-config-git.d.ts +18 -0
- package/dist/utils/update-config-git.d.ts.map +1 -0
- package/dist/utils/update-config-git.js +146 -0
- package/dist/utils/update-config-git.js.map +1 -0
- package/dist/utils/update-config-mcp.d.ts +7 -0
- package/dist/utils/update-config-mcp.d.ts.map +1 -0
- package/dist/utils/update-config-mcp.js +98 -0
- package/dist/utils/update-config-mcp.js.map +1 -0
- package/dist/utils/validate-config.d.ts +3 -0
- package/dist/utils/validate-config.d.ts.map +1 -0
- package/dist/utils/validate-config.js +109 -0
- package/dist/utils/validate-config.js.map +1 -0
- package/dist/utils/version-tracker.d.ts +130 -0
- package/dist/utils/version-tracker.d.ts.map +1 -0
- package/dist/utils/version-tracker.js +298 -0
- package/dist/utils/version-tracker.js.map +1 -0
- package/dist/utils/worktree.d.ts +68 -0
- package/dist/utils/worktree.d.ts.map +1 -0
- package/dist/utils/worktree.js +446 -0
- package/dist/utils/worktree.js.map +1 -0
- package/package.json +77 -0
- package/templates/ARCHAI_README.md +329 -0
- package/templates/CLAUDE.md +67 -0
- package/templates/PROMPTS.md +506 -0
- package/templates/core-agents/boss-agent.md +671 -0
- package/templates/core-agents/cleanup-agent.md +145 -0
- package/templates/core-agents/code-reviewer.md +175 -0
- package/templates/core-agents/critical-reviewer.md +117 -0
- package/templates/core-agents/deep-analyst.md +216 -0
- package/templates/core-agents/finalization-agent.md +252 -0
- package/templates/core-agents/git-coordinator.md +240 -0
- package/templates/core-agents/implementation-agent.md +151 -0
- package/templates/core-agents/maestro-agent.md +413 -0
- package/templates/core-agents/maestro-headless-agent.md +422 -0
- package/templates/core-agents/plan-validator.md +198 -0
- package/templates/core-agents/quick-fix.md +56 -0
- package/templates/core-agents/routing-templates.md +338 -0
- package/templates/core-agents/task-orchestrator.md +143 -0
- package/templates/core-agents/task-prep.md +202 -0
- package/templates/core-agents/tdd-designer.md +143 -0
- package/templates/specialist-meta.md +275 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Read .claude/settings.json from a project root.
|
|
5
|
+
* Returns an empty object if the file does not exist or is malformed.
|
|
6
|
+
*/
|
|
7
|
+
export async function readClaudeSettings(projectRoot) {
|
|
8
|
+
const settingsPath = path.join(projectRoot, '.claude', 'settings.json');
|
|
9
|
+
try {
|
|
10
|
+
const content = await fs.readFile(settingsPath, 'utf-8');
|
|
11
|
+
return JSON.parse(content);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return {};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Atomically write .claude/settings.json for a project root.
|
|
19
|
+
* Uses temp file + rename to prevent corruption.
|
|
20
|
+
*/
|
|
21
|
+
export async function writeClaudeSettings(projectRoot, settings) {
|
|
22
|
+
const settingsDir = path.join(projectRoot, '.claude');
|
|
23
|
+
const settingsPath = path.join(settingsDir, 'settings.json');
|
|
24
|
+
const tmpPath = path.join(settingsDir, `.settings.json.tmp.${Date.now()}`);
|
|
25
|
+
await fs.ensureDir(settingsDir);
|
|
26
|
+
await fs.writeFile(tmpPath, JSON.stringify(settings, null, 2) + '\n');
|
|
27
|
+
await fs.rename(tmpPath, settingsPath);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Read .claude/settings.local.json from a project root.
|
|
31
|
+
* Returns an empty object if the file does not exist or is malformed.
|
|
32
|
+
*/
|
|
33
|
+
export async function readSettingsLocal(projectRoot) {
|
|
34
|
+
const localPath = path.join(projectRoot, '.claude', 'settings.local.json');
|
|
35
|
+
try {
|
|
36
|
+
const content = await fs.readFile(localPath, 'utf-8');
|
|
37
|
+
return JSON.parse(content);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Atomically write .claude/settings.local.json for a project root.
|
|
45
|
+
*/
|
|
46
|
+
async function writeSettingsLocal(projectRoot, data) {
|
|
47
|
+
const settingsDir = path.join(projectRoot, '.claude');
|
|
48
|
+
const localPath = path.join(settingsDir, 'settings.local.json');
|
|
49
|
+
const tmpPath = path.join(settingsDir, `.settings.local.json.tmp.${Date.now()}`);
|
|
50
|
+
await fs.ensureDir(settingsDir);
|
|
51
|
+
await fs.writeFile(tmpPath, JSON.stringify(data, null, 2) + '\n');
|
|
52
|
+
await fs.rename(tmpPath, localPath);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Add a permission rule to the allow list in .claude/settings.local.json.
|
|
56
|
+
* Idempotent — skips if the rule already exists.
|
|
57
|
+
*/
|
|
58
|
+
export async function addAllowPermission(projectRoot, rule) {
|
|
59
|
+
const settings = await readSettingsLocal(projectRoot);
|
|
60
|
+
if (!settings.permissions) {
|
|
61
|
+
settings.permissions = {};
|
|
62
|
+
}
|
|
63
|
+
if (!settings.permissions.allow) {
|
|
64
|
+
settings.permissions.allow = [];
|
|
65
|
+
}
|
|
66
|
+
if (!settings.permissions.allow.includes(rule)) {
|
|
67
|
+
settings.permissions.allow.push(rule);
|
|
68
|
+
await writeSettingsLocal(projectRoot, settings);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Remove a permission rule from the allow list in .claude/settings.local.json.
|
|
73
|
+
* No-op if the rule does not exist.
|
|
74
|
+
*/
|
|
75
|
+
export async function removeAllowPermission(projectRoot, rule) {
|
|
76
|
+
const settings = await readSettingsLocal(projectRoot);
|
|
77
|
+
if (!settings.permissions?.allow)
|
|
78
|
+
return;
|
|
79
|
+
const idx = settings.permissions.allow.indexOf(rule);
|
|
80
|
+
if (idx >= 0) {
|
|
81
|
+
settings.permissions.allow.splice(idx, 1);
|
|
82
|
+
await writeSettingsLocal(projectRoot, settings);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Read .mcp.json from a project root.
|
|
87
|
+
* Claude Code reads project-level MCP servers from this file (not .claude/settings.json).
|
|
88
|
+
* Returns an empty object if the file does not exist or is malformed.
|
|
89
|
+
*/
|
|
90
|
+
export async function readMcpJson(projectRoot) {
|
|
91
|
+
const mcpJsonPath = path.join(projectRoot, '.mcp.json');
|
|
92
|
+
try {
|
|
93
|
+
const content = await fs.readFile(mcpJsonPath, 'utf-8');
|
|
94
|
+
return JSON.parse(content);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return {};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Atomically write .mcp.json for a project root.
|
|
102
|
+
*/
|
|
103
|
+
async function writeMcpJson(projectRoot, data) {
|
|
104
|
+
const mcpJsonPath = path.join(projectRoot, '.mcp.json');
|
|
105
|
+
const tmpPath = path.join(projectRoot, `.mcp.json.tmp.${Date.now()}`);
|
|
106
|
+
await fs.writeFile(tmpPath, JSON.stringify(data, null, 2) + '\n');
|
|
107
|
+
await fs.rename(tmpPath, mcpJsonPath);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Add an MCP server entry to .mcp.json (project root).
|
|
111
|
+
* Claude Code reads project-level MCP servers from .mcp.json.
|
|
112
|
+
* Preserves existing entries.
|
|
113
|
+
*/
|
|
114
|
+
export async function addMcpServer(projectRoot, serverName, config) {
|
|
115
|
+
const mcpJson = await readMcpJson(projectRoot);
|
|
116
|
+
if (!mcpJson.mcpServers) {
|
|
117
|
+
mcpJson.mcpServers = {};
|
|
118
|
+
}
|
|
119
|
+
mcpJson.mcpServers[serverName] = config;
|
|
120
|
+
await writeMcpJson(projectRoot, mcpJson);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Remove an MCP server entry from .mcp.json (project root).
|
|
124
|
+
* No-op if the server does not exist.
|
|
125
|
+
*/
|
|
126
|
+
export async function removeMcpServer(projectRoot, serverName) {
|
|
127
|
+
const mcpJson = await readMcpJson(projectRoot);
|
|
128
|
+
if (mcpJson.mcpServers && serverName in mcpJson.mcpServers) {
|
|
129
|
+
delete mcpJson.mcpServers[serverName];
|
|
130
|
+
await writeMcpJson(projectRoot, mcpJson);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=merge-claude-settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-claude-settings.js","sourceRoot":"","sources":["../../src/utils/merge-claude-settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type VersionFile } from './version-tracker.js';
|
|
2
|
+
/**
|
|
3
|
+
* Result of a migration operation.
|
|
4
|
+
*/
|
|
5
|
+
export interface MigrationResult {
|
|
6
|
+
success: boolean;
|
|
7
|
+
migrated: boolean;
|
|
8
|
+
versionFile: VersionFile | null;
|
|
9
|
+
warnings: string[];
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Information about a template file.
|
|
14
|
+
*/
|
|
15
|
+
export interface TemplateFile {
|
|
16
|
+
relativePath: string;
|
|
17
|
+
templatePath: string;
|
|
18
|
+
hash: string | null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get the templates directory path.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getTemplatesDir(): string;
|
|
24
|
+
/**
|
|
25
|
+
* Get the core agents templates directory path.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getCoreAgentsTemplatesDir(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Check if an installation is legacy (pre-version.json).
|
|
30
|
+
*/
|
|
31
|
+
export declare function detectLegacyInstall(claudeDir: string): Promise<boolean>;
|
|
32
|
+
/**
|
|
33
|
+
* Check if a .claude directory exists.
|
|
34
|
+
*/
|
|
35
|
+
export declare function hasExistingInstall(claudeDir: string): Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* Get hashes of all current archai template files.
|
|
38
|
+
* Returns a map of relative paths (as they would be installed) to their hashes.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getTemplateHashes(): Promise<Map<string, string>>;
|
|
41
|
+
/**
|
|
42
|
+
* Get list of all template files with their paths and hashes.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getTemplateFiles(): Promise<TemplateFile[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Get the path to a specific template file.
|
|
47
|
+
*/
|
|
48
|
+
export declare function getTemplatePath(relativePath: string): string | null;
|
|
49
|
+
/**
|
|
50
|
+
* Migrate a legacy installation to use version.json.
|
|
51
|
+
*
|
|
52
|
+
* This function:
|
|
53
|
+
* 1. Gets current template hashes
|
|
54
|
+
* 2. Compares each existing file to templates
|
|
55
|
+
* 3. If file matches template exactly, use template hash as base
|
|
56
|
+
* 4. If file differs, use current file hash as base (assume user modified)
|
|
57
|
+
* 5. Marks specialist files as generated
|
|
58
|
+
* 6. Creates version.json
|
|
59
|
+
*/
|
|
60
|
+
export declare function migrateFromLegacy(claudeDir: string, archaiVersion: string): Promise<MigrationResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Check if migration is needed and perform it if necessary.
|
|
63
|
+
* Safe to call on any installation - will do nothing if not needed.
|
|
64
|
+
*/
|
|
65
|
+
export declare function ensureMigrated(claudeDir: string, archaiVersion: string): Promise<MigrationResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Get the archai version from package.json.
|
|
68
|
+
*/
|
|
69
|
+
export declare function getArchaiVersion(): Promise<string>;
|
|
70
|
+
/**
|
|
71
|
+
* List files that exist locally but not in templates (custom files).
|
|
72
|
+
*/
|
|
73
|
+
export declare function getCustomFiles(claudeDir: string): Promise<string[]>;
|
|
74
|
+
//# sourceMappingURL=migration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../../src/utils/migration.ts"],"names":[],"mappings":"AAKA,OAAO,EAML,KAAK,WAAW,EAEjB,MAAM,sBAAsB,CAAC;AAK9B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM7E;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE5E;AAgCD;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAoCtE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAuChE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoBnE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,eAAe,CAAC,CAkI1B;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,eAAe,CAAC,CAgB1B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CASxD;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA6BzE"}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { logger } from './logger.js';
|
|
5
|
+
import { hashFile, isGeneratedSpecialist } from './file-comparison.js';
|
|
6
|
+
import { loadVersionFile, saveVersionFile, createVersionFile, versionFileExists, normalizePath, } from './version-tracker.js';
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
/**
|
|
10
|
+
* Get the templates directory path.
|
|
11
|
+
*/
|
|
12
|
+
export function getTemplatesDir() {
|
|
13
|
+
return path.resolve(__dirname, '../../templates');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get the core agents templates directory path.
|
|
17
|
+
*/
|
|
18
|
+
export function getCoreAgentsTemplatesDir() {
|
|
19
|
+
return path.join(getTemplatesDir(), 'core-agents');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check if an installation is legacy (pre-version.json).
|
|
23
|
+
*/
|
|
24
|
+
export async function detectLegacyInstall(claudeDir) {
|
|
25
|
+
// A legacy install has a .claude directory but no version.json
|
|
26
|
+
const claudeExists = await fs.pathExists(claudeDir);
|
|
27
|
+
const hasVersionFile = await versionFileExists(claudeDir);
|
|
28
|
+
return claudeExists && !hasVersionFile;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if a .claude directory exists.
|
|
32
|
+
*/
|
|
33
|
+
export async function hasExistingInstall(claudeDir) {
|
|
34
|
+
return fs.pathExists(claudeDir);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get all files recursively from a directory.
|
|
38
|
+
*/
|
|
39
|
+
async function getFilesRecursive(dir, base = dir) {
|
|
40
|
+
const files = [];
|
|
41
|
+
if (!await fs.pathExists(dir)) {
|
|
42
|
+
return files;
|
|
43
|
+
}
|
|
44
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
const fullPath = path.join(dir, entry.name);
|
|
47
|
+
if (entry.isDirectory()) {
|
|
48
|
+
// Skip certain directories
|
|
49
|
+
if (entry.name === 'backups' || entry.name === 'node_modules') {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const subFiles = await getFilesRecursive(fullPath, base);
|
|
53
|
+
files.push(...subFiles);
|
|
54
|
+
}
|
|
55
|
+
else if (entry.isFile()) {
|
|
56
|
+
files.push(path.relative(base, fullPath));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return files;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get hashes of all current archai template files.
|
|
63
|
+
* Returns a map of relative paths (as they would be installed) to their hashes.
|
|
64
|
+
*/
|
|
65
|
+
export async function getTemplateHashes() {
|
|
66
|
+
const hashes = new Map();
|
|
67
|
+
const templatesDir = getTemplatesDir();
|
|
68
|
+
const coreAgentsDir = getCoreAgentsTemplatesDir();
|
|
69
|
+
// Core agents templates → .claude/agents/
|
|
70
|
+
if (await fs.pathExists(coreAgentsDir)) {
|
|
71
|
+
const agentFiles = await getFilesRecursive(coreAgentsDir);
|
|
72
|
+
for (const file of agentFiles) {
|
|
73
|
+
const templatePath = path.join(coreAgentsDir, file);
|
|
74
|
+
const hash = await hashFile(templatePath);
|
|
75
|
+
if (hash) {
|
|
76
|
+
// These get installed to .claude/agents/
|
|
77
|
+
const installedPath = normalizePath(`.claude/agents/${file}`);
|
|
78
|
+
hashes.set(installedPath, hash);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Root templates (PROMPTS.md, etc.) → .claude/
|
|
83
|
+
const rootTemplates = ['PROMPTS.md', 'ARCHAI_README.md'];
|
|
84
|
+
for (const file of rootTemplates) {
|
|
85
|
+
const templatePath = path.join(templatesDir, file);
|
|
86
|
+
if (await fs.pathExists(templatePath)) {
|
|
87
|
+
const hash = await hashFile(templatePath);
|
|
88
|
+
if (hash) {
|
|
89
|
+
// Map to their installed locations
|
|
90
|
+
const installedPath = file === 'ARCHAI_README.md'
|
|
91
|
+
? normalizePath('.claude/ARCHAI_README.md')
|
|
92
|
+
: normalizePath(`.claude/${file}`);
|
|
93
|
+
hashes.set(installedPath, hash);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return hashes;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get list of all template files with their paths and hashes.
|
|
101
|
+
*/
|
|
102
|
+
export async function getTemplateFiles() {
|
|
103
|
+
const files = [];
|
|
104
|
+
const templatesDir = getTemplatesDir();
|
|
105
|
+
const coreAgentsDir = getCoreAgentsTemplatesDir();
|
|
106
|
+
// Core agents
|
|
107
|
+
if (await fs.pathExists(coreAgentsDir)) {
|
|
108
|
+
const agentFiles = await getFilesRecursive(coreAgentsDir);
|
|
109
|
+
for (const file of agentFiles) {
|
|
110
|
+
const templatePath = path.join(coreAgentsDir, file);
|
|
111
|
+
const hash = await hashFile(templatePath);
|
|
112
|
+
files.push({
|
|
113
|
+
relativePath: normalizePath(`.claude/agents/${file}`),
|
|
114
|
+
templatePath,
|
|
115
|
+
hash,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Root templates
|
|
120
|
+
const rootTemplates = [
|
|
121
|
+
{ src: 'PROMPTS.md', dest: '.claude/PROMPTS.md' },
|
|
122
|
+
{ src: 'ARCHAI_README.md', dest: '.claude/ARCHAI_README.md' },
|
|
123
|
+
{ src: 'CLAUDE.md', dest: 'CLAUDE.md' },
|
|
124
|
+
];
|
|
125
|
+
for (const { src, dest } of rootTemplates) {
|
|
126
|
+
const templatePath = path.join(templatesDir, src);
|
|
127
|
+
if (await fs.pathExists(templatePath)) {
|
|
128
|
+
const hash = await hashFile(templatePath);
|
|
129
|
+
files.push({
|
|
130
|
+
relativePath: normalizePath(dest),
|
|
131
|
+
templatePath,
|
|
132
|
+
hash,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return files;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get the path to a specific template file.
|
|
140
|
+
*/
|
|
141
|
+
export function getTemplatePath(relativePath) {
|
|
142
|
+
const normalized = normalizePath(relativePath);
|
|
143
|
+
const templatesDir = getTemplatesDir();
|
|
144
|
+
// Check if it's a core agent
|
|
145
|
+
if (normalized.startsWith('.claude/agents/')) {
|
|
146
|
+
const agentFile = normalized.replace('.claude/agents/', '');
|
|
147
|
+
const templatePath = path.join(getCoreAgentsTemplatesDir(), agentFile);
|
|
148
|
+
return templatePath;
|
|
149
|
+
}
|
|
150
|
+
// Check other template mappings
|
|
151
|
+
if (normalized === '.claude/PROMPTS.md') {
|
|
152
|
+
return path.join(templatesDir, 'PROMPTS.md');
|
|
153
|
+
}
|
|
154
|
+
if (normalized === '.claude/ARCHAI_README.md') {
|
|
155
|
+
return path.join(templatesDir, 'ARCHAI_README.md');
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Migrate a legacy installation to use version.json.
|
|
161
|
+
*
|
|
162
|
+
* This function:
|
|
163
|
+
* 1. Gets current template hashes
|
|
164
|
+
* 2. Compares each existing file to templates
|
|
165
|
+
* 3. If file matches template exactly, use template hash as base
|
|
166
|
+
* 4. If file differs, use current file hash as base (assume user modified)
|
|
167
|
+
* 5. Marks specialist files as generated
|
|
168
|
+
* 6. Creates version.json
|
|
169
|
+
*/
|
|
170
|
+
export async function migrateFromLegacy(claudeDir, archaiVersion) {
|
|
171
|
+
const warnings = [];
|
|
172
|
+
try {
|
|
173
|
+
// Check if already migrated
|
|
174
|
+
if (await versionFileExists(claudeDir)) {
|
|
175
|
+
return {
|
|
176
|
+
success: true,
|
|
177
|
+
migrated: false,
|
|
178
|
+
versionFile: await loadVersionFile(claudeDir),
|
|
179
|
+
warnings: ['Already migrated (version.json exists)'],
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// Check if .claude directory exists
|
|
183
|
+
if (!await fs.pathExists(claudeDir)) {
|
|
184
|
+
return {
|
|
185
|
+
success: false,
|
|
186
|
+
migrated: false,
|
|
187
|
+
versionFile: null,
|
|
188
|
+
warnings: [],
|
|
189
|
+
error: '.claude directory does not exist',
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
// Get template hashes
|
|
193
|
+
const templateHashes = await getTemplateHashes();
|
|
194
|
+
// Get all files in the .claude directory
|
|
195
|
+
const existingFiles = await getFilesRecursive(claudeDir);
|
|
196
|
+
const files = {};
|
|
197
|
+
const expectedFiles = [];
|
|
198
|
+
// Process each existing file — only track template files and generated specialists.
|
|
199
|
+
// Non-template files (settings.local.json, status/*, plans/*, etc.) are user-owned
|
|
200
|
+
// and must NOT be tracked, otherwise they'd be flagged as orphaned/deprecated.
|
|
201
|
+
for (const relativePath of existingFiles) {
|
|
202
|
+
const fullPath = path.join(claudeDir, relativePath);
|
|
203
|
+
const normalizedPath = normalizePath(`.claude/${relativePath}`);
|
|
204
|
+
// Skip version.json itself if it somehow exists
|
|
205
|
+
if (relativePath === 'version.json') {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
// Check if this is a generated specialist
|
|
209
|
+
const isGenerated = isGeneratedSpecialist(normalizedPath);
|
|
210
|
+
if (isGenerated) {
|
|
211
|
+
// Generated files have no base hash
|
|
212
|
+
files[normalizedPath] = {
|
|
213
|
+
baseHash: null,
|
|
214
|
+
isGenerated: true,
|
|
215
|
+
};
|
|
216
|
+
logger.debug(`Marked as generated: ${normalizedPath}`);
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
// Only track files that match a known template path
|
|
220
|
+
const templateHash = templateHashes.get(normalizedPath);
|
|
221
|
+
if (!templateHash) {
|
|
222
|
+
logger.debug(`Skipping non-template file: ${normalizedPath}`);
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
// Get current file hash
|
|
226
|
+
const currentHash = await hashFile(fullPath);
|
|
227
|
+
if (currentHash === templateHash) {
|
|
228
|
+
// File matches template exactly - not user modified
|
|
229
|
+
files[normalizedPath] = {
|
|
230
|
+
baseHash: templateHash,
|
|
231
|
+
isGenerated: false,
|
|
232
|
+
};
|
|
233
|
+
expectedFiles.push(normalizedPath);
|
|
234
|
+
logger.debug(`Unchanged from template: ${normalizedPath}`);
|
|
235
|
+
}
|
|
236
|
+
else if (currentHash) {
|
|
237
|
+
// File differs from template - user modified or old archai version.
|
|
238
|
+
// Set baseHash to null so determineFileStatus returns 'modified_by_user',
|
|
239
|
+
// which prompts the user instead of silently overwriting their changes.
|
|
240
|
+
files[normalizedPath] = {
|
|
241
|
+
baseHash: null,
|
|
242
|
+
isGenerated: false,
|
|
243
|
+
};
|
|
244
|
+
warnings.push(`${normalizedPath} differs from template, assuming user-modified`);
|
|
245
|
+
expectedFiles.push(normalizedPath);
|
|
246
|
+
logger.debug(`User modified template file: ${normalizedPath}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Add expected files from templates that don't exist locally
|
|
250
|
+
for (const [templatePath, _] of templateHashes) {
|
|
251
|
+
if (!files[templatePath] && !expectedFiles.includes(templatePath)) {
|
|
252
|
+
expectedFiles.push(templatePath);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Create version file
|
|
256
|
+
const versionFile = createVersionFile(archaiVersion, files, expectedFiles);
|
|
257
|
+
// Save it
|
|
258
|
+
const saved = await saveVersionFile(claudeDir, versionFile);
|
|
259
|
+
if (!saved) {
|
|
260
|
+
return {
|
|
261
|
+
success: false,
|
|
262
|
+
migrated: false,
|
|
263
|
+
versionFile: null,
|
|
264
|
+
warnings,
|
|
265
|
+
error: 'Failed to save version.json',
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
logger.debug(`Migration complete: ${Object.keys(files).length} files tracked`);
|
|
269
|
+
return {
|
|
270
|
+
success: true,
|
|
271
|
+
migrated: true,
|
|
272
|
+
versionFile,
|
|
273
|
+
warnings,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
logger.debug('Migration failed', error);
|
|
278
|
+
return {
|
|
279
|
+
success: false,
|
|
280
|
+
migrated: false,
|
|
281
|
+
versionFile: null,
|
|
282
|
+
warnings,
|
|
283
|
+
error: error instanceof Error ? error.message : String(error),
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Check if migration is needed and perform it if necessary.
|
|
289
|
+
* Safe to call on any installation - will do nothing if not needed.
|
|
290
|
+
*/
|
|
291
|
+
export async function ensureMigrated(claudeDir, archaiVersion) {
|
|
292
|
+
const isLegacy = await detectLegacyInstall(claudeDir);
|
|
293
|
+
if (!isLegacy) {
|
|
294
|
+
// Not a legacy install - either fresh or already migrated
|
|
295
|
+
const versionFile = await loadVersionFile(claudeDir);
|
|
296
|
+
return {
|
|
297
|
+
success: true,
|
|
298
|
+
migrated: false,
|
|
299
|
+
versionFile,
|
|
300
|
+
warnings: [],
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
// Perform migration
|
|
304
|
+
return migrateFromLegacy(claudeDir, archaiVersion);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Get the archai version from package.json.
|
|
308
|
+
*/
|
|
309
|
+
export async function getArchaiVersion() {
|
|
310
|
+
const pkgPath = path.resolve(__dirname, '../../package.json');
|
|
311
|
+
try {
|
|
312
|
+
const pkg = await fs.readJson(pkgPath);
|
|
313
|
+
return pkg.version ?? 'unknown';
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
return 'unknown';
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* List files that exist locally but not in templates (custom files).
|
|
321
|
+
*/
|
|
322
|
+
export async function getCustomFiles(claudeDir) {
|
|
323
|
+
const templateHashes = await getTemplateHashes();
|
|
324
|
+
const templatePaths = new Set(templateHashes.keys());
|
|
325
|
+
const existingFiles = await getFilesRecursive(claudeDir);
|
|
326
|
+
const customFiles = [];
|
|
327
|
+
for (const relativePath of existingFiles) {
|
|
328
|
+
const normalizedPath = normalizePath(`.claude/${relativePath}`);
|
|
329
|
+
// Skip version.json
|
|
330
|
+
if (relativePath === 'version.json') {
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
// Skip if it's a known template
|
|
334
|
+
if (templatePaths.has(normalizedPath)) {
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
// Skip generated specialists
|
|
338
|
+
if (isGeneratedSpecialist(normalizedPath)) {
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
customFiles.push(normalizedPath);
|
|
342
|
+
}
|
|
343
|
+
return customFiles;
|
|
344
|
+
}
|
|
345
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../../src/utils/migration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAe,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EACL,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GAGd,MAAM,sBAAsB,CAAC;AAE9B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAsB3C;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB;IACvC,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,aAAa,CAAC,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,SAAiB;IACzD,+DAA+D;IAC/D,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAE1D,OAAO,YAAY,IAAI,CAAC,cAAc,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,SAAiB;IACxD,OAAO,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,iBAAiB,CAAC,GAAW,EAAE,OAAe,GAAG;IAC9D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE5C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,2BAA2B;YAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBAC9D,SAAS;YACX,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACzD,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC1B,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,MAAM,aAAa,GAAG,yBAAyB,EAAE,CAAC;IAElD,0CAA0C;IAC1C,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACvC,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,aAAa,CAAC,CAAC;QAC1D,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC1C,IAAI,IAAI,EAAE,CAAC;gBACT,yCAAyC;gBACzC,MAAM,aAAa,GAAG,aAAa,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC;gBAC9D,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,MAAM,aAAa,GAAG,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;IACzD,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QACnD,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC1C,IAAI,IAAI,EAAE,CAAC;gBACT,mCAAmC;gBACnC,MAAM,aAAa,GAAG,IAAI,KAAK,kBAAkB;oBAC/C,CAAC,CAAC,aAAa,CAAC,0BAA0B,CAAC;oBAC3C,CAAC,CAAC,aAAa,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;gBACrC,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,MAAM,aAAa,GAAG,yBAAyB,EAAE,CAAC;IAElD,cAAc;IACd,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACvC,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,aAAa,CAAC,CAAC;QAC1D,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC;gBACT,YAAY,EAAE,aAAa,CAAC,kBAAkB,IAAI,EAAE,CAAC;gBACrD,YAAY;gBACZ,IAAI;aACL,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,MAAM,aAAa,GAAG;QACpB,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,oBAAoB,EAAE;QACjD,EAAE,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,0BAA0B,EAAE;QAC7D,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE;KACxC,CAAC;IAEF,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,aAAa,EAAE,CAAC;QAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAClD,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC;gBACT,YAAY,EAAE,aAAa,CAAC,IAAI,CAAC;gBACjC,YAAY;gBACZ,IAAI;aACL,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,YAAoB;IAClD,MAAM,UAAU,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IAC/C,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IAEvC,6BAA6B;IAC7B,IAAI,UAAU,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC7C,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;QAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,SAAS,CAAC,CAAC;QACvE,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,gCAAgC;IAChC,IAAI,UAAU,KAAK,oBAAoB,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,UAAU,KAAK,0BAA0B,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAiB,EACjB,aAAqB;IAErB,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,4BAA4B;QAC5B,IAAI,MAAM,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,MAAM,eAAe,CAAC,SAAS,CAAC;gBAC7C,QAAQ,EAAE,CAAC,wCAAwC,CAAC;aACrD,CAAC;QACJ,CAAC;QAED,oCAAoC;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACpC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,IAAI;gBACjB,QAAQ,EAAE,EAAE;gBACZ,KAAK,EAAE,kCAAkC;aAC1C,CAAC;QACJ,CAAC;QAED,sBAAsB;QACtB,MAAM,cAAc,GAAG,MAAM,iBAAiB,EAAE,CAAC;QAEjD,yCAAyC;QACzC,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACzD,MAAM,KAAK,GAA+B,EAAE,CAAC;QAC7C,MAAM,aAAa,GAAa,EAAE,CAAC;QAEnC,oFAAoF;QACpF,mFAAmF;QACnF,+EAA+E;QAC/E,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;YACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YACpD,MAAM,cAAc,GAAG,aAAa,CAAC,WAAW,YAAY,EAAE,CAAC,CAAC;YAEhE,gDAAgD;YAChD,IAAI,YAAY,KAAK,cAAc,EAAE,CAAC;gBACpC,SAAS;YACX,CAAC;YAED,0CAA0C;YAC1C,MAAM,WAAW,GAAG,qBAAqB,CAAC,cAAc,CAAC,CAAC;YAE1D,IAAI,WAAW,EAAE,CAAC;gBAChB,oCAAoC;gBACpC,KAAK,CAAC,cAAc,CAAC,GAAG;oBACtB,QAAQ,EAAE,IAAI;oBACd,WAAW,EAAE,IAAI;iBAClB,CAAC;gBACF,MAAM,CAAC,KAAK,CAAC,wBAAwB,cAAc,EAAE,CAAC,CAAC;gBACvD,SAAS;YACX,CAAC;YAED,oDAAoD;YACpD,MAAM,YAAY,GAAG,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YACxD,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,MAAM,CAAC,KAAK,CAAC,+BAA+B,cAAc,EAAE,CAAC,CAAC;gBAC9D,SAAS;YACX,CAAC;YAED,wBAAwB;YACxB,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAE7C,IAAI,WAAW,KAAK,YAAY,EAAE,CAAC;gBACjC,oDAAoD;gBACpD,KAAK,CAAC,cAAc,CAAC,GAAG;oBACtB,QAAQ,EAAE,YAAY;oBACtB,WAAW,EAAE,KAAK;iBACnB,CAAC;gBACF,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBACnC,MAAM,CAAC,KAAK,CAAC,4BAA4B,cAAc,EAAE,CAAC,CAAC;YAC7D,CAAC;iBAAM,IAAI,WAAW,EAAE,CAAC;gBACvB,oEAAoE;gBACpE,0EAA0E;gBAC1E,wEAAwE;gBACxE,KAAK,CAAC,cAAc,CAAC,GAAG;oBACtB,QAAQ,EAAE,IAAI;oBACd,WAAW,EAAE,KAAK;iBACnB,CAAC;gBACF,QAAQ,CAAC,IAAI,CAAC,GAAG,cAAc,gDAAgD,CAAC,CAAC;gBACjF,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBACnC,MAAM,CAAC,KAAK,CAAC,gCAAgC,cAAc,EAAE,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;QAED,6DAA6D;QAC7D,KAAK,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,IAAI,cAAc,EAAE,CAAC;YAC/C,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBAClE,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,MAAM,WAAW,GAAG,iBAAiB,CAAC,aAAa,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;QAE3E,UAAU;QACV,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAC5D,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,IAAI;gBACjB,QAAQ;gBACR,KAAK,EAAE,6BAA6B;aACrC,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,KAAK,CAAC,uBAAuB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,gBAAgB,CAAC,CAAC;QAE/E,OAAO;YACL,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,WAAW;YACX,QAAQ;SACT,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;QACxC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,QAAQ,EAAE,KAAK;YACf,WAAW,EAAE,IAAI;YACjB,QAAQ;YACR,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,SAAiB,EACjB,aAAqB;IAErB,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAEtD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,0DAA0D;QAC1D,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC;QACrD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,KAAK;YACf,WAAW;YACX,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IAED,oBAAoB;IACpB,OAAO,iBAAiB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;IAE9D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAiB;IACpD,MAAM,cAAc,GAAG,MAAM,iBAAiB,EAAE,CAAC;IACjD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC;IAErD,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;QACzC,MAAM,cAAc,GAAG,aAAa,CAAC,WAAW,YAAY,EAAE,CAAC,CAAC;QAEhE,oBAAoB;QACpB,IAAI,YAAY,KAAK,cAAc,EAAE,CAAC;YACpC,SAAS;QACX,CAAC;QAED,gCAAgC;QAChC,IAAI,aAAa,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YACtC,SAAS;QACX,CAAC;QAED,6BAA6B;QAC7B,IAAI,qBAAqB,CAAC,cAAc,CAAC,EAAE,CAAC;YAC1C,SAAS;QACX,CAAC;QAED,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* On-demand health assessment for tracked processes.
|
|
3
|
+
*
|
|
4
|
+
* Pure classification logic (`classifyHealth`) plus I/O wrappers
|
|
5
|
+
* (`assessHealth`, `assessAll`) that resolve process data from
|
|
6
|
+
* in-process registry or cross-process state files.
|
|
7
|
+
*
|
|
8
|
+
* @module process-health
|
|
9
|
+
* @since Task-PROC-004
|
|
10
|
+
*/
|
|
11
|
+
import type { ProcessHealthReport, ProcessHealthOptions } from '../types/index.js';
|
|
12
|
+
/**
|
|
13
|
+
* Input shape for the pure classification function.
|
|
14
|
+
* Matches the subset of ProcessStateData needed for health assessment.
|
|
15
|
+
*/
|
|
16
|
+
interface ClassifyInput {
|
|
17
|
+
id: string;
|
|
18
|
+
pid: number;
|
|
19
|
+
state: string;
|
|
20
|
+
lastEventTime: number | null;
|
|
21
|
+
startTime: number;
|
|
22
|
+
eventCount: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Pure classification function — no I/O, no side effects.
|
|
26
|
+
* Exported for direct unit testing.
|
|
27
|
+
*
|
|
28
|
+
* Priority order: dead > zombie > stuck > idle > healthy.
|
|
29
|
+
*/
|
|
30
|
+
export declare function classifyHealth(data: ClassifyInput, alive: boolean, thresholds: {
|
|
31
|
+
idleThresholdMs: number;
|
|
32
|
+
stuckThresholdMs: number;
|
|
33
|
+
}): ProcessHealthReport;
|
|
34
|
+
/**
|
|
35
|
+
* Assess the health of a single tracked process.
|
|
36
|
+
*
|
|
37
|
+
* Checks the in-process registry first (freshest data), then falls back
|
|
38
|
+
* to cross-process state files on disk.
|
|
39
|
+
*
|
|
40
|
+
* @returns ProcessHealthReport or null if process not found
|
|
41
|
+
*/
|
|
42
|
+
export declare function assessHealth(id: string, opts?: ProcessHealthOptions): ProcessHealthReport | null;
|
|
43
|
+
/**
|
|
44
|
+
* Assess the health of all tracked processes.
|
|
45
|
+
*
|
|
46
|
+
* Combines in-process registry entries with cross-process state files,
|
|
47
|
+
* deduplicating by ID (in-process wins).
|
|
48
|
+
*/
|
|
49
|
+
export declare function assessAll(opts?: ProcessHealthOptions): ProcessHealthReport[];
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=process-health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-health.d.ts","sourceRoot":"","sources":["../../src/utils/process-health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,mBAAmB,EAAuB,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAIxG;;;GAGG;AACH,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,OAAO,EACd,UAAU,EAAE;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GAChE,mBAAmB,CAyCrB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,oBAAoB,GAAG,mBAAmB,GAAG,IAAI,CA6BhG;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,CAAC,EAAE,oBAAoB,GAAG,mBAAmB,EAAE,CAkC5E"}
|