capus 0.2.0__py3-none-any.whl
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.
- capus-0.2.0.dist-info/METADATA +325 -0
- capus-0.2.0.dist-info/RECORD +76 -0
- capus-0.2.0.dist-info/WHEEL +4 -0
- capus-0.2.0.dist-info/entry_points.txt +2 -0
- capus-0.2.0.dist-info/licenses/LICENSE +202 -0
- capusd/__init__.py +3 -0
- capusd/agentic.py +229 -0
- capusd/assets/claude-plugin/.claude-plugin/marketplace.json +11 -0
- capusd/assets/claude-plugin/capus/.claude-plugin/plugin.json +6 -0
- capusd/assets/claude-plugin/capus/.mcp.json +8 -0
- capusd/assets/claude-plugin/capus/agents/capus-agent-tester.md +72 -0
- capusd/assets/claude-plugin/capus/agents/capus-judge.md +72 -0
- capusd/assets/claude-plugin/capus/agents/capus-tester.md +215 -0
- capusd/assets/claude-plugin/capus/skills/credentials/SKILL.md +52 -0
- capusd/assets/claude-plugin/capus/skills/doctor/SKILL.md +68 -0
- capusd/assets/claude-plugin/capus/skills/fix/SKILL.md +42 -0
- capusd/assets/claude-plugin/capus/skills/help/SKILL.md +97 -0
- capusd/assets/claude-plugin/capus/skills/personas/SKILL.md +83 -0
- capusd/assets/claude-plugin/capus/skills/recon/SKILL.md +72 -0
- capusd/assets/claude-plugin/capus/skills/report/SKILL.md +28 -0
- capusd/assets/claude-plugin/capus/skills/run/SKILL.md +91 -0
- capusd/assets/claude-plugin/capus/skills/setup/SKILL.md +77 -0
- capusd/assets/claude-plugin/capus/skills/spec/SKILL.md +124 -0
- capusd/assets/claude-plugin/capus/skills/status/SKILL.md +91 -0
- capusd/cli.py +176 -0
- capusd/config.py +81 -0
- capusd/dashboard.py +1301 -0
- capusd/dashboard_static/css/base.css +93 -0
- capusd/dashboard_static/css/components.css +393 -0
- capusd/dashboard_static/css/layout.css +214 -0
- capusd/dashboard_static/css/tokens.css +95 -0
- capusd/dashboard_static/css/views.css +221 -0
- capusd/dashboard_static/index.html +82 -0
- capusd/dashboard_static/js/api.js +50 -0
- capusd/dashboard_static/js/app.js +101 -0
- capusd/dashboard_static/js/components/handoff.js +145 -0
- capusd/dashboard_static/js/format.js +129 -0
- capusd/dashboard_static/js/ui.js +127 -0
- capusd/dashboard_static/js/views/credentials.js +84 -0
- capusd/dashboard_static/js/views/live.js +86 -0
- capusd/dashboard_static/js/views/new_run.js +177 -0
- capusd/dashboard_static/js/views/overview.js +102 -0
- capusd/dashboard_static/js/views/personas.js +276 -0
- capusd/dashboard_static/js/views/run.js +363 -0
- capusd/dashboard_static/js/views/runs.js +77 -0
- capusd/dashboard_static/js/views/session.js +81 -0
- capusd/dashboard_static/js/views/setup.js +162 -0
- capusd/dashboard_static/js/views/specs.js +162 -0
- capusd/doctor.py +176 -0
- capusd/driver/__init__.py +11 -0
- capusd/driver/base.py +68 -0
- capusd/driver/browser.py +468 -0
- capusd/driver/dom_extract.js +260 -0
- capusd/driver/keys.py +136 -0
- capusd/driver/macos.py +479 -0
- capusd/driver/safety.py +65 -0
- capusd/fixtures.py +87 -0
- capusd/humanize.py +225 -0
- capusd/oracles.py +173 -0
- capusd/personas.py +747 -0
- capusd/report/__init__.py +3 -0
- capusd/report/generate.py +462 -0
- capusd/report/template.py +150 -0
- capusd/runner.py +705 -0
- capusd/server.py +499 -0
- capusd/sessions.py +1179 -0
- capusd/setup_wizard.py +242 -0
- capusd/spec.py +327 -0
- capusd/store.py +584 -0
- capusd/ux.py +152 -0
- capusd/vision/__init__.py +3 -0
- capusd/vision/annotate.py +40 -0
- capusd/vision/download.py +48 -0
- capusd/vision/ocr.py +56 -0
- capusd/vision/omniparser.py +131 -0
- capusd/vision/service.py +123 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: capus
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Capus: persona-driven LLM agent testing for macOS and web apps, served as a local MCP daemon
|
|
5
|
+
Project-URL: Homepage, https://github.com/DanielBirk04/capus
|
|
6
|
+
Author: Daniel Birk
|
|
7
|
+
License-Expression: Apache-2.0
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: llm-agents,macos,mcp,personas,playwright,testing,ui-testing
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: MacOS X
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: MacOS
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Software Development :: Testing
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Requires-Dist: jinja2>=3.1
|
|
20
|
+
Requires-Dist: mcp>=1.10
|
|
21
|
+
Requires-Dist: pillow>=10.0
|
|
22
|
+
Requires-Dist: pyobjc-framework-applicationservices>=10.3
|
|
23
|
+
Requires-Dist: pyobjc-framework-cocoa>=10.3
|
|
24
|
+
Requires-Dist: pyobjc-framework-quartz>=10.3
|
|
25
|
+
Requires-Dist: pyobjc-framework-vision>=10.3
|
|
26
|
+
Requires-Dist: pyyaml>=6.0
|
|
27
|
+
Provides-Extra: browser
|
|
28
|
+
Requires-Dist: playwright>=1.45; extra == 'browser'
|
|
29
|
+
Provides-Extra: runner
|
|
30
|
+
Requires-Dist: anthropic>=0.40; extra == 'runner'
|
|
31
|
+
Provides-Extra: vision
|
|
32
|
+
Requires-Dist: einops; extra == 'vision'
|
|
33
|
+
Requires-Dist: huggingface-hub>=0.23; extra == 'vision'
|
|
34
|
+
Requires-Dist: timm; extra == 'vision'
|
|
35
|
+
Requires-Dist: torch>=2.3; extra == 'vision'
|
|
36
|
+
Requires-Dist: transformers<4.50,>=4.45; extra == 'vision'
|
|
37
|
+
Requires-Dist: ultralytics>=8.2; extra == 'vision'
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# Capus
|
|
41
|
+
|
|
42
|
+
Persona-driven LLM agent testing for macOS apps **and web apps**, served as
|
|
43
|
+
a **local MCP daemon**. LLM agents role-play sampled human personas
|
|
44
|
+
("silicon sampling") and exercise your app through the GUI — screenshots in,
|
|
45
|
+
real synthesized input out. The daemon is deliberately dumb (no LLM calls,
|
|
46
|
+
ever); the intelligence is an MCP client: Claude Code/Codex driving it
|
|
47
|
+
interactively, **or the built-in runner** started from the dashboard or
|
|
48
|
+
`capus agents` (Anthropic API key or a Claude subscription via the
|
|
49
|
+
`claude` CLI).
|
|
50
|
+
|
|
51
|
+
Two target drivers behind one identical tool surface:
|
|
52
|
+
|
|
53
|
+
- **macOS** (`app_path` = .app/executable/.py): window screenshots parsed by
|
|
54
|
+
**OmniParser v2**, CGEvent mouse/keyboard. Needs the machine free during
|
|
55
|
+
runs (one shared screen + pointer).
|
|
56
|
+
- **Browser** (`app_path` = http(s):// or file:// URL): one isolated headless
|
|
57
|
+
Chromium context per persona session — truly parallel, zero desktop
|
|
58
|
+
contention, no macOS permissions. The persona still *sees* a screenshot
|
|
59
|
+
(numbered Set-of-Mark boxes), but element geometry comes from the DOM
|
|
60
|
+
(visible, in-viewport, interactive elements with accessible names; shadow
|
|
61
|
+
DOM and same-origin iframes traversed), input goes through CDP at real
|
|
62
|
+
coordinates (move, then click — the same trusted path as a human mouse),
|
|
63
|
+
and oracles get browser-grade signals: uncaught JS exceptions, console
|
|
64
|
+
errors, failed/4xx+ requests, native dialogs, renderer crashes. OmniParser
|
|
65
|
+
remains the automatic fallback for canvas-rendered UIs.
|
|
66
|
+
|
|
67
|
+
Output is two deliverables from one findings database:
|
|
68
|
+
|
|
69
|
+
- **`report.html` / `report.md`** — for the developer: findings with
|
|
70
|
+
screenshots and repro steps, business-rule coverage matrix (personas ×
|
|
71
|
+
rules), persona journey filmstrips.
|
|
72
|
+
- **`feedback.json`** — for coding agents: stable finding IDs, expected vs
|
|
73
|
+
observed, deterministic repro traces, a status queue (`open`/`fixed`/
|
|
74
|
+
`wontfix`) plus MCP tools (`findings_query`, `trace_replay`,
|
|
75
|
+
`finding_update`) to fix and verify autonomously.
|
|
76
|
+
|
|
77
|
+
## Architecture
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
the MIND (an MCP client — choose one per run)
|
|
81
|
+
Claude Code / Codex capus runner (capusd/runner.py)
|
|
82
|
+
orchestrator + tester spawned by the dashboard ▶ button or
|
|
83
|
+
subagents (parallel) `capus agents`; Anthropic API or claude CLI
|
|
84
|
+
│ MCP over streamable HTTP (127.0.0.1:7777/mcp)
|
|
85
|
+
▼
|
|
86
|
+
capusd (the BODY: dumb on purpose — zero LLM calls)
|
|
87
|
+
session manager + work queue │ persona sampler (correlated human sampling)
|
|
88
|
+
humanize (motor simulation: typing cadence+typos, Fitts-law mouse paths,
|
|
89
|
+
click scatter, think pauses — seeded per session) │ Driver protocol
|
|
90
|
+
├─ macOS driver (Quartz windows, screenshots, CGEvent input)
|
|
91
|
+
└─ browser driver (Playwright Chromium, DOM perception, CDP input)
|
|
92
|
+
vision (OmniParser v2 + Apple-Vision OCR) │ oracles (crash/hang/log/no-op
|
|
93
|
+
+ JS/console/network/dialog for browser) │ SQLite store + artifacts │
|
|
94
|
+
report generator │ dashboard (live streaming + run/persona control)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
One daemon serves many parallel clients. The split is deliberate: the
|
|
98
|
+
client decides WHAT a persona does (cognition), the daemon decides HOW it
|
|
99
|
+
physically unfolds (motor execution) — so even a fast model produces
|
|
100
|
+
sessions that look and pace like a human when watched live.
|
|
101
|
+
|
|
102
|
+
## Human realism
|
|
103
|
+
|
|
104
|
+
Personas are sampled, not invented: demographics from an overridable
|
|
105
|
+
population spec, behavioral traits drawn from a correlated-but-noisy latent
|
|
106
|
+
model calibrated against real data — OECD PIAAC tech-skill bands (~60% of
|
|
107
|
+
adults are level 1 or below: the "average user" fails multi-step tasks),
|
|
108
|
+
CDC disability prevalence, CHI'18 typing statistics (52±25 WPM, ~6% of
|
|
109
|
+
keystrokes are corrections). Counter-stereotypical draws are guaranteed by
|
|
110
|
+
design (the 79-year-old engineer happens; so does the low-tech 19-year-old).
|
|
111
|
+
|
|
112
|
+
Each persona compiles into:
|
|
113
|
+
|
|
114
|
+
- a **behavior contract** (`task_claim` returns it) — first-person system
|
|
115
|
+
prompt: identity, reading style, patience, blame attribution, quirks, and
|
|
116
|
+
hard anti-"superuser" rules (satisfice, knowledge limits, giving up is
|
|
117
|
+
valid data) — plus a 3-line `persona_reminder` to re-inject every few
|
|
118
|
+
turns against persona drift;
|
|
119
|
+
- a **motor profile** the daemon enforces mechanically: typing WPM with
|
|
120
|
+
corrected typo bursts, Fitts's-law mouse movement (curved Bezier paths,
|
|
121
|
+
bell velocity, terminal overshoot), click scatter inside targets,
|
|
122
|
+
hesitation pauses. Seeded per session — reproducible. `pacing: "fast"`
|
|
123
|
+
switches it all off for CI throughput.
|
|
124
|
+
|
|
125
|
+
**macOS targets**: perception AND targeting are pure screenshot vision
|
|
126
|
+
(OmniParser); actuation is real synthesized mouse/keyboard events
|
|
127
|
+
(move-then-click, like a human) at the vision-derived coordinates —
|
|
128
|
+
serialized through a global input mutex, so on one attended machine sessions
|
|
129
|
+
interleave. Emergency aborts: touch /tmp/capus.stop, hold cmd+option+ctrl+
|
|
130
|
+
escape, or slam the pointer into a screen corner. For unattended, truly
|
|
131
|
+
parallel runs, a VM/container isolation tier is on the roadmap.
|
|
132
|
+
|
|
133
|
+
**Browser targets**: each session gets its own incognito Chromium context
|
|
134
|
+
(own storage, own pointer) — no input mutex, no contention with you or with
|
|
135
|
+
other sessions; the isolation problem the macOS tier needs VMs for simply
|
|
136
|
+
doesn't exist. Headless by default; pass `headless: false` to run_create to
|
|
137
|
+
watch.
|
|
138
|
+
|
|
139
|
+
## Install
|
|
140
|
+
|
|
141
|
+
One line:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
curl -fsSL https://raw.githubusercontent.com/DanielBirk04/capus/main/scripts/install.sh | sh
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
That installs [uv](https://docs.astral.sh/uv/) if needed, installs capus as
|
|
148
|
+
an isolated tool (with web-target support out of the box), and runs the
|
|
149
|
+
guided **`capus setup`** wizard: environment checks, headless Chromium,
|
|
150
|
+
optional native-app permissions/models, one-click Claude Code wiring (MCP +
|
|
151
|
+
plugin), then starts the daemon and opens the dashboard. Already have uv?
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
uv tool install 'capus[browser]' && capus setup
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The dashboard's **Setup page** (`http://127.0.0.1:7777/#/setup`) mirrors the
|
|
158
|
+
same checklist with live re-checks and action buttons — first run lands
|
|
159
|
+
there automatically.
|
|
160
|
+
|
|
161
|
+
Web (URL) targets need **no macOS permissions at all**. Native macOS apps
|
|
162
|
+
are the advanced path: Screen Recording + Accessibility for the app hosting
|
|
163
|
+
the daemon (your terminal — restart it after granting) and the OmniParser
|
|
164
|
+
vision extra (`pip install 'capus[vision]'` + `capus models download`,
|
|
165
|
+
~1.5 GB). Without it the daemon still works for browser targets (DOM
|
|
166
|
+
perception) and in **OCR-only degraded mode** for macOS targets.
|
|
167
|
+
|
|
168
|
+
### Development install
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
uv venv --python 3.12 .venv
|
|
172
|
+
uv pip install --python .venv/bin/python -e '.[browser]' # web targets
|
|
173
|
+
uv pip install --python .venv/bin/python -e '.[vision]' # + OmniParser deps (heavy)
|
|
174
|
+
.venv/bin/playwright install chromium # browser binary
|
|
175
|
+
.venv/bin/capus models download # OmniParser v2 weights (~1.5 GB)
|
|
176
|
+
.venv/bin/capus doctor # permissions check
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Run
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
capus serve --open # daemon + dashboard (--open pops the browser)
|
|
183
|
+
# register in Claude Code (capus setup / the Setup page do this for you):
|
|
184
|
+
claude mcp add --transport http capus http://127.0.0.1:7777/mcp
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Control dashboard** — open `http://127.0.0.1:7777/` in a browser while the
|
|
188
|
+
daemon runs. It streams the live screen each agent is driving, lists every
|
|
189
|
+
run with its findings, and lets you drill into a run (persona cards,
|
|
190
|
+
findings with screenshots and the exact pages where each problem appears) or
|
|
191
|
+
into a session's full reasoning trace — every step's screenshot, the action,
|
|
192
|
+
and the agent's intent ("why, in persona voice"), plus the persona's exit
|
|
193
|
+
verdict and per-session model/cost. Every run and session view has
|
|
194
|
+
**Copy Markdown** / **Download .md** so the whole thing is documented and
|
|
195
|
+
portable.
|
|
196
|
+
|
|
197
|
+
The dashboard is also the **control room**: **▶ New run** configures and
|
|
198
|
+
launches a run (target, goals, persona count/seed or hand-picked library
|
|
199
|
+
personas, pacing, model, parallel workers) and can start the built-in agent
|
|
200
|
+
runner with one click; **Personas** manages the persona library — sample
|
|
201
|
+
new ones, edit names/backstories (first-person interview style conditions
|
|
202
|
+
best), and preview each persona's compiled behavior contract. Runs created
|
|
203
|
+
from chat (Claude Code) appear the same way and can be started/stopped from
|
|
204
|
+
either side. POST endpoints honor `CAPUS_DASHBOARD_TOKEN` (Bearer) when set.
|
|
205
|
+
|
|
206
|
+
**Credentials** manages a local vault of accounts the personas may need
|
|
207
|
+
(staging logins etc.): attach credential sets to a run in the New-Run form
|
|
208
|
+
and each persona receives them with its assignment and signs in naturally.
|
|
209
|
+
Secret values (keys containing password/secret/token/pin/key/otp) are
|
|
210
|
+
masked out of every recorded trace, repro step and report — agents type
|
|
211
|
+
them, records show `{{secret:…}}` placeholders, and `trace_replay` resolves
|
|
212
|
+
them back at replay time. Use test accounts, not production ones.
|
|
213
|
+
|
|
214
|
+
Sessions have **no fixed step limit** — a persona keeps going as long as it
|
|
215
|
+
makes progress (the daemon stops a session only after 25 consecutive
|
|
216
|
+
zero-change actions, or at the 10000-step runaway cap). Patience is still
|
|
217
|
+
personal: low-patience personas give up early because they *choose* to.
|
|
218
|
+
Parallel workers are automatically capped at the number of queued sessions.
|
|
219
|
+
|
|
220
|
+
**⇪ Share with coding agent** (run view) hands findings to the agent that
|
|
221
|
+
will fix them: pick the findings, point at your project folder, optionally
|
|
222
|
+
add instructions, then choose where it lands —
|
|
223
|
+
**VS Code** (recommended: the agent spawns in the project folder and starts
|
|
224
|
+
working immediately, connected to the capus MCP so it can `trace_replay`
|
|
225
|
+
fixes and mark findings `fixed`; VS Code opens there so you can watch and
|
|
226
|
+
resume the chat from the Claude Code panel — status also streams into the
|
|
227
|
+
run page's Handoffs panel), **Claude desktop app** (a new chat via
|
|
228
|
+
`claude://` deep link, pre-filled with the brief; plain chat, not
|
|
229
|
+
folder-bound), or **⧉ Copy brief** (paste into any coding agent).
|
|
230
|
+
|
|
231
|
+
Model/effort for agents and handoffs work exactly like a normal chat:
|
|
232
|
+
the default inherits your own Claude settings (model AND effort), or pick
|
|
233
|
+
any current model (Fable 5, Opus, Sonnet, Haiku, 1M-context variants) and
|
|
234
|
+
an effort level (low → max) per run/handoff.
|
|
235
|
+
|
|
236
|
+
A note on cost: the runner's `auto` backend prefers the **claude CLI, which
|
|
237
|
+
runs on your Claude subscription — no API key is billed**. The `$` figures
|
|
238
|
+
shown for such sessions (marked `sub`/`≈`) are the nominal API-equivalent
|
|
239
|
+
the CLI reports, not a charge. The pay-per-token Anthropic API backend is
|
|
240
|
+
strictly opt-in.
|
|
241
|
+
|
|
242
|
+
While watching a live session you can **moderate it like a usability test**:
|
|
243
|
+
the 🎙 Steer box delivers your instruction with the agent's next look at the
|
|
244
|
+
screen ("now try to export a PDF", "you may give up now") — the persona
|
|
245
|
+
acknowledges it in voice and follows it, and the note is recorded in the
|
|
246
|
+
trace (🎙 operator). **■ Stop** ends one session (overview cards and the
|
|
247
|
+
live view) without touching the rest of the run; the run-level Stop halts
|
|
248
|
+
the runner and all its sessions.
|
|
249
|
+
|
|
250
|
+
**Headless agents without Claude Code** — `capus agents --run-id <id>
|
|
251
|
+
[--model haiku|sonnet|opus] [--workers N] [--backend auto|api|claude-cli]`
|
|
252
|
+
plays all queued sessions of a run. The runner is an ordinary MCP client:
|
|
253
|
+
the daemon stays dumb even when the dashboard's Start button spawns it.
|
|
254
|
+
|
|
255
|
+
Install the skills/agents as a plugin — `capus setup` (or the dashboard's
|
|
256
|
+
Setup page) does this with one click; manually from a checkout:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
claude plugin marketplace add ./client/claude
|
|
260
|
+
claude plugin install capus@capus-marketplace
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Claude Code workflow (skills in `client/claude/capus`) — Capus is fully
|
|
264
|
+
drivable from chat; **`/capus:help` is the front desk** (the command map +
|
|
265
|
+
troubleshooting, and it routes you to the right command). The core loop:
|
|
266
|
+
|
|
267
|
+
1. `/capus:setup` — extracts business rules from your PRD into
|
|
268
|
+
`capus/rules.yaml`, samples personas, writes their narrative cards.
|
|
269
|
+
(Prefer `/capus:spec` for realistic-workflow testing; `/capus:recon` grounds
|
|
270
|
+
a spec against the live app; `/capus:personas` authors a custom panel.)
|
|
271
|
+
2. `/capus:run` — spawns parallel tester subagents; each claims a
|
|
272
|
+
persona-session and plays it against the app.
|
|
273
|
+
3. `/capus:report` — judge pass + generates `report.html`, `report.md`,
|
|
274
|
+
`feedback.json`.
|
|
275
|
+
4. `/capus:fix` — run inside the app's repo: works open findings, verifies
|
|
276
|
+
fixes with `trace_replay`, marks them fixed.
|
|
277
|
+
|
|
278
|
+
The control-room commands cover everything else the dashboard does, from chat:
|
|
279
|
+
`/capus:status` (list/inspect runs, sessions and findings; start/stop the
|
|
280
|
+
built-in runner; steer or stop a live session), `/capus:doctor` (permissions,
|
|
281
|
+
vision models, browser, daemon health), and `/capus:credentials` (the
|
|
282
|
+
login/secret vault). **Chat and the dashboard are two windows onto one daemon
|
|
283
|
+
store** — anything you do from chat is persisted immediately and visible in the
|
|
284
|
+
dashboard (runs, traces, screenshots, verdicts, findings) days or weeks later;
|
|
285
|
+
nothing is chat-only.
|
|
286
|
+
|
|
287
|
+
Codex: see `client/codex/AGENTS.md`.
|
|
288
|
+
|
|
289
|
+
## Try it on the demo apps
|
|
290
|
+
|
|
291
|
+
`examples/invoice_mini/app.py` is a tiny Cocoa app with planted bugs (a dead
|
|
292
|
+
Export button, a missing volume discount, a wrong confirmation message,
|
|
293
|
+
silent input validation). Its PRD is `examples/invoice_mini/PRD.md`, expected
|
|
294
|
+
extracted rules in `examples/rules.example.yaml`. A full verification pass:
|
|
295
|
+
setup → run (3 personas) → report should find at least the dead control and
|
|
296
|
+
the discount rule violation.
|
|
297
|
+
|
|
298
|
+
`examples/invoice_web/index.html` is the same app (and the same 4 planted
|
|
299
|
+
bugs) as a self-contained web page — point run_create at
|
|
300
|
+
`file:///…/examples/invoice_web/index.html` to exercise the browser driver
|
|
301
|
+
end to end, headless, with no permissions.
|
|
302
|
+
|
|
303
|
+
## Security
|
|
304
|
+
|
|
305
|
+
Capus runs entirely on your machine. The daemon and dashboard bind to
|
|
306
|
+
`127.0.0.1` and assume a **localhost trust boundary**: the read-only
|
|
307
|
+
dashboard API (runs, sessions, live screenshots) is open to local processes.
|
|
308
|
+
Mutating routes (start/stop runs, edit personas/credentials) **and the
|
|
309
|
+
credentials vault** require `CAPUS_DASHBOARD_TOKEN` (a `Bearer` token) when
|
|
310
|
+
it is set — set it before exposing the dashboard beyond localhost (e.g.
|
|
311
|
+
behind an authenticating reverse proxy or tunnel).
|
|
312
|
+
|
|
313
|
+
Test credentials live in a local SQLite vault. Secret-ish field values (keys
|
|
314
|
+
containing `password/secret/token/pin/key/otp`) are masked out of every
|
|
315
|
+
recorded trace, repro step and report — agents type them, records only show
|
|
316
|
+
`{{secret:…}}` placeholders. Use dedicated test accounts, never production
|
|
317
|
+
credentials.
|
|
318
|
+
|
|
319
|
+
## Notes
|
|
320
|
+
|
|
321
|
+
- macOS only (Quartz, Apple Vision OCR, Screen Capture). Apple Silicon
|
|
322
|
+
recommended for OmniParser on MPS.
|
|
323
|
+
- OmniParser v2 icon-detector weights are AGPL-3.0 (caption model MIT) —
|
|
324
|
+
fine locally; re-check before commercial distribution.
|
|
325
|
+
- Data dir: `~/.capus` (override with `CAPUS_DATA_DIR` or `--data-dir`).
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
capusd/__init__.py,sha256=GqDk918BADNAxjBy7Ix1_D6e0wj4fCcrPX2FLFX0ewM,101
|
|
2
|
+
capusd/agentic.py,sha256=Wip6WEO3PbccWVGsryYMvqPApCqyJJ-vK-UoDBWOtzM,11670
|
|
3
|
+
capusd/cli.py,sha256=7HliTqs7zG5gTgK5V9Zj-DBY_7kNzk7sV_rOyCZ-OHo,6860
|
|
4
|
+
capusd/config.py,sha256=ZaE-YHk4uBjMP-yNCQDWA9JhTkWOUGQQrqM5tgIiR_A,2902
|
|
5
|
+
capusd/dashboard.py,sha256=S_sQYzj3uSj82RrCA3CeGK2nWfA9-tF0g-uw2KTehaA,64251
|
|
6
|
+
capusd/doctor.py,sha256=TKUwMf0eilTNVx69GrtyaOegpX9cEkq5a6Ob65BY_K8,7215
|
|
7
|
+
capusd/fixtures.py,sha256=ztHbp6lk4mRkk3Yj1iYTJqMUJhQZ3BjAp8n2HFAL3ZU,3984
|
|
8
|
+
capusd/humanize.py,sha256=RKrnhIdIMuuHauQ0NmS_fNv-6ZPqMDQ-Vx25-uzekBU,10069
|
|
9
|
+
capusd/oracles.py,sha256=ROurNOsmf5uEvn9WVKgio81nCUp-XXWkDPlmTbEIu4g,6496
|
|
10
|
+
capusd/personas.py,sha256=PTF_7AlSweAyUQu5XAUo79gRg9_SCzCBCLTgF7Cj6zE,40349
|
|
11
|
+
capusd/runner.py,sha256=ULNiJKj_WRsvcbasSCjCxtB_2psMwHttWQWz6DBOv6A,31610
|
|
12
|
+
capusd/server.py,sha256=LKTJCitHLLkZSNG7JmX-HKnfeQnknk8VHN7QZa7eexA,25519
|
|
13
|
+
capusd/sessions.py,sha256=oPkpPl3t86J21U4cKKvNwzt8drRE1TfOfhWoG-bVc20,53337
|
|
14
|
+
capusd/setup_wizard.py,sha256=WAA2-fQy05KScMC_OvXzjXgBEf8w3wQdCBG2_1rgBnM,10569
|
|
15
|
+
capusd/spec.py,sha256=jKb19oVquWs1ZMPAXhdq_2Ui8n0f6vp0VFtdvrH6nkY,14559
|
|
16
|
+
capusd/store.py,sha256=Lbj3r9aEqRHIqP3ng5TK-WnzTRULrwGeGwl75907Xb4,25214
|
|
17
|
+
capusd/ux.py,sha256=AKbDYI6cWzEYSPY6KXuktegeLnKQ70FVbB7mcTMlUx8,6136
|
|
18
|
+
capusd/dashboard_static/index.html,sha256=mJeS1cyDsjU54NMfXrcmEcCRv3KTk_rmVuyT3iqEYrs,4048
|
|
19
|
+
capusd/dashboard_static/css/base.css,sha256=uRYPc5oXTcHlXnAMhV3K1AWbQk907viBJY_x38bXEW4,2665
|
|
20
|
+
capusd/dashboard_static/css/components.css,sha256=_Q-0uiJlEES7drdxyOhNF8TRsDfkbiONBQwQzMgwLjA,13370
|
|
21
|
+
capusd/dashboard_static/css/layout.css,sha256=IPCNntlipyLx9lyuizbPJR9i9cTTkC9U7IJXb8fDql0,6089
|
|
22
|
+
capusd/dashboard_static/css/tokens.css,sha256=GDLdu8mOB79j7zX38fWcNmjuia1BY7_TGYZ-FBOCMH0,3558
|
|
23
|
+
capusd/dashboard_static/css/views.css,sha256=BUKH4nAYEozfCEH5UuOMzLAoO5oZeqZBNgwhzW-P69g,8255
|
|
24
|
+
capusd/dashboard_static/js/api.js,sha256=9gkWUF2pKL_wwEEBgTK7NuvxB6lWBOcWRZEJyIgXCe0,1671
|
|
25
|
+
capusd/dashboard_static/js/app.js,sha256=B17wQG1yhYsbhyDFVVCSppGTASYnYifrWIIgqzH68xE,3865
|
|
26
|
+
capusd/dashboard_static/js/format.js,sha256=RQ9prbO9Mt-xippbP-fUc7mjAvLZqUYbhhw-CEqiuGY,6809
|
|
27
|
+
capusd/dashboard_static/js/ui.js,sha256=vZpTRlYLCECq0uoVMlDqPXL6IGmPd618u77Fka85A3w,4917
|
|
28
|
+
capusd/dashboard_static/js/components/handoff.js,sha256=_IixJn69qcYxbZZ_bpINiXZLGoP7Ivw5KbzEmReiAKI,7021
|
|
29
|
+
capusd/dashboard_static/js/views/credentials.js,sha256=uUf9-UHOlZHaIZxY4Gqkj5qoizbXcDkLR-w-Y1-MW3E,3674
|
|
30
|
+
capusd/dashboard_static/js/views/live.js,sha256=OY6kW72QqrVyEagD7yAb3GCvfQ6HlY7v_N7vKEYBDC8,4176
|
|
31
|
+
capusd/dashboard_static/js/views/new_run.js,sha256=YBuyqZmdCi33hfHOkRIjyQr_B_XQYfgdylGukbYampQ,9867
|
|
32
|
+
capusd/dashboard_static/js/views/overview.js,sha256=ltI_sbEvZqE3ug7mZxp_uuYDSwpxHwLKKgyDvgCKEYA,4695
|
|
33
|
+
capusd/dashboard_static/js/views/personas.js,sha256=euOwwfvY9Gle4xv3ssRpFZTrPk0Y7ervUXxfDLtp6ZQ,14729
|
|
34
|
+
capusd/dashboard_static/js/views/run.js,sha256=KPOeqbeXGZsLumsIo3zSpWtupord-lmzcbU0TyD6B4g,19001
|
|
35
|
+
capusd/dashboard_static/js/views/runs.js,sha256=cS1d1XvZoWBEhdtvg8aEUoDJfxbWp58i1FxpkqBJrtA,3489
|
|
36
|
+
capusd/dashboard_static/js/views/session.js,sha256=YyKI2tqFVo3P0Mr5JAY2wyxfSG9SJ9PoGX1hrgQyzqc,4595
|
|
37
|
+
capusd/dashboard_static/js/views/setup.js,sha256=M5cfNzBD2Cjz8TOOBQmXonVhPvwQNl2ssKPwXYFWENw,7443
|
|
38
|
+
capusd/dashboard_static/js/views/specs.js,sha256=tJrnxIFpJjdTpnN8NWiIrJ4JAEx_lpGZ44WPI-bXWu0,8939
|
|
39
|
+
capusd/driver/__init__.py,sha256=YtDpn8mirx6qIRW2YjIvDgUAtNlqstYZIaR9m3PuO90,241
|
|
40
|
+
capusd/driver/base.py,sha256=wmOna1w-ASrqrTs-AuFyDS3xGADyreBz1ztAlfWm3-E,2164
|
|
41
|
+
capusd/driver/browser.py,sha256=TtVGzCtZlapG03xo8EPBPyuoaKjTMtRp3FSWFAK3V_o,19349
|
|
42
|
+
capusd/driver/dom_extract.js,sha256=XYUmMdOcvWE9OewutlpEhdrzjzm-tZbp6bOCAEIo9Os,10742
|
|
43
|
+
capusd/driver/keys.py,sha256=Kuw4fywHshaDl-OlBO1B89L2PXPZninLXw-pj4SHGLw,5643
|
|
44
|
+
capusd/driver/macos.py,sha256=Oy1H3Mnv0tVMR26xBItxIlwGh-J-LBV0338pUgxmKrE,19639
|
|
45
|
+
capusd/driver/safety.py,sha256=1VNlGEO49GAgwG9UPO_v-UsG2zCe-6olCKgCA0MUOMk,2255
|
|
46
|
+
capusd/report/__init__.py,sha256=qfjoYkBZMqspk-uVKoikLQ2O7uXpRibFzFnh6YzrtDU,69
|
|
47
|
+
capusd/report/generate.py,sha256=g3Je6VA18OrV_ASEEhTWanNkGD1SOFgzDzdtcvwF9Ok,18901
|
|
48
|
+
capusd/report/template.py,sha256=TLCmz6B30UmkNoaV5h5grhk2emJeJegJuQ2h8DIuNC0,6512
|
|
49
|
+
capusd/vision/__init__.py,sha256=qmCxU71hG4X1KUxEvm2Twnhi7JhKrCiRdfZqQMda5Sk,150
|
|
50
|
+
capusd/vision/annotate.py,sha256=x5QUGmKTCDOECZ3thKBwfnDvDe_q4fkAOz8-yQT88Eo,1480
|
|
51
|
+
capusd/vision/download.py,sha256=dVz9K_GDw54Otp5OHbDkwv_PN9HLHGB6-RVhMFqF6w0,1541
|
|
52
|
+
capusd/vision/ocr.py,sha256=tmrk7nBdoeDpQQImOTuyAa5Z_NCyMa9_MPS1-DtDozY,1989
|
|
53
|
+
capusd/vision/omniparser.py,sha256=TkqznrGKDJvm8LDMZLc_Vsjosn01STOSWKYuGwaFP4U,4714
|
|
54
|
+
capusd/vision/service.py,sha256=7HQQKETLohS7PuwACPCE0zv59NgKnueDVYmJ1irp5E0,4728
|
|
55
|
+
capusd/assets/claude-plugin/.claude-plugin/marketplace.json,sha256=BjIjR9ir5XKbArzrFdl4T1WKxydJ5EzmF3NuEU_81mg,449
|
|
56
|
+
capusd/assets/claude-plugin/capus/.mcp.json,sha256=tLTAN_wmRNFluwIA9gHDAFMl8Oh7nwRSQ-NoPm67VeY,110
|
|
57
|
+
capusd/assets/claude-plugin/capus/.claude-plugin/plugin.json,sha256=hQ6sirf_EC0TlGJdgayETFO-PCt7p-oWuq9hURX4Je4,488
|
|
58
|
+
capusd/assets/claude-plugin/capus/agents/capus-agent-tester.md,sha256=auFJo6AayrzFyla4pW4uR9TWjatkcoWC0WsT5DUIOKc,4284
|
|
59
|
+
capusd/assets/claude-plugin/capus/agents/capus-judge.md,sha256=zDqjOo7CjGc7n9LSNLu4yo0T-YmQbTCXYvZ3MUhE6ZM,4824
|
|
60
|
+
capusd/assets/claude-plugin/capus/agents/capus-tester.md,sha256=TixtoW6y2lC7gs3JbUws7zkeann8fI3SNk8gdWSnOG0,12483
|
|
61
|
+
capusd/assets/claude-plugin/capus/skills/credentials/SKILL.md,sha256=ajnHGrcQWlOahiUUqK7snioFYjMdGarv8tn8WTUlhAE,2986
|
|
62
|
+
capusd/assets/claude-plugin/capus/skills/doctor/SKILL.md,sha256=xu_GD2n1oiE-VNE256R4ebfi3hdpEw4DUL7JbFdtTzQ,3861
|
|
63
|
+
capusd/assets/claude-plugin/capus/skills/fix/SKILL.md,sha256=ChIqALGLtF1KMFdYA-X1e3-VssOzSa0cgQGukD05Bpc,2368
|
|
64
|
+
capusd/assets/claude-plugin/capus/skills/help/SKILL.md,sha256=GjIzvfkDSd3iPgzsEvyqCXtoIfHBHcXmE1CMcaklXiE,6281
|
|
65
|
+
capusd/assets/claude-plugin/capus/skills/personas/SKILL.md,sha256=NqlBijw9GIcSmxjkW3yBc8Wt2fHZGecFJOvd0H16K_0,4221
|
|
66
|
+
capusd/assets/claude-plugin/capus/skills/recon/SKILL.md,sha256=zTDh6wicdatnKfnjV2WIPy_ep2qjkpWRUZ0WVjgYOyw,3949
|
|
67
|
+
capusd/assets/claude-plugin/capus/skills/report/SKILL.md,sha256=nwfLfhbDD26Wp3mozs72u0DRi6k4cGlkYU7qtONGnFc,1446
|
|
68
|
+
capusd/assets/claude-plugin/capus/skills/run/SKILL.md,sha256=3VD2daU2Nh6IVVqW5TcXq20YH7qltmyQSh1CZePbaiw,5332
|
|
69
|
+
capusd/assets/claude-plugin/capus/skills/setup/SKILL.md,sha256=YEckA7U1xSa-Ne0fnTd5cUEUGIGlbRhwEknKjsnvyhM,3656
|
|
70
|
+
capusd/assets/claude-plugin/capus/skills/spec/SKILL.md,sha256=f91TLqqvlWlZPPmgZMhZvHKXSI7B01p-Vjnqsd1NcbI,6263
|
|
71
|
+
capusd/assets/claude-plugin/capus/skills/status/SKILL.md,sha256=Dsep0GVtmlLi9K-xev3zxaXvZcAJUG3HJS6_gNQmr24,5259
|
|
72
|
+
capus-0.2.0.dist-info/METADATA,sha256=VAkHYXq_vV8ByvUat73HLbTRmgXqihhmN2dX97TS6rk,16446
|
|
73
|
+
capus-0.2.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
74
|
+
capus-0.2.0.dist-info/entry_points.txt,sha256=nZFqA9kfodPQZyiRo90LMRngSkmqfZbwB7Pnu8w5UME,42
|
|
75
|
+
capus-0.2.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
76
|
+
capus-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
capusd/__init__.py
ADDED