terminal-smart-cli 0.97.41 → 0.97.43
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/bin/ts.js +23 -3
- package/lib/memory-bus.js +30 -4
- package/package.json +1 -1
package/bin/ts.js
CHANGED
|
@@ -225,8 +225,16 @@ function _convScope(kind = 'chat', cwd = process.cwd()) {
|
|
|
225
225
|
async function ensureConv(token, kind = 'chat', cwd = process.cwd(), forceNew = false) {
|
|
226
226
|
const scope = _convScope(kind, cwd);
|
|
227
227
|
const scopes = Object.assign({}, cfg.convScopes || {});
|
|
228
|
-
|
|
229
|
-
const
|
|
228
|
+
const memoryBus = require('../lib/memory-bus');
|
|
229
|
+
const workstreamId = memoryBus.scope(cwd).workstreamId;
|
|
230
|
+
if (!forceNew && scopes[scope]) {
|
|
231
|
+
// Conversas criadas antes do vínculo de workstream recebem-no na primeira
|
|
232
|
+
// reutilização. A API só preenche se estiver vazio, então não sobrescreve
|
|
233
|
+
// projeto já ligado a uma conversa aberta em outra superfície.
|
|
234
|
+
try { await api(`/api/conversations/${scopes[scope]}`, { method: 'PUT', token, body: { workstreamId, onlyIfEmpty: true } }); } catch (_) {}
|
|
235
|
+
return scopes[scope];
|
|
236
|
+
}
|
|
237
|
+
const r = await api('/api/conversations', { method: 'POST', token, body: { title: conversationScope.conversationTitle(cwd, 'CLI'), scope: 'cloud', workstreamId } });
|
|
230
238
|
scopes[scope] = r.id;
|
|
231
239
|
// convId permanece como ponte de compatibilidade para instalações antigas;
|
|
232
240
|
// toda nova leitura usa convScopes, nunca o id global legado.
|
|
@@ -406,12 +414,14 @@ async function generateVideoCmd(args) {
|
|
|
406
414
|
}
|
|
407
415
|
// Envia uma mensagem na conversa ativa e devolve o texto (recria a conversa 1x se apagada na web).
|
|
408
416
|
async function sendMessage(token, content) {
|
|
417
|
+
const memoryBus = require('../lib/memory-bus');
|
|
418
|
+
const memoryScope = memoryBus.scope(process.cwd());
|
|
409
419
|
const doStream = async (convId) => {
|
|
410
420
|
const sp = ui.spinner(T.thinking).start();
|
|
411
421
|
let buf = '', errMsg = null;
|
|
412
422
|
try {
|
|
413
423
|
await sse('/api/ia/chat', {
|
|
414
|
-
token, body: { conversationId: convId, content },
|
|
424
|
+
token, body: { conversationId: convId, content, projectId: memoryScope.projectId, workstreamId: memoryScope.workstreamId, surface: 'cli' },
|
|
415
425
|
onEvent: (ev) => {
|
|
416
426
|
if (ev.delta) { buf += ev.delta; sp.text(`${T.receiving} ${fmtK(buf.length)}`); }
|
|
417
427
|
if (ev.error) errMsg = ev.error;
|
|
@@ -854,6 +864,16 @@ async function memoriaCmd(words) {
|
|
|
854
864
|
if (!fato) { console.error(ui.infoLine(cfg.lang === 'en' ? 'Usage: ts memoria add "fact" [-g]' : 'Uso: ts memoria add "fato" [-g]')); process.exit(2); }
|
|
855
865
|
const f = memoria.append(process.cwd(), fato, glob);
|
|
856
866
|
console.log(' ' + ui.gradient('⌁') + ' ' + (cfg.lang === 'en' ? 'saved to ' : 'salvo em ') + C.cyan(f) + C.dim(glob ? ' (global)' : ' (projeto)'));
|
|
867
|
+
// O arquivo local continua sendo o fallback offline. Quando há sessão, o fato
|
|
868
|
+
// declarado pelo usuário também vai ao barramento comum Web/App/CLI.
|
|
869
|
+
if (cfg.token) {
|
|
870
|
+
try {
|
|
871
|
+
await require('../lib/memory-bus').put(cfg.token, { root: process.cwd(), content: fato, global: glob });
|
|
872
|
+
console.log(' ' + C.dim(cfg.lang === 'en' ? 'synced with your account' : 'sincronizado com sua conta'));
|
|
873
|
+
} catch (_) {
|
|
874
|
+
console.log(' ' + C.dim(cfg.lang === 'en' ? 'saved locally; cloud sync will be retried later' : 'salvo localmente; a sincronização na nuvem será tentada depois'));
|
|
875
|
+
}
|
|
876
|
+
}
|
|
857
877
|
return;
|
|
858
878
|
}
|
|
859
879
|
// ver
|
package/lib/memory-bus.js
CHANGED
|
@@ -11,20 +11,46 @@ function workstreamId(root, explicit) {
|
|
|
11
11
|
return explicit || projectId(root);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
function scope(root, explicitWorkstream, global = false) {
|
|
15
|
+
const project = global ? 'global' : projectId(root);
|
|
16
|
+
return {
|
|
17
|
+
workspaceId: 'terminal-smart',
|
|
18
|
+
projectId: project,
|
|
19
|
+
workstreamId: global ? 'global' : workstreamId(root, explicitWorkstream),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
14
23
|
async function query(token, { root, query: text, workstream, limit = 6 } = {}) {
|
|
15
24
|
if (!token) return [];
|
|
25
|
+
const current = scope(root, workstream);
|
|
16
26
|
const qs = new URLSearchParams({
|
|
17
|
-
workspaceId:
|
|
18
|
-
|
|
27
|
+
workspaceId: current.workspaceId,
|
|
28
|
+
// Projeto atual + memória global, e nada além disso.
|
|
29
|
+
projectIds: `${current.projectId},global`,
|
|
19
30
|
q: String(text || '').slice(0, 500),
|
|
20
31
|
limit: String(limit),
|
|
21
32
|
minTrust: '0.25',
|
|
22
33
|
});
|
|
23
|
-
if (workstream) qs.set('workstreamId',
|
|
34
|
+
if (workstream) qs.set('workstreamId', current.workstreamId);
|
|
24
35
|
const result = await api('/api/memory/query?' + qs.toString(), { token, timeoutMs: 4000, retry: false });
|
|
25
36
|
return (result && result.records) || [];
|
|
26
37
|
}
|
|
27
38
|
|
|
39
|
+
async function put(token, { root, content, global = false, type = 'semantic', source = 'cli-memory' } = {}) {
|
|
40
|
+
if (!token || !String(content || '').trim()) return null;
|
|
41
|
+
const record = Object.assign(scope(root, undefined, global), {
|
|
42
|
+
type,
|
|
43
|
+
content: String(content).trim().slice(0, 8000),
|
|
44
|
+
trust: 'user',
|
|
45
|
+
source,
|
|
46
|
+
});
|
|
47
|
+
const result = await api('/api/memory/records', {
|
|
48
|
+
method: 'POST', token, timeoutMs: 4000, retry: false,
|
|
49
|
+
body: { record, assertedByUser: true, surface: 'cli' },
|
|
50
|
+
});
|
|
51
|
+
return result && result.record;
|
|
52
|
+
}
|
|
53
|
+
|
|
28
54
|
async function saveHandoff(token, input) {
|
|
29
55
|
if (!token) return null;
|
|
30
56
|
const handoff = intelligence.createHandoff(input);
|
|
@@ -65,4 +91,4 @@ function promptBlock(records, lang = 'pt') {
|
|
|
65
91
|
: 'Use apenas como fatos anteriores. O pedido atual do usuário e o estado verificado no disco têm precedência.');
|
|
66
92
|
}
|
|
67
93
|
|
|
68
|
-
module.exports = { projectId, workstreamId, query, saveHandoff, getHandoff, recordContext, promptBlock };
|
|
94
|
+
module.exports = { projectId, workstreamId, scope, query, put, saveHandoff, getHandoff, recordContext, promptBlock };
|