@piagent/platform 1.1.9 → 1.2.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/CHANGELOG.md +43 -1
- package/README.md +2 -2
- package/docs/command-reference-vietnamese.md +13 -4
- package/docs/distribution-standard.md +7 -7
- package/docs/mcp-and-tools.md +108 -2
- package/docs/model-options.md +10 -8
- package/docs/operator-manual-vietnamese.md +12 -12
- package/docs/publishing-for-teams.md +1 -0
- package/docs/quickstart-vietnamese.md +2 -2
- package/docs/release-install-policy.md +6 -6
- package/docs/security-threat-model.md +1 -1
- package/docs/team-onboarding.md +4 -4
- package/docs/vercel-docs-site.md +34 -4
- package/docs-site/architecture.html +152 -0
- package/docs-site/assets/docs.css +1001 -0
- package/docs-site/assets/docs.js +84 -0
- package/docs-site/commands.html +203 -0
- package/docs-site/content/architecture.html +29 -0
- package/docs-site/content/commands.html +80 -0
- package/docs-site/content/index.html +80 -0
- package/docs-site/content/mcp-approval.html +81 -0
- package/docs-site/content/mcp-auth.html +76 -0
- package/docs-site/content/mcp-servers.html +111 -0
- package/docs-site/content/mcp.html +120 -0
- package/docs-site/content/permissions.html +54 -0
- package/docs-site/content/profiles.html +68 -0
- package/docs-site/content/quickstart.html +144 -0
- package/docs-site/content/runtime.html +45 -0
- package/docs-site/content/scope.html +71 -0
- package/docs-site/content/security.html +51 -0
- package/docs-site/content/team.html +23 -0
- package/docs-site/content/workflows.html +47 -0
- package/docs-site/index.html +131 -1534
- package/docs-site/mcp-approval.html +204 -0
- package/docs-site/mcp-auth.html +199 -0
- package/docs-site/mcp-servers.html +234 -0
- package/docs-site/mcp.html +243 -0
- package/docs-site/permissions.html +177 -0
- package/docs-site/profiles.html +191 -0
- package/docs-site/quickstart.html +267 -0
- package/docs-site/runtime.html +168 -0
- package/docs-site/scope.html +194 -0
- package/docs-site/security.html +174 -0
- package/docs-site/team.html +142 -0
- package/docs-site/workflows.html +170 -0
- package/package.json +4 -2
- package/packages/piagent-core/capabilities/capability-core.js +17 -1
- package/packages/piagent-core/extensions/document-intake.ts +5 -5
- package/packages/piagent-core/extensions/piagent-guard.ts +316 -0
- package/packages/piagent-core/mcp/mcp-approval-store.js +175 -0
- package/packages/piagent-core/mcp/mcp-auth-readiness.js +197 -0
- package/packages/piagent-core/mcp/mcp-command-actions.js +291 -0
- package/packages/piagent-core/mcp/mcp-config-layers.js +133 -0
- package/packages/piagent-core/mcp/mcp-server-catalog.js +150 -0
- package/packages/piagent-core/mcp/mcp-server-entry.js +242 -0
- package/packages/piagent-core/mcp/mcp-session-view.js +185 -0
- package/packages/piagent-core/package.json +7 -3
- package/packages/piagent-core/prompts/model-options.md +8 -8
- package/scripts/build-docs-site.mjs +421 -0
- package/scripts/configure-model-scope.sh +2 -2
- package/scripts/configure-subagents.sh +1 -1
- package/scripts/install-global.sh +5 -5
- package/scripts/mcp-manage.mjs +567 -0
- package/scripts/piagent-cli.mjs +1 -1
- package/scripts/preview-docs-site.mjs +88 -0
- package/scripts/setup.sh +2 -2
- package/scripts/team-doctor.sh +18 -2
- package/scripts/verify-local.sh +46 -19
- package/scripts/verify-release-identity.mjs +8 -2
- package/scripts/configure-mcp.sh +0 -349
package/scripts/team-doctor.sh
CHANGED
|
@@ -137,7 +137,7 @@ function runtimeMatrixStatus() {
|
|
|
137
137
|
surface: `${platform}/${arch}`,
|
|
138
138
|
status: "outside-release-matrix",
|
|
139
139
|
teamRolloutReady: false,
|
|
140
|
-
note: "This runtime is outside the documented v1.
|
|
140
|
+
note: "This runtime is outside the documented v1.2.0 support matrix."
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
143
|
|
|
@@ -169,7 +169,7 @@ for (const rel of [
|
|
|
169
169
|
"templates/project/.pi/memory/memory_summary.md",
|
|
170
170
|
"templates/project/.pi/memory/MEMORY.md",
|
|
171
171
|
"scripts/setup.sh",
|
|
172
|
-
"scripts/
|
|
172
|
+
"scripts/mcp-manage.mjs",
|
|
173
173
|
"scripts/configure-subagents.sh"
|
|
174
174
|
]) {
|
|
175
175
|
if (!exists(rel)) errors.push(`missing platform file: ${rel}`);
|
|
@@ -247,6 +247,22 @@ if (piHasMcpAdapter && totalMcpServers === 0) {
|
|
|
247
247
|
warnings.push("Pi MCP adapter is installed but no MCP servers are configured; run `piagent-mcp --preset core --scope global` or `/mcp setup`");
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
+
// Counting servers says nothing about whether any of them can answer. A server
|
|
251
|
+
// whose token is not exported, or which this repository defines and nobody
|
|
252
|
+
// approved, is configured and unusable, and finding that out when a call fails
|
|
253
|
+
// is the thing this check exists to prevent.
|
|
254
|
+
try {
|
|
255
|
+
const { collectServers } = await import(pathToFileURL(path.join(platformRoot, "packages", "piagent-core", "mcp", "mcp-config-layers.js")).href);
|
|
256
|
+
const { evaluateServerReadiness, BLOCKING_STATES } = await import(pathToFileURL(path.join(platformRoot, "packages", "piagent-core", "mcp", "mcp-auth-readiness.js")).href);
|
|
257
|
+
for (const server of collectServers({ projectPath })) {
|
|
258
|
+
const readiness = evaluateServerReadiness(server, { projectPath });
|
|
259
|
+
if (!BLOCKING_STATES.has(readiness.state)) continue;
|
|
260
|
+
warnings.push(`MCP server ${server.name} (${server.scope}) is configured but not usable: ${readiness.detail}${readiness.remedy ? `; ${readiness.remedy}` : ""}`);
|
|
261
|
+
}
|
|
262
|
+
} catch (error) {
|
|
263
|
+
warnings.push(`MCP readiness check could not run: ${error instanceof Error ? error.message : String(error)}`);
|
|
264
|
+
}
|
|
265
|
+
|
|
250
266
|
const subagentConfigPath = path.join(process.env.PI_CODING_AGENT_DIR || path.join(process.env.HOME || "", ".pi", "agent"), "extensions", "subagent", "config.json");
|
|
251
267
|
const subagentConfig = readJsonIfPresent(subagentConfigPath);
|
|
252
268
|
if (piHasSubagents && !subagentConfig) {
|
package/scripts/verify-local.sh
CHANGED
|
@@ -126,9 +126,16 @@ required_files=(
|
|
|
126
126
|
"$ROOT/docs/capability-packs.md"
|
|
127
127
|
"$ROOT/docs/runtime-policy-design.md"
|
|
128
128
|
"$ROOT/docs-site/index.html"
|
|
129
|
+
"$ROOT/docs-site/mcp.html"
|
|
129
130
|
"$ROOT/docs-site/favicon.svg"
|
|
130
131
|
"$ROOT/docs-site/assets/piagent-logo.svg"
|
|
132
|
+
"$ROOT/docs-site/assets/docs.css"
|
|
133
|
+
"$ROOT/docs-site/assets/docs.js"
|
|
134
|
+
"$ROOT/docs-site/content/index.html"
|
|
135
|
+
"$ROOT/docs-site/content/mcp.html"
|
|
131
136
|
"$ROOT/docs-site/vercel.json"
|
|
137
|
+
"$ROOT/scripts/build-docs-site.mjs"
|
|
138
|
+
"$ROOT/scripts/preview-docs-site.mjs"
|
|
132
139
|
"$ROOT/schemas/project-profile.schema.json"
|
|
133
140
|
"$ROOT/schemas/task-contract.schema.json"
|
|
134
141
|
"$ROOT/schemas/capability-pack.schema.json"
|
|
@@ -160,7 +167,7 @@ required_files=(
|
|
|
160
167
|
"$ROOT/scripts/pi-auto.sh"
|
|
161
168
|
"$ROOT/scripts/pi-model-catalog.sh"
|
|
162
169
|
"$ROOT/scripts/configure-model-scope.sh"
|
|
163
|
-
"$ROOT/scripts/
|
|
170
|
+
"$ROOT/scripts/mcp-manage.mjs"
|
|
164
171
|
"$ROOT/scripts/configure-subagents.sh"
|
|
165
172
|
"$ROOT/scripts/capability-catalog.mjs"
|
|
166
173
|
"$ROOT/scripts/migrate-project-state.mjs"
|
|
@@ -182,6 +189,9 @@ required_files=(
|
|
|
182
189
|
"$ROOT/tests/document-intake.test.mjs"
|
|
183
190
|
"$ROOT/tests/runtime-advisories.test.mjs"
|
|
184
191
|
"$ROOT/scripts/check-runtime-advisories.mjs"
|
|
192
|
+
"$ROOT/packages/piagent-core/mcp/mcp-session-view.js"
|
|
193
|
+
"$ROOT/packages/piagent-core/mcp/mcp-command-actions.js"
|
|
194
|
+
"$ROOT/tests/mcp-session-command.test.mjs"
|
|
185
195
|
"$ROOT/tests/migrate-project-state.test.mjs"
|
|
186
196
|
"$ROOT/tests/uninstall-global.test.mjs"
|
|
187
197
|
"$ROOT/tests/import-agent-instructions.test.mjs"
|
|
@@ -413,33 +423,33 @@ require_documented "gpt-5.6" "$ROOT/README.md" "$ROOT/docs/model-options.md" "$R
|
|
|
413
423
|
require_documented "claude-fable-5" "$ROOT/README.md" "$ROOT/docs/model-options.md" "$ROOT/packages/piagent-core/prompts/model-options.md"
|
|
414
424
|
require_documented "piagent-models" "$ROOT/README.md" "$ROOT/docs/model-options.md"
|
|
415
425
|
require_documented "enabledModels" "$ROOT/templates/global/settings.json" "$ROOT/docs/model-options.md" "$ROOT/scripts/configure-model-scope.sh"
|
|
416
|
-
require_documented "piagent-mcp" "$ROOT/README.md" "$ROOT/docs/mcp-and-tools.md" "$ROOT/scripts/
|
|
426
|
+
require_documented "piagent-mcp" "$ROOT/README.md" "$ROOT/docs/mcp-and-tools.md" "$ROOT/scripts/mcp-manage.mjs"
|
|
417
427
|
require_documented "pi-mcp-adapter" "$ROOT/README.md" "$ROOT/docs/mcp-and-tools.md" "$ROOT/scripts/install-global.sh"
|
|
418
428
|
require_documented "piagent-subagents" "$ROOT/README.md" "$ROOT/docs/subagents-and-multiagent.md" "$ROOT/scripts/configure-subagents.sh"
|
|
419
429
|
require_documented "subagents-fleet" "$ROOT/docs/command-reference-vietnamese.md" "$ROOT/docs/subagents-and-multiagent.md" "$ROOT/README.md"
|
|
420
430
|
require_documented "health check" "$ROOT/docs/command-reference-vietnamese.md" "$ROOT/docs/subagents-and-multiagent.md" "$ROOT/README.md"
|
|
421
431
|
require_documented "pi-subagents" "$ROOT/README.md" "$ROOT/docs/subagents-and-multiagent.md" "$ROOT/scripts/install-global.sh" "$ROOT/scripts/setup.sh"
|
|
422
432
|
require_documented "piagent-scout" "$ROOT/README.md" "$ROOT/docs/subagents-and-multiagent.md" "$ROOT/packages/piagent-core/subagents"
|
|
423
|
-
grep -F "@upstash/context7-mcp@3.2.4" "$ROOT/
|
|
433
|
+
grep -F "@upstash/context7-mcp@3.2.4" "$ROOT/packages/piagent-core/mcp/mcp-server-catalog.js" >/dev/null
|
|
424
434
|
grep -F "@upstash/context7-mcp@3.2.4" "$ROOT/docs/mcp-and-tools.md" >/dev/null
|
|
425
|
-
grep -F "chrome-devtools-mcp@1.6.0" "$ROOT/
|
|
435
|
+
grep -F "chrome-devtools-mcp@1.6.0" "$ROOT/packages/piagent-core/mcp/mcp-server-catalog.js" >/dev/null
|
|
426
436
|
grep -F "chrome-devtools-mcp@1.6.0" "$ROOT/docs/mcp-and-tools.md" >/dev/null
|
|
427
|
-
grep -F "@playwright/mcp@0.0.78" "$ROOT/
|
|
437
|
+
grep -F "@playwright/mcp@0.0.78" "$ROOT/packages/piagent-core/mcp/mcp-server-catalog.js" >/dev/null
|
|
428
438
|
grep -F "@playwright/mcp@0.0.78" "$ROOT/docs/mcp-and-tools.md" >/dev/null
|
|
429
|
-
require_documented "https://mcp.figma.com/mcp" "$ROOT/
|
|
430
|
-
grep -F "ghcr.io/github/github-mcp-server@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3" "$ROOT/
|
|
439
|
+
require_documented "https://mcp.figma.com/mcp" "$ROOT/packages/piagent-core/mcp/mcp-server-catalog.js" "$ROOT/docs/mcp-and-tools.md"
|
|
440
|
+
grep -F "ghcr.io/github/github-mcp-server@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3" "$ROOT/packages/piagent-core/mcp/mcp-server-catalog.js" >/dev/null
|
|
431
441
|
grep -F "ghcr.io/github/github-mcp-server@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3" "$ROOT/docs/mcp-and-tools.md" >/dev/null
|
|
432
|
-
grep -F '"GITHUB_READ_ONLY=1"' "$ROOT/
|
|
442
|
+
grep -F '"GITHUB_READ_ONLY=1"' "$ROOT/packages/piagent-core/mcp/mcp-server-catalog.js" >/dev/null
|
|
433
443
|
grep -F '"GITHUB_READ_ONLY=1"' "$ROOT/docs/mcp-and-tools.md" >/dev/null
|
|
434
|
-
grep -F '"GITHUB_LOCKDOWN_MODE=1"' "$ROOT/
|
|
444
|
+
grep -F '"GITHUB_LOCKDOWN_MODE=1"' "$ROOT/packages/piagent-core/mcp/mcp-server-catalog.js" >/dev/null
|
|
435
445
|
grep -F '"GITHUB_LOCKDOWN_MODE=1"' "$ROOT/docs/mcp-and-tools.md" >/dev/null
|
|
436
|
-
grep -F 'CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS: "1"' "$ROOT/
|
|
446
|
+
grep -F 'CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS: "1"' "$ROOT/packages/piagent-core/mcp/mcp-server-catalog.js" >/dev/null
|
|
437
447
|
grep -F '"CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS": "1"' "$ROOT/docs/mcp-and-tools.md" >/dev/null
|
|
438
|
-
grep -F 'CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS: "1"' "$ROOT/
|
|
448
|
+
grep -F 'CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS: "1"' "$ROOT/packages/piagent-core/mcp/mcp-server-catalog.js" >/dev/null
|
|
439
449
|
grep -F '"CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS": "1"' "$ROOT/docs/mcp-and-tools.md" >/dev/null
|
|
440
|
-
grep -F '
|
|
441
|
-
grep -F 'piagent-mcp --preset core --scope global --replace' "$ROOT/scripts/
|
|
442
|
-
if grep -E '@latest|"@upstash/context7-mcp"|"chrome-devtools-mcp"|"@playwright/mcp"|"ghcr\.io/github/github-mcp-server"' "$ROOT/
|
|
450
|
+
grep -F 'mcp-manage.mjs" --scope global --preset "$MCP_PRESET" --replace' "$ROOT/scripts/install-global.sh" >/dev/null
|
|
451
|
+
grep -F 'piagent-mcp --preset core --scope global --replace' "$ROOT/scripts/mcp-manage.mjs" >/dev/null
|
|
452
|
+
if grep -E '@latest|"@upstash/context7-mcp"|"chrome-devtools-mcp"|"@playwright/mcp"|"ghcr\.io/github/github-mcp-server"' "$ROOT/packages/piagent-core/mcp/mcp-server-catalog.js" >/dev/null; then
|
|
443
453
|
echo "MCP production presets contain a mutable dependency source"
|
|
444
454
|
exit 1
|
|
445
455
|
fi
|
|
@@ -471,6 +481,9 @@ const terms = [
|
|
|
471
481
|
["mit", "suhiko"].join(""),
|
|
472
482
|
["Cod", "ex CLI"].join(""),
|
|
473
483
|
["Claude", " CLI"].join(""),
|
|
484
|
+
["Claude", " Code"].join(""),
|
|
485
|
+
["claude", " mcp"].join(""),
|
|
486
|
+
["codex", " mcp"].join(""),
|
|
474
487
|
["Cod", "ex-inspired"].join(""),
|
|
475
488
|
["Cod", "ex-grade"].join(""),
|
|
476
489
|
["Pi vs ", "Codex"].join(""),
|
|
@@ -485,12 +498,21 @@ console.log(terms.map(escapeRegex).join("|"));
|
|
|
485
498
|
NODE
|
|
486
499
|
)"
|
|
487
500
|
|
|
501
|
+
# Every surface an outsider reads: the published docs, the site, and the strings
|
|
502
|
+
# the runtime prints back at an operator. The site is checked at its source,
|
|
503
|
+
# since `build-docs-site.mjs --check` separately proves the committed pages match
|
|
504
|
+
# it; the builder itself is listed too, because navigation labels and page titles
|
|
505
|
+
# live there rather than in a content fragment.
|
|
488
506
|
if grep -R -E -i \
|
|
489
507
|
"$public_wording_pattern" \
|
|
490
508
|
"$ROOT/README.md" \
|
|
491
509
|
"$ROOT/docs" \
|
|
510
|
+
"$ROOT/docs-site/content" \
|
|
511
|
+
"$ROOT/scripts/build-docs-site.mjs" \
|
|
492
512
|
"$ROOT/packages/piagent-core/README.md" \
|
|
493
513
|
"$ROOT/packages/piagent-core/prompts" \
|
|
514
|
+
"$ROOT/packages/piagent-core/mcp" \
|
|
515
|
+
"$ROOT/packages/piagent-core/extensions" \
|
|
494
516
|
"$ROOT/templates/project/AGENTS.md" >/dev/null; then
|
|
495
517
|
echo "Public docs contain non-neutral platform wording"
|
|
496
518
|
exit 1
|
|
@@ -509,6 +531,8 @@ node --check "$ROOT/scripts/migrate-project-state.mjs" >/dev/null
|
|
|
509
531
|
node --check "$ROOT/scripts/import-agent-instructions.mjs" >/dev/null
|
|
510
532
|
node --check "$ROOT/scripts/check-runtime-advisories.mjs" >/dev/null
|
|
511
533
|
node --check "$ROOT/scripts/check-published-site.mjs" >/dev/null
|
|
534
|
+
node --check "$ROOT/scripts/build-docs-site.mjs" >/dev/null
|
|
535
|
+
node --check "$ROOT/scripts/preview-docs-site.mjs" >/dev/null
|
|
512
536
|
run_quietly "npm test" npm test
|
|
513
537
|
if [[ -x "$ROOT/node_modules/.bin/tsc" ]]; then
|
|
514
538
|
run_quietly "npm run typecheck" npm run typecheck
|
|
@@ -519,7 +543,9 @@ bash -n "$ROOT/scripts/pi-session-stats.sh"
|
|
|
519
543
|
bash -n "$ROOT/scripts/pi-auto.sh"
|
|
520
544
|
bash -n "$ROOT/scripts/pi-model-catalog.sh"
|
|
521
545
|
bash -n "$ROOT/scripts/configure-model-scope.sh"
|
|
522
|
-
|
|
546
|
+
node --check "$ROOT/scripts/mcp-manage.mjs"
|
|
547
|
+
node --check "$ROOT/packages/piagent-core/mcp/mcp-session-view.js"
|
|
548
|
+
node --check "$ROOT/packages/piagent-core/mcp/mcp-command-actions.js"
|
|
523
549
|
bash -n "$ROOT/scripts/configure-subagents.sh"
|
|
524
550
|
bash -n "$ROOT/scripts/install-global.sh"
|
|
525
551
|
bash -n "$ROOT/scripts/init-project.sh"
|
|
@@ -531,8 +557,8 @@ else
|
|
|
531
557
|
bash "$ROOT/scripts/pi-model-catalog.sh" --json >/dev/null
|
|
532
558
|
fi
|
|
533
559
|
bash "$ROOT/scripts/configure-model-scope.sh" --dry-run --preset full --default-model openai-codex/gpt-5.5:xhigh >/dev/null
|
|
534
|
-
|
|
535
|
-
|
|
560
|
+
node "$ROOT/scripts/mcp-manage.mjs" --list >/dev/null
|
|
561
|
+
node "$ROOT/scripts/mcp-manage.mjs" --dry-run --preset popular --scope project --project "$ROOT" >/dev/null
|
|
536
562
|
node --input-type=module - "$ROOT" <<'NODE'
|
|
537
563
|
import assert from "node:assert/strict";
|
|
538
564
|
import { execFileSync } from "node:child_process";
|
|
@@ -553,8 +579,8 @@ try {
|
|
|
553
579
|
internal: { url: "https://mcp.example.invalid/api" }
|
|
554
580
|
}
|
|
555
581
|
}, null, 2)}\n`);
|
|
556
|
-
execFileSync(
|
|
557
|
-
path.join(root, "scripts", "
|
|
582
|
+
execFileSync(process.execPath, [
|
|
583
|
+
path.join(root, "scripts", "mcp-manage.mjs"),
|
|
558
584
|
"--config", configPath,
|
|
559
585
|
"--preset", "popular",
|
|
560
586
|
"--replace"
|
|
@@ -577,6 +603,7 @@ bash "$ROOT/scripts/configure-subagents.sh" --list >/dev/null
|
|
|
577
603
|
bash "$ROOT/scripts/configure-subagents.sh" --dry-run --preset safe >/dev/null
|
|
578
604
|
bash "$ROOT/scripts/runtime-policy-smoke.sh" >/dev/null
|
|
579
605
|
|
|
606
|
+
node "$ROOT/scripts/build-docs-site.mjs" --check >/dev/null
|
|
580
607
|
node "$ROOT/scripts/capability-catalog.mjs" catalog --check >/dev/null
|
|
581
608
|
node "$ROOT/scripts/capability-catalog.mjs" doctor --profile "$ROOT/.pi/piagent-profile.json" --lock "$ROOT/.pi/piagent-profile.lock.json" >/dev/null
|
|
582
609
|
node "$ROOT/scripts/capability-catalog.mjs" doctor --profile "$ROOT/adapters/generic/profile.json" >/dev/null
|
|
@@ -71,8 +71,14 @@ if (capabilityLock.core?.packageVersion !== version) fail("capability lock packa
|
|
|
71
71
|
const changelog = fs.readFileSync(path.join(root, "CHANGELOG.md"), "utf8");
|
|
72
72
|
if (!changelog.includes(`## ${expectedTag} -`)) fail(`CHANGELOG.md has no ${expectedTag} release section`);
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
// The badge is generated onto every page, so a stale build shows up as one page
|
|
75
|
+
// still carrying the previous version rather than as a single missed edit.
|
|
76
|
+
const docsPages = fs.readdirSync(path.join(root, "docs-site")).filter((name) => name.endsWith(".html"));
|
|
77
|
+
if (docsPages.length === 0) fail("docs-site has no generated pages");
|
|
78
|
+
for (const page of docsPages) {
|
|
79
|
+
const html = fs.readFileSync(path.join(root, "docs-site", page), "utf8");
|
|
80
|
+
if (!html.includes(`${expectedTag} docs`)) fail(`docs-site/${page} version badge does not identify ${expectedTag}`);
|
|
81
|
+
}
|
|
76
82
|
|
|
77
83
|
if (options.tag) {
|
|
78
84
|
if (options.tag !== expectedTag) fail(`release tag ${options.tag} does not match package version ${expectedTag}`);
|
package/scripts/configure-mcp.sh
DELETED
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
set -euo pipefail
|
|
3
|
-
|
|
4
|
-
usage() {
|
|
5
|
-
cat <<'USAGE'
|
|
6
|
-
Usage:
|
|
7
|
-
scripts/configure-mcp.sh [options]
|
|
8
|
-
|
|
9
|
-
Purpose:
|
|
10
|
-
Merge a safe MCP baseline into a standard MCP config file for Pi and other MCP clients.
|
|
11
|
-
Secrets are never written directly; configs reference environment variables.
|
|
12
|
-
|
|
13
|
-
Options:
|
|
14
|
-
--scope <global|pi-global|project|pi-project>
|
|
15
|
-
Config target (default: global)
|
|
16
|
-
--project <path> Project path for project/pi-project scopes (default: current directory)
|
|
17
|
-
--config <path> Explicit config path; overrides --scope/--project
|
|
18
|
-
--preset <minimal|docs|browser|github|design|design-local|web|core|popular|all>
|
|
19
|
-
MCP preset to merge (default: core)
|
|
20
|
-
--replace Replace existing definitions for servers in the preset
|
|
21
|
-
--dry-run Print the merged JSON without writing
|
|
22
|
-
--list Print available presets/servers
|
|
23
|
-
-h, --help
|
|
24
|
-
|
|
25
|
-
Recommended presets:
|
|
26
|
-
core Context7 docs + Chrome DevTools + GitHub
|
|
27
|
-
popular core + Playwright + Figma remote MCP
|
|
28
|
-
all popular + Figma desktop/local MCP
|
|
29
|
-
|
|
30
|
-
Examples:
|
|
31
|
-
piagent-mcp --preset core --scope global --replace
|
|
32
|
-
piagent-mcp --preset popular --scope project --project /path/to/repo
|
|
33
|
-
piagent-mcp --preset design-local --scope project
|
|
34
|
-
|
|
35
|
-
After writing config:
|
|
36
|
-
pi
|
|
37
|
-
/mcp
|
|
38
|
-
/mcp setup
|
|
39
|
-
/mcp reconnect
|
|
40
|
-
USAGE
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
PLATFORM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
44
|
-
SCOPE="global"
|
|
45
|
-
PROJECT_PATH="$PWD"
|
|
46
|
-
CONFIG_PATH=""
|
|
47
|
-
PRESET="core"
|
|
48
|
-
REPLACE=false
|
|
49
|
-
DRY_RUN=false
|
|
50
|
-
LIST=false
|
|
51
|
-
# Answers "is this preset name real?" and writes nothing, so a caller can reject
|
|
52
|
-
# a bad preset before it installs anything.
|
|
53
|
-
VALIDATE_PRESET=false
|
|
54
|
-
|
|
55
|
-
while [[ $# -gt 0 ]]; do
|
|
56
|
-
case "$1" in
|
|
57
|
-
--scope)
|
|
58
|
-
SCOPE="${2:-}"
|
|
59
|
-
shift 2
|
|
60
|
-
;;
|
|
61
|
-
--project)
|
|
62
|
-
PROJECT_PATH="${2:-}"
|
|
63
|
-
shift 2
|
|
64
|
-
;;
|
|
65
|
-
--config)
|
|
66
|
-
CONFIG_PATH="${2:-}"
|
|
67
|
-
shift 2
|
|
68
|
-
;;
|
|
69
|
-
--preset)
|
|
70
|
-
PRESET="${2:-}"
|
|
71
|
-
shift 2
|
|
72
|
-
;;
|
|
73
|
-
--replace)
|
|
74
|
-
REPLACE=true
|
|
75
|
-
shift
|
|
76
|
-
;;
|
|
77
|
-
--dry-run)
|
|
78
|
-
DRY_RUN=true
|
|
79
|
-
shift
|
|
80
|
-
;;
|
|
81
|
-
--list)
|
|
82
|
-
LIST=true
|
|
83
|
-
shift
|
|
84
|
-
;;
|
|
85
|
-
--validate-preset)
|
|
86
|
-
VALIDATE_PRESET=true
|
|
87
|
-
shift
|
|
88
|
-
;;
|
|
89
|
-
-h|--help)
|
|
90
|
-
usage
|
|
91
|
-
exit 0
|
|
92
|
-
;;
|
|
93
|
-
*)
|
|
94
|
-
echo "Unknown option: $1" >&2
|
|
95
|
-
usage >&2
|
|
96
|
-
exit 2
|
|
97
|
-
;;
|
|
98
|
-
esac
|
|
99
|
-
done
|
|
100
|
-
|
|
101
|
-
if [[ -z "$PRESET" ]]; then
|
|
102
|
-
echo "FAIL: --preset cannot be empty" >&2
|
|
103
|
-
exit 2
|
|
104
|
-
fi
|
|
105
|
-
|
|
106
|
-
if [[ -z "$CONFIG_PATH" ]]; then
|
|
107
|
-
case "$SCOPE" in
|
|
108
|
-
global)
|
|
109
|
-
CONFIG_PATH="${XDG_CONFIG_HOME:-"${HOME}/.config"}/mcp/mcp.json"
|
|
110
|
-
;;
|
|
111
|
-
pi-global)
|
|
112
|
-
CONFIG_PATH="${PI_CODING_AGENT_DIR:-"${HOME}/.pi/agent"}/mcp.json"
|
|
113
|
-
;;
|
|
114
|
-
project)
|
|
115
|
-
CONFIG_PATH="$PROJECT_PATH/.mcp.json"
|
|
116
|
-
;;
|
|
117
|
-
pi-project)
|
|
118
|
-
CONFIG_PATH="$PROJECT_PATH/.pi/mcp.json"
|
|
119
|
-
;;
|
|
120
|
-
*)
|
|
121
|
-
echo "FAIL: unsupported scope: $SCOPE" >&2
|
|
122
|
-
usage >&2
|
|
123
|
-
exit 2
|
|
124
|
-
;;
|
|
125
|
-
esac
|
|
126
|
-
fi
|
|
127
|
-
|
|
128
|
-
node --input-type=module - "$CONFIG_PATH" "$PRESET" "$REPLACE" "$DRY_RUN" "$LIST" "$VALIDATE_PRESET" <<'NODE'
|
|
129
|
-
import fs from "node:fs";
|
|
130
|
-
import path from "node:path";
|
|
131
|
-
|
|
132
|
-
const [configPath, presetName, replaceRaw, dryRunRaw, listRaw, validateRaw] = process.argv.slice(2);
|
|
133
|
-
const replace = replaceRaw === "true";
|
|
134
|
-
const dryRun = dryRunRaw === "true";
|
|
135
|
-
const listOnly = listRaw === "true";
|
|
136
|
-
const validateOnly = validateRaw === "true";
|
|
137
|
-
|
|
138
|
-
const baselineSettings = {
|
|
139
|
-
toolPrefix: "server",
|
|
140
|
-
directTools: false,
|
|
141
|
-
idleTimeout: 10,
|
|
142
|
-
outputGuard: true
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const servers = {
|
|
146
|
-
context7: {
|
|
147
|
-
description: "Official Context7 MCP server for up-to-date library/framework docs.",
|
|
148
|
-
config: {
|
|
149
|
-
command: "npx",
|
|
150
|
-
args: ["-y", "@upstash/context7-mcp@3.2.4"],
|
|
151
|
-
env: {
|
|
152
|
-
CONTEXT7_API_KEY: "${CONTEXT7_API_KEY}"
|
|
153
|
-
},
|
|
154
|
-
lifecycle: "lazy",
|
|
155
|
-
directTools: false
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
"chrome-devtools": {
|
|
159
|
-
description: "Chrome DevTools MCP for runtime browser inspection, console logs, screenshots, and performance checks.",
|
|
160
|
-
config: {
|
|
161
|
-
command: "npx",
|
|
162
|
-
args: ["-y", "chrome-devtools-mcp@1.6.0", "--no-performance-crux"],
|
|
163
|
-
env: {
|
|
164
|
-
CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS: "1",
|
|
165
|
-
CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS: "1"
|
|
166
|
-
},
|
|
167
|
-
lifecycle: "lazy",
|
|
168
|
-
directTools: false
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
playwright: {
|
|
172
|
-
description: "Playwright MCP for browser automation and UI verification workflows.",
|
|
173
|
-
config: {
|
|
174
|
-
command: "npx",
|
|
175
|
-
args: ["-y", "@playwright/mcp@0.0.78"],
|
|
176
|
-
lifecycle: "lazy",
|
|
177
|
-
directTools: false
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
github: {
|
|
181
|
-
description: "Official GitHub MCP server via Docker. Requires Docker and GITHUB_PERSONAL_ACCESS_TOKEN when used.",
|
|
182
|
-
config: {
|
|
183
|
-
command: "docker",
|
|
184
|
-
args: [
|
|
185
|
-
"run",
|
|
186
|
-
"-i",
|
|
187
|
-
"--rm",
|
|
188
|
-
"-e",
|
|
189
|
-
"GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
190
|
-
"-e",
|
|
191
|
-
"GITHUB_READ_ONLY=1",
|
|
192
|
-
"-e",
|
|
193
|
-
"GITHUB_LOCKDOWN_MODE=1",
|
|
194
|
-
"ghcr.io/github/github-mcp-server@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"
|
|
195
|
-
],
|
|
196
|
-
env: {
|
|
197
|
-
GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_PERSONAL_ACCESS_TOKEN}"
|
|
198
|
-
},
|
|
199
|
-
lifecycle: "lazy",
|
|
200
|
-
directTools: false
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
figma: {
|
|
204
|
-
description: "Figma remote MCP server. Requires Figma OAuth from the MCP panel when first used.",
|
|
205
|
-
config: {
|
|
206
|
-
url: "https://mcp.figma.com/mcp",
|
|
207
|
-
auth: "oauth",
|
|
208
|
-
lifecycle: "lazy",
|
|
209
|
-
directTools: false
|
|
210
|
-
}
|
|
211
|
-
},
|
|
212
|
-
"figma-desktop": {
|
|
213
|
-
description: "Figma desktop/local MCP server. Requires Figma desktop Dev Mode MCP enabled.",
|
|
214
|
-
config: {
|
|
215
|
-
url: "http://127.0.0.1:3845/mcp",
|
|
216
|
-
lifecycle: "lazy",
|
|
217
|
-
directTools: false
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
// Writing a server definition does not make it usable. What each one still
|
|
223
|
-
// needs from the operator is stated here so it can be printed at the moment the
|
|
224
|
-
// definition is written, rather than living only in a description string that
|
|
225
|
-
// shows up under --list.
|
|
226
|
-
const prerequisites = {
|
|
227
|
-
context7: ["optional: export CONTEXT7_API_KEY for a higher documentation quota"],
|
|
228
|
-
"chrome-devtools": ["a local Chrome installation"],
|
|
229
|
-
github: [
|
|
230
|
-
"Docker running",
|
|
231
|
-
"export GITHUB_PERSONAL_ACCESS_TOKEN with the scopes you intend to use"
|
|
232
|
-
],
|
|
233
|
-
playwright: ["browsers installed on first use (npx playwright install)"],
|
|
234
|
-
figma: ["Figma OAuth, completed from the Pi MCP panel on first use"],
|
|
235
|
-
"figma-desktop": ["Figma desktop running with Dev Mode MCP enabled"]
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
const presets = {
|
|
239
|
-
minimal: [],
|
|
240
|
-
docs: ["context7"],
|
|
241
|
-
browser: ["chrome-devtools", "playwright"],
|
|
242
|
-
github: ["github"],
|
|
243
|
-
design: ["figma"],
|
|
244
|
-
"design-local": ["figma-desktop"],
|
|
245
|
-
web: ["context7", "chrome-devtools", "playwright"],
|
|
246
|
-
core: ["context7", "chrome-devtools", "github"],
|
|
247
|
-
popular: ["context7", "chrome-devtools", "playwright", "github", "figma"],
|
|
248
|
-
all: ["context7", "chrome-devtools", "playwright", "github", "figma", "figma-desktop"]
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
if (listOnly) {
|
|
252
|
-
console.log(JSON.stringify({
|
|
253
|
-
presets,
|
|
254
|
-
servers: Object.fromEntries(Object.entries(servers).map(([name, value]) => [
|
|
255
|
-
name,
|
|
256
|
-
{ description: value.description, requires: prerequisites[name] ?? [] }
|
|
257
|
-
]))
|
|
258
|
-
}, null, 2));
|
|
259
|
-
process.exit(0);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
if (!Object.hasOwn(presets, presetName)) {
|
|
263
|
-
console.error(`FAIL: unknown preset: ${presetName}`);
|
|
264
|
-
console.error(`Available presets: ${Object.keys(presets).join(", ")}`);
|
|
265
|
-
process.exit(2);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// Answering the name question and stopping, so a caller can ask before it
|
|
269
|
-
// installs rather than discovering the typo after two packages have landed.
|
|
270
|
-
if (validateOnly) {
|
|
271
|
-
process.stdout.write(`${presetName}\n`);
|
|
272
|
-
process.exit(0);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
let current = {};
|
|
276
|
-
if (fs.existsSync(configPath)) {
|
|
277
|
-
try {
|
|
278
|
-
current = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
279
|
-
} catch (error) {
|
|
280
|
-
console.error(`FAIL: cannot parse existing MCP config: ${configPath}`);
|
|
281
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
282
|
-
process.exit(1);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
if (!current || typeof current !== "object" || Array.isArray(current)) current = {};
|
|
287
|
-
if (!current.settings || typeof current.settings !== "object" || Array.isArray(current.settings)) current.settings = {};
|
|
288
|
-
if (!current.mcpServers || typeof current.mcpServers !== "object" || Array.isArray(current.mcpServers)) current.mcpServers = {};
|
|
289
|
-
|
|
290
|
-
current.settings = {
|
|
291
|
-
...baselineSettings,
|
|
292
|
-
...current.settings
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
const added = [];
|
|
296
|
-
const kept = [];
|
|
297
|
-
const replaced = [];
|
|
298
|
-
for (const name of presets[presetName]) {
|
|
299
|
-
if (!Object.hasOwn(servers, name)) {
|
|
300
|
-
throw new Error(`Preset ${presetName} references missing server ${name}`);
|
|
301
|
-
}
|
|
302
|
-
if (Object.hasOwn(current.mcpServers, name)) {
|
|
303
|
-
if (replace) {
|
|
304
|
-
current.mcpServers[name] = servers[name].config;
|
|
305
|
-
replaced.push(name);
|
|
306
|
-
} else {
|
|
307
|
-
kept.push(name);
|
|
308
|
-
}
|
|
309
|
-
} else {
|
|
310
|
-
current.mcpServers[name] = servers[name].config;
|
|
311
|
-
added.push(name);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
const output = `${JSON.stringify(current, null, 2)}\n`;
|
|
316
|
-
const report = {
|
|
317
|
-
configPath,
|
|
318
|
-
preset: presetName,
|
|
319
|
-
dryRun,
|
|
320
|
-
replace,
|
|
321
|
-
added,
|
|
322
|
-
kept,
|
|
323
|
-
replaced,
|
|
324
|
-
serverCount: Object.keys(current.mcpServers).length
|
|
325
|
-
};
|
|
326
|
-
|
|
327
|
-
// stdout stays machine-readable; the operator note goes to stderr.
|
|
328
|
-
function reportPrerequisites() {
|
|
329
|
-
const lines = [];
|
|
330
|
-
for (const name of presets[presetName]) {
|
|
331
|
-
for (const item of prerequisites[name] ?? []) lines.push(` ${name}: ${item}`);
|
|
332
|
-
}
|
|
333
|
-
if (lines.length === 0) return;
|
|
334
|
-
console.error("");
|
|
335
|
-
console.error("Server definitions are written. Each still needs this before it can connect:");
|
|
336
|
-
for (const line of lines) console.error(line);
|
|
337
|
-
console.error("Servers connect lazily, so nothing above is checked until the first call.");
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
if (dryRun) {
|
|
341
|
-
console.log(JSON.stringify(report, null, 2));
|
|
342
|
-
console.log(output);
|
|
343
|
-
} else {
|
|
344
|
-
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
345
|
-
fs.writeFileSync(configPath, output);
|
|
346
|
-
console.log(JSON.stringify(report, null, 2));
|
|
347
|
-
reportPrerequisites();
|
|
348
|
-
}
|
|
349
|
-
NODE
|