open-agreements 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agreements",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "workspaces": [
5
5
  "packages/allure-test-factory",
6
6
  "packages/contract-templates-mcp",
@@ -23,8 +23,8 @@ File your Delaware annual franchise tax and annual report.
23
23
  ## Security model
24
24
 
25
25
  - This skill **does not** download or execute any code.
26
- - It **does not** access the Delaware eCorp portal programmatically (the portal prohibits automated tools).
27
26
  - All portal interactions are performed by the user, guided step-by-step by the agent.
27
+ - If the user opts in to browser automation (Playwright via CDP), the agent may assist with portal navigation — but credit card and banking details must **always** be entered by the user directly.
28
28
 
29
29
  ## When to Use
30
30
 
@@ -117,28 +117,64 @@ Total due: $XXX + $50 = $XXX
117
117
 
118
118
  ## Phase 3: File via Portal
119
119
 
120
- Guide the user step by step. The agent reads instructions aloud; the user operates the browser.
120
+ The agent can automate the portal using Playwright if Chrome is running with remote debugging enabled. Otherwise, guide the user step-by-step.
121
+
122
+ ### Automation Setup (Playwright via CDP)
123
+
124
+ If the user says "use playwright", "use the browser" or requests similar automation:
125
+
126
+ 1. **Launch Chrome with remote debugging** (see `reference/ecorp-portal-playwright-notes.md` for commands)
127
+ 2. **Connect via Playwright** (see reference for CDP connection snippet)
128
+ 3. **Portal field reference**: See `reference/ecorp-portal-playwright-notes.md` for:
129
+ - All field selector IDs
130
+ - Date field workaround (must use JS `el.value =` not Playwright `.fill()`)
131
+ - State dropdown abbreviations (use `value="NY"` not `label="New York"`)
132
+ - Director name fields (separate first/middle/last fields, NOT one name field)
133
+ - APVC activation sequence
134
+ - Session/eId behavior
135
+
136
+ ### Filing Steps
121
137
 
122
138
  1. **Navigate**: Open https://icis.corp.delaware.gov/ecorp/logintax.aspx
123
139
  2. **Login**: Enter Business Entity File Number. Solve CAPTCHA (if the user shares a screenshot, the agent can try to read it). Click **Continue**.
124
140
  3. **Entity verification**: Confirm entity name, registered agent, and registered office match your records.
