ultimate-pi 0.18.1 → 0.19.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 (284) hide show
  1. package/.agents/skills/harness-debate-plan/SKILL.md +1 -1
  2. package/.agents/skills/harness-decisions/SKILL.md +1 -2
  3. package/.agents/skills/harness-governor/SKILL.md +6 -5
  4. package/.pi/PACKAGING.md +4 -4
  5. package/.pi/SYSTEM.md +54 -120
  6. package/.pi/agents/harness/incident-recorder.md +0 -1
  7. package/.pi/agents/harness/planning/decompose.md +0 -2
  8. package/.pi/agents/harness/planning/execution-plan-author.md +0 -2
  9. package/.pi/agents/harness/planning/hypothesis-validator.md +0 -2
  10. package/.pi/agents/harness/planning/hypothesis.md +0 -2
  11. package/.pi/agents/harness/planning/implementation-researcher.md +0 -2
  12. package/.pi/agents/harness/planning/plan-adversary.md +0 -2
  13. package/.pi/agents/harness/planning/plan-evaluator.md +1 -3
  14. package/.pi/agents/harness/planning/planning-context.md +0 -2
  15. package/.pi/agents/harness/planning/review-integrator.md +0 -2
  16. package/.pi/agents/harness/planning/sprint-contract-auditor.md +0 -2
  17. package/.pi/agents/harness/planning/stack-researcher.md +0 -2
  18. package/.pi/agents/harness/reviewing/adversary.md +0 -2
  19. package/.pi/agents/harness/reviewing/evaluator.md +0 -2
  20. package/.pi/agents/harness/reviewing/tie-breaker.md +0 -2
  21. package/.pi/agents/harness/running/executor.md +0 -2
  22. package/.pi/agents/harness/sentrux-bootstrap.md +0 -1
  23. package/.pi/agents/harness/sentrux-steward.md +0 -2
  24. package/.pi/agents/harness/trace-librarian.md +0 -1
  25. package/.pi/extensions/00-posthog-network-bootstrap.ts +1 -1
  26. package/.pi/extensions/agt-kill-switch.ts +57 -0
  27. package/.pi/extensions/agt-prompt-guard.ts +32 -0
  28. package/.pi/extensions/custom-footer.ts +46 -145
  29. package/.pi/extensions/custom-header.ts +1 -1
  30. package/.pi/extensions/custom-system-prompt.ts +1 -1
  31. package/.pi/extensions/debate-orchestrator.ts +6 -6
  32. package/.pi/extensions/harness-ask-user.ts +7 -7
  33. package/.pi/extensions/harness-debate-tools.ts +26 -42
  34. package/.pi/extensions/harness-lens.ts +94 -0
  35. package/.pi/extensions/harness-plan-approval.ts +11 -11
  36. package/.pi/extensions/harness-run-context.ts +1070 -876
  37. package/.pi/extensions/harness-subagent-governance.ts +8 -0
  38. package/.pi/extensions/harness-subagent-submit.ts +34 -163
  39. package/.pi/extensions/harness-subagents.ts +3 -3
  40. package/.pi/extensions/harness-telemetry.ts +2 -2
  41. package/.pi/extensions/harness-web-tools.ts +2 -2
  42. package/.pi/extensions/policy-gate.ts +25 -5
  43. package/.pi/extensions/sentrux-rules-sync.ts +1 -1
  44. package/.pi/extensions/subagent-governance.ts +92 -0
  45. package/.pi/extensions/trace-recorder.ts +1 -1
  46. package/.pi/extensions/{ultimate-pi-vcc.ts → vcc-compaction.ts} +1 -1
  47. package/.pi/harness/README.md +6 -2
  48. package/.pi/harness/agents.manifest.json +22 -25
  49. package/.pi/harness/agents.policy.yaml +275 -0
  50. package/.pi/harness/docs/adrs/0030-inhouse-vcc-compaction.md +1 -1
  51. package/.pi/harness/docs/adrs/0035-plan-phase-review-gate.md +1 -1
  52. package/.pi/harness/docs/adrs/0045-harness-lens-minimal-contract.md +49 -0
  53. package/.pi/harness/docs/adrs/0046-agt-policy-engine.md +51 -0
  54. package/.pi/harness/docs/adrs/0047-agt-layered-security.md +39 -0
  55. package/.pi/harness/docs/adrs/0048-tool-call-hook-order.md +25 -0
  56. package/.pi/harness/docs/adrs/0049-agents-policy-manifest.md +36 -0
  57. package/.pi/harness/docs/adrs/README.md +5 -0
  58. package/.pi/harness/evolution/README.md +1 -2
  59. package/.pi/harness/examples/agents.policy.project.yaml +19 -0
  60. package/.pi/harness/examples/policies/custom-deny-bash.yaml +9 -0
  61. package/.pi/harness/policies/bash-denylists.yaml +5 -0
  62. package/.pi/harness/policies/defaults.yaml +51 -0
  63. package/.pi/harness/policies/orchestrator.yaml +18 -0
  64. package/.pi/harness/policies/phases.yaml +10 -0
  65. package/.pi/harness/policies/roles.yaml +5 -0
  66. package/.pi/harness/policies/web-guard.yaml +5 -0
  67. package/.pi/harness/policies/workflow-sequences.yaml +9 -0
  68. package/.pi/harness/sentrux/architecture.manifest.json +26 -4
  69. package/.pi/harness/specs/observation.schema.json +2 -1
  70. package/.pi/lib/agents-policy.d.mts +70 -0
  71. package/.pi/lib/agents-policy.mjs +325 -0
  72. package/.pi/lib/agents-policy.ts +19 -0
  73. package/.pi/lib/agt/audit-run-sink.ts +52 -0
  74. package/.pi/lib/agt/build-evaluation-context.ts +285 -0
  75. package/.pi/lib/agt/config.ts +28 -0
  76. package/.pi/lib/agt/delegation.ts +69 -0
  77. package/.pi/lib/agt/evaluate-policy.ts +56 -0
  78. package/.pi/lib/agt/identity-registry.ts +41 -0
  79. package/.pi/lib/agt/index.ts +55 -0
  80. package/.pi/lib/agt/kill-switch-state.ts +11 -0
  81. package/.pi/lib/agt/legacy-evaluate.ts +101 -0
  82. package/.pi/lib/agt/policy-engine.ts +154 -0
  83. package/.pi/lib/agt/rings.ts +21 -0
  84. package/.pi/lib/agt/sre-hooks.ts +45 -0
  85. package/.pi/lib/agt/trust-run-store.ts +26 -0
  86. package/.pi/lib/agt/workflow-history.ts +29 -0
  87. package/.pi/lib/agt-governance-active.ts +14 -0
  88. package/.pi/lib/agt-tool-guard.ts +78 -0
  89. package/.pi/lib/ask-user/dialog.ts +314 -0
  90. package/.pi/{extensions/lib → lib}/debate-bus-core.ts +10 -10
  91. package/.pi/{extensions/lib → lib}/debate-bus-state.ts +1 -1
  92. package/.pi/{extensions/lib → lib}/extension-load-guard.ts +13 -2
  93. package/.pi/lib/harness-agt-tool-guard.ts +5 -0
  94. package/.pi/{extensions/lib → lib}/harness-artifact-gate.ts +1 -1
  95. package/.pi/lib/harness-debate-core-deps.ts +14 -0
  96. package/.pi/lib/harness-debate-workflow-deps.ts +43 -0
  97. package/.pi/lib/harness-lens/.gitattributes +1 -0
  98. package/.pi/lib/harness-lens/clients/edit-autopatch.ts +88 -0
  99. package/.pi/lib/harness-lens/clients/file-kinds.ts +380 -0
  100. package/.pi/lib/harness-lens/clients/file-time.ts +215 -0
  101. package/.pi/lib/harness-lens/clients/file-utils.ts +484 -0
  102. package/.pi/lib/harness-lens/clients/format-service.ts +276 -0
  103. package/.pi/lib/harness-lens/clients/formatters.ts +1000 -0
  104. package/.pi/lib/harness-lens/clients/git-guard.ts +31 -0
  105. package/.pi/lib/harness-lens/clients/indent-retarget.ts +90 -0
  106. package/.pi/lib/harness-lens/clients/installer/index.ts +2368 -0
  107. package/.pi/lib/harness-lens/clients/latency-logger.ts +80 -0
  108. package/.pi/lib/harness-lens/clients/lens-config.ts +43 -0
  109. package/.pi/lib/harness-lens/clients/lens-events.ts +164 -0
  110. package/.pi/lib/harness-lens/clients/lsp/aggregation.ts +91 -0
  111. package/.pi/lib/harness-lens/clients/lsp/client.ts +1466 -0
  112. package/.pi/lib/harness-lens/clients/lsp/config.ts +216 -0
  113. package/.pi/lib/harness-lens/clients/lsp/edits.ts +297 -0
  114. package/.pi/lib/harness-lens/clients/lsp/index.ts +1355 -0
  115. package/.pi/lib/harness-lens/clients/lsp/interactive-install.ts +424 -0
  116. package/.pi/lib/harness-lens/clients/lsp/language.ts +223 -0
  117. package/.pi/lib/harness-lens/clients/lsp/launch.ts +939 -0
  118. package/.pi/lib/harness-lens/clients/lsp/lsp-index.ts +11 -0
  119. package/.pi/lib/harness-lens/clients/lsp/path-utils.ts +12 -0
  120. package/.pi/lib/harness-lens/clients/lsp/server-strategies.ts +81 -0
  121. package/.pi/lib/harness-lens/clients/lsp/server.ts +1971 -0
  122. package/.pi/lib/harness-lens/clients/path-utils.ts +182 -0
  123. package/.pi/lib/harness-lens/clients/pipeline.ts +360 -0
  124. package/.pi/lib/harness-lens/clients/project-profile.ts +117 -0
  125. package/.pi/lib/harness-lens/clients/runtime-agent-end.ts +112 -0
  126. package/.pi/lib/harness-lens/clients/runtime-config.ts +33 -0
  127. package/.pi/lib/harness-lens/clients/runtime-coordinator.ts +186 -0
  128. package/.pi/lib/harness-lens/clients/runtime-tool-result.ts +171 -0
  129. package/.pi/lib/harness-lens/clients/safe-spawn.ts +339 -0
  130. package/.pi/lib/harness-lens/clients/secrets-scanner.ts +214 -0
  131. package/.pi/lib/harness-lens/clients/tool-policy.ts +2072 -0
  132. package/.pi/lib/harness-lens/clients/types.ts +59 -0
  133. package/.pi/lib/harness-lens/clients/widget-state.ts +283 -0
  134. package/.pi/lib/harness-lens/index.ts +532 -0
  135. package/.pi/lib/harness-lens/tools/lsp-diagnostics.ts +706 -0
  136. package/.pi/lib/harness-lens/tools/lsp-navigation.ts +1246 -0
  137. package/.pi/{extensions/lib → lib}/harness-posthog.ts +3 -0
  138. package/.pi/lib/harness-run-context-responses.ts +9 -0
  139. package/.pi/lib/harness-run-context.ts +0 -2
  140. package/.pi/{extensions/lib/spawn-policy.ts → lib/harness-spawn-policy.ts} +1 -0
  141. package/.pi/{extensions/lib → lib}/harness-spawn-topology.ts +1 -1
  142. package/.pi/lib/harness-subagent-auth.ts +51 -0
  143. package/.pi/{extensions/lib → lib}/harness-subagent-precheck.ts +10 -7
  144. package/.pi/{extensions/lib → lib}/harness-subagent-submit-pipeline.ts +3 -3
  145. package/.pi/lib/harness-subagent-submit-register.ts +163 -0
  146. package/.pi/{extensions/lib → lib}/harness-subagent-submit-registry.ts +1 -37
  147. package/.pi/{extensions/lib → lib}/harness-subagents-bridge.ts +53 -14
  148. package/.pi/{extensions/lib → lib}/harness-subprocess-bootstrap.ts +1 -1
  149. package/.pi/{extensions/lib → lib}/plan-approval/create-plan.ts +2 -2
  150. package/.pi/{extensions/lib → lib}/plan-approval/format-plan.ts +2 -2
  151. package/.pi/{extensions/lib → lib}/plan-approval/plan-review.ts +162 -201
  152. package/.pi/{extensions/lib → lib}/plan-approval/render.ts +1 -1
  153. package/.pi/{extensions/lib → lib}/plan-approval/resolve-disk.ts +2 -2
  154. package/.pi/{extensions/lib → lib}/plan-approval/types.ts +1 -1
  155. package/.pi/{extensions/lib → lib}/plan-approval/validate.ts +3 -3
  156. package/.pi/{extensions/lib → lib}/plan-debate-envelope.ts +1 -1
  157. package/.pi/{extensions/lib → lib}/plan-debate-gate.ts +1 -1
  158. package/.pi/{extensions/lib → lib}/plan-debate-lane.ts +1 -4
  159. package/.pi/{extensions/lib → lib}/plan-messenger.ts +1 -1
  160. package/.pi/prompts/harness-plan.md +1 -1
  161. package/.pi/prompts/harness-setup.md +37 -64
  162. package/.pi/scripts/README.md +2 -5
  163. package/.pi/scripts/generate-agents-policy-yaml.mjs +148 -0
  164. package/.pi/scripts/harness-agents-manifest.mjs +60 -3
  165. package/.pi/scripts/harness-agt-doctor.ts +36 -0
  166. package/.pi/scripts/harness-cli-verify.sh +9 -2
  167. package/.pi/scripts/harness-verify.mjs +113 -39
  168. package/.pi/scripts/harness-web-policy-guard.mjs +2 -2
  169. package/.pi/scripts/validate-plan-dag.mjs +65 -74
  170. package/.pi/scripts/vendor-pi-vcc-settings.stub.ts +2 -2
  171. package/.pi/scripts/vendor-sync-pi-vcc.sh +1 -1
  172. package/.pi/skills/architecture/broker-domain/SKILL.md +65 -0
  173. package/.pi/skills/architecture/cqrs/SKILL.md +63 -0
  174. package/.pi/skills/architecture/event-driven/SKILL.md +60 -0
  175. package/.pi/skills/architecture/hexagonal-ports-adapters/SKILL.md +66 -0
  176. package/.pi/skills/architecture/layered/SKILL.md +68 -0
  177. package/.pi/skills/architecture/microkernel/SKILL.md +62 -0
  178. package/.pi/skills/architecture/microservices/SKILL.md +64 -0
  179. package/.pi/skills/architecture/modular-monolith/SKILL.md +65 -0
  180. package/.pi/skills/architecture/orchestration-driven-soa/SKILL.md +61 -0
  181. package/.pi/skills/architecture/pipeline/SKILL.md +63 -0
  182. package/.pi/skills/architecture/service-based/SKILL.md +64 -0
  183. package/.pi/skills/architecture/service-mesh/SKILL.md +60 -0
  184. package/.pi/skills/architecture/space-based/SKILL.md +60 -0
  185. package/.pi/skills/ast-grep/SKILL.md +40 -321
  186. package/.pi/skills/delivery/debugging-discipline/SKILL.md +36 -0
  187. package/.pi/skills/delivery/documentation-update/SKILL.md +33 -0
  188. package/.pi/skills/delivery/requirements-to-implementation/SKILL.md +34 -0
  189. package/.pi/skills/delivery/risk-based-verification/SKILL.md +43 -0
  190. package/.pi/skills/delivery/tradeoff-analysis/SKILL.md +34 -0
  191. package/.pi/skills/engineering/api-contract-design/SKILL.md +38 -0
  192. package/.pi/skills/engineering/cohesion-coupling/SKILL.md +43 -0
  193. package/.pi/skills/engineering/complexity-control/SKILL.md +31 -0
  194. package/.pi/skills/engineering/defensive-programming/SKILL.md +38 -0
  195. package/.pi/skills/engineering/dependency-management/SKILL.md +29 -0
  196. package/.pi/skills/engineering/domain-modeling/SKILL.md +32 -0
  197. package/.pi/skills/engineering/error-handling/SKILL.md +37 -0
  198. package/.pi/skills/engineering/legacy-code-seams/SKILL.md +35 -0
  199. package/.pi/skills/engineering/naming-and-intent/SKILL.md +29 -0
  200. package/.pi/skills/engineering/refactoring-safe-evolution/SKILL.md +35 -0
  201. package/.pi/skills/engineering/routine-function-design/SKILL.md +34 -0
  202. package/.pi/skills/engineering/small-change-discipline/SKILL.md +35 -0
  203. package/.pi/skills/lsp-navigation/SKILL.md +89 -0
  204. package/.pi/skills/quality/code-review-self-check/SKILL.md +35 -0
  205. package/.pi/skills/quality/privacy-data-handling/SKILL.md +26 -0
  206. package/.pi/skills/quality/security-review/SKILL.md +34 -0
  207. package/.pi/skills/quality/test-strategy/SKILL.md +33 -0
  208. package/.pi/skills/quality/testability-design/SKILL.md +33 -0
  209. package/.pi/skills/systems/concurrency-safety/SKILL.md +32 -0
  210. package/.pi/skills/systems/data-modeling-migrations/SKILL.md +31 -0
  211. package/.pi/skills/systems/observability-instrumentation/SKILL.md +32 -0
  212. package/.pi/skills/systems/performance-measurement/SKILL.md +35 -0
  213. package/.pi/skills/systems/reliability-design/SKILL.md +32 -0
  214. package/.sentrux/rules.toml +20 -4
  215. package/AGENTS.md +5 -0
  216. package/CHANGELOG.md +14 -0
  217. package/README.md +3 -12
  218. package/THIRD_PARTY_NOTICES.md +12 -21
  219. package/package.json +15 -7
  220. package/vendor/pi-subagents/src/agents.ts +45 -1
  221. package/vendor/pi-subagents/src/subagents.ts +866 -811
  222. package/vendor/pi-vcc/src/core/brief.ts +68 -99
  223. package/vendor/pi-vcc/src/core/settings.ts +2 -2
  224. package/.agents/skills/caveman/SKILL.md +0 -67
  225. package/.pi/agents/harness/meta-optimizer.md +0 -36
  226. package/.pi/extensions/lib/ask-user/dialog.ts +0 -260
  227. package/.pi/extensions/lib/harness-subagent-auth.ts +0 -207
  228. package/.pi/extensions/lib/harness-subagent-policy.ts +0 -236
  229. package/.pi/extensions/pi-model-router-harness.ts +0 -42
  230. package/.pi/harness/evolution/meta-optimizer.mjs +0 -99
  231. package/.pi/harness/specs/router-tuning-proposal.schema.json +0 -114
  232. package/.pi/model-router.example.json +0 -36
  233. package/.pi/prompts/harness-critic.md +0 -10
  234. package/.pi/prompts/harness-eval.md +0 -10
  235. package/.pi/prompts/harness-router-tune.md +0 -52
  236. package/.pi/scripts/harness-generate-model-router.mjs +0 -327
  237. package/.pi/scripts/harness-model-router-routing.test.mjs +0 -97
  238. package/.pi/scripts/harness-sync-model-router.mjs +0 -97
  239. package/.pi/scripts/vendor-sync-pi-model-router.sh +0 -47
  240. package/vendor/pi-model-router/.prettierignore +0 -4
  241. package/vendor/pi-model-router/.prettierrc +0 -5
  242. package/vendor/pi-model-router/AGENTS.md +0 -39
  243. package/vendor/pi-model-router/LICENSE +0 -21
  244. package/vendor/pi-model-router/README.md +0 -99
  245. package/vendor/pi-model-router/UPSTREAM_PIN.md +0 -10
  246. package/vendor/pi-model-router/docs/ARCHITECTURE.md +0 -54
  247. package/vendor/pi-model-router/extensions/commands.ts +0 -720
  248. package/vendor/pi-model-router/extensions/config.ts +0 -348
  249. package/vendor/pi-model-router/extensions/constants.ts +0 -1
  250. package/vendor/pi-model-router/extensions/index.ts +0 -478
  251. package/vendor/pi-model-router/extensions/provider.ts +0 -580
  252. package/vendor/pi-model-router/extensions/routing.ts +0 -564
  253. package/vendor/pi-model-router/extensions/state.ts +0 -52
  254. package/vendor/pi-model-router/extensions/types.ts +0 -95
  255. package/vendor/pi-model-router/extensions/ui.ts +0 -144
  256. package/vendor/pi-model-router/model-router.example.json +0 -48
  257. package/vendor/pi-model-router/package.json +0 -48
  258. package/vendor/pi-model-router/tsconfig.json +0 -16
  259. /package/.pi/{prompts → harness/docs}/planning-rubrics.md +0 -0
  260. /package/.pi/{extensions/lib → lib}/ask-user/fallback.ts +0 -0
  261. /package/.pi/{extensions/lib → lib}/ask-user/render.ts +0 -0
  262. /package/.pi/{extensions/lib → lib}/ask-user/schema.ts +0 -0
  263. /package/.pi/{extensions/lib → lib}/ask-user/types.ts +0 -0
  264. /package/.pi/{extensions/lib → lib}/ask-user/validate-core.mjs +0 -0
  265. /package/.pi/{extensions/lib → lib}/ask-user/validate.ts +0 -0
  266. /package/.pi/{extensions/lib → lib}/harness-cocoindex-refresh.ts +0 -0
  267. /package/.pi/{extensions/lib → lib}/harness-paths.ts +0 -0
  268. /package/.pi/{extensions/lib → lib}/harness-spawn-budget.ts +0 -0
  269. /package/.pi/{extensions/lib → lib}/harness-vcc-settings.ts +0 -0
  270. /package/.pi/{extensions/lib → lib}/harness-web/run-cli.ts +0 -0
  271. /package/.pi/{extensions/lib → lib}/plan-approval/dialog.ts +0 -0
  272. /package/.pi/{extensions/lib → lib}/plan-approval/schema.ts +0 -0
  273. /package/.pi/{extensions/lib → lib}/plan-approval-readiness.ts +0 -0
  274. /package/.pi/{extensions/lib → lib}/plan-debate-eligibility.ts +0 -0
  275. /package/.pi/{extensions/lib → lib}/plan-debate-focus.ts +0 -0
  276. /package/.pi/{extensions/lib → lib}/plan-debate-id.ts +0 -0
  277. /package/.pi/{extensions/lib → lib}/plan-debate-lanes.ts +0 -0
  278. /package/.pi/{extensions/lib → lib}/plan-debate-round-status.ts +0 -0
  279. /package/.pi/{extensions/lib → lib}/plan-debate-write-guard.ts +0 -0
  280. /package/.pi/{extensions/lib → lib}/plan-review-gate.ts +0 -0
  281. /package/.pi/{extensions/lib → lib}/plan-review-integrator-rules.ts +0 -0
  282. /package/.pi/{extensions/lib → lib}/plan-scope-guard.ts +0 -0
  283. /package/.pi/{extensions/lib → lib}/posthog-client.ts +0 -0
  284. /package/.pi/{extensions/lib → lib}/posthog-node.d.ts +0 -0
