@enterpriseai/cli 3.19.0 → 3.19.2

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 (364) hide show
  1. package/package.json +3 -3
  2. package/resources/deploy/eai-app-template/producer-pin.json +5 -5
  3. package/resources/deploy/eai-app-template/tests/source-unknown-deployment-evidence.test.mjs +2141 -1
  4. package/resources/gofer/.gofer-version +4 -357
  5. package/resources/gofer/agents-skills/eai/SKILL.md +365 -0
  6. package/resources/gofer/agents-skills/eai-update/SKILL.md +56 -0
  7. package/resources/gofer/agents-skills/gofer-documentation/SKILL.md +93 -0
  8. package/resources/gofer/bash-scripts/create-new-feature.sh +3 -1
  9. package/resources/gofer/bash-scripts/sync-implementation-status.sh +4 -3
  10. package/resources/gofer/bash-scripts/update-agent-context.sh +7 -8
  11. package/resources/gofer/bash-scripts/validate-artifact.sh +10 -6
  12. package/resources/gofer/bash-scripts/verify-object-type-routing-workspace.sh +184 -0
  13. package/resources/gofer/claude-commands/eai-update.md +46 -0
  14. package/resources/gofer/claude-commands/eai.md +355 -0
  15. package/resources/gofer/claude-skills/eai/SKILL.md +365 -0
  16. package/resources/gofer/claude-skills/eai-update/SKILL.md +56 -0
  17. package/resources/gofer/claude-skills/gofer-documentation/SKILL.md +93 -0
  18. package/resources/gofer/commands/0_gofer_start.md +440 -99
  19. package/resources/gofer/commands/0a_problem_validation.md +187 -27
  20. package/resources/gofer/commands/10_gofer_cloud.md +183 -23
  21. package/resources/gofer/commands/1_gofer_research.md +239 -30
  22. package/resources/gofer/commands/2_gofer_specify.md +239 -35
  23. package/resources/gofer/commands/3_gofer_plan.md +259 -43
  24. package/resources/gofer/commands/4_gofer_tasks.md +401 -81
  25. package/resources/gofer/commands/5_gofer_implement.md +375 -84
  26. package/resources/gofer/commands/6_gofer_validate.md +284 -53
  27. package/resources/gofer/commands/7_gofer_save.md +187 -26
  28. package/resources/gofer/commands/7a_stakeholder_comms.md +183 -23
  29. package/resources/gofer/commands/8_gofer_branding.md +183 -23
  30. package/resources/gofer/commands/9_gofer_tests.md +212 -23
  31. package/resources/gofer/commands/gofer_bootstrap_workspace.md +121 -8
  32. package/resources/gofer/commands/gofer_check_workspace.md +123 -8
  33. package/resources/gofer/commands/gofer_constitution.md +183 -23
  34. package/resources/gofer/commands/gofer_diagnose.md +183 -23
  35. package/resources/gofer/commands/gofer_eai_first_run.md +254 -25
  36. package/resources/gofer/commands/gofer_hydrate.md +183 -23
  37. package/resources/gofer/commands/gofer_personality.md +117 -6
  38. package/resources/gofer/commands/gofer_plan.md +117 -6
  39. package/resources/gofer/commands/gofer_side.md +117 -6
  40. package/resources/gofer/commands/gofer_spec_summary.md +183 -23
  41. package/resources/gofer/commands/gofer_tdd.md +183 -23
  42. package/resources/gofer/commands/gofer_vocabulary.md +185 -25
  43. package/resources/gofer/commands/gofer_zoom_out.md +183 -23
  44. package/resources/gofer/config/typesafe-learning-review.json +16 -0
  45. package/resources/gofer/config/typesafe-semantic-review.json +9 -0
  46. package/resources/gofer/copilot-instructions/gofer-cost.instructions.md +15 -6
  47. package/resources/gofer/copilot-instructions/typescript.instructions.md +1 -1
  48. package/resources/gofer/copilot-prompts/eai-update.prompt.md +58 -0
  49. package/resources/gofer/copilot-prompts/eai.prompt.md +367 -0
  50. package/resources/gofer/gemini/commands/gofer/eai-update.md +22 -0
  51. package/resources/gofer/gemini/commands/gofer/eai-update.toml +2 -0
  52. package/resources/gofer/gemini/commands/gofer/eai.md +357 -0
  53. package/resources/gofer/gemini/commands/gofer/eai.toml +2 -0
  54. package/resources/gofer/gemini/commands/gofer/manifest.json +3 -27
  55. package/resources/gofer/gemini/extension.json +4 -4
  56. package/resources/gofer/github-agents/eai.agent.md +83 -0
  57. package/resources/gofer/github-agents/gofer-business.agent.md +73 -4
  58. package/resources/gofer/github-agents/gofer-implement.agent.md +71 -2
  59. package/resources/gofer/github-agents/gofer-plan.agent.md +72 -2
  60. package/resources/gofer/github-agents/gofer-research.agent.md +72 -2
  61. package/resources/gofer/github-agents/gofer-validate.agent.md +72 -2
  62. package/resources/gofer/github-skills/eai/SKILL.md +365 -0
  63. package/resources/gofer/github-skills/eai-update/SKILL.md +56 -0
  64. package/resources/gofer/github-skills/gofer-documentation/SKILL.md +93 -0
  65. package/resources/gofer/grok-skills/eai/SKILL.md +267 -14
  66. package/resources/gofer/grok-skills/eai-update/SKILL.md +56 -0
  67. package/resources/gofer/hook-scripts/user-prompt-submit.mjs +58 -13
  68. package/resources/gofer/instruction-templates/base/agents-base.md +8 -4
  69. package/resources/gofer/instruction-templates/gofer/gofer-claude.md +7 -5
  70. package/resources/gofer/instruction-templates/gofer/gofer-copilot.md +10 -8
  71. package/resources/gofer/memory/constitution.md +9 -7
  72. package/resources/gofer/memory/gofer-model-policy.yaml +23 -1
  73. package/resources/gofer/memory/lessons.md +0 -31
  74. package/resources/gofer/node-scripts/canonical-descriptions.mjs +1 -1
  75. package/resources/gofer/node-scripts/check-version-alignment.mjs +4 -7
  76. package/resources/gofer/node-scripts/delivery-lineage-corpus.mjs +156 -0
  77. package/resources/gofer/node-scripts/generate-commands.mjs +1073 -265
  78. package/resources/gofer/node-scripts/gofer-acceptance-check.mjs +143 -0
  79. package/resources/gofer/node-scripts/gofer-agent-catalog.mjs +271 -0
  80. package/resources/gofer/node-scripts/gofer-benchmark-executor.mjs +123 -0
  81. package/resources/gofer/node-scripts/gofer-benchmark-sign.mjs +62 -0
  82. package/resources/gofer/node-scripts/gofer-benchmark-signer.mjs +89 -0
  83. package/resources/gofer/node-scripts/gofer-benchmark.mjs +76 -0
  84. package/resources/gofer/node-scripts/gofer-blocker-control.mjs +274 -0
  85. package/resources/gofer/node-scripts/gofer-claude-adapter.mjs +154 -0
  86. package/resources/gofer/node-scripts/gofer-closed-loop-audit.mjs +19 -2
  87. package/resources/gofer/node-scripts/gofer-delivery-check.mjs +121 -0
  88. package/resources/gofer/node-scripts/gofer-encrypted-key.mjs +58 -0
  89. package/resources/gofer/node-scripts/gofer-execution-metrics.mjs +477 -0
  90. package/resources/gofer/node-scripts/gofer-execution-recovery.mjs +334 -0
  91. package/resources/gofer/node-scripts/gofer-grok-adapter.mjs +184 -0
  92. package/resources/gofer/node-scripts/gofer-heldout-corpus.mjs +73 -0
  93. package/resources/gofer/node-scripts/gofer-heldout-snapshot.mjs +286 -0
  94. package/resources/gofer/node-scripts/gofer-heldout-verifier.mjs +211 -0
  95. package/resources/gofer/node-scripts/gofer-host-capability.mjs +335 -0
  96. package/resources/gofer/node-scripts/gofer-independent-reviewer.mjs +130 -0
  97. package/resources/gofer/node-scripts/gofer-live-routing.mjs +109 -0
  98. package/resources/gofer/node-scripts/gofer-local-capability-issuer.mjs +71 -0
  99. package/resources/gofer/node-scripts/gofer-local-isolation.mjs +175 -0
  100. package/resources/gofer/node-scripts/gofer-local-settings-cleanup.mjs +388 -0
  101. package/resources/gofer/node-scripts/gofer-loop-audit.mjs +54 -3
  102. package/resources/gofer/node-scripts/gofer-native-adapter.mjs +567 -0
  103. package/resources/gofer/node-scripts/gofer-native-benchmark-dispatch.mjs +145 -0
  104. package/resources/gofer/node-scripts/gofer-native-runtime.mjs +169 -0
  105. package/resources/gofer/node-scripts/gofer-pre-edit-check.mjs +204 -0
  106. package/resources/gofer/node-scripts/gofer-priority-check.mjs +214 -0
  107. package/resources/gofer/node-scripts/gofer-response-check.mjs +56 -0
  108. package/resources/gofer/node-scripts/gofer-reviewed-learning.mjs +1232 -0
  109. package/resources/gofer/node-scripts/gofer-run-verified-task.mjs +330 -0
  110. package/resources/gofer/node-scripts/gofer-runtime-ledger.mjs +289 -0
  111. package/resources/gofer/node-scripts/gofer-semantic-drift.mjs +584 -0
  112. package/resources/gofer/node-scripts/gofer-surface-update.mjs +1178 -0
  113. package/resources/gofer/node-scripts/gofer-trust-bootstrap.mjs +77 -0
  114. package/resources/gofer/node-scripts/gofer-trusted-benchmark.mjs +102 -0
  115. package/resources/gofer/node-scripts/gofer-trusted-evaluator.mjs +274 -0
  116. package/resources/gofer/node-scripts/gofer-tty-prompt.mjs +34 -0
  117. package/resources/gofer/node-scripts/gofer-typesafe-credentials.mjs +435 -0
  118. package/resources/gofer/node-scripts/gofer-ui-preview.mjs +1212 -0
  119. package/resources/gofer/node-scripts/gofer-verified-execution.mjs +484 -0
  120. package/resources/gofer/node-scripts/gofer-verifier-key-ceremony.mjs +101 -0
  121. package/resources/gofer/node-scripts/gofer-worktree-layout.mjs +32 -0
  122. package/resources/gofer/node-scripts/object-type-routing-phase-bundle.mjs +360 -0
  123. package/resources/gofer/node-scripts/package-agent-plugin.mjs +574 -82
  124. package/resources/gofer/node-scripts/parse-stage-command.mjs +1 -1
  125. package/resources/gofer/node-scripts/render-delivery-lineage.mjs +178 -0
  126. package/resources/gofer/node-scripts/sync-extension-resources.mjs +78 -2
  127. package/resources/gofer/node-scripts/validate-object-type-identifiers.mjs +767 -0
  128. package/resources/gofer/node-scripts/validate-object-type-routing-workspace.mjs +1325 -0
  129. package/resources/gofer/node-scripts/validate-v4-resource-contract.d.mts +44 -0
  130. package/resources/gofer/node-scripts/validate-v4-resource-contract.mjs +957 -0
  131. package/resources/gofer/node-scripts/workspace-bootstrap-lib.mjs +685 -116
  132. package/resources/gofer/references/agent-catalog.json +126 -0
  133. package/resources/gofer/references/blocker-mediation.md +156 -0
  134. package/resources/gofer/references/business-updates-and-goal-checks.md +109 -0
  135. package/resources/gofer/references/delivery-lineage.md +48 -0
  136. package/resources/gofer/references/mvp-capability-validation.md +102 -0
  137. package/resources/gofer/references/platform/README.md +1 -1
  138. package/resources/gofer/references/platform/eai-app-template.md +15 -13
  139. package/resources/gofer/references/platform/eai-auth-access.md +104 -0
  140. package/resources/gofer/references/platform/eai-config-driven-ui.md +5 -5
  141. package/resources/gofer/references/platform/eai-error-catalog.yaml +77 -19
  142. package/resources/gofer/references/platform/eai-repo-contract.md +61 -23
  143. package/resources/gofer/references/platform/eai-service-patterns.md +102 -105
  144. package/resources/gofer/references/platform/eai.md +44 -8
  145. package/resources/gofer/references/platform/vertical-template.md +10 -9
  146. package/resources/gofer/references/priority-outcome-protection.md +152 -0
  147. package/resources/gofer/references/verified-agent-execution.md +179 -0
  148. package/resources/gofer/schemas/gofer-learning-trace-v1.json +70 -0
  149. package/resources/gofer/specify-commands/0_gofer_start.md +440 -99
  150. package/resources/gofer/specify-commands/0a_problem_validation.md +187 -27
  151. package/resources/gofer/specify-commands/10_gofer_cloud.md +183 -23
  152. package/resources/gofer/specify-commands/1_gofer_research.md +239 -30
  153. package/resources/gofer/specify-commands/2_gofer_specify.md +239 -35
  154. package/resources/gofer/specify-commands/3_gofer_plan.md +259 -43
  155. package/resources/gofer/specify-commands/4_gofer_tasks.md +401 -81
  156. package/resources/gofer/specify-commands/5_gofer_implement.md +375 -84
  157. package/resources/gofer/specify-commands/6_gofer_validate.md +284 -53
  158. package/resources/gofer/specify-commands/7_gofer_save.md +187 -26
  159. package/resources/gofer/specify-commands/7a_stakeholder_comms.md +183 -23
  160. package/resources/gofer/specify-commands/8_gofer_branding.md +183 -23
  161. package/resources/gofer/specify-commands/9_gofer_tests.md +212 -23
  162. package/resources/gofer/specify-commands/gofer_bootstrap_workspace.md +121 -8
  163. package/resources/gofer/specify-commands/gofer_check_workspace.md +123 -8
  164. package/resources/gofer/specify-commands/gofer_constitution.md +183 -23
  165. package/resources/gofer/specify-commands/gofer_diagnose.md +183 -23
  166. package/resources/gofer/specify-commands/gofer_eai_first_run.md +254 -25
  167. package/resources/gofer/specify-commands/gofer_hydrate.md +183 -23
  168. package/resources/gofer/specify-commands/gofer_personality.md +117 -6
  169. package/resources/gofer/specify-commands/gofer_plan.md +117 -6
  170. package/resources/gofer/specify-commands/gofer_side.md +117 -6
  171. package/resources/gofer/specify-commands/gofer_spec_summary.md +183 -23
  172. package/resources/gofer/specify-commands/gofer_tdd.md +183 -23
  173. package/resources/gofer/specify-commands/gofer_vocabulary.md +185 -25
  174. package/resources/gofer/specify-commands/gofer_zoom_out.md +183 -23
  175. package/resources/gofer/specify-config/object-type-routing.json +24 -0
  176. package/resources/gofer/specify-config/typesafe-learning-review.json +16 -0
  177. package/resources/gofer/specify-config/typesafe-semantic-review.json +9 -0
  178. package/resources/gofer/system-skills/eai/SKILL.md +365 -0
  179. package/resources/gofer/system-skills/eai-update/SKILL.md +56 -0
  180. package/resources/gofer/system-skills/gofer-documentation/SKILL.md +93 -0
  181. package/resources/gofer/templates/build-map-template.md +64 -0
  182. package/resources/gofer/templates/business-scenarios-template.json +14 -0
  183. package/resources/gofer/templates/ciso-security-summary-template.md +3 -3
  184. package/resources/gofer/templates/context-bundle-template.md +4 -3
  185. package/resources/gofer/templates/contract-pack-template.md +8 -8
  186. package/resources/gofer/templates/cto-architecture-summary-template.md +3 -3
  187. package/resources/gofer/templates/delivery-lineage-template.json +8 -0
  188. package/resources/gofer/templates/eai-preflight-template.md +109 -68
  189. package/resources/gofer/templates/goal-ledger-template.json +1 -1
  190. package/resources/gofer/templates/gofer-model-policy.yaml +28 -6
  191. package/resources/gofer/templates/loop-contract-template.json +3 -1
  192. package/resources/gofer/templates/plan-template.md +8 -7
  193. package/resources/gofer/templates/priority-plan-template.json +29 -0
  194. package/resources/gofer/templates/proposal-review-template.md +6 -3
  195. package/resources/gofer/templates/release-capability-ledger-template.md +24 -0
  196. package/resources/gofer/templates/research-template.md +7 -6
  197. package/resources/gofer/templates/spec-summary-template.md +1 -1
  198. package/resources/gofer/templates/spec-template.md +45 -6
  199. package/resources/gofer/templates/tasks-template.md +12 -3
  200. package/resources/gofer/templates/ui-preview-brief-template.md +55 -5
  201. package/resources/gofer/templates/ui-review-log-template.md +21 -3
  202. package/resources/gofer/templates/ui-show-and-tell-template.md +46 -0
  203. package/resources/gofer/templates/visuals/capability-heatmap-template.md +2 -2
  204. package/resources/gofer/templates/working-backwards-prfaq-template.md +9 -8
  205. package/resources/linked-sources.json +4 -4
  206. package/resources/gofer/agents-skills/0_gofer_start/SKILL.md +0 -1287
  207. package/resources/gofer/agents-skills/0a_problem_validation/SKILL.md +0 -429
  208. package/resources/gofer/agents-skills/10_gofer_cloud/SKILL.md +0 -635
  209. package/resources/gofer/agents-skills/1_gofer_research/SKILL.md +0 -1159
  210. package/resources/gofer/agents-skills/2_gofer_specify/SKILL.md +0 -860
  211. package/resources/gofer/agents-skills/3_gofer_plan/SKILL.md +0 -899
  212. package/resources/gofer/agents-skills/4_gofer_tasks/SKILL.md +0 -760
  213. package/resources/gofer/agents-skills/5_gofer_implement/SKILL.md +0 -944
  214. package/resources/gofer/agents-skills/6_gofer_validate/SKILL.md +0 -2302
  215. package/resources/gofer/agents-skills/7_gofer_save/SKILL.md +0 -423
  216. package/resources/gofer/agents-skills/7a_stakeholder_comms/SKILL.md +0 -508
  217. package/resources/gofer/agents-skills/8_gofer_branding/SKILL.md +0 -315
  218. package/resources/gofer/agents-skills/9_gofer_tests/SKILL.md +0 -558
  219. package/resources/gofer/agents-skills/gofer_bootstrap_workspace/SKILL.md +0 -148
  220. package/resources/gofer/agents-skills/gofer_check_workspace/SKILL.md +0 -119
  221. package/resources/gofer/agents-skills/gofer_constitution/SKILL.md +0 -612
  222. package/resources/gofer/agents-skills/gofer_diagnose/SKILL.md +0 -114
  223. package/resources/gofer/agents-skills/gofer_eai_first_run/SKILL.md +0 -397
  224. package/resources/gofer/agents-skills/gofer_hydrate/SKILL.md +0 -561
  225. package/resources/gofer/agents-skills/gofer_personality/SKILL.md +0 -44
  226. package/resources/gofer/agents-skills/gofer_plan/SKILL.md +0 -40
  227. package/resources/gofer/agents-skills/gofer_side/SKILL.md +0 -45
  228. package/resources/gofer/agents-skills/gofer_spec_summary/SKILL.md +0 -112
  229. package/resources/gofer/agents-skills/gofer_tdd/SKILL.md +0 -112
  230. package/resources/gofer/agents-skills/gofer_vocabulary/SKILL.md +0 -112
  231. package/resources/gofer/agents-skills/gofer_zoom_out/SKILL.md +0 -112
  232. package/resources/gofer/claude-commands/0_gofer_start.md +0 -1282
  233. package/resources/gofer/claude-commands/0a_problem_validation.md +0 -424
  234. package/resources/gofer/claude-commands/10_gofer_cloud.md +0 -630
  235. package/resources/gofer/claude-commands/1_gofer_research.md +0 -1154
  236. package/resources/gofer/claude-commands/2_gofer_specify.md +0 -855
  237. package/resources/gofer/claude-commands/3_gofer_plan.md +0 -894
  238. package/resources/gofer/claude-commands/4_gofer_tasks.md +0 -755
  239. package/resources/gofer/claude-commands/5_gofer_implement.md +0 -939
  240. package/resources/gofer/claude-commands/6_gofer_validate.md +0 -2297
  241. package/resources/gofer/claude-commands/7_gofer_save.md +0 -418
  242. package/resources/gofer/claude-commands/7a_stakeholder_comms.md +0 -503
  243. package/resources/gofer/claude-commands/8_gofer_branding.md +0 -310
  244. package/resources/gofer/claude-commands/9_gofer_tests.md +0 -553
  245. package/resources/gofer/claude-commands/gofer_bootstrap_workspace.md +0 -143
  246. package/resources/gofer/claude-commands/gofer_check_workspace.md +0 -114
  247. package/resources/gofer/claude-commands/gofer_constitution.md +0 -607
  248. package/resources/gofer/claude-commands/gofer_diagnose.md +0 -109
  249. package/resources/gofer/claude-commands/gofer_eai_first_run.md +0 -392
  250. package/resources/gofer/claude-commands/gofer_hydrate.md +0 -556
  251. package/resources/gofer/claude-commands/gofer_personality.md +0 -39
  252. package/resources/gofer/claude-commands/gofer_plan.md +0 -35
  253. package/resources/gofer/claude-commands/gofer_side.md +0 -40
  254. package/resources/gofer/claude-commands/gofer_spec_summary.md +0 -107
  255. package/resources/gofer/claude-commands/gofer_tdd.md +0 -107
  256. package/resources/gofer/claude-commands/gofer_vocabulary.md +0 -107
  257. package/resources/gofer/claude-commands/gofer_zoom_out.md +0 -107
  258. package/resources/gofer/claude-skills/eai-gofer/SKILL.md +0 -56
  259. package/resources/gofer/copilot-prompts/0_gofer_start.prompt.md +0 -1308
  260. package/resources/gofer/copilot-prompts/0a_problem_validation.prompt.md +0 -429
  261. package/resources/gofer/copilot-prompts/10_gofer_cloud.prompt.md +0 -644
  262. package/resources/gofer/copilot-prompts/1_gofer_research.prompt.md +0 -1177
  263. package/resources/gofer/copilot-prompts/2_gofer_specify.prompt.md +0 -878
  264. package/resources/gofer/copilot-prompts/3_gofer_plan.prompt.md +0 -917
  265. package/resources/gofer/copilot-prompts/4_gofer_tasks.prompt.md +0 -778
  266. package/resources/gofer/copilot-prompts/5_gofer_implement.prompt.md +0 -962
  267. package/resources/gofer/copilot-prompts/6_gofer_validate.prompt.md +0 -2310
  268. package/resources/gofer/copilot-prompts/7_gofer_save.prompt.md +0 -433
  269. package/resources/gofer/copilot-prompts/7a_stakeholder_comms.prompt.md +0 -516
  270. package/resources/gofer/copilot-prompts/8_gofer_branding.prompt.md +0 -323
  271. package/resources/gofer/copilot-prompts/9_gofer_tests.prompt.md +0 -566
  272. package/resources/gofer/copilot-prompts/gofer_bootstrap_workspace.prompt.md +0 -161
  273. package/resources/gofer/copilot-prompts/gofer_check_workspace.prompt.md +0 -132
  274. package/resources/gofer/copilot-prompts/gofer_constitution.prompt.md +0 -621
  275. package/resources/gofer/copilot-prompts/gofer_diagnose.prompt.md +0 -127
  276. package/resources/gofer/copilot-prompts/gofer_eai_first_run.prompt.md +0 -410
  277. package/resources/gofer/copilot-prompts/gofer_hydrate.prompt.md +0 -571
  278. package/resources/gofer/copilot-prompts/gofer_personality.prompt.md +0 -57
  279. package/resources/gofer/copilot-prompts/gofer_plan.prompt.md +0 -53
  280. package/resources/gofer/copilot-prompts/gofer_side.prompt.md +0 -58
  281. package/resources/gofer/copilot-prompts/gofer_spec_summary.prompt.md +0 -125
  282. package/resources/gofer/copilot-prompts/gofer_tdd.prompt.md +0 -125
  283. package/resources/gofer/copilot-prompts/gofer_vocabulary.prompt.md +0 -125
  284. package/resources/gofer/copilot-prompts/gofer_zoom_out.prompt.md +0 -125
  285. package/resources/gofer/gemini/commands/gofer/0_gofer_start.md +0 -1282
  286. package/resources/gofer/gemini/commands/gofer/0_gofer_start.toml +0 -2
  287. package/resources/gofer/gemini/commands/gofer/0a_problem_validation.md +0 -424
  288. package/resources/gofer/gemini/commands/gofer/0a_problem_validation.toml +0 -2
  289. package/resources/gofer/gemini/commands/gofer/10_gofer_cloud.md +0 -630
  290. package/resources/gofer/gemini/commands/gofer/10_gofer_cloud.toml +0 -2
  291. package/resources/gofer/gemini/commands/gofer/1_gofer_research.md +0 -1154
  292. package/resources/gofer/gemini/commands/gofer/1_gofer_research.toml +0 -2
  293. package/resources/gofer/gemini/commands/gofer/2_gofer_specify.md +0 -855
  294. package/resources/gofer/gemini/commands/gofer/2_gofer_specify.toml +0 -2
  295. package/resources/gofer/gemini/commands/gofer/3_gofer_plan.md +0 -894
  296. package/resources/gofer/gemini/commands/gofer/3_gofer_plan.toml +0 -2
  297. package/resources/gofer/gemini/commands/gofer/4_gofer_tasks.md +0 -755
  298. package/resources/gofer/gemini/commands/gofer/4_gofer_tasks.toml +0 -2
  299. package/resources/gofer/gemini/commands/gofer/5_gofer_implement.md +0 -939
  300. package/resources/gofer/gemini/commands/gofer/5_gofer_implement.toml +0 -2
  301. package/resources/gofer/gemini/commands/gofer/6_gofer_validate.md +0 -2297
  302. package/resources/gofer/gemini/commands/gofer/6_gofer_validate.toml +0 -2
  303. package/resources/gofer/gemini/commands/gofer/7_gofer_save.md +0 -418
  304. package/resources/gofer/gemini/commands/gofer/7_gofer_save.toml +0 -2
  305. package/resources/gofer/gemini/commands/gofer/7a_stakeholder_comms.md +0 -503
  306. package/resources/gofer/gemini/commands/gofer/7a_stakeholder_comms.toml +0 -2
  307. package/resources/gofer/gemini/commands/gofer/8_gofer_branding.md +0 -310
  308. package/resources/gofer/gemini/commands/gofer/8_gofer_branding.toml +0 -2
  309. package/resources/gofer/gemini/commands/gofer/9_gofer_tests.md +0 -553
  310. package/resources/gofer/gemini/commands/gofer/9_gofer_tests.toml +0 -2
  311. package/resources/gofer/gemini/commands/gofer/gofer_bootstrap_workspace.md +0 -143
  312. package/resources/gofer/gemini/commands/gofer/gofer_bootstrap_workspace.toml +0 -2
  313. package/resources/gofer/gemini/commands/gofer/gofer_check_workspace.md +0 -114
  314. package/resources/gofer/gemini/commands/gofer/gofer_check_workspace.toml +0 -2
  315. package/resources/gofer/gemini/commands/gofer/gofer_constitution.md +0 -607
  316. package/resources/gofer/gemini/commands/gofer/gofer_constitution.toml +0 -2
  317. package/resources/gofer/gemini/commands/gofer/gofer_diagnose.md +0 -109
  318. package/resources/gofer/gemini/commands/gofer/gofer_diagnose.toml +0 -2
  319. package/resources/gofer/gemini/commands/gofer/gofer_eai_first_run.md +0 -392
  320. package/resources/gofer/gemini/commands/gofer/gofer_eai_first_run.toml +0 -2
  321. package/resources/gofer/gemini/commands/gofer/gofer_hydrate.md +0 -556
  322. package/resources/gofer/gemini/commands/gofer/gofer_hydrate.toml +0 -2
  323. package/resources/gofer/gemini/commands/gofer/gofer_personality.md +0 -39
  324. package/resources/gofer/gemini/commands/gofer/gofer_personality.toml +0 -2
  325. package/resources/gofer/gemini/commands/gofer/gofer_plan.md +0 -35
  326. package/resources/gofer/gemini/commands/gofer/gofer_plan.toml +0 -2
  327. package/resources/gofer/gemini/commands/gofer/gofer_side.md +0 -40
  328. package/resources/gofer/gemini/commands/gofer/gofer_side.toml +0 -2
  329. package/resources/gofer/gemini/commands/gofer/gofer_spec_summary.md +0 -107
  330. package/resources/gofer/gemini/commands/gofer/gofer_spec_summary.toml +0 -2
  331. package/resources/gofer/gemini/commands/gofer/gofer_tdd.md +0 -107
  332. package/resources/gofer/gemini/commands/gofer/gofer_tdd.toml +0 -2
  333. package/resources/gofer/gemini/commands/gofer/gofer_vocabulary.md +0 -107
  334. package/resources/gofer/gemini/commands/gofer/gofer_vocabulary.toml +0 -2
  335. package/resources/gofer/gemini/commands/gofer/gofer_zoom_out.md +0 -107
  336. package/resources/gofer/gemini/commands/gofer/gofer_zoom_out.toml +0 -2
  337. package/resources/gofer/github-skills/eai-gofer/SKILL.md +0 -56
  338. package/resources/gofer/system-skills/0_gofer_start/SKILL.md +0 -1287
  339. package/resources/gofer/system-skills/0a_problem_validation/SKILL.md +0 -429
  340. package/resources/gofer/system-skills/10_gofer_cloud/SKILL.md +0 -635
  341. package/resources/gofer/system-skills/1_gofer_research/SKILL.md +0 -1159
  342. package/resources/gofer/system-skills/2_gofer_specify/SKILL.md +0 -860
  343. package/resources/gofer/system-skills/3_gofer_plan/SKILL.md +0 -899
  344. package/resources/gofer/system-skills/4_gofer_tasks/SKILL.md +0 -760
  345. package/resources/gofer/system-skills/5_gofer_implement/SKILL.md +0 -944
  346. package/resources/gofer/system-skills/6_gofer_validate/SKILL.md +0 -2302
  347. package/resources/gofer/system-skills/7_gofer_save/SKILL.md +0 -423
  348. package/resources/gofer/system-skills/7a_stakeholder_comms/SKILL.md +0 -508
  349. package/resources/gofer/system-skills/8_gofer_branding/SKILL.md +0 -315
  350. package/resources/gofer/system-skills/9_gofer_tests/SKILL.md +0 -558
  351. package/resources/gofer/system-skills/gofer_bootstrap_workspace/SKILL.md +0 -148
  352. package/resources/gofer/system-skills/gofer_check_workspace/SKILL.md +0 -119
  353. package/resources/gofer/system-skills/gofer_constitution/SKILL.md +0 -612
  354. package/resources/gofer/system-skills/gofer_diagnose/SKILL.md +0 -114
  355. package/resources/gofer/system-skills/gofer_eai_first_run/SKILL.md +0 -397
  356. package/resources/gofer/system-skills/gofer_hydrate/SKILL.md +0 -561
  357. package/resources/gofer/system-skills/gofer_personality/SKILL.md +0 -44
  358. package/resources/gofer/system-skills/gofer_plan/SKILL.md +0 -40
  359. package/resources/gofer/system-skills/gofer_side/SKILL.md +0 -45
  360. package/resources/gofer/system-skills/gofer_spec_summary/SKILL.md +0 -112
  361. package/resources/gofer/system-skills/gofer_tdd/SKILL.md +0 -112
  362. package/resources/gofer/system-skills/gofer_vocabulary/SKILL.md +0 -112
  363. package/resources/gofer/system-skills/gofer_zoom_out/SKILL.md +0 -112
  364. package/resources/gofer/templates/ui-approval-template.md +0 -32
@@ -0,0 +1,435 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { constants } from 'fs';
4
+ import { promises as fs } from 'fs';
5
+ import { execFile, spawn } from 'child_process';
6
+ import path from 'path';
7
+ import process from 'process';
8
+ import { promisify } from 'util';
9
+
10
+ const SECRET_RELATIVE_PATH = path.join('.specify', 'secrets', 'typesafe.env');
11
+ const POLICY_RELATIVE_PATHS = [
12
+ path.join('.specify', 'config', 'typesafe-semantic-review.json'),
13
+ path.join('.specify', 'config', 'typesafe-learning-review.json'),
14
+ ];
15
+ const KEYCHAIN_SERVICE = 'com.enterpriseai.gofer.jev';
16
+ const KEYCHAIN_ACCOUNT = 'shared-api-key';
17
+ const execFileAsync = promisify(execFile);
18
+
19
+ export function parseArgs(argv) {
20
+ const action = argv.find((value) => value === '--connect' || value === '--disconnect' || value === '--status');
21
+ const scopeIndex = argv.indexOf('--scope');
22
+ const scope = scopeIndex === -1 ? (process.platform === 'darwin' ? 'shared' : 'project') : argv[scopeIndex + 1];
23
+ const expectedLength = scopeIndex === -1 ? 1 : 3;
24
+ if (!action || argv.length !== expectedLength || !['project', 'shared'].includes(scope)) {
25
+ throw new Error('Usage: --connect | --disconnect | --status [--scope project|shared]');
26
+ }
27
+ if (action === '--status' && scopeIndex !== -1) {
28
+ throw new Error('--status reports the effective credential and does not accept --scope.');
29
+ }
30
+ return { action: action.slice(2), scope };
31
+ }
32
+
33
+ const macOSKeychain = {
34
+ async has() {
35
+ if (process.platform !== 'darwin') return false;
36
+ try {
37
+ await execFileAsync('/usr/bin/security', [
38
+ 'find-generic-password', '-a', KEYCHAIN_ACCOUNT, '-s', KEYCHAIN_SERVICE,
39
+ ], { encoding: 'utf8', maxBuffer: 64 * 1024 });
40
+ return true;
41
+ } catch (error) {
42
+ if (error?.code === 44 || error?.stderr?.includes('could not be found')) return false;
43
+ throw new Error('Gofer could not check the shared Jev credential in macOS Keychain.');
44
+ }
45
+ },
46
+ async read() {
47
+ if (process.platform !== 'darwin') return '';
48
+ try {
49
+ const { stdout } = await execFileAsync('/usr/bin/security', [
50
+ 'find-generic-password', '-a', KEYCHAIN_ACCOUNT, '-s', KEYCHAIN_SERVICE, '-w',
51
+ ], { encoding: 'utf8', maxBuffer: 64 * 1024 });
52
+ return String(stdout).trim();
53
+ } catch (error) {
54
+ if (error?.code === 44 || error?.stderr?.includes('could not be found')) return '';
55
+ throw new Error('Gofer could not read the shared Jev credential from macOS Keychain.');
56
+ }
57
+ },
58
+ async write(key) {
59
+ if (process.platform !== 'darwin') throw new Error('Shared Jev credentials require macOS Keychain.');
60
+ const encoded = Buffer.from(String(key), 'utf8').toString('hex');
61
+ const child = spawn('/usr/bin/security', ['-i'], { stdio: ['pipe', 'ignore', 'pipe'] });
62
+ let stderr = '';
63
+ child.stderr.on('data', (chunk) => {
64
+ if (stderr.length < 64 * 1024) stderr += chunk.toString('utf8');
65
+ });
66
+ child.stdin.end(
67
+ `add-generic-password -a "${KEYCHAIN_ACCOUNT}" -s "${KEYCHAIN_SERVICE}" ` +
68
+ `-l "EAI Gofer Jev API key" -U -X ${encoded}\n`
69
+ );
70
+ const exitCode = await new Promise((resolve, reject) => {
71
+ child.once('error', reject);
72
+ child.once('exit', (code) => resolve(code));
73
+ });
74
+ if (exitCode !== 0 || stderr.includes('SecKeychainItem')) {
75
+ throw new Error('macOS Keychain did not save the shared Jev credential.');
76
+ }
77
+ },
78
+ async remove() {
79
+ if (process.platform !== 'darwin') return false;
80
+ try {
81
+ await execFileAsync('/usr/bin/security', [
82
+ 'delete-generic-password', '-a', KEYCHAIN_ACCOUNT, '-s', KEYCHAIN_SERVICE,
83
+ ]);
84
+ return true;
85
+ } catch (error) {
86
+ if (error?.code === 44 || error?.stderr?.includes('could not be found')) return false;
87
+ throw new Error('Gofer could not remove the shared Jev credential from macOS Keychain.');
88
+ }
89
+ },
90
+ };
91
+
92
+ // A lexical check alone does not stop a symlinked intermediate directory
93
+ // (e.g. .specify/secrets) from redirecting the confined path outside the
94
+ // workspace. Walk every component from the workspace root and reject any
95
+ // that is a symlink, matching gofer-surface-update.mjs's existing check.
96
+ async function assertNoSymlinkComponents(root, relativeTarget) {
97
+ const components = relativeTarget.split(path.sep).filter(Boolean);
98
+ let currentPath = root;
99
+ for (const component of components) {
100
+ currentPath = path.join(currentPath, component);
101
+ try {
102
+ const status = await fs.lstat(currentPath);
103
+ if (status.isSymbolicLink()) {
104
+ throw new Error('Gofer credential path must not pass through a symbolic link.');
105
+ }
106
+ } catch (error) {
107
+ if (error?.code === 'ENOENT') return;
108
+ throw error;
109
+ }
110
+ }
111
+ }
112
+
113
+ // assertNoSymlinkComponents only walks descendants of root; it never checks
114
+ // root itself. A caller-supplied workspace that is a symlink (or missing, or
115
+ // not a directory) would otherwise sail through every confinement check
116
+ // below it. Matches workspace-bootstrap-lib.mjs's assertSafeWorkspaceRoot.
117
+ async function assertSafeWorkspaceRoot(workspaceRoot) {
118
+ const resolvedRoot = path.resolve(workspaceRoot);
119
+ const rootStat = await fs.lstat(resolvedRoot).catch((error) => {
120
+ if (error?.code === 'ENOENT') return null;
121
+ throw error;
122
+ });
123
+ if (!rootStat) throw new Error('Gofer workspace root does not exist.');
124
+ if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
125
+ throw new Error('Gofer workspace root must be a real directory, not a symbolic link.');
126
+ }
127
+ return resolvedRoot;
128
+ }
129
+
130
+ async function confinedPath(workspace, relativePath) {
131
+ const root = await assertSafeWorkspaceRoot(workspace);
132
+ const target = path.resolve(root, relativePath);
133
+ const relative = path.relative(root, target);
134
+ if (relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
135
+ throw new Error('Gofer credential path must remain inside the workspace.');
136
+ }
137
+ await assertNoSymlinkComponents(root, relative);
138
+ return target;
139
+ }
140
+
141
+ async function existingFile(target) {
142
+ try {
143
+ const stat = await fs.lstat(target);
144
+ if (stat.isSymbolicLink() || !stat.isFile()) throw new Error('Gofer credential path must be a regular file.');
145
+ return true;
146
+ } catch (error) {
147
+ if (error?.code === 'ENOENT') return false;
148
+ throw error;
149
+ }
150
+ }
151
+
152
+ // O_NOFOLLOW is unavailable on Windows; the bitwise OR silently contributes
153
+ // nothing there rather than erroring. lstat detects a symlink or junction
154
+ // cross-platform (including Windows) and is the actual protection;
155
+ // O_NOFOLLOW only closes the small remaining gap between that check and the
156
+ // open, on platforms that support it.
157
+ const noFollowFlag = process.platform === 'win32' ? 0 : constants.O_NOFOLLOW;
158
+ function sameIdentity(left, right) {
159
+ if (left.dev === undefined || left.ino === undefined ||
160
+ right.dev === undefined || right.ino === undefined) return true;
161
+ return left.dev === right.dev && left.ino === right.ino;
162
+ }
163
+
164
+ async function withVerifiedParent(target, action) {
165
+ const parent = path.dirname(target);
166
+ const parentHandle = await fs.open(parent,
167
+ constants.O_RDONLY | (constants.O_DIRECTORY ?? 0) | noFollowFlag);
168
+ const openedParent = await parentHandle.stat();
169
+ try {
170
+ const currentParent = await fs.lstat(parent);
171
+ if (!openedParent.isDirectory() || currentParent.isSymbolicLink() ||
172
+ !sameIdentity(openedParent, currentParent)) {
173
+ throw new Error('Gofer credential parent directory changed during access.');
174
+ }
175
+ const result = await action();
176
+ const parentAfter = await fs.lstat(parent);
177
+ if (parentAfter.isSymbolicLink() || !sameIdentity(openedParent, parentAfter)) {
178
+ throw new Error('Gofer credential parent directory changed during access.');
179
+ }
180
+ return result;
181
+ } finally {
182
+ await parentHandle.close();
183
+ }
184
+ }
185
+
186
+ async function assertNotSymlink(target) {
187
+ const info = await fs.lstat(target).catch((error) => {
188
+ if (error?.code === 'ENOENT') return null;
189
+ throw error;
190
+ });
191
+ if (info?.isSymbolicLink()) throw new Error('Gofer credential path must not be a symbolic link.');
192
+ }
193
+
194
+ // The static confinement check happens before the caller ever opens the file;
195
+ // a same-account process could still swap a symlink in between. The lstat
196
+ // check immediately before opening, plus O_NOFOLLOW where available, closes
197
+ // that window instead of merely trusting the earlier confinedPath check.
198
+ async function readNoFollow(target) {
199
+ return withVerifiedParent(target, async () => {
200
+ await assertNotSymlink(target);
201
+ const handle = await fs.open(target, constants.O_RDONLY | noFollowFlag);
202
+ try {
203
+ const opened = await handle.stat();
204
+ const current = await fs.lstat(target);
205
+ if (!opened.isFile() || current.isSymbolicLink() || !sameIdentity(opened, current)) {
206
+ throw new Error('Gofer credential path must be a stable regular file.');
207
+ }
208
+ return await handle.readFile('utf8');
209
+ } finally { await handle.close(); }
210
+ });
211
+ }
212
+
213
+ async function writeNoFollow(target, content, mode) {
214
+ return withVerifiedParent(target, async () => {
215
+ await assertNotSymlink(target);
216
+ const handle = await fs.open(target,
217
+ constants.O_WRONLY | constants.O_CREAT | constants.O_TRUNC | noFollowFlag, mode);
218
+ try {
219
+ const opened = await handle.stat();
220
+ const current = await fs.lstat(target);
221
+ if (!opened.isFile() || current.isSymbolicLink() || !sameIdentity(opened, current)) {
222
+ throw new Error('Gofer credential path must be a stable regular file.');
223
+ }
224
+ await handle.writeFile(content);
225
+ await handle.sync();
226
+ } finally { await handle.close(); }
227
+ });
228
+ }
229
+
230
+ async function unlinkNoFollow(target) {
231
+ return withVerifiedParent(target, async () => {
232
+ const before = await fs.lstat(target);
233
+ if (before.isSymbolicLink() || !before.isFile()) {
234
+ throw new Error('Gofer credential path must be a regular file.');
235
+ }
236
+ await fs.unlink(target);
237
+ });
238
+ }
239
+
240
+ async function ensurePrivateParent(target) {
241
+ const parent = path.dirname(target);
242
+ const grandparent = path.dirname(parent);
243
+ const grandparentHandle = await fs.open(grandparent,
244
+ constants.O_RDONLY | (constants.O_DIRECTORY ?? 0) | noFollowFlag);
245
+ const openedGrandparent = await grandparentHandle.stat();
246
+ try {
247
+ const currentGrandparent = await fs.lstat(grandparent);
248
+ if (!openedGrandparent.isDirectory() || currentGrandparent.isSymbolicLink() ||
249
+ !sameIdentity(openedGrandparent, currentGrandparent)) {
250
+ throw new Error('Gofer credential parent directory changed during setup.');
251
+ }
252
+ await fs.mkdir(parent, { mode: 0o700 }).catch((error) => {
253
+ if (error?.code !== 'EEXIST') throw error;
254
+ });
255
+ const parentHandle = await fs.open(parent,
256
+ constants.O_RDONLY | (constants.O_DIRECTORY ?? 0) | noFollowFlag);
257
+ try {
258
+ const openedParent = await parentHandle.stat();
259
+ const [parentCurrent, grandparentAfter] = await Promise.all([
260
+ fs.lstat(parent),
261
+ fs.lstat(grandparent),
262
+ ]);
263
+ if (!openedParent.isDirectory() || parentCurrent.isSymbolicLink() ||
264
+ !sameIdentity(openedParent, parentCurrent) || grandparentAfter.isSymbolicLink() ||
265
+ !sameIdentity(openedGrandparent, grandparentAfter)) {
266
+ throw new Error('Gofer credential parent directory changed during setup.');
267
+ }
268
+ await parentHandle.chmod(0o700);
269
+ } finally {
270
+ await parentHandle.close();
271
+ }
272
+ } finally {
273
+ await grandparentHandle.close();
274
+ }
275
+ }
276
+
277
+ async function readSecretFile(secretPath) {
278
+ if (!(await existingFile(secretPath))) return '';
279
+ const match = (await readNoFollow(secretPath)).match(/^TYPESAFE_API_KEY=([^\r\n]+)$/m);
280
+ return match?.[1]?.trim() || '';
281
+ }
282
+
283
+ async function writePolicyEnabled(workspace, enabled) {
284
+ for (const relativePath of POLICY_RELATIVE_PATHS) {
285
+ const policyPath = await confinedPath(workspace, relativePath);
286
+ // Older Gofer workspaces have only the semantic-review policy. Keep
287
+ // connect/disconnect compatible until workspace bootstrap adds the
288
+ // reviewed-learning policy.
289
+ if (!(await existingFile(policyPath))) continue;
290
+ const current = JSON.parse(await readNoFollow(policyPath));
291
+ current.enabled = enabled;
292
+ await writeNoFollow(policyPath, `${JSON.stringify(current, null, 2)}\n`, 0o600);
293
+ }
294
+ }
295
+
296
+ async function promptForKey() {
297
+ if (!process.stdin.isTTY) throw new Error('Set TYPESAFE_API_KEY, then run --connect from an interactive terminal.');
298
+ process.stdout.write('TypeSafe API key: ');
299
+ const key = await new Promise((resolve, reject) => {
300
+ let value = '';
301
+ process.stdin.setRawMode(true);
302
+ process.stdin.resume();
303
+ process.stdin.on('data', (chunk) => {
304
+ const character = chunk.toString('utf8');
305
+ if (character === '\r' || character === '\n') {
306
+ process.stdin.setRawMode(false);
307
+ process.stdin.pause();
308
+ process.stdout.write('\n');
309
+ resolve(value);
310
+ } else if (character === '\u0003') {
311
+ process.stdin.setRawMode(false);
312
+ reject(new Error('Credential setup cancelled.'));
313
+ } else if (character === '\u007f') {
314
+ value = value.slice(0, -1);
315
+ } else {
316
+ value += character;
317
+ }
318
+ });
319
+ });
320
+ return String(key).trim();
321
+ }
322
+
323
+ export async function credentialStatus({ workspace = process.cwd(), env = process.env, keychain = macOSKeychain } = {}) {
324
+ const { source } = await resolveApiKey({ workspace, env, keychain });
325
+ return {
326
+ configured: source !== 'none',
327
+ source,
328
+ secretPath: source === 'project_secret_file' ? SECRET_RELATIVE_PATH : null,
329
+ sharedAcrossLocalWorkspaces: source === 'macos_keychain',
330
+ };
331
+ }
332
+
333
+ export async function resolveApiKey({ workspace = process.cwd(), env = process.env, keychain = macOSKeychain } = {}) {
334
+ const environmentKey = String(env.TYPESAFE_API_KEY || '').trim();
335
+ if (environmentKey) return { apiKey: environmentKey, source: 'environment' };
336
+ const fileKey = await readSecretFile(await confinedPath(workspace, SECRET_RELATIVE_PATH));
337
+ if (fileKey) return { apiKey: fileKey, source: 'project_secret_file' };
338
+ if (env.GOFER_DISABLE_SHARED_CREDENTIALS !== '1') {
339
+ const sharedKey = String(await keychain.read()).trim();
340
+ if (sharedKey) return { apiKey: sharedKey, source: 'macos_keychain' };
341
+ }
342
+ return { apiKey: '', source: 'none' };
343
+ }
344
+
345
+ export async function sharedCredentialConfigured({ keychain = macOSKeychain } = {}) {
346
+ return keychain.has();
347
+ }
348
+
349
+ export async function requestTypeSafeEvaluation({ workspace, env = process.env, fetchImpl = globalThis.fetch, policy, projection, rubric, keychain = macOSKeychain }) {
350
+ const { apiKey, source } = await resolveApiKey({ workspace, env, keychain });
351
+ if (!apiKey) return { status: 'not_configured', networkCalled: false };
352
+ let response;
353
+ try {
354
+ response = await fetchImpl(policy.endpoint, {
355
+ method: 'POST',
356
+ headers: { authorization: `Bearer ${apiKey}`, 'content-type': 'application/json' },
357
+ signal: AbortSignal.timeout(policy.timeoutMs),
358
+ body: JSON.stringify({ model: policy.model, state: JSON.stringify(projection), questions: rubric }),
359
+ });
360
+ } catch (error) {
361
+ return {
362
+ status: 'unavailable',
363
+ networkCalled: true,
364
+ reason: ['AbortError', 'TimeoutError'].includes(error?.name) ? 'timeout' : 'network_error',
365
+ };
366
+ }
367
+ if (!response.ok) return { status: 'unavailable', networkCalled: true, httpStatus: response.status };
368
+ try {
369
+ if (!response.body?.getReader) throw new Error('response body is not streamable');
370
+ const reader = response.body.getReader();
371
+ const chunks = [];
372
+ let bytes = 0;
373
+ while (true) {
374
+ const { done, value } = await reader.read();
375
+ if (done) break;
376
+ bytes += value.byteLength;
377
+ if (bytes > 2 * 1024 * 1024) {
378
+ await reader.cancel('response too large');
379
+ throw new Error('response too large');
380
+ }
381
+ chunks.push(Buffer.from(value));
382
+ }
383
+ const raw = Buffer.concat(chunks, bytes).toString('utf8');
384
+ return { status: 'received', networkCalled: true, credentialSource: source, payload: JSON.parse(raw) };
385
+ } catch {
386
+ return { status: 'unavailable', networkCalled: true, reason: 'invalid_response' };
387
+ }
388
+ }
389
+
390
+ export async function connect({ workspace = process.cwd(), key } = {}) {
391
+ const secretPath = await confinedPath(workspace, SECRET_RELATIVE_PATH);
392
+ const resolvedKey = String(key || process.env.TYPESAFE_API_KEY || '').trim() || await promptForKey();
393
+ if (!resolvedKey) throw new Error('TypeSafe API key cannot be empty.');
394
+ await ensurePrivateParent(secretPath);
395
+ if (await existingFile(secretPath)) await fs.chmod(secretPath, 0o600);
396
+ await writeNoFollow(secretPath, `TYPESAFE_API_KEY=${resolvedKey}\n`, 0o600);
397
+ await fs.chmod(secretPath, 0o600);
398
+ await writePolicyEnabled(workspace, true);
399
+ return { configured: true, source: process.env.TYPESAFE_API_KEY ? 'environment' : 'project_secret_file', secretPath: SECRET_RELATIVE_PATH };
400
+ }
401
+
402
+ export async function connectShared({ workspace = process.cwd(), key, keychain = macOSKeychain } = {}) {
403
+ await assertSafeWorkspaceRoot(workspace);
404
+ const resolvedKey = String(key || process.env.TYPESAFE_API_KEY || '').trim() || await promptForKey();
405
+ if (!resolvedKey) throw new Error('TypeSafe API key cannot be empty.');
406
+ await keychain.write(resolvedKey);
407
+ const stored = String(await keychain.read()).trim();
408
+ if (!stored) throw new Error('macOS Keychain saved no Jev credential.');
409
+ return { configured: true, source: 'macos_keychain', secretPath: null, sharedAcrossLocalWorkspaces: true };
410
+ }
411
+
412
+ export async function disconnect({ workspace = process.cwd() } = {}) {
413
+ const secretPath = await confinedPath(workspace, SECRET_RELATIVE_PATH);
414
+ const existed = await existingFile(secretPath);
415
+ if (existed) await unlinkNoFollow(secretPath);
416
+ await writePolicyEnabled(workspace, false);
417
+ return { removedProjectSecret: existed, environmentStillConfigured: Boolean(process.env.TYPESAFE_API_KEY), secretPath: SECRET_RELATIVE_PATH };
418
+ }
419
+
420
+ export async function disconnectShared({ workspace = process.cwd(), keychain = macOSKeychain } = {}) {
421
+ await assertSafeWorkspaceRoot(workspace);
422
+ const removed = await keychain.remove();
423
+ return { removedSharedCredential: removed, source: 'macos_keychain', sharedAcrossLocalWorkspaces: false };
424
+ }
425
+
426
+ async function main() {
427
+ const { action, scope } = parseArgs(process.argv.slice(2));
428
+ const result = action === 'status' ? await credentialStatus()
429
+ : action === 'connect' && scope === 'shared' ? await connectShared()
430
+ : action === 'disconnect' && scope === 'shared' ? await disconnectShared()
431
+ : action === 'connect' ? await connect() : await disconnect();
432
+ process.stdout.write(`${JSON.stringify(result)}\n`);
433
+ }
434
+
435
+ if (import.meta.url === `file://${process.argv[1]}`) main().catch((error) => { process.stderr.write(`${error.message}\n`); process.exitCode = 1; });