@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,532 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ usage() {
5
+ cat <<'USAGE'
6
+ Usage:
7
+ scripts/install-global.sh [--stable|--dev|--local|--channel <stable|dev|local>] [--version <tag>] [--resolve-tag] [--package-source <source>] [--dry-run] [--with-mcp] [--mcp-preset <preset>] [--with-subagents] [--subagents-preset <preset>] [--with-web-access] [--with-herdr] [--model-scope <preset>]
8
+
9
+ Purpose:
10
+ Install the piagent Pi package into the current user's global Pi settings.
11
+
12
+ Package source examples:
13
+ # Recommended stable install: exact current release tag
14
+ scripts/install-global.sh --stable
15
+ # Installs the stable tag after resolving it to a commit SHA.
16
+
17
+ # Pin a specific release:
18
+ scripts/install-global.sh --version v1.0.0 --resolve-tag
19
+
20
+ # Preview the planned install/update without changing user config:
21
+ scripts/install-global.sh --stable --dry-run
22
+
23
+ # Exact sources for reviewed/team rollout:
24
+ git:github.com/Vt-mmm/piagent@vX.Y.Z
25
+ https://github.com/Vt-mmm/piagent/archive/refs/tags/vX.Y.Z.tar.gz
26
+ npm:@your-scope/platform@x.y.z
27
+ /absolute/path/to/piagent
28
+
29
+ # Personal/sandbox moving source:
30
+ scripts/install-global.sh --dev
31
+
32
+ Notes:
33
+ - `currentRelease` in output is the version of the terminal helper executing this command.
34
+ - Use exactly one package selector. The first CLI selector overrides environment defaults; a second selector fails closed.
35
+ - OAuth is intentionally not automated. Run `pi` then `/login`.
36
+ - Model scope is configured with Pi's native `enabledModels` so users choose via `/model`, Ctrl+L, `/scoped-models`, and Ctrl+P.
37
+ - Herdr integration is optional and modifies user-level Herdr/Pi config.
38
+ - MCP preset defaults to core: Context7 docs, Chrome DevTools, GitHub.
39
+ - Subagents preset defaults to safe: compact tool description, bounded concurrency/depth.
40
+ - Web access is optional. Install it only when you want the builtin `researcher` subagent to browse/fetch web sources inside Pi.
41
+ USAGE
42
+ }
43
+
44
+ PLATFORM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
45
+ CURRENT_RELEASE_TAG=""
46
+ EXPECTED_PI_VERSION=""
47
+ EXPECTED_RELEASE_COMMIT="${PIAGENT_EXPECTED_RELEASE_COMMIT:-}"
48
+ DEFAULT_REPO_SOURCE="git:github.com/Vt-mmm/piagent"
49
+ DEFAULT_REPO_REMOTE_URL="https://github.com/Vt-mmm/piagent.git"
50
+ PACKAGE_SOURCE="${PIAGENT_PACKAGE_SOURCE:-}"
51
+ PACKAGE_VERSION="${PIAGENT_PACKAGE_VERSION:-}"
52
+ RELEASE_CHANNEL="${PIAGENT_RELEASE_CHANNEL:-}"
53
+ WITH_MCP=false
54
+ MCP_PRESET="core"
55
+ WITH_SUBAGENTS=false
56
+ SUBAGENTS_PRESET="safe"
57
+ SUBAGENTS_MODEL_SCOPE="none"
58
+ WITH_WEB_ACCESS=false
59
+ WITH_HERDR=false
60
+ CONFIGURE_MODEL_SCOPE=true
61
+ MODEL_SCOPE_PRESET="full"
62
+ DEFAULT_MODEL="openai-codex/gpt-5.5:xhigh"
63
+ DRY_RUN=false
64
+ FLOATING_PACKAGE_SOURCE=false
65
+ RESOLVED_CHANNEL_LABEL="custom"
66
+ RESOLVE_TAG=false
67
+ RESOLVED_PACKAGE_TAG=""
68
+ RESOLVED_PACKAGE_COMMIT=""
69
+ CLI_PACKAGE_SELECTOR=""
70
+ PI_MCP_ADAPTER_SOURCE="npm:pi-mcp-adapter@2.11.0"
71
+ PI_SUBAGENTS_SOURCE="npm:pi-subagents@0.35.1"
72
+ PI_WEB_ACCESS_SOURCE="npm:pi-web-access@0.13.0"
73
+ PI_MCP_ADAPTER_INTEGRITY="sha512-4Y/eLbhbxnRih519dJUxMyQ5QASvPcdWyBlS8+dDXteAzaMuLnd4nMTWgoZw3JRIW+0r93KAQcz1Rbli4xCwEQ=="
74
+ PI_SUBAGENTS_INTEGRITY="sha512-nIH6liO541FZ1RoeEu58Ligd59tiNw0/ODPgHh7uvx9Dk4UpWH08F84/l1+hXCzUgC85OCmyVtngWkZjcK94Cg=="
75
+ PI_WEB_ACCESS_INTEGRITY="sha512-ny0bHisMWdobmu1hcMp/jqjaRh6pYrH7dctBK2CVyRF4ia7bP47RnOPYdG1yiks9ohtcanWir5Hl9EFap8h0zQ=="
76
+
77
+ require_value() {
78
+ local option="$1"
79
+ local value="${2:-}"
80
+ if [[ -z "$value" || "$value" == --* ]]; then
81
+ echo "Missing value for $option" >&2
82
+ exit 2
83
+ fi
84
+ }
85
+
86
+ require_node_version() {
87
+ if ! command -v node >/dev/null 2>&1; then
88
+ echo "FAIL: Node.js >=22.19.0 is required." >&2
89
+ exit 1
90
+ fi
91
+ local node_version
92
+ node_version="$(node -p 'process.versions.node' 2>/dev/null || true)"
93
+ 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
94
+ echo "FAIL: Node.js >=22.19.0 is required; found ${node_version:-unknown}." >&2
95
+ exit 1
96
+ fi
97
+ }
98
+
99
+ detect_runtime_surface() {
100
+ local os_name arch_name
101
+ os_name="$(uname -s 2>/dev/null || echo unknown)"
102
+ arch_name="$(uname -m 2>/dev/null || echo unknown)"
103
+
104
+ if [[ "$os_name" == "Linux" && -r /proc/version ]] && grep -qiE "microsoft|wsl" /proc/version 2>/dev/null; then
105
+ printf 'wsl2/%s (experimental; not release-gated)' "$arch_name"
106
+ return
107
+ fi
108
+
109
+ case "${os_name}:${arch_name}" in
110
+ Darwin:arm64)
111
+ printf 'macos-apple-silicon/darwin-arm64 (verified)'
112
+ ;;
113
+ Darwin:x86_64)
114
+ printf 'macos-intel/darwin-x64 (supported target; run smoke before team rollout)'
115
+ ;;
116
+ Linux:x86_64|Linux:amd64)
117
+ printf 'linux-x64 (verified in CI)'
118
+ ;;
119
+ Linux:aarch64|Linux:arm64)
120
+ printf 'linux-arm64 (supported target; run smoke before team rollout)'
121
+ ;;
122
+ MINGW*|MSYS*|CYGWIN*)
123
+ printf 'native-windows/%s (not release-gated; terminal helpers require Bash semantics)' "$arch_name"
124
+ ;;
125
+ *)
126
+ printf '%s/%s (outside v1.0.0 release matrix)' "$os_name" "$arch_name"
127
+ ;;
128
+ esac
129
+ }
130
+
131
+ warn_runtime_surface_if_needed() {
132
+ local surface="$1"
133
+ case "$surface" in
134
+ *"supported target"*|*"experimental"*|*"not release-gated"*|*"outside v1.0.0 release matrix"*)
135
+ echo "WARN: runtime surface is $surface." >&2
136
+ echo "WARN: For team rollout, run piagent-doctor plus the project smoke/verify suite on this machine before relying on it." >&2
137
+ ;;
138
+ esac
139
+ }
140
+
141
+ claim_cli_package_selector() {
142
+ local option="$1"
143
+ if [[ -n "$CLI_PACKAGE_SELECTOR" ]]; then
144
+ echo "FAIL: only one CLI package selector is allowed; received $CLI_PACKAGE_SELECTOR before $option." >&2
145
+ exit 2
146
+ fi
147
+
148
+ CLI_PACKAGE_SELECTOR="$option"
149
+ # Environment values are defaults. The first explicit CLI selector replaces
150
+ # all of them; any later CLI selector is rejected above.
151
+ PACKAGE_SOURCE=""
152
+ PACKAGE_VERSION=""
153
+ RELEASE_CHANNEL=""
154
+ }
155
+
156
+ case "${PIAGENT_DRY_RUN:-}" in
157
+ 1|true|TRUE|yes|YES)
158
+ DRY_RUN=true
159
+ ;;
160
+ esac
161
+
162
+ print_cmd() {
163
+ printf '+'
164
+ for arg in "$@"; do
165
+ printf ' %q' "$arg"
166
+ done
167
+ printf '\n'
168
+ }
169
+
170
+ run_cmd() {
171
+ print_cmd "$@"
172
+ if [[ "$DRY_RUN" == false ]]; then
173
+ "$@"
174
+ fi
175
+ }
176
+
177
+ verify_npm_integrity() {
178
+ local source="$1"
179
+ local expected="$2"
180
+ local package_spec="${source#npm:}"
181
+ if ! command -v npm >/dev/null 2>&1; then
182
+ echo "FAIL: npm is required to verify package integrity for $package_spec." >&2
183
+ exit 1
184
+ fi
185
+ local actual
186
+ actual="$(npm view "$package_spec" dist.integrity 2>/dev/null | tr -d '\r\n')"
187
+ if [[ -z "$actual" || "$actual" != "$expected" ]]; then
188
+ echo "FAIL: registry integrity does not match the approved digest for $package_spec." >&2
189
+ exit 1
190
+ fi
191
+ }
192
+
193
+ resolve_git_tag_commit() {
194
+ local tag="$1"
195
+ if [[ -z "$tag" ]]; then
196
+ echo "FAIL: tag is required for release resolution." >&2
197
+ exit 2
198
+ fi
199
+ if [[ "$tag" =~ ^[0-9a-fA-F]{40}$ ]]; then
200
+ echo "FAIL: --resolve-tag expects a tag, not a commit SHA: $tag" >&2
201
+ exit 2
202
+ fi
203
+ if [[ "$tag" == *".."* || "$tag" == *"~"* || "$tag" == *"^"* || "$tag" == *":"* || "$tag" == *" "* ]]; then
204
+ echo "FAIL: unsupported tag syntax for release resolution: $tag" >&2
205
+ exit 2
206
+ fi
207
+ if ! command -v git >/dev/null 2>&1; then
208
+ echo "FAIL: git is required to resolve release tag $tag to a commit SHA." >&2
209
+ exit 1
210
+ fi
211
+
212
+ local refs commit=""
213
+ refs="$(git ls-remote --tags "$DEFAULT_REPO_REMOTE_URL" "refs/tags/${tag}" "refs/tags/${tag}^{}" 2>/dev/null || true)"
214
+ if [[ -z "$refs" ]]; then
215
+ echo "FAIL: could not resolve release tag $tag from $DEFAULT_REPO_REMOTE_URL." >&2
216
+ exit 1
217
+ fi
218
+
219
+ commit="$(printf '%s\n' "$refs" | awk -v exact="refs/tags/${tag}^{}" '$2 == exact { print $1; exit }')"
220
+ if [[ -z "$commit" ]]; then
221
+ commit="$(printf '%s\n' "$refs" | awk -v exact="refs/tags/${tag}" '$2 == exact { print $1; exit }')"
222
+ fi
223
+ if [[ ! "$commit" =~ ^[0-9a-fA-F]{40}$ ]]; then
224
+ echo "FAIL: release tag $tag did not resolve to a valid commit SHA." >&2
225
+ exit 1
226
+ fi
227
+
228
+ printf '%s\n' "$commit"
229
+ }
230
+
231
+ while [[ $# -gt 0 ]]; do
232
+ case "$1" in
233
+ --package-source)
234
+ require_value "$1" "${2:-}"
235
+ claim_cli_package_selector "$1"
236
+ PACKAGE_SOURCE="$2"
237
+ shift 2
238
+ ;;
239
+ --channel)
240
+ require_value "$1" "${2:-}"
241
+ claim_cli_package_selector "$1"
242
+ RELEASE_CHANNEL="$2"
243
+ shift 2
244
+ ;;
245
+ --stable)
246
+ claim_cli_package_selector "$1"
247
+ RELEASE_CHANNEL="stable"
248
+ shift
249
+ ;;
250
+ --dev)
251
+ claim_cli_package_selector "$1"
252
+ RELEASE_CHANNEL="dev"
253
+ shift
254
+ ;;
255
+ --local)
256
+ claim_cli_package_selector "$1"
257
+ RELEASE_CHANNEL="local"
258
+ shift
259
+ ;;
260
+ --version|--tag)
261
+ require_value "$1" "${2:-}"
262
+ claim_cli_package_selector "$1"
263
+ PACKAGE_VERSION="$2"
264
+ shift 2
265
+ ;;
266
+ --dry-run)
267
+ DRY_RUN=true
268
+ shift
269
+ ;;
270
+ --resolve-tag)
271
+ RESOLVE_TAG=true
272
+ shift
273
+ ;;
274
+ --with-mcp)
275
+ WITH_MCP=true
276
+ shift
277
+ ;;
278
+ --mcp-preset)
279
+ require_value "$1" "${2:-}"
280
+ MCP_PRESET="$2"
281
+ shift 2
282
+ ;;
283
+ --with-subagents)
284
+ WITH_SUBAGENTS=true
285
+ shift
286
+ ;;
287
+ --subagents-preset)
288
+ require_value "$1" "${2:-}"
289
+ SUBAGENTS_PRESET="$2"
290
+ shift 2
291
+ ;;
292
+ --subagents-model-scope)
293
+ require_value "$1" "${2:-}"
294
+ SUBAGENTS_MODEL_SCOPE="$2"
295
+ shift 2
296
+ ;;
297
+ --with-web-access)
298
+ WITH_WEB_ACCESS=true
299
+ shift
300
+ ;;
301
+ --with-herdr)
302
+ WITH_HERDR=true
303
+ shift
304
+ ;;
305
+ --model-scope)
306
+ require_value "$1" "${2:-}"
307
+ MODEL_SCOPE_PRESET="$2"
308
+ shift 2
309
+ ;;
310
+ --default-model)
311
+ require_value "$1" "${2:-}"
312
+ DEFAULT_MODEL="$2"
313
+ shift 2
314
+ ;;
315
+ --no-model-scope)
316
+ CONFIGURE_MODEL_SCOPE=false
317
+ shift
318
+ ;;
319
+ -h|--help)
320
+ usage
321
+ exit 0
322
+ ;;
323
+ *)
324
+ echo "Unknown option: $1" >&2
325
+ usage >&2
326
+ exit 2
327
+ ;;
328
+ esac
329
+ done
330
+
331
+ require_node_version
332
+ CURRENT_RUNTIME_SURFACE="$(detect_runtime_surface)"
333
+ warn_runtime_surface_if_needed "$CURRENT_RUNTIME_SURFACE"
334
+ CURRENT_RELEASE_TAG="$(node -e 'const fs = require("node:fs"); const p = JSON.parse(fs.readFileSync(process.argv[1], "utf8")); process.stdout.write(`v${p.version}`);' "$PLATFORM_ROOT/package.json")"
335
+ 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")"
336
+ if [[ ! "$EXPECTED_PI_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?$ ]]; then
337
+ echo "FAIL: package.json must pin an exact Pi Coding Agent version." >&2
338
+ exit 1
339
+ fi
340
+
341
+ resolve_package_source() {
342
+ if [[ -n "$PACKAGE_SOURCE" ]]; then
343
+ if [[ -n "$RELEASE_CHANNEL" || -n "$PACKAGE_VERSION" ]]; then
344
+ echo "FAIL: use either --package-source or --channel/--version, not both." >&2
345
+ exit 2
346
+ fi
347
+ if [[ "$RESOLVE_TAG" == true ]]; then
348
+ echo "FAIL: --resolve-tag only works with --stable or --version <tag>." >&2
349
+ exit 2
350
+ fi
351
+ RESOLVED_CHANNEL_LABEL="custom"
352
+ return
353
+ fi
354
+
355
+ if [[ -n "$RELEASE_CHANNEL" && -n "$PACKAGE_VERSION" ]]; then
356
+ echo "FAIL: use either --channel or --version, not both." >&2
357
+ exit 2
358
+ fi
359
+
360
+ if [[ -n "$PACKAGE_VERSION" ]]; then
361
+ if [[ "$RESOLVE_TAG" == true ]]; then
362
+ RESOLVED_PACKAGE_TAG="$PACKAGE_VERSION"
363
+ RESOLVED_PACKAGE_COMMIT="$(resolve_git_tag_commit "$PACKAGE_VERSION")"
364
+ PACKAGE_SOURCE="${DEFAULT_REPO_SOURCE}@${RESOLVED_PACKAGE_COMMIT}"
365
+ else
366
+ PACKAGE_SOURCE="${DEFAULT_REPO_SOURCE}@${PACKAGE_VERSION}"
367
+ fi
368
+ RESOLVED_CHANNEL_LABEL="exact"
369
+ return
370
+ fi
371
+
372
+ case "$RELEASE_CHANNEL" in
373
+ stable)
374
+ RESOLVED_PACKAGE_TAG="$CURRENT_RELEASE_TAG"
375
+ RESOLVED_PACKAGE_COMMIT="$(resolve_git_tag_commit "$CURRENT_RELEASE_TAG")"
376
+ PACKAGE_SOURCE="${DEFAULT_REPO_SOURCE}@${RESOLVED_PACKAGE_COMMIT}"
377
+ RESOLVED_CHANNEL_LABEL="stable"
378
+ ;;
379
+ dev|latest)
380
+ if [[ "$RESOLVE_TAG" == true ]]; then
381
+ echo "FAIL: --resolve-tag cannot be used with the floating dev/latest channel." >&2
382
+ exit 2
383
+ fi
384
+ PACKAGE_SOURCE="$DEFAULT_REPO_SOURCE"
385
+ FLOATING_PACKAGE_SOURCE=true
386
+ RESOLVED_CHANNEL_LABEL="dev"
387
+ ;;
388
+ local)
389
+ if [[ "$RESOLVE_TAG" == true ]]; then
390
+ echo "FAIL: --resolve-tag cannot be used with the local channel." >&2
391
+ exit 2
392
+ fi
393
+ PACKAGE_SOURCE="$PLATFORM_ROOT"
394
+ RESOLVED_CHANNEL_LABEL="local"
395
+ ;;
396
+ "")
397
+ if [[ "$RESOLVE_TAG" == true ]]; then
398
+ echo "FAIL: --resolve-tag requires --stable or --version <tag>." >&2
399
+ exit 2
400
+ fi
401
+ PACKAGE_SOURCE="$PLATFORM_ROOT"
402
+ RESOLVED_CHANNEL_LABEL="local"
403
+ echo "WARN: No exact package source provided. Installing from local path." >&2
404
+ echo "WARN: For team rollout, pass --stable, --version vX.Y.Z, or --package-source git:github.com/Vt-mmm/piagent@TAG." >&2
405
+ ;;
406
+ *)
407
+ echo "FAIL: unsupported release channel: $RELEASE_CHANNEL" >&2
408
+ echo "Expected: stable, dev, or local." >&2
409
+ exit 2
410
+ ;;
411
+ esac
412
+ }
413
+
414
+ resolve_package_source
415
+
416
+ if [[ -n "$EXPECTED_RELEASE_COMMIT" ]]; then
417
+ if [[ ! "$EXPECTED_RELEASE_COMMIT" =~ ^[0-9a-fA-F]{40}$ ]]; then
418
+ echo "FAIL: PIAGENT_EXPECTED_RELEASE_COMMIT must be a 40-character commit SHA." >&2
419
+ exit 2
420
+ fi
421
+ normalized_resolved_commit="$(printf '%s' "$RESOLVED_PACKAGE_COMMIT" | tr '[:upper:]' '[:lower:]')"
422
+ normalized_expected_commit="$(printf '%s' "$EXPECTED_RELEASE_COMMIT" | tr '[:upper:]' '[:lower:]')"
423
+ if [[ -z "$RESOLVED_PACKAGE_COMMIT" || "$normalized_resolved_commit" != "$normalized_expected_commit" ]]; then
424
+ echo "FAIL: resolved commit does not match the required release commit." >&2
425
+ exit 1
426
+ fi
427
+ fi
428
+
429
+ if [[ "$FLOATING_PACKAGE_SOURCE" == true ]]; then
430
+ echo "WARN: Installing a floating dev/latest source. Use only for personal machines or sandbox testing." >&2
431
+ else
432
+ node "$PLATFORM_ROOT/scripts/capability-catalog.mjs" validate-source --package-source "$PACKAGE_SOURCE" >/dev/null
433
+ fi
434
+
435
+ if ! command -v pi >/dev/null 2>&1; then
436
+ if [[ "$DRY_RUN" == true ]]; then
437
+ echo "DRY RUN: pi is not on PATH; install would require Pi CLI first." >&2
438
+ else
439
+ echo "FAIL: pi is not on PATH." >&2
440
+ echo "Install Pi first, then rerun this script." >&2
441
+ echo "Expected command on npm-based installs: npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.81.1" >&2
442
+ exit 1
443
+ fi
444
+ else
445
+ pi_version_output="$(pi --version 2>/dev/null || true)"
446
+ current_pi_version=""
447
+ if [[ "$pi_version_output" =~ ([0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?) ]]; then
448
+ current_pi_version="${BASH_REMATCH[1]}"
449
+ fi
450
+ if [[ "$current_pi_version" != "$EXPECTED_PI_VERSION" ]]; then
451
+ echo "FAIL: Pi Coding Agent $EXPECTED_PI_VERSION is required; found ${current_pi_version:-${pi_version_output:-unknown}}." >&2
452
+ echo "Install the supported host with: npm install -g --ignore-scripts @earendil-works/pi-coding-agent@$EXPECTED_PI_VERSION" >&2
453
+ exit 1
454
+ fi
455
+ fi
456
+
457
+ echo "Installing Pi Agent Platform package:"
458
+ echo " channel: $RESOLVED_CHANNEL_LABEL"
459
+ echo " currentRelease: $CURRENT_RELEASE_TAG (helper package version)"
460
+ echo " runtime: $CURRENT_RUNTIME_SURFACE"
461
+ if [[ -n "$RESOLVED_PACKAGE_TAG" ]]; then
462
+ echo " tag: $RESOLVED_PACKAGE_TAG"
463
+ fi
464
+ if [[ -n "$RESOLVED_PACKAGE_COMMIT" ]]; then
465
+ echo " resolvedCommit: $RESOLVED_PACKAGE_COMMIT"
466
+ fi
467
+ echo " source: $PACKAGE_SOURCE"
468
+ run_cmd pi install "$PACKAGE_SOURCE"
469
+
470
+ if [[ "$WITH_MCP" == true ]]; then
471
+ echo "Installing Pi MCP adapter:"
472
+ if [[ "$DRY_RUN" == false ]]; then
473
+ verify_npm_integrity "$PI_MCP_ADAPTER_SOURCE" "$PI_MCP_ADAPTER_INTEGRITY"
474
+ fi
475
+ run_cmd pi install "$PI_MCP_ADAPTER_SOURCE"
476
+ if [[ "$DRY_RUN" == false ]] && command -v pi-mcp-adapter >/dev/null 2>&1; then
477
+ pi-mcp-adapter init || true
478
+ fi
479
+ echo "Configuring shared global MCP baseline:"
480
+ run_cmd bash "$PLATFORM_ROOT/scripts/configure-mcp.sh" --scope global --preset "$MCP_PRESET" --replace
481
+ fi
482
+
483
+ if [[ "$WITH_SUBAGENTS" == true ]]; then
484
+ echo "Installing Pi subagents:"
485
+ if [[ "$DRY_RUN" == false ]]; then
486
+ verify_npm_integrity "$PI_SUBAGENTS_SOURCE" "$PI_SUBAGENTS_INTEGRITY"
487
+ fi
488
+ run_cmd pi install "$PI_SUBAGENTS_SOURCE"
489
+ echo "Configuring Pi subagents baseline:"
490
+ run_cmd bash "$PLATFORM_ROOT/scripts/configure-subagents.sh" --preset "$SUBAGENTS_PRESET" --model-scope "$SUBAGENTS_MODEL_SCOPE"
491
+ fi
492
+
493
+ if [[ "$WITH_WEB_ACCESS" == true ]]; then
494
+ echo "Installing Pi web access for researcher subagent:"
495
+ if [[ "$DRY_RUN" == false ]]; then
496
+ verify_npm_integrity "$PI_WEB_ACCESS_SOURCE" "$PI_WEB_ACCESS_INTEGRITY"
497
+ fi
498
+ run_cmd pi install "$PI_WEB_ACCESS_SOURCE"
499
+ fi
500
+
501
+ if [[ "$CONFIGURE_MODEL_SCOPE" == true ]]; then
502
+ echo "Configuring Pi model selector scope:"
503
+ run_cmd bash "$PLATFORM_ROOT/scripts/configure-model-scope.sh" --preset "$MODEL_SCOPE_PRESET" --default-model "$DEFAULT_MODEL"
504
+ fi
505
+
506
+ if [[ "$WITH_HERDR" == true ]]; then
507
+ if ! command -v herdr >/dev/null 2>&1; then
508
+ echo "WARN: herdr is not on PATH. Skipping Herdr integration." >&2
509
+ else
510
+ PI_AGENT_DIR="${PI_CODING_AGENT_DIR:-"${HOME}/.pi/agent"}"
511
+ run_cmd mkdir -p "$PI_AGENT_DIR/extensions"
512
+ run_cmd herdr integration install pi
513
+ fi
514
+ fi
515
+
516
+ echo
517
+ echo "Installed packages:"
518
+ if [[ "$DRY_RUN" == true ]]; then
519
+ print_cmd pi list
520
+ else
521
+ pi list
522
+ fi
523
+
524
+ echo
525
+ echo "Next:"
526
+ echo " pi"
527
+ echo " /login"
528
+ echo " /model # or Ctrl+L: select provider/model from Pi selector"
529
+ echo " /scoped-models # optional: edit Ctrl+P model cycle scope"
530
+ echo " /mcp # inspect MCP servers; authenticate Figma/GitHub only when needed"
531
+ echo " /subagents-doctor"
532
+ echo " /task Implement <task> # parent may auto-delegate scout/planner/reviewer"
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ if [[ $# -lt 2 ]]; then
5
+ echo "Usage: $0 <project-path> <adapter-profile-json> [package-source]" >&2
6
+ echo "Deprecated wrapper. Prefer scripts/init-project.sh <project-path> --profile <name-or-json> --package-source <source>" >&2
7
+ exit 2
8
+ fi
9
+
10
+ PROJECT_PATH="$1"
11
+ ADAPTER_PROFILE="$2"
12
+ PACKAGE_SOURCE="${3:-${PIAGENT_PACKAGE_SOURCE:-}}"
13
+ PLATFORM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
14
+
15
+ args=(
16
+ "$PROJECT_PATH"
17
+ --profile "$ADAPTER_PROFILE"
18
+ )
19
+
20
+ if [[ -n "$PACKAGE_SOURCE" ]]; then
21
+ args+=(--package-source "$PACKAGE_SOURCE")
22
+ fi
23
+
24
+ echo "WARN: link-project.sh is deprecated; forwarding to init-project.sh" >&2
25
+ exec "$PLATFORM_ROOT/scripts/init-project.sh" "${args[@]}"