pigeongov 0.2.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/AGENTS.md +258 -0
- package/LICENSE +21 -0
- package/PRIVACY.md +38 -0
- package/README.md +234 -0
- package/agents.json +72 -0
- package/dist/bin/pigeongov.d.ts +2 -0
- package/dist/bin/pigeongov.js +4 -0
- package/dist/bin/pigeongov.js.map +1 -0
- package/dist/src/advisory/decision-support/contribution-optimizer.d.ts +36 -0
- package/dist/src/advisory/decision-support/contribution-optimizer.js +88 -0
- package/dist/src/advisory/decision-support/contribution-optimizer.js.map +1 -0
- package/dist/src/advisory/decision-support/deduction-optimizer.d.ts +31 -0
- package/dist/src/advisory/decision-support/deduction-optimizer.js +96 -0
- package/dist/src/advisory/decision-support/deduction-optimizer.js.map +1 -0
- package/dist/src/advisory/life-events/events.d.ts +4 -0
- package/dist/src/advisory/life-events/events.js +156 -0
- package/dist/src/advisory/life-events/events.js.map +1 -0
- package/dist/src/advisory/life-events/planner.d.ts +19 -0
- package/dist/src/advisory/life-events/planner.js +72 -0
- package/dist/src/advisory/life-events/planner.js.map +1 -0
- package/dist/src/advisory/screener/engine.d.ts +4 -0
- package/dist/src/advisory/screener/engine.js +368 -0
- package/dist/src/advisory/screener/engine.js.map +1 -0
- package/dist/src/advisory/screener/intake.d.ts +68 -0
- package/dist/src/advisory/screener/intake.js +93 -0
- package/dist/src/advisory/screener/intake.js.map +1 -0
- package/dist/src/analytics/stats.d.ts +18 -0
- package/dist/src/analytics/stats.js +158 -0
- package/dist/src/analytics/stats.js.map +1 -0
- package/dist/src/api/handlers/deadlines.d.ts +2 -0
- package/dist/src/api/handlers/deadlines.js +7 -0
- package/dist/src/api/handlers/deadlines.js.map +1 -0
- package/dist/src/api/handlers/openapi.d.ts +2 -0
- package/dist/src/api/handlers/openapi.js +7 -0
- package/dist/src/api/handlers/openapi.js.map +1 -0
- package/dist/src/api/handlers/workflows.d.ts +5 -0
- package/dist/src/api/handlers/workflows.js +73 -0
- package/dist/src/api/handlers/workflows.js.map +1 -0
- package/dist/src/api/index.d.ts +20 -0
- package/dist/src/api/index.js +70 -0
- package/dist/src/api/index.js.map +1 -0
- package/dist/src/api/openapi.d.ts +5 -0
- package/dist/src/api/openapi.js +384 -0
- package/dist/src/api/openapi.js.map +1 -0
- package/dist/src/api/router.d.ts +19 -0
- package/dist/src/api/router.js +57 -0
- package/dist/src/api/router.js.map +1 -0
- package/dist/src/cli/commands/completions.d.ts +2 -0
- package/dist/src/cli/commands/completions.js +396 -0
- package/dist/src/cli/commands/completions.js.map +1 -0
- package/dist/src/cli/commands/deadlines.d.ts +2 -0
- package/dist/src/cli/commands/deadlines.js +47 -0
- package/dist/src/cli/commands/deadlines.js.map +1 -0
- package/dist/src/cli/commands/doctor.d.ts +2 -0
- package/dist/src/cli/commands/doctor.js +50 -0
- package/dist/src/cli/commands/doctor.js.map +1 -0
- package/dist/src/cli/commands/drafts.d.ts +2 -0
- package/dist/src/cli/commands/drafts.js +75 -0
- package/dist/src/cli/commands/drafts.js.map +1 -0
- package/dist/src/cli/commands/extract.d.ts +2 -0
- package/dist/src/cli/commands/extract.js +17 -0
- package/dist/src/cli/commands/extract.js.map +1 -0
- package/dist/src/cli/commands/fees.d.ts +2 -0
- package/dist/src/cli/commands/fees.js +40 -0
- package/dist/src/cli/commands/fees.js.map +1 -0
- package/dist/src/cli/commands/fill.d.ts +25 -0
- package/dist/src/cli/commands/fill.js +354 -0
- package/dist/src/cli/commands/fill.js.map +1 -0
- package/dist/src/cli/commands/glossary.d.ts +2 -0
- package/dist/src/cli/commands/glossary.js +90 -0
- package/dist/src/cli/commands/glossary.js.map +1 -0
- package/dist/src/cli/commands/life-event.d.ts +2 -0
- package/dist/src/cli/commands/life-event.js +41 -0
- package/dist/src/cli/commands/life-event.js.map +1 -0
- package/dist/src/cli/commands/list.d.ts +2 -0
- package/dist/src/cli/commands/list.js +19 -0
- package/dist/src/cli/commands/list.js.map +1 -0
- package/dist/src/cli/commands/machine.d.ts +2 -0
- package/dist/src/cli/commands/machine.js +100 -0
- package/dist/src/cli/commands/machine.js.map +1 -0
- package/dist/src/cli/commands/merge.d.ts +2 -0
- package/dist/src/cli/commands/merge.js +24 -0
- package/dist/src/cli/commands/merge.js.map +1 -0
- package/dist/src/cli/commands/plugin.d.ts +2 -0
- package/dist/src/cli/commands/plugin.js +119 -0
- package/dist/src/cli/commands/plugin.js.map +1 -0
- package/dist/src/cli/commands/profile.d.ts +2 -0
- package/dist/src/cli/commands/profile.js +125 -0
- package/dist/src/cli/commands/profile.js.map +1 -0
- package/dist/src/cli/commands/review.d.ts +2 -0
- package/dist/src/cli/commands/review.js +25 -0
- package/dist/src/cli/commands/review.js.map +1 -0
- package/dist/src/cli/commands/scaffold.d.ts +2 -0
- package/dist/src/cli/commands/scaffold.js +304 -0
- package/dist/src/cli/commands/scaffold.js.map +1 -0
- package/dist/src/cli/commands/schemas.d.ts +2 -0
- package/dist/src/cli/commands/schemas.js +14 -0
- package/dist/src/cli/commands/schemas.js.map +1 -0
- package/dist/src/cli/commands/screen.d.ts +2 -0
- package/dist/src/cli/commands/screen.js +89 -0
- package/dist/src/cli/commands/screen.js.map +1 -0
- package/dist/src/cli/commands/serve.d.ts +2 -0
- package/dist/src/cli/commands/serve.js +46 -0
- package/dist/src/cli/commands/serve.js.map +1 -0
- package/dist/src/cli/commands/start.d.ts +2 -0
- package/dist/src/cli/commands/start.js +16 -0
- package/dist/src/cli/commands/start.js.map +1 -0
- package/dist/src/cli/commands/stats.d.ts +2 -0
- package/dist/src/cli/commands/stats.js +17 -0
- package/dist/src/cli/commands/stats.js.map +1 -0
- package/dist/src/cli/commands/testdata.d.ts +2 -0
- package/dist/src/cli/commands/testdata.js +60 -0
- package/dist/src/cli/commands/testdata.js.map +1 -0
- package/dist/src/cli/commands/tui.d.ts +2 -0
- package/dist/src/cli/commands/tui.js +26 -0
- package/dist/src/cli/commands/tui.js.map +1 -0
- package/dist/src/cli/commands/validate.d.ts +2 -0
- package/dist/src/cli/commands/validate.js +22 -0
- package/dist/src/cli/commands/validate.js.map +1 -0
- package/dist/src/cli/commands/vault.d.ts +2 -0
- package/dist/src/cli/commands/vault.js +73 -0
- package/dist/src/cli/commands/vault.js.map +1 -0
- package/dist/src/cli/commands/workflows.d.ts +2 -0
- package/dist/src/cli/commands/workflows.js +23 -0
- package/dist/src/cli/commands/workflows.js.map +1 -0
- package/dist/src/cli/display/review.d.ts +2 -0
- package/dist/src/cli/display/review.js +4 -0
- package/dist/src/cli/display/review.js.map +1 -0
- package/dist/src/cli/display/summary.d.ts +2 -0
- package/dist/src/cli/display/summary.js +19 -0
- package/dist/src/cli/display/summary.js.map +1 -0
- package/dist/src/cli/display/validation.d.ts +2 -0
- package/dist/src/cli/display/validation.js +16 -0
- package/dist/src/cli/display/validation.js.map +1 -0
- package/dist/src/cli/index.d.ts +1 -0
- package/dist/src/cli/index.js +83 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/output.d.ts +21 -0
- package/dist/src/cli/output.js +107 -0
- package/dist/src/cli/output.js.map +1 -0
- package/dist/src/cli/prompts/common.d.ts +21 -0
- package/dist/src/cli/prompts/common.js +53 -0
- package/dist/src/cli/prompts/common.js.map +1 -0
- package/dist/src/cli/prompts/credits.d.ts +3 -0
- package/dist/src/cli/prompts/credits.js +23 -0
- package/dist/src/cli/prompts/credits.js.map +1 -0
- package/dist/src/cli/prompts/deductions.d.ts +12 -0
- package/dist/src/cli/prompts/deductions.js +26 -0
- package/dist/src/cli/prompts/deductions.js.map +1 -0
- package/dist/src/cli/prompts/identity.d.ts +8 -0
- package/dist/src/cli/prompts/identity.js +36 -0
- package/dist/src/cli/prompts/identity.js.map +1 -0
- package/dist/src/cli/prompts/income.d.ts +15 -0
- package/dist/src/cli/prompts/income.js +61 -0
- package/dist/src/cli/prompts/income.js.map +1 -0
- package/dist/src/cli/prompts/workflow.d.ts +3 -0
- package/dist/src/cli/prompts/workflow.js +74 -0
- package/dist/src/cli/prompts/workflow.js.map +1 -0
- package/dist/src/cli/support.d.ts +53 -0
- package/dist/src/cli/support.js +80 -0
- package/dist/src/cli/support.js.map +1 -0
- package/dist/src/cli/tui.d.ts +22 -0
- package/dist/src/cli/tui.js +122 -0
- package/dist/src/cli/tui.js.map +1 -0
- package/dist/src/engine/audit-risk/scorer.d.ts +36 -0
- package/dist/src/engine/audit-risk/scorer.js +132 -0
- package/dist/src/engine/audit-risk/scorer.js.map +1 -0
- package/dist/src/engine/crypto/cost-basis.d.ts +19 -0
- package/dist/src/engine/crypto/cost-basis.js +115 -0
- package/dist/src/engine/crypto/cost-basis.js.map +1 -0
- package/dist/src/engine/crypto/transaction-parser.d.ts +36 -0
- package/dist/src/engine/crypto/transaction-parser.js +124 -0
- package/dist/src/engine/crypto/transaction-parser.js.map +1 -0
- package/dist/src/engine/crypto/wash-sale.d.ts +25 -0
- package/dist/src/engine/crypto/wash-sale.js +51 -0
- package/dist/src/engine/crypto/wash-sale.js.map +1 -0
- package/dist/src/engine/equity/espp.d.ts +41 -0
- package/dist/src/engine/equity/espp.js +90 -0
- package/dist/src/engine/equity/espp.js.map +1 -0
- package/dist/src/engine/equity/iso.d.ts +42 -0
- package/dist/src/engine/equity/iso.js +94 -0
- package/dist/src/engine/equity/iso.js.map +1 -0
- package/dist/src/engine/equity/nso.d.ts +35 -0
- package/dist/src/engine/equity/nso.js +63 -0
- package/dist/src/engine/equity/nso.js.map +1 -0
- package/dist/src/engine/equity/rsu.d.ts +33 -0
- package/dist/src/engine/equity/rsu.js +64 -0
- package/dist/src/engine/equity/rsu.js.map +1 -0
- package/dist/src/engine/field-mapper.d.ts +26 -0
- package/dist/src/engine/field-mapper.js +119 -0
- package/dist/src/engine/field-mapper.js.map +1 -0
- package/dist/src/engine/forms/core-1040.d.ts +2 -0
- package/dist/src/engine/forms/core-1040.js +124 -0
- package/dist/src/engine/forms/core-1040.js.map +1 -0
- package/dist/src/engine/forms/form-8949.d.ts +21 -0
- package/dist/src/engine/forms/form-8949.js +96 -0
- package/dist/src/engine/forms/form-8949.js.map +1 -0
- package/dist/src/engine/forms/index.d.ts +7 -0
- package/dist/src/engine/forms/index.js +6 -0
- package/dist/src/engine/forms/index.js.map +1 -0
- package/dist/src/engine/forms/schedule-b.d.ts +15 -0
- package/dist/src/engine/forms/schedule-b.js +78 -0
- package/dist/src/engine/forms/schedule-b.js.map +1 -0
- package/dist/src/engine/forms/schedule-d.d.ts +9 -0
- package/dist/src/engine/forms/schedule-d.js +86 -0
- package/dist/src/engine/forms/schedule-d.js.map +1 -0
- package/dist/src/engine/fpl.d.ts +70 -0
- package/dist/src/engine/fpl.js +127 -0
- package/dist/src/engine/fpl.js.map +1 -0
- package/dist/src/engine/gig/home-office.d.ts +34 -0
- package/dist/src/engine/gig/home-office.js +53 -0
- package/dist/src/engine/gig/home-office.js.map +1 -0
- package/dist/src/engine/gig/mileage.d.ts +30 -0
- package/dist/src/engine/gig/mileage.js +45 -0
- package/dist/src/engine/gig/mileage.js.map +1 -0
- package/dist/src/engine/gig/multi-1099.d.ts +19 -0
- package/dist/src/engine/gig/multi-1099.js +28 -0
- package/dist/src/engine/gig/multi-1099.js.map +1 -0
- package/dist/src/engine/multiyear/carryforward.d.ts +31 -0
- package/dist/src/engine/multiyear/carryforward.js +77 -0
- package/dist/src/engine/multiyear/carryforward.js.map +1 -0
- package/dist/src/engine/multiyear/compare.d.ts +25 -0
- package/dist/src/engine/multiyear/compare.js +94 -0
- package/dist/src/engine/multiyear/compare.js.map +1 -0
- package/dist/src/engine/multiyear/import.d.ts +23 -0
- package/dist/src/engine/multiyear/import.js +193 -0
- package/dist/src/engine/multiyear/import.js.map +1 -0
- package/dist/src/engine/optimizer/filing-status.d.ts +29 -0
- package/dist/src/engine/optimizer/filing-status.js +66 -0
- package/dist/src/engine/optimizer/filing-status.js.map +1 -0
- package/dist/src/engine/orchestrator.d.ts +14 -0
- package/dist/src/engine/orchestrator.js +135 -0
- package/dist/src/engine/orchestrator.js.map +1 -0
- package/dist/src/engine/scenarios/whatif.d.ts +34 -0
- package/dist/src/engine/scenarios/whatif.js +70 -0
- package/dist/src/engine/scenarios/whatif.js.map +1 -0
- package/dist/src/engine/state/ca/calculator.d.ts +3 -0
- package/dist/src/engine/state/ca/calculator.js +107 -0
- package/dist/src/engine/state/ca/calculator.js.map +1 -0
- package/dist/src/engine/state/common.d.ts +39 -0
- package/dist/src/engine/state/common.js +115 -0
- package/dist/src/engine/state/common.js.map +1 -0
- package/dist/src/engine/state/ga/calculator.d.ts +3 -0
- package/dist/src/engine/state/ga/calculator.js +82 -0
- package/dist/src/engine/state/ga/calculator.js.map +1 -0
- package/dist/src/engine/state/il/calculator.d.ts +3 -0
- package/dist/src/engine/state/il/calculator.js +49 -0
- package/dist/src/engine/state/il/calculator.js.map +1 -0
- package/dist/src/engine/state/mi/calculator.d.ts +3 -0
- package/dist/src/engine/state/mi/calculator.js +60 -0
- package/dist/src/engine/state/mi/calculator.js.map +1 -0
- package/dist/src/engine/state/nc/calculator.d.ts +3 -0
- package/dist/src/engine/state/nc/calculator.js +54 -0
- package/dist/src/engine/state/nc/calculator.js.map +1 -0
- package/dist/src/engine/state/nj/calculator.d.ts +3 -0
- package/dist/src/engine/state/nj/calculator.js +90 -0
- package/dist/src/engine/state/nj/calculator.js.map +1 -0
- package/dist/src/engine/state/ny/calculator.d.ts +3 -0
- package/dist/src/engine/state/ny/calculator.js +103 -0
- package/dist/src/engine/state/ny/calculator.js.map +1 -0
- package/dist/src/engine/state/oh/calculator.d.ts +3 -0
- package/dist/src/engine/state/oh/calculator.js +79 -0
- package/dist/src/engine/state/oh/calculator.js.map +1 -0
- package/dist/src/engine/state/pa/calculator.d.ts +3 -0
- package/dist/src/engine/state/pa/calculator.js +58 -0
- package/dist/src/engine/state/pa/calculator.js.map +1 -0
- package/dist/src/engine/state/registry.d.ts +9 -0
- package/dist/src/engine/state/registry.js +67 -0
- package/dist/src/engine/state/registry.js.map +1 -0
- package/dist/src/engine/state/types.d.ts +57 -0
- package/dist/src/engine/state/types.js +2 -0
- package/dist/src/engine/state/types.js.map +1 -0
- package/dist/src/engine/state/va/calculator.d.ts +3 -0
- package/dist/src/engine/state/va/calculator.js +76 -0
- package/dist/src/engine/state/va/calculator.js.map +1 -0
- package/dist/src/engine/suggestions/missed-deductions.d.ts +43 -0
- package/dist/src/engine/suggestions/missed-deductions.js +128 -0
- package/dist/src/engine/suggestions/missed-deductions.js.map +1 -0
- package/dist/src/engine/tax-calculator.d.ts +55 -0
- package/dist/src/engine/tax-calculator.js +156 -0
- package/dist/src/engine/tax-calculator.js.map +1 -0
- package/dist/src/engine/tax-constants-2025.d.ts +56 -0
- package/dist/src/engine/tax-constants-2025.js +138 -0
- package/dist/src/engine/tax-constants-2025.js.map +1 -0
- package/dist/src/engine/types.d.ts +77 -0
- package/dist/src/engine/types.js +2 -0
- package/dist/src/engine/types.js.map +1 -0
- package/dist/src/engine/va-math.d.ts +24 -0
- package/dist/src/engine/va-math.js +90 -0
- package/dist/src/engine/va-math.js.map +1 -0
- package/dist/src/engine/validator.d.ts +7 -0
- package/dist/src/engine/validator.js +108 -0
- package/dist/src/engine/validator.js.map +1 -0
- package/dist/src/glossary/entries/healthcare.d.ts +2 -0
- package/dist/src/glossary/entries/healthcare.js +78 -0
- package/dist/src/glossary/entries/healthcare.js.map +1 -0
- package/dist/src/glossary/entries/immigration.d.ts +2 -0
- package/dist/src/glossary/entries/immigration.js +112 -0
- package/dist/src/glossary/entries/immigration.js.map +1 -0
- package/dist/src/glossary/entries/tax.d.ts +2 -0
- package/dist/src/glossary/entries/tax.js +149 -0
- package/dist/src/glossary/entries/tax.js.map +1 -0
- package/dist/src/glossary/entries/unemployment.d.ts +2 -0
- package/dist/src/glossary/entries/unemployment.js +52 -0
- package/dist/src/glossary/entries/unemployment.js.map +1 -0
- package/dist/src/glossary/index.d.ts +19 -0
- package/dist/src/glossary/index.js +39 -0
- package/dist/src/glossary/index.js.map +1 -0
- package/dist/src/i18n/index.d.ts +21 -0
- package/dist/src/i18n/index.js +92 -0
- package/dist/src/i18n/index.js.map +1 -0
- package/dist/src/mcp/result.d.ts +3 -0
- package/dist/src/mcp/result.js +7 -0
- package/dist/src/mcp/result.js.map +1 -0
- package/dist/src/mcp/return-bundle.d.ts +19 -0
- package/dist/src/mcp/return-bundle.js +49 -0
- package/dist/src/mcp/return-bundle.js.map +1 -0
- package/dist/src/mcp/shared.d.ts +49102 -0
- package/dist/src/mcp/shared.js +354 -0
- package/dist/src/mcp/shared.js.map +1 -0
- package/dist/src/mcp/tools/build-packet.d.ts +7 -0
- package/dist/src/mcp/tools/build-packet.js +23 -0
- package/dist/src/mcp/tools/build-packet.js.map +1 -0
- package/dist/src/mcp/tools/calculate-tax.d.ts +40 -0
- package/dist/src/mcp/tools/calculate-tax.js +17 -0
- package/dist/src/mcp/tools/calculate-tax.js.map +1 -0
- package/dist/src/mcp/tools/deadlines.d.ts +7 -0
- package/dist/src/mcp/tools/deadlines.js +23 -0
- package/dist/src/mcp/tools/deadlines.js.map +1 -0
- package/dist/src/mcp/tools/describe-form.d.ts +14 -0
- package/dist/src/mcp/tools/describe-form.js +23 -0
- package/dist/src/mcp/tools/describe-form.js.map +1 -0
- package/dist/src/mcp/tools/describe-workflow.d.ts +6 -0
- package/dist/src/mcp/tools/describe-workflow.js +16 -0
- package/dist/src/mcp/tools/describe-workflow.js.map +1 -0
- package/dist/src/mcp/tools/explain-flag.d.ts +7 -0
- package/dist/src/mcp/tools/explain-flag.js +19 -0
- package/dist/src/mcp/tools/explain-flag.js.map +1 -0
- package/dist/src/mcp/tools/extract-document.d.ts +13 -0
- package/dist/src/mcp/tools/extract-document.js +20 -0
- package/dist/src/mcp/tools/extract-document.js.map +1 -0
- package/dist/src/mcp/tools/fees.d.ts +7 -0
- package/dist/src/mcp/tools/fees.js +24 -0
- package/dist/src/mcp/tools/fees.js.map +1 -0
- package/dist/src/mcp/tools/fill-form.d.ts +56 -0
- package/dist/src/mcp/tools/fill-form.js +47 -0
- package/dist/src/mcp/tools/fill-form.js.map +1 -0
- package/dist/src/mcp/tools/fill-workflow.d.ts +7 -0
- package/dist/src/mcp/tools/fill-workflow.js +24 -0
- package/dist/src/mcp/tools/fill-workflow.js.map +1 -0
- package/dist/src/mcp/tools/glossary.d.ts +8 -0
- package/dist/src/mcp/tools/glossary.js +54 -0
- package/dist/src/mcp/tools/glossary.js.map +1 -0
- package/dist/src/mcp/tools/list-forms.d.ts +6 -0
- package/dist/src/mcp/tools/list-forms.js +15 -0
- package/dist/src/mcp/tools/list-forms.js.map +1 -0
- package/dist/src/mcp/tools/list-workflows.d.ts +6 -0
- package/dist/src/mcp/tools/list-workflows.js +16 -0
- package/dist/src/mcp/tools/list-workflows.js.map +1 -0
- package/dist/src/mcp/tools/plan-life-event.d.ts +59 -0
- package/dist/src/mcp/tools/plan-life-event.js +41 -0
- package/dist/src/mcp/tools/plan-life-event.js.map +1 -0
- package/dist/src/mcp/tools/review-form.d.ts +40 -0
- package/dist/src/mcp/tools/review-form.js +26 -0
- package/dist/src/mcp/tools/review-form.js.map +1 -0
- package/dist/src/mcp/tools/review-workflow.d.ts +7 -0
- package/dist/src/mcp/tools/review-workflow.js +27 -0
- package/dist/src/mcp/tools/review-workflow.js.map +1 -0
- package/dist/src/mcp/tools/screen-eligibility.d.ts +53 -0
- package/dist/src/mcp/tools/screen-eligibility.js +44 -0
- package/dist/src/mcp/tools/screen-eligibility.js.map +1 -0
- package/dist/src/mcp/tools/start-workflow.d.ts +6 -0
- package/dist/src/mcp/tools/start-workflow.js +17 -0
- package/dist/src/mcp/tools/start-workflow.js.map +1 -0
- package/dist/src/mcp/tools/validate-form.d.ts +48 -0
- package/dist/src/mcp/tools/validate-form.js +30 -0
- package/dist/src/mcp/tools/validate-form.js.map +1 -0
- package/dist/src/mcp/tools/validate-workflow.d.ts +7 -0
- package/dist/src/mcp/tools/validate-workflow.js +24 -0
- package/dist/src/mcp/tools/validate-workflow.js.map +1 -0
- package/dist/src/pdf/batch.d.ts +8 -0
- package/dist/src/pdf/batch.js +15 -0
- package/dist/src/pdf/batch.js.map +1 -0
- package/dist/src/pdf/merge.d.ts +10 -0
- package/dist/src/pdf/merge.js +62 -0
- package/dist/src/pdf/merge.js.map +1 -0
- package/dist/src/pdf/ocr.d.ts +22 -0
- package/dist/src/pdf/ocr.js +52 -0
- package/dist/src/pdf/ocr.js.map +1 -0
- package/dist/src/pdf/reader.d.ts +2 -0
- package/dist/src/pdf/reader.js +354 -0
- package/dist/src/pdf/reader.js.map +1 -0
- package/dist/src/pdf/shared.d.ts +89 -0
- package/dist/src/pdf/shared.js +137 -0
- package/dist/src/pdf/shared.js.map +1 -0
- package/dist/src/pdf/writer.d.ts +7 -0
- package/dist/src/pdf/writer.js +311 -0
- package/dist/src/pdf/writer.js.map +1 -0
- package/dist/src/plugins/loader.d.ts +15 -0
- package/dist/src/plugins/loader.js +86 -0
- package/dist/src/plugins/loader.js.map +1 -0
- package/dist/src/plugins/sandbox.d.ts +14 -0
- package/dist/src/plugins/sandbox.js +88 -0
- package/dist/src/plugins/sandbox.js.map +1 -0
- package/dist/src/plugins/types.d.ts +17 -0
- package/dist/src/plugins/types.js +13 -0
- package/dist/src/plugins/types.js.map +1 -0
- package/dist/src/schemas/2025/f1040.d.ts +127 -0
- package/dist/src/schemas/2025/f1040.js +104 -0
- package/dist/src/schemas/2025/f1040.js.map +1 -0
- package/dist/src/schemas/2025/f1099-int.d.ts +53 -0
- package/dist/src/schemas/2025/f1099-int.js +51 -0
- package/dist/src/schemas/2025/f1099-int.js.map +1 -0
- package/dist/src/schemas/2025/f1099-nec.d.ts +47 -0
- package/dist/src/schemas/2025/f1099-nec.js +45 -0
- package/dist/src/schemas/2025/f1099-nec.js.map +1 -0
- package/dist/src/schemas/2025/form-8949.d.ts +46 -0
- package/dist/src/schemas/2025/form-8949.js +71 -0
- package/dist/src/schemas/2025/form-8949.js.map +1 -0
- package/dist/src/schemas/2025/index.d.ts +1004 -0
- package/dist/src/schemas/2025/index.js +60 -0
- package/dist/src/schemas/2025/index.js.map +1 -0
- package/dist/src/schemas/2025/schedule-1.d.ts +44 -0
- package/dist/src/schemas/2025/schedule-1.js +56 -0
- package/dist/src/schemas/2025/schedule-1.js.map +1 -0
- package/dist/src/schemas/2025/schedule-b.d.ts +32 -0
- package/dist/src/schemas/2025/schedule-b.js +53 -0
- package/dist/src/schemas/2025/schedule-b.js.map +1 -0
- package/dist/src/schemas/2025/schedule-c.d.ts +58 -0
- package/dist/src/schemas/2025/schedule-c.js +46 -0
- package/dist/src/schemas/2025/schedule-c.js.map +1 -0
- package/dist/src/schemas/2025/schedule-d.d.ts +36 -0
- package/dist/src/schemas/2025/schedule-d.js +52 -0
- package/dist/src/schemas/2025/schedule-d.js.map +1 -0
- package/dist/src/schemas/2025/shared.d.ts +98 -0
- package/dist/src/schemas/2025/shared.js +161 -0
- package/dist/src/schemas/2025/shared.js.map +1 -0
- package/dist/src/schemas/2025/w2.d.ts +57 -0
- package/dist/src/schemas/2025/w2.js +62 -0
- package/dist/src/schemas/2025/w2.js.map +1 -0
- package/dist/src/storage/drafts.d.ts +25 -0
- package/dist/src/storage/drafts.js +117 -0
- package/dist/src/storage/drafts.js.map +1 -0
- package/dist/src/storage/paths.d.ts +15 -0
- package/dist/src/storage/paths.js +33 -0
- package/dist/src/storage/paths.js.map +1 -0
- package/dist/src/storage/profile.d.ts +17 -0
- package/dist/src/storage/profile.js +59 -0
- package/dist/src/storage/profile.js.map +1 -0
- package/dist/src/storage/vault.d.ts +38 -0
- package/dist/src/storage/vault.js +187 -0
- package/dist/src/storage/vault.js.map +1 -0
- package/dist/src/testing/synthetic.d.ts +13 -0
- package/dist/src/testing/synthetic.js +164 -0
- package/dist/src/testing/synthetic.js.map +1 -0
- package/dist/src/types.d.ts +362 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/workflows/deadlines.d.ts +13 -0
- package/dist/src/workflows/deadlines.js +88 -0
- package/dist/src/workflows/deadlines.js.map +1 -0
- package/dist/src/workflows/domains/benefits.d.ts +409 -0
- package/dist/src/workflows/domains/benefits.js +744 -0
- package/dist/src/workflows/domains/benefits.js.map +1 -0
- package/dist/src/workflows/domains/business.d.ts +65 -0
- package/dist/src/workflows/domains/business.js +76 -0
- package/dist/src/workflows/domains/business.js.map +1 -0
- package/dist/src/workflows/domains/education.d.ts +251 -0
- package/dist/src/workflows/domains/education.js +504 -0
- package/dist/src/workflows/domains/education.js.map +1 -0
- package/dist/src/workflows/domains/estate.d.ts +217 -0
- package/dist/src/workflows/domains/estate.js +407 -0
- package/dist/src/workflows/domains/estate.js.map +1 -0
- package/dist/src/workflows/domains/healthcare-ext.d.ts +88 -0
- package/dist/src/workflows/domains/healthcare-ext.js +150 -0
- package/dist/src/workflows/domains/healthcare-ext.js.map +1 -0
- package/dist/src/workflows/domains/healthcare.d.ts +92 -0
- package/dist/src/workflows/domains/healthcare.js +126 -0
- package/dist/src/workflows/domains/healthcare.js.map +1 -0
- package/dist/src/workflows/domains/identity-domain.d.ts +291 -0
- package/dist/src/workflows/domains/identity-domain.js +541 -0
- package/dist/src/workflows/domains/identity-domain.js.map +1 -0
- package/dist/src/workflows/domains/immigration-ext.d.ts +282 -0
- package/dist/src/workflows/domains/immigration-ext.js +590 -0
- package/dist/src/workflows/domains/immigration-ext.js.map +1 -0
- package/dist/src/workflows/domains/immigration.d.ts +121 -0
- package/dist/src/workflows/domains/immigration.js +152 -0
- package/dist/src/workflows/domains/immigration.js.map +1 -0
- package/dist/src/workflows/domains/legal.d.ts +235 -0
- package/dist/src/workflows/domains/legal.js +380 -0
- package/dist/src/workflows/domains/legal.js.map +1 -0
- package/dist/src/workflows/domains/permits.d.ts +65 -0
- package/dist/src/workflows/domains/permits.js +74 -0
- package/dist/src/workflows/domains/permits.js.map +1 -0
- package/dist/src/workflows/domains/retirement.d.ts +59 -0
- package/dist/src/workflows/domains/retirement.js +155 -0
- package/dist/src/workflows/domains/retirement.js.map +1 -0
- package/dist/src/workflows/domains/tax.d.ts +133 -0
- package/dist/src/workflows/domains/tax.js +187 -0
- package/dist/src/workflows/domains/tax.js.map +1 -0
- package/dist/src/workflows/domains/unemployment.d.ts +105 -0
- package/dist/src/workflows/domains/unemployment.js +122 -0
- package/dist/src/workflows/domains/unemployment.js.map +1 -0
- package/dist/src/workflows/domains/veterans.d.ts +189 -0
- package/dist/src/workflows/domains/veterans.js +380 -0
- package/dist/src/workflows/domains/veterans.js.map +1 -0
- package/dist/src/workflows/fees.d.ts +15 -0
- package/dist/src/workflows/fees.js +93 -0
- package/dist/src/workflows/fees.js.map +1 -0
- package/dist/src/workflows/helpers.d.ts +8 -0
- package/dist/src/workflows/helpers.js +66 -0
- package/dist/src/workflows/helpers.js.map +1 -0
- package/dist/src/workflows/io.d.ts +3 -0
- package/dist/src/workflows/io.js +38 -0
- package/dist/src/workflows/io.js.map +1 -0
- package/dist/src/workflows/registry.d.ts +51355 -0
- package/dist/src/workflows/registry.js +140 -0
- package/dist/src/workflows/registry.js.map +1 -0
- package/dist/src/workflows/schemas/benefits.d.ts +78 -0
- package/dist/src/workflows/schemas/benefits.js +91 -0
- package/dist/src/workflows/schemas/benefits.js.map +1 -0
- package/dist/src/workflows/schemas/common.d.ts +27 -0
- package/dist/src/workflows/schemas/common.js +28 -0
- package/dist/src/workflows/schemas/common.js.map +1 -0
- package/dist/src/workflows/schemas/education.d.ts +70 -0
- package/dist/src/workflows/schemas/education.js +85 -0
- package/dist/src/workflows/schemas/education.js.map +1 -0
- package/dist/src/workflows/schemas/estate.d.ts +64 -0
- package/dist/src/workflows/schemas/estate.js +85 -0
- package/dist/src/workflows/schemas/estate.js.map +1 -0
- package/dist/src/workflows/schemas/healthcare-ext.d.ts +15 -0
- package/dist/src/workflows/schemas/healthcare-ext.js +17 -0
- package/dist/src/workflows/schemas/healthcare-ext.js.map +1 -0
- package/dist/src/workflows/schemas/healthcare.d.ts +33 -0
- package/dist/src/workflows/schemas/healthcare.js +20 -0
- package/dist/src/workflows/schemas/healthcare.js.map +1 -0
- package/dist/src/workflows/schemas/identity-domain.d.ts +64 -0
- package/dist/src/workflows/schemas/identity-domain.js +87 -0
- package/dist/src/workflows/schemas/identity-domain.js.map +1 -0
- package/dist/src/workflows/schemas/immigration-ext.d.ts +63 -0
- package/dist/src/workflows/schemas/immigration-ext.js +58 -0
- package/dist/src/workflows/schemas/immigration-ext.js.map +1 -0
- package/dist/src/workflows/schemas/immigration.d.ts +48 -0
- package/dist/src/workflows/schemas/immigration.js +27 -0
- package/dist/src/workflows/schemas/immigration.js.map +1 -0
- package/dist/src/workflows/schemas/legal.d.ts +45 -0
- package/dist/src/workflows/schemas/legal.js +45 -0
- package/dist/src/workflows/schemas/legal.js.map +1 -0
- package/dist/src/workflows/schemas/planning.d.ts +23 -0
- package/dist/src/workflows/schemas/planning.js +15 -0
- package/dist/src/workflows/schemas/planning.js.map +1 -0
- package/dist/src/workflows/schemas/retirement.d.ts +14 -0
- package/dist/src/workflows/schemas/retirement.js +22 -0
- package/dist/src/workflows/schemas/retirement.js.map +1 -0
- package/dist/src/workflows/schemas/tax.d.ts +58 -0
- package/dist/src/workflows/schemas/tax.js +51 -0
- package/dist/src/workflows/schemas/tax.js.map +1 -0
- package/dist/src/workflows/schemas/unemployment.d.ts +33 -0
- package/dist/src/workflows/schemas/unemployment.js +19 -0
- package/dist/src/workflows/schemas/unemployment.js.map +1 -0
- package/dist/src/workflows/schemas/veterans.d.ts +47 -0
- package/dist/src/workflows/schemas/veterans.js +51 -0
- package/dist/src/workflows/schemas/veterans.js.map +1 -0
- package/dist/src/workflows/types.d.ts +9 -0
- package/dist/src/workflows/types.js +2 -0
- package/dist/src/workflows/types.js.map +1 -0
- package/dist/xmcp.config.d.ts +3 -0
- package/dist/xmcp.config.js +29 -0
- package/dist/xmcp.config.js.map +1 -0
- package/llms.txt +48 -0
- package/package.json +82 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// ESPP (Employee Stock Purchase Plan) Handler — IRC §423
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// ESPPs let employees buy company stock at a discount (typically 15%).
|
|
5
|
+
// The tax treatment depends on when you sell:
|
|
6
|
+
//
|
|
7
|
+
// Qualifying disposition: held >2 years from offering date AND >1 year
|
|
8
|
+
// from purchase date. Ordinary income = lesser of (discount at offering,
|
|
9
|
+
// actual gain). Rest is long-term capital gain.
|
|
10
|
+
//
|
|
11
|
+
// Disqualifying disposition: either holding period not met.
|
|
12
|
+
// Ordinary income = FMV at purchase - purchase price (the actual discount).
|
|
13
|
+
// Rest is capital gain/loss.
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
function roundCurrency(value) {
|
|
16
|
+
return Number(value.toFixed(2));
|
|
17
|
+
}
|
|
18
|
+
const ONE_YEAR_MS = 365.25 * 24 * 60 * 60 * 1000;
|
|
19
|
+
const TWO_YEARS_MS = ONE_YEAR_MS * 2;
|
|
20
|
+
/**
|
|
21
|
+
* Calculate the purchase details of an ESPP transaction.
|
|
22
|
+
*
|
|
23
|
+
* Employees typically buy shares at 85% of the lower of (FMV at offering
|
|
24
|
+
* start, FMV at purchase date). The discount is a future tax liability
|
|
25
|
+
* waiting to happen — the IRS always gets its cut.
|
|
26
|
+
*/
|
|
27
|
+
export function calculateEsppPurchase(shares, purchasePrice, fairMarketValue, purchaseDate) {
|
|
28
|
+
const discount = roundCurrency((fairMarketValue - purchasePrice) * shares);
|
|
29
|
+
const costBasis = roundCurrency(purchasePrice * shares);
|
|
30
|
+
return {
|
|
31
|
+
purchaseDate,
|
|
32
|
+
shares,
|
|
33
|
+
purchasePrice,
|
|
34
|
+
fairMarketValue,
|
|
35
|
+
discount,
|
|
36
|
+
costBasis,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Calculate the tax consequences of selling ESPP shares.
|
|
41
|
+
*
|
|
42
|
+
* Qualifying disposition (both required):
|
|
43
|
+
* - >2 years from offering date
|
|
44
|
+
* - >1 year from purchase date
|
|
45
|
+
* Ordinary income = lesser of:
|
|
46
|
+
* (a) actual gain (sale price - purchase price) × shares
|
|
47
|
+
* (b) offering discount (offering FMV × discount %) × shares
|
|
48
|
+
* For simplicity, we use (FMV at purchase - purchase price) as the
|
|
49
|
+
* discount baseline when offering-date FMV isn't provided.
|
|
50
|
+
*
|
|
51
|
+
* Disqualifying disposition:
|
|
52
|
+
* Ordinary income = (FMV at purchase - purchase price) × shares
|
|
53
|
+
* Capital gain = total gain - ordinary income
|
|
54
|
+
*/
|
|
55
|
+
export function calculateEsppSale(purchase, salePrice, saleDate, offeringDate) {
|
|
56
|
+
const saleDateMs = new Date(saleDate).getTime();
|
|
57
|
+
const purchaseDateMs = new Date(purchase.purchaseDate).getTime();
|
|
58
|
+
const offeringDateMs = new Date(offeringDate).getTime();
|
|
59
|
+
const offeringHoldingMet = saleDateMs - offeringDateMs > TWO_YEARS_MS;
|
|
60
|
+
const purchaseHoldingMet = saleDateMs - purchaseDateMs > ONE_YEAR_MS;
|
|
61
|
+
const isQualifying = offeringHoldingMet && purchaseHoldingMet;
|
|
62
|
+
const proceeds = roundCurrency(purchase.shares * salePrice);
|
|
63
|
+
const totalGain = roundCurrency(proceeds - purchase.costBasis);
|
|
64
|
+
if (isQualifying) {
|
|
65
|
+
// Qualifying: ordinary income is capped at the discount or actual gain,
|
|
66
|
+
// whichever is less (and never negative)
|
|
67
|
+
const ordinaryIncome = roundCurrency(Math.max(0, Math.min(purchase.discount, totalGain)));
|
|
68
|
+
const capitalGain = roundCurrency(totalGain - ordinaryIncome);
|
|
69
|
+
return {
|
|
70
|
+
dispositionType: "qualifying",
|
|
71
|
+
ordinaryIncome,
|
|
72
|
+
capitalGain,
|
|
73
|
+
totalGain,
|
|
74
|
+
proceeds,
|
|
75
|
+
adjustedCostBasis: roundCurrency(purchase.costBasis + ordinaryIncome),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// Disqualifying: full discount at purchase is ordinary income
|
|
79
|
+
const ordinaryIncome = roundCurrency(Math.max(0, purchase.discount));
|
|
80
|
+
const capitalGain = roundCurrency(totalGain - ordinaryIncome);
|
|
81
|
+
return {
|
|
82
|
+
dispositionType: "disqualifying",
|
|
83
|
+
ordinaryIncome,
|
|
84
|
+
capitalGain,
|
|
85
|
+
totalGain,
|
|
86
|
+
proceeds,
|
|
87
|
+
adjustedCostBasis: roundCurrency(purchase.costBasis + ordinaryIncome),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=espp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"espp.js","sourceRoot":"","sources":["../../../../src/engine/equity/espp.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,yDAAyD;AACzD,8EAA8E;AAC9E,uEAAuE;AACvE,8CAA8C;AAC9C,EAAE;AACF,uEAAuE;AACvE,yEAAyE;AACzE,gDAAgD;AAChD,EAAE;AACF,4DAA4D;AAC5D,4EAA4E;AAC5E,6BAA6B;AAC7B,8EAA8E;AAoB9E,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,WAAW,GAAG,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACjD,MAAM,YAAY,GAAG,WAAW,GAAG,CAAC,CAAC;AAErC;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAc,EACd,aAAqB,EACrB,eAAuB,EACvB,YAAoB;IAEpB,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC,eAAe,GAAG,aAAa,CAAC,GAAG,MAAM,CAAC,CAAC;IAC3E,MAAM,SAAS,GAAG,aAAa,CAAC,aAAa,GAAG,MAAM,CAAC,CAAC;IAExD,OAAO;QACL,YAAY;QACZ,MAAM;QACN,aAAa;QACb,eAAe;QACf,QAAQ;QACR,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAA4B,EAC5B,SAAiB,EACjB,QAAgB,EAChB,YAAoB;IAEpB,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;IAChD,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IACjE,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IAExD,MAAM,kBAAkB,GAAG,UAAU,GAAG,cAAc,GAAG,YAAY,CAAC;IACtE,MAAM,kBAAkB,GAAG,UAAU,GAAG,cAAc,GAAG,WAAW,CAAC;IACrE,MAAM,YAAY,GAAG,kBAAkB,IAAI,kBAAkB,CAAC;IAE9D,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5D,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAE/D,IAAI,YAAY,EAAE,CAAC;QACjB,wEAAwE;QACxE,yCAAyC;QACzC,MAAM,cAAc,GAAG,aAAa,CAClC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CACpD,CAAC;QACF,MAAM,WAAW,GAAG,aAAa,CAAC,SAAS,GAAG,cAAc,CAAC,CAAC;QAE9D,OAAO;YACL,eAAe,EAAE,YAAY;YAC7B,cAAc;YACd,WAAW;YACX,SAAS;YACT,QAAQ;YACR,iBAAiB,EAAE,aAAa,CAAC,QAAQ,CAAC,SAAS,GAAG,cAAc,CAAC;SACtE,CAAC;IACJ,CAAC;IAED,8DAA8D;IAC9D,MAAM,cAAc,GAAG,aAAa,CAClC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAC/B,CAAC;IACF,MAAM,WAAW,GAAG,aAAa,CAAC,SAAS,GAAG,cAAc,CAAC,CAAC;IAE9D,OAAO;QACL,eAAe,EAAE,eAAe;QAChC,cAAc;QACd,WAAW;QACX,SAAS;QACT,QAAQ;QACR,iBAAiB,EAAE,aAAa,CAAC,QAAQ,CAAC,SAAS,GAAG,cAAc,CAAC;KACtE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface IsoExerciseResult {
|
|
2
|
+
exerciseDate: string;
|
|
3
|
+
shares: number;
|
|
4
|
+
exercisePrice: number;
|
|
5
|
+
fairMarketValue: number;
|
|
6
|
+
bargainElement: number;
|
|
7
|
+
amtPreferenceItem: number;
|
|
8
|
+
regularTaxIncome: number;
|
|
9
|
+
}
|
|
10
|
+
export interface IsoDispositionResult {
|
|
11
|
+
dispositionType: "qualifying" | "disqualifying";
|
|
12
|
+
ordinaryIncome: number;
|
|
13
|
+
capitalGain: number;
|
|
14
|
+
holdingPeriodMet: boolean;
|
|
15
|
+
totalGain: number;
|
|
16
|
+
costBasis: number;
|
|
17
|
+
proceeds: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Calculate the tax consequences of exercising an ISO.
|
|
21
|
+
*
|
|
22
|
+
* For regular tax: $0 income recognized at exercise.
|
|
23
|
+
* For AMT: the bargain element (FMV - exercise price) × shares
|
|
24
|
+
* is added as a preference item. This is where ISOs get people —
|
|
25
|
+
* you owe no regular tax, but might owe AMT on phantom income.
|
|
26
|
+
*/
|
|
27
|
+
export declare function calculateIsoExercise(shares: number, exercisePrice: number, fairMarketValue: number, exerciseDate: string): IsoExerciseResult;
|
|
28
|
+
/**
|
|
29
|
+
* Determine whether an ISO disposition is qualifying or disqualifying,
|
|
30
|
+
* and compute the resulting income breakdown.
|
|
31
|
+
*
|
|
32
|
+
* Qualifying disposition (both must be true):
|
|
33
|
+
* - Sale date > 2 years after grant date
|
|
34
|
+
* - Sale date > 1 year after exercise date
|
|
35
|
+
* → Entire gain (sale price - exercise price) is long-term capital gain
|
|
36
|
+
*
|
|
37
|
+
* Disqualifying disposition (either holding period not met):
|
|
38
|
+
* → Ordinary income = (FMV at exercise - exercise price) × shares
|
|
39
|
+
* (but capped at actual gain if sale price < FMV at exercise)
|
|
40
|
+
* → Remainder = capital gain/loss
|
|
41
|
+
*/
|
|
42
|
+
export declare function calculateIsoDisposition(shares: number, exercisePrice: number, fairMarketValue: number, salePrice: number, grantDate: string, exerciseDate: string, saleDate: string): IsoDispositionResult;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// ISO (Incentive Stock Option) Compensation Handler
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// ISOs are the tax code's way of saying "congratulations on your options,
|
|
5
|
+
// now here's a parallel tax universe (AMT) to worry about."
|
|
6
|
+
//
|
|
7
|
+
// Key rules:
|
|
8
|
+
// - No ordinary income at exercise (for regular tax purposes)
|
|
9
|
+
// - Bargain element (FMV - exercise price) is an AMT preference item
|
|
10
|
+
// - Qualifying disposition: >2 years from grant AND >1 year from exercise
|
|
11
|
+
// → entire gain is long-term capital gain
|
|
12
|
+
// - Disqualifying disposition: ordinary income on bargain element,
|
|
13
|
+
// remainder is capital gain
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
function roundCurrency(value) {
|
|
16
|
+
return Number(value.toFixed(2));
|
|
17
|
+
}
|
|
18
|
+
const ONE_YEAR_MS = 365.25 * 24 * 60 * 60 * 1000;
|
|
19
|
+
const TWO_YEARS_MS = ONE_YEAR_MS * 2;
|
|
20
|
+
/**
|
|
21
|
+
* Calculate the tax consequences of exercising an ISO.
|
|
22
|
+
*
|
|
23
|
+
* For regular tax: $0 income recognized at exercise.
|
|
24
|
+
* For AMT: the bargain element (FMV - exercise price) × shares
|
|
25
|
+
* is added as a preference item. This is where ISOs get people —
|
|
26
|
+
* you owe no regular tax, but might owe AMT on phantom income.
|
|
27
|
+
*/
|
|
28
|
+
export function calculateIsoExercise(shares, exercisePrice, fairMarketValue, exerciseDate) {
|
|
29
|
+
const bargainElement = roundCurrency(Math.max(0, (fairMarketValue - exercisePrice) * shares));
|
|
30
|
+
return {
|
|
31
|
+
exerciseDate,
|
|
32
|
+
shares,
|
|
33
|
+
exercisePrice,
|
|
34
|
+
fairMarketValue,
|
|
35
|
+
bargainElement,
|
|
36
|
+
amtPreferenceItem: bargainElement,
|
|
37
|
+
regularTaxIncome: 0, // No regular tax income at exercise
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Determine whether an ISO disposition is qualifying or disqualifying,
|
|
42
|
+
* and compute the resulting income breakdown.
|
|
43
|
+
*
|
|
44
|
+
* Qualifying disposition (both must be true):
|
|
45
|
+
* - Sale date > 2 years after grant date
|
|
46
|
+
* - Sale date > 1 year after exercise date
|
|
47
|
+
* → Entire gain (sale price - exercise price) is long-term capital gain
|
|
48
|
+
*
|
|
49
|
+
* Disqualifying disposition (either holding period not met):
|
|
50
|
+
* → Ordinary income = (FMV at exercise - exercise price) × shares
|
|
51
|
+
* (but capped at actual gain if sale price < FMV at exercise)
|
|
52
|
+
* → Remainder = capital gain/loss
|
|
53
|
+
*/
|
|
54
|
+
export function calculateIsoDisposition(shares, exercisePrice, fairMarketValue, salePrice, grantDate, exerciseDate, saleDate) {
|
|
55
|
+
const saleDateMs = new Date(saleDate).getTime();
|
|
56
|
+
const grantDateMs = new Date(grantDate).getTime();
|
|
57
|
+
const exerciseDateMs = new Date(exerciseDate).getTime();
|
|
58
|
+
const grantHoldingMet = saleDateMs - grantDateMs > TWO_YEARS_MS;
|
|
59
|
+
const exerciseHoldingMet = saleDateMs - exerciseDateMs > ONE_YEAR_MS;
|
|
60
|
+
const holdingPeriodMet = grantHoldingMet && exerciseHoldingMet;
|
|
61
|
+
const totalProceeds = roundCurrency(shares * salePrice);
|
|
62
|
+
const totalExerciseCost = roundCurrency(shares * exercisePrice);
|
|
63
|
+
const totalGain = roundCurrency(totalProceeds - totalExerciseCost);
|
|
64
|
+
if (holdingPeriodMet) {
|
|
65
|
+
// Qualifying disposition: all gain is long-term capital gain
|
|
66
|
+
return {
|
|
67
|
+
dispositionType: "qualifying",
|
|
68
|
+
ordinaryIncome: 0,
|
|
69
|
+
capitalGain: totalGain,
|
|
70
|
+
holdingPeriodMet: true,
|
|
71
|
+
totalGain,
|
|
72
|
+
costBasis: totalExerciseCost,
|
|
73
|
+
proceeds: totalProceeds,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// Disqualifying disposition: bargain element becomes ordinary income
|
|
77
|
+
const bargainElement = roundCurrency(Math.max(0, (fairMarketValue - exercisePrice) * shares));
|
|
78
|
+
// If the stock dropped below FMV, ordinary income is capped at actual gain
|
|
79
|
+
// (you don't recognize more ordinary income than you actually gained)
|
|
80
|
+
const ordinaryIncome = totalGain <= 0
|
|
81
|
+
? Math.max(0, totalGain)
|
|
82
|
+
: Math.min(bargainElement, totalGain);
|
|
83
|
+
const capitalGain = roundCurrency(totalGain - ordinaryIncome);
|
|
84
|
+
return {
|
|
85
|
+
dispositionType: "disqualifying",
|
|
86
|
+
ordinaryIncome: roundCurrency(ordinaryIncome),
|
|
87
|
+
capitalGain,
|
|
88
|
+
holdingPeriodMet: false,
|
|
89
|
+
totalGain,
|
|
90
|
+
costBasis: totalExerciseCost,
|
|
91
|
+
proceeds: totalProceeds,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=iso.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iso.js","sourceRoot":"","sources":["../../../../src/engine/equity/iso.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface NsoExerciseResult {
|
|
2
|
+
exerciseDate: string;
|
|
3
|
+
shares: number;
|
|
4
|
+
exercisePrice: number;
|
|
5
|
+
fairMarketValue: number;
|
|
6
|
+
spread: number;
|
|
7
|
+
ordinaryIncome: number;
|
|
8
|
+
costBasis: number;
|
|
9
|
+
}
|
|
10
|
+
export interface NsoSaleResult {
|
|
11
|
+
saleDate: string;
|
|
12
|
+
shares: number;
|
|
13
|
+
salePrice: number;
|
|
14
|
+
costBasis: number;
|
|
15
|
+
proceeds: number;
|
|
16
|
+
capitalGain: number;
|
|
17
|
+
holdingPeriod: "short-term" | "long-term";
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Calculate the tax consequences of exercising non-qualified stock options.
|
|
21
|
+
*
|
|
22
|
+
* The spread (FMV - exercise price) × shares is immediately recognized as
|
|
23
|
+
* ordinary income and included on the employee's W-2. There's no deferral
|
|
24
|
+
* mechanism, no AMT dance — just straightforward (if painful) taxation.
|
|
25
|
+
*/
|
|
26
|
+
export declare function calculateNsoExercise(shares: number, exercisePrice: number, fairMarketValue: number, exerciseDate: string): NsoExerciseResult;
|
|
27
|
+
/**
|
|
28
|
+
* Calculate the capital gain/loss from selling shares acquired via NSO exercise.
|
|
29
|
+
*
|
|
30
|
+
* Post-exercise, the shares are treated like any other stock:
|
|
31
|
+
* - Cost basis = FMV at exercise
|
|
32
|
+
* - Held > 1 year from exercise → long-term capital gain
|
|
33
|
+
* - Otherwise → short-term
|
|
34
|
+
*/
|
|
35
|
+
export declare function calculateNsoSale(exerciseResult: NsoExerciseResult, salePrice: number, saleDate: string): NsoSaleResult;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// NSO (Non-Qualified Stock Option) Compensation Handler
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// NSOs are the blunt instrument of equity compensation:
|
|
5
|
+
// - At exercise: spread (FMV - exercise price) is ordinary income on W-2
|
|
6
|
+
// - Subject to income tax + payroll taxes at exercise
|
|
7
|
+
// - Cost basis = FMV at exercise (for subsequent sale calculations)
|
|
8
|
+
// - Any gain/loss after exercise is capital gain/loss
|
|
9
|
+
//
|
|
10
|
+
// The lack of AMT complexity is the only consolation for the higher
|
|
11
|
+
// tax bill at exercise compared to ISOs.
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
function roundCurrency(value) {
|
|
14
|
+
return Number(value.toFixed(2));
|
|
15
|
+
}
|
|
16
|
+
const ONE_YEAR_MS = 365.25 * 24 * 60 * 60 * 1000;
|
|
17
|
+
/**
|
|
18
|
+
* Calculate the tax consequences of exercising non-qualified stock options.
|
|
19
|
+
*
|
|
20
|
+
* The spread (FMV - exercise price) × shares is immediately recognized as
|
|
21
|
+
* ordinary income and included on the employee's W-2. There's no deferral
|
|
22
|
+
* mechanism, no AMT dance — just straightforward (if painful) taxation.
|
|
23
|
+
*/
|
|
24
|
+
export function calculateNsoExercise(shares, exercisePrice, fairMarketValue, exerciseDate) {
|
|
25
|
+
const spread = roundCurrency(Math.max(0, (fairMarketValue - exercisePrice) * shares));
|
|
26
|
+
const costBasis = roundCurrency(fairMarketValue * shares);
|
|
27
|
+
return {
|
|
28
|
+
exerciseDate,
|
|
29
|
+
shares,
|
|
30
|
+
exercisePrice,
|
|
31
|
+
fairMarketValue,
|
|
32
|
+
spread,
|
|
33
|
+
ordinaryIncome: spread,
|
|
34
|
+
costBasis,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Calculate the capital gain/loss from selling shares acquired via NSO exercise.
|
|
39
|
+
*
|
|
40
|
+
* Post-exercise, the shares are treated like any other stock:
|
|
41
|
+
* - Cost basis = FMV at exercise
|
|
42
|
+
* - Held > 1 year from exercise → long-term capital gain
|
|
43
|
+
* - Otherwise → short-term
|
|
44
|
+
*/
|
|
45
|
+
export function calculateNsoSale(exerciseResult, salePrice, saleDate) {
|
|
46
|
+
const costBasisPerShare = roundCurrency(exerciseResult.costBasis / exerciseResult.shares);
|
|
47
|
+
const proceeds = roundCurrency(exerciseResult.shares * salePrice);
|
|
48
|
+
const totalCostBasis = roundCurrency(exerciseResult.shares * costBasisPerShare);
|
|
49
|
+
const capitalGain = roundCurrency(proceeds - totalCostBasis);
|
|
50
|
+
const exerciseDateMs = new Date(exerciseResult.exerciseDate).getTime();
|
|
51
|
+
const saleDateMs = new Date(saleDate).getTime();
|
|
52
|
+
const holdingPeriod = saleDateMs - exerciseDateMs > ONE_YEAR_MS ? "long-term" : "short-term";
|
|
53
|
+
return {
|
|
54
|
+
saleDate,
|
|
55
|
+
shares: exerciseResult.shares,
|
|
56
|
+
salePrice,
|
|
57
|
+
costBasis: costBasisPerShare,
|
|
58
|
+
proceeds,
|
|
59
|
+
capitalGain,
|
|
60
|
+
holdingPeriod,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=nso.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nso.js","sourceRoot":"","sources":["../../../../src/engine/equity/nso.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,wDAAwD;AACxD,8EAA8E;AAC9E,wDAAwD;AACxD,yEAAyE;AACzE,sDAAsD;AACtD,oEAAoE;AACpE,sDAAsD;AACtD,EAAE;AACF,oEAAoE;AACpE,yCAAyC;AACzC,8EAA8E;AAsB9E,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,WAAW,GAAG,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAc,EACd,aAAqB,EACrB,eAAuB,EACvB,YAAoB;IAEpB,MAAM,MAAM,GAAG,aAAa,CAC1B,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,eAAe,GAAG,aAAa,CAAC,GAAG,MAAM,CAAC,CACxD,CAAC;IACF,MAAM,SAAS,GAAG,aAAa,CAAC,eAAe,GAAG,MAAM,CAAC,CAAC;IAE1D,OAAO;QACL,YAAY;QACZ,MAAM;QACN,aAAa;QACb,eAAe;QACf,MAAM;QACN,cAAc,EAAE,MAAM;QACtB,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,cAAiC,EACjC,SAAiB,EACjB,QAAgB;IAEhB,MAAM,iBAAiB,GAAG,aAAa,CACrC,cAAc,CAAC,SAAS,GAAG,cAAc,CAAC,MAAM,CACjD,CAAC;IACF,MAAM,QAAQ,GAAG,aAAa,CAAC,cAAc,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClE,MAAM,cAAc,GAAG,aAAa,CAClC,cAAc,CAAC,MAAM,GAAG,iBAAiB,CAC1C,CAAC;IACF,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,GAAG,cAAc,CAAC,CAAC;IAE7D,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IACvE,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;IAChD,MAAM,aAAa,GACjB,UAAU,GAAG,cAAc,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;IAEzE,OAAO;QACL,QAAQ;QACR,MAAM,EAAE,cAAc,CAAC,MAAM;QAC7B,SAAS;QACT,SAAS,EAAE,iBAAiB;QAC5B,QAAQ;QACR,WAAW;QACX,aAAa;KACd,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface RsuVestingEvent {
|
|
2
|
+
vestDate: string;
|
|
3
|
+
shares: number;
|
|
4
|
+
fairMarketValue: number;
|
|
5
|
+
totalIncome: number;
|
|
6
|
+
costBasis: number;
|
|
7
|
+
}
|
|
8
|
+
export interface RsuSaleResult {
|
|
9
|
+
saleDate: string;
|
|
10
|
+
shares: number;
|
|
11
|
+
salePrice: number;
|
|
12
|
+
costBasis: number;
|
|
13
|
+
proceeds: number;
|
|
14
|
+
gainOrLoss: number;
|
|
15
|
+
holdingPeriod: "short-term" | "long-term";
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Calculate the income recognized when RSU shares vest.
|
|
19
|
+
*
|
|
20
|
+
* At vesting, RSU income = shares × FMV per share.
|
|
21
|
+
* This amount is reported as ordinary income on the employee's W-2.
|
|
22
|
+
* The cost basis for any future sale is the FMV at the time of vesting.
|
|
23
|
+
*/
|
|
24
|
+
export declare function calculateRsuVesting(shares: number, fmvPerShare: number, vestDate: string): RsuVestingEvent;
|
|
25
|
+
/**
|
|
26
|
+
* Calculate gain/loss on the sale of previously-vested RSU shares.
|
|
27
|
+
*
|
|
28
|
+
* Proceeds = shares × sale price.
|
|
29
|
+
* Gain/loss = proceeds - (cost basis per share × shares).
|
|
30
|
+
* If held > 1 year from vest date → long-term capital gain/loss.
|
|
31
|
+
* Otherwise → short-term.
|
|
32
|
+
*/
|
|
33
|
+
export declare function calculateRsuSale(vestEvent: RsuVestingEvent, salePrice: number, saleDate: string): RsuSaleResult;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// RSU (Restricted Stock Unit) Compensation Handler
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// RSUs are straightforward: shares vest, FMV at vesting is ordinary income
|
|
5
|
+
// reported on W-2. Cost basis for future sale equals FMV at vest.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
function roundCurrency(value) {
|
|
8
|
+
return Number(value.toFixed(2));
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Determines how many milliseconds constitute one year for holding-period
|
|
12
|
+
* purposes. We use 365.25 days to account for leap years — close enough
|
|
13
|
+
* for the IRS's "more than one year" rule, which in practice uses calendar
|
|
14
|
+
* dates. A proper calendar-date check would be more precise, but this
|
|
15
|
+
* handles the vast majority of cases correctly.
|
|
16
|
+
*/
|
|
17
|
+
const ONE_YEAR_MS = 365.25 * 24 * 60 * 60 * 1000;
|
|
18
|
+
function determineHoldingPeriod(acquiredDate, soldDate) {
|
|
19
|
+
const acquired = new Date(acquiredDate).getTime();
|
|
20
|
+
const sold = new Date(soldDate).getTime();
|
|
21
|
+
return sold - acquired > ONE_YEAR_MS ? "long-term" : "short-term";
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Calculate the income recognized when RSU shares vest.
|
|
25
|
+
*
|
|
26
|
+
* At vesting, RSU income = shares × FMV per share.
|
|
27
|
+
* This amount is reported as ordinary income on the employee's W-2.
|
|
28
|
+
* The cost basis for any future sale is the FMV at the time of vesting.
|
|
29
|
+
*/
|
|
30
|
+
export function calculateRsuVesting(shares, fmvPerShare, vestDate) {
|
|
31
|
+
const totalIncome = roundCurrency(shares * fmvPerShare);
|
|
32
|
+
return {
|
|
33
|
+
vestDate,
|
|
34
|
+
shares,
|
|
35
|
+
fairMarketValue: fmvPerShare,
|
|
36
|
+
totalIncome,
|
|
37
|
+
costBasis: totalIncome,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Calculate gain/loss on the sale of previously-vested RSU shares.
|
|
42
|
+
*
|
|
43
|
+
* Proceeds = shares × sale price.
|
|
44
|
+
* Gain/loss = proceeds - (cost basis per share × shares).
|
|
45
|
+
* If held > 1 year from vest date → long-term capital gain/loss.
|
|
46
|
+
* Otherwise → short-term.
|
|
47
|
+
*/
|
|
48
|
+
export function calculateRsuSale(vestEvent, salePrice, saleDate) {
|
|
49
|
+
const costBasisPerShare = roundCurrency(vestEvent.costBasis / vestEvent.shares);
|
|
50
|
+
const proceeds = roundCurrency(vestEvent.shares * salePrice);
|
|
51
|
+
const totalCostBasis = roundCurrency(vestEvent.shares * costBasisPerShare);
|
|
52
|
+
const gainOrLoss = roundCurrency(proceeds - totalCostBasis);
|
|
53
|
+
const holdingPeriod = determineHoldingPeriod(vestEvent.vestDate, saleDate);
|
|
54
|
+
return {
|
|
55
|
+
saleDate,
|
|
56
|
+
shares: vestEvent.shares,
|
|
57
|
+
salePrice,
|
|
58
|
+
costBasis: costBasisPerShare,
|
|
59
|
+
proceeds,
|
|
60
|
+
gainOrLoss,
|
|
61
|
+
holdingPeriod,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=rsu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rsu.js","sourceRoot":"","sources":["../../../../src/engine/equity/rsu.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,mDAAmD;AACnD,8EAA8E;AAC9E,2EAA2E;AAC3E,kEAAkE;AAClE,8EAA8E;AAoB9E,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,GAAG,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEjD,SAAS,sBAAsB,CAC7B,YAAoB,EACpB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IAClD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;IAC1C,OAAO,IAAI,GAAG,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAc,EACd,WAAmB,EACnB,QAAgB;IAEhB,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC;IACxD,OAAO;QACL,QAAQ;QACR,MAAM;QACN,eAAe,EAAE,WAAW;QAC5B,WAAW;QACX,SAAS,EAAE,WAAW;KACvB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,SAA0B,EAC1B,SAAiB,EACjB,QAAgB;IAEhB,MAAM,iBAAiB,GAAG,aAAa,CACrC,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,MAAM,CACvC,CAAC;IACF,MAAM,QAAQ,GAAG,aAAa,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7D,MAAM,cAAc,GAAG,aAAa,CAAC,SAAS,CAAC,MAAM,GAAG,iBAAiB,CAAC,CAAC;IAC3E,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,GAAG,cAAc,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,sBAAsB,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAE3E,OAAO;QACL,QAAQ;QACR,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,SAAS;QACT,SAAS,EAAE,iBAAiB;QAC5B,QAAQ;QACR,UAAU;QACV,aAAa;KACd,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ImportedDocument, PersonIdentity } from "../types.js";
|
|
2
|
+
import { calculateFederalTax, type TaxCalculationInput } from "./tax-calculator.js";
|
|
3
|
+
import { f1040Schema, schedule1Schema, scheduleCSchema } from "../schemas/2025/index.js";
|
|
4
|
+
export interface BuildReturnBundleInput {
|
|
5
|
+
formId: "1040";
|
|
6
|
+
taxYear: 2025;
|
|
7
|
+
filingStatus: TaxCalculationInput["filingStatus"];
|
|
8
|
+
taxpayer: PersonIdentity;
|
|
9
|
+
spouse?: PersonIdentity;
|
|
10
|
+
dependents: TaxCalculationInput["dependents"];
|
|
11
|
+
importedDocuments: ImportedDocument[];
|
|
12
|
+
taxInput: TaxCalculationInput;
|
|
13
|
+
}
|
|
14
|
+
export interface ReturnBundle {
|
|
15
|
+
formId: "1040";
|
|
16
|
+
taxYear: 2025;
|
|
17
|
+
taxpayer: PersonIdentity;
|
|
18
|
+
spouse?: PersonIdentity;
|
|
19
|
+
dependents: TaxCalculationInput["dependents"];
|
|
20
|
+
importedDocuments: ImportedDocument[];
|
|
21
|
+
calculation: ReturnType<typeof calculateFederalTax>;
|
|
22
|
+
form1040: ReturnType<typeof f1040Schema.parse>;
|
|
23
|
+
schedule1: ReturnType<typeof schedule1Schema.parse>;
|
|
24
|
+
scheduleC?: ReturnType<typeof scheduleCSchema.parse>;
|
|
25
|
+
}
|
|
26
|
+
export declare function buildReturnBundle(input: BuildReturnBundleInput): ReturnBundle;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { calculateFederalTax } from "./tax-calculator.js";
|
|
2
|
+
import { f1040Schema, schedule1Schema, scheduleCSchema } from "../schemas/2025/index.js";
|
|
3
|
+
function roundCurrency(value) {
|
|
4
|
+
return Number(value.toFixed(2));
|
|
5
|
+
}
|
|
6
|
+
function getImportedWithholding(importedDocuments, documentType) {
|
|
7
|
+
return roundCurrency(importedDocuments
|
|
8
|
+
.filter((document) => document.type === documentType)
|
|
9
|
+
.reduce((total, document) => {
|
|
10
|
+
if (document.type === "w2") {
|
|
11
|
+
return total + document.federalWithheld;
|
|
12
|
+
}
|
|
13
|
+
if ("federalWithheld" in document && typeof document.federalWithheld === "number") {
|
|
14
|
+
return total + document.federalWithheld;
|
|
15
|
+
}
|
|
16
|
+
return total;
|
|
17
|
+
}, 0));
|
|
18
|
+
}
|
|
19
|
+
export function buildReturnBundle(input) {
|
|
20
|
+
const calculation = calculateFederalTax(input.taxInput);
|
|
21
|
+
const federalWithheldW2 = getImportedWithholding(input.importedDocuments, "w2");
|
|
22
|
+
const federalWithheld1099 = roundCurrency(input.importedDocuments
|
|
23
|
+
.filter((document) => document.type !== "w2")
|
|
24
|
+
.reduce((total, document) => {
|
|
25
|
+
if ("federalWithheld" in document && typeof document.federalWithheld === "number") {
|
|
26
|
+
return total + document.federalWithheld;
|
|
27
|
+
}
|
|
28
|
+
return total;
|
|
29
|
+
}, 0));
|
|
30
|
+
const unassignedWithholding = roundCurrency(Math.max(0, input.taxInput.federalWithheld - federalWithheldW2 - federalWithheld1099));
|
|
31
|
+
const schedule1 = schedule1Schema.parse({
|
|
32
|
+
taxYear: input.taxYear,
|
|
33
|
+
filingStatus: input.filingStatus,
|
|
34
|
+
additionalIncome: {
|
|
35
|
+
line3BusinessIncomeOrLoss: input.taxInput.scheduleCNet || undefined,
|
|
36
|
+
line8OtherIncome: input.taxInput.otherIncome || undefined,
|
|
37
|
+
line10TotalAdditionalIncome: input.taxInput.scheduleCNet + input.taxInput.otherIncome || undefined,
|
|
38
|
+
},
|
|
39
|
+
adjustments: {
|
|
40
|
+
line11EducatorExpenses: input.taxInput.adjustments.educatorExpenses || undefined,
|
|
41
|
+
line13HealthSavingsAccountDeduction: input.taxInput.adjustments.hsaDeduction || undefined,
|
|
42
|
+
line15DeductiblePartOfSelfEmploymentTax: calculation.selfEmploymentTax > 0
|
|
43
|
+
? roundCurrency(calculation.selfEmploymentTax / 2)
|
|
44
|
+
: undefined,
|
|
45
|
+
line20IraDeductions: input.taxInput.adjustments.iraDeduction || undefined,
|
|
46
|
+
line21StudentLoanInterestDeduction: input.taxInput.adjustments.studentLoanInterest || undefined,
|
|
47
|
+
line27TotalAdjustments: calculation.grossIncome - calculation.adjustedGrossIncome || undefined,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
const scheduleC = input.taxInput.scheduleCNet !== 0
|
|
51
|
+
? scheduleCSchema.parse({
|
|
52
|
+
taxYear: input.taxYear,
|
|
53
|
+
ownerName: `${input.taxpayer.firstName} ${input.taxpayer.lastName}`,
|
|
54
|
+
ownerSsn: input.taxpayer.ssn,
|
|
55
|
+
businessName: "Sole Proprietorship",
|
|
56
|
+
principalBusinessOrProfession: "Self-employment",
|
|
57
|
+
accountingMethod: "cash",
|
|
58
|
+
income: {
|
|
59
|
+
grossReceiptsOrSales: input.taxInput.scheduleCNet,
|
|
60
|
+
otherIncome: input.taxInput.otherIncome || undefined,
|
|
61
|
+
},
|
|
62
|
+
cogs: {},
|
|
63
|
+
expenses: {},
|
|
64
|
+
netProfitOrLoss: input.taxInput.scheduleCNet,
|
|
65
|
+
})
|
|
66
|
+
: undefined;
|
|
67
|
+
const form1040 = f1040Schema.parse({
|
|
68
|
+
taxYear: input.taxYear,
|
|
69
|
+
filingStatus: input.filingStatus,
|
|
70
|
+
taxpayer: input.taxpayer,
|
|
71
|
+
spouse: input.spouse,
|
|
72
|
+
mailingAddress: input.taxpayer.address,
|
|
73
|
+
dependents: input.dependents,
|
|
74
|
+
lines: {
|
|
75
|
+
line1a: input.taxInput.wages || undefined,
|
|
76
|
+
line2b: input.taxInput.taxableInterest || undefined,
|
|
77
|
+
line3b: input.taxInput.ordinaryDividends || undefined,
|
|
78
|
+
line8: schedule1.additionalIncome.line10TotalAdditionalIncome,
|
|
79
|
+
line9: calculation.grossIncome,
|
|
80
|
+
line10: schedule1.adjustments.line27TotalAdjustments,
|
|
81
|
+
line11: calculation.adjustedGrossIncome,
|
|
82
|
+
line12a: input.taxInput.useItemizedDeductions ? undefined : calculation.deduction,
|
|
83
|
+
line12b: input.taxInput.useItemizedDeductions ? calculation.deduction : undefined,
|
|
84
|
+
line12z: calculation.deduction,
|
|
85
|
+
line13: calculation.taxableIncome,
|
|
86
|
+
line14: calculation.federalTax,
|
|
87
|
+
line16: calculation.federalTax,
|
|
88
|
+
line17: calculation.selfEmploymentTax || undefined,
|
|
89
|
+
line21: calculation.totalCredits || undefined,
|
|
90
|
+
line24: calculation.totalTax,
|
|
91
|
+
line25a: roundCurrency(federalWithheldW2 + unassignedWithholding) || undefined,
|
|
92
|
+
line25b: federalWithheld1099 || undefined,
|
|
93
|
+
line26: input.taxInput.estimatedPayments || undefined,
|
|
94
|
+
line27: calculation.earnedIncomeCredit || undefined,
|
|
95
|
+
line28: calculation.additionalChildTaxCredit || undefined,
|
|
96
|
+
line33: calculation.totalPayments,
|
|
97
|
+
line34: calculation.refund || undefined,
|
|
98
|
+
line37: calculation.amountOwed || undefined,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
const bundle = {
|
|
102
|
+
formId: input.formId,
|
|
103
|
+
taxYear: input.taxYear,
|
|
104
|
+
taxpayer: input.taxpayer,
|
|
105
|
+
dependents: input.dependents,
|
|
106
|
+
importedDocuments: input.importedDocuments,
|
|
107
|
+
calculation,
|
|
108
|
+
form1040,
|
|
109
|
+
schedule1,
|
|
110
|
+
};
|
|
111
|
+
if (input.spouse) {
|
|
112
|
+
bundle.spouse = input.spouse;
|
|
113
|
+
}
|
|
114
|
+
if (scheduleC) {
|
|
115
|
+
bundle.scheduleC = scheduleC;
|
|
116
|
+
}
|
|
117
|
+
return bundle;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=field-mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-mapper.js","sourceRoot":"","sources":["../../../src/engine/field-mapper.ts"],"names":[],"mappings":"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"}
|