sp2react 0.1.0__tar.gz

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.
Files changed (126) hide show
  1. sp2react-0.1.0/CHANGELOG.md +19 -0
  2. sp2react-0.1.0/LICENSE +21 -0
  3. sp2react-0.1.0/MANIFEST.in +10 -0
  4. sp2react-0.1.0/PKG-INFO +238 -0
  5. sp2react-0.1.0/README.md +190 -0
  6. sp2react-0.1.0/SECURITY.md +47 -0
  7. sp2react-0.1.0/pyproject.toml +62 -0
  8. sp2react-0.1.0/setup.cfg +4 -0
  9. sp2react-0.1.0/src/sp2react/__init__.py +18 -0
  10. sp2react-0.1.0/src/sp2react/agents/__init__.py +0 -0
  11. sp2react-0.1.0/src/sp2react/agents/core.py +146 -0
  12. sp2react-0.1.0/src/sp2react/agents/prompts/dbmap.md +28 -0
  13. sp2react-0.1.0/src/sp2react/agents/prompts/fix.md +11 -0
  14. sp2react-0.1.0/src/sp2react/agents/prompts/handler.md +22 -0
  15. sp2react-0.1.0/src/sp2react/agents/prompts/page.md +40 -0
  16. sp2react-0.1.0/src/sp2react/agents/prompts/review.md +21 -0
  17. sp2react-0.1.0/src/sp2react/agents/prompts/spec.md +79 -0
  18. sp2react-0.1.0/src/sp2react/agents/tasks.py +374 -0
  19. sp2react-0.1.0/src/sp2react/analysis/__init__.py +0 -0
  20. sp2react-0.1.0/src/sp2react/analysis/aspx.py +254 -0
  21. sp2react-0.1.0/src/sp2react/analysis/behaviors.py +357 -0
  22. sp2react-0.1.0/src/sp2react/analysis/fields.py +152 -0
  23. sp2react-0.1.0/src/sp2react/analysis/inventory.py +314 -0
  24. sp2react-0.1.0/src/sp2react/analysis/jsscan.py +330 -0
  25. sp2react-0.1.0/src/sp2react/checks.py +105 -0
  26. sp2react-0.1.0/src/sp2react/cli.py +188 -0
  27. sp2react-0.1.0/src/sp2react/config.py +172 -0
  28. sp2react-0.1.0/src/sp2react/dbmap.py +245 -0
  29. sp2react-0.1.0/src/sp2react/llm/__init__.py +0 -0
  30. sp2react-0.1.0/src/sp2react/llm/providers.py +219 -0
  31. sp2react-0.1.0/src/sp2react/migrate.py +255 -0
  32. sp2react-0.1.0/src/sp2react/net.py +60 -0
  33. sp2react-0.1.0/src/sp2react/pipeline.py +583 -0
  34. sp2react-0.1.0/src/sp2react/scaffold/__init__.py +0 -0
  35. sp2react-0.1.0/src/sp2react/scaffold/generate.py +279 -0
  36. sp2react-0.1.0/src/sp2react/scaffold/rule_vectors.json +3826 -0
  37. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/__init__.py +0 -0
  38. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/api.py +293 -0
  39. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/auth.py +33 -0
  40. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/custom/__init__.py +22 -0
  41. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/main.py +47 -0
  42. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/odata.py +185 -0
  43. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/rules.py +256 -0
  44. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/sp_repo.py +159 -0
  45. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/sql_repo.py +437 -0
  46. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/app/store.py +224 -0
  47. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/requirements.txt +8 -0
  48. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/tests/conftest.py +10 -0
  49. sp2react-0.1.0/src/sp2react/scaffold/templates/backend/tests/test_rule_vectors.py +38 -0
  50. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/index.html +12 -0
  51. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/package.json +24 -0
  52. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/scripts/check-rules.ts +23 -0
  53. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/api.ts +88 -0
  54. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/Banner.tsx +4 -0
  55. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/DataTable.tsx +38 -0
  56. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/Form.tsx +252 -0
  57. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/GenericPage.tsx +28 -0
  58. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/Layout.tsx +54 -0
  59. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/LegacyHtml.tsx +9 -0
  60. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/ListView.tsx +59 -0
  61. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/Tiles.tsx +21 -0
  62. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/components/sp/fields.tsx +132 -0
  63. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/custom/types.ts +10 -0
  64. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/main.tsx +14 -0
  65. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/runtime/format.ts +36 -0
  66. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/runtime/rules.ts +225 -0
  67. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/runtime/spec.ts +102 -0
  68. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/runtime/user.tsx +21 -0
  69. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/screens/LegacyRedirect.tsx +27 -0
  70. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/screens/ListFormScreen.tsx +33 -0
  71. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/styles/sp.css +95 -0
  72. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/src/vite-env.d.ts +1 -0
  73. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/tsconfig.json +18 -0
  74. sp2react-0.1.0/src/sp2react/scaffold/templates/frontend/vite.config.ts +7 -0
  75. sp2react-0.1.0/src/sp2react/sharepoint/__init__.py +0 -0
  76. sp2react-0.1.0/src/sp2react/sharepoint/client.py +210 -0
  77. sp2react-0.1.0/src/sp2react/sharepoint/extract.py +217 -0
  78. sp2react-0.1.0/src/sp2react/spec/__init__.py +0 -0
  79. sp2react-0.1.0/src/sp2react/spec/base.py +80 -0
  80. sp2react-0.1.0/src/sp2react/spec/coverage.py +191 -0
  81. sp2react-0.1.0/src/sp2react/spec/model.py +133 -0
  82. sp2react-0.1.0/src/sp2react.egg-info/PKG-INFO +238 -0
  83. sp2react-0.1.0/src/sp2react.egg-info/SOURCES.txt +124 -0
  84. sp2react-0.1.0/src/sp2react.egg-info/dependency_links.txt +1 -0
  85. sp2react-0.1.0/src/sp2react.egg-info/entry_points.txt +2 -0
  86. sp2react-0.1.0/src/sp2react.egg-info/requires.txt +24 -0
  87. sp2react-0.1.0/src/sp2react.egg-info/top_level.txt +1 -0
  88. sp2react-0.1.0/tests/conftest.py +4 -0
  89. sp2react-0.1.0/tests/fixtures/agent_responses/dbmap/mapping.json +96 -0
  90. sp2react-0.1.0/tests/fixtures/agent_responses/page/Dashboard.txt +158 -0
  91. sp2react-0.1.0/tests/fixtures/agent_responses/spec/Dashboard.json +59 -0
  92. sp2react-0.1.0/tests/fixtures/agent_responses/spec/VendorRequests-form.json +97 -0
  93. sp2react-0.1.0/tests/fixtures/legacy-site/files/Lists/VendorRequests/Attachments/2/customs-bond.pdf +5 -0
  94. sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/css/dashboard.css +9 -0
  95. sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/css/vendor-request.css +4 -0
  96. sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/html/review-instructions.html +4 -0
  97. sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/js/dashboard.js +112 -0
  98. sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/js/jquery-1.12.4.min.js +2 -0
  99. sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/js/jquery.SPServices-2014.02.min.js +6 -0
  100. sp2react-0.1.0/tests/fixtures/legacy-site/files/SiteAssets/js/vendor-request-form.js +214 -0
  101. sp2react-0.1.0/tests/fixtures/legacy-site/lists/ComplianceAlerts/fields.json +299 -0
  102. sp2react-0.1.0/tests/fixtures/legacy-site/lists/ComplianceAlerts/items.json +5 -0
  103. sp2react-0.1.0/tests/fixtures/legacy-site/lists/CostCenters/fields.json +276 -0
  104. sp2react-0.1.0/tests/fixtures/legacy-site/lists/CostCenters/items.json +104 -0
  105. sp2react-0.1.0/tests/fixtures/legacy-site/lists/Countries/fields.json +285 -0
  106. sp2react-0.1.0/tests/fixtures/legacy-site/lists/Countries/items.json +188 -0
  107. sp2react-0.1.0/tests/fixtures/legacy-site/lists/Departments/fields.json +251 -0
  108. sp2react-0.1.0/tests/fixtures/legacy-site/lists/Departments/items.json +58 -0
  109. sp2react-0.1.0/tests/fixtures/legacy-site/lists/VendorRequests/fields.json +672 -0
  110. sp2react-0.1.0/tests/fixtures/legacy-site/lists/VendorRequests/items.json +93 -0
  111. sp2react-0.1.0/tests/fixtures/legacy-site/pages/Lists/VendorRequests/DispForm.aspx +105 -0
  112. sp2react-0.1.0/tests/fixtures/legacy-site/pages/Lists/VendorRequests/EditForm.aspx +102 -0
  113. sp2react-0.1.0/tests/fixtures/legacy-site/pages/Lists/VendorRequests/NewForm.aspx +90 -0
  114. sp2react-0.1.0/tests/fixtures/legacy-site/pages/SitePages/Dashboard.aspx +21 -0
  115. sp2react-0.1.0/tests/fixtures/legacy-site/pages/SitePages/Dashboard.aspx.webparts.json +77 -0
  116. sp2react-0.1.0/tests/fixtures/legacy-site/rendered/SitePages/Dashboard.html +22 -0
  117. sp2react-0.1.0/tests/fixtures/legacy-site/site.json +66 -0
  118. sp2react-0.1.0/tests/fixtures/legacy-site/siteusers.json +30 -0
  119. sp2react-0.1.0/tests/migrated_db.py +80 -0
  120. sp2react-0.1.0/tests/mock_sharepoint.py +171 -0
  121. sp2react-0.1.0/tests/scripted_agents.py +37 -0
  122. sp2react-0.1.0/tests/test_agents.py +140 -0
  123. sp2react-0.1.0/tests/test_extract_inventory.py +111 -0
  124. sp2react-0.1.0/tests/test_network.py +87 -0
  125. sp2react-0.1.0/tests/test_pipeline.py +203 -0
  126. sp2react-0.1.0/tests/ui_walkthrough.py +147 -0
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ All notable changes to `sp2react` are documented here.
4
+
5
+ ## [0.1.0] - 2026-10-29
6
+
7
+ First public release.
8
+
9
+ ### Added
10
+ - Ten-stage pipeline (inputs, extract, inventory, spec, approve spec, convert, review, test, fix, approve) with gating: a stage only starts when the one before it is done
11
+ - Read-only SharePoint extraction: `.aspx` source, browser-added web parts, Script Editor / Content Editor content and links, JSLink, custom scripts and CSS, list schemas, views, forms, groups, navigation
12
+ - Inventory of jQuery / SPServices behaviour with file:line references (show/hide, read-only, defaults, cascades, PreSaveAction validation, group checks, redirects, REST and SPServices calls)
13
+ - Spec model, deterministic base spec and a coverage gate that blocks approval until every required behaviour is covered and legacy texts are verbatim
14
+ - AI agents (Claude through GitHub Copilot Bridger by default; Anthropic, OpenAI and Azure OpenAI also supported) for spec, page, custom handler, review, fix and database mapping, each validated before its output is accepted
15
+ - Generated React (Vite + TypeScript) + FastAPI app: shared list-form engine driven by the spec, the same rule engine in the browser and the API (checked by shared test vectors), legacy URL redirects, SharePoint groups as roles
16
+ - `data_source: database`: the generated API reads and writes your existing tables (MySQL, SQL Server, PostgreSQL via SQLAlchemy) through a reviewed list-to-table mapping drafted by `sp2react map-db`; filters, sorting and paging run as SQL
17
+ - `data_source: sqlite`: full paged export of list items and attachments, loaded into a SQLite copy
18
+ - Field-by-field reconciliation report between SharePoint lists and the app's data (opt-in in database mode)
19
+ - Network policy: every request is checked against the configured SharePoint and model hosts, including redirects; list items, attachments, people and rendered pages are never read in database mode
sp2react-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Karthikeyan Balasundaram
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,10 @@
1
+ include README.md
2
+ include LICENSE
3
+ include CHANGELOG.md
4
+ include SECURITY.md
5
+ recursive-include src/sp2react/agents/prompts *.md
6
+ recursive-include src/sp2react/scaffold *
7
+ recursive-include tests *
8
+ prune examples
9
+ global-exclude __pycache__ *.py[cod] *.db
10
+ exclude CLAUDE.md
@@ -0,0 +1,238 @@
1
+ Metadata-Version: 2.4
2
+ Name: sp2react
3
+ Version: 0.1.0
4
+ Summary: AI-agent pipeline that converts classic SharePoint ASPX/jQuery list forms and pages into a React + FastAPI app on your existing database
5
+ Author: Karthikeyan Balasundaram
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/karthikbd/sp2react
8
+ Project-URL: Source Code, https://github.com/karthikbd/sp2react
9
+ Project-URL: Repository, https://github.com/karthikbd/sp2react
10
+ Project-URL: Bug Tracker, https://github.com/karthikbd/sp2react/issues
11
+ Project-URL: Changelog, https://github.com/karthikbd/sp2react/blob/main/CHANGELOG.md
12
+ Project-URL: Documentation, https://github.com/karthikbd/sp2react#readme
13
+ Keywords: sharepoint,sharepoint migration,react,fastapi,jquery,spservices,aspx,list forms,migration,code conversion,ai agents,claude
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Topic :: Software Development :: Code Generators
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: License :: OSI Approved :: MIT License
24
+ Classifier: Operating System :: OS Independent
25
+ Requires-Python: >=3.10
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: pydantic>=2.5
29
+ Requires-Dist: pyyaml>=6.0
30
+ Requires-Dist: requests>=2.31
31
+ Provides-Extra: ntlm
32
+ Requires-Dist: requests-ntlm>=1.2; extra == "ntlm"
33
+ Provides-Extra: db
34
+ Requires-Dist: sqlalchemy>=2.0; extra == "db"
35
+ Provides-Extra: mysql
36
+ Requires-Dist: sqlalchemy>=2.0; extra == "mysql"
37
+ Requires-Dist: pymysql>=1.1; extra == "mysql"
38
+ Provides-Extra: mssql
39
+ Requires-Dist: sqlalchemy>=2.0; extra == "mssql"
40
+ Requires-Dist: pyodbc>=5.0; extra == "mssql"
41
+ Provides-Extra: dev
42
+ Requires-Dist: pytest>=8; extra == "dev"
43
+ Requires-Dist: fastapi>=0.110; extra == "dev"
44
+ Requires-Dist: httpx>=0.27; extra == "dev"
45
+ Requires-Dist: uvicorn>=0.27; extra == "dev"
46
+ Requires-Dist: sqlalchemy>=2.0; extra == "dev"
47
+ Dynamic: license-file
48
+
49
+ # sp2react
50
+
51
+ [![PyPI version](https://badge.fury.io/py/sp2react.svg)](https://pypi.org/project/sp2react/)
52
+ [![Python versions](https://img.shields.io/pypi/pyversions/sp2react.svg)](https://pypi.org/project/sp2react/)
53
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
54
+ [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/karthikbd/sp2react/badge)](https://securityscorecards.dev/viewer/?uri=github.com/karthikbd/sp2react)
55
+
56
+ Convert classic SharePoint (2013 / 2016 / 2019 / Subscription Edition) list forms and pages built with **ASPX, jQuery and SPServices** into a **React + FastAPI** app that runs on **your existing database**.
57
+
58
+ Plain code does everything mechanical. AI agents (Claude through your GitHub Copilot **Bridger** by default) do the parts that need judgement. Nothing an agent writes is accepted until it passes automatic checks.
59
+
60
+ **No business data over HTTP:** in the default `database` mode, list items, attachments and people are never read from SharePoint, and every request is checked against the hosts in your config.
61
+
62
+ ---
63
+
64
+ ## Table of Contents
65
+
66
+ - [Installation](#installation)
67
+ - [Quick Start](#quick-start)
68
+ - [Configuration](#configuration)
69
+ - [The ten stages](#the-ten-stages)
70
+ - [Your existing database](#your-existing-database)
71
+ - [The generated app](#the-generated-app)
72
+ - [Use it from your own tool](#use-it-from-your-own-tool)
73
+ - [What converts and what does not](#what-converts-and-what-does-not)
74
+ - [Running Tests](#running-tests)
75
+ - [CI / CD](#ci--cd)
76
+ - [Security](#security)
77
+ - [Changelog](#changelog)
78
+ - [License](#license)
79
+
80
+ ---
81
+
82
+ ## Installation
83
+
84
+ ```bash
85
+ pip install "sp2react[mysql]" # MySQL / MariaDB tables
86
+ pip install "sp2react[mssql]" # SQL Server tables
87
+ pip install "sp2react[ntlm]" # add for on-premises Windows authentication
88
+ ```
89
+
90
+ Python 3.10+. Node.js 20+ is needed to build the generated React app.
91
+
92
+ ## Quick Start
93
+
94
+ ```bash
95
+ sp2react init # writes sp2react.yaml
96
+ export SP_USERNAME='CORP\me' SP_PASSWORD='...' # or SP_COOKIE / SP_TOKEN
97
+ export BRIDGER_TOKEN='...' # only if Bridger needs one
98
+ export SP2REACT_DB_URL='mysql+pymysql://user:password@db-host:3306/sea'
99
+
100
+ sp2react doctor # checks SharePoint, lists Bridger's Claude models
101
+ sp2react run --page /sites/SEA/SitePages/Dashboard.aspx --until spec
102
+ # review sp2react-work/specs/<screen>.coverage.md, then:
103
+ sp2react approve Dashboard
104
+ sp2react map-db # drafts db-mapping.json; review db-mapping.md
105
+ sp2react run --page /sites/SEA/SitePages/Dashboard.aspx --offline
106
+ sp2react status
107
+ ```
108
+
109
+ ## Configuration
110
+
111
+ ```yaml
112
+ sharepoint:
113
+ site_url: https://sharepoint.example.com/sites/SEA
114
+ auth: ntlm # ntlm | cookie | bearer | none ; secrets come from environment variables
115
+ llm:
116
+ provider: bridger # bridger | anthropic | openai | azure_openai
117
+ api_format: anthropic # how Bridger serves Claude: anthropic (/v1/messages) or openai (/v1/chat/completions)
118
+ base_url: http://localhost:4141
119
+ model: claude-sonnet-4 # exact id from `sp2react doctor`
120
+ api_key_env: BRIDGER_TOKEN
121
+ pipeline:
122
+ data_source: database # database | sqlite | sharepoint
123
+ max_concurrency: 4
124
+ max_fix_iterations: 5
125
+ database:
126
+ url_env: SP2REACT_DB_URL
127
+ mapping: ./db-mapping.json
128
+ security:
129
+ allowed_hosts: []
130
+ ```
131
+
132
+ ## The ten stages
133
+
134
+ Each stage starts only after the previous one has finished.
135
+
136
+ | # | Stage | Who | What happens | Checked by |
137
+ |---|---|---|---|---|
138
+ | 1 | inputs | code | config and connectivity | |
139
+ | 2 | extract | code | `.aspx` source, browser-added web parts, Script Editor / Content Editor content, JSLink, custom JS/CSS, list schemas, views, forms, group names, navigation. GET only | manifest of fetched files and errors |
140
+ | 3 | inventory | code | groups each list's New/Edit/Display forms into one screen and finds every jQuery behaviour and data call, with file:line | deterministic |
141
+ | 4 | spec | **agent** | builds the base spec from the schema, then the agent adds the rules that need interpretation | **coverage gate**: every required behaviour covered, legacy texts verbatim, rules valid |
142
+ | 5 | approve_spec | you | read `specs/<screen>.coverage.md` | |
143
+ | 6 | convert | code + **agents** | writes the fixed scaffold in seconds. List forms are rendered by the shared form engine from the spec; agents write only page components and custom handlers, in parallel | import whitelist, no fetch/jQuery/innerHTML, legacy texts present, `tsc` |
144
+ | 7 | review | **agent** | independent parity review | findings fed to fix |
145
+ | 8 | test | code | generated API tests, rule vectors (browser and API engines must agree), `tsc` + `vite build`, data reconciliation | |
146
+ | 9 | fix | **agent** | gets the real compiler and test output and edits only agent-owned files; up to N rounds | re-test |
147
+ | 10 | approve | you | | |
148
+
149
+ ## Your existing database
150
+
151
+ If your team has already moved the list data into MySQL or SQL Server, the generated FastAPI app reads and writes those tables directly.
152
+
153
+ 1. `sp2react map-db` reads the database **schema only** (tables, columns, types, keys).
154
+ 2. It drafts the mapping: each list to a table, each field to a column, lookups to foreign keys, people to a users table or login column, plus created/modified/author/editor/version columns and attachments.
155
+ 3. The `dbmap` agent resolves what the draft could not, for example `Countries.Title` migrated as `countries.country_name`.
156
+ 4. Validation blocks code generation until every table and column exists and every required field is mapped.
157
+ 5. You review `db-mapping.md`, and can edit `db-mapping.json` directly.
158
+
159
+ At runtime, OData-style queries from the forms and pages (`$filter`, `$orderby`, `$top`, lookup paths such as `Country/Title`) are translated to SQL. Optimistic concurrency uses your version column if you have one, otherwise the modified timestamp.
160
+
161
+ To check the earlier migration, set `security.sharepoint_item_reads: true`. `reconciliation.md` then compares every list item with its row, field by field, including orphaned lookups and attachment checksums.
162
+
163
+ ## The generated app
164
+
165
+ ```bash
166
+ cd converted-app/backend && pip install -r requirements.txt pymysql && cp .env.example .env && uvicorn app.main:app
167
+ cd converted-app/frontend && npm install && npm run dev
168
+ ```
169
+
170
+ - Behaviour comes from the spec at runtime. `runtime/rules.ts` (browser) and `app/rules.py` (API) interpret the same rules, and shared vectors keep them in agreement, so a direct API call cannot bypass a rule.
171
+ - The form uses SharePoint's layout, labels and control titles, the legacy site CSS is carried over, and old URLs (`/Lists/X/EditForm.aspx?ID=3&Source=...`) redirect to the new routes.
172
+ - SharePoint groups become roles. Membership comes from your users/groups tables or `data/roles.json`.
173
+ - Authentication: `AUTH_MODE=dev` for local work; `header` behind your gateway, or Entra ID in `app/auth.py`.
174
+
175
+ ## Use it from your own tool
176
+
177
+ ```python
178
+ from sp2react import Pipeline, load_config
179
+
180
+ p = Pipeline(load_config("sp2react.yaml"), progress=print)
181
+ p.stage_inputs(offline=False)
182
+ p.stage_extract(pages=["SitePages/Dashboard.aspx"], offline=False)
183
+ screens = [s["id"] for s in p.stage_inventory(["SitePages/Dashboard.aspx"])]
184
+ p.stage_spec(screens)
185
+ p.approve("Dashboard", "spec", by="reviewer")
186
+ p.stage_map_db([p.load_spec(s) for s in p.approved_sids()])
187
+ p.stage_convert(screens)
188
+ p.stage_review(screens)
189
+ p.stage_test_and_fix(screens)
190
+ p.state # also written to sp2react-work/state.json
191
+ ```
192
+
193
+ ## What converts and what does not
194
+
195
+ | Converts | Needs your input, or is not converted yet |
196
+ |---|---|
197
+ | List forms (New/Edit/Display) and their jQuery/SPServices behaviour | Workflows, event receivers, compiled solutions: their code is not reachable over REST. They are flagged; export the definitions or source to convert them |
198
+ | Web part pages (SitePages) with Script Editor / Content Editor JavaScript | InfoPath and Power Apps forms: reported, not converted |
199
+ | Basic list views (columns, sort, row limit) | Views with filters and grouping, document libraries, custom master-page branding, rich grids (sort/search/select/export), modal dialogs: planned |
200
+ | SharePoint groups as roles, old URL redirects | Calculated columns are shown but not recomputed; managed metadata, item-level permissions, alert emails |
201
+
202
+ Run the inventory on your site first. It shows which pages and scripts were found and what each one does, before you commit to a conversion.
203
+
204
+ ## Running Tests
205
+
206
+ ```bash
207
+ pip install -e ".[dev]"
208
+ python -m pytest tests/ -v
209
+ ```
210
+
211
+ The suite runs against `tests/fixtures/legacy-site`, a fictional Contoso procurement site with jQuery 1.12 / SPServices list forms and a REST-driven dashboard. It covers:
212
+ - a mock SharePoint server that rejects writes,
213
+ - a scripted stand-in for the model, including retry-on-feedback and give-up,
214
+ - a renamed-schema database standing in for an earlier migration,
215
+ - the network policy,
216
+ - all ten stages including the fix loop,
217
+ - a real `npm install` + `tsc` + `vite build` of the generated app.
218
+
219
+ ## CI / CD
220
+
221
+ - `tests.yml`: runs the test suite on Python 3.10–3.13 on every push and pull request.
222
+ - `python-publish.yml`: on a `v*` tag or a published release, tests, builds and publishes to PyPI through **Trusted Publishing** (OIDC, no stored token).
223
+ - `scorecard.yml`: runs the OpenSSF Scorecard weekly and on every push to `main`.
224
+
225
+ ## Security
226
+
227
+ See [SECURITY.md](SECURITY.md). In short:
228
+ - Requests go only to the configured SharePoint and model hosts, and SharePoint is read-only.
229
+ - In database mode no list data is read over HTTP and no business data is sent to the model.
230
+ - Secrets come from environment variables only.
231
+
232
+ ## Changelog
233
+
234
+ See [CHANGELOG.md](CHANGELOG.md).
235
+
236
+ ## License
237
+
238
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,190 @@
1
+ # sp2react
2
+
3
+ [![PyPI version](https://badge.fury.io/py/sp2react.svg)](https://pypi.org/project/sp2react/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/sp2react.svg)](https://pypi.org/project/sp2react/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+ [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/karthikbd/sp2react/badge)](https://securityscorecards.dev/viewer/?uri=github.com/karthikbd/sp2react)
7
+
8
+ Convert classic SharePoint (2013 / 2016 / 2019 / Subscription Edition) list forms and pages built with **ASPX, jQuery and SPServices** into a **React + FastAPI** app that runs on **your existing database**.
9
+
10
+ Plain code does everything mechanical. AI agents (Claude through your GitHub Copilot **Bridger** by default) do the parts that need judgement. Nothing an agent writes is accepted until it passes automatic checks.
11
+
12
+ **No business data over HTTP:** in the default `database` mode, list items, attachments and people are never read from SharePoint, and every request is checked against the hosts in your config.
13
+
14
+ ---
15
+
16
+ ## Table of Contents
17
+
18
+ - [Installation](#installation)
19
+ - [Quick Start](#quick-start)
20
+ - [Configuration](#configuration)
21
+ - [The ten stages](#the-ten-stages)
22
+ - [Your existing database](#your-existing-database)
23
+ - [The generated app](#the-generated-app)
24
+ - [Use it from your own tool](#use-it-from-your-own-tool)
25
+ - [What converts and what does not](#what-converts-and-what-does-not)
26
+ - [Running Tests](#running-tests)
27
+ - [CI / CD](#ci--cd)
28
+ - [Security](#security)
29
+ - [Changelog](#changelog)
30
+ - [License](#license)
31
+
32
+ ---
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ pip install "sp2react[mysql]" # MySQL / MariaDB tables
38
+ pip install "sp2react[mssql]" # SQL Server tables
39
+ pip install "sp2react[ntlm]" # add for on-premises Windows authentication
40
+ ```
41
+
42
+ Python 3.10+. Node.js 20+ is needed to build the generated React app.
43
+
44
+ ## Quick Start
45
+
46
+ ```bash
47
+ sp2react init # writes sp2react.yaml
48
+ export SP_USERNAME='CORP\me' SP_PASSWORD='...' # or SP_COOKIE / SP_TOKEN
49
+ export BRIDGER_TOKEN='...' # only if Bridger needs one
50
+ export SP2REACT_DB_URL='mysql+pymysql://user:password@db-host:3306/sea'
51
+
52
+ sp2react doctor # checks SharePoint, lists Bridger's Claude models
53
+ sp2react run --page /sites/SEA/SitePages/Dashboard.aspx --until spec
54
+ # review sp2react-work/specs/<screen>.coverage.md, then:
55
+ sp2react approve Dashboard
56
+ sp2react map-db # drafts db-mapping.json; review db-mapping.md
57
+ sp2react run --page /sites/SEA/SitePages/Dashboard.aspx --offline
58
+ sp2react status
59
+ ```
60
+
61
+ ## Configuration
62
+
63
+ ```yaml
64
+ sharepoint:
65
+ site_url: https://sharepoint.example.com/sites/SEA
66
+ auth: ntlm # ntlm | cookie | bearer | none ; secrets come from environment variables
67
+ llm:
68
+ provider: bridger # bridger | anthropic | openai | azure_openai
69
+ api_format: anthropic # how Bridger serves Claude: anthropic (/v1/messages) or openai (/v1/chat/completions)
70
+ base_url: http://localhost:4141
71
+ model: claude-sonnet-4 # exact id from `sp2react doctor`
72
+ api_key_env: BRIDGER_TOKEN
73
+ pipeline:
74
+ data_source: database # database | sqlite | sharepoint
75
+ max_concurrency: 4
76
+ max_fix_iterations: 5
77
+ database:
78
+ url_env: SP2REACT_DB_URL
79
+ mapping: ./db-mapping.json
80
+ security:
81
+ allowed_hosts: []
82
+ ```
83
+
84
+ ## The ten stages
85
+
86
+ Each stage starts only after the previous one has finished.
87
+
88
+ | # | Stage | Who | What happens | Checked by |
89
+ |---|---|---|---|---|
90
+ | 1 | inputs | code | config and connectivity | |
91
+ | 2 | extract | code | `.aspx` source, browser-added web parts, Script Editor / Content Editor content, JSLink, custom JS/CSS, list schemas, views, forms, group names, navigation. GET only | manifest of fetched files and errors |
92
+ | 3 | inventory | code | groups each list's New/Edit/Display forms into one screen and finds every jQuery behaviour and data call, with file:line | deterministic |
93
+ | 4 | spec | **agent** | builds the base spec from the schema, then the agent adds the rules that need interpretation | **coverage gate**: every required behaviour covered, legacy texts verbatim, rules valid |
94
+ | 5 | approve_spec | you | read `specs/<screen>.coverage.md` | |
95
+ | 6 | convert | code + **agents** | writes the fixed scaffold in seconds. List forms are rendered by the shared form engine from the spec; agents write only page components and custom handlers, in parallel | import whitelist, no fetch/jQuery/innerHTML, legacy texts present, `tsc` |
96
+ | 7 | review | **agent** | independent parity review | findings fed to fix |
97
+ | 8 | test | code | generated API tests, rule vectors (browser and API engines must agree), `tsc` + `vite build`, data reconciliation | |
98
+ | 9 | fix | **agent** | gets the real compiler and test output and edits only agent-owned files; up to N rounds | re-test |
99
+ | 10 | approve | you | | |
100
+
101
+ ## Your existing database
102
+
103
+ If your team has already moved the list data into MySQL or SQL Server, the generated FastAPI app reads and writes those tables directly.
104
+
105
+ 1. `sp2react map-db` reads the database **schema only** (tables, columns, types, keys).
106
+ 2. It drafts the mapping: each list to a table, each field to a column, lookups to foreign keys, people to a users table or login column, plus created/modified/author/editor/version columns and attachments.
107
+ 3. The `dbmap` agent resolves what the draft could not, for example `Countries.Title` migrated as `countries.country_name`.
108
+ 4. Validation blocks code generation until every table and column exists and every required field is mapped.
109
+ 5. You review `db-mapping.md`, and can edit `db-mapping.json` directly.
110
+
111
+ At runtime, OData-style queries from the forms and pages (`$filter`, `$orderby`, `$top`, lookup paths such as `Country/Title`) are translated to SQL. Optimistic concurrency uses your version column if you have one, otherwise the modified timestamp.
112
+
113
+ To check the earlier migration, set `security.sharepoint_item_reads: true`. `reconciliation.md` then compares every list item with its row, field by field, including orphaned lookups and attachment checksums.
114
+
115
+ ## The generated app
116
+
117
+ ```bash
118
+ cd converted-app/backend && pip install -r requirements.txt pymysql && cp .env.example .env && uvicorn app.main:app
119
+ cd converted-app/frontend && npm install && npm run dev
120
+ ```
121
+
122
+ - Behaviour comes from the spec at runtime. `runtime/rules.ts` (browser) and `app/rules.py` (API) interpret the same rules, and shared vectors keep them in agreement, so a direct API call cannot bypass a rule.
123
+ - The form uses SharePoint's layout, labels and control titles, the legacy site CSS is carried over, and old URLs (`/Lists/X/EditForm.aspx?ID=3&Source=...`) redirect to the new routes.
124
+ - SharePoint groups become roles. Membership comes from your users/groups tables or `data/roles.json`.
125
+ - Authentication: `AUTH_MODE=dev` for local work; `header` behind your gateway, or Entra ID in `app/auth.py`.
126
+
127
+ ## Use it from your own tool
128
+
129
+ ```python
130
+ from sp2react import Pipeline, load_config
131
+
132
+ p = Pipeline(load_config("sp2react.yaml"), progress=print)
133
+ p.stage_inputs(offline=False)
134
+ p.stage_extract(pages=["SitePages/Dashboard.aspx"], offline=False)
135
+ screens = [s["id"] for s in p.stage_inventory(["SitePages/Dashboard.aspx"])]
136
+ p.stage_spec(screens)
137
+ p.approve("Dashboard", "spec", by="reviewer")
138
+ p.stage_map_db([p.load_spec(s) for s in p.approved_sids()])
139
+ p.stage_convert(screens)
140
+ p.stage_review(screens)
141
+ p.stage_test_and_fix(screens)
142
+ p.state # also written to sp2react-work/state.json
143
+ ```
144
+
145
+ ## What converts and what does not
146
+
147
+ | Converts | Needs your input, or is not converted yet |
148
+ |---|---|
149
+ | List forms (New/Edit/Display) and their jQuery/SPServices behaviour | Workflows, event receivers, compiled solutions: their code is not reachable over REST. They are flagged; export the definitions or source to convert them |
150
+ | Web part pages (SitePages) with Script Editor / Content Editor JavaScript | InfoPath and Power Apps forms: reported, not converted |
151
+ | Basic list views (columns, sort, row limit) | Views with filters and grouping, document libraries, custom master-page branding, rich grids (sort/search/select/export), modal dialogs: planned |
152
+ | SharePoint groups as roles, old URL redirects | Calculated columns are shown but not recomputed; managed metadata, item-level permissions, alert emails |
153
+
154
+ Run the inventory on your site first. It shows which pages and scripts were found and what each one does, before you commit to a conversion.
155
+
156
+ ## Running Tests
157
+
158
+ ```bash
159
+ pip install -e ".[dev]"
160
+ python -m pytest tests/ -v
161
+ ```
162
+
163
+ The suite runs against `tests/fixtures/legacy-site`, a fictional Contoso procurement site with jQuery 1.12 / SPServices list forms and a REST-driven dashboard. It covers:
164
+ - a mock SharePoint server that rejects writes,
165
+ - a scripted stand-in for the model, including retry-on-feedback and give-up,
166
+ - a renamed-schema database standing in for an earlier migration,
167
+ - the network policy,
168
+ - all ten stages including the fix loop,
169
+ - a real `npm install` + `tsc` + `vite build` of the generated app.
170
+
171
+ ## CI / CD
172
+
173
+ - `tests.yml`: runs the test suite on Python 3.10–3.13 on every push and pull request.
174
+ - `python-publish.yml`: on a `v*` tag or a published release, tests, builds and publishes to PyPI through **Trusted Publishing** (OIDC, no stored token).
175
+ - `scorecard.yml`: runs the OpenSSF Scorecard weekly and on every push to `main`.
176
+
177
+ ## Security
178
+
179
+ See [SECURITY.md](SECURITY.md). In short:
180
+ - Requests go only to the configured SharePoint and model hosts, and SharePoint is read-only.
181
+ - In database mode no list data is read over HTTP and no business data is sent to the model.
182
+ - Secrets come from environment variables only.
183
+
184
+ ## Changelog
185
+
186
+ See [CHANGELOG.md](CHANGELOG.md).
187
+
188
+ ## License
189
+
190
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,47 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ | Version | Supported |
6
+ |---------|-----------|
7
+ | 0.1.x | ✅ Active |
8
+
9
+ ## Reporting a Vulnerability
10
+
11
+ **Please do not open a public GitHub issue for security vulnerabilities.**
12
+
13
+ Report vulnerabilities privately via GitHub's [Security Advisories](https://github.com/karthikbd/sp2react/security/advisories/new).
14
+
15
+ You can expect:
16
+ - **Acknowledgement** within 48 hours
17
+ - **Status update** within 7 days
18
+ - **Fix or mitigation** as soon as reasonably possible, coordinated with a disclosure date
19
+
20
+ ## Network access
21
+
22
+ `sp2react` has no telemetry, no update check and no third-party calls. It opens HTTP connections to exactly two kinds of host, both named in your `sp2react.yaml`:
23
+
24
+ | Host | Why | What is sent / received |
25
+ |------|-----|-------------------------|
26
+ | `sharepoint.site_url` | Read the site being converted | GET requests only (the client refuses any other verb). Page source, web part definitions, custom scripts/CSS, list schemas, views, group names, navigation |
27
+ | `llm.base_url` (Bridger, or the provider you chose) | AI agent calls | Page source, scripts, list schemas and the draft spec or code under review |
28
+
29
+ Every request, and every redirect hop, is checked against that allowlist before it is sent (`sp2react/net.py`); anything else raises `NetworkPolicyError`. Extra hosts must be added explicitly under `security.allowed_hosts`.
30
+
31
+ ## Business data
32
+
33
+ With `pipeline.data_source: database` (the default):
34
+ - list items, attachments, site users and rendered pages are **never read** from SharePoint; the client raises `ItemReadBlocked` if anything tries
35
+ - group membership is not read (group names only)
36
+ - no business data is sent to the model; prompts contain code and schema only
37
+ - `sp2react map-db` reads your database **schema** (tables, columns, types, keys) over the database driver; it does not read rows
38
+
39
+ Item reads over HTTP happen only when you set `data_source: sqlite` (sp2react migrates the data itself) or explicitly enable `security.sharepoint_item_reads: true` to reconcile the lists with your tables.
40
+
41
+ ## Secrets
42
+
43
+ Credentials are read from environment variables named in the config (`SP_USERNAME`/`SP_PASSWORD`, `SP_COOKIE`, `SP_TOKEN`, the model token, the database URL). They are never written to the workspace, the generated app or agent transcripts.
44
+
45
+ ## Generated application
46
+
47
+ The generated FastAPI app ships with `AUTH_MODE=dev` (an `X-User` header) for local testing only. Before deployment, use `AUTH_MODE=header` behind an authenticating gateway, or replace `app/auth.py` with Entra ID token validation.
@@ -0,0 +1,62 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sp2react"
7
+ version = "0.1.0"
8
+ authors = [{name = "Karthikeyan Balasundaram"}]
9
+ description = "AI-agent pipeline that converts classic SharePoint ASPX/jQuery list forms and pages into a React + FastAPI app on your existing database"
10
+ readme = "README.md"
11
+ requires-python = ">=3.10"
12
+ license = {text = "MIT"}
13
+ keywords = [
14
+ "sharepoint", "sharepoint migration", "react", "fastapi", "jquery", "spservices",
15
+ "aspx", "list forms", "migration", "code conversion", "ai agents", "claude",
16
+ ]
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Intended Audience :: Developers",
20
+ "Topic :: Software Development :: Code Generators",
21
+ "Topic :: Software Development :: Libraries :: Python Modules",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "License :: OSI Approved :: MIT License",
28
+ "Operating System :: OS Independent",
29
+ ]
30
+ dependencies = [
31
+ "pydantic>=2.5",
32
+ "pyyaml>=6.0",
33
+ "requests>=2.31",
34
+ ]
35
+
36
+ [project.optional-dependencies]
37
+ ntlm = ["requests-ntlm>=1.2"]
38
+ db = ["sqlalchemy>=2.0"]
39
+ mysql = ["sqlalchemy>=2.0", "pymysql>=1.1"]
40
+ mssql = ["sqlalchemy>=2.0", "pyodbc>=5.0"]
41
+ dev = ["pytest>=8", "fastapi>=0.110", "httpx>=0.27", "uvicorn>=0.27", "sqlalchemy>=2.0"]
42
+
43
+ [project.scripts]
44
+ sp2react = "sp2react.cli:main"
45
+
46
+ [project.urls]
47
+ Homepage = "https://github.com/karthikbd/sp2react"
48
+ "Source Code" = "https://github.com/karthikbd/sp2react"
49
+ Repository = "https://github.com/karthikbd/sp2react"
50
+ "Bug Tracker" = "https://github.com/karthikbd/sp2react/issues"
51
+ Changelog = "https://github.com/karthikbd/sp2react/blob/main/CHANGELOG.md"
52
+ Documentation = "https://github.com/karthikbd/sp2react#readme"
53
+
54
+ [tool.setuptools.packages.find]
55
+ where = ["src"]
56
+ include = ["sp2react*"]
57
+
58
+ [tool.setuptools.package-data]
59
+ sp2react = ["agents/prompts/*.md", "scaffold/*.json", "scaffold/templates/**/*"]
60
+
61
+ [tool.pytest.ini_options]
62
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,18 @@
1
+ """sp2react: convert classic SharePoint ASPX/jQuery list forms and pages into React + FastAPI with AI agents.
2
+
3
+ Python API:
4
+ from sp2react import Pipeline, load_config
5
+ p = Pipeline(load_config("sp2react.yaml"))
6
+ p.run(pages=["SitePages/Dashboard.aspx"])
7
+ """
8
+ __version__ = "0.1.0"
9
+
10
+
11
+ def __getattr__(name):
12
+ if name == "Pipeline":
13
+ from .pipeline import Pipeline
14
+ return Pipeline
15
+ if name == "load_config":
16
+ from .config import load_config
17
+ return load_config
18
+ raise AttributeError(name)
File without changes