pi-harness-runtime 1.1.439 → 1.1.441

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 (359) hide show
  1. package/harness/e2e/auto-test-loop.ts +8 -2
  2. package/harness/e2e/browser-scrapers/base-browser-scraper.ts +2 -0
  3. package/harness/e2e/browser-scrapers/chrome-profile-manager.ts +2 -0
  4. package/harness/e2e/browser-scrapers/codex-browser-scraper.ts +2 -0
  5. package/harness/e2e/tools-detector.ts +2 -0
  6. package/harness/index.ts +2 -1
  7. package/harness/key-loader.ts +2 -0
  8. package/harness/langchain/checkpointer.ts +2 -0
  9. package/harness/langchain/cron-cli.ts +2 -0
  10. package/harness/langchain/graph.ts +2 -0
  11. package/harness/master-planner.ts +1 -1
  12. package/harness/notification-center.ts +2 -0
  13. package/harness/output-limit-handler.ts +1 -1
  14. package/harness/project-detector/detector.ts +2 -4
  15. package/harness/secret-provider.ts +2 -0
  16. package/harness/task-graph.ts +460 -113
  17. package/index.ts +16 -7
  18. package/package.json +7 -1
  19. package/packages/a2a-adapter/package.json +1 -1
  20. package/packages/agent-policy/dist/extension.d.ts.map +1 -1
  21. package/packages/agent-policy/dist/extension.js +2 -0
  22. package/packages/agent-policy/dist/extension.js.map +1 -1
  23. package/packages/agent-policy/package.json +1 -1
  24. package/packages/agent-policy/src/extension.ts +2 -0
  25. package/packages/architecture-generator/package.json +1 -1
  26. package/packages/auth/dist/minimax-browser-auth.d.ts.map +1 -1
  27. package/packages/auth/dist/minimax-browser-auth.js +23 -1
  28. package/packages/auth/dist/minimax-browser-auth.js.map +1 -1
  29. package/packages/auth/package.json +1 -1
  30. package/packages/auth/src/minimax-browser-auth.ts +30 -5
  31. package/packages/autonomous-refactor/package.json +1 -1
  32. package/packages/autonomous-runtime/dist/inbox.d.ts.map +1 -1
  33. package/packages/autonomous-runtime/dist/inbox.js +2 -0
  34. package/packages/autonomous-runtime/dist/inbox.js.map +1 -1
  35. package/packages/autonomous-runtime/package.json +1 -1
  36. package/packages/autonomous-runtime/src/inbox.ts +2 -0
  37. package/packages/cache-strategy/package.json +1 -1
  38. package/packages/capability-registry/package.json +1 -1
  39. package/packages/checkpoint/package.json +1 -1
  40. package/packages/cli-plugin-sdk/package.json +1 -1
  41. package/packages/clipboard/dist/src/clipboard.d.ts.map +1 -1
  42. package/packages/clipboard/dist/src/clipboard.js +2 -0
  43. package/packages/clipboard/dist/src/clipboard.js.map +1 -1
  44. package/packages/clipboard/dist/src/copy-sync.d.ts.map +1 -1
  45. package/packages/clipboard/dist/src/copy-sync.js +2 -0
  46. package/packages/clipboard/dist/src/copy-sync.js.map +1 -1
  47. package/packages/clipboard/dist/src/gist-relay.d.ts.map +1 -1
  48. package/packages/clipboard/dist/src/gist-relay.js +2 -0
  49. package/packages/clipboard/dist/src/gist-relay.js.map +1 -1
  50. package/packages/clipboard/package.json +1 -1
  51. package/packages/clipboard/src/clipboard.ts +2 -0
  52. package/packages/clipboard/src/copy-sync.ts +2 -0
  53. package/packages/clipboard/src/gist-relay.ts +2 -0
  54. package/packages/clipboard-plugin/dist/types.d.ts +9 -2
  55. package/packages/clipboard-plugin/dist/types.d.ts.map +1 -1
  56. package/packages/clipboard-plugin/package.json +1 -1
  57. package/packages/clipboard-plugin/src/types.ts +9 -2
  58. package/packages/code-generation/package.json +1 -1
  59. package/packages/code-review/package.json +1 -1
  60. package/packages/codex-adapter/package.json +1 -1
  61. package/packages/codex-watcher/package.json +1 -1
  62. package/packages/config-capture/package.json +1 -1
  63. package/packages/connection-runtime/package.json +1 -1
  64. package/packages/context-compiler/package.json +1 -1
  65. package/packages/context-discovery/package.json +1 -1
  66. package/packages/context-manager/package.json +1 -1
  67. package/packages/contracts/dist/delegation-store.js +1 -4
  68. package/packages/contracts/dist/workspace-env.js +28 -1
  69. package/packages/contracts/package.json +1 -1
  70. package/packages/contracts/src/delegation-store.ts +9 -4
  71. package/packages/contracts/src/workspace-env.ts +29 -4
  72. package/packages/cookie-sanitizer/package.json +1 -1
  73. package/packages/cost-optimizer/package.json +1 -1
  74. package/packages/dependency-analyzer/package.json +1 -1
  75. package/packages/django-plugin/package.json +1 -1
  76. package/packages/doc-generator/package.json +1 -1
  77. package/packages/durable-review/package.json +1 -1
  78. package/packages/e2e-tester/package.json +1 -1
  79. package/packages/evaluation-engine/package.json +1 -1
  80. package/packages/evaluation-runner/package.json +1 -1
  81. package/packages/event-bus/package.json +1 -1
  82. package/packages/event-sink/package.json +1 -1
  83. package/packages/event-store/dist/src/store.d.ts.map +1 -1
  84. package/packages/event-store/dist/src/store.js +2 -0
  85. package/packages/event-store/dist/src/store.js.map +1 -1
  86. package/packages/event-store/package.json +1 -1
  87. package/packages/event-store/src/store.ts +3 -0
  88. package/packages/experience-replay/package.json +1 -1
  89. package/packages/feedback-collector/package.json +1 -1
  90. package/packages/file-copy-helper/package.json +1 -1
  91. package/packages/framework-detector/package.json +1 -1
  92. package/packages/framework-plugin-sdk/package.json +1 -1
  93. package/packages/frappe-plugin/package.json +1 -1
  94. package/packages/generic-web-plugin/dist/analyzer.d.ts.map +1 -1
  95. package/packages/generic-web-plugin/dist/analyzer.js +2 -0
  96. package/packages/generic-web-plugin/dist/analyzer.js.map +1 -1
  97. package/packages/generic-web-plugin/package.json +1 -1
  98. package/packages/generic-web-plugin/src/analyzer.ts +3 -0
  99. package/packages/health-monitor/package.json +1 -1
  100. package/packages/intent-analyzer/package.json +1 -1
  101. package/packages/jev-judge/package.json +1 -1
  102. package/packages/knowledge-graph/package.json +1 -1
  103. package/packages/knowledge-retrieval/dist/mcp-client.d.ts.map +1 -1
  104. package/packages/knowledge-retrieval/dist/mcp-client.js +0 -1
  105. package/packages/knowledge-retrieval/dist/mcp-client.js.map +1 -1
  106. package/packages/knowledge-retrieval/package.json +1 -4
  107. package/packages/knowledge-retrieval/src/mcp-client.ts +0 -1
  108. package/packages/laravel-plugin/package.json +1 -1
  109. package/packages/learning-engine/package.json +1 -1
  110. package/packages/logging/package.json +1 -1
  111. package/packages/mcp-adapter/dist/server.d.ts.map +1 -1
  112. package/packages/mcp-adapter/dist/server.js +2 -0
  113. package/packages/mcp-adapter/dist/server.js.map +1 -1
  114. package/packages/mcp-adapter/package.json +1 -1
  115. package/packages/mcp-adapter/src/server.ts +3 -0
  116. package/packages/memory-engine/package.json +1 -1
  117. package/packages/milestone-manager/package.json +1 -1
  118. package/packages/model-registry/package.json +1 -1
  119. package/packages/nextjs-plugin/package.json +1 -1
  120. package/packages/notification/package.json +1 -1
  121. package/packages/observability/package.json +1 -1
  122. package/packages/okf-indexer/package.json +1 -1
  123. package/packages/paperclip-integration/dist/index.d.ts.map +1 -1
  124. package/packages/paperclip-integration/dist/index.js +2 -0
  125. package/packages/paperclip-integration/dist/index.js.map +1 -1
  126. package/packages/paperclip-integration/package.json +1 -1
  127. package/packages/paperclip-integration/src/index.ts +2 -0
  128. package/packages/performance-optimizer/package.json +1 -1
  129. package/packages/permission-mode/package.json +1 -1
  130. package/packages/privilege-broker/dist/audit.d.ts.map +1 -1
  131. package/packages/privilege-broker/dist/audit.js +2 -0
  132. package/packages/privilege-broker/dist/audit.js.map +1 -1
  133. package/packages/privilege-broker/package.json +1 -1
  134. package/packages/privilege-broker/src/audit.ts +2 -0
  135. package/packages/project-analyzer/package.json +1 -1
  136. package/packages/project-bootstrap/package.json +1 -1
  137. package/packages/projection-engine/package.json +1 -1
  138. package/packages/prompt-compiler/dist/compiler.d.ts.map +1 -1
  139. package/packages/prompt-compiler/dist/compiler.js +2 -0
  140. package/packages/prompt-compiler/dist/compiler.js.map +1 -1
  141. package/packages/prompt-compiler/package.json +1 -1
  142. package/packages/prompt-compiler/src/compiler.ts +2 -0
  143. package/packages/prompt-versioning/package.json +1 -1
  144. package/packages/provider-adapter-sdk/package.json +1 -1
  145. package/packages/provider-router/package.json +1 -1
  146. package/packages/provider-selector/package.json +1 -1
  147. package/packages/providers/package.json +1 -1
  148. package/packages/qdrant-skills/package.json +1 -1
  149. package/packages/quota-manager/package.json +1 -1
  150. package/packages/rate-limiter/package.json +1 -1
  151. package/packages/react-vite-plugin/package.json +1 -1
  152. package/packages/relay/package.json +1 -1
  153. package/packages/release-manager/package.json +1 -1
  154. package/packages/requirement-compiler/package.json +1 -1
  155. package/packages/runtime/package.json +1 -1
  156. package/packages/scheduler/package.json +1 -1
  157. package/packages/scheduler-adapter/package.json +1 -1
  158. package/packages/session/package.json +1 -1
  159. package/packages/session-api/package.json +1 -1
  160. package/packages/session-export/package.json +1 -1
  161. package/packages/shared-context/package.json +1 -1
  162. package/packages/skill-mcp-client/dist/client.d.ts.map +1 -1
  163. package/packages/skill-mcp-client/dist/client.js +0 -1
  164. package/packages/skill-mcp-client/dist/client.js.map +1 -1
  165. package/packages/skill-mcp-client/package.json +1 -4
  166. package/packages/skill-mcp-client/src/client.ts +0 -1
  167. package/packages/skill-registry/package.json +1 -1
  168. package/packages/skills/dist/parser.d.ts.map +1 -1
  169. package/packages/skills/dist/parser.js +2 -0
  170. package/packages/skills/dist/parser.js.map +1 -1
  171. package/packages/skills/dist/skill-versioning.d.ts.map +1 -1
  172. package/packages/skills/dist/skill-versioning.js +2 -0
  173. package/packages/skills/dist/skill-versioning.js.map +1 -1
  174. package/packages/skills/package.json +1 -1
  175. package/packages/skills/src/parser.ts +3 -0
  176. package/packages/skills/src/skill-versioning.ts +2 -0
  177. package/packages/sprint-planner/package.json +1 -1
  178. package/packages/subscription-engine/package.json +1 -1
  179. package/packages/task-compiler/package.json +1 -1
  180. package/packages/tencentdb-memory/package.json +1 -1
  181. package/packages/tencentdb-sync/package.json +1 -1
  182. package/packages/test-data-generator/package.json +1 -1
  183. package/packages/test-generator/package.json +1 -1
  184. package/packages/todo-bd-sync/package.json +1 -1
  185. package/packages/token-estimation/package.json +1 -1
  186. package/packages/token-optimizer/package.json +1 -1
  187. package/packages/tooling-preference/package.json +1 -1
  188. package/packages/trajectory/package.json +1 -1
  189. package/packages/tui/package.json +1 -1
  190. package/packages/two-phase-review/package.json +1 -1
  191. package/packages/types/package.json +1 -1
  192. package/packages/voice-api/package.json +1 -1
  193. package/packages/webmcp-tester/dist/index.js +0 -2
  194. package/packages/webmcp-tester/package.json +1 -1
  195. package/packages/webmcp-tester/src/index.ts +0 -3
  196. package/packages/wiki/package.json +1 -1
  197. package/packages/workflow-events/package.json +1 -1
  198. package/packages/workspace-scanner/package.json +1 -1
  199. package/packages/worktree/package.json +1 -1
  200. package/packages/write-review/dist/trigger.d.ts.map +1 -1
  201. package/packages/write-review/dist/trigger.js +1 -2
  202. package/packages/write-review/dist/trigger.js.map +1 -1
  203. package/packages/write-review/package.json +1 -1
  204. package/packages/write-review/src/trigger.ts +1 -2
  205. package/scripts/lib/runtime-imports.ts +189 -3
  206. package/scripts/release-all.ts +5 -3
  207. package/scripts/telegram-webhook-server.ts +2 -0
  208. package/scripts/typecheck-packages.mjs +7 -4
  209. package/scripts/verify-package-contents.ts +161 -2
  210. package/harness/e2e/tools-detector.test.ts +0 -156
  211. package/harness/glm-quota-countdown.test.ts +0 -323
  212. package/harness/langchain/agents.test.ts +0 -39
  213. package/harness/langchain/checkpointer.test.ts +0 -243
  214. package/harness/langchain/daemon.test.ts +0 -459
  215. package/harness/langchain/model-router.test.ts +0 -191
  216. package/harness/langchain/ping-pong-middleware.test.ts +0 -69
  217. package/harness/langchain/scoreboard.test.ts +0 -245
  218. package/harness/langchain/status-line.test.ts +0 -106
  219. package/harness/langchain/surge.test.ts +0 -467
  220. package/harness/langchain/widget.test.ts +0 -251
  221. package/harness/skill-sync.test.ts +0 -57
  222. package/harness/ssh-detach-interceptor.test.ts +0 -263
  223. package/harness/ssh-hang-recovery.test.ts +0 -86
  224. package/packages/a2a-adapter/test/a2a.test.ts +0 -151
  225. package/packages/agent-policy/test/interlock.test.ts +0 -101
  226. package/packages/agent-policy/test/policy-retention.test.ts +0 -380
  227. package/packages/agent-policy/test/policy.test.ts +0 -387
  228. package/packages/auth/test/auth.test.ts +0 -238
  229. package/packages/autonomous-refactor/test/refactor.test.ts +0 -202
  230. package/packages/autonomous-runtime/test/types.test.ts +0 -95
  231. package/packages/cache-strategy/test/cache.test.ts +0 -137
  232. package/packages/capability-registry/test/registry.test.ts +0 -204
  233. package/packages/checkpoint/test/engine.test.ts +0 -265
  234. package/packages/cli-plugin-sdk/test/cli.test.ts +0 -45
  235. package/packages/code-generation/test/generator.test.ts +0 -238
  236. package/packages/code-review/test/engine.test.ts +0 -302
  237. package/packages/codex-adapter/test/provider.test.ts +0 -142
  238. package/packages/codex-watcher/test/watch.test.ts +0 -453
  239. package/packages/context-compiler/test/context-compiler.test.ts +0 -746
  240. package/packages/context-manager/test/context.test.ts +0 -198
  241. package/packages/contracts/test/delegation.test.ts +0 -350
  242. package/packages/contracts/test/workspace-env.test.ts +0 -802
  243. package/packages/cookie-sanitizer/test/infer.test.ts +0 -110
  244. package/packages/cookie-sanitizer/test/normalize.test.ts +0 -113
  245. package/packages/cookie-sanitizer/test/parse.test.ts +0 -204
  246. package/packages/cookie-sanitizer/test/sync.test.ts +0 -237
  247. package/packages/cookie-sanitizer/test/watcher.test.ts +0 -27
  248. package/packages/cost-optimizer/test/cost-optimizer.test.ts +0 -438
  249. package/packages/dependency-analyzer/test/analyzer.test.ts +0 -49
  250. package/packages/django-plugin/test/analyzer.test.ts +0 -195
  251. package/packages/doc-generator/test/docs.test.ts +0 -168
  252. package/packages/durable-review/test/acceptance.test.ts +0 -357
  253. package/packages/durable-review/test/smoke.test.ts +0 -107
  254. package/packages/evaluation-engine/test/engine.test.ts +0 -277
  255. package/packages/evaluation-runner/test/runner.test.ts +0 -168
  256. package/packages/event-bus/test/bus.test.ts +0 -100
  257. package/packages/event-store/test/store.test.ts +0 -115
  258. package/packages/experience-replay/test/replay.test.ts +0 -267
  259. package/packages/feedback-collector/test/collector.test.ts +0 -142
  260. package/packages/framework-detector/test/detector.test.ts +0 -75
  261. package/packages/framework-plugin-sdk/test/manager.test.ts +0 -320
  262. package/packages/frappe-plugin/test/analyzer.test.ts +0 -250
  263. package/packages/generic-web-plugin/test/analyzer.test.ts +0 -134
  264. package/packages/health-monitor/test/health.test.ts +0 -231
  265. package/packages/intent-analyzer/test/analyzer.test.ts +0 -72
  266. package/packages/intent-analyzer/test/ping-pong.test.ts +0 -96
  267. package/packages/jev-judge/tests/auto-continue-context.test.ts +0 -280
  268. package/packages/jev-judge/tests/continuation-controller.test.ts +0 -1396
  269. package/packages/jev-judge/tests/jev-provider-chain.test.ts +0 -536
  270. package/packages/jev-judge/tests/outcome-application.test.ts +0 -132
  271. package/packages/jev-judge/tests/question-risk.test.ts +0 -129
  272. package/packages/jev-judge/tests/typesafe-provider.test.ts +0 -640
  273. package/packages/jev-judge/tests/validation-ledger.test.ts +0 -181
  274. package/packages/jev-judge/tests/validation-plan.test.ts +0 -170
  275. package/packages/jev-judge/tests/validation-tie-breaker.test.ts +0 -88
  276. package/packages/laravel-plugin/test/analyzer.test.ts +0 -220
  277. package/packages/learning-engine/test/engine.test.ts +0 -331
  278. package/packages/logging/test/buffer.test.ts +0 -44
  279. package/packages/logging/test/classification.test.ts +0 -137
  280. package/packages/logging/test/config.test.ts +0 -97
  281. package/packages/logging/test/fanout.test.ts +0 -186
  282. package/packages/logging/test/identity-transport.test.ts +0 -197
  283. package/packages/logging/test/incidents.test.ts +0 -404
  284. package/packages/logging/test/ingest-schema.test.ts +0 -184
  285. package/packages/logging/test/integration.test.ts +0 -140
  286. package/packages/logging/test/log-http.test.ts +0 -246
  287. package/packages/logging/test/redact.test.ts +0 -109
  288. package/packages/logging/test/sampler.test.ts +0 -57
  289. package/packages/logging/test/server.test.ts +0 -444
  290. package/packages/logging/test/shipper.test.ts +0 -152
  291. package/packages/logging/test/spool.test.ts +0 -96
  292. package/packages/mcp-adapter/test/server.test.ts +0 -91
  293. package/packages/memory-engine/test/engine.test.ts +0 -456
  294. package/packages/model-registry/test/registry.test.ts +0 -342
  295. package/packages/nextjs-plugin/test/analyzer.test.ts +0 -149
  296. package/packages/notification/test/approval-payload.test.ts +0 -269
  297. package/packages/notification/test/detail-format.test.ts +0 -106
  298. package/packages/notification/test/notification.test.ts +0 -375
  299. package/packages/notification/test/pending-question-lifecycle.test.ts +0 -195
  300. package/packages/notification/test/pending-question.test.ts +0 -331
  301. package/packages/notification/test/tooling-proposal-payload.test.ts +0 -212
  302. package/packages/observability/test/observability.test.ts +0 -1350
  303. package/packages/performance-optimizer/test/optimizer.test.ts +0 -267
  304. package/packages/project-analyzer/test/index.test.ts +0 -1719
  305. package/packages/prompt-compiler/test/prompt-compiler.test.ts +0 -813
  306. package/packages/prompt-versioning/test/versioning.test.ts +0 -112
  307. package/packages/provider-adapter-sdk/test/sdk.test.ts +0 -220
  308. package/packages/provider-router/test/provider-router.test.ts +0 -405
  309. package/packages/provider-selector/test/selector.test.ts +0 -192
  310. package/packages/providers/test/providers.test.ts +0 -225
  311. package/packages/qdrant-skills/test/collection-info.test.ts +0 -165
  312. package/packages/qdrant-skills/test/embedder-batch.test.ts +0 -184
  313. package/packages/qdrant-skills/test/embedder.test.ts +0 -97
  314. package/packages/quota-manager/test/quota.test.ts +0 -432
  315. package/packages/rate-limiter/test/limiter.test.ts +0 -128
  316. package/packages/react-vite-plugin/test/analyzer.test.ts +0 -139
  317. package/packages/relay/test/client.test.ts +0 -446
  318. package/packages/relay/test/relay-e2e.test.ts +0 -299
  319. package/packages/relay/test/relay-endpoint.test.ts +0 -278
  320. package/packages/release-manager/test/release.test.ts +0 -215
  321. package/packages/requirement-compiler/test/requirement-compiler.test.ts +0 -743
  322. package/packages/runtime/test/runtime-api.test.ts +0 -169
  323. package/packages/runtime/test/runtime.test.ts +0 -297
  324. package/packages/scheduler/test/scheduler.test.ts +0 -125
  325. package/packages/session/test/manager.test.ts +0 -233
  326. package/packages/shared-context/test/shared-context.test.ts +0 -114
  327. package/packages/skill-registry/test/registry.test.ts +0 -508
  328. package/packages/skills/test/init-skills.test.ts +0 -114
  329. package/packages/skills/test/remote-skills.test.ts +0 -360
  330. package/packages/skills/test/remote-source.test.ts +0 -248
  331. package/packages/skills/test/sanitize.test.ts +0 -250
  332. package/packages/skills/test/vector-indexing.test.ts +0 -205
  333. package/packages/skills/test/vector-schema.test.ts +0 -180
  334. package/packages/skills/test/vector-threshold.test.ts +0 -108
  335. package/packages/sprint-planner/test/planner.test.ts +0 -187
  336. package/packages/task-compiler/test/task-compiler.test.ts +0 -628
  337. package/packages/test-data-generator/test/generator.test.ts +0 -265
  338. package/packages/test-generator/test/generator.test.ts +0 -156
  339. package/packages/token-estimation/test/token-estimation.test.ts +0 -207
  340. package/packages/token-optimizer/test/optimizer.test.ts +0 -141
  341. package/packages/tooling-preference/tests/changed-files.test.ts +0 -124
  342. package/packages/tooling-preference/tests/detect.test.ts +0 -188
  343. package/packages/tooling-preference/tests/proposal.test.ts +0 -107
  344. package/packages/tooling-preference/tests/quality-check.test.ts +0 -272
  345. package/packages/tooling-preference/tests/registry.test.ts +0 -51
  346. package/packages/tooling-preference/tests/store.test.ts +0 -99
  347. package/packages/trajectory/test/store.test.ts +0 -250
  348. package/packages/tui/test/harness-footer.test.ts +0 -559
  349. package/packages/tui/test/harness-header.test.ts +0 -590
  350. package/packages/two-phase-review/test/classify.test.ts +0 -102
  351. package/packages/two-phase-review/test/helpers.ts +0 -72
  352. package/packages/two-phase-review/test/rules.test.ts +0 -150
  353. package/packages/two-phase-review/test/runtime.test.ts +0 -362
  354. package/packages/two-phase-review/test/scope.test.ts +0 -186
  355. package/packages/two-phase-review/test/signals.test.ts +0 -183
  356. package/packages/two-phase-review/test/state.test.ts +0 -201
  357. package/packages/wiki/test/basic.test.ts +0 -242
  358. package/packages/workspace-scanner/test/scanner.test.ts +0 -43
  359. package/packages/worktree/test/worktree.test.ts +0 -163
