@orkastery/cli 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +87 -0
  3. package/adapters/README.md +22 -0
  4. package/adapters/claude-code/.claude-plugin/marketplace.json +15 -0
  5. package/adapters/claude-code/.claude-plugin/plugin.json +31 -0
  6. package/adapters/claude-code/README.md +102 -0
  7. package/adapters/claude-code/agents/ork-check.md +32 -0
  8. package/adapters/claude-code/agents/ork-go.md +32 -0
  9. package/adapters/claude-code/agents/ork-goal.md +33 -0
  10. package/adapters/claude-code/agents/ork-master.md +32 -0
  11. package/adapters/claude-code/agents/ork-plan.md +32 -0
  12. package/adapters/claude-code/agents/ork-ship.md +32 -0
  13. package/adapters/claude-code/commands/check.md +45 -0
  14. package/adapters/claude-code/commands/go.md +46 -0
  15. package/adapters/claude-code/commands/goal.md +54 -0
  16. package/adapters/claude-code/commands/master.md +42 -0
  17. package/adapters/claude-code/commands/ork.md +37 -0
  18. package/adapters/claude-code/commands/plan.md +47 -0
  19. package/adapters/claude-code/commands/ship.md +45 -0
  20. package/adapters/claude-code/hooks/hooks.json +17 -0
  21. package/adapters/claude-code/hooks/ork-guard.js +130 -0
  22. package/adapters/hermes/README.md +45 -0
  23. package/adapters/hermes/bin/ork-abrir-thread.sh +25 -0
  24. package/adapters/hermes/hermes.plugin.json +21 -0
  25. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +116 -0
  26. package/adapters/openclaw/README.md +63 -0
  27. package/adapters/openclaw/bin/ork-abrir-thread.sh +24 -0
  28. package/adapters/openclaw/openclaw.plugin.json +138 -0
  29. package/dist/adapters/claude-bg.js +308 -0
  30. package/dist/auditoria.js +848 -0
  31. package/dist/auditrun.js +976 -0
  32. package/dist/board.js +314 -0
  33. package/dist/canarios.js +271 -0
  34. package/dist/catalogo.js +124 -0
  35. package/dist/ciclos.js +156 -0
  36. package/dist/claims.js +226 -0
  37. package/dist/divida.js +374 -0
  38. package/dist/doctor.js +246 -0
  39. package/dist/evalrunner.js +458 -0
  40. package/dist/fix.js +450 -0
  41. package/dist/gates.js +92 -0
  42. package/dist/handoff.js +521 -0
  43. package/dist/hosts.js +331 -0
  44. package/dist/index.js +1910 -0
  45. package/dist/init.js +231 -0
  46. package/dist/leases.js +508 -0
  47. package/dist/ledger.js +138 -0
  48. package/dist/manifest.js +255 -0
  49. package/dist/master.js +453 -0
  50. package/dist/memoria.js +773 -0
  51. package/dist/modos.js +220 -0
  52. package/dist/orkmind.js +487 -0
  53. package/dist/orquestracao.js +559 -0
  54. package/dist/phase.js +572 -0
  55. package/dist/policies.js +176 -0
  56. package/dist/prompts.js +406 -0
  57. package/dist/ratelimit.js +179 -0
  58. package/dist/recall.js +252 -0
  59. package/dist/retry.js +917 -0
  60. package/dist/sandbox.js +94 -0
  61. package/dist/sessoes.js +104 -0
  62. package/dist/ship.js +551 -0
  63. package/dist/slug.js +100 -0
  64. package/dist/superficie.js +1347 -0
  65. package/dist/thread.js +333 -0
  66. package/dist/tokens.js +228 -0
  67. package/dist/types.js +20 -0
  68. package/dist/util.js +156 -0
  69. package/dist/verify.js +262 -0
  70. package/dist/worktree.js +576 -0
  71. package/dist/yaml.js +112 -0
  72. package/eval/README.md +85 -0
  73. package/eval/casos/check-quality.json +103 -0
  74. package/eval/casos/code-reviewer.json +102 -0
  75. package/eval/casos/decision-triage.json +103 -0
  76. package/eval/casos/go-implementation.json +103 -0
  77. package/eval/casos/goal-definition.json +103 -0
  78. package/eval/casos/master-metrics.json +103 -0
  79. package/eval/casos/narrative-guardian.json +163 -0
  80. package/eval/casos/orkastery-bootstrap.json +102 -0
  81. package/eval/casos/plan-specification.json +102 -0
  82. package/eval/casos/roadmap-keeper.json +103 -0
  83. package/eval/casos/scope-check-capability-map.json +83 -0
  84. package/eval/casos/security-auditor.json +102 -0
  85. package/eval/casos/ship-release.json +122 -0
  86. package/eval/casos/test-engineer.json +122 -0
  87. package/eval/casos/thread-state.json +82 -0
  88. package/eval/casos/thread-tracing.json +83 -0
  89. package/eval/casos/web-performance-auditor.json +102 -0
  90. package/eval/fixtures/b0-slug-e-modos/caso.json +56 -0
  91. package/eval/fixtures/b2-master-log/caso.json +91 -0
  92. package/eval/fixtures/fx-concurrency/caso.json +15 -0
  93. package/eval/fixtures/fx-hallucination/caso.json +12 -0
  94. package/eval/fixtures/fx-happy/caso.json +16 -0
  95. package/eval/fixtures/fx-schema-drift/caso.json +15 -0
  96. package/eval/fixtures/fx-stale-base/caso.json +12 -0
  97. package/eval/fixtures/fx-wiki-destroy/caso.json +16 -0
  98. package/eval/fixtures/superficie-de-rede/README.md +22 -0
  99. package/eval/fixtures/superficie-de-rede/api-express.js +30 -0
  100. package/eval/fixtures/superficie-de-rede/api_fastapi.py +17 -0
  101. package/eval/fixtures/superficie-de-rede/api_gin.go +18 -0
  102. package/package.json +56 -0
  103. package/references/README.md +25 -0
  104. package/references/code-review-axes.md +82 -0
  105. package/references/definition-of-done.md +74 -0
  106. package/references/performance-checklist.md +53 -0
  107. package/references/security-checklist.md +101 -0
  108. package/references/testing-patterns.md +51 -0
  109. package/skills/README.md +43 -0
  110. package/skills/core/orkastery-bootstrap/SKILL.md +89 -0
  111. package/skills/core/thread-state/SKILL.md +86 -0
  112. package/skills/governance/decision-triage/SKILL.md +65 -0
  113. package/skills/governance/narrative-guardian/SKILL.md +66 -0
  114. package/skills/governance/roadmap-keeper/SKILL.md +60 -0
  115. package/skills/governance/scope-check-capability-map/SKILL.md +61 -0
  116. package/skills/observability/thread-tracing/SKILL.md +63 -0
  117. package/skills/phases/check-quality/SKILL.md +87 -0
  118. package/skills/phases/go-implementation/SKILL.md +70 -0
  119. package/skills/phases/goal-definition/SKILL.md +69 -0
  120. package/skills/phases/master-metrics/SKILL.md +65 -0
  121. package/skills/phases/plan-specification/SKILL.md +67 -0
  122. package/skills/phases/ship-release/SKILL.md +68 -0
  123. package/skills/reviewers/code-reviewer/SKILL.md +61 -0
  124. package/skills/reviewers/security-auditor/SKILL.md +68 -0
  125. package/skills/reviewers/test-engineer/SKILL.md +66 -0
  126. package/skills/reviewers/web-performance-auditor/SKILL.md +63 -0
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ /**
3
+ * Manifesto por projeto (`orkastery.yaml`), com `devmaster.yaml` lido como fallback
4
+ * durante a migracao dos habitos.
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.LIMITE_MANIFESTO_BYTES = exports.DIR_ESTADO = exports.NOME_MANIFESTO_LEGADO = exports.NOME_MANIFESTO = void 0;
41
+ exports.acharRaiz = acharRaiz;
42
+ exports.dirEstado = dirEstado;
43
+ exports.carregarManifesto = carregarManifesto;
44
+ exports.exigirManifesto = exigirManifesto;
45
+ const fs = __importStar(require("node:fs"));
46
+ const path = __importStar(require("node:path"));
47
+ const yaml_1 = require("./yaml");
48
+ const modos_1 = require("./modos");
49
+ const slug_1 = require("./slug");
50
+ const util_1 = require("./util");
51
+ exports.NOME_MANIFESTO = 'orkastery.yaml';
52
+ exports.NOME_MANIFESTO_LEGADO = 'devmaster.yaml';
53
+ exports.DIR_ESTADO = '.orkastery';
54
+ /** Limite duro: o manifesto nao pode virar o novo arquivo de 100 KB. */
55
+ exports.LIMITE_MANIFESTO_BYTES = 16384;
56
+ /** Raiz do projeto: o diretorio que contem o manifesto; senao, a raiz do repositorio git. */
57
+ function acharRaiz(dirInicial = process.cwd()) {
58
+ const porManifesto = (0, util_1.subirAte)(dirInicial, exports.NOME_MANIFESTO);
59
+ if (porManifesto)
60
+ return porManifesto;
61
+ const porLegado = (0, util_1.subirAte)(dirInicial, exports.NOME_MANIFESTO_LEGADO);
62
+ if (porLegado)
63
+ return porLegado;
64
+ const git = (0, util_1.exec)('git', ['rev-parse', '--show-toplevel'], dirInicial);
65
+ if (git.ok)
66
+ return git.stdout.trim();
67
+ return path.resolve(dirInicial);
68
+ }
69
+ /** Caminho do diretorio de estado da raiz informada. */
70
+ function dirEstado(raiz) {
71
+ return path.join(raiz, exports.DIR_ESTADO);
72
+ }
73
+ function texto(v, padrao) {
74
+ return typeof v === 'string' ? v : typeof v === 'number' ? String(v) : padrao;
75
+ }
76
+ function numero(v, padrao) {
77
+ return typeof v === 'number' ? v : typeof v === 'string' && v.trim() !== '' && !isNaN(Number(v)) ? Number(v) : padrao;
78
+ }
79
+ function booleano(v, padrao) {
80
+ return typeof v === 'boolean' ? v : padrao;
81
+ }
82
+ function mapa(v) {
83
+ return v && typeof v === 'object' && !Array.isArray(v) ? v : {};
84
+ }
85
+ /** Le e valida o manifesto. Nunca lanca: erros e avisos voltam na estrutura. */
86
+ function carregarManifesto(dirInicial = process.cwd()) {
87
+ const raiz = acharRaiz(dirInicial);
88
+ const candidatos = [
89
+ { caminho: path.join(raiz, exports.NOME_MANIFESTO), legado: false },
90
+ { caminho: path.join(raiz, exports.NOME_MANIFESTO_LEGADO), legado: true },
91
+ ];
92
+ const achado = candidatos.find((c) => fs.existsSync(c.caminho));
93
+ if (!achado)
94
+ return null;
95
+ const bruto = fs.readFileSync(achado.caminho, 'utf8');
96
+ const erros = [];
97
+ const avisos = [];
98
+ let dados = {};
99
+ try {
100
+ dados = mapa((0, yaml_1.lerYaml)(bruto));
101
+ }
102
+ catch (e) {
103
+ erros.push(e.message);
104
+ }
105
+ const project = mapa(dados.project);
106
+ const board = mapa(dados.board);
107
+ const runtime = mapa(dados.runtime);
108
+ const conduction = mapa(dados.conduction);
109
+ const worktree = mapa(dados.worktree);
110
+ const verify = mapa(dados.verify);
111
+ const concurrency = mapa(dados.concurrency);
112
+ const handoff = mapa(dados.handoff);
113
+ const retry = mapa(dados.retry);
114
+ const memory = mapa(dados.memory);
115
+ const audit = mapa(dados.audit);
116
+ const abbrev = texto(project.abbrev, '');
117
+ const checkAbbrev = (0, slug_1.validarAbbrev)(abbrev);
118
+ if (!checkAbbrev.ok)
119
+ erros.push(checkAbbrev.erro);
120
+ const nomeProjeto = texto(project.name, '');
121
+ if (!nomeProjeto)
122
+ erros.push('project.name ausente no manifesto');
123
+ const defaultModo = (0, modos_1.parseModo)(texto(conduction.default_mode, 'classic'));
124
+ if (!defaultModo) {
125
+ erros.push(`conduction.default_mode invalido: "${texto(conduction.default_mode, '')}"`);
126
+ }
127
+ const brutosPermitidos = Array.isArray(conduction.allowed_modes)
128
+ ? conduction.allowed_modes.map((m) => texto(m, ''))
129
+ : [...modos_1.ORDEM_DOS_MODOS];
130
+ const permitidos = [];
131
+ for (const b of brutosPermitidos) {
132
+ const m = (0, modos_1.parseModo)(b);
133
+ if (!m)
134
+ erros.push(`conduction.allowed_modes contem modo invalido: "${b}"`);
135
+ else
136
+ permitidos.push(m);
137
+ }
138
+ if (permitidos.length === 0)
139
+ permitidos.push(...modos_1.ORDEM_DOS_MODOS);
140
+ if (defaultModo && !permitidos.includes(defaultModo)) {
141
+ erros.push(`conduction.default_mode (${defaultModo}) fora de conduction.allowed_modes`);
142
+ }
143
+ const providerPolicy = texto(runtime.provider_policy, 'subscription-only');
144
+ if (providerPolicy !== 'subscription-only' && providerPolicy !== 'any') {
145
+ avisos.push(`runtime.provider_policy desconhecida: "${providerPolicy}"`);
146
+ }
147
+ // Bloco B6, isolamento por tenant (precedente do incidente memory-orkmind):
148
+ // `database_url_env` recebe o NOME da variavel de ambiente, nunca a string de conexao.
149
+ // Uma DSN colada aqui e exatamente o defeito que fez a memoria de um produto escrever
150
+ // na base de outro, entao ela reprova o manifesto em vez de degradar em silencio.
151
+ const modoDeMemoria = texto(memory.mode, 'files');
152
+ if (modoDeMemoria !== 'files' && modoDeMemoria !== 'orkmind') {
153
+ erros.push(`memory.mode invalido: "${modoDeMemoria}" (esperado files ou orkmind)`);
154
+ }
155
+ const variavelDaDsn = texto(memory.database_url_env, '').trim();
156
+ if (variavelDaDsn.includes('://')) {
157
+ erros.push('memory.database_url_env recebe o NOME da variavel de ambiente com a DSN, nunca a ' +
158
+ 'string de conexao (base propria por tenant, sem fallback para base alheia)');
159
+ }
160
+ else if (variavelDaDsn !== '' && !/^[A-Z][A-Z0-9_]*$/.test(variavelDaDsn)) {
161
+ erros.push(`memory.database_url_env invalido: "${variavelDaDsn}" (esperado nome de variavel de ambiente, [A-Z][A-Z0-9_]*)`);
162
+ }
163
+ if (modoDeMemoria === 'orkmind' && variavelDaDsn === '') {
164
+ avisos.push('memory.mode: orkmind sem memory.database_url_env: o regime efetivo cai para files ' +
165
+ '(o `ork` nao adivinha DSN, e base alheia e pior do que base nenhuma)');
166
+ }
167
+ const bytes = Buffer.byteLength(bruto, 'utf8');
168
+ if (bytes > exports.LIMITE_MANIFESTO_BYTES) {
169
+ erros.push(`manifesto com ${bytes} bytes, acima do limite duro de ${exports.LIMITE_MANIFESTO_BYTES} (prosa vai para memoria com tag, nao para o YAML)`);
170
+ }
171
+ if (achado.legado) {
172
+ avisos.push(`lendo ${exports.NOME_MANIFESTO_LEGADO} como fallback; migre para ${exports.NOME_MANIFESTO}`);
173
+ }
174
+ const manifesto = {
175
+ project: {
176
+ name: nomeProjeto,
177
+ abbrev,
178
+ stage: texto(project.stage, 'nascente') ?? 'nascente',
179
+ repo_root: texto(project.repo_root, raiz),
180
+ },
181
+ board: {
182
+ adapter: texto(board.adapter, 'hermes-kanban'),
183
+ default: texto(board.default, 'default'),
184
+ },
185
+ runtime: {
186
+ adapter: texto(runtime.adapter, 'claude-bg'),
187
+ model: texto(runtime.model, 'opus'),
188
+ effort: texto(runtime.effort, 'high'),
189
+ provider_policy: providerPolicy,
190
+ },
191
+ conduction: {
192
+ default_mode: defaultModo ?? 'classic',
193
+ allowed_modes: permitidos,
194
+ },
195
+ worktree: {
196
+ base_branch: texto(worktree.base_branch, 'main'),
197
+ dir: texto(worktree.dir, '.claude/worktrees'),
198
+ por_thread: booleano(worktree.por_thread, true),
199
+ },
200
+ verify: {
201
+ build: verify.build === null || verify.build === undefined ? undefined : texto(verify.build, ''),
202
+ test: verify.test === null || verify.test === undefined ? undefined : texto(verify.test, ''),
203
+ typecheck: verify.typecheck === null || verify.typecheck === undefined
204
+ ? undefined
205
+ : texto(verify.typecheck, ''),
206
+ },
207
+ concurrency: {
208
+ max_parallel_threads: numero(concurrency.max_parallel_threads, 3),
209
+ },
210
+ handoff: {
211
+ rotate_above: numero(handoff.rotate_above, 0.7),
212
+ force_rotate_above: numero(handoff.force_rotate_above, 0.85),
213
+ },
214
+ // Bloco B3: o limite de escalacao tem padrao, e o padrao e conservador. Manifesto
215
+ // sem bloco `retry:` continua andando com 3 tentativas e janela estimada de 60 min,
216
+ // que e exatamente o que o B3 promete, nao um "sem limite" implicito.
217
+ retry: {
218
+ max_tentativas: Math.max(0, Math.trunc(numero(retry.max_tentativas, 3))),
219
+ janela_padrao_min: Math.max(1, Math.trunc(numero(retry.janela_padrao_min, 60))),
220
+ escalar_esforco: booleano(retry.escalar_esforco, true),
221
+ },
222
+ // Bloco B6: regime de memoria. `files` e o padrao e continua sendo o fallback
223
+ // honesto; `orkmind` liga a camada semantica POR CIMA, e so liga quando a base
224
+ // propria do tenant esta declarada por NOME de variavel de ambiente.
225
+ memory: {
226
+ mode: modoDeMemoria,
227
+ database_url_env: variavelDaDsn,
228
+ cli: texto(memory.cli, 'orkmind'),
229
+ tenant: texto(memory.tenant, '') || nomeProjeto,
230
+ timeout_ms: numero(memory.timeout_ms, 15000),
231
+ },
232
+ // Bloco B5: governanca de custo dos auditores. Ausente no manifesto quer dizer
233
+ // "nao declarada", nao "sem limite": a rodada avisa que so `eco` e o escopo
234
+ // incremental estao governando o custo, em vez de fingir uma janela que ninguem escreveu.
235
+ audit: {
236
+ janela_ociosa: texto(audit.janela_ociosa, ''),
237
+ effort: texto(audit.effort, 'eco'),
238
+ since_padrao: texto(audit.since_padrao, '7d'),
239
+ graphify: texto(audit.graphify, 'auto'),
240
+ },
241
+ policies: Object.fromEntries(Object.entries(mapa(dados.policies)).map(([k, v]) => [k, texto(v, '')])),
242
+ };
243
+ return { caminho: achado.caminho, raiz, legado: achado.legado, bytes, manifesto, erros, avisos };
244
+ }
245
+ /** Carrega o manifesto ou encerra com mensagem acionavel (uso nos subcomandos). */
246
+ function exigirManifesto(dirInicial = process.cwd()) {
247
+ const carregado = carregarManifesto(dirInicial);
248
+ if (!carregado) {
249
+ throw new Error(`manifesto ${exports.NOME_MANIFESTO} nao encontrado a partir de ${dirInicial}. Rode: ork init`);
250
+ }
251
+ if (carregado.erros.length > 0) {
252
+ throw new Error(`manifesto invalido (${carregado.caminho}):\n - ${carregado.erros.join('\n - ')}`);
253
+ }
254
+ return carregado;
255
+ }