driggsby 0.9.0 → 0.9.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.
|
@@ -117,7 +117,8 @@ async function runStart(session, options, io) {
|
|
|
117
117
|
}
|
|
118
118
|
return renderStatus(view, {
|
|
119
119
|
compact: options.wait && startedIn === "categorizing",
|
|
120
|
-
|
|
120
|
+
// Found already this far: a wait that watched it land shows it in full.
|
|
121
|
+
repeated: target.kind === "file" && !created && given === null && view.state === startedIn,
|
|
121
122
|
unchanged: outcome.note !== null,
|
|
122
123
|
rerun: { file: typedFile, account: options.account, create: options.create },
|
|
123
124
|
}, context(io));
|
|
@@ -60,7 +60,9 @@ function statusBody(view, options, context) {
|
|
|
60
60
|
case "waiting":
|
|
61
61
|
return ok(renderQuestion(view));
|
|
62
62
|
case "categorizing":
|
|
63
|
-
|
|
63
|
+
if (options.compact)
|
|
64
|
+
return ok(categorizingLine(view));
|
|
65
|
+
return ok(options.repeated ? alreadyImported(view) : landed(view, "Imported"));
|
|
64
66
|
case "done":
|
|
65
67
|
return ok(done(view, options, context));
|
|
66
68
|
case "stopped":
|
|
@@ -136,10 +138,15 @@ export function renderQuestion(view) {
|
|
|
136
138
|
export function choiceLines(choices, command) {
|
|
137
139
|
return `${choices.map((choice) => ` ${name(choice.label)}\n ${command(choice)}`).join("\n")}\n`;
|
|
138
140
|
}
|
|
141
|
+
// One transaction "is", any other count "are".
|
|
142
|
+
function be(count) {
|
|
143
|
+
return count === 1 ? "is" : "are";
|
|
144
|
+
}
|
|
139
145
|
// The transactions are in: what landed, then what's left to do.
|
|
140
146
|
function landed(view, headline) {
|
|
141
|
-
const
|
|
142
|
-
const
|
|
147
|
+
const count = view.counts?.new ?? 0;
|
|
148
|
+
const where = view.account === null ? " landed" : ` ${be(count)} in ${name(view.account)}`;
|
|
149
|
+
const top = `${headline}: ${plural(count, "transaction")} from ${name(view.file)}${where}.`;
|
|
143
150
|
const undoCommand = ` ${CLI} import undo ${view.ref}\n`;
|
|
144
151
|
// A new account is the person's to name by its ID from here on.
|
|
145
152
|
const again = view.newAccount && view.accountRef !== null ? `Next time, for this account:\n ${CLI} import <FILE> --account ${view.accountRef}\n\n` : "";
|
|
@@ -182,6 +189,14 @@ function progressText(view) {
|
|
|
182
189
|
const left = progress.secondsLeft === null ? "" : `, ${timeLeft(progress.secondsLeft)}`;
|
|
183
190
|
return `${progress.categorized.toLocaleString("en-US")} of ${progress.total.toLocaleString("en-US")} so far${left}`;
|
|
184
191
|
}
|
|
192
|
+
// The same file sent again while categories fill in: it's already in, and
|
|
193
|
+
// this run imported nothing, so it never reads as a second import.
|
|
194
|
+
function alreadyImported(view) {
|
|
195
|
+
const count = view.counts?.new ?? 0;
|
|
196
|
+
const into = view.account === null ? " landed" : ` ${be(count)} in ${name(view.account)}`;
|
|
197
|
+
return (`Already imported: this file's ${plural(count, "transaction")}${into} (${view.ref}). Categories: ${progressText(view)}.\n\n` +
|
|
198
|
+
`${wrapProse("Nothing else to do unless you need the categories. To wait for them:")}\n ${waitCommand(view.ref)}\n`);
|
|
199
|
+
}
|
|
185
200
|
function categorizingLine(view) {
|
|
186
201
|
const progress = view.progress;
|
|
187
202
|
const where = progress === null || progress.categorized === 0
|
|
@@ -194,14 +209,15 @@ function done(view, options, context) {
|
|
|
194
209
|
const why = NOTHING_NEW[view.nothingNew] ?? "none of its transactions were new";
|
|
195
210
|
return `Done: nothing new in ${name(view.file)}: ${why}.\n\nNothing else to do.\n`;
|
|
196
211
|
}
|
|
212
|
+
const count = view.counts?.new ?? 0;
|
|
197
213
|
// A wait that followed categorizing ends on how it went, even for a file
|
|
198
214
|
// sent again.
|
|
199
215
|
if (options.compact && view.categorized === false) {
|
|
200
|
-
return (`Done: ${plural(
|
|
216
|
+
return (`Done: ${plural(count, "transaction")} from ${name(view.file)} ${be(count)} in, but some couldn't be categorized.\n\n` +
|
|
201
217
|
`${wrapProse("Those show as uncategorized. Nothing else to do: the import is finished.")}\n`);
|
|
202
218
|
}
|
|
203
219
|
if (options.compact) {
|
|
204
|
-
return `Done: all ${plural(
|
|
220
|
+
return `Done: ${count === 1 ? "the" : "all"} ${plural(count, "transaction")} from ${name(view.file)} ${be(count)} categorized.\n\nNothing else to do: the import is finished.\n`;
|
|
205
221
|
}
|
|
206
222
|
if (options.repeated) {
|
|
207
223
|
const on = view.finishedAt === null ? "" : ` on ${shortDate(view.finishedAt, context)}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "driggsby",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Set up and build on Driggsby, the MCP server for personal finance.",
|
|
5
5
|
"license": "Apache-2.0 AND OFL-1.1",
|
|
6
6
|
"repository": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"node": ">=18"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@driggsby/deploy": "0.9.
|
|
34
|
-
"@driggsby/sdk": "0.9.
|
|
33
|
+
"@driggsby/deploy": "0.9.1",
|
|
34
|
+
"@driggsby/sdk": "0.9.1"
|
|
35
35
|
}
|
|
36
36
|
}
|