@piagent/platform 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/.gitattributes +7 -0
  2. package/AGENTS.md +31 -0
  3. package/CHANGELOG.md +296 -0
  4. package/CODE_OF_CONDUCT.md +36 -0
  5. package/CONTRIBUTING.md +66 -0
  6. package/LICENSE +21 -0
  7. package/README.md +588 -0
  8. package/SECURITY.md +38 -0
  9. package/adapters/backend-api/profile.json +88 -0
  10. package/adapters/be-readonly-fe/profile.json +120 -0
  11. package/adapters/data/profile.json +88 -0
  12. package/adapters/devops/profile.json +92 -0
  13. package/adapters/docs/profile.json +74 -0
  14. package/adapters/fullstack/profile.json +94 -0
  15. package/adapters/generic/profile.json +95 -0
  16. package/adapters/mobile/profile.json +87 -0
  17. package/adapters/node-typescript/profile.json +76 -0
  18. package/adapters/python/profile.json +75 -0
  19. package/adapters/web-frontend/profile.json +101 -0
  20. package/catalog/capabilities.json +206 -0
  21. package/docs/architecture.md +64 -0
  22. package/docs/auto-delegation-policy.md +192 -0
  23. package/docs/capability-packs.md +234 -0
  24. package/docs/command-reference-vietnamese.md +484 -0
  25. package/docs/context-window-policy.md +85 -0
  26. package/docs/distribution-standard.md +229 -0
  27. package/docs/herdr-workflow.md +58 -0
  28. package/docs/mcp-and-tools.md +316 -0
  29. package/docs/memory-policy.md +164 -0
  30. package/docs/model-options.md +165 -0
  31. package/docs/oauth-providers.md +53 -0
  32. package/docs/operator-manual-vietnamese.md +1080 -0
  33. package/docs/package-architecture-notes.md +101 -0
  34. package/docs/project-adapters.md +174 -0
  35. package/docs/project-onboarding.md +135 -0
  36. package/docs/publishing-for-teams.md +64 -0
  37. package/docs/quality-benchmark.md +74 -0
  38. package/docs/quickstart-vietnamese.md +350 -0
  39. package/docs/release-install-policy.md +223 -0
  40. package/docs/runtime-harness-standard.md +118 -0
  41. package/docs/runtime-policy-design.md +132 -0
  42. package/docs/runtime-quality-baseline.md +257 -0
  43. package/docs/security-redaction-benchmark.md +56 -0
  44. package/docs/security-threat-model.md +66 -0
  45. package/docs/subagent-orchestration-capabilities.md +104 -0
  46. package/docs/subagents-and-multiagent.md +346 -0
  47. package/docs/task-implementation-contract.md +200 -0
  48. package/docs/team-onboarding.md +333 -0
  49. package/docs/usage-observability.md +130 -0
  50. package/docs/vercel-docs-site.md +115 -0
  51. package/docs/workflow-recipes.md +125 -0
  52. package/docs-site/assets/piagent-logo.svg +35 -0
  53. package/docs-site/favicon.svg +18 -0
  54. package/docs-site/index.html +1613 -0
  55. package/docs-site/vercel.json +24 -0
  56. package/evals/fixtures/action-proposal.invalid.json +34 -0
  57. package/evals/fixtures/action-proposal.valid.json +34 -0
  58. package/evals/fixtures/capability-pack.invalid.json +123 -0
  59. package/evals/fixtures/capability-pack.valid.json +123 -0
  60. package/evals/fixtures/capability-recipe.invalid.json +81 -0
  61. package/evals/fixtures/capability-recipe.valid.json +82 -0
  62. package/evals/fixtures/context-index.invalid.json +25 -0
  63. package/evals/fixtures/context-index.valid.json +25 -0
  64. package/evals/fixtures/eval-scenario.invalid.json +40 -0
  65. package/evals/fixtures/eval-scenario.valid.json +45 -0
  66. package/evals/fixtures/project-profile.invalid.json +88 -0
  67. package/evals/fixtures/project-profile.valid.json +95 -0
  68. package/evals/fixtures/task-contract.invalid.json +73 -0
  69. package/evals/fixtures/task-contract.valid.json +74 -0
  70. package/evals/golden/enforcement-decisions.json +329 -0
  71. package/evals/scenarios/capability-resolution.json +45 -0
  72. package/package.json +132 -0
  73. package/packages/piagent-core/README.md +147 -0
  74. package/packages/piagent-core/capabilities/capability-core.js +1023 -0
  75. package/packages/piagent-core/capabilities/capability-sources.js +265 -0
  76. package/packages/piagent-core/extensions/guard-io.js +45 -0
  77. package/packages/piagent-core/extensions/guard-shell-analysis.ts +558 -0
  78. package/packages/piagent-core/extensions/guard-types.ts +406 -0
  79. package/packages/piagent-core/extensions/piagent-guard.ts +5760 -0
  80. package/packages/piagent-core/extensions/policy-core.js +1070 -0
  81. package/packages/piagent-core/extensions/redaction-core.js +4 -0
  82. package/packages/piagent-core/extensions/runtime-evidence.js +215 -0
  83. package/packages/piagent-core/package.json +46 -0
  84. package/packages/piagent-core/policies/base-policy.json +249 -0
  85. package/packages/piagent-core/prompts/be-to-fe.md +82 -0
  86. package/packages/piagent-core/prompts/commit.md +27 -0
  87. package/packages/piagent-core/prompts/discuss.md +35 -0
  88. package/packages/piagent-core/prompts/memory-policy.md +52 -0
  89. package/packages/piagent-core/prompts/model-options.md +68 -0
  90. package/packages/piagent-core/prompts/onboard-project.md +147 -0
  91. package/packages/piagent-core/prompts/piagent-commands.md +68 -0
  92. package/packages/piagent-core/prompts/plan.md +35 -0
  93. package/packages/piagent-core/prompts/platform-improve.md +69 -0
  94. package/packages/piagent-core/prompts/pr.md +26 -0
  95. package/packages/piagent-core/prompts/review.md +38 -0
  96. package/packages/piagent-core/prompts/scout.md +50 -0
  97. package/packages/piagent-core/prompts/task.md +69 -0
  98. package/packages/piagent-core/security/sensitive-data.js +187 -0
  99. package/packages/piagent-core/skills/piagent-ops/SKILL.md +44 -0
  100. package/packages/piagent-core/skills/piagent-source-cache/SKILL.md +59 -0
  101. package/packages/piagent-core/skills/piagent-source-cache/checkout-source-repo.sh +144 -0
  102. package/packages/piagent-core/subagents/piagent-oracle.md +29 -0
  103. package/packages/piagent-core/subagents/piagent-planner.md +46 -0
  104. package/packages/piagent-core/subagents/piagent-reviewer.md +48 -0
  105. package/packages/piagent-core/subagents/piagent-scout.md +37 -0
  106. package/packages/piagent-core/subagents/piagent-worker.md +44 -0
  107. package/packs/engineering-base/pack.json +123 -0
  108. package/packs/engineering-base/recipes/bounded-change.json +82 -0
  109. package/packs/web-delivery/pack.json +72 -0
  110. package/packs/web-delivery/recipes/verified-web-change.json +57 -0
  111. package/schemas/action-proposal.schema.json +90 -0
  112. package/schemas/capability-pack.schema.json +190 -0
  113. package/schemas/capability-recipe.schema.json +72 -0
  114. package/schemas/context-index.schema.json +258 -0
  115. package/schemas/eval-scenario.schema.json +67 -0
  116. package/schemas/project-profile.schema.json +555 -0
  117. package/schemas/task-contract.schema.json +314 -0
  118. package/scripts/audit-runtime-host.sh +78 -0
  119. package/scripts/bootstrap-local.sh +25 -0
  120. package/scripts/capability-catalog.mjs +290 -0
  121. package/scripts/check-runtime-advisories.mjs +114 -0
  122. package/scripts/configure-mcp.sh +301 -0
  123. package/scripts/configure-model-scope.sh +143 -0
  124. package/scripts/configure-subagents.sh +241 -0
  125. package/scripts/import-agent-instructions.mjs +199 -0
  126. package/scripts/init-project.sh +369 -0
  127. package/scripts/install-global.sh +532 -0
  128. package/scripts/link-project.sh +25 -0
  129. package/scripts/migrate-project-state.mjs +176 -0
  130. package/scripts/pi-auto.sh +79 -0
  131. package/scripts/pi-model-catalog.sh +154 -0
  132. package/scripts/pi-session-stats.sh +135 -0
  133. package/scripts/piagent-cli.mjs +53 -0
  134. package/scripts/profile-doctor.sh +238 -0
  135. package/scripts/quality-benchmark.sh +185 -0
  136. package/scripts/redaction-benchmark.mjs +227 -0
  137. package/scripts/runtime-policy-smoke.sh +48 -0
  138. package/scripts/setup.sh +425 -0
  139. package/scripts/team-doctor.sh +461 -0
  140. package/scripts/verify-local.sh +540 -0
  141. package/scripts/verify-release-identity.mjs +85 -0
  142. package/scripts/verify-vercel-link.mjs +64 -0
  143. package/templates/global/mcp.json +9 -0
  144. package/templates/global/settings.json +37 -0
  145. package/templates/project/.mcp.json +9 -0
  146. package/templates/project/.pi/context-index.json +25 -0
  147. package/templates/project/.pi/gitignore.template +22 -0
  148. package/templates/project/.pi/mcp.json +9 -0
  149. package/templates/project/.pi/memory/MEMORY.md +11 -0
  150. package/templates/project/.pi/memory/memory_summary.md +9 -0
  151. package/templates/project/.pi/piagent-profile.json +107 -0
  152. package/templates/project/.pi/project-context.md +30 -0
  153. package/templates/project/.pi/settings.json +17 -0
  154. package/templates/project/.pi/task-contract.template.json +74 -0
  155. package/templates/project/.pi/tech-context/README.md +7 -0
  156. package/templates/project/.pi/tech-stack.json +10 -0
  157. package/templates/project/AGENTS.md +34 -0
  158. package/templates/project/REVIEW_GUIDELINES.md +23 -0
  159. package/types/pi-runtime-shims.d.ts +13 -0
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ TMP_ROOT="$(mktemp -d)"
6
+ cleanup() {
7
+ rm -rf "$TMP_ROOT"
8
+ }
9
+ trap cleanup EXIT
10
+
11
+ PROJECT="$TMP_ROOT/sample-project"
12
+ PLATFORM_VERSION="$(node -p "require(process.argv[1]).version" "$ROOT/package.json")"
13
+ mkdir -p "$PROJECT"
14
+ cat > "$PROJECT/README.md" <<'README'
15
+ # Sample Project
16
+ README
17
+ cat > "$PROJECT/AGENTS.md" <<'AGENTS'
18
+ # Sample Agent Instructions
19
+
20
+ Use project profile and verify before done.
21
+ AGENTS
22
+
23
+ bash "$ROOT/scripts/init-project.sh" "$PROJECT" --profile generic --package-source "git:github.com/Vt-mmm/piagent@v${PLATFORM_VERSION}" >/dev/null
24
+ bash "$ROOT/scripts/profile-doctor.sh" "$PROJECT" >/dev/null
25
+ bash "$ROOT/scripts/quality-benchmark.sh" "$PROJECT" --init >/dev/null
26
+ bash "$ROOT/scripts/quality-benchmark.sh" "$PROJECT" --record --scenario smoke --surface pi --result pass --tokens 1 --verify "test -s README.md" >/dev/null
27
+
28
+ node --input-type=module - "$PROJECT/.pi/piagent-profile.json" "$PROJECT/.pi/benchmarks/quality-runs.jsonl" <<'NODE'
29
+ import fs from "node:fs";
30
+
31
+ const [profilePath, benchmarkPath] = process.argv.slice(2);
32
+ const profile = JSON.parse(fs.readFileSync(profilePath, "utf8"));
33
+ for (const capability of ["filesystem-readonly", "filesystem-write", "shell", "memory"]) {
34
+ if (!profile.mcpCapabilities.includes(capability)) {
35
+ throw new Error(`missing capability ${capability}`);
36
+ }
37
+ }
38
+ const runtimePolicy = profile.runtimePolicy ?? {};
39
+ for (const key of ["execPolicy", "contextBudget", "toolRegistry", "finalGate"]) {
40
+ if (!runtimePolicy[key]) throw new Error(`missing runtimePolicy.${key}`);
41
+ }
42
+ const runs = fs.readFileSync(benchmarkPath, "utf8").trim().split(/\n+/).map((line) => JSON.parse(line));
43
+ if (runs.length !== 1 || runs[0].scenario !== "smoke" || runs[0].surface !== "pi" || runs[0].result !== "pass") {
44
+ throw new Error("benchmark smoke record is invalid");
45
+ }
46
+ NODE
47
+
48
+ echo "PASS: runtime policy smoke"
@@ -0,0 +1,425 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ usage() {
5
+ cat <<'USAGE'
6
+ Usage:
7
+ scripts/setup.sh [project-path] [options]
8
+
9
+ Default behavior:
10
+ - install the platform package globally into Pi;
11
+ - initialize the target project with .pi settings/profile;
12
+ - run the team doctor.
13
+
14
+ If project-path is omitted:
15
+ - from a normal project directory: initialize the current directory;
16
+ - from the platform repo itself: global install only.
17
+
18
+ Options:
19
+ --profile <name-or-json> auto | generic | web-frontend | backend-api | be-readonly-fe | fullstack | node-typescript | python | data | devops | mobile | docs | path/to/profile.json
20
+ --package-source <source> Portable Pi package source committed into project .pi/settings.json
21
+ --global-only Only install global Pi package
22
+ --project-only, --no-global Only initialize project, skip global install
23
+ --no-project Skip project initialization
24
+ --with-mcp / --no-mcp Install/skip Pi MCP adapter during global install (default: install)
25
+ --mcp-preset <minimal|core|popular|all|docs|browser|github|design|design-local|web>
26
+ Configure shared global MCP baseline when --with-mcp is enabled (default: core)
27
+ --with-subagents / --no-subagents
28
+ Install/skip pi-subagents during global install (default: install)
29
+ --subagents-preset <minimal|safe|async|parallel>
30
+ Configure pi-subagents runtime baseline (default: safe)
31
+ --subagents-model-scope <none|piagent|codex|claude>
32
+ Optional subagent model allowlist (default: none)
33
+ --with-web-access Install pi-web-access for builtin `researcher` subagent (default: skip)
34
+ --with-herdr / --no-herdr Install/skip Herdr Pi integration if herdr exists (default: install)
35
+ --model-scope <full|codex|claude>
36
+ Configure Pi enabledModels for selector/cycling (default: full)
37
+ --default-model <provider/model[:thinking]>
38
+ Configure default provider/model/thinking (default: openai-codex/gpt-5.5:xhigh)
39
+ --no-model-scope Skip global model-scope configuration
40
+ --install-pi / --no-install-pi Install/skip Pi CLI with npm if `pi` is missing (default: install)
41
+ --force-profile Replace existing project .pi/piagent-profile.json
42
+ --force-settings Replace existing project .pi/settings.json
43
+ --force Replace both profile and settings
44
+ --skip-agents Do not create AGENTS.md
45
+ --skip-review-guidelines Do not create REVIEW_GUIDELINES.md
46
+ --dry-run Print commands without executing
47
+ -h, --help
48
+
49
+ Package source examples:
50
+ # Moving latest for a personal machine or sandbox only:
51
+ pi install git:github.com/Vt-mmm/piagent
52
+
53
+ # Exact sources for .pi/settings.json and capability lock:
54
+ git:github.com/Vt-mmm/piagent@vX.Y.Z
55
+ https://github.com/Vt-mmm/piagent/archive/refs/tags/vX.Y.Z.tar.gz
56
+ npm:@your-scope/platform@x.y.z
57
+ /absolute/path/to/piagent
58
+
59
+ One-command team setup example:
60
+ bash /path/to/piagent/scripts/setup.sh . --profile auto --package-source git:github.com/Vt-mmm/piagent@vX.Y.Z
61
+ USAGE
62
+ }
63
+
64
+ PLATFORM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
65
+ PROJECT_PATH=""
66
+ PROFILE_INPUT="auto"
67
+ PACKAGE_SOURCE="${PIAGENT_PACKAGE_SOURCE:-}"
68
+ DO_GLOBAL=true
69
+ DO_PROJECT=true
70
+ WITH_MCP=true
71
+ MCP_PRESET="core"
72
+ WITH_SUBAGENTS=true
73
+ SUBAGENTS_PRESET="safe"
74
+ SUBAGENTS_MODEL_SCOPE="none"
75
+ WITH_WEB_ACCESS=false
76
+ WITH_HERDR=true
77
+ CONFIGURE_MODEL_SCOPE=true
78
+ MODEL_SCOPE_PRESET="full"
79
+ DEFAULT_MODEL="openai-codex/gpt-5.5:xhigh"
80
+ AUTO_INSTALL_PI=true
81
+ FORCE_PROFILE=false
82
+ FORCE_SETTINGS=false
83
+ SKIP_AGENTS=false
84
+ SKIP_REVIEW=false
85
+ DRY_RUN=false
86
+
87
+ while [[ $# -gt 0 ]]; do
88
+ case "$1" in
89
+ --profile)
90
+ if [[ $# -lt 2 ]]; then
91
+ echo "Missing value for --profile" >&2
92
+ exit 2
93
+ fi
94
+ PROFILE_INPUT="$2"
95
+ shift 2
96
+ ;;
97
+ --package-source)
98
+ if [[ $# -lt 2 ]]; then
99
+ echo "Missing value for --package-source" >&2
100
+ exit 2
101
+ fi
102
+ PACKAGE_SOURCE="$2"
103
+ shift 2
104
+ ;;
105
+ --global-only)
106
+ DO_PROJECT=false
107
+ shift
108
+ ;;
109
+ --project-only|--no-global)
110
+ DO_GLOBAL=false
111
+ shift
112
+ ;;
113
+ --no-project)
114
+ DO_PROJECT=false
115
+ shift
116
+ ;;
117
+ --with-mcp)
118
+ WITH_MCP=true
119
+ shift
120
+ ;;
121
+ --no-mcp)
122
+ WITH_MCP=false
123
+ shift
124
+ ;;
125
+ --mcp-preset)
126
+ MCP_PRESET="${2:-}"
127
+ shift 2
128
+ ;;
129
+ --with-subagents)
130
+ WITH_SUBAGENTS=true
131
+ shift
132
+ ;;
133
+ --no-subagents)
134
+ WITH_SUBAGENTS=false
135
+ shift
136
+ ;;
137
+ --subagents-preset)
138
+ SUBAGENTS_PRESET="${2:-}"
139
+ shift 2
140
+ ;;
141
+ --subagents-model-scope)
142
+ SUBAGENTS_MODEL_SCOPE="${2:-}"
143
+ shift 2
144
+ ;;
145
+ --with-web-access)
146
+ WITH_WEB_ACCESS=true
147
+ shift
148
+ ;;
149
+ --with-herdr)
150
+ WITH_HERDR=true
151
+ shift
152
+ ;;
153
+ --no-herdr)
154
+ WITH_HERDR=false
155
+ shift
156
+ ;;
157
+ --model-scope)
158
+ MODEL_SCOPE_PRESET="${2:-}"
159
+ shift 2
160
+ ;;
161
+ --default-model)
162
+ DEFAULT_MODEL="${2:-}"
163
+ shift 2
164
+ ;;
165
+ --no-model-scope)
166
+ CONFIGURE_MODEL_SCOPE=false
167
+ shift
168
+ ;;
169
+ --install-pi)
170
+ AUTO_INSTALL_PI=true
171
+ shift
172
+ ;;
173
+ --no-install-pi)
174
+ AUTO_INSTALL_PI=false
175
+ shift
176
+ ;;
177
+ --force-profile)
178
+ FORCE_PROFILE=true
179
+ shift
180
+ ;;
181
+ --force-settings)
182
+ FORCE_SETTINGS=true
183
+ shift
184
+ ;;
185
+ --force)
186
+ FORCE_PROFILE=true
187
+ FORCE_SETTINGS=true
188
+ shift
189
+ ;;
190
+ --skip-agents)
191
+ SKIP_AGENTS=true
192
+ shift
193
+ ;;
194
+ --skip-review-guidelines)
195
+ SKIP_REVIEW=true
196
+ shift
197
+ ;;
198
+ --dry-run)
199
+ DRY_RUN=true
200
+ shift
201
+ ;;
202
+ -h|--help)
203
+ usage
204
+ exit 0
205
+ ;;
206
+ --*)
207
+ echo "Unknown option: $1" >&2
208
+ usage >&2
209
+ exit 2
210
+ ;;
211
+ *)
212
+ if [[ -z "$PROJECT_PATH" ]]; then
213
+ PROJECT_PATH="$1"
214
+ shift
215
+ else
216
+ echo "Unknown argument: $1" >&2
217
+ usage >&2
218
+ exit 2
219
+ fi
220
+ ;;
221
+ esac
222
+ done
223
+
224
+ resolve_package_source() {
225
+ if [[ -n "$PACKAGE_SOURCE" ]]; then
226
+ printf '%s\n' "$PACKAGE_SOURCE"
227
+ return
228
+ fi
229
+
230
+ if [[ "$DO_PROJECT" == true && -n "$PROJECT_PATH" && -f "$PROJECT_PATH/.pi/settings.json" ]]; then
231
+ local existing_source
232
+ existing_source="$(node --input-type=module - "$PROJECT_PATH/.pi/settings.json" <<'NODE'
233
+ import fs from "node:fs";
234
+ const settings = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
235
+ const source = Array.isArray(settings.packages)
236
+ ? settings.packages.find((item) => typeof item === "string" && item.length > 0)
237
+ : undefined;
238
+ if (source) process.stdout.write(source);
239
+ NODE
240
+ )"
241
+ if [[ -n "$existing_source" ]]; then
242
+ printf '%s\n' "$existing_source"
243
+ return
244
+ fi
245
+ fi
246
+
247
+ echo "WARN: No exact package source provided." >&2
248
+ echo "WARN: using local platform path; do not commit project .pi/settings.json with this value for team rollout." >&2
249
+ printf '%s\n' "$PLATFORM_ROOT"
250
+ }
251
+
252
+ print_cmd() {
253
+ printf '+'
254
+ for arg in "$@"; do
255
+ printf ' %q' "$arg"
256
+ done
257
+ printf '\n'
258
+ }
259
+
260
+ run_cmd() {
261
+ print_cmd "$@"
262
+ if [[ "$DRY_RUN" == false ]]; then
263
+ "$@"
264
+ fi
265
+ }
266
+
267
+ require_node_version() {
268
+ if ! command -v node >/dev/null 2>&1; then
269
+ echo "FAIL: Node.js >=22.19.0 is required." >&2
270
+ exit 1
271
+ fi
272
+ local node_version
273
+ node_version="$(node -p 'process.versions.node' 2>/dev/null || true)"
274
+ if ! node -e 'const [major, minor, patch] = process.versions.node.split(".").map(Number); process.exit(major > 22 || (major === 22 && (minor > 19 || (minor === 19 && patch >= 0))) ? 0 : 1);'; then
275
+ echo "FAIL: Node.js >=22.19.0 is required; found ${node_version:-unknown}." >&2
276
+ exit 1
277
+ fi
278
+ }
279
+
280
+ ensure_pi_cli() {
281
+ local expected_pi_version current_output current_version=""
282
+ expected_pi_version="$(node -e 'const fs=require("node:fs"); const p=JSON.parse(fs.readFileSync(process.argv[1], "utf8")); process.stdout.write(p.peerDependencies?.["@earendil-works/pi-coding-agent"] ?? "");' "$PLATFORM_ROOT/package.json")"
283
+ if [[ ! "$expected_pi_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?$ ]]; then
284
+ echo "FAIL: package.json must pin an exact Pi Coding Agent version." >&2
285
+ exit 1
286
+ fi
287
+
288
+ if command -v pi >/dev/null 2>&1; then
289
+ current_output="$(pi --version 2>/dev/null || true)"
290
+ if [[ "$current_output" =~ ([0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?) ]]; then
291
+ current_version="${BASH_REMATCH[1]}"
292
+ fi
293
+ if [[ "$current_version" == "$expected_pi_version" ]]; then
294
+ return
295
+ fi
296
+ if [[ "$AUTO_INSTALL_PI" == false ]]; then
297
+ echo "FAIL: Pi Coding Agent $expected_pi_version is required; found ${current_version:-${current_output:-unknown}}. Remove --no-install-pi or upgrade it manually." >&2
298
+ exit 1
299
+ fi
300
+ echo "Pi CLI ${current_version:-unknown} is not supported; installing exact host $expected_pi_version:"
301
+ elif [[ "$AUTO_INSTALL_PI" == false ]]; then
302
+ echo "FAIL: pi is not on PATH. Rerun without --no-install-pi or install Pi manually." >&2
303
+ exit 1
304
+ else
305
+ echo "Pi CLI not found; installing exact host $expected_pi_version:"
306
+ fi
307
+
308
+ if ! command -v npm >/dev/null 2>&1; then
309
+ echo "FAIL: npm is required to install Pi Coding Agent $expected_pi_version." >&2
310
+ echo "Install Node.js >=22.19.0 with npm, then rerun setup." >&2
311
+ exit 1
312
+ fi
313
+
314
+ run_cmd npm install -g --ignore-scripts "@earendil-works/pi-coding-agent@$expected_pi_version"
315
+ if [[ "$DRY_RUN" == false ]]; then
316
+ hash -r
317
+ current_output="$(pi --version 2>/dev/null || true)"
318
+ current_version=""
319
+ if [[ "$current_output" =~ ([0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?) ]]; then
320
+ current_version="${BASH_REMATCH[1]}"
321
+ fi
322
+ if [[ "$current_version" != "$expected_pi_version" ]]; then
323
+ echo "FAIL: Pi Coding Agent upgrade did not activate version $expected_pi_version; found ${current_version:-${current_output:-unknown}}." >&2
324
+ exit 1
325
+ fi
326
+ fi
327
+ }
328
+
329
+ require_node_version
330
+
331
+ if [[ -z "$PROJECT_PATH" && "$DO_PROJECT" == true ]]; then
332
+ if [[ "$(pwd)" == "$PLATFORM_ROOT" ]]; then
333
+ DO_PROJECT=false
334
+ else
335
+ PROJECT_PATH="$(pwd)"
336
+ fi
337
+ fi
338
+
339
+ if [[ "$DO_PROJECT" == true ]]; then
340
+ if [[ -z "$PROJECT_PATH" ]]; then
341
+ echo "FAIL: project path is required when project initialization is enabled." >&2
342
+ exit 2
343
+ fi
344
+ if [[ ! -d "$PROJECT_PATH" ]]; then
345
+ echo "FAIL: project path does not exist: $PROJECT_PATH" >&2
346
+ exit 1
347
+ fi
348
+ PROJECT_PATH="$(cd "$PROJECT_PATH" && pwd)"
349
+ fi
350
+
351
+ PACKAGE_SOURCE="$(resolve_package_source)"
352
+
353
+ echo "Pi Agent Platform setup"
354
+ echo " platform: $PLATFORM_ROOT"
355
+ echo " packageSource: $PACKAGE_SOURCE"
356
+ echo " globalInstall: $DO_GLOBAL"
357
+ echo " projectInit: $DO_PROJECT"
358
+ if [[ "$DO_PROJECT" == true ]]; then
359
+ echo " project: $PROJECT_PATH"
360
+ echo " profile: $PROFILE_INPUT"
361
+ fi
362
+ echo
363
+
364
+ if [[ "$DO_GLOBAL" == true ]]; then
365
+ ensure_pi_cli
366
+ install_args=("$PLATFORM_ROOT/scripts/install-global.sh" "--package-source" "$PACKAGE_SOURCE")
367
+ if [[ "$WITH_MCP" == true ]]; then
368
+ install_args+=("--with-mcp" "--mcp-preset" "$MCP_PRESET")
369
+ fi
370
+ if [[ "$WITH_SUBAGENTS" == true ]]; then
371
+ install_args+=("--with-subagents" "--subagents-preset" "$SUBAGENTS_PRESET" "--subagents-model-scope" "$SUBAGENTS_MODEL_SCOPE")
372
+ fi
373
+ if [[ "$WITH_WEB_ACCESS" == true ]]; then
374
+ install_args+=("--with-web-access")
375
+ fi
376
+ if [[ "$WITH_HERDR" == true ]]; then
377
+ install_args+=("--with-herdr")
378
+ fi
379
+ if [[ "$CONFIGURE_MODEL_SCOPE" == true ]]; then
380
+ install_args+=("--model-scope" "$MODEL_SCOPE_PRESET" "--default-model" "$DEFAULT_MODEL")
381
+ else
382
+ install_args+=("--no-model-scope")
383
+ fi
384
+ run_cmd bash "${install_args[@]}"
385
+ fi
386
+
387
+ if [[ "$DO_PROJECT" == true ]]; then
388
+ init_args=("$PLATFORM_ROOT/scripts/init-project.sh" "$PROJECT_PATH" "--profile" "$PROFILE_INPUT" "--package-source" "$PACKAGE_SOURCE")
389
+ if [[ "$FORCE_PROFILE" == true ]]; then
390
+ init_args+=("--force-profile")
391
+ fi
392
+ if [[ "$FORCE_SETTINGS" == true ]]; then
393
+ init_args+=("--force-settings")
394
+ fi
395
+ if [[ "$SKIP_AGENTS" == true ]]; then
396
+ init_args+=("--skip-agents")
397
+ fi
398
+ if [[ "$SKIP_REVIEW" == true ]]; then
399
+ init_args+=("--skip-review-guidelines")
400
+ fi
401
+ run_cmd bash "${init_args[@]}"
402
+ run_cmd bash "$PLATFORM_ROOT/scripts/team-doctor.sh" "$PROJECT_PATH" --strict-share
403
+ fi
404
+
405
+ echo
406
+ echo "Next:"
407
+ if [[ "$DO_PROJECT" == true ]]; then
408
+ echo " cd \"$PROJECT_PATH\""
409
+ fi
410
+ echo " pi"
411
+ echo " /login # first time only"
412
+ if [[ "$DO_PROJECT" == true ]]; then
413
+ echo " /model # or Ctrl+L: select provider/model from Pi selector"
414
+ echo " /scoped-models # optional: edit Ctrl+P model cycle scope"
415
+ echo " /mcp # inspect MCP servers; run /mcp setup for guided changes"
416
+ echo " /subagents-doctor # inspect subagent setup"
417
+ echo " /onboard-project # first project-read snapshot before implementation"
418
+ echo " /memory-policy # inspect project memory policy when needed"
419
+ fi
420
+ echo
421
+ echo "Daily flow after setup:"
422
+ echo " herdr # optional"
423
+ echo " cd <project>"
424
+ echo " pi"
425
+ echo " /task Implement <task> # parent may auto-delegate scout/planner/reviewer"