floop 2.0.0__tar.gz → 2.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. floop-2.0.1/PKG-INFO +170 -0
  2. floop-2.0.1/README.md +155 -0
  3. floop-2.0.1/src/floop/__init__.py +14 -0
  4. {floop-2.0.0 → floop-2.0.1}/src/floop/adapters.py +27 -5
  5. {floop-2.0.0 → floop-2.0.1}/src/floop/cli.py +149 -45
  6. {floop-2.0.0 → floop-2.0.1}/src/floop/preview.py +4 -3
  7. floop-2.0.1/src/floop/project.py +444 -0
  8. {floop-2.0.0 → floop-2.0.1}/src/floop/review.py +14 -36
  9. floop-2.0.1/src/floop/skills.py +159 -0
  10. floop-2.0.1/src/floop.egg-info/PKG-INFO +170 -0
  11. {floop-2.0.0 → floop-2.0.1}/src/floop.egg-info/scm_file_list.json +14 -14
  12. floop-2.0.1/src/floop.egg-info/scm_version.json +8 -0
  13. {floop-2.0.0 → floop-2.0.1}/tests/test_adapters.py +51 -11
  14. {floop-2.0.0 → floop-2.0.1}/tests/test_cli.py +188 -25
  15. {floop-2.0.0 → floop-2.0.1}/tests/test_preview.py +1 -1
  16. floop-2.0.1/tests/test_project.py +196 -0
  17. {floop-2.0.0 → floop-2.0.1}/tests/test_review.py +26 -26
  18. floop-2.0.0/PKG-INFO +0 -275
  19. floop-2.0.0/README.md +0 -260
  20. floop-2.0.0/src/floop/__init__.py +0 -8
  21. floop-2.0.0/src/floop/project.py +0 -230
  22. floop-2.0.0/src/floop/skills.py +0 -155
  23. floop-2.0.0/src/floop.egg-info/PKG-INFO +0 -275
  24. floop-2.0.0/src/floop.egg-info/scm_version.json +0 -8
  25. floop-2.0.0/tests/test_project.py +0 -101
  26. {floop-2.0.0 → floop-2.0.1}/.github/workflows/cicd.yml +0 -0
  27. {floop-2.0.0 → floop-2.0.1}/.github/workflows/release.yml +0 -0
  28. {floop-2.0.0 → floop-2.0.1}/.gitignore +0 -0
  29. {floop-2.0.0 → floop-2.0.1}/LICENSE +0 -0
  30. {floop-2.0.0 → floop-2.0.1}/pyproject.toml +0 -0
  31. {floop-2.0.0 → floop-2.0.1}/setup.cfg +0 -0
  32. {floop-2.0.0 → floop-2.0.1}/src/floop.egg-info/SOURCES.txt +0 -0
  33. {floop-2.0.0 → floop-2.0.1}/src/floop.egg-info/dependency_links.txt +0 -0
  34. {floop-2.0.0 → floop-2.0.1}/src/floop.egg-info/entry_points.txt +0 -0
  35. {floop-2.0.0 → floop-2.0.1}/src/floop.egg-info/requires.txt +0 -0
  36. {floop-2.0.0 → floop-2.0.1}/src/floop.egg-info/top_level.txt +0 -0
  37. {floop-2.0.0 → floop-2.0.1}/tests/__init__.py +0 -0
floop-2.0.1/PKG-INFO ADDED
@@ -0,0 +1,170 @@
1
+ Metadata-Version: 2.4
2
+ Name: floop
3
+ Version: 2.0.1
4
+ Summary: Project/version review loop CLI and agent skill for AI artifacts
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: click>=8.1
10
+ Requires-Dist: pyyaml>=6.0
11
+ Provides-Extra: test
12
+ Requires-Dist: pytest>=8.0; extra == "test"
13
+ Requires-Dist: pytest-cov>=5.0; extra == "test"
14
+ Dynamic: license-file
15
+
16
+ # floop-client
17
+
18
+ **floop-client is the CLI for project/version uploads and server comments.**
19
+
20
+ [![PyPI version](https://img.shields.io/pypi/v/floop?style=for-the-badge)](https://pypi.org/project/floop/)
21
+ [![Python](https://img.shields.io/pypi/pyversions/floop?style=for-the-badge)](https://pypi.org/project/floop/)
22
+ [![License](https://img.shields.io/badge/license-MIT-blue?style=for-the-badge)](LICENSE)
23
+ [![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?style=for-the-badge)](#)
24
+
25
+ floop-client is intentionally small. It helps agents and users choose the right
26
+ local project/version, upload the right files to floop-server, read server
27
+ comments, and resolve comments after a newer version addresses them.
28
+
29
+ It does not build artifacts, validate design tokens, generate UI, or decide
30
+ which files belong to another tool. The tool or user that owns the files places
31
+ them in a floop version directory; floop handles the upload and comment loop.
32
+
33
+ ## Core Flow
34
+
35
+ ```text
36
+ Create/select project -> Create/select version -> Add files -> Upload -> Read comments -> Resolve comments
37
+ ```
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ pip install floop
43
+ ```
44
+
45
+ Verify:
46
+
47
+ ```bash
48
+ floop --version
49
+ ```
50
+
51
+ ## Quick Start
52
+
53
+ ```bash
54
+ # 1. Initialize workspace
55
+ cd your-project
56
+ floop init
57
+
58
+ # 2. Install the floop skill into your AI agent
59
+ floop enable copilot # or: cursor, claude, trae, qwen-code, opencode, openclaw
60
+
61
+ # 3. Create and select a local project
62
+ floop projects create my-review
63
+ floop projects use my-review
64
+
65
+ # 4. Create and select a version
66
+ floop versions create v1 --project my-review --artifact-type custom --entrypoint index.html
67
+ floop versions use v1 --project my-review
68
+
69
+ # 5. Put uploadable files in .floop/my-review/v1/
70
+
71
+ # 6. Configure server access and upload
72
+ floop review set --project my-review
73
+ floop review upload --project my-review --version v1 --json-output
74
+
75
+ # 7. Read server comments and cache them locally
76
+ floop comments --project my-review --version v1 --version-id <server-version-id> --json-output
77
+
78
+ # 8. Resolve addressed comments after a newer version has been uploaded
79
+ floop resolve <comment-id> --project my-review --version-id <server-version-id> --status resolved
80
+ ```
81
+
82
+ ## Workspace
83
+
84
+ ```text
85
+ .floop/
86
+ ├─ floop.env # Server URL + API key only
87
+ ├─ projects.csv # Local projects, server bindings, selected project/version
88
+ └─ <projectid>/
89
+ └─ <version>/
90
+ ├─ floop.version.json
91
+ ├─ floop.upload.json
92
+ ├─ floop.comments.json
93
+ └─ ...uploadable files...
94
+ ```
95
+
96
+ `.floop/floop.env` contains secrets. floop-client warns through docs and command
97
+ copy, but it does not create or edit `.floop/.gitignore`; ignore policy belongs
98
+ to the host repository.
99
+
100
+ Legacy workspaces under `.floop/projects/<project>/versions/<version>/` are
101
+ readable for compatibility. floop-client does not move or delete legacy files
102
+ automatically.
103
+
104
+ ## Commands
105
+
106
+ ### Workspace
107
+
108
+ ```bash
109
+ floop init
110
+ floop preview
111
+ ```
112
+
113
+ ### Projects
114
+
115
+ ```bash
116
+ floop projects
117
+ floop projects create <project>
118
+ floop projects use <project>
119
+ ```
120
+
121
+ ### Versions
122
+
123
+ ```bash
124
+ floop versions --project <project>
125
+ floop versions create <version> --project <project> --artifact-type <type> --entrypoint index.html
126
+ floop versions use <version> --project <project>
127
+ ```
128
+
129
+ When a project and version are selected, commands that support defaults can use
130
+ the selected values.
131
+
132
+ ### Server
133
+
134
+ ```bash
135
+ floop review set --project <project>
136
+ floop review upload --project <project> --version <version> --json-output
137
+ floop comments --project <project> --version <local-version> --version-id <server-version-id> --json-output
138
+ floop resolve <comment-id> --project <project> --version-id <server-version-id> --status resolved
139
+ ```
140
+
141
+ ## Responsibility Boundary
142
+
143
+ | floop-client owns | Other tools or users own |
144
+ |---|---|
145
+ | `.floop/` workspace | Source files |
146
+ | `projects.csv` project/version selection | File generation |
147
+ | Server project binding | File validation |
148
+ | Version upload | Build systems |
149
+ | Server comments cache | Artifact internals |
150
+ | Comment status updates | Content changes |
151
+
152
+ ## Supported Agents
153
+
154
+ | Agent | Command |
155
+ |-------|---------|
156
+ | GitHub Copilot | `floop enable copilot` |
157
+ | Cursor | `floop enable cursor` |
158
+ | Claude Code | `floop enable claude` |
159
+ | Trae IDE | `floop enable trae` |
160
+ | Qwen Code | `floop enable qwen-code` |
161
+ | OpenCode | `floop enable opencode` |
162
+ | OpenClaw | `floop enable openclaw` |
163
+
164
+ ## For Contributors
165
+
166
+ Run the full test gate:
167
+
168
+ ```bash
169
+ PYTHONPATH=src python3 -m pytest --cov=floop --cov-report=term-missing --cov-fail-under=100
170
+ ```
floop-2.0.1/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # floop-client
2
+
3
+ **floop-client is the CLI for project/version uploads and server comments.**
4
+
5
+ [![PyPI version](https://img.shields.io/pypi/v/floop?style=for-the-badge)](https://pypi.org/project/floop/)
6
+ [![Python](https://img.shields.io/pypi/pyversions/floop?style=for-the-badge)](https://pypi.org/project/floop/)
7
+ [![License](https://img.shields.io/badge/license-MIT-blue?style=for-the-badge)](LICENSE)
8
+ [![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?style=for-the-badge)](#)
9
+
10
+ floop-client is intentionally small. It helps agents and users choose the right
11
+ local project/version, upload the right files to floop-server, read server
12
+ comments, and resolve comments after a newer version addresses them.
13
+
14
+ It does not build artifacts, validate design tokens, generate UI, or decide
15
+ which files belong to another tool. The tool or user that owns the files places
16
+ them in a floop version directory; floop handles the upload and comment loop.
17
+
18
+ ## Core Flow
19
+
20
+ ```text
21
+ Create/select project -> Create/select version -> Add files -> Upload -> Read comments -> Resolve comments
22
+ ```
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install floop
28
+ ```
29
+
30
+ Verify:
31
+
32
+ ```bash
33
+ floop --version
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ ```bash
39
+ # 1. Initialize workspace
40
+ cd your-project
41
+ floop init
42
+
43
+ # 2. Install the floop skill into your AI agent
44
+ floop enable copilot # or: cursor, claude, trae, qwen-code, opencode, openclaw
45
+
46
+ # 3. Create and select a local project
47
+ floop projects create my-review
48
+ floop projects use my-review
49
+
50
+ # 4. Create and select a version
51
+ floop versions create v1 --project my-review --artifact-type custom --entrypoint index.html
52
+ floop versions use v1 --project my-review
53
+
54
+ # 5. Put uploadable files in .floop/my-review/v1/
55
+
56
+ # 6. Configure server access and upload
57
+ floop review set --project my-review
58
+ floop review upload --project my-review --version v1 --json-output
59
+
60
+ # 7. Read server comments and cache them locally
61
+ floop comments --project my-review --version v1 --version-id <server-version-id> --json-output
62
+
63
+ # 8. Resolve addressed comments after a newer version has been uploaded
64
+ floop resolve <comment-id> --project my-review --version-id <server-version-id> --status resolved
65
+ ```
66
+
67
+ ## Workspace
68
+
69
+ ```text
70
+ .floop/
71
+ ├─ floop.env # Server URL + API key only
72
+ ├─ projects.csv # Local projects, server bindings, selected project/version
73
+ └─ <projectid>/
74
+ └─ <version>/
75
+ ├─ floop.version.json
76
+ ├─ floop.upload.json
77
+ ├─ floop.comments.json
78
+ └─ ...uploadable files...
79
+ ```
80
+
81
+ `.floop/floop.env` contains secrets. floop-client warns through docs and command
82
+ copy, but it does not create or edit `.floop/.gitignore`; ignore policy belongs
83
+ to the host repository.
84
+
85
+ Legacy workspaces under `.floop/projects/<project>/versions/<version>/` are
86
+ readable for compatibility. floop-client does not move or delete legacy files
87
+ automatically.
88
+
89
+ ## Commands
90
+
91
+ ### Workspace
92
+
93
+ ```bash
94
+ floop init
95
+ floop preview
96
+ ```
97
+
98
+ ### Projects
99
+
100
+ ```bash
101
+ floop projects
102
+ floop projects create <project>
103
+ floop projects use <project>
104
+ ```
105
+
106
+ ### Versions
107
+
108
+ ```bash
109
+ floop versions --project <project>
110
+ floop versions create <version> --project <project> --artifact-type <type> --entrypoint index.html
111
+ floop versions use <version> --project <project>
112
+ ```
113
+
114
+ When a project and version are selected, commands that support defaults can use
115
+ the selected values.
116
+
117
+ ### Server
118
+
119
+ ```bash
120
+ floop review set --project <project>
121
+ floop review upload --project <project> --version <version> --json-output
122
+ floop comments --project <project> --version <local-version> --version-id <server-version-id> --json-output
123
+ floop resolve <comment-id> --project <project> --version-id <server-version-id> --status resolved
124
+ ```
125
+
126
+ ## Responsibility Boundary
127
+
128
+ | floop-client owns | Other tools or users own |
129
+ |---|---|
130
+ | `.floop/` workspace | Source files |
131
+ | `projects.csv` project/version selection | File generation |
132
+ | Server project binding | File validation |
133
+ | Version upload | Build systems |
134
+ | Server comments cache | Artifact internals |
135
+ | Comment status updates | Content changes |
136
+
137
+ ## Supported Agents
138
+
139
+ | Agent | Command |
140
+ |-------|---------|
141
+ | GitHub Copilot | `floop enable copilot` |
142
+ | Cursor | `floop enable cursor` |
143
+ | Claude Code | `floop enable claude` |
144
+ | Trae IDE | `floop enable trae` |
145
+ | Qwen Code | `floop enable qwen-code` |
146
+ | OpenCode | `floop enable opencode` |
147
+ | OpenClaw | `floop enable openclaw` |
148
+
149
+ ## For Contributors
150
+
151
+ Run the full test gate:
152
+
153
+ ```bash
154
+ PYTHONPATH=src python3 -m pytest --cov=floop --cov-report=term-missing --cov-fail-under=100
155
+ ```
@@ -0,0 +1,14 @@
1
+ """floop-client package metadata."""
2
+
3
+ from importlib.metadata import PackageNotFoundError, version
4
+ from pathlib import Path
5
+
6
+ try:
7
+ __version__ = version("floop")
8
+ except PackageNotFoundError: # pragma: no cover - source tree fallback depends on install mode.
9
+ try:
10
+ from setuptools_scm import get_version
11
+
12
+ __version__ = get_version(root=Path(__file__).resolve().parents[2])
13
+ except Exception:
14
+ __version__ = "0+unknown"
@@ -7,6 +7,7 @@ configuration format and directory structure.
7
7
  from __future__ import annotations
8
8
 
9
9
  import os
10
+ import shutil
10
11
  from pathlib import Path
11
12
  from typing import Protocol
12
13
 
@@ -15,6 +16,9 @@ import click
15
16
  from floop.skills import INSTRUCTION, SKILLS
16
17
 
17
18
 
19
+ LEGACY_SKILL_NAMES = ("floop-feedback", "floop-prototype", "floop-review")
20
+
21
+
18
22
  class AgentAdapter(Protocol):
19
23
  """Interface for agent platform adapters."""
20
24
 
@@ -42,7 +46,7 @@ class CopilotAdapter:
42
46
  instr_path = instr_dir / "floop.instructions.md"
43
47
  instr_path.write_text(
44
48
  "---\n"
45
- "description: 'This project uses floop-client for artifact review projects, versions, uploads, and comments.'\n"
49
+ "description: 'This project uses floop for projects, versions, uploads, and server comments.'\n"
46
50
  "applyTo: '**'\n"
47
51
  "---\n\n"
48
52
  + INSTRUCTION,
@@ -52,6 +56,7 @@ class CopilotAdapter:
52
56
 
53
57
  # Write skill files
54
58
  skills_dir = project_dir / ".github" / "skills"
59
+ _remove_legacy_skill_dirs(skills_dir)
55
60
 
56
61
  for skill in SKILLS.values():
57
62
  skill_dir = skills_dir / skill["name"]
@@ -85,12 +90,13 @@ class CursorAdapter:
85
90
  created: list[Path] = []
86
91
  rules_dir = project_dir / ".cursor" / "rules"
87
92
  rules_dir.mkdir(parents=True, exist_ok=True)
93
+ _remove_legacy_skill_files(rules_dir, ".mdc")
88
94
 
89
95
  # Write always-on instruction rule
90
96
  instr_path = rules_dir / "floop.mdc"
91
97
  instr_path.write_text(
92
98
  '---\n'
93
- 'description: "floop-client review workflow — always-on context"\n'
99
+ 'description: "floop project/version upload workflow — always-on context"\n'
94
100
  'globs: \n'
95
101
  'alwaysApply: true\n'
96
102
  '---\n\n'
@@ -134,6 +140,7 @@ class ClaudeAdapter:
134
140
 
135
141
  # Write individual skill files
136
142
  skills_dir = project_dir / ".claude" / "skills"
143
+ _remove_legacy_skill_dirs(skills_dir)
137
144
  for skill in SKILLS.values():
138
145
  skill_dir = skills_dir / skill["name"]
139
146
  skill_dir.mkdir(parents=True, exist_ok=True)
@@ -179,7 +186,7 @@ class ClaudeAdapter:
179
186
 
180
187
  @staticmethod
181
188
  def _render_claude_md() -> str:
182
- lines = ["<!-- floop:skills -->", "## floop Skills\n"]
189
+ lines = ["<!-- floop:skills -->", "## floop Skill\n"]
183
190
  for skill in SKILLS.values():
184
191
  lines.append(f'- **{skill["name"]}**: {skill["description"]}')
185
192
  lines.append(
@@ -206,7 +213,7 @@ class TraeAdapter:
206
213
 
207
214
  @staticmethod
208
215
  def _render() -> str:
209
- lines = ["# floop Workflow Rules\n", INSTRUCTION, "\n## floop Skills\n"]
216
+ lines = ["# floop Workflow Rules\n", INSTRUCTION, "\n## floop Skill\n"]
210
217
  for skill in SKILLS.values():
211
218
  lines.append(f'### {skill["name"]}\n')
212
219
  lines.append(skill["content"])
@@ -230,6 +237,7 @@ class _AgentsMdAdapter:
230
237
 
231
238
  if self._skills_subdir:
232
239
  skills_dir = project_dir / f".{self._skills_subdir}" / "skills"
240
+ _remove_legacy_skill_dirs(skills_dir)
233
241
  for skill in SKILLS.values():
234
242
  skill_dir = skills_dir / skill["name"]
235
243
  skill_dir.mkdir(parents=True, exist_ok=True)
@@ -278,7 +286,7 @@ class _AgentsMdAdapter:
278
286
  lines.append(f'- **{skill["name"]}**: {skill["description"]}')
279
287
  lines.append(
280
288
  f' - See `.{self._skills_subdir}/skills/'
281
- f'{skill["name"]}/SKILL.md` for full workflow'
289
+ f'{skill["name"]}/SKILL.md` for full rules'
282
290
  )
283
291
  lines.append("\n<!-- /floop:skills -->")
284
292
  return "\n".join(lines) + "\n"
@@ -317,3 +325,17 @@ ADAPTERS: dict[str, type[AgentAdapter]] = {
317
325
  }
318
326
 
319
327
  SUPPORTED_AGENTS = list(ADAPTERS.keys())
328
+
329
+
330
+ def _remove_legacy_skill_dirs(skills_dir: Path) -> None:
331
+ for name in LEGACY_SKILL_NAMES:
332
+ path = skills_dir / name
333
+ if path.exists():
334
+ shutil.rmtree(path)
335
+
336
+
337
+ def _remove_legacy_skill_files(rules_dir: Path, suffix: str) -> None:
338
+ for name in LEGACY_SKILL_NAMES:
339
+ path = rules_dir / f"{name}{suffix}"
340
+ if path.exists():
341
+ path.unlink()