multimodel-dev-os 1.1.0 → 2.0.1
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/.ai/adapters/custom-adapter.example.yaml +9 -0
- package/.ai/adapters/registry.yaml +56 -0
- package/.ai/models/README.md +14 -0
- package/.ai/models/local-models.yaml +20 -0
- package/.ai/models/providers.yaml +29 -0
- package/.ai/models/registry.yaml +73 -0
- package/.ai/models/routing-presets.yaml +23 -0
- package/.ai/skills/custom-skill.example.md +15 -0
- package/.ai/templates/custom-template.example.yaml +19 -0
- package/.ai/templates/registry.yaml +522 -0
- package/README.md +30 -18
- package/bin/multimodel-dev-os.js +835 -92
- package/docs/.vitepress/config.js +36 -1
- package/docs/adapter-authoring.md +46 -0
- package/docs/agent-compatibility.md +51 -0
- package/docs/cli-roadmap.md +12 -23
- package/docs/faq.md +1 -1
- package/docs/final-launch.md +5 -4
- package/docs/index.md +5 -5
- package/docs/local-models.md +48 -0
- package/docs/mobile-android.md +75 -0
- package/docs/model-compatibility.md +65 -0
- package/docs/model-routing.md +45 -0
- package/docs/npm-publishing.md +38 -11
- package/docs/package-safety.md +29 -0
- package/docs/provider-strategy.md +44 -0
- package/docs/public/llms-full.txt +82 -73
- package/docs/public/llms.txt +36 -34
- package/docs/public/sitemap.xml +51 -1
- package/docs/quickstart.md +11 -18
- package/docs/registry-contribution.md +20 -0
- package/docs/release-policy.md +9 -0
- package/docs/skill-authoring.md +56 -0
- package/docs/template-authoring.md +65 -0
- package/docs/templates-guide.md +3 -3
- package/docs/token-optimization.md +27 -0
- package/docs/v2-migration.md +31 -0
- package/docs/v2-release-checklist.md +30 -0
- package/docs/v2-roadmap.md +95 -0
- package/examples/expo-react-native-android/.ai/config.yaml +22 -0
- package/examples/expo-react-native-android/.ai/context/architecture.md +18 -0
- package/examples/expo-react-native-android/.ai/context/context-budget.md +4 -0
- package/examples/expo-react-native-android/.ai/context/model-map.md +6 -0
- package/examples/expo-react-native-android/.ai/context/project-brief.md +9 -0
- package/examples/expo-react-native-android/.ai/session-logs/.gitkeep +1 -0
- package/examples/expo-react-native-android/.ai/skills/expo-android-build.md +11 -0
- package/examples/expo-react-native-android/AGENTS.md +20 -0
- package/examples/expo-react-native-android/MEMORY.md +13 -0
- package/examples/expo-react-native-android/README.md +101 -0
- package/examples/expo-react-native-android/RUNBOOK.md +36 -0
- package/examples/expo-react-native-android/TASKS.md +14 -0
- package/examples/expo-react-native-android/app.config.ts +40 -0
- package/examples/expo-react-native-android/app.json +34 -0
- package/examples/expo-react-native-android/eas.json +26 -0
- package/examples/expo-react-native-android/jest.config.js +11 -0
- package/examples/expo-react-native-android/src/app/_layout.tsx +89 -0
- package/examples/expo-react-native-android/src/lib/secure-storage.ts +63 -0
- package/examples/expo-react-native-android/src/services/api-client.ts +106 -0
- package/package.json +3 -2
- package/scripts/install.ps1 +230 -230
- package/scripts/install.sh +1 -1
- package/scripts/prepublish-guard.js +43 -0
- package/scripts/verify.js +178 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import Constants from 'expo-constants';
|
|
2
|
+
|
|
3
|
+
export interface ApiResponse<T> {
|
|
4
|
+
data: T | null;
|
|
5
|
+
error: string | null;
|
|
6
|
+
status: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class ApiClient {
|
|
10
|
+
private baseUrl: string;
|
|
11
|
+
private timeoutMs: number = 10000;
|
|
12
|
+
private maxRetries: number = 3;
|
|
13
|
+
private useMockData: boolean = false; // Toggle true for offline mock validations
|
|
14
|
+
|
|
15
|
+
constructor() {
|
|
16
|
+
// Dynamically retrieve base API URL configured in app.config.ts extras
|
|
17
|
+
const extra = Constants.expoConfig?.extra || {};
|
|
18
|
+
this.baseUrl = extra.apiUrl || 'http://10.0.2.2:3000/api';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async request<T>(path: string, options: RequestInit = {}): Promise<ApiResponse<T>> {
|
|
22
|
+
if (this.useMockData) {
|
|
23
|
+
// Mock response resolver
|
|
24
|
+
return new Promise((resolve) => {
|
|
25
|
+
setTimeout(() => {
|
|
26
|
+
resolve({
|
|
27
|
+
data: { message: "Mock Success data from ApiClient" } as unknown as T,
|
|
28
|
+
error: null,
|
|
29
|
+
status: 200
|
|
30
|
+
});
|
|
31
|
+
}, 500);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const url = `${this.baseUrl}${path}`;
|
|
36
|
+
const defaultHeaders = {
|
|
37
|
+
'Content-Type': 'application/json',
|
|
38
|
+
'Accept': 'application/json'
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
let attempt = 0;
|
|
42
|
+
while (attempt < this.maxRetries) {
|
|
43
|
+
attempt++;
|
|
44
|
+
const controller = new AbortController();
|
|
45
|
+
const id = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const response = await fetch(url, {
|
|
49
|
+
...options,
|
|
50
|
+
headers: {
|
|
51
|
+
...defaultHeaders,
|
|
52
|
+
...options.headers
|
|
53
|
+
},
|
|
54
|
+
signal: controller.signal
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
clearTimeout(id);
|
|
58
|
+
|
|
59
|
+
// Retry on Server Error (5xx)
|
|
60
|
+
if (response.status >= 500 && attempt < this.maxRetries) {
|
|
61
|
+
console.warn(`[ApiClient] Attempt ${attempt} failed with status ${response.status}. Retrying...`);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
return {
|
|
67
|
+
data: null,
|
|
68
|
+
error: `HTTP Error: ${response.status} ${response.statusText}`,
|
|
69
|
+
status: response.status
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const data = await response.json();
|
|
74
|
+
return {
|
|
75
|
+
data: data as T,
|
|
76
|
+
error: null,
|
|
77
|
+
status: response.status
|
|
78
|
+
};
|
|
79
|
+
} catch (e: any) {
|
|
80
|
+
clearTimeout(id);
|
|
81
|
+
const isTimeout = e.name === 'AbortError';
|
|
82
|
+
|
|
83
|
+
// Retry on timeout or transient network failures
|
|
84
|
+
if (attempt < this.maxRetries) {
|
|
85
|
+
console.warn(`[ApiClient] Attempt ${attempt} failed: ${e.message}. Retrying...`);
|
|
86
|
+
await new Promise((res) => setTimeout(res, 1000 * attempt)); // Exponential backoff
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
data: null,
|
|
92
|
+
error: isTimeout ? 'Request Timeout' : e.message || 'Unknown network error',
|
|
93
|
+
status: 0
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
data: null,
|
|
100
|
+
error: 'Max retries exceeded',
|
|
101
|
+
status: 0
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export const apiClient = new ApiClient();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "multimodel-dev-os",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"bin": {
|
|
5
5
|
"multimodel-dev-os": "bin/multimodel-dev-os.js"
|
|
6
6
|
},
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
"pack": "bash scripts/pack-template.sh",
|
|
46
46
|
"docs:dev": "vitepress dev docs",
|
|
47
47
|
"docs:build": "vitepress build docs",
|
|
48
|
-
"docs:preview": "vitepress preview docs"
|
|
48
|
+
"docs:preview": "vitepress preview docs",
|
|
49
|
+
"prepublishOnly": "node scripts/prepublish-guard.js"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"vitepress": "^1.6.4"
|
package/scripts/install.ps1
CHANGED
|
@@ -1,230 +1,230 @@
|
|
|
1
|
-
# multimodel-dev-os installer for Windows (PowerShell)
|
|
2
|
-
# Usage: irm https://raw.githubusercontent.com/rizvee/multimodel-dev-os/main/scripts/install.ps1 | iex
|
|
3
|
-
# Flags: -Caveman (use minimal-token templates)
|
|
4
|
-
# -All (install all adapters)
|
|
5
|
-
# -DryRun (show what would be created without creating)
|
|
6
|
-
|
|
7
|
-
param(
|
|
8
|
-
[switch]$Caveman,
|
|
9
|
-
[switch]$All,
|
|
10
|
-
[switch]$DryRun,
|
|
11
|
-
[switch]$Help
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
$Version = "0.
|
|
15
|
-
$RepoUrl = "https://raw.githubusercontent.com/rizvee/multimodel-dev-os/main"
|
|
16
|
-
|
|
17
|
-
if ($Help) {
|
|
18
|
-
Write-Host "multimodel-dev-os installer v$Version" -ForegroundColor Blue
|
|
19
|
-
Write-Host ""
|
|
20
|
-
Write-Host "Usage: irm .../install.ps1 | iex"
|
|
21
|
-
Write-Host ""
|
|
22
|
-
Write-Host "Options:"
|
|
23
|
-
Write-Host " -Caveman Use minimal-token templates (~79% fewer tokens)"
|
|
24
|
-
Write-Host " -All Install all adapters"
|
|
25
|
-
Write-Host " -DryRun Show what would be created without creating"
|
|
26
|
-
Write-Host " -Help Show this help message"
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
Write-Host "multimodel-dev-os installer v$Version" -ForegroundColor Blue
|
|
31
|
-
Write-Host ""
|
|
32
|
-
|
|
33
|
-
# --- Helper Functions ---
|
|
34
|
-
|
|
35
|
-
function New-ProjectFile {
|
|
36
|
-
param(
|
|
37
|
-
[string]$Path,
|
|
38
|
-
[string]$Url
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
if (Test-Path $Path) {
|
|
42
|
-
Write-Host " SKIP $Path (already exists)" -ForegroundColor Yellow
|
|
43
|
-
return
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if ($DryRun) {
|
|
47
|
-
Write-Host " WOULD CREATE $Path" -ForegroundColor Blue
|
|
48
|
-
return
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
$dir = Split-Path -Parent $Path
|
|
52
|
-
if ($dir -and !(Test-Path $dir)) {
|
|
53
|
-
New-Item -ItemType Directory -Path $dir -Force | Out-Null
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
Invoke-WebRequest -Uri $Url -OutFile $Path -UseBasicParsing -ErrorAction Stop
|
|
58
|
-
Write-Host " CREATE $Path" -ForegroundColor Green
|
|
59
|
-
}
|
|
60
|
-
catch {
|
|
61
|
-
Write-Host " FAIL $Path (download failed)" -ForegroundColor Red
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function New-ProjectDir {
|
|
66
|
-
param([string]$Path)
|
|
67
|
-
|
|
68
|
-
if (Test-Path $Path) {
|
|
69
|
-
Write-Host " SKIP $Path/ (already exists)" -ForegroundColor Yellow
|
|
70
|
-
return
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if ($DryRun) {
|
|
74
|
-
Write-Host " WOULD CREATE $Path/" -ForegroundColor Blue
|
|
75
|
-
return
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
New-Item -ItemType Directory -Path $Path -Force | Out-Null
|
|
79
|
-
Write-Host " CREATE $Path/" -ForegroundColor Green
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
# --- Phase 1: Core Files ---
|
|
83
|
-
|
|
84
|
-
Write-Host "Creating core files..." -ForegroundColor Blue
|
|
85
|
-
|
|
86
|
-
if ($Caveman) {
|
|
87
|
-
New-ProjectFile "AGENTS.md" "$RepoUrl/.ai/templates/AGENTS.caveman.md"
|
|
88
|
-
New-ProjectFile "MEMORY.md" "$RepoUrl/.ai/templates/MEMORY.caveman.md"
|
|
89
|
-
New-ProjectFile "TASKS.md" "$RepoUrl/.ai/templates/TASKS.caveman.md"
|
|
90
|
-
New-ProjectFile "RUNBOOK.md" "$RepoUrl/.ai/templates/RUNBOOK.caveman.md"
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
New-ProjectFile "AGENTS.md" "$RepoUrl/AGENTS.md"
|
|
94
|
-
New-ProjectFile "MEMORY.md" "$RepoUrl/MEMORY.md"
|
|
95
|
-
New-ProjectFile "TASKS.md" "$RepoUrl/TASKS.md"
|
|
96
|
-
New-ProjectFile "RUNBOOK.md" "$RepoUrl/RUNBOOK.md"
|
|
97
|
-
}
|
|
98
|
-
New-ProjectFile ".gitattributes" "$RepoUrl/.gitattributes"
|
|
99
|
-
New-ProjectFile "bin/multimodel-dev-os.js" "$RepoUrl/bin/multimodel-dev-os.js"
|
|
100
|
-
|
|
101
|
-
# --- Phase 2: .ai/ Directory ---
|
|
102
|
-
|
|
103
|
-
Write-Host ""
|
|
104
|
-
Write-Host "Creating .ai/ directory..." -ForegroundColor Blue
|
|
105
|
-
|
|
106
|
-
New-ProjectFile ".ai/config.yaml" "$RepoUrl/.ai/config.yaml"
|
|
107
|
-
New-ProjectDir ".ai/context"
|
|
108
|
-
New-ProjectFile ".ai/context/README.md" "$RepoUrl/.ai/context/README.md"
|
|
109
|
-
New-ProjectDir ".ai/agents"
|
|
110
|
-
New-ProjectFile ".ai/agents/README.md" "$RepoUrl/.ai/agents/README.md"
|
|
111
|
-
New-ProjectFile ".ai/agents/multimodel-orchestrator.md" "$RepoUrl/.ai/agents/multimodel-orchestrator.md"
|
|
112
|
-
New-ProjectDir ".ai/skills"
|
|
113
|
-
New-ProjectFile ".ai/skills/README.md" "$RepoUrl/.ai/skills/README.md"
|
|
114
|
-
New-ProjectFile ".ai/skills/example-skill.md" "$RepoUrl/.ai/skills/example-skill.md"
|
|
115
|
-
New-ProjectDir ".ai/prompts"
|
|
116
|
-
New-ProjectFile ".ai/prompts/README.md" "$RepoUrl/.ai/prompts/README.md"
|
|
117
|
-
New-ProjectDir ".ai/checks"
|
|
118
|
-
New-ProjectFile ".ai/checks/README.md" "$RepoUrl/.ai/checks/README.md"
|
|
119
|
-
New-ProjectFile ".ai/checks/pre-commit.md" "$RepoUrl/.ai/checks/pre-commit.md"
|
|
120
|
-
New-ProjectDir ".ai/session-logs"
|
|
121
|
-
New-ProjectFile ".ai/session-logs/README.md" "$RepoUrl/.ai/session-logs/README.md"
|
|
122
|
-
New-ProjectDir ".ai/templates"
|
|
123
|
-
New-ProjectFile ".ai/templates/AGENTS.caveman.md" "$RepoUrl/.ai/templates/AGENTS.caveman.md"
|
|
124
|
-
New-ProjectFile ".ai/templates/MEMORY.caveman.md" "$RepoUrl/.ai/templates/MEMORY.caveman.md"
|
|
125
|
-
New-ProjectFile ".ai/templates/TASKS.caveman.md" "$RepoUrl/.ai/templates/TASKS.caveman.md"
|
|
126
|
-
New-ProjectFile ".ai/templates/RUNBOOK.caveman.md" "$RepoUrl/.ai/templates/RUNBOOK.caveman.md"
|
|
127
|
-
|
|
128
|
-
# --- Phase 3: Adapters ---
|
|
129
|
-
|
|
130
|
-
Write-Host ""
|
|
131
|
-
|
|
132
|
-
function Install-Adapter {
|
|
133
|
-
param([string]$Name)
|
|
134
|
-
|
|
135
|
-
Write-Host "Installing $Name adapter..." -ForegroundColor Blue
|
|
136
|
-
|
|
137
|
-
switch ($Name) {
|
|
138
|
-
"codex" {
|
|
139
|
-
New-ProjectFile "adapters/codex/AGENTS.md" "$RepoUrl/adapters/codex/AGENTS.md"
|
|
140
|
-
New-ProjectFile "adapters/codex/setup.md" "$RepoUrl/adapters/codex/setup.md"
|
|
141
|
-
}
|
|
142
|
-
"antigravity" {
|
|
143
|
-
New-ProjectFile "adapters/antigravity/AGENTS.md" "$RepoUrl/adapters/antigravity/AGENTS.md"
|
|
144
|
-
New-ProjectFile "adapters/antigravity/.gemini/settings.json" "$RepoUrl/adapters/antigravity/.gemini/settings.json"
|
|
145
|
-
New-ProjectFile "adapters/antigravity/setup.md" "$RepoUrl/adapters/antigravity/setup.md"
|
|
146
|
-
}
|
|
147
|
-
"cursor" {
|
|
148
|
-
New-ProjectFile "adapters/cursor/.cursorrules" "$RepoUrl/adapters/cursor/.cursorrules"
|
|
149
|
-
New-ProjectFile "adapters/cursor/setup.md" "$RepoUrl/adapters/cursor/setup.md"
|
|
150
|
-
}
|
|
151
|
-
"claude" {
|
|
152
|
-
New-ProjectFile "adapters/claude/CLAUDE.md" "$RepoUrl/adapters/claude/CLAUDE.md"
|
|
153
|
-
New-ProjectFile "adapters/claude/setup.md" "$RepoUrl/adapters/claude/setup.md"
|
|
154
|
-
}
|
|
155
|
-
"gemini" {
|
|
156
|
-
New-ProjectFile "adapters/gemini/GEMINI.md" "$RepoUrl/adapters/gemini/GEMINI.md"
|
|
157
|
-
New-ProjectFile "adapters/gemini/setup.md" "$RepoUrl/adapters/gemini/setup.md"
|
|
158
|
-
}
|
|
159
|
-
"vscode" {
|
|
160
|
-
New-ProjectFile "adapters/vscode/.vscode/settings.json" "$RepoUrl/adapters/vscode/.vscode/settings.json"
|
|
161
|
-
New-ProjectFile "adapters/vscode/setup.md" "$RepoUrl/adapters/vscode/setup.md"
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if ($All) {
|
|
167
|
-
foreach ($adapter in @("codex", "antigravity", "cursor", "claude", "gemini", "vscode")) {
|
|
168
|
-
Install-Adapter $adapter
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
Write-Host "Which adapters do you want to install?" -ForegroundColor Yellow
|
|
173
|
-
Write-Host " 1) all"
|
|
174
|
-
Write-Host " 2) codex"
|
|
175
|
-
Write-Host " 3) antigravity"
|
|
176
|
-
Write-Host " 4) cursor"
|
|
177
|
-
Write-Host " 5) claude"
|
|
178
|
-
Write-Host " 6) gemini"
|
|
179
|
-
Write-Host " 7) vscode"
|
|
180
|
-
Write-Host " 8) none"
|
|
181
|
-
Write-Host ""
|
|
182
|
-
$choices = Read-Host "Enter choices (comma-separated, e.g., 2,4,5)"
|
|
183
|
-
|
|
184
|
-
if ([string]::IsNullOrWhiteSpace($choices) -or $choices -eq "8") {
|
|
185
|
-
Write-Host "Skipping adapters." -ForegroundColor Yellow
|
|
186
|
-
}
|
|
187
|
-
elseif ($choices -eq "1") {
|
|
188
|
-
foreach ($adapter in @("codex", "antigravity", "cursor", "claude", "gemini", "vscode")) {
|
|
189
|
-
Install-Adapter $adapter
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
$selected = $choices -split "," | ForEach-Object { $_.Trim() }
|
|
194
|
-
foreach ($choice in $selected) {
|
|
195
|
-
switch ($choice) {
|
|
196
|
-
"2" { Install-Adapter "codex" }
|
|
197
|
-
"3" { Install-Adapter "antigravity" }
|
|
198
|
-
"4" { Install-Adapter "cursor" }
|
|
199
|
-
"5" { Install-Adapter "claude" }
|
|
200
|
-
"6" { Install-Adapter "gemini" }
|
|
201
|
-
"7" { Install-Adapter "vscode" }
|
|
202
|
-
default { Write-Host "Unknown choice: $choice" -ForegroundColor Red }
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
# --- Summary ---
|
|
209
|
-
|
|
210
|
-
Write-Host ""
|
|
211
|
-
Write-Host "multimodel-dev-os installed!" -ForegroundColor Green
|
|
212
|
-
Write-Host ""
|
|
213
|
-
Write-Host "Next steps:"
|
|
214
|
-
Write-Host " 1. Edit AGENTS.md with your project details"
|
|
215
|
-
Write-Host " 2. Edit .ai/config.yaml to enable your adapters"
|
|
216
|
-
Write-Host " 3. Copy adapter files to your project root as needed:"
|
|
217
|
-
Write-Host " - Cursor: Copy-Item adapters/cursor/.cursorrules .cursorrules"
|
|
218
|
-
Write-Host " - Claude: Copy-Item adapters/claude/CLAUDE.md CLAUDE.md"
|
|
219
|
-
Write-Host " - VS Code: Copy-Item -Recurse adapters/vscode/.vscode/ .vscode/"
|
|
220
|
-
Write-Host ""
|
|
221
|
-
Write-Host " Docs: https://github.com/rizvee/multimodel-dev-os"
|
|
222
|
-
Write-Host ""
|
|
223
|
-
|
|
224
|
-
if ($Caveman) {
|
|
225
|
-
Write-Host " Caveman Mode active - minimal-token templates installed" -ForegroundColor Yellow
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
if ($DryRun) {
|
|
229
|
-
Write-Host " Dry run - no files were created" -ForegroundColor Blue
|
|
230
|
-
}
|
|
1
|
+
# multimodel-dev-os installer for Windows (PowerShell)
|
|
2
|
+
# Usage: irm https://raw.githubusercontent.com/rizvee/multimodel-dev-os/main/scripts/install.ps1 | iex
|
|
3
|
+
# Flags: -Caveman (use minimal-token templates)
|
|
4
|
+
# -All (install all adapters)
|
|
5
|
+
# -DryRun (show what would be created without creating)
|
|
6
|
+
|
|
7
|
+
param(
|
|
8
|
+
[switch]$Caveman,
|
|
9
|
+
[switch]$All,
|
|
10
|
+
[switch]$DryRun,
|
|
11
|
+
[switch]$Help
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
$Version = "2.0.1"
|
|
15
|
+
$RepoUrl = "https://raw.githubusercontent.com/rizvee/multimodel-dev-os/main"
|
|
16
|
+
|
|
17
|
+
if ($Help) {
|
|
18
|
+
Write-Host "multimodel-dev-os installer v$Version" -ForegroundColor Blue
|
|
19
|
+
Write-Host ""
|
|
20
|
+
Write-Host "Usage: irm .../install.ps1 | iex"
|
|
21
|
+
Write-Host ""
|
|
22
|
+
Write-Host "Options:"
|
|
23
|
+
Write-Host " -Caveman Use minimal-token templates (~79% fewer tokens)"
|
|
24
|
+
Write-Host " -All Install all adapters"
|
|
25
|
+
Write-Host " -DryRun Show what would be created without creating"
|
|
26
|
+
Write-Host " -Help Show this help message"
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
Write-Host "multimodel-dev-os installer v$Version" -ForegroundColor Blue
|
|
31
|
+
Write-Host ""
|
|
32
|
+
|
|
33
|
+
# --- Helper Functions ---
|
|
34
|
+
|
|
35
|
+
function New-ProjectFile {
|
|
36
|
+
param(
|
|
37
|
+
[string]$Path,
|
|
38
|
+
[string]$Url
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
if (Test-Path $Path) {
|
|
42
|
+
Write-Host " SKIP $Path (already exists)" -ForegroundColor Yellow
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if ($DryRun) {
|
|
47
|
+
Write-Host " WOULD CREATE $Path" -ForegroundColor Blue
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
$dir = Split-Path -Parent $Path
|
|
52
|
+
if ($dir -and !(Test-Path $dir)) {
|
|
53
|
+
New-Item -ItemType Directory -Path $dir -Force | Out-Null
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
Invoke-WebRequest -Uri $Url -OutFile $Path -UseBasicParsing -ErrorAction Stop
|
|
58
|
+
Write-Host " CREATE $Path" -ForegroundColor Green
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
Write-Host " FAIL $Path (download failed)" -ForegroundColor Red
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function New-ProjectDir {
|
|
66
|
+
param([string]$Path)
|
|
67
|
+
|
|
68
|
+
if (Test-Path $Path) {
|
|
69
|
+
Write-Host " SKIP $Path/ (already exists)" -ForegroundColor Yellow
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if ($DryRun) {
|
|
74
|
+
Write-Host " WOULD CREATE $Path/" -ForegroundColor Blue
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
New-Item -ItemType Directory -Path $Path -Force | Out-Null
|
|
79
|
+
Write-Host " CREATE $Path/" -ForegroundColor Green
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# --- Phase 1: Core Files ---
|
|
83
|
+
|
|
84
|
+
Write-Host "Creating core files..." -ForegroundColor Blue
|
|
85
|
+
|
|
86
|
+
if ($Caveman) {
|
|
87
|
+
New-ProjectFile "AGENTS.md" "$RepoUrl/.ai/templates/AGENTS.caveman.md"
|
|
88
|
+
New-ProjectFile "MEMORY.md" "$RepoUrl/.ai/templates/MEMORY.caveman.md"
|
|
89
|
+
New-ProjectFile "TASKS.md" "$RepoUrl/.ai/templates/TASKS.caveman.md"
|
|
90
|
+
New-ProjectFile "RUNBOOK.md" "$RepoUrl/.ai/templates/RUNBOOK.caveman.md"
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
New-ProjectFile "AGENTS.md" "$RepoUrl/AGENTS.md"
|
|
94
|
+
New-ProjectFile "MEMORY.md" "$RepoUrl/MEMORY.md"
|
|
95
|
+
New-ProjectFile "TASKS.md" "$RepoUrl/TASKS.md"
|
|
96
|
+
New-ProjectFile "RUNBOOK.md" "$RepoUrl/RUNBOOK.md"
|
|
97
|
+
}
|
|
98
|
+
New-ProjectFile ".gitattributes" "$RepoUrl/.gitattributes"
|
|
99
|
+
New-ProjectFile "bin/multimodel-dev-os.js" "$RepoUrl/bin/multimodel-dev-os.js"
|
|
100
|
+
|
|
101
|
+
# --- Phase 2: .ai/ Directory ---
|
|
102
|
+
|
|
103
|
+
Write-Host ""
|
|
104
|
+
Write-Host "Creating .ai/ directory..." -ForegroundColor Blue
|
|
105
|
+
|
|
106
|
+
New-ProjectFile ".ai/config.yaml" "$RepoUrl/.ai/config.yaml"
|
|
107
|
+
New-ProjectDir ".ai/context"
|
|
108
|
+
New-ProjectFile ".ai/context/README.md" "$RepoUrl/.ai/context/README.md"
|
|
109
|
+
New-ProjectDir ".ai/agents"
|
|
110
|
+
New-ProjectFile ".ai/agents/README.md" "$RepoUrl/.ai/agents/README.md"
|
|
111
|
+
New-ProjectFile ".ai/agents/multimodel-orchestrator.md" "$RepoUrl/.ai/agents/multimodel-orchestrator.md"
|
|
112
|
+
New-ProjectDir ".ai/skills"
|
|
113
|
+
New-ProjectFile ".ai/skills/README.md" "$RepoUrl/.ai/skills/README.md"
|
|
114
|
+
New-ProjectFile ".ai/skills/example-skill.md" "$RepoUrl/.ai/skills/example-skill.md"
|
|
115
|
+
New-ProjectDir ".ai/prompts"
|
|
116
|
+
New-ProjectFile ".ai/prompts/README.md" "$RepoUrl/.ai/prompts/README.md"
|
|
117
|
+
New-ProjectDir ".ai/checks"
|
|
118
|
+
New-ProjectFile ".ai/checks/README.md" "$RepoUrl/.ai/checks/README.md"
|
|
119
|
+
New-ProjectFile ".ai/checks/pre-commit.md" "$RepoUrl/.ai/checks/pre-commit.md"
|
|
120
|
+
New-ProjectDir ".ai/session-logs"
|
|
121
|
+
New-ProjectFile ".ai/session-logs/README.md" "$RepoUrl/.ai/session-logs/README.md"
|
|
122
|
+
New-ProjectDir ".ai/templates"
|
|
123
|
+
New-ProjectFile ".ai/templates/AGENTS.caveman.md" "$RepoUrl/.ai/templates/AGENTS.caveman.md"
|
|
124
|
+
New-ProjectFile ".ai/templates/MEMORY.caveman.md" "$RepoUrl/.ai/templates/MEMORY.caveman.md"
|
|
125
|
+
New-ProjectFile ".ai/templates/TASKS.caveman.md" "$RepoUrl/.ai/templates/TASKS.caveman.md"
|
|
126
|
+
New-ProjectFile ".ai/templates/RUNBOOK.caveman.md" "$RepoUrl/.ai/templates/RUNBOOK.caveman.md"
|
|
127
|
+
|
|
128
|
+
# --- Phase 3: Adapters ---
|
|
129
|
+
|
|
130
|
+
Write-Host ""
|
|
131
|
+
|
|
132
|
+
function Install-Adapter {
|
|
133
|
+
param([string]$Name)
|
|
134
|
+
|
|
135
|
+
Write-Host "Installing $Name adapter..." -ForegroundColor Blue
|
|
136
|
+
|
|
137
|
+
switch ($Name) {
|
|
138
|
+
"codex" {
|
|
139
|
+
New-ProjectFile "adapters/codex/AGENTS.md" "$RepoUrl/adapters/codex/AGENTS.md"
|
|
140
|
+
New-ProjectFile "adapters/codex/setup.md" "$RepoUrl/adapters/codex/setup.md"
|
|
141
|
+
}
|
|
142
|
+
"antigravity" {
|
|
143
|
+
New-ProjectFile "adapters/antigravity/AGENTS.md" "$RepoUrl/adapters/antigravity/AGENTS.md"
|
|
144
|
+
New-ProjectFile "adapters/antigravity/.gemini/settings.json" "$RepoUrl/adapters/antigravity/.gemini/settings.json"
|
|
145
|
+
New-ProjectFile "adapters/antigravity/setup.md" "$RepoUrl/adapters/antigravity/setup.md"
|
|
146
|
+
}
|
|
147
|
+
"cursor" {
|
|
148
|
+
New-ProjectFile "adapters/cursor/.cursorrules" "$RepoUrl/adapters/cursor/.cursorrules"
|
|
149
|
+
New-ProjectFile "adapters/cursor/setup.md" "$RepoUrl/adapters/cursor/setup.md"
|
|
150
|
+
}
|
|
151
|
+
"claude" {
|
|
152
|
+
New-ProjectFile "adapters/claude/CLAUDE.md" "$RepoUrl/adapters/claude/CLAUDE.md"
|
|
153
|
+
New-ProjectFile "adapters/claude/setup.md" "$RepoUrl/adapters/claude/setup.md"
|
|
154
|
+
}
|
|
155
|
+
"gemini" {
|
|
156
|
+
New-ProjectFile "adapters/gemini/GEMINI.md" "$RepoUrl/adapters/gemini/GEMINI.md"
|
|
157
|
+
New-ProjectFile "adapters/gemini/setup.md" "$RepoUrl/adapters/gemini/setup.md"
|
|
158
|
+
}
|
|
159
|
+
"vscode" {
|
|
160
|
+
New-ProjectFile "adapters/vscode/.vscode/settings.json" "$RepoUrl/adapters/vscode/.vscode/settings.json"
|
|
161
|
+
New-ProjectFile "adapters/vscode/setup.md" "$RepoUrl/adapters/vscode/setup.md"
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if ($All) {
|
|
167
|
+
foreach ($adapter in @("codex", "antigravity", "cursor", "claude", "gemini", "vscode")) {
|
|
168
|
+
Install-Adapter $adapter
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
Write-Host "Which adapters do you want to install?" -ForegroundColor Yellow
|
|
173
|
+
Write-Host " 1) all"
|
|
174
|
+
Write-Host " 2) codex"
|
|
175
|
+
Write-Host " 3) antigravity"
|
|
176
|
+
Write-Host " 4) cursor"
|
|
177
|
+
Write-Host " 5) claude"
|
|
178
|
+
Write-Host " 6) gemini"
|
|
179
|
+
Write-Host " 7) vscode"
|
|
180
|
+
Write-Host " 8) none"
|
|
181
|
+
Write-Host ""
|
|
182
|
+
$choices = Read-Host "Enter choices (comma-separated, e.g., 2,4,5)"
|
|
183
|
+
|
|
184
|
+
if ([string]::IsNullOrWhiteSpace($choices) -or $choices -eq "8") {
|
|
185
|
+
Write-Host "Skipping adapters." -ForegroundColor Yellow
|
|
186
|
+
}
|
|
187
|
+
elseif ($choices -eq "1") {
|
|
188
|
+
foreach ($adapter in @("codex", "antigravity", "cursor", "claude", "gemini", "vscode")) {
|
|
189
|
+
Install-Adapter $adapter
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
$selected = $choices -split "," | ForEach-Object { $_.Trim() }
|
|
194
|
+
foreach ($choice in $selected) {
|
|
195
|
+
switch ($choice) {
|
|
196
|
+
"2" { Install-Adapter "codex" }
|
|
197
|
+
"3" { Install-Adapter "antigravity" }
|
|
198
|
+
"4" { Install-Adapter "cursor" }
|
|
199
|
+
"5" { Install-Adapter "claude" }
|
|
200
|
+
"6" { Install-Adapter "gemini" }
|
|
201
|
+
"7" { Install-Adapter "vscode" }
|
|
202
|
+
default { Write-Host "Unknown choice: $choice" -ForegroundColor Red }
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# --- Summary ---
|
|
209
|
+
|
|
210
|
+
Write-Host ""
|
|
211
|
+
Write-Host "multimodel-dev-os installed!" -ForegroundColor Green
|
|
212
|
+
Write-Host ""
|
|
213
|
+
Write-Host "Next steps:"
|
|
214
|
+
Write-Host " 1. Edit AGENTS.md with your project details"
|
|
215
|
+
Write-Host " 2. Edit .ai/config.yaml to enable your adapters"
|
|
216
|
+
Write-Host " 3. Copy adapter files to your project root as needed:"
|
|
217
|
+
Write-Host " - Cursor: Copy-Item adapters/cursor/.cursorrules .cursorrules"
|
|
218
|
+
Write-Host " - Claude: Copy-Item adapters/claude/CLAUDE.md CLAUDE.md"
|
|
219
|
+
Write-Host " - VS Code: Copy-Item -Recurse adapters/vscode/.vscode/ .vscode/"
|
|
220
|
+
Write-Host ""
|
|
221
|
+
Write-Host " Docs: https://github.com/rizvee/multimodel-dev-os"
|
|
222
|
+
Write-Host ""
|
|
223
|
+
|
|
224
|
+
if ($Caveman) {
|
|
225
|
+
Write-Host " Caveman Mode active - minimal-token templates installed" -ForegroundColor Yellow
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if ($DryRun) {
|
|
229
|
+
Write-Host " Dry run - no files were created" -ForegroundColor Blue
|
|
230
|
+
}
|
package/scripts/install.sh
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MultiModel Dev OS - Prepublish Guard
|
|
5
|
+
* Blocks accidental npm publications.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync, existsSync } from 'fs';
|
|
9
|
+
import { join, dirname } from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = dirname(__filename);
|
|
14
|
+
const projectRoot = join(__dirname, '..');
|
|
15
|
+
|
|
16
|
+
// 1. Check environment variable override
|
|
17
|
+
if (process.env.MMDO_ALLOW_PUBLISH !== 'true') {
|
|
18
|
+
console.error('\n\x1b[31m[ABORT] Publishing requires explicit release approval. Set MMDO_ALLOW_PUBLISH=true only during an approved npm publish.\x1b[0m');
|
|
19
|
+
console.error('To override this guard during the approved release, set the environment variable:');
|
|
20
|
+
console.log(' \x1b[33mMMDO_ALLOW_PUBLISH=true\x1b[0m\n');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 2. Enforce package version begins with '2.'
|
|
25
|
+
try {
|
|
26
|
+
const packageJsonPath = join(projectRoot, 'package.json');
|
|
27
|
+
if (existsSync(packageJsonPath)) {
|
|
28
|
+
const pkgData = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
29
|
+
const version = pkgData.version || '';
|
|
30
|
+
if (!version.startsWith('2.')) {
|
|
31
|
+
console.error(`\n\x1b[31m[ABORT] Blocked publishing version ${version}.\x1b[0m`);
|
|
32
|
+
console.error('Only major v2 version package releases (version starting with "2.") are permitted.');
|
|
33
|
+
console.log('Update the version in package.json to v2.0.0 or higher.\n');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
} catch (e) {
|
|
38
|
+
console.error(`\n\x1b[31m[ERROR] Failed to read package.json version: ${e.message}\x1b[0m\n`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
console.log('\x1b[32m✔ Prepublish guard passed. Proceeding with approved publication...\x1b[0m');
|
|
43
|
+
process.exit(0);
|