canvas-chat 0.1.24__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.
- canvas_chat-0.1.24/.bumpversion.cfg +12 -0
- canvas_chat-0.1.24/.github/dependabot.yml +17 -0
- canvas_chat-0.1.24/.github/workflows/auto-release.yaml +177 -0
- canvas_chat-0.1.24/.github/workflows/code-style.yaml +30 -0
- canvas_chat-0.1.24/.github/workflows/modal-deploy.yaml +151 -0
- canvas_chat-0.1.24/.github/workflows/tests.yaml +69 -0
- canvas_chat-0.1.24/.gitignore +180 -0
- canvas_chat-0.1.24/.llamabot/.gitignore +2 -0
- canvas_chat-0.1.24/.llamabot/message_log.db +0 -0
- canvas_chat-0.1.24/.markdownlint.jsonc +4 -0
- canvas_chat-0.1.24/.pre-commit-config.yaml +28 -0
- canvas_chat-0.1.24/AGENTS.md +477 -0
- canvas_chat-0.1.24/PKG-INFO +127 -0
- canvas_chat-0.1.24/README.md +102 -0
- canvas_chat-0.1.24/docs/explanation/auto-layout.md +140 -0
- canvas_chat-0.1.24/docs/explanation/committee-architecture.md +322 -0
- canvas_chat-0.1.24/docs/explanation/matrix-evaluation.md +135 -0
- canvas_chat-0.1.24/docs/explanation/matrix-resize-behavior.md +152 -0
- canvas_chat-0.1.24/docs/explanation/node-protocols.md +211 -0
- canvas_chat-0.1.24/docs/explanation/streaming-architecture.md +72 -0
- canvas_chat-0.1.24/docs/explanation/url-fetching.md +73 -0
- canvas_chat-0.1.24/docs/explanation/webrtc-signaling.md +142 -0
- canvas_chat-0.1.24/docs/how-to/deep-research.md +196 -0
- canvas_chat-0.1.24/docs/how-to/highlight-and-branch.md +268 -0
- canvas_chat-0.1.24/docs/how-to/import-pdfs.md +67 -0
- canvas_chat-0.1.24/docs/how-to/llm-committee.md +307 -0
- canvas_chat-0.1.24/docs/how-to/navigate-nodes.md +46 -0
- canvas_chat-0.1.24/docs/how-to/use-images.md +141 -0
- canvas_chat-0.1.24/docs/how-to/use-matrix-evaluation.md +94 -0
- canvas_chat-0.1.24/docs/how-to/web-search.md +110 -0
- canvas_chat-0.1.24/docs/reference/keyboard-shortcuts.md +178 -0
- canvas_chat-0.1.24/docs/releases/.gitkeep +0 -0
- canvas_chat-0.1.24/docs/releases/v0.1.0.md +92 -0
- canvas_chat-0.1.24/docs/releases/v0.1.1.md +21 -0
- canvas_chat-0.1.24/docs/releases/v0.1.10.md +20 -0
- canvas_chat-0.1.24/docs/releases/v0.1.11.md +20 -0
- canvas_chat-0.1.24/docs/releases/v0.1.12.md +24 -0
- canvas_chat-0.1.24/docs/releases/v0.1.13.md +21 -0
- canvas_chat-0.1.24/docs/releases/v0.1.14.md +19 -0
- canvas_chat-0.1.24/docs/releases/v0.1.15.md +16 -0
- canvas_chat-0.1.24/docs/releases/v0.1.16.md +23 -0
- canvas_chat-0.1.24/docs/releases/v0.1.17.md +16 -0
- canvas_chat-0.1.24/docs/releases/v0.1.18.md +16 -0
- canvas_chat-0.1.24/docs/releases/v0.1.19.md +18 -0
- canvas_chat-0.1.24/docs/releases/v0.1.2.md +17 -0
- canvas_chat-0.1.24/docs/releases/v0.1.20.md +24 -0
- canvas_chat-0.1.24/docs/releases/v0.1.21.md +18 -0
- canvas_chat-0.1.24/docs/releases/v0.1.22.md +15 -0
- canvas_chat-0.1.24/docs/releases/v0.1.23.md +16 -0
- canvas_chat-0.1.24/docs/releases/v0.1.24.md +15 -0
- canvas_chat-0.1.24/docs/releases/v0.1.3.md +15 -0
- canvas_chat-0.1.24/docs/releases/v0.1.4.md +18 -0
- canvas_chat-0.1.24/docs/releases/v0.1.5.md +16 -0
- canvas_chat-0.1.24/docs/releases/v0.1.6.md +17 -0
- canvas_chat-0.1.24/docs/releases/v0.1.7.md +17 -0
- canvas_chat-0.1.24/docs/releases/v0.1.8.md +19 -0
- canvas_chat-0.1.24/docs/releases/v0.1.9.md +17 -0
- canvas_chat-0.1.24/modal_app.py +51 -0
- canvas_chat-0.1.24/package-lock.json +846 -0
- canvas_chat-0.1.24/package.json +14 -0
- canvas_chat-0.1.24/pixi.lock +4157 -0
- canvas_chat-0.1.24/pyproject.toml +67 -0
- canvas_chat-0.1.24/src/canvas_chat/__init__.py +3 -0
- canvas_chat-0.1.24/src/canvas_chat/__main__.py +68 -0
- canvas_chat-0.1.24/src/canvas_chat/app.py +2434 -0
- canvas_chat-0.1.24/src/canvas_chat/static/css/style.css +3490 -0
- canvas_chat-0.1.24/src/canvas_chat/static/index.html +611 -0
- canvas_chat-0.1.24/src/canvas_chat/static/js/app.js +6519 -0
- canvas_chat-0.1.24/src/canvas_chat/static/js/canvas.js +3268 -0
- canvas_chat-0.1.24/src/canvas_chat/static/js/chat.js +201 -0
- canvas_chat-0.1.24/src/canvas_chat/static/js/crdt-graph.js +1704 -0
- canvas_chat-0.1.24/src/canvas_chat/static/js/graph.js +1257 -0
- canvas_chat-0.1.24/src/canvas_chat/static/js/node-protocols.js +666 -0
- canvas_chat-0.1.24/src/canvas_chat/static/js/search.js +326 -0
- canvas_chat-0.1.24/src/canvas_chat/static/js/sse.js +188 -0
- canvas_chat-0.1.24/src/canvas_chat/static/js/storage.js +404 -0
- canvas_chat-0.1.24/tests/__init__.py +0 -0
- canvas_chat-0.1.24/tests/test_models.py +339 -0
- canvas_chat-0.1.24/tests/test_node_protocols.js +511 -0
- canvas_chat-0.1.24/tests/test_search.js +444 -0
- canvas_chat-0.1.24/tests/test_ui.js +577 -0
- canvas_chat-0.1.24/tests/test_utils.js +2410 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[bumpversion]
|
|
2
|
+
current_version = 0.1.24
|
|
3
|
+
commit = True
|
|
4
|
+
tag = True
|
|
5
|
+
|
|
6
|
+
[bumpversion:file:pyproject.toml]
|
|
7
|
+
search = version = "{current_version}"
|
|
8
|
+
replace = version = "{new_version}"
|
|
9
|
+
|
|
10
|
+
[bumpversion:file:src/canvas_chat/__init__.py]
|
|
11
|
+
search = __version__ = "{current_version}"
|
|
12
|
+
replace = __version__ = "{new_version}"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Dependabot configuration
|
|
2
|
+
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
|
3
|
+
|
|
4
|
+
version: 2
|
|
5
|
+
updates:
|
|
6
|
+
# Keep GitHub Actions up to date
|
|
7
|
+
- package-ecosystem: "github-actions"
|
|
8
|
+
directory: "/"
|
|
9
|
+
schedule:
|
|
10
|
+
interval: "weekly"
|
|
11
|
+
day: "monday"
|
|
12
|
+
commit-message:
|
|
13
|
+
prefix: "ci"
|
|
14
|
+
labels:
|
|
15
|
+
- "dependencies"
|
|
16
|
+
- "github-actions"
|
|
17
|
+
open-pull-requests-limit: 5
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
name: Auto-release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
# Automatic patch release after tests pass on main.
|
|
5
|
+
# This triggers whenever the "Tests" workflow completes.
|
|
6
|
+
# The job-level `if` condition ensures we only release when:
|
|
7
|
+
# 1. Tests passed (conclusion == 'success')
|
|
8
|
+
# 2. It was a push event (not a PR) - i.e., code was merged to main
|
|
9
|
+
workflow_run:
|
|
10
|
+
workflows: ["Tests"]
|
|
11
|
+
types:
|
|
12
|
+
- completed
|
|
13
|
+
branches:
|
|
14
|
+
- main
|
|
15
|
+
|
|
16
|
+
# Manual release for minor/major versions.
|
|
17
|
+
# To cut a new release, navigate to the Actions section of the repo
|
|
18
|
+
# and select this workflow (Auto-release) on the right hand side.
|
|
19
|
+
# Then, click "Run workflow" and select major, minor, or patch.
|
|
20
|
+
workflow_dispatch:
|
|
21
|
+
inputs:
|
|
22
|
+
version_name:
|
|
23
|
+
description: "One of major, minor, or patch"
|
|
24
|
+
required: true
|
|
25
|
+
type: choice
|
|
26
|
+
options:
|
|
27
|
+
- major
|
|
28
|
+
- minor
|
|
29
|
+
- patch
|
|
30
|
+
|
|
31
|
+
permissions:
|
|
32
|
+
contents: write
|
|
33
|
+
id-token: write
|
|
34
|
+
|
|
35
|
+
env:
|
|
36
|
+
DEFAULT_VERSION_NAME: patch
|
|
37
|
+
|
|
38
|
+
jobs:
|
|
39
|
+
release:
|
|
40
|
+
name: Create a new release
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
# Run if:
|
|
43
|
+
# 1. Manual trigger (workflow_dispatch), OR
|
|
44
|
+
# 2. Automatic trigger where deploy passed AND it was a push (not PR)
|
|
45
|
+
if: |
|
|
46
|
+
github.event_name == 'workflow_dispatch' ||
|
|
47
|
+
(github.event.workflow_run.conclusion == 'success' &&
|
|
48
|
+
github.event.workflow_run.event == 'push')
|
|
49
|
+
|
|
50
|
+
steps:
|
|
51
|
+
- name: Checkout repository
|
|
52
|
+
uses: actions/checkout@v6
|
|
53
|
+
with:
|
|
54
|
+
fetch-depth: 0
|
|
55
|
+
fetch-tags: true
|
|
56
|
+
|
|
57
|
+
- name: Pull latest commits of main branch
|
|
58
|
+
run: |
|
|
59
|
+
git checkout main
|
|
60
|
+
git pull
|
|
61
|
+
|
|
62
|
+
- name: Check if already released
|
|
63
|
+
id: check_release
|
|
64
|
+
run: |
|
|
65
|
+
CURRENT_COMMIT=$(git rev-parse HEAD)
|
|
66
|
+
echo "Current commit: $CURRENT_COMMIT"
|
|
67
|
+
if git tag --points-at $CURRENT_COMMIT | grep -q "^v"; then
|
|
68
|
+
echo "already_released=true" >> $GITHUB_OUTPUT
|
|
69
|
+
echo "This commit already has a release tag. Will skip release."
|
|
70
|
+
git tag --points-at $CURRENT_COMMIT
|
|
71
|
+
else
|
|
72
|
+
echo "already_released=false" >> $GITHUB_OUTPUT
|
|
73
|
+
echo "No release tag found. Proceeding with release."
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
- name: Setup Python environment
|
|
77
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
78
|
+
uses: actions/setup-python@v6
|
|
79
|
+
with:
|
|
80
|
+
python-version: "3.12"
|
|
81
|
+
|
|
82
|
+
- name: Install uv
|
|
83
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
84
|
+
uses: astral-sh/setup-uv@v7
|
|
85
|
+
|
|
86
|
+
- name: Set up Python tools
|
|
87
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
88
|
+
run: uv tool install bump2version
|
|
89
|
+
|
|
90
|
+
- name: Set version name
|
|
91
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
92
|
+
run: echo "VERSION_NAME=${{ github.event.inputs.version_name || env.DEFAULT_VERSION_NAME }}" >> $GITHUB_ENV
|
|
93
|
+
|
|
94
|
+
- name: Dry run bump2version
|
|
95
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
96
|
+
run: bump2version --dry-run ${{ env.VERSION_NAME }} --allow-dirty --verbose
|
|
97
|
+
|
|
98
|
+
- name: Store new version number
|
|
99
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
100
|
+
run: echo "version_number=$(bump2version --dry-run --list ${{ env.VERSION_NAME }} | grep new_version | sed -r 's/^.*=//')" >> $GITHUB_ENV
|
|
101
|
+
|
|
102
|
+
- name: Display new version number
|
|
103
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
104
|
+
run: |
|
|
105
|
+
echo "version_name: ${{ env.VERSION_NAME }}"
|
|
106
|
+
echo "version_number: v${{ env.version_number }}"
|
|
107
|
+
|
|
108
|
+
- name: Ensure repo status is clean
|
|
109
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
110
|
+
run: git status
|
|
111
|
+
|
|
112
|
+
- name: Configure Git
|
|
113
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
114
|
+
run: |
|
|
115
|
+
git config user.name github-actions
|
|
116
|
+
git config user.email github-actions@github.com
|
|
117
|
+
|
|
118
|
+
- name: Run bump2version
|
|
119
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
120
|
+
run: bump2version ${{ env.VERSION_NAME }} --verbose
|
|
121
|
+
|
|
122
|
+
- name: Sync pixi.lock
|
|
123
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
124
|
+
uses: prefix-dev/setup-pixi@v0.9.3
|
|
125
|
+
with:
|
|
126
|
+
run-install: false
|
|
127
|
+
|
|
128
|
+
- name: Update pixi.lock
|
|
129
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
130
|
+
run: pixi lock
|
|
131
|
+
|
|
132
|
+
- name: Ensure tag creation
|
|
133
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
134
|
+
run: git tag | grep ${{ env.version_number }}
|
|
135
|
+
|
|
136
|
+
- name: Install llamabot
|
|
137
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
138
|
+
run: uv tool install llamabot[cli]
|
|
139
|
+
|
|
140
|
+
- name: Write release notes
|
|
141
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
142
|
+
env:
|
|
143
|
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
144
|
+
run: |
|
|
145
|
+
llamabot configure default-model --model-name="gpt-4.1-mini"
|
|
146
|
+
llamabot git write-release-notes
|
|
147
|
+
|
|
148
|
+
- name: Commit release notes
|
|
149
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
150
|
+
run: |
|
|
151
|
+
git add .
|
|
152
|
+
git commit -m "Add release notes for v${{ env.version_number }}"
|
|
153
|
+
|
|
154
|
+
- name: Build package
|
|
155
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
156
|
+
run: uv build --sdist --wheel
|
|
157
|
+
|
|
158
|
+
- name: Publish package (trusted publishing)
|
|
159
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
160
|
+
run: uv publish --trusted-publishing always
|
|
161
|
+
|
|
162
|
+
- name: Push changes with tags
|
|
163
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
164
|
+
run: |
|
|
165
|
+
git push && git push --tags
|
|
166
|
+
|
|
167
|
+
- name: Create release in GitHub repo
|
|
168
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
169
|
+
uses: ncipollo/release-action@v1
|
|
170
|
+
with:
|
|
171
|
+
bodyFile: "docs/releases/v${{ env.version_number }}.md"
|
|
172
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
173
|
+
tag: v${{ env.version_number }}
|
|
174
|
+
|
|
175
|
+
- name: Ensure complete
|
|
176
|
+
if: steps.check_release.outputs.already_released == 'false'
|
|
177
|
+
run: echo "Auto-release complete!"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Run code style checks on each pull request.
|
|
2
|
+
name: Code style checks
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
pull_request:
|
|
6
|
+
push:
|
|
7
|
+
branches:
|
|
8
|
+
- main
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
linting:
|
|
12
|
+
env:
|
|
13
|
+
# Configure a constant location for the uv cache
|
|
14
|
+
UV_CACHE_DIR: /tmp/.uv-cache
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v6
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v7
|
|
21
|
+
|
|
22
|
+
- name: Setup Pixi Environment
|
|
23
|
+
uses: prefix-dev/setup-pixi@v0.9.3
|
|
24
|
+
with:
|
|
25
|
+
pixi-version: latest
|
|
26
|
+
cache: true
|
|
27
|
+
cache-write: ${{ github.event_name == 'push' && github.ref_name == 'main' }}
|
|
28
|
+
|
|
29
|
+
- name: Run pre-commit
|
|
30
|
+
run: uvx pre-commit run --all-files
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
name: Deploy to Modal
|
|
2
|
+
|
|
3
|
+
permissions:
|
|
4
|
+
contents: read
|
|
5
|
+
issues: write
|
|
6
|
+
pull-requests: write
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
branches:
|
|
11
|
+
- main
|
|
12
|
+
pull_request:
|
|
13
|
+
types: [opened, synchronize, reopened]
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
deploy:
|
|
17
|
+
name: Deploy Canvas Chat
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
env:
|
|
20
|
+
MODAL_TOKEN_ID: ${{ secrets.MODAL_TOKEN_ID }}
|
|
21
|
+
MODAL_TOKEN_SECRET: ${{ secrets.MODAL_TOKEN_SECRET }}
|
|
22
|
+
# Deployed app URLs (not Modal dashboard URLs)
|
|
23
|
+
TEST_APP_URL: "https://ericmjl-test--canvas-chat-fastapi-app.modal.run"
|
|
24
|
+
MAIN_APP_URL: "https://ericmjl--canvas-chat-fastapi-app.modal.run"
|
|
25
|
+
outputs:
|
|
26
|
+
test_url: ${{ steps.deploy-test.outputs.url }}
|
|
27
|
+
main_url: ${{ steps.deploy-main.outputs.url }}
|
|
28
|
+
test_app_url: ${{ steps.deploy-test.outputs.app_url }}
|
|
29
|
+
main_app_url: ${{ steps.deploy-main.outputs.app_url }}
|
|
30
|
+
|
|
31
|
+
steps:
|
|
32
|
+
- name: Checkout repository
|
|
33
|
+
uses: actions/checkout@v6
|
|
34
|
+
|
|
35
|
+
- name: Install uv
|
|
36
|
+
uses: astral-sh/setup-uv@v7
|
|
37
|
+
|
|
38
|
+
- name: Deploy to test environment (PR)
|
|
39
|
+
if: github.event_name == 'pull_request'
|
|
40
|
+
id: deploy-test
|
|
41
|
+
run: |
|
|
42
|
+
OUTPUT=$(uv run --with modal modal deploy modal_app.py -e test 2>&1)
|
|
43
|
+
echo "$OUTPUT"
|
|
44
|
+
URL=$(echo "$OUTPUT" | grep -oE 'https://modal\.com/apps/[^ ]+' | head -1)
|
|
45
|
+
echo "url=$URL" >> $GITHUB_OUTPUT
|
|
46
|
+
echo "app_url=$TEST_APP_URL" >> $GITHUB_OUTPUT
|
|
47
|
+
|
|
48
|
+
- name: Deploy to main environment (push to main)
|
|
49
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
50
|
+
id: deploy-main
|
|
51
|
+
run: |
|
|
52
|
+
OUTPUT=$(uv run --with modal modal deploy modal_app.py 2>&1)
|
|
53
|
+
echo "$OUTPUT"
|
|
54
|
+
URL=$(echo "$OUTPUT" | grep -oE 'https://modal\.com/apps/[^ ]+' | head -1)
|
|
55
|
+
echo "url=$URL" >> $GITHUB_OUTPUT
|
|
56
|
+
echo "app_url=$MAIN_APP_URL" >> $GITHUB_OUTPUT
|
|
57
|
+
|
|
58
|
+
- name: Health check (test deploy)
|
|
59
|
+
if: github.event_name == 'pull_request'
|
|
60
|
+
run: |
|
|
61
|
+
URL="${TEST_APP_URL}/health"
|
|
62
|
+
echo "Checking health for $URL"
|
|
63
|
+
for i in 1 2 3 4 5; do
|
|
64
|
+
status=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 5 --max-time 10 "$URL" || echo "000")
|
|
65
|
+
echo "Attempt $i: HTTP $status"
|
|
66
|
+
if [ "$status" = "200" ]; then
|
|
67
|
+
echo "Deployment healthy"
|
|
68
|
+
exit 0
|
|
69
|
+
fi
|
|
70
|
+
sleep 3
|
|
71
|
+
done
|
|
72
|
+
echo "Deployment health check failed for $URL"
|
|
73
|
+
exit 1
|
|
74
|
+
|
|
75
|
+
- name: Health check (main deploy)
|
|
76
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
77
|
+
run: |
|
|
78
|
+
URL="${MAIN_APP_URL}/health"
|
|
79
|
+
echo "Checking health for $URL"
|
|
80
|
+
for i in 1 2 3 4 5; do
|
|
81
|
+
status=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 5 --max-time 10 "$URL" || echo "000")
|
|
82
|
+
echo "Attempt $i: HTTP $status"
|
|
83
|
+
if [ "$status" = "200" ]; then
|
|
84
|
+
echo "Deployment healthy"
|
|
85
|
+
exit 0
|
|
86
|
+
fi
|
|
87
|
+
sleep 3
|
|
88
|
+
done
|
|
89
|
+
echo "Deployment health check failed for $URL"
|
|
90
|
+
exit 1
|
|
91
|
+
|
|
92
|
+
- name: Write deployment summary
|
|
93
|
+
run: |
|
|
94
|
+
echo "## 🚀 Modal Deployment" >> $GITHUB_STEP_SUMMARY
|
|
95
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
96
|
+
if [ "${{ github.event_name }}" == "pull_request" ]; then
|
|
97
|
+
echo "**Environment:** test" >> $GITHUB_STEP_SUMMARY
|
|
98
|
+
echo "**App URL:** ${TEST_APP_URL}" >> $GITHUB_STEP_SUMMARY
|
|
99
|
+
echo "**Dashboard:** ${{ steps.deploy-test.outputs.url }}" >> $GITHUB_STEP_SUMMARY
|
|
100
|
+
else
|
|
101
|
+
echo "**Environment:** main" >> $GITHUB_STEP_SUMMARY
|
|
102
|
+
echo "**App URL:** ${MAIN_APP_URL}" >> $GITHUB_STEP_SUMMARY
|
|
103
|
+
echo "**Dashboard:** ${{ steps.deploy-main.outputs.url }}" >> $GITHUB_STEP_SUMMARY
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
post-pr-comment:
|
|
108
|
+
name: Post PR comment
|
|
109
|
+
runs-on: ubuntu-latest
|
|
110
|
+
needs: deploy
|
|
111
|
+
if: github.event_name == 'pull_request'
|
|
112
|
+
steps:
|
|
113
|
+
- name: Post or update PR comment
|
|
114
|
+
uses: actions/github-script@v7
|
|
115
|
+
with:
|
|
116
|
+
script: |
|
|
117
|
+
const marker = '<!-- modal-deploy-comment -->';
|
|
118
|
+
const appUrl = '${{ needs.deploy.outputs.test_app_url }}';
|
|
119
|
+
const dashboardUrl = '${{ needs.deploy.outputs.test_url }}';
|
|
120
|
+
const body = `${marker}
|
|
121
|
+
## 🚀 Modal Deployment
|
|
122
|
+
|
|
123
|
+
**Environment:** test
|
|
124
|
+
**App URL:** ${appUrl}
|
|
125
|
+
**Dashboard:** ${dashboardUrl}
|
|
126
|
+
|
|
127
|
+
_This comment is automatically updated on each push._`;
|
|
128
|
+
|
|
129
|
+
const { data: comments } = await github.rest.issues.listComments({
|
|
130
|
+
owner: context.repo.owner,
|
|
131
|
+
repo: context.repo.repo,
|
|
132
|
+
issue_number: context.issue.number,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const existing = comments.find(c => c.body.includes(marker));
|
|
136
|
+
|
|
137
|
+
if (existing) {
|
|
138
|
+
await github.rest.issues.updateComment({
|
|
139
|
+
owner: context.repo.owner,
|
|
140
|
+
repo: context.repo.repo,
|
|
141
|
+
comment_id: existing.id,
|
|
142
|
+
body: body,
|
|
143
|
+
});
|
|
144
|
+
} else {
|
|
145
|
+
await github.rest.issues.createComment({
|
|
146
|
+
owner: context.repo.owner,
|
|
147
|
+
repo: context.repo.repo,
|
|
148
|
+
issue_number: context.issue.number,
|
|
149
|
+
body: body,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
paths:
|
|
8
|
+
- "src/**"
|
|
9
|
+
- "tests/**"
|
|
10
|
+
- "pyproject.toml"
|
|
11
|
+
- ".github/workflows/tests.yaml"
|
|
12
|
+
pull_request:
|
|
13
|
+
branches:
|
|
14
|
+
- main
|
|
15
|
+
paths:
|
|
16
|
+
- "src/**"
|
|
17
|
+
- "tests/**"
|
|
18
|
+
- "pyproject.toml"
|
|
19
|
+
- "package.json"
|
|
20
|
+
- "package-lock.json"
|
|
21
|
+
- ".github/workflows/tests.yaml"
|
|
22
|
+
|
|
23
|
+
concurrency:
|
|
24
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
25
|
+
cancel-in-progress: true
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
python-tests:
|
|
29
|
+
name: Python tests (Python ${{ matrix.python-version }})
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
strategy:
|
|
32
|
+
fail-fast: false
|
|
33
|
+
matrix:
|
|
34
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
35
|
+
|
|
36
|
+
steps:
|
|
37
|
+
- name: Checkout repository
|
|
38
|
+
uses: actions/checkout@v6
|
|
39
|
+
|
|
40
|
+
- name: Setup Python
|
|
41
|
+
uses: actions/setup-python@v6
|
|
42
|
+
with:
|
|
43
|
+
python-version: ${{ matrix.python-version }}
|
|
44
|
+
|
|
45
|
+
- name: Install uv
|
|
46
|
+
uses: astral-sh/setup-uv@v7
|
|
47
|
+
|
|
48
|
+
- name: Install dependencies
|
|
49
|
+
run: uv pip install --system -e ".[dev]"
|
|
50
|
+
|
|
51
|
+
- name: Run Python tests
|
|
52
|
+
run: pytest tests/ -v --color=yes
|
|
53
|
+
|
|
54
|
+
javascript-tests:
|
|
55
|
+
name: JavaScript tests
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
|
|
58
|
+
steps:
|
|
59
|
+
- name: Checkout repository
|
|
60
|
+
uses: actions/checkout@v6
|
|
61
|
+
|
|
62
|
+
- name: Install pixi
|
|
63
|
+
uses: prefix-dev/setup-pixi@v0.9.3
|
|
64
|
+
|
|
65
|
+
- name: Install npm dependencies
|
|
66
|
+
run: pixi run npm install
|
|
67
|
+
|
|
68
|
+
- name: Run JavaScript tests
|
|
69
|
+
run: pixi run test-js
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Created by https://www.toptal.com/developers/gitignore/api/python
|
|
2
|
+
# Edit at https://www.toptal.com/developers/gitignore?templates=python
|
|
3
|
+
|
|
4
|
+
### Python ###
|
|
5
|
+
# Byte-compiled / optimized / DLL files
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[cod]
|
|
8
|
+
*$py.class
|
|
9
|
+
|
|
10
|
+
# C extensions
|
|
11
|
+
*.so
|
|
12
|
+
|
|
13
|
+
# Distribution / packaging
|
|
14
|
+
.Python
|
|
15
|
+
build/
|
|
16
|
+
develop-eggs/
|
|
17
|
+
dist/
|
|
18
|
+
downloads/
|
|
19
|
+
eggs/
|
|
20
|
+
.eggs/
|
|
21
|
+
lib/
|
|
22
|
+
lib64/
|
|
23
|
+
parts/
|
|
24
|
+
sdist/
|
|
25
|
+
var/
|
|
26
|
+
wheels/
|
|
27
|
+
share/python-wheels/
|
|
28
|
+
*.egg-info/
|
|
29
|
+
.installed.cfg
|
|
30
|
+
*.egg
|
|
31
|
+
MANIFEST
|
|
32
|
+
|
|
33
|
+
# PyInstaller
|
|
34
|
+
# Usually these files are written by a python script from a template
|
|
35
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
36
|
+
*.manifest
|
|
37
|
+
*.spec
|
|
38
|
+
|
|
39
|
+
# Installer logs
|
|
40
|
+
pip-log.txt
|
|
41
|
+
pip-delete-this-directory.txt
|
|
42
|
+
|
|
43
|
+
# Unit test / coverage reports
|
|
44
|
+
htmlcov/
|
|
45
|
+
.tox/
|
|
46
|
+
.nox/
|
|
47
|
+
.coverage
|
|
48
|
+
.coverage.*
|
|
49
|
+
.cache
|
|
50
|
+
nosetests.xml
|
|
51
|
+
coverage.xml
|
|
52
|
+
*.cover
|
|
53
|
+
*.py,cover
|
|
54
|
+
.hypothesis/
|
|
55
|
+
.pytest_cache/
|
|
56
|
+
cover/
|
|
57
|
+
|
|
58
|
+
# Translations
|
|
59
|
+
*.mo
|
|
60
|
+
*.pot
|
|
61
|
+
|
|
62
|
+
# Django stuff:
|
|
63
|
+
*.log
|
|
64
|
+
local_settings.py
|
|
65
|
+
db.sqlite3
|
|
66
|
+
db.sqlite3-journal
|
|
67
|
+
|
|
68
|
+
# Flask stuff:
|
|
69
|
+
instance/
|
|
70
|
+
.webassets-cache
|
|
71
|
+
|
|
72
|
+
# Scrapy stuff:
|
|
73
|
+
.scrapy
|
|
74
|
+
|
|
75
|
+
# Sphinx documentation
|
|
76
|
+
docs/_build/
|
|
77
|
+
|
|
78
|
+
# PyBuilder
|
|
79
|
+
.pybuilder/
|
|
80
|
+
target/
|
|
81
|
+
|
|
82
|
+
# Jupyter Notebook
|
|
83
|
+
.ipynb_checkpoints
|
|
84
|
+
|
|
85
|
+
# IPython
|
|
86
|
+
profile_default/
|
|
87
|
+
ipython_config.py
|
|
88
|
+
|
|
89
|
+
# pyenv
|
|
90
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
91
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
92
|
+
# .python-version
|
|
93
|
+
|
|
94
|
+
# pipenv
|
|
95
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
96
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
97
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
98
|
+
# install all needed dependencies.
|
|
99
|
+
#Pipfile.lock
|
|
100
|
+
|
|
101
|
+
# poetry
|
|
102
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
103
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
104
|
+
# commonly ignored for libraries.
|
|
105
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
106
|
+
#poetry.lock
|
|
107
|
+
|
|
108
|
+
# pdm
|
|
109
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
110
|
+
#pdm.lock
|
|
111
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
112
|
+
# in version control.
|
|
113
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
114
|
+
.pdm.toml
|
|
115
|
+
|
|
116
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
117
|
+
__pypackages__/
|
|
118
|
+
|
|
119
|
+
# Celery stuff
|
|
120
|
+
celerybeat-schedule
|
|
121
|
+
celerybeat.pid
|
|
122
|
+
|
|
123
|
+
# SageMath parsed files
|
|
124
|
+
*.sage.py
|
|
125
|
+
|
|
126
|
+
# Environments
|
|
127
|
+
.env
|
|
128
|
+
.venv
|
|
129
|
+
env/
|
|
130
|
+
venv/
|
|
131
|
+
ENV/
|
|
132
|
+
env.bak/
|
|
133
|
+
venv.bak/
|
|
134
|
+
|
|
135
|
+
# Spyder project settings
|
|
136
|
+
.spyderproject
|
|
137
|
+
.spyproject
|
|
138
|
+
|
|
139
|
+
# Rope project settings
|
|
140
|
+
.ropeproject
|
|
141
|
+
|
|
142
|
+
# mkdocs documentation
|
|
143
|
+
/site
|
|
144
|
+
|
|
145
|
+
# mypy
|
|
146
|
+
.mypy_cache/
|
|
147
|
+
.dmypy.json
|
|
148
|
+
dmypy.json
|
|
149
|
+
|
|
150
|
+
# Pyre type checker
|
|
151
|
+
.pyre/
|
|
152
|
+
|
|
153
|
+
# pytype static type analyzer
|
|
154
|
+
.pytype/
|
|
155
|
+
|
|
156
|
+
# Cython debug symbols
|
|
157
|
+
cython_debug/
|
|
158
|
+
|
|
159
|
+
# PyCharm
|
|
160
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
161
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
162
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
163
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
164
|
+
#.idea/
|
|
165
|
+
|
|
166
|
+
### Python Patch ###
|
|
167
|
+
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
|
|
168
|
+
poetry.toml
|
|
169
|
+
|
|
170
|
+
# ruff
|
|
171
|
+
.ruff_cache/
|
|
172
|
+
|
|
173
|
+
# LSP config files
|
|
174
|
+
pyrightconfig.json
|
|
175
|
+
|
|
176
|
+
# End of https://www.toptal.com/developers/gitignore/api/python
|
|
177
|
+
.envrc
|
|
178
|
+
|
|
179
|
+
# Node.js
|
|
180
|
+
node_modules/
|
|
Binary file
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v5.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: check-yaml
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: trailing-whitespace
|
|
8
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
9
|
+
# Ruff version.
|
|
10
|
+
rev: v0.11.10
|
|
11
|
+
hooks:
|
|
12
|
+
- id: ruff
|
|
13
|
+
args: [--fix, --exit-non-zero-on-fix]
|
|
14
|
+
types_or: [python]
|
|
15
|
+
- id: ruff-format
|
|
16
|
+
types_or: [python]
|
|
17
|
+
- repo: https://github.com/DavidAnson/markdownlint-cli2
|
|
18
|
+
rev: v0.17.2
|
|
19
|
+
hooks:
|
|
20
|
+
- id: markdownlint-cli2
|
|
21
|
+
args: ["--fix"]
|
|
22
|
+
- repo: local
|
|
23
|
+
hooks:
|
|
24
|
+
- id: pixi-lock
|
|
25
|
+
name: Update pixi.lock
|
|
26
|
+
entry: pixi lock
|
|
27
|
+
language: system
|
|
28
|
+
pass_filenames: false
|