@fuzzle/opencode-accountant 0.5.1-next.1 → 0.5.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.
- package/dist/index.js +38 -26
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17079,6 +17079,9 @@ function buildPricehistArgs(startDate, endDate, currencyConfig) {
|
|
|
17079
17079
|
}
|
|
17080
17080
|
return cmdArgs;
|
|
17081
17081
|
}
|
|
17082
|
+
function buildErrorResult(error45) {
|
|
17083
|
+
return buildToolErrorResult(error45);
|
|
17084
|
+
}
|
|
17082
17085
|
function buildSuccessResult(results, endDate, backfill) {
|
|
17083
17086
|
return buildToolSuccessResult({
|
|
17084
17087
|
success: results.every((r) => !("error" in r)),
|
|
@@ -17113,7 +17116,7 @@ async function fetchCurrencyPrices(directory, agent, backfill, priceFetcher = de
|
|
|
17113
17116
|
config2 = configLoader(directory);
|
|
17114
17117
|
} catch (err) {
|
|
17115
17118
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
17116
|
-
return
|
|
17119
|
+
return buildErrorResult(errorMessage);
|
|
17117
17120
|
}
|
|
17118
17121
|
const endDate = getYesterday();
|
|
17119
17122
|
const defaultBackfillDate = getDefaultBackfillDate();
|
|
@@ -17430,6 +17433,9 @@ import { randomUUID } from "crypto";
|
|
|
17430
17433
|
function getContextPath(directory, contextId) {
|
|
17431
17434
|
return path5.join(directory, ".memory", `${contextId}.json`);
|
|
17432
17435
|
}
|
|
17436
|
+
function ensureMemoryDir(directory) {
|
|
17437
|
+
ensureDirectory(path5.join(directory, ".memory"));
|
|
17438
|
+
}
|
|
17433
17439
|
function createContext(directory, params) {
|
|
17434
17440
|
const now = new Date().toISOString();
|
|
17435
17441
|
const context = {
|
|
@@ -17448,7 +17454,7 @@ function createContext(directory, params) {
|
|
|
17448
17454
|
closingBalance: params.closingBalance,
|
|
17449
17455
|
account: params.account
|
|
17450
17456
|
};
|
|
17451
|
-
|
|
17457
|
+
ensureMemoryDir(directory);
|
|
17452
17458
|
const contextPath = getContextPath(directory, context.id);
|
|
17453
17459
|
fs5.writeFileSync(contextPath, JSON.stringify(context, null, 2), "utf-8");
|
|
17454
17460
|
return context;
|
|
@@ -17509,6 +17515,20 @@ function buildSuccessResult2(classified, unrecognized, message) {
|
|
|
17509
17515
|
}
|
|
17510
17516
|
});
|
|
17511
17517
|
}
|
|
17518
|
+
function buildErrorResult2(error45, hint) {
|
|
17519
|
+
return buildToolErrorResult(error45, hint, {
|
|
17520
|
+
classified: [],
|
|
17521
|
+
unrecognized: []
|
|
17522
|
+
});
|
|
17523
|
+
}
|
|
17524
|
+
function buildCollisionError(collisions) {
|
|
17525
|
+
const error45 = `Cannot classify: ${collisions.length} file(s) would overwrite existing pending files.`;
|
|
17526
|
+
return buildToolErrorResult(error45, undefined, {
|
|
17527
|
+
collisions,
|
|
17528
|
+
classified: [],
|
|
17529
|
+
unrecognized: []
|
|
17530
|
+
});
|
|
17531
|
+
}
|
|
17512
17532
|
function planMoves(csvFiles, importsDir, pendingDir, unrecognizedDir, config2) {
|
|
17513
17533
|
const plannedMoves = [];
|
|
17514
17534
|
const collisions = [];
|
|
@@ -17609,10 +17629,7 @@ async function classifyStatements(directory, agent, configLoader = loadImportCon
|
|
|
17609
17629
|
config2 = configLoader(directory);
|
|
17610
17630
|
} catch (err) {
|
|
17611
17631
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
17612
|
-
return
|
|
17613
|
-
classified: [],
|
|
17614
|
-
unrecognized: []
|
|
17615
|
-
});
|
|
17632
|
+
return buildErrorResult2(errorMessage);
|
|
17616
17633
|
}
|
|
17617
17634
|
const importsDir = path6.join(directory, config2.paths.import);
|
|
17618
17635
|
const pendingDir = path6.join(directory, config2.paths.pending);
|
|
@@ -17623,12 +17640,7 @@ async function classifyStatements(directory, agent, configLoader = loadImportCon
|
|
|
17623
17640
|
}
|
|
17624
17641
|
const { plannedMoves, collisions } = planMoves(csvFiles, importsDir, pendingDir, unrecognizedDir, config2);
|
|
17625
17642
|
if (collisions.length > 0) {
|
|
17626
|
-
|
|
17627
|
-
return buildToolErrorResult(error45, undefined, {
|
|
17628
|
-
collisions,
|
|
17629
|
-
classified: [],
|
|
17630
|
-
unrecognized: []
|
|
17631
|
-
});
|
|
17643
|
+
return buildCollisionError(collisions);
|
|
17632
17644
|
}
|
|
17633
17645
|
const { classified, unrecognized } = executeMoves(plannedMoves, config2, unrecognizedDir, directory);
|
|
17634
17646
|
return buildSuccessResult2(classified, unrecognized);
|
|
@@ -23414,7 +23426,7 @@ function findMatchingCsvRow(posting, csvRows, config2) {
|
|
|
23414
23426
|
}
|
|
23415
23427
|
|
|
23416
23428
|
// src/tools/import-statements.ts
|
|
23417
|
-
function
|
|
23429
|
+
function buildErrorResult3(error45, hint) {
|
|
23418
23430
|
return buildToolErrorResult(error45, hint, {
|
|
23419
23431
|
files: [],
|
|
23420
23432
|
summary: {
|
|
@@ -23585,7 +23597,7 @@ async function importStatements(directory, agent, options, configLoader = loadIm
|
|
|
23585
23597
|
config2 = configLoader(directory);
|
|
23586
23598
|
} catch (error45) {
|
|
23587
23599
|
const errorMessage = `Failed to load configuration: ${error45 instanceof Error ? error45.message : String(error45)}`;
|
|
23588
|
-
return
|
|
23600
|
+
return buildErrorResult3(errorMessage, 'Ensure config/import/providers.yaml exists with required paths including "rules"');
|
|
23589
23601
|
}
|
|
23590
23602
|
const pendingDir = path9.join(directory, config2.paths.pending);
|
|
23591
23603
|
const rulesDir = path9.join(directory, config2.paths.rules);
|
|
@@ -23594,7 +23606,7 @@ async function importStatements(directory, agent, options, configLoader = loadIm
|
|
|
23594
23606
|
const importContext = loadContext(directory, options.contextId);
|
|
23595
23607
|
const csvPath = path9.join(directory, importContext.filePath);
|
|
23596
23608
|
if (!fs10.existsSync(csvPath)) {
|
|
23597
|
-
return
|
|
23609
|
+
return buildErrorResult3(`CSV file not found: ${importContext.filePath}`, "The file may have been moved or deleted");
|
|
23598
23610
|
}
|
|
23599
23611
|
const csvFiles = [csvPath];
|
|
23600
23612
|
const fileResults = [];
|
|
@@ -23746,7 +23758,7 @@ Note: This tool is typically called via import-pipeline for the full workflow.`,
|
|
|
23746
23758
|
// src/tools/reconcile-statement.ts
|
|
23747
23759
|
import * as fs11 from "fs";
|
|
23748
23760
|
import * as path10 from "path";
|
|
23749
|
-
function
|
|
23761
|
+
function buildErrorResult4(params) {
|
|
23750
23762
|
return buildToolErrorResult(params.error, params.hint, {
|
|
23751
23763
|
account: params.account ?? "",
|
|
23752
23764
|
expectedBalance: params.expectedBalance ?? "",
|
|
@@ -23763,7 +23775,7 @@ function loadConfiguration(directory, configLoader) {
|
|
|
23763
23775
|
return { config: config2 };
|
|
23764
23776
|
} catch (error45) {
|
|
23765
23777
|
return {
|
|
23766
|
-
error:
|
|
23778
|
+
error: buildErrorResult4({
|
|
23767
23779
|
error: `Failed to load configuration: ${error45 instanceof Error ? error45.message : String(error45)}`,
|
|
23768
23780
|
hint: "Ensure config/import/providers.yaml exists"
|
|
23769
23781
|
})
|
|
@@ -23774,7 +23786,7 @@ function verifyCsvExists(directory, importContext) {
|
|
|
23774
23786
|
const csvFile = path10.join(directory, importContext.filePath);
|
|
23775
23787
|
if (!fs11.existsSync(csvFile)) {
|
|
23776
23788
|
return {
|
|
23777
|
-
error:
|
|
23789
|
+
error: buildErrorResult4({
|
|
23778
23790
|
error: `CSV file not found: ${importContext.filePath}`,
|
|
23779
23791
|
hint: `The file may have been moved or deleted. Context ID: ${importContext.id}`
|
|
23780
23792
|
})
|
|
@@ -23841,7 +23853,7 @@ function determineClosingBalance(csvFile, config2, importContext, manualClosingB
|
|
|
23841
23853
|
const exampleBalance = `${currency} <amount>`;
|
|
23842
23854
|
const retryCmd = buildRetryCommand(importContext.id, exampleBalance);
|
|
23843
23855
|
return {
|
|
23844
|
-
error:
|
|
23856
|
+
error: buildErrorResult4({
|
|
23845
23857
|
csvFile: relativeCsvPath,
|
|
23846
23858
|
error: "No closing balance found in CSV metadata or data",
|
|
23847
23859
|
hint: `Provide closingBalance parameter manually. Example retry: ${retryCmd}`,
|
|
@@ -23871,7 +23883,7 @@ function determineAccount(csvFile, rulesDir, importContext, manualAccount, relat
|
|
|
23871
23883
|
if (!account) {
|
|
23872
23884
|
const rulesHint = rulesFile ? `Add 'account1 assets:bank:...' to ${rulesFile} or retry with: ${buildRetryCommand(importContext.id, undefined, "assets:bank:...")}` : `Create a rules file in ${rulesDir} with 'account1' directive or retry with: ${buildRetryCommand(importContext.id, undefined, "assets:bank:...")}`;
|
|
23873
23885
|
return {
|
|
23874
|
-
error:
|
|
23886
|
+
error: buildErrorResult4({
|
|
23875
23887
|
csvFile: relativeCsvPath,
|
|
23876
23888
|
error: "Could not determine account from rules file",
|
|
23877
23889
|
hint: rulesHint,
|
|
@@ -23954,7 +23966,7 @@ async function reconcileStatement(directory, agent, options, configLoader = load
|
|
|
23954
23966
|
try {
|
|
23955
23967
|
importContext = loadContext(directory, options.contextId);
|
|
23956
23968
|
} catch {
|
|
23957
|
-
return
|
|
23969
|
+
return buildErrorResult4({
|
|
23958
23970
|
error: `Failed to load import context: ${options.contextId}`,
|
|
23959
23971
|
hint: "Ensure the context ID is valid and the context file exists in .memory/"
|
|
23960
23972
|
});
|
|
@@ -23983,7 +23995,7 @@ async function reconcileStatement(directory, agent, options, configLoader = load
|
|
|
23983
23995
|
const { account } = accountResult;
|
|
23984
23996
|
const lastTransactionDate = await getLastTransactionDate(mainJournalPath, account, hledgerExecutor);
|
|
23985
23997
|
if (!lastTransactionDate) {
|
|
23986
|
-
return
|
|
23998
|
+
return buildErrorResult4({
|
|
23987
23999
|
csvFile: relativeCsvPath,
|
|
23988
24000
|
account,
|
|
23989
24001
|
error: "No transactions found for account",
|
|
@@ -23993,7 +24005,7 @@ async function reconcileStatement(directory, agent, options, configLoader = load
|
|
|
23993
24005
|
}
|
|
23994
24006
|
const actualBalance = await getAccountBalance(mainJournalPath, account, lastTransactionDate, hledgerExecutor);
|
|
23995
24007
|
if (actualBalance === null) {
|
|
23996
|
-
return
|
|
24008
|
+
return buildErrorResult4({
|
|
23997
24009
|
csvFile: relativeCsvPath,
|
|
23998
24010
|
account,
|
|
23999
24011
|
lastTransactionDate,
|
|
@@ -24006,7 +24018,7 @@ async function reconcileStatement(directory, agent, options, configLoader = load
|
|
|
24006
24018
|
try {
|
|
24007
24019
|
doBalancesMatch = balancesMatch(closingBalance, actualBalance);
|
|
24008
24020
|
} catch (error45) {
|
|
24009
|
-
return
|
|
24021
|
+
return buildErrorResult4({
|
|
24010
24022
|
csvFile: relativeCsvPath,
|
|
24011
24023
|
account,
|
|
24012
24024
|
lastTransactionDate,
|
|
@@ -24035,7 +24047,7 @@ async function reconcileStatement(directory, agent, options, configLoader = load
|
|
|
24035
24047
|
try {
|
|
24036
24048
|
difference = calculateDifference(closingBalance, actualBalance);
|
|
24037
24049
|
} catch (error45) {
|
|
24038
|
-
return
|
|
24050
|
+
return buildErrorResult4({
|
|
24039
24051
|
csvFile: relativeCsvPath,
|
|
24040
24052
|
account,
|
|
24041
24053
|
lastTransactionDate,
|
|
@@ -24045,7 +24057,7 @@ async function reconcileStatement(directory, agent, options, configLoader = load
|
|
|
24045
24057
|
metadata
|
|
24046
24058
|
});
|
|
24047
24059
|
}
|
|
24048
|
-
return
|
|
24060
|
+
return buildErrorResult4({
|
|
24049
24061
|
csvFile: relativeCsvPath,
|
|
24050
24062
|
account,
|
|
24051
24063
|
lastTransactionDate,
|