@orkastery/cli 0.2.0 → 0.3.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.
- package/LICENSE +1 -1
- package/README.md +86 -65
- package/adapters/README.md +30 -15
- package/adapters/claude-code/.claude-plugin/plugin.json +11 -5
- package/adapters/claude-code/README.md +110 -8
- package/adapters/claude-code/commands/onboarding.md +21 -0
- package/adapters/claude-code/commands/ork.md +99 -27
- package/adapters/claude-code/hooks/hooks.json +6 -1
- package/adapters/claude-code/hooks/ork-sensor.js +66 -0
- package/adapters/codex/skills/ork/SKILL.md +57 -0
- package/adapters/hermes/README.md +163 -0
- package/adapters/hermes/bin/ork-abrir-thread.sh +2 -0
- package/adapters/hermes/bin/ork-brain.sh +4 -0
- package/adapters/hermes/bin/ork-hitl-answer.py +82 -0
- package/adapters/hermes/bin/ork-maestro.sh +6 -0
- package/adapters/hermes/bin/ork-master-enviar.py +84 -0
- package/adapters/hermes/bin/ork-objective-message.sh +17 -0
- package/adapters/hermes/bin/ork-objective-status.sh +12 -0
- package/adapters/hermes/bin/ork-pulse-enviar.py +47 -0
- package/adapters/hermes/hermes.plugin.json +26 -4
- package/adapters/hermes/hitl-ingress/__init__.py +356 -0
- package/adapters/hermes/hitl-ingress/plugin.yaml +4 -0
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +75 -22
- package/adapters/openclaw/README.md +135 -26
- package/adapters/openclaw/bin/ork-brain.sh +4 -0
- package/adapters/openclaw/construir.sh +19 -0
- package/adapters/openclaw/dist/hitl-ingress.js +199 -0
- package/adapters/openclaw/dist/index.js +437 -0
- package/adapters/openclaw/openclaw.plugin.json +39 -134
- package/adapters/openclaw/package.json +26 -0
- package/adapters/openclaw/src/hitl-ingress.ts +180 -0
- package/adapters/openclaw/src/index.ts +458 -0
- package/adapters/openclaw/src/tipos-openclaw.d.ts +58 -0
- package/adapters/openclaw/tsconfig.json +15 -0
- package/assets/docs/markdownlint-cli2.jsonc +22 -0
- package/assets/docs/padroes/documentacao-de-produto.md +133 -0
- package/assets/docs/padroes/roadmap-de-produto.md +98 -0
- package/assets/docs/produto/README.md +14 -0
- package/assets/docs/produto/_modelo-feature.md +59 -0
- package/assets/docs/roadmap/README.md +14 -0
- package/assets/docs/roadmap/_modelo-item.md +73 -0
- package/assets/orkmind-native-schema.json +32 -0
- package/assets/orkmind_bridge.py +357 -0
- package/assets/orkmind_fixture.py +67 -0
- package/assets/orkmind_prospective.py +138 -0
- package/assets/reference-tariffs-i07.json +23 -0
- package/dist/adapters/claude-bg.js +488 -39
- package/dist/adapters/codex-controller-sensor.js +449 -0
- package/dist/adapters/codex-controller-worker.js +361 -0
- package/dist/adapters/codex-controller.js +252 -0
- package/dist/adapters/codex-events.js +205 -0
- package/dist/adapters/codex-question.js +26 -0
- package/dist/adapters/codex-runner.js +133 -0
- package/dist/adapters/codex.js +394 -0
- package/dist/agents-md.js +84 -0
- package/dist/auditoria.js +11 -8
- package/dist/auditrun.js +5 -4
- package/dist/board.js +173 -22
- package/dist/branch-de-estado.js +136 -0
- package/dist/canarios-hitl.js +177 -0
- package/dist/canarios-i43.js +543 -0
- package/dist/canarios-pulse.js +147 -0
- package/dist/canarios-sensores.js +129 -0
- package/dist/canarios.js +111 -2
- package/dist/catalogo.js +9 -0
- package/dist/ci.js +216 -0
- package/dist/ciclos.js +2 -1
- package/dist/claim-lint.js +64 -0
- package/dist/claims.js +60 -0
- package/dist/company-brain-capture.js +195 -0
- package/dist/company-brain-cli.js +123 -0
- package/dist/company-brain-client.js +61 -0
- package/dist/company-brain-contract.js +166 -0
- package/dist/company-brain-journal.js +192 -0
- package/dist/company-brain-mcp.js +33 -0
- package/dist/company-brain-migration.js +60 -0
- package/dist/company-brain-source.js +177 -0
- package/dist/company-brain-worker.js +18 -0
- package/dist/conducao-texto.js +61 -0
- package/dist/conducao.js +876 -0
- package/dist/contrato-publico.js +39 -0
- package/dist/creation-operation-store.js +251 -0
- package/dist/creation-operation.js +148 -0
- package/dist/decisao-autonoma.js +183 -0
- package/dist/delegation.js +79 -0
- package/dist/demo.js +120 -0
- package/dist/docs.js +828 -0
- package/dist/doctor.js +183 -24
- package/dist/entrega-pr.js +117 -0
- package/dist/escopo-escrita.js +71 -0
- package/dist/estado-thread.js +222 -0
- package/dist/evalrunner.js +12 -0
- package/dist/fabrica-estado.js +329 -0
- package/dist/fabrica-publicar.js +76 -0
- package/dist/fix.js +21 -0
- package/dist/gates.js +55 -9
- package/dist/handoff.js +39 -23
- package/dist/hitl-canais.js +333 -0
- package/dist/hitl-classificacao.js +131 -0
- package/dist/hitl-contract.js +465 -0
- package/dist/hitl-estado.js +136 -0
- package/dist/hitl-gates.js +554 -0
- package/dist/hitl-ingress-receipt.js +382 -0
- package/dist/hitl-local-atestado.js +57 -0
- package/dist/hitl-local-receipt.js +328 -0
- package/dist/hitl-local.js +143 -0
- package/dist/hitl-lock.js +139 -0
- package/dist/hitl-lote.js +223 -0
- package/dist/hitl-native-offer.js +97 -0
- package/dist/hitl-native.js +65 -0
- package/dist/hitl-presentation.js +209 -0
- package/dist/hitl-public-receipt.js +176 -0
- package/dist/hitl-resumo.js +209 -0
- package/dist/hitl-sessions.js +475 -0
- package/dist/hitl.js +711 -0
- package/dist/horario.js +269 -0
- package/dist/hosts.js +198 -22
- package/dist/index.js +1736 -93
- package/dist/indice.js +99 -0
- package/dist/init.js +28 -3
- package/dist/integracoes-locais.js +17 -0
- package/dist/leases.js +65 -21
- package/dist/ledger-stats.js +272 -0
- package/dist/ledger.js +107 -2
- package/dist/licoes.js +215 -0
- package/dist/liveness.js +218 -0
- package/dist/maestro-actions.js +51 -0
- package/dist/maestro-authority.js +152 -0
- package/dist/maestro-cli.js +97 -0
- package/dist/maestro-contract.js +55 -0
- package/dist/maestro-discovery.js +132 -0
- package/dist/maestro-runtime.js +268 -0
- package/dist/maestro-snapshot.js +86 -0
- package/dist/maestro-sources.js +224 -0
- package/dist/manifest.js +165 -6
- package/dist/maquina.js +102 -0
- package/dist/master-audit.js +101 -0
- package/dist/master-batch.js +43 -0
- package/dist/master-digest.js +149 -0
- package/dist/master-migracao.js +155 -0
- package/dist/master.js +361 -77
- package/dist/mcp-artifacts.js +234 -0
- package/dist/mcp-git.js +433 -0
- package/dist/mcp-install.js +310 -0
- package/dist/mcp-maestro.js +25 -0
- package/dist/mcp-server.js +469 -0
- package/dist/mcp-ship.js +436 -0
- package/dist/mcp-verify.js +173 -0
- package/dist/memoria-humana.js +207 -0
- package/dist/memoria.js +314 -78
- package/dist/memory-migration.js +279 -0
- package/dist/memory-prospective.js +148 -0
- package/dist/modos-migracao.js +191 -0
- package/dist/modos.js +151 -15
- package/dist/monitor-lock.js +110 -0
- package/dist/objective.js +449 -0
- package/dist/ocupacao.js +267 -0
- package/dist/onboarding.js +303 -0
- package/dist/orkmind.js +389 -90
- package/dist/orquestracao.js +96 -69
- package/dist/phase.js +596 -150
- package/dist/playbook-capabilities.js +150 -0
- package/dist/playbook-contracts.js +188 -0
- package/dist/portfolio-context.js +61 -0
- package/dist/portfolio.js +180 -0
- package/dist/preflight.js +207 -0
- package/dist/process-audit.js +112 -0
- package/dist/project-state.js +93 -0
- package/dist/prompts.js +25 -5
- package/dist/prova-minima.js +112 -0
- package/dist/pulse-cadencia.js +163 -0
- package/dist/pulse-consentimento.js +260 -0
- package/dist/pulse-delivery.js +323 -0
- package/dist/pulse-resposta.js +542 -0
- package/dist/pulse.js +262 -0
- package/dist/ratelimit.js +35 -2
- package/dist/recall.js +80 -3
- package/dist/redacao-saida.js +45 -0
- package/dist/redacao-url.js +66 -0
- package/dist/retry.js +637 -115
- package/dist/roadmap-reservas.js +243 -0
- package/dist/runtime-ambiente.js +38 -0
- package/dist/runtime-context.js +215 -0
- package/dist/runtime-profiles.js +869 -0
- package/dist/runtimes.js +103 -0
- package/dist/sandbox.js +9 -0
- package/dist/session-events.js +203 -0
- package/dist/session-watcher-claude.js +637 -0
- package/dist/session-watcher.js +683 -0
- package/dist/sessoes-adopt.js +154 -0
- package/dist/sessoes-inventario.js +159 -0
- package/dist/sessoes.js +16 -35
- package/dist/setup.js +691 -0
- package/dist/ship.js +150 -15
- package/dist/slug.js +1 -1
- package/dist/thread-close.js +115 -0
- package/dist/thread.js +142 -28
- package/dist/tokens.js +1 -1
- package/dist/util.js +4 -2
- package/dist/verify-sandbox.js +265 -0
- package/dist/verify.js +270 -25
- package/dist/versao.js +60 -0
- package/dist/worktree.js +31 -2
- package/dist/write-activation.js +291 -0
- package/dist/yaml.js +2 -0
- package/eval/casos/onboarding.json +102 -0
- package/eval/casos/orkastery-bootstrap.json +35 -1
- package/eval/casos/scope-check-capability-map.json +45 -7
- package/eval/casos/ship-release.json +2 -2
- package/eval/fixtures/b0-slug-e-modos/caso.json +35 -22
- package/eval/fixtures/b2-master-log/caso.json +1 -1
- package/eval/fixtures/fx-adapter-editado-detectado/caso.json +19 -0
- package/eval/fixtures/fx-auto-quiet/caso.json +11 -0
- package/eval/fixtures/fx-blanket-approve/caso.json +10 -0
- package/eval/fixtures/fx-check-runtime-cruzado/caso.json +20 -0
- package/eval/fixtures/fx-codex-dry/caso.json +18 -0
- package/eval/fixtures/fx-donewhen-executavel/caso.json +15 -0
- package/eval/fixtures/fx-estado-dividido/caso.json +15 -0
- package/eval/fixtures/fx-fase-orfa/caso.json +116 -0
- package/eval/fixtures/fx-happy/caso.json +6 -4
- package/eval/fixtures/fx-hitl-latency/caso.json +20 -0
- package/eval/fixtures/fx-indice-reversao/caso.json +25 -0
- package/eval/fixtures/fx-listagem-abertas/caso.json +16 -0
- package/eval/fixtures/fx-maestro-bootstrap/caso.json +21 -0
- package/eval/fixtures/fx-modo-aposentado-escritor/caso.json +21 -0
- package/eval/fixtures/fx-modo-aposentado-leitor/caso.json +16 -0
- package/eval/fixtures/fx-objective-oscillation/caso.json +14 -0
- package/eval/fixtures/fx-omnicanal/caso.json +17 -0
- package/eval/fixtures/fx-sensores-runtime/caso.json +17 -0
- package/monitor/company-brain.cjs +17 -0
- package/monitor/pulse-scope.cjs +45 -0
- package/monitor/pulse.cron +18 -0
- package/monitor/varredura-pulse.sh +27 -0
- package/package.json +25 -4
- package/schemas/claims.schema.json +25 -0
- package/schemas/company-brain.schema.json +1158 -0
- package/schemas/creation-operation.schema.json +365 -0
- package/schemas/maestro-snapshot.schema.json +2716 -0
- package/skills/core/onboarding/SKILL.md +50 -0
- package/skills/core/orkastery-bootstrap/SKILL.md +95 -65
- package/skills/core/thread-state/SKILL.md +3 -1
- package/skills/governance/scope-check-capability-map/SKILL.md +17 -7
package/dist/index.js
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.parseArgs = parseArgs;
|
|
38
|
+
exports.main = main;
|
|
39
|
+
const company_brain_cli_1 = require("./company-brain-cli");
|
|
40
|
+
const maestro_cli_1 = require("./maestro-cli");
|
|
41
|
+
const hitl_public_receipt_1 = require("./hitl-public-receipt");
|
|
42
|
+
const hitl_presentation_1 = require("./hitl-presentation");
|
|
43
|
+
const hitl_native_offer_1 = require("./hitl-native-offer");
|
|
44
|
+
const hitl_ingress_receipt_1 = require("./hitl-ingress-receipt");
|
|
45
|
+
const node_path_1 = require("node:path");
|
|
46
|
+
const project_state_1 = require("./project-state");
|
|
47
|
+
const hitl_sessions_1 = require("./hitl-sessions");
|
|
48
|
+
const write_activation_1 = require("./write-activation");
|
|
49
|
+
const escopo_escrita_1 = require("./escopo-escrita");
|
|
50
|
+
const node_os_1 = require("node:os");
|
|
51
|
+
const fs = __importStar(require("node:fs"));
|
|
52
|
+
const path = __importStar(require("node:path"));
|
|
53
|
+
const node_child_process_1 = require("node:child_process");
|
|
54
|
+
const creation_operation_1 = require("./creation-operation");
|
|
55
|
+
const creation_operation_store_1 = require("./creation-operation-store");
|
|
56
|
+
const portfolio_context_1 = require("./portfolio-context");
|
|
3
57
|
/**
|
|
4
58
|
* `ork`: nucleo CLI deterministico do Orkastery (bloco B0).
|
|
5
59
|
*
|
|
@@ -7,45 +61,90 @@
|
|
|
7
61
|
* mundo real e registra no ledger. Quem escreve codigo e a orquestra (Camada 3);
|
|
8
62
|
* quem decide e o humano; o meio e conduzido por software.
|
|
9
63
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
64
|
+
const thread_close_1 = require("./thread-close");
|
|
65
|
+
const session_events_1 = require("./session-events");
|
|
66
|
+
const session_watcher_1 = require("./session-watcher");
|
|
67
|
+
const master_migracao_1 = require("./master-migracao");
|
|
68
|
+
const master_batch_1 = require("./master-batch");
|
|
69
|
+
const master_digest_1 = require("./master-digest");
|
|
70
|
+
const master_audit_1 = require("./master-audit");
|
|
71
|
+
const process_audit_1 = require("./process-audit");
|
|
72
|
+
const master_1 = require("./master");
|
|
13
73
|
const auditoria_1 = require("./auditoria");
|
|
14
74
|
const auditrun_1 = require("./auditrun");
|
|
15
75
|
const superficie_1 = require("./superficie");
|
|
16
76
|
const board_1 = require("./board");
|
|
77
|
+
const hitl_1 = require("./hitl");
|
|
78
|
+
const pulse_1 = require("./pulse");
|
|
79
|
+
const pulse_resposta_1 = require("./pulse-resposta");
|
|
80
|
+
const pulse_cadencia_1 = require("./pulse-cadencia");
|
|
81
|
+
const decisao_autonoma_1 = require("./decisao-autonoma");
|
|
17
82
|
const orquestracao_1 = require("./orquestracao");
|
|
18
83
|
const divida_1 = require("./divida");
|
|
19
84
|
const ciclos_1 = require("./ciclos");
|
|
20
85
|
const claims_1 = require("./claims");
|
|
21
86
|
const catalogo_1 = require("./catalogo");
|
|
22
87
|
const doctor_1 = require("./doctor");
|
|
88
|
+
const preflight_1 = require("./preflight");
|
|
23
89
|
const evalrunner_1 = require("./evalrunner");
|
|
24
90
|
const gates_1 = require("./gates");
|
|
91
|
+
const hitl_gates_1 = require("./hitl-gates");
|
|
25
92
|
const handoff_1 = require("./handoff");
|
|
26
93
|
const hosts_1 = require("./hosts");
|
|
27
94
|
const init_1 = require("./init");
|
|
95
|
+
const portfolio_1 = require("./portfolio");
|
|
96
|
+
const agents_md_1 = require("./agents-md");
|
|
28
97
|
const leases_1 = require("./leases");
|
|
29
|
-
const
|
|
98
|
+
const sessoes_inventario_1 = require("./sessoes-inventario");
|
|
99
|
+
const ledger_stats_1 = require("./ledger-stats");
|
|
100
|
+
const sessoes_adopt_1 = require("./sessoes-adopt");
|
|
101
|
+
const sessoes_1 = require("./sessoes");
|
|
102
|
+
const runtime_ambiente_1 = require("./runtime-ambiente");
|
|
103
|
+
const policies_1 = require("./policies");
|
|
104
|
+
const master_2 = require("./master");
|
|
30
105
|
const manifest_1 = require("./manifest");
|
|
106
|
+
const horario_1 = require("./horario");
|
|
107
|
+
const onboarding_1 = require("./onboarding");
|
|
108
|
+
const init_2 = require("./init");
|
|
31
109
|
const memoria_1 = require("./memoria");
|
|
110
|
+
const orkmind_1 = require("./orkmind");
|
|
32
111
|
const recall_1 = require("./recall");
|
|
112
|
+
const memory_migration_1 = require("./memory-migration");
|
|
33
113
|
const fix_1 = require("./fix");
|
|
34
114
|
const ratelimit_1 = require("./ratelimit");
|
|
35
115
|
const retry_1 = require("./retry");
|
|
116
|
+
const prova_minima_1 = require("./prova-minima");
|
|
117
|
+
const versao_1 = require("./versao");
|
|
36
118
|
const modos_1 = require("./modos");
|
|
119
|
+
const modos_migracao_1 = require("./modos-migracao");
|
|
120
|
+
const setup_1 = require("./setup");
|
|
121
|
+
const runtime_profiles_1 = require("./runtime-profiles");
|
|
122
|
+
const claude_bg_1 = require("./adapters/claude-bg");
|
|
123
|
+
const codex_1 = require("./adapters/codex");
|
|
124
|
+
const conducao_1 = require("./conducao");
|
|
37
125
|
const phase_1 = require("./phase");
|
|
38
126
|
const prompts_1 = require("./prompts");
|
|
39
|
-
const
|
|
127
|
+
const sessoes_2 = require("./sessoes");
|
|
40
128
|
const util_1 = require("./util");
|
|
41
129
|
const ship_1 = require("./ship");
|
|
130
|
+
const ci_1 = require("./ci");
|
|
42
131
|
const thread_1 = require("./thread");
|
|
132
|
+
const docs_1 = require("./docs");
|
|
133
|
+
const roadmap_reservas_1 = require("./roadmap-reservas");
|
|
134
|
+
const fabrica_estado_1 = require("./fabrica-estado");
|
|
135
|
+
const fabrica_publicar_1 = require("./fabrica-publicar");
|
|
136
|
+
const maquina_1 = require("./maquina");
|
|
137
|
+
const ledger_1 = require("./ledger");
|
|
43
138
|
const tokens_1 = require("./tokens");
|
|
44
139
|
const types_1 = require("./types");
|
|
45
140
|
const verify_1 = require("./verify");
|
|
46
141
|
const worktree_1 = require("./worktree");
|
|
47
|
-
|
|
48
|
-
const
|
|
142
|
+
const claim_lint_1 = require("./claim-lint");
|
|
143
|
+
const licoes_1 = require("./licoes");
|
|
144
|
+
const demo_1 = require("./demo");
|
|
145
|
+
const entrega_pr_1 = require("./entrega-pr");
|
|
146
|
+
/** A versao publicada em `@orkastery/cli`, lida do package.json (`versao.ts`). */
|
|
147
|
+
const VERSAO = versao_1.VERSAO_DO_ORK;
|
|
49
148
|
/** Parse simples de argumentos: `--chave valor`, `--chave=valor` e flags booleanas. */
|
|
50
149
|
function parseArgs(argv) {
|
|
51
150
|
const posicionais = [];
|
|
@@ -77,44 +176,137 @@ function parseArgs(argv) {
|
|
|
77
176
|
function texto(v) {
|
|
78
177
|
return typeof v === 'string' ? v : undefined;
|
|
79
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* I-36 (D2, D6): o que o CLI declara sobre a conducao. `--canal` (sem ele, o que a borda exporta),
|
|
181
|
+
* `--correlacao` (conversa ou mensagem de origem) e `--esperar [minutos]` (sem valor, 30).
|
|
182
|
+
*/
|
|
183
|
+
function conducaoDoCli(args) {
|
|
184
|
+
if (args.opcoes.canal === true)
|
|
185
|
+
throw new Error('uso: --canal <claude-code|hermes|openclaw|codex|mcp|cli>');
|
|
186
|
+
const bruto = args.opcoes.esperar;
|
|
187
|
+
let esperarMs;
|
|
188
|
+
if (bruto === true)
|
|
189
|
+
esperarMs = conducao_1.ESPERA_PADRAO_MS;
|
|
190
|
+
else if (typeof bruto === 'string') {
|
|
191
|
+
const minutos = Number(bruto);
|
|
192
|
+
if (!Number.isFinite(minutos) || minutos <= 0 || minutos > 24 * 60)
|
|
193
|
+
throw new Error('uso: --esperar [minutos], de 1 a 1440 (sem valor, 30)');
|
|
194
|
+
esperarMs = Math.round(minutos * 60_000);
|
|
195
|
+
}
|
|
196
|
+
return { canal: (0, conducao_1.canalDoProcesso)(texto(args.opcoes.canal)), correlacao: texto(args.opcoes.correlacao) ?? null, esperarMs };
|
|
197
|
+
}
|
|
80
198
|
const AJUDA = `ork ${VERSAO}, nucleo de orquestracao do Orkastery
|
|
81
199
|
|
|
82
200
|
Uso: ork <comando> [argumentos]
|
|
83
201
|
|
|
84
202
|
doctor O que vale nesta maquina agora (sai != 0 se bloqueado)
|
|
85
203
|
init [--force] [--name N] [--abbrev A] Gera o orkastery.yaml do repositorio
|
|
86
|
-
modos Tabela dos
|
|
204
|
+
modos Tabela dos ${modos_1.ORDEM_DOS_MODOS.length} modos de conducao vivos por #TAG
|
|
205
|
+
|
|
206
|
+
setup Pauta da entrevista #setup: runtime/modelo/esforco
|
|
207
|
+
onboarding [show|set <etapa>|reset [etapa]] Pauta e respostas do projeto (9 etapas)
|
|
208
|
+
[--conteudo JSON] [--por Q] [--json] Valores secretos somente em ~/.hermes/.env
|
|
209
|
+
[--reset [etapa]] Reset seletivo ou total, idempotente
|
|
210
|
+
onboarding sync [--json] Publicação opcional na memória, com degradação
|
|
211
|
+
por bloco de cada modo (default claude-bg/opus/high; #Fast: sonnet)
|
|
212
|
+
setup <modo> Config atual de cada bloco do modo
|
|
213
|
+
setup <modo> --bloco N [--runtime R] Edita o bloco (runtimes: claude-bg, codex);
|
|
214
|
+
[--model M] [--effort E] [--por Q] evento setup_configured no ledger do projeto
|
|
215
|
+
[--fallback R:M[:E],...] ordem de fallback de runtime do bloco (I-33)
|
|
216
|
+
accounts list [--json] Perfis de conta por runtime, sem segredo (I-33)
|
|
217
|
+
accounts add <id> --runtime R --dir D Cria o perfil e roda o login do proprio CLI com o env
|
|
218
|
+
[--sem-login] do perfil (nunca copia credencial)
|
|
219
|
+
accounts remove <id> Desativa o perfil (diretorio e login ficam onde estao)
|
|
220
|
+
accounts check [<id>] Confere o login de cada perfil e marca o store
|
|
221
|
+
setup [<modo>] --reset Volta o modo (ou tudo) ao default
|
|
222
|
+
setup versionar Leva o setup que vale para orkastery.setup.json: por PR, vale em
|
|
223
|
+
todas as maquinas e passa a ser o arquivo editado (I-52)
|
|
87
224
|
|
|
88
225
|
thread new <nome> --modo <MODO> Cria a thread, o slug de 3 partes e o ledger
|
|
226
|
+
[--exige-runtime-diferente] o CHECK precisa de runtime que o GO nao usou
|
|
227
|
+
[--done "<criterio> :: <comando>"] criterio de pronto EXECUTAVEL (use ;; para varios)
|
|
89
228
|
[--slug S] [--assunto A] [--worktree auto|DIR] [--dry-run]
|
|
90
|
-
|
|
91
|
-
thread
|
|
229
|
+
[--roadmap RM-NNN] reserva o item do roadmap antes de criar (I-47)
|
|
230
|
+
thread list [--todas] [--json] Threads NAO fechadas do projeto (--todas inclui as fechadas)
|
|
231
|
+
thread close <id> --motivo orfa|engano|superada --por Q --justificativa J
|
|
232
|
+
thread entrega <id> --arquivo A --sha256 H --por Q
|
|
233
|
+
thread status <thread-id> [--json] Estado da thread, cruzado com o runtime
|
|
234
|
+
|
|
235
|
+
portfolio inspect <id> --json Entidade, origem e ciclos com lacunas explícitas
|
|
236
|
+
creation start --input-file F --json Criação durável com identidade do processo local
|
|
237
|
+
creation show|list|events [id] --json Consulta journal e recuperação
|
|
238
|
+
creation resume|compensate <id> --expected-version N --json
|
|
239
|
+
portfolio create <product|project|initiative> <id> --title T [--parent ID]
|
|
240
|
+
portfolio list [product|project|initiative] [--parent ID] [--json]
|
|
241
|
+
portfolio show <id> [--json] Catálogo prod -> proj -> init
|
|
242
|
+
[--constraints A;B] [--outcomes A;B] [--threads N]
|
|
243
|
+
[--execution-runtime R] [--validation-runtimes R1,R2]
|
|
244
|
+
objective ... Aposentado na I-43: as duas vigas viraram
|
|
245
|
+
--exige-runtime-diferente e --done de thread
|
|
92
246
|
|
|
93
247
|
phase run <thread-id> <FASE> --prompt "<texto>"
|
|
94
|
-
[--
|
|
95
|
-
|
|
248
|
+
[--runtime R] [--model M] Despacha a fase como background agent
|
|
249
|
+
[--effort E] [--dry-run] (runtime: CLI > setup do bloco > manifesto;
|
|
250
|
+
so --model assume --effort high; o trio
|
|
96
251
|
efetivo vai ao ledger como fato verificavel)
|
|
252
|
+
[--canal C] [--correlacao ID] Canal de origem (sem ele, o que o host declara)
|
|
253
|
+
[--esperar [min]] Com a thread ja conduzida, espera a vez (sem: recusa na hora)
|
|
97
254
|
phase list <thread-id> Historico do ledger da thread
|
|
98
255
|
(mostra o modelo/esforco reais de cada fase)
|
|
256
|
+
ledger stats --desde 7d [--ate ISO] Telemetria economica do ledger (intervalo [desde,ate))
|
|
257
|
+
[--thread T] [--modo M] [--runtime R] [--json]
|
|
258
|
+
ledger estimate <thread-id> --sem-ia H --ia-sem-ork H --por Q --metodo M --premissas P
|
|
259
|
+
[--incerteza I] Registra estimativas explicitas da fase PLAN
|
|
99
260
|
|
|
100
|
-
sessions [--all]
|
|
261
|
+
sessions [--all] [--global] [--json] Inventário Claude e Codex da conta atual
|
|
262
|
+
[--exigir-limpo] Sai != 0 com fonte inválida ou sessão sem thread
|
|
263
|
+
sessions adopt <id> [--json] Adota identidade real sem executar prompt
|
|
264
|
+
sessions event --tipo T --sessao ID Ingere JSON limitado no stdin; observa sem aprovar gates
|
|
265
|
+
sessions watch --thread T [--sessao ID] Observa somente a sessão selecionada; --once faz uma varredura
|
|
101
266
|
sessions logs <sessao> [--linhas N] Logs de uma sessao
|
|
267
|
+
sessions supersede <thread> <UUID> --fase F --runtime R Confirma encerramento de sessão superada
|
|
268
|
+
sessions request <thread> <UUID> --fase F --runtime R --pergunta P Abre pedido vinculado ao prompt nativo
|
|
269
|
+
sessions answer <thread> <pedido> --stdin --origem telegram --canal C --por ID --mensagem REF [--conta ID] Confirma entrega autenticada
|
|
270
|
+
sessions reconcile <thread> <pedido> Fecha envio pendente so com thread e pedido; consulta recibo, nunca reenvia
|
|
102
271
|
sessions stop <sessao> Para uma sessao
|
|
103
272
|
sessions attach <sessao> Imprime o comando de attach (precisa de TTY)
|
|
273
|
+
pulse [--json] [--registrar] Fila unificada de atenção humana e retry de órfãs
|
|
274
|
+
pulse responder --resposta-stdin --origem telegram --canal C --por ID --mensagem REF [--conta ID]
|
|
275
|
+
Recebe o que o dono digitou no canal do resumo (P4EJ a, 1a 2c)
|
|
276
|
+
pulse cadencia [<tag>] [--por P] [--json] Mostra ou troca a cadencia do resumo: OrkPulseOn, OrkPulseOn-15m,
|
|
277
|
+
-30m, -60m ou OrkPulseOff; pergunta nova sai na hora (I-50)
|
|
278
|
+
sessions hitl [--json] [--so-paradas] Radar de sessoes que exigem acao humana AGORA:
|
|
279
|
+
[--atencao N] [--sem-logs] classifica o estado de cada sessao do runtime,
|
|
280
|
+
[--so-da-raiz] [--exigir-limpo] le a pergunta que a sessao trava e diz o que
|
|
281
|
+
destrava (pega HITL de sessao SEM thread)
|
|
104
282
|
|
|
105
283
|
claims add <thread-id> <arquivo> --claim "<alegacao>" [--verificar "<comando>"] [--fase F]
|
|
106
284
|
Registra alegacao verificavel da thread
|
|
107
285
|
claims list <thread-id> Claims da thread e o estado de cada uma
|
|
286
|
+
decisao registrar <thread-id> --decidido D --porque P --como-mudar C --custo-agora A --custo-depois B
|
|
287
|
+
--criterio manifesto:CHAVE|ledger:REF|medicao:COMANDO --quem Q --evidencia E [--razao R] [--reverte ID]
|
|
288
|
+
Decisao tomada sem perguntar: chega ao dono no resumo
|
|
289
|
+
decisao placar <thread-id> [--json] Decididas contra perguntas por fase, reversoes e o limiar
|
|
108
290
|
claims verificar <thread-id> <claim-id> --comando "<comando>"
|
|
109
291
|
Anexa o comando que comprova uma claim ja feita
|
|
110
292
|
claims retirar <thread-id> <claim-id> --motivo "<motivo>"
|
|
111
293
|
Retira a alegacao (o historico fica no claims.jsonl)
|
|
294
|
+
claims ausente <thread-id> --paths A,B --motivo "<motivo>" [--commit SHA]
|
|
295
|
+
Ciclo sem CHECK: declara no ledger o que ficou sem prova
|
|
112
296
|
verify <thread-id> [--baseline] Reexecuta claims e verify do manifesto no HEAD real
|
|
113
297
|
[--so-claims] --baseline grava o estado do mundo antes do GO
|
|
298
|
+
[--canal C] [--esperar [min]] So executa com a conducao da thread (sai 3 se outra conduz)
|
|
299
|
+
ci prepare <thread-id> Exporta claims/comandos para a candidata
|
|
300
|
+
ci run [<thread-id>] [--bundle ARQ] Executa o CHECK no runner independente
|
|
301
|
+
ci status [--sha SHA] [--remoto origin] Consulta o check exato publicado no GitHub
|
|
114
302
|
|
|
115
303
|
gate next <thread-id> [--proximo FASE] Gate de tokens: mesma sessao ou nova sessao
|
|
116
304
|
[--ocupacao 0..1] [--fonte F] [--transcript ARQ] [--janela N] [--refazer]
|
|
117
|
-
gate
|
|
305
|
+
gate request <thread-id> [--motivo M] Apresenta pedido HITL correlacionado à pausa
|
|
306
|
+
gate answer <thread-id> <pedido> Recebe envelope do ingresso humano autenticado
|
|
307
|
+
--resposta-stdin --por Q --mensagem ID --origem telegram [--canal hermes|openclaw]
|
|
308
|
+
[--conta ID] conta homologada do canal; obrigatoria no canal openclaw
|
|
309
|
+
gate approve Aposentado: aprovação sem pedido é recusada
|
|
118
310
|
|
|
119
311
|
retry policy [--motivo M] [--json] Politica de retry por motivo tipado de gate
|
|
120
312
|
retry plan <thread-id> [--motivo M] O que o ork faria pelo ultimo gate reprovado
|
|
@@ -141,15 +333,21 @@ Uso: ork <comando> [argumentos]
|
|
|
141
333
|
[--id ptr-N] [--todos] [--forcar] momento (retrieve_when), nunca a janela inteira
|
|
142
334
|
[--sem-conteudo] [--json] (orkmind por tag, files por path#ancora)
|
|
143
335
|
|
|
336
|
+
brain status|inventory|get|query|receipts|sync|reconcile|apply|rollback|bind
|
|
144
337
|
memory status [--json] Regime efetivo (files|orkmind), tenant e degradacao
|
|
145
338
|
memory sync [<thread-id>] [--json] Publica decisoes, policies, handoff, licao e roadmap
|
|
339
|
+
memory inventory --escopo <threads> [--json] Inventaria fontes canonicas e tenants excluidos, sem gravar
|
|
340
|
+
memory migrate --operadora <thread> --escopo <threads> [--dry-run] [--json] Migra handoffs por G3, com pacote integral e readback
|
|
146
341
|
memory search --tags '<json>' [--colecao C] Busca deterministica por tag (mandatory sempre volta)
|
|
147
|
-
[--limite N] [--json]
|
|
342
|
+
[--thread ID] [--restrito] [--janela N] [--limite N] [--json]
|
|
148
343
|
|
|
149
344
|
ship <thread-id> --para <branch> Merge --no-ff serializado por lease e push PROVADO
|
|
345
|
+
ship registrar-pr <thread-id>|--todas A entrega feita por PR vira ship_done: merge ship(<thread>) na base
|
|
346
|
+
[--remoto R] [--json] remota e CI verde no head do PR; depois, ork master --aceitar-omissao
|
|
150
347
|
[--de <branch>] [--remoto origin] [--autorizar-push <quem>] [--sem-push] [--dry-run]
|
|
151
348
|
|
|
152
|
-
board [--all]
|
|
349
|
+
board [--all] [--sem-remoto] Visao unica das threads (todos os perfis com --all); com a
|
|
350
|
+
fabrica compartilhada, tambem as outras maquinas (I-51)
|
|
153
351
|
board plan Escalonador: quem avanca agora, quem espera e por que
|
|
154
352
|
|
|
155
353
|
orquestracao status [--all] [--json] Monitor PROATIVO de pausas e impedimentos: quem esta
|
|
@@ -161,18 +359,33 @@ Uso: ork <comando> [argumentos]
|
|
|
161
359
|
worktree audit <thread-id> Confere a worktree no proprio git (sai != 0 se divergir)
|
|
162
360
|
worktree release <thread-id> [--forcar] Remove a worktree e limpa o registro
|
|
163
361
|
|
|
362
|
+
activation plan|status|enable|disable Escrita escopada com aceite, hash, leases e recibo
|
|
164
363
|
lease list Leases, familias e as filas (merge e colisao de regiao)
|
|
165
364
|
lease acquire <nome> --thread T --motivo M Toma um lease tipado (entra na fila se colidir)
|
|
166
365
|
lease release <nome> [--thread T] [--forcar]
|
|
366
|
+
conducao status <thread-id> [--json] Quem conduz a thread agora (canal, sessao, fase, desde)
|
|
367
|
+
conducao assumir <thread-id> --por Q --motivo M
|
|
368
|
+
Handoff: encerra a conducao atual pelo runtime e registra quem assumiu
|
|
167
369
|
|
|
370
|
+
master propor <id> --score N --justificativa J --por <agente>
|
|
371
|
+
master batch --aceitar <thread:assinatura,...> --por <humano>
|
|
372
|
+
master migrar --dry-run --por Q Inspeciona correções sem alterar originais
|
|
373
|
+
master digest <enviar|preview|responder> Digest semanal com recibos do host
|
|
168
374
|
master <thread-id> --score 0-5 --justificativa "<texto>"
|
|
169
375
|
[--classe C[,C]] [--resumo R] [--por Q] [--refazer]
|
|
170
376
|
Fecha a thread: POSTMORTEM + MASTER log + score
|
|
171
|
-
master --
|
|
377
|
+
master [--todas] [--json] As entregas, com o indice derivado do ledger
|
|
378
|
+
master --aceitar-omissao [--json] Aceita as entregues por omissao, com registro
|
|
172
379
|
master classes As classes de falha fixas do POSTMORTEM
|
|
380
|
+
licoes [--json] O que volta no GOAL e no PLAN da proxima thread (POSTMORTEM e
|
|
381
|
+
MASTER) e as propostas de policy por recorrencia (I-55)
|
|
173
382
|
|
|
383
|
+
demo [--manter] [--dir D] A promessa em 30 s: uma afirmacao falsa reprovada e a corrigida aceita,
|
|
384
|
+
offline, num repositorio temporario (I-56)
|
|
174
385
|
ciclos Variantes de ciclo de "ork thread new --ciclo"
|
|
175
386
|
modos --do-pedido "<texto>" [--json] Le a #TAG do pedido do builder (usado pelos adaptadores)
|
|
387
|
+
modos migrar [--dry-run] [--por Q] Tira modo aposentado do orkastery.yaml e do setup.json
|
|
388
|
+
[--json] (idempotente, com backup; nao toca em historico)
|
|
176
389
|
|
|
177
390
|
prompt list Templates de prompt (embutidos e os do projeto)
|
|
178
391
|
prompt lint [--template ID] Reprova template quebrado antes de ele virar despacho
|
|
@@ -180,10 +393,33 @@ Uso: ork <comando> [argumentos]
|
|
|
180
393
|
[--pedido "<texto>"] [--template ID]
|
|
181
394
|
prompt render --exemplo --fase F --modo M Renderiza sem thread nenhuma, para revisar o texto
|
|
182
395
|
|
|
396
|
+
roadmap reservas [--json] [--remoto R] Quem esta com cada item do roadmap, lido da branch ork/roadmap-reservas
|
|
397
|
+
roadmap pegar <RM-NNN> [--thread T] Reserva o item para esta maquina (push atomico: o primeiro vence)
|
|
398
|
+
[--nota N] [--por Q] [--maquina M] maquina = --maquina, ORK_MAQUINA ou o hostname
|
|
399
|
+
[--forcar --motivo M] tomar a reserva de outra maquina fica registrado
|
|
400
|
+
roadmap soltar <RM-NNN> [--forcar --motivo M] Devolve o item
|
|
401
|
+
fabrica [--json] [--sem-remoto] O que cada maquina conduz, lido da branch ork/fabrica-estado (I-51)
|
|
402
|
+
fabrica entrar [--maquina NOME] Esta maquina entra na fabrica compartilhada deste usuario, com
|
|
403
|
+
este nome (~/.orkastery/maquina.json), e publica o primeiro retrato
|
|
404
|
+
fabrica publicar [--forcar] [--json] Grava o retrato desta maquina na branch (push atomico, sem forca);
|
|
405
|
+
depois de entrar, sai sozinho ao criar thread, despachar fase,
|
|
406
|
+
entregar e fechar, e a cada batida do pulse
|
|
407
|
+
fabrica sair Para de publicar daqui e tira o retrato desta maquina da branch
|
|
408
|
+
docs verificar [--json] Documentacao de produto e roadmap contra o codigo e o git
|
|
409
|
+
(padrao do dono: frontmatter, leitura, paridade; sai != 0 com erro)
|
|
410
|
+
docs sincronizar [--escrever] Fatos do ledger e do git para o roadmap (merge, fase) e indices;
|
|
411
|
+
sem --escrever so mostra; nunca muda status por passagem de tempo
|
|
412
|
+
docs init Cria padroes, modelos, indices e o lint de Markdown no projeto
|
|
413
|
+
|
|
414
|
+
mcp serve --project RAIZ --host HOST Servidor MCP stdio deste projeto (codex|claude-code)
|
|
415
|
+
mcp install --project RAIZ --host HOST Prepara MCP; aceita --dry-run, --ship-transport, --child-permissions e --owner-permissions (Codex)
|
|
416
|
+
|
|
183
417
|
adapter list Adaptadores de host (Camada 1) e o destino de cada um
|
|
184
418
|
adapter show <host> Os 3 pitfalls de instalacao do host
|
|
185
|
-
adapter install <host> [--dir D] Instala o adaptador (hermes|openclaw
|
|
186
|
-
[--dry-run] [--force]
|
|
419
|
+
adapter install <host> [--dir D] Instala o adaptador (claude-code|codex|hermes|openclaw)
|
|
420
|
+
[--dry-run] [--force] divergencia segura resolve sozinha; o resto pergunta
|
|
421
|
+
[--aceitar-catalogo <arquivo>] sobrescreve a copia com o catalogo, arquivo a arquivo
|
|
422
|
+
[--manter-copia <arquivo>] deixa a copia como esta, arquivo a arquivo
|
|
187
423
|
|
|
188
424
|
eval [--skill S] [--canario C] Canarios de comportamento + corpus das skills finas
|
|
189
425
|
[--so-canarios] [--so-skills] [--json] (sai != 0 em qualquer falha)
|
|
@@ -227,11 +463,11 @@ pausaSobre do bloco dizendo o que o humano decide); impedimento e a nao prevista
|
|
|
227
463
|
DERIVADO de thread.json, ledger.jsonl e das filas em disco: o monitor le, nunca grava.
|
|
228
464
|
--exigir-limpo sai != 0 enquanto houver thread parada, para virar watchdog do orquestrador.
|
|
229
465
|
|
|
230
|
-
Fases: GOAL PLAN GO CHECK SHIP MASTER. Modos:
|
|
466
|
+
Fases: GOAL PLAN GO CHECK SHIP MASTER. Modos: ${modos_1.ORDEM_DOS_MODOS.map((m) => modos_1.MODOS[m].tag).join(' ')}.
|
|
231
467
|
Familias de lease: main-tree, worktree-write:<thread>, path:<glob>, board:<card>, service:<porta>.
|
|
232
468
|
Ciclos: greenfield, merge-branch, goal-plan, gap, feature-xl-faseada.
|
|
233
469
|
Fontes de medida do gate de tokens: runtime_reported, estimated, informada, unavailable.
|
|
234
|
-
Hosts de Camada 1: claude-code, hermes, openclaw. Canarios: fx-happy, fx-hallucination,
|
|
470
|
+
Hosts de Camada 1: claude-code, codex, hermes, openclaw. Canarios: fx-happy, fx-hallucination,
|
|
235
471
|
fx-stale-base, fx-wiki-destroy, fx-schema-drift, fx-concurrency.
|
|
236
472
|
Packs de auditoria: clean-code, reuse, architecture, data-model, ux, security-privacy, process.
|
|
237
473
|
Superficie de ataque de rede (SP8..SP12, varredura deterministica): rota sem auth, endpoint de
|
|
@@ -239,6 +475,17 @@ administracao exposto, rota sem rate limit, CORS permissivo, rota sem esquema de
|
|
|
239
475
|
Estagios do produto: nascente, crescendo, maduro (hardening gradual, visao secao 5.2).
|
|
240
476
|
`;
|
|
241
477
|
function comandoThread(args) {
|
|
478
|
+
if (args.posicionais[1] === 'close' || args.posicionais[1] === 'entrega') {
|
|
479
|
+
const raiz = (0, manifest_1.exigirManifesto)().raiz, id = args.posicionais[2];
|
|
480
|
+
if (!id)
|
|
481
|
+
throw new Error('informe o id da thread');
|
|
482
|
+
const por = texto(args.opcoes.por) ?? '';
|
|
483
|
+
const r = args.posicionais[1] === 'close'
|
|
484
|
+
? (0, thread_close_1.fecharAdministrativamente)(raiz, id, { motivo: texto(args.opcoes.motivo) ?? '', por, justificativa: texto(args.opcoes.justificativa) ?? '' })
|
|
485
|
+
: (0, thread_close_1.registrarArtefato)(raiz, id, texto(args.opcoes.arquivo) ?? '', texto(args.opcoes.sha256) ?? '', por);
|
|
486
|
+
console.log(JSON.stringify(r, null, 2));
|
|
487
|
+
return 0;
|
|
488
|
+
}
|
|
242
489
|
const sub = args.posicionais[1];
|
|
243
490
|
if (sub === 'new') {
|
|
244
491
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
@@ -247,10 +494,15 @@ function comandoThread(args) {
|
|
|
247
494
|
const doAchado = texto(args.opcoes['from-finding']) ?? texto(args.opcoes['do-achado']);
|
|
248
495
|
if (doAchado) {
|
|
249
496
|
const brutoModoAchado = texto(args.opcoes.modo) ?? texto(args.opcoes.mode);
|
|
250
|
-
|
|
251
|
-
if (brutoModoAchado
|
|
252
|
-
|
|
253
|
-
|
|
497
|
+
let modoAchado;
|
|
498
|
+
if (brutoModoAchado !== undefined) {
|
|
499
|
+
try {
|
|
500
|
+
modoAchado = (0, modos_1.exigirModoVivo)(brutoModoAchado);
|
|
501
|
+
}
|
|
502
|
+
catch (e) {
|
|
503
|
+
console.error(e.message);
|
|
504
|
+
return 2;
|
|
505
|
+
}
|
|
254
506
|
}
|
|
255
507
|
const brutoWorktreeAchado = args.opcoes.worktree;
|
|
256
508
|
const criarWorktreeAchado = brutoWorktreeAchado === true || brutoWorktreeAchado === 'auto';
|
|
@@ -314,13 +566,35 @@ function comandoThread(args) {
|
|
|
314
566
|
return 2;
|
|
315
567
|
}
|
|
316
568
|
const brutoModo = texto(args.opcoes.modo) ?? texto(args.opcoes.mode);
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
569
|
+
let modo;
|
|
570
|
+
try {
|
|
571
|
+
modo = brutoModo !== undefined
|
|
572
|
+
? (0, modos_1.exigirModoVivo)(brutoModo)
|
|
573
|
+
: carregado.manifesto.conduction.default_mode;
|
|
574
|
+
}
|
|
575
|
+
catch (e) {
|
|
576
|
+
console.error(e.message);
|
|
322
577
|
return 2;
|
|
323
578
|
}
|
|
579
|
+
// I-43 (D4, viga a): a exigencia de validacao cruzada e declarada na criacao e
|
|
580
|
+
// fica gravada na thread, em vez de morar num envelope a parte.
|
|
581
|
+
const exigeRuntimeDiferente = args.opcoes['exige-runtime-diferente'] === true;
|
|
582
|
+
// I-43 (D4, viga b): `--done "criterio :: comando"`, com `;;` separando varios.
|
|
583
|
+
// O separador `::` e obrigatorio: criterio sem comando e a prosa que o envelope
|
|
584
|
+
// tinha, e o produto nao aceita de volta um criterio de pronto que ninguem executa.
|
|
585
|
+
const doneWhen = (texto(args.opcoes.done) ?? '').split(';;').map((p) => p.trim()).filter(Boolean)
|
|
586
|
+
.map((entrada) => {
|
|
587
|
+
const corte = entrada.indexOf('::');
|
|
588
|
+
if (corte < 0) {
|
|
589
|
+
throw new Error(`done.sem-comando: "${entrada}" nao traz comando. `
|
|
590
|
+
+ 'Use --done "<criterio> :: <comando que o prova>"; criterio sem comando e prosa, nao criterio de pronto.');
|
|
591
|
+
}
|
|
592
|
+
const criterio = entrada.slice(0, corte).trim();
|
|
593
|
+
const comando = entrada.slice(corte + 2).trim();
|
|
594
|
+
if (!criterio || !comando)
|
|
595
|
+
throw new Error(`done.incompleto: "${entrada}" precisa de criterio E comando`);
|
|
596
|
+
return { criterio, comando };
|
|
597
|
+
});
|
|
324
598
|
const dryRun = args.opcoes['dry-run'] === true;
|
|
325
599
|
const brutoWorktree = args.opcoes.worktree;
|
|
326
600
|
// `--worktree auto` (ou `--worktree` sozinho) cria a worktree isolada da thread;
|
|
@@ -333,19 +607,46 @@ function comandoThread(args) {
|
|
|
333
607
|
return 2;
|
|
334
608
|
}
|
|
335
609
|
const brutoFatias = texto(args.opcoes.fatias);
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
610
|
+
// I-47: `--roadmap RM-NNN` reserva o item ANTES de criar a thread. A reserva e o passo
|
|
611
|
+
// atomico entre maquinas (o primeiro push vence); a thread e local. Se a criacao falhar,
|
|
612
|
+
// a reserva e devolvida; se der certo, ela passa a apontar para a thread.
|
|
613
|
+
const itemDoRoadmap = dryRun ? undefined : texto(args.opcoes.roadmap);
|
|
614
|
+
const itemReservado = itemDoRoadmap ? (0, roadmap_reservas_1.pegarItem)(carregado.raiz, itemDoRoadmap).item : undefined;
|
|
615
|
+
let criada;
|
|
616
|
+
try {
|
|
617
|
+
criada = (0, thread_1.novaThread)(carregado, {
|
|
618
|
+
nome,
|
|
619
|
+
modo,
|
|
620
|
+
slug: texto(args.opcoes.slug),
|
|
621
|
+
assunto: texto(args.opcoes.assunto),
|
|
622
|
+
worktree: criarWorktree ? null : (texto(brutoWorktree) ?? null),
|
|
623
|
+
criarWorktree,
|
|
624
|
+
dryRun,
|
|
625
|
+
variante,
|
|
626
|
+
branch: texto(args.opcoes.branch),
|
|
627
|
+
fatias: brutoFatias !== undefined ? Number(brutoFatias) : undefined,
|
|
628
|
+
exigeRuntimeDiferente,
|
|
629
|
+
doneWhen,
|
|
630
|
+
roadmap: itemReservado,
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
catch (e) {
|
|
634
|
+
if (itemDoRoadmap) {
|
|
635
|
+
try {
|
|
636
|
+
(0, roadmap_reservas_1.soltarItem)(carregado.raiz, itemDoRoadmap);
|
|
637
|
+
}
|
|
638
|
+
catch { /* fica reservado; `ork roadmap soltar` resolve */ }
|
|
639
|
+
}
|
|
640
|
+
throw e;
|
|
641
|
+
}
|
|
642
|
+
const { thread, gravada } = criada;
|
|
643
|
+
const reservaDoItem = itemDoRoadmap && gravada ? (0, roadmap_reservas_1.pegarItem)(carregado.raiz, itemDoRoadmap, { thread: thread.id }) : null;
|
|
644
|
+
// I-51 (RM-047): com a fabrica compartilhada, as outras maquinas veem a thread nova.
|
|
645
|
+
if (gravada)
|
|
646
|
+
(0, fabrica_publicar_1.publicarEmSegundoPlano)(carregado.raiz);
|
|
348
647
|
console.log(gravada ? 'Thread criada.' : 'Simulacao (--dry-run), nada foi gravado.');
|
|
648
|
+
if (reservaDoItem)
|
|
649
|
+
console.log(` roadmap: ${reservaDoItem.item} reservado para esta maquina (${reservaDoItem.reserva?.maquina})`);
|
|
349
650
|
console.log((0, thread_1.resumoDaThread)(thread));
|
|
350
651
|
console.log('');
|
|
351
652
|
console.log(` slug em 3 partes: ${(0, phase_1.descreverSlug)(thread.slug)}`);
|
|
@@ -361,7 +662,16 @@ function comandoThread(args) {
|
|
|
361
662
|
}
|
|
362
663
|
if (sub === 'list' || sub === undefined) {
|
|
363
664
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
364
|
-
|
|
665
|
+
// I-43 (D8): `--todas` abre o que o default esconde, e `--json` passa a devolver
|
|
666
|
+
// JSON de verdade. Acrescentar uma flag numa tela onde `--json` era aceito e
|
|
667
|
+
// IGNORADO em silencio (saindo 0) seria deixar dois pesos na mesma linha.
|
|
668
|
+
const todas = args.opcoes.todas === true;
|
|
669
|
+
if (args.opcoes.json === true) {
|
|
670
|
+
const linhas = (0, thread_1.threadsDaListagem)(carregado.raiz, { todas });
|
|
671
|
+
console.log(JSON.stringify({ todas, total: linhas.length, threads: linhas }, null, 2));
|
|
672
|
+
return 0;
|
|
673
|
+
}
|
|
674
|
+
console.log((0, thread_1.tabelaDeThreads)(carregado.raiz, { todas }));
|
|
365
675
|
return 0;
|
|
366
676
|
}
|
|
367
677
|
if (sub === 'status') {
|
|
@@ -372,8 +682,14 @@ function comandoThread(args) {
|
|
|
372
682
|
return 2;
|
|
373
683
|
}
|
|
374
684
|
const thread = (0, thread_1.lerThread)(carregado.raiz, id);
|
|
685
|
+
if (args.opcoes.json === true) {
|
|
686
|
+
// Idem: `ork thread status <id> --json` imprimia o TEXTO e saia 0.
|
|
687
|
+
console.log(JSON.stringify(thread, null, 2));
|
|
688
|
+
return 0;
|
|
689
|
+
}
|
|
375
690
|
console.log(`Thread ${thread.id}`);
|
|
376
|
-
|
|
691
|
+
// I-36 (T17): a linha de conducao vem da leitura unica do nucleo.
|
|
692
|
+
console.log((0, thread_1.resumoDaThread)(thread, (0, conducao_1.conducaoDaThread)(carregado.raiz, thread.id)));
|
|
377
693
|
console.log('');
|
|
378
694
|
if (thread.sessoes.length === 0) {
|
|
379
695
|
console.log(' nenhuma sessao despachada ainda');
|
|
@@ -382,7 +698,7 @@ function comandoThread(args) {
|
|
|
382
698
|
console.log(' sessoes despachadas (estado real conferido em `ork sessions`)');
|
|
383
699
|
for (const s of thread.sessoes) {
|
|
384
700
|
console.log(` ${s.slug.padEnd(24)} ${s.fase.padEnd(6)} ${s.sessionId.slice(0, 8)} ` +
|
|
385
|
-
`verificada no runtime: ${s.verificada ? 'sim' : 'nao'}`);
|
|
701
|
+
`verificada no runtime: ${s.verificada ? 'sim' : 'nao'} canal: ${(0, thread_1.canalDaSessao)(s)}`);
|
|
386
702
|
}
|
|
387
703
|
}
|
|
388
704
|
console.log('');
|
|
@@ -392,10 +708,280 @@ function comandoThread(args) {
|
|
|
392
708
|
console.error(`subcomando desconhecido: thread ${sub}`);
|
|
393
709
|
return 2;
|
|
394
710
|
}
|
|
711
|
+
/**
|
|
712
|
+
* `ork setup [modo]`: a feature #setup no nucleo.
|
|
713
|
+
*
|
|
714
|
+
* Sem argumento, imprime a pauta da entrevista (a lista topificada dos modos vivos com a
|
|
715
|
+
* config atual de cada bloco): e o texto que o orquestrador entrega ao owner quando a
|
|
716
|
+
* tag #setup chega no pedido. Com um modo, mostra/edita/reseta a config daquele modo.
|
|
717
|
+
* Toda edicao vira evento `setup_configured` no ledger do projeto.
|
|
718
|
+
*/
|
|
719
|
+
function comandoOnboarding(args) {
|
|
720
|
+
const invalido = () => { throw new Error('onboarding.input.invalid: use ork onboarding [show|set <etapa>|reset [etapa]] --conteudo <JSON> [--por Q] [--json]'); };
|
|
721
|
+
if (Object.keys(args.opcoes).some(k => !['conteudo', 'por', 'json', 'reset'].includes(k)))
|
|
722
|
+
invalido();
|
|
723
|
+
if ('json' in args.opcoes && args.opcoes.json !== true)
|
|
724
|
+
invalido();
|
|
725
|
+
if ('por' in args.opcoes && typeof args.opcoes.por !== 'string')
|
|
726
|
+
invalido();
|
|
727
|
+
const alias = 'reset' in args.opcoes;
|
|
728
|
+
const sub = alias ? 'reset' : args.posicionais[1] ?? 'show';
|
|
729
|
+
const etapa = alias ? texto(args.opcoes.reset) : args.posicionais[2];
|
|
730
|
+
if (alias && args.posicionais.length !== 1)
|
|
731
|
+
invalido();
|
|
732
|
+
if (!['show', 'set', 'reset', 'sync'].includes(sub))
|
|
733
|
+
invalido();
|
|
734
|
+
if (['show', 'sync'].includes(sub) && (args.posicionais.length > 2 || 'conteudo' in args.opcoes))
|
|
735
|
+
invalido();
|
|
736
|
+
if (sub === 'set' && (!etapa || args.posicionais.length !== 3 || typeof args.opcoes.conteudo !== 'string'))
|
|
737
|
+
invalido();
|
|
738
|
+
if (sub === 'reset' && (args.posicionais.length > 3 || 'conteudo' in args.opcoes))
|
|
739
|
+
invalido();
|
|
740
|
+
if (sub === 'sync' && 'por' in args.opcoes)
|
|
741
|
+
throw new Error('onboarding.input.invalid: sync não aceita --por; informe autoria em set ou reset.');
|
|
742
|
+
const carregado = (0, manifest_1.exigirManifesto)(), raiz = carregado.raiz, por = texto(args.opcoes.por) ?? 'owner';
|
|
743
|
+
if (sub === 'sync') {
|
|
744
|
+
const r = (0, memoria_1.sincronizarOnboarding)(carregado);
|
|
745
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : `${r.regime}${r.motivo ? ` (${r.motivo})` : ''}: ${r.detalhe}`);
|
|
746
|
+
return 0;
|
|
747
|
+
}
|
|
748
|
+
let estado;
|
|
749
|
+
if (sub === 'set') {
|
|
750
|
+
let conteudo;
|
|
751
|
+
try {
|
|
752
|
+
conteudo = JSON.parse(args.opcoes.conteudo);
|
|
753
|
+
}
|
|
754
|
+
catch {
|
|
755
|
+
return invalido();
|
|
756
|
+
}
|
|
757
|
+
estado = (0, onboarding_1.gravarEtapa)(raiz, etapa, conteudo, por);
|
|
758
|
+
}
|
|
759
|
+
else if (sub === 'reset')
|
|
760
|
+
estado = (0, onboarding_1.resetarOnboarding)(raiz, etapa, por);
|
|
761
|
+
else
|
|
762
|
+
estado = (0, onboarding_1.lerOnboarding)(raiz);
|
|
763
|
+
console.log(args.opcoes.json === true ? JSON.stringify(estado, null, 2) : (0, onboarding_1.textoDaPauta)(estado));
|
|
764
|
+
return 0;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* I-33 (D8): `ork accounts list|add|remove|check`. O login e sempre do proprio CLI com o env do
|
|
768
|
+
* perfil (`claude auth login`, `codex login`); o `ork` so guarda identidade, diretorio e estado,
|
|
769
|
+
* nunca le, copia ou migra o que o CLI grava. A lista nao tem segredo porque o store nao tem.
|
|
770
|
+
*/
|
|
771
|
+
/** A8: valor citado para colar no shell: aspas simples, e a aspa simples do proprio valor fechada e reaberta. */
|
|
772
|
+
function aspasDeShell(valor) {
|
|
773
|
+
return `'${valor.split("'").join(`'"'"'`)}'`;
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* I-33 (N2): o aviso da chave de troca entre perfis sai no proprio comando que a usa (`phase run`,
|
|
777
|
+
* `retry`, `accounts`), nao so no `ork doctor`: valor invalido nunca liga a troca em silencio.
|
|
778
|
+
*/
|
|
779
|
+
function avisarChavesDePerfis(carregado) {
|
|
780
|
+
for (const a of carregado.avisos)
|
|
781
|
+
if (a.startsWith('runtime_profiles.'))
|
|
782
|
+
console.error(`aviso: ${a}`);
|
|
783
|
+
}
|
|
784
|
+
function comandoAccounts(args) {
|
|
785
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
786
|
+
avisarChavesDePerfis(carregado);
|
|
787
|
+
const raiz = carregado.raiz;
|
|
788
|
+
const sub = args.posicionais[1] ?? 'list';
|
|
789
|
+
const conferir = (p) => p.runtime === 'claude-bg' ? (0, claude_bg_1.conferirAuth)(p) : (0, codex_1.conferirAuth)(p);
|
|
790
|
+
const imprimir = () => {
|
|
791
|
+
const store = (0, runtime_profiles_1.lerPerfis)(raiz);
|
|
792
|
+
if (args.opcoes.json === true) {
|
|
793
|
+
console.log(JSON.stringify(store, null, 2));
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
// I-49: a tabela mostra o que o despacho enxerga, com o que outra fabrica viu na mesma conta.
|
|
797
|
+
const visto = (0, runtime_profiles_1.lerPerfisComContas)(raiz);
|
|
798
|
+
console.log(visto.perfis.length === 0 ? 'Nenhum perfil configurado: cada runtime despacha pelo ambiente do processo.'
|
|
799
|
+
: (0, util_1.tabela)(runtime_profiles_1.COLUNAS_DE_PERFIS, (0, runtime_profiles_1.linhasDePerfis)(visto)));
|
|
800
|
+
// I-35: a tabela mostra horario do dono; o fuso sai uma vez, no fim da mensagem.
|
|
801
|
+
if ((0, runtime_profiles_1.perfisComHorario)(store))
|
|
802
|
+
console.log((0, horario_1.legendaDoFuso)());
|
|
803
|
+
};
|
|
804
|
+
if (sub === 'list') {
|
|
805
|
+
imprimir();
|
|
806
|
+
return 0;
|
|
807
|
+
}
|
|
808
|
+
if (sub === 'add') {
|
|
809
|
+
const id = args.posicionais[2], runtime = texto(args.opcoes.runtime), dirBruto = texto(args.opcoes.dir);
|
|
810
|
+
if (!id || !runtime || !dirBruto) {
|
|
811
|
+
console.error('uso: ork accounts add <id> --runtime claude-bg|codex --dir <diretorio> [--sem-login]');
|
|
812
|
+
return 2;
|
|
813
|
+
}
|
|
814
|
+
const dir = path.resolve(dirBruto);
|
|
815
|
+
let perfil;
|
|
816
|
+
try {
|
|
817
|
+
// A7: diretorio inacessivel ou de outro usuario e recusado antes de qualquer gravacao no store.
|
|
818
|
+
(0, runtime_profiles_1.prepararDiretorioDoPerfil)(dir);
|
|
819
|
+
const desativado = (0, runtime_profiles_1.lerPerfis)(raiz).perfis.some(p => p.id === id && p.estado === 'desativado');
|
|
820
|
+
perfil = (0, runtime_profiles_1.adicionarPerfil)(raiz, { id, runtime, dir });
|
|
821
|
+
if (desativado)
|
|
822
|
+
console.log(`Perfil ${id} reativado: mesmo id, runtime e diretorio do perfil desativado.`);
|
|
823
|
+
}
|
|
824
|
+
catch (e) {
|
|
825
|
+
console.error(`perfil recusado: ${e.message}`);
|
|
826
|
+
return 1;
|
|
827
|
+
}
|
|
828
|
+
const despacho = (0, runtime_profiles_1.perfilDeDespacho)(perfil);
|
|
829
|
+
const variavel = runtime_profiles_1.VARIAVEL_DO_PERFIL[perfil.runtime];
|
|
830
|
+
// D13: o login do claude e fixado na assinatura (`--claudeai`), nunca no Console de API.
|
|
831
|
+
const comando = perfil.runtime === 'claude-bg' ? ['claude', 'auth', 'login', '--claudeai'] : ['codex', 'login'];
|
|
832
|
+
if (args.opcoes['sem-login'] !== true && process.stdin.isTTY && process.stdout.isTTY) {
|
|
833
|
+
// Login interativo do proprio CLI, com o env do perfil sobre a assinatura higienizada.
|
|
834
|
+
const env = perfil.runtime === 'claude-bg' ? (0, claude_bg_1.ambienteDoPerfil)(despacho) : (0, codex_1.ambienteDoDespacho)(process.env, despacho);
|
|
835
|
+
(0, node_child_process_1.spawnSync)(comando[0], comando.slice(1), { stdio: 'inherit', env });
|
|
836
|
+
}
|
|
837
|
+
else {
|
|
838
|
+
console.log(`Login pendente: rode ${variavel}=${aspasDeShell(dir)} ${comando.join(' ')} e depois ork accounts check ${id}`);
|
|
839
|
+
}
|
|
840
|
+
const auth = conferir(despacho);
|
|
841
|
+
// A14: conferencia inconclusiva nao marca sem-auth; o preflight do proximo despacho confere de novo.
|
|
842
|
+
if (!auth.ok && !auth.transitorio)
|
|
843
|
+
(0, runtime_profiles_1.marcarFalhaDePerfil)(raiz, id, auth.pago
|
|
844
|
+
? { estado: 'provider-pago', esgotadoAte: null, motivo: 'cost.violation', detalhe: auth.detalhe }
|
|
845
|
+
: { estado: 'sem-auth', esgotadoAte: null, motivo: 'runtime.auth-missing', detalhe: auth.detalhe });
|
|
846
|
+
console.log(`Perfil ${id} (${perfil.runtime}) em ${dir}: ${auth.ok ? 'login de assinatura conferido'
|
|
847
|
+
: auth.transitorio ? `conferencia de login inconclusiva (${auth.detalhe}); o proximo despacho confere de novo`
|
|
848
|
+
: auth.pago ? `provider pago (${auth.detalhe}); nunca recebe despacho` : `sem login (${auth.detalhe}); fora do rodizio`}`);
|
|
849
|
+
return 0;
|
|
850
|
+
}
|
|
851
|
+
if (sub === 'remove') {
|
|
852
|
+
const id = args.posicionais[2];
|
|
853
|
+
if (!id) {
|
|
854
|
+
console.error('uso: ork accounts remove <id>');
|
|
855
|
+
return 2;
|
|
856
|
+
}
|
|
857
|
+
try {
|
|
858
|
+
(0, runtime_profiles_1.desativarPerfil)(raiz, id);
|
|
859
|
+
}
|
|
860
|
+
catch (e) {
|
|
861
|
+
console.error(e.message);
|
|
862
|
+
return 1;
|
|
863
|
+
}
|
|
864
|
+
console.log(`Perfil ${id} desativado: o diretorio e o login do CLI ficam onde estao.`);
|
|
865
|
+
return 0;
|
|
866
|
+
}
|
|
867
|
+
if (sub === 'check') {
|
|
868
|
+
const alvo = args.posicionais[2];
|
|
869
|
+
const perfis = (0, runtime_profiles_1.lerPerfis)(raiz).perfis.filter(p => p.estado !== 'desativado' && (alvo === undefined || p.id === alvo));
|
|
870
|
+
if (alvo !== undefined && perfis.length === 0) {
|
|
871
|
+
console.error(`perfil ativo "${alvo}" nao existe (veja: ork accounts list)`);
|
|
872
|
+
return 1;
|
|
873
|
+
}
|
|
874
|
+
let falhas = 0;
|
|
875
|
+
for (const p of perfis) {
|
|
876
|
+
const auth = conferir((0, runtime_profiles_1.perfilDeDespacho)(p));
|
|
877
|
+
if (auth.ok && (p.estado === 'sem-auth' || p.estado === 'provider-pago'))
|
|
878
|
+
(0, runtime_profiles_1.reativarPerfil)(raiz, p.id);
|
|
879
|
+
if (!auth.ok)
|
|
880
|
+
falhas++;
|
|
881
|
+
if (!auth.ok && auth.transitorio)
|
|
882
|
+
(0, runtime_profiles_1.registrarConferenciaInconclusiva)(raiz, p.id, auth.detalhe);
|
|
883
|
+
else if (!auth.ok) {
|
|
884
|
+
(0, runtime_profiles_1.marcarFalhaDePerfil)(raiz, p.id, auth.pago
|
|
885
|
+
? { estado: 'provider-pago', esgotadoAte: null, motivo: 'cost.violation', detalhe: auth.detalhe }
|
|
886
|
+
: { estado: 'sem-auth', esgotadoAte: null, motivo: 'runtime.auth-missing', detalhe: auth.detalhe });
|
|
887
|
+
}
|
|
888
|
+
console.log(`${p.id} (${p.runtime}): ${auth.ok ? 'login de assinatura conferido'
|
|
889
|
+
: auth.transitorio ? `conferencia de login inconclusiva, estado mantido (${auth.detalhe})`
|
|
890
|
+
: auth.pago ? `provider pago, nunca despacha (${auth.detalhe})` : `sem login (${auth.detalhe})`}`);
|
|
891
|
+
}
|
|
892
|
+
console.log('');
|
|
893
|
+
imprimir();
|
|
894
|
+
return falhas > 0 ? 1 : 0;
|
|
895
|
+
}
|
|
896
|
+
console.error(`subcomando desconhecido: accounts ${sub} (use list, add, remove ou check)`);
|
|
897
|
+
return 2;
|
|
898
|
+
}
|
|
899
|
+
function comandoSetup(args) {
|
|
900
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
901
|
+
const raiz = carregado.raiz;
|
|
902
|
+
const modoBruto = args.posicionais[1];
|
|
903
|
+
const por = texto(args.opcoes.por) ?? 'owner';
|
|
904
|
+
if (modoBruto === 'versionar') {
|
|
905
|
+
// I-52 (RM-047): o setup que vale agora vai para orkastery.setup.json, para entrar por PR.
|
|
906
|
+
const r = (0, setup_1.versionarSetup)(raiz, por);
|
|
907
|
+
if (args.opcoes.json === true) {
|
|
908
|
+
console.log(JSON.stringify({ caminho: r.caminho, setup: r.setup }, null, 2));
|
|
909
|
+
return 0;
|
|
910
|
+
}
|
|
911
|
+
console.log(`Setup versionado em ${r.caminho}.`);
|
|
912
|
+
console.log(' Leve para o repositorio por PR: dali em diante ele vale em todas as maquinas, e ork setup <modo> --bloco N passa a editar este arquivo.');
|
|
913
|
+
return 0;
|
|
914
|
+
}
|
|
915
|
+
if (!modoBruto) {
|
|
916
|
+
if (args.opcoes.reset === true) {
|
|
917
|
+
(0, setup_1.resetarSetup)(raiz, undefined, por);
|
|
918
|
+
if (args.opcoes.json === true) {
|
|
919
|
+
console.log(JSON.stringify((0, setup_1.lerSetup)(raiz), null, 2));
|
|
920
|
+
return 0;
|
|
921
|
+
}
|
|
922
|
+
console.log('Setup resetado: todos os blocos de todos os modos voltaram ao default.');
|
|
923
|
+
console.log((0, setup_1.textoDaEntrevista)(raiz));
|
|
924
|
+
return 0;
|
|
925
|
+
}
|
|
926
|
+
console.log(args.opcoes.json === true ? JSON.stringify((0, setup_1.lerSetup)(raiz), null, 2) : (0, setup_1.textoDaEntrevista)(raiz));
|
|
927
|
+
return 0;
|
|
928
|
+
}
|
|
929
|
+
const modo = (0, modos_1.parseModo)(modoBruto);
|
|
930
|
+
if (!modo) {
|
|
931
|
+
console.error(`modo de conducao desconhecido: "${modoBruto}" (aceitos: ${modos_1.ORDEM_DOS_MODOS.join(', ')})`);
|
|
932
|
+
return 2;
|
|
933
|
+
}
|
|
934
|
+
if (args.opcoes.reset === true) {
|
|
935
|
+
(0, setup_1.resetarSetup)(raiz, modo, por);
|
|
936
|
+
if (args.opcoes.json === true) {
|
|
937
|
+
console.log(JSON.stringify((0, setup_1.lerSetup)(raiz).modos[modo], null, 2));
|
|
938
|
+
return 0;
|
|
939
|
+
}
|
|
940
|
+
console.log(`Setup do modo ${modos_1.MODOS[modo].tag} resetado para o default.`);
|
|
941
|
+
console.log('');
|
|
942
|
+
console.log((0, setup_1.textoDoSetup)(raiz, modo));
|
|
943
|
+
return 0;
|
|
944
|
+
}
|
|
945
|
+
const bloco = texto(args.opcoes.bloco);
|
|
946
|
+
const runtime = texto(args.opcoes.runtime);
|
|
947
|
+
const model = texto(args.opcoes.model);
|
|
948
|
+
const effort = texto(args.opcoes.effort);
|
|
949
|
+
// I-33 (D6): `--fallback runtime:modelo[:esforco],...`; `--fallback ""` remove a ordem.
|
|
950
|
+
const fallbackBruto = args.opcoes.fallback === true ? '' : texto(args.opcoes.fallback);
|
|
951
|
+
const fallback = fallbackBruto === undefined ? undefined : fallbackBruto.split(',').map(s => s.trim()).filter(s => s !== '');
|
|
952
|
+
if (bloco === undefined && (runtime !== undefined || model !== undefined || effort !== undefined || fallback !== undefined)) {
|
|
953
|
+
console.error('para editar, informe o bloco: ork setup <modo> --bloco N [--runtime R] [--model M] [--effort E] [--fallback R:M,...]');
|
|
954
|
+
return 2;
|
|
955
|
+
}
|
|
956
|
+
if (bloco !== undefined) {
|
|
957
|
+
if (runtime === undefined && model === undefined && effort === undefined && fallback === undefined) {
|
|
958
|
+
console.error('nada para editar: informe --runtime, --model, --effort e/ou --fallback junto de --bloco');
|
|
959
|
+
return 2;
|
|
960
|
+
}
|
|
961
|
+
const r = (0, setup_1.editarBloco)(raiz, modo, Number(bloco), { runtime, model, effort, ...(fallback !== undefined ? { fallback } : {}) }, por);
|
|
962
|
+
if (!r.ok) {
|
|
963
|
+
console.error(`edicao recusada: ${r.erro}`);
|
|
964
|
+
return 1;
|
|
965
|
+
}
|
|
966
|
+
if (args.opcoes.json === true) {
|
|
967
|
+
console.log(JSON.stringify(r.setup.modos[modo], null, 2));
|
|
968
|
+
return 0;
|
|
969
|
+
}
|
|
970
|
+
console.log(`Bloco ${r.bloco} do modo ${modos_1.MODOS[modo].tag}: ` +
|
|
971
|
+
`${r.de?.runtime}/${r.de?.model}/${r.de?.effort} -> ${r.para?.runtime}/${r.para?.model}/${r.para?.effort}`);
|
|
972
|
+
console.log(` gravado em ${r.caminho}; evento setup_configured no ledger do projeto`);
|
|
973
|
+
console.log('');
|
|
974
|
+
console.log((0, setup_1.textoDoSetup)(raiz, modo));
|
|
975
|
+
return 0;
|
|
976
|
+
}
|
|
977
|
+
console.log(args.opcoes.json === true ? JSON.stringify((0, setup_1.lerSetup)(raiz).modos[modo], null, 2) : (0, setup_1.textoDoSetup)(raiz, modo));
|
|
978
|
+
return 0;
|
|
979
|
+
}
|
|
395
980
|
function comandoPhase(args) {
|
|
396
981
|
const sub = args.posicionais[1];
|
|
397
982
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
398
983
|
if (sub === 'run') {
|
|
984
|
+
avisarChavesDePerfis(carregado);
|
|
399
985
|
const id = args.posicionais[2];
|
|
400
986
|
const faseBruta = args.posicionais[3];
|
|
401
987
|
const prompt = texto(args.opcoes.prompt);
|
|
@@ -405,21 +991,37 @@ function comandoPhase(args) {
|
|
|
405
991
|
}
|
|
406
992
|
const thread = (0, thread_1.lerThread)(carregado.raiz, id);
|
|
407
993
|
const fase = (0, thread_1.exigirFase)(thread, faseBruta);
|
|
994
|
+
const conducao = conducaoDoCli(args);
|
|
408
995
|
const r = (0, phase_1.rodarFase)(carregado, id, {
|
|
409
996
|
fase,
|
|
410
997
|
prompt,
|
|
998
|
+
runtime: texto(args.opcoes.runtime),
|
|
411
999
|
model: texto(args.opcoes.model),
|
|
412
1000
|
effort: texto(args.opcoes.effort),
|
|
413
1001
|
dryRun: args.opcoes['dry-run'] === true,
|
|
1002
|
+
canal: conducao.canal,
|
|
1003
|
+
...(conducao.correlacao ? { correlacao: conducao.correlacao } : {}),
|
|
1004
|
+
...(conducao.esperarMs ? { esperarMs: conducao.esperarMs } : {}),
|
|
414
1005
|
});
|
|
415
|
-
|
|
1006
|
+
// I-36 (T12, T14): pedido repetido e segundo pedido tem resposta propria, antes dos outros gates.
|
|
1007
|
+
if (r.idempotente && r.conducao) {
|
|
1008
|
+
console.log((0, conducao_1.textoDoPedidoRepetido)(id, r.conducao));
|
|
1009
|
+
return 0;
|
|
1010
|
+
}
|
|
1011
|
+
if (r.motivo === 'conducao.em-andamento') {
|
|
1012
|
+
console.log(args.opcoes.json === true && r.recusa ? JSON.stringify(r.recusa, null, 2) : r.recusa?.texto ?? r.erro);
|
|
1013
|
+
return 3;
|
|
1014
|
+
}
|
|
1015
|
+
if (r.dryRun && !r.bloqueado) {
|
|
416
1016
|
console.log('Simulacao (--dry-run), nada foi despachado.');
|
|
417
1017
|
console.log(` slug da sessao : ${r.slug}`);
|
|
418
1018
|
console.log(` prompt : ${r.promptPath}`);
|
|
419
1019
|
console.log(` sha256 : ${r.promptSha256}`);
|
|
420
1020
|
console.log(` pausa ao fim : ${r.pausaAoFim ? 'sim' : 'nao'}`);
|
|
1021
|
+
console.log(` runtime : ${r.runtime}`);
|
|
421
1022
|
console.log(` modelo/esforco : ${r.model}/${r.effort}`);
|
|
422
|
-
|
|
1023
|
+
// O prompt inteiro nao cabe na tela: o argumento longo aparece mascarado.
|
|
1024
|
+
console.log(` comando : ${r.comando.map((c) => (c.length > 80 ? '"<prompt>"' : c)).join(' ')}`);
|
|
423
1025
|
return 0;
|
|
424
1026
|
}
|
|
425
1027
|
if (r.bloqueado) {
|
|
@@ -432,7 +1034,8 @@ function comandoPhase(args) {
|
|
|
432
1034
|
return 1;
|
|
433
1035
|
}
|
|
434
1036
|
if (!r.sessionId) {
|
|
435
|
-
|
|
1037
|
+
// I-35: o erro vai ao ledger com o ISO; o dono le no fuso dele, com o fuso dito uma vez.
|
|
1038
|
+
console.error(`Despacho falhou: ${r.erro ? (0, horario_1.localizarTextoRotulado)(r.erro) : r.erro}`);
|
|
436
1039
|
console.error(` evento registrado no ledger de ${id}`);
|
|
437
1040
|
return 1;
|
|
438
1041
|
}
|
|
@@ -441,11 +1044,17 @@ function comandoPhase(args) {
|
|
|
441
1044
|
console.log(` slug da sessao : ${r.slug} (${(0, phase_1.descreverSlug)(r.slug)})`);
|
|
442
1045
|
console.log(` prompt : ${r.promptPath}`);
|
|
443
1046
|
console.log(` sha256 : ${r.promptSha256}`);
|
|
1047
|
+
console.log(` runtime : ${r.runtime}`);
|
|
444
1048
|
console.log(` modelo/esforco : ${r.model}/${r.effort} (gravado no ledger, veja \`ork phase list\`)`);
|
|
445
1049
|
console.log(` verificada no runtime: ${r.verificada ? 'sim' : 'NAO (confira `ork sessions`)'}`);
|
|
446
1050
|
console.log(` pausa ao fim do bloco: ${r.pausaAoFim ? 'sim' : 'nao (decisao autonoma no ledger)'}`);
|
|
447
1051
|
console.log('');
|
|
448
|
-
|
|
1052
|
+
if (r.runtime === 'claude-bg') {
|
|
1053
|
+
console.log(`Acompanhe: claude attach ${r.sessionId} | ork phase list ${id}`);
|
|
1054
|
+
}
|
|
1055
|
+
else {
|
|
1056
|
+
console.log(`Acompanhe: ork phase list ${id} (eventos do despacho no log da thread)`);
|
|
1057
|
+
}
|
|
449
1058
|
return r.verificada ? 0 : 1;
|
|
450
1059
|
}
|
|
451
1060
|
if (sub === 'list') {
|
|
@@ -460,12 +1069,137 @@ function comandoPhase(args) {
|
|
|
460
1069
|
console.error(`subcomando desconhecido: phase ${sub}`);
|
|
461
1070
|
return 2;
|
|
462
1071
|
}
|
|
1072
|
+
function comandoLedger(args) {
|
|
1073
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1074
|
+
const sub = args.posicionais[1];
|
|
1075
|
+
if (sub === 'stats') {
|
|
1076
|
+
const desde = texto(args.opcoes.desde);
|
|
1077
|
+
if (!desde)
|
|
1078
|
+
throw Error('uso: ork ledger stats --desde 7d [--ate ISO] [--thread T] [--modo M] [--runtime R] [--json]');
|
|
1079
|
+
const r = (0, ledger_stats_1.coletarEstatisticas)(carregado.raiz, { desde, ate: texto(args.opcoes.ate), thread: texto(args.opcoes.thread), modo: texto(args.opcoes.modo), runtime: texto(args.opcoes.runtime) });
|
|
1080
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : (0, ledger_stats_1.textoDasEstatisticas)(r));
|
|
1081
|
+
return 0;
|
|
1082
|
+
}
|
|
1083
|
+
if (sub === 'estimate') {
|
|
1084
|
+
const thread = args.posicionais[2], semIa = Number(texto(args.opcoes['sem-ia'])), iaSemOrk = Number(texto(args.opcoes['ia-sem-ork']));
|
|
1085
|
+
const por = texto(args.opcoes.por), metodo = texto(args.opcoes.metodo), premissas = texto(args.opcoes.premissas);
|
|
1086
|
+
if (!thread || !por || !metodo || !premissas)
|
|
1087
|
+
throw Error('uso: ork ledger estimate <thread-id> --sem-ia H --ia-sem-ork H --por Q --metodo M --premissas P [--incerteza I]');
|
|
1088
|
+
const e = (0, ledger_stats_1.registrarEstimativaPlano)(carregado.raiz, thread, { semIaHoras: semIa, iaSemOrkHoras: iaSemOrk, por, metodo, premissas, incerteza: texto(args.opcoes.incerteza) });
|
|
1089
|
+
console.log(args.opcoes.json === true ? JSON.stringify(e, null, 2) : `Estimativa PLAN registrada em ${thread}: sem IA ${semIa} h; IA sem Orkastery ${iaSemOrk} h.`);
|
|
1090
|
+
return 0;
|
|
1091
|
+
}
|
|
1092
|
+
throw Error('uso: ork ledger stats|estimate ...');
|
|
1093
|
+
}
|
|
1094
|
+
/**
|
|
1095
|
+
* `ork sessions hitl`: quem, entre as sessoes do runtime, espera o humano AGORA.
|
|
1096
|
+
*
|
|
1097
|
+
* Complementa o `ork monitor`, que e thread-centrico: aqui a varredura parte das SESSOES,
|
|
1098
|
+
* entao ela enxerga a sessao `claude --bg` que travou em HITL sem ter thread nenhuma --
|
|
1099
|
+
* o buraco exato do incidente de 05/09/2026 (codigo 2FA do `npm publish`).
|
|
1100
|
+
*
|
|
1101
|
+
* O `--exigir-limpo` transforma o radar em watchdog: sai != 0 enquanto houver sessao
|
|
1102
|
+
* esperando humano, entao um cron ou o proprio orquestrador trata "tem gente esperando"
|
|
1103
|
+
* como falha acionavel, sem precisar interpretar texto.
|
|
1104
|
+
*/
|
|
1105
|
+
function comandoSessionsHitl(args, raiz) {
|
|
1106
|
+
const bruto = texto(args.opcoes.atencao);
|
|
1107
|
+
const atencaoMin = bruto === undefined ? undefined : Number(bruto);
|
|
1108
|
+
if (atencaoMin !== undefined && (!Number.isFinite(atencaoMin) || atencaoMin < 0)) {
|
|
1109
|
+
console.error(`--atencao espera minutos (inteiro >= 0), recebeu "${bruto}"`);
|
|
1110
|
+
return 2;
|
|
1111
|
+
}
|
|
1112
|
+
const radar = (0, hitl_1.varrerSessoes)({
|
|
1113
|
+
raiz,
|
|
1114
|
+
registrar: args.opcoes.registrar === true,
|
|
1115
|
+
escopo: texto(args.opcoes.escopo)?.split(',').map(s => s.trim()),
|
|
1116
|
+
registrarMaquina: args.opcoes['registrar-maquina'] === true,
|
|
1117
|
+
linhasLogs: texto(args.opcoes.linhas) === undefined ? undefined : Number(texto(args.opcoes.linhas)),
|
|
1118
|
+
soDaRaiz: args.opcoes['so-da-raiz'] === true,
|
|
1119
|
+
soParadas: args.opcoes['so-paradas'] === true,
|
|
1120
|
+
semLogs: args.opcoes['sem-logs'] === true,
|
|
1121
|
+
atencaoMin,
|
|
1122
|
+
});
|
|
1123
|
+
console.log(args.opcoes.json === true ? JSON.stringify(radar, null, 2) : (0, hitl_1.textoDoRadar)(radar));
|
|
1124
|
+
if (!radar.runtimeConsultado)
|
|
1125
|
+
return 1;
|
|
1126
|
+
if (args.opcoes['exigir-limpo'] === true)
|
|
1127
|
+
return radar.resumo.precisamDeHumano > 0 ? 1 : 0;
|
|
1128
|
+
return 0;
|
|
1129
|
+
}
|
|
463
1130
|
function comandoSessions(args) {
|
|
464
1131
|
const sub = args.posicionais[1];
|
|
465
1132
|
const carregado = (0, manifest_1.carregarManifesto)();
|
|
466
1133
|
const raiz = carregado?.raiz ?? process.cwd();
|
|
1134
|
+
if (sub === 'watch') {
|
|
1135
|
+
const id = texto(args.opcoes.thread);
|
|
1136
|
+
if (!carregado || !id) {
|
|
1137
|
+
console.error('uso: ork sessions watch --thread T [--sessao ID] [--once]');
|
|
1138
|
+
return 2;
|
|
1139
|
+
}
|
|
1140
|
+
const thread = (0, thread_1.lerThread)(raiz, id);
|
|
1141
|
+
const sessionId = texto(args.opcoes.sessao) ?? thread.sessoes.at(-1)?.sessionId;
|
|
1142
|
+
if (!sessionId || !thread.sessoes.some(s => s.sessionId === sessionId))
|
|
1143
|
+
throw new Error('sessão não pertence à thread');
|
|
1144
|
+
console.log(JSON.stringify(args.opcoes.once === true ? (0, session_watcher_1.observarSessao)(carregado, sessionId) : { pid: (0, session_watcher_1.iniciarWatcher)(raiz, sessionId) }));
|
|
1145
|
+
return 0;
|
|
1146
|
+
}
|
|
1147
|
+
if (sub === 'event') {
|
|
1148
|
+
const tipo = texto(args.opcoes.tipo), sessao = texto(args.opcoes.sessao);
|
|
1149
|
+
if (!carregado || !tipo || !sessao) {
|
|
1150
|
+
console.error('uso: ork sessions event --tipo <tipo> --sessao <id> < payload.json (máximo 16384 bytes)');
|
|
1151
|
+
return 2;
|
|
1152
|
+
}
|
|
1153
|
+
try {
|
|
1154
|
+
console.log(JSON.stringify((0, session_events_1.ingerirEvento)(raiz, sessao, tipo, (0, session_events_1.lerPayloadSensor)())));
|
|
1155
|
+
return 0;
|
|
1156
|
+
}
|
|
1157
|
+
catch (e) {
|
|
1158
|
+
console.error(`evento recusado: ${e.message}`);
|
|
1159
|
+
return 1;
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
467
1162
|
if (sub === undefined || sub === 'list') {
|
|
468
|
-
|
|
1163
|
+
const r = (0, sessoes_inventario_1.inventariarSessoes)(raiz, { todas: args.opcoes.all === true, global: args.opcoes.global === true });
|
|
1164
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : (0, sessoes_1.textoDoInventario)(r));
|
|
1165
|
+
return !r.ok || (args.opcoes['exigir-limpo'] === true && r.semThread > 0) ? 1 : 0;
|
|
1166
|
+
}
|
|
1167
|
+
if (sub === 'hitl') {
|
|
1168
|
+
return comandoSessionsHitl(args, carregado ? raiz : '');
|
|
1169
|
+
}
|
|
1170
|
+
if (sub === 'request') {
|
|
1171
|
+
const id = args.posicionais[2], sessionId = args.posicionais[3];
|
|
1172
|
+
const fase = texto(args.opcoes.fase), runtime = texto(args.opcoes.runtime), pergunta = texto(args.opcoes.pergunta);
|
|
1173
|
+
if (!id || !sessionId || !fase || !types_1.FASES.includes(fase) || !runtime)
|
|
1174
|
+
throw new Error('sessions request exige thread, UUID, --fase e --runtime; --pergunta só confere o conteúdo nativo');
|
|
1175
|
+
console.log(JSON.stringify((0, hitl_sessions_1.abrirPedidoSessao)(raiz, id, sessionId, { fase: fase, runtime, pergunta, prazo: texto(args.opcoes.prazo) })));
|
|
1176
|
+
return 0;
|
|
1177
|
+
}
|
|
1178
|
+
if (sub === 'answer') {
|
|
1179
|
+
const id = args.posicionais[2], pedido = args.posicionais[3];
|
|
1180
|
+
if (!id || !pedido || args.opcoes.stdin !== true)
|
|
1181
|
+
throw new Error('sessions answer exige thread, pedido e envelope autenticado em --stdin');
|
|
1182
|
+
const r = (0, hitl_gates_1.lerRespostaStdin)({ origem: texto(args.opcoes.origem), por: texto(args.opcoes.por),
|
|
1183
|
+
mensagem: texto(args.opcoes.mensagem), canal: texto(args.opcoes.canal), conta: texto(args.opcoes.conta) });
|
|
1184
|
+
console.log(JSON.stringify((0, hitl_sessions_1.responderSessao)(raiz, id, pedido, r)));
|
|
1185
|
+
return 0;
|
|
1186
|
+
}
|
|
1187
|
+
if (sub === 'reconcile') {
|
|
1188
|
+
// FX3: fecha um envio pendente so com (thread, pedido). Nao reenvia e nao re-elicita:
|
|
1189
|
+
// pergunta ao receptor, pelo recibo correlacionado, se ele recebeu aquele envioId.
|
|
1190
|
+
const id = args.posicionais[2], pedido = args.posicionais[3];
|
|
1191
|
+
if (!id || !pedido)
|
|
1192
|
+
throw new Error('sessions reconcile exige thread e pedido');
|
|
1193
|
+
const r = (0, hitl_sessions_1.reconciliarEnvioDeSessao)(raiz, id, pedido);
|
|
1194
|
+
console.log(JSON.stringify(r));
|
|
1195
|
+
return r.estado === 'entregue' ? 0 : 1;
|
|
1196
|
+
}
|
|
1197
|
+
if (sub === 'supersede') {
|
|
1198
|
+
const id = args.posicionais[2], sessionId = args.posicionais[3];
|
|
1199
|
+
const fase = texto(args.opcoes.fase), runtime = texto(args.opcoes.runtime);
|
|
1200
|
+
if (!id || !sessionId || !fase || !types_1.FASES.includes(fase) || !runtime)
|
|
1201
|
+
throw new Error('sessions supersede exige thread, UUID, --fase e --runtime');
|
|
1202
|
+
console.log(JSON.stringify((0, hitl_sessions_1.superarSessao)(raiz, id, sessionId, fase, runtime)));
|
|
469
1203
|
return 0;
|
|
470
1204
|
}
|
|
471
1205
|
const chave = args.posicionais[2];
|
|
@@ -473,25 +1207,110 @@ function comandoSessions(args) {
|
|
|
473
1207
|
console.error(`uso: ork sessions ${sub} <sessao>`);
|
|
474
1208
|
return 2;
|
|
475
1209
|
}
|
|
1210
|
+
if (sub === 'adopt') {
|
|
1211
|
+
const r = (0, sessoes_adopt_1.adotarSessao)((0, manifest_1.exigirManifesto)(), chave);
|
|
1212
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) :
|
|
1213
|
+
`${r.detalhe}${r.vinculo ? `: ${r.sessionId} -> ${r.vinculo.thread} (${r.vinculo.raiz})` : ''}`);
|
|
1214
|
+
return r.ok ? 0 : 1;
|
|
1215
|
+
}
|
|
476
1216
|
if (sub === 'logs') {
|
|
477
1217
|
const n = Number(texto(args.opcoes.linhas) ?? '60');
|
|
478
|
-
const r = (0,
|
|
1218
|
+
const r = (0, sessoes_2.logsDaSessao)(chave, Number.isFinite(n) ? n : 60);
|
|
479
1219
|
console.log(r.texto);
|
|
480
1220
|
return r.codigo;
|
|
481
1221
|
}
|
|
482
1222
|
if (sub === 'stop') {
|
|
483
|
-
const r = (0,
|
|
1223
|
+
const r = (0, sessoes_2.pararSessao)(chave);
|
|
484
1224
|
console.log(r.texto);
|
|
485
1225
|
return r.codigo;
|
|
486
1226
|
}
|
|
487
1227
|
if (sub === 'attach') {
|
|
488
|
-
const r = (0,
|
|
1228
|
+
const r = (0, sessoes_2.comandoDeAttach)(chave);
|
|
489
1229
|
console.log(r.texto);
|
|
490
1230
|
return r.codigo;
|
|
491
1231
|
}
|
|
492
1232
|
console.error(`subcomando desconhecido: sessions ${sub}`);
|
|
493
1233
|
return 2;
|
|
494
1234
|
}
|
|
1235
|
+
/**
|
|
1236
|
+
* I-41 (GO-FIX 1, B4): a decisao que a sessao toma sem perguntar ao dono vai ao ledger por aqui,
|
|
1237
|
+
* com o que foi decidido, o porque, como mudar, o custo de reverter, o criterio escrito, quem
|
|
1238
|
+
* decidiu e a evidencia. E assim que ela chega ao dono no resumo, em vez de sumir na conversa.
|
|
1239
|
+
*/
|
|
1240
|
+
function comandoDecisao(args) {
|
|
1241
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1242
|
+
const sub = args.posicionais[1], id = args.posicionais[2];
|
|
1243
|
+
if (sub === 'registrar') {
|
|
1244
|
+
const campo = (nome) => {
|
|
1245
|
+
const v = texto(args.opcoes[nome]);
|
|
1246
|
+
if (!v)
|
|
1247
|
+
throw new Error(`decisao registrar exige --${nome}`);
|
|
1248
|
+
return v;
|
|
1249
|
+
};
|
|
1250
|
+
if (!id)
|
|
1251
|
+
throw new Error('uso: ork decisao registrar <thread-id> --decidido D --porque P ...');
|
|
1252
|
+
const bruto = campo('criterio'), separador = bruto.indexOf(':');
|
|
1253
|
+
const tipo = bruto.slice(0, separador), referencia = bruto.slice(separador + 1);
|
|
1254
|
+
if (separador < 1 || !['manifesto', 'ledger', 'medicao'].includes(tipo) || !referencia.trim()) {
|
|
1255
|
+
throw new Error('decisao registrar: --criterio manifesto:CHAVE, ledger:REF ou medicao:COMANDO');
|
|
1256
|
+
}
|
|
1257
|
+
const { pedido, evento } = (0, decisao_autonoma_1.registrarDecisao)(carregado.raiz, id, {
|
|
1258
|
+
decidido: campo('decidido'), porque: campo('porque'), comoMudar: campo('como-mudar'),
|
|
1259
|
+
custoDeReverter: { agora: campo('custo-agora'), depois: campo('custo-depois') },
|
|
1260
|
+
criterio: { tipo, referencia }, quemDecidiu: campo('quem'), evidencia: campo('evidencia'),
|
|
1261
|
+
razao: texto(args.opcoes.razao), reverte: texto(args.opcoes.reverte),
|
|
1262
|
+
});
|
|
1263
|
+
const placar = (0, decisao_autonoma_1.placarDaThread)((0, ledger_1.lerLedger)((0, thread_1.dirThread)(carregado.raiz, id))).find(f => f.fase === pedido.fase);
|
|
1264
|
+
console.log(JSON.stringify({ ok: true, pedidoId: pedido.id, eventId: evento.eventId, fase: pedido.fase, placar }));
|
|
1265
|
+
return 0;
|
|
1266
|
+
}
|
|
1267
|
+
if (sub === 'placar') {
|
|
1268
|
+
if (!id)
|
|
1269
|
+
throw new Error('uso: ork decisao placar <thread-id> [--json]');
|
|
1270
|
+
(0, thread_1.lerThread)(carregado.raiz, id);
|
|
1271
|
+
const placar = (0, decisao_autonoma_1.placarDaThread)((0, ledger_1.lerLedger)((0, thread_1.dirThread)(carregado.raiz, id)));
|
|
1272
|
+
const taxa = (0, decisao_autonoma_1.taxaDeReversao)(placar);
|
|
1273
|
+
if (args.opcoes.json === true) {
|
|
1274
|
+
console.log(JSON.stringify({ thread: id, limiar: decisao_autonoma_1.LIMIAR_DE_DECISOES_POR_FASE, taxaDeReversao: taxa, fases: placar }, null, 2));
|
|
1275
|
+
return 0;
|
|
1276
|
+
}
|
|
1277
|
+
console.log((0, util_1.tabela)(['FASE', 'DECIDIDAS', 'INFORMADAS', 'PERGUNTAS', 'REVERTIDAS', 'SEM RASTRO', 'LIMIAR'], placar.map(f => [f.fase, String(f.decididas), String(f.informadas), String(f.perguntas), String(f.revertidas),
|
|
1278
|
+
String(f.semRastro), f.acimaDoLimiar ? `acima de ${decisao_autonoma_1.LIMIAR_DE_DECISOES_POR_FASE}: revisar` : 'ok'])));
|
|
1279
|
+
console.log(`\ntaxa de reversão das decisões informadas: ${taxa === null ? 'sem decisão informada ainda' : `${Math.round(taxa * 100)}%`}`);
|
|
1280
|
+
return 0;
|
|
1281
|
+
}
|
|
1282
|
+
throw new Error('uso: ork decisao registrar|placar <thread-id>');
|
|
1283
|
+
}
|
|
1284
|
+
/**
|
|
1285
|
+
* I-50 (RM-039): a tag que o dono manda no Telegram, pelo terminal. Sem tag, mostra a cadencia em
|
|
1286
|
+
* vigor. O `#` e opcional porque o shell trata `#` no inicio da palavra como comentario.
|
|
1287
|
+
*/
|
|
1288
|
+
function comandoCadenciaDoPulse(args) {
|
|
1289
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1290
|
+
if (args.posicionais.length > 3)
|
|
1291
|
+
throw new Error('pulse cadencia: uma tag por vez');
|
|
1292
|
+
const bruta = args.posicionais[2];
|
|
1293
|
+
const agora = new Date().toISOString();
|
|
1294
|
+
if (bruta !== undefined) {
|
|
1295
|
+
const lido = (0, pulse_resposta_1.interpretarRespostaDoPulse)(bruta.trim().startsWith('#') ? bruta : `#${bruta.trim()}`);
|
|
1296
|
+
if (lido.forma !== 'cadencia') {
|
|
1297
|
+
throw new Error(`pulse cadencia: tag desconhecida "${bruta}"; use ${Object.keys(pulse_cadencia_1.CADENCIAS).join(', ')}`);
|
|
1298
|
+
}
|
|
1299
|
+
(0, pulse_cadencia_1.gravarCadencia)(carregado.raiz, lido.tag, { por: texto(args.opcoes.por) ?? (0, node_os_1.userInfo)().username,
|
|
1300
|
+
canal: texto(args.opcoes.canal) ?? 'terminal', em: agora });
|
|
1301
|
+
}
|
|
1302
|
+
const vigente = (0, pulse_cadencia_1.lerCadencia)(carregado.raiz);
|
|
1303
|
+
if (args.opcoes.json === true) {
|
|
1304
|
+
console.log(JSON.stringify({ tag: vigente.tag, janelaMin: vigente.janelaMin, ancoraMin: vigente.ancoraMin,
|
|
1305
|
+
descricao: vigente.descricao, gravada: vigente.gravada, proximaJanela: (0, pulse_cadencia_1.inicioDaProximaJanela)(vigente, agora) }, null, 2));
|
|
1306
|
+
return 0;
|
|
1307
|
+
}
|
|
1308
|
+
console.log((0, pulse_cadencia_1.textoDaCadencia)(vigente, agora));
|
|
1309
|
+
console.log(vigente.gravada
|
|
1310
|
+
? `Trocada por ${vigente.gravada.por} (${vigente.gravada.canal}) em ${(0, horario_1.formatarDataHoraRotulada)(vigente.gravada.em)}.`
|
|
1311
|
+
: 'Nenhuma tag gravada: vale a cadência padrão.');
|
|
1312
|
+
return 0;
|
|
1313
|
+
}
|
|
495
1314
|
function comandoClaims(args) {
|
|
496
1315
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
497
1316
|
const sub = args.posicionais[1];
|
|
@@ -522,6 +1341,11 @@ function comandoClaims(args) {
|
|
|
522
1341
|
console.log('');
|
|
523
1342
|
console.log('AVISO: alegacao negativa sem comando de verificacao reprova em `ork verify`.');
|
|
524
1343
|
}
|
|
1344
|
+
// I-53 (RM-037, P6): o lint avisa aqui; a suite inteira e recusada no `ci prepare`.
|
|
1345
|
+
for (const a of claim.lint ?? []) {
|
|
1346
|
+
console.log('');
|
|
1347
|
+
console.log(`AVISO: ${(0, claim_lint_1.linhaDoLintDeClaim)(claim.id, a)}${a.regra === 'suite-inteira' ? '. O `ci prepare` recusa esta claim.' : ''}`);
|
|
1348
|
+
}
|
|
525
1349
|
return 0;
|
|
526
1350
|
}
|
|
527
1351
|
if (sub === 'verificar') {
|
|
@@ -555,6 +1379,19 @@ function comandoClaims(args) {
|
|
|
555
1379
|
console.log(' o historico da alegacao continua no claims.jsonl e no ledger.');
|
|
556
1380
|
return 0;
|
|
557
1381
|
}
|
|
1382
|
+
if (sub === 'ausente') {
|
|
1383
|
+
const id = args.posicionais[2];
|
|
1384
|
+
const paths = (texto(args.opcoes.paths) ?? '').split(',').map((p) => p.trim()).filter(Boolean);
|
|
1385
|
+
const motivo = texto(args.opcoes.motivo);
|
|
1386
|
+
if (!id || paths.length === 0 || !motivo) {
|
|
1387
|
+
console.error('uso: ork claims ausente <thread-id> --paths A,B --motivo "<motivo>" [--commit SHA]');
|
|
1388
|
+
return 2;
|
|
1389
|
+
}
|
|
1390
|
+
(0, prova_minima_1.registrarProvaAusente)(carregado.raiz, id, { paths, motivo, commit: texto(args.opcoes.commit) });
|
|
1391
|
+
console.log(`Ausencia de prova registrada na thread ${id}: ${paths.join(', ')}.`);
|
|
1392
|
+
console.log(` motivo ${motivo}`);
|
|
1393
|
+
return 0;
|
|
1394
|
+
}
|
|
558
1395
|
if (sub === 'list' || sub === undefined) {
|
|
559
1396
|
const id = args.posicionais[2];
|
|
560
1397
|
if (!id) {
|
|
@@ -571,11 +1408,12 @@ function comandoVerify(args) {
|
|
|
571
1408
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
572
1409
|
const id = args.posicionais[1];
|
|
573
1410
|
if (!id) {
|
|
574
|
-
console.error('uso: ork verify <thread-id> [--baseline] [--so-claims]');
|
|
1411
|
+
console.error('uso: ork verify <thread-id> [--baseline] [--so-claims] [--canal C] [--esperar [min]]');
|
|
575
1412
|
return 2;
|
|
576
1413
|
}
|
|
1414
|
+
const conducao = conducaoDoCli(args);
|
|
577
1415
|
if (args.opcoes.baseline === true) {
|
|
578
|
-
const b = (0, verify_1.gravarBaseline)(carregado, id);
|
|
1416
|
+
const b = (0, verify_1.gravarBaseline)(carregado, id, undefined, conducao);
|
|
579
1417
|
console.log(`Baseline gravada para a thread ${id}.`);
|
|
580
1418
|
console.log(` commit ${b.commit}`);
|
|
581
1419
|
for (const c of b.comandos) {
|
|
@@ -586,13 +1424,67 @@ function comandoVerify(args) {
|
|
|
586
1424
|
}
|
|
587
1425
|
return 0;
|
|
588
1426
|
}
|
|
589
|
-
const r = (0, verify_1.verificar)(carregado, id, { soClaims: args.opcoes['so-claims'] === true });
|
|
1427
|
+
const r = (0, verify_1.verificar)(carregado, id, { soClaims: args.opcoes['so-claims'] === true, conducao });
|
|
590
1428
|
console.log((0, verify_1.textoDoVerify)(r));
|
|
591
1429
|
return r.ok ? 0 : 1;
|
|
592
1430
|
}
|
|
1431
|
+
/**
|
|
1432
|
+
* `ork conducao status|assumir` (I-36, T15): quem conduz a thread agora, e o handoff explicito. O
|
|
1433
|
+
* status tambem libera, com prova no ledger, a conducao que ficou sem dono (T16).
|
|
1434
|
+
*/
|
|
1435
|
+
function comandoConducao(args) {
|
|
1436
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1437
|
+
const sub = args.posicionais[1];
|
|
1438
|
+
const id = args.posicionais[2];
|
|
1439
|
+
if (sub === 'status') {
|
|
1440
|
+
if (!id)
|
|
1441
|
+
throw new Error('uso: ork conducao status <thread-id> [--json]');
|
|
1442
|
+
(0, thread_1.lerThread)(carregado.raiz, id);
|
|
1443
|
+
(0, conducao_1.liberarSeOrfa)(carregado.raiz, id);
|
|
1444
|
+
const atual = (0, conducao_1.conducaoDaThread)(carregado.raiz, id);
|
|
1445
|
+
console.log(args.opcoes.json === true ? JSON.stringify({ thread: id, conducao: atual }, null, 2) : (0, conducao_1.textoDoStatusDaConducao)(id, atual));
|
|
1446
|
+
return 0;
|
|
1447
|
+
}
|
|
1448
|
+
if (sub === 'assumir') {
|
|
1449
|
+
const por = texto(args.opcoes.por), motivo = texto(args.opcoes.motivo);
|
|
1450
|
+
if (!id || !por || !motivo)
|
|
1451
|
+
throw new Error('uso: ork conducao assumir <thread-id> --por <quem> --motivo "<por que>" [--canal C]');
|
|
1452
|
+
const r = (0, conducao_1.assumirConducao)(carregado.raiz, id, { por, motivo, canal: conducaoDoCli(args).canal });
|
|
1453
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : `${r.ok ? 'Conducao assumida.' : 'Handoff recusado.'} ${r.detalhe}`);
|
|
1454
|
+
return r.ok ? 0 : 3;
|
|
1455
|
+
}
|
|
1456
|
+
throw new Error('uso: ork conducao status|assumir <thread-id>');
|
|
1457
|
+
}
|
|
593
1458
|
function comandoGate(args) {
|
|
594
1459
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
595
1460
|
const sub = args.posicionais[1];
|
|
1461
|
+
if (sub === 'context') {
|
|
1462
|
+
const id = args.posicionais[2], pedido = args.posicionais[3];
|
|
1463
|
+
if (!id || !pedido || args.posicionais.length !== 4 ||
|
|
1464
|
+
Object.entries(args.opcoes).some(([k, v]) => k !== 'native-offer-stdin' || v !== true))
|
|
1465
|
+
throw Error('uso: ork gate context <thread> <pedido> [--native-offer-stdin]');
|
|
1466
|
+
const view = (0, hitl_gates_1.contextoDoPedidoNativo)(carregado.raiz, id, pedido);
|
|
1467
|
+
const callback = args.opcoes['native-offer-stdin'] ? (0, hitl_native_offer_1.readNativeOfferStdin)() : undefined;
|
|
1468
|
+
console.log(JSON.stringify({ ...view, canais: (0, hitl_presentation_1.ofertaDoPedido)(view.pedido, [], callback === undefined ? undefined : { callback, raiz: carregado.raiz }),
|
|
1469
|
+
apresentacao: (0, hitl_presentation_1.apresentarDecisao)(view.pedido), prazoLocal: (0, hitl_presentation_1.prazoLocalDoPedido)(view.pedido) }));
|
|
1470
|
+
return 0;
|
|
1471
|
+
}
|
|
1472
|
+
if (sub === 'request') {
|
|
1473
|
+
const id = args.posicionais[2];
|
|
1474
|
+
if (!id)
|
|
1475
|
+
throw new Error('gate request exige thread');
|
|
1476
|
+
console.log(JSON.stringify((0, hitl_gates_1.abrirPedidoGate)(carregado.raiz, id, texto(args.opcoes.motivo))));
|
|
1477
|
+
return 0;
|
|
1478
|
+
}
|
|
1479
|
+
if (sub === 'answer') {
|
|
1480
|
+
const id = args.posicionais[2], pedido = args.posicionais[3];
|
|
1481
|
+
if (!id || !pedido || args.opcoes['resposta-stdin'] !== true || args.opcoes.resposta !== undefined)
|
|
1482
|
+
throw new Error('gate answer exige thread, pedido e --resposta-stdin');
|
|
1483
|
+
const r = (0, hitl_gates_1.lerRespostaStdin)({ por: texto(args.opcoes.por), mensagem: texto(args.opcoes.mensagem),
|
|
1484
|
+
origem: texto(args.opcoes.origem), canal: texto(args.opcoes.canal), conta: texto(args.opcoes.conta) });
|
|
1485
|
+
console.log(JSON.stringify((0, hitl_gates_1.responderGate)(carregado.raiz, id, pedido, r)));
|
|
1486
|
+
return 0;
|
|
1487
|
+
}
|
|
596
1488
|
if (sub === 'next') {
|
|
597
1489
|
const id = args.posicionais[2];
|
|
598
1490
|
if (!id) {
|
|
@@ -628,7 +1520,7 @@ function comandoGate(args) {
|
|
|
628
1520
|
console.log(`Autorizacao humana registrada no ledger da thread ${id}.`);
|
|
629
1521
|
console.log(` sobre ${sobre}`);
|
|
630
1522
|
console.log(` autorizado por ${por}`);
|
|
631
|
-
console.log(` quando ${e.ts}`);
|
|
1523
|
+
console.log(` quando ${(0, horario_1.formatarDataHoraRotulada)(e.ts)}`);
|
|
632
1524
|
return 0;
|
|
633
1525
|
}
|
|
634
1526
|
console.error(`subcomando desconhecido: gate ${sub}`);
|
|
@@ -694,7 +1586,7 @@ function comandoRetry(args) {
|
|
|
694
1586
|
}
|
|
695
1587
|
console.log('Sinal de rate limit reconhecido no stderr do runtime:');
|
|
696
1588
|
console.log(` fonte da hora ${sinal.fonte}`);
|
|
697
|
-
console.log(` reset em ${sinal.resetEm
|
|
1589
|
+
console.log(` reset em ${sinal.resetEm ? (0, horario_1.formatarDataHoraRotulada)(sinal.resetEm) : '(o runtime nao disse a hora)'}`);
|
|
698
1590
|
console.log(` trecho ${sinal.trecho}`);
|
|
699
1591
|
if (sinal.resetEm === null) {
|
|
700
1592
|
console.log('');
|
|
@@ -704,6 +1596,7 @@ function comandoRetry(args) {
|
|
|
704
1596
|
return 0;
|
|
705
1597
|
}
|
|
706
1598
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1599
|
+
avisarChavesDePerfis(carregado);
|
|
707
1600
|
if (sub === 'plan' || sub === 'run') {
|
|
708
1601
|
const id = args.posicionais[2];
|
|
709
1602
|
if (!id) {
|
|
@@ -726,6 +1619,10 @@ function comandoRetry(args) {
|
|
|
726
1619
|
console.log((0, retry_1.textoDoPlano)(plano));
|
|
727
1620
|
return 0;
|
|
728
1621
|
}
|
|
1622
|
+
// I-36 (D2): `--esperar` espera a conducao em andamento terminar antes de executar a retomada.
|
|
1623
|
+
const conducao = conducaoDoCli(args);
|
|
1624
|
+
if (conducao.esperarMs && args.opcoes['dry-run'] !== true)
|
|
1625
|
+
(0, conducao_1.esperarConducaoLivre)(carregado.raiz, id, conducao.esperarMs);
|
|
729
1626
|
const r = (0, retry_1.executarRetry)(carregado, id, {
|
|
730
1627
|
...opcoes,
|
|
731
1628
|
dryRun: args.opcoes['dry-run'] === true,
|
|
@@ -750,7 +1647,7 @@ function comandoRetry(args) {
|
|
|
750
1647
|
const espera = (0, ratelimit_1.lerFilaDeRetomada)(carregado.raiz).filter((p) => p.estado === 'aguardando');
|
|
751
1648
|
if (espera.length > 0) {
|
|
752
1649
|
console.log('');
|
|
753
|
-
console.log(`Proxima janela: ${espera[0].liberaEm} (${(0, ratelimit_1.faltaPara)(espera[0])}).`);
|
|
1650
|
+
console.log(`Proxima janela: ${(0, horario_1.formatarDataHora)(espera[0].liberaEm)} (${(0, ratelimit_1.faltaPara)(espera[0])}).`);
|
|
754
1651
|
console.log('Retome com: ork retry resume');
|
|
755
1652
|
}
|
|
756
1653
|
return 0;
|
|
@@ -810,9 +1707,10 @@ function comandoFix(args) {
|
|
|
810
1707
|
console.error('uso: ork fix open <thread-id> [--so-claims] [--reverify]');
|
|
811
1708
|
return 2;
|
|
812
1709
|
}
|
|
813
|
-
const
|
|
1710
|
+
const conducao = conducaoDoCli(args);
|
|
1711
|
+
const rodada = (0, fix_1.abrirRodada)(carregado, id, { soClaims: args.opcoes['so-claims'] === true, conducao });
|
|
814
1712
|
const reverify = args.opcoes.reverify === true && rodada.correcoes.length > 0
|
|
815
|
-
? (0, fix_1.reverificar)(carregado, id, { rodada: rodada.rodada })
|
|
1713
|
+
? (0, fix_1.reverificar)(carregado, id, { rodada: rodada.rodada, conducao })
|
|
816
1714
|
: null;
|
|
817
1715
|
if (args.opcoes.json === true) {
|
|
818
1716
|
console.log(JSON.stringify({ rodada, reverify }, null, 2));
|
|
@@ -864,6 +1762,7 @@ function comandoFix(args) {
|
|
|
864
1762
|
}
|
|
865
1763
|
const rodadaBruta = texto(args.opcoes.rodada);
|
|
866
1764
|
const r = (0, fix_1.reverificar)(carregado, id, {
|
|
1765
|
+
conducao: conducaoDoCli(args),
|
|
867
1766
|
rodada: rodadaBruta ? Number(rodadaBruta) : undefined,
|
|
868
1767
|
parcial: args.opcoes.parcial === true,
|
|
869
1768
|
});
|
|
@@ -918,6 +1817,30 @@ function comandoHandoff(args) {
|
|
|
918
1817
|
}
|
|
919
1818
|
function comandoShip(args) {
|
|
920
1819
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1820
|
+
if (args.posicionais[1] === 'registrar-pr') {
|
|
1821
|
+
// I-57 (RM-008): a entrega feita por PR vira ship_done, provada no remoto e no CI.
|
|
1822
|
+
const alvo = args.posicionais[2];
|
|
1823
|
+
const remoto = texto(args.opcoes.remoto);
|
|
1824
|
+
if (!alvo && args.opcoes.todas !== true) {
|
|
1825
|
+
console.error('uso: ork ship registrar-pr <thread-id> | --todas [--remoto R] [--json]');
|
|
1826
|
+
return 2;
|
|
1827
|
+
}
|
|
1828
|
+
const r = alvo ? [(0, entrega_pr_1.registrarEntregaPorPr)(carregado, alvo, { remoto })] : (0, entrega_pr_1.registrarEntregasPorPr)(carregado, { remoto });
|
|
1829
|
+
if (args.opcoes.json === true) {
|
|
1830
|
+
console.log(JSON.stringify(r, null, 2));
|
|
1831
|
+
return r.some((x) => x.acao === 'recusada') ? 1 : 0;
|
|
1832
|
+
}
|
|
1833
|
+
if (r.length === 0)
|
|
1834
|
+
console.log('Nenhuma thread aberta com merge ship(<thread>) na base.');
|
|
1835
|
+
for (const x of r)
|
|
1836
|
+
console.log(` ${x.thread.padEnd(20)} ${x.acao.padEnd(13)} ${x.motivo}`);
|
|
1837
|
+
const registradas = r.filter((x) => x.acao === 'registrou').length;
|
|
1838
|
+
if (registradas) {
|
|
1839
|
+
console.log('');
|
|
1840
|
+
console.log(`${registradas} entrega(s) registrada(s). Fechar pelo MASTER: ork master --aceitar-omissao (a nota humana sobrescreve).`);
|
|
1841
|
+
}
|
|
1842
|
+
return r.some((x) => x.acao === 'recusada') ? 1 : 0;
|
|
1843
|
+
}
|
|
921
1844
|
const id = args.posicionais[1];
|
|
922
1845
|
const para = texto(args.opcoes.para) ?? texto(args.opcoes.to);
|
|
923
1846
|
if (!id || !para) {
|
|
@@ -937,6 +1860,190 @@ function comandoShip(args) {
|
|
|
937
1860
|
console.log((0, ship_1.textoDoShip)(r));
|
|
938
1861
|
return r.ok ? 0 : 1;
|
|
939
1862
|
}
|
|
1863
|
+
function comandoPortfolio(args) {
|
|
1864
|
+
const root = (0, manifest_1.exigirManifesto)().raiz;
|
|
1865
|
+
const sub = args.posicionais[1] ?? 'list';
|
|
1866
|
+
if (sub === 'inspect') {
|
|
1867
|
+
const id = args.posicionais[2];
|
|
1868
|
+
if (!id) {
|
|
1869
|
+
console.error('uso: ork portfolio inspect <id> --json');
|
|
1870
|
+
return 2;
|
|
1871
|
+
}
|
|
1872
|
+
console.log(JSON.stringify((0, portfolio_context_1.inspectPortfolio)(root, id), null, 2));
|
|
1873
|
+
return 0;
|
|
1874
|
+
}
|
|
1875
|
+
const aliases = { product: 'product', project: 'project', initiative: 'initiative', prod: 'product', proj: 'project', init: 'initiative' };
|
|
1876
|
+
const split = (value, separator = ',') => value?.split(separator).map((item) => item.trim()).filter(Boolean) ?? [];
|
|
1877
|
+
if (sub === 'list') {
|
|
1878
|
+
const rawKind = args.posicionais[2];
|
|
1879
|
+
const kind = rawKind ? aliases[rawKind] : undefined;
|
|
1880
|
+
if (rawKind && !kind) {
|
|
1881
|
+
console.error('tipo deve ser product, project ou initiative');
|
|
1882
|
+
return 2;
|
|
1883
|
+
}
|
|
1884
|
+
const items = (0, portfolio_1.listEntities)(root, kind, texto(args.opcoes.parent));
|
|
1885
|
+
console.log(args.opcoes.json === true ? JSON.stringify({ schema: 'ork.portfolio-list/v1', updatedAt: (0, portfolio_1.readPortfolio)(root).updatedAt, items }, null, 2)
|
|
1886
|
+
: items.length ? items.map((item) => `${item.id}\t${item.kind}\t${item.status}\t${item.title}`).join('\n') : 'Portfólio vazio.');
|
|
1887
|
+
return 0;
|
|
1888
|
+
}
|
|
1889
|
+
if (sub === 'show') {
|
|
1890
|
+
const id = args.posicionais[2];
|
|
1891
|
+
if (!id) {
|
|
1892
|
+
console.error('uso: ork portfolio show <id>');
|
|
1893
|
+
return 2;
|
|
1894
|
+
}
|
|
1895
|
+
const item = (0, portfolio_1.findEntity)(root, id);
|
|
1896
|
+
if (!item) {
|
|
1897
|
+
console.error(`entidade ${id} não encontrada`);
|
|
1898
|
+
return 1;
|
|
1899
|
+
}
|
|
1900
|
+
console.log(args.opcoes.json === true ? JSON.stringify(item, null, 2) : `${item.id}\n${item.title}\nEstado: ${item.status}`);
|
|
1901
|
+
return 0;
|
|
1902
|
+
}
|
|
1903
|
+
if (sub === 'create') {
|
|
1904
|
+
const kind = aliases[args.posicionais[2] ?? ''];
|
|
1905
|
+
const id = args.posicionais[3], title = texto(args.opcoes.title), parent = texto(args.opcoes.parent);
|
|
1906
|
+
if (!kind || !id || !title) {
|
|
1907
|
+
console.error('uso: ork portfolio create <product|project|initiative> <id> --title T [--parent ID]');
|
|
1908
|
+
return 2;
|
|
1909
|
+
}
|
|
1910
|
+
const common = { id, title, description: texto(args.opcoes.description), ownerId: texto(args.opcoes.owner), status: texto(args.opcoes.status), acceptanceCriteria: split(texto(args.opcoes.acceptance), ';') };
|
|
1911
|
+
const item = kind === 'product' ? (0, portfolio_1.createProduct)(root, common)
|
|
1912
|
+
: kind === 'project' ? (0, portfolio_1.createProject)(root, { ...common, productId: parent ?? '', workspaceIds: split(texto(args.opcoes.workspaces)) })
|
|
1913
|
+
: (0, portfolio_1.createInitiative)(root, { ...common, projectId: parent ?? '', dependsOn: split(texto(args.opcoes.depends)) });
|
|
1914
|
+
console.log(JSON.stringify({ schema: 'ork.portfolio-created/v1', item }, null, 2));
|
|
1915
|
+
return 0;
|
|
1916
|
+
}
|
|
1917
|
+
console.error(`subcomando desconhecido: portfolio ${sub}`);
|
|
1918
|
+
return 2;
|
|
1919
|
+
}
|
|
1920
|
+
function comandoCreation(args) {
|
|
1921
|
+
const loaded = (0, manifest_1.exigirManifesto)();
|
|
1922
|
+
// CLI local opera com a autoridade do usuário do SO, assim como portfolio create.
|
|
1923
|
+
// Fachadas HTTP devem usar a API com principal e authorize autenticados no servidor.
|
|
1924
|
+
const actor = { principal: `local:uid:${(0, node_os_1.userInfo)().uid}`, authorize: () => { } };
|
|
1925
|
+
const sub = args.posicionais[1], id = args.posicionais[2];
|
|
1926
|
+
if (args.opcoes.principal !== undefined || args.opcoes.por !== undefined)
|
|
1927
|
+
throw new Error('creation.identity: payload não escolhe principal');
|
|
1928
|
+
let result;
|
|
1929
|
+
if (sub === 'session') {
|
|
1930
|
+
const portfolio = (0, portfolio_1.readPortfolio)(loaded.raiz);
|
|
1931
|
+
result = {
|
|
1932
|
+
schema: 'ork.creation-session/v1', principal: actor.principal,
|
|
1933
|
+
workspaceIds: [...new Set(portfolio.projects.flatMap((project) => project.workspaceIds))].sort(),
|
|
1934
|
+
modes: loaded.manifesto.conduction.allowed_modes,
|
|
1935
|
+
actions: ['create_entity', 'create_entity_with_ticket', 'open_ticket'],
|
|
1936
|
+
};
|
|
1937
|
+
}
|
|
1938
|
+
else if (sub === 'start') {
|
|
1939
|
+
const file = texto(args.opcoes['input-file']);
|
|
1940
|
+
if (!file) {
|
|
1941
|
+
console.error('uso: ork creation start --input-file F --json');
|
|
1942
|
+
return 2;
|
|
1943
|
+
}
|
|
1944
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
1945
|
+
if (Buffer.byteLength(content) > 100_000)
|
|
1946
|
+
throw new Error('creation.input: arquivo excede limite');
|
|
1947
|
+
result = (0, creation_operation_1.startCreation)(loaded, actor, JSON.parse(content));
|
|
1948
|
+
}
|
|
1949
|
+
else if (sub === 'list')
|
|
1950
|
+
result = (0, creation_operation_store_1.listCreationOperations)(loaded.raiz, actor.principal);
|
|
1951
|
+
else if (!id) {
|
|
1952
|
+
console.error('creation exige id');
|
|
1953
|
+
return 2;
|
|
1954
|
+
}
|
|
1955
|
+
else if (sub === 'show' || sub === 'events') {
|
|
1956
|
+
const op = (0, creation_operation_store_1.readCreationOperation)(loaded.raiz, id, actor.principal);
|
|
1957
|
+
result = sub === 'events' ? { schema: 'ork.creation-events/v1', operationId: id, version: op.version, events: op.events } : op;
|
|
1958
|
+
}
|
|
1959
|
+
else if (sub === 'resume' || sub === 'compensate') {
|
|
1960
|
+
const version = Number(texto(args.opcoes['expected-version']));
|
|
1961
|
+
if (!Number.isSafeInteger(version) || version < 1) {
|
|
1962
|
+
console.error('creation exige --expected-version inteiro positivo');
|
|
1963
|
+
return 2;
|
|
1964
|
+
}
|
|
1965
|
+
result = sub === 'resume' ? (0, creation_operation_1.resumeCreation)(loaded, actor, id, version) : (0, creation_operation_1.compensateCreation)(loaded, actor, id, version);
|
|
1966
|
+
}
|
|
1967
|
+
else {
|
|
1968
|
+
console.error('subcomando creation desconhecido');
|
|
1969
|
+
return 2;
|
|
1970
|
+
}
|
|
1971
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1972
|
+
return 0;
|
|
1973
|
+
}
|
|
1974
|
+
/**
|
|
1975
|
+
* `ork objective`: APOSENTADO na I-43 (D4).
|
|
1976
|
+
*
|
|
1977
|
+
* O Objective Envelope descrevia um gate que nao bloqueava nada, e a medida foi mais
|
|
1978
|
+
* dura que a suspeita do GOAL: das 137 threads do projeto, ZERO tinham
|
|
1979
|
+
* `creationOrigin`, e `creationOrigin` era a unica via pela qual `phase.ts` consultava
|
|
1980
|
+
* o envelope. O ramo nunca disparou para thread nenhuma. Havia um envelope em disco,
|
|
1981
|
+
* `obj-i27gatedomae`, em `awaiting_approval` desde 17/09, com tres threads de zero
|
|
1982
|
+
* sessoes: a unica pausa do `#Maestro` nao bloqueava o despacho das proprias threads
|
|
1983
|
+
* que ela criou, e aprova-la nao teria efeito.
|
|
1984
|
+
*
|
|
1985
|
+
* As DUAS VIGAS que ele guardava sairam vivas, e viraram propriedade de thread comum:
|
|
1986
|
+
* - validacao por runtime diferente -> `thread.exigeRuntimeDiferente` (T9);
|
|
1987
|
+
* - `doneWhen` executavel -> `thread.doneWhen`, que vira claim do nucleo (T10).
|
|
1988
|
+
*
|
|
1989
|
+
* A recusa e TIPADA e diz para onde ir. Sumir em silencio seria o mesmo pecado da
|
|
1990
|
+
* #TAG aposentada virando default: quem tem o comando num script precisa saber.
|
|
1991
|
+
*/
|
|
1992
|
+
function comandoObjective(args) {
|
|
1993
|
+
const sub = args.posicionais[1] ?? 'list';
|
|
1994
|
+
console.error(`objective.aposentado: o Objective Envelope saiu do produto na I-43 (subcomando "${sub}").\n` +
|
|
1995
|
+
' Ele descrevia um gate que nao bloqueava nada: das 137 threads do projeto, zero\n' +
|
|
1996
|
+
' tinham creationOrigin, que era a unica via pela qual o despacho o consultava.\n' +
|
|
1997
|
+
' As duas vigas que ele guardava viraram propriedade de thread comum:\n' +
|
|
1998
|
+
' ork thread new "<nome>" --modo <MODO> --exige-runtime-diferente\n' +
|
|
1999
|
+
' o CHECK precisa de runtime que o GO nao usou\n' +
|
|
2000
|
+
' ork thread new "<nome>" --modo <MODO> --done "<criterio> :: <comando>"\n' +
|
|
2001
|
+
' criterio de pronto EXECUTAVEL, que vira claim e roda no ork verify\n' +
|
|
2002
|
+
' Os envelopes ja gravados continuam em .orkastery/objectives, intocados.');
|
|
2003
|
+
return 2;
|
|
2004
|
+
}
|
|
2005
|
+
function comandoCi(args) {
|
|
2006
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
2007
|
+
const sub = args.posicionais[1] ?? 'status';
|
|
2008
|
+
if (sub === 'prepare') {
|
|
2009
|
+
const thread = args.posicionais[2];
|
|
2010
|
+
if (!thread) {
|
|
2011
|
+
console.error('uso: ork ci prepare <thread-id>');
|
|
2012
|
+
return 2;
|
|
2013
|
+
}
|
|
2014
|
+
const arquivo = (0, ci_1.prepararBundleCi)(carregado, thread, { aoAvisar: (linha) => console.log(`AVISO: ${linha}`) });
|
|
2015
|
+
console.log(`Bundle de CI: ${arquivo}`);
|
|
2016
|
+
return 0;
|
|
2017
|
+
}
|
|
2018
|
+
if (sub === 'run') {
|
|
2019
|
+
const bundle = texto(args.opcoes.bundle);
|
|
2020
|
+
if (bundle) {
|
|
2021
|
+
const result = (0, ci_1.executarBundleCi)(carregado, bundle);
|
|
2022
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2023
|
+
return result.ok ? 0 : 1;
|
|
2024
|
+
}
|
|
2025
|
+
const thread = args.posicionais[2];
|
|
2026
|
+
if (!thread) {
|
|
2027
|
+
console.error('uso: ork ci run <thread-id> [--json] | ork ci run --bundle <arquivo>');
|
|
2028
|
+
return 2;
|
|
2029
|
+
}
|
|
2030
|
+
const result = (0, ci_1.executarCi)(carregado, thread);
|
|
2031
|
+
console.log(args.opcoes.json === true ? JSON.stringify(result, null, 2) : `${result.status.ok ? 'CI APROVADO' : 'CI REPROVADO'}: ${result.status.detail}`);
|
|
2032
|
+
return result.status.ok ? 0 : 1;
|
|
2033
|
+
}
|
|
2034
|
+
if (sub === 'status') {
|
|
2035
|
+
const sha = texto(args.opcoes.sha) ?? args.posicionais[2] ?? (0, util_1.exec)('git', ['rev-parse', 'HEAD'], carregado.raiz).stdout.trim();
|
|
2036
|
+
if (!/^[0-9a-f]{40}$/.test(sha)) {
|
|
2037
|
+
console.error('uso: ork ci status --sha <commit> [--remoto origin]');
|
|
2038
|
+
return 2;
|
|
2039
|
+
}
|
|
2040
|
+
const result = (0, ci_1.consultarCi)(carregado, sha, texto(args.opcoes.remoto) ?? 'origin');
|
|
2041
|
+
console.log(args.opcoes.json === true ? JSON.stringify(result, null, 2) : `${result.ok ? 'CI VERDE' : 'CI NÃO LIBEROU'}: ${result.detail}`);
|
|
2042
|
+
return result.ok ? 0 : 1;
|
|
2043
|
+
}
|
|
2044
|
+
console.error(`subcomando desconhecido: ci ${sub}`);
|
|
2045
|
+
return 2;
|
|
2046
|
+
}
|
|
940
2047
|
function comandoLease(args) {
|
|
941
2048
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
942
2049
|
const sub = args.posicionais[1];
|
|
@@ -956,14 +2063,14 @@ function comandoLease(args) {
|
|
|
956
2063
|
const r = (0, leases_1.adquirirRegiao)(carregado.raiz, nome, { thread, motivo });
|
|
957
2064
|
if (r.ok) {
|
|
958
2065
|
console.log(`Lease ${r.nome} [${r.tipo}] adquirido pela thread ${thread}.`);
|
|
959
|
-
console.log(` expira em ${r.lease?.expiraEm}`);
|
|
2066
|
+
console.log(` expira em ${(0, horario_1.formatarDataHoraRotulada)(r.lease?.expiraEm)}`);
|
|
960
2067
|
if (r.tomadoDeVencido)
|
|
961
2068
|
console.log(' (o lease anterior estava VENCIDO e foi tomado)');
|
|
962
2069
|
return 0;
|
|
963
2070
|
}
|
|
964
2071
|
console.error(`Lease ${r.nome} NAO adquirido.`);
|
|
965
2072
|
console.error(` motivo tipado: ${r.motivo}`);
|
|
966
|
-
console.error(` detalhe: ${r.detalhe}`);
|
|
2073
|
+
console.error(` detalhe: ${(0, horario_1.localizarTextoRotulado)(r.detalhe)}`);
|
|
967
2074
|
console.error(` posicao na fila: ${r.posicaoNaFila}`);
|
|
968
2075
|
console.error(` correcao: ${r.correcao}`);
|
|
969
2076
|
return 1;
|
|
@@ -985,14 +2092,105 @@ function comandoBoard(args) {
|
|
|
985
2092
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
986
2093
|
const sub = args.posicionais[1];
|
|
987
2094
|
if (sub === 'plan' || sub === 'plano') {
|
|
988
|
-
|
|
2095
|
+
const plano = (0, board_1.planejar)(carregado);
|
|
2096
|
+
console.log(args.opcoes.json === true ? JSON.stringify(plano, null, 2) : (0, board_1.textoDoPlano)(plano));
|
|
2097
|
+
return 0;
|
|
2098
|
+
}
|
|
2099
|
+
if (sub === 'reap') {
|
|
2100
|
+
const devolvidas = (0, board_1.devolverVagas)(carregado, { por: texto(args.opcoes.por) });
|
|
2101
|
+
if (args.opcoes.json === true)
|
|
2102
|
+
console.log(JSON.stringify(devolvidas, null, 2));
|
|
2103
|
+
else
|
|
2104
|
+
console.log((0, board_1.textoDoReap)(devolvidas));
|
|
989
2105
|
return 0;
|
|
990
2106
|
}
|
|
991
2107
|
if (sub !== undefined && sub !== 'list') {
|
|
992
2108
|
console.error(`subcomando desconhecido: board ${sub}`);
|
|
2109
|
+
console.error('uso: ork board [list|plan|reap] [--all] [--por <quem>] [--json]');
|
|
993
2110
|
return 2;
|
|
994
2111
|
}
|
|
995
|
-
|
|
2112
|
+
const todos = args.opcoes.all === true || args.opcoes.todos === true;
|
|
2113
|
+
if (args.opcoes.json === true) {
|
|
2114
|
+
console.log(JSON.stringify((0, board_1.threadsDeTodosOsPerfis)(carregado, todos), null, 2));
|
|
2115
|
+
return 0;
|
|
2116
|
+
}
|
|
2117
|
+
console.log((0, board_1.textoDoBoard)(carregado, todos));
|
|
2118
|
+
// I-51 (RM-047): com a fabrica compartilhada, o board mostra tambem as outras maquinas.
|
|
2119
|
+
if ((0, maquina_1.fabricaCompartilhada)(carregado.manifesto)) {
|
|
2120
|
+
const painel = (0, fabrica_estado_1.lerFabrica)(carregado.raiz, { remoto: carregado.manifesto.fabrica.remoto,
|
|
2121
|
+
semRemoto: args.opcoes['sem-remoto'] === true });
|
|
2122
|
+
console.log('');
|
|
2123
|
+
console.log((0, fabrica_estado_1.textoDasOutrasMaquinas)(painel, (0, maquina_1.nomeDaMaquina)()));
|
|
2124
|
+
}
|
|
2125
|
+
return 0;
|
|
2126
|
+
}
|
|
2127
|
+
/**
|
|
2128
|
+
* I-51 (RM-047): `ork fabrica` mostra o que cada maquina conduz; `ork fabrica publicar` grava o
|
|
2129
|
+
* retrato desta maquina na branch `ork/fabrica-estado`. O `--silencioso` e o da publicacao em
|
|
2130
|
+
* segundo plano: nada no terminal, uma linha em `.orkastery/monitor/fabrica.log`.
|
|
2131
|
+
*/
|
|
2132
|
+
function comandoFabrica(args) {
|
|
2133
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
2134
|
+
const sub = args.posicionais[1];
|
|
2135
|
+
const remoto = texto(args.opcoes.remoto) ?? carregado.manifesto.fabrica.remoto;
|
|
2136
|
+
if (sub === 'publicar') {
|
|
2137
|
+
const silencioso = args.opcoes.silencioso === true;
|
|
2138
|
+
try {
|
|
2139
|
+
const r = (0, fabrica_estado_1.publicarMaquina)(carregado, { remoto, forcar: args.opcoes.forcar === true });
|
|
2140
|
+
if (silencioso) {
|
|
2141
|
+
(0, fabrica_estado_1.registrarPublicacao)(carregado.raiz, { ...r });
|
|
2142
|
+
return 0;
|
|
2143
|
+
}
|
|
2144
|
+
if (args.opcoes.json === true)
|
|
2145
|
+
console.log(JSON.stringify(r, null, 2));
|
|
2146
|
+
else
|
|
2147
|
+
console.log(r.acao === 'publicou'
|
|
2148
|
+
? `Fabrica: ${r.maquina} publicou ${r.threads} thread(s) em ork/fabrica-estado (${r.commit?.slice(0, 7)}, ${r.tentativas} tentativa(s)).`
|
|
2149
|
+
: r.acao === 'ocupado'
|
|
2150
|
+
? `Fabrica: outra publicacao desta maquina esta em andamento; tente de novo em instantes.`
|
|
2151
|
+
: `Fabrica: retrato de ${r.maquina} igual ao ultimo publicado; nada a enviar (use --forcar para publicar mesmo assim).`);
|
|
2152
|
+
if (!(0, maquina_1.fabricaCompartilhada)(carregado.manifesto) && !silencioso) {
|
|
2153
|
+
console.log(' esta maquina nao entrou na fabrica compartilhada: so publica quando voce pede (ork fabrica entrar liga).');
|
|
2154
|
+
}
|
|
2155
|
+
return 0;
|
|
2156
|
+
}
|
|
2157
|
+
catch (e) {
|
|
2158
|
+
if (silencioso) {
|
|
2159
|
+
(0, fabrica_estado_1.registrarPublicacao)(carregado.raiz, { acao: 'falhou', erro: e.message });
|
|
2160
|
+
return 1;
|
|
2161
|
+
}
|
|
2162
|
+
throw e;
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
if (sub === 'entrar') {
|
|
2166
|
+
// A adesao e o nome ficam no arquivo do usuario: valem para o shell, o cron e os gateways.
|
|
2167
|
+
const config = (0, maquina_1.gravarConfigDaMaquina)({ nome: texto(args.opcoes.maquina) ?? (0, maquina_1.lerConfigDaMaquina)()?.nome ?? (0, maquina_1.nomeDaMaquina)(),
|
|
2168
|
+
fabricaCompartilhada: true });
|
|
2169
|
+
const r = (0, fabrica_estado_1.publicarMaquina)(carregado, { remoto, forcar: true });
|
|
2170
|
+
console.log(`Fabrica: esta maquina entrou como ${config.nome}; publica ao criar thread, despachar fase, entregar e fechar,`);
|
|
2171
|
+
console.log(` e a cada batida do pulse. Primeiro retrato: ${r.threads} thread(s) em ork/fabrica-estado (${r.commit?.slice(0, 7)}).`);
|
|
2172
|
+
if (process.env.ORK_MAQUINA && process.env.ORK_MAQUINA.trim() !== config.nome) {
|
|
2173
|
+
console.log(` AVISO: ORK_MAQUINA=${process.env.ORK_MAQUINA} neste shell vence o arquivo; alinhe os dois.`);
|
|
2174
|
+
}
|
|
2175
|
+
return 0;
|
|
2176
|
+
}
|
|
2177
|
+
if (sub === 'sair') {
|
|
2178
|
+
const config = (0, maquina_1.gravarConfigDaMaquina)({ fabricaCompartilhada: false });
|
|
2179
|
+
const r = (0, fabrica_estado_1.removerMaquina)(carregado, { remoto });
|
|
2180
|
+
console.log(`Fabrica: ${(0, maquina_1.nomeDaMaquina)()} saiu; nada mais e publicado daqui.` +
|
|
2181
|
+
(r ? ` Retrato removido de ork/fabrica-estado (${r.slice(0, 7)}).` : ' Nao havia retrato desta maquina na branch.'));
|
|
2182
|
+
if ((0, maquina_1.fabricaCompartilhada)(carregado.manifesto))
|
|
2183
|
+
console.log(' AVISO: o manifesto do projeto (ou ORK_FABRICA_COMPARTILHADA) ainda liga a fabrica aqui.');
|
|
2184
|
+
void config;
|
|
2185
|
+
return 0;
|
|
2186
|
+
}
|
|
2187
|
+
if (sub !== undefined && sub !== 'list') {
|
|
2188
|
+
console.error(`subcomando desconhecido: fabrica ${sub}`);
|
|
2189
|
+
console.error('uso: ork fabrica [--json] [--sem-remoto] | fabrica publicar [--forcar] [--json] | fabrica entrar [--maquina NOME] | fabrica sair');
|
|
2190
|
+
return 2;
|
|
2191
|
+
}
|
|
2192
|
+
const painel = (0, fabrica_estado_1.lerFabrica)(carregado.raiz, { remoto, semRemoto: args.opcoes['sem-remoto'] === true });
|
|
2193
|
+
console.log(args.opcoes.json === true ? JSON.stringify(painel, null, 2) : (0, fabrica_estado_1.textoDaFabrica)(painel, (0, maquina_1.nomeDaMaquina)()));
|
|
996
2194
|
return 0;
|
|
997
2195
|
}
|
|
998
2196
|
/**
|
|
@@ -1105,15 +2303,95 @@ function comandoWorktree(args) {
|
|
|
1105
2303
|
function comandoMaster(args) {
|
|
1106
2304
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1107
2305
|
const primeiro = args.posicionais[1];
|
|
2306
|
+
if (primeiro === 'audit') {
|
|
2307
|
+
const r = (0, master_audit_1.auditarMaster)(carregado.raiz);
|
|
2308
|
+
console.log(JSON.stringify(r, null, 2));
|
|
2309
|
+
return r.ok ? 0 : 1;
|
|
2310
|
+
}
|
|
2311
|
+
if (primeiro === 'digest') {
|
|
2312
|
+
const sub = args.posicionais[2];
|
|
2313
|
+
if (sub === 'responder') {
|
|
2314
|
+
console.log(JSON.stringify((0, master_digest_1.responderLoteDigest)(carregado.raiz, texto(args.opcoes.resposta) ?? '', texto(args.opcoes.por) ?? '').map(r => ({ thread: r.thread.id, score: r.masterLog.score })), null, 2));
|
|
2315
|
+
return 0;
|
|
2316
|
+
}
|
|
2317
|
+
if (sub === 'preview') {
|
|
2318
|
+
console.log(JSON.stringify((0, master_digest_1.montarDigest)(carregado.raiz, new Date().toISOString()), null, 2));
|
|
2319
|
+
return 0;
|
|
2320
|
+
}
|
|
2321
|
+
if (sub !== 'enviar')
|
|
2322
|
+
throw new Error('uso: ork master digest <enviar|preview|responder>');
|
|
2323
|
+
const r = (0, master_digest_1.enviarDigest)({ raiz: carregado.raiz });
|
|
2324
|
+
console.log(JSON.stringify(r, null, 2));
|
|
2325
|
+
return r.code;
|
|
2326
|
+
}
|
|
2327
|
+
if (primeiro === 'migrar') {
|
|
2328
|
+
console.log(JSON.stringify((0, master_migracao_1.migrarMaster)(carregado.raiz, { dryRun: args.opcoes['dry-run'] === true, por: texto(args.opcoes.por) ?? '' }), null, 2));
|
|
2329
|
+
return 0;
|
|
2330
|
+
}
|
|
1108
2331
|
if (primeiro === 'classes') {
|
|
1109
|
-
console.log((0,
|
|
2332
|
+
console.log((0, master_2.tabelaDeClasses)());
|
|
1110
2333
|
return 0;
|
|
1111
2334
|
}
|
|
1112
|
-
if (args.opcoes.batch === true || primeiro === 'batch'
|
|
1113
|
-
|
|
2335
|
+
if (primeiro === 'ratificar' || ((args.opcoes.batch === true || primeiro === 'batch') && args.opcoes.aceitar)) {
|
|
2336
|
+
let selecao;
|
|
2337
|
+
if (primeiro === 'ratificar') {
|
|
2338
|
+
const partes = (texto(args.opcoes.resposta) ?? '').trim().split(/\s+/);
|
|
2339
|
+
const classe = (0, master_2.parseClasse)(partes[3]);
|
|
2340
|
+
if (partes.length !== 4 || partes[0] !== 'ratificar' || !classe)
|
|
2341
|
+
throw new Error('resposta deve ser ratificar <thread> <assinatura> <classe>');
|
|
2342
|
+
selecao = [{ thread: partes[1], assinatura: partes[2], classe }];
|
|
2343
|
+
}
|
|
2344
|
+
else {
|
|
2345
|
+
selecao = (texto(args.opcoes.aceitar) ?? '').split(',').map(v => {
|
|
2346
|
+
const partes = v.trim().split(':');
|
|
2347
|
+
if (partes.length !== 2 || !/^[a-f0-9]{64}$/.test(partes[1]))
|
|
2348
|
+
throw new Error('seleção deve ser thread:assinatura');
|
|
2349
|
+
return { thread: partes[0], assinatura: partes[1] };
|
|
2350
|
+
});
|
|
2351
|
+
}
|
|
2352
|
+
console.log(JSON.stringify((0, master_batch_1.ratificarBatch)(carregado.raiz, selecao, texto(args.opcoes.por) ?? '').map(r => ({ thread: r.thread.id, score: r.masterLog.score, por: r.masterLog.avaliadoPor })), null, 2));
|
|
1114
2353
|
return 0;
|
|
1115
2354
|
}
|
|
1116
|
-
|
|
2355
|
+
// I-43 (T8): a FILA saiu. `--batch` recebe recusa tipada em vez de sumir em
|
|
2356
|
+
// silencio: quem tem o comando no dedo ou num script precisa SABER que o regime
|
|
2357
|
+
// mudou, e para onde ir. Desaparecer sem dizer nada seria o mesmo pecado da #TAG
|
|
2358
|
+
// aposentada virando default.
|
|
2359
|
+
if (args.opcoes.batch === true || primeiro === 'batch') {
|
|
2360
|
+
console.error('master.fila-aposentada: a fila de ratificacao de score saiu na I-43. ' +
|
|
2361
|
+
'Entregue e aceito, a menos que voce diga o contrario.\n' +
|
|
2362
|
+
' ork master as entregas, com o indice ja derivado do ledger\n' +
|
|
2363
|
+
' ork master --aceitar-omissao aceita as entregues, com indice e insumos no ledger\n' +
|
|
2364
|
+
' ork master <id> --score <0-5> --justificativa "<por que>" --por <humano> para reclamar');
|
|
2365
|
+
return 2;
|
|
2366
|
+
}
|
|
2367
|
+
if (args.opcoes['aceitar-omissao'] === true) {
|
|
2368
|
+
const aceitos = (0, master_2.aceitarPendentesPorOmissao)(carregado.raiz);
|
|
2369
|
+
if (args.opcoes.json === true) {
|
|
2370
|
+
console.log(JSON.stringify(aceitos, null, 2));
|
|
2371
|
+
return 0;
|
|
2372
|
+
}
|
|
2373
|
+
if (aceitos.length === 0) {
|
|
2374
|
+
console.log('Nenhuma entrega esperando decisao.');
|
|
2375
|
+
return 0;
|
|
2376
|
+
}
|
|
2377
|
+
console.log(`Aceitas por omissao: ${aceitos.length}. O indice e os insumos foram ao ledger.`);
|
|
2378
|
+
for (const a of aceitos)
|
|
2379
|
+
console.log(` ${a.thread.padEnd(20)} indice ${a.indice.valor}/${a.indice.base}`);
|
|
2380
|
+
console.log('');
|
|
2381
|
+
console.log('Discordou? A nota humana sobrescreve, e o registro da omissao permanece.');
|
|
2382
|
+
return 0;
|
|
2383
|
+
}
|
|
2384
|
+
if (primeiro === undefined) {
|
|
2385
|
+
console.log(args.opcoes.json
|
|
2386
|
+
? JSON.stringify({ entregas: (0, master_batch_1.listarBatch)(carregado.raiz, args.opcoes.todas === true),
|
|
2387
|
+
aceitasPorOmissao: (0, master_2.aceitosPorOmissao)(carregado.raiz) }, null, 2)
|
|
2388
|
+
: (0, master_2.tabelaDeEntregas)(carregado.raiz, args.opcoes.todas === true));
|
|
2389
|
+
return 0;
|
|
2390
|
+
}
|
|
2391
|
+
const propor = primeiro === 'propor';
|
|
2392
|
+
const id = propor ? args.posicionais[2] : primeiro;
|
|
2393
|
+
if (!id)
|
|
2394
|
+
throw new Error('informe a thread para propor MASTER');
|
|
1117
2395
|
const brutoScore = texto(args.opcoes.score);
|
|
1118
2396
|
const justificativa = texto(args.opcoes.justificativa) ?? texto(args.opcoes.porque);
|
|
1119
2397
|
if (brutoScore === undefined) {
|
|
@@ -1130,28 +2408,51 @@ function comandoMaster(args) {
|
|
|
1130
2408
|
const brutasClasses = texto(args.opcoes.classe) ?? texto(args.opcoes.classes);
|
|
1131
2409
|
const classes = [];
|
|
1132
2410
|
for (const bruta of (brutasClasses ?? '').split(',').map((c) => c.trim()).filter(Boolean)) {
|
|
1133
|
-
const classe = (0,
|
|
2411
|
+
const classe = (0, master_2.parseClasse)(bruta);
|
|
1134
2412
|
if (!classe) {
|
|
1135
2413
|
console.error(`classe de falha invalida: "${bruta}".`);
|
|
1136
|
-
console.error(` classes fixas: ${
|
|
2414
|
+
console.error(` classes fixas: ${master_2.ORDEM_DAS_CLASSES.join(', ')}`);
|
|
1137
2415
|
return 2;
|
|
1138
2416
|
}
|
|
1139
2417
|
classes.push(classe);
|
|
1140
2418
|
}
|
|
1141
|
-
const
|
|
2419
|
+
const opcoesMaster = {
|
|
1142
2420
|
score: Number(brutoScore),
|
|
1143
2421
|
justificativa,
|
|
1144
2422
|
classes,
|
|
1145
2423
|
resumo: texto(args.opcoes.resumo),
|
|
1146
2424
|
por: texto(args.opcoes.por) ?? texto(args.opcoes.quem),
|
|
1147
2425
|
refazer: args.opcoes.refazer === true,
|
|
1148
|
-
}
|
|
1149
|
-
|
|
2426
|
+
};
|
|
2427
|
+
if (propor) {
|
|
2428
|
+
console.log(JSON.stringify((0, master_1.proporMaster)(carregado.raiz, id, opcoesMaster), null, 2));
|
|
2429
|
+
return 0;
|
|
2430
|
+
}
|
|
2431
|
+
const r = (0, master_2.registrarMaster)(carregado.raiz, id, opcoesMaster);
|
|
2432
|
+
console.log((0, master_2.textoDoMaster)(r));
|
|
1150
2433
|
// Bloco B6: fechada a thread, a licao (POSTMORTEM + score) vai para a colecao
|
|
1151
2434
|
// `learning`, e e o que uma thread NOVA do mesmo produto recebe no GOAL.
|
|
1152
2435
|
relatarPublicacao((0, memoria_1.publicar)(carregado, id));
|
|
2436
|
+
// I-55 (RM-008): a thread fechada pode fazer uma falha recorrente passar do piso. A proposta
|
|
2437
|
+
// vai ao ledger do projeto uma vez por janela; virar policy continua sendo do dono.
|
|
2438
|
+
for (const p of (0, licoes_1.registrarPropostasNovas)(carregado.raiz)) {
|
|
2439
|
+
console.log('');
|
|
2440
|
+
console.log(`Proposta de policy: ${p.chave} em ${p.threads.length} threads nos ultimos ${p.janelaDias} dias.`);
|
|
2441
|
+
console.log(` ${p.sugestao}`);
|
|
2442
|
+
console.log(' So proposta: vira policy quando voce a declara em policies: no orkastery.yaml (ork licoes).');
|
|
2443
|
+
}
|
|
1153
2444
|
console.log('');
|
|
1154
|
-
console.log(`Proximo passo: ork board --all |
|
|
2445
|
+
console.log(`Proximo passo: ork board --all | entregas e indice: ork master`);
|
|
2446
|
+
return 0;
|
|
2447
|
+
}
|
|
2448
|
+
/** I-55 (RM-008): `ork licoes` mostra o que volta no proximo GOAL e PLAN, e as propostas de policy. */
|
|
2449
|
+
function comandoLicoes(args) {
|
|
2450
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
2451
|
+
if (args.opcoes.json === true) {
|
|
2452
|
+
console.log(JSON.stringify({ resumo: (0, licoes_1.resumoDasLicoes)(carregado.raiz, null), propostas: (0, licoes_1.propostasDePolicy)(carregado.raiz) }, null, 2));
|
|
2453
|
+
return 0;
|
|
2454
|
+
}
|
|
2455
|
+
console.log((0, licoes_1.textoDeLicoes)(carregado.raiz));
|
|
1155
2456
|
return 0;
|
|
1156
2457
|
}
|
|
1157
2458
|
/**
|
|
@@ -1161,6 +2462,81 @@ function comandoMaster(args) {
|
|
|
1161
2462
|
* exato com o mesmo sha256 que iria para o ledger, para o builder revisar texto sem gastar
|
|
1162
2463
|
* uma sessao do runtime para descobrir o que foi pedido.
|
|
1163
2464
|
*/
|
|
2465
|
+
/**
|
|
2466
|
+
* I-44: documentacao como codigo. `verificar` le docs e git (roda no CI); `sincronizar` le tambem
|
|
2467
|
+
* o estado das threads, que nao e versionado, e por isso roda na maquina do projeto.
|
|
2468
|
+
*/
|
|
2469
|
+
/** I-47: reservas de item do roadmap entre maquinas (`ork roadmap reservas|pegar|soltar`). */
|
|
2470
|
+
function comandoRoadmap(args) {
|
|
2471
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
2472
|
+
const sub = args.posicionais[1] ?? 'reservas';
|
|
2473
|
+
const remoto = texto(args.opcoes.remoto);
|
|
2474
|
+
if (sub === 'reservas') {
|
|
2475
|
+
const painel = (0, roadmap_reservas_1.listarReservas)(carregado.raiz, { remoto });
|
|
2476
|
+
console.log(args.opcoes.json === true ? JSON.stringify(painel, null, 2) : (0, roadmap_reservas_1.textoDasReservas)(painel));
|
|
2477
|
+
return 0;
|
|
2478
|
+
}
|
|
2479
|
+
const item = args.posicionais[2];
|
|
2480
|
+
if ((sub !== 'pegar' && sub !== 'soltar') || !item) {
|
|
2481
|
+
console.error('uso: ork roadmap reservas | pegar <RM-NNN> [--thread T] [--nota N] | soltar <RM-NNN> [--forcar --motivo M]');
|
|
2482
|
+
return 2;
|
|
2483
|
+
}
|
|
2484
|
+
const opcoes = {
|
|
2485
|
+
remoto,
|
|
2486
|
+
por: texto(args.opcoes.por),
|
|
2487
|
+
maquina: texto(args.opcoes.maquina),
|
|
2488
|
+
...(texto(args.opcoes.thread) !== undefined ? { thread: texto(args.opcoes.thread) } : {}),
|
|
2489
|
+
...(texto(args.opcoes.nota) !== undefined ? { nota: texto(args.opcoes.nota) } : {}),
|
|
2490
|
+
forcar: args.opcoes.forcar === true,
|
|
2491
|
+
motivo: texto(args.opcoes.motivo),
|
|
2492
|
+
};
|
|
2493
|
+
const r = sub === 'pegar' ? (0, roadmap_reservas_1.pegarItem)(carregado.raiz, item, opcoes) : (0, roadmap_reservas_1.soltarItem)(carregado.raiz, item, opcoes);
|
|
2494
|
+
if (args.opcoes.json === true) {
|
|
2495
|
+
console.log(JSON.stringify(r, null, 2));
|
|
2496
|
+
return 0;
|
|
2497
|
+
}
|
|
2498
|
+
const verbo = { pegou: 'reservado para esta maquina', renovou: 'reserva renovada', tomou: 'reserva TOMADA de outra maquina',
|
|
2499
|
+
soltou: 'devolvido', nada: 'ja estava livre' }[r.acao];
|
|
2500
|
+
console.log(`${r.item}: ${verbo}.`);
|
|
2501
|
+
if (r.reserva && r.acao !== 'soltou')
|
|
2502
|
+
console.log(` com ${r.reserva.por} em ${r.reserva.maquina}${r.reserva.thread ? `, thread ${r.reserva.thread}` : ''}`);
|
|
2503
|
+
if (r.commit)
|
|
2504
|
+
console.log(` branch ork/roadmap-reservas em ${r.commit.slice(0, 7)}`);
|
|
2505
|
+
return 0;
|
|
2506
|
+
}
|
|
2507
|
+
function comandoDocs(args) {
|
|
2508
|
+
const sub = args.posicionais[1] ?? 'verificar';
|
|
2509
|
+
const carregado = (0, manifest_1.carregarManifesto)();
|
|
2510
|
+
const raiz = carregado?.raiz ?? process.cwd();
|
|
2511
|
+
const baseBranch = carregado?.manifesto.worktree?.base_branch ?? 'main';
|
|
2512
|
+
if (sub === 'verificar') {
|
|
2513
|
+
const { docs, achados } = (0, docs_1.verificarDocs)(raiz, { baseBranch, ajudaDoCli: AJUDA });
|
|
2514
|
+
if (args.opcoes.json === true) {
|
|
2515
|
+
console.log(JSON.stringify({ paginas: docs.length, erros: achados.filter((a) => a.gravidade === 'erro').length,
|
|
2516
|
+
achados }, null, 2));
|
|
2517
|
+
}
|
|
2518
|
+
else {
|
|
2519
|
+
console.log((0, docs_1.textoDaVerificacao)(docs, achados));
|
|
2520
|
+
}
|
|
2521
|
+
return achados.some((a) => a.gravidade === 'erro') ? 2 : 0;
|
|
2522
|
+
}
|
|
2523
|
+
if (sub === 'sincronizar') {
|
|
2524
|
+
const escrever = args.opcoes.escrever === true;
|
|
2525
|
+
const r = (0, docs_1.sincronizarDocs)(raiz, { baseBranch, escrever });
|
|
2526
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : (0, docs_1.textoDaSincronizacao)(r, escrever));
|
|
2527
|
+
return 0;
|
|
2528
|
+
}
|
|
2529
|
+
if (sub === 'init') {
|
|
2530
|
+
const criados = (0, docs_1.iniciarDocs)(raiz);
|
|
2531
|
+
console.log(criados.length === 0
|
|
2532
|
+
? 'Documentacao como codigo ja estava no projeto: nada criado.'
|
|
2533
|
+
: ['Criado:', ...criados.map((c) => ` ${c}`), '',
|
|
2534
|
+
'Proximo passo: copie docs/produto/_modelo-feature.md e docs/roadmap/_modelo-item.md, e rode ork docs verificar'].join('\n'));
|
|
2535
|
+
return 0;
|
|
2536
|
+
}
|
|
2537
|
+
console.error(`uso: ork docs verificar [--json] | sincronizar [--escrever] | init`);
|
|
2538
|
+
return 2;
|
|
2539
|
+
}
|
|
1164
2540
|
function comandoPrompt(args) {
|
|
1165
2541
|
const sub = args.posicionais[1] ?? 'list';
|
|
1166
2542
|
const carregado = (0, manifest_1.carregarManifesto)();
|
|
@@ -1186,9 +2562,12 @@ function comandoPrompt(args) {
|
|
|
1186
2562
|
// abrir trabalho. Nada e gravado, e o `ork` diz em voz alta que a thread e ficticia.
|
|
1187
2563
|
if (args.opcoes.exemplo === true || args.opcoes.modo !== undefined || args.opcoes.mode !== undefined) {
|
|
1188
2564
|
const bruto = texto(args.opcoes.modo) ?? texto(args.opcoes.mode) ?? 'classic';
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
2565
|
+
let modo;
|
|
2566
|
+
try {
|
|
2567
|
+
modo = (0, modos_1.exigirModoVivo)(bruto);
|
|
2568
|
+
}
|
|
2569
|
+
catch (e) {
|
|
2570
|
+
console.error(e.message);
|
|
1192
2571
|
return 2;
|
|
1193
2572
|
}
|
|
1194
2573
|
const exemplo = (0, prompts_1.threadDeExemplo)(modo, fase, carregado?.manifesto.project);
|
|
@@ -1266,6 +2645,10 @@ function comandoAdapter(args) {
|
|
|
1266
2645
|
force: args.opcoes.force === true || args.opcoes.forcar === true,
|
|
1267
2646
|
orkBin: texto(args.opcoes.ork),
|
|
1268
2647
|
versao: VERSAO,
|
|
2648
|
+
// I-43 (D5): a decisao por ARQUIVO, que e o que faz `--force` deixar de ser o
|
|
2649
|
+
// unico caminho de saida. `;` separa varios, como o resto do CLI ja faz.
|
|
2650
|
+
aceitarCatalogo: (texto(args.opcoes['aceitar-catalogo']) ?? '').split(';').map(x => x.trim()).filter(Boolean),
|
|
2651
|
+
manterCopia: (texto(args.opcoes['manter-copia']) ?? '').split(';').map(x => x.trim()).filter(Boolean),
|
|
1269
2652
|
});
|
|
1270
2653
|
console.log((0, hosts_1.textoDaInstalacao)(r));
|
|
1271
2654
|
return r.ok ? 0 : 2;
|
|
@@ -1308,6 +2691,12 @@ function comandoEval(args) {
|
|
|
1308
2691
|
* diferente de zero quando reprova, para o agendador do host perceber sem ler texto.
|
|
1309
2692
|
*/
|
|
1310
2693
|
function comandoAudit(args) {
|
|
2694
|
+
if (args.posicionais[1] === 'process') {
|
|
2695
|
+
const r = (0, process_audit_1.auditarProcesso)((0, manifest_1.exigirManifesto)(), args.opcoes.registrar === true);
|
|
2696
|
+
console.log(JSON.stringify(r, null, 2));
|
|
2697
|
+
const chave = texto(args.opcoes['exigir-achado']);
|
|
2698
|
+
return chave && !r.achados.some(a => a.chave === chave) ? 1 : 0;
|
|
2699
|
+
}
|
|
1311
2700
|
const sub = args.posicionais[1] ?? 'packs';
|
|
1312
2701
|
// `audit packs` e `audit lint` funcionam sem manifesto: sao catalogo, nao estado.
|
|
1313
2702
|
if (sub === 'packs' || sub === 'pack') {
|
|
@@ -1673,6 +3062,10 @@ function comandoAudit(args) {
|
|
|
1673
3062
|
* que sempre teve. E o que garante que ligar o B6 nao muda o que o builder ja conhece.
|
|
1674
3063
|
*/
|
|
1675
3064
|
function relatarPublicacao(r) {
|
|
3065
|
+
if (r.publicacao?.estado === 'pendente') {
|
|
3066
|
+
console.log(`Memoria: publicacao pendente (${r.publicacao.motivo}); ativacao explicita necessaria.`);
|
|
3067
|
+
return;
|
|
3068
|
+
}
|
|
1676
3069
|
if (r.regime !== 'orkmind')
|
|
1677
3070
|
return;
|
|
1678
3071
|
const gravados = [
|
|
@@ -1687,9 +3080,18 @@ function relatarPublicacao(r) {
|
|
|
1687
3080
|
if (r.falhas > 0)
|
|
1688
3081
|
console.log(` ${r.falhas} gravacao(oes) nao concluida(s); veja ork memory status.`);
|
|
1689
3082
|
}
|
|
3083
|
+
/** Janela de origem e corte de apresentação são inteiros positivos explícitos. */
|
|
3084
|
+
function limiteDeLeitura(valor) {
|
|
3085
|
+
if (valor === undefined)
|
|
3086
|
+
return undefined;
|
|
3087
|
+
if (typeof valor !== 'string' || !/^[0-9]+$/.test(valor) ||
|
|
3088
|
+
Number(valor) < 1 || Number(valor) > 1000)
|
|
3089
|
+
throw Error('memory.query.invalid');
|
|
3090
|
+
return Number(valor);
|
|
3091
|
+
}
|
|
1690
3092
|
/** `ork recall`: recuperacao tardia dos ponteiros do handoff, no momento indicado. */
|
|
1691
3093
|
function comandoRecall(args) {
|
|
1692
|
-
const carregado = (0, manifest_1.exigirManifesto)();
|
|
3094
|
+
const carregado = (0, project_state_1.memoryState)((0, manifest_1.exigirManifesto)()).loaded;
|
|
1693
3095
|
const id = args.posicionais[1];
|
|
1694
3096
|
if (!id) {
|
|
1695
3097
|
console.error('uso: ork recall <thread-id> [--fase FASE] [--id ptr-N] [--todos] [--forcar]');
|
|
@@ -1698,7 +3100,7 @@ function comandoRecall(args) {
|
|
|
1698
3100
|
const thread = (0, thread_1.lerThread)(carregado.raiz, id);
|
|
1699
3101
|
const faseBruta = texto(args.opcoes.fase) ?? texto(args.opcoes.momento);
|
|
1700
3102
|
const momento = faseBruta ? (0, thread_1.exigirFase)(thread, faseBruta) : undefined;
|
|
1701
|
-
const memoria = (0, memoria_1.abrirMemoria)(carregado);
|
|
3103
|
+
const memoria = (0, memoria_1.abrirMemoria)(carregado, { leituraRestrita: { thread: id, limite: limiteDeLeitura(args.opcoes.janela) } });
|
|
1702
3104
|
const r = (0, recall_1.recallDaThread)(carregado, memoria, id, {
|
|
1703
3105
|
momento,
|
|
1704
3106
|
id: texto(args.opcoes.id),
|
|
@@ -1716,32 +3118,96 @@ function comandoRecall(args) {
|
|
|
1716
3118
|
}
|
|
1717
3119
|
/** `ork memory`: o regime, a publicacao e a busca deterministica por tag. */
|
|
1718
3120
|
function comandoMemory(args) {
|
|
1719
|
-
const
|
|
3121
|
+
const candidate = (0, manifest_1.exigirManifesto)();
|
|
3122
|
+
const carregado = (0, project_state_1.memoryState)(candidate).loaded;
|
|
1720
3123
|
const sub = args.posicionais[1] ?? 'status';
|
|
1721
|
-
const
|
|
3124
|
+
const escopo = texto(args.opcoes.escopo)?.split(',').map(s => s.trim());
|
|
3125
|
+
if (sub === 'inventory' || (sub === 'migrate' && args.opcoes['dry-run'] === true)) {
|
|
3126
|
+
const r = (0, memory_migration_1.inventariarHandoffs)(carregado, escopo);
|
|
3127
|
+
if (args.opcoes.json === true)
|
|
3128
|
+
console.log(JSON.stringify(r, null, 2));
|
|
3129
|
+
else {
|
|
3130
|
+
console.log(`Inventario do tenant ${r.tenant}: ${r.incluidos} incluidos, ${r.excluidos} excluidos.`);
|
|
3131
|
+
for (const f of r.fontes)
|
|
3132
|
+
console.log(` ${f.incluir ? 'incluir' : 'excluir'} ${f.arquivo}: ${f.motivo}`);
|
|
3133
|
+
}
|
|
3134
|
+
return r.fontes.some(f => f.bloqueante) ? 1 : 0;
|
|
3135
|
+
}
|
|
3136
|
+
if (sub === 'migrate') {
|
|
3137
|
+
const operadora = texto(args.opcoes.operadora);
|
|
3138
|
+
if (!operadora || !escopo)
|
|
3139
|
+
throw new Error('scope.write.required: --operadora <thread> --escopo <thread,...>');
|
|
3140
|
+
if (carregado.manifesto.memory.mode === 'orkmind') {
|
|
3141
|
+
const autorizacao = (0, write_activation_1.exigirAtivacao)(carregado, operadora, 'memory');
|
|
3142
|
+
if (escopo.some(id => !autorizacao.threads.includes(id)))
|
|
3143
|
+
throw Error('write.activation.scope-denied');
|
|
3144
|
+
}
|
|
3145
|
+
const r = (0, memory_migration_1.migrarHandoffs)(carregado, { operadora, escopo });
|
|
3146
|
+
if (args.opcoes.json === true)
|
|
3147
|
+
console.log(JSON.stringify(r, null, 2));
|
|
3148
|
+
else {
|
|
3149
|
+
console.log(`Migracao do tenant ${r.inventario.tenant}: ${r.resultados.filter(i => i.ok).length} confirmados, ${r.falhas} falhas, ${r.inventario.excluidos} excluidos.`);
|
|
3150
|
+
for (const item of r.resultados)
|
|
3151
|
+
console.log(` ${item.arquivo}: ${item.ok ? item.gravacao?.id : item.erro}`);
|
|
3152
|
+
}
|
|
3153
|
+
return r.ok ? 0 : 1;
|
|
3154
|
+
}
|
|
3155
|
+
if (sub === 'sync' && args.posicionais[2])
|
|
3156
|
+
(0, escopo_escrita_1.validarDiretorioDeThread)(carregado.raiz, args.posicionais[2]);
|
|
1722
3157
|
if (sub === 'status') {
|
|
3158
|
+
const memoria = (0, memoria_1.abrirMemoria)(candidate);
|
|
1723
3159
|
if (args.opcoes.json === true) {
|
|
1724
|
-
console.log(JSON.stringify(memoria.estado, null, 2));
|
|
3160
|
+
console.log(JSON.stringify({ ...memoria.estado, configSource: memoria.configSource, configDivergent: memoria.configDivergent }, null, 2));
|
|
1725
3161
|
return 0;
|
|
1726
3162
|
}
|
|
1727
3163
|
console.log((0, memoria_1.textoDoEstado)(memoria.estado));
|
|
1728
3164
|
return 0;
|
|
1729
3165
|
}
|
|
1730
3166
|
if (sub === 'sync') {
|
|
3167
|
+
const memoria = (0, memoria_1.abrirMemoria)(carregado);
|
|
1731
3168
|
const threadId = args.posicionais[2];
|
|
1732
3169
|
// Thread inexistente reprova aqui, e nao no meio da gravacao.
|
|
1733
3170
|
if (threadId)
|
|
1734
3171
|
(0, thread_1.lerThread)(carregado.raiz, threadId);
|
|
1735
|
-
const
|
|
3172
|
+
const perfil = (texto(args.opcoes.perfil) ?? 'integral');
|
|
3173
|
+
if (!['fabrica', 'integral'].includes(perfil))
|
|
3174
|
+
throw Error('memory.publication.profile-invalid');
|
|
3175
|
+
if (carregado.manifesto.memory.mode === 'orkmind') {
|
|
3176
|
+
try {
|
|
3177
|
+
const autorizacao = (0, write_activation_1.exigirAtivacao)(carregado, threadId ?? '', 'memory');
|
|
3178
|
+
if (autorizacao.perfil !== 'integral' && perfil !== autorizacao.perfil)
|
|
3179
|
+
throw Error('write.activation.profile-denied');
|
|
3180
|
+
}
|
|
3181
|
+
catch (error) {
|
|
3182
|
+
const motivo = error instanceof Error
|
|
3183
|
+
? /^(?:write\.activation|scope|memory)\.[a-z.-]+/.exec(error.message)?.[0] ?? 'write.activation.invalid'
|
|
3184
|
+
: 'write.activation.invalid';
|
|
3185
|
+
const detalhe = 'sync nao executado; colisao legada nao foi reavaliada';
|
|
3186
|
+
if (args.opcoes.json === true)
|
|
3187
|
+
console.log(JSON.stringify({
|
|
3188
|
+
regime: memoria.regime, estado: memoria.estado, thread: threadId ?? null, perfil,
|
|
3189
|
+
publicacao: { estado: 'pendente', motivo }, falhas: 1, gravadas: [], erro: motivo, detalhe,
|
|
3190
|
+
}, null, 2));
|
|
3191
|
+
console.error(`${motivo}: ${detalhe}`);
|
|
3192
|
+
return 1;
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
const r = (0, memoria_1.sincronizarMemoria)(carregado, memoria, threadId ?? null, undefined, perfil);
|
|
1736
3196
|
if (args.opcoes.json === true) {
|
|
1737
3197
|
console.log(JSON.stringify(r, null, 2));
|
|
1738
3198
|
}
|
|
1739
3199
|
else {
|
|
1740
3200
|
console.log((0, memoria_1.textoDoSync)(r));
|
|
1741
3201
|
}
|
|
1742
|
-
return 0;
|
|
3202
|
+
return r.estado.pedido === 'orkmind' && r.falhas > 0 ? 1 : 0;
|
|
1743
3203
|
}
|
|
1744
3204
|
if (sub === 'search') {
|
|
3205
|
+
const threadId = texto(args.opcoes.thread);
|
|
3206
|
+
if ((args.opcoes.restrito !== undefined || args.opcoes.thread !== undefined ||
|
|
3207
|
+
args.opcoes.janela !== undefined) && !threadId) {
|
|
3208
|
+
throw Error('memory.query.thread-required: use --thread <id>');
|
|
3209
|
+
}
|
|
3210
|
+
const janela = limiteDeLeitura(args.opcoes.janela);
|
|
1745
3211
|
const tagsBrutas = texto(args.opcoes.tags);
|
|
1746
3212
|
if (!tagsBrutas) {
|
|
1747
3213
|
console.error('uso: ork memory search --tags \'{"project":["orkastery"],"skill":["orkastery-decision"]}\'');
|
|
@@ -1757,11 +3223,19 @@ function comandoMemory(args) {
|
|
|
1757
3223
|
}
|
|
1758
3224
|
const colecao = texto(args.opcoes.colecao) ?? texto(args.opcoes.collection);
|
|
1759
3225
|
const limiteBruto = texto(args.opcoes.limite);
|
|
3226
|
+
const limite = threadId ? limiteDeLeitura(args.opcoes.limite) : limiteBruto ? Number(limiteBruto) : undefined;
|
|
3227
|
+
if (threadId)
|
|
3228
|
+
(0, orkmind_1.validarConsultaDelimitada)({ collection: colecao,
|
|
3229
|
+
escopo: (0, orkmind_1.criarEscopoDeLeitura)(carregado.manifesto, threadId), tags,
|
|
3230
|
+
limite: janela ?? orkmind_1.LIMITE_CONSULTA_PADRAO });
|
|
3231
|
+
const memoria = (0, memoria_1.abrirMemoria)(carregado, threadId ? { leituraRestrita: { thread: threadId, limite: janela } } : {});
|
|
1760
3232
|
const entradas = memoria.buscar({
|
|
1761
3233
|
collection: colecao,
|
|
1762
3234
|
tags,
|
|
1763
|
-
limite
|
|
3235
|
+
limite,
|
|
1764
3236
|
});
|
|
3237
|
+
if (threadId && memoria.regime === 'files')
|
|
3238
|
+
console.error(`memory.query.files: ${memoria.estado.motivo}; resultado nao comprova ausencia na memoria semantica`);
|
|
1765
3239
|
if (args.opcoes.json === true) {
|
|
1766
3240
|
console.log(JSON.stringify(entradas, null, 2));
|
|
1767
3241
|
return 0;
|
|
@@ -1785,19 +3259,93 @@ function comandoMemory(args) {
|
|
|
1785
3259
|
return 2;
|
|
1786
3260
|
}
|
|
1787
3261
|
function main(argv) {
|
|
3262
|
+
// I-35: todo horário para pessoa sai no fuso do dono deste projeto (lido só se for preciso).
|
|
3263
|
+
(0, horario_1.registrarFonteDoFuso)(() => (0, horario_1.fusoDoManifesto)((0, manifest_1.carregarManifesto)()));
|
|
3264
|
+
// Helper fixo do host confiável: o projeto vem da instalação, nunca de toolargs.
|
|
3265
|
+
if (argv[0] === 'receipt-verifiers') {
|
|
3266
|
+
if (argv.length !== 2 || argv[1] !== '--json')
|
|
3267
|
+
throw Error('uso: ork receipt-verifiers --json');
|
|
3268
|
+
const root = process.env.ORK_HITL_ROOT;
|
|
3269
|
+
const privateKey = Object.keys(process.env).some(name => /^ORK_HITL_(?:INGRESS_KEY|NATIVE_KEY)/.test(name));
|
|
3270
|
+
if (root !== undefined || privateKey) {
|
|
3271
|
+
if (!root || !(0, node_path_1.isAbsolute)(root) || fs.realpathSync(root) !== root)
|
|
3272
|
+
throw Error('hitl.receipt.project-unavailable');
|
|
3273
|
+
const carregado = (0, manifest_1.exigirManifesto)(root);
|
|
3274
|
+
if (carregado.raiz !== root)
|
|
3275
|
+
throw Error('hitl.receipt.project-unavailable');
|
|
3276
|
+
for (const id of (0, thread_1.listarIds)(root))
|
|
3277
|
+
(0, hitl_ingress_receipt_1.prepararRecibosParaDespacho)(root, id);
|
|
3278
|
+
}
|
|
3279
|
+
console.log((0, hitl_public_receipt_1.publicHitlVerifiers)() ?? 'null');
|
|
3280
|
+
return 0;
|
|
3281
|
+
}
|
|
3282
|
+
if (argv[0] === 'maestro')
|
|
3283
|
+
return (0, maestro_cli_1.runMaestroCli)(argv.slice(1));
|
|
1788
3284
|
const args = parseArgs(argv);
|
|
1789
3285
|
const comando = args.posicionais[0];
|
|
3286
|
+
// `ork --version` tambem chega sem comando: a versao e conferida antes da ajuda.
|
|
3287
|
+
if (args.opcoes.version === true || comando === 'version') {
|
|
3288
|
+
console.log(VERSAO);
|
|
3289
|
+
return 0;
|
|
3290
|
+
}
|
|
1790
3291
|
if (!comando || args.opcoes.help === true || comando === 'help') {
|
|
1791
3292
|
console.log(AJUDA);
|
|
1792
3293
|
return 0;
|
|
1793
3294
|
}
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
3295
|
+
const nomesHerdados = (0, runtime_ambiente_1.nomesDeProviderAtivos)();
|
|
3296
|
+
const ambienteManifesto = (0, manifest_1.carregarManifesto)();
|
|
3297
|
+
if (ambienteManifesto?.manifesto.runtime.provider_policy === 'subscription-only') {
|
|
3298
|
+
// Avaliar ANTES de limpar: um redirecionamento bloqueante não pode desaparecer.
|
|
3299
|
+
const violacoes = (0, policies_1.avaliarPolicies)(ambienteManifesto.manifesto, { gate: 'phase.dispatch' });
|
|
3300
|
+
// O gate oficial precisa observar e registrar a violação (inclusive warn).
|
|
3301
|
+
// Diagnósticos continuam acessíveis; os adapters sanitizam seus filhos sempre.
|
|
3302
|
+
if (violacoes.length === 0)
|
|
3303
|
+
for (const nome of runtime_ambiente_1.ENVS_DE_PROVIDER_PAGO)
|
|
3304
|
+
delete process.env[nome];
|
|
1797
3305
|
}
|
|
1798
3306
|
switch (comando) {
|
|
3307
|
+
case 'mcp': {
|
|
3308
|
+
const projeto = texto(args.opcoes.project), host = texto(args.opcoes.host), threadId = texto(args.opcoes.thread);
|
|
3309
|
+
// I-36 (D4): a identidade do despacho so chega com a thread vinculada da sessao filha.
|
|
3310
|
+
const dispatchId = texto(args.opcoes.dispatch);
|
|
3311
|
+
const transporteShip = texto(args.opcoes['ship-transport']) ?? 'github-ssh';
|
|
3312
|
+
const permissoesFilho = texto(args.opcoes['child-permissions']) ?? 'interactive';
|
|
3313
|
+
const permissoesDono = texto(args.opcoes['owner-permissions']);
|
|
3314
|
+
const acao = args.posicionais[1];
|
|
3315
|
+
if (args.posicionais.length !== 2 || !['serve', 'install'].includes(acao) || !projeto ||
|
|
3316
|
+
(host !== 'codex' && host !== 'claude-code') ||
|
|
3317
|
+
Object.keys(args.opcoes).some(k => !['project', 'host', 'ship-transport', 'child-permissions', ...(acao === 'install' ? ['dry-run', 'owner-permissions'] : ['thread', 'dispatch'])].includes(k)) ||
|
|
3318
|
+
(args.opcoes.dispatch !== undefined && (!threadId || !dispatchId || !/^[a-f0-9-]{36}$/.test(dispatchId))) ||
|
|
3319
|
+
argv.filter(a => a === '--ship-transport' || a.startsWith('--ship-transport=')).length > 1 ||
|
|
3320
|
+
argv.filter(a => a === '--child-permissions' || a.startsWith('--child-permissions=')).length > 1 ||
|
|
3321
|
+
(args.opcoes['owner-permissions'] !== undefined && (host !== 'codex' || typeof args.opcoes['owner-permissions'] !== 'string' || !['interactive', 'orchestrate'].includes(permissoesDono ?? ''))) ||
|
|
3322
|
+
argv.filter(a => a === '--owner-permissions' || a.startsWith('--owner-permissions=')).length > 1 ||
|
|
3323
|
+
!['interactive', 'worktree'].includes(permissoesFilho) ||
|
|
3324
|
+
(args.opcoes['child-permissions'] !== undefined && typeof args.opcoes['child-permissions'] !== 'string') ||
|
|
3325
|
+
!['github-ssh', 'bare-local'].includes(transporteShip) ||
|
|
3326
|
+
(args.opcoes['ship-transport'] !== undefined && typeof args.opcoes['ship-transport'] !== 'string') ||
|
|
3327
|
+
(args.opcoes.thread !== undefined && (!threadId || !/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$/.test(threadId))) ||
|
|
3328
|
+
(args.opcoes['dry-run'] !== undefined && args.opcoes['dry-run'] !== true))
|
|
3329
|
+
throw new Error('uso: ork mcp serve|install --project <raiz absoluta> --host codex|claude-code [--ship-transport github-ssh|bare-local] [--child-permissions interactive|worktree] [--owner-permissions interactive|orchestrate somente install Codex] [--dry-run somente install]');
|
|
3330
|
+
if (acao === 'install') {
|
|
3331
|
+
void Promise.resolve().then(() => __importStar(require('./mcp-install'))).then(({ instalarMcp, textoInstalacaoMcp }) => console.log(textoInstalacaoMcp(instalarMcp({ projeto, host, dryRun: args.opcoes['dry-run'] === true, transporteShip: transporteShip, permissoesFilho: permissoesFilho, permissoesDono: permissoesDono }))))
|
|
3332
|
+
.catch(e => { console.error(`mcp: ${e.message}`); process.exitCode = 1; });
|
|
3333
|
+
return 0;
|
|
3334
|
+
}
|
|
3335
|
+
void Promise.resolve().then(() => __importStar(require('./mcp-server'))).then(({ servirMcp }) => servirMcp({ projeto, host, threadId, dispatchId, nomesProviderHerdados: nomesHerdados, transporteShip: transporteShip, permissoesFilho: permissoesFilho })).catch(e => { console.error(`mcp: ${e.message}`); process.exitCode = 1; });
|
|
3336
|
+
return 0;
|
|
3337
|
+
}
|
|
1799
3338
|
case 'doctor': {
|
|
1800
|
-
|
|
3339
|
+
if (args.opcoes.modo !== undefined) {
|
|
3340
|
+
const bruto = texto(args.opcoes.modo);
|
|
3341
|
+
if (args.posicionais.length !== 1 || !bruto ||
|
|
3342
|
+
Object.keys(args.opcoes).some(k => k !== 'modo') || argv.filter(a => a === '--modo' || a.startsWith('--modo=')).length !== 1)
|
|
3343
|
+
throw Error(`uso: ork doctor --modo ${modos_1.ORDEM_DOS_MODOS.join('|')}`);
|
|
3344
|
+
const r = (0, preflight_1.preflight)(process.cwd(), (0, modos_1.exigirModoVivo)(bruto), nomesHerdados);
|
|
3345
|
+
console.log((0, preflight_1.textoPreflight)(r));
|
|
3346
|
+
return r.prontoPrimeiroBloco ? 0 : 1;
|
|
3347
|
+
}
|
|
3348
|
+
const r = (0, doctor_1.doctor)(process.cwd(), nomesHerdados);
|
|
1801
3349
|
console.log(r.texto);
|
|
1802
3350
|
return r.codigo;
|
|
1803
3351
|
}
|
|
@@ -1807,9 +3355,12 @@ function main(argv) {
|
|
|
1807
3355
|
nome: texto(args.opcoes.name) ?? texto(args.opcoes.nome),
|
|
1808
3356
|
abbrev: texto(args.opcoes.abbrev),
|
|
1809
3357
|
});
|
|
3358
|
+
const carregado = (0, manifest_1.exigirManifesto)(r.deteccao.raiz);
|
|
3359
|
+
const agents = (0, agents_md_1.atualizarAgentsMd)(r.deteccao.raiz, carregado.manifesto);
|
|
1810
3360
|
if (!r.criado) {
|
|
1811
3361
|
console.log(`Manifesto ja existe: ${r.caminho}`);
|
|
1812
3362
|
console.log('Nada foi sobrescrito. Use --force para regerar.');
|
|
3363
|
+
console.log(`AGENTS.md ${agents.estado}: ${agents.caminho}`);
|
|
1813
3364
|
return 0;
|
|
1814
3365
|
}
|
|
1815
3366
|
console.log(`Manifesto criado: ${r.caminho}`);
|
|
@@ -1817,17 +3368,37 @@ function main(argv) {
|
|
|
1817
3368
|
console.log(` branch base ${r.deteccao.baseBranch}`);
|
|
1818
3369
|
console.log(` gerenciador ${r.deteccao.gerenciador}`);
|
|
1819
3370
|
console.log(` verify ${Object.entries(r.deteccao.verify).map(([k, v]) => `${k}="${v}"`).join(', ') || '(nenhum script detectado)'}`);
|
|
3371
|
+
console.log(` AGENTS.md ${agents.estado}: ${agents.caminho}`);
|
|
1820
3372
|
console.log('');
|
|
1821
|
-
console.log(
|
|
3373
|
+
console.log(init_2.PROXIMO_PASSO_INIT);
|
|
1822
3374
|
return 0;
|
|
1823
3375
|
}
|
|
1824
3376
|
case 'modos': {
|
|
3377
|
+
// I-43 (T4): `ork modos migrar` tira modo aposentado da CONFIGURACAO do projeto
|
|
3378
|
+
// (`orkastery.yaml` e `setup.json`) e nao toca em historico nenhum. Idempotente:
|
|
3379
|
+
// rodar de novo num projeto ja migrado nao escreve nada.
|
|
3380
|
+
if (args.posicionais[1] === 'migrar') {
|
|
3381
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
3382
|
+
const r = (0, modos_migracao_1.migrarModosAposentados)(carregado.raiz, {
|
|
3383
|
+
dryRun: args.opcoes['dry-run'] === true,
|
|
3384
|
+
por: texto(args.opcoes.por),
|
|
3385
|
+
});
|
|
3386
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : (0, modos_migracao_1.textoDaMigracaoModos)(r));
|
|
3387
|
+
return 0;
|
|
3388
|
+
}
|
|
1825
3389
|
// `--do-pedido` existe para os adaptadores de host: eles extraem a #TAG do texto do
|
|
1826
3390
|
// builder SEM reimplementar o parse, e repassam `--mode` ao `ork`. A validacao contra
|
|
1827
3391
|
// `conduction.allowed_modes` continua sendo do nucleo, no `ork thread new`.
|
|
1828
3392
|
const pedido = texto(args.opcoes['do-pedido']);
|
|
1829
3393
|
if (pedido !== undefined) {
|
|
1830
3394
|
const carregado = (0, manifest_1.carregarManifesto)();
|
|
3395
|
+
// I-43: `#Look` no pedido nao pode cair no default em silencio. O adaptador
|
|
3396
|
+
// recebe a recusa tipada e saida != 0, e quem escreveu a #TAG fica sabendo.
|
|
3397
|
+
const aposentado = (0, modos_1.extrairTagAposentadaDoPedido)(pedido);
|
|
3398
|
+
if (aposentado) {
|
|
3399
|
+
console.error((0, modos_1.recusaDeModoAposentado)(aposentado));
|
|
3400
|
+
return 2;
|
|
3401
|
+
}
|
|
1831
3402
|
const extraido = (0, modos_1.extrairTagDoPedido)(pedido);
|
|
1832
3403
|
const modo = extraido ?? carregado?.manifesto.conduction.default_mode ?? 'classic';
|
|
1833
3404
|
if (args.opcoes.json === true) {
|
|
@@ -1847,16 +3418,59 @@ function main(argv) {
|
|
|
1847
3418
|
console.log((0, modos_1.tabelaDeModos)());
|
|
1848
3419
|
return 0;
|
|
1849
3420
|
}
|
|
3421
|
+
case 'setup':
|
|
3422
|
+
return comandoSetup(args);
|
|
3423
|
+
case 'accounts':
|
|
3424
|
+
return comandoAccounts(args);
|
|
3425
|
+
case 'onboarding':
|
|
3426
|
+
return comandoOnboarding(args);
|
|
1850
3427
|
case 'thread':
|
|
1851
3428
|
return comandoThread(args);
|
|
3429
|
+
case 'objective':
|
|
3430
|
+
return comandoObjective(args);
|
|
3431
|
+
case 'creation':
|
|
3432
|
+
return comandoCreation(args);
|
|
3433
|
+
case 'portfolio':
|
|
3434
|
+
return comandoPortfolio(args);
|
|
1852
3435
|
case 'phase':
|
|
1853
3436
|
return comandoPhase(args);
|
|
3437
|
+
case 'ledger':
|
|
3438
|
+
return comandoLedger(args);
|
|
1854
3439
|
case 'sessions':
|
|
1855
3440
|
return comandoSessions(args);
|
|
3441
|
+
case 'pulse': {
|
|
3442
|
+
if (args.posicionais[1] === 'responder') {
|
|
3443
|
+
// I-41 (GO-FIX 1, B1 e B2): o caminho de volta do resumo. So o ingresso autenticado chama;
|
|
3444
|
+
// argv traz identificadores e o envelope assinado vem por stdin, como no `gate answer`.
|
|
3445
|
+
if (args.opcoes['resposta-stdin'] !== true || args.opcoes.resposta !== undefined || args.posicionais.length !== 2) {
|
|
3446
|
+
throw new Error('pulse responder exige --resposta-stdin e o envelope do ingresso autenticado');
|
|
3447
|
+
}
|
|
3448
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
3449
|
+
const envelope = (0, hitl_gates_1.lerRespostaStdin)({ por: texto(args.opcoes.por), mensagem: texto(args.opcoes.mensagem),
|
|
3450
|
+
origem: texto(args.opcoes.origem), canal: texto(args.opcoes.canal), conta: texto(args.opcoes.conta) });
|
|
3451
|
+
const formato = texto(args.opcoes.formato);
|
|
3452
|
+
if (formato !== undefined && formato !== 'telegram' && formato !== 'terminal')
|
|
3453
|
+
throw new Error('pulse responder: --formato telegram|terminal');
|
|
3454
|
+
console.log(JSON.stringify((0, pulse_resposta_1.responderPeloPulse)(carregado.raiz, envelope, { canal: formato ?? 'telegram' })));
|
|
3455
|
+
return 0;
|
|
3456
|
+
}
|
|
3457
|
+
if (args.posicionais[1] === 'cadencia')
|
|
3458
|
+
return comandoCadenciaDoPulse(args);
|
|
3459
|
+
const p = (0, pulse_1.montarPulse)((0, manifest_1.exigirManifesto)(), { registrar: args.opcoes.registrar === true,
|
|
3460
|
+
escopo: texto(args.opcoes.escopo)?.split(',').map(s => s.trim()),
|
|
3461
|
+
semRuntime: args.opcoes['sem-runtime'] === true,
|
|
3462
|
+
linhasLogs: texto(args.opcoes.linhas) === undefined ? undefined : Number(texto(args.opcoes.linhas)) });
|
|
3463
|
+
console.log(args.opcoes.json === true ? JSON.stringify(p, null, 2) : (0, pulse_1.textoDoPulse)(p));
|
|
3464
|
+
return p.runtime.ok || args.opcoes['sem-runtime'] === true ? 0 : 1;
|
|
3465
|
+
}
|
|
1856
3466
|
case 'claims':
|
|
1857
3467
|
return comandoClaims(args);
|
|
3468
|
+
case 'decisao':
|
|
3469
|
+
return comandoDecisao(args);
|
|
1858
3470
|
case 'verify':
|
|
1859
3471
|
return comandoVerify(args);
|
|
3472
|
+
case 'ci':
|
|
3473
|
+
return comandoCi(args);
|
|
1860
3474
|
case 'gate':
|
|
1861
3475
|
return comandoGate(args);
|
|
1862
3476
|
case 'retry':
|
|
@@ -1867,12 +3481,21 @@ function main(argv) {
|
|
|
1867
3481
|
return comandoHandoff(args);
|
|
1868
3482
|
case 'recall':
|
|
1869
3483
|
return comandoRecall(args);
|
|
3484
|
+
case 'brain': {
|
|
3485
|
+
const result = (0, company_brain_cli_1.runBrain)((0, manifest_1.exigirManifesto)(), args.posicionais[1] ?? 'status', args.opcoes, args.posicionais.slice(2));
|
|
3486
|
+
console.log(JSON.stringify(result, null, 2));
|
|
3487
|
+
return ['ok', 'empty', 'unknown', 'withheld', 'applied', 'rolled-back'].includes(result.state) ? 0 : 1;
|
|
3488
|
+
}
|
|
1870
3489
|
case 'memory':
|
|
1871
3490
|
return comandoMemory(args);
|
|
1872
3491
|
case 'ship':
|
|
1873
3492
|
return comandoShip(args);
|
|
3493
|
+
case 'activation':
|
|
3494
|
+
return (0, write_activation_1.comandoAtivacao)((0, manifest_1.exigirManifesto)(), args);
|
|
1874
3495
|
case 'lease':
|
|
1875
3496
|
return comandoLease(args);
|
|
3497
|
+
case 'conducao':
|
|
3498
|
+
return comandoConducao(args);
|
|
1876
3499
|
case 'board':
|
|
1877
3500
|
return comandoBoard(args);
|
|
1878
3501
|
case 'orquestracao':
|
|
@@ -1890,6 +3513,19 @@ function main(argv) {
|
|
|
1890
3513
|
return comandoAdapter(args);
|
|
1891
3514
|
case 'prompt':
|
|
1892
3515
|
return comandoPrompt(args);
|
|
3516
|
+
case 'docs':
|
|
3517
|
+
return comandoDocs(args);
|
|
3518
|
+
case 'roadmap':
|
|
3519
|
+
return comandoRoadmap(args);
|
|
3520
|
+
case 'demo': {
|
|
3521
|
+
// I-56 (RM-046): a promessa em trinta segundos, offline, sem runtime e sem tocar o projeto.
|
|
3522
|
+
const r = (0, demo_1.executarDemo)({ dir: texto(args.opcoes.dir), manter: args.opcoes.manter === true, escrever: (l) => console.log(l) });
|
|
3523
|
+
return r.ok ? 0 : 1;
|
|
3524
|
+
}
|
|
3525
|
+
case 'fabrica':
|
|
3526
|
+
return comandoFabrica(args);
|
|
3527
|
+
case 'licoes':
|
|
3528
|
+
return comandoLicoes(args);
|
|
1893
3529
|
case 'ciclos':
|
|
1894
3530
|
console.log((0, ciclos_1.tabelaDeVariantes)());
|
|
1895
3531
|
return 0;
|
|
@@ -1904,7 +3540,14 @@ if (require.main === module) {
|
|
|
1904
3540
|
process.exitCode = main(process.argv.slice(2));
|
|
1905
3541
|
}
|
|
1906
3542
|
catch (e) {
|
|
1907
|
-
|
|
1908
|
-
|
|
3543
|
+
// I-36 (T12): a recusa de conducao e resposta, nao erro: o texto para o humano, ou o JSON.
|
|
3544
|
+
if (e instanceof conducao_1.ErroDeConducao) {
|
|
3545
|
+
console.log(process.argv.includes('--json') ? JSON.stringify(e.recusa, null, 2) : e.recusa.texto);
|
|
3546
|
+
process.exitCode = 3;
|
|
3547
|
+
}
|
|
3548
|
+
else {
|
|
3549
|
+
console.error(`erro: ${e.message}`);
|
|
3550
|
+
process.exitCode = 1;
|
|
3551
|
+
}
|
|
1909
3552
|
}
|
|
1910
3553
|
}
|