@fuzzle/opencode-accountant 0.13.21 → 0.14.0
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 +60 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16952,7 +16952,19 @@ function loadPricesConfig(directory) {
|
|
|
16952
16952
|
for (const [name, config2] of Object.entries(currenciesObj)) {
|
|
16953
16953
|
currencies[name] = validateCurrencyConfig(name, config2);
|
|
16954
16954
|
}
|
|
16955
|
-
|
|
16955
|
+
let stocks;
|
|
16956
|
+
if (parsedObj.stocks !== undefined) {
|
|
16957
|
+
if (!Array.isArray(parsedObj.stocks) || parsedObj.stocks.length === 0) {
|
|
16958
|
+
throw new Error(`Invalid config: 'stocks' must be a non-empty array`);
|
|
16959
|
+
}
|
|
16960
|
+
for (const [i2, ticker] of parsedObj.stocks.entries()) {
|
|
16961
|
+
if (typeof ticker !== "string" || ticker === "") {
|
|
16962
|
+
throw new Error(`Invalid config: stock entry at index ${i2} must be a non-empty string`);
|
|
16963
|
+
}
|
|
16964
|
+
}
|
|
16965
|
+
stocks = parsedObj.stocks;
|
|
16966
|
+
}
|
|
16967
|
+
return { currencies, stocks };
|
|
16956
16968
|
}, `Configuration file not found: ${CONFIG_FILE}. Please refer to the plugin's GitHub repository for setup instructions.`);
|
|
16957
16969
|
}
|
|
16958
16970
|
|
|
@@ -17227,6 +17239,14 @@ function parsePriceLine(line) {
|
|
|
17227
17239
|
formattedLine: line
|
|
17228
17240
|
};
|
|
17229
17241
|
}
|
|
17242
|
+
function ensureQuotedSymbols(line) {
|
|
17243
|
+
return line.replace(/^(P \d{4}-\d{2}-\d{2}(?: \d{2}:\d{2}:\d{2})?) (\S+) /, (_match, prefix, symbol2) => {
|
|
17244
|
+
if (symbol2.includes(".") && !symbol2.startsWith('"')) {
|
|
17245
|
+
return `${prefix} "${symbol2}" `;
|
|
17246
|
+
}
|
|
17247
|
+
return `${prefix} ${symbol2} `;
|
|
17248
|
+
});
|
|
17249
|
+
}
|
|
17230
17250
|
function filterAndSortPriceLinesByDateRange(priceLines, startDate, endDate) {
|
|
17231
17251
|
return priceLines.map(parsePriceLine).filter((parsed) => {
|
|
17232
17252
|
if (!parsed)
|
|
@@ -17286,10 +17306,48 @@ async function fetchCurrencyPrices(directory, agent, backfill, priceFetcher = de
|
|
|
17286
17306
|
});
|
|
17287
17307
|
}
|
|
17288
17308
|
}
|
|
17309
|
+
for (const ticker of config2.stocks ?? []) {
|
|
17310
|
+
try {
|
|
17311
|
+
const startDate = backfill ? defaultBackfillDate : endDate;
|
|
17312
|
+
const cmdArgs = ["fetch", "-o", "ledger", "-s", startDate, "-e", endDate, "yahoo", ticker];
|
|
17313
|
+
const output = await priceFetcher(cmdArgs);
|
|
17314
|
+
const rawPriceLines = output.split(`
|
|
17315
|
+
`).filter((line) => line.startsWith("P "));
|
|
17316
|
+
if (rawPriceLines.length === 0) {
|
|
17317
|
+
results.push({
|
|
17318
|
+
ticker,
|
|
17319
|
+
error: `No price lines in pricehist output: ${output}`
|
|
17320
|
+
});
|
|
17321
|
+
continue;
|
|
17322
|
+
}
|
|
17323
|
+
const priceLines = filterAndSortPriceLinesByDateRange(rawPriceLines, startDate, endDate).map(ensureQuotedSymbols);
|
|
17324
|
+
if (priceLines.length === 0) {
|
|
17325
|
+
results.push({
|
|
17326
|
+
ticker,
|
|
17327
|
+
error: `No price data found within date range ${startDate} to ${endDate}`
|
|
17328
|
+
});
|
|
17329
|
+
continue;
|
|
17330
|
+
}
|
|
17331
|
+
const file2 = `${ticker.toLowerCase()}.journal`;
|
|
17332
|
+
const journalPath = path4.join(directory, "ledger", "stocks", file2);
|
|
17333
|
+
updatePriceJournal(journalPath, priceLines);
|
|
17334
|
+
const latestPriceLine = priceLines[priceLines.length - 1];
|
|
17335
|
+
results.push({
|
|
17336
|
+
ticker,
|
|
17337
|
+
priceLine: latestPriceLine,
|
|
17338
|
+
file: file2
|
|
17339
|
+
});
|
|
17340
|
+
} catch (err) {
|
|
17341
|
+
results.push({
|
|
17342
|
+
ticker,
|
|
17343
|
+
error: String(err)
|
|
17344
|
+
});
|
|
17345
|
+
}
|
|
17346
|
+
}
|
|
17289
17347
|
return buildSuccessResult(results, endDate, backfill);
|
|
17290
17348
|
}
|
|
17291
17349
|
var fetch_currency_prices_default = tool({
|
|
17292
|
-
description: "ACCOUNTANT AGENT ONLY: Fetches end-of-day prices for all configured currencies (from config/prices.yaml) and appends them to the corresponding price journals in ledger/currencies/.",
|
|
17350
|
+
description: "ACCOUNTANT AGENT ONLY: Fetches end-of-day prices for all configured currencies and stock tickers (from config/prices.yaml) and appends them to the corresponding price journals in ledger/currencies/ and ledger/stocks/.",
|
|
17293
17351
|
args: {
|
|
17294
17352
|
backfill: tool.schema.boolean().optional().describe("If true, fetch history from each currency's configured backfill_date (or Jan 1 of current year if not specified)")
|
|
17295
17353
|
},
|