@opensassi/opencode 0.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.
Files changed (46) hide show
  1. package/AGENTS.md +35 -0
  2. package/README.md +81 -0
  3. package/bin/opencode.js +3 -0
  4. package/lib/cli.js +38 -0
  5. package/lib/commands/init.js +117 -0
  6. package/lib/commands/print-agents.js +6 -0
  7. package/lib/commands/print-skill.js +8 -0
  8. package/lib/commands/run.js +57 -0
  9. package/lib/index.js +4 -0
  10. package/lib/util/paths.js +21 -0
  11. package/package.json +40 -0
  12. package/scripts/asm-optimizer/run-baseline.sh +158 -0
  13. package/scripts/check-artifacts.js +131 -0
  14. package/scripts/extract-artifacts.js +204 -0
  15. package/scripts/install/linux/ubuntu-noble-24.04/install.sh +94 -0
  16. package/scripts/install/osx/macos-sequoia-15.0/install.sh +115 -0
  17. package/scripts/install/windows/wsl2/install.ps1 +98 -0
  18. package/scripts/install.ps1 +32 -0
  19. package/scripts/install.sh +83 -0
  20. package/scripts/puppeteer-config.json +3 -0
  21. package/scripts/test-artifacts.js +346 -0
  22. package/scripts/validate-all.js +18 -0
  23. package/scripts/verify-artifact.js +157 -0
  24. package/skills/asm-optimizer/SKILL.md +295 -0
  25. package/skills/daily-evaluation/SKILL.md +86 -0
  26. package/skills/git/SKILL.md +100 -0
  27. package/skills/issue/SKILL.md +104 -0
  28. package/skills/npm-optimizer/SKILL.md +218 -0
  29. package/skills/opensassi/SKILL.md +77 -0
  30. package/skills/opensassi/scripts/ensure-gitignore.sh +89 -0
  31. package/skills/opensassi/scripts/env-check.ps1 +139 -0
  32. package/skills/opensassi/scripts/env-check.sh +200 -0
  33. package/skills/opensassi/scripts/install-flamegraph.sh +32 -0
  34. package/skills/opensassi/scripts/install-npm-deps.sh +25 -0
  35. package/skills/profiler/SKILL.md +213 -0
  36. package/skills/profiler/scripts/benchmark.sh +63 -0
  37. package/skills/profiler/scripts/common.sh +55 -0
  38. package/skills/profiler/scripts/compare.sh +63 -0
  39. package/skills/profiler/scripts/profile.sh +63 -0
  40. package/skills/profiler/scripts/setup.sh +32 -0
  41. package/skills/session-evaluation/SKILL.md +128 -0
  42. package/skills/skill-manager/SKILL.md +251 -0
  43. package/skills/system-design/SKILL.md +558 -0
  44. package/skills/system-design-review/SKILL.md +396 -0
  45. package/skills/todo/SKILL.md +165 -0
  46. package/skills-index.json +137 -0
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env node
2
+ import { fileURLToPath } from 'url';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+
6
+ const __dirname = fileURLToPath(new URL('.', import.meta.url));
7
+ const ROOT = path.resolve(__dirname, '..');
8
+
9
+ function getReviewPath(specPath) {
10
+ const rel = path.relative(ROOT, specPath);
11
+ const dir = path.dirname(rel);
12
+ const basename = path.basename(rel);
13
+
14
+ if (rel === 'technical-specification.md') {
15
+ return path.join(ROOT, '.artifacts', 'review.md');
16
+ }
17
+
18
+ return path.join(ROOT, dir, '.artifacts', basename, 'review.md');
19
+ }
20
+
21
+ function getReviewStatus(specPath) {
22
+ const reviewPath = getReviewPath(specPath);
23
+
24
+ if (!fs.existsSync(reviewPath)) return { reviewFile: null, reviewMtime: null, reviewStatus: "MISSING" };
25
+
26
+ const reviewMtime = fs.statSync(reviewPath).mtimeMs;
27
+ const specMtime = fs.statSync(specPath).mtimeMs;
28
+ const status = reviewMtime < specMtime ? "STALE" : "OK";
29
+
30
+ return {
31
+ reviewFile: path.relative(ROOT, reviewPath),
32
+ reviewMtime: Math.floor(reviewMtime),
33
+ reviewStatus: status,
34
+ };
35
+ }
36
+
37
+ function getAllSpecFiles() {
38
+ const files = [];
39
+
40
+ const rootSpec = path.join(ROOT, 'technical-specification.md');
41
+ if (fs.existsSync(rootSpec)) files.push(rootSpec);
42
+
43
+ const srcDir = path.join(ROOT, 'src');
44
+ if (!fs.existsSync(srcDir)) return files;
45
+
46
+ for (const entry of fs.readdirSync(srcDir)) {
47
+ const moduleDir = path.join(srcDir, entry);
48
+ if (!fs.statSync(moduleDir).isDirectory()) continue;
49
+
50
+ for (const file of fs.readdirSync(moduleDir)) {
51
+ if (file.endsWith('.spec.md')) {
52
+ files.push(path.join(moduleDir, file));
53
+ }
54
+ }
55
+ }
56
+
57
+ return files;
58
+ }
59
+
60
+ function getModuleSpecFiles(name) {
61
+ const moduleDir = path.join(ROOT, 'src', name);
62
+ if (!fs.existsSync(moduleDir) || !fs.statSync(moduleDir).isDirectory()) {
63
+ console.error(`ERROR: No such module: "${name}" (not found at src/${name}/)`);
64
+ process.exit(1);
65
+ }
66
+
67
+ const files = [];
68
+ for (const file of fs.readdirSync(moduleDir)) {
69
+ if (file.endsWith('.spec.md')) {
70
+ files.push(path.join(moduleDir, file));
71
+ }
72
+ }
73
+
74
+ return files;
75
+ }
76
+
77
+ function main() {
78
+ const args = process.argv.slice(2);
79
+ const issuesOnly = args.includes('--errors');
80
+ const subModuleIdx = args.indexOf('--sub-module');
81
+ const fileIdx = args.indexOf('--file');
82
+
83
+ let specFiles;
84
+
85
+ if (subModuleIdx !== -1) {
86
+ const moduleName = args[subModuleIdx + 1];
87
+ if (!moduleName) {
88
+ console.error('Usage: node scripts/check-artifacts.js --sub-module <name>');
89
+ process.exit(1);
90
+ }
91
+ specFiles = getModuleSpecFiles(moduleName);
92
+ } else if (fileIdx !== -1) {
93
+ const filePath = args[fileIdx + 1];
94
+ if (!filePath) {
95
+ console.error('Usage: node scripts/check-artifacts.js --file <path>');
96
+ process.exit(1);
97
+ }
98
+ const resolvedPath = path.resolve(process.cwd(), filePath);
99
+ if (!fs.existsSync(resolvedPath)) {
100
+ console.error(`ERROR: File not found: ${filePath}`);
101
+ process.exit(1);
102
+ }
103
+ if (!resolvedPath.endsWith('.spec.md')) {
104
+ console.error(`ERROR: Not a .spec.md file: ${filePath}`);
105
+ process.exit(1);
106
+ }
107
+ specFiles = [resolvedPath];
108
+ } else {
109
+ specFiles = getAllSpecFiles();
110
+ }
111
+
112
+ const results = specFiles.map(specPath => {
113
+ const relSpecPath = path.relative(ROOT, specPath);
114
+ const specMtime = fs.statSync(specPath).mtimeMs;
115
+ const review = getReviewStatus(specPath);
116
+
117
+ return {
118
+ specFile: relSpecPath,
119
+ specMtime: Math.floor(specMtime),
120
+ reviewFile: review.reviewFile,
121
+ reviewMtime: review.reviewMtime,
122
+ reviewStatus: review.reviewStatus,
123
+ };
124
+ });
125
+
126
+ const output = issuesOnly ? results.filter(r => r.reviewStatus !== "OK") : results;
127
+
128
+ console.log(JSON.stringify(output, null, 2));
129
+ }
130
+
131
+ main();
@@ -0,0 +1,204 @@
1
+ #!/usr/bin/env node
2
+ import { fileURLToPath } from 'url';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+
6
+ const __dirname = fileURLToPath(new URL('.', import.meta.url));
7
+ const ROOT = path.resolve(__dirname, '..');
8
+ const SPEC_FILE = 'technical-specification.md';
9
+
10
+ function parseModuleReference() {
11
+ const content = fs.readFileSync(path.join(ROOT, SPEC_FILE), 'utf-8');
12
+ const lines = content.split('\n');
13
+
14
+ let inTable = false;
15
+ const rows = [];
16
+
17
+ for (const line of lines) {
18
+ const trimmed = line.trim();
19
+ if (!trimmed.startsWith('|') || !trimmed.endsWith('|')) {
20
+ if (inTable) break;
21
+ continue;
22
+ }
23
+
24
+ const cells = trimmed.split('|').map(c => c.trim()).filter(c => c.length > 0);
25
+
26
+ if (!inTable) {
27
+ inTable = true;
28
+ continue;
29
+ }
30
+
31
+ if (cells.every(c => /^[-:` ]+$/.test(c))) continue;
32
+
33
+ rows.push(cells);
34
+ }
35
+
36
+ const modules = {};
37
+ for (const row of rows) {
38
+ if (row.length < 4) continue;
39
+ const name = row[0];
40
+ const dir = row[1].replace(/`/g, '').trim();
41
+ const specRaw = row[3];
42
+
43
+ if (dir === '—' || dir === '-') continue;
44
+
45
+ const specFiles = specRaw
46
+ .split(',')
47
+ .map(s => {
48
+ const cleaned = s.replace(/`/g, '').trim();
49
+ const parenIdx = cleaned.indexOf('(');
50
+ return parenIdx !== -1 ? cleaned.substring(0, parenIdx).trim() : cleaned;
51
+ })
52
+ .filter(s => s.endsWith('.spec.md') && s.length > 0);
53
+
54
+ modules[name.toLowerCase()] = { name, dir, specFiles };
55
+ }
56
+
57
+ return modules;
58
+ }
59
+
60
+ function extractCodeBlocks(content) {
61
+ const blocks = [];
62
+ const regex = /```(mermaid|html)\s*\n([\s\S]*?)```/g;
63
+ let match;
64
+ while ((match = regex.exec(content)) !== null) {
65
+ const code = match[2].trim();
66
+ if (code.length > 0) {
67
+ blocks.push({ lang: match[1], code });
68
+ }
69
+ }
70
+ return blocks;
71
+ }
72
+
73
+ function getDiagramName(code, lang, index) {
74
+ if (lang === 'html') return 'd3-animation.html';
75
+ const firstLine = code.trim().split('\n')[0].trim();
76
+ if (/^graph\s+(TB|LR|RL|BT|TD)/.test(firstLine)) return 'architecture.mmd';
77
+ if (/^sequenceDiagram/.test(firstLine)) return 'sequence.mmd';
78
+ return `diagram-${index + 1}.mmd`;
79
+ }
80
+
81
+ function processSpecFile(specPath, outputDir, extraFiles) {
82
+ const content = fs.readFileSync(specPath, 'utf-8');
83
+ const blocks = extractCodeBlocks(content);
84
+
85
+ const specName = path.basename(specPath);
86
+ const specOutputDir = path.join(outputDir, specName);
87
+ fs.mkdirSync(specOutputDir, { recursive: true });
88
+
89
+ const usedNames = new Set();
90
+ for (let i = 0; i < blocks.length; i++) {
91
+ const { lang, code } = blocks[i];
92
+ let filename = getDiagramName(code, lang, i);
93
+ if (usedNames.has(filename)) {
94
+ const base = filename.replace(/\.(mmd|html)$/, '');
95
+ const ext = filename.match(/\.(mmd|html)$/)[0];
96
+ let counter = 2;
97
+ while (usedNames.has(`${base}-${counter}${ext}`)) counter++;
98
+ filename = `${base}-${counter}${ext}`;
99
+ }
100
+ usedNames.add(filename);
101
+ fs.writeFileSync(path.join(specOutputDir, filename), code + '\n');
102
+ console.log(` extracted ${specName}/${filename}`);
103
+ }
104
+
105
+ if (extraFiles) {
106
+ for (const { src, dest } of extraFiles) {
107
+ if (fs.existsSync(src)) {
108
+ fs.copyFileSync(src, path.join(specOutputDir, dest));
109
+ console.log(` copied ${dest} from project root`);
110
+ }
111
+ }
112
+ }
113
+
114
+ const hasMermaid = blocks.some(b => b.lang === 'mermaid');
115
+ if (blocks.length === 0 && !extraFiles?.some(e => fs.existsSync(e.src))) {
116
+ console.error(`ERROR: No artifacts found in ${specPath}`);
117
+ console.error(`HINT: Run system-design skill to regenerate spec with diagrams.`);
118
+ process.exit(1);
119
+ }
120
+ if (!hasMermaid && blocks.length > 0) {
121
+ console.log(` (no mermaid diagrams in this spec file — HTML only)`);
122
+ }
123
+ }
124
+
125
+ function processSubModule(mod) {
126
+ const outputDir = path.join(ROOT, mod.dir, '.artifacts');
127
+ fs.mkdirSync(outputDir, { recursive: true });
128
+ console.log(`\nProcessing ${mod.name} module → ${path.join(mod.dir, '.artifacts/')}`);
129
+ for (const specFile of mod.specFiles) {
130
+ const specPath = path.join(ROOT, mod.dir, specFile);
131
+ if (fs.existsSync(specPath)) {
132
+ processSpecFile(specPath, outputDir);
133
+ } else {
134
+ console.error(` WARNING: ${path.join(mod.dir, specFile)} not found, skipping`);
135
+ }
136
+ }
137
+ }
138
+
139
+ function main() {
140
+ const args = process.argv.slice(2);
141
+ const subModuleIdx = args.indexOf('--sub-module');
142
+ const allFlag = args.includes('--all');
143
+ const fileIdx = args.indexOf('--file');
144
+
145
+ if (fileIdx !== -1) {
146
+ const filePath = args[fileIdx + 1];
147
+ if (!filePath) {
148
+ console.error('Usage: node scripts/extract-artifacts.js --file <relative-path>');
149
+ process.exit(1);
150
+ }
151
+ const absPath = path.resolve(ROOT, filePath);
152
+ if (!fs.existsSync(absPath)) {
153
+ console.error(`ERROR: File not found: ${absPath}`);
154
+ process.exit(1);
155
+ }
156
+ const outputDir = path.join(path.dirname(absPath), '.artifacts');
157
+ fs.mkdirSync(outputDir, { recursive: true });
158
+ console.log(`Processing ${filePath} → ${path.join(path.dirname(filePath), '.artifacts/')}`);
159
+ processSpecFile(absPath, outputDir);
160
+ console.log('\nDone. Run `npm run test-artifacts` to validate.');
161
+ return;
162
+ }
163
+
164
+ const modules = parseModuleReference();
165
+
166
+ if (subModuleIdx !== -1) {
167
+ const moduleName = args[subModuleIdx + 1];
168
+ if (!moduleName) {
169
+ console.error('Usage: node scripts/extract-artifacts.js --sub-module <name>');
170
+ console.error(`Available modules: ${Object.keys(modules).join(', ')}`);
171
+ process.exit(1);
172
+ }
173
+ const mod = modules[moduleName.toLowerCase()];
174
+ if (!mod) {
175
+ console.error(`Unknown sub-module: "${moduleName}". Available: ${Object.keys(modules).join(', ')}`);
176
+ process.exit(1);
177
+ }
178
+ processSubModule(mod);
179
+ return;
180
+ }
181
+
182
+ if (allFlag) {
183
+ console.log(`Processing ${SPEC_FILE} → .artifacts/`);
184
+ const rootD3 = path.join(ROOT, 'd3-animation.html');
185
+ const rootExtra = fs.existsSync(rootD3) ? [{ src: rootD3, dest: 'd3-animation.html' }] : [];
186
+ processSpecFile(path.join(ROOT, SPEC_FILE), path.join(ROOT, '.artifacts'), rootExtra);
187
+ console.log('Extracting artifacts from all modules...');
188
+ for (const mod of Object.values(modules)) {
189
+ processSubModule(mod);
190
+ }
191
+ console.log('\nDone. Run `npm run test-artifacts` to validate.');
192
+ return;
193
+ }
194
+
195
+ const outputDir = path.join(ROOT, '.artifacts');
196
+ fs.mkdirSync(outputDir, { recursive: true });
197
+ console.log(`Processing ${SPEC_FILE} → .artifacts/`);
198
+ const rootD3 = path.join(ROOT, 'd3-animation.html');
199
+ const extraFiles = fs.existsSync(rootD3) ? [{ src: rootD3, dest: 'd3-animation.html' }] : [];
200
+ processSpecFile(path.join(ROOT, SPEC_FILE), outputDir, extraFiles);
201
+ console.log('\nDone. Run `npm run test-artifacts` to validate.');
202
+ }
203
+
204
+ main();
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Ubuntu 24.04.2 LTS (noble) — full development environment for opencode projects
5
+ # Usage: bash scripts/install/linux/ubuntu-noble-24.04/install.sh
6
+ UBUNTU_CODENAME="$(lsb_release -c -s 2>/dev/null || echo 'noble')"
7
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
9
+
10
+ PACKAGES=(
11
+ # ---- Build toolchain ----
12
+ build-essential
13
+ cmake
14
+ nasm
15
+ git
16
+
17
+ # ---- Artifact pipeline ----
18
+ nodejs
19
+ npm
20
+
21
+ # ---- Code search & navigation ----
22
+ ripgrep
23
+ fd-find
24
+ bat
25
+ fzf
26
+
27
+ # ---- System monitoring ----
28
+ htop
29
+ duf
30
+
31
+ # ---- Performance & benchmarking ----
32
+ hyperfine
33
+ linux-tools-common
34
+ linux-tools-generic
35
+
36
+ # ---- Network tools ----
37
+ httpie
38
+ whois
39
+ net-tools
40
+ dnsutils
41
+ traceroute
42
+ nmap
43
+ mtr
44
+
45
+ # ---- Development utilities ----
46
+ tmux
47
+ parallel
48
+ pv
49
+ entr
50
+ tree
51
+ strace
52
+ ltrace
53
+ jq
54
+ zip
55
+ unzip
56
+ pigz
57
+ rsync
58
+ curl
59
+ wget
60
+ ssh
61
+
62
+ # ---- Debugging ----
63
+ gdb
64
+ python3-pip
65
+ )
66
+
67
+ echo "==> opencode: installing ${#PACKAGES[@]} packages for Ubuntu $UBUNTU_CODENAME..."
68
+
69
+ sudo apt update
70
+ sudo apt install -y "${PACKAGES[@]}"
71
+
72
+ echo "==> Installing gdb-mcp-server (structured GDB interface for agents)..."
73
+ pip3 install gdb-mcp-server
74
+
75
+ if [ -f "$REPO_ROOT/package.json" ]; then
76
+ echo "==> Installing npm dependencies..."
77
+ cd "$REPO_ROOT" && npm install
78
+ fi
79
+
80
+ echo ""
81
+ echo "=============================="
82
+ echo " Toolchain Verification"
83
+ echo "=============================="
84
+ printf "%-20s %s\n" "g++" "$(g++ --version | head -1)"
85
+ printf "%-20s %s\n" "cmake" "$(cmake --version | head -1)"
86
+ printf "%-20s %s\n" "nasm" "$(nasm --version | head -1)"
87
+ printf "%-20s %s\n" "node" "$(node --version)"
88
+ printf "%-20s %s\n" "perf" "$(perf --version | head -1)"
89
+ printf "%-20s %s\n" "gdb" "$(gdb --version | head -1)"
90
+ printf "%-20s %s\n" "rg" "$(rg --version | head -1)"
91
+ printf "%-20s %s\n" "gdb-mcp" "$(pip3 show gdb-mcp-server 2>/dev/null | grep Version || echo 'not found')"
92
+ echo ""
93
+ echo "Installation complete."
94
+ echo "Run 'gh auth login' for GitHub CLI (issue management)."
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # macOS — full development environment for opencode projects
5
+ # Usage: bash scripts/install/osx/macos-sequoia-15.0/install.sh
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
9
+
10
+ # ---- Version detection ----
11
+ OS_NAME="macos"
12
+ OS_VERSION=$(sw_vers -productVersion 2>/dev/null || echo "0.0")
13
+
14
+ # Codename lookup (newest → oldest)
15
+ if [[ $OS_VERSION == 15.* ]]; then OS_CODENAME="sequoia"
16
+ elif [[ $OS_VERSION == 14.* ]]; then OS_CODENAME="sonoma"
17
+ elif [[ $OS_VERSION == 13.* ]]; then OS_CODENAME="ventura"
18
+ elif [[ $OS_VERSION == 12.* ]]; then OS_CODENAME="monterey"
19
+ elif [[ $OS_VERSION == 11.* ]]; then OS_CODENAME="big-sur"
20
+ else OS_CODENAME="unknown"
21
+ fi
22
+
23
+ echo "==> opencode: installing for macOS ${OS_VERSION} (${OS_CODENAME})..."
24
+
25
+ # ---- 1. Xcode Command Line Tools ----
26
+ if ! xcode-select -p &>/dev/null; then
27
+ echo "==> Installing Xcode Command Line Tools..."
28
+ xcode-select --install
29
+ echo " Please complete the installation dialog, then re-run this script."
30
+ exit 0
31
+ fi
32
+ echo " ✓ Xcode Command Line Tools found"
33
+
34
+ # ---- 2. Homebrew ----
35
+ if ! command -v brew &>/dev/null; then
36
+ echo "==> Installing Homebrew..."
37
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
38
+ fi
39
+ echo " ✓ Homebrew found"
40
+
41
+ # ---- 3. Install packages ----
42
+ BREW_PACKAGES=(
43
+ # Build toolchain
44
+ cmake
45
+ nasm
46
+ git
47
+ node
48
+
49
+ # Code search & navigation
50
+ ripgrep
51
+ fd
52
+ bat
53
+ fzf
54
+
55
+ # System monitoring
56
+ htop
57
+ duf
58
+
59
+ # Performance & benchmarking
60
+ hyperfine
61
+
62
+ # Network tools
63
+ httpie
64
+ whois
65
+ nmap
66
+ mtr
67
+
68
+ # Development utilities
69
+ tmux
70
+ parallel
71
+ pv
72
+ entr
73
+ tree
74
+ jq
75
+ pigz
76
+ wget
77
+
78
+ # Debugging
79
+ python
80
+ )
81
+
82
+ echo "==> Installing ${#BREW_PACKAGES[@]} Homebrew packages..."
83
+ brew install "${BREW_PACKAGES[@]}"
84
+
85
+ # ---- 4. Python + GDB MCP ----
86
+ echo "==> Installing gdb-mcp-server..."
87
+ pip3 install gdb-mcp-server
88
+
89
+ # ---- 5. npm ----
90
+ if [ -f "$REPO_ROOT/package.json" ]; then
91
+ echo "==> Installing npm dependencies..."
92
+ cd "$REPO_ROOT" && npm install
93
+ fi
94
+
95
+ # ---- 6. Verification ----
96
+ echo ""
97
+ echo "=============================="
98
+ echo " Toolchain Verification"
99
+ echo "=============================="
100
+ printf "%-20s %s\n" "clang++" "$(clang++ --version | head -1)"
101
+ printf "%-20s %s\n" "cmake" "$(cmake --version | head -1)"
102
+ printf "%-20s %s\n" "nasm" "$(nasm --version | head -1)"
103
+ printf "%-20s %s\n" "node" "$(node --version)"
104
+ printf "%-20s %s\n" "lldb" "$(lldb --version | head -1)"
105
+ printf "%-20s %s\n" "rg" "$(rg --version | head -1)"
106
+ printf "%-20s %s\n" "gdb-mcp" "$(pip3 show gdb-mcp-server 2>/dev/null | grep Version || echo 'not found')"
107
+ echo ""
108
+ echo "Installation complete."
109
+ echo ""
110
+ echo "Notes:"
111
+ echo " - perf/strace/ltrace are Linux-specific and not available on macOS."
112
+ echo " - Use Xcode Instruments.app for profiling."
113
+ echo " - Use lldb for debugging (Xcode CLT provides it)."
114
+ echo " - Run 'gh auth login' for GitHub CLI (issue management)."
115
+ echo ""
@@ -0,0 +1,98 @@
1
+ #Requires -RunAsAdministrator
2
+
3
+ # WSL2 — full development environment for opencode projects
4
+ # Usage (as Administrator):
5
+ # powershell -ExecutionPolicy Bypass -File scripts\install\windows\wsl2\install.ps1
6
+
7
+ $ErrorActionPreference = "Stop"
8
+ $SCRIPT_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path
9
+ $REPO_ROOT = Resolve-Path "$SCRIPT_DIR\..\..\..\.."
10
+
11
+ Write-Host "==> opencode: installing for Windows (WSL2)..."
12
+
13
+ # ---- 1. Check if WSL feature is enabled ----
14
+ $wslFeature = Get-WindowsOptionalFeature -Online -FeatureName "Microsoft-Windows-Subsystem-Linux"
15
+ $vmpFeature = Get-WindowsOptionalFeature -Online -FeatureName "VirtualMachinePlatform"
16
+
17
+ if ($wslFeature.State -ne "Enabled" -or $vmpFeature.State -ne "Enabled") {
18
+ Write-Host "==> Enabling WSL and Virtual Machine Platform..."
19
+ Enable-WindowsOptionalFeature -Online -FeatureName "Microsoft-Windows-Subsystem-Linux" -NoRestart
20
+ Enable-WindowsOptionalFeature -Online -FeatureName "VirtualMachinePlatform" -NoRestart
21
+ Write-Host ""
22
+ Write-Host "WARNING: A system reboot is required before continuing."
23
+ Write-Host "After rebooting, run this script again to complete setup."
24
+ Write-Host ""
25
+ pause
26
+ exit
27
+ }
28
+ Write-Host " ✓ WSL feature is enabled"
29
+
30
+ # ---- 2. Install/update WSL2 kernel ----
31
+ Write-Host "==> Updating WSL2 kernel..."
32
+ wsl --update
33
+
34
+ # ---- 3. Set WSL2 as default ----
35
+ Write-Host "==> Setting WSL2 as default..."
36
+ wsl --set-default-version 2
37
+
38
+ # ---- 4. Install Ubuntu distro if not present ----
39
+ $distros = wsl --list --quiet
40
+ if ($distros -notcontains "Ubuntu") {
41
+ Write-Host "==> Installing Ubuntu distribution..."
42
+ wsl --install -d Ubuntu
43
+ Write-Host ""
44
+ Write-Host "Ubuntu installed. It will start automatically to complete setup."
45
+ Write-Host "Create a Linux username/password when prompted, then re-run this script."
46
+ Write-Host ""
47
+ pause
48
+ exit
49
+ }
50
+ Write-Host " ✓ Ubuntu distribution found"
51
+
52
+ # ---- 5. Set up the repo inside WSL ----
53
+ $WSL_HOME = "~"
54
+ $WSL_REPO_DIR = Split-Path -Leaf $REPO_ROOT
55
+
56
+ # Check if the repo already exists in WSL
57
+ $repoExists = wsl -d Ubuntu -e bash -c "test -d $WSL_HOME/$WSL_REPO_DIR && echo 'exists' || echo ''"
58
+ if (-not $repoExists) {
59
+ # Check if we're inside a git repo (clone scenario)
60
+ if (Test-Path "$REPO_ROOT\.git") {
61
+ $repoUrl = (git -C $REPO_ROOT remote get-url origin 2>$null)
62
+ if ($repoUrl) {
63
+ Write-Host "==> Cloning existing repository inside WSL..."
64
+ wsl -d Ubuntu -e bash -c "cd $WSL_HOME && git clone $repoUrl $WSL_REPO_DIR"
65
+ } else {
66
+ Write-Host "==> Copying files to WSL (no remote origin)..."
67
+ wsl -d Ubuntu -e bash -c "mkdir -p $WSL_HOME/$WSL_REPO_DIR"
68
+ # Copy files from current directory into WSL (excluding node_modules, .git, etc.)
69
+ wsl -d Ubuntu -e bash -c "rsync -a --exclude='node_modules' --exclude='.git' '$REPO_ROOT/' '$WSL_HOME/$WSL_REPO_DIR/'"
70
+ }
71
+ } else {
72
+ # Starter scenario — create directory structure
73
+ Write-Host "==> Creating project structure inside WSL..."
74
+ wsl -d Ubuntu -e bash -c "mkdir -p $WSL_HOME/$WSL_REPO_DIR"
75
+ if (Test-Path $REPO_ROOT) {
76
+ wsl -d Ubuntu -e bash -c "rsync -a '$REPO_ROOT/' '$WSL_HOME/$WSL_REPO_DIR/'"
77
+ }
78
+ }
79
+ }
80
+ Write-Host " ✓ Repository set up at ~/$WSL_REPO_DIR inside WSL"
81
+
82
+ # ---- 6. Run the Ubuntu install script inside WSL ----
83
+ Write-Host "==> Running Ubuntu install script inside WSL..."
84
+ wsl -d Ubuntu -e bash -c "
85
+ cd ~/$WSL_REPO_DIR
86
+ bash scripts/install/linux/ubuntu-noble-24.04/install.sh
87
+ "
88
+
89
+ # ---- 7. Done ----
90
+ Write-Host ""
91
+ Write-Host "=============================="
92
+ Write-Host " WSL2 Setup Complete"
93
+ Write-Host "=============================="
94
+ Write-Host " Enter WSL: wsl -d Ubuntu"
95
+ Write-Host " Project path: ~/$WSL_REPO_DIR"
96
+ Write-Host ""
97
+ Write-Host " Run 'gh auth login' inside WSL for GitHub CLI access."
98
+ Write-Host ""
@@ -0,0 +1,32 @@
1
+ #Requires -RunAsAdministrator
2
+
3
+ # deepenc environment installer — Windows detection and dispatch
4
+ # Usage (as Administrator):
5
+ # powershell -ExecutionPolicy Bypass -File scripts\install.ps1
6
+
7
+ $ErrorActionPreference = "Stop"
8
+ $SCRIPT_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path
9
+
10
+ Write-Host "==> deepenc: detected Windows"
11
+
12
+ # Check if WSL is available
13
+ $wslFeature = Get-WindowsOptionalFeature -Online -FeatureName "Microsoft-Windows-Subsystem-Linux" -ErrorAction SilentlyContinue
14
+ $hasWsl = ($wslFeature -and $wslFeature.State -eq "Enabled")
15
+
16
+ if (-not $hasWsl) {
17
+ Write-Host "==> WSL is not installed. Running WSL2 installer..."
18
+ & "$SCRIPT_DIR\install\windows\wsl2\install.ps1"
19
+ } else {
20
+ # WSL is already enabled — check if Ubuntu distro exists
21
+ $distros = wsl --list --quiet 2>$null
22
+ if ($distros -contains "Ubuntu") {
23
+ Write-Host "==> WSL2 + Ubuntu detected. Running Ubuntu installer inside WSL..."
24
+ wsl -d Ubuntu -e bash -c "
25
+ cd ~/deepenc 2>/dev/null || mkdir -p ~/deepenc
26
+ bash scripts/install/linux/ubuntu-noble-24.04/install.sh
27
+ "
28
+ } else {
29
+ Write-Host "==> WSL enabled but Ubuntu not installed. Running WSL2 installer..."
30
+ & "$SCRIPT_DIR\install\windows\wsl2\install.ps1"
31
+ }
32
+ }