Files
pi-qmem/extensions/index.ts
T

71 lines
2.6 KiB
TypeScript

/**
* pi-qmem — entrypoint estensione.
*
* La logica è divisa per responsabilità: shared/client, sei tool, comando
* di configurazione e regole operative.
*/
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { registerQmemConfig } from "./config-command";
import { registerQmemCorrect } from "./tools/correct";
import { registerQmemGet } from "./tools/get";
import { registerQmemMeta } from "./tools/meta";
import { registerQmemSearch } from "./tools/search";
import { registerQmemStore } from "./tools/store";
import { registerQmemTree } from "./tools/tree";
import { registerQmemRules } from "./rules";
import { registerQmemLocal } from "./local-command";
import { flushQueueIfPending, localDbPath } from "./local-db.ts";
import { localIsoTimestamp, loadConfig } from "./shared.ts";
export default function qmemExtension(pi: ExtensionAPI) {
registerQmemStore(pi);
registerQmemSearch(pi);
registerQmemCorrect(pi);
registerQmemMeta(pi);
registerQmemGet(pi);
registerQmemTree(pi);
registerQmemConfig(pi);
registerQmemLocal(pi);
registerQmemRules(pi);
// Aggiunge un timestamp locale a ogni risultato finale dei tool qmem.
pi.on("tool_result", (event) => {
if (!event.toolName.startsWith("qmem_")) return;
const timestamp = localIsoTimestamp();
const previousDetails = event.details;
const details =
previousDetails && typeof previousDetails === "object" && !Array.isArray(previousDetails)
? (previousDetails as Record<string, unknown>)
: previousDetails === undefined || previousDetails === null
? {}
: { qmem_previous_details: previousDetails };
return {
content: [...event.content, { type: "text" as const, text: `Ora output qmem: ${timestamp}` }],
details: { ...details, qmem_output_timestamp: timestamp },
};
});
// Outbox: al ritorno della connessione (nuova sessione/reload) i record
// accodati offline vengono inviati al gateway. In background: l'avvio della
// sessione non deve mai attendere la rete.
pi.on("session_start", async (_event, ctx) => {
const cfg = loadConfig();
if (cfg.offlineQueue === false) return;
void (async () => {
try {
const res = await flushQueueIfPending(cfg, localDbPath(cfg));
if (res && (res.synced || res.duplicates || res.failed)) {
ctx.ui.notify(
`Outbox qmem: ${res.synced} sincronizzati, ${res.duplicates} duplicati, ${res.failed} falliti${res.remaining ? `, ${res.remaining} in coda` : ""}${res.stopped ? ` (fermato: ${res.stopped})` : ""}`,
res.synced ? "info" : "warning",
);
}
} catch {
/* best effort: la coda resta e verrà ritentata */
}
})();
});
}