@@ -1,36 +0,0 @@
1
- {
2
- "defaultProfile": "auto",
3
- "debug": false,
4
- "classifierModel": "openai/gpt-5.4-nano",
5
- "phaseBias": 0.5,
6
- "maxSessionBudget": 1.0,
7
- "largeContextThreshold": 100000,
8
- "rules": [
9
- {
10
- "matches": ["deploy", "production", "release"],
11
- "tier": "high",
12
- "reason": "Safety check for production tasks"
13
- },
14
- { "matches": "changelog", "tier": "low" }
15
- ],
16
- "profiles": {
17
- "auto": {
18
- "high": {
19
- "model": "openai/gpt-5.5",
20
- "thinking": "high",
21
- "fallbacks": ["openai/gpt-5.4-nano"]
22
- },
23
- "medium": { "model": "openai/gpt-5.5", "thinking": "medium" },
24
- "low": { "model": "openai/gpt-5.5", "thinking": "low" }
25
- },
26
- "opencode-go": {
27
- "high": {
28
- "model": "opencode-go/qwen3.6-plus",
29
- "thinking": "high",
30
- "fallbacks": ["opencode-go/deepseek-v4-flash"]
31
- },
32
- "medium": { "model": "opencode-go/qwen3.6-plus", "thinking": "medium" },
33
- "low": { "model": "opencode-go/qwen3.6-plus", "thinking": "low" }
34
- }
35
- }
36
- }
@@ -1,10 +0,0 @@
1
- ---
2
- description: "Deprecated alias — use /harness-review (includes adversary phase)."
3
- argument-hint: "[--run <run-id>] [--trace <trace-ref>] [--risk low|med|high]"
4
- ---
5
-
6
- # harness-critic
7
-
8
- **This command is deprecated.** Run **`/harness-review`** instead — Phase 4 runs `harness/reviewing/adversary` after benchmark and policy verdict pass (skip with `--quick`).
9
-
10
- If you must continue this turn only: forward to `/harness-review` with the same `$ARGUMENTS` (omit `--quick` if you need adversary). Do not spawn adversary in isolation unless the user explicitly requested adversary-only review.
@@ -1,10 +0,0 @@
1
- ---
2
- description: "Deprecated alias — use /harness-review (post-run master orchestrator)."
3
- argument-hint: "[--run <run-id>] [--quick] [--trace <trace-ref>]"
4
- ---
5
-
6
- # harness-eval
7
-
8
- **This command is deprecated.** Run **`/harness-review`** instead — it orchestrates deterministic gates, benchmark eval, policy verdict, and adversary review in one flow (ADR 0039).
9
-
10
- If you must continue this turn only: forward all work to `/harness-review` with the same arguments (`$ARGUMENTS`). Do not spawn a separate benchmark-only pass unless the user explicitly asked for benchmark-only diagnostics.
@@ -1,52 +0,0 @@
1
- ---
2
- description: Propose model-router updates from eval evidence; apply only with explicit approval.
3
- argument-hint: "--evidence <evidence.json> --candidate <candidate-router.json> [--proposal <out.json>]"
4
- ---
5
-
6
- # harness-router-tune
7
-
8
- Orchestrator — scripts + `harness/meta-optimizer` spawn. **Never** write `.pi/model-router.json` directly.
9
-
10
- ## Step 0 — Parse arguments
11
-
12
- - required: `--evidence <evidence.json>`, `--candidate <candidate-router.json>`
13
- - optional: `--proposal <out.json>`
14
-
15
- If missing required args:
16
-
17
- `Usage: /harness-router-tune --evidence <path> --candidate <path> [--proposal <out.json>]`
18
-
19
- ## Orchestration (required)
20
-
21
- 1. Parent validates evidence paths exist.
22
- 2. Optionally spawn:
23
-
24
- ```
25
- subagent({ agentScope: "both", agent: "harness/meta-optimizer", task: "mode: tune, evidence paths…" })
26
- ```
27
-
28
- 3. Parent runs proposal script:
29
-
30
- ```bash
31
- node .pi/harness/router/propose-router-tuning.mjs \
32
- --evidence <evidence.json> \
33
- --candidate <candidate-router.json> \
34
- --proposal-out .pi/harness/router/proposals/<id>.json
35
- ```
36
-
37
- 4. `ask_user` approve / reject / edit (harness-decisions).
38
- 5. Apply only after approval:
39
-
40
- ```bash
41
- node .pi/harness/router/apply-router-proposal.mjs \
42
- --proposal .pi/harness/router/proposals/<id>.json \
43
- --approve-by "<human>" \
44
- --justification "<reason>" \
45
- --write
46
- ```
47
-
48
- ## Completion
49
-
50
- - `tuning_status`: `proposed`, `human_required`, or `rejected`
51
- - Evidence gate summary
52
- - Confirm `.pi/model-router.json` was not mutated without apply script
@@ -1,327 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Generate `.pi/model-router.json` from Pi's authenticated providers (auth.json + env),
4
- * not from raw env-var heuristics alone.
5
- *
6
- * Uses @earendil-works/pi-coding-agent ModelRegistry.getAvailable() — same source as /login.
7
- *
8
- * Usage: node harness-generate-model-router.mjs [--force] [--dry-run]
9
- * --force overwrite existing .pi/model-router.json
10
- * --dry-run print JSON to stdout, do not write
11
- *
12
- * Requires @earendil-works/pi-coding-agent (peer of ultimate-pi; bundled with pi).
13
- */
14
-
15
- import { existsSync, mkdirSync, writeFileSync } from "node:fs";
16
- import { createRequire } from "node:module";
17
- import { dirname, join } from "node:path";
18
- import { fileURLToPath, pathToFileURL } from "node:url";
19
-
20
- const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
21
- const UP_PKG = join(SCRIPT_DIR, "..", "..");
22
- const OUT_PATH = join(process.cwd(), ".pi", "model-router.json");
23
-
24
- const PROVIDER_PRIORITY = [
25
- "openai",
26
- "opencode-go",
27
- "anthropic",
28
- "google",
29
- "openrouter",
30
- "groq",
31
- "mistral",
32
- "amazon",
33
- ];
34
-
35
- /** Substring hints per tier (first match in available ids wins). */
36
- const TIER_HINTS = {
37
- high: [
38
- "gpt-5.5-pro",
39
- "deepseek-v4-pro",
40
- "gpt-5.4-pro",
41
- "claude-opus",
42
- "sonnet-4",
43
- "gemini-2.5-pro",
44
- "pro",
45
- ],
46
- medium: [
47
- "gpt-5.5",
48
- "qwen3.6-plus",
49
- "kimi-k2.6",
50
- "gpt-5.4",
51
- "claude-sonnet",
52
- "gemini-flash",
53
- "plus",
54
- ],
55
- low: [
56
- "deepseek-v4-flash",
57
- "gpt-5.4-nano",
58
- "haiku",
59
- "flash-lite",
60
- "flash",
61
- "mini",
62
- ],
63
- };
64
-
65
- function fail(msg) {
66
- console.error(`harness-generate-model-router: ${msg}`);
67
- process.exit(1);
68
- }
69
-
70
- async function loadPiCodingAgent() {
71
- const scopes = ["@earendil-works", "@mariozechner"];
72
- const agentRoots = scopes.flatMap((scope) => [
73
- join(UP_PKG, "node_modules", scope, "pi-coding-agent"),
74
- join(UP_PKG, ".pi", "npm", "node_modules", scope, "pi-coding-agent"),
75
- ]);
76
- for (const root of agentRoots) {
77
- const entry = join(root, "dist", "index.js");
78
- if (existsSync(entry)) {
79
- return import(pathToFileURL(entry).href);
80
- }
81
- }
82
- for (const spec of ["@earendil-works/pi-coding-agent", "@mariozechner/pi-coding-agent"]) {
83
- for (const base of [UP_PKG, process.cwd()]) {
84
- try {
85
- const req = createRequire(join(base, "package.json"));
86
- return req(spec);
87
- } catch {
88
- /* try next */
89
- }
90
- }
91
- }
92
- fail(
93
- "@earendil-works/pi-coding-agent not found (install pi or npm i in ultimate-pi). Peer: @earendil-works/pi-coding-agent",
94
- );
95
- }
96
-
97
- function canonicalRef(provider, modelId) {
98
- return `${provider}/${modelId}`;
99
- }
100
-
101
- function pickTierModel(models, tier) {
102
- const hints = TIER_HINTS[tier];
103
- for (const hint of hints) {
104
- const exact = models.find((m) => m.id === hint);
105
- if (exact) return canonicalRef(exact.provider, exact.id);
106
- }
107
- for (const hint of hints) {
108
- const match = models.find((m) => m.id.includes(hint));
109
- if (match) return canonicalRef(match.provider, match.id);
110
- }
111
- if (models.length === 0) return null;
112
- if (tier === "high") {
113
- const reasoning = models.find((m) => m.reasoning);
114
- if (reasoning) return canonicalRef(reasoning.provider, reasoning.id);
115
- }
116
- if (tier === "low") {
117
- return canonicalRef(models[models.length - 1].provider, models[models.length - 1].id);
118
- }
119
- return canonicalRef(models[0].provider, models[0].id);
120
- }
121
-
122
- function modelsForProvider(available, provider) {
123
- return available.filter((m) => m.provider === provider);
124
- }
125
-
126
- function choosePrimaryProvider(available) {
127
- const byProvider = new Map();
128
- for (const m of available) {
129
- if (!byProvider.has(m.provider)) byProvider.set(m.provider, []);
130
- byProvider.get(m.provider).push(m);
131
- }
132
- for (const p of PROVIDER_PRIORITY) {
133
- if (byProvider.has(p)) return { provider: p, models: byProvider.get(p) };
134
- }
135
- const first = [...byProvider.keys()].sort()[0];
136
- return { provider: first, models: byProvider.get(first) ?? [] };
137
- }
138
-
139
- function buildFallbacks(available, primaryProvider, highModel) {
140
- const fallbacks = [];
141
- for (const p of ["anthropic", "google", "openai", "opencode-go"]) {
142
- if (p === primaryProvider) continue;
143
- const alt = available.filter((m) => m.provider === p);
144
- if (alt.length === 0) continue;
145
- const ref = pickTierModel(alt, "medium");
146
- if (ref && ref !== highModel) fallbacks.push(ref);
147
- }
148
- return fallbacks.slice(0, 3);
149
- }
150
-
151
- /** Session-locked router: one model SKU per profile; tiers vary thinking only. */
152
- function buildRoutedProfile(available, provider) {
153
- const models = modelsForProvider(available, provider);
154
- if (models.length === 0) return null;
155
- const sku =
156
- pickTierModel(models, "medium") ??
157
- pickTierModel(models, "high") ??
158
- pickTierModel(models, "low");
159
- if (!sku) return null;
160
- const fallbacks = buildFallbacks(available, provider, sku);
161
- const high = { model: sku, thinking: "high" };
162
- if (fallbacks.length) high.fallbacks = fallbacks;
163
- return {
164
- high,
165
- medium: { model: sku, thinking: "medium" },
166
- low: { model: sku, thinking: "low" },
167
- };
168
- }
169
-
170
- function addCheapDeepProfiles(profiles, available, provider) {
171
- const models = modelsForProvider(available, provider);
172
- if (models.length === 0) return;
173
- const sku =
174
- pickTierModel(models, "medium") ??
175
- pickTierModel(models, "high") ??
176
- pickTierModel(models, "low");
177
- if (!sku) return;
178
- const fallbacks = buildFallbacks(available, provider, sku);
179
- const deepHigh = { model: sku, thinking: "xhigh" };
180
- if (fallbacks.length) deepHigh.fallbacks = fallbacks;
181
- profiles.cheap = {
182
- high: { model: sku, thinking: "low" },
183
- medium: { model: sku, thinking: "off" },
184
- low: { model: sku, thinking: "off" },
185
- };
186
- profiles.deep = {
187
- high: deepHigh,
188
- medium: { model: sku, thinking: "medium" },
189
- low: { model: sku, thinking: "low" },
190
- };
191
- }
192
-
193
- function resolveClassifierModel(available) {
194
- const openaiModels = modelsForProvider(available, "openai");
195
- if (openaiModels.length > 0) {
196
- return (
197
- pickTierModel(openaiModels, "low") ??
198
- canonicalRef(openaiModels[openaiModels.length - 1].provider, openaiModels[openaiModels.length - 1].id)
199
- );
200
- }
201
- const { models } = choosePrimaryProvider(available);
202
- return pickTierModel(models, "medium");
203
- }
204
-
205
- /** OpenAI-backed default profile name exposed as `router/auto`. */
206
- const OPENAI_PROFILE_NAME = "auto";
207
-
208
- function routerProfileName(provider) {
209
- return provider === "openai" ? OPENAI_PROFILE_NAME : provider;
210
- }
211
-
212
- function resolveDefaultProfile(profiles) {
213
- if (profiles[OPENAI_PROFILE_NAME]) return OPENAI_PROFILE_NAME;
214
- if (profiles["opencode-go"]) return "opencode-go";
215
- return (
216
- Object.keys(profiles).find((name) => name !== "cheap" && name !== "deep") ??
217
- OPENAI_PROFILE_NAME
218
- );
219
- }
220
-
221
- async function main() {
222
- const force = process.argv.includes("--force");
223
- const dryRun = process.argv.includes("--dry-run");
224
-
225
- if (existsSync(OUT_PATH) && !force) {
226
- console.log(
227
- "✓ .pi/model-router.json already exists — preserving (use --force to regenerate)",
228
- );
229
- process.exit(0);
230
- }
231
-
232
- const { AuthStorage, ModelRegistry } = await loadPiCodingAgent();
233
- const authStorage = AuthStorage.create();
234
- const modelRegistry = ModelRegistry.create(authStorage);
235
- const available = await modelRegistry.getAvailable();
236
-
237
- if (available.length === 0) {
238
- console.log(
239
- "✗ No authenticated Pi providers — skip model-router.json",
240
- );
241
- console.log(
242
- " Log in inside pi: /login (or set API keys in ~/.pi/agent/auth.json)",
243
- );
244
- const providers = authStorage.list();
245
- if (providers.length > 0) {
246
- console.log(
247
- ` Stored providers in auth.json (may need refresh): ${providers.join(", ")}`,
248
- );
249
- }
250
- process.exit(0);
251
- }
252
-
253
- const profiles = {};
254
- for (const provider of ["openai", "opencode-go"]) {
255
- const profile = buildRoutedProfile(available, provider);
256
- if (profile) profiles[routerProfileName(provider)] = profile;
257
- }
258
-
259
- if (Object.keys(profiles).length === 0) {
260
- const { provider: primaryProvider, models: primaryModels } =
261
- choosePrimaryProvider(available);
262
- const profile = buildRoutedProfile(available, primaryProvider);
263
- if (!profile) {
264
- fail("could not assign tier models from available registry");
265
- }
266
- profiles[primaryProvider] = profile;
267
- }
268
-
269
- const cheapDeepSource = profiles["opencode-go"]
270
- ? "opencode-go"
271
- : resolveDefaultProfile(profiles);
272
- addCheapDeepProfiles(profiles, available, cheapDeepSource);
273
-
274
- const defaultProfile = resolveDefaultProfile(profiles);
275
- const classifierModel = resolveClassifierModel(available);
276
- if (!classifierModel) {
277
- fail("could not assign classifier model from available registry");
278
- }
279
-
280
- const config = {
281
- defaultProfile,
282
- debug: false,
283
- classifierModel,
284
- phaseBias: 0.5,
285
- maxSessionBudget: 1.0,
286
- largeContextThreshold: 100000,
287
- rules: [
288
- {
289
- matches: ["deploy", "production", "release"],
290
- tier: "high",
291
- reason: "Safety check for production tasks",
292
- },
293
- { matches: "changelog", tier: "low" },
294
- ],
295
- profiles,
296
- };
297
-
298
- const json = `${JSON.stringify(config, null, 2)}\n`;
299
- const providerSet = [...new Set(available.map((m) => m.provider))].sort();
300
- const autoProfile = profiles[OPENAI_PROFILE_NAME];
301
- const opencodeProfile = profiles["opencode-go"];
302
-
303
- if (dryRun) {
304
- process.stdout.write(json);
305
- process.exit(0);
306
- }
307
-
308
- mkdirSync(dirname(OUT_PATH), { recursive: true });
309
- writeFileSync(OUT_PATH, json, "utf8");
310
-
311
- console.log("✓ Generated .pi/model-router.json from Pi authenticated providers:");
312
- console.log(` Default profile: ${defaultProfile}`);
313
- console.log(` Classifier: ${classifierModel}`);
314
- console.log(` Authenticated providers: ${providerSet.join(", ")}`);
315
- console.log(` Available models: ${available.length}`);
316
- if (autoProfile) {
317
- console.log(` auto (openai) high: ${autoProfile.high.model}`);
318
- }
319
- if (opencodeProfile) {
320
- console.log(` opencode-go high: ${opencodeProfile.high.model}`);
321
- }
322
- }
323
-
324
- main().catch((err) => {
325
- console.error(err);
326
- process.exit(1);
327
- });
@@ -1,97 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Unit tests for session-locked pi-model-router routing (no LLM).
4
- * Run: npx tsx .pi/scripts/harness-model-router-routing.test.mjs
5
- */
6
-
7
- import assert from "node:assert/strict";
8
- import { readFileSync } from "node:fs";
9
- import { join, dirname } from "node:path";
10
- import { fileURLToPath } from "node:url";
11
- import {
12
- decideSessionLock,
13
- applyThinkingToDecision,
14
- buildRoutingDecision,
15
- decideRouting,
16
- } from "../../vendor/pi-model-router/extensions/routing.js";
17
-
18
- const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
19
-
20
- const sampleProfile = {
21
- high: { model: "openai/gpt-5.5", thinking: "high" },
22
- medium: { model: "openai/gpt-5.5", thinking: "medium" },
23
- low: { model: "openai/gpt-5.5", thinking: "low" },
24
- };
25
-
26
- const planningContext = {
27
- systemPrompt: "You are a harness architect. Design tradeoffs and migration strategy.",
28
- messages: [
29
- {
30
- role: "user",
31
- content:
32
- "Plan a multi-phase refactor across modules with architecture review.",
33
- timestamp: 1,
34
- },
35
- ],
36
- };
37
-
38
- const shortContext = {
39
- systemPrompt: "Summarize briefly.",
40
- messages: [{ role: "user", content: "changelog", timestamp: 1 }],
41
- };
42
-
43
- const lockHigh = decideSessionLock(
44
- planningContext,
45
- "auto",
46
- sampleProfile,
47
- undefined,
48
- undefined,
49
- 0.5,
50
- [{ matches: "changelog", tier: "low" }],
51
- );
52
- assert.equal(lockHigh.tier, "high", "planning prompt locks high tier");
53
-
54
- const lockLow = decideSessionLock(shortContext, "auto", sampleProfile);
55
- assert.equal(lockLow.tier, "low", "short summary locks low tier");
56
-
57
- const locked = buildRoutingDecision(
58
- "auto",
59
- sampleProfile,
60
- lockHigh.tier,
61
- "planning",
62
- lockHigh.reasoning,
63
- );
64
- const thinkingTurn = decideRouting(
65
- {
66
- ...planningContext,
67
- messages: [
68
- ...planningContext.messages,
69
- { role: "user", content: "changelog only", timestamp: 2 },
70
- ],
71
- },
72
- "auto",
73
- sampleProfile,
74
- locked,
75
- );
76
- const merged = applyThinkingToDecision(locked, thinkingTurn, sampleProfile);
77
- assert.equal(merged.targetLabel, locked.targetLabel, "model stays locked");
78
- assert.equal(merged.tier, thinkingTurn.tier, "thinking tier follows turn");
79
- assert.equal(merged.thinking, "low", "low thinking from turn tier config");
80
-
81
- const examplePath = join(ROOT, ".pi", "model-router.example.json");
82
- const example = JSON.parse(readFileSync(examplePath, "utf8"));
83
- for (const [name, profile] of Object.entries(example.profiles ?? {})) {
84
- const { high, medium, low } = profile;
85
- assert.equal(
86
- high.model,
87
- medium.model,
88
- `example profile ${name}: medium/high same model`,
89
- );
90
- assert.equal(
91
- medium.model,
92
- low.model,
93
- `example profile ${name}: low/medium same model`,
94
- );
95
- }
96
-
97
- console.log("harness-model-router-routing.test: PASS");
@@ -1,97 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * After `.pi/model-router.json` exists, set sensible Pi defaults (`router` / `auto`)
4
- * when the project has no `defaultProvider`. Does **not** add/remove npm packages
5
- * — model routing ships vendored inside ultimate-pi.
6
- */
7
-
8
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
9
- import { join, dirname } from "node:path";
10
-
11
- function loadSettings(settingsPath) {
12
- if (!existsSync(settingsPath)) {
13
- return null;
14
- }
15
- try {
16
- return JSON.parse(readFileSync(settingsPath, "utf8"));
17
- } catch {
18
- console.error("[harness-model-router] Invalid JSON:", settingsPath);
19
- process.exit(1);
20
- }
21
- }
22
-
23
- function saveSettings(settingsPath, data) {
24
- mkdirSync(dirname(settingsPath), { recursive: true });
25
- writeFileSync(
26
- settingsPath,
27
- `${JSON.stringify(data, null, "\t")}\n`,
28
- "utf8",
29
- );
30
- }
31
-
32
- function readDefaultRouterProfile(configPath) {
33
- if (!existsSync(configPath)) return "auto";
34
- try {
35
- const data = JSON.parse(readFileSync(configPath, "utf8"));
36
- const profile =
37
- typeof data.defaultProfile === "string" ? data.defaultProfile.trim() : "";
38
- return profile || "auto";
39
- } catch {
40
- return "auto";
41
- }
42
- }
43
-
44
- function main() {
45
- const root = process.cwd();
46
- const configPath = join(root, ".pi", "model-router.json");
47
- const settingsPath = join(root, ".pi", "settings.json");
48
- const hasConfig = existsSync(configPath);
49
- const defaultRouterProfile = readDefaultRouterProfile(configPath);
50
-
51
- const settings = loadSettings(settingsPath);
52
- if (!settings) {
53
- console.warn(
54
- "[harness-model-router] No .pi/settings.json — skipping (merge Step 3 first)",
55
- );
56
- process.exit(0);
57
- }
58
-
59
- let changed = false;
60
-
61
- if (!hasConfig) {
62
- if (settings.defaultProvider === "router") {
63
- delete settings.defaultProvider;
64
- delete settings.defaultModel;
65
- changed = true;
66
- }
67
- if (changed) {
68
- saveSettings(settingsPath, settings);
69
- console.warn(
70
- "⚠ No .pi/model-router.json — cleared router defaultProvider if present",
71
- );
72
- } else {
73
- console.log("[harness-model-router] No config file; nothing to do");
74
- }
75
- process.exit(0);
76
- }
77
-
78
- const noProjectDefault =
79
- settings.defaultProvider == null || settings.defaultProvider === "";
80
-
81
- if (noProjectDefault) {
82
- settings.defaultProvider = "router";
83
- settings.defaultModel = defaultRouterProfile;
84
- changed = true;
85
- }
86
-
87
- if (changed) {
88
- saveSettings(settingsPath, settings);
89
- console.log(
90
- `✓ Router defaults set (\`router\` / \`${defaultRouterProfile}\`) — run /reload in pi when ready`,
91
- );
92
- } else {
93
- console.log("[harness-model-router] Defaults unchanged (user set defaultProvider)");
94
- }
95
- }
96
-
97
- main();
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Re-fetch upstream pi-model-router and re-apply ultimate-pi patches.
3
- set -euo pipefail
4
- ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5
- VEND="$ROOT/vendor/pi-model-router"
6
-
7
- rm -rf "$VEND"
8
- git clone --depth 1 https://github.com/yeliu84/pi-model-router.git "$VEND"
9
- COMMIT="$(git -C "$VEND" rev-parse HEAD)"
10
- rm -rf "$VEND/.git"
11
-
12
- for f in "$VEND"/extensions/*.ts; do
13
- sed -i \
14
- -e "s|'@earendil-works/pi-agent-core'|'@earendil-works/pi-agent-core'|g" \
15
- -e "s|'@earendil-works/pi-ai'|'@earendil-works/pi-ai'|g" \
16
- -e "s|'@earendil-works/pi-coding-agent'|'@earendil-works/pi-coding-agent'|g" \
17
- -e "s|'@earendil-works/pi-tui'|'@earendil-works/pi-tui'|g" \
18
- "$f"
19
- done
20
-
21
- # Align package.json peers with @earendil-works (upstream lists @earendil-works)
22
- sed -i \
23
- -e 's|"@earendil-works/pi-agent-core"|"@earendil-works/pi-agent-core"|g' \
24
- -e 's|"@earendil-works/pi-ai"|"@earendil-works/pi-ai"|g' \
25
- -e 's|"@earendil-works/pi-coding-agent"|"@earendil-works/pi-coding-agent"|g' \
26
- -e 's|"@earendil-works/pi-tui"|"@earendil-works/pi-tui"|g' \
27
- "$VEND/package.json"
28
-
29
- python3 -c "
30
- import re, pathlib
31
- for p in pathlib.Path('$VEND/extensions').glob('*.ts'):
32
- t = p.read_text()
33
- t2 = re.sub(r\"from '\\./([^']+)'\", lambda m: f\"from './{m.group(1)}.js'\" if not m.group(1).endswith('.js') else m.group(0), t)
34
- p.write_text(t2)
35
- "
36
-
37
- cat >"$VEND/UPSTREAM_PIN.md" <<EOF
38
- # Vendored \`pi-model-router\`
39
-
40
- - **Repository:** https://github.com/yeliu84/pi-model-router
41
- - **License:** MIT (\`LICENSE\` in this tree)
42
- - **Pinned upstream commit:** \`$COMMIT\`
43
- - **Local changes:** \`extensions/*.ts\` imports use \`@earendil-works/*\` and relative paths end in \`.js\` for TypeScript nodenext.
44
- EOF
45
-
46
- rm -f "$VEND/package-lock.json"
47
- echo "✓ Vendor refreshed at $VEND (commit $COMMIT)"
@@ -1,4 +0,0 @@
1
- node_modules
2
- dist
3
- .git
4
- .pi
@@ -1,5 +0,0 @@
1
- {
2
- "tabWidth": 2,
3
- "useTabs": false,
4
- "singleQuote": true
5
- }