@fuzzle/opencode-accountant 0.0.7-next.1 → 0.0.8-next.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/README.md +39 -9
- package/dist/index.js +164 -79
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,10 +93,10 @@ The `classify-statements` tool classifies bank statement CSV files by provider a
|
|
|
93
93
|
|
|
94
94
|
```yaml
|
|
95
95
|
paths:
|
|
96
|
-
|
|
96
|
+
import: statements/import
|
|
97
97
|
pending: doc/agent/todo/import
|
|
98
98
|
done: doc/agent/done/import
|
|
99
|
-
unrecognized: statements/
|
|
99
|
+
unrecognized: statements/import/unrecognized
|
|
100
100
|
|
|
101
101
|
providers:
|
|
102
102
|
revolut:
|
|
@@ -112,6 +112,23 @@ providers:
|
|
|
112
112
|
EUR: eur
|
|
113
113
|
USD: usd
|
|
114
114
|
BTC: btc
|
|
115
|
+
|
|
116
|
+
ubs:
|
|
117
|
+
detect:
|
|
118
|
+
- header: 'Trade date,Trade time,Booking date,Value date,Currency,Debit,Credit,Individual amount,Balance,Transaction no.,Description1,Description2,Description3,Footnotes'
|
|
119
|
+
currencyField: Currency
|
|
120
|
+
skipRows: 9
|
|
121
|
+
delimiter: ';'
|
|
122
|
+
renamePattern: 'transactions-ubs-{accountnumber}.csv'
|
|
123
|
+
metadata:
|
|
124
|
+
- field: accountnumber
|
|
125
|
+
row: 0
|
|
126
|
+
column: 1
|
|
127
|
+
normalize: spaces-to-dashes
|
|
128
|
+
currencies:
|
|
129
|
+
CHF: chf
|
|
130
|
+
EUR: eur
|
|
131
|
+
USD: usd
|
|
115
132
|
```
|
|
116
133
|
|
|
117
134
|
#### Configuration Options
|
|
@@ -120,19 +137,32 @@ providers:
|
|
|
120
137
|
|
|
121
138
|
| Field | Description |
|
|
122
139
|
| -------------- | ----------------------------------------------- |
|
|
123
|
-
| `
|
|
140
|
+
| `import` | Drop zone for new CSV files |
|
|
124
141
|
| `pending` | Base path for classified files awaiting import |
|
|
125
142
|
| `done` | Base path for archived files after import |
|
|
126
143
|
| `unrecognized` | Directory for files that couldn't be classified |
|
|
127
144
|
|
|
128
145
|
**Provider Detection Rules:**
|
|
129
146
|
|
|
130
|
-
| Field | Description
|
|
131
|
-
| ----------------- |
|
|
132
|
-
| `filenamePattern` | Regex pattern to match against filename
|
|
133
|
-
| `header` | Expected CSV header row (exact match)
|
|
134
|
-
| `currencyField` | Column name containing the currency/symbol
|
|
135
|
-
| `
|
|
147
|
+
| Field | Required | Description |
|
|
148
|
+
| ----------------- | -------- | ---------------------------------------------------------- |
|
|
149
|
+
| `filenamePattern` | No | Regex pattern to match against filename |
|
|
150
|
+
| `header` | Yes | Expected CSV header row (exact match) |
|
|
151
|
+
| `currencyField` | Yes | Column name containing the currency/symbol |
|
|
152
|
+
| `skipRows` | No | Number of rows to skip before header (default: 0) |
|
|
153
|
+
| `delimiter` | No | CSV delimiter character (default: `,`) |
|
|
154
|
+
| `renamePattern` | No | Output filename pattern with `{placeholder}` substitutions |
|
|
155
|
+
| `metadata` | No | Array of metadata extraction rules (see below) |
|
|
156
|
+
| `currencies` | Yes | Map of raw currency values to normalized folder names |
|
|
157
|
+
|
|
158
|
+
**Metadata Extraction Rules:**
|
|
159
|
+
|
|
160
|
+
| Field | Required | Description |
|
|
161
|
+
| ----------- | -------- | ------------------------------------------------------- |
|
|
162
|
+
| `field` | Yes | Placeholder name to use in `renamePattern` |
|
|
163
|
+
| `row` | Yes | Row index within `skipRows` to extract from (0-indexed) |
|
|
164
|
+
| `column` | Yes | Column index to extract from (0-indexed) |
|
|
165
|
+
| `normalize` | No | Normalization type: `spaces-to-dashes` |
|
|
136
166
|
|
|
137
167
|
#### Directory Structure
|
|
138
168
|
|
package/dist/index.js
CHANGED
|
@@ -1341,7 +1341,7 @@ var require_papaparse = __commonJS((exports, module) => {
|
|
|
1341
1341
|
});
|
|
1342
1342
|
|
|
1343
1343
|
// src/index.ts
|
|
1344
|
-
import { dirname, join as join5 } from "path";
|
|
1344
|
+
import { dirname as dirname2, join as join5 } from "path";
|
|
1345
1345
|
import { fileURLToPath } from "url";
|
|
1346
1346
|
|
|
1347
1347
|
// src/utils/agentLoader.ts
|
|
@@ -16584,12 +16584,8 @@ import * as fs4 from "fs";
|
|
|
16584
16584
|
import * as fs3 from "fs";
|
|
16585
16585
|
import * as path3 from "path";
|
|
16586
16586
|
var CONFIG_FILE2 = "config/import/providers.yaml";
|
|
16587
|
-
var REQUIRED_PATH_FIELDS = ["
|
|
16588
|
-
var REQUIRED_DETECTION_FIELDS = [
|
|
16589
|
-
"filenamePattern",
|
|
16590
|
-
"header",
|
|
16591
|
-
"currencyField"
|
|
16592
|
-
];
|
|
16587
|
+
var REQUIRED_PATH_FIELDS = ["import", "pending", "done", "unrecognized"];
|
|
16588
|
+
var REQUIRED_DETECTION_FIELDS = ["header", "currencyField"];
|
|
16593
16589
|
function validatePaths(paths) {
|
|
16594
16590
|
if (typeof paths !== "object" || paths === null) {
|
|
16595
16591
|
throw new Error("Invalid config: 'paths' must be an object");
|
|
@@ -16601,7 +16597,7 @@ function validatePaths(paths) {
|
|
|
16601
16597
|
}
|
|
16602
16598
|
}
|
|
16603
16599
|
return {
|
|
16604
|
-
|
|
16600
|
+
import: pathsObj.import,
|
|
16605
16601
|
pending: pathsObj.pending,
|
|
16606
16602
|
done: pathsObj.done,
|
|
16607
16603
|
unrecognized: pathsObj.unrecognized
|
|
@@ -16617,15 +16613,59 @@ function validateDetectionRule(providerName, index, rule) {
|
|
|
16617
16613
|
throw new Error(`Invalid config: provider '${providerName}' detect[${index}].${field} is required`);
|
|
16618
16614
|
}
|
|
16619
16615
|
}
|
|
16620
|
-
|
|
16621
|
-
|
|
16622
|
-
|
|
16623
|
-
|
|
16616
|
+
if (ruleObj.filenamePattern !== undefined) {
|
|
16617
|
+
if (typeof ruleObj.filenamePattern !== "string") {
|
|
16618
|
+
throw new Error(`Invalid config: provider '${providerName}' detect[${index}].filenamePattern must be a string`);
|
|
16619
|
+
}
|
|
16620
|
+
try {
|
|
16621
|
+
new RegExp(ruleObj.filenamePattern);
|
|
16622
|
+
} catch {
|
|
16623
|
+
throw new Error(`Invalid config: provider '${providerName}' detect[${index}].filenamePattern is not a valid regex`);
|
|
16624
|
+
}
|
|
16625
|
+
}
|
|
16626
|
+
if (ruleObj.skipRows !== undefined) {
|
|
16627
|
+
if (typeof ruleObj.skipRows !== "number" || ruleObj.skipRows < 0) {
|
|
16628
|
+
throw new Error(`Invalid config: provider '${providerName}' detect[${index}].skipRows must be a non-negative number`);
|
|
16629
|
+
}
|
|
16630
|
+
}
|
|
16631
|
+
if (ruleObj.delimiter !== undefined) {
|
|
16632
|
+
if (typeof ruleObj.delimiter !== "string" || ruleObj.delimiter.length !== 1) {
|
|
16633
|
+
throw new Error(`Invalid config: provider '${providerName}' detect[${index}].delimiter must be a single character`);
|
|
16634
|
+
}
|
|
16635
|
+
}
|
|
16636
|
+
if (ruleObj.renamePattern !== undefined) {
|
|
16637
|
+
if (typeof ruleObj.renamePattern !== "string") {
|
|
16638
|
+
throw new Error(`Invalid config: provider '${providerName}' detect[${index}].renamePattern must be a string`);
|
|
16639
|
+
}
|
|
16640
|
+
}
|
|
16641
|
+
if (ruleObj.metadata !== undefined) {
|
|
16642
|
+
if (!Array.isArray(ruleObj.metadata)) {
|
|
16643
|
+
throw new Error(`Invalid config: provider '${providerName}' detect[${index}].metadata must be an array`);
|
|
16644
|
+
}
|
|
16645
|
+
for (let i2 = 0;i2 < ruleObj.metadata.length; i2++) {
|
|
16646
|
+
const meta = ruleObj.metadata[i2];
|
|
16647
|
+
if (typeof meta.field !== "string" || meta.field === "") {
|
|
16648
|
+
throw new Error(`Invalid config: provider '${providerName}' detect[${index}].metadata[${i2}].field is required`);
|
|
16649
|
+
}
|
|
16650
|
+
if (typeof meta.row !== "number" || meta.row < 0) {
|
|
16651
|
+
throw new Error(`Invalid config: provider '${providerName}' detect[${index}].metadata[${i2}].row must be a non-negative number`);
|
|
16652
|
+
}
|
|
16653
|
+
if (typeof meta.column !== "number" || meta.column < 0) {
|
|
16654
|
+
throw new Error(`Invalid config: provider '${providerName}' detect[${index}].metadata[${i2}].column must be a non-negative number`);
|
|
16655
|
+
}
|
|
16656
|
+
if (meta.normalize !== undefined && meta.normalize !== "spaces-to-dashes") {
|
|
16657
|
+
throw new Error(`Invalid config: provider '${providerName}' detect[${index}].metadata[${i2}].normalize must be 'spaces-to-dashes'`);
|
|
16658
|
+
}
|
|
16659
|
+
}
|
|
16624
16660
|
}
|
|
16625
16661
|
return {
|
|
16626
16662
|
filenamePattern: ruleObj.filenamePattern,
|
|
16627
16663
|
header: ruleObj.header,
|
|
16628
|
-
currencyField: ruleObj.currencyField
|
|
16664
|
+
currencyField: ruleObj.currencyField,
|
|
16665
|
+
skipRows: ruleObj.skipRows,
|
|
16666
|
+
delimiter: ruleObj.delimiter,
|
|
16667
|
+
renamePattern: ruleObj.renamePattern,
|
|
16668
|
+
metadata: ruleObj.metadata
|
|
16629
16669
|
};
|
|
16630
16670
|
}
|
|
16631
16671
|
function validateProviderConfig(name, config2) {
|
|
@@ -16695,11 +16735,50 @@ function loadImportConfig(directory) {
|
|
|
16695
16735
|
|
|
16696
16736
|
// src/utils/providerDetector.ts
|
|
16697
16737
|
var import_papaparse = __toESM(require_papaparse(), 1);
|
|
16698
|
-
function
|
|
16699
|
-
|
|
16738
|
+
function extractMetadata(content, skipRows, delimiter, metadataConfig) {
|
|
16739
|
+
if (!metadataConfig || metadataConfig.length === 0 || skipRows === 0) {
|
|
16740
|
+
return {};
|
|
16741
|
+
}
|
|
16742
|
+
const lines = content.split(`
|
|
16743
|
+
`).slice(0, skipRows);
|
|
16744
|
+
const metadata = {};
|
|
16745
|
+
for (const config2 of metadataConfig) {
|
|
16746
|
+
if (config2.row >= lines.length)
|
|
16747
|
+
continue;
|
|
16748
|
+
const columns = lines[config2.row].split(delimiter);
|
|
16749
|
+
if (config2.column >= columns.length)
|
|
16750
|
+
continue;
|
|
16751
|
+
let value = columns[config2.column].trim();
|
|
16752
|
+
if (config2.normalize === "spaces-to-dashes") {
|
|
16753
|
+
value = value.replace(/\s+/g, "-");
|
|
16754
|
+
}
|
|
16755
|
+
metadata[config2.field] = value;
|
|
16756
|
+
}
|
|
16757
|
+
return metadata;
|
|
16758
|
+
}
|
|
16759
|
+
function generateOutputFilename(renamePattern, metadata) {
|
|
16760
|
+
if (!renamePattern) {
|
|
16761
|
+
return;
|
|
16762
|
+
}
|
|
16763
|
+
let filename = renamePattern;
|
|
16764
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
16765
|
+
filename = filename.replace(`{${key}}`, value);
|
|
16766
|
+
}
|
|
16767
|
+
return filename;
|
|
16768
|
+
}
|
|
16769
|
+
function parseCSVPreview(content, skipRows = 0, delimiter = ",") {
|
|
16770
|
+
let csvContent = content;
|
|
16771
|
+
if (skipRows > 0) {
|
|
16772
|
+
const lines = content.split(`
|
|
16773
|
+
`);
|
|
16774
|
+
csvContent = lines.slice(skipRows).join(`
|
|
16775
|
+
`);
|
|
16776
|
+
}
|
|
16777
|
+
const result = import_papaparse.default.parse(csvContent, {
|
|
16700
16778
|
header: true,
|
|
16701
16779
|
preview: 1,
|
|
16702
|
-
skipEmptyLines: true
|
|
16780
|
+
skipEmptyLines: true,
|
|
16781
|
+
delimiter
|
|
16703
16782
|
});
|
|
16704
16783
|
return {
|
|
16705
16784
|
fields: result.meta.fields,
|
|
@@ -16710,17 +16789,21 @@ function normalizeHeader(fields) {
|
|
|
16710
16789
|
return fields.map((f) => f.trim()).join(",");
|
|
16711
16790
|
}
|
|
16712
16791
|
function detectProvider(filename, content, config2) {
|
|
16713
|
-
const { fields, firstRow } = parseCSVPreview(content);
|
|
16714
|
-
if (!fields || fields.length === 0) {
|
|
16715
|
-
return null;
|
|
16716
|
-
}
|
|
16717
|
-
const actualHeader = normalizeHeader(fields);
|
|
16718
16792
|
for (const [providerName, providerConfig] of Object.entries(config2.providers)) {
|
|
16719
16793
|
for (const rule of providerConfig.detect) {
|
|
16720
|
-
|
|
16721
|
-
|
|
16794
|
+
if (rule.filenamePattern !== undefined) {
|
|
16795
|
+
const filenameRegex = new RegExp(rule.filenamePattern);
|
|
16796
|
+
if (!filenameRegex.test(filename)) {
|
|
16797
|
+
continue;
|
|
16798
|
+
}
|
|
16799
|
+
}
|
|
16800
|
+
const skipRows = rule.skipRows ?? 0;
|
|
16801
|
+
const delimiter = rule.delimiter ?? ",";
|
|
16802
|
+
const { fields, firstRow } = parseCSVPreview(content, skipRows, delimiter);
|
|
16803
|
+
if (!fields || fields.length === 0) {
|
|
16722
16804
|
continue;
|
|
16723
16805
|
}
|
|
16806
|
+
const actualHeader = normalizeHeader(fields);
|
|
16724
16807
|
if (actualHeader !== rule.header) {
|
|
16725
16808
|
continue;
|
|
16726
16809
|
}
|
|
@@ -16731,18 +16814,24 @@ function detectProvider(filename, content, config2) {
|
|
|
16731
16814
|
if (!rawCurrency) {
|
|
16732
16815
|
continue;
|
|
16733
16816
|
}
|
|
16817
|
+
const metadata = extractMetadata(content, skipRows, delimiter, rule.metadata);
|
|
16818
|
+
const outputFilename = generateOutputFilename(rule.renamePattern, metadata);
|
|
16734
16819
|
const normalizedCurrency = providerConfig.currencies[rawCurrency];
|
|
16735
16820
|
if (!normalizedCurrency) {
|
|
16736
16821
|
return {
|
|
16737
16822
|
provider: providerName,
|
|
16738
16823
|
currency: rawCurrency.toLowerCase(),
|
|
16739
|
-
rule
|
|
16824
|
+
rule,
|
|
16825
|
+
outputFilename,
|
|
16826
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : undefined
|
|
16740
16827
|
};
|
|
16741
16828
|
}
|
|
16742
16829
|
return {
|
|
16743
16830
|
provider: providerName,
|
|
16744
16831
|
currency: normalizedCurrency,
|
|
16745
|
-
rule
|
|
16832
|
+
rule,
|
|
16833
|
+
outputFilename,
|
|
16834
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : undefined
|
|
16746
16835
|
};
|
|
16747
16836
|
}
|
|
16748
16837
|
}
|
|
@@ -16759,35 +16848,6 @@ function findCSVFiles(importsDir) {
|
|
|
16759
16848
|
return fs4.statSync(fullPath).isFile();
|
|
16760
16849
|
});
|
|
16761
16850
|
}
|
|
16762
|
-
function checkPendingFiles(directory, pendingBasePath) {
|
|
16763
|
-
const pendingDir = path4.join(directory, pendingBasePath);
|
|
16764
|
-
const pendingFiles = [];
|
|
16765
|
-
if (!fs4.existsSync(pendingDir)) {
|
|
16766
|
-
return [];
|
|
16767
|
-
}
|
|
16768
|
-
const providers = fs4.readdirSync(pendingDir);
|
|
16769
|
-
for (const provider of providers) {
|
|
16770
|
-
const providerPath = path4.join(pendingDir, provider);
|
|
16771
|
-
if (!fs4.statSync(providerPath).isDirectory())
|
|
16772
|
-
continue;
|
|
16773
|
-
const currencies = fs4.readdirSync(providerPath);
|
|
16774
|
-
for (const currency of currencies) {
|
|
16775
|
-
const currencyPath = path4.join(providerPath, currency);
|
|
16776
|
-
if (!fs4.statSync(currencyPath).isDirectory())
|
|
16777
|
-
continue;
|
|
16778
|
-
const files = fs4.readdirSync(currencyPath).filter((f) => f.toLowerCase().endsWith(".csv"));
|
|
16779
|
-
for (const file2 of files) {
|
|
16780
|
-
pendingFiles.push({
|
|
16781
|
-
provider,
|
|
16782
|
-
currency,
|
|
16783
|
-
filename: file2,
|
|
16784
|
-
path: path4.join(currencyPath, file2)
|
|
16785
|
-
});
|
|
16786
|
-
}
|
|
16787
|
-
}
|
|
16788
|
-
}
|
|
16789
|
-
return pendingFiles;
|
|
16790
|
-
}
|
|
16791
16851
|
function ensureDirectory(dirPath) {
|
|
16792
16852
|
if (!fs4.existsSync(dirPath)) {
|
|
16793
16853
|
fs4.mkdirSync(dirPath, { recursive: true });
|
|
@@ -16815,52 +16875,77 @@ async function classifyStatementsCore(directory, agent, configLoader = loadImpor
|
|
|
16815
16875
|
unrecognized: []
|
|
16816
16876
|
});
|
|
16817
16877
|
}
|
|
16818
|
-
const importsDir = path4.join(directory, config2.paths.
|
|
16878
|
+
const importsDir = path4.join(directory, config2.paths.import);
|
|
16819
16879
|
const pendingDir = path4.join(directory, config2.paths.pending);
|
|
16820
16880
|
const unrecognizedDir = path4.join(directory, config2.paths.unrecognized);
|
|
16821
|
-
const pendingFiles = checkPendingFiles(directory, config2.paths.pending);
|
|
16822
|
-
if (pendingFiles.length > 0) {
|
|
16823
|
-
return JSON.stringify({
|
|
16824
|
-
success: false,
|
|
16825
|
-
error: `Found ${pendingFiles.length} pending file(s) that must be processed before classifying new statements.`,
|
|
16826
|
-
pendingFiles,
|
|
16827
|
-
classified: [],
|
|
16828
|
-
unrecognized: []
|
|
16829
|
-
});
|
|
16830
|
-
}
|
|
16831
16881
|
const csvFiles = findCSVFiles(importsDir);
|
|
16832
16882
|
if (csvFiles.length === 0) {
|
|
16833
16883
|
return JSON.stringify({
|
|
16834
16884
|
success: true,
|
|
16835
16885
|
classified: [],
|
|
16836
16886
|
unrecognized: [],
|
|
16837
|
-
message: `No CSV files found in ${config2.paths.
|
|
16887
|
+
message: `No CSV files found in ${config2.paths.import}`
|
|
16838
16888
|
});
|
|
16839
16889
|
}
|
|
16840
|
-
const
|
|
16841
|
-
const
|
|
16890
|
+
const plannedMoves = [];
|
|
16891
|
+
const collisions = [];
|
|
16842
16892
|
for (const filename of csvFiles) {
|
|
16843
16893
|
const sourcePath = path4.join(importsDir, filename);
|
|
16844
16894
|
const content = fs4.readFileSync(sourcePath, "utf-8");
|
|
16845
16895
|
const detection = detectProvider(filename, content, config2);
|
|
16896
|
+
let targetPath;
|
|
16897
|
+
let targetFilename;
|
|
16846
16898
|
if (detection) {
|
|
16899
|
+
targetFilename = detection.outputFilename || filename;
|
|
16847
16900
|
const targetDir = path4.join(pendingDir, detection.provider, detection.currency);
|
|
16901
|
+
targetPath = path4.join(targetDir, targetFilename);
|
|
16902
|
+
} else {
|
|
16903
|
+
targetFilename = filename;
|
|
16904
|
+
targetPath = path4.join(unrecognizedDir, filename);
|
|
16905
|
+
}
|
|
16906
|
+
if (fs4.existsSync(targetPath)) {
|
|
16907
|
+
collisions.push({
|
|
16908
|
+
filename,
|
|
16909
|
+
existingPath: targetPath
|
|
16910
|
+
});
|
|
16911
|
+
}
|
|
16912
|
+
plannedMoves.push({
|
|
16913
|
+
filename,
|
|
16914
|
+
sourcePath,
|
|
16915
|
+
targetPath,
|
|
16916
|
+
targetFilename,
|
|
16917
|
+
detection
|
|
16918
|
+
});
|
|
16919
|
+
}
|
|
16920
|
+
if (collisions.length > 0) {
|
|
16921
|
+
return JSON.stringify({
|
|
16922
|
+
success: false,
|
|
16923
|
+
error: `Cannot classify: ${collisions.length} file(s) would overwrite existing pending files.`,
|
|
16924
|
+
collisions,
|
|
16925
|
+
classified: [],
|
|
16926
|
+
unrecognized: []
|
|
16927
|
+
});
|
|
16928
|
+
}
|
|
16929
|
+
const classified = [];
|
|
16930
|
+
const unrecognized = [];
|
|
16931
|
+
for (const move of plannedMoves) {
|
|
16932
|
+
if (move.detection) {
|
|
16933
|
+
const targetDir = path4.dirname(move.targetPath);
|
|
16848
16934
|
ensureDirectory(targetDir);
|
|
16849
|
-
|
|
16850
|
-
fs4.renameSync(sourcePath, targetPath);
|
|
16935
|
+
fs4.renameSync(move.sourcePath, move.targetPath);
|
|
16851
16936
|
classified.push({
|
|
16852
|
-
filename,
|
|
16853
|
-
|
|
16854
|
-
|
|
16855
|
-
|
|
16937
|
+
filename: move.targetFilename,
|
|
16938
|
+
originalFilename: move.detection.outputFilename ? move.filename : undefined,
|
|
16939
|
+
provider: move.detection.provider,
|
|
16940
|
+
currency: move.detection.currency,
|
|
16941
|
+
targetPath: path4.join(config2.paths.pending, move.detection.provider, move.detection.currency, move.targetFilename)
|
|
16856
16942
|
});
|
|
16857
16943
|
} else {
|
|
16858
16944
|
ensureDirectory(unrecognizedDir);
|
|
16859
|
-
|
|
16860
|
-
fs4.renameSync(sourcePath, targetPath);
|
|
16945
|
+
fs4.renameSync(move.sourcePath, move.targetPath);
|
|
16861
16946
|
unrecognized.push({
|
|
16862
|
-
filename,
|
|
16863
|
-
targetPath: path4.join(config2.paths.unrecognized, filename)
|
|
16947
|
+
filename: move.filename,
|
|
16948
|
+
targetPath: path4.join(config2.paths.unrecognized, move.filename)
|
|
16864
16949
|
});
|
|
16865
16950
|
}
|
|
16866
16951
|
}
|
|
@@ -16884,7 +16969,7 @@ var classify_statements_default = tool({
|
|
|
16884
16969
|
}
|
|
16885
16970
|
});
|
|
16886
16971
|
// src/index.ts
|
|
16887
|
-
var __dirname2 =
|
|
16972
|
+
var __dirname2 = dirname2(fileURLToPath(import.meta.url));
|
|
16888
16973
|
var AGENT_FILE = join5(__dirname2, "..", "agent", "accountant.md");
|
|
16889
16974
|
var AccountantPlugin = async () => {
|
|
16890
16975
|
const agent = loadAgent(AGENT_FILE);
|
package/package.json
CHANGED