plasalid 0.7.7 → 0.7.9
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/README.md
CHANGED
|
@@ -19,7 +19,7 @@ In US and Europe, the most of financial apps are likely powered by aggregators e
|
|
|
19
19
|
|
|
20
20
|
Your data is locked in bank silos. Tracking your net worth means logging into half a dozen apps and crunching the numbers manually. This fragmentation creates massive blind spots. Subscriptions are forgotten, strange charges go unnoticed, and planning for big financial goals becomes a guessing game.
|
|
21
21
|
|
|
22
|
-
**Plasalid is built to fix this
|
|
22
|
+
**Plasalid is built to fix this. Think of it as a personal financial AI harness**.
|
|
23
23
|
|
|
24
24
|
You drop your raw financial documents (bank statements, credit card bills, payslips) straight into a folder on your machine. Plasalid parses those files and extracts every transaction, balance, and holding. It transforms a messy pile of PDFs into a clean, double-entry ledger. You only have to build this foundation once. The result is an open, structured backend for your finances, ready to plug into any tool you want.
|
|
25
25
|
|
package/dist/ai/thinking.js
CHANGED
|
@@ -28,7 +28,7 @@ const THINKING_PHRASES = [
|
|
|
28
28
|
"Doing math, the slow kind...",
|
|
29
29
|
"Computing... probably correctly...",
|
|
30
30
|
"Pondering quietly...",
|
|
31
|
-
"
|
|
31
|
+
"Connecting the dots...",
|
|
32
32
|
"Making sense of it...",
|
|
33
33
|
"Sharpening the pencil...",
|
|
34
34
|
"Catching up on the details...",
|
|
@@ -18,7 +18,7 @@ export async function runClarifyCommand() {
|
|
|
18
18
|
promptUser,
|
|
19
19
|
onProgress,
|
|
20
20
|
});
|
|
21
|
-
spinner.succeed("
|
|
21
|
+
spinner.succeed("Done.");
|
|
22
22
|
console.log("");
|
|
23
23
|
console.log(formatSummary(summary));
|
|
24
24
|
}
|
|
@@ -31,12 +31,7 @@ function formatSummary(summary) {
|
|
|
31
31
|
if (summary.total === 0) {
|
|
32
32
|
return chalk.dim("No questions.");
|
|
33
33
|
}
|
|
34
|
-
const
|
|
35
|
-
.map(([k, v]) => `${k}×${v}`)
|
|
36
|
-
.join(", ");
|
|
37
|
-
const lines = [
|
|
38
|
-
chalk.bold(`Clarified ${summary.clarified}/${summary.total} questions${tally ? ` (${tally})` : ""}.`),
|
|
39
|
-
];
|
|
34
|
+
const lines = [chalk.bold(`Clarified ${summary.clarified}/${summary.total} questions.`)];
|
|
40
35
|
if (summary.remaining > 0) {
|
|
41
36
|
lines.push(chalk.yellow(`${summary.remaining} question(s) remain.`));
|
|
42
37
|
}
|
|
@@ -43,7 +43,7 @@ export function ScanDashboard(props) {
|
|
|
43
43
|
}
|
|
44
44
|
function usePhase(controller) {
|
|
45
45
|
const [phase, setPhase] = useState("parse");
|
|
46
|
-
useEffect(() => controller.subscribe(event => {
|
|
46
|
+
useEffect(() => controller.subscribe((event) => {
|
|
47
47
|
if (event.type === "phase-set")
|
|
48
48
|
setPhase(event.phase);
|
|
49
49
|
}), [controller]);
|
|
@@ -57,13 +57,15 @@ function useRuleWidth() {
|
|
|
57
57
|
return;
|
|
58
58
|
const onResize = () => setCols(stdout.columns ?? 100);
|
|
59
59
|
stdout.on("resize", onResize);
|
|
60
|
-
return () => {
|
|
60
|
+
return () => {
|
|
61
|
+
stdout.off("resize", onResize);
|
|
62
|
+
};
|
|
61
63
|
}, [stdout]);
|
|
62
64
|
return Math.min(cols, 120);
|
|
63
65
|
}
|
|
64
66
|
const PHASE_RENDER = {
|
|
65
67
|
pending: (label) => _jsx(Text, { dimColor: true, children: label }),
|
|
66
|
-
running: (label) => _jsxs(Text, { color: "yellow", children: [_jsx(Spinner, { type: "dots" }), " ", label] }),
|
|
68
|
+
running: (label) => (_jsxs(Text, { color: "yellow", children: [_jsx(Spinner, { type: "dots" }), " ", label] })),
|
|
67
69
|
done: (label) => _jsxs(Text, { color: "green", children: ["\u2713 ", label] }),
|
|
68
70
|
};
|
|
69
71
|
const PHASE_ORDER = ["parse", "clarify", "done"];
|
|
@@ -117,10 +119,10 @@ function FileGroupView({ group }) {
|
|
|
117
119
|
const chunks = Array.from(group.chunks.values()).sort((a, b) => a.pageNumber - b.pageNumber);
|
|
118
120
|
const agg = aggregate(chunks, group.totalChunks);
|
|
119
121
|
const fileName = `> ${truncateMiddle(group.fileName, COL.files - 2)}`;
|
|
120
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Row, { status: _jsx(StatusText, { status: agg.status }), files: _jsx(Text, { dimColor: true, children: fileName }), transactions: agg.totalTx, questions: agg.totalQuestions }), chunks.map((c
|
|
122
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Row, { status: _jsx(StatusText, { status: agg.status }), files: _jsx(Text, { dimColor: true, children: fileName }), transactions: agg.totalTx, questions: agg.totalQuestions }), chunks.map((c) => (_jsx(ChunkRow, { chunk: c }, c.pageNumber)))] }));
|
|
121
123
|
}
|
|
122
|
-
function ChunkRow({ chunk
|
|
123
|
-
const connector =
|
|
124
|
+
function ChunkRow({ chunk }) {
|
|
125
|
+
const connector = "|-";
|
|
124
126
|
return (_jsx(Row, { status: _jsx(StatusText, { status: chunk.status }), files: _jsx(Text, { dimColor: true, children: ` ${connector} part ${chunk.pageNumber}` }), transactions: chunk.txCount, questions: chunk.questionsCount }));
|
|
125
127
|
}
|
|
126
128
|
function StatusText({ status }) {
|
package/dist/scanner/engine.js
CHANGED
|
@@ -8,7 +8,7 @@ import { errorMessage } from "./result.js";
|
|
|
8
8
|
const chunkPhase = async (_db, state, hooks) => {
|
|
9
9
|
await hooks.beforeChunk?.(state);
|
|
10
10
|
for (const file of state.decrypted)
|
|
11
|
-
state.chunks.push(...await chunkPdf(file));
|
|
11
|
+
state.chunks.push(...(await chunkPdf(file)));
|
|
12
12
|
await hooks.afterChunk?.(state);
|
|
13
13
|
};
|
|
14
14
|
const clarifyPhase = async (db, state, hooks) => {
|