ai-mind-map 1.1.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/LICENSE +21 -0
- package/README.md +554 -0
- package/dist/change-tracker/change-log.d.ts +160 -0
- package/dist/change-tracker/change-log.d.ts.map +1 -0
- package/dist/change-tracker/change-log.js +507 -0
- package/dist/change-tracker/change-log.js.map +1 -0
- package/dist/change-tracker/diff-engine.d.ts +149 -0
- package/dist/change-tracker/diff-engine.d.ts.map +1 -0
- package/dist/change-tracker/diff-engine.js +530 -0
- package/dist/change-tracker/diff-engine.js.map +1 -0
- package/dist/change-tracker/watcher.d.ts +137 -0
- package/dist/change-tracker/watcher.d.ts.map +1 -0
- package/dist/change-tracker/watcher.js +300 -0
- package/dist/change-tracker/watcher.js.map +1 -0
- package/dist/cli.d.ts +20 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +937 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +38 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +222 -0
- package/dist/config.js.map +1 -0
- package/dist/context/compressor.d.ts +49 -0
- package/dist/context/compressor.d.ts.map +1 -0
- package/dist/context/compressor.js +769 -0
- package/dist/context/compressor.js.map +1 -0
- package/dist/context/progressive-disclosure.d.ts +71 -0
- package/dist/context/progressive-disclosure.d.ts.map +1 -0
- package/dist/context/progressive-disclosure.js +470 -0
- package/dist/context/progressive-disclosure.js.map +1 -0
- package/dist/context/token-budget.d.ts +121 -0
- package/dist/context/token-budget.d.ts.map +1 -0
- package/dist/context/token-budget.js +282 -0
- package/dist/context/token-budget.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +944 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +66 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +946 -0
- package/dist/install.js.map +1 -0
- package/dist/knowledge-graph/architecture.d.ts +213 -0
- package/dist/knowledge-graph/architecture.d.ts.map +1 -0
- package/dist/knowledge-graph/architecture.js +585 -0
- package/dist/knowledge-graph/architecture.js.map +1 -0
- package/dist/knowledge-graph/cypher.d.ts +113 -0
- package/dist/knowledge-graph/cypher.d.ts.map +1 -0
- package/dist/knowledge-graph/cypher.js +1051 -0
- package/dist/knowledge-graph/cypher.js.map +1 -0
- package/dist/knowledge-graph/dead-code.d.ts +121 -0
- package/dist/knowledge-graph/dead-code.d.ts.map +1 -0
- package/dist/knowledge-graph/dead-code.js +331 -0
- package/dist/knowledge-graph/dead-code.js.map +1 -0
- package/dist/knowledge-graph/flow-analyzer.d.ts +167 -0
- package/dist/knowledge-graph/flow-analyzer.d.ts.map +1 -0
- package/dist/knowledge-graph/flow-analyzer.js +739 -0
- package/dist/knowledge-graph/flow-analyzer.js.map +1 -0
- package/dist/knowledge-graph/graph.d.ts +291 -0
- package/dist/knowledge-graph/graph.d.ts.map +1 -0
- package/dist/knowledge-graph/graph.js +978 -0
- package/dist/knowledge-graph/graph.js.map +1 -0
- package/dist/knowledge-graph/index.d.ts +17 -0
- package/dist/knowledge-graph/index.d.ts.map +1 -0
- package/dist/knowledge-graph/index.js +14 -0
- package/dist/knowledge-graph/index.js.map +1 -0
- package/dist/knowledge-graph/indexer.d.ts +112 -0
- package/dist/knowledge-graph/indexer.d.ts.map +1 -0
- package/dist/knowledge-graph/indexer.js +506 -0
- package/dist/knowledge-graph/indexer.js.map +1 -0
- package/dist/knowledge-graph/pagerank.d.ts +141 -0
- package/dist/knowledge-graph/pagerank.d.ts.map +1 -0
- package/dist/knowledge-graph/pagerank.js +493 -0
- package/dist/knowledge-graph/pagerank.js.map +1 -0
- package/dist/knowledge-graph/parser.d.ts +55 -0
- package/dist/knowledge-graph/parser.d.ts.map +1 -0
- package/dist/knowledge-graph/parser.js +1090 -0
- package/dist/knowledge-graph/parser.js.map +1 -0
- package/dist/knowledge-graph/snapshot.d.ts +107 -0
- package/dist/knowledge-graph/snapshot.d.ts.map +1 -0
- package/dist/knowledge-graph/snapshot.js +435 -0
- package/dist/knowledge-graph/snapshot.js.map +1 -0
- package/dist/memory/decision-log.d.ts +151 -0
- package/dist/memory/decision-log.d.ts.map +1 -0
- package/dist/memory/decision-log.js +482 -0
- package/dist/memory/decision-log.js.map +1 -0
- package/dist/memory/persistent-memory.d.ts +182 -0
- package/dist/memory/persistent-memory.d.ts.map +1 -0
- package/dist/memory/persistent-memory.js +579 -0
- package/dist/memory/persistent-memory.js.map +1 -0
- package/dist/memory/session-memory.d.ts +165 -0
- package/dist/memory/session-memory.d.ts.map +1 -0
- package/dist/memory/session-memory.js +382 -0
- package/dist/memory/session-memory.js.map +1 -0
- package/dist/stress-test.d.ts +10 -0
- package/dist/stress-test.d.ts.map +1 -0
- package/dist/stress-test.js +258 -0
- package/dist/stress-test.js.map +1 -0
- package/dist/tools/advanced-tools.d.ts +32 -0
- package/dist/tools/advanced-tools.d.ts.map +1 -0
- package/dist/tools/advanced-tools.js +480 -0
- package/dist/tools/advanced-tools.js.map +1 -0
- package/dist/tools/change-tools.d.ts +76 -0
- package/dist/tools/change-tools.d.ts.map +1 -0
- package/dist/tools/change-tools.js +93 -0
- package/dist/tools/change-tools.js.map +1 -0
- package/dist/tools/context-tools.d.ts +68 -0
- package/dist/tools/context-tools.d.ts.map +1 -0
- package/dist/tools/context-tools.js +141 -0
- package/dist/tools/context-tools.js.map +1 -0
- package/dist/tools/debug-tools.d.ts +25 -0
- package/dist/tools/debug-tools.d.ts.map +1 -0
- package/dist/tools/debug-tools.js +286 -0
- package/dist/tools/debug-tools.js.map +1 -0
- package/dist/tools/evolving-tools.d.ts +23 -0
- package/dist/tools/evolving-tools.d.ts.map +1 -0
- package/dist/tools/evolving-tools.js +207 -0
- package/dist/tools/evolving-tools.js.map +1 -0
- package/dist/tools/flow-tools.d.ts +24 -0
- package/dist/tools/flow-tools.d.ts.map +1 -0
- package/dist/tools/flow-tools.js +265 -0
- package/dist/tools/flow-tools.js.map +1 -0
- package/dist/tools/graph-tools.d.ts +71 -0
- package/dist/tools/graph-tools.d.ts.map +1 -0
- package/dist/tools/graph-tools.js +165 -0
- package/dist/tools/graph-tools.js.map +1 -0
- package/dist/tools/memory-tools.d.ts +62 -0
- package/dist/tools/memory-tools.d.ts.map +1 -0
- package/dist/tools/memory-tools.js +195 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/smart-tools.d.ts +23 -0
- package/dist/tools/smart-tools.d.ts.map +1 -0
- package/dist/tools/smart-tools.js +482 -0
- package/dist/tools/smart-tools.js.map +1 -0
- package/dist/tools/snapshot-tools.d.ts +19 -0
- package/dist/tools/snapshot-tools.d.ts.map +1 -0
- package/dist/tools/snapshot-tools.js +149 -0
- package/dist/tools/snapshot-tools.js.map +1 -0
- package/dist/types.d.ts +181 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +45 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/logger.d.ts +59 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +142 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/token-counter.d.ts +51 -0
- package/dist/utils/token-counter.d.ts.map +1 -0
- package/dist/utils/token-counter.js +181 -0
- package/dist/utils/token-counter.js.map +1 -0
- package/install.ps1 +321 -0
- package/install.sh +345 -0
- package/package.json +94 -0
- package/setup.bat +62 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Mind Map — Fast Token Counter
|
|
3
|
+
*
|
|
4
|
+
* Provides a fast, dependency-free approximation of GPT-style token counts
|
|
5
|
+
* without loading the heavy tiktoken library.
|
|
6
|
+
*
|
|
7
|
+
* Algorithm:
|
|
8
|
+
* 1. Split input by whitespace and punctuation boundaries.
|
|
9
|
+
* 2. Count the resulting chunks.
|
|
10
|
+
* 3. Apply a calibrated multiplier (1.3) for sub-word tokenisation.
|
|
11
|
+
* 4. Add a correction for special / non-ASCII characters.
|
|
12
|
+
*
|
|
13
|
+
* Accuracy: within ~10% of the real cl100k_base token count.
|
|
14
|
+
* Performance: <1 ms for 10 K-character strings.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Regex that splits text at token-like boundaries.
|
|
18
|
+
*
|
|
19
|
+
* This intentionally captures:
|
|
20
|
+
* - Runs of word characters (a-z, A-Z, 0-9, _)
|
|
21
|
+
* - Individual punctuation / symbol characters
|
|
22
|
+
* - Individual non-ASCII characters (each counts as ~1 token)
|
|
23
|
+
*/
|
|
24
|
+
const TOKEN_SPLIT_RE = /[\w]+|[^\s\w]/g;
|
|
25
|
+
/** Calibration multiplier. Tuned against cl100k_base across many samples. */
|
|
26
|
+
const BASE_MULTIPLIER = 1.3;
|
|
27
|
+
/**
|
|
28
|
+
* Characters that typically expand into multiple BPE tokens.
|
|
29
|
+
* Each occurrence adds a small correction.
|
|
30
|
+
*/
|
|
31
|
+
const EXPENSIVE_CHAR_RE = /[{}()\[\]<>:;,."'`~!@#$%^&*+=|\\/?]/g;
|
|
32
|
+
/** Extra token fraction added per expensive character. */
|
|
33
|
+
const EXPENSIVE_CHAR_COST = 0.15;
|
|
34
|
+
/**
|
|
35
|
+
* Estimate the token count of `text` using a fast heuristic.
|
|
36
|
+
*
|
|
37
|
+
* @param text - The input string.
|
|
38
|
+
* @returns Estimated token count (integer, ≥ 0).
|
|
39
|
+
*/
|
|
40
|
+
export function estimateTokens(text) {
|
|
41
|
+
if (!text) {
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
// Fast-path for very short strings.
|
|
45
|
+
if (text.length <= 4) {
|
|
46
|
+
return 1;
|
|
47
|
+
}
|
|
48
|
+
const chunks = text.match(TOKEN_SPLIT_RE);
|
|
49
|
+
if (!chunks) {
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
const baseCount = chunks.length;
|
|
53
|
+
// Count expensive characters for correction.
|
|
54
|
+
const expensiveMatches = text.match(EXPENSIVE_CHAR_RE);
|
|
55
|
+
const expensiveCount = expensiveMatches ? expensiveMatches.length : 0;
|
|
56
|
+
// Count non-ASCII characters (each often becomes 2-3 tokens in BPE).
|
|
57
|
+
let nonAsciiCount = 0;
|
|
58
|
+
for (let i = 0; i < text.length; i++) {
|
|
59
|
+
if (text.charCodeAt(i) > 127) {
|
|
60
|
+
nonAsciiCount++;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const estimate = baseCount * BASE_MULTIPLIER +
|
|
64
|
+
expensiveCount * EXPENSIVE_CHAR_COST +
|
|
65
|
+
nonAsciiCount * 0.5;
|
|
66
|
+
return Math.max(1, Math.round(estimate));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Estimate the token count for an array of strings (summed).
|
|
70
|
+
*
|
|
71
|
+
* @param texts - The input strings.
|
|
72
|
+
* @returns Total estimated token count.
|
|
73
|
+
*/
|
|
74
|
+
export function estimateTokensMany(texts) {
|
|
75
|
+
let total = 0;
|
|
76
|
+
for (const t of texts) {
|
|
77
|
+
total += estimateTokens(t);
|
|
78
|
+
}
|
|
79
|
+
return total;
|
|
80
|
+
}
|
|
81
|
+
// ── Smart Truncation ──────────────────────────────────────────
|
|
82
|
+
/**
|
|
83
|
+
* Logical boundary characters / patterns for smart truncation,
|
|
84
|
+
* ordered from most desirable to least desirable.
|
|
85
|
+
*/
|
|
86
|
+
const BOUNDARY_PATTERNS = [
|
|
87
|
+
/\n\n/, // Paragraph / blank-line boundary
|
|
88
|
+
/\n}/, // End of block (function, class, object)
|
|
89
|
+
/\n\)/, // End of parenthesised block
|
|
90
|
+
/\n/, // Any newline
|
|
91
|
+
/\.\s/, // End of sentence
|
|
92
|
+
/;\s/, // End of statement
|
|
93
|
+
/,\s/, // After comma
|
|
94
|
+
/\s/, // Any whitespace (last resort)
|
|
95
|
+
];
|
|
96
|
+
/**
|
|
97
|
+
* Truncate `text` so that its estimated token count is ≤ `maxTokens`.
|
|
98
|
+
*
|
|
99
|
+
* The function tries to cut at a logical boundary (end of paragraph,
|
|
100
|
+
* end of function, end of sentence, etc.) rather than mid-word.
|
|
101
|
+
*
|
|
102
|
+
* @param text - The input string.
|
|
103
|
+
* @param maxTokens - Maximum token budget.
|
|
104
|
+
* @param suffix - Optional suffix appended to indicate truncation.
|
|
105
|
+
* Defaults to `"\n... [truncated]"`.
|
|
106
|
+
* @returns The (possibly truncated) string.
|
|
107
|
+
*/
|
|
108
|
+
export function truncateToTokenBudget(text, maxTokens, suffix = '\n... [truncated]') {
|
|
109
|
+
if (maxTokens <= 0) {
|
|
110
|
+
return suffix;
|
|
111
|
+
}
|
|
112
|
+
const currentTokens = estimateTokens(text);
|
|
113
|
+
if (currentTokens <= maxTokens) {
|
|
114
|
+
return text;
|
|
115
|
+
}
|
|
116
|
+
const suffixTokens = estimateTokens(suffix);
|
|
117
|
+
const targetTokens = maxTokens - suffixTokens;
|
|
118
|
+
if (targetTokens <= 0) {
|
|
119
|
+
return suffix;
|
|
120
|
+
}
|
|
121
|
+
// Estimate a rough character-to-token ratio for this text.
|
|
122
|
+
const ratio = text.length / currentTokens;
|
|
123
|
+
// Start with a character budget derived from the ratio, with a small buffer.
|
|
124
|
+
let charBudget = Math.floor(targetTokens * ratio * 0.95);
|
|
125
|
+
charBudget = Math.min(charBudget, text.length);
|
|
126
|
+
if (charBudget <= 0) {
|
|
127
|
+
return suffix;
|
|
128
|
+
}
|
|
129
|
+
// Try to find the best logical boundary before the char budget.
|
|
130
|
+
const candidate = text.slice(0, charBudget);
|
|
131
|
+
let bestCut = charBudget;
|
|
132
|
+
for (const pattern of BOUNDARY_PATTERNS) {
|
|
133
|
+
// Search backwards from the end of the candidate for the pattern.
|
|
134
|
+
const lastIndex = findLastMatch(candidate, pattern);
|
|
135
|
+
if (lastIndex !== -1 && lastIndex > charBudget * 0.5) {
|
|
136
|
+
// Only accept boundaries in the latter half to avoid over-truncation.
|
|
137
|
+
bestCut = lastIndex + findMatchLength(candidate, pattern, lastIndex);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
let truncated = text.slice(0, bestCut).trimEnd() + suffix;
|
|
142
|
+
// Safety check: verify we're within budget, shrink if needed.
|
|
143
|
+
let attempts = 0;
|
|
144
|
+
while (estimateTokens(truncated) > maxTokens && bestCut > 10 && attempts < 5) {
|
|
145
|
+
bestCut = Math.floor(bestCut * 0.85);
|
|
146
|
+
truncated = text.slice(0, bestCut).trimEnd() + suffix;
|
|
147
|
+
attempts++;
|
|
148
|
+
}
|
|
149
|
+
return truncated;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Find the last occurrence of `pattern` within `text`.
|
|
153
|
+
* Returns the start index, or -1 if not found.
|
|
154
|
+
*/
|
|
155
|
+
function findLastMatch(text, pattern) {
|
|
156
|
+
const global = new RegExp(pattern.source, 'g');
|
|
157
|
+
let lastIndex = -1;
|
|
158
|
+
let match;
|
|
159
|
+
while ((match = global.exec(text)) !== null) {
|
|
160
|
+
lastIndex = match.index;
|
|
161
|
+
}
|
|
162
|
+
return lastIndex;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Return the length of the match of `pattern` at `index` in `text`.
|
|
166
|
+
*/
|
|
167
|
+
function findMatchLength(text, pattern, index) {
|
|
168
|
+
const m = text.slice(index).match(pattern);
|
|
169
|
+
return m ? m[0].length : 0;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Check whether `text` fits within the given token budget.
|
|
173
|
+
*
|
|
174
|
+
* @param text - The input string.
|
|
175
|
+
* @param maxTokens - Maximum allowed tokens.
|
|
176
|
+
* @returns `true` if estimated tokens ≤ maxTokens.
|
|
177
|
+
*/
|
|
178
|
+
export function fitsWithinBudget(text, maxTokens) {
|
|
179
|
+
return estimateTokens(text) <= maxTokens;
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=token-counter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-counter.js","sourceRoot":"","sources":["../../src/utils/token-counter.ts"],"names":[],"mappings":"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"}
|
package/install.ps1
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
#Requires -Version 5.1
|
|
2
|
+
<#
|
|
3
|
+
.SYNOPSIS
|
|
4
|
+
AI Mind Map — One-line installer for Windows.
|
|
5
|
+
|
|
6
|
+
.DESCRIPTION
|
|
7
|
+
Installs the AI Mind Map MCP server by cloning the repository,
|
|
8
|
+
building from source, and optionally configuring detected AI agents.
|
|
9
|
+
|
|
10
|
+
.PARAMETER InstallDir
|
|
11
|
+
Custom installation directory. Default: $env:USERPROFILE\.ai-mind-map
|
|
12
|
+
|
|
13
|
+
.PARAMETER SkipConfig
|
|
14
|
+
Skip automatic AI agent configuration.
|
|
15
|
+
|
|
16
|
+
.PARAMETER Update
|
|
17
|
+
Force update mode — pulls latest changes and rebuilds.
|
|
18
|
+
|
|
19
|
+
.EXAMPLE
|
|
20
|
+
# Default install
|
|
21
|
+
.\install.ps1
|
|
22
|
+
|
|
23
|
+
# Custom directory
|
|
24
|
+
.\install.ps1 -InstallDir "D:\tools\ai-mind-map"
|
|
25
|
+
|
|
26
|
+
# Update existing installation
|
|
27
|
+
.\install.ps1 -Update
|
|
28
|
+
|
|
29
|
+
.LINK
|
|
30
|
+
https://github.com/shdra06/ai-mind-map
|
|
31
|
+
#>
|
|
32
|
+
[CmdletBinding()]
|
|
33
|
+
param(
|
|
34
|
+
[string]$InstallDir = "",
|
|
35
|
+
[switch]$SkipConfig,
|
|
36
|
+
[switch]$Update
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
Set-StrictMode -Version Latest
|
|
40
|
+
$ErrorActionPreference = "Stop"
|
|
41
|
+
|
|
42
|
+
# ── Constants ────────────────────────────────────────────────────────────────
|
|
43
|
+
$REPO_URL = "https://github.com/shdra06/ai-mind-map.git"
|
|
44
|
+
$MIN_NODE_MAJOR = 18
|
|
45
|
+
$ENTRY_POINT = "dist\index.js"
|
|
46
|
+
|
|
47
|
+
# ── Banner ───────────────────────────────────────────────────────────────────
|
|
48
|
+
function Show-Banner {
|
|
49
|
+
$banner = @"
|
|
50
|
+
|
|
51
|
+
█████╗ ██╗ ███╗ ███╗██╗███╗ ██╗██████╗ ███╗ ███╗ █████╗ ██████╗
|
|
52
|
+
██╔══██╗██║ ████╗ ████║██║████╗ ██║██╔══██╗ ████╗ ████║██╔══██╗██╔══██╗
|
|
53
|
+
███████║██║ ██╔████╔██║██║██╔██╗ ██║██║ ██║ ██╔████╔██║███████║██████╔╝
|
|
54
|
+
██╔══██║██║ ██║╚██╔╝██║██║██║╚██╗██║██║ ██║ ██║╚██╔╝██║██╔══██║██╔═══╝
|
|
55
|
+
██║ ██║██║ ██║ ╚═╝ ██║██║██║ ╚████║██████╔╝ ██║ ╚═╝ ██║██║ ██║██║
|
|
56
|
+
╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝
|
|
57
|
+
|
|
58
|
+
MCP Server — Reduce AI token usage by 80-99%%
|
|
59
|
+
https://github.com/shdra06/ai-mind-map
|
|
60
|
+
|
|
61
|
+
"@
|
|
62
|
+
Write-Host $banner -ForegroundColor Cyan
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# ── Helpers ──────────────────────────────────────────────────────────────────
|
|
66
|
+
function Write-Step { param([string]$Msg) Write-Host " [*] $Msg" -ForegroundColor Blue }
|
|
67
|
+
function Write-Ok { param([string]$Msg) Write-Host " [✓] $Msg" -ForegroundColor Green }
|
|
68
|
+
function Write-Warn { param([string]$Msg) Write-Host " [!] $Msg" -ForegroundColor Yellow }
|
|
69
|
+
function Write-Err { param([string]$Msg) Write-Host " [✗] $Msg" -ForegroundColor Red }
|
|
70
|
+
|
|
71
|
+
function Test-CommandExists {
|
|
72
|
+
param([string]$Command)
|
|
73
|
+
$null -ne (Get-Command $Command -ErrorAction SilentlyContinue)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function Invoke-StepCommand {
|
|
77
|
+
param([string]$Label, [string]$Exe, [string[]]$Arguments, [string]$WorkDir)
|
|
78
|
+
Write-Step $Label
|
|
79
|
+
$psi = @{
|
|
80
|
+
FilePath = $Exe
|
|
81
|
+
ArgumentList = $Arguments
|
|
82
|
+
WorkingDirectory = $WorkDir
|
|
83
|
+
NoNewWindow = $true
|
|
84
|
+
Wait = $true
|
|
85
|
+
PassThru = $true
|
|
86
|
+
}
|
|
87
|
+
$proc = Start-Process @psi
|
|
88
|
+
if ($proc.ExitCode -ne 0) {
|
|
89
|
+
Write-Err "$Label failed with exit code $($proc.ExitCode)."
|
|
90
|
+
exit 1
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# ── Pre-flight Checks ───────────────────────────────────────────────────────
|
|
95
|
+
function Assert-Prerequisites {
|
|
96
|
+
Write-Host "`n Checking prerequisites..." -ForegroundColor White
|
|
97
|
+
|
|
98
|
+
# Node.js
|
|
99
|
+
if (-not (Test-CommandExists "node")) {
|
|
100
|
+
Write-Err "Node.js is not installed."
|
|
101
|
+
Write-Err "Download it from: https://nodejs.org (v$MIN_NODE_MAJOR or later)"
|
|
102
|
+
exit 1
|
|
103
|
+
}
|
|
104
|
+
$nodeVersionRaw = (node --version 2>&1).ToString().Trim()
|
|
105
|
+
$nodeMatch = [regex]::Match($nodeVersionRaw, 'v(\d+)\.')
|
|
106
|
+
if (-not $nodeMatch.Success) {
|
|
107
|
+
Write-Err "Could not determine Node.js version from: $nodeVersionRaw"
|
|
108
|
+
exit 1
|
|
109
|
+
}
|
|
110
|
+
$nodeMajor = [int]$nodeMatch.Groups[1].Value
|
|
111
|
+
if ($nodeMajor -lt $MIN_NODE_MAJOR) {
|
|
112
|
+
Write-Err "Node.js v$MIN_NODE_MAJOR+ is required. Found: $nodeVersionRaw"
|
|
113
|
+
Write-Err "Download the latest LTS from: https://nodejs.org"
|
|
114
|
+
exit 1
|
|
115
|
+
}
|
|
116
|
+
Write-Ok "Node.js $nodeVersionRaw"
|
|
117
|
+
|
|
118
|
+
# npm (comes with Node, but verify)
|
|
119
|
+
if (-not (Test-CommandExists "npm")) {
|
|
120
|
+
Write-Err "npm is not installed. It should come with Node.js — try reinstalling Node."
|
|
121
|
+
exit 1
|
|
122
|
+
}
|
|
123
|
+
$npmVersion = (npm --version 2>&1).ToString().Trim()
|
|
124
|
+
Write-Ok "npm v$npmVersion"
|
|
125
|
+
|
|
126
|
+
# Git
|
|
127
|
+
if (-not (Test-CommandExists "git")) {
|
|
128
|
+
Write-Err "Git is not installed."
|
|
129
|
+
Write-Err "Download it from: https://git-scm.com/download/win"
|
|
130
|
+
exit 1
|
|
131
|
+
}
|
|
132
|
+
$gitVersion = (git --version 2>&1).ToString().Trim()
|
|
133
|
+
Write-Ok "$gitVersion"
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
# ── Installation ─────────────────────────────────────────────────────────────
|
|
137
|
+
function Install-AiMindMap {
|
|
138
|
+
$targetDir = if ($InstallDir -ne "") { $InstallDir } else { Join-Path $env:USERPROFILE ".ai-mind-map" }
|
|
139
|
+
$isExisting = Test-Path (Join-Path $targetDir ".git")
|
|
140
|
+
|
|
141
|
+
# Decide: fresh install or update
|
|
142
|
+
if ($isExisting -and -not $Update) {
|
|
143
|
+
Write-Warn "AI Mind Map is already installed at: $targetDir"
|
|
144
|
+
$choice = Read-Host " Update to latest version? (Y/n)"
|
|
145
|
+
if ($choice -match '^[Nn]') {
|
|
146
|
+
Write-Host "`n Installation cancelled." -ForegroundColor Gray
|
|
147
|
+
exit 0
|
|
148
|
+
}
|
|
149
|
+
$Update = $true
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if ($Update -and $isExisting) {
|
|
153
|
+
# ── Update path ──────────────────────────────────────────────────
|
|
154
|
+
Write-Host "`n Updating AI Mind Map..." -ForegroundColor White
|
|
155
|
+
Write-Step "Pulling latest changes..."
|
|
156
|
+
$gitPull = Start-Process -FilePath "git" -ArgumentList "pull","--ff-only" `
|
|
157
|
+
-WorkingDirectory $targetDir -NoNewWindow -Wait -PassThru
|
|
158
|
+
if ($gitPull.ExitCode -ne 0) {
|
|
159
|
+
Write-Warn "Fast-forward pull failed. Trying git pull --rebase..."
|
|
160
|
+
$gitRebase = Start-Process -FilePath "git" -ArgumentList "pull","--rebase" `
|
|
161
|
+
-WorkingDirectory $targetDir -NoNewWindow -Wait -PassThru
|
|
162
|
+
if ($gitRebase.ExitCode -ne 0) {
|
|
163
|
+
Write-Err "Git pull failed. You may have local changes."
|
|
164
|
+
Write-Err "Resolve manually in: $targetDir"
|
|
165
|
+
exit 1
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
Write-Ok "Repository updated"
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
# ── Fresh install ────────────────────────────────────────────────
|
|
172
|
+
Write-Host "`n Installing AI Mind Map..." -ForegroundColor White
|
|
173
|
+
Write-Step "Cloning repository to: $targetDir"
|
|
174
|
+
if (Test-Path $targetDir) {
|
|
175
|
+
Write-Warn "Directory exists but is not a git repo. Removing..."
|
|
176
|
+
Remove-Item -Recurse -Force $targetDir
|
|
177
|
+
}
|
|
178
|
+
$gitClone = Start-Process -FilePath "git" -ArgumentList "clone",$REPO_URL,$targetDir `
|
|
179
|
+
-NoNewWindow -Wait -PassThru
|
|
180
|
+
if ($gitClone.ExitCode -ne 0) {
|
|
181
|
+
Write-Err "Failed to clone repository."
|
|
182
|
+
Write-Err "Check your internet connection and try again."
|
|
183
|
+
exit 1
|
|
184
|
+
}
|
|
185
|
+
Write-Ok "Repository cloned"
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
# ── Install dependencies ─────────────────────────────────────────────
|
|
189
|
+
Invoke-StepCommand -Label "Installing dependencies (this may take a minute)..." `
|
|
190
|
+
-Exe "npm" -Arguments @("install","--legacy-peer-deps") -WorkDir $targetDir
|
|
191
|
+
Write-Ok "Dependencies installed"
|
|
192
|
+
|
|
193
|
+
# ── Build ────────────────────────────────────────────────────────────
|
|
194
|
+
Invoke-StepCommand -Label "Building TypeScript..." `
|
|
195
|
+
-Exe "npx" -Arguments @("tsc") -WorkDir $targetDir
|
|
196
|
+
Write-Ok "Build complete"
|
|
197
|
+
|
|
198
|
+
# ── Verify build ─────────────────────────────────────────────────────
|
|
199
|
+
$entryFile = Join-Path $targetDir $ENTRY_POINT
|
|
200
|
+
if (-not (Test-Path $entryFile)) {
|
|
201
|
+
Write-Err "Build verification failed: $ENTRY_POINT not found."
|
|
202
|
+
Write-Err "Please report this issue: https://github.com/shdra06/ai-mind-map/issues"
|
|
203
|
+
exit 1
|
|
204
|
+
}
|
|
205
|
+
Write-Ok "Build verified ($ENTRY_POINT exists)"
|
|
206
|
+
|
|
207
|
+
# ── PATH management ──────────────────────────────────────────────────
|
|
208
|
+
Add-ToUserPath -Dir $targetDir
|
|
209
|
+
|
|
210
|
+
# ── Agent configuration ──────────────────────────────────────────────
|
|
211
|
+
if (-not $SkipConfig) {
|
|
212
|
+
Configure-Agents -Dir $targetDir
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
# ── Done ─────────────────────────────────────────────────────────────
|
|
216
|
+
Show-Success -Dir $targetDir
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
# ── PATH ─────────────────────────────────────────────────────────────────────
|
|
220
|
+
function Add-ToUserPath {
|
|
221
|
+
param([string]$Dir)
|
|
222
|
+
|
|
223
|
+
$currentPath = [Environment]::GetEnvironmentVariable("PATH", "User")
|
|
224
|
+
if ($currentPath -and $currentPath.Split(';') -contains $Dir) {
|
|
225
|
+
Write-Ok "Install directory already in PATH"
|
|
226
|
+
return
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
$newPath = if ($currentPath) { "$currentPath;$Dir" } else { $Dir }
|
|
231
|
+
[Environment]::SetEnvironmentVariable("PATH", $newPath, "User")
|
|
232
|
+
# Also update current session
|
|
233
|
+
$env:PATH = "$env:PATH;$Dir"
|
|
234
|
+
Write-Ok "Added to user PATH: $Dir"
|
|
235
|
+
Write-Warn "Restart your terminal for PATH changes to take effect."
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
Write-Warn "Could not update PATH automatically."
|
|
239
|
+
Write-Warn "Manually add this directory to your PATH: $Dir"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
# ── Agent Auto-Configuration ────────────────────────────────────────────────
|
|
244
|
+
function Configure-Agents {
|
|
245
|
+
param([string]$Dir)
|
|
246
|
+
|
|
247
|
+
Write-Host "`n Detecting AI agents..." -ForegroundColor White
|
|
248
|
+
|
|
249
|
+
$agents = @()
|
|
250
|
+
|
|
251
|
+
# Claude Desktop / Claude Code
|
|
252
|
+
$claudeConfig = Join-Path $env:APPDATA "Claude\claude_desktop_config.json"
|
|
253
|
+
if (Test-Path $claudeConfig) { $agents += "Claude Desktop" }
|
|
254
|
+
$claudeCodeDir = Join-Path $env:USERPROFILE ".claude"
|
|
255
|
+
if (Test-Path $claudeCodeDir) { $agents += "Claude Code" }
|
|
256
|
+
|
|
257
|
+
# Cursor
|
|
258
|
+
$cursorDir = Join-Path $env:USERPROFILE ".cursor"
|
|
259
|
+
if (Test-Path $cursorDir) { $agents += "Cursor" }
|
|
260
|
+
|
|
261
|
+
# VS Code
|
|
262
|
+
$vscodeDir = Join-Path $env:APPDATA "Code\User"
|
|
263
|
+
if (Test-Path $vscodeDir) { $agents += "VS Code" }
|
|
264
|
+
|
|
265
|
+
# Windsurf / Codeium
|
|
266
|
+
$windsurfDir = Join-Path $env:APPDATA "Windsurf"
|
|
267
|
+
if (Test-Path $windsurfDir) { $agents += "Windsurf" }
|
|
268
|
+
|
|
269
|
+
if ($agents.Count -eq 0) {
|
|
270
|
+
Write-Warn "No AI agents detected. See README for manual setup."
|
|
271
|
+
return
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
Write-Ok "Detected: $($agents -join ', ')"
|
|
275
|
+
Write-Host ""
|
|
276
|
+
Write-Host " To configure an agent, add this to its MCP config:" -ForegroundColor White
|
|
277
|
+
$escapedDir = ($Dir -replace '\\', '\\')
|
|
278
|
+
Write-Host @"
|
|
279
|
+
|
|
280
|
+
{
|
|
281
|
+
"mcpServers": {
|
|
282
|
+
"ai-mind-map": {
|
|
283
|
+
"command": "node",
|
|
284
|
+
"args": [
|
|
285
|
+
"$escapedDir\\dist\\index.js",
|
|
286
|
+
"--project-root",
|
|
287
|
+
"<YOUR_PROJECT_PATH>"
|
|
288
|
+
]
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
"@ -ForegroundColor Gray
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
# ── Success ──────────────────────────────────────────────────────────────────
|
|
297
|
+
function Show-Success {
|
|
298
|
+
param([string]$Dir)
|
|
299
|
+
|
|
300
|
+
$divider = "─" * 60
|
|
301
|
+
Write-Host ""
|
|
302
|
+
Write-Host " $divider" -ForegroundColor Green
|
|
303
|
+
Write-Host " ✅ AI Mind Map installed successfully!" -ForegroundColor Green
|
|
304
|
+
Write-Host " $divider" -ForegroundColor Green
|
|
305
|
+
Write-Host ""
|
|
306
|
+
Write-Host " Location: $Dir" -ForegroundColor White
|
|
307
|
+
Write-Host ""
|
|
308
|
+
Write-Host " Next steps:" -ForegroundColor White
|
|
309
|
+
Write-Host " 1. Configure your AI agent (see above or README)" -ForegroundColor Gray
|
|
310
|
+
Write-Host " 2. Test with: node `"$Dir\$ENTRY_POINT`" --project-root ." -ForegroundColor Gray
|
|
311
|
+
Write-Host " 3. Star the repo: https://github.com/shdra06/ai-mind-map" -ForegroundColor Gray
|
|
312
|
+
Write-Host ""
|
|
313
|
+
Write-Host " To update later: .\install.ps1 -Update" -ForegroundColor Yellow
|
|
314
|
+
Write-Host " Full docs: https://github.com/shdra06/ai-mind-map#readme" -ForegroundColor Yellow
|
|
315
|
+
Write-Host ""
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
# ── Main ─────────────────────────────────────────────────────────────────────
|
|
319
|
+
Show-Banner
|
|
320
|
+
Assert-Prerequisites
|
|
321
|
+
Install-AiMindMap
|