Repository navigation
Add headless pp-cli for AI-agent access - #6262
Open
idodoron11 wants to merge 133 commits into
Open
idodoron11 wants to merge 133 commits into
idodoron11 wants to merge 133 commits into
Conversation
…including feasibility of loading client files and prior art analysis; update architecture considerations for CLI design.
…arify CLI integration details
…enhance write operations overview
…and safe-write sequence
… structure, validation rules, and backup behavior
…ptions, and MCP server integration
…d packaging options for headless Java CLI
…ersion checks, and password management for CLI
…launch instructions for CLI
- Implement walking skeleton for `pp-cli` with `info` command to return client file details. - Create `describe` command to list all declared commands and their schemas. - Enable reading of encrypted client files and support for all seven formats. - Add master-data list commands with pagination for instruments, investment accounts, and cash accounts. - Implement reference resolver for price history retrieval by UUID, ISIN, ticker, or name. - Create `transactions` command to return joined transaction records with filtering options. - Implement `holdings` command to report ownership and value at a specific date. - Add `performance` command for client performance metrics with period and cost method options. - Extend `performance` command to support account and instrument scopes. - Implement `taxonomies` and `allocation` commands for classification and value reporting. - Create `apply` command for adding and updating instruments with safe-write sequence. - Harden safe-write sequence for `apply` and `restore` commands. - Enable writing back in all formats and migrating older files. - Implement account operations for cash and investment accounts. - Add transaction types for cash-account transactions. - Implement transaction operations for adding, updating, and deleting records. - Create `taxonomy.assign` command for instrument classification. - Implement `restore` command to roll back to backups. - Package Windows and macOS bundles with installation scripts and documentation. - Add `--format table` option for human-readable output in CLI commands.
New additive CLI module and test bundle in the reactor. A single in-process
entry point parses declared commands, loads client files (xml, xml-id-references,
xml-zip, binary), applies a version guard on every load and returns the
{data, meta, warnings} envelope or a problem+json error.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Declares response schemas and write operations alongside commands, renders them in describe with known limits, the pinned tag and maxSupportedVersion, and adds a consistency test that validates real responses against the published schemas. The CLI tests bundle becomes a fragment of the CLI bundle so tests can reach the declarations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Passwords come from PP_PASSWORD or one line on stdin, never a flag. The CLI decrypts the file header itself to report password-required, incorrect-password, file-version-unsupported and the normalized format without depending on core's localized messages. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ed pagination and filtering rules
Record the answers in the spec, tickets 05/15/22/25, ADR 0004 (list output deviations from upstream portfolio-performance#5870) and the glossary (Master data, Reference cash account). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds the instruments, investment-accounts and cash-accounts commands with shared --limit/--offset paging, stable name-then-UUID ordering, typed instrument attributes, and a shared meta helper. OptionSpec now carries an optional type, default and range that describe publishes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Write quote, shares and amount attributes as plain decimals instead of scientific notation, reject "+5" and non-ASCII digits as paging values, and use glossary vocabulary in the published schema descriptions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The readers that cash events, trades and transfers share (accounts, instrument, date and time, currency, amounts, units, gross amount and the refusal of members a kind doesn't take) move from TransactionOperations into TransactionInput. TransactionOperations keeps the schema, the dispatch by type, the cash-event rules and the commit that all kinds share. Codes, fields and messages of every failure are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
transaction.update and transaction.delete found their record among all records of the evolving model, so they could change one that an earlier operation of the same batch had created. The spec allows no in-batch references (story 79: every reference is a UUID that existed before the batch), and every other write already refused them. Transaction records are now an EntityKind like the others: ApplyBatch remembers the transactions that were in the file, and a record exists if its primary side does. The CLI can't reach the case today, because a new record's UUID is only known from the response. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-up: a transfer read its input through three readers over the same operation. Also drops a stray blank line and rewraps the TransactionOperations javadoc. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both directions now share one type list, in the published order, and one unit catalog with a read and a write description per member. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each member of a transaction record is declared once in TransactionShape, with whether a record shows it, whether an add takes it, and a read and a write description. The write help now lists members in read order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The overlay keeps the rendered members that TransactionShape marks as input instead of removing a hand-kept list of derived ones, and drops an empty list of units for every record rather than only for transfers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each member is a named constant, declared with what a record shows and what an add takes, so a derived or never-shown member carries no null description and declares itself on a schema. render() and the update overlay use the members' names instead of literals, an add and an update each have their own declaring method, and the investment-account types sit next to the type list. The overlay and the round-trip test share inputOf, which keeps the members an add takes, from a set, and drops an empty units list only. The test names its investment accounts without "depot". The published schemas are byte-for-byte unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… own The catalog speaks of a member as output (what transactions shows) and as input (what an add takes): Output/Input with their presences, outputType/inputType and inputAs replace Shown/Taken, Read/Write, schemaOf/inputSchemaOf and takenAs. The unit members all carry the UNIT_ prefix, and both unit schemas are fields, UNIT_OUTPUT and UNIT_INPUT. A UUID member and its name member are one NamedUuid that puts both, so render passes one constant per account. The round-trip test lists the members an add takes itself instead of using inputOf, so it no longer checks the catalog with the catalog. A second case updates every type of record with an empty patch and expects it unchanged, which is what covers inputOf in the update overlay. The comment on dropping an empty units list says why. The published schemas are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ReportingCurrency owns what every converting command wired itself: the --currency option and its validation, the base-currency default, figures with their rates and the zero rule, totals, the converted member and its schema, the exchangeRates meta member and the rate warnings. ExchangeRates stays the rate source underneath. Holdings drops its own Figure and Valuation; its output is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Allocation checks its rates with allRated, performance gets its strict converter and its day-counting warnings from the facet. Output unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
transactions --currency is a reporting currency without a default. The command still finds the record's own forex or transfer rate; the facet tries the identity, that rate, then the rate series. Output unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
parseCurrency, converted, convertedSchema, metaSchema and WARNINGS now live in ReportingCurrency; ExchangeRates keeps the rates, the cache and the warning specs it emits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Name the record's own rate after the reporting currency, not a target, as the glossary asks, and say why the own-rate figure takes a code and an amount rather than a Money. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test read every dotted name in the skill as an operation, so the holdings member `converted.amount` in insights.md failed it. A dotted name now passes if it is an operation or a member path in some command's data or meta schema; a misspelling of either still fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
holdings and allocation each kept their own map to warn once per instrument, in the order they met instruments. In allocation that is core's position order, so the order of the warnings changed from run to run. StalePrices now does both for them: one warning per instrument, sorted by name, then UUID. holdings --by-account changes too: an instrument from a later account no longer comes after one it sorts before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Commands read an option as a raw string by name and then parsed it themselves, e.g. DATE.parseDate(context.option(DATE.name())), and Sorting looked its option up by the literal "sort". CommandContext now has text, date, integer and choice accessors that take the OptionSpec and check its declared type, plus given for a presence check that must not reject a bad value (--period with --from stays conflicting-options). option(String) is gone. No output changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…text Each command resolved its reference options by hand, as References.instrument(client, X.name(), context.text(X).get()), and transactions kept a private Resolver to do it for three options. ReferenceOption now ties an option to the kind of entity it names, and context.reference(option, client) returns the entity, or empty when the option is absent. References keeps the matching rules behind one resolve per kind; its four per-kind methods are gone, and ReferencesTest calls resolve directly. Help and responses are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ErrorSpec named the commands that can return reference-not-found, reference-ambiguous and option-required, and nothing checked those lists, so a new reference or required option left its codes out of the command's help. The reference codes now apply to any command that declares a reference option, and option-required to any command that declares a required option. performance is still named: it raises option-required when --with-reference-cash-account comes without --investment-account, a rule no declaration states. The codes from other rules between options keep their lists. Help is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lines flag() now rejects an option that is not a switch, like the other accessors. The type-mismatch test also covers reading a reference option as text and resolving a reference option declared with another type. Lines this branch pushed past 120 characters are wrapped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The CLI package had grown to 78 classes in one flat folder. This is the first of several moves into feature packages. ClientLoader, LoadedClient, EncryptedHeader, FileFormat, FileVersionProbe, SafeWrite, WriteEnvironment and ConsistencyCheck now live in cli.file, with their tests and the historic test files next to them. The declarations used across the new package boundary are now public. Anything used only inside its own package stays package-private. The bundle still exports only the root package, so none of this is visible outside it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ReportingCurrency, ExchangeRates, EcbCache, StrictConverter, Prices and StalePrices now live in cli.currency, with ReportingCurrencyTest and StalePricesTest. As in the cli.file move, only the declarations used across the package boundary are now public. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ormance PerformanceCommand, PerformanceByInstrument, PerformancePeriod, PerformanceScope and CostMethod now live in cli.performance, with PerformanceCommandTest and PerformanceScopesTest. Only the declarations used across the package boundary are now public. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApplyCommand, RestoreCommand, ApplyBatch, the operation framework (OperationContext, OperationInput, OperationSpec, EntityKind) and the per-entity operations, with TransactionInput, TransactionUpdates and OversellGuard, now live in cli.apply. Their tests moved with them. Only the declarations used across the package boundary are now public. The declarations that grew past 120 characters are wrapped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
info, cash-accounts, investment-accounts, instruments, prices, holdings, allocation, taxonomies and transactions now live in cli.query. So do the types they are built on: AttributeCodec, TaxonomyTree, TransactionRecord, TransactionShape and BuiltRecord. Their tests moved with them. Only the declarations used across the package boundary are now public. The declarations that grew past 120 characters are wrapped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CommandSpec, CommandContext, the option and reference types, responses, warnings, schemas, table output, paging, sorting and the master-data helpers now live in cli.command, with their tests. The root package keeps only the entry point and what spans every command: PpCli, ArgumentParser, Commands, HelpText, ErrorSpec, QuietStatusFilter and CoreVersion. The shared test fixtures stay there too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The replacing context counts its own failures, so it never saw a type-immutable or kind-immutable failure and still built the replacement. The batch was refused, but later operations of the same batch validated against the changed record. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Added ticket 01: Define the interface for the Transaction record module, addressing ownership of transaction aspects and interface clarity. - Added ticket 02: Establish the facet interface for commands, focusing on options declaration and error-code scoping. - Added ticket 03: Evaluate the consolidation of Master data kinds into single modules, assessing interface and dependencies. - Added ticket 04: Investigate the necessity of an amounts & rates module, including rounding consistency and conversion rules. - Added ticket 05: Define the valuation module for Reporting currency, ensuring correct conversion and error handling. - Added ticket 06: Clarify the declaration of write operation failure codes for better error management and documentation. - Added ticket 07: Outline the refactoring spec and implementation ticket strategy for seamless integration and testing. - Created a map for the deepening effort, detailing scope, decisions, and outstanding specifications.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…us and enhance documentation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a headless Java 21 CLI that reads calculated figures and safely applies validated changes to client files, preserving supported formats and refusing unsupported file versions.
Evidence
mvn -f portfolio-app/pom.xml verify -Plocal-dev -pl :portfolio-target-definition,:name.abuchen.portfolio.pdfbox1,:name.abuchen.portfolio.pdfbox3,:name.abuchen.portfolio,:name.abuchen.portfolio.cli,:name.abuchen.portfolio.junit,:name.abuchen.portfolio.cli.tests -amMerge Danger
Door: Two-way
The CLI is additive; installations have uninstall scripts, and client-file writes create backups with a restore command.
Blast Radius: Moderate
The write surface can change client files, and installers modify per-user PATH or shell configuration. The desktop workflow remains unchanged.