@orkastery/cli 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +87 -0
  3. package/adapters/README.md +22 -0
  4. package/adapters/claude-code/.claude-plugin/marketplace.json +15 -0
  5. package/adapters/claude-code/.claude-plugin/plugin.json +31 -0
  6. package/adapters/claude-code/README.md +102 -0
  7. package/adapters/claude-code/agents/ork-check.md +32 -0
  8. package/adapters/claude-code/agents/ork-go.md +32 -0
  9. package/adapters/claude-code/agents/ork-goal.md +33 -0
  10. package/adapters/claude-code/agents/ork-master.md +32 -0
  11. package/adapters/claude-code/agents/ork-plan.md +32 -0
  12. package/adapters/claude-code/agents/ork-ship.md +32 -0
  13. package/adapters/claude-code/commands/check.md +45 -0
  14. package/adapters/claude-code/commands/go.md +46 -0
  15. package/adapters/claude-code/commands/goal.md +54 -0
  16. package/adapters/claude-code/commands/master.md +42 -0
  17. package/adapters/claude-code/commands/ork.md +37 -0
  18. package/adapters/claude-code/commands/plan.md +47 -0
  19. package/adapters/claude-code/commands/ship.md +45 -0
  20. package/adapters/claude-code/hooks/hooks.json +17 -0
  21. package/adapters/claude-code/hooks/ork-guard.js +130 -0
  22. package/adapters/hermes/README.md +45 -0
  23. package/adapters/hermes/bin/ork-abrir-thread.sh +25 -0
  24. package/adapters/hermes/hermes.plugin.json +21 -0
  25. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +116 -0
  26. package/adapters/openclaw/README.md +63 -0
  27. package/adapters/openclaw/bin/ork-abrir-thread.sh +24 -0
  28. package/adapters/openclaw/openclaw.plugin.json +138 -0
  29. package/dist/adapters/claude-bg.js +308 -0
  30. package/dist/auditoria.js +848 -0
  31. package/dist/auditrun.js +976 -0
  32. package/dist/board.js +314 -0
  33. package/dist/canarios.js +271 -0
  34. package/dist/catalogo.js +124 -0
  35. package/dist/ciclos.js +156 -0
  36. package/dist/claims.js +226 -0
  37. package/dist/divida.js +374 -0
  38. package/dist/doctor.js +246 -0
  39. package/dist/evalrunner.js +458 -0
  40. package/dist/fix.js +450 -0
  41. package/dist/gates.js +92 -0
  42. package/dist/handoff.js +521 -0
  43. package/dist/hosts.js +331 -0
  44. package/dist/index.js +1910 -0
  45. package/dist/init.js +231 -0
  46. package/dist/leases.js +508 -0
  47. package/dist/ledger.js +138 -0
  48. package/dist/manifest.js +255 -0
  49. package/dist/master.js +453 -0
  50. package/dist/memoria.js +773 -0
  51. package/dist/modos.js +220 -0
  52. package/dist/orkmind.js +487 -0
  53. package/dist/orquestracao.js +559 -0
  54. package/dist/phase.js +572 -0
  55. package/dist/policies.js +176 -0
  56. package/dist/prompts.js +406 -0
  57. package/dist/ratelimit.js +179 -0
  58. package/dist/recall.js +252 -0
  59. package/dist/retry.js +917 -0
  60. package/dist/sandbox.js +94 -0
  61. package/dist/sessoes.js +104 -0
  62. package/dist/ship.js +551 -0
  63. package/dist/slug.js +100 -0
  64. package/dist/superficie.js +1347 -0
  65. package/dist/thread.js +333 -0
  66. package/dist/tokens.js +228 -0
  67. package/dist/types.js +20 -0
  68. package/dist/util.js +156 -0
  69. package/dist/verify.js +262 -0
  70. package/dist/worktree.js +576 -0
  71. package/dist/yaml.js +112 -0
  72. package/eval/README.md +85 -0
  73. package/eval/casos/check-quality.json +103 -0
  74. package/eval/casos/code-reviewer.json +102 -0
  75. package/eval/casos/decision-triage.json +103 -0
  76. package/eval/casos/go-implementation.json +103 -0
  77. package/eval/casos/goal-definition.json +103 -0
  78. package/eval/casos/master-metrics.json +103 -0
  79. package/eval/casos/narrative-guardian.json +163 -0
  80. package/eval/casos/orkastery-bootstrap.json +102 -0
  81. package/eval/casos/plan-specification.json +102 -0
  82. package/eval/casos/roadmap-keeper.json +103 -0
  83. package/eval/casos/scope-check-capability-map.json +83 -0
  84. package/eval/casos/security-auditor.json +102 -0
  85. package/eval/casos/ship-release.json +122 -0
  86. package/eval/casos/test-engineer.json +122 -0
  87. package/eval/casos/thread-state.json +82 -0
  88. package/eval/casos/thread-tracing.json +83 -0
  89. package/eval/casos/web-performance-auditor.json +102 -0
  90. package/eval/fixtures/b0-slug-e-modos/caso.json +56 -0
  91. package/eval/fixtures/b2-master-log/caso.json +91 -0
  92. package/eval/fixtures/fx-concurrency/caso.json +15 -0
  93. package/eval/fixtures/fx-hallucination/caso.json +12 -0
  94. package/eval/fixtures/fx-happy/caso.json +16 -0
  95. package/eval/fixtures/fx-schema-drift/caso.json +15 -0
  96. package/eval/fixtures/fx-stale-base/caso.json +12 -0
  97. package/eval/fixtures/fx-wiki-destroy/caso.json +16 -0
  98. package/eval/fixtures/superficie-de-rede/README.md +22 -0
  99. package/eval/fixtures/superficie-de-rede/api-express.js +30 -0
  100. package/eval/fixtures/superficie-de-rede/api_fastapi.py +17 -0
  101. package/eval/fixtures/superficie-de-rede/api_gin.go +18 -0
  102. package/package.json +56 -0
  103. package/references/README.md +25 -0
  104. package/references/code-review-axes.md +82 -0
  105. package/references/definition-of-done.md +74 -0
  106. package/references/performance-checklist.md +53 -0
  107. package/references/security-checklist.md +101 -0
  108. package/references/testing-patterns.md +51 -0
  109. package/skills/README.md +43 -0
  110. package/skills/core/orkastery-bootstrap/SKILL.md +89 -0
  111. package/skills/core/thread-state/SKILL.md +86 -0
  112. package/skills/governance/decision-triage/SKILL.md +65 -0
  113. package/skills/governance/narrative-guardian/SKILL.md +66 -0
  114. package/skills/governance/roadmap-keeper/SKILL.md +60 -0
  115. package/skills/governance/scope-check-capability-map/SKILL.md +61 -0
  116. package/skills/observability/thread-tracing/SKILL.md +63 -0
  117. package/skills/phases/check-quality/SKILL.md +87 -0
  118. package/skills/phases/go-implementation/SKILL.md +70 -0
  119. package/skills/phases/goal-definition/SKILL.md +69 -0
  120. package/skills/phases/master-metrics/SKILL.md +65 -0
  121. package/skills/phases/plan-specification/SKILL.md +67 -0
  122. package/skills/phases/ship-release/SKILL.md +68 -0
  123. package/skills/reviewers/code-reviewer/SKILL.md +61 -0
  124. package/skills/reviewers/security-auditor/SKILL.md +68 -0
  125. package/skills/reviewers/test-engineer/SKILL.md +66 -0
  126. package/skills/reviewers/web-performance-auditor/SKILL.md +63 -0
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ /**
3
+ * Fila DURAVEL de rate limit (bloco B3).
4
+ *
5
+ * Quando o runtime da assinatura bate o limite de uso, a fase morre no meio. Ate aqui
6
+ * isso virava um `runtime.unavailable` seco e alguem tinha que lembrar de redespachar
7
+ * na mao, na janela seguinte, com o prompt certo. O B3 troca a lembranca por estado em
8
+ * disco: o sinal de rate limit vira um PEDIDO na fila, com o horario de reset que o
9
+ * proprio runtime disse, o caminho do prompt EXATO e o sha256 dele.
10
+ *
11
+ * Duas honestidades que mandam neste arquivo:
12
+ *
13
+ * 1. **Horario nunca e chutado.** Quando o stderr traz a hora (epoch, ISO, relogio ou
14
+ * duracao), ela e o `liberaEm`. Quando nao traz, o `liberaEm` sai da janela padrao
15
+ * do manifesto e o pedido carrega `janelaEstimada: true`. Estimativa declarada e
16
+ * diferente de medida inventada, a mesma regra do gate de tokens.
17
+ * 2. **O prompt nao muda entre a morte e a retomada.** A retomada confere o sha256 do
18
+ * arquivo antes de despachar. Prompt alterado nao e retomada, e outro despacho.
19
+ *
20
+ * Este modulo e FOLHA de proposito: ele guarda e le a fila. Quem redespacha e o
21
+ * `retry.ts`, que e quem pode importar o `phase.ts` sem criar ciclo.
22
+ */
23
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ var desc = Object.getOwnPropertyDescriptor(m, k);
26
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
27
+ desc = { enumerable: true, get: function() { return m[k]; } };
28
+ }
29
+ Object.defineProperty(o, k2, desc);
30
+ }) : (function(o, m, k, k2) {
31
+ if (k2 === undefined) k2 = k;
32
+ o[k2] = m[k];
33
+ }));
34
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
35
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
36
+ }) : function(o, v) {
37
+ o["default"] = v;
38
+ });
39
+ var __importStar = (this && this.__importStar) || (function () {
40
+ var ownKeys = function(o) {
41
+ ownKeys = Object.getOwnPropertyNames || function (o) {
42
+ var ar = [];
43
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
44
+ return ar;
45
+ };
46
+ return ownKeys(o);
47
+ };
48
+ return function (mod) {
49
+ if (mod && mod.__esModule) return mod;
50
+ var result = {};
51
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
52
+ __setModuleDefault(result, mod);
53
+ return result;
54
+ };
55
+ })();
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ exports.parseRateLimit = void 0;
58
+ exports.dirRetry = dirRetry;
59
+ exports.caminhoDaFila = caminhoDaFila;
60
+ exports.lerFilaDeRetomada = lerFilaDeRetomada;
61
+ exports.janelaPadraoMs = janelaPadraoMs;
62
+ exports.enfileirar = enfileirar;
63
+ exports.gravarPedido = gravarPedido;
64
+ exports.exigirPedido = exigirPedido;
65
+ exports.aguardando = aguardando;
66
+ exports.vencidos = vencidos;
67
+ exports.faltaPara = faltaPara;
68
+ exports.tabelaDaFila = tabelaDaFila;
69
+ const path = __importStar(require("node:path"));
70
+ const manifest_1 = require("./manifest");
71
+ const util_1 = require("./util");
72
+ var claude_bg_1 = require("./adapters/claude-bg");
73
+ Object.defineProperty(exports, "parseRateLimit", { enumerable: true, get: function () { return claude_bg_1.parseRateLimit; } });
74
+ /** Diretorio de estado da autonomia do B3. */
75
+ function dirRetry(raiz) {
76
+ return path.join((0, manifest_1.dirEstado)(raiz), 'retry');
77
+ }
78
+ /**
79
+ * Fila duravel do projeto.
80
+ *
81
+ * Fica no projeto, e nao na thread, porque o limite de uso e da ASSINATURA: uma fase de
82
+ * outra thread que morre no mesmo minuto espera a mesma janela, e quem olha a fila
83
+ * precisa ver as duas de uma vez.
84
+ */
85
+ function caminhoDaFila(raiz) {
86
+ return path.join(dirRetry(raiz), 'fila.jsonl');
87
+ }
88
+ /** Le a fila inteira (JSONL append-only: a ultima gravacao de um id vence). */
89
+ function lerFilaDeRetomada(raiz) {
90
+ return (0, util_1.lerJsonl)(caminhoDaFila(raiz));
91
+ }
92
+ /** Janela padrao do manifesto, em ms, usada so quando o runtime nao disse a hora. */
93
+ function janelaPadraoMs(manifesto) {
94
+ return manifesto.retry.janela_padrao_min * 60 * 1000;
95
+ }
96
+ /**
97
+ * Enfileira a fase morta por rate limit.
98
+ *
99
+ * `liberaEm` sai do horario que o runtime disse; sem horario, da janela padrao, e ai o
100
+ * pedido nasce com `janelaEstimada: true` para o `ork retry list` mostrar a diferenca.
101
+ */
102
+ function enfileirar(carregado, novo, agoraMs = Date.now()) {
103
+ const { raiz, manifesto } = carregado;
104
+ const ids = lerFilaDeRetomada(raiz).map((p) => p.id);
105
+ const estimada = novo.sinal.resetEm === null;
106
+ const pedido = {
107
+ id: (0, util_1.proximoIdSequencial)(ids, 'R'),
108
+ thread: novo.thread,
109
+ fase: novo.fase,
110
+ slug: novo.slug,
111
+ promptPath: path.isAbsolute(novo.promptPath)
112
+ ? path.relative(raiz, novo.promptPath)
113
+ : novo.promptPath,
114
+ promptSha256: novo.promptSha256,
115
+ cwd: novo.cwd,
116
+ model: novo.model,
117
+ effort: novo.effort,
118
+ sinal: novo.sinal,
119
+ liberaEm: novo.sinal.resetEm ?? new Date(agoraMs + janelaPadraoMs(manifesto)).toISOString(),
120
+ janelaEstimada: estimada,
121
+ tentativas: 0,
122
+ estado: 'aguardando',
123
+ criadoEm: (0, util_1.agora)(),
124
+ atualizadoEm: (0, util_1.agora)(),
125
+ detalhe: novo.detalhe,
126
+ };
127
+ (0, util_1.anexarJsonl)(caminhoDaFila(raiz), pedido);
128
+ return pedido;
129
+ }
130
+ /** Regrava um pedido (append-only: a versao nova vence, o historico fica). */
131
+ function gravarPedido(raiz, pedido) {
132
+ const atualizado = { ...pedido, atualizadoEm: (0, util_1.agora)() };
133
+ (0, util_1.anexarJsonl)(caminhoDaFila(raiz), atualizado);
134
+ return atualizado;
135
+ }
136
+ /** Um pedido pelo id, ou erro acionavel quando o id nao existe. */
137
+ function exigirPedido(raiz, id) {
138
+ const achado = lerFilaDeRetomada(raiz).find((p) => p.id === id);
139
+ if (!achado) {
140
+ throw new Error(`pedido "${id}" nao existe na fila de rate limit (veja: ork retry list)`);
141
+ }
142
+ return achado;
143
+ }
144
+ /** Pedidos ainda aguardando, na ordem em que a janela libera. */
145
+ function aguardando(raiz) {
146
+ return lerFilaDeRetomada(raiz)
147
+ .filter((p) => p.estado === 'aguardando')
148
+ .sort((a, b) => a.liberaEm.localeCompare(b.liberaEm));
149
+ }
150
+ /** Pedidos cuja janela JA liberou no instante informado (padrao: agora). */
151
+ function vencidos(raiz, quando = (0, util_1.agora)()) {
152
+ return aguardando(raiz).filter((p) => p.liberaEm <= quando);
153
+ }
154
+ /** Quanto falta para a janela de um pedido, em texto curto para o CLI. */
155
+ function faltaPara(pedido, quando = (0, util_1.agora)()) {
156
+ const ms = new Date(pedido.liberaEm).getTime() - new Date(quando).getTime();
157
+ if (ms <= 0)
158
+ return 'ja liberou';
159
+ const min = Math.ceil(ms / 60000);
160
+ return min < 60 ? `em ${min} min` : `em ${Math.floor(min / 60)}h${String(min % 60).padStart(2, '0')}`;
161
+ }
162
+ /** Tabela de `ork retry list`. */
163
+ function tabelaDaFila(raiz, quando = (0, util_1.agora)()) {
164
+ const fila = lerFilaDeRetomada(raiz).sort((a, b) => a.id.localeCompare(b.id, 'en', { numeric: true }));
165
+ if (fila.length === 0) {
166
+ return 'Fila de rate limit vazia: nenhuma fase morreu por limite de uso neste projeto.';
167
+ }
168
+ const linhas = fila.map((p) => [
169
+ p.id,
170
+ p.thread,
171
+ p.fase,
172
+ p.estado,
173
+ p.liberaEm.replace('T', ' ').slice(0, 16),
174
+ p.janelaEstimada ? `estimada (${p.sinal.fonte})` : `dita pelo runtime (${p.sinal.fonte})`,
175
+ p.estado === 'aguardando' ? faltaPara(p, quando) : '',
176
+ String(p.tentativas),
177
+ ]);
178
+ return (0, util_1.tabela)(['ID', 'THREAD', 'FASE', 'ESTADO', 'LIBERA EM', 'ORIGEM DA HORA', 'FALTA', 'TENT'], linhas);
179
+ }
package/dist/recall.js ADDED
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+ /**
3
+ * `ork recall` (bloco B6): recuperacao TARDIA do que ficou fora do prompt.
4
+ *
5
+ * O problema que este comando resolve e o da janela queimada na abertura: uma sessao nova
6
+ * que recebe tudo o que a anterior sabia comeca cheia e sem espaco para trabalhar. O
7
+ * handoff do B1 ja separava CRITICO (inline) de IMPORTANTE (ponteiro); o que faltava era
8
+ * o outro lado da promessa, o momento de puxar o ponteiro.
9
+ *
10
+ * A regra e o campo `retrieve_when` do ponteiro:
11
+ *
12
+ * - `ork recall <thread> --fase CHECK` resolve SO os ponteiros marcados para o CHECK;
13
+ * - um ponteiro de CHECK pedido no GO volta como `fora-do-momento`, SEM conteudo: nao
14
+ * adianta ter momento declarado se o comando entrega o texto de qualquer jeito;
15
+ * - `--forcar` existe para o humano, e diz no resultado que o momento foi ignorado.
16
+ *
17
+ * A degradacao e a mesma do resto do bloco. Com OrkMind ligado, um ponteiro que tem
18
+ * endereco semantico (`orkmind://<colecao>/<id>`) resolve por tag. Com o OrkMind fora, o
19
+ * MESMO ponteiro resolve pelo `location` (`path#ancora`), por leitura dirigida, sem que o
20
+ * fluxo de quem le o handoff mude em nada.
21
+ */
22
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ var desc = Object.getOwnPropertyDescriptor(m, k);
25
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
26
+ desc = { enumerable: true, get: function() { return m[k]; } };
27
+ }
28
+ Object.defineProperty(o, k2, desc);
29
+ }) : (function(o, m, k, k2) {
30
+ if (k2 === undefined) k2 = k;
31
+ o[k2] = m[k];
32
+ }));
33
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
34
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
35
+ }) : function(o, v) {
36
+ o["default"] = v;
37
+ });
38
+ var __importStar = (this && this.__importStar) || (function () {
39
+ var ownKeys = function(o) {
40
+ ownKeys = Object.getOwnPropertyNames || function (o) {
41
+ var ar = [];
42
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
43
+ return ar;
44
+ };
45
+ return ownKeys(o);
46
+ };
47
+ return function (mod) {
48
+ if (mod && mod.__esModule) return mod;
49
+ var result = {};
50
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
51
+ __setModuleDefault(result, mod);
52
+ return result;
53
+ };
54
+ })();
55
+ Object.defineProperty(exports, "__esModule", { value: true });
56
+ exports.momentoCasa = momentoCasa;
57
+ exports.lerHandoff = lerHandoff;
58
+ exports.resolverPonteiro = resolverPonteiro;
59
+ exports.recallDaThread = recallDaThread;
60
+ exports.textoDoRecall = textoDoRecall;
61
+ const fs = __importStar(require("node:fs"));
62
+ const handoff_1 = require("./handoff");
63
+ const ledger_1 = require("./ledger");
64
+ const orkmind_1 = require("./orkmind");
65
+ const thread_1 = require("./thread");
66
+ const util_1 = require("./util");
67
+ /** Momento do ponteiro e momento pedido casam? Comparacao exata, sem case. */
68
+ function momentoCasa(ponteiro, momento) {
69
+ return ponteiro.retrieve_when.trim().toLowerCase() === momento.trim().toLowerCase();
70
+ }
71
+ /** Le o handoff mais recente da thread, com erro acionavel quando ele nao existe. */
72
+ function lerHandoff(raiz, threadId) {
73
+ const caminho = (0, handoff_1.caminhoHandoff)(raiz, threadId);
74
+ if (!fs.existsSync(caminho)) {
75
+ throw new Error(`a thread ${threadId} nao tem handoff exportado (${caminho}). Rode: ork handoff export ${threadId}`);
76
+ }
77
+ return (0, util_1.lerJson)(caminho);
78
+ }
79
+ function naoResolvido(p, motivo, detalhe) {
80
+ return {
81
+ id: p.id,
82
+ titulo: p.titulo,
83
+ location: p.location,
84
+ orkmind: p.orkmind ?? null,
85
+ retrieve_when: p.retrieve_when,
86
+ resolvido: false,
87
+ motivo,
88
+ via: null,
89
+ conteudo: '',
90
+ metodo: '',
91
+ sha256: p.sha256,
92
+ intervalo: null,
93
+ detalhe,
94
+ };
95
+ }
96
+ /**
97
+ * Resolve UM ponteiro, escolhendo a via pelo regime efetivo.
98
+ *
99
+ * Preferencia pela memoria semantica quando ela existe e o ponteiro tem endereco; queda
100
+ * para o arquivo quando ela nao existe, quando o endereco nao resolve ou quando o
101
+ * ponteiro nunca teve endereco (todo handoff do regime `files`).
102
+ */
103
+ function resolverPonteiro(carregado, memoria, threadId, p) {
104
+ if (memoria.ativo && p.orkmind) {
105
+ const endereco = (0, orkmind_1.lerEndereco)(p.orkmind);
106
+ const entrada = endereco ? memoria.porId(endereco.colecao, endereco.id) : null;
107
+ if (entrada) {
108
+ return {
109
+ id: p.id,
110
+ titulo: p.titulo,
111
+ location: p.location,
112
+ orkmind: p.orkmind,
113
+ retrieve_when: p.retrieve_when,
114
+ resolvido: true,
115
+ motivo: 'ok',
116
+ via: 'orkmind',
117
+ conteudo: entrada.content,
118
+ metodo: `entrada ${entrada.collection} recuperada por tag na memoria semantica`,
119
+ sha256: p.sha256,
120
+ intervalo: null,
121
+ detalhe: `orkmind://${entrada.collection}/${entrada.id}`,
122
+ };
123
+ }
124
+ }
125
+ try {
126
+ const r = (0, handoff_1.recall)(carregado, threadId, p.location);
127
+ return {
128
+ id: p.id,
129
+ titulo: p.titulo,
130
+ location: p.location,
131
+ orkmind: p.orkmind ?? null,
132
+ retrieve_when: p.retrieve_when,
133
+ resolvido: true,
134
+ motivo: 'ok',
135
+ via: 'files',
136
+ conteudo: r.conteudo,
137
+ metodo: r.metodo,
138
+ sha256: r.sha256,
139
+ intervalo: r.intervalo,
140
+ detalhe: memoria.ativo && p.orkmind
141
+ ? 'endereco semantico nao resolveu; o mesmo ponteiro caiu para path#ancora'
142
+ : 'leitura dirigida por path#ancora (regime files)',
143
+ };
144
+ }
145
+ catch (e) {
146
+ const semantico = memoria.estado.efetivo === 'files' && p.orkmind;
147
+ return naoResolvido(p, semantico ? 'orkmind-indisponivel' : 'nao-resolve', e.message);
148
+ }
149
+ }
150
+ /**
151
+ * `ork recall`: resolve os ponteiros do handoff que sao DESTE momento.
152
+ *
153
+ * O que nao e deste momento volta em `adiados`, com o momento declarado: a sessao sabe
154
+ * que existe, sabe onde esta e sabe quando puxar, sem gastar janela agora. E o item 4 da
155
+ * secao 6.1 da visao (rastreabilidade): nada some, nada entra sem hora marcada.
156
+ */
157
+ function recallDaThread(carregado, memoria, threadId, opcoes = {}) {
158
+ const { raiz } = carregado;
159
+ // Thread inexistente e erro, nao lista vazia: o CLI precisa reprovar o id errado.
160
+ (0, thread_1.lerThread)(raiz, threadId);
161
+ const handoff = lerHandoff(raiz, threadId);
162
+ const momento = opcoes.momento ?? null;
163
+ const resolvidos = [];
164
+ const adiados = [];
165
+ const falhas = [];
166
+ for (const p of handoff.pointers) {
167
+ const pedidoPorId = opcoes.id !== undefined && (p.id === opcoes.id || p.location === opcoes.id);
168
+ if (opcoes.id !== undefined && !pedidoPorId)
169
+ continue;
170
+ const naHora = opcoes.forcar === true ||
171
+ opcoes.todos === true ||
172
+ pedidoPorId ||
173
+ (momento !== null && momentoCasa(p, momento));
174
+ if (!naHora) {
175
+ adiados.push(naoResolvido(p, 'fora-do-momento', momento === null
176
+ ? `sem momento pedido: este ponteiro e do momento "${p.retrieve_when}"`
177
+ : `este ponteiro e do momento "${p.retrieve_when}", e o pedido foi "${momento}"`));
178
+ continue;
179
+ }
180
+ const r = resolverPonteiro(carregado, memoria, threadId, p);
181
+ if (r.resolvido)
182
+ resolvidos.push(r);
183
+ else
184
+ falhas.push(r);
185
+ }
186
+ if (opcoes.id !== undefined && resolvidos.length === 0 && falhas.length === 0 && adiados.length === 0) {
187
+ throw new Error(`ponteiro "${opcoes.id}" nao existe no handoff da thread ${threadId} ` +
188
+ `(ids: ${handoff.pointers.map((p) => p.id).join(', ') || 'nenhum'})`);
189
+ }
190
+ const resultado = {
191
+ thread: threadId,
192
+ momento,
193
+ regime: memoria.regime,
194
+ regimeDoHandoff: handoff.memory,
195
+ resolvidos,
196
+ adiados,
197
+ falhas,
198
+ resolvidoEm: (0, util_1.agora)(),
199
+ };
200
+ (0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, threadId), threadId, ledger_1.TIPOS_DE_EVENTO.recallResolvido, {
201
+ momento: momento ?? '(todos)',
202
+ regime: memoria.regime,
203
+ regimeDoHandoff: handoff.memory,
204
+ resolvidos: resolvidos.length,
205
+ adiados: adiados.length,
206
+ falhas: falhas.length,
207
+ forcado: opcoes.forcar === true,
208
+ vias: resolvidos.map((r) => `${r.id}:${r.via}`),
209
+ bytes: resolvidos.reduce((t, r) => t + Buffer.byteLength(r.conteudo, 'utf8'), 0),
210
+ });
211
+ return resultado;
212
+ }
213
+ /** Texto de `ork recall`. */
214
+ function textoDoRecall(r, comConteudo = true) {
215
+ const linhas = [];
216
+ linhas.push(`Recall da thread ${r.thread} no momento ${r.momento ?? '(todos)'} ` +
217
+ `(regime efetivo ${r.regime}, handoff escrito em regime ${r.regimeDoHandoff})`);
218
+ linhas.push('');
219
+ linhas.push(`RESOLVIDOS (${r.resolvidos.length}, entram no contexto agora):`);
220
+ for (const p of r.resolvidos) {
221
+ linhas.push(` ${p.id} ${p.titulo}`);
222
+ linhas.push(` via ${p.via} (${p.metodo})`);
223
+ linhas.push(` location ${p.location}`);
224
+ if (p.orkmind)
225
+ linhas.push(` orkmind ${p.orkmind}`);
226
+ linhas.push(` quando ${p.retrieve_when}`);
227
+ if (comConteudo) {
228
+ linhas.push('');
229
+ for (const l of p.conteudo.split('\n'))
230
+ linhas.push(` | ${l}`);
231
+ linhas.push('');
232
+ }
233
+ }
234
+ linhas.push('');
235
+ linhas.push(`ADIADOS (${r.adiados.length}, existem e NAO entram agora):`);
236
+ for (const p of r.adiados) {
237
+ linhas.push(` ${p.id} ${p.titulo}`);
238
+ linhas.push(` quando ${p.retrieve_when}`);
239
+ linhas.push(` onde ${p.location}`);
240
+ linhas.push(` recuperar ork recall ${r.thread} --fase ${p.retrieve_when}`);
241
+ }
242
+ if (r.falhas.length > 0) {
243
+ linhas.push('');
244
+ linhas.push(`FALHAS (${r.falhas.length}):`);
245
+ for (const p of r.falhas) {
246
+ linhas.push(` ${p.id} ${p.titulo}`);
247
+ linhas.push(` motivo ${p.motivo}`);
248
+ linhas.push(` detalhe ${p.detalhe}`);
249
+ }
250
+ }
251
+ return linhas.join('\n');
252
+ }