pi-plans 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +217 -0
- package/agents/criticizer.md +18 -0
- package/agents/reviewer.md +20 -0
- package/docs/assets/pi-plans-logo.svg +66 -0
- package/index.ts +375 -0
- package/package.json +58 -0
- package/references/pi-planning-workflow.md +154 -0
- package/references/plan-artifact-template.md +77 -0
- package/references/state-and-config.md +137 -0
- package/scripts/run-tests.ts +31 -0
- package/scripts/validate.ts +185 -0
- package/skills/debug-and-plan/SKILL.md +35 -0
- package/skills/plan-big/SKILL.md +24 -0
- package/skills/plan-normal/SKILL.md +24 -0
- package/skills/plan-small/SKILL.md +23 -0
- package/skills/plan-with-refs/SKILL.md +30 -0
- package/skills/planning/SKILL.md +22 -0
- package/src/exec.ts +317 -0
- package/src/execution-panel.ts +497 -0
- package/src/guard.ts +38 -0
- package/src/plan.ts +63 -0
- package/src/refine-prompts.ts +70 -0
- package/src/state.ts +490 -0
- package/src/subagent.ts +197 -0
- package/tests/exec.test.ts +249 -0
- package/tests/execution-panel.test.ts +198 -0
- package/tests/guard.test.ts +70 -0
- package/tests/plan.test.ts +105 -0
- package/tests/refine-prompts.test.ts +49 -0
- package/tests/state.test.ts +240 -0
- package/tools/ask-choice.ts +199 -0
- package/tools/execute-plan.ts +137 -0
- package/tools/plans.ts +195 -0
- package/tools/refine.ts +237 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MaxInGaussian
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
<h1 align="center">pi-plans</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="docs/assets/pi-plans-logo.svg?v=3" alt="pi-plans: Plan. Review. Execute." width="640" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<h2 align="center"><b>Plan. Review. Execute.</b></h2>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<i>Versioned, reviewed Markdown plans land before any code changes.<br>Human-in-the-loop planning for the Pi coding agent.</i>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://github.com/MaxInGaussian/pi-plans/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/MaxInGaussian/pi-plans?style=square" /></a>
|
|
15
|
+
<a href="https://hits.sh/github.com/MaxInGaussian/pi-plans/"><img alt="Repo views" src="https://hits.sh/github.com/MaxInGaussian/pi-plans.svg?label=repo%20views" /></a>
|
|
16
|
+
<a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-blue.svg?style=square" /></a>
|
|
17
|
+
<img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-TS-3178C6?style=square&logo=typescript&logoColor=white" />
|
|
18
|
+
<img alt="pi-package" src="https://img.shields.io/badge/pi--package-ready-7c3aed?style=square" />
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
A rough change request becomes a versioned Markdown plan instead of a surprise diff. The agent inspects your repository read-only, asks scoped planning questions one at a time, and stores every answer in a per-run ledger. Reviewer and criticizer subagents refine the plan until it converges — and only after you explicitly approve the handoff does the extension enter a tracked execution loop that injects the remaining verifier checklist every turn and lifts the write guard. Nothing outside planning artifacts is writable until that approval.
|
|
24
|
+
|
|
25
|
+
## Contents
|
|
26
|
+
|
|
27
|
+
- [How it works](#how-it-works)
|
|
28
|
+
- [Quick start](#quick-start)
|
|
29
|
+
- [What it does](#what-it-does)
|
|
30
|
+
- [Interface overview](#interface-overview)
|
|
31
|
+
- [Skills](#skills)
|
|
32
|
+
- [Installation details](#installation-details)
|
|
33
|
+
- [Layout](#layout)
|
|
34
|
+
- [Safety model](#safety-model)
|
|
35
|
+
- [Verification](#verification)
|
|
36
|
+
- [FAQ](#faq)
|
|
37
|
+
- [License](#license)
|
|
38
|
+
|
|
39
|
+
## How it works
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
rough change request
|
|
43
|
+
|
|
|
44
|
+
language + docs location (once per workspace)
|
|
45
|
+
|
|
|
46
|
+
planning questions, one ask_choice at a time | write guard ON
|
|
47
|
+
| | only .git/pi_plans/,
|
|
48
|
+
v | run artifacts, cache
|
|
49
|
+
PLAN_vN.md + Verifier Checklist | are writable
|
|
50
|
+
^ |
|
|
51
|
+
| refine rounds |
|
|
52
|
+
+----------------+
|
|
53
|
+
reviewer (x1..x3) -> criticizer -> revise
|
|
54
|
+
|
|
|
55
|
+
v
|
|
56
|
+
explicit approval (never auto-completed)
|
|
57
|
+
|
|
|
58
|
+
=============================================== write guard OFF
|
|
59
|
+
|
|
|
60
|
+
tracked execution loop
|
|
61
|
+
checklist injected each turn, [DONE:VC-xxx]
|
|
62
|
+
markers tracked with a footer widget
|
|
63
|
+
|
|
|
64
|
+
v
|
|
65
|
+
run status: done
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Every plan version carries stable IDs (`I-###`, `VC-###`) that never get recycled across revisions, so acceptance criteria survive refinement rounds intact.
|
|
69
|
+
|
|
70
|
+
## Quick start
|
|
71
|
+
|
|
72
|
+
Install from npm:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pi install npm:pi-plans
|
|
76
|
+
# or try it without installing:
|
|
77
|
+
pi -e npm:pi-plans
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Then describe a change from any repository:
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
You: Create a plan to split the execution loop into smaller modules.
|
|
84
|
+
|
|
85
|
+
Pi: Which planning docs location should this workspace use?
|
|
86
|
+
1. ./docs/pi-plans (recommended)
|
|
87
|
+
2. ./.git/pi_plans/plans
|
|
88
|
+
3. Other
|
|
89
|
+
4. Auto-complete
|
|
90
|
+
|
|
91
|
+
Pi: Wrote ./docs/pi-plans/2026-08-26-split-execution-loop/PLAN_v1.md
|
|
92
|
+
Example verifier item:
|
|
93
|
+
- [ ] `VC-001` covers `I-001`; pass condition: `npm test` passes;
|
|
94
|
+
evidence: test output; metric: zero failing tests.
|
|
95
|
+
|
|
96
|
+
Pi: Next step for refining the plan?
|
|
97
|
+
1. Reviewer round (recommended)
|
|
98
|
+
2. Criticizer round
|
|
99
|
+
3. Accept plan for tracked execution
|
|
100
|
+
...
|
|
101
|
+
|
|
102
|
+
You: Accept plan for tracked execution.
|
|
103
|
+
|
|
104
|
+
Pi: Execute this plan now?
|
|
105
|
+
1. Execute this plan now (recommended)
|
|
106
|
+
2. Stop after planning
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Planning artifacts live under `./docs/pi-plans/YYYY-MM-DD-<topic>/` by default (public, committed). Prefer `.git/pi_plans/plans` if you want them private to the repository.
|
|
110
|
+
|
|
111
|
+
## What it does
|
|
112
|
+
|
|
113
|
+
| Capability | In short |
|
|
114
|
+
|---|---|
|
|
115
|
+
| Planning router + five specialist skills | Start with `/skill:planning` to route to the narrowest matching specialist (`plan-small` → `plan-big`, `debug-and-plan`, `plan-with-refs`) |
|
|
116
|
+
| Choice prompts | `ask_choice`: recommended option first, answers auto-recorded per run |
|
|
117
|
+
| Refinement rounds | Read-only reviewer/criticizer Pi subagents consolidate findings into the next plan version |
|
|
118
|
+
| Workspace state | Config, runs, decisions, refs, and subagent ledgers in `.git/pi_plans/` (git common dir) |
|
|
119
|
+
| Tracked execution | Checklist injected each turn; `[DONE:VC-xxx]` markers drive progress |
|
|
120
|
+
| Write guard | `edit`/`write` blocked outside planning artifacts while a run is active |
|
|
121
|
+
|
|
122
|
+
## Interface overview
|
|
123
|
+
|
|
124
|
+
| Tool / Command | Purpose |
|
|
125
|
+
|---|---|
|
|
126
|
+
| `plans` | State CLI: `init`, `show`, `set-language`, `set-artifact-root`, `set-role`, `start-run`, `set-status`, `record-decision`, `record-ref`, `record-subagent` |
|
|
127
|
+
| `ask_choice` | Numbered choice prompt; `autoComplete: false` for execution handoff / external-state questions |
|
|
128
|
+
| `refine` | Reviewer/criticizer round via read-only subagents (`--tools read,grep,find,ls`); `reviewers: 3` for big plans; enforces role/model confirmation gates |
|
|
129
|
+
| `execute_plan` | Execution handoff: re-confirms with the user, enters extension-managed execution mode |
|
|
130
|
+
| `/plans` | Show config, active run, execution progress |
|
|
131
|
+
| `/plans-execute [plan.md]` | Manual execution handoff (defaults to highest `PLAN_vN.md`) |
|
|
132
|
+
| `/update-plan [plan.md] [reason…]` | Interrupt-and-refine: stops execution (if any), returns the run to planning, and directs the agent to revise the plan into `PLAN_vN+1.md` while preserving verified work |
|
|
133
|
+
| `/plans-stop` | Stop execution mode |
|
|
134
|
+
| `/plans-abandon` | Abandon the active run (lifts the write guard; artifacts stay) |
|
|
135
|
+
|
|
136
|
+
## Skills
|
|
137
|
+
|
|
138
|
+
Invoked via `resources_discover`, callable as `/skill:<name>`, directly as `/<name>` (e.g. `/planning`, `/plan-small` — extension aliases that forward to the skill), or picked automatically from the task description.
|
|
139
|
+
|
|
140
|
+
| Skill | Use it when |
|
|
141
|
+
|---|---|
|
|
142
|
+
| [`planning`](skills/planning/SKILL.md) | General router; selects the narrowest specialist skill before planning starts |
|
|
143
|
+
| [`plan-small`](skills/plan-small/SKILL.md) | Small scoped change; 1–3 questions; one criticizer round |
|
|
144
|
+
| [`plan-normal`](skills/plan-normal/SKILL.md) | Broad or risky change; 5–10 questions; reviewer + criticizer rounds |
|
|
145
|
+
| [`plan-big`](skills/plan-big/SKILL.md) | Open-ended/high-risk effort; 10+ questions; three concurrent reviewers |
|
|
146
|
+
| [`debug-and-plan`](skills/debug-and-plan/SKILL.md) | Bug, CI failure, regression, incident — diagnose before planning |
|
|
147
|
+
| [`plan-with-refs`](skills/plan-with-refs/SKILL.md) | External projects/papers/docs must be analyzed before planning |
|
|
148
|
+
|
|
149
|
+
## Installation details
|
|
150
|
+
|
|
151
|
+
Dev / quick test against a local checkout:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pi -e /path/to/pi-plans
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Permanent (global), via symlink into the auto-discovered extensions dir:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
mkdir -p ~/.pi/agent/extensions/pi-plans
|
|
161
|
+
ln -s "$(pwd)"/index.ts "$(pwd)"/tools "$(pwd)"/src "$(pwd)"/skills "$(pwd)"/references "$(pwd)"/agents ~/.pi/agent/extensions/pi-plans/
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
or register the absolute path in `~/.pi/agent/settings.json`:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{ "extensions": ["/absolute/path/to/pi-plans"] }
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Layout
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
pi-plans/
|
|
174
|
+
├── index.ts # Extension entry: tools, commands, guard, execution loop
|
|
175
|
+
├── tools/ # plans, ask-choice, refine, execute-plan
|
|
176
|
+
├── src/ # state, guard, plan parsing, subagent runner, exec loop
|
|
177
|
+
├── skills/ # The planning router plus five specialist planning skills
|
|
178
|
+
├── references/ # Shared workflow, state/config, plan template (normative)
|
|
179
|
+
├── agents/ # reviewer.md / criticizer.md subagent prompts
|
|
180
|
+
├── scripts/validate.ts # Structure validator
|
|
181
|
+
└── tests/ # node:test suite (state, guard, plan parsing, execution)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Safety model
|
|
185
|
+
|
|
186
|
+
Before the approved handoff the workflow writes only `.git/pi_plans/` state, the run's artifact directory, and `~/.cache/pi-plans/` — the extension blocks `edit`/`write` elsewhere while a run is `planning`/`accepted` (bash stays discipline-bound: inspection, `git init`, downloads into the cache). Reviewer/criticizer subagents run with read-only tools. `Auto-complete` may answer planning and refinement questions only; it is never offered for execution, installs, publishing, deployment, merge, push, or credential use, and non-interactive sessions stop instead of auto-approving those.
|
|
187
|
+
|
|
188
|
+
## Verification
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
npm run validate # structure validator
|
|
192
|
+
npm test # node:test suite (stdlib only, no deps)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Both run on Node ≥ 22.6 via `--experimental-strip-types`; no npm dependencies.
|
|
196
|
+
|
|
197
|
+
## FAQ
|
|
198
|
+
|
|
199
|
+
**Why do I have to approve before any code changes?**
|
|
200
|
+
|
|
201
|
+
The plan is the contract. Refinement converges on scope while nothing is writable yet; the execution handoff is a separate explicit approval that also lifts the write guard. You always see — and can veto — what will happen before it happens.
|
|
202
|
+
|
|
203
|
+
**What can Auto-complete decide on my behalf?**
|
|
204
|
+
|
|
205
|
+
Planning and refinement choices only (the recommended option). It is never offered for execution approval, installs, publishing, deployment, merge, push, or credentials — those questions stop and wait for you.
|
|
206
|
+
|
|
207
|
+
**Where does all the state live?**
|
|
208
|
+
|
|
209
|
+
Preferences and run ledgers in `.git/pi_plans/` inside your workspace's git directory (never tracked, never published); plan artifacts under the configured artifact root (default `./docs/pi-plans/`); large downloaded references outside the repo under `~/.cache/pi-plans/`.
|
|
210
|
+
|
|
211
|
+
**How is this different from just prompting an AI to make changes?**
|
|
212
|
+
|
|
213
|
+
Prompts produce one-shot diffs with no recorded reasoning. pi-plans produces versioned artifacts — decisions, references, reviewer findings, dispositions, a verifier checklist — that are auditable, resumable across sessions, and enforced by tooling rather than goodwill.
|
|
214
|
+
|
|
215
|
+
## License
|
|
216
|
+
|
|
217
|
+
MIT.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pi-plans-criticizer
|
|
3
|
+
description: Read-only adversarial questioner for pi-plans refinement rounds; stress-tests plan assumptions with adaptive questions.
|
|
4
|
+
tools: read, grep, find, ls
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a read-only criticizer in the pi-plans workflow.
|
|
8
|
+
|
|
9
|
+
Rules:
|
|
10
|
+
|
|
11
|
+
- Perform read-only analysis. Never edit, write, or delete any file.
|
|
12
|
+
- Stress-test the plan's assumptions; do not rewrite the plan.
|
|
13
|
+
- You may inspect the repository to ground your questions.
|
|
14
|
+
|
|
15
|
+
Output Markdown in exactly this shape:
|
|
16
|
+
|
|
17
|
+
1. A summary of your core criticism in at most three sentences, highlighting the single most important point.
|
|
18
|
+
2. Then at most five adaptive questions, numbered, each with one line of why it matters. Questions must be concrete and answerable by a user with repo access — never rhetorical. Stop earlier if the plan genuinely holds.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pi-plans-reviewer
|
|
3
|
+
description: Read-only plan reviewer for pi-plans refinement rounds; verifies plan claims against the repository.
|
|
4
|
+
tools: read, grep, find, ls
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a read-only plan reviewer in the pi-plans workflow.
|
|
8
|
+
|
|
9
|
+
Rules:
|
|
10
|
+
|
|
11
|
+
- Perform read-only analysis. Never edit, write, or delete any file.
|
|
12
|
+
- Verify the plan's claims against the actual repository using your read tools before judging them.
|
|
13
|
+
- Every finding needs evidence: a repo path, a command, or an external citation. No evidence, no finding.
|
|
14
|
+
- You are evidence, not authority: state what you verified, not what you assume.
|
|
15
|
+
|
|
16
|
+
Output findings as Markdown, highest severity first, in this shape per finding:
|
|
17
|
+
|
|
18
|
+
- `F-###` — severity: high | medium | low; affected plan IDs; evidence: <repo path/command or source>; impact: <what breaks>; recommended fix: <concrete change>; suggested disposition: accept | reject | needs-discussion.
|
|
19
|
+
|
|
20
|
+
Surface at most five high-priority findings first; list lower-severity findings after them. If the plan holds up, say so explicitly and list what you checked.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="720" height="180" viewBox="0 0 720 180" role="img" aria-label="pi-plans: Plan. Review. Execute.">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0" y1="0" x2="720" y2="180" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop offset="0" stop-color="#14102a"/>
|
|
5
|
+
<stop offset=".55" stop-color="#241b4d"/>
|
|
6
|
+
<stop offset="1" stop-color="#7c3aed"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
<linearGradient id="bar" x1="0" y1="0" x2="1" y2="0">
|
|
9
|
+
<stop offset="0" stop-color="#a78bfa"/>
|
|
10
|
+
<stop offset="1" stop-color="#f472b6"/>
|
|
11
|
+
</linearGradient>
|
|
12
|
+
</defs>
|
|
13
|
+
|
|
14
|
+
<!-- backdrop -->
|
|
15
|
+
<rect width="720" height="180" rx="20" fill="url(#bg)"/>
|
|
16
|
+
<rect x="14" y="14" width="692" height="152" rx="14" fill="none" stroke="#ffffff" stroke-opacity=".08"/>
|
|
17
|
+
|
|
18
|
+
<!-- plan document -->
|
|
19
|
+
<g transform="translate(52,37)">
|
|
20
|
+
<path d="M0 10 Q0 0 10 0 H52 L74 22 V96 Q74 106 64 106 H10 Q0 106 0 96 Z" fill="#ffffff" fill-opacity=".10" stroke="#c4b5fd" stroke-width="2.5"/>
|
|
21
|
+
<path d="M52 0 V22 H74" fill="none" stroke="#c4b5fd" stroke-width="2.5" stroke-linejoin="round"/>
|
|
22
|
+
<g stroke="#a7f3d0" stroke-width="3" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
23
|
+
<path d="M12 34 l5 5 l9 -10"/>
|
|
24
|
+
<path d="M12 56 l5 5 l9 -10"/>
|
|
25
|
+
<path d="M12 78 l5 5 l9 -10"/>
|
|
26
|
+
</g>
|
|
27
|
+
<g stroke="#e9d5ff" stroke-width="3" stroke-linecap="round" opacity=".85">
|
|
28
|
+
<line x1="36" y1="32" x2="62" y2="32"/>
|
|
29
|
+
<line x1="36" y1="54" x2="62" y2="54"/>
|
|
30
|
+
<line x1="36" y1="76" x2="56" y2="76"/>
|
|
31
|
+
</g>
|
|
32
|
+
</g>
|
|
33
|
+
|
|
34
|
+
<!-- wordmark -->
|
|
35
|
+
<text x="150" y="96" font-family="-apple-system,'Segoe UI',Helvetica,Arial,sans-serif" font-size="60" font-weight="700" fill="#ffffff">pi-plans</text>
|
|
36
|
+
<rect x="153" y="110" width="236" height="6" rx="3" fill="url(#bar)"/>
|
|
37
|
+
<text x="151" y="147" font-family="'SF Mono',Menlo,Consolas,monospace" font-size="16" letter-spacing="4" fill="#ddd6fe">PLAN·REVIEW·EXECUTE</text>
|
|
38
|
+
|
|
39
|
+
<!-- pipeline: plan -> review -> execute -->
|
|
40
|
+
<g>
|
|
41
|
+
<g stroke="#c4b5fd" stroke-width="3" stroke-linecap="round" opacity=".85">
|
|
42
|
+
<line x1="502" y1="90" x2="528" y2="90"/>
|
|
43
|
+
<line x1="598" y1="90" x2="624" y2="90"/>
|
|
44
|
+
</g>
|
|
45
|
+
<polygon points="528,84 538,90 528,96" fill="#c4b5fd"/>
|
|
46
|
+
<polygon points="624,84 634,90 624,96" fill="#c4b5fd"/>
|
|
47
|
+
|
|
48
|
+
<circle cx="470" cy="90" r="26" fill="#ffffff" fill-opacity=".07" stroke="#c4b5fd" stroke-width="2.5"/>
|
|
49
|
+
<circle cx="566" cy="90" r="26" fill="#ffffff" fill-opacity=".07" stroke="#c4b5fd" stroke-width="2.5"/>
|
|
50
|
+
<circle cx="662" cy="90" r="26" fill="#7c3aed" stroke="#e9d5ff" stroke-width="2.5"/>
|
|
51
|
+
|
|
52
|
+
<!-- list -->
|
|
53
|
+
<g stroke="#e9d5ff" stroke-width="3" stroke-linecap="round">
|
|
54
|
+
<line x1="458" y1="82" x2="482" y2="82"/>
|
|
55
|
+
<line x1="458" y1="90" x2="482" y2="90"/>
|
|
56
|
+
<line x1="458" y1="98" x2="474" y2="98"/>
|
|
57
|
+
</g>
|
|
58
|
+
|
|
59
|
+
<!-- magnifier -->
|
|
60
|
+
<circle cx="561" cy="85" r="9" fill="none" stroke="#e9d5ff" stroke-width="3"/>
|
|
61
|
+
<line x1="568" y1="92" x2="578" y2="102" stroke="#e9d5ff" stroke-width="3" stroke-linecap="round"/>
|
|
62
|
+
|
|
63
|
+
<!-- play -->
|
|
64
|
+
<polygon points="654,79 654,101 673,90" fill="#ffffff"/>
|
|
65
|
+
</g>
|
|
66
|
+
</svg>
|