125
- 4. **Officers and directors**: Review and confirm or update names and addresses. Enter Nature of Business if prompted.
126
- 5. **Stock information**: Enter authorized shares, par value, issued shares, and gross assets for each class.
127
- 6. **Tax method**: Select **Assumed Par Value Capital Method** (or whichever method produced the lower tax). Verify the displayed tax matches your calculation from Phase 2. If it does not match, stop and troubleshoot before proceeding.
128
- 7. **Payment**: Enter credit card or ACH details. Total = tax + filing fee. **Click Submit ONCE** — the portal warns about duplicate charges on double-click. If tax exceeds $5,000, ACH payment is required.
129
- 8. **Confirmation**: Save the confirmation number. Screenshot the confirmation page.
130
-
131
- ## Phase 4: Record and Remind
132
-
133
- Save a filing record with the following details:
134
- - Entity name
135
- - Delaware file number
136
- - Tax year
137
- - Calculation method used and intermediate values
138
- - Amount paid (tax + filing fee)
139
- - Confirmation number
140
- - Date filed
141
- - Next due date (March 1 of next year for corps, June 1 for LLCs)
141
+ 4. **Fill form fields** (all on one page):
142
+ - **Stock info**: Issued shares (per-class field, NOT the readonly total), gross assets, asset date (must == fiscal year end)
143
+ - **Address**: Principal business address with state abbreviation
144
+ - **Nature of business**: Select from dropdown (e.g., "Technology/Software")
145
+ - **Officer**: First/middle/last name, title, address
146
+ - **Directors**: Set total count, click "Enter Directors Info", fill first/middle/last name + address for each
147
+ - **Authorization**: First/middle/last name, title, address
148
+ - **T&C checkbox**: Must check `chkCertify` before continuing
149
+ 5. **Recalculate tax**: Click "Recalculate Tax" button. Verify the displayed tax matches your calculation from Phase 2. If it still shows the Authorized Shares method amount, the asset date is probably wrong — fix it via JavaScript.
150
+ 6. **Review**: Click "Continue Filing" to see the Review Copy. Verify all data.
151
+ 7. **Payment**: Click "Proceed to Payment". The agent **must stop here** — credit card and banking details must be entered by the user. If tax exceeds $5,000, ACH payment is required.
152
+ 8. **Confirmation**: After payment:
153
+ - Click **"Display Confirmation Copy"** (`onclick="downloadConfirmation();return false;"`) to save receipt PDF
154
+ - Click **"Email Confirmation Copy"** to email the filed report (opens popup at `Email.aspx`, enter email address)
155
+ - **CRITICAL**: "Once you leave this screen, you will no longer be able to obtain a confirmation copy" — save/email before navigating away
156
+ - Record the Service Request Number from the URL: `srNo=XXXXX`
157
+
158
+ ## Phase 4: Save Receipt and Remind
159
+
160
+ ### Save the confirmation PDF
161
+
162
+ The downloaded confirmation PDF **is** the filing record — no need to create a separate one.
163
+
164
+ The portal downloads the receipt as `Ecorp_Confirmation_<ServiceRequestNumber>.pdf` to the default Downloads folder. Move it to a durable location:
165
+ - `~/Documents/Tax/Delaware/<EntityName>/` on local disk
166
+ - A "Tax" or "Corporate Records" folder in cloud storage if available
167
+ - Keep the original filename — it contains the Service Request Number for future reference
168
+
169
+ ```bash
170
+ # Example
171
+ mkdir -p ~/Documents/Tax/Delaware/My-Corp-Name
172
+ mv ~/Downloads/Ecorp_Confirmation_*.pdf ~/Documents/Tax/Delaware/My-Corp-Name/
173
+ ```
174
+
175
+ Ask the user where they keep tax records and move the file there.
176
+
177
+ ### Set a reminder
142
178
 
143
179
  Remind the user to set an annual reminder for approximately 2 weeks before the deadline:
144
180
  - **Mid-February** for corporations (March 1 deadline)
@@ -156,6 +192,7 @@ For detailed calculation formulas and official guidance, see the `reference/` di
156
192
  - `reference/tax-calculation.md` — full formulas for both methods with examples
157
193
  - `reference/filing-instructions.md` — fees, payment methods, deadlines
158
194
  - `reference/faq.md` — frequently asked questions
195
+ - `reference/ecorp-portal-playwright-notes.md` — field selectors, gotchas, and automation tips for the eCorp portal
159
196
 
160
197
  **Official source**: https://corp.delaware.gov/paytaxes/
161
198
  **Help line**: 302-739-3073, Option 3
