@nometria-ai/nom 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.
- package/LICENSE +21 -0
- package/README.md +112 -0
- package/package.json +47 -0
- package/src/cli.js +164 -0
- package/src/commands/deploy.js +157 -0
- package/src/commands/domain.js +57 -0
- package/src/commands/env.js +120 -0
- package/src/commands/github.js +291 -0
- package/src/commands/init.js +90 -0
- package/src/commands/login.js +280 -0
- package/src/commands/logs.js +49 -0
- package/src/commands/preview.js +60 -0
- package/src/commands/scan.js +70 -0
- package/src/commands/setup.js +854 -0
- package/src/commands/start.js +26 -0
- package/src/commands/status.js +33 -0
- package/src/commands/stop.js +24 -0
- package/src/commands/terminate.js +33 -0
- package/src/commands/upgrade.js +49 -0
- package/src/commands/whoami.js +18 -0
- package/src/lib/api.js +85 -0
- package/src/lib/auth.js +56 -0
- package/src/lib/config.js +93 -0
- package/src/lib/detect.js +88 -0
- package/src/lib/prompt.js +76 -0
- package/src/lib/spinner.js +43 -0
- package/src/lib/tar.js +55 -0
|
@@ -0,0 +1,854 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nom setup — Generate AI tool config files for every major IDE/agent.
|
|
3
|
+
*
|
|
4
|
+
* Creates:
|
|
5
|
+
* .cursor/rules/nometria.mdc — Cursor AI rules
|
|
6
|
+
* .clinerules — Cline / Roo Code
|
|
7
|
+
* .windsurfrules — Windsurf (Codeium)
|
|
8
|
+
* .github/copilot-instructions.md — GitHub Copilot
|
|
9
|
+
* .github/workflows/nometria-deploy.yml — Auto-deploy on push
|
|
10
|
+
* CLAUDE.md — Claude Code project instructions
|
|
11
|
+
* AGENTS.md — Universal agent deployment guide
|
|
12
|
+
* .claude/commands/deploy.md — Claude Code /deploy slash command
|
|
13
|
+
* .claude/commands/preview.md — Claude Code /preview slash command
|
|
14
|
+
* .claude/commands/status.md — Claude Code /status slash command
|
|
15
|
+
* .claude/commands/nometria-login.md — Claude Code /nometria-login slash command
|
|
16
|
+
* .continue/config.json — Continue.dev MCP config
|
|
17
|
+
*/
|
|
18
|
+
import { mkdirSync, writeFileSync, existsSync, readFileSync } from 'node:fs';
|
|
19
|
+
import { join } from 'node:path';
|
|
20
|
+
|
|
21
|
+
export async function setup(flags) {
|
|
22
|
+
const dir = process.cwd();
|
|
23
|
+
|
|
24
|
+
// Read nometria.json if it exists
|
|
25
|
+
let config = { name: 'my-app', platform: 'aws', region: 'us-east-1' };
|
|
26
|
+
const configPath = join(dir, 'nometria.json');
|
|
27
|
+
if (existsSync(configPath)) {
|
|
28
|
+
try {
|
|
29
|
+
config = { ...config, ...JSON.parse(readFileSync(configPath, 'utf8')) };
|
|
30
|
+
} catch { /* use defaults */ }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const appName = config.name || 'my-app';
|
|
34
|
+
const platform = config.platform || 'aws';
|
|
35
|
+
|
|
36
|
+
console.log('\n Setting up AI tool integrations for Nometria\n');
|
|
37
|
+
|
|
38
|
+
const files = [];
|
|
39
|
+
|
|
40
|
+
// 1. Cursor rules
|
|
41
|
+
const cursorDir = join(dir, '.cursor', 'rules');
|
|
42
|
+
mkdirSync(cursorDir, { recursive: true });
|
|
43
|
+
writeFileSync(join(cursorDir, 'nometria.mdc'), cursorRules(appName, platform));
|
|
44
|
+
files.push('.cursor/rules/nometria.mdc');
|
|
45
|
+
|
|
46
|
+
// 2. Cline rules
|
|
47
|
+
writeFileSync(join(dir, '.clinerules'), clineRules(appName, platform));
|
|
48
|
+
files.push('.clinerules');
|
|
49
|
+
|
|
50
|
+
// 3. Windsurf rules
|
|
51
|
+
writeFileSync(join(dir, '.windsurfrules'), windsurfRules(appName, platform));
|
|
52
|
+
files.push('.windsurfrules');
|
|
53
|
+
|
|
54
|
+
// 4. GitHub Copilot instructions
|
|
55
|
+
const githubDir = join(dir, '.github');
|
|
56
|
+
mkdirSync(githubDir, { recursive: true });
|
|
57
|
+
writeFileSync(join(githubDir, 'copilot-instructions.md'), copilotInstructions(appName, platform));
|
|
58
|
+
files.push('.github/copilot-instructions.md');
|
|
59
|
+
|
|
60
|
+
// 5. GitHub Action for auto-deploy
|
|
61
|
+
const workflowDir = join(dir, '.github', 'workflows');
|
|
62
|
+
mkdirSync(workflowDir, { recursive: true });
|
|
63
|
+
writeFileSync(join(workflowDir, 'nometria-deploy.yml'), deployAction(appName));
|
|
64
|
+
files.push('.github/workflows/nometria-deploy.yml');
|
|
65
|
+
|
|
66
|
+
// 6. CLAUDE.md
|
|
67
|
+
writeFileSync(join(dir, 'CLAUDE.md'), claudeMd(appName, platform));
|
|
68
|
+
files.push('CLAUDE.md');
|
|
69
|
+
|
|
70
|
+
// 7. AGENTS.md — universal agent guide
|
|
71
|
+
writeFileSync(join(dir, 'AGENTS.md'), agentsMd(appName, platform));
|
|
72
|
+
files.push('AGENTS.md');
|
|
73
|
+
|
|
74
|
+
// 8. Claude Code slash commands
|
|
75
|
+
const claudeCommandsDir = join(dir, '.claude', 'commands');
|
|
76
|
+
mkdirSync(claudeCommandsDir, { recursive: true });
|
|
77
|
+
writeFileSync(join(claudeCommandsDir, 'deploy.md'), claudeCommandDeploy());
|
|
78
|
+
files.push('.claude/commands/deploy.md');
|
|
79
|
+
writeFileSync(join(claudeCommandsDir, 'preview.md'), claudeCommandPreview());
|
|
80
|
+
files.push('.claude/commands/preview.md');
|
|
81
|
+
writeFileSync(join(claudeCommandsDir, 'status.md'), claudeCommandStatus());
|
|
82
|
+
files.push('.claude/commands/status.md');
|
|
83
|
+
writeFileSync(join(claudeCommandsDir, 'nometria-login.md'), claudeCommandLogin());
|
|
84
|
+
files.push('.claude/commands/nometria-login.md');
|
|
85
|
+
|
|
86
|
+
// 9. Continue.dev config
|
|
87
|
+
const continueDir = join(dir, '.continue');
|
|
88
|
+
mkdirSync(continueDir, { recursive: true });
|
|
89
|
+
const continueConfigPath = join(continueDir, 'config.json');
|
|
90
|
+
writeContinueConfig(continueConfigPath);
|
|
91
|
+
files.push('.continue/config.json');
|
|
92
|
+
|
|
93
|
+
// Print results
|
|
94
|
+
for (const f of files) {
|
|
95
|
+
console.log(` ${f}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
console.log(`
|
|
99
|
+
All AI tools now know how to deploy this project with Nometria.
|
|
100
|
+
|
|
101
|
+
Works with: Cursor, Claude Code, Cline, Windsurf, GitHub Copilot,
|
|
102
|
+
Continue.dev, Aider, and any MCP-compatible tool.
|
|
103
|
+
|
|
104
|
+
Claude Code users can now type:
|
|
105
|
+
/deploy Deploy to production
|
|
106
|
+
/preview Staging preview (free, 2hr)
|
|
107
|
+
/status Check deployment status
|
|
108
|
+
/nometria-login Set up authentication
|
|
109
|
+
`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ─── Templates ──────────────────────────────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
function cursorRules(appName, platform) {
|
|
115
|
+
return `---
|
|
116
|
+
description: Nometria deployment rules for ${appName}
|
|
117
|
+
globs: ["**/*"]
|
|
118
|
+
alwaysApply: true
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
# Nometria Deployment
|
|
122
|
+
|
|
123
|
+
This project deploys via **Nometria** (\`nom\` CLI). Configuration is in \`nometria.json\`.
|
|
124
|
+
|
|
125
|
+
## Deployment Commands
|
|
126
|
+
|
|
127
|
+
| Command | Description |
|
|
128
|
+
|---------|-------------|
|
|
129
|
+
| \`nom deploy\` | Deploy to production (${platform}) |
|
|
130
|
+
| \`nom preview\` | Create staging preview (free, 2hr) |
|
|
131
|
+
| \`nom status\` | Check deployment status |
|
|
132
|
+
| \`nom logs -f\` | Stream live logs |
|
|
133
|
+
| \`nom github connect\` | Connect GitHub for auto-deploy |
|
|
134
|
+
|
|
135
|
+
## Rules
|
|
136
|
+
|
|
137
|
+
1. When the user asks to deploy, run \`nom deploy\` in the terminal
|
|
138
|
+
2. When the user asks for a preview, run \`nom preview\`
|
|
139
|
+
3. For deployment status, run \`nom status\`
|
|
140
|
+
4. Environment variables are managed via \`nom env set KEY=VALUE\`
|
|
141
|
+
5. Never call the Nometria Python API directly — use the \`nom\` CLI
|
|
142
|
+
6. The deployment config is in \`nometria.json\` — do not modify it without asking
|
|
143
|
+
7. If not authenticated, run \`nom login\` first (opens browser)
|
|
144
|
+
|
|
145
|
+
## Quick Reference
|
|
146
|
+
|
|
147
|
+
- App: ${appName}
|
|
148
|
+
- Platform: ${platform}
|
|
149
|
+
- Config: \`nometria.json\`
|
|
150
|
+
- Docs: https://docs.nometria.com
|
|
151
|
+
`;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function clineRules(appName, platform) {
|
|
155
|
+
return `# Nometria Deployment Rules
|
|
156
|
+
|
|
157
|
+
This project (${appName}) deploys via Nometria.
|
|
158
|
+
|
|
159
|
+
## How to Deploy
|
|
160
|
+
|
|
161
|
+
1. Run \`nom deploy\` to deploy to production (${platform})
|
|
162
|
+
2. Run \`nom preview\` for a staging preview (free, 2 hours)
|
|
163
|
+
3. Run \`nom status\` to check deployment status
|
|
164
|
+
4. Run \`nom logs -f\` to stream live logs
|
|
165
|
+
|
|
166
|
+
## Important
|
|
167
|
+
|
|
168
|
+
- Configuration is in \`nometria.json\` — read it before making deployment decisions
|
|
169
|
+
- If not authenticated, run \`nom login\` (opens browser for sign-in)
|
|
170
|
+
- Environment variables: \`nom env set KEY=VALUE\` / \`nom env list\`
|
|
171
|
+
- Custom domains: \`nom domain add yourdomain.com\`
|
|
172
|
+
- Instance management: \`nom start\`, \`nom stop\`, \`nom upgrade 8gb\`
|
|
173
|
+
- GitHub auto-deploy: \`nom github connect\`
|
|
174
|
+
- Security scan: \`nom scan\`
|
|
175
|
+
- Never call backend APIs directly — always use the \`nom\` CLI
|
|
176
|
+
- The MCP server \`@nometria-ai/claude-code\` is also available for tool-based access
|
|
177
|
+
`;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function windsurfRules(appName, platform) {
|
|
181
|
+
return `# Nometria Deployment
|
|
182
|
+
|
|
183
|
+
This project (${appName}) deploys to ${platform} via Nometria.
|
|
184
|
+
|
|
185
|
+
## Commands
|
|
186
|
+
|
|
187
|
+
Deploy: \`nom deploy\`
|
|
188
|
+
Preview: \`nom preview\` (free, 2hr expiry)
|
|
189
|
+
Status: \`nom status\`
|
|
190
|
+
Logs: \`nom logs -f\`
|
|
191
|
+
Login: \`nom login\` (opens browser)
|
|
192
|
+
GitHub: \`nom github connect\` (auto-deploy on push)
|
|
193
|
+
Env vars: \`nom env set KEY=VALUE\`
|
|
194
|
+
Scan: \`nom scan\`
|
|
195
|
+
Instance: \`nom start\` / \`nom stop\` / \`nom upgrade <size>\`
|
|
196
|
+
Domain: \`nom domain add yourdomain.com\`
|
|
197
|
+
|
|
198
|
+
## Config
|
|
199
|
+
|
|
200
|
+
Deployment configuration is in \`nometria.json\`. Do not modify without asking the user.
|
|
201
|
+
|
|
202
|
+
## Rules
|
|
203
|
+
|
|
204
|
+
- Always use the \`nom\` CLI for deployment operations
|
|
205
|
+
- Never call Nometria APIs directly
|
|
206
|
+
- If the user is not authenticated, run \`nom login\` first
|
|
207
|
+
- Check \`nom status\` before deploying to see current state
|
|
208
|
+
`;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function copilotInstructions(appName, platform) {
|
|
212
|
+
return `# Nometria Deployment
|
|
213
|
+
|
|
214
|
+
This project (**${appName}**) deploys to **${platform}** using Nometria.
|
|
215
|
+
|
|
216
|
+
## Deployment
|
|
217
|
+
|
|
218
|
+
- Deploy: \`nom deploy\`
|
|
219
|
+
- Preview: \`nom preview\` (free staging URL, expires in 2 hours)
|
|
220
|
+
- Status: \`nom status\`
|
|
221
|
+
- Logs: \`nom logs -f\`
|
|
222
|
+
|
|
223
|
+
## Setup
|
|
224
|
+
|
|
225
|
+
- Config: \`nometria.json\`
|
|
226
|
+
- Login: \`nom login\` (opens browser for authentication)
|
|
227
|
+
- GitHub auto-deploy: \`nom github connect\`
|
|
228
|
+
|
|
229
|
+
## Management
|
|
230
|
+
|
|
231
|
+
- Environment variables: \`nom env set KEY=VALUE\` / \`nom env list\`
|
|
232
|
+
- Custom domain: \`nom domain add yourdomain.com\`
|
|
233
|
+
- Instance control: \`nom start\` / \`nom stop\` / \`nom upgrade 8gb\`
|
|
234
|
+
- Security scan: \`nom scan\`
|
|
235
|
+
|
|
236
|
+
## Notes
|
|
237
|
+
|
|
238
|
+
- Always use the \`nom\` CLI — do not call Nometria APIs directly
|
|
239
|
+
- Read \`nometria.json\` for current deployment configuration
|
|
240
|
+
- Install: \`npm i -g @nometria-ai/nom\` or use \`npx @nometria-ai/nom\`
|
|
241
|
+
`;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function claudeMd(appName, platform) {
|
|
245
|
+
return `# ${appName}
|
|
246
|
+
|
|
247
|
+
This project deploys via **Nometria** to **${platform}**.
|
|
248
|
+
|
|
249
|
+
## Deployment
|
|
250
|
+
|
|
251
|
+
\`\`\`bash
|
|
252
|
+
nom deploy # Deploy to production
|
|
253
|
+
nom preview # Staging preview (free, 2hr)
|
|
254
|
+
nom status # Check status
|
|
255
|
+
nom logs -f # Stream logs
|
|
256
|
+
\`\`\`
|
|
257
|
+
|
|
258
|
+
## Config
|
|
259
|
+
|
|
260
|
+
Deployment configuration is in \`nometria.json\`. Read it before making deployment decisions.
|
|
261
|
+
|
|
262
|
+
## Full CLI Reference
|
|
263
|
+
|
|
264
|
+
| Command | Description |
|
|
265
|
+
|---------|-------------|
|
|
266
|
+
| \`nom login\` | Sign in via browser |
|
|
267
|
+
| \`nom deploy\` | Deploy to production |
|
|
268
|
+
| \`nom preview\` | Staging preview |
|
|
269
|
+
| \`nom status\` | Deployment status |
|
|
270
|
+
| \`nom logs [-f]\` | View/stream logs |
|
|
271
|
+
| \`nom github connect\` | GitHub OAuth for auto-deploy |
|
|
272
|
+
| \`nom github push -m "msg"\` | Push to GitHub |
|
|
273
|
+
| \`nom start\` / \`nom stop\` | Instance control |
|
|
274
|
+
| \`nom upgrade <size>\` | Resize (2gb/4gb/8gb/16gb) |
|
|
275
|
+
| \`nom domain add <domain>\` | Custom domain |
|
|
276
|
+
| \`nom env set KEY=VALUE\` | Set env var |
|
|
277
|
+
| \`nom env list\` | List env vars |
|
|
278
|
+
| \`nom scan\` | AI security scan |
|
|
279
|
+
| \`nom setup\` | Regenerate AI tool configs |
|
|
280
|
+
|
|
281
|
+
## MCP Server
|
|
282
|
+
|
|
283
|
+
For tool-based access: \`claude mcp add nometria -- npx @nometria-ai/claude-code\`
|
|
284
|
+
|
|
285
|
+
## Rules
|
|
286
|
+
|
|
287
|
+
- Use the \`nom\` CLI for all deployment operations
|
|
288
|
+
- Never call backend APIs directly
|
|
289
|
+
- If unauthenticated, run \`nom login\` first
|
|
290
|
+
`;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function deployAction(appName) {
|
|
294
|
+
return `name: Deploy to Nometria
|
|
295
|
+
|
|
296
|
+
on:
|
|
297
|
+
push:
|
|
298
|
+
branches: [main]
|
|
299
|
+
workflow_dispatch:
|
|
300
|
+
|
|
301
|
+
jobs:
|
|
302
|
+
deploy:
|
|
303
|
+
runs-on: ubuntu-latest
|
|
304
|
+
steps:
|
|
305
|
+
- uses: actions/checkout@v4
|
|
306
|
+
|
|
307
|
+
- uses: actions/setup-node@v4
|
|
308
|
+
with:
|
|
309
|
+
node-version: '20'
|
|
310
|
+
|
|
311
|
+
- name: Install dependencies
|
|
312
|
+
run: npm ci
|
|
313
|
+
|
|
314
|
+
- name: Deploy
|
|
315
|
+
run: npx @nometria-ai/nom deploy --yes
|
|
316
|
+
env:
|
|
317
|
+
NOMETRIA_API_KEY: \${{ secrets.NOMETRIA_API_KEY }}
|
|
318
|
+
`;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// ─── Claude Code Slash Commands ─────────────────────────────────────────────
|
|
322
|
+
|
|
323
|
+
function claudeCommandDeploy() {
|
|
324
|
+
return `---
|
|
325
|
+
allowed-tools: Bash(curl:*), Bash(cat:*), Bash(sleep:*), Bash(echo:*), Bash(grep:*), Read, Write
|
|
326
|
+
description: Deploy your app to production via Nometria
|
|
327
|
+
argument-hint: Optional app name or migration ID
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
# Deploy to Production
|
|
331
|
+
|
|
332
|
+
You are deploying the user's app to production via the Nometria platform. Execute this workflow precisely.
|
|
333
|
+
|
|
334
|
+
## Step 1: Resolve API token
|
|
335
|
+
|
|
336
|
+
Find the Nometria API token. Check in this order:
|
|
337
|
+
|
|
338
|
+
\`\`\`bash
|
|
339
|
+
# 1. Environment variables (API key or JWT token)
|
|
340
|
+
echo "$NOMETRIA_API_KEY"
|
|
341
|
+
echo "$NOMETRIA_TOKEN"
|
|
342
|
+
|
|
343
|
+
# 2. .env file in current project
|
|
344
|
+
grep -s 'NOMETRIA_API_KEY\\|NOMETRIA_TOKEN' .env .env.local 2>/dev/null
|
|
345
|
+
|
|
346
|
+
# 3. Stored credentials from \\\`nom login\\\`
|
|
347
|
+
cat ~/.nometria/credentials.json 2>/dev/null
|
|
348
|
+
|
|
349
|
+
# 4. Home directory config (legacy)
|
|
350
|
+
cat ~/.nometria 2>/dev/null
|
|
351
|
+
\`\`\`
|
|
352
|
+
|
|
353
|
+
If no token is found, tell the user:
|
|
354
|
+
|
|
355
|
+
> No Nometria API token found. Run \\\`nom login\\\` or \\\`/nometria-login\\\` to authenticate.
|
|
356
|
+
> Get your API key at https://ownmy.app/settings/api-keys
|
|
357
|
+
|
|
358
|
+
**Stop here if no token.** Do not proceed without a valid token.
|
|
359
|
+
|
|
360
|
+
Store the token: \\\`TOKEN="<the token>"\\\`
|
|
361
|
+
|
|
362
|
+
## Step 2: Identify the app
|
|
363
|
+
|
|
364
|
+
Check if there's a \\\`nometria.json\\\` in the workspace root:
|
|
365
|
+
\`\`\`bash
|
|
366
|
+
cat nometria.json 2>/dev/null
|
|
367
|
+
\`\`\`
|
|
368
|
+
|
|
369
|
+
If it exists, extract \\\`app_id\\\` and \\\`migration_id\\\` from it.
|
|
370
|
+
|
|
371
|
+
If not, or if the user specified an app name as \\\`$ARGUMENTS\\\`, list all migrations:
|
|
372
|
+
|
|
373
|
+
\`\`\`bash
|
|
374
|
+
curl -s -X POST https://app.ownmy.app/listUserMigrations \\
|
|
375
|
+
-H "Content-Type: application/json" \\
|
|
376
|
+
-H "Authorization: Bearer $TOKEN" \\
|
|
377
|
+
-d '{}'
|
|
378
|
+
\`\`\`
|
|
379
|
+
|
|
380
|
+
From the response, find the matching migration. If multiple apps exist and the user didn't specify which one, show a numbered list and ask them to pick.
|
|
381
|
+
|
|
382
|
+
Only proceed with migrations that have \\\`delivery_type: "hosting"\\\` and \\\`payment_status: "paid"\\\`.
|
|
383
|
+
|
|
384
|
+
Store: \\\`APP_ID="<app_id>"\\\` and \\\`MIGRATION_ID="<migration_id>"\\\`
|
|
385
|
+
|
|
386
|
+
## Step 3: Check current deployment status
|
|
387
|
+
|
|
388
|
+
\`\`\`bash
|
|
389
|
+
curl -s -X POST https://app.ownmy.app/checkAwsStatus \\
|
|
390
|
+
-H "Content-Type: application/json" \\
|
|
391
|
+
-H "Authorization: Bearer $TOKEN" \\
|
|
392
|
+
-d "{\\"app_id\\": \\"$APP_ID\\"}"
|
|
393
|
+
\`\`\`
|
|
394
|
+
|
|
395
|
+
Parse the response to determine the instance state.
|
|
396
|
+
|
|
397
|
+
## Step 4: Deploy or resync
|
|
398
|
+
|
|
399
|
+
**If instance is running** (\\\`data.instanceState === "running"\\\`):
|
|
400
|
+
|
|
401
|
+
Tell the user: "App is already running. Resyncing code to production..."
|
|
402
|
+
|
|
403
|
+
\`\`\`bash
|
|
404
|
+
curl -s -X POST https://app.ownmy.app/resyncHosting \\
|
|
405
|
+
-H "Content-Type: application/json" \\
|
|
406
|
+
-H "Authorization: Bearer $TOKEN" \\
|
|
407
|
+
-d "{\\"app_id\\": \\"$APP_ID\\"}"
|
|
408
|
+
\`\`\`
|
|
409
|
+
|
|
410
|
+
**If instance is stopped** (\\\`data.instanceState === "stopped"\\\`):
|
|
411
|
+
|
|
412
|
+
Tell the user: "Instance is stopped. Starting and resyncing..."
|
|
413
|
+
|
|
414
|
+
\`\`\`bash
|
|
415
|
+
curl -s -X POST https://app.ownmy.app/updateInstanceState \\
|
|
416
|
+
-H "Content-Type: application/json" \\
|
|
417
|
+
-H "Authorization: Bearer $TOKEN" \\
|
|
418
|
+
-d "{\\"app_id\\": \\"$APP_ID\\", \\"instance_state\\": \\"start\\"}"
|
|
419
|
+
\`\`\`
|
|
420
|
+
|
|
421
|
+
Then resync once it's running.
|
|
422
|
+
|
|
423
|
+
**If not deployed** (\\\`status === "not_deployed"\\\`):
|
|
424
|
+
|
|
425
|
+
Tell the user: "Deploying new production instance..."
|
|
426
|
+
|
|
427
|
+
\`\`\`bash
|
|
428
|
+
curl -s -X POST https://app.ownmy.app/deployToAws \\
|
|
429
|
+
-H "Content-Type: application/json" \\
|
|
430
|
+
-H "Authorization: Bearer $TOKEN" \\
|
|
431
|
+
-d "{\\"migration_id\\": \\"$MIGRATION_ID\\"}"
|
|
432
|
+
\`\`\`
|
|
433
|
+
|
|
434
|
+
## Step 5: Poll for completion
|
|
435
|
+
|
|
436
|
+
Poll every 5 seconds until the deployment reaches a terminal state:
|
|
437
|
+
|
|
438
|
+
\`\`\`bash
|
|
439
|
+
curl -s -X POST https://app.ownmy.app/checkAwsStatus \\
|
|
440
|
+
-H "Content-Type: application/json" \\
|
|
441
|
+
-H "Authorization: Bearer $TOKEN" \\
|
|
442
|
+
-d "{\\"app_id\\": \\"$APP_ID\\"}"
|
|
443
|
+
\`\`\`
|
|
444
|
+
|
|
445
|
+
Terminal states:
|
|
446
|
+
- \\\`instanceState: "running"\\\` -> **Success**
|
|
447
|
+
- \\\`deploymentStatus: "failed"\\\` -> **Failure** (report \\\`errorMessage\\\`)
|
|
448
|
+
- \\\`instanceState: "terminated"\\\` -> **Failure**
|
|
449
|
+
|
|
450
|
+
Poll up to 60 times (5 minutes). Report progress every 3 polls.
|
|
451
|
+
|
|
452
|
+
## Step 6: Report result
|
|
453
|
+
|
|
454
|
+
**On success**, display:
|
|
455
|
+
|
|
456
|
+
\`\`\`
|
|
457
|
+
Deployed successfully!
|
|
458
|
+
|
|
459
|
+
App: <app_name>
|
|
460
|
+
URL: <deployUrl or hosted_url>
|
|
461
|
+
IP: <ipAddress>
|
|
462
|
+
Type: <instanceType>
|
|
463
|
+
\`\`\`
|
|
464
|
+
|
|
465
|
+
**On failure**, display the error and suggest checking the Nometria dashboard.
|
|
466
|
+
|
|
467
|
+
## Step 7: Save workspace config
|
|
468
|
+
|
|
469
|
+
If \\\`nometria.json\\\` doesn't exist, create it so future deploys are faster:
|
|
470
|
+
|
|
471
|
+
\`\`\`json
|
|
472
|
+
{
|
|
473
|
+
"app_id": "<APP_ID>",
|
|
474
|
+
"migration_id": "<MIGRATION_ID>",
|
|
475
|
+
"app_name": "<app_name>",
|
|
476
|
+
"api_url": "https://app.ownmy.app"
|
|
477
|
+
}
|
|
478
|
+
\`\`\`
|
|
479
|
+
|
|
480
|
+
Do all of the above. Execute every curl call and report results to the user.
|
|
481
|
+
`;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function claudeCommandPreview() {
|
|
485
|
+
return `---
|
|
486
|
+
allowed-tools: Bash(curl:*), Bash(cat:*), Bash(grep:*), Bash(echo:*), Read
|
|
487
|
+
description: Deploy a staging preview of your app via Nometria
|
|
488
|
+
argument-hint: Optional app name
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
# Deploy Staging Preview
|
|
492
|
+
|
|
493
|
+
You are creating a temporary staging preview of the user's app. This is free and creates a short-lived URL.
|
|
494
|
+
|
|
495
|
+
## Step 1: Resolve token
|
|
496
|
+
|
|
497
|
+
\`\`\`bash
|
|
498
|
+
TOKEN="\${NOMETRIA_API_KEY:-\${NOMETRIA_TOKEN:-$(grep -s 'NOMETRIA_API_KEY\\|NOMETRIA_TOKEN' .env .env.local 2>/dev/null | head -1 | cut -d= -f2- | tr -d ' "'"'"'')}}"
|
|
499
|
+
echo "Token found: $([ -n "$TOKEN" ] && echo 'yes' || echo 'no')"
|
|
500
|
+
\`\`\`
|
|
501
|
+
|
|
502
|
+
If no token: tell the user to run \\\`nom login\\\` or \\\`/nometria-login\\\` and stop.
|
|
503
|
+
|
|
504
|
+
## Step 2: Identify the app
|
|
505
|
+
|
|
506
|
+
\`\`\`bash
|
|
507
|
+
# Try workspace config first
|
|
508
|
+
cat nometria.json 2>/dev/null
|
|
509
|
+
\`\`\`
|
|
510
|
+
|
|
511
|
+
If no \\\`nometria.json\\\`, list migrations:
|
|
512
|
+
|
|
513
|
+
\`\`\`bash
|
|
514
|
+
curl -s -X POST https://app.ownmy.app/listUserMigrations \\
|
|
515
|
+
-H "Content-Type: application/json" \\
|
|
516
|
+
-H "Authorization: Bearer $TOKEN" \\
|
|
517
|
+
-d '{}'
|
|
518
|
+
\`\`\`
|
|
519
|
+
|
|
520
|
+
Pick the correct migration. If \\\`$ARGUMENTS\\\` was provided, match by app name. Otherwise, if multiple exist, ask the user. Store \\\`MIGRATION_ID\\\`.
|
|
521
|
+
|
|
522
|
+
## Step 3: Deploy preview
|
|
523
|
+
|
|
524
|
+
\`\`\`bash
|
|
525
|
+
curl -s -X POST https://app.ownmy.app/deployStagingPreview \\
|
|
526
|
+
-H "Content-Type: application/json" \\
|
|
527
|
+
-H "Authorization: Bearer $TOKEN" \\
|
|
528
|
+
-d "{\\"migration_id\\": \\"$MIGRATION_ID\\", \\"production\\": false}"
|
|
529
|
+
\`\`\`
|
|
530
|
+
|
|
531
|
+
## Step 4: Report result
|
|
532
|
+
|
|
533
|
+
Parse the response. On success, display:
|
|
534
|
+
|
|
535
|
+
\`\`\`
|
|
536
|
+
Preview deployed!
|
|
537
|
+
|
|
538
|
+
URL: <preview_url>
|
|
539
|
+
Expires: ~2 hours
|
|
540
|
+
|
|
541
|
+
This is a temporary preview. Use /deploy for production.
|
|
542
|
+
\`\`\`
|
|
543
|
+
|
|
544
|
+
On failure, show the error message and suggest checking the dashboard.
|
|
545
|
+
|
|
546
|
+
Execute all curl commands and report the results.
|
|
547
|
+
`;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
function claudeCommandStatus() {
|
|
551
|
+
return `---
|
|
552
|
+
allowed-tools: Bash(curl:*), Bash(cat:*), Bash(grep:*), Bash(echo:*), Read
|
|
553
|
+
description: Check deployment status of your Nometria apps
|
|
554
|
+
argument-hint: Optional app name to filter
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
# Check Deployment Status
|
|
558
|
+
|
|
559
|
+
Show the user the current state of their Nometria deployments.
|
|
560
|
+
|
|
561
|
+
## Step 1: Resolve token
|
|
562
|
+
|
|
563
|
+
\`\`\`bash
|
|
564
|
+
TOKEN="\${NOMETRIA_API_KEY:-\${NOMETRIA_TOKEN:-$(grep -s 'NOMETRIA_API_KEY\\|NOMETRIA_TOKEN' .env .env.local 2>/dev/null | head -1 | cut -d= -f2- | tr -d ' "'"'"'')}}"
|
|
565
|
+
\`\`\`
|
|
566
|
+
|
|
567
|
+
If no token: tell the user to run \\\`/nometria-login\\\` and stop.
|
|
568
|
+
|
|
569
|
+
## Step 2: List all migrations
|
|
570
|
+
|
|
571
|
+
\`\`\`bash
|
|
572
|
+
curl -s -X POST https://app.ownmy.app/listUserMigrations \\
|
|
573
|
+
-H "Content-Type: application/json" \\
|
|
574
|
+
-H "Authorization: Bearer $TOKEN" \\
|
|
575
|
+
-d '{}'
|
|
576
|
+
\`\`\`
|
|
577
|
+
|
|
578
|
+
## Step 3: Check AWS status for hosting apps
|
|
579
|
+
|
|
580
|
+
For each migration with \\\`delivery_type: "hosting"\\\`, check its status:
|
|
581
|
+
|
|
582
|
+
\`\`\`bash
|
|
583
|
+
curl -s -X POST https://app.ownmy.app/checkAwsStatus \\
|
|
584
|
+
-H "Content-Type: application/json" \\
|
|
585
|
+
-H "Authorization: Bearer $TOKEN" \\
|
|
586
|
+
-d "{\\"app_id\\": \\"<APP_ID>\\"}"
|
|
587
|
+
\`\`\`
|
|
588
|
+
|
|
589
|
+
## Step 4: Display formatted table
|
|
590
|
+
|
|
591
|
+
Present results as a clear table showing App, Platform, Status, URL, and Instance.
|
|
592
|
+
|
|
593
|
+
Use these status indicators:
|
|
594
|
+
- running — app is live
|
|
595
|
+
- deploying / launching — deployment in progress
|
|
596
|
+
- stopped — instance exists but is off
|
|
597
|
+
- failed — deployment failed (show error if available)
|
|
598
|
+
- none — not deployed to hosting
|
|
599
|
+
|
|
600
|
+
If \\\`$ARGUMENTS\\\` was provided, filter the results to match that app name.
|
|
601
|
+
|
|
602
|
+
Also show totals: Total apps, Running, Stopped.
|
|
603
|
+
|
|
604
|
+
If there's a \\\`nometria.json\\\` in the workspace, highlight the linked app.
|
|
605
|
+
|
|
606
|
+
Execute all the curl calls and display the results.
|
|
607
|
+
`;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
function claudeCommandLogin() {
|
|
611
|
+
return `---
|
|
612
|
+
allowed-tools: Bash(echo:*), Bash(cat:*), Bash(grep:*), Read, Write
|
|
613
|
+
description: Authenticate with the Nometria deployment platform
|
|
614
|
+
---
|
|
615
|
+
|
|
616
|
+
# Nometria Login
|
|
617
|
+
|
|
618
|
+
Help the user set up their Nometria API token for deployments.
|
|
619
|
+
|
|
620
|
+
## Step 1: Check existing token
|
|
621
|
+
|
|
622
|
+
\`\`\`bash
|
|
623
|
+
# Check environment (API key or JWT)
|
|
624
|
+
echo "API_KEY: $([ -n "$NOMETRIA_API_KEY" ] && echo 'set' || echo 'not set')"
|
|
625
|
+
echo "TOKEN: $([ -n "$NOMETRIA_TOKEN" ] && echo 'set' || echo 'not set')"
|
|
626
|
+
|
|
627
|
+
# Check .env
|
|
628
|
+
grep -s 'NOMETRIA_API_KEY\\|NOMETRIA_TOKEN' .env .env.local 2>/dev/null && echo "Found in .env" || echo ".env: not found"
|
|
629
|
+
|
|
630
|
+
# Check nom CLI credentials
|
|
631
|
+
cat ~/.nometria/credentials.json 2>/dev/null && echo "Found ~/.nometria/credentials.json" || echo "~/.nometria/credentials.json: not found"
|
|
632
|
+
\`\`\`
|
|
633
|
+
|
|
634
|
+
If a token already exists, tell the user they're already authenticated and show which source it was found in. Ask if they want to update it.
|
|
635
|
+
|
|
636
|
+
## Step 2: Get the token
|
|
637
|
+
|
|
638
|
+
Tell the user:
|
|
639
|
+
|
|
640
|
+
> To get your Nometria API key:
|
|
641
|
+
>
|
|
642
|
+
> 1. Go to **https://ownmy.app/settings/api-keys**
|
|
643
|
+
> 2. Sign in to your account
|
|
644
|
+
> 3. Click **Generate New Key**
|
|
645
|
+
> 4. Copy the key and paste it here
|
|
646
|
+
>
|
|
647
|
+
> Your key is stored locally and never sent anywhere except the Nometria API.
|
|
648
|
+
> Alternatively, you can use \\\`nom login\\\` from the CLI.
|
|
649
|
+
|
|
650
|
+
Wait for the user to provide the token. They will paste it in the chat.
|
|
651
|
+
|
|
652
|
+
## Step 3: Validate the token
|
|
653
|
+
|
|
654
|
+
Once the user provides a token, validate it:
|
|
655
|
+
|
|
656
|
+
\`\`\`bash
|
|
657
|
+
curl -s -X POST https://app.ownmy.app/listUserMigrations \\
|
|
658
|
+
-H "Content-Type: application/json" \\
|
|
659
|
+
-H "Authorization: Bearer <USER_TOKEN>" \\
|
|
660
|
+
-d '{}'
|
|
661
|
+
\`\`\`
|
|
662
|
+
|
|
663
|
+
If the response contains \\\`"success": true\\\`, the token is valid.
|
|
664
|
+
|
|
665
|
+
## Step 4: Store the token
|
|
666
|
+
|
|
667
|
+
If the current directory has a \\\`.env\\\` file, append \\\`NOMETRIA_API_KEY=<key>\\\` to it.
|
|
668
|
+
If no \\\`.env\\\` exists, create \\\`.env\\\` with the key.
|
|
669
|
+
Warn the user if \\\`.env\\\` is not in \\\`.gitignore\\\`.
|
|
670
|
+
|
|
671
|
+
## Step 5: Confirm
|
|
672
|
+
|
|
673
|
+
Tell the user they're authenticated and show available commands:
|
|
674
|
+
/deploy - Deploy to production
|
|
675
|
+
/preview - Deploy staging preview
|
|
676
|
+
/status - Check deployment status
|
|
677
|
+
nom deploy - Deploy from CLI
|
|
678
|
+
`;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// ─── AGENTS.md ──────────────────────────────────────────────────────────────
|
|
682
|
+
|
|
683
|
+
function agentsMd(appName, platform) {
|
|
684
|
+
return `# Nometria Agent Deployment Guide
|
|
685
|
+
|
|
686
|
+
> Deploy any app to any cloud from your IDE, CLI, or AI agent. Works with VS Code, Cursor, Claude Code, and any tool that can run \\\`curl\\\` or \\\`npx\\\`.
|
|
687
|
+
|
|
688
|
+
## Quick Start — CLI (recommended)
|
|
689
|
+
|
|
690
|
+
\`\`\`bash
|
|
691
|
+
# Install and deploy in seconds
|
|
692
|
+
npx @nometria-ai/nom login
|
|
693
|
+
npx @nometria-ai/nom init
|
|
694
|
+
npx @nometria-ai/nom deploy
|
|
695
|
+
\`\`\`
|
|
696
|
+
|
|
697
|
+
## Quick Start — curl (for AI agents)
|
|
698
|
+
|
|
699
|
+
\`\`\`bash
|
|
700
|
+
# 1. Set your token (API key or JWT)
|
|
701
|
+
export NOMETRIA_API_KEY="nometria_sk_..." # from https://ownmy.app/settings/api-keys
|
|
702
|
+
|
|
703
|
+
# 2. List your apps
|
|
704
|
+
curl -s -X POST https://app.ownmy.app/listUserMigrations \\
|
|
705
|
+
-H "Content-Type: application/json" \\
|
|
706
|
+
-H "Authorization: Bearer $NOMETRIA_API_KEY" -d '{}'
|
|
707
|
+
|
|
708
|
+
# 3. Deploy to production (resync if already running)
|
|
709
|
+
curl -s -X POST https://app.ownmy.app/resyncHosting \\
|
|
710
|
+
-H "Content-Type: application/json" \\
|
|
711
|
+
-H "Authorization: Bearer $NOMETRIA_API_KEY" \\
|
|
712
|
+
-d '{"app_id": "YOUR_APP_ID"}'
|
|
713
|
+
\`\`\`
|
|
714
|
+
|
|
715
|
+
---
|
|
716
|
+
|
|
717
|
+
## Developer Surfaces
|
|
718
|
+
|
|
719
|
+
| Surface | Install | Auth |
|
|
720
|
+
|---------|---------|------|
|
|
721
|
+
| **nom CLI** | \\\`npx @nometria-ai/nom\\\` | API key (\\\`NOMETRIA_API_KEY\\\`) |
|
|
722
|
+
| **VS Code/Cursor** | Extensions marketplace | OAuth login |
|
|
723
|
+
| **Claude Code** | \\\`/deploy\\\`, \\\`/preview\\\`, \\\`/status\\\` | API key or JWT |
|
|
724
|
+
| **Any AI agent** | curl | API key or JWT |
|
|
725
|
+
|
|
726
|
+
---
|
|
727
|
+
|
|
728
|
+
## Authentication
|
|
729
|
+
|
|
730
|
+
Every API call requires \\\`Authorization: Bearer <token>\\\` header. Both API keys (\\\`nometria_sk_...\\\`) and JWT tokens are accepted.
|
|
731
|
+
|
|
732
|
+
**Getting an API key:**
|
|
733
|
+
1. Sign in at https://ownmy.app/settings/api-keys
|
|
734
|
+
2. Go to Settings -> API Token
|
|
735
|
+
3. Copy and store as \\\`NOMETRIA_API_KEY\\\` environment variable
|
|
736
|
+
|
|
737
|
+
**Base URL:** \\\`https://app.ownmy.app\\\`
|
|
738
|
+
|
|
739
|
+
All endpoints are \\\`POST\\\` with JSON body and \\\`Content-Type: application/json\\\`.
|
|
740
|
+
|
|
741
|
+
---
|
|
742
|
+
|
|
743
|
+
## API Reference
|
|
744
|
+
|
|
745
|
+
### List Apps
|
|
746
|
+
\\\`POST /listUserMigrations\\\` — Returns all migrations with app_id, status, delivery_type, hosted_url
|
|
747
|
+
|
|
748
|
+
### Check Status
|
|
749
|
+
\\\`POST /checkAwsStatus\\\` — Body: \\\`{"app_id": "..."}\\\` — Returns instanceState, deploymentStatus, ipAddress, deployUrl
|
|
750
|
+
|
|
751
|
+
### Deploy New Instance
|
|
752
|
+
\\\`POST /deployToAws\\\` — Body: \\\`{"migration_id": "..."}\\\` — Creates new EC2 instance. Poll checkAwsStatus every 5s.
|
|
753
|
+
|
|
754
|
+
### Resync Running App
|
|
755
|
+
\\\`POST /resyncHosting\\\` — Body: \\\`{"app_id": "..."}\\\` — Syncs latest code to running instance.
|
|
756
|
+
|
|
757
|
+
### Staging Preview
|
|
758
|
+
\\\`POST /deployStagingPreview\\\` — Body: \\\`{"migration_id": "...", "production": false}\\\` — Free, 2hr preview.
|
|
759
|
+
|
|
760
|
+
### Instance Control
|
|
761
|
+
\\\`POST /updateInstanceState\\\` — Body: \\\`{"app_id": "...", "instance_state": "start|stop|terminate"}\\\`
|
|
762
|
+
|
|
763
|
+
### Upgrade Instance
|
|
764
|
+
\\\`POST /upgradeInstance\\\` — Body: \\\`{"app_id": "...", "instance_type": "2gb|4gb|8gb|16gb"}\\\`
|
|
765
|
+
|
|
766
|
+
### Environment Variables
|
|
767
|
+
\\\`POST /setEnvVars\\\` — Body: \\\`{"app_id": "...", "env_vars": {"KEY": "value"}}\\\`
|
|
768
|
+
|
|
769
|
+
### Custom Domain
|
|
770
|
+
\\\`POST /addCustomDomain\\\` — Body: \\\`{"app_id": "...", "custom_domain": "app.yourdomain.com"}\\\`
|
|
771
|
+
|
|
772
|
+
### AI Security Scan
|
|
773
|
+
\\\`POST /runAiScan\\\` — Body: \\\`{"app_id": "...", "migration_id": "..."}\\\`
|
|
774
|
+
|
|
775
|
+
---
|
|
776
|
+
|
|
777
|
+
## Decision Logic for Agents
|
|
778
|
+
|
|
779
|
+
When the user says "deploy":
|
|
780
|
+
|
|
781
|
+
\\\`\\\`\\\`
|
|
782
|
+
Is there a nometria.json?
|
|
783
|
+
YES -> Use its app_id/migration_id
|
|
784
|
+
NO -> POST /listUserMigrations, pick the right one
|
|
785
|
+
|
|
786
|
+
POST /checkAwsStatus with app_id
|
|
787
|
+
instanceState === "running"?
|
|
788
|
+
YES -> POST /resyncHosting (fast code sync)
|
|
789
|
+
instanceState === "stopped"?
|
|
790
|
+
YES -> POST /updateInstanceState (start), then resyncHosting
|
|
791
|
+
status === "not_deployed"?
|
|
792
|
+
YES -> POST /deployToAws (new instance, takes 2-5 min)
|
|
793
|
+
|
|
794
|
+
Poll /checkAwsStatus every 5s until terminal state
|
|
795
|
+
Report URL to user
|
|
796
|
+
\\\`\\\`\\\`
|
|
797
|
+
|
|
798
|
+
---
|
|
799
|
+
|
|
800
|
+
## Configuration (\\\`nometria.json\\\`)
|
|
801
|
+
|
|
802
|
+
\\\`\\\`\\\`json
|
|
803
|
+
{
|
|
804
|
+
"name": "${appName}",
|
|
805
|
+
"framework": "vite",
|
|
806
|
+
"platform": "${platform}",
|
|
807
|
+
"region": "us-east-1",
|
|
808
|
+
"instanceType": "4gb",
|
|
809
|
+
"build": { "command": "npm run build", "output": "dist" }
|
|
810
|
+
}
|
|
811
|
+
\\\`\\\`\\\`
|
|
812
|
+
|
|
813
|
+
---
|
|
814
|
+
|
|
815
|
+
## IDE & CLI Integration
|
|
816
|
+
|
|
817
|
+
| Tool | Integration |
|
|
818
|
+
|------|-------------|
|
|
819
|
+
| **nom CLI** | \\\`npx @nometria-ai/nom deploy\\\` — deploy from terminal |
|
|
820
|
+
| **Claude Code** | Slash commands: \\\`/deploy\\\`, \\\`/preview\\\`, \\\`/status\\\`, \\\`/nometria-login\\\` |
|
|
821
|
+
| **Cursor** | Auto-rules in \\\`.cursor/rules/nometria.mdc\\\` |
|
|
822
|
+
| **VS Code / Cursor** | Extension: search "Nometria" in marketplace |
|
|
823
|
+
| **Any agent** | Read this file and use the curl commands above |
|
|
824
|
+
`;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
function writeContinueConfig(configPath) {
|
|
828
|
+
let config = {};
|
|
829
|
+
if (existsSync(configPath)) {
|
|
830
|
+
try {
|
|
831
|
+
config = JSON.parse(readFileSync(configPath, 'utf8'));
|
|
832
|
+
} catch { /* start fresh */ }
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
// Add/update MCP server config
|
|
836
|
+
if (!config.experimental) config.experimental = {};
|
|
837
|
+
if (!config.experimental.modelContextProtocolServers) config.experimental.modelContextProtocolServers = [];
|
|
838
|
+
|
|
839
|
+
const servers = config.experimental.modelContextProtocolServers;
|
|
840
|
+
const existing = servers.findIndex(s => s.name === 'nometria');
|
|
841
|
+
const nometriaServer = {
|
|
842
|
+
name: 'nometria',
|
|
843
|
+
command: 'npx',
|
|
844
|
+
args: ['@nometria-ai/claude-code'],
|
|
845
|
+
};
|
|
846
|
+
|
|
847
|
+
if (existing >= 0) {
|
|
848
|
+
servers[existing] = nometriaServer;
|
|
849
|
+
} else {
|
|
850
|
+
servers.push(nometriaServer);
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
854
|
+
}
|