openuispec 0.1.37 → 0.1.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/cli/init.ts +91 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ cd your-project
|
|
|
52
52
|
openuispec init
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
This scaffolds a spec directory, starter tokens, adds rules to `CLAUDE.md` / `AGENTS.md`, and configures the MCP server
|
|
55
|
+
This scaffolds a spec directory, starter tokens, adds rules to `CLAUDE.md` / `AGENTS.md`, and configures the MCP server so AI assistants track spec changes automatically.
|
|
56
56
|
Use `openuispec init --no-configure-targets` if you want to scaffold first and choose target stacks later.
|
|
57
57
|
|
|
58
58
|
Then hand your spec to any AI code generator:
|
|
@@ -251,8 +251,9 @@ OpenUISpec includes an MCP (Model Context Protocol) server that exposes CLI comm
|
|
|
251
251
|
|
|
252
252
|
### Setup
|
|
253
253
|
|
|
254
|
-
`openuispec init` automatically configures the MCP server
|
|
254
|
+
`openuispec init` automatically configures the MCP server for your coding agent. For existing projects, run `openuispec update-rules` or add the config manually:
|
|
255
255
|
|
|
256
|
+
**Claude Code** (`.mcp.json`), **VS Code / Copilot** (`.vscode/mcp.json`):
|
|
256
257
|
```json
|
|
257
258
|
{
|
|
258
259
|
"mcpServers": {
|
|
@@ -264,6 +265,13 @@ OpenUISpec includes an MCP (Model Context Protocol) server that exposes CLI comm
|
|
|
264
265
|
}
|
|
265
266
|
```
|
|
266
267
|
|
|
268
|
+
**Codex** (`.codex/config.toml`):
|
|
269
|
+
```toml
|
|
270
|
+
[mcp_servers.openuispec]
|
|
271
|
+
command = "openuispec"
|
|
272
|
+
args = ["mcp"]
|
|
273
|
+
```
|
|
274
|
+
|
|
267
275
|
Or run directly: `openuispec mcp`
|
|
268
276
|
|
|
269
277
|
Set `OPENUISPEC_PROJECT_DIR` to override the working directory.
|
package/cli/init.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
readdirSync,
|
|
15
15
|
existsSync,
|
|
16
16
|
appendFileSync,
|
|
17
|
+
unlinkSync,
|
|
17
18
|
} from "node:fs";
|
|
18
19
|
import { join, relative, dirname, resolve } from "node:path";
|
|
19
20
|
import { fileURLToPath } from "node:url";
|
|
@@ -263,7 +264,7 @@ Do NOT guess the file format — skipping this step will produce invalid YAML th
|
|
|
263
264
|
|
|
264
265
|
## MCP Tools (recommended for AI assistants)
|
|
265
266
|
|
|
266
|
-
When the openuispec MCP server is configured
|
|
267
|
+
When the openuispec MCP server is configured, AI assistants should use these tools instead of CLI commands:
|
|
267
268
|
|
|
268
269
|
| Tool | When to use |
|
|
269
270
|
|------|-------------|
|
|
@@ -481,35 +482,104 @@ const EXPECTED_MCP_CONFIG = {
|
|
|
481
482
|
args: ["mcp"],
|
|
482
483
|
};
|
|
483
484
|
|
|
484
|
-
|
|
485
|
-
|
|
485
|
+
/**
|
|
486
|
+
* MCP config files by agent:
|
|
487
|
+
* .mcp.json — Claude Code (project scope)
|
|
488
|
+
* .vscode/mcp.json — VS Code / Copilot Chat
|
|
489
|
+
*
|
|
490
|
+
* All use the same { mcpServers: { openuispec: { command, args } } } shape.
|
|
491
|
+
*/
|
|
492
|
+
const JSON_MCP_PATHS = [
|
|
493
|
+
".mcp.json",
|
|
494
|
+
join(".vscode", "mcp.json"),
|
|
495
|
+
];
|
|
496
|
+
|
|
497
|
+
/** Codex uses TOML: .codex/config.toml */
|
|
498
|
+
const CODEX_CONFIG_PATH = join(".codex", "config.toml");
|
|
499
|
+
const CODEX_MCP_BLOCK = `\n[mcp_servers.openuispec]\ncommand = "openuispec"\nargs = ["mcp"]\n`;
|
|
486
500
|
|
|
501
|
+
function configureCodexMcp(cwd: string, quiet: boolean): void {
|
|
502
|
+
const codexDir = join(cwd, ".codex");
|
|
503
|
+
if (!existsSync(codexDir)) return;
|
|
504
|
+
|
|
505
|
+
const configPath = join(codexDir, "config.toml");
|
|
487
506
|
try {
|
|
488
|
-
let
|
|
507
|
+
let content = "";
|
|
489
508
|
try {
|
|
490
|
-
|
|
509
|
+
content = readFileSync(configPath, "utf-8");
|
|
491
510
|
} catch {
|
|
492
|
-
// file doesn't exist
|
|
511
|
+
// file doesn't exist — will create
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
if (content.includes("[mcp_servers.openuispec]")) {
|
|
515
|
+
if (!quiet) console.log(` skip ${CODEX_CONFIG_PATH} (openuispec MCP already configured)`);
|
|
516
|
+
return;
|
|
493
517
|
}
|
|
494
518
|
|
|
495
|
-
|
|
519
|
+
writeFileSync(configPath, content + CODEX_MCP_BLOCK);
|
|
520
|
+
if (!quiet) console.log(` ${content ? "update" : "create"} ${CODEX_CONFIG_PATH} (MCP server configured)`);
|
|
521
|
+
} catch {
|
|
522
|
+
if (!quiet) console.log(` skip ${CODEX_CONFIG_PATH} (could not configure MCP server)`);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
function configureMcp(cwd: string, showRestart: boolean, quiet: boolean = false): void {
|
|
527
|
+
for (const relPath of JSON_MCP_PATHS) {
|
|
528
|
+
const configPath = join(cwd, relPath);
|
|
496
529
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
!existing ||
|
|
500
|
-
existing.command !== EXPECTED_MCP_CONFIG.command ||
|
|
501
|
-
JSON.stringify(existing.args) !== JSON.stringify(EXPECTED_MCP_CONFIG.args);
|
|
530
|
+
// .vscode/mcp.json: only write if .vscode/ already exists
|
|
531
|
+
if (relPath.startsWith(".vscode") && !existsSync(join(cwd, ".vscode"))) continue;
|
|
502
532
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
533
|
+
try {
|
|
534
|
+
let config: Record<string, any> = {};
|
|
535
|
+
try {
|
|
536
|
+
config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
537
|
+
} catch {
|
|
538
|
+
// file doesn't exist or isn't valid JSON — start fresh
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
if (!config.mcpServers) config.mcpServers = {};
|
|
542
|
+
|
|
543
|
+
const existing = config.mcpServers.openuispec;
|
|
544
|
+
const needsUpdate =
|
|
545
|
+
!existing ||
|
|
546
|
+
existing.command !== EXPECTED_MCP_CONFIG.command ||
|
|
547
|
+
JSON.stringify(existing.args) !== JSON.stringify(EXPECTED_MCP_CONFIG.args);
|
|
548
|
+
|
|
549
|
+
if (needsUpdate) {
|
|
550
|
+
config.mcpServers.openuispec = { ...EXPECTED_MCP_CONFIG };
|
|
551
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
552
|
+
if (!quiet) console.log(` ${existing ? "update" : "create"} ${relPath} (MCP server configured)`);
|
|
553
|
+
} else {
|
|
554
|
+
if (!quiet) console.log(` skip ${relPath} (openuispec MCP already configured)`);
|
|
555
|
+
}
|
|
556
|
+
} catch {
|
|
557
|
+
if (!quiet) console.log(` skip ${relPath} (could not configure MCP server)`);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// Codex: .codex/config.toml (TOML format)
|
|
562
|
+
configureCodexMcp(cwd, quiet);
|
|
563
|
+
|
|
564
|
+
if (showRestart) console.log(`\n Restart your AI coding agent to activate the MCP server.`);
|
|
565
|
+
|
|
566
|
+
// Clean up stale .claude.json MCP config from older versions
|
|
567
|
+
const claudeJsonPath = join(cwd, ".claude.json");
|
|
568
|
+
try {
|
|
569
|
+
const claudeJson = JSON.parse(readFileSync(claudeJsonPath, "utf-8"));
|
|
570
|
+
if (claudeJson.mcpServers?.openuispec) {
|
|
571
|
+
delete claudeJson.mcpServers.openuispec;
|
|
572
|
+
if (Object.keys(claudeJson.mcpServers).length === 0) delete claudeJson.mcpServers;
|
|
573
|
+
if (Object.keys(claudeJson).length === 0) {
|
|
574
|
+
unlinkSync(claudeJsonPath);
|
|
575
|
+
if (!quiet) console.log(` remove .claude.json (migrated MCP config)`);
|
|
576
|
+
} else {
|
|
577
|
+
writeFileSync(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
|
|
578
|
+
if (!quiet) console.log(` update .claude.json (removed stale MCP config)`);
|
|
579
|
+
}
|
|
510
580
|
}
|
|
511
581
|
} catch {
|
|
512
|
-
|
|
582
|
+
// .claude.json doesn't exist or not parseable — nothing to clean up
|
|
513
583
|
}
|
|
514
584
|
}
|
|
515
585
|
|
|
@@ -825,7 +895,7 @@ Commands:
|
|
|
825
895
|
openuispec drift --snapshot --target ios Save current state + git baseline after target output exists
|
|
826
896
|
|
|
827
897
|
AI rules have been added to CLAUDE.md and AGENTS.md.
|
|
828
|
-
MCP server configured
|
|
898
|
+
MCP server configured (AI assistants will use openuispec tools automatically).
|
|
829
899
|
|
|
830
900
|
Docs: https://openuispec.rsteam.uz
|
|
831
901
|
`);
|