@@ -1,151 +0,0 @@
1
- /**
2
- * A2A Adapter Tests (RFC-0069)
3
- */
4
-
5
- import { describe, it, expect } from "bun:test";
6
- import {
7
- createAgentCard,
8
- routeTask,
9
- getTask,
10
- cancelTask,
11
- taskStatusUpdateSSE,
12
- } from "../src/agent.js";
13
- import { A2AClient } from "../src/client.js";
14
- import { A2ATransport } from "../src/transport.js";
15
- import {
16
- A2A_PROTOCOL_VERSION,
17
- WELL_KNOWN_AGENT_PATH,
18
- } from "../src/protocol.js";
19
- import type { TaskMessage } from "../src/types.js";
20
-
21
- describe("A2A Protocol Constants", () => {
22
- it("exports protocol version", () => {
23
- expect(A2A_PROTOCOL_VERSION).toBe("1.0.0");
24
- });
25
-
26
- it("exports well-known agent path", () => {
27
- expect(WELL_KNOWN_AGENT_PATH).toBe("/.well-known/agent.json");
28
- });
29
- });
30
-
31
- describe("AgentCard", () => {
32
- it("creates agent card with defaults", () => {
33
- const card = createAgentCard({
34
- name: "pi-harness",
35
- description: "AI coding harness",
36
- url: "http://localhost:3000",
37
- version: "0.9.4",
38
- });
39
- expect(card.name).toBe("pi-harness");
40
- expect(card.capabilities.streaming).toBe(true);
41
- expect(card.skills.length).toBeGreaterThan(0);
42
- expect(card.skills[0].id).toBe("code-analysis");
43
- });
44
-
45
- it("creates agent card with custom skills", () => {
46
- const card = createAgentCard({
47
- name: "test-agent",
48
- description: "Test",
49
- url: "http://localhost:3001",
50
- version: "1.0.0",
51
- skills: [
52
- {
53
- id: "custom",
54
- name: "Custom",
55
- description: "Custom skill",
56
- tags: ["test"],
57
- },
58
- ],
59
- });
60
- expect(card.skills).toHaveLength(1);
61
- expect(card.skills[0].id).toBe("custom");
62
- });
63
-
64
- it("merges custom capabilities", () => {
65
- const card = createAgentCard({
66
- name: "test",
67
- description: "Test",
68
- url: "http://localhost:3002",
69
- version: "1.0.0",
70
- capabilities: { pushNotifications: true },
71
- });
72
- expect(card.capabilities.streaming).toBe(true);
73
- expect(card.capabilities.pushNotifications).toBe(true);
74
- });
75
- });
76
-
77
- describe("Task Routing", () => {
78
- it("routes a task message", async () => {
79
- const message: TaskMessage = { role: "user", content: "Analyze this code" };
80
- const task = await routeTask(message);
81
- expect(task.id).toMatch(/^task-/);
82
- expect(task.status).toBe("completed");
83
- expect(task.artifacts).toHaveLength(1);
84
- expect(task.artifacts![0].parts[0].text).toContain("Analyze this code");
85
- });
86
-
87
- it("stores and retrieves task", async () => {
88
- const message: TaskMessage = { role: "user", content: "Test" };
89
- const task = await routeTask(message);
90
- const retrieved = getTask(task.id);
91
- expect(retrieved).not.toBeNull();
92
- expect(retrieved!.id).toBe(task.id);
93
- });
94
-
95
- it("returns null for unknown task", () => {
96
- expect(getTask("nonexistent-task")).toBeNull();
97
- });
98
-
99
- it("cancels a task", async () => {
100
- const message: TaskMessage = { role: "user", content: "Cancel test" };
101
- const task = await routeTask(message);
102
- expect(task.status).toBe("completed");
103
- const result = cancelTask(task.id);
104
- expect(result).toBe(true);
105
- expect(getTask(task.id)!.status).toBe("canceled");
106
- });
107
-
108
- it("returns false when canceling unknown task", () => {
109
- expect(cancelTask("nonexistent")).toBe(false);
110
- });
111
-
112
- it("generates SSE status update", async () => {
113
- const message: TaskMessage = { role: "user", content: "SSE test" };
114
- const task = await routeTask(message);
115
- const sse = taskStatusUpdateSSE(task.id);
116
- expect(sse).toContain("task_status_update");
117
- expect(sse).toContain(task.id);
118
- expect(sse).toContain("completed");
119
- expect(sse).toContain("final");
120
- });
121
- });
122
-
123
- describe("A2AClient", () => {
124
- it("creates client with URL", () => {
125
- const client = new A2AClient("http://localhost:3000");
126
- expect(client).toBeDefined();
127
- });
128
-
129
- it("sendTask throws on unreachable server", async () => {
130
- const client = new A2AClient("http://localhost:9999");
131
- await expect(client.sendTask("test")).rejects.toThrow();
132
- });
133
-
134
- it("findAgents returns empty array", async () => {
135
- const client = new A2AClient("http://localhost:3000");
136
- const results = await client.findAgents({ skill: "test" });
137
- expect(results).toEqual([]);
138
- });
139
- });
140
-
141
- describe("A2ATransport", () => {
142
- it("creates transport with config", () => {
143
- const t = new A2ATransport("http://localhost:3000", { timeout: 5000 });
144
- expect(t).toBeDefined();
145
- });
146
-
147
- it("getAgentCard throws on invalid URL", async () => {
148
- const t = new A2ATransport("http://localhost:9999", { timeout: 2000 });
149
- await expect(t.getAgentCard()).rejects.toThrow();
150
- });
151
- });
@@ -1,101 +0,0 @@
1
- import { afterEach, beforeEach, expect, test } from "bun:test";
2
- import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
- import { pathToFileURL } from "node:url";
6
- import { registerAgentPolicy } from "../src/extension.js";
7
- import { PolicyLoader } from "../src/policy-loader.js";
8
- import { resetPolicyStore } from "../src/policy-store.js";
9
-
10
- let root: string;
11
- let cwd: string;
12
- let harnessRulesPath: URL;
13
- beforeEach(() => {
14
- resetPolicyStore();
15
- root = mkdtempSync(join(tmpdir(), "policy-interlock-"));
16
- cwd = join(root, "project");
17
- mkdirSync(join(cwd, "src"), { recursive: true });
18
- mkdirSync(join(cwd, ".git"));
19
- writeFileSync(join(root, "harness.md"), "Harness mandatory rules");
20
- writeFileSync(join(root, "AGENTS.md"), "Ancestor mandatory rules");
21
- writeFileSync(join(cwd, "AGENTS.md"), "Project mandatory rules");
22
- writeFileSync(join(cwd, "RULES.md"), "Advisory rules");
23
- harnessRulesPath = pathToFileURL(join(root, "harness.md"));
24
- });
25
- afterEach(() => rmSync(root, { recursive: true, force: true }));
26
-
27
- function runtime(requireReceiptBeforeMutation = true) {
28
- const hooks = new Map<string, Function[]>();
29
- let tool: any;
30
- registerAgentPolicy({
31
- on(name: string, handler: Function) {
32
- hooks.set(name, [...(hooks.get(name) ?? []), handler]);
33
- },
34
- registerTool(value: unknown) { tool = value; },
35
- } as any, { harnessRulesPath, requireReceiptBeforeMutation, lspMode: "pi-lens" });
36
- return {
37
- call: (params: unknown, ctx: unknown) => tool.execute("test", params, undefined, undefined, ctx),
38
- gate: (ctx: unknown, path = "src/file.ts") => hooks.get("tool_call")![0](
39
- { toolName: "edit", input: { path } }, ctx),
40
- };
41
- }
42
-
43
- test("target checks preserve mandatory revision, ancestor rules, and cached manifest", async () => {
44
- const loader = new PolicyLoader({ harnessRulesPath });
45
- const manifest = await loader.load(cwd);
46
- const snapshot = JSON.stringify(manifest);
47
- for (const path of ["src/file.ts", join(cwd, "src/file.ts"), "packages/a/file.ts"]) {
48
- const target = await loader.loadForTarget(cwd, path);
49
- expect(target.revision).toBe(manifest.revision);
50
- expect(target.sources.some(s => s.path === join(root, "AGENTS.md"))).toBe(true);
51
- expect(JSON.stringify(manifest)).toBe(snapshot);
52
- }
53
- loader.invalidateCache();
54
- expect((await loader.load(cwd)).revision).toBe(manifest.revision);
55
- });
56
-
57
- test("acknowledgment unlocks the next target call using Pi sessionManager identity", async () => {
58
- const r = runtime();
59
- const context = (id = "session-a") => ({ cwd, sessionManager: { getSessionId: () => id } });
60
- expect((await r.gate(context())).block).toBe(true);
61
- const revision = (await r.call({ action: "manifest" }, context())).details.manifest.revision;
62
- expect((await r.call({ action: "acknowledge", revision }, context())).isError).not.toBe(true);
63
- expect((await r.gate(context())).block).not.toBe(true);
64
- expect((await r.gate(context(), join(cwd, "src/file.ts"))).block).not.toBe(true);
65
- expect((await r.gate(context("session-b"))).block).toBe(true);
66
- });
67
-
68
- test("legacy contexts reuse a stable fallback identity", async () => {
69
- const r = runtime();
70
- const revision = (await r.call({ action: "manifest" }, { cwd })).details.manifest.revision;
71
- await r.call({ action: "acknowledge", revision }, { cwd });
72
- expect((await r.gate({ cwd })).block).not.toBe(true);
73
- });
74
-
75
- test("explicitly disabled receipt enforcement allows tools without an acknowledgment", async () => {
76
- const r = runtime(false);
77
- expect((await r.gate({ cwd })).block).not.toBe(true);
78
- });
79
-
80
- test("wrong revisions remain rejected when receipt enforcement is enabled", async () => {
81
- const r = runtime();
82
- const ctx = { cwd, sessionId: "session-a" };
83
- const result = await r.call({ action: "acknowledge", revision: "stale" }, ctx);
84
- expect(result.isError).toBe(true);
85
- expect((await r.gate(ctx)).block).toBe(true);
86
- });
87
-
88
- test("rule changes still require a new receipt after policy cache refresh", async () => {
89
- const r = runtime();
90
- const ctx = { cwd, sessionId: "session-a" };
91
- const revision = (await r.call({ action: "manifest" }, ctx)).details.manifest.revision;
92
- await r.call({ action: "acknowledge", revision }, ctx);
93
- writeFileSync(join(cwd, "AGENTS.md"), "Updated mandatory rules");
94
- // A fresh loader/registration models cache refresh without a five-second wait.
95
- const refreshed = runtime();
96
- expect((await refreshed.gate(ctx)).block).toBe(true);
97
- const current = (await refreshed.call({ action: "manifest" }, ctx)).details.manifest.revision;
98
- expect(current).not.toBe(revision);
99
- await refreshed.call({ action: "acknowledge", revision: current }, ctx);
100
- expect((await refreshed.gate(ctx)).block).not.toBe(true);
101
- });
@@ -1,380 +0,0 @@
1
- /**
2
- * Policy Retention Tests
3
- *
4
- * Tests for lifecycle retention after compaction, reset, resume.
5
- */
6
-
7
- import { describe, it, before, after } from "node:test";
8
- import assert from "node:assert";
9
- import { existsSync, mkdirSync, writeFileSync, unlinkSync, rmSync } from "node:fs";
10
- import { join, dirname } from "node:path";
11
- import { randomUUID } from "node:crypto";
12
- import type { PolicyManifest } from "../dist/types.js";
13
- import { PolicyLoader } from "../dist/policy-loader.js";
14
- import { getPolicyStore, resetPolicyStore } from "../dist/policy-store.js";
15
-
16
- // Test workspace
17
- const TEST_DIR = "/tmp/policy-retention-test-" + Date.now();
18
- const AGENTS_MD = join(TEST_DIR, "AGENTS.md");
19
- const RULES_MD = join(TEST_DIR, "RULES.md");
20
-
21
- describe("Policy Retention Tests", () => {
22
- before(() => {
23
- mkdirSync(TEST_DIR, { recursive: true });
24
- resetPolicyStore();
25
- });
26
-
27
- after(() => {
28
- try {
29
- rmSync(TEST_DIR, { recursive: true, force: true });
30
- } catch {
31
- // ignore cleanup errors
32
- }
33
- resetPolicyStore();
34
- });
35
-
36
- // --- Session Epoch Tests ---
37
- describe("Session epochs", () => {
38
- it("should track session epochs separately", async () => {
39
- const store = getPolicyStore();
40
- const session1 = "session-1-" + randomUUID().slice(0, 8);
41
- const session2 = "session-2-" + randomUUID().slice(0, 8);
42
-
43
- // Create a manifest
44
- const manifest: PolicyManifest = {
45
- revision: "abc123",
46
- projectRoot: TEST_DIR,
47
- trust: "unknown",
48
- coverage: "complete",
49
- sources: [],
50
- loadedAt: Date.now(),
51
- };
52
-
53
- // Note delivery for session 1
54
- const receipt1 = store.noteDelivered(session1, manifest, "system_prompt");
55
- assert.strictEqual(receipt1.sessionId, session1);
56
-
57
- // Session 2 should NOT have a receipt
58
- const receipt2 = store.getReceipt(session2, TEST_DIR);
59
- assert.strictEqual(receipt2, null);
60
- });
61
-
62
- it("should not leak receipts between sessions after reset", async () => {
63
- const store = getPolicyStore();
64
- const sessionId = "session-reset-" + randomUUID().slice(0, 8);
65
-
66
- const manifest: PolicyManifest = {
67
- revision: "abc123",
68
- projectRoot: TEST_DIR,
69
- trust: "unknown",
70
- coverage: "complete",
71
- sources: [],
72
- loadedAt: Date.now(),
73
- };
74
-
75
- // Deliver to session
76
- store.noteDelivered(sessionId, manifest, "system_prompt");
77
-
78
- // Clear session
79
- store.clearSession(sessionId);
80
-
81
- // Receipt should be gone
82
- const receipt = store.getReceipt(sessionId, TEST_DIR);
83
- assert.strictEqual(receipt, null);
84
- });
85
- });
86
-
87
- // --- Source Change Tests ---
88
- describe("Source changes", () => {
89
- it("should invalidate receipts when AGENTS.md changes", async () => {
90
- const store = getPolicyStore();
91
- const sessionId = "session-change-" + randomUUID().slice(0, 8);
92
-
93
- // Write initial content
94
- writeFileSync(AGENTS_MD, "# Original Agents\n\nFollow the rules.", "utf8");
95
-
96
- const loader = new PolicyLoader({
97
- harnessRulesPath: new URL(`file://${AGENTS_MD}`),
98
- });
99
-
100
- // Load and deliver
101
- const manifest1 = await loader.load(TEST_DIR);
102
- store.noteDelivered(sessionId, manifest1, "system_prompt");
103
-
104
- // Modify file
105
- writeFileSync(AGENTS_MD, "# Updated Agents\n\nDifferent rules.", "utf8");
106
-
107
- // Invalidate cache
108
- loader.invalidateCache(TEST_DIR);
109
-
110
- // Load new manifest
111
- const manifest2 = await loader.load(TEST_DIR);
112
-
113
- // Revision should be different
114
- assert.notStrictEqual(manifest1.revision, manifest2.revision);
115
-
116
- // Old receipt should NOT cover new manifest
117
- const hasCoverage = store.hasValidReceipt(sessionId, manifest2);
118
- assert.strictEqual(hasCoverage, false);
119
- });
120
-
121
- it("should include RULES.md in sources", async () => {
122
- // Write RULES.md
123
- writeFileSync(RULES_MD, "# Rules\n\nThese are rules.", "utf8");
124
-
125
- const loader = new PolicyLoader({
126
- harnessRulesPath: new URL(`file://${AGENTS_MD}`),
127
- });
128
-
129
- const manifest = await loader.load(TEST_DIR);
130
-
131
- // RULES.md should be included as advisory at minimum
132
- const rulesSource = manifest.sources.find(s => s.path.includes("RULES.md"));
133
- assert.ok(rulesSource, "RULES.md should be included in sources");
134
-
135
- // Clean up
136
- unlinkSync(RULES_MD);
137
- });
138
- });
139
-
140
- // --- Bounded Delivery Tests ---
141
- describe("Bounded delivery", () => {
142
- it("should track exact revision and source coverage", async () => {
143
- const store = getPolicyStore();
144
- const sessionId = "session-exact-" + randomUUID().slice(0, 8);
145
-
146
- writeFileSync(AGENTS_MD, "# Agents\n\nContent.", "utf8");
147
-
148
- const loader = new PolicyLoader({
149
- harnessRulesPath: new URL(`file://${AGENTS_MD}`),
150
- });
151
-
152
- const manifest = await loader.load(TEST_DIR);
153
-
154
- // Note delivery with specific sections
155
- const receipt = store.noteDelivered(sessionId, manifest, "tool", ["section-1"]);
156
-
157
- assert.strictEqual(receipt.revision, manifest.revision);
158
- assert.deepStrictEqual(receipt.sectionsDelivered, ["section-1"]);
159
- });
160
-
161
- it("should reject acknowledgement of wrong revision", async () => {
162
- const store = getPolicyStore();
163
- const sessionId = "session-wrong-rev-" + randomUUID().slice(0, 8);
164
-
165
- writeFileSync(AGENTS_MD, "# Agents v1\n\nContent.", "utf8");
166
-
167
- const loader = new PolicyLoader({
168
- harnessRulesPath: new URL(`file://${AGENTS_MD}`),
169
- });
170
-
171
- const manifest1 = await loader.load(TEST_DIR);
172
- store.noteDelivered(sessionId, manifest1, "system_prompt");
173
-
174
- // Update content
175
- writeFileSync(AGENTS_MD, "# Agents v2\n\nDifferent content.", "utf8");
176
- loader.invalidateCache(TEST_DIR);
177
- const manifest2 = await loader.load(TEST_DIR);
178
-
179
- // Old receipt should NOT cover new manifest
180
- const hasCoverage = store.hasValidReceipt(sessionId, manifest2);
181
- assert.strictEqual(hasCoverage, false);
182
- });
183
- });
184
-
185
- // --- Trust Evaluation Tests ---
186
- describe("Trust evaluation", () => {
187
- it("should evaluate trust appropriately", async () => {
188
- // Create a .git directory (indicates repository)
189
- mkdirSync(join(TEST_DIR, ".git"), { recursive: true });
190
-
191
- const loader = new PolicyLoader({
192
- harnessRulesPath: new URL(`file://${AGENTS_MD}`),
193
- });
194
-
195
- const manifest = await loader.load(TEST_DIR);
196
-
197
- // Trust should be evaluated
198
- assert.ok(["trusted", "untrusted", "unknown"].includes(manifest.trust));
199
-
200
- // Clean up
201
- rmSync(join(TEST_DIR, ".git"), { recursive: true, force: true });
202
- });
203
- });
204
-
205
- // --- Compaction Recovery Tests ---
206
- describe("Compaction recovery", () => {
207
- it("should invalidate receipts on session_compact event", async () => {
208
- const store = getPolicyStore();
209
- const sessionId = "session-compact-" + randomUUID().slice(0, 8);
210
-
211
- writeFileSync(AGENTS_MD, "# Agents\n\nContent.", "utf8");
212
-
213
- const loader = new PolicyLoader({
214
- harnessRulesPath: new URL(`file://${AGENTS_MD}`),
215
- });
216
-
217
- const manifest = await loader.load(TEST_DIR);
218
- store.noteDelivered(sessionId, manifest, "system_prompt");
219
-
220
- // Simulate compaction: invalidate all
221
- store.invalidateAll();
222
-
223
- // Receipt should be gone
224
- const receipt = store.getReceipt(sessionId, TEST_DIR);
225
- assert.strictEqual(receipt, null);
226
- });
227
- });
228
-
229
- // --- Nested Scope Tests ---
230
- describe("Nested scope resolution", () => {
231
- it("should load scoped rules for subdirectories", async () => {
232
- // Create nested structure
233
- mkdirSync(join(TEST_DIR, "packages", "my-pkg"), { recursive: true });
234
- writeFileSync(AGENTS_MD, "# Root Agents\n\nRoot rules.", "utf8");
235
- writeFileSync(join(TEST_DIR, "packages", "AGENTS.md"), "# Package Agents\n\nPackage rules.", "utf8");
236
-
237
- const loader = new PolicyLoader({
238
- harnessRulesPath: new URL(`file://${AGENTS_MD}`),
239
- });
240
-
241
- const manifest = await loader.load(TEST_DIR);
242
-
243
- // Should have both root and package rules
244
- assert.ok(manifest.sources.length >= 2, "Should include both root and package rules");
245
-
246
- // Clean up nested structure
247
- rmSync(join(TEST_DIR, "packages"), { recursive: true, force: true });
248
- });
249
- });
250
-
251
- // --- Delivery Deduplication Tests ---
252
- describe("Delivery deduplication", () => {
253
- it("should not create duplicate receipts in same session", async () => {
254
- const store = getPolicyStore();
255
- const sessionId = "session-dedup-" + randomUUID().slice(0, 8);
256
-
257
- writeFileSync(AGENTS_MD, "# Agents\n\nContent.", "utf8");
258
-
259
- const loader = new PolicyLoader({
260
- harnessRulesPath: new URL(`file://${AGENTS_MD}`),
261
- });
262
-
263
- const manifest = await loader.load(TEST_DIR);
264
-
265
- // First delivery
266
- const receipt1 = store.noteDelivered(sessionId, manifest, "system_prompt");
267
-
268
- // Second delivery should update, not create duplicate
269
- const receipt2 = store.noteDelivered(sessionId, manifest, "system_prompt");
270
-
271
- // Should be same session
272
- assert.strictEqual(receipt1.sessionId, receipt2.sessionId);
273
-
274
- // Should have same revision
275
- assert.strictEqual(receipt1.revision, receipt2.revision);
276
- });
277
- });
278
-
279
- // --- Partial Read Tracking Tests ---
280
- describe("Partial read tracking", () => {
281
- it("should track which sections were actually delivered", async () => {
282
- const store = getPolicyStore();
283
- const sessionId = "session-partial-" + randomUUID().slice(0, 8);
284
-
285
- writeFileSync(AGENTS_MD, "# Agents\n\n## Section 1\n\nContent 1.\n\n## Section 2\n\nContent 2.", "utf8");
286
-
287
- const loader = new PolicyLoader({
288
- harnessRulesPath: new URL(`file://${AGENTS_MD}`),
289
- });
290
-
291
- const manifest = await loader.load(TEST_DIR);
292
-
293
- // Note partial delivery (only section 1)
294
- const receipt = store.noteDelivered(sessionId, manifest, "tool", ["section-1"]);
295
- assert.deepStrictEqual(receipt.sectionsDelivered, ["section-1"]);
296
- });
297
- });
298
-
299
- // --- Full Policy Text Delivery Tests ---
300
- describe("Full policy text delivery", () => {
301
- it("should compute full policy text after revision change", async () => {
302
- writeFileSync(AGENTS_MD, "# Full Agents\n\n## Rule 1\n\nContent 1.\n\n## Rule 2\n\nContent 2.", "utf8");
303
-
304
- const loader = new PolicyLoader({
305
- harnessRulesPath: new URL(`file://${AGENTS_MD}`),
306
- });
307
-
308
- const manifest = await loader.load(TEST_DIR);
309
-
310
- // Full text should include actual content, not just contract pointers
311
- const { renderFullPolicyText } = await import("../dist/index.js");
312
- const fullText = renderFullPolicyText(manifest);
313
-
314
- assert.ok(fullText.includes("Full Agents"), "Should include source title");
315
- assert.ok(fullText.includes("Rule 1"), "Should include section heading");
316
- assert.ok(fullText.includes("Content 1"), "Should include actual content");
317
- assert.ok(fullText.includes("revision="), "Should include revision info");
318
- });
319
-
320
- it("should detect when full policy exceeds size limit", async () => {
321
- const loader = new PolicyLoader({
322
- harnessRulesPath: new URL(`file://${AGENTS_MD}`),
323
- });
324
-
325
- const manifest = await loader.load(TEST_DIR);
326
- const { checkPolicyTextSize } = await import("../dist/index.js");
327
-
328
- // With normal-sized content, should fit in 100KB limit
329
- const result = checkPolicyTextSize(manifest, 100 * 1024);
330
- assert.strictEqual(result.fits, true, "Normal policy should fit in 100KB");
331
-
332
- // With very small limit, should report overflow
333
- const smallResult = checkPolicyTextSize(manifest, 10);
334
- assert.strictEqual(smallResult.fits, false, "Should report when limit is too small");
335
- assert.ok(smallResult.reason?.includes("exceeds limit"), "Should explain overflow");
336
- });
337
- });
338
-
339
- // --- Scope Separation Tests ---
340
- describe("Scope separation", () => {
341
- it("should NOT include harness rules when working outside harness repo", async () => {
342
- // Create a harness rules file in a different location
343
- const harnessRulesPath = join(TEST_DIR, "harness-rules", "AGENTS.md");
344
- mkdirSync(dirname(harnessRulesPath), { recursive: true });
345
- writeFileSync(harnessRulesPath, "# Harness Rules\n\nThese are harness-specific rules.", "utf8");
346
-
347
- // Working in a different directory (not the harness repo)
348
- const userProjectDir = join(TEST_DIR, "user-project");
349
- mkdirSync(userProjectDir, { recursive: true });
350
-
351
- const loader = new PolicyLoader({
352
- harnessRulesPath: new URL(`file://${harnessRulesPath}`),
353
- });
354
-
355
- const manifest = await loader.load(userProjectDir);
356
-
357
- // Harness rules should NOT be included since we're not in the harness repo
358
- const harnessSources = manifest.sources.filter(s => s.harnessOwned);
359
- assert.strictEqual(harnessSources.length, 0, "Harness rules should not apply outside harness repo");
360
- });
361
-
362
- it("should include harness rules when working inside harness repo", async () => {
363
- // Create a harness rules file
364
- writeFileSync(AGENTS_MD, "# Harness Rules\n\nThese are harness-specific rules.", "utf8");
365
-
366
- const harnessDir = TEST_DIR; // The harness rules are in this directory
367
-
368
- const loader = new PolicyLoader({
369
- harnessRulesPath: new URL(`file://${AGENTS_MD}`),
370
- });
371
-
372
- // Working in the harness directory itself
373
- const manifest = await loader.load(harnessDir);
374
-
375
- // Harness rules SHOULD be included since we're in the harness repo
376
- const harnessSources = manifest.sources.filter(s => s.harnessOwned);
377
- assert.ok(harnessSources.length > 0, "Harness rules should apply inside harness repo");
378
- });
379
- });
380
- });