@orkastery/cli 0.2.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/check.md +4 -3
- package/adapters/claude-code/commands/goal.md +3 -2
- package/adapters/claude-code/commands/master.md +3 -2
- 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-guard.js +1 -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 +161 -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-pulse-enviar.py +47 -0
- package/adapters/hermes/hermes.plugin.json +24 -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 +136 -27
- 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 +460 -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 +12 -9
- package/dist/auditrun.js +5 -4
- package/dist/board.js +174 -23
- 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 +223 -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 +184 -25
- 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 +22 -1
- package/dist/gates.js +59 -11
- 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 +1741 -94
- 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 +109 -2
- package/dist/licoes.js +221 -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 +612 -151
- package/dist/playbook-capabilities.js +150 -0
- package/dist/playbook-contracts.js +188 -0
- package/dist/policies.js +72 -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 +640 -118
- 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 +700 -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 +168 -19
- 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 +5 -1
- package/eval/casos/master-metrics.json +1 -1
- package/eval/casos/onboarding.json +102 -0
- package/eval/casos/orkastery-bootstrap.json +37 -3
- package/eval/casos/scope-check-capability-map.json +45 -7
- package/eval/casos/ship-release.json +3 -3
- 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 +28 -7
- package/references/definition-of-done.md +2 -2
- 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/README.md +3 -3
- 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/decision-triage/SKILL.md +4 -4
- package/skills/governance/narrative-guardian/SKILL.md +1 -1
- package/skills/governance/roadmap-keeper/SKILL.md +1 -1
- package/skills/governance/scope-check-capability-map/SKILL.md +17 -7
- package/skills/observability/thread-tracing/SKILL.md +1 -1
- package/skills/phases/check-quality/SKILL.md +2 -2
- package/skills/phases/goal-definition/SKILL.md +1 -1
- package/skills/phases/master-metrics/SKILL.md +9 -7
- package/skills/phases/plan-specification/SKILL.md +1 -1
- package/skills/phases/ship-release/SKILL.md +1 -1
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,39 @@ 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(' ')}`);
|
|
1025
|
+
for (const l of (0, policies_1.linhasDeAviso)(r.violacoes ?? []))
|
|
1026
|
+
console.log(l);
|
|
423
1027
|
return 0;
|
|
424
1028
|
}
|
|
425
1029
|
if (r.bloqueado) {
|
|
@@ -432,20 +1036,29 @@ function comandoPhase(args) {
|
|
|
432
1036
|
return 1;
|
|
433
1037
|
}
|
|
434
1038
|
if (!r.sessionId) {
|
|
435
|
-
|
|
1039
|
+
// I-35: o erro vai ao ledger com o ISO; o dono le no fuso dele, com o fuso dito uma vez.
|
|
1040
|
+
console.error(`Despacho falhou: ${r.erro ? (0, horario_1.localizarTextoRotulado)(r.erro) : r.erro}`);
|
|
436
1041
|
console.error(` evento registrado no ledger de ${id}`);
|
|
437
1042
|
return 1;
|
|
438
1043
|
}
|
|
439
1044
|
console.log(`Fase ${fase} despachada como background agent.`);
|
|
1045
|
+
for (const l of (0, policies_1.linhasDeAviso)(r.violacoes ?? []))
|
|
1046
|
+
console.log(l);
|
|
440
1047
|
console.log(` sessionId : ${r.sessionId}`);
|
|
441
1048
|
console.log(` slug da sessao : ${r.slug} (${(0, phase_1.descreverSlug)(r.slug)})`);
|
|
442
1049
|
console.log(` prompt : ${r.promptPath}`);
|
|
443
1050
|
console.log(` sha256 : ${r.promptSha256}`);
|
|
1051
|
+
console.log(` runtime : ${r.runtime}`);
|
|
444
1052
|
console.log(` modelo/esforco : ${r.model}/${r.effort} (gravado no ledger, veja \`ork phase list\`)`);
|
|
445
1053
|
console.log(` verificada no runtime: ${r.verificada ? 'sim' : 'NAO (confira `ork sessions`)'}`);
|
|
446
1054
|
console.log(` pausa ao fim do bloco: ${r.pausaAoFim ? 'sim' : 'nao (decisao autonoma no ledger)'}`);
|
|
447
1055
|
console.log('');
|
|
448
|
-
|
|
1056
|
+
if (r.runtime === 'claude-bg') {
|
|
1057
|
+
console.log(`Acompanhe: claude attach ${r.sessionId} | ork phase list ${id}`);
|
|
1058
|
+
}
|
|
1059
|
+
else {
|
|
1060
|
+
console.log(`Acompanhe: ork phase list ${id} (eventos do despacho no log da thread)`);
|
|
1061
|
+
}
|
|
449
1062
|
return r.verificada ? 0 : 1;
|
|
450
1063
|
}
|
|
451
1064
|
if (sub === 'list') {
|
|
@@ -460,12 +1073,137 @@ function comandoPhase(args) {
|
|
|
460
1073
|
console.error(`subcomando desconhecido: phase ${sub}`);
|
|
461
1074
|
return 2;
|
|
462
1075
|
}
|
|
1076
|
+
function comandoLedger(args) {
|
|
1077
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1078
|
+
const sub = args.posicionais[1];
|
|
1079
|
+
if (sub === 'stats') {
|
|
1080
|
+
const desde = texto(args.opcoes.desde);
|
|
1081
|
+
if (!desde)
|
|
1082
|
+
throw Error('uso: ork ledger stats --desde 7d [--ate ISO] [--thread T] [--modo M] [--runtime R] [--json]');
|
|
1083
|
+
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) });
|
|
1084
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : (0, ledger_stats_1.textoDasEstatisticas)(r));
|
|
1085
|
+
return 0;
|
|
1086
|
+
}
|
|
1087
|
+
if (sub === 'estimate') {
|
|
1088
|
+
const thread = args.posicionais[2], semIa = Number(texto(args.opcoes['sem-ia'])), iaSemOrk = Number(texto(args.opcoes['ia-sem-ork']));
|
|
1089
|
+
const por = texto(args.opcoes.por), metodo = texto(args.opcoes.metodo), premissas = texto(args.opcoes.premissas);
|
|
1090
|
+
if (!thread || !por || !metodo || !premissas)
|
|
1091
|
+
throw Error('uso: ork ledger estimate <thread-id> --sem-ia H --ia-sem-ork H --por Q --metodo M --premissas P [--incerteza I]');
|
|
1092
|
+
const e = (0, ledger_stats_1.registrarEstimativaPlano)(carregado.raiz, thread, { semIaHoras: semIa, iaSemOrkHoras: iaSemOrk, por, metodo, premissas, incerteza: texto(args.opcoes.incerteza) });
|
|
1093
|
+
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.`);
|
|
1094
|
+
return 0;
|
|
1095
|
+
}
|
|
1096
|
+
throw Error('uso: ork ledger stats|estimate ...');
|
|
1097
|
+
}
|
|
1098
|
+
/**
|
|
1099
|
+
* `ork sessions hitl`: quem, entre as sessoes do runtime, espera o humano AGORA.
|
|
1100
|
+
*
|
|
1101
|
+
* Complementa o `ork monitor`, que e thread-centrico: aqui a varredura parte das SESSOES,
|
|
1102
|
+
* entao ela enxerga a sessao `claude --bg` que travou em HITL sem ter thread nenhuma --
|
|
1103
|
+
* o buraco exato do incidente de 05/09/2026 (codigo 2FA do `npm publish`).
|
|
1104
|
+
*
|
|
1105
|
+
* O `--exigir-limpo` transforma o radar em watchdog: sai != 0 enquanto houver sessao
|
|
1106
|
+
* esperando humano, entao um cron ou o proprio orquestrador trata "tem gente esperando"
|
|
1107
|
+
* como falha acionavel, sem precisar interpretar texto.
|
|
1108
|
+
*/
|
|
1109
|
+
function comandoSessionsHitl(args, raiz) {
|
|
1110
|
+
const bruto = texto(args.opcoes.atencao);
|
|
1111
|
+
const atencaoMin = bruto === undefined ? undefined : Number(bruto);
|
|
1112
|
+
if (atencaoMin !== undefined && (!Number.isFinite(atencaoMin) || atencaoMin < 0)) {
|
|
1113
|
+
console.error(`--atencao espera minutos (inteiro >= 0), recebeu "${bruto}"`);
|
|
1114
|
+
return 2;
|
|
1115
|
+
}
|
|
1116
|
+
const radar = (0, hitl_1.varrerSessoes)({
|
|
1117
|
+
raiz,
|
|
1118
|
+
registrar: args.opcoes.registrar === true,
|
|
1119
|
+
escopo: texto(args.opcoes.escopo)?.split(',').map(s => s.trim()),
|
|
1120
|
+
registrarMaquina: args.opcoes['registrar-maquina'] === true,
|
|
1121
|
+
linhasLogs: texto(args.opcoes.linhas) === undefined ? undefined : Number(texto(args.opcoes.linhas)),
|
|
1122
|
+
soDaRaiz: args.opcoes['so-da-raiz'] === true,
|
|
1123
|
+
soParadas: args.opcoes['so-paradas'] === true,
|
|
1124
|
+
semLogs: args.opcoes['sem-logs'] === true,
|
|
1125
|
+
atencaoMin,
|
|
1126
|
+
});
|
|
1127
|
+
console.log(args.opcoes.json === true ? JSON.stringify(radar, null, 2) : (0, hitl_1.textoDoRadar)(radar));
|
|
1128
|
+
if (!radar.runtimeConsultado)
|
|
1129
|
+
return 1;
|
|
1130
|
+
if (args.opcoes['exigir-limpo'] === true)
|
|
1131
|
+
return radar.resumo.precisamDeHumano > 0 ? 1 : 0;
|
|
1132
|
+
return 0;
|
|
1133
|
+
}
|
|
463
1134
|
function comandoSessions(args) {
|
|
464
1135
|
const sub = args.posicionais[1];
|
|
465
1136
|
const carregado = (0, manifest_1.carregarManifesto)();
|
|
466
1137
|
const raiz = carregado?.raiz ?? process.cwd();
|
|
1138
|
+
if (sub === 'watch') {
|
|
1139
|
+
const id = texto(args.opcoes.thread);
|
|
1140
|
+
if (!carregado || !id) {
|
|
1141
|
+
console.error('uso: ork sessions watch --thread T [--sessao ID] [--once]');
|
|
1142
|
+
return 2;
|
|
1143
|
+
}
|
|
1144
|
+
const thread = (0, thread_1.lerThread)(raiz, id);
|
|
1145
|
+
const sessionId = texto(args.opcoes.sessao) ?? thread.sessoes.at(-1)?.sessionId;
|
|
1146
|
+
if (!sessionId || !thread.sessoes.some(s => s.sessionId === sessionId))
|
|
1147
|
+
throw new Error('sessão não pertence à thread');
|
|
1148
|
+
console.log(JSON.stringify(args.opcoes.once === true ? (0, session_watcher_1.observarSessao)(carregado, sessionId) : { pid: (0, session_watcher_1.iniciarWatcher)(raiz, sessionId) }));
|
|
1149
|
+
return 0;
|
|
1150
|
+
}
|
|
1151
|
+
if (sub === 'event') {
|
|
1152
|
+
const tipo = texto(args.opcoes.tipo), sessao = texto(args.opcoes.sessao);
|
|
1153
|
+
if (!carregado || !tipo || !sessao) {
|
|
1154
|
+
console.error('uso: ork sessions event --tipo <tipo> --sessao <id> < payload.json (máximo 16384 bytes)');
|
|
1155
|
+
return 2;
|
|
1156
|
+
}
|
|
1157
|
+
try {
|
|
1158
|
+
console.log(JSON.stringify((0, session_events_1.ingerirEvento)(raiz, sessao, tipo, (0, session_events_1.lerPayloadSensor)())));
|
|
1159
|
+
return 0;
|
|
1160
|
+
}
|
|
1161
|
+
catch (e) {
|
|
1162
|
+
console.error(`evento recusado: ${e.message}`);
|
|
1163
|
+
return 1;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
467
1166
|
if (sub === undefined || sub === 'list') {
|
|
468
|
-
|
|
1167
|
+
const r = (0, sessoes_inventario_1.inventariarSessoes)(raiz, { todas: args.opcoes.all === true, global: args.opcoes.global === true });
|
|
1168
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : (0, sessoes_1.textoDoInventario)(r));
|
|
1169
|
+
return !r.ok || (args.opcoes['exigir-limpo'] === true && r.semThread > 0) ? 1 : 0;
|
|
1170
|
+
}
|
|
1171
|
+
if (sub === 'hitl') {
|
|
1172
|
+
return comandoSessionsHitl(args, carregado ? raiz : '');
|
|
1173
|
+
}
|
|
1174
|
+
if (sub === 'request') {
|
|
1175
|
+
const id = args.posicionais[2], sessionId = args.posicionais[3];
|
|
1176
|
+
const fase = texto(args.opcoes.fase), runtime = texto(args.opcoes.runtime), pergunta = texto(args.opcoes.pergunta);
|
|
1177
|
+
if (!id || !sessionId || !fase || !types_1.FASES.includes(fase) || !runtime)
|
|
1178
|
+
throw new Error('sessions request exige thread, UUID, --fase e --runtime; --pergunta só confere o conteúdo nativo');
|
|
1179
|
+
console.log(JSON.stringify((0, hitl_sessions_1.abrirPedidoSessao)(raiz, id, sessionId, { fase: fase, runtime, pergunta, prazo: texto(args.opcoes.prazo) })));
|
|
1180
|
+
return 0;
|
|
1181
|
+
}
|
|
1182
|
+
if (sub === 'answer') {
|
|
1183
|
+
const id = args.posicionais[2], pedido = args.posicionais[3];
|
|
1184
|
+
if (!id || !pedido || args.opcoes.stdin !== true)
|
|
1185
|
+
throw new Error('sessions answer exige thread, pedido e envelope autenticado em --stdin');
|
|
1186
|
+
const r = (0, hitl_gates_1.lerRespostaStdin)({ origem: texto(args.opcoes.origem), por: texto(args.opcoes.por),
|
|
1187
|
+
mensagem: texto(args.opcoes.mensagem), canal: texto(args.opcoes.canal), conta: texto(args.opcoes.conta) });
|
|
1188
|
+
console.log(JSON.stringify((0, hitl_sessions_1.responderSessao)(raiz, id, pedido, r)));
|
|
1189
|
+
return 0;
|
|
1190
|
+
}
|
|
1191
|
+
if (sub === 'reconcile') {
|
|
1192
|
+
// FX3: fecha um envio pendente so com (thread, pedido). Nao reenvia e nao re-elicita:
|
|
1193
|
+
// pergunta ao receptor, pelo recibo correlacionado, se ele recebeu aquele envioId.
|
|
1194
|
+
const id = args.posicionais[2], pedido = args.posicionais[3];
|
|
1195
|
+
if (!id || !pedido)
|
|
1196
|
+
throw new Error('sessions reconcile exige thread e pedido');
|
|
1197
|
+
const r = (0, hitl_sessions_1.reconciliarEnvioDeSessao)(raiz, id, pedido);
|
|
1198
|
+
console.log(JSON.stringify(r));
|
|
1199
|
+
return r.estado === 'entregue' ? 0 : 1;
|
|
1200
|
+
}
|
|
1201
|
+
if (sub === 'supersede') {
|
|
1202
|
+
const id = args.posicionais[2], sessionId = args.posicionais[3];
|
|
1203
|
+
const fase = texto(args.opcoes.fase), runtime = texto(args.opcoes.runtime);
|
|
1204
|
+
if (!id || !sessionId || !fase || !types_1.FASES.includes(fase) || !runtime)
|
|
1205
|
+
throw new Error('sessions supersede exige thread, UUID, --fase e --runtime');
|
|
1206
|
+
console.log(JSON.stringify((0, hitl_sessions_1.superarSessao)(raiz, id, sessionId, fase, runtime)));
|
|
469
1207
|
return 0;
|
|
470
1208
|
}
|
|
471
1209
|
const chave = args.posicionais[2];
|
|
@@ -473,25 +1211,110 @@ function comandoSessions(args) {
|
|
|
473
1211
|
console.error(`uso: ork sessions ${sub} <sessao>`);
|
|
474
1212
|
return 2;
|
|
475
1213
|
}
|
|
1214
|
+
if (sub === 'adopt') {
|
|
1215
|
+
const r = (0, sessoes_adopt_1.adotarSessao)((0, manifest_1.exigirManifesto)(), chave);
|
|
1216
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) :
|
|
1217
|
+
`${r.detalhe}${r.vinculo ? `: ${r.sessionId} -> ${r.vinculo.thread} (${r.vinculo.raiz})` : ''}`);
|
|
1218
|
+
return r.ok ? 0 : 1;
|
|
1219
|
+
}
|
|
476
1220
|
if (sub === 'logs') {
|
|
477
1221
|
const n = Number(texto(args.opcoes.linhas) ?? '60');
|
|
478
|
-
const r = (0,
|
|
1222
|
+
const r = (0, sessoes_2.logsDaSessao)(chave, Number.isFinite(n) ? n : 60);
|
|
479
1223
|
console.log(r.texto);
|
|
480
1224
|
return r.codigo;
|
|
481
1225
|
}
|
|
482
1226
|
if (sub === 'stop') {
|
|
483
|
-
const r = (0,
|
|
1227
|
+
const r = (0, sessoes_2.pararSessao)(chave);
|
|
484
1228
|
console.log(r.texto);
|
|
485
1229
|
return r.codigo;
|
|
486
1230
|
}
|
|
487
1231
|
if (sub === 'attach') {
|
|
488
|
-
const r = (0,
|
|
1232
|
+
const r = (0, sessoes_2.comandoDeAttach)(chave);
|
|
489
1233
|
console.log(r.texto);
|
|
490
1234
|
return r.codigo;
|
|
491
1235
|
}
|
|
492
1236
|
console.error(`subcomando desconhecido: sessions ${sub}`);
|
|
493
1237
|
return 2;
|
|
494
1238
|
}
|
|
1239
|
+
/**
|
|
1240
|
+
* I-41 (GO-FIX 1, B4): a decisao que a sessao toma sem perguntar ao dono vai ao ledger por aqui,
|
|
1241
|
+
* com o que foi decidido, o porque, como mudar, o custo de reverter, o criterio escrito, quem
|
|
1242
|
+
* decidiu e a evidencia. E assim que ela chega ao dono no resumo, em vez de sumir na conversa.
|
|
1243
|
+
*/
|
|
1244
|
+
function comandoDecisao(args) {
|
|
1245
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1246
|
+
const sub = args.posicionais[1], id = args.posicionais[2];
|
|
1247
|
+
if (sub === 'registrar') {
|
|
1248
|
+
const campo = (nome) => {
|
|
1249
|
+
const v = texto(args.opcoes[nome]);
|
|
1250
|
+
if (!v)
|
|
1251
|
+
throw new Error(`decisao registrar exige --${nome}`);
|
|
1252
|
+
return v;
|
|
1253
|
+
};
|
|
1254
|
+
if (!id)
|
|
1255
|
+
throw new Error('uso: ork decisao registrar <thread-id> --decidido D --porque P ...');
|
|
1256
|
+
const bruto = campo('criterio'), separador = bruto.indexOf(':');
|
|
1257
|
+
const tipo = bruto.slice(0, separador), referencia = bruto.slice(separador + 1);
|
|
1258
|
+
if (separador < 1 || !['manifesto', 'ledger', 'medicao'].includes(tipo) || !referencia.trim()) {
|
|
1259
|
+
throw new Error('decisao registrar: --criterio manifesto:CHAVE, ledger:REF ou medicao:COMANDO');
|
|
1260
|
+
}
|
|
1261
|
+
const { pedido, evento } = (0, decisao_autonoma_1.registrarDecisao)(carregado.raiz, id, {
|
|
1262
|
+
decidido: campo('decidido'), porque: campo('porque'), comoMudar: campo('como-mudar'),
|
|
1263
|
+
custoDeReverter: { agora: campo('custo-agora'), depois: campo('custo-depois') },
|
|
1264
|
+
criterio: { tipo, referencia }, quemDecidiu: campo('quem'), evidencia: campo('evidencia'),
|
|
1265
|
+
razao: texto(args.opcoes.razao), reverte: texto(args.opcoes.reverte),
|
|
1266
|
+
});
|
|
1267
|
+
const placar = (0, decisao_autonoma_1.placarDaThread)((0, ledger_1.lerLedger)((0, thread_1.dirThread)(carregado.raiz, id))).find(f => f.fase === pedido.fase);
|
|
1268
|
+
console.log(JSON.stringify({ ok: true, pedidoId: pedido.id, eventId: evento.eventId, fase: pedido.fase, placar }));
|
|
1269
|
+
return 0;
|
|
1270
|
+
}
|
|
1271
|
+
if (sub === 'placar') {
|
|
1272
|
+
if (!id)
|
|
1273
|
+
throw new Error('uso: ork decisao placar <thread-id> [--json]');
|
|
1274
|
+
(0, thread_1.lerThread)(carregado.raiz, id);
|
|
1275
|
+
const placar = (0, decisao_autonoma_1.placarDaThread)((0, ledger_1.lerLedger)((0, thread_1.dirThread)(carregado.raiz, id)));
|
|
1276
|
+
const taxa = (0, decisao_autonoma_1.taxaDeReversao)(placar);
|
|
1277
|
+
if (args.opcoes.json === true) {
|
|
1278
|
+
console.log(JSON.stringify({ thread: id, limiar: decisao_autonoma_1.LIMIAR_DE_DECISOES_POR_FASE, taxaDeReversao: taxa, fases: placar }, null, 2));
|
|
1279
|
+
return 0;
|
|
1280
|
+
}
|
|
1281
|
+
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),
|
|
1282
|
+
String(f.semRastro), f.acimaDoLimiar ? `acima de ${decisao_autonoma_1.LIMIAR_DE_DECISOES_POR_FASE}: revisar` : 'ok'])));
|
|
1283
|
+
console.log(`\ntaxa de reversão das decisões informadas: ${taxa === null ? 'sem decisão informada ainda' : `${Math.round(taxa * 100)}%`}`);
|
|
1284
|
+
return 0;
|
|
1285
|
+
}
|
|
1286
|
+
throw new Error('uso: ork decisao registrar|placar <thread-id>');
|
|
1287
|
+
}
|
|
1288
|
+
/**
|
|
1289
|
+
* I-50 (RM-039): a tag que o dono manda no Telegram, pelo terminal. Sem tag, mostra a cadencia em
|
|
1290
|
+
* vigor. O `#` e opcional porque o shell trata `#` no inicio da palavra como comentario.
|
|
1291
|
+
*/
|
|
1292
|
+
function comandoCadenciaDoPulse(args) {
|
|
1293
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1294
|
+
if (args.posicionais.length > 3)
|
|
1295
|
+
throw new Error('pulse cadencia: uma tag por vez');
|
|
1296
|
+
const bruta = args.posicionais[2];
|
|
1297
|
+
const agora = new Date().toISOString();
|
|
1298
|
+
if (bruta !== undefined) {
|
|
1299
|
+
const lido = (0, pulse_resposta_1.interpretarRespostaDoPulse)(bruta.trim().startsWith('#') ? bruta : `#${bruta.trim()}`);
|
|
1300
|
+
if (lido.forma !== 'cadencia') {
|
|
1301
|
+
throw new Error(`pulse cadencia: tag desconhecida "${bruta}"; use ${Object.keys(pulse_cadencia_1.CADENCIAS).join(', ')}`);
|
|
1302
|
+
}
|
|
1303
|
+
(0, pulse_cadencia_1.gravarCadencia)(carregado.raiz, lido.tag, { por: texto(args.opcoes.por) ?? (0, node_os_1.userInfo)().username,
|
|
1304
|
+
canal: texto(args.opcoes.canal) ?? 'terminal', em: agora });
|
|
1305
|
+
}
|
|
1306
|
+
const vigente = (0, pulse_cadencia_1.lerCadencia)(carregado.raiz);
|
|
1307
|
+
if (args.opcoes.json === true) {
|
|
1308
|
+
console.log(JSON.stringify({ tag: vigente.tag, janelaMin: vigente.janelaMin, ancoraMin: vigente.ancoraMin,
|
|
1309
|
+
descricao: vigente.descricao, gravada: vigente.gravada, proximaJanela: (0, pulse_cadencia_1.inicioDaProximaJanela)(vigente, agora) }, null, 2));
|
|
1310
|
+
return 0;
|
|
1311
|
+
}
|
|
1312
|
+
console.log((0, pulse_cadencia_1.textoDaCadencia)(vigente, agora));
|
|
1313
|
+
console.log(vigente.gravada
|
|
1314
|
+
? `Trocada por ${vigente.gravada.por} (${vigente.gravada.canal}) em ${(0, horario_1.formatarDataHoraRotulada)(vigente.gravada.em)}.`
|
|
1315
|
+
: 'Nenhuma tag gravada: vale a cadência padrão.');
|
|
1316
|
+
return 0;
|
|
1317
|
+
}
|
|
495
1318
|
function comandoClaims(args) {
|
|
496
1319
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
497
1320
|
const sub = args.posicionais[1];
|
|
@@ -522,6 +1345,11 @@ function comandoClaims(args) {
|
|
|
522
1345
|
console.log('');
|
|
523
1346
|
console.log('AVISO: alegacao negativa sem comando de verificacao reprova em `ork verify`.');
|
|
524
1347
|
}
|
|
1348
|
+
// I-53 (RM-037, P6): o lint avisa aqui; a suite inteira e recusada no `ci prepare`.
|
|
1349
|
+
for (const a of claim.lint ?? []) {
|
|
1350
|
+
console.log('');
|
|
1351
|
+
console.log(`AVISO: ${(0, claim_lint_1.linhaDoLintDeClaim)(claim.id, a)}${a.regra === 'suite-inteira' ? '. O `ci prepare` recusa esta claim.' : ''}`);
|
|
1352
|
+
}
|
|
525
1353
|
return 0;
|
|
526
1354
|
}
|
|
527
1355
|
if (sub === 'verificar') {
|
|
@@ -555,6 +1383,19 @@ function comandoClaims(args) {
|
|
|
555
1383
|
console.log(' o historico da alegacao continua no claims.jsonl e no ledger.');
|
|
556
1384
|
return 0;
|
|
557
1385
|
}
|
|
1386
|
+
if (sub === 'ausente') {
|
|
1387
|
+
const id = args.posicionais[2];
|
|
1388
|
+
const paths = (texto(args.opcoes.paths) ?? '').split(',').map((p) => p.trim()).filter(Boolean);
|
|
1389
|
+
const motivo = texto(args.opcoes.motivo);
|
|
1390
|
+
if (!id || paths.length === 0 || !motivo) {
|
|
1391
|
+
console.error('uso: ork claims ausente <thread-id> --paths A,B --motivo "<motivo>" [--commit SHA]');
|
|
1392
|
+
return 2;
|
|
1393
|
+
}
|
|
1394
|
+
(0, prova_minima_1.registrarProvaAusente)(carregado.raiz, id, { paths, motivo, commit: texto(args.opcoes.commit) });
|
|
1395
|
+
console.log(`Ausencia de prova registrada na thread ${id}: ${paths.join(', ')}.`);
|
|
1396
|
+
console.log(` motivo ${motivo}`);
|
|
1397
|
+
return 0;
|
|
1398
|
+
}
|
|
558
1399
|
if (sub === 'list' || sub === undefined) {
|
|
559
1400
|
const id = args.posicionais[2];
|
|
560
1401
|
if (!id) {
|
|
@@ -571,11 +1412,12 @@ function comandoVerify(args) {
|
|
|
571
1412
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
572
1413
|
const id = args.posicionais[1];
|
|
573
1414
|
if (!id) {
|
|
574
|
-
console.error('uso: ork verify <thread-id> [--baseline] [--so-claims]');
|
|
1415
|
+
console.error('uso: ork verify <thread-id> [--baseline] [--so-claims] [--canal C] [--esperar [min]]');
|
|
575
1416
|
return 2;
|
|
576
1417
|
}
|
|
1418
|
+
const conducao = conducaoDoCli(args);
|
|
577
1419
|
if (args.opcoes.baseline === true) {
|
|
578
|
-
const b = (0, verify_1.gravarBaseline)(carregado, id);
|
|
1420
|
+
const b = (0, verify_1.gravarBaseline)(carregado, id, undefined, conducao);
|
|
579
1421
|
console.log(`Baseline gravada para a thread ${id}.`);
|
|
580
1422
|
console.log(` commit ${b.commit}`);
|
|
581
1423
|
for (const c of b.comandos) {
|
|
@@ -586,13 +1428,67 @@ function comandoVerify(args) {
|
|
|
586
1428
|
}
|
|
587
1429
|
return 0;
|
|
588
1430
|
}
|
|
589
|
-
const r = (0, verify_1.verificar)(carregado, id, { soClaims: args.opcoes['so-claims'] === true });
|
|
1431
|
+
const r = (0, verify_1.verificar)(carregado, id, { soClaims: args.opcoes['so-claims'] === true, conducao });
|
|
590
1432
|
console.log((0, verify_1.textoDoVerify)(r));
|
|
591
1433
|
return r.ok ? 0 : 1;
|
|
592
1434
|
}
|
|
1435
|
+
/**
|
|
1436
|
+
* `ork conducao status|assumir` (I-36, T15): quem conduz a thread agora, e o handoff explicito. O
|
|
1437
|
+
* status tambem libera, com prova no ledger, a conducao que ficou sem dono (T16).
|
|
1438
|
+
*/
|
|
1439
|
+
function comandoConducao(args) {
|
|
1440
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1441
|
+
const sub = args.posicionais[1];
|
|
1442
|
+
const id = args.posicionais[2];
|
|
1443
|
+
if (sub === 'status') {
|
|
1444
|
+
if (!id)
|
|
1445
|
+
throw new Error('uso: ork conducao status <thread-id> [--json]');
|
|
1446
|
+
(0, thread_1.lerThread)(carregado.raiz, id);
|
|
1447
|
+
(0, conducao_1.liberarSeOrfa)(carregado.raiz, id);
|
|
1448
|
+
const atual = (0, conducao_1.conducaoDaThread)(carregado.raiz, id);
|
|
1449
|
+
console.log(args.opcoes.json === true ? JSON.stringify({ thread: id, conducao: atual }, null, 2) : (0, conducao_1.textoDoStatusDaConducao)(id, atual));
|
|
1450
|
+
return 0;
|
|
1451
|
+
}
|
|
1452
|
+
if (sub === 'assumir') {
|
|
1453
|
+
const por = texto(args.opcoes.por), motivo = texto(args.opcoes.motivo);
|
|
1454
|
+
if (!id || !por || !motivo)
|
|
1455
|
+
throw new Error('uso: ork conducao assumir <thread-id> --por <quem> --motivo "<por que>" [--canal C]');
|
|
1456
|
+
const r = (0, conducao_1.assumirConducao)(carregado.raiz, id, { por, motivo, canal: conducaoDoCli(args).canal });
|
|
1457
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : `${r.ok ? 'Conducao assumida.' : 'Handoff recusado.'} ${r.detalhe}`);
|
|
1458
|
+
return r.ok ? 0 : 3;
|
|
1459
|
+
}
|
|
1460
|
+
throw new Error('uso: ork conducao status|assumir <thread-id>');
|
|
1461
|
+
}
|
|
593
1462
|
function comandoGate(args) {
|
|
594
1463
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
595
1464
|
const sub = args.posicionais[1];
|
|
1465
|
+
if (sub === 'context') {
|
|
1466
|
+
const id = args.posicionais[2], pedido = args.posicionais[3];
|
|
1467
|
+
if (!id || !pedido || args.posicionais.length !== 4 ||
|
|
1468
|
+
Object.entries(args.opcoes).some(([k, v]) => k !== 'native-offer-stdin' || v !== true))
|
|
1469
|
+
throw Error('uso: ork gate context <thread> <pedido> [--native-offer-stdin]');
|
|
1470
|
+
const view = (0, hitl_gates_1.contextoDoPedidoNativo)(carregado.raiz, id, pedido);
|
|
1471
|
+
const callback = args.opcoes['native-offer-stdin'] ? (0, hitl_native_offer_1.readNativeOfferStdin)() : undefined;
|
|
1472
|
+
console.log(JSON.stringify({ ...view, canais: (0, hitl_presentation_1.ofertaDoPedido)(view.pedido, [], callback === undefined ? undefined : { callback, raiz: carregado.raiz }),
|
|
1473
|
+
apresentacao: (0, hitl_presentation_1.apresentarDecisao)(view.pedido), prazoLocal: (0, hitl_presentation_1.prazoLocalDoPedido)(view.pedido) }));
|
|
1474
|
+
return 0;
|
|
1475
|
+
}
|
|
1476
|
+
if (sub === 'request') {
|
|
1477
|
+
const id = args.posicionais[2];
|
|
1478
|
+
if (!id)
|
|
1479
|
+
throw new Error('gate request exige thread');
|
|
1480
|
+
console.log(JSON.stringify((0, hitl_gates_1.abrirPedidoGate)(carregado.raiz, id, texto(args.opcoes.motivo))));
|
|
1481
|
+
return 0;
|
|
1482
|
+
}
|
|
1483
|
+
if (sub === 'answer') {
|
|
1484
|
+
const id = args.posicionais[2], pedido = args.posicionais[3];
|
|
1485
|
+
if (!id || !pedido || args.opcoes['resposta-stdin'] !== true || args.opcoes.resposta !== undefined)
|
|
1486
|
+
throw new Error('gate answer exige thread, pedido e --resposta-stdin');
|
|
1487
|
+
const r = (0, hitl_gates_1.lerRespostaStdin)({ por: texto(args.opcoes.por), mensagem: texto(args.opcoes.mensagem),
|
|
1488
|
+
origem: texto(args.opcoes.origem), canal: texto(args.opcoes.canal), conta: texto(args.opcoes.conta) });
|
|
1489
|
+
console.log(JSON.stringify((0, hitl_gates_1.responderGate)(carregado.raiz, id, pedido, r)));
|
|
1490
|
+
return 0;
|
|
1491
|
+
}
|
|
596
1492
|
if (sub === 'next') {
|
|
597
1493
|
const id = args.posicionais[2];
|
|
598
1494
|
if (!id) {
|
|
@@ -620,7 +1516,7 @@ function comandoGate(args) {
|
|
|
620
1516
|
const sobre = args.posicionais[3];
|
|
621
1517
|
const por = texto(args.opcoes.por) ?? texto(args.opcoes.quem);
|
|
622
1518
|
if (!id || !sobre || !por) {
|
|
623
|
-
console.error('
|
|
1519
|
+
console.error('gate approve aposentado: aprovação sem pedido é recusada. Use ork gate request <thread-id> e responda pelo ingresso humano autenticado.');
|
|
624
1520
|
return 2;
|
|
625
1521
|
}
|
|
626
1522
|
(0, thread_1.lerThread)(carregado.raiz, id);
|
|
@@ -628,7 +1524,7 @@ function comandoGate(args) {
|
|
|
628
1524
|
console.log(`Autorizacao humana registrada no ledger da thread ${id}.`);
|
|
629
1525
|
console.log(` sobre ${sobre}`);
|
|
630
1526
|
console.log(` autorizado por ${por}`);
|
|
631
|
-
console.log(` quando ${e.ts}`);
|
|
1527
|
+
console.log(` quando ${(0, horario_1.formatarDataHoraRotulada)(e.ts)}`);
|
|
632
1528
|
return 0;
|
|
633
1529
|
}
|
|
634
1530
|
console.error(`subcomando desconhecido: gate ${sub}`);
|
|
@@ -694,7 +1590,7 @@ function comandoRetry(args) {
|
|
|
694
1590
|
}
|
|
695
1591
|
console.log('Sinal de rate limit reconhecido no stderr do runtime:');
|
|
696
1592
|
console.log(` fonte da hora ${sinal.fonte}`);
|
|
697
|
-
console.log(` reset em ${sinal.resetEm
|
|
1593
|
+
console.log(` reset em ${sinal.resetEm ? (0, horario_1.formatarDataHoraRotulada)(sinal.resetEm) : '(o runtime nao disse a hora)'}`);
|
|
698
1594
|
console.log(` trecho ${sinal.trecho}`);
|
|
699
1595
|
if (sinal.resetEm === null) {
|
|
700
1596
|
console.log('');
|
|
@@ -704,6 +1600,7 @@ function comandoRetry(args) {
|
|
|
704
1600
|
return 0;
|
|
705
1601
|
}
|
|
706
1602
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1603
|
+
avisarChavesDePerfis(carregado);
|
|
707
1604
|
if (sub === 'plan' || sub === 'run') {
|
|
708
1605
|
const id = args.posicionais[2];
|
|
709
1606
|
if (!id) {
|
|
@@ -726,6 +1623,10 @@ function comandoRetry(args) {
|
|
|
726
1623
|
console.log((0, retry_1.textoDoPlano)(plano));
|
|
727
1624
|
return 0;
|
|
728
1625
|
}
|
|
1626
|
+
// I-36 (D2): `--esperar` espera a conducao em andamento terminar antes de executar a retomada.
|
|
1627
|
+
const conducao = conducaoDoCli(args);
|
|
1628
|
+
if (conducao.esperarMs && args.opcoes['dry-run'] !== true)
|
|
1629
|
+
(0, conducao_1.esperarConducaoLivre)(carregado.raiz, id, conducao.esperarMs);
|
|
729
1630
|
const r = (0, retry_1.executarRetry)(carregado, id, {
|
|
730
1631
|
...opcoes,
|
|
731
1632
|
dryRun: args.opcoes['dry-run'] === true,
|
|
@@ -750,7 +1651,7 @@ function comandoRetry(args) {
|
|
|
750
1651
|
const espera = (0, ratelimit_1.lerFilaDeRetomada)(carregado.raiz).filter((p) => p.estado === 'aguardando');
|
|
751
1652
|
if (espera.length > 0) {
|
|
752
1653
|
console.log('');
|
|
753
|
-
console.log(`Proxima janela: ${espera[0].liberaEm} (${(0, ratelimit_1.faltaPara)(espera[0])}).`);
|
|
1654
|
+
console.log(`Proxima janela: ${(0, horario_1.formatarDataHora)(espera[0].liberaEm)} (${(0, ratelimit_1.faltaPara)(espera[0])}).`);
|
|
754
1655
|
console.log('Retome com: ork retry resume');
|
|
755
1656
|
}
|
|
756
1657
|
return 0;
|
|
@@ -810,9 +1711,10 @@ function comandoFix(args) {
|
|
|
810
1711
|
console.error('uso: ork fix open <thread-id> [--so-claims] [--reverify]');
|
|
811
1712
|
return 2;
|
|
812
1713
|
}
|
|
813
|
-
const
|
|
1714
|
+
const conducao = conducaoDoCli(args);
|
|
1715
|
+
const rodada = (0, fix_1.abrirRodada)(carregado, id, { soClaims: args.opcoes['so-claims'] === true, conducao });
|
|
814
1716
|
const reverify = args.opcoes.reverify === true && rodada.correcoes.length > 0
|
|
815
|
-
? (0, fix_1.reverificar)(carregado, id, { rodada: rodada.rodada })
|
|
1717
|
+
? (0, fix_1.reverificar)(carregado, id, { rodada: rodada.rodada, conducao })
|
|
816
1718
|
: null;
|
|
817
1719
|
if (args.opcoes.json === true) {
|
|
818
1720
|
console.log(JSON.stringify({ rodada, reverify }, null, 2));
|
|
@@ -864,6 +1766,7 @@ function comandoFix(args) {
|
|
|
864
1766
|
}
|
|
865
1767
|
const rodadaBruta = texto(args.opcoes.rodada);
|
|
866
1768
|
const r = (0, fix_1.reverificar)(carregado, id, {
|
|
1769
|
+
conducao: conducaoDoCli(args),
|
|
867
1770
|
rodada: rodadaBruta ? Number(rodadaBruta) : undefined,
|
|
868
1771
|
parcial: args.opcoes.parcial === true,
|
|
869
1772
|
});
|
|
@@ -918,6 +1821,30 @@ function comandoHandoff(args) {
|
|
|
918
1821
|
}
|
|
919
1822
|
function comandoShip(args) {
|
|
920
1823
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1824
|
+
if (args.posicionais[1] === 'registrar-pr') {
|
|
1825
|
+
// I-57 (RM-008): a entrega feita por PR vira ship_done, provada no remoto e no CI.
|
|
1826
|
+
const alvo = args.posicionais[2];
|
|
1827
|
+
const remoto = texto(args.opcoes.remoto);
|
|
1828
|
+
if (!alvo && args.opcoes.todas !== true) {
|
|
1829
|
+
console.error('uso: ork ship registrar-pr <thread-id> | --todas [--remoto R] [--json]');
|
|
1830
|
+
return 2;
|
|
1831
|
+
}
|
|
1832
|
+
const r = alvo ? [(0, entrega_pr_1.registrarEntregaPorPr)(carregado, alvo, { remoto })] : (0, entrega_pr_1.registrarEntregasPorPr)(carregado, { remoto });
|
|
1833
|
+
if (args.opcoes.json === true) {
|
|
1834
|
+
console.log(JSON.stringify(r, null, 2));
|
|
1835
|
+
return r.some((x) => x.acao === 'recusada') ? 1 : 0;
|
|
1836
|
+
}
|
|
1837
|
+
if (r.length === 0)
|
|
1838
|
+
console.log('Nenhuma thread aberta com merge ship(<thread>) na base.');
|
|
1839
|
+
for (const x of r)
|
|
1840
|
+
console.log(` ${x.thread.padEnd(20)} ${x.acao.padEnd(13)} ${x.motivo}`);
|
|
1841
|
+
const registradas = r.filter((x) => x.acao === 'registrou').length;
|
|
1842
|
+
if (registradas) {
|
|
1843
|
+
console.log('');
|
|
1844
|
+
console.log(`${registradas} entrega(s) registrada(s). Fechar pelo MASTER: ork master --aceitar-omissao (a nota humana sobrescreve).`);
|
|
1845
|
+
}
|
|
1846
|
+
return r.some((x) => x.acao === 'recusada') ? 1 : 0;
|
|
1847
|
+
}
|
|
921
1848
|
const id = args.posicionais[1];
|
|
922
1849
|
const para = texto(args.opcoes.para) ?? texto(args.opcoes.to);
|
|
923
1850
|
if (!id || !para) {
|
|
@@ -937,6 +1864,190 @@ function comandoShip(args) {
|
|
|
937
1864
|
console.log((0, ship_1.textoDoShip)(r));
|
|
938
1865
|
return r.ok ? 0 : 1;
|
|
939
1866
|
}
|
|
1867
|
+
function comandoPortfolio(args) {
|
|
1868
|
+
const root = (0, manifest_1.exigirManifesto)().raiz;
|
|
1869
|
+
const sub = args.posicionais[1] ?? 'list';
|
|
1870
|
+
if (sub === 'inspect') {
|
|
1871
|
+
const id = args.posicionais[2];
|
|
1872
|
+
if (!id) {
|
|
1873
|
+
console.error('uso: ork portfolio inspect <id> --json');
|
|
1874
|
+
return 2;
|
|
1875
|
+
}
|
|
1876
|
+
console.log(JSON.stringify((0, portfolio_context_1.inspectPortfolio)(root, id), null, 2));
|
|
1877
|
+
return 0;
|
|
1878
|
+
}
|
|
1879
|
+
const aliases = { product: 'product', project: 'project', initiative: 'initiative', prod: 'product', proj: 'project', init: 'initiative' };
|
|
1880
|
+
const split = (value, separator = ',') => value?.split(separator).map((item) => item.trim()).filter(Boolean) ?? [];
|
|
1881
|
+
if (sub === 'list') {
|
|
1882
|
+
const rawKind = args.posicionais[2];
|
|
1883
|
+
const kind = rawKind ? aliases[rawKind] : undefined;
|
|
1884
|
+
if (rawKind && !kind) {
|
|
1885
|
+
console.error('tipo deve ser product, project ou initiative');
|
|
1886
|
+
return 2;
|
|
1887
|
+
}
|
|
1888
|
+
const items = (0, portfolio_1.listEntities)(root, kind, texto(args.opcoes.parent));
|
|
1889
|
+
console.log(args.opcoes.json === true ? JSON.stringify({ schema: 'ork.portfolio-list/v1', updatedAt: (0, portfolio_1.readPortfolio)(root).updatedAt, items }, null, 2)
|
|
1890
|
+
: items.length ? items.map((item) => `${item.id}\t${item.kind}\t${item.status}\t${item.title}`).join('\n') : 'Portfólio vazio.');
|
|
1891
|
+
return 0;
|
|
1892
|
+
}
|
|
1893
|
+
if (sub === 'show') {
|
|
1894
|
+
const id = args.posicionais[2];
|
|
1895
|
+
if (!id) {
|
|
1896
|
+
console.error('uso: ork portfolio show <id>');
|
|
1897
|
+
return 2;
|
|
1898
|
+
}
|
|
1899
|
+
const item = (0, portfolio_1.findEntity)(root, id);
|
|
1900
|
+
if (!item) {
|
|
1901
|
+
console.error(`entidade ${id} não encontrada`);
|
|
1902
|
+
return 1;
|
|
1903
|
+
}
|
|
1904
|
+
console.log(args.opcoes.json === true ? JSON.stringify(item, null, 2) : `${item.id}\n${item.title}\nEstado: ${item.status}`);
|
|
1905
|
+
return 0;
|
|
1906
|
+
}
|
|
1907
|
+
if (sub === 'create') {
|
|
1908
|
+
const kind = aliases[args.posicionais[2] ?? ''];
|
|
1909
|
+
const id = args.posicionais[3], title = texto(args.opcoes.title), parent = texto(args.opcoes.parent);
|
|
1910
|
+
if (!kind || !id || !title) {
|
|
1911
|
+
console.error('uso: ork portfolio create <product|project|initiative> <id> --title T [--parent ID]');
|
|
1912
|
+
return 2;
|
|
1913
|
+
}
|
|
1914
|
+
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), ';') };
|
|
1915
|
+
const item = kind === 'product' ? (0, portfolio_1.createProduct)(root, common)
|
|
1916
|
+
: kind === 'project' ? (0, portfolio_1.createProject)(root, { ...common, productId: parent ?? '', workspaceIds: split(texto(args.opcoes.workspaces)) })
|
|
1917
|
+
: (0, portfolio_1.createInitiative)(root, { ...common, projectId: parent ?? '', dependsOn: split(texto(args.opcoes.depends)) });
|
|
1918
|
+
console.log(JSON.stringify({ schema: 'ork.portfolio-created/v1', item }, null, 2));
|
|
1919
|
+
return 0;
|
|
1920
|
+
}
|
|
1921
|
+
console.error(`subcomando desconhecido: portfolio ${sub}`);
|
|
1922
|
+
return 2;
|
|
1923
|
+
}
|
|
1924
|
+
function comandoCreation(args) {
|
|
1925
|
+
const loaded = (0, manifest_1.exigirManifesto)();
|
|
1926
|
+
// CLI local opera com a autoridade do usuário do SO, assim como portfolio create.
|
|
1927
|
+
// Fachadas HTTP devem usar a API com principal e authorize autenticados no servidor.
|
|
1928
|
+
const actor = { principal: `local:uid:${(0, node_os_1.userInfo)().uid}`, authorize: () => { } };
|
|
1929
|
+
const sub = args.posicionais[1], id = args.posicionais[2];
|
|
1930
|
+
if (args.opcoes.principal !== undefined || args.opcoes.por !== undefined)
|
|
1931
|
+
throw new Error('creation.identity: payload não escolhe principal');
|
|
1932
|
+
let result;
|
|
1933
|
+
if (sub === 'session') {
|
|
1934
|
+
const portfolio = (0, portfolio_1.readPortfolio)(loaded.raiz);
|
|
1935
|
+
result = {
|
|
1936
|
+
schema: 'ork.creation-session/v1', principal: actor.principal,
|
|
1937
|
+
workspaceIds: [...new Set(portfolio.projects.flatMap((project) => project.workspaceIds))].sort(),
|
|
1938
|
+
modes: loaded.manifesto.conduction.allowed_modes,
|
|
1939
|
+
actions: ['create_entity', 'create_entity_with_ticket', 'open_ticket'],
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
else if (sub === 'start') {
|
|
1943
|
+
const file = texto(args.opcoes['input-file']);
|
|
1944
|
+
if (!file) {
|
|
1945
|
+
console.error('uso: ork creation start --input-file F --json');
|
|
1946
|
+
return 2;
|
|
1947
|
+
}
|
|
1948
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
1949
|
+
if (Buffer.byteLength(content) > 100_000)
|
|
1950
|
+
throw new Error('creation.input: arquivo excede limite');
|
|
1951
|
+
result = (0, creation_operation_1.startCreation)(loaded, actor, JSON.parse(content));
|
|
1952
|
+
}
|
|
1953
|
+
else if (sub === 'list')
|
|
1954
|
+
result = (0, creation_operation_store_1.listCreationOperations)(loaded.raiz, actor.principal);
|
|
1955
|
+
else if (!id) {
|
|
1956
|
+
console.error('creation exige id');
|
|
1957
|
+
return 2;
|
|
1958
|
+
}
|
|
1959
|
+
else if (sub === 'show' || sub === 'events') {
|
|
1960
|
+
const op = (0, creation_operation_store_1.readCreationOperation)(loaded.raiz, id, actor.principal);
|
|
1961
|
+
result = sub === 'events' ? { schema: 'ork.creation-events/v1', operationId: id, version: op.version, events: op.events } : op;
|
|
1962
|
+
}
|
|
1963
|
+
else if (sub === 'resume' || sub === 'compensate') {
|
|
1964
|
+
const version = Number(texto(args.opcoes['expected-version']));
|
|
1965
|
+
if (!Number.isSafeInteger(version) || version < 1) {
|
|
1966
|
+
console.error('creation exige --expected-version inteiro positivo');
|
|
1967
|
+
return 2;
|
|
1968
|
+
}
|
|
1969
|
+
result = sub === 'resume' ? (0, creation_operation_1.resumeCreation)(loaded, actor, id, version) : (0, creation_operation_1.compensateCreation)(loaded, actor, id, version);
|
|
1970
|
+
}
|
|
1971
|
+
else {
|
|
1972
|
+
console.error('subcomando creation desconhecido');
|
|
1973
|
+
return 2;
|
|
1974
|
+
}
|
|
1975
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1976
|
+
return 0;
|
|
1977
|
+
}
|
|
1978
|
+
/**
|
|
1979
|
+
* `ork objective`: APOSENTADO na I-43 (D4).
|
|
1980
|
+
*
|
|
1981
|
+
* O Objective Envelope descrevia um gate que nao bloqueava nada, e a medida foi mais
|
|
1982
|
+
* dura que a suspeita do GOAL: das 137 threads do projeto, ZERO tinham
|
|
1983
|
+
* `creationOrigin`, e `creationOrigin` era a unica via pela qual `phase.ts` consultava
|
|
1984
|
+
* o envelope. O ramo nunca disparou para thread nenhuma. Havia um envelope em disco,
|
|
1985
|
+
* `obj-i27gatedomae`, em `awaiting_approval` desde 17/09, com tres threads de zero
|
|
1986
|
+
* sessoes: a unica pausa do `#Maestro` nao bloqueava o despacho das proprias threads
|
|
1987
|
+
* que ela criou, e aprova-la nao teria efeito.
|
|
1988
|
+
*
|
|
1989
|
+
* As DUAS VIGAS que ele guardava sairam vivas, e viraram propriedade de thread comum:
|
|
1990
|
+
* - validacao por runtime diferente -> `thread.exigeRuntimeDiferente` (T9);
|
|
1991
|
+
* - `doneWhen` executavel -> `thread.doneWhen`, que vira claim do nucleo (T10).
|
|
1992
|
+
*
|
|
1993
|
+
* A recusa e TIPADA e diz para onde ir. Sumir em silencio seria o mesmo pecado da
|
|
1994
|
+
* #TAG aposentada virando default: quem tem o comando num script precisa saber.
|
|
1995
|
+
*/
|
|
1996
|
+
function comandoObjective(args) {
|
|
1997
|
+
const sub = args.posicionais[1] ?? 'list';
|
|
1998
|
+
console.error(`objective.aposentado: o Objective Envelope saiu do produto na I-43 (subcomando "${sub}").\n` +
|
|
1999
|
+
' Ele descrevia um gate que nao bloqueava nada: das 137 threads do projeto, zero\n' +
|
|
2000
|
+
' tinham creationOrigin, que era a unica via pela qual o despacho o consultava.\n' +
|
|
2001
|
+
' As duas vigas que ele guardava viraram propriedade de thread comum:\n' +
|
|
2002
|
+
' ork thread new "<nome>" --modo <MODO> --exige-runtime-diferente\n' +
|
|
2003
|
+
' o CHECK precisa de runtime que o GO nao usou\n' +
|
|
2004
|
+
' ork thread new "<nome>" --modo <MODO> --done "<criterio> :: <comando>"\n' +
|
|
2005
|
+
' criterio de pronto EXECUTAVEL, que vira claim e roda no ork verify\n' +
|
|
2006
|
+
' Os envelopes ja gravados continuam em .orkastery/objectives, intocados.');
|
|
2007
|
+
return 2;
|
|
2008
|
+
}
|
|
2009
|
+
function comandoCi(args) {
|
|
2010
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
2011
|
+
const sub = args.posicionais[1] ?? 'status';
|
|
2012
|
+
if (sub === 'prepare') {
|
|
2013
|
+
const thread = args.posicionais[2];
|
|
2014
|
+
if (!thread) {
|
|
2015
|
+
console.error('uso: ork ci prepare <thread-id>');
|
|
2016
|
+
return 2;
|
|
2017
|
+
}
|
|
2018
|
+
const arquivo = (0, ci_1.prepararBundleCi)(carregado, thread, { aoAvisar: (linha) => console.log(`AVISO: ${linha}`) });
|
|
2019
|
+
console.log(`Bundle de CI: ${arquivo}`);
|
|
2020
|
+
return 0;
|
|
2021
|
+
}
|
|
2022
|
+
if (sub === 'run') {
|
|
2023
|
+
const bundle = texto(args.opcoes.bundle);
|
|
2024
|
+
if (bundle) {
|
|
2025
|
+
const result = (0, ci_1.executarBundleCi)(carregado, bundle);
|
|
2026
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2027
|
+
return result.ok ? 0 : 1;
|
|
2028
|
+
}
|
|
2029
|
+
const thread = args.posicionais[2];
|
|
2030
|
+
if (!thread) {
|
|
2031
|
+
console.error('uso: ork ci run <thread-id> [--json] | ork ci run --bundle <arquivo>');
|
|
2032
|
+
return 2;
|
|
2033
|
+
}
|
|
2034
|
+
const result = (0, ci_1.executarCi)(carregado, thread);
|
|
2035
|
+
console.log(args.opcoes.json === true ? JSON.stringify(result, null, 2) : `${result.status.ok ? 'CI APROVADO' : 'CI REPROVADO'}: ${result.status.detail}`);
|
|
2036
|
+
return result.status.ok ? 0 : 1;
|
|
2037
|
+
}
|
|
2038
|
+
if (sub === 'status') {
|
|
2039
|
+
const sha = texto(args.opcoes.sha) ?? args.posicionais[2] ?? (0, util_1.exec)('git', ['rev-parse', 'HEAD'], carregado.raiz).stdout.trim();
|
|
2040
|
+
if (!/^[0-9a-f]{40}$/.test(sha)) {
|
|
2041
|
+
console.error('uso: ork ci status --sha <commit> [--remoto origin]');
|
|
2042
|
+
return 2;
|
|
2043
|
+
}
|
|
2044
|
+
const result = (0, ci_1.consultarCi)(carregado, sha, texto(args.opcoes.remoto) ?? 'origin');
|
|
2045
|
+
console.log(args.opcoes.json === true ? JSON.stringify(result, null, 2) : `${result.ok ? 'CI VERDE' : 'CI NÃO LIBEROU'}: ${result.detail}`);
|
|
2046
|
+
return result.ok ? 0 : 1;
|
|
2047
|
+
}
|
|
2048
|
+
console.error(`subcomando desconhecido: ci ${sub}`);
|
|
2049
|
+
return 2;
|
|
2050
|
+
}
|
|
940
2051
|
function comandoLease(args) {
|
|
941
2052
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
942
2053
|
const sub = args.posicionais[1];
|
|
@@ -956,14 +2067,14 @@ function comandoLease(args) {
|
|
|
956
2067
|
const r = (0, leases_1.adquirirRegiao)(carregado.raiz, nome, { thread, motivo });
|
|
957
2068
|
if (r.ok) {
|
|
958
2069
|
console.log(`Lease ${r.nome} [${r.tipo}] adquirido pela thread ${thread}.`);
|
|
959
|
-
console.log(` expira em ${r.lease?.expiraEm}`);
|
|
2070
|
+
console.log(` expira em ${(0, horario_1.formatarDataHoraRotulada)(r.lease?.expiraEm)}`);
|
|
960
2071
|
if (r.tomadoDeVencido)
|
|
961
2072
|
console.log(' (o lease anterior estava VENCIDO e foi tomado)');
|
|
962
2073
|
return 0;
|
|
963
2074
|
}
|
|
964
2075
|
console.error(`Lease ${r.nome} NAO adquirido.`);
|
|
965
2076
|
console.error(` motivo tipado: ${r.motivo}`);
|
|
966
|
-
console.error(` detalhe: ${r.detalhe}`);
|
|
2077
|
+
console.error(` detalhe: ${(0, horario_1.localizarTextoRotulado)(r.detalhe)}`);
|
|
967
2078
|
console.error(` posicao na fila: ${r.posicaoNaFila}`);
|
|
968
2079
|
console.error(` correcao: ${r.correcao}`);
|
|
969
2080
|
return 1;
|
|
@@ -985,14 +2096,105 @@ function comandoBoard(args) {
|
|
|
985
2096
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
986
2097
|
const sub = args.posicionais[1];
|
|
987
2098
|
if (sub === 'plan' || sub === 'plano') {
|
|
988
|
-
|
|
2099
|
+
const plano = (0, board_1.planejar)(carregado);
|
|
2100
|
+
console.log(args.opcoes.json === true ? JSON.stringify(plano, null, 2) : (0, board_1.textoDoPlano)(plano));
|
|
2101
|
+
return 0;
|
|
2102
|
+
}
|
|
2103
|
+
if (sub === 'reap') {
|
|
2104
|
+
const devolvidas = (0, board_1.devolverVagas)(carregado, { por: texto(args.opcoes.por) });
|
|
2105
|
+
if (args.opcoes.json === true)
|
|
2106
|
+
console.log(JSON.stringify(devolvidas, null, 2));
|
|
2107
|
+
else
|
|
2108
|
+
console.log((0, board_1.textoDoReap)(devolvidas));
|
|
989
2109
|
return 0;
|
|
990
2110
|
}
|
|
991
2111
|
if (sub !== undefined && sub !== 'list') {
|
|
992
2112
|
console.error(`subcomando desconhecido: board ${sub}`);
|
|
2113
|
+
console.error('uso: ork board [list|plan|reap] [--all] [--por <quem>] [--json]');
|
|
993
2114
|
return 2;
|
|
994
2115
|
}
|
|
995
|
-
|
|
2116
|
+
const todos = args.opcoes.all === true || args.opcoes.todos === true;
|
|
2117
|
+
if (args.opcoes.json === true) {
|
|
2118
|
+
console.log(JSON.stringify((0, board_1.threadsDeTodosOsPerfis)(carregado, todos), null, 2));
|
|
2119
|
+
return 0;
|
|
2120
|
+
}
|
|
2121
|
+
console.log((0, board_1.textoDoBoard)(carregado, todos));
|
|
2122
|
+
// I-51 (RM-047): com a fabrica compartilhada, o board mostra tambem as outras maquinas.
|
|
2123
|
+
if ((0, maquina_1.fabricaCompartilhada)(carregado.manifesto)) {
|
|
2124
|
+
const painel = (0, fabrica_estado_1.lerFabrica)(carregado.raiz, { remoto: carregado.manifesto.fabrica.remoto,
|
|
2125
|
+
semRemoto: args.opcoes['sem-remoto'] === true });
|
|
2126
|
+
console.log('');
|
|
2127
|
+
console.log((0, fabrica_estado_1.textoDasOutrasMaquinas)(painel, (0, maquina_1.nomeDaMaquina)()));
|
|
2128
|
+
}
|
|
2129
|
+
return 0;
|
|
2130
|
+
}
|
|
2131
|
+
/**
|
|
2132
|
+
* I-51 (RM-047): `ork fabrica` mostra o que cada maquina conduz; `ork fabrica publicar` grava o
|
|
2133
|
+
* retrato desta maquina na branch `ork/fabrica-estado`. O `--silencioso` e o da publicacao em
|
|
2134
|
+
* segundo plano: nada no terminal, uma linha em `.orkastery/monitor/fabrica.log`.
|
|
2135
|
+
*/
|
|
2136
|
+
function comandoFabrica(args) {
|
|
2137
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
2138
|
+
const sub = args.posicionais[1];
|
|
2139
|
+
const remoto = texto(args.opcoes.remoto) ?? carregado.manifesto.fabrica.remoto;
|
|
2140
|
+
if (sub === 'publicar') {
|
|
2141
|
+
const silencioso = args.opcoes.silencioso === true;
|
|
2142
|
+
try {
|
|
2143
|
+
const r = (0, fabrica_estado_1.publicarMaquina)(carregado, { remoto, forcar: args.opcoes.forcar === true });
|
|
2144
|
+
if (silencioso) {
|
|
2145
|
+
(0, fabrica_estado_1.registrarPublicacao)(carregado.raiz, { ...r });
|
|
2146
|
+
return 0;
|
|
2147
|
+
}
|
|
2148
|
+
if (args.opcoes.json === true)
|
|
2149
|
+
console.log(JSON.stringify(r, null, 2));
|
|
2150
|
+
else
|
|
2151
|
+
console.log(r.acao === 'publicou'
|
|
2152
|
+
? `Fabrica: ${r.maquina} publicou ${r.threads} thread(s) em ork/fabrica-estado (${r.commit?.slice(0, 7)}, ${r.tentativas} tentativa(s)).`
|
|
2153
|
+
: r.acao === 'ocupado'
|
|
2154
|
+
? `Fabrica: outra publicacao desta maquina esta em andamento; tente de novo em instantes.`
|
|
2155
|
+
: `Fabrica: retrato de ${r.maquina} igual ao ultimo publicado; nada a enviar (use --forcar para publicar mesmo assim).`);
|
|
2156
|
+
if (!(0, maquina_1.fabricaCompartilhada)(carregado.manifesto) && !silencioso) {
|
|
2157
|
+
console.log(' esta maquina nao entrou na fabrica compartilhada: so publica quando voce pede (ork fabrica entrar liga).');
|
|
2158
|
+
}
|
|
2159
|
+
return 0;
|
|
2160
|
+
}
|
|
2161
|
+
catch (e) {
|
|
2162
|
+
if (silencioso) {
|
|
2163
|
+
(0, fabrica_estado_1.registrarPublicacao)(carregado.raiz, { acao: 'falhou', erro: e.message });
|
|
2164
|
+
return 1;
|
|
2165
|
+
}
|
|
2166
|
+
throw e;
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
if (sub === 'entrar') {
|
|
2170
|
+
// A adesao e o nome ficam no arquivo do usuario: valem para o shell, o cron e os gateways.
|
|
2171
|
+
const config = (0, maquina_1.gravarConfigDaMaquina)({ nome: texto(args.opcoes.maquina) ?? (0, maquina_1.lerConfigDaMaquina)()?.nome ?? (0, maquina_1.nomeDaMaquina)(),
|
|
2172
|
+
fabricaCompartilhada: true });
|
|
2173
|
+
const r = (0, fabrica_estado_1.publicarMaquina)(carregado, { remoto, forcar: true });
|
|
2174
|
+
console.log(`Fabrica: esta maquina entrou como ${config.nome}; publica ao criar thread, despachar fase, entregar e fechar,`);
|
|
2175
|
+
console.log(` e a cada batida do pulse. Primeiro retrato: ${r.threads} thread(s) em ork/fabrica-estado (${r.commit?.slice(0, 7)}).`);
|
|
2176
|
+
if (process.env.ORK_MAQUINA && process.env.ORK_MAQUINA.trim() !== config.nome) {
|
|
2177
|
+
console.log(` AVISO: ORK_MAQUINA=${process.env.ORK_MAQUINA} neste shell vence o arquivo; alinhe os dois.`);
|
|
2178
|
+
}
|
|
2179
|
+
return 0;
|
|
2180
|
+
}
|
|
2181
|
+
if (sub === 'sair') {
|
|
2182
|
+
const config = (0, maquina_1.gravarConfigDaMaquina)({ fabricaCompartilhada: false });
|
|
2183
|
+
const r = (0, fabrica_estado_1.removerMaquina)(carregado, { remoto });
|
|
2184
|
+
console.log(`Fabrica: ${(0, maquina_1.nomeDaMaquina)()} saiu; nada mais e publicado daqui.` +
|
|
2185
|
+
(r ? ` Retrato removido de ork/fabrica-estado (${r.slice(0, 7)}).` : ' Nao havia retrato desta maquina na branch.'));
|
|
2186
|
+
if ((0, maquina_1.fabricaCompartilhada)(carregado.manifesto))
|
|
2187
|
+
console.log(' AVISO: o manifesto do projeto (ou ORK_FABRICA_COMPARTILHADA) ainda liga a fabrica aqui.');
|
|
2188
|
+
void config;
|
|
2189
|
+
return 0;
|
|
2190
|
+
}
|
|
2191
|
+
if (sub !== undefined && sub !== 'list') {
|
|
2192
|
+
console.error(`subcomando desconhecido: fabrica ${sub}`);
|
|
2193
|
+
console.error('uso: ork fabrica [--json] [--sem-remoto] | fabrica publicar [--forcar] [--json] | fabrica entrar [--maquina NOME] | fabrica sair');
|
|
2194
|
+
return 2;
|
|
2195
|
+
}
|
|
2196
|
+
const painel = (0, fabrica_estado_1.lerFabrica)(carregado.raiz, { remoto, semRemoto: args.opcoes['sem-remoto'] === true });
|
|
2197
|
+
console.log(args.opcoes.json === true ? JSON.stringify(painel, null, 2) : (0, fabrica_estado_1.textoDaFabrica)(painel, (0, maquina_1.nomeDaMaquina)()));
|
|
996
2198
|
return 0;
|
|
997
2199
|
}
|
|
998
2200
|
/**
|
|
@@ -1105,15 +2307,95 @@ function comandoWorktree(args) {
|
|
|
1105
2307
|
function comandoMaster(args) {
|
|
1106
2308
|
const carregado = (0, manifest_1.exigirManifesto)();
|
|
1107
2309
|
const primeiro = args.posicionais[1];
|
|
2310
|
+
if (primeiro === 'audit') {
|
|
2311
|
+
const r = (0, master_audit_1.auditarMaster)(carregado.raiz);
|
|
2312
|
+
console.log(JSON.stringify(r, null, 2));
|
|
2313
|
+
return r.ok ? 0 : 1;
|
|
2314
|
+
}
|
|
2315
|
+
if (primeiro === 'digest') {
|
|
2316
|
+
const sub = args.posicionais[2];
|
|
2317
|
+
if (sub === 'responder') {
|
|
2318
|
+
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));
|
|
2319
|
+
return 0;
|
|
2320
|
+
}
|
|
2321
|
+
if (sub === 'preview') {
|
|
2322
|
+
console.log(JSON.stringify((0, master_digest_1.montarDigest)(carregado.raiz, new Date().toISOString()), null, 2));
|
|
2323
|
+
return 0;
|
|
2324
|
+
}
|
|
2325
|
+
if (sub !== 'enviar')
|
|
2326
|
+
throw new Error('uso: ork master digest <enviar|preview|responder>');
|
|
2327
|
+
const r = (0, master_digest_1.enviarDigest)({ raiz: carregado.raiz });
|
|
2328
|
+
console.log(JSON.stringify(r, null, 2));
|
|
2329
|
+
return r.code;
|
|
2330
|
+
}
|
|
2331
|
+
if (primeiro === 'migrar') {
|
|
2332
|
+
console.log(JSON.stringify((0, master_migracao_1.migrarMaster)(carregado.raiz, { dryRun: args.opcoes['dry-run'] === true, por: texto(args.opcoes.por) ?? '' }), null, 2));
|
|
2333
|
+
return 0;
|
|
2334
|
+
}
|
|
1108
2335
|
if (primeiro === 'classes') {
|
|
1109
|
-
console.log((0,
|
|
2336
|
+
console.log((0, master_2.tabelaDeClasses)());
|
|
1110
2337
|
return 0;
|
|
1111
2338
|
}
|
|
1112
|
-
if (args.opcoes.batch === true || primeiro === 'batch'
|
|
1113
|
-
|
|
2339
|
+
if (primeiro === 'ratificar' || ((args.opcoes.batch === true || primeiro === 'batch') && args.opcoes.aceitar)) {
|
|
2340
|
+
let selecao;
|
|
2341
|
+
if (primeiro === 'ratificar') {
|
|
2342
|
+
const partes = (texto(args.opcoes.resposta) ?? '').trim().split(/\s+/);
|
|
2343
|
+
const classe = (0, master_2.parseClasse)(partes[3]);
|
|
2344
|
+
if (partes.length !== 4 || partes[0] !== 'ratificar' || !classe)
|
|
2345
|
+
throw new Error('resposta deve ser ratificar <thread> <assinatura> <classe>');
|
|
2346
|
+
selecao = [{ thread: partes[1], assinatura: partes[2], classe }];
|
|
2347
|
+
}
|
|
2348
|
+
else {
|
|
2349
|
+
selecao = (texto(args.opcoes.aceitar) ?? '').split(',').map(v => {
|
|
2350
|
+
const partes = v.trim().split(':');
|
|
2351
|
+
if (partes.length !== 2 || !/^[a-f0-9]{64}$/.test(partes[1]))
|
|
2352
|
+
throw new Error('seleção deve ser thread:assinatura');
|
|
2353
|
+
return { thread: partes[0], assinatura: partes[1] };
|
|
2354
|
+
});
|
|
2355
|
+
}
|
|
2356
|
+
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
2357
|
return 0;
|
|
1115
2358
|
}
|
|
1116
|
-
|
|
2359
|
+
// I-43 (T8): a FILA saiu. `--batch` recebe recusa tipada em vez de sumir em
|
|
2360
|
+
// silencio: quem tem o comando no dedo ou num script precisa SABER que o regime
|
|
2361
|
+
// mudou, e para onde ir. Desaparecer sem dizer nada seria o mesmo pecado da #TAG
|
|
2362
|
+
// aposentada virando default.
|
|
2363
|
+
if (args.opcoes.batch === true || primeiro === 'batch') {
|
|
2364
|
+
console.error('master.fila-aposentada: a fila de ratificacao de score saiu na I-43. ' +
|
|
2365
|
+
'Entregue e aceito, a menos que voce diga o contrario.\n' +
|
|
2366
|
+
' ork master as entregas, com o indice ja derivado do ledger\n' +
|
|
2367
|
+
' ork master --aceitar-omissao aceita as entregues, com indice e insumos no ledger\n' +
|
|
2368
|
+
' ork master <id> --score <0-5> --justificativa "<por que>" --por <humano> para reclamar');
|
|
2369
|
+
return 2;
|
|
2370
|
+
}
|
|
2371
|
+
if (args.opcoes['aceitar-omissao'] === true) {
|
|
2372
|
+
const aceitos = (0, master_2.aceitarPendentesPorOmissao)(carregado.raiz);
|
|
2373
|
+
if (args.opcoes.json === true) {
|
|
2374
|
+
console.log(JSON.stringify(aceitos, null, 2));
|
|
2375
|
+
return 0;
|
|
2376
|
+
}
|
|
2377
|
+
if (aceitos.length === 0) {
|
|
2378
|
+
console.log('Nenhuma entrega esperando decisao.');
|
|
2379
|
+
return 0;
|
|
2380
|
+
}
|
|
2381
|
+
console.log(`Aceitas por omissao: ${aceitos.length}. O indice e os insumos foram ao ledger.`);
|
|
2382
|
+
for (const a of aceitos)
|
|
2383
|
+
console.log(` ${a.thread.padEnd(20)} indice ${a.indice.valor}/${a.indice.base}`);
|
|
2384
|
+
console.log('');
|
|
2385
|
+
console.log('Discordou? A nota humana sobrescreve, e o registro da omissao permanece.');
|
|
2386
|
+
return 0;
|
|
2387
|
+
}
|
|
2388
|
+
if (primeiro === undefined) {
|
|
2389
|
+
console.log(args.opcoes.json
|
|
2390
|
+
? JSON.stringify({ entregas: (0, master_batch_1.listarBatch)(carregado.raiz, args.opcoes.todas === true),
|
|
2391
|
+
aceitasPorOmissao: (0, master_2.aceitosPorOmissao)(carregado.raiz) }, null, 2)
|
|
2392
|
+
: (0, master_2.tabelaDeEntregas)(carregado.raiz, args.opcoes.todas === true));
|
|
2393
|
+
return 0;
|
|
2394
|
+
}
|
|
2395
|
+
const propor = primeiro === 'propor';
|
|
2396
|
+
const id = propor ? args.posicionais[2] : primeiro;
|
|
2397
|
+
if (!id)
|
|
2398
|
+
throw new Error('informe a thread para propor MASTER');
|
|
1117
2399
|
const brutoScore = texto(args.opcoes.score);
|
|
1118
2400
|
const justificativa = texto(args.opcoes.justificativa) ?? texto(args.opcoes.porque);
|
|
1119
2401
|
if (brutoScore === undefined) {
|
|
@@ -1130,28 +2412,51 @@ function comandoMaster(args) {
|
|
|
1130
2412
|
const brutasClasses = texto(args.opcoes.classe) ?? texto(args.opcoes.classes);
|
|
1131
2413
|
const classes = [];
|
|
1132
2414
|
for (const bruta of (brutasClasses ?? '').split(',').map((c) => c.trim()).filter(Boolean)) {
|
|
1133
|
-
const classe = (0,
|
|
2415
|
+
const classe = (0, master_2.parseClasse)(bruta);
|
|
1134
2416
|
if (!classe) {
|
|
1135
2417
|
console.error(`classe de falha invalida: "${bruta}".`);
|
|
1136
|
-
console.error(` classes fixas: ${
|
|
2418
|
+
console.error(` classes fixas: ${master_2.ORDEM_DAS_CLASSES.join(', ')}`);
|
|
1137
2419
|
return 2;
|
|
1138
2420
|
}
|
|
1139
2421
|
classes.push(classe);
|
|
1140
2422
|
}
|
|
1141
|
-
const
|
|
2423
|
+
const opcoesMaster = {
|
|
1142
2424
|
score: Number(brutoScore),
|
|
1143
2425
|
justificativa,
|
|
1144
2426
|
classes,
|
|
1145
2427
|
resumo: texto(args.opcoes.resumo),
|
|
1146
2428
|
por: texto(args.opcoes.por) ?? texto(args.opcoes.quem),
|
|
1147
2429
|
refazer: args.opcoes.refazer === true,
|
|
1148
|
-
}
|
|
1149
|
-
|
|
2430
|
+
};
|
|
2431
|
+
if (propor) {
|
|
2432
|
+
console.log(JSON.stringify((0, master_1.proporMaster)(carregado.raiz, id, opcoesMaster), null, 2));
|
|
2433
|
+
return 0;
|
|
2434
|
+
}
|
|
2435
|
+
const r = (0, master_2.registrarMaster)(carregado.raiz, id, opcoesMaster);
|
|
2436
|
+
console.log((0, master_2.textoDoMaster)(r));
|
|
1150
2437
|
// Bloco B6: fechada a thread, a licao (POSTMORTEM + score) vai para a colecao
|
|
1151
2438
|
// `learning`, e e o que uma thread NOVA do mesmo produto recebe no GOAL.
|
|
1152
2439
|
relatarPublicacao((0, memoria_1.publicar)(carregado, id));
|
|
2440
|
+
// I-55 (RM-008): a thread fechada pode fazer uma falha recorrente passar do piso. A proposta
|
|
2441
|
+
// vai ao ledger do projeto uma vez por janela; virar policy continua sendo do dono.
|
|
2442
|
+
for (const p of (0, licoes_1.registrarPropostasNovas)(carregado.raiz)) {
|
|
2443
|
+
console.log('');
|
|
2444
|
+
console.log(`Proposta de policy: ${p.chave} em ${p.threads.length} threads nos ultimos ${p.janelaDias} dias.`);
|
|
2445
|
+
console.log(` ${p.sugestao}`);
|
|
2446
|
+
console.log(' So proposta: vira policy quando voce a declara em policies: no orkastery.yaml (ork licoes).');
|
|
2447
|
+
}
|
|
1153
2448
|
console.log('');
|
|
1154
|
-
console.log(`Proximo passo: ork board --all |
|
|
2449
|
+
console.log(`Proximo passo: ork board --all | entregas e indice: ork master`);
|
|
2450
|
+
return 0;
|
|
2451
|
+
}
|
|
2452
|
+
/** I-55 (RM-008): `ork licoes` mostra o que volta no proximo GOAL e PLAN, e as propostas de policy. */
|
|
2453
|
+
function comandoLicoes(args) {
|
|
2454
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
2455
|
+
if (args.opcoes.json === true) {
|
|
2456
|
+
console.log(JSON.stringify({ resumo: (0, licoes_1.resumoDasLicoes)(carregado.raiz, null), propostas: (0, licoes_1.propostasDePolicy)(carregado.raiz) }, null, 2));
|
|
2457
|
+
return 0;
|
|
2458
|
+
}
|
|
2459
|
+
console.log((0, licoes_1.textoDeLicoes)(carregado.raiz));
|
|
1155
2460
|
return 0;
|
|
1156
2461
|
}
|
|
1157
2462
|
/**
|
|
@@ -1161,6 +2466,81 @@ function comandoMaster(args) {
|
|
|
1161
2466
|
* exato com o mesmo sha256 que iria para o ledger, para o builder revisar texto sem gastar
|
|
1162
2467
|
* uma sessao do runtime para descobrir o que foi pedido.
|
|
1163
2468
|
*/
|
|
2469
|
+
/**
|
|
2470
|
+
* I-44: documentacao como codigo. `verificar` le docs e git (roda no CI); `sincronizar` le tambem
|
|
2471
|
+
* o estado das threads, que nao e versionado, e por isso roda na maquina do projeto.
|
|
2472
|
+
*/
|
|
2473
|
+
/** I-47: reservas de item do roadmap entre maquinas (`ork roadmap reservas|pegar|soltar`). */
|
|
2474
|
+
function comandoRoadmap(args) {
|
|
2475
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
2476
|
+
const sub = args.posicionais[1] ?? 'reservas';
|
|
2477
|
+
const remoto = texto(args.opcoes.remoto);
|
|
2478
|
+
if (sub === 'reservas') {
|
|
2479
|
+
const painel = (0, roadmap_reservas_1.listarReservas)(carregado.raiz, { remoto });
|
|
2480
|
+
console.log(args.opcoes.json === true ? JSON.stringify(painel, null, 2) : (0, roadmap_reservas_1.textoDasReservas)(painel));
|
|
2481
|
+
return 0;
|
|
2482
|
+
}
|
|
2483
|
+
const item = args.posicionais[2];
|
|
2484
|
+
if ((sub !== 'pegar' && sub !== 'soltar') || !item) {
|
|
2485
|
+
console.error('uso: ork roadmap reservas | pegar <RM-NNN> [--thread T] [--nota N] | soltar <RM-NNN> [--forcar --motivo M]');
|
|
2486
|
+
return 2;
|
|
2487
|
+
}
|
|
2488
|
+
const opcoes = {
|
|
2489
|
+
remoto,
|
|
2490
|
+
por: texto(args.opcoes.por),
|
|
2491
|
+
maquina: texto(args.opcoes.maquina),
|
|
2492
|
+
...(texto(args.opcoes.thread) !== undefined ? { thread: texto(args.opcoes.thread) } : {}),
|
|
2493
|
+
...(texto(args.opcoes.nota) !== undefined ? { nota: texto(args.opcoes.nota) } : {}),
|
|
2494
|
+
forcar: args.opcoes.forcar === true,
|
|
2495
|
+
motivo: texto(args.opcoes.motivo),
|
|
2496
|
+
};
|
|
2497
|
+
const r = sub === 'pegar' ? (0, roadmap_reservas_1.pegarItem)(carregado.raiz, item, opcoes) : (0, roadmap_reservas_1.soltarItem)(carregado.raiz, item, opcoes);
|
|
2498
|
+
if (args.opcoes.json === true) {
|
|
2499
|
+
console.log(JSON.stringify(r, null, 2));
|
|
2500
|
+
return 0;
|
|
2501
|
+
}
|
|
2502
|
+
const verbo = { pegou: 'reservado para esta maquina', renovou: 'reserva renovada', tomou: 'reserva TOMADA de outra maquina',
|
|
2503
|
+
soltou: 'devolvido', nada: 'ja estava livre' }[r.acao];
|
|
2504
|
+
console.log(`${r.item}: ${verbo}.`);
|
|
2505
|
+
if (r.reserva && r.acao !== 'soltou')
|
|
2506
|
+
console.log(` com ${r.reserva.por} em ${r.reserva.maquina}${r.reserva.thread ? `, thread ${r.reserva.thread}` : ''}`);
|
|
2507
|
+
if (r.commit)
|
|
2508
|
+
console.log(` branch ork/roadmap-reservas em ${r.commit.slice(0, 7)}`);
|
|
2509
|
+
return 0;
|
|
2510
|
+
}
|
|
2511
|
+
function comandoDocs(args) {
|
|
2512
|
+
const sub = args.posicionais[1] ?? 'verificar';
|
|
2513
|
+
const carregado = (0, manifest_1.carregarManifesto)();
|
|
2514
|
+
const raiz = carregado?.raiz ?? process.cwd();
|
|
2515
|
+
const baseBranch = carregado?.manifesto.worktree?.base_branch ?? 'main';
|
|
2516
|
+
if (sub === 'verificar') {
|
|
2517
|
+
const { docs, achados } = (0, docs_1.verificarDocs)(raiz, { baseBranch, ajudaDoCli: AJUDA });
|
|
2518
|
+
if (args.opcoes.json === true) {
|
|
2519
|
+
console.log(JSON.stringify({ paginas: docs.length, erros: achados.filter((a) => a.gravidade === 'erro').length,
|
|
2520
|
+
achados }, null, 2));
|
|
2521
|
+
}
|
|
2522
|
+
else {
|
|
2523
|
+
console.log((0, docs_1.textoDaVerificacao)(docs, achados));
|
|
2524
|
+
}
|
|
2525
|
+
return achados.some((a) => a.gravidade === 'erro') ? 2 : 0;
|
|
2526
|
+
}
|
|
2527
|
+
if (sub === 'sincronizar') {
|
|
2528
|
+
const escrever = args.opcoes.escrever === true;
|
|
2529
|
+
const r = (0, docs_1.sincronizarDocs)(raiz, { baseBranch, escrever });
|
|
2530
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : (0, docs_1.textoDaSincronizacao)(r, escrever));
|
|
2531
|
+
return 0;
|
|
2532
|
+
}
|
|
2533
|
+
if (sub === 'init') {
|
|
2534
|
+
const criados = (0, docs_1.iniciarDocs)(raiz);
|
|
2535
|
+
console.log(criados.length === 0
|
|
2536
|
+
? 'Documentacao como codigo ja estava no projeto: nada criado.'
|
|
2537
|
+
: ['Criado:', ...criados.map((c) => ` ${c}`), '',
|
|
2538
|
+
'Proximo passo: copie docs/produto/_modelo-feature.md e docs/roadmap/_modelo-item.md, e rode ork docs verificar'].join('\n'));
|
|
2539
|
+
return 0;
|
|
2540
|
+
}
|
|
2541
|
+
console.error(`uso: ork docs verificar [--json] | sincronizar [--escrever] | init`);
|
|
2542
|
+
return 2;
|
|
2543
|
+
}
|
|
1164
2544
|
function comandoPrompt(args) {
|
|
1165
2545
|
const sub = args.posicionais[1] ?? 'list';
|
|
1166
2546
|
const carregado = (0, manifest_1.carregarManifesto)();
|
|
@@ -1186,9 +2566,12 @@ function comandoPrompt(args) {
|
|
|
1186
2566
|
// abrir trabalho. Nada e gravado, e o `ork` diz em voz alta que a thread e ficticia.
|
|
1187
2567
|
if (args.opcoes.exemplo === true || args.opcoes.modo !== undefined || args.opcoes.mode !== undefined) {
|
|
1188
2568
|
const bruto = texto(args.opcoes.modo) ?? texto(args.opcoes.mode) ?? 'classic';
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
2569
|
+
let modo;
|
|
2570
|
+
try {
|
|
2571
|
+
modo = (0, modos_1.exigirModoVivo)(bruto);
|
|
2572
|
+
}
|
|
2573
|
+
catch (e) {
|
|
2574
|
+
console.error(e.message);
|
|
1192
2575
|
return 2;
|
|
1193
2576
|
}
|
|
1194
2577
|
const exemplo = (0, prompts_1.threadDeExemplo)(modo, fase, carregado?.manifesto.project);
|
|
@@ -1266,6 +2649,10 @@ function comandoAdapter(args) {
|
|
|
1266
2649
|
force: args.opcoes.force === true || args.opcoes.forcar === true,
|
|
1267
2650
|
orkBin: texto(args.opcoes.ork),
|
|
1268
2651
|
versao: VERSAO,
|
|
2652
|
+
// I-43 (D5): a decisao por ARQUIVO, que e o que faz `--force` deixar de ser o
|
|
2653
|
+
// unico caminho de saida. `;` separa varios, como o resto do CLI ja faz.
|
|
2654
|
+
aceitarCatalogo: (texto(args.opcoes['aceitar-catalogo']) ?? '').split(';').map(x => x.trim()).filter(Boolean),
|
|
2655
|
+
manterCopia: (texto(args.opcoes['manter-copia']) ?? '').split(';').map(x => x.trim()).filter(Boolean),
|
|
1269
2656
|
});
|
|
1270
2657
|
console.log((0, hosts_1.textoDaInstalacao)(r));
|
|
1271
2658
|
return r.ok ? 0 : 2;
|
|
@@ -1308,6 +2695,12 @@ function comandoEval(args) {
|
|
|
1308
2695
|
* diferente de zero quando reprova, para o agendador do host perceber sem ler texto.
|
|
1309
2696
|
*/
|
|
1310
2697
|
function comandoAudit(args) {
|
|
2698
|
+
if (args.posicionais[1] === 'process') {
|
|
2699
|
+
const r = (0, process_audit_1.auditarProcesso)((0, manifest_1.exigirManifesto)(), args.opcoes.registrar === true);
|
|
2700
|
+
console.log(JSON.stringify(r, null, 2));
|
|
2701
|
+
const chave = texto(args.opcoes['exigir-achado']);
|
|
2702
|
+
return chave && !r.achados.some(a => a.chave === chave) ? 1 : 0;
|
|
2703
|
+
}
|
|
1311
2704
|
const sub = args.posicionais[1] ?? 'packs';
|
|
1312
2705
|
// `audit packs` e `audit lint` funcionam sem manifesto: sao catalogo, nao estado.
|
|
1313
2706
|
if (sub === 'packs' || sub === 'pack') {
|
|
@@ -1673,6 +3066,10 @@ function comandoAudit(args) {
|
|
|
1673
3066
|
* que sempre teve. E o que garante que ligar o B6 nao muda o que o builder ja conhece.
|
|
1674
3067
|
*/
|
|
1675
3068
|
function relatarPublicacao(r) {
|
|
3069
|
+
if (r.publicacao?.estado === 'pendente') {
|
|
3070
|
+
console.log(`Memoria: publicacao pendente (${r.publicacao.motivo}); ativacao explicita necessaria.`);
|
|
3071
|
+
return;
|
|
3072
|
+
}
|
|
1676
3073
|
if (r.regime !== 'orkmind')
|
|
1677
3074
|
return;
|
|
1678
3075
|
const gravados = [
|
|
@@ -1687,9 +3084,18 @@ function relatarPublicacao(r) {
|
|
|
1687
3084
|
if (r.falhas > 0)
|
|
1688
3085
|
console.log(` ${r.falhas} gravacao(oes) nao concluida(s); veja ork memory status.`);
|
|
1689
3086
|
}
|
|
3087
|
+
/** Janela de origem e corte de apresentação são inteiros positivos explícitos. */
|
|
3088
|
+
function limiteDeLeitura(valor) {
|
|
3089
|
+
if (valor === undefined)
|
|
3090
|
+
return undefined;
|
|
3091
|
+
if (typeof valor !== 'string' || !/^[0-9]+$/.test(valor) ||
|
|
3092
|
+
Number(valor) < 1 || Number(valor) > 1000)
|
|
3093
|
+
throw Error('memory.query.invalid');
|
|
3094
|
+
return Number(valor);
|
|
3095
|
+
}
|
|
1690
3096
|
/** `ork recall`: recuperacao tardia dos ponteiros do handoff, no momento indicado. */
|
|
1691
3097
|
function comandoRecall(args) {
|
|
1692
|
-
const carregado = (0, manifest_1.exigirManifesto)();
|
|
3098
|
+
const carregado = (0, project_state_1.memoryState)((0, manifest_1.exigirManifesto)()).loaded;
|
|
1693
3099
|
const id = args.posicionais[1];
|
|
1694
3100
|
if (!id) {
|
|
1695
3101
|
console.error('uso: ork recall <thread-id> [--fase FASE] [--id ptr-N] [--todos] [--forcar]');
|
|
@@ -1698,7 +3104,7 @@ function comandoRecall(args) {
|
|
|
1698
3104
|
const thread = (0, thread_1.lerThread)(carregado.raiz, id);
|
|
1699
3105
|
const faseBruta = texto(args.opcoes.fase) ?? texto(args.opcoes.momento);
|
|
1700
3106
|
const momento = faseBruta ? (0, thread_1.exigirFase)(thread, faseBruta) : undefined;
|
|
1701
|
-
const memoria = (0, memoria_1.abrirMemoria)(carregado);
|
|
3107
|
+
const memoria = (0, memoria_1.abrirMemoria)(carregado, { leituraRestrita: { thread: id, limite: limiteDeLeitura(args.opcoes.janela) } });
|
|
1702
3108
|
const r = (0, recall_1.recallDaThread)(carregado, memoria, id, {
|
|
1703
3109
|
momento,
|
|
1704
3110
|
id: texto(args.opcoes.id),
|
|
@@ -1716,32 +3122,96 @@ function comandoRecall(args) {
|
|
|
1716
3122
|
}
|
|
1717
3123
|
/** `ork memory`: o regime, a publicacao e a busca deterministica por tag. */
|
|
1718
3124
|
function comandoMemory(args) {
|
|
1719
|
-
const
|
|
3125
|
+
const candidate = (0, manifest_1.exigirManifesto)();
|
|
3126
|
+
const carregado = (0, project_state_1.memoryState)(candidate).loaded;
|
|
1720
3127
|
const sub = args.posicionais[1] ?? 'status';
|
|
1721
|
-
const
|
|
3128
|
+
const escopo = texto(args.opcoes.escopo)?.split(',').map(s => s.trim());
|
|
3129
|
+
if (sub === 'inventory' || (sub === 'migrate' && args.opcoes['dry-run'] === true)) {
|
|
3130
|
+
const r = (0, memory_migration_1.inventariarHandoffs)(carregado, escopo);
|
|
3131
|
+
if (args.opcoes.json === true)
|
|
3132
|
+
console.log(JSON.stringify(r, null, 2));
|
|
3133
|
+
else {
|
|
3134
|
+
console.log(`Inventario do tenant ${r.tenant}: ${r.incluidos} incluidos, ${r.excluidos} excluidos.`);
|
|
3135
|
+
for (const f of r.fontes)
|
|
3136
|
+
console.log(` ${f.incluir ? 'incluir' : 'excluir'} ${f.arquivo}: ${f.motivo}`);
|
|
3137
|
+
}
|
|
3138
|
+
return r.fontes.some(f => f.bloqueante) ? 1 : 0;
|
|
3139
|
+
}
|
|
3140
|
+
if (sub === 'migrate') {
|
|
3141
|
+
const operadora = texto(args.opcoes.operadora);
|
|
3142
|
+
if (!operadora || !escopo)
|
|
3143
|
+
throw new Error('scope.write.required: --operadora <thread> --escopo <thread,...>');
|
|
3144
|
+
if (carregado.manifesto.memory.mode === 'orkmind') {
|
|
3145
|
+
const autorizacao = (0, write_activation_1.exigirAtivacao)(carregado, operadora, 'memory');
|
|
3146
|
+
if (escopo.some(id => !autorizacao.threads.includes(id)))
|
|
3147
|
+
throw Error('write.activation.scope-denied');
|
|
3148
|
+
}
|
|
3149
|
+
const r = (0, memory_migration_1.migrarHandoffs)(carregado, { operadora, escopo });
|
|
3150
|
+
if (args.opcoes.json === true)
|
|
3151
|
+
console.log(JSON.stringify(r, null, 2));
|
|
3152
|
+
else {
|
|
3153
|
+
console.log(`Migracao do tenant ${r.inventario.tenant}: ${r.resultados.filter(i => i.ok).length} confirmados, ${r.falhas} falhas, ${r.inventario.excluidos} excluidos.`);
|
|
3154
|
+
for (const item of r.resultados)
|
|
3155
|
+
console.log(` ${item.arquivo}: ${item.ok ? item.gravacao?.id : item.erro}`);
|
|
3156
|
+
}
|
|
3157
|
+
return r.ok ? 0 : 1;
|
|
3158
|
+
}
|
|
3159
|
+
if (sub === 'sync' && args.posicionais[2])
|
|
3160
|
+
(0, escopo_escrita_1.validarDiretorioDeThread)(carregado.raiz, args.posicionais[2]);
|
|
1722
3161
|
if (sub === 'status') {
|
|
3162
|
+
const memoria = (0, memoria_1.abrirMemoria)(candidate);
|
|
1723
3163
|
if (args.opcoes.json === true) {
|
|
1724
|
-
console.log(JSON.stringify(memoria.estado, null, 2));
|
|
3164
|
+
console.log(JSON.stringify({ ...memoria.estado, configSource: memoria.configSource, configDivergent: memoria.configDivergent }, null, 2));
|
|
1725
3165
|
return 0;
|
|
1726
3166
|
}
|
|
1727
3167
|
console.log((0, memoria_1.textoDoEstado)(memoria.estado));
|
|
1728
3168
|
return 0;
|
|
1729
3169
|
}
|
|
1730
3170
|
if (sub === 'sync') {
|
|
3171
|
+
const memoria = (0, memoria_1.abrirMemoria)(carregado);
|
|
1731
3172
|
const threadId = args.posicionais[2];
|
|
1732
3173
|
// Thread inexistente reprova aqui, e nao no meio da gravacao.
|
|
1733
3174
|
if (threadId)
|
|
1734
3175
|
(0, thread_1.lerThread)(carregado.raiz, threadId);
|
|
1735
|
-
const
|
|
3176
|
+
const perfil = (texto(args.opcoes.perfil) ?? 'integral');
|
|
3177
|
+
if (!['fabrica', 'integral'].includes(perfil))
|
|
3178
|
+
throw Error('memory.publication.profile-invalid');
|
|
3179
|
+
if (carregado.manifesto.memory.mode === 'orkmind') {
|
|
3180
|
+
try {
|
|
3181
|
+
const autorizacao = (0, write_activation_1.exigirAtivacao)(carregado, threadId ?? '', 'memory');
|
|
3182
|
+
if (autorizacao.perfil !== 'integral' && perfil !== autorizacao.perfil)
|
|
3183
|
+
throw Error('write.activation.profile-denied');
|
|
3184
|
+
}
|
|
3185
|
+
catch (error) {
|
|
3186
|
+
const motivo = error instanceof Error
|
|
3187
|
+
? /^(?:write\.activation|scope|memory)\.[a-z.-]+/.exec(error.message)?.[0] ?? 'write.activation.invalid'
|
|
3188
|
+
: 'write.activation.invalid';
|
|
3189
|
+
const detalhe = 'sync nao executado; colisao legada nao foi reavaliada';
|
|
3190
|
+
if (args.opcoes.json === true)
|
|
3191
|
+
console.log(JSON.stringify({
|
|
3192
|
+
regime: memoria.regime, estado: memoria.estado, thread: threadId ?? null, perfil,
|
|
3193
|
+
publicacao: { estado: 'pendente', motivo }, falhas: 1, gravadas: [], erro: motivo, detalhe,
|
|
3194
|
+
}, null, 2));
|
|
3195
|
+
console.error(`${motivo}: ${detalhe}`);
|
|
3196
|
+
return 1;
|
|
3197
|
+
}
|
|
3198
|
+
}
|
|
3199
|
+
const r = (0, memoria_1.sincronizarMemoria)(carregado, memoria, threadId ?? null, undefined, perfil);
|
|
1736
3200
|
if (args.opcoes.json === true) {
|
|
1737
3201
|
console.log(JSON.stringify(r, null, 2));
|
|
1738
3202
|
}
|
|
1739
3203
|
else {
|
|
1740
3204
|
console.log((0, memoria_1.textoDoSync)(r));
|
|
1741
3205
|
}
|
|
1742
|
-
return 0;
|
|
3206
|
+
return r.estado.pedido === 'orkmind' && r.falhas > 0 ? 1 : 0;
|
|
1743
3207
|
}
|
|
1744
3208
|
if (sub === 'search') {
|
|
3209
|
+
const threadId = texto(args.opcoes.thread);
|
|
3210
|
+
if ((args.opcoes.restrito !== undefined || args.opcoes.thread !== undefined ||
|
|
3211
|
+
args.opcoes.janela !== undefined) && !threadId) {
|
|
3212
|
+
throw Error('memory.query.thread-required: use --thread <id>');
|
|
3213
|
+
}
|
|
3214
|
+
const janela = limiteDeLeitura(args.opcoes.janela);
|
|
1745
3215
|
const tagsBrutas = texto(args.opcoes.tags);
|
|
1746
3216
|
if (!tagsBrutas) {
|
|
1747
3217
|
console.error('uso: ork memory search --tags \'{"project":["orkastery"],"skill":["orkastery-decision"]}\'');
|
|
@@ -1757,11 +3227,19 @@ function comandoMemory(args) {
|
|
|
1757
3227
|
}
|
|
1758
3228
|
const colecao = texto(args.opcoes.colecao) ?? texto(args.opcoes.collection);
|
|
1759
3229
|
const limiteBruto = texto(args.opcoes.limite);
|
|
3230
|
+
const limite = threadId ? limiteDeLeitura(args.opcoes.limite) : limiteBruto ? Number(limiteBruto) : undefined;
|
|
3231
|
+
if (threadId)
|
|
3232
|
+
(0, orkmind_1.validarConsultaDelimitada)({ collection: colecao,
|
|
3233
|
+
escopo: (0, orkmind_1.criarEscopoDeLeitura)(carregado.manifesto, threadId), tags,
|
|
3234
|
+
limite: janela ?? orkmind_1.LIMITE_CONSULTA_PADRAO });
|
|
3235
|
+
const memoria = (0, memoria_1.abrirMemoria)(carregado, threadId ? { leituraRestrita: { thread: threadId, limite: janela } } : {});
|
|
1760
3236
|
const entradas = memoria.buscar({
|
|
1761
3237
|
collection: colecao,
|
|
1762
3238
|
tags,
|
|
1763
|
-
limite
|
|
3239
|
+
limite,
|
|
1764
3240
|
});
|
|
3241
|
+
if (threadId && memoria.regime === 'files')
|
|
3242
|
+
console.error(`memory.query.files: ${memoria.estado.motivo}; resultado nao comprova ausencia na memoria semantica`);
|
|
1765
3243
|
if (args.opcoes.json === true) {
|
|
1766
3244
|
console.log(JSON.stringify(entradas, null, 2));
|
|
1767
3245
|
return 0;
|
|
@@ -1785,19 +3263,93 @@ function comandoMemory(args) {
|
|
|
1785
3263
|
return 2;
|
|
1786
3264
|
}
|
|
1787
3265
|
function main(argv) {
|
|
3266
|
+
// I-35: todo horário para pessoa sai no fuso do dono deste projeto (lido só se for preciso).
|
|
3267
|
+
(0, horario_1.registrarFonteDoFuso)(() => (0, horario_1.fusoDoManifesto)((0, manifest_1.carregarManifesto)()));
|
|
3268
|
+
// Helper fixo do host confiável: o projeto vem da instalação, nunca de toolargs.
|
|
3269
|
+
if (argv[0] === 'receipt-verifiers') {
|
|
3270
|
+
if (argv.length !== 2 || argv[1] !== '--json')
|
|
3271
|
+
throw Error('uso: ork receipt-verifiers --json');
|
|
3272
|
+
const root = process.env.ORK_HITL_ROOT;
|
|
3273
|
+
const privateKey = Object.keys(process.env).some(name => /^ORK_HITL_(?:INGRESS_KEY|NATIVE_KEY)/.test(name));
|
|
3274
|
+
if (root !== undefined || privateKey) {
|
|
3275
|
+
if (!root || !(0, node_path_1.isAbsolute)(root) || fs.realpathSync(root) !== root)
|
|
3276
|
+
throw Error('hitl.receipt.project-unavailable');
|
|
3277
|
+
const carregado = (0, manifest_1.exigirManifesto)(root);
|
|
3278
|
+
if (carregado.raiz !== root)
|
|
3279
|
+
throw Error('hitl.receipt.project-unavailable');
|
|
3280
|
+
for (const id of (0, thread_1.listarIds)(root))
|
|
3281
|
+
(0, hitl_ingress_receipt_1.prepararRecibosParaDespacho)(root, id);
|
|
3282
|
+
}
|
|
3283
|
+
console.log((0, hitl_public_receipt_1.publicHitlVerifiers)() ?? 'null');
|
|
3284
|
+
return 0;
|
|
3285
|
+
}
|
|
3286
|
+
if (argv[0] === 'maestro')
|
|
3287
|
+
return (0, maestro_cli_1.runMaestroCli)(argv.slice(1));
|
|
1788
3288
|
const args = parseArgs(argv);
|
|
1789
3289
|
const comando = args.posicionais[0];
|
|
3290
|
+
// `ork --version` tambem chega sem comando: a versao e conferida antes da ajuda.
|
|
3291
|
+
if (args.opcoes.version === true || comando === 'version') {
|
|
3292
|
+
console.log(VERSAO);
|
|
3293
|
+
return 0;
|
|
3294
|
+
}
|
|
1790
3295
|
if (!comando || args.opcoes.help === true || comando === 'help') {
|
|
1791
3296
|
console.log(AJUDA);
|
|
1792
3297
|
return 0;
|
|
1793
3298
|
}
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
3299
|
+
const nomesHerdados = (0, runtime_ambiente_1.nomesDeProviderAtivos)();
|
|
3300
|
+
const ambienteManifesto = (0, manifest_1.carregarManifesto)();
|
|
3301
|
+
if (ambienteManifesto?.manifesto.runtime.provider_policy === 'subscription-only') {
|
|
3302
|
+
// Avaliar ANTES de limpar: um redirecionamento bloqueante não pode desaparecer.
|
|
3303
|
+
const violacoes = (0, policies_1.avaliarPolicies)(ambienteManifesto.manifesto, { gate: 'phase.dispatch' });
|
|
3304
|
+
// O gate oficial precisa observar e registrar a violação (inclusive warn).
|
|
3305
|
+
// Diagnósticos continuam acessíveis; os adapters sanitizam seus filhos sempre.
|
|
3306
|
+
if (violacoes.length === 0)
|
|
3307
|
+
for (const nome of runtime_ambiente_1.ENVS_DE_PROVIDER_PAGO)
|
|
3308
|
+
delete process.env[nome];
|
|
1797
3309
|
}
|
|
1798
3310
|
switch (comando) {
|
|
3311
|
+
case 'mcp': {
|
|
3312
|
+
const projeto = texto(args.opcoes.project), host = texto(args.opcoes.host), threadId = texto(args.opcoes.thread);
|
|
3313
|
+
// I-36 (D4): a identidade do despacho so chega com a thread vinculada da sessao filha.
|
|
3314
|
+
const dispatchId = texto(args.opcoes.dispatch);
|
|
3315
|
+
const transporteShip = texto(args.opcoes['ship-transport']) ?? 'github-ssh';
|
|
3316
|
+
const permissoesFilho = texto(args.opcoes['child-permissions']) ?? 'interactive';
|
|
3317
|
+
const permissoesDono = texto(args.opcoes['owner-permissions']);
|
|
3318
|
+
const acao = args.posicionais[1];
|
|
3319
|
+
if (args.posicionais.length !== 2 || !['serve', 'install'].includes(acao) || !projeto ||
|
|
3320
|
+
(host !== 'codex' && host !== 'claude-code') ||
|
|
3321
|
+
Object.keys(args.opcoes).some(k => !['project', 'host', 'ship-transport', 'child-permissions', ...(acao === 'install' ? ['dry-run', 'owner-permissions'] : ['thread', 'dispatch'])].includes(k)) ||
|
|
3322
|
+
(args.opcoes.dispatch !== undefined && (!threadId || !dispatchId || !/^[a-f0-9-]{36}$/.test(dispatchId))) ||
|
|
3323
|
+
argv.filter(a => a === '--ship-transport' || a.startsWith('--ship-transport=')).length > 1 ||
|
|
3324
|
+
argv.filter(a => a === '--child-permissions' || a.startsWith('--child-permissions=')).length > 1 ||
|
|
3325
|
+
(args.opcoes['owner-permissions'] !== undefined && (host !== 'codex' || typeof args.opcoes['owner-permissions'] !== 'string' || !['interactive', 'orchestrate'].includes(permissoesDono ?? ''))) ||
|
|
3326
|
+
argv.filter(a => a === '--owner-permissions' || a.startsWith('--owner-permissions=')).length > 1 ||
|
|
3327
|
+
!['interactive', 'worktree'].includes(permissoesFilho) ||
|
|
3328
|
+
(args.opcoes['child-permissions'] !== undefined && typeof args.opcoes['child-permissions'] !== 'string') ||
|
|
3329
|
+
!['github-ssh', 'bare-local'].includes(transporteShip) ||
|
|
3330
|
+
(args.opcoes['ship-transport'] !== undefined && typeof args.opcoes['ship-transport'] !== 'string') ||
|
|
3331
|
+
(args.opcoes.thread !== undefined && (!threadId || !/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$/.test(threadId))) ||
|
|
3332
|
+
(args.opcoes['dry-run'] !== undefined && args.opcoes['dry-run'] !== true))
|
|
3333
|
+
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]');
|
|
3334
|
+
if (acao === 'install') {
|
|
3335
|
+
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 }))))
|
|
3336
|
+
.catch(e => { console.error(`mcp: ${e.message}`); process.exitCode = 1; });
|
|
3337
|
+
return 0;
|
|
3338
|
+
}
|
|
3339
|
+
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; });
|
|
3340
|
+
return 0;
|
|
3341
|
+
}
|
|
1799
3342
|
case 'doctor': {
|
|
1800
|
-
|
|
3343
|
+
if (args.opcoes.modo !== undefined) {
|
|
3344
|
+
const bruto = texto(args.opcoes.modo);
|
|
3345
|
+
if (args.posicionais.length !== 1 || !bruto ||
|
|
3346
|
+
Object.keys(args.opcoes).some(k => k !== 'modo') || argv.filter(a => a === '--modo' || a.startsWith('--modo=')).length !== 1)
|
|
3347
|
+
throw Error(`uso: ork doctor --modo ${modos_1.ORDEM_DOS_MODOS.join('|')}`);
|
|
3348
|
+
const r = (0, preflight_1.preflight)(process.cwd(), (0, modos_1.exigirModoVivo)(bruto), nomesHerdados);
|
|
3349
|
+
console.log((0, preflight_1.textoPreflight)(r));
|
|
3350
|
+
return r.prontoPrimeiroBloco ? 0 : 1;
|
|
3351
|
+
}
|
|
3352
|
+
const r = (0, doctor_1.doctor)(process.cwd(), nomesHerdados);
|
|
1801
3353
|
console.log(r.texto);
|
|
1802
3354
|
return r.codigo;
|
|
1803
3355
|
}
|
|
@@ -1807,9 +3359,12 @@ function main(argv) {
|
|
|
1807
3359
|
nome: texto(args.opcoes.name) ?? texto(args.opcoes.nome),
|
|
1808
3360
|
abbrev: texto(args.opcoes.abbrev),
|
|
1809
3361
|
});
|
|
3362
|
+
const carregado = (0, manifest_1.exigirManifesto)(r.deteccao.raiz);
|
|
3363
|
+
const agents = (0, agents_md_1.atualizarAgentsMd)(r.deteccao.raiz, carregado.manifesto);
|
|
1810
3364
|
if (!r.criado) {
|
|
1811
3365
|
console.log(`Manifesto ja existe: ${r.caminho}`);
|
|
1812
3366
|
console.log('Nada foi sobrescrito. Use --force para regerar.');
|
|
3367
|
+
console.log(`AGENTS.md ${agents.estado}: ${agents.caminho}`);
|
|
1813
3368
|
return 0;
|
|
1814
3369
|
}
|
|
1815
3370
|
console.log(`Manifesto criado: ${r.caminho}`);
|
|
@@ -1817,17 +3372,37 @@ function main(argv) {
|
|
|
1817
3372
|
console.log(` branch base ${r.deteccao.baseBranch}`);
|
|
1818
3373
|
console.log(` gerenciador ${r.deteccao.gerenciador}`);
|
|
1819
3374
|
console.log(` verify ${Object.entries(r.deteccao.verify).map(([k, v]) => `${k}="${v}"`).join(', ') || '(nenhum script detectado)'}`);
|
|
3375
|
+
console.log(` AGENTS.md ${agents.estado}: ${agents.caminho}`);
|
|
1820
3376
|
console.log('');
|
|
1821
|
-
console.log(
|
|
3377
|
+
console.log(init_2.PROXIMO_PASSO_INIT);
|
|
1822
3378
|
return 0;
|
|
1823
3379
|
}
|
|
1824
3380
|
case 'modos': {
|
|
3381
|
+
// I-43 (T4): `ork modos migrar` tira modo aposentado da CONFIGURACAO do projeto
|
|
3382
|
+
// (`orkastery.yaml` e `setup.json`) e nao toca em historico nenhum. Idempotente:
|
|
3383
|
+
// rodar de novo num projeto ja migrado nao escreve nada.
|
|
3384
|
+
if (args.posicionais[1] === 'migrar') {
|
|
3385
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
3386
|
+
const r = (0, modos_migracao_1.migrarModosAposentados)(carregado.raiz, {
|
|
3387
|
+
dryRun: args.opcoes['dry-run'] === true,
|
|
3388
|
+
por: texto(args.opcoes.por),
|
|
3389
|
+
});
|
|
3390
|
+
console.log(args.opcoes.json === true ? JSON.stringify(r, null, 2) : (0, modos_migracao_1.textoDaMigracaoModos)(r));
|
|
3391
|
+
return 0;
|
|
3392
|
+
}
|
|
1825
3393
|
// `--do-pedido` existe para os adaptadores de host: eles extraem a #TAG do texto do
|
|
1826
3394
|
// builder SEM reimplementar o parse, e repassam `--mode` ao `ork`. A validacao contra
|
|
1827
3395
|
// `conduction.allowed_modes` continua sendo do nucleo, no `ork thread new`.
|
|
1828
3396
|
const pedido = texto(args.opcoes['do-pedido']);
|
|
1829
3397
|
if (pedido !== undefined) {
|
|
1830
3398
|
const carregado = (0, manifest_1.carregarManifesto)();
|
|
3399
|
+
// I-43: `#Look` no pedido nao pode cair no default em silencio. O adaptador
|
|
3400
|
+
// recebe a recusa tipada e saida != 0, e quem escreveu a #TAG fica sabendo.
|
|
3401
|
+
const aposentado = (0, modos_1.extrairTagAposentadaDoPedido)(pedido);
|
|
3402
|
+
if (aposentado) {
|
|
3403
|
+
console.error((0, modos_1.recusaDeModoAposentado)(aposentado));
|
|
3404
|
+
return 2;
|
|
3405
|
+
}
|
|
1831
3406
|
const extraido = (0, modos_1.extrairTagDoPedido)(pedido);
|
|
1832
3407
|
const modo = extraido ?? carregado?.manifesto.conduction.default_mode ?? 'classic';
|
|
1833
3408
|
if (args.opcoes.json === true) {
|
|
@@ -1847,16 +3422,59 @@ function main(argv) {
|
|
|
1847
3422
|
console.log((0, modos_1.tabelaDeModos)());
|
|
1848
3423
|
return 0;
|
|
1849
3424
|
}
|
|
3425
|
+
case 'setup':
|
|
3426
|
+
return comandoSetup(args);
|
|
3427
|
+
case 'accounts':
|
|
3428
|
+
return comandoAccounts(args);
|
|
3429
|
+
case 'onboarding':
|
|
3430
|
+
return comandoOnboarding(args);
|
|
1850
3431
|
case 'thread':
|
|
1851
3432
|
return comandoThread(args);
|
|
3433
|
+
case 'objective':
|
|
3434
|
+
return comandoObjective(args);
|
|
3435
|
+
case 'creation':
|
|
3436
|
+
return comandoCreation(args);
|
|
3437
|
+
case 'portfolio':
|
|
3438
|
+
return comandoPortfolio(args);
|
|
1852
3439
|
case 'phase':
|
|
1853
3440
|
return comandoPhase(args);
|
|
3441
|
+
case 'ledger':
|
|
3442
|
+
return comandoLedger(args);
|
|
1854
3443
|
case 'sessions':
|
|
1855
3444
|
return comandoSessions(args);
|
|
3445
|
+
case 'pulse': {
|
|
3446
|
+
if (args.posicionais[1] === 'responder') {
|
|
3447
|
+
// I-41 (GO-FIX 1, B1 e B2): o caminho de volta do resumo. So o ingresso autenticado chama;
|
|
3448
|
+
// argv traz identificadores e o envelope assinado vem por stdin, como no `gate answer`.
|
|
3449
|
+
if (args.opcoes['resposta-stdin'] !== true || args.opcoes.resposta !== undefined || args.posicionais.length !== 2) {
|
|
3450
|
+
throw new Error('pulse responder exige --resposta-stdin e o envelope do ingresso autenticado');
|
|
3451
|
+
}
|
|
3452
|
+
const carregado = (0, manifest_1.exigirManifesto)();
|
|
3453
|
+
const envelope = (0, hitl_gates_1.lerRespostaStdin)({ por: texto(args.opcoes.por), mensagem: texto(args.opcoes.mensagem),
|
|
3454
|
+
origem: texto(args.opcoes.origem), canal: texto(args.opcoes.canal), conta: texto(args.opcoes.conta) });
|
|
3455
|
+
const formato = texto(args.opcoes.formato);
|
|
3456
|
+
if (formato !== undefined && formato !== 'telegram' && formato !== 'terminal')
|
|
3457
|
+
throw new Error('pulse responder: --formato telegram|terminal');
|
|
3458
|
+
console.log(JSON.stringify((0, pulse_resposta_1.responderPeloPulse)(carregado.raiz, envelope, { canal: formato ?? 'telegram' })));
|
|
3459
|
+
return 0;
|
|
3460
|
+
}
|
|
3461
|
+
if (args.posicionais[1] === 'cadencia')
|
|
3462
|
+
return comandoCadenciaDoPulse(args);
|
|
3463
|
+
const p = (0, pulse_1.montarPulse)((0, manifest_1.exigirManifesto)(), { registrar: args.opcoes.registrar === true,
|
|
3464
|
+
escopo: texto(args.opcoes.escopo)?.split(',').map(s => s.trim()),
|
|
3465
|
+
semRuntime: args.opcoes['sem-runtime'] === true,
|
|
3466
|
+
linhasLogs: texto(args.opcoes.linhas) === undefined ? undefined : Number(texto(args.opcoes.linhas)) });
|
|
3467
|
+
console.log(args.opcoes.json === true ? JSON.stringify(p, null, 2) : (0, pulse_1.textoDoPulse)(p));
|
|
3468
|
+
return p.runtime.ok || args.opcoes['sem-runtime'] === true ? 0 : 1;
|
|
3469
|
+
}
|
|
1856
3470
|
case 'claims':
|
|
1857
3471
|
return comandoClaims(args);
|
|
3472
|
+
case 'decisao':
|
|
3473
|
+
return comandoDecisao(args);
|
|
1858
3474
|
case 'verify':
|
|
1859
3475
|
return comandoVerify(args);
|
|
3476
|
+
case 'ci':
|
|
3477
|
+
return comandoCi(args);
|
|
1860
3478
|
case 'gate':
|
|
1861
3479
|
return comandoGate(args);
|
|
1862
3480
|
case 'retry':
|
|
@@ -1867,12 +3485,21 @@ function main(argv) {
|
|
|
1867
3485
|
return comandoHandoff(args);
|
|
1868
3486
|
case 'recall':
|
|
1869
3487
|
return comandoRecall(args);
|
|
3488
|
+
case 'brain': {
|
|
3489
|
+
const result = (0, company_brain_cli_1.runBrain)((0, manifest_1.exigirManifesto)(), args.posicionais[1] ?? 'status', args.opcoes, args.posicionais.slice(2));
|
|
3490
|
+
console.log(JSON.stringify(result, null, 2));
|
|
3491
|
+
return ['ok', 'empty', 'unknown', 'withheld', 'applied', 'rolled-back'].includes(result.state) ? 0 : 1;
|
|
3492
|
+
}
|
|
1870
3493
|
case 'memory':
|
|
1871
3494
|
return comandoMemory(args);
|
|
1872
3495
|
case 'ship':
|
|
1873
3496
|
return comandoShip(args);
|
|
3497
|
+
case 'activation':
|
|
3498
|
+
return (0, write_activation_1.comandoAtivacao)((0, manifest_1.exigirManifesto)(), args);
|
|
1874
3499
|
case 'lease':
|
|
1875
3500
|
return comandoLease(args);
|
|
3501
|
+
case 'conducao':
|
|
3502
|
+
return comandoConducao(args);
|
|
1876
3503
|
case 'board':
|
|
1877
3504
|
return comandoBoard(args);
|
|
1878
3505
|
case 'orquestracao':
|
|
@@ -1890,6 +3517,19 @@ function main(argv) {
|
|
|
1890
3517
|
return comandoAdapter(args);
|
|
1891
3518
|
case 'prompt':
|
|
1892
3519
|
return comandoPrompt(args);
|
|
3520
|
+
case 'docs':
|
|
3521
|
+
return comandoDocs(args);
|
|
3522
|
+
case 'roadmap':
|
|
3523
|
+
return comandoRoadmap(args);
|
|
3524
|
+
case 'demo': {
|
|
3525
|
+
// I-56 (RM-046): a promessa em trinta segundos, offline, sem runtime e sem tocar o projeto.
|
|
3526
|
+
const r = (0, demo_1.executarDemo)({ dir: texto(args.opcoes.dir), manter: args.opcoes.manter === true, escrever: (l) => console.log(l) });
|
|
3527
|
+
return r.ok ? 0 : 1;
|
|
3528
|
+
}
|
|
3529
|
+
case 'fabrica':
|
|
3530
|
+
return comandoFabrica(args);
|
|
3531
|
+
case 'licoes':
|
|
3532
|
+
return comandoLicoes(args);
|
|
1893
3533
|
case 'ciclos':
|
|
1894
3534
|
console.log((0, ciclos_1.tabelaDeVariantes)());
|
|
1895
3535
|
return 0;
|
|
@@ -1904,7 +3544,14 @@ if (require.main === module) {
|
|
|
1904
3544
|
process.exitCode = main(process.argv.slice(2));
|
|
1905
3545
|
}
|
|
1906
3546
|
catch (e) {
|
|
1907
|
-
|
|
1908
|
-
|
|
3547
|
+
// I-36 (T12): a recusa de conducao e resposta, nao erro: o texto para o humano, ou o JSON.
|
|
3548
|
+
if (e instanceof conducao_1.ErroDeConducao) {
|
|
3549
|
+
console.log(process.argv.includes('--json') ? JSON.stringify(e.recusa, null, 2) : e.recusa.texto);
|
|
3550
|
+
process.exitCode = 3;
|
|
3551
|
+
}
|
|
3552
|
+
else {
|
|
3553
|
+
console.error(`erro: ${e.message}`);
|
|
3554
|
+
process.exitCode = 1;
|
|
3555
|
+
}
|
|
1909
3556
|
}
|
|
1910
3557
|
}
|