@orkastery/cli 0.2.0 → 0.4.1

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 (257) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +86 -65
  3. package/adapters/README.md +30 -15
  4. package/adapters/claude-code/.claude-plugin/plugin.json +11 -5
  5. package/adapters/claude-code/README.md +110 -8
  6. package/adapters/claude-code/commands/check.md +4 -3
  7. package/adapters/claude-code/commands/goal.md +3 -2
  8. package/adapters/claude-code/commands/master.md +3 -2
  9. package/adapters/claude-code/commands/onboarding.md +21 -0
  10. package/adapters/claude-code/commands/ork.md +99 -27
  11. package/adapters/claude-code/hooks/hooks.json +6 -1
  12. package/adapters/claude-code/hooks/ork-guard.js +1 -1
  13. package/adapters/claude-code/hooks/ork-sensor.js +66 -0
  14. package/adapters/codex/skills/ork/SKILL.md +57 -0
  15. package/adapters/hermes/README.md +161 -0
  16. package/adapters/hermes/bin/ork-abrir-thread.sh +2 -0
  17. package/adapters/hermes/bin/ork-brain.sh +4 -0
  18. package/adapters/hermes/bin/ork-hitl-answer.py +82 -0
  19. package/adapters/hermes/bin/ork-maestro.sh +6 -0
  20. package/adapters/hermes/bin/ork-master-enviar.py +84 -0
  21. package/adapters/hermes/bin/ork-pulse-enviar.py +47 -0
  22. package/adapters/hermes/hermes.plugin.json +24 -4
  23. package/adapters/hermes/hitl-ingress/__init__.py +356 -0
  24. package/adapters/hermes/hitl-ingress/plugin.yaml +4 -0
  25. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +75 -22
  26. package/adapters/openclaw/README.md +136 -27
  27. package/adapters/openclaw/bin/ork-brain.sh +4 -0
  28. package/adapters/openclaw/construir.sh +19 -0
  29. package/adapters/openclaw/dist/hitl-ingress.js +199 -0
  30. package/adapters/openclaw/dist/index.js +437 -0
  31. package/adapters/openclaw/openclaw.plugin.json +39 -134
  32. package/adapters/openclaw/package.json +26 -0
  33. package/adapters/openclaw/src/hitl-ingress.ts +180 -0
  34. package/adapters/openclaw/src/index.ts +460 -0
  35. package/adapters/openclaw/src/tipos-openclaw.d.ts +58 -0
  36. package/adapters/openclaw/tsconfig.json +15 -0
  37. package/assets/docs/markdownlint-cli2.jsonc +22 -0
  38. package/assets/docs/padroes/documentacao-de-produto.md +133 -0
  39. package/assets/docs/padroes/roadmap-de-produto.md +98 -0
  40. package/assets/docs/produto/README.md +14 -0
  41. package/assets/docs/produto/_modelo-feature.md +59 -0
  42. package/assets/docs/roadmap/README.md +14 -0
  43. package/assets/docs/roadmap/_modelo-item.md +73 -0
  44. package/assets/orkmind-native-schema.json +32 -0
  45. package/assets/orkmind_bridge.py +357 -0
  46. package/assets/orkmind_fixture.py +67 -0
  47. package/assets/orkmind_prospective.py +138 -0
  48. package/assets/reference-tariffs-i07.json +23 -0
  49. package/dist/adapters/claude-bg.js +488 -39
  50. package/dist/adapters/codex-controller-sensor.js +449 -0
  51. package/dist/adapters/codex-controller-worker.js +361 -0
  52. package/dist/adapters/codex-controller.js +252 -0
  53. package/dist/adapters/codex-events.js +205 -0
  54. package/dist/adapters/codex-question.js +26 -0
  55. package/dist/adapters/codex-runner.js +133 -0
  56. package/dist/adapters/codex.js +394 -0
  57. package/dist/agents-md.js +84 -0
  58. package/dist/auditoria.js +12 -9
  59. package/dist/auditrun.js +5 -4
  60. package/dist/board.js +174 -23
  61. package/dist/branch-de-estado.js +136 -0
  62. package/dist/canarios-hitl.js +177 -0
  63. package/dist/canarios-i43.js +543 -0
  64. package/dist/canarios-pulse.js +147 -0
  65. package/dist/canarios-sensores.js +129 -0
  66. package/dist/canarios.js +111 -2
  67. package/dist/catalogo.js +9 -0
  68. package/dist/ci.js +223 -0
  69. package/dist/ciclos.js +2 -1
  70. package/dist/claim-lint.js +64 -0
  71. package/dist/claims.js +60 -0
  72. package/dist/company-brain-capture.js +195 -0
  73. package/dist/company-brain-cli.js +123 -0
  74. package/dist/company-brain-client.js +61 -0
  75. package/dist/company-brain-contract.js +166 -0
  76. package/dist/company-brain-journal.js +192 -0
  77. package/dist/company-brain-mcp.js +33 -0
  78. package/dist/company-brain-migration.js +60 -0
  79. package/dist/company-brain-source.js +177 -0
  80. package/dist/company-brain-worker.js +18 -0
  81. package/dist/conducao-texto.js +61 -0
  82. package/dist/conducao.js +876 -0
  83. package/dist/contrato-publico.js +39 -0
  84. package/dist/creation-operation-store.js +251 -0
  85. package/dist/creation-operation.js +148 -0
  86. package/dist/decisao-autonoma.js +183 -0
  87. package/dist/delegation.js +79 -0
  88. package/dist/demo.js +120 -0
  89. package/dist/docs.js +828 -0
  90. package/dist/doctor.js +184 -25
  91. package/dist/entrega-pr.js +117 -0
  92. package/dist/escopo-escrita.js +71 -0
  93. package/dist/estado-thread.js +222 -0
  94. package/dist/evalrunner.js +12 -0
  95. package/dist/fabrica-estado.js +329 -0
  96. package/dist/fabrica-publicar.js +76 -0
  97. package/dist/fix.js +22 -1
  98. package/dist/gates.js +59 -11
  99. package/dist/handoff.js +39 -23
  100. package/dist/hitl-canais.js +333 -0
  101. package/dist/hitl-classificacao.js +131 -0
  102. package/dist/hitl-contract.js +465 -0
  103. package/dist/hitl-estado.js +136 -0
  104. package/dist/hitl-gates.js +554 -0
  105. package/dist/hitl-ingress-receipt.js +382 -0
  106. package/dist/hitl-local-atestado.js +57 -0
  107. package/dist/hitl-local-receipt.js +328 -0
  108. package/dist/hitl-local.js +143 -0
  109. package/dist/hitl-lock.js +139 -0
  110. package/dist/hitl-lote.js +223 -0
  111. package/dist/hitl-native-offer.js +97 -0
  112. package/dist/hitl-native.js +65 -0
  113. package/dist/hitl-presentation.js +209 -0
  114. package/dist/hitl-public-receipt.js +176 -0
  115. package/dist/hitl-resumo.js +209 -0
  116. package/dist/hitl-sessions.js +475 -0
  117. package/dist/hitl.js +711 -0
  118. package/dist/horario.js +269 -0
  119. package/dist/hosts.js +198 -22
  120. package/dist/index.js +1741 -94
  121. package/dist/indice.js +99 -0
  122. package/dist/init.js +28 -3
  123. package/dist/integracoes-locais.js +17 -0
  124. package/dist/leases.js +65 -21
  125. package/dist/ledger-stats.js +272 -0
  126. package/dist/ledger.js +109 -2
  127. package/dist/licoes.js +221 -0
  128. package/dist/liveness.js +218 -0
  129. package/dist/maestro-actions.js +51 -0
  130. package/dist/maestro-authority.js +152 -0
  131. package/dist/maestro-cli.js +97 -0
  132. package/dist/maestro-contract.js +55 -0
  133. package/dist/maestro-discovery.js +132 -0
  134. package/dist/maestro-runtime.js +268 -0
  135. package/dist/maestro-snapshot.js +86 -0
  136. package/dist/maestro-sources.js +224 -0
  137. package/dist/manifest.js +165 -6
  138. package/dist/maquina.js +102 -0
  139. package/dist/master-audit.js +101 -0
  140. package/dist/master-batch.js +43 -0
  141. package/dist/master-digest.js +149 -0
  142. package/dist/master-migracao.js +155 -0
  143. package/dist/master.js +361 -77
  144. package/dist/mcp-artifacts.js +234 -0
  145. package/dist/mcp-git.js +433 -0
  146. package/dist/mcp-install.js +310 -0
  147. package/dist/mcp-maestro.js +25 -0
  148. package/dist/mcp-server.js +469 -0
  149. package/dist/mcp-ship.js +436 -0
  150. package/dist/mcp-verify.js +173 -0
  151. package/dist/memoria-humana.js +207 -0
  152. package/dist/memoria.js +314 -78
  153. package/dist/memory-migration.js +279 -0
  154. package/dist/memory-prospective.js +148 -0
  155. package/dist/modos-migracao.js +191 -0
  156. package/dist/modos.js +151 -15
  157. package/dist/monitor-lock.js +110 -0
  158. package/dist/objective.js +449 -0
  159. package/dist/ocupacao.js +267 -0
  160. package/dist/onboarding.js +303 -0
  161. package/dist/orkmind.js +389 -90
  162. package/dist/orquestracao.js +96 -69
  163. package/dist/phase.js +612 -151
  164. package/dist/playbook-capabilities.js +150 -0
  165. package/dist/playbook-contracts.js +188 -0
  166. package/dist/policies.js +72 -0
  167. package/dist/portfolio-context.js +61 -0
  168. package/dist/portfolio.js +180 -0
  169. package/dist/preflight.js +207 -0
  170. package/dist/process-audit.js +112 -0
  171. package/dist/project-state.js +93 -0
  172. package/dist/prompts.js +25 -5
  173. package/dist/prova-minima.js +112 -0
  174. package/dist/pulse-cadencia.js +163 -0
  175. package/dist/pulse-consentimento.js +260 -0
  176. package/dist/pulse-delivery.js +323 -0
  177. package/dist/pulse-resposta.js +542 -0
  178. package/dist/pulse.js +262 -0
  179. package/dist/ratelimit.js +35 -2
  180. package/dist/recall.js +80 -3
  181. package/dist/redacao-saida.js +45 -0
  182. package/dist/redacao-url.js +66 -0
  183. package/dist/retry.js +640 -118
  184. package/dist/roadmap-reservas.js +243 -0
  185. package/dist/runtime-ambiente.js +38 -0
  186. package/dist/runtime-context.js +215 -0
  187. package/dist/runtime-profiles.js +869 -0
  188. package/dist/runtimes.js +103 -0
  189. package/dist/sandbox.js +9 -0
  190. package/dist/session-events.js +203 -0
  191. package/dist/session-watcher-claude.js +637 -0
  192. package/dist/session-watcher.js +700 -0
  193. package/dist/sessoes-adopt.js +154 -0
  194. package/dist/sessoes-inventario.js +159 -0
  195. package/dist/sessoes.js +16 -35
  196. package/dist/setup.js +691 -0
  197. package/dist/ship.js +168 -19
  198. package/dist/slug.js +1 -1
  199. package/dist/thread-close.js +115 -0
  200. package/dist/thread.js +142 -28
  201. package/dist/tokens.js +1 -1
  202. package/dist/util.js +4 -2
  203. package/dist/verify-sandbox.js +265 -0
  204. package/dist/verify.js +270 -25
  205. package/dist/versao.js +60 -0
  206. package/dist/worktree.js +31 -2
  207. package/dist/write-activation.js +291 -0
  208. package/dist/yaml.js +5 -1
  209. package/eval/casos/master-metrics.json +1 -1
  210. package/eval/casos/onboarding.json +102 -0
  211. package/eval/casos/orkastery-bootstrap.json +37 -3
  212. package/eval/casos/scope-check-capability-map.json +45 -7
  213. package/eval/casos/ship-release.json +3 -3
  214. package/eval/fixtures/b0-slug-e-modos/caso.json +35 -22
  215. package/eval/fixtures/b2-master-log/caso.json +1 -1
  216. package/eval/fixtures/fx-adapter-editado-detectado/caso.json +19 -0
  217. package/eval/fixtures/fx-auto-quiet/caso.json +11 -0
  218. package/eval/fixtures/fx-blanket-approve/caso.json +10 -0
  219. package/eval/fixtures/fx-check-runtime-cruzado/caso.json +20 -0
  220. package/eval/fixtures/fx-codex-dry/caso.json +18 -0
  221. package/eval/fixtures/fx-donewhen-executavel/caso.json +15 -0
  222. package/eval/fixtures/fx-estado-dividido/caso.json +15 -0
  223. package/eval/fixtures/fx-fase-orfa/caso.json +116 -0
  224. package/eval/fixtures/fx-happy/caso.json +6 -4
  225. package/eval/fixtures/fx-hitl-latency/caso.json +20 -0
  226. package/eval/fixtures/fx-indice-reversao/caso.json +25 -0
  227. package/eval/fixtures/fx-listagem-abertas/caso.json +16 -0
  228. package/eval/fixtures/fx-maestro-bootstrap/caso.json +21 -0
  229. package/eval/fixtures/fx-modo-aposentado-escritor/caso.json +21 -0
  230. package/eval/fixtures/fx-modo-aposentado-leitor/caso.json +16 -0
  231. package/eval/fixtures/fx-objective-oscillation/caso.json +14 -0
  232. package/eval/fixtures/fx-omnicanal/caso.json +17 -0
  233. package/eval/fixtures/fx-sensores-runtime/caso.json +17 -0
  234. package/monitor/company-brain.cjs +17 -0
  235. package/monitor/pulse-scope.cjs +45 -0
  236. package/monitor/pulse.cron +18 -0
  237. package/monitor/varredura-pulse.sh +27 -0
  238. package/package.json +28 -7
  239. package/references/definition-of-done.md +2 -2
  240. package/schemas/claims.schema.json +25 -0
  241. package/schemas/company-brain.schema.json +1158 -0
  242. package/schemas/creation-operation.schema.json +365 -0
  243. package/schemas/maestro-snapshot.schema.json +2716 -0
  244. package/skills/README.md +3 -3
  245. package/skills/core/onboarding/SKILL.md +50 -0
  246. package/skills/core/orkastery-bootstrap/SKILL.md +95 -65
  247. package/skills/core/thread-state/SKILL.md +3 -1
  248. package/skills/governance/decision-triage/SKILL.md +4 -4
  249. package/skills/governance/narrative-guardian/SKILL.md +1 -1
  250. package/skills/governance/roadmap-keeper/SKILL.md +1 -1
  251. package/skills/governance/scope-check-capability-map/SKILL.md +17 -7
  252. package/skills/observability/thread-tracing/SKILL.md +1 -1
  253. package/skills/phases/check-quality/SKILL.md +2 -2
  254. package/skills/phases/goal-definition/SKILL.md +1 -1
  255. package/skills/phases/master-metrics/SKILL.md +9 -7
  256. package/skills/phases/plan-specification/SKILL.md +1 -1
  257. package/skills/phases/ship-release/SKILL.md +1 -1
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.REMOTO_PADRAO = exports.BRANCH_DE_RESERVAS = exports.CONTRATO_RESERVA = void 0;
37
+ exports.exigirItem = exigirItem;
38
+ exports.quemSouEu = quemSouEu;
39
+ exports.reservasLocais = reservasLocais;
40
+ exports.listarReservas = listarReservas;
41
+ exports.painelEmMarkdown = painelEmMarkdown;
42
+ exports.pegarItem = pegarItem;
43
+ exports.soltarItem = soltarItem;
44
+ exports.textoDasReservas = textoDasReservas;
45
+ /**
46
+ * I-47: reservas de item do roadmap entre maquinas, como documentacao em codigo.
47
+ *
48
+ * Mais de um computador (ou builder) trabalha no mesmo repositorio. Sem reserva, dois pegam o
49
+ * mesmo item e so descobrem no PR. A reserva e um arquivo por item (`reservas/RM-042.json`,
50
+ * contrato `ork.roadmap-reserva/v1`) numa branch propria, `ork/roadmap-reservas`, ao lado de um
51
+ * `RESERVAS.md` legivel no GitHub. Ela nao passa por PR nem por CI e nao mexe na `main`.
52
+ *
53
+ * A atomicidade vem do proprio git: a nova versao da branch e um commit em cima da ponta lida, e
54
+ * o push nunca e forcado. Se outra maquina gravou antes, o push e recusado, a leitura e refeita e
55
+ * a regra roda de novo sobre o estado novo. O primeiro push vence; o segundo ve a reserva do
56
+ * primeiro e recusa com `roadmap.reservado`, dizendo com quem esta o item.
57
+ *
58
+ * Nada aqui toca a arvore de trabalho nem o indice do repositorio: blobs, arvore e commit sao
59
+ * montados com um indice temporario, e a branch local de reservas nunca e criada. A mecanica e a
60
+ * de `branch-de-estado.ts`, a mesma do estado compartilhado da fabrica (I-51).
61
+ */
62
+ const fs = __importStar(require("node:fs"));
63
+ const os = __importStar(require("node:os"));
64
+ const path = __importStar(require("node:path"));
65
+ const branch_de_estado_1 = require("./branch-de-estado");
66
+ const horario_1 = require("./horario");
67
+ const maquina_1 = require("./maquina");
68
+ const util_1 = require("./util");
69
+ exports.CONTRATO_RESERVA = 'ork.roadmap-reserva/v1';
70
+ exports.BRANCH_DE_RESERVAS = 'ork/roadmap-reservas';
71
+ exports.REMOTO_PADRAO = 'origin';
72
+ const DIR = 'reservas';
73
+ const PAINEL = 'RESERVAS.md';
74
+ const TENTATIVAS = 5;
75
+ const ITEM = /^RM-\d{3}$/;
76
+ const PREFIXO = 'roadmap';
77
+ /** O item precisa existir no roadmap do projeto (`docs/roadmap/RM-NNN-*.md`). */
78
+ function exigirItem(raiz, item) {
79
+ const id = item.trim().toUpperCase();
80
+ if (!ITEM.test(id))
81
+ throw new Error(`roadmap.item: "${item}" nao e um item do roadmap (esperado RM-NNN)`);
82
+ const dir = path.join(raiz, 'docs', 'roadmap');
83
+ const doItem = (f) => path.basename(f).startsWith(`${id}-`) && f.endsWith('.md');
84
+ const naArvore = fs.existsSync(dir) && fs.readdirSync(dir).some(doItem);
85
+ // O checkout pode estar numa branch antiga, sem o item: vale tambem o que a main ja tem.
86
+ const naBase = !naArvore && ['main', 'origin/main'].some((ref) => (0, branch_de_estado_1.git)(raiz, ['ls-tree', '--name-only', ref, '--', 'docs/roadmap/']).stdout.split('\n').some(doItem));
87
+ if (!naArvore && !naBase)
88
+ throw new Error(`roadmap.item: ${id} nao existe em docs/roadmap`);
89
+ return id;
90
+ }
91
+ /** Quem esta pegando: `--por`, senao o `user.name` do git, senao o usuario do sistema. */
92
+ function quemSouEu(raiz, opcoes = {}) {
93
+ const doGit = (0, branch_de_estado_1.git)(raiz, ['config', 'user.name']).stdout.trim();
94
+ const por = (opcoes.por ?? '').trim() || doGit || os.userInfo().username;
95
+ return { por, maquina: (0, maquina_1.nomeDaMaquina)(opcoes.maquina) };
96
+ }
97
+ /** Traz a ponta da branch de reservas. `null` quando ela ainda nao existe no remoto. */
98
+ function buscar(raiz, remoto) {
99
+ return (0, branch_de_estado_1.buscarBranch)(raiz, remoto, exports.BRANCH_DE_RESERVAS, PREFIXO);
100
+ }
101
+ function lerDaPonta(raiz, ponta) {
102
+ return (0, branch_de_estado_1.jsonsDaPonta)(raiz, ponta, DIR, PREFIXO)
103
+ .filter((r) => r.contrato === exports.CONTRATO_RESERVA)
104
+ .sort((a, b) => a.item.localeCompare(b.item));
105
+ }
106
+ /** As reservas da ultima copia lida nesta maquina, sem rede (I-51: o retrato da fabrica usa). */
107
+ function reservasLocais(raiz, remoto = exports.REMOTO_PADRAO) {
108
+ try {
109
+ return lerDaPonta(raiz, (0, branch_de_estado_1.pontaLocal)(raiz, remoto, exports.BRANCH_DE_RESERVAS));
110
+ }
111
+ catch {
112
+ return [];
113
+ }
114
+ }
115
+ /** `ork roadmap reservas`: quem esta com cada item, lido do remoto (ou da ultima copia, sem rede). */
116
+ function listarReservas(raiz, opcoes = {}) {
117
+ const { ponta, atualizado } = buscar(raiz, opcoes.remoto ?? exports.REMOTO_PADRAO);
118
+ return { reservas: lerDaPonta(raiz, ponta), atualizado, ponta };
119
+ }
120
+ /** O `RESERVAS.md` da branch: a mesma lista, para quem abre o GitHub. */
121
+ function painelEmMarkdown(reservas) {
122
+ const linhas = [
123
+ '# Reservas do roadmap',
124
+ '',
125
+ 'Quem está com cada item agora. Gerado pelo `ork roadmap pegar` e pelo `ork roadmap soltar`;',
126
+ 'não edite à mão. Antes de começar um item: `ork roadmap reservas`.',
127
+ '',
128
+ ];
129
+ if (reservas.length === 0)
130
+ return [...linhas, 'Nenhum item reservado.', ''].join('\n');
131
+ linhas.push('| Item | Com quem | Máquina | Thread | Desde | Nota |', '| --- | --- | --- | --- | --- | --- |');
132
+ for (const r of reservas) {
133
+ linhas.push(`| ${r.item} | ${r.por} | ${r.maquina} | ${r.thread ?? '—'} | ${(0, horario_1.formatarDataHora)(r.desdeEm)} | ${r.nota ?? '—'} |`);
134
+ }
135
+ return [...linhas, '', (0, horario_1.legendaDoFuso)(), ''].join('\n');
136
+ }
137
+ /** Grava a reserva (ou a remocao dela) e o painel numa versao nova da branch. Recusa volta `false`. */
138
+ function gravar(raiz, remoto, ponta, mudanca, todas, mensagem) {
139
+ return (0, branch_de_estado_1.gravarNaBranch)(raiz, remoto, exports.BRANCH_DE_RESERVAS, ponta, [
140
+ { caminho: `${DIR}/${mudanca.item}.json`, conteudo: mudanca.reserva ? JSON.stringify(mudanca.reserva, null, 2) + '\n' : null },
141
+ { caminho: PAINEL, conteudo: painelEmMarkdown(todas) },
142
+ ], mensagem, PREFIXO);
143
+ }
144
+ function ehMinha(r, eu) {
145
+ return r.por === eu.por && r.maquina === eu.maquina;
146
+ }
147
+ function descrever(r) {
148
+ return `${r.item} esta com ${r.por} em ${r.maquina} desde ${(0, horario_1.formatarDataHora)(r.desdeEm)}` +
149
+ (r.thread ? ` (thread ${r.thread})` : '');
150
+ }
151
+ function exigirMotivo(opcoes) {
152
+ const motivo = (opcoes.motivo ?? '').trim();
153
+ if (!motivo)
154
+ throw new Error('roadmap.forcar: --forcar exige --motivo (tomar a reserva de outra maquina e decisao registrada)');
155
+ return motivo;
156
+ }
157
+ /**
158
+ * `ork roadmap pegar`: reserva o item para esta maquina. Renovar a propria reserva e idempotente
159
+ * (atualiza thread, nota e carimbo); a de outra maquina so sai com `--forcar --motivo`.
160
+ */
161
+ function pegarItem(raiz, item, opcoes = {}) {
162
+ const id = exigirItem(raiz, item);
163
+ const remoto = opcoes.remoto ?? exports.REMOTO_PADRAO;
164
+ const eu = quemSouEu(raiz, opcoes);
165
+ for (let tentativa = 1; tentativa <= TENTATIVAS; tentativa++) {
166
+ const { ponta, atualizado } = buscar(raiz, remoto);
167
+ if (!atualizado)
168
+ throw new Error(`roadmap.sem-remoto: nao consegui ler ${exports.BRANCH_DE_RESERVAS} em ${remoto}; reservar exige rede`);
169
+ const todas = lerDaPonta(raiz, ponta);
170
+ const atual = todas.find((r) => r.item === id) ?? null;
171
+ const quando = opcoes.agora ?? (0, util_1.agora)();
172
+ let acao = 'pegou';
173
+ let tomadaDe;
174
+ if (atual && ehMinha(atual, eu))
175
+ acao = 'renovou';
176
+ else if (atual) {
177
+ if (!opcoes.forcar)
178
+ throw new Error(`roadmap.reservado: ${descrever(atual)}. Escolha outro item ou combine com quem esta nele`);
179
+ tomadaDe = { por: atual.por, maquina: atual.maquina, motivo: exigirMotivo(opcoes) };
180
+ acao = 'tomou';
181
+ }
182
+ const reserva = {
183
+ contrato: exports.CONTRATO_RESERVA, item: id, por: eu.por, maquina: eu.maquina,
184
+ thread: opcoes.thread !== undefined ? opcoes.thread : (acao === 'renovou' ? atual.thread : null),
185
+ nota: opcoes.nota !== undefined ? opcoes.nota : (acao === 'renovou' ? atual.nota : null),
186
+ desdeEm: acao === 'renovou' ? atual.desdeEm : quando,
187
+ atualizadaEm: quando,
188
+ ...(tomadaDe ? { tomadaDe } : {}),
189
+ };
190
+ const novas = [...todas.filter((r) => r.item !== id), reserva].sort((a, b) => a.item.localeCompare(b.item));
191
+ const mensagem = acao === 'tomou'
192
+ ? `reserva: ${id} tomada por ${eu.por} em ${eu.maquina} (de ${tomadaDe.por} em ${tomadaDe.maquina}): ${tomadaDe.motivo}`
193
+ : `reserva: ${id} ${acao === 'renovou' ? 'renovada' : 'pega'} por ${eu.por} em ${eu.maquina}`;
194
+ const commit = gravar(raiz, remoto, ponta, { item: id, reserva }, novas, mensagem);
195
+ if (commit)
196
+ return { acao, item: id, reserva, commit, tentativas: tentativa };
197
+ }
198
+ throw new Error(`roadmap.concorrencia: ${TENTATIVAS} pushes recusados seguidos; tente de novo em instantes`);
199
+ }
200
+ /** `ork roadmap soltar`: devolve o item. Soltar a reserva de outra maquina exige `--forcar --motivo`. */
201
+ function soltarItem(raiz, item, opcoes = {}) {
202
+ const id = exigirItem(raiz, item);
203
+ const remoto = opcoes.remoto ?? exports.REMOTO_PADRAO;
204
+ const eu = quemSouEu(raiz, opcoes);
205
+ for (let tentativa = 1; tentativa <= TENTATIVAS; tentativa++) {
206
+ const { ponta, atualizado } = buscar(raiz, remoto);
207
+ if (!atualizado)
208
+ throw new Error(`roadmap.sem-remoto: nao consegui ler ${exports.BRANCH_DE_RESERVAS} em ${remoto}; soltar exige rede`);
209
+ const todas = lerDaPonta(raiz, ponta);
210
+ const atual = todas.find((r) => r.item === id);
211
+ if (!atual)
212
+ return { acao: 'nada', item: id, reserva: null, commit: null, tentativas: tentativa };
213
+ let motivo = '';
214
+ if (!ehMinha(atual, eu)) {
215
+ if (!opcoes.forcar)
216
+ throw new Error(`roadmap.reservado: ${descrever(atual)}; so quem pegou solta, ou --forcar --motivo`);
217
+ motivo = `: ${exigirMotivo(opcoes)}`;
218
+ }
219
+ const restantes = todas.filter((r) => r.item !== id);
220
+ const mensagem = `reserva: ${id} solta por ${eu.por} em ${eu.maquina}${motivo}`;
221
+ const commit = gravar(raiz, remoto, ponta, { item: id, reserva: null }, restantes, mensagem);
222
+ if (commit)
223
+ return { acao: 'soltou', item: id, reserva: atual, commit, tentativas: tentativa };
224
+ }
225
+ throw new Error(`roadmap.concorrencia: ${TENTATIVAS} pushes recusados seguidos; tente de novo em instantes`);
226
+ }
227
+ /** O texto de `ork roadmap reservas` para o terminal, no fuso do dono. */
228
+ function textoDasReservas(p) {
229
+ const linhas = [];
230
+ if (!p.atualizado)
231
+ linhas.push('AVISO: sem acesso ao remoto; esta e a ultima copia lida nesta maquina.', '');
232
+ if (p.reservas.length === 0) {
233
+ linhas.push('Nenhum item do roadmap reservado.');
234
+ return linhas.join('\n');
235
+ }
236
+ linhas.push('ITEM COM QUEM MAQUINA THREAD DESDE');
237
+ for (const r of p.reservas) {
238
+ linhas.push(`${r.item.padEnd(8)} ${r.por.slice(0, 19).padEnd(19)} ${r.maquina.slice(0, 15).padEnd(15)} ` +
239
+ `${(r.thread ?? '-').slice(0, 18).padEnd(18)} ${(0, horario_1.formatarDataHora)(r.desdeEm)}` + (r.nota ? ` ${r.nota}` : ''));
240
+ }
241
+ linhas.push('', (0, horario_1.legendaDoFuso)());
242
+ return linhas.join('\n');
243
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ENVS_DE_PROVIDER_PAGO = void 0;
4
+ exports.nomesDeProviderAtivos = nomesDeProviderAtivos;
5
+ exports.ambienteDeAssinatura = ambienteDeAssinatura;
6
+ const hitl_public_receipt_1 = require("./hitl-public-receipt");
7
+ /**
8
+ * Lista explícita removida dos runtimes homologados. Nunca registra valores.
9
+ * Não é uma lista de todas as formas de redirecionamento: proxies genéricos,
10
+ * cabeçalhos personalizados e credenciais de outros serviços ficam fora do contrato.
11
+ */
12
+ exports.ENVS_DE_PROVIDER_PAGO = [
13
+ 'ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN', 'ANTHROPIC_BASE_URL',
14
+ 'CLAUDE_CODE_USE_BEDROCK', 'CLAUDE_CODE_USE_VERTEX',
15
+ 'OPENAI_API_KEY', 'OPENAI_BASE_URL', 'OPENROUTER_API_KEY', 'OPENROUTER_BASE_URL',
16
+ 'GEMINI_API_KEY', 'GOOGLE_API_KEY', 'AZURE_OPENAI_API_KEY', 'AZURE_OPENAI_ENDPOINT',
17
+ 'MISTRAL_API_KEY', 'GROQ_API_KEY', 'DEEPSEEK_API_KEY', 'TOGETHER_API_KEY',
18
+ ];
19
+ /** Retrato de presença, sem guardar valores ou credenciais. */
20
+ function nomesDeProviderAtivos(base = process.env) {
21
+ return exports.ENVS_DE_PROVIDER_PAGO.filter(nome => (base[nome] ?? '').trim() !== '');
22
+ }
23
+ /** Copia, sem alterar o ambiente em que as policies ainda precisam ser avaliadas. */
24
+ function ambienteDeAssinatura(base = process.env) {
25
+ const env = { ...base };
26
+ const publicVerifiers = (0, hitl_public_receipt_1.publicHitlVerifiers)(base);
27
+ for (const nome of exports.ENVS_DE_PROVIDER_PAGO)
28
+ delete env[nome];
29
+ // A autoridade de ingresso pertence ao processo do host/núcleo. Um executor
30
+ // de código não recebe chaves, bindings ou allowlists de respostas humanas.
31
+ for (const nome of Object.keys(env))
32
+ if (nome.startsWith('ORK_HITL_'))
33
+ delete env[nome];
34
+ delete env[hitl_public_receipt_1.ENV_HITL_VERIFIERS];
35
+ if (publicVerifiers)
36
+ env[hitl_public_receipt_1.ENV_HITL_VERIFIERS] = publicVerifiers;
37
+ return env;
38
+ }
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.novaIdentidadeDeDespacho = novaIdentidadeDeDespacho;
37
+ exports.contextoDoProjeto = contextoDoProjeto;
38
+ exports.validarContextoRuntime = validarContextoRuntime;
39
+ /** Contexto interno opt-in: configuracao M4 existente + catalogo instalado, nunca args do modelo. */
40
+ const fs = __importStar(require("node:fs"));
41
+ const path = __importStar(require("node:path"));
42
+ const node_crypto_1 = require("node:crypto");
43
+ const smol_toml_1 = require("smol-toml");
44
+ const manifest_1 = require("./manifest");
45
+ const thread_1 = require("./thread");
46
+ const hosts_1 = require("./hosts");
47
+ const worktree_1 = require("./worktree");
48
+ const mcp_install_1 = require("./mcp-install");
49
+ const hitl_public_receipt_1 = require("./hitl-public-receipt");
50
+ /** Correlação interna; nenhuma identidade de despacho concede poder de gate. */
51
+ function novaIdentidadeDeDespacho(threadId, fase) {
52
+ return { schema: 'ork.dispatch-identity/v1', dispatchId: (0, node_crypto_1.randomUUID)(), threadId, role: fase === 'CHECK' ? 'reviewer' : 'executor' };
53
+ }
54
+ function objeto(v) {
55
+ if (!v || typeof v !== 'object' || Array.isArray(v))
56
+ throw Error('runtime.context.invalid: objeto esperado');
57
+ return v;
58
+ }
59
+ function dentro(raiz, file) {
60
+ const real = fs.realpathSync(file);
61
+ if (real !== raiz && !real.startsWith(raiz + path.sep))
62
+ throw Error('runtime.context.scope: caminho fora do projeto');
63
+ return real;
64
+ }
65
+ function ler(raiz, file, limite) {
66
+ dentro(raiz, file);
67
+ const fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_NONBLOCK);
68
+ try {
69
+ const st = fs.fstatSync(fd);
70
+ if (!st.isFile() || st.size > limite)
71
+ throw Error('runtime.context.invalid: arquivo invalido');
72
+ const bytes = fs.readFileSync(fd);
73
+ if (bytes.length > limite)
74
+ throw Error('runtime.context.invalid: arquivo excedeu limite');
75
+ return bytes;
76
+ }
77
+ finally {
78
+ fs.closeSync(fd);
79
+ }
80
+ }
81
+ function preparado(raiz) {
82
+ let encontrado;
83
+ for (const host of ['claude-code', 'codex']) {
84
+ const file = path.join(raiz, host === 'codex' ? '.codex/config.toml' : '.mcp.json');
85
+ if (!fs.existsSync(file))
86
+ continue;
87
+ const text = ler(raiz, file, 262144).toString('utf8');
88
+ const config = objeto(host === 'codex' ? (0, smol_toml_1.parse)(text) : JSON.parse(text));
89
+ const chave = host === 'codex' ? 'mcp_servers' : 'mcpServers';
90
+ if (config[chave] === undefined)
91
+ continue;
92
+ const servidores = objeto(config[chave]);
93
+ if (!Object.hasOwn(servidores, 'orkastery'))
94
+ continue;
95
+ const entrada = objeto(servidores.orkastery), padrao = (0, mcp_install_1.configuracaoServidorMcp)(raiz, host);
96
+ const legado = padrao.args.slice(0, -2);
97
+ let transporte = 'github-ssh';
98
+ let argv = entrada.args;
99
+ let permissoesFilho = 'interactive';
100
+ if (Array.isArray(argv) && argv[argv.length - 2] === '--child-permissions') {
101
+ if (!['interactive', 'worktree'].includes(argv[argv.length - 1]))
102
+ throw Error('runtime.context.conflict: perfil de filho invalido');
103
+ permissoesFilho = argv[argv.length - 1];
104
+ argv = argv.slice(0, -2);
105
+ }
106
+ if (JSON.stringify(argv) !== JSON.stringify(legado)) {
107
+ if (!Array.isArray(argv) || argv.length !== padrao.args.length ||
108
+ argv[argv.length - 2] !== '--ship-transport' || !['github-ssh', 'bare-local'].includes(argv[argv.length - 1]))
109
+ throw Error('runtime.context.conflict: MCP Orkastery divergente; transporte invalido ou argumentos extras');
110
+ transporte = argv[argv.length - 1];
111
+ }
112
+ const esperado = (0, mcp_install_1.configuracaoServidorMcp)(raiz, host, undefined, transporte);
113
+ if (entrada.command !== esperado.command || (JSON.stringify(argv) !== JSON.stringify(esperado.args) && JSON.stringify(argv) !== JSON.stringify(legado)))
114
+ throw Error('runtime.context.conflict: MCP Orkastery divergente; repare a instalacao do projeto');
115
+ if (encontrado !== undefined && encontrado.transporteShip !== transporte)
116
+ throw Error('runtime.context.conflict: transportes SHIP divergentes entre hosts');
117
+ if (encontrado !== undefined && encontrado.permissoesFilho !== permissoesFilho)
118
+ throw Error('runtime.context.conflict: perfis de filho divergentes entre hosts');
119
+ encontrado = { ...encontrado, transporteShip: transporte, permissoesFilho, ...(host === 'codex' ? { politicasCodex: entrada } : {}) };
120
+ }
121
+ return encontrado;
122
+ }
123
+ function raizCanonica(projeto) {
124
+ if (!path.isAbsolute(projeto))
125
+ throw Error('runtime.context.invalid: projeto absoluto obrigatorio');
126
+ const raiz = fs.realpathSync(projeto);
127
+ if (raiz !== projeto || fs.realpathSync((0, manifest_1.exigirManifesto)(raiz).raiz) !== raiz)
128
+ throw Error('runtime.context.invalid: raiz canonica do manifesto obrigatoria');
129
+ if (fs.existsSync(path.join(raiz, '.orkastery')))
130
+ dentro(raiz, path.join(raiz, '.orkastery'));
131
+ return raiz;
132
+ }
133
+ /** Projeto sem entrada MCP Orkastery continua com o contrato legado. Nao instala nem altera arquivos. */
134
+ function contextoDoProjeto(projeto, runtime, cwd, threadId) {
135
+ const raiz = raizCanonica(projeto);
136
+ const perfil = preparado(raiz);
137
+ if (!perfil)
138
+ return undefined;
139
+ if (!['claude-bg', 'codex'].includes(runtime))
140
+ throw Error('runtime.context.invalid: runtime desconhecido');
141
+ if (!threadId)
142
+ throw Error('runtime.context.invalid: thread obrigatoria para sessao filha');
143
+ const contexto = { projeto: raiz, host: runtime === 'codex' ? 'codex' : 'claude-code', threadId, transporteShip: perfil.transporteShip, permissoesFilho: perfil.permissoesFilho };
144
+ validarContextoRuntime(contexto, cwd);
145
+ return contexto;
146
+ }
147
+ /** Revalida no receptor do despacho, incluindo bytes instalados e escopo real do cwd. */
148
+ function validarContextoRuntime(contexto, cwd) {
149
+ if (!contexto || !['claude-code', 'codex'].includes(contexto.host))
150
+ throw Error('runtime.context.invalid: host desconhecido');
151
+ if (contexto.transporteShip !== undefined && !['github-ssh', 'bare-local'].includes(contexto.transporteShip))
152
+ throw Error('runtime.context.invalid: transporte desconhecido');
153
+ const raiz = raizCanonica(contexto.projeto);
154
+ if (contexto.permissoesFilho !== undefined && !['interactive', 'worktree'].includes(contexto.permissoesFilho))
155
+ throw Error('runtime.context.invalid: perfil de filho desconhecido');
156
+ const perfil = preparado(raiz);
157
+ if (!perfil)
158
+ throw Error('runtime.context.missing: projeto nao preparado pelo instalador MCP');
159
+ const { transporteShip, permissoesFilho } = perfil;
160
+ if ((contexto.permissoesFilho ?? 'interactive') !== permissoesFilho)
161
+ throw Error('runtime.context.conflict: perfil de filho difere da instalacao');
162
+ if ((contexto.transporteShip ?? 'github-ssh') !== transporteShip)
163
+ throw Error('runtime.context.conflict: transporte SHIP difere da instalacao');
164
+ if (!path.isAbsolute(cwd) || dentro(raiz, cwd) !== cwd)
165
+ throw Error('runtime.context.scope: cwd divergente');
166
+ if (typeof contexto.threadId !== 'string' || !/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$/.test(contexto.threadId))
167
+ throw Error('runtime.context.invalid: identidade da thread invalida');
168
+ if (contexto.identidade && (contexto.identidade.schema !== 'ork.dispatch-identity/v1' ||
169
+ contexto.identidade.threadId !== contexto.threadId || !['executor', 'reviewer'].includes(contexto.identidade.role) ||
170
+ !/^[a-f0-9-]{36}$/.test(contexto.identidade.dispatchId)))
171
+ throw Error('runtime.context.identity');
172
+ dentro(raiz, (0, thread_1.dirThread)(raiz, contexto.threadId));
173
+ const thread = (0, thread_1.lerThread)(raiz, contexto.threadId);
174
+ if (thread.id !== contexto.threadId || fs.realpathSync(thread.worktree ?? raiz) !== cwd)
175
+ throw Error('runtime.context.scope: cwd nao corresponde a thread vinculada');
176
+ if (permissoesFilho === 'worktree') {
177
+ if (thread.status === 'fechada' || !thread.worktree || thread.worktree === raiz || thread.worktree !== cwd ||
178
+ !fs.lstatSync(thread.worktree).isDirectory() || fs.realpathSync(thread.worktree) !== thread.worktree)
179
+ throw Error('runtime.context.worktree: perfil exige thread aberta e worktree fisica propria');
180
+ if (!(0, worktree_1.worktreesDoGit)(raiz).some(w => w.dir === cwd && w.branch === (0, worktree_1.branchDaWorktree)(thread)))
181
+ throw Error('runtime.context.worktree: worktree nao registrada na branch da thread');
182
+ }
183
+ const def = hosts_1.HOSTS[contexto.host];
184
+ const instalacao = path.join(raiz, def.destinoPadrao, def.subdir ?? '');
185
+ let recibo;
186
+ try {
187
+ recibo = objeto(JSON.parse(ler(raiz, path.join(instalacao, 'INSTALADO.json'), 1048576).toString('utf8')));
188
+ }
189
+ catch {
190
+ throw Error('runtime.context.installation: instale/verifique o adaptador do runtime neste projeto');
191
+ }
192
+ if (recibo.contrato !== 'ork.adapter-install/v1' || recibo.host !== contexto.host || !Array.isArray(recibo.arquivos) || recibo.arquivos.length > 512)
193
+ throw Error('runtime.context.installation: recibo instalado invalido');
194
+ const arquivos = new Map();
195
+ for (const item of recibo.arquivos) {
196
+ const a = objeto(item);
197
+ if (typeof a.arquivo !== 'string' || path.isAbsolute(a.arquivo) || a.arquivo.split(/[\\/]/).includes('..') ||
198
+ typeof a.sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(a.sha256) || arquivos.has(a.arquivo))
199
+ throw Error('runtime.context.installation: arquivo do recibo invalido');
200
+ const file = path.join(instalacao, a.arquivo);
201
+ if (!dentro(raiz, file).startsWith(instalacao + path.sep) || (0, node_crypto_1.createHash)('sha256').update(ler(raiz, file, 1048576)).digest('hex') !== a.sha256)
202
+ throw Error('runtime.context.installation: bytes instalados divergentes');
203
+ arquivos.set(a.arquivo, file);
204
+ }
205
+ const bootstrap = arquivos.get('skills/core/orkastery-bootstrap/SKILL.md');
206
+ if (!bootstrap || (contexto.host === 'claude-code' && !arquivos.has('.claude-plugin/plugin.json')))
207
+ throw Error('runtime.context.installation: catalogo ou plugin incompleto');
208
+ // Capacidade derivada do bloco atual, nunca aceita como entrada do modelo.
209
+ const permiteEditarProduto = permissoesFilho === 'worktree' && (0, thread_1.blocoDaThread)(thread, thread.faseAtual).fases.includes('GO');
210
+ const publicVerifiers = (0, hitl_public_receipt_1.publicHitlVerifiers)();
211
+ const servidor = { ...(0, mcp_install_1.configuracaoServidorMcp)(raiz, contexto.host, contexto.threadId, transporteShip, permissoesFilho, contexto.identidade?.dispatchId),
212
+ ...(publicVerifiers ? { env: { [hitl_public_receipt_1.ENV_HITL_VERIFIERS]: publicVerifiers } } : {}),
213
+ ...(contexto.host === 'codex' && permissoesFilho === 'worktree' ? (0, mcp_install_1.politicasFilhoCodex)(perfil.politicasCodex ?? {}) : {}) };
214
+ return { projeto: raiz, instalacao, bootstrap, permissoesFilho, permiteEditarProduto, servidor };
215
+ }