@@ -0,0 +1,136 @@
1
+ # Delaware eCorp Portal — Playwright Automation Notes
2
+
3
+ ## Setup
4
+
5
+ ### Launch Chrome with remote debugging
6
+
7
+ ```bash
8
+ # Must quit Chrome first, then relaunch with debug port
9
+ osascript -e 'tell application "Google Chrome" to quit'
10
+ sleep 2
11
+ /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
12
+ --remote-debugging-port=9222 \
13
+ --user-data-dir=/tmp/chrome-debug-profile &
14
+ ```
15
+
16
+ ### Connect via Playwright (CDP)
17
+
18
+ ```python
19
+ NODE_OPTIONS='--no-deprecation' uv run python3 << 'PYEOF'
20
+ from playwright.sync_api import sync_playwright
21
+ with sync_playwright() as p:
22
+ browser = p.chromium.connect_over_cdp("http://localhost:9222")
23
+ ctx = browser.contexts[0]
24
+ page = ctx.pages[0]
25
+ PYEOF
26
+ ```
27
+
28
+ ## Fixes & Gotchas
29
+
30
+ ### 1. Readonly "Total Issued Shares" field
31
+ - `gridStock_ctl02_txtIssuedShares` is **readonly** — it's auto-summed from per-class fields
32
+ - Fill the per-class field instead: `gridStock_ctl02_gridStockDetails_ctl02_txtIssuedShares`
33
+ - This populates the readonly total automatically on recalculate
34
+
35
+ ### 2. Asset Date field mangles input with Playwright .fill()/.type()
36
+ - The date field has a mask/formatter that garbles Playwright keyboard input
37
+ - **Fix**: Use JavaScript to set the value directly:
38
+ ```python
39
+ page.evaluate('''
40
+ const el = document.getElementById('ctl00_ContentPlaceHolder1_gridStock_ctl02_txtAssetDate');
41
+ el.value = '12/31/2025';
42
+ el.dispatchEvent(new Event('change', { bubbles: true }));
43
+ ''')
44
+ ```
45
+ - The portal requires asset date == fiscal year end date, or it ignores gross assets
46
+
47
+ ### 3. APVC method activation
48
+ - Portal defaults to Authorized Shares method ($85,165 for 10M shares)
49
+ - To get APVC: fill issued shares + gross assets + correct asset date, then click "Recalculate Tax"
50
+ - If asset date doesn't match fiscal year end, recalculate silently stays on Authorized Shares
51
+
52
+ ### 4. ASP.NET ViewState breaks on back-navigation
53
+ - Never use `page.go_back()` — the ViewState expires and you get a server error
54
+ - Always start fresh from the login page: `https://icis.corp.delaware.gov/ecorp/logintax.aspx`
55
+
56
+ ### 5. Postback links (2024 "File Amended Annual Report")
57
+ - The link is `javascript:__doPostBack(...)`, not a real URL
58
+ - Can't open in a new tab via href — must execute on the page
59
+ - Use: `page.evaluate("__doPostBack('ctl00$ContentPlaceHolder1$lnkPrevAR','')")`
60
+
61
+ ### 6. CAPTCHA
62
+ - Field: `#ctl00_ContentPlaceHolder1_ecorpCaptcha1_txtCaptcha`
63
+ - Image: `#ctl00_ContentPlaceHolder1_ecorpCaptcha1_captchaImage` (NOT `img[src*='Captcha']`)
64
+ - Case-insensitive in practice (all caps in image)
65
+ - Screenshot cropping can be unreliable — fetch the CAPTCHA image bytes via JS `fetch()` on `img.src` as fallback
66
+
67
+ ### 7. Key field selectors
68
+ | Field | Selector ID (after ctl00_ContentPlaceHolder1_) |
69
+ |-------|------------------------------------------------|
70
+ | File number | txtPrimaryFileNo |
71
+ | CAPTCHA | ecorpCaptcha1_txtCaptcha |
72
+ | Continue button | btnContinue |
73
+ | Issued shares (per-class) | gridStock_ctl02_gridStockDetails_ctl02_txtIssuedShares |
74
+ | Issued shares (total, readonly) | gridStock_ctl02_txtIssuedShares |
75
+ | Gross assets | gridStock_ctl02_txtGrossAsset |
76
+ | Asset date | gridStock_ctl02_txtAssetDate |
77
+ | Fiscal year end | txtFiscalYearEndYear |
78
+ | Recalculate button | btnRecalucation (note: typo in portal) |
79
+ | Continue Filing button | btnProceedPayment |
80
+ | Enter Directors button | btnDisplayDirectorForm |
81
+ | Nature of Business | ddlBusinessNatures |
82
+
83
+ ### 8. State dropdowns use abbreviations (NY, WA, etc.)
84
+ - All state dropdowns (`drpHidePrincipal`, `drpHideOfficer`, `drpHideAuthor`, `drpDirectorStatesN`) use 2-letter state codes
85
+ - Use `page.select_option("#drpHidePrincipal", value="NY")` — NOT `label="New York"`
86
+
87
+ ### 9. Director form fields (inline, not popup)
88
+ - Click `#btnDisplayDirectorForm` to reveal director rows
89
+ - **CRITICAL**: Director names have THREE separate fields per director:
90
+ - `txtDirectorName{N}` = **first name only** (NOT full name!)
91
+ - `txtMiddleName{N}` = middle name/initial
92
+ - `txtLastName{N}` = last name (REQUIRED — validation fails without it)
93
+ - Other fields: `txtDirectorAddress{N}`, `txtDirectorCity{N}`, `drpDirectorStates{N}`, `txtDirectorZip{N}`, `drpDirectorCountry{N}`
94
+ - Numbered 1–N based on `txtTotalNumOfDirectors`
95
+ - All use simple IDs (no ASP.NET prefix)
96
+
97
+ ### 10. Tax result label IDs (different from what you'd expect)
98
+ | Label | Selector ID (after ctl00_ContentPlaceHolder1_) |
99
+ |-------|------------------------------------------------|
100
+ | Franchise Tax | lblFranchisetaxData |
101
+ | Penalty | lblPenaltyData |
102
+ | Interest | lblMonthlyIntrestData |
103
+ | Filing Fee | lblAnnualFilingDta |
104
+ | Credit | lblPreviousData |
105
+ | Prepaid | lblPrepaidPaymentData |
106
+ | **Total Due** | **lblAmountDue** |
107
+
108
+ ### 11. Officer and Authorization address fields
109
+ | Section | Street | City | State | Zip |
110
+ |---------|--------|------|-------|-----|
111
+ | Principal | txtStreetPrincipal | txtCityPrincipal | drpHidePrincipal | txtZipPrincipal |
112
+ | Officer | txtStreetOfficer | txtCityOfficer | drpHideOfficer | txtZipOfficer |
113
+ | Auth | txtStreetAuthorization | txtCityAuthorization | drpHideAuthor | txtZipAuthorization |
114
+
115
+ ### 12. Session/eId behavior
116
+ - Dashboard URL needs `eId` parameter from login — can't bookmark dashboard directly
117
+ - **BUT**: Cmd+Back (browser history) in a new tab CAN get back to dashboard within the same session
118
+ - Each login generates a unique eId; session cookies are shared across tabs
119
+
120
+ ### 13. T&C checkbox required before Continue Filing
121
+ - Must check `#ctl00_ContentPlaceHolder1_chkCertify` before clicking Continue Filing
122
+ - Validation error: "Authorization: Please check the box to confirm that you have read the Terms and Conditions"
123
+
124
+ ### 14. Confirmation page — save BEFORE navigating away
125
+ - **"Once you leave this screen, you will no longer be able to obtain a confirmation copy"**
126
+ - **PDF download**: `downloadConfirmation()` → opens `DownLoadConfirmation.ashx?srNo=...&fileNo=...`
127
+ - Triggers a file download, NOT a page navigation — Playwright will throw "Download is starting" error (that's OK, the file downloads)
128
+ - **Email confirmation**: `openARemail()` → opens `Email.aspx?srNo=...` popup
129
+ - Fill `#txtEmailAddress` and `#txtVerifyEmailAddress`, click `#btnEmail`
130
+ - Response: "Your e-mail request has been received. Please allow 48 hours."
131
+ - Service Request Number is in the URL: `?srNo=XXXXXXXXXXX`
132
+
133
+ ### 15. Deprecation warning
134
+ - `[DEP0169] url.parse() behavior is not standardized` comes from Playwright's Node.js internals
135
+ - Harmless — Playwright uses `url.parse()` in its server; fix is upstream (Playwright issue)
136
+ - Suppress with: `NODE_OPTIONS='--no-deprecation'` env var