Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
150403c
Track crypto held on exchanges and wallets by hand (#32)
joaoguimaraespro Oct 4, 2026
4743b79
IBKR: later syncs no longer fail with 1003 (#35)
joaoguimaraespro Oct 4, 2026
ff70eb6
feat(remote-control): finance commands as project skills for the phon…
joaoguimaraespro Oct 4, 2026
a94aa6a
MCP: tools for accounts, savings interest, recurring, any transaction…
joaoguimaraespro Oct 4, 2026
3ecb31d
fix(sync): back off after failed syncs; handle IBKR 1025 lockout; cap…
joaoguimaraespro Oct 4, 2026
ded164a
Portfolio by wallet, with coin icons (#39)
joaoguimaraespro Oct 4, 2026
501d689
fix: weekend day change shows Friday's move; labelled wallet card fig…
joaoguimaraespro Oct 4, 2026
f03dd16
feat(crypto): wallet is always picked from a list, with common exchan…
joaoguimaraespro Oct 4, 2026
56e4f26
feat(portfolio): returns over 1M/YTD/1Y/All with their period stated;…
joaoguimaraespro Oct 5, 2026
b0da12e
AI write access: opt-in write tools with a 30-day recycle bin (ADR-00…
joaoguimaraespro Oct 5, 2026
02adafe
Recurring: every N days (daily frequency with interval) (#44)
joaoguimaraespro Oct 5, 2026
bf45cac
feat(categories): rename any category (built-in too) and reset to the…
joaoguimaraespro Oct 5, 2026
c559a67
feat: notification centre — header bell for pending recurring items, …
joaoguimaraespro Oct 5, 2026
30be72e
Windows deployment: Docker Desktop install, app launcher, auto-start …
joaoguimaraespro Oct 5, 2026
1bb6ac3
Bump the dotnet group with 2 updates (#34)
dependabot[bot] Oct 5, 2026
eb74828
feat: split transactions — one movement over several categories (#48)
joaoguimaraespro Oct 6, 2026
7e29842
Linux and macOS desktop install: app shortcut, sign-in item, catch-up…
joaoguimaraespro Oct 7, 2026
a87d0cf
AI access: activity at a glance, tabs and client cards; full-height f…
joaoguimaraespro Oct 7, 2026
a76b4ea
Monthly allocation like recurring items: automatic done/partial, reco…
joaoguimaraespro Oct 7, 2026
6278a28
Binance: spot and Simple Earn through a key verified as read-only; Ea…
joaoguimaraespro Oct 7, 2026
f79bf1d
Connections: step-by-step Binance guide, like Trading 212 and IBKR (#53)
joaoguimaraespro Oct 8, 2026
9d00e38
Connections: the step-by-step guide lives in the add/fix dialog only …
joaoguimaraespro Oct 8, 2026
4dd68b2
Monthly allocation counts deposits synced at a linked broker; Binance…
joaoguimaraespro Oct 9, 2026
c866946
UI: bundled Inter font, one colour per meaning across charts, clearer…
joaoguimaraespro Oct 9, 2026
51a4279
UI: transactions grouped by day, phone bottom navigation, foldable fi…
joaoguimaraespro Oct 9, 2026
f2b11f6
UI: balanced dashboard and portfolio cards, live budget split, shorte…
joaoguimaraespro Oct 9, 2026
12e3e53
Goals can follow a savings account; recording a savings allocation as…
joaoguimaraespro Oct 10, 2026
ae23086
Loans: terms, amortisation plan, rate revisions, early repayments and…
joaoguimaraespro Oct 10, 2026
d08d335
Loans: instalments proposed for booking, rate-revision reminder, dash…
joaoguimaraespro Oct 10, 2026
1fbacfe
Nav by purpose, Loans page, assistant only when configured, clearer s…
joaoguimaraespro Oct 10, 2026
d52617d
Company logos next to holdings, EUR/USD display currency, SafePal wal…
joaoguimaraespro Oct 10, 2026
920b551
fix(binance): rebuild coin cost from full history; keep first-synced …
joaoguimaraespro Oct 11, 2026
776dd9a
fix(web): translate built-in buckets, skip empty previous month, alwa…
joaoguimaraespro Oct 11, 2026
110ceb2
fix: crypto wallet return from cost; list loans without terms (#69)
joaoguimaraespro Oct 11, 2026
192a30b
feat(binance): cost details per coin (#70)
joaoguimaraespro Oct 11, 2026
602a516
fix(binance): rebuild cost from the account's whole history, kept bet…
joaoguimaraespro Oct 12, 2026
592bd23
feat(web): month and year dropdowns in the date picker (#72)
joaoguimaraespro Oct 12, 2026
9b94473
feat(web): date picker opens years from its heading, then months (#73)
joaoguimaraespro Oct 12, 2026
7a1c293
feat: loan charges in each instalment; IBKR positions follow public p…
joaoguimaraespro Oct 12, 2026
6953fbf
feat(web): charges column in the loan payment plan (#75)
joaoguimaraespro Oct 12, 2026
c6370de
feat: start fresh in Settings; imports only from the app's own archiv…
joaoguimaraespro Oct 12, 2026
acf95f6
feat: Trading 212 spending pot — transfers out of a broker account; p…
joaoguimaraespro Oct 13, 2026
9688037
fix(binance): label crypto wallets' return as gain over cost; show ea…
joaoguimaraespro Oct 13, 2026
1b2602d
fix(web): Binance Earn rewards summed per coin and month; rewards wor…
joaoguimaraespro Oct 13, 2026
7211979
fix(binance): cost like Binance's cost price — the average of everyth…
joaoguimaraespro Oct 13, 2026
083ec08
feat: net worth history before the first snapshot; dashboard cards fo…
joaoguimaraespro Oct 13, 2026
27c64d6
fix(binance): card purchases cost the coins' price, without the card …
joaoguimaraespro Oct 13, 2026
f39216f
fix(binance): coins in cost their market price, as Binance's average …
joaoguimaraespro Oct 13, 2026
f8b1be1
fix(binance): cost in dollars shown at today's rate, as Binance; live…
joaoguimaraespro Oct 13, 2026
977c863
feat: real cost basis in euros for every holding; remove cost details…
joaoguimaraespro Oct 13, 2026
f641b1e
feat(trading212): use Trading 212's own euro cost and value for each …
joaoguimaraespro Oct 14, 2026
f00f74f
fix: savings without a destination account set money aside, they do n…
joaoguimaraespro Oct 14, 2026
01d0b73
feat: refunds lower spending; capital repaid shows in the month (#88)
joaoguimaraespro Oct 14, 2026
8f0295f
feat(web): "this account earns interest" checkbox on bank and savings…
joaoguimaraespro Oct 14, 2026
92d215e
feat: yearly recurring items repeat on a date; varying bills proposed…
joaoguimaraespro Oct 14, 2026
1a41b1c
feat: group accounts by institution; restricted-use balances shown ap…
joaoguimaraespro Oct 15, 2026
22c5f8e
feat: suggest the cost of coins sent from Binance when adding them to…
joaoguimaraespro Oct 15, 2026
ed75022
feat(desktop): desktop mode in the API — own PostgreSQL, serves the w…
joaoguimaraespro Oct 15, 2026
0d8cc62
feat(desktop): native launcher and Windows/macOS installers (#94)
joaoguimaraespro Oct 15, 2026
e109ff3
fix(desktop): first-run text, app name without version, release check…
joaoguimaraespro Oct 15, 2026
143bedf
build(deps): bump the angular group in /web with 10 updates (#60)
dependabot[bot] Oct 15, 2026
2505499
Bump the dotnet group with 4 updates (#61)
dependabot[bot] Oct 15, 2026
e2418de
docs: public-repo documentation and community files (#96)
joaoguimaraespro Oct 15, 2026
63e0c78
build(deps): bump postgres from 17.6-alpine to 17.11-alpine in /deplo…
dependabot[bot] Oct 15, 2026
fabe31d
build(deps): bump actions/download-artifact (#99)
dependabot[bot] Oct 15, 2026
94a30ec
build(deps): bump the angular group in /web with 8 updates (#98)
dependabot[bot] Oct 15, 2026
b61023f
build(deps): bump the web group across 1 directory with 5 updates (#100)
dependabot[bot] Oct 15, 2026
a87ec90
Bump the dotnet group with 16 updates (#101)
dependabot[bot] Oct 15, 2026
45338b3
fix: no account ids or raw user input in logs (code scanning) (#102)
joaoguimaraespro Oct 15, 2026
2eca592
feat(loans): interest on real days (Actual/360) (#103)
joaoguimaraespro Oct 15, 2026
60b91a8
feat(web): accounts show their bank with a coloured monogram (#104)
joaoguimaraespro Oct 15, 2026
3c93619
fix(ai): loans tool, account names without IBANs, refunds lower expen…
joaoguimaraespro Oct 16, 2026
37f207f
feat: shared expenses with people (ADR-0011) (#106)
joaoguimaraespro Oct 16, 2026
9ce7c27
feat: shared recurring items, reminders and dashboard card (#107)
joaoguimaraespro Oct 16, 2026
744241d
feat(web): edit a recurring item's amount before confirming from noti…
joaoguimaraespro Oct 16, 2026
456f7c6
docs: changelog for 1.1.0, the first public release (#109)
joaoguimaraespro Oct 17, 2026
00425ef
feat(sharing): people out of account lists, settle without an account…
joaoguimaraespro Oct 18, 2026
13ca9a7
feat(web): monthly allocation shows its status, with 'not this month'…
joaoguimaraespro Oct 18, 2026
cc8c54c
feat(desktop): MCP server inside the app; uninstall can delete the da…
joaoguimaraespro Oct 18, 2026
eb2286e
feat(portfolio): dividend calendar by month, positions without divide…
joaoguimaraespro Oct 18, 2026
74e3133
feat: delete accounts and people for good; docs for the latest featur…
joaoguimaraespro Oct 18, 2026
389509a
feat: delete custom categories, buckets, goals and assets for good (#…
joaoguimaraespro Oct 19, 2026
2dac85d
feat(web): account selects show the account's bank (#116)
joaoguimaraespro Oct 19, 2026
8d690ca
feat(sharing): what was owed before the app, when adding or editing a…
joaoguimaraespro Oct 19, 2026
d58736e
fix(web): errors visible over dialogs; dialogs validate their fields …
joaoguimaraespro Oct 19, 2026
7cbd8ee
feat(monthly): clearer spending and allocation; the first month is ma…
joaoguimaraespro Oct 20, 2026
0e48a09
docs: changelog for 1.3.0; step-by-step MCP setup for the desktop app…
joaoguimaraespro Oct 20, 2026
4d4a817
feat(recurring): a recurring expense paid by someone else is owed to …
joaoguimaraespro Oct 20, 2026
9f54261
docs: recurring paid by someone else goes in 1.3.0 (#123)
joaoguimaraespro Oct 20, 2026
9eb7bfe
feat(portfolio): a card with the cash at the brokers (#125)
joaoguimaraespro Oct 21, 2026
a67c48d
feat(brokers): synced deposits ask which account the money came from …
joaoguimaraespro Oct 21, 2026
41409a6
feat(web): tables fit a phone without scrolling sideways (#126)
joaoguimaraespro Oct 21, 2026
e5dab90
feat(portfolio): the income chart follows the chosen period, empty mo…
joaoguimaraespro Oct 21, 2026
a696cf9
feat(brokers): a withdrawal can be a payment with the broker's card (…
joaoguimaraespro Oct 21, 2026
6f31fdb
feat(brokers): record a deposit as cash moved to the broker, invested…
joaoguimaraespro Oct 22, 2026
586f687
chore: spec-driven workflow with Spec Kit, agent subagents and loop g…
joaoguimaraespro Oct 22, 2026
f554f27
ci: check formatting and Conventional Commits PR titles (#131)
joaoguimaraespro Oct 22, 2026
3efb7a4
build: Bump the dotnet group with 8 updates
dependabot[bot] Oct 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 12 additions & 0 deletions .agent-loop.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Config for ~/Development/nexus/scripts/agent-loop.sh (one fresh agent per Spec Kit task).
# The loop marks a task done only when VERIFY_CMD exits 0.

# Local gate: build + every backend test project except Integration.Tests (needs Docker), then web tests and format.
VERIFY_CMD='set -e
cd backend && dotnet build --nologo -v q
for p in tests/*.Tests; do case "$p" in */Integration.Tests) continue ;; esac; dotnet test --project "$p" --no-build; done
cd ../web && npm test && npm run lint:format'

SETUP_CMD='cd web && npm ci --no-audit --no-fund'

CLAUDE_ALLOWED_TOOLS='Read,Edit,Write,Glob,Grep,Task,Bash(dotnet build:*),Bash(dotnet test:*),Bash(dotnet format:*),Bash(dotnet ef:*),Bash(npm test:*),Bash(npm run:*),Bash(npx prettier:*),Bash(git status:*),Bash(git diff:*),Bash(ls:*)'
259 changes: 259 additions & 0 deletions .agents/skills/speckit-analyze/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
---
name: "speckit-analyze"
description: "Perform a non-destructive cross-artifact consistency and quality analysis across spec.md, plan.md, and tasks.md after task generation."
compatibility: "Requires spec-kit project structure with .specify/ directory"
metadata:
author: "github-spec-kit"
source: "templates/commands/analyze.md"
---


## User Input

```text
$ARGUMENTS
```

You **MUST** consider the user input before proceeding (if not empty).

## Pre-Execution Checks

**Check for extension hooks (before analysis)**:
- Check if `.specify/extensions.yml` exists in the project root.
- If it exists, read it and look for entries under the `hooks.before_analyze` key
- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally
- Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default.
- For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
- If the hook has no `condition` field, or it is null/empty, treat the hook as executable
- If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation
- When constructing command invocations from hook command names, replace dots (`.`) with hyphens (`-`). For example, `speckit.git.commit` → `$speckit-git-commit`.
- For each executable hook, output the following based on its `optional` flag:
- **Optional hook** (`optional: true`):
```
## Extension Hooks
**Optional Pre-Hook**: {extension}
Command: `/{command}`
Description: {description}
Prompt: {prompt}
To execute: `/{command}`
```
- **Mandatory hook** (`optional: false`):
```
## Extension Hooks
**Automatic Pre-Hook**: {extension}
Executing: `/{command}`
EXECUTE_COMMAND: {command}
Wait for the result of the hook command before proceeding to the Goal.
```
After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
- If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
## Goal
Identify inconsistencies, duplications, ambiguities, and underspecified items across the three core artifacts (`spec.md`, `plan.md`, `tasks.md`) before implementation. This command MUST run only after `$speckit-tasks` has successfully produced a complete `tasks.md`.
## Operating Constraints
**STRICTLY READ-ONLY**: Do **not** modify any files. Output a structured analysis report. Offer an optional remediation plan (user must explicitly approve before any follow-up editing commands would be invoked manually).
**Constitution Authority**: The project constitution (`.specify/memory/constitution.md`) is **non-negotiable** within this analysis scope. Constitution conflicts are automatically CRITICAL and require adjustment of the spec, plan, or tasks—not dilution, reinterpretation, or silent ignoring of the principle. If a principle itself needs to change, that must occur in a separate, explicit constitution update outside `$speckit-analyze`.
## Execution Steps
### 1. Initialize Analysis Context
Run `.specify/scripts/bash/check-prerequisites.sh --json --require-spec --require-tasks --include-tasks` once from repo root and parse JSON for FEATURE_DIR and AVAILABLE_DOCS. Derive absolute paths:
- SPEC = FEATURE_DIR/spec.md
- PLAN = FEATURE_DIR/plan.md
- TASKS = FEATURE_DIR/tasks.md
Abort with an error message if any required file is missing (instruct the user to run missing prerequisite command).
For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\''m Groot' (or double-quote if possible: "I'm Groot").
### 2. Load Artifacts (Progressive Disclosure)
Load only the minimal necessary context from each artifact:
**From spec.md:**
- Overview/Context
- Functional Requirements
- Success Criteria (measurable outcomes — e.g., performance, security, availability, user success, business impact)
- User Stories
- Edge Cases (if present)
**From plan.md:**
- Architecture/stack choices
- Data Model references
- Phases
- Technical constraints
**From tasks.md:**
- Task IDs
- Descriptions
- Phase grouping
- Parallel markers [P]
- Referenced file paths
**From constitution:**
- Load `.specify/memory/constitution.md` for principle validation
### 3. Build Semantic Models
Create internal representations (do not include raw artifacts in output):
- **Requirements inventory**: For each Functional Requirement (FR-###) and Success Criterion (SC-###), record a stable key. Use the explicit FR-/SC- identifier as the primary key when present, and optionally also derive an imperative-phrase slug for readability (e.g., "User can upload file" → `user-can-upload-file`). Include only Success Criteria items that require buildable work (e.g., load-testing infrastructure, security audit tooling), and exclude post-launch outcome metrics and business KPIs (e.g., "Reduce support tickets by 50%").
- **User story/action inventory**: Discrete user actions with acceptance criteria
- **Task coverage mapping**: Map each task to one or more requirements or stories (inference by keyword / explicit reference patterns like IDs or key phrases)
- **Constitution rule set**: Extract principle names and MUST/SHOULD normative statements
### 4. Detection Passes (Token-Efficient Analysis)
Focus on high-signal findings. Limit to 50 findings total; aggregate remainder in overflow summary.
#### A. Duplication Detection
- Identify near-duplicate requirements
- Mark lower-quality phrasing for consolidation
#### B. Ambiguity Detection
- Flag vague adjectives (fast, scalable, secure, intuitive, robust) lacking measurable criteria
- Flag unresolved placeholders (TODO, TKTK, ???, `<placeholder>`, etc.)
#### C. Underspecification
- Requirements with verbs but missing object or measurable outcome
- User stories missing acceptance criteria alignment
- Tasks referencing files or components not defined in spec/plan
#### D. Constitution Alignment
- Any requirement or plan element conflicting with a MUST principle
- Missing mandated sections or quality gates from constitution
#### E. Coverage Gaps
- Requirements with zero associated tasks
- Tasks with no mapped requirement/story
- Success Criteria requiring buildable work (performance, security, availability) not reflected in tasks
#### F. Inconsistency
- Terminology drift (same concept named differently across files)
- Data entities referenced in plan but absent in spec (or vice versa)
- Task ordering contradictions (e.g., integration tasks before foundational setup tasks without dependency note)
- Conflicting requirements (e.g., one requires Next.js while other specifies Vue)
### 5. Severity Assignment
Use this heuristic to prioritize findings:
- **CRITICAL**: Violates constitution MUST, missing core spec artifact, or requirement with zero coverage that blocks baseline functionality
- **HIGH**: Duplicate or conflicting requirement, ambiguous security/performance attribute, untestable acceptance criterion
- **MEDIUM**: Terminology drift, missing non-functional task coverage, underspecified edge case
- **LOW**: Style/wording improvements, minor redundancy not affecting execution order
### 6. Produce Compact Analysis Report
Output a Markdown report (no file writes) with the following structure:
## Specification Analysis Report
| ID | Category | Severity | Location(s) | Summary | Recommendation |
|----|----------|----------|-------------|---------|----------------|
| A1 | Duplication | HIGH | spec.md:L120-134 | Two similar requirements ... | Merge phrasing; keep clearer version |
(Add one row per finding; generate stable IDs prefixed by category initial.)
**Coverage Summary Table:**
| Requirement Key | Has Task? | Task IDs | Notes |
|-----------------|-----------|----------|-------|
**Constitution Alignment Issues:** (if any)
**Unmapped Tasks:** (if any)
**Metrics:**
- Total Requirements
- Total Tasks
- Coverage % (requirements with >=1 task)
- Ambiguity Count
- Duplication Count
- Critical Issues Count
### 7. Provide Next Actions
At end of report, output a concise Next Actions block:
- If CRITICAL issues exist: Recommend resolving before `$speckit-implement`
- If only LOW/MEDIUM: User may proceed, but provide improvement suggestions
- Provide explicit command suggestions: e.g., "Run $speckit-specify with refinement", "Run $speckit-plan to adjust architecture", "Manually edit tasks.md to add coverage for 'performance-metrics'"
### 8. Offer Remediation
Ask the user: "Would you like me to suggest concrete remediation edits for the top N issues?" (Do NOT apply them automatically.)
### 9. Check for extension hooks
After reporting, check if `.specify/extensions.yml` exists in the project root.
- If it exists, read it and look for entries under the `hooks.after_analyze` key
- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally
- Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default.
- For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
- If the hook has no `condition` field, or it is null/empty, treat the hook as executable
- If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation
- When constructing command invocations from hook command names, replace dots (`.`) with hyphens (`-`). For example, `speckit.git.commit` → `$speckit-git-commit`.
- For each executable hook, output the following based on its `optional` flag:
- **Optional hook** (`optional: true`):
```
## Extension Hooks
**Optional Hook**: {extension}
Command: `/{command}`
Description: {description}
Prompt: {prompt}
To execute: `/{command}`
```
- **Mandatory hook** (`optional: false`):
```
## Extension Hooks
**Automatic Hook**: {extension}
Executing: `/{command}`
EXECUTE_COMMAND: {command}
```
After emitting the block above you MUST actually invoke the hook and wait for it to finish before continuing. Run it the same way you would run the command yourself in this agent/session (the invocation may differ from the literal `{command}` id shown above, e.g. a skills-mode agent runs it as `/skill:speckit-...` or `$speckit-...`). Emitting the block alone does not run the hook.
- If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
## Operating Principles
### Context Efficiency
- **Minimal high-signal tokens**: Focus on actionable findings, not exhaustive documentation
- **Progressive disclosure**: Load artifacts incrementally; don't dump all content into analysis
- **Token-efficient output**: Limit findings table to 50 rows; summarize overflow
- **Deterministic results**: Rerunning without changes should produce consistent IDs and counts
### Analysis Guidelines
- **NEVER modify files** (this is read-only analysis)
- **NEVER hallucinate missing sections** (if absent, report them accurately)
- **Prioritize constitution violations** (these are always CRITICAL)
- **Use examples over exhaustive rules** (cite specific instances, not generic patterns)
- **Report zero issues gracefully** (emit success report with coverage statistics)
## Context
$ARGUMENTS
Loading
Loading