@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,187 @@
1
+ const REDACTION = "[REDACTED_SECRET]";
2
+
3
+ const TOKEN_PATTERNS = [
4
+ /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
5
+ /\bAKIA[0-9A-Z]{16}\b/g,
6
+ /\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,
7
+ /\bgh[opsru]_[A-Za-z0-9_]{20,}\b/g,
8
+ /\bsk-(?:(?:proj|svcacct|admin|ant)-)?[A-Za-z0-9_-]{20,}\b/g,
9
+ /\bsk_(?:live|test)_[A-Za-z0-9]{16,}\b/g,
10
+ /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g,
11
+ /\bAIza[0-9A-Za-z_-]{20,}\b/g,
12
+ /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g
13
+ ];
14
+
15
+ const CONNECTION_URL_PATTERN = /\b((?:https?|ftp|postgres(?:ql)?|mysql|mariadb|mongodb(?:\+srv)?|redis):\/\/[^:\s/"']+:)([^@\s/"']+)(@[^\s"'<>]+)/gi;
16
+ const BEARER_PATTERN = /\b(Bearer\s+)([A-Za-z0-9._~+/=-]{20,})\b/gi;
17
+ const BASIC_AUTH_PATTERN = /\b(Basic\s+)([A-Za-z0-9+/]{12,}={0,2})(?=$|[\s,;}])/gi;
18
+ const AUTHORIZATION_HEADER_PATTERN = /\b(Authorization\s*:\s*)([A-Za-z][A-Za-z0-9_-]{0,31})(\s+)([^\r\n]+)/gi;
19
+ const QUERY_SECRET_PATTERN = /([?&])([A-Za-z][A-Za-z0-9_.-]{0,80})(=)([^&#\s]+)/gi;
20
+ const DOUBLE_QUOTED_SECRET_ASSIGNMENT_PATTERN = /(^|[\s{[,(;])((?:"|')?[A-Za-z][A-Za-z0-9_.-]{0,80}(?:"|')?\s*)(:|=(?!=))\s*"((?:\\.|[^"\\\r\n])*)"/gim;
21
+ const SINGLE_QUOTED_SECRET_ASSIGNMENT_PATTERN = /(^|[\s{[,(;])((?:"|')?[A-Za-z][A-Za-z0-9_.-]{0,80}(?:"|')?\s*)(:|=(?!=))\s*'((?:\\.|[^'\\\r\n])*)'/gim;
22
+ const SECRET_ASSIGNMENT_PATTERN = /(^|[\s{[,(;])((?:"|')?[A-Za-z][A-Za-z0-9_.-]{0,80}(?:"|')?\s*)(:|=(?!=))\s*([^"'\s,;}]+)/gim;
23
+ const WHITESPACE_SECRET_ASSIGNMENT_PATTERN = /(^|[\s{[,(;])((?:"|')?(?:aws_)?secret_access_key(?:"|')?\s+)(["']?)([A-Za-z0-9/+=]{20,})/gim;
24
+
25
+ const SENSITIVE_KEY_TERMS = [
26
+ "api_key",
27
+ "token",
28
+ "password",
29
+ "passwd",
30
+ "pwd",
31
+ "secret",
32
+ "credential",
33
+ "client_secret",
34
+ "access_token",
35
+ "refresh_token",
36
+ "secret_access_key",
37
+ "passphrase",
38
+ "private_key",
39
+ "signing_key",
40
+ "authorization"
41
+ ];
42
+ const SENSITIVE_PLURAL_KEYS = new Set([
43
+ "tokens",
44
+ "api_keys",
45
+ "passwords",
46
+ "secrets",
47
+ "credentials",
48
+ "client_secrets",
49
+ "access_tokens",
50
+ "refresh_tokens",
51
+ "session_tokens",
52
+ "passphrases",
53
+ "private_keys",
54
+ "signing_keys",
55
+ "authorizations"
56
+ ]);
57
+ const LOWER_THRESHOLD_PLURAL_KEYS = new Set([
58
+ "passwords",
59
+ "secrets",
60
+ "credentials",
61
+ "passphrases",
62
+ "private_keys",
63
+ "signing_keys"
64
+ ]);
65
+
66
+ function normalizeSecretValue(value) {
67
+ return String(value ?? "")
68
+ .trim()
69
+ .replace(/^[`"']|[`"']$/g, "")
70
+ .replace(/[.;)]+$/g, "");
71
+ }
72
+
73
+ function patternMatches(pattern, value) {
74
+ pattern.lastIndex = 0;
75
+ return pattern.test(value);
76
+ }
77
+
78
+ function looksLikeKnownSecret(value) {
79
+ return TOKEN_PATTERNS.some((pattern) => patternMatches(pattern, value))
80
+ || patternMatches(CONNECTION_URL_PATTERN, value)
81
+ || patternMatches(BEARER_PATTERN, value);
82
+ }
83
+
84
+ function normalizeSecretKey(key) {
85
+ return String(key ?? "")
86
+ .trim()
87
+ .replace(/^["']|["']$/g, "")
88
+ .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
89
+ .replace(/[^A-Za-z0-9]+/g, "_")
90
+ .replace(/^_+|_+$/g, "")
91
+ .toLowerCase();
92
+ }
93
+
94
+ function keyLooksSensitive(key) {
95
+ const normalized = normalizeSecretKey(key);
96
+ return SENSITIVE_PLURAL_KEYS.has(normalized) || SENSITIVE_KEY_TERMS.some((term) => normalized === term
97
+ || normalized.endsWith(`_${term}`));
98
+ }
99
+
100
+ function keyRequiresLowerThreshold(key) {
101
+ const normalized = normalizeSecretKey(key);
102
+ return LOWER_THRESHOLD_PLURAL_KEYS.has(normalized)
103
+ || ["password", "passwd", "pwd", "secret", "credential", "passphrase", "private_key", "signing_key"]
104
+ .some((term) => normalized === term || normalized.endsWith(`_${term}`));
105
+ }
106
+
107
+ function valueLooksPlaceholder(value) {
108
+ const clean = normalizeSecretValue(value);
109
+ if (!clean) return true;
110
+ if (/^(?:null|undefined|none|false|true|0|""|'')$/i.test(clean)) return true;
111
+ if (/^<[^>\n]{1,80}>$/.test(clean)) return true;
112
+ if (/^\[REDACTED_SECRET\]$/i.test(clean)) return true;
113
+ if (/^(?:not-set|unset|placeholder|example|changeme|change-me|redacted|xxx|\*{3,})$/i.test(clean)) return true;
114
+ if (/^your[-_][a-z0-9][a-z0-9_-]*$/i.test(clean)) return true;
115
+ return false;
116
+ }
117
+
118
+ function valueLooksSensitive(key, value) {
119
+ const clean = normalizeSecretValue(value);
120
+ if (!clean || valueLooksPlaceholder(clean)) return false;
121
+ if (looksLikeKnownSecret(clean)) return true;
122
+ if (keyRequiresLowerThreshold(key)) return clean.length >= 8;
123
+ return keyLooksSensitive(key) && clean.length >= 12;
124
+ }
125
+
126
+ export function redactSensitiveText(input) {
127
+ if (typeof input !== "string") return { text: "", redacted: false };
128
+ let text = input;
129
+
130
+ text = text.replace(CONNECTION_URL_PATTERN, (_match, prefix, _password, suffix) => `${prefix}${REDACTION}${suffix}`);
131
+ text = text.replace(BEARER_PATTERN, (_match, prefix) => `${prefix}${REDACTION}`);
132
+ text = text.replace(BASIC_AUTH_PATTERN, (_match, prefix) => `${prefix}${REDACTION}`);
133
+ text = text.replace(AUTHORIZATION_HEADER_PATTERN, (match, prefix, scheme, spacing, value) => {
134
+ if (!valueLooksSensitive("authorization", value)) return match;
135
+ return `${prefix}${scheme}${spacing}${REDACTION}`;
136
+ });
137
+
138
+ for (const pattern of TOKEN_PATTERNS) text = text.replace(pattern, REDACTION);
139
+
140
+ text = text.replace(QUERY_SECRET_PATTERN, (match, prefix, key, separator, value) => {
141
+ if (!keyLooksSensitive(key) || !valueLooksSensitive(key, value)) return match;
142
+ return `${prefix}${key}${separator}${REDACTION}`;
143
+ });
144
+
145
+ text = text.replace(DOUBLE_QUOTED_SECRET_ASSIGNMENT_PATTERN, (match, prefix, key, separator, value) => {
146
+ if (!keyLooksSensitive(key) || !valueLooksSensitive(key, value)) return match;
147
+ return `${prefix}${key}${separator} "${REDACTION}"`;
148
+ });
149
+
150
+ text = text.replace(SINGLE_QUOTED_SECRET_ASSIGNMENT_PATTERN, (match, prefix, key, separator, value) => {
151
+ if (!keyLooksSensitive(key) || !valueLooksSensitive(key, value)) return match;
152
+ return `${prefix}${key}${separator} '${REDACTION}'`;
153
+ });
154
+
155
+ text = text.replace(SECRET_ASSIGNMENT_PATTERN, (match, prefix, key, separator, value) => {
156
+ if (!keyLooksSensitive(key) || !valueLooksSensitive(key, value)) return match;
157
+ return `${prefix}${key}${separator} ${REDACTION}`;
158
+ });
159
+
160
+ text = text.replace(WHITESPACE_SECRET_ASSIGNMENT_PATTERN, (match, prefix, key, quote, value) => {
161
+ if (!valueLooksSensitive(key, value)) return match;
162
+ return `${prefix}${key}${quote}${REDACTION}`;
163
+ });
164
+
165
+ return { text, redacted: text !== input };
166
+ }
167
+
168
+ export function containsSensitiveText(input) {
169
+ return typeof input === "string" && redactSensitiveText(input).redacted;
170
+ }
171
+
172
+ function redactStorageValue(value, key) {
173
+ if (typeof value === "string") {
174
+ const redacted = redactSensitiveText(value);
175
+ if (redacted.redacted) return redacted.text;
176
+ return key && keyLooksSensitive(key) && valueLooksSensitive(key, value) ? REDACTION : value;
177
+ }
178
+ if (Array.isArray(value)) return value.map((item) => redactStorageValue(item, key));
179
+ if (!value || typeof value !== "object") return value;
180
+ return Object.fromEntries(
181
+ Object.entries(value).map(([childKey, item]) => [childKey, redactStorageValue(item, childKey)])
182
+ );
183
+ }
184
+
185
+ export function redactForStorage(value) {
186
+ return redactStorageValue(value, undefined);
187
+ }
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: piagent-ops
3
+ description: Piagent operating policy for Pi tasks across projects.
4
+ ---
5
+
6
+ # Piagent Ops Skill
7
+
8
+ Use this skill for every implementation, review, planning, MCP, or tooling task in a project using Pi Agent Platform.
9
+
10
+ ## Mandatory steps
11
+
12
+ 1. Load active project profile with `piagent_context`.
13
+ 2. Read required context before planning or editing; use `piagent_context_budget` for large files.
14
+ 3. Start source-changing work with `piagent_task_start`.
15
+ 4. Respect `protectedPaths`.
16
+ 5. Check complex/high-impact shell with `piagent_exec_policy_check`.
17
+ 6. Check non-piagent MCP/app tools with `piagent_tool_policy_check`.
18
+ 7. Use MCP only when capability is declared.
19
+ 8. Prefer small diffs with explicit verification.
20
+ 9. Run the exact command from `task.verifyCommands` for passing evidence; ad-hoc commands are advisory only.
21
+ 10. Record context, verify, and trace with `piagent_context_record`, `piagent_verify_record`, and `piagent_trace_record`.
22
+ 11. Before DONE, call `piagent_task_gate_check`.
23
+
24
+ ## Risk gates
25
+
26
+ Stop for human confirmation when task touches:
27
+
28
+ - auth
29
+ - payments
30
+ - data migration
31
+ - external provider setup
32
+ - deploy/release
33
+ - destructive filesystem operation
34
+ - broad refactor across unrelated modules
35
+
36
+ ## Final response
37
+
38
+ Always include:
39
+
40
+ - what changed
41
+ - where
42
+ - exact verification result
43
+ - task gate result
44
+ - what remains manual
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: piagent-source-cache
3
+ description: Cache and inspect user-provided external Git repositories.
4
+ ---
5
+
6
+ # Piagent Source Cache
7
+
8
+ Use this skill when the user provides a GitHub/GitLab/Bitbucket repository as source context for a task.
9
+
10
+ ## Goal
11
+
12
+ Keep external source repositories:
13
+
14
+ - stable: predictable cache path;
15
+ - fresh: throttled fetch;
16
+ - cheap: no repeated clone;
17
+ - safe: never edit the shared cache directly.
18
+
19
+ ## Workflow
20
+
21
+ 1. Prefer the runtime tool if available:
22
+
23
+ ```text
24
+ piagent_source_checkout(repoRef="owner/repo")
25
+ ```
26
+
27
+ 2. If the runtime tool is unavailable, resolve the repo into a local checkout from a platform clone:
28
+
29
+ ```bash
30
+ PIAGENT_PLATFORM_HOME=/path/to/piagent-platform
31
+ bash "$PIAGENT_PLATFORM_HOME/packages/piagent-core/skills/piagent-source-cache/checkout-source-repo.sh" <repo-ref> --path-only
32
+ ```
33
+
34
+ 3. Use the printed path for targeted `rg`, `sed`, and file reads.
35
+ 4. Read only files relevant to the user request.
36
+ 5. If edits are needed, create a separate project/worktree; do not edit the cache.
37
+ 6. Cite the source URL in reports when needed.
38
+
39
+ ## Supported refs
40
+
41
+ - `owner/repo`
42
+ - `github.com/owner/repo`
43
+ - `https://github.com/owner/repo`
44
+ - `git@github.com:owner/repo.git`
45
+
46
+ ## Cache location
47
+
48
+ Default:
49
+
50
+ ```text
51
+ ${XDG_CACHE_HOME:-$HOME/.cache}/piagent-platform/checkouts/<host>/<owner>/<repo>
52
+ ```
53
+
54
+ Override:
55
+
56
+ ```bash
57
+ PIAGENT_PLATFORM_HOME=/path/to/piagent-platform
58
+ PIAGENT_CHECKOUT_CACHE=/path/to/cache bash "$PIAGENT_PLATFORM_HOME/packages/piagent-core/skills/piagent-source-cache/checkout-source-repo.sh" owner/repo --path-only
59
+ ```
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ usage() {
5
+ echo "Usage: $0 <repo-ref> [--path-only] [--force-update]"
6
+ }
7
+
8
+ if [[ $# -lt 1 ]]; then
9
+ usage
10
+ exit 2
11
+ fi
12
+
13
+ REPO_REF="$1"
14
+ shift
15
+
16
+ PATH_ONLY=false
17
+ FORCE_UPDATE=false
18
+ for arg in "$@"; do
19
+ case "$arg" in
20
+ --path-only)
21
+ PATH_ONLY=true
22
+ ;;
23
+ --force-update)
24
+ FORCE_UPDATE=true
25
+ ;;
26
+ -h|--help)
27
+ usage
28
+ exit 0
29
+ ;;
30
+ *)
31
+ echo "Unknown option: $arg" >&2
32
+ usage >&2
33
+ exit 2
34
+ ;;
35
+ esac
36
+ done
37
+
38
+ parse_repo_ref() {
39
+ local ref="$1"
40
+ local host=""
41
+ local rest=""
42
+
43
+ case "$ref" in
44
+ http://*|https://*)
45
+ local no_proto="${ref#*://}"
46
+ host="${no_proto%%/*}"
47
+ rest="${no_proto#*/}"
48
+ ;;
49
+ git@*:*)
50
+ local no_user="${ref#git@}"
51
+ host="${no_user%%:*}"
52
+ rest="${no_user#*:}"
53
+ ;;
54
+ *.*/*/*)
55
+ host="${ref%%/*}"
56
+ rest="${ref#*/}"
57
+ ;;
58
+ */*)
59
+ host="github.com"
60
+ rest="$ref"
61
+ ;;
62
+ *)
63
+ echo "Unsupported repository reference: $ref" >&2
64
+ return 1
65
+ ;;
66
+ esac
67
+
68
+ rest="${rest%.git}"
69
+ IFS="/" read -r owner repo _extra <<< "$rest"
70
+
71
+ if [[ -z "${host:-}" || -z "${owner:-}" || -z "${repo:-}" ]]; then
72
+ echo "Could not parse repository reference: $ref" >&2
73
+ return 1
74
+ fi
75
+
76
+ if [[ ! "$host" =~ ^[A-Za-z0-9._-]+$ || ! "$owner" =~ ^[A-Za-z0-9._-]+$ || ! "$repo" =~ ^[A-Za-z0-9._-]+$ ]]; then
77
+ echo "Repository reference contains unsupported characters: $ref" >&2
78
+ return 1
79
+ fi
80
+
81
+ printf '%s\t%s\t%s\n' "$host" "$owner" "$repo"
82
+ }
83
+
84
+ IFS=$'\t' read -r HOST OWNER REPO <<< "$(parse_repo_ref "$REPO_REF")"
85
+
86
+ if [[ -n "${PIAGENT_CHECKOUT_CACHE:-}" ]]; then
87
+ CACHE_ROOT="$PIAGENT_CHECKOUT_CACHE"
88
+ elif [[ -n "${XDG_CACHE_HOME:-}" ]]; then
89
+ CACHE_ROOT="$XDG_CACHE_HOME/piagent-platform/checkouts"
90
+ elif [[ -n "${HOME:-}" ]]; then
91
+ CACHE_ROOT="$HOME/.cache/piagent-platform/checkouts"
92
+ else
93
+ echo "HOME or PIAGENT_CHECKOUT_CACHE is required" >&2
94
+ exit 1
95
+ fi
96
+
97
+ TARGET="$CACHE_ROOT/$HOST/$OWNER/$REPO"
98
+ STAMP_FILE="$TARGET/.piagent-last-fetch"
99
+ FETCH_INTERVAL_SECONDS="${PIAGENT_CHECKOUT_FETCH_INTERVAL_SECONDS:-300}"
100
+ CLONE_URL="https://$HOST/$OWNER/$REPO.git"
101
+
102
+ if [[ ! -d "$TARGET/.git" ]]; then
103
+ mkdir -p "$(dirname "$TARGET")"
104
+ git clone --filter=blob:none -- "$CLONE_URL" "$TARGET" >/dev/null
105
+ date +%s > "$STAMP_FILE"
106
+ else
107
+ NOW_SECONDS="$(date +%s)"
108
+ LAST_FETCH_SECONDS=0
109
+ if [[ -f "$STAMP_FILE" ]]; then
110
+ LAST_FETCH_SECONDS="$(tr -cd '0-9' < "$STAMP_FILE" || true)"
111
+ LAST_FETCH_SECONDS="${LAST_FETCH_SECONDS:-0}"
112
+ fi
113
+
114
+ SHOULD_FETCH=false
115
+ if [[ "$FORCE_UPDATE" == true ]]; then
116
+ SHOULD_FETCH=true
117
+ elif (( NOW_SECONDS - LAST_FETCH_SECONDS >= FETCH_INTERVAL_SECONDS )); then
118
+ SHOULD_FETCH=true
119
+ fi
120
+
121
+ if [[ "$SHOULD_FETCH" == true ]]; then
122
+ CLEAN_WORKTREE=false
123
+ if git -C "$TARGET" diff --quiet --ignore-submodules -- && git -C "$TARGET" diff --cached --quiet --ignore-submodules --; then
124
+ CLEAN_WORKTREE=true
125
+ fi
126
+
127
+ git -C "$TARGET" fetch --filter=blob:none --prune origin >/dev/null
128
+
129
+ if [[ "$CLEAN_WORKTREE" == true ]] && git -C "$TARGET" rev-parse --abbrev-ref --symbolic-full-name '@{u}' >/dev/null 2>&1; then
130
+ git -C "$TARGET" merge --ff-only '@{u}' >/dev/null || true
131
+ fi
132
+
133
+ date +%s > "$STAMP_FILE"
134
+ fi
135
+ fi
136
+
137
+ if [[ "$PATH_ONLY" == true ]]; then
138
+ printf '%s\n' "$TARGET"
139
+ else
140
+ echo "Source cache ready:"
141
+ echo " ref: $REPO_REF"
142
+ echo " url: $CLONE_URL"
143
+ echo " path: $TARGET"
144
+ fi
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: piagent-oracle
3
+ description: Piagent second-opinion advisor for risky plans and architecture decisions
4
+ tools: read, grep, find, ls
5
+ thinking: high
6
+ systemPromptMode: replace
7
+ inheritProjectContext: true
8
+ inheritSkills: false
9
+ defaultContext: fork
10
+ defaultProgress: true
11
+ acceptance: {"level":"attested"}
12
+ acceptanceRole: read-only
13
+ ---
14
+
15
+ You are `piagent-oracle`, a second-opinion subagent.
16
+
17
+ Your job is to challenge assumptions before implementation. Do not edit files. Focus on risks, missed constraints, simpler alternatives, and verification strategy.
18
+
19
+ Return a concise recommendation:
20
+
21
+ ## Oracle Review
22
+ - Best path:
23
+ - Assumptions to challenge:
24
+ - Hidden risks:
25
+ - Simpler alternative:
26
+ - Required verification:
27
+ - Human gate needed:
28
+ - Suggested parent prompt for execution:
29
+
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: piagent-planner
3
+ description: Piagent planner that turns scoped context into an implementation plan with verification gates
4
+ tools: read, grep, find, ls
5
+ thinking: high
6
+ systemPromptMode: replace
7
+ inheritProjectContext: true
8
+ inheritSkills: false
9
+ defaultContext: fork
10
+ defaultReads: context.md
11
+ defaultProgress: true
12
+ acceptance: {"level":"attested"}
13
+ acceptanceRole: read-only
14
+ ---
15
+
16
+ You are `piagent-planner`, a planning subagent for Pi Agent Platform projects.
17
+
18
+ Your job is to produce a concrete implementation plan, not to edit files.
19
+
20
+ Required behavior:
21
+ - Follow project profile, protected paths, required context, memory policy, and verification rules.
22
+ - Apply the current solo-first orchestration policy: parent owns decisions; subagents are bounded helpers, not a default swarm.
23
+ - Use Field Guide/memory only as advisory context and verify durable claims against repository files.
24
+ - Classify risk before proposing source changes.
25
+ - Split work into small stories with non-overlapping write sets when parallel execution is useful.
26
+ - Prefer one writer for a write set. Parallel writers must use worktree isolation.
27
+ - Recommend model roles only as guidance: strongest available model for planning/risk, fastest reliable model for bounded workers, decorrelated model/thinking for review when quality matters.
28
+ - Include exact verification commands and acceptance evidence.
29
+ - If a human gate is required, state it explicitly.
30
+
31
+ Final output:
32
+
33
+ ## Implementation Plan
34
+ - Goal:
35
+ - Current evidence:
36
+ - Risk lane:
37
+ - Write set:
38
+ - Read-only/protected areas:
39
+ - Task tree/workPlan:
40
+ - Review lenses:
41
+ - Steps:
42
+ - Verification:
43
+ - Suggested subagents:
44
+ - Model-role guidance:
45
+ - Human gates:
46
+ - Open questions:
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: piagent-reviewer
3
+ description: Piagent reviewer for implementation diff, policy, tests, and scope drift
4
+ tools: read, grep, find, ls, bash, edit, write, contact_supervisor
5
+ thinking: high
6
+ systemPromptMode: replace
7
+ inheritProjectContext: true
8
+ inheritSkills: false
9
+ defaultContext: fork
10
+ defaultReads: plan.md, progress.md
11
+ defaultProgress: true
12
+ acceptance: {"level":"attested"}
13
+ acceptanceRole: read-only
14
+ maxSubagentDepth: 0
15
+ ---
16
+
17
+ You are `piagent-reviewer`, a disciplined review subagent for Pi Agent Platform projects.
18
+
19
+ Your job is to review evidence, not to invent issues. Make small corrective edits only when the parent explicitly asks for autofix.
20
+
21
+ Use explicit review lenses from the parent task when provided. If no lenses are provided, cover correctness, tests/verification, and scope drift first; add security/release/package only when relevant to the change.
22
+
23
+ Review:
24
+ - task/plan alignment;
25
+ - protected path violations;
26
+ - implementation correctness;
27
+ - tests/verification evidence;
28
+ - security/data-migration/external-provider gates;
29
+ - unnecessary complexity and scope drift.
30
+
31
+ Rules:
32
+ - Cite exact files and line numbers when possible.
33
+ - Do not run destructive commands.
34
+ - Treat Field Guide/memory as advisory, not as proof.
35
+ - If review-only conflicts with progress-writing or artifact-writing instructions, review-only wins.
36
+ - If a blocker needs a decision, use `contact_supervisor` with `reason: "need_decision"`.
37
+ - Do not spawn other subagents.
38
+
39
+ Final output:
40
+
41
+ ## Review
42
+ - Lenses covered:
43
+ - Correct:
44
+ - Blockers:
45
+ - Important findings:
46
+ - Notes:
47
+ - Verification observed:
48
+ - Recommended fixes:
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: piagent-scout
3
+ description: Piagent read-only scout for bounded repo mapping before planning or implementation
4
+ tools: read, grep, find, ls
5
+ thinking: low
6
+ systemPromptMode: replace
7
+ inheritProjectContext: true
8
+ inheritSkills: false
9
+ defaultContext: fresh
10
+ defaultProgress: true
11
+ acceptance: {"level":"attested"}
12
+ acceptanceRole: read-only
13
+ ---
14
+
15
+ You are `piagent-scout`, a read-only reconnaissance subagent for Pi Agent Platform projects.
16
+
17
+ Your job is to map only the code/context needed for the delegated task. Do not edit files. Do not run mutation commands. Do not infer product decisions.
18
+
19
+ Required behavior:
20
+ - Follow project `AGENTS.md`, `.pi/piagent-profile.json`, `.pi/project-context.md`, and protected-path rules when they are present.
21
+ - Prefer `grep`, `find`, `ls`, and targeted `read`.
22
+ - Return exact file paths and the smallest useful code/context slices.
23
+ - If backend or another protected area is read-only, report gaps instead of changing it.
24
+ - If the task is unclear, list the minimum clarification questions.
25
+
26
+ Final output:
27
+
28
+ ## Scout Summary
29
+ - Scope inspected:
30
+ - Files that matter:
31
+ - Entry points:
32
+ - Data/control flow:
33
+ - Likely change targets:
34
+ - Protected/read-only areas:
35
+ - Risks or unknowns:
36
+ - Recommended next subagent/task:
37
+
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: piagent-worker
3
+ description: Piagent implementation worker for bounded approved tasks
4
+ tools: read, grep, find, ls, bash, edit, write, contact_supervisor
5
+ thinking: high
6
+ systemPromptMode: replace
7
+ inheritProjectContext: true
8
+ inheritSkills: false
9
+ defaultContext: fork
10
+ defaultReads: context.md, plan.md
11
+ defaultProgress: true
12
+ acceptance: {"level":"checked"}
13
+ acceptanceRole: writer
14
+ maxSubagentDepth: 0
15
+ ---
16
+
17
+ You are `piagent-worker`, a single-writer implementation subagent for Pi Agent Platform projects.
18
+
19
+ Your job is to implement a bounded, approved task. The parent session and user remain the decision authority.
20
+
21
+ Required behavior:
22
+ - Read supplied context/plan first.
23
+ - Follow `AGENTS.md`, `.pi/piagent-profile.json`, `.pi/project-context.md`, protected paths, and verification rules.
24
+ - Stay inside the assigned workPlan step/write set; do not re-plan broader scope unless you contact the supervisor.
25
+ - Treat Field Guide/memory as advisory and verify against current files before relying on it.
26
+ - Make the smallest correct source changes.
27
+ - Do not edit protected/read-only paths unless explicitly delegated by the user.
28
+ - Use `bash` for inspection and verification only.
29
+ - If a required decision is not approved, use `contact_supervisor` with `reason: "need_decision"` and wait.
30
+ - Do not spawn other subagents.
31
+ - Remain the only writer for the delegated write set unless the supervisor explicitly approves worktree-isolated parallel writers.
32
+ - Do not claim success if no edits were made for an implementation task.
33
+
34
+ Final output:
35
+
36
+ Implemented: <what changed>
37
+ Changed files:
38
+ - <path>
39
+ Validation:
40
+ - <command/result or N/A with reason>
41
+ Risks/questions:
42
+ - <remaining risk or none>
43
+ Recommended next step:
44
+ - <review/test/ship/etc>