argos-harness 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 +21 -0
- package/assets/agents/auditor.md +140 -0
- package/assets/agents/commit-pr-pilot.md +154 -0
- package/assets/agents/explorer.md +93 -0
- package/assets/agents/implementer.md +117 -0
- package/assets/agents/leader.md +149 -0
- package/assets/agents/researcher.md +89 -0
- package/assets/agents/review-readability.md +87 -0
- package/assets/agents/review-reliability.md +100 -0
- package/assets/agents/review-resilience.md +87 -0
- package/assets/agents/review-risk.md +87 -0
- package/assets/agents/reviewer.md +167 -0
- package/assets/agents/ticket-audit.md +129 -0
- package/assets/hooks/argos-guard-destructive.sh +127 -0
- package/assets/hooks/argos-quality-gate.sh +129 -0
- package/assets/managed/aterrizaje.md +24 -0
- package/assets/managed/formato-respuesta.md +21 -0
- package/assets/managed/identidad.md +48 -0
- package/assets/managed/operaciones-seguras.md +14 -0
- package/assets/managed/orquestacion.md +169 -0
- package/assets/output-styles/argos.md +71 -0
- package/assets/skills/ai-sdk-5/SKILL.md +230 -0
- package/assets/skills/angular/SKILL.md +19 -0
- package/assets/skills/angular/references/architecture.md +137 -0
- package/assets/skills/angular/references/core.md +197 -0
- package/assets/skills/angular/references/forms.md +115 -0
- package/assets/skills/angular/references/performance.md +124 -0
- package/assets/skills/apollo-client/SKILL.md +61 -0
- package/assets/skills/app-blueprint/SKILL.md +45 -0
- package/assets/skills/app-blueprint/assets/module-template.md +48 -0
- package/assets/skills/app-blueprint/assets/system-template.md +38 -0
- package/assets/skills/app-blueprint/references/workflow.md +101 -0
- package/assets/skills/app-builder/SKILL.md +43 -0
- package/assets/skills/app-builder/phases/0-product.md +58 -0
- package/assets/skills/app-builder/phases/1-scaffold.md +33 -0
- package/assets/skills/app-builder/phases/10-store.md +40 -0
- package/assets/skills/app-builder/phases/2-data.md +34 -0
- package/assets/skills/app-builder/phases/3-domain.md +33 -0
- package/assets/skills/app-builder/phases/4-ui-nav.md +32 -0
- package/assets/skills/app-builder/phases/5-identity.md +30 -0
- package/assets/skills/app-builder/phases/6-polish.md +34 -0
- package/assets/skills/app-builder/phases/7-brand.md +31 -0
- package/assets/skills/app-builder/phases/8-web.md +30 -0
- package/assets/skills/app-builder/phases/9-docs.md +31 -0
- package/assets/skills/app-ia/SKILL.md +54 -0
- package/assets/skills/astro/SKILL.md +39 -0
- package/assets/skills/axios/SKILL.md +61 -0
- package/assets/skills/branch-pr/SKILL.md +200 -0
- package/assets/skills/bullmq/SKILL.md +55 -0
- package/assets/skills/chained-pr/SKILL.md +48 -0
- package/assets/skills/chained-pr/references/chaining-details.md +99 -0
- package/assets/skills/cognitive-doc-design/SKILL.md +81 -0
- package/assets/skills/comment-writer/SKILL.md +74 -0
- package/assets/skills/dashboard-ia/SKILL.md +54 -0
- package/assets/skills/django-drf/SKILL.md +180 -0
- package/assets/skills/go-testing/SKILL.md +47 -0
- package/assets/skills/go-testing/references/examples.md +89 -0
- package/assets/skills/issue-creation/SKILL.md +223 -0
- package/assets/skills/jira-epic/SKILL.md +306 -0
- package/assets/skills/jira-task/SKILL.md +382 -0
- package/assets/skills/judgment-day/SKILL.md +52 -0
- package/assets/skills/judgment-day/references/prompts-and-formats.md +98 -0
- package/assets/skills/lightsail-deploy/SKILL.md +44 -0
- package/assets/skills/lightsail-deploy/references/runbook.md +102 -0
- package/assets/skills/loop-back-debug/SKILL.md +102 -0
- package/assets/skills/mantine-form/SKILL.md +57 -0
- package/assets/skills/mongoose/SKILL.md +66 -0
- package/assets/skills/nextjs-15/SKILL.md +144 -0
- package/assets/skills/not-boring-mobile/SKILL.md +43 -0
- package/assets/skills/not-boring-mobile/references/not-boring-playbook.md +65 -0
- package/assets/skills/playwright/SKILL.md +315 -0
- package/assets/skills/pr-comments/SKILL.md +93 -0
- package/assets/skills/pr-create/SKILL.md +64 -0
- package/assets/skills/promo-video/SKILL.md +52 -0
- package/assets/skills/promo-video/assets/package.template.json +22 -0
- package/assets/skills/promo-video/assets/promo.template.tsx +469 -0
- package/assets/skills/promo-video/assets/theme.template.ts +27 -0
- package/assets/skills/promo-video/references/pipeline.md +119 -0
- package/assets/skills/promo-video-web/SKILL.md +51 -0
- package/assets/skills/promo-video-web/assets/browser-promo.template.tsx +385 -0
- package/assets/skills/promo-video-web/assets/capture.template.ts +70 -0
- package/assets/skills/promo-video-web/assets/package.template.json +26 -0
- package/assets/skills/promo-video-web/references/pipeline.md +84 -0
- package/assets/skills/pytest/SKILL.md +180 -0
- package/assets/skills/react-19/SKILL.md +118 -0
- package/assets/skills/react-hook-form/SKILL.md +59 -0
- package/assets/skills/react-router/SKILL.md +60 -0
- package/assets/skills/redux-toolkit/SKILL.md +60 -0
- package/assets/skills/review-diff/SKILL.md +101 -0
- package/assets/skills/ship-docs/SKILL.md +45 -0
- package/assets/skills/ship-docs/references/ship-docs-playbook.md +31 -0
- package/assets/skills/skill-creator/SKILL.md +97 -0
- package/assets/skills/skill-creator/assets/SKILL-TEMPLATE.md +68 -0
- package/assets/skills/skill-creator/references/skill-style-guide.md +79 -0
- package/assets/skills/skill-improver/SKILL.md +50 -0
- package/assets/skills/skill-improver/references/skill-style-guide.md +79 -0
- package/assets/skills/socketio/SKILL.md +58 -0
- package/assets/skills/spec-bootstrap/SKILL.md +62 -0
- package/assets/skills/store-ship/SKILL.md +52 -0
- package/assets/skills/store-ship/assets/android-supply.template.md +22 -0
- package/assets/skills/store-ship/assets/eas.template.json +32 -0
- package/assets/skills/store-ship/assets/maestro-flow.template.yaml +27 -0
- package/assets/skills/store-ship/assets/store.config.template.json +28 -0
- package/assets/skills/store-ship/references/pipeline.md +198 -0
- package/assets/skills/stripe/SKILL.md +83 -0
- package/assets/skills/tailwind-4/SKILL.md +193 -0
- package/assets/skills/tamagui/SKILL.md +60 -0
- package/assets/skills/tanstack-query/SKILL.md +58 -0
- package/assets/skills/ticket-intake/SKILL.md +55 -0
- package/assets/skills/typescript/SKILL.md +134 -0
- package/assets/skills/verify-before-done/SKILL.md +111 -0
- package/assets/skills/webapp-rebuilder/SKILL.md +48 -0
- package/assets/skills/webapp-rebuilder/assets/charter-template.md +46 -0
- package/assets/skills/webapp-rebuilder/references/workflow.md +47 -0
- package/assets/skills/winston-logging/SKILL.md +61 -0
- package/assets/skills/work-unit-commits/SKILL.md +84 -0
- package/assets/skills/zod-4/SKILL.md +210 -0
- package/assets/skills/zustand-5/SKILL.md +216 -0
- package/bin/argos.js +6 -0
- package/dist/commands/adopt.d.ts +35 -0
- package/dist/commands/adopt.d.ts.map +1 -0
- package/dist/commands/adopt.js +347 -0
- package/dist/commands/adopt.js.map +1 -0
- package/dist/commands/doctor.d.ts +20 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +478 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +32 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +358 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/remove.d.ts +62 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +487 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/workspace.d.ts +73 -0
- package/dist/commands/workspace.d.ts.map +1 -0
- package/dist/commands/workspace.js +354 -0
- package/dist/commands/workspace.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/assets.d.ts +29 -0
- package/dist/lib/assets.d.ts.map +1 -0
- package/dist/lib/assets.js +57 -0
- package/dist/lib/assets.js.map +1 -0
- package/dist/lib/atomic-write.d.ts +17 -0
- package/dist/lib/atomic-write.d.ts.map +1 -0
- package/dist/lib/atomic-write.js +41 -0
- package/dist/lib/atomic-write.js.map +1 -0
- package/dist/lib/backup.d.ts +11 -0
- package/dist/lib/backup.d.ts.map +1 -0
- package/dist/lib/backup.js +42 -0
- package/dist/lib/backup.js.map +1 -0
- package/dist/lib/config.d.ts +36 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +52 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/detect.d.ts +58 -0
- package/dist/lib/detect.d.ts.map +1 -0
- package/dist/lib/detect.js +330 -0
- package/dist/lib/detect.js.map +1 -0
- package/dist/lib/ficha.d.ts +10 -0
- package/dist/lib/ficha.d.ts.map +1 -0
- package/dist/lib/ficha.js +38 -0
- package/dist/lib/ficha.js.map +1 -0
- package/dist/lib/git.d.ts +27 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +79 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/managed-files.d.ts +35 -0
- package/dist/lib/managed-files.d.ts.map +1 -0
- package/dist/lib/managed-files.js +97 -0
- package/dist/lib/managed-files.js.map +1 -0
- package/dist/lib/markers.d.ts +64 -0
- package/dist/lib/markers.d.ts.map +1 -0
- package/dist/lib/markers.js +157 -0
- package/dist/lib/markers.js.map +1 -0
- package/dist/lib/navori-import.d.ts +42 -0
- package/dist/lib/navori-import.d.ts.map +1 -0
- package/dist/lib/navori-import.js +65 -0
- package/dist/lib/navori-import.js.map +1 -0
- package/dist/lib/openclaw-agents.d.ts +53 -0
- package/dist/lib/openclaw-agents.d.ts.map +1 -0
- package/dist/lib/openclaw-agents.js +118 -0
- package/dist/lib/openclaw-agents.js.map +1 -0
- package/dist/lib/package-root.d.ts +11 -0
- package/dist/lib/package-root.d.ts.map +1 -0
- package/dist/lib/package-root.js +23 -0
- package/dist/lib/package-root.js.map +1 -0
- package/dist/lib/paths.d.ts +11 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +16 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/settings-merge.d.ts +125 -0
- package/dist/lib/settings-merge.d.ts.map +1 -0
- package/dist/lib/settings-merge.js +373 -0
- package/dist/lib/settings-merge.js.map +1 -0
- package/dist/lib/version.d.ts +3 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +13 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/lib/which.d.ts +8 -0
- package/dist/lib/which.d.ts.map +1 -0
- package/dist/lib/which.js +30 -0
- package/dist/lib/which.js.map +1 -0
- package/dist/lib/workspaces.d.ts +133 -0
- package/dist/lib/workspaces.d.ts.map +1 -0
- package/dist/lib/workspaces.js +241 -0
- package/dist/lib/workspaces.js.map +1 -0
- package/dist/lib/zod-messages.d.ts +4 -0
- package/dist/lib/zod-messages.d.ts.map +1 -0
- package/dist/lib/zod-messages.js +28 -0
- package/dist/lib/zod-messages.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dashboard-ia
|
|
3
|
+
description: Information architecture for operator/admin tools — entity-centric, dense, action-fast. Trigger: dashboard IA, admin panel information architecture, back-office UX, operator tool layout, organize a dashboard, admin navigation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dashboard Information Architecture
|
|
7
|
+
|
|
8
|
+
## Activation Contract
|
|
9
|
+
|
|
10
|
+
Apply when structuring an admin / back-office / operator tool — where staff manage the records end users consume. For consumer products (web or mobile), use `app-ia` instead; the register is different.
|
|
11
|
+
|
|
12
|
+
## Hard Rules
|
|
13
|
+
|
|
14
|
+
- **Organize by ENTITY, not by action.** The operator thinks in records ("this customer"), not verbs ("payments"). A roster row opens the record's DETAIL page; every action on that record (edit, charge, promote, deactivate) lives on its detail — never on a separate action-page that forces re-finding the record.
|
|
15
|
+
- **See state, then act.** The landing view surfaces what needs attention (overdue, pending, failures) with quick counts — not an empty welcome screen.
|
|
16
|
+
- **Density over drama.** Tables are the primary surface: sortable, filterable, paginated, with real empty/loading/error states. Restrained register — no delight motion.
|
|
17
|
+
- **Status is computed, never hand-typed** — derive from domain rules, render as a Badge.
|
|
18
|
+
- **Selection from a growing set is searchable** (combobox), never a plain dropdown.
|
|
19
|
+
- **Always show the current operator** (identity + sign-out) so no one acts on the wrong account.
|
|
20
|
+
- **Enforcement is server-side.** Hiding a button is convenience; back every permission with a real policy.
|
|
21
|
+
- **Omit dead ends.** If an operator lacks read permission for an entity, remove it from the navigation entirely. "Access Denied" empty states should only catch direct URL navigation, never normal click paths.
|
|
22
|
+
- **Global search is mandatory.** Power users bypass click-navigation. Provide a global search or command palette (`Cmd + K`) to jump directly to a record's detail hub using unique identifiers (ID, email, reference number).
|
|
23
|
+
- **Sub-entities live inside the parent.** If a record has heavy 1-to-many relationships (e.g., a customer's payment history), organize them via tabs or sub-routes within the parent's detail page (e.g., `/customers/[id]/payments`). Never create floating, disconnected pages for dependent records.
|
|
24
|
+
|
|
25
|
+
## Decision Gates
|
|
26
|
+
|
|
27
|
+
| Situation | Structure |
|
|
28
|
+
| ---------------------------------------------- | --------------------------------------------------------------- |
|
|
29
|
+
| Acting on one record | Its detail page — actions inline |
|
|
30
|
+
| Acting on multiple records at once | Table selection + Bulk action bar + Impact confirmation modal |
|
|
31
|
+
| Seeing activity across all records | A read-only global log/table |
|
|
32
|
+
| Deep 1-to-many relationships (child entities) | Tabs or sub-routes within the parent entity's detail hub |
|
|
33
|
+
| A closed fixed set (≤7, never grows) | Plain select |
|
|
34
|
+
| A growing set (records, people) | Searchable combobox |
|
|
35
|
+
| Destructive / irreversible | Confirm step; prefer append-only correction |
|
|
36
|
+
|
|
37
|
+
## Execution Steps
|
|
38
|
+
|
|
39
|
+
1. List the core ENTITIES; make each one's detail the hub for its actions + history.
|
|
40
|
+
2. Make the landing an at-a-glance "needs attention" view that links into the relevant detail.
|
|
41
|
+
3. Map every nav item to an entity or an overview — never to a verb.
|
|
42
|
+
4. Push business rules to a shared layer; the dashboard reads/writes, it does not redefine them.
|
|
43
|
+
5. Map out batch operations early (e.g., bulk approvals, reassignments); handle them on the landing table via row selection, followed by a summary confirmation step.
|
|
44
|
+
6. Structure nested routing to strictly reflect your database hierarchy (e.g., `/entities/:id/sub-entities`) so URLs remain shareable and preserve context.
|
|
45
|
+
|
|
46
|
+
## Output Contract
|
|
47
|
+
|
|
48
|
+
An IA where: nav items are entities/overviews (not actions), each record has one detail hub, the landing shows state first, and no flow forces re-selecting a record you already had.
|
|
49
|
+
|
|
50
|
+
## References
|
|
51
|
+
|
|
52
|
+
- Complement: `app-ia` for consumer products. Build-time stack specifics for a dashboard's data-table, filters, and bulk-action components are a build-phase concern, not an IA one — resolve them against the repo's actual UI kit at build time.
|
|
53
|
+
|
|
54
|
+
_Adapted from a skill originally authored by ricardomarin._
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: django-drf
|
|
3
|
+
description: Django REST Framework patterns. Trigger: When building REST APIs with Django - ViewSets, Serializers, Filters.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## ViewSet Pattern
|
|
7
|
+
|
|
8
|
+
```python
|
|
9
|
+
from rest_framework import viewsets, status
|
|
10
|
+
from rest_framework.response import Response
|
|
11
|
+
from rest_framework.decorators import action
|
|
12
|
+
|
|
13
|
+
class UserViewSet(viewsets.ModelViewSet):
|
|
14
|
+
queryset = User.objects.all()
|
|
15
|
+
serializer_class = UserSerializer
|
|
16
|
+
filterset_class = UserFilter
|
|
17
|
+
permission_classes = [IsAuthenticated]
|
|
18
|
+
|
|
19
|
+
def get_serializer_class(self):
|
|
20
|
+
if self.action == "create":
|
|
21
|
+
return UserCreateSerializer
|
|
22
|
+
if self.action in ["update", "partial_update"]:
|
|
23
|
+
return UserUpdateSerializer
|
|
24
|
+
return UserSerializer
|
|
25
|
+
|
|
26
|
+
@action(detail=True, methods=["post"])
|
|
27
|
+
def activate(self, request, pk=None):
|
|
28
|
+
user = self.get_object()
|
|
29
|
+
user.is_active = True
|
|
30
|
+
user.save()
|
|
31
|
+
return Response({"status": "activated"})
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Serializer Patterns
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from rest_framework import serializers
|
|
38
|
+
|
|
39
|
+
# Read Serializer
|
|
40
|
+
class UserSerializer(serializers.ModelSerializer):
|
|
41
|
+
full_name = serializers.SerializerMethodField()
|
|
42
|
+
|
|
43
|
+
class Meta:
|
|
44
|
+
model = User
|
|
45
|
+
fields = ["id", "email", "full_name", "created_at"]
|
|
46
|
+
read_only_fields = ["id", "created_at"]
|
|
47
|
+
|
|
48
|
+
def get_full_name(self, obj):
|
|
49
|
+
return f"{obj.first_name} {obj.last_name}"
|
|
50
|
+
|
|
51
|
+
# Create Serializer
|
|
52
|
+
class UserCreateSerializer(serializers.ModelSerializer):
|
|
53
|
+
password = serializers.CharField(write_only=True)
|
|
54
|
+
|
|
55
|
+
class Meta:
|
|
56
|
+
model = User
|
|
57
|
+
fields = ["email", "password", "first_name", "last_name"]
|
|
58
|
+
|
|
59
|
+
def create(self, validated_data):
|
|
60
|
+
password = validated_data.pop("password")
|
|
61
|
+
user = User(**validated_data)
|
|
62
|
+
user.set_password(password)
|
|
63
|
+
user.save()
|
|
64
|
+
return user
|
|
65
|
+
|
|
66
|
+
# Update Serializer
|
|
67
|
+
class UserUpdateSerializer(serializers.ModelSerializer):
|
|
68
|
+
class Meta:
|
|
69
|
+
model = User
|
|
70
|
+
fields = ["first_name", "last_name"]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Filters
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from django_filters import rest_framework as filters
|
|
77
|
+
|
|
78
|
+
class UserFilter(filters.FilterSet):
|
|
79
|
+
email = filters.CharFilter(lookup_expr="icontains")
|
|
80
|
+
is_active = filters.BooleanFilter()
|
|
81
|
+
created_after = filters.DateTimeFilter(
|
|
82
|
+
field_name="created_at",
|
|
83
|
+
lookup_expr="gte"
|
|
84
|
+
)
|
|
85
|
+
created_before = filters.DateTimeFilter(
|
|
86
|
+
field_name="created_at",
|
|
87
|
+
lookup_expr="lte"
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
class Meta:
|
|
91
|
+
model = User
|
|
92
|
+
fields = ["email", "is_active"]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Permissions
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from rest_framework.permissions import BasePermission
|
|
99
|
+
|
|
100
|
+
class IsOwner(BasePermission):
|
|
101
|
+
def has_object_permission(self, request, view, obj):
|
|
102
|
+
return obj.owner == request.user
|
|
103
|
+
|
|
104
|
+
class IsAdminOrReadOnly(BasePermission):
|
|
105
|
+
def has_permission(self, request, view):
|
|
106
|
+
if request.method in ["GET", "HEAD", "OPTIONS"]:
|
|
107
|
+
return True
|
|
108
|
+
return request.user.is_staff
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Pagination
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from rest_framework.pagination import PageNumberPagination
|
|
115
|
+
|
|
116
|
+
class StandardPagination(PageNumberPagination):
|
|
117
|
+
page_size = 20
|
|
118
|
+
page_size_query_param = "page_size"
|
|
119
|
+
max_page_size = 100
|
|
120
|
+
|
|
121
|
+
# settings.py
|
|
122
|
+
REST_FRAMEWORK = {
|
|
123
|
+
"DEFAULT_PAGINATION_CLASS": "api.pagination.StandardPagination",
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## URL Routing
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from rest_framework.routers import DefaultRouter
|
|
131
|
+
|
|
132
|
+
router = DefaultRouter()
|
|
133
|
+
router.register(r"users", UserViewSet, basename="user")
|
|
134
|
+
router.register(r"posts", PostViewSet, basename="post")
|
|
135
|
+
|
|
136
|
+
urlpatterns = [
|
|
137
|
+
path("api/v1/", include(router.urls)),
|
|
138
|
+
]
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Testing
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
import pytest
|
|
145
|
+
from rest_framework import status
|
|
146
|
+
from rest_framework.test import APIClient
|
|
147
|
+
|
|
148
|
+
@pytest.fixture
|
|
149
|
+
def api_client():
|
|
150
|
+
return APIClient()
|
|
151
|
+
|
|
152
|
+
@pytest.fixture
|
|
153
|
+
def authenticated_client(api_client, user):
|
|
154
|
+
api_client.force_authenticate(user=user)
|
|
155
|
+
return api_client
|
|
156
|
+
|
|
157
|
+
@pytest.mark.django_db
|
|
158
|
+
class TestUserViewSet:
|
|
159
|
+
def test_list_users(self, authenticated_client):
|
|
160
|
+
response = authenticated_client.get("/api/v1/users/")
|
|
161
|
+
assert response.status_code == status.HTTP_200_OK
|
|
162
|
+
|
|
163
|
+
def test_create_user(self, authenticated_client):
|
|
164
|
+
data = {"email": "new@test.com", "password": "pass123"}
|
|
165
|
+
response = authenticated_client.post("/api/v1/users/", data)
|
|
166
|
+
assert response.status_code == status.HTTP_201_CREATED
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Commands
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
python manage.py runserver
|
|
173
|
+
python manage.py makemigrations
|
|
174
|
+
python manage.py migrate
|
|
175
|
+
python manage.py createsuperuser
|
|
176
|
+
python manage.py shell
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Keywords
|
|
180
|
+
django, drf, rest framework, viewset, serializer, api, rest api
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: go-testing
|
|
3
|
+
description: Apply focused Go testing patterns. Trigger: Go tests, go test coverage, Bubbletea teatest, golden files.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Activation Contract
|
|
7
|
+
|
|
8
|
+
Load this skill when writing or reviewing Go tests, adding coverage, testing Bubbletea/TUI flows, using `teatest`, or updating golden files.
|
|
9
|
+
|
|
10
|
+
## Hard Rules
|
|
11
|
+
|
|
12
|
+
- Prefer table-driven tests for multiple cases; use `t.Run(tt.name, ...)`.
|
|
13
|
+
- Test behavior and state transitions, not implementation trivia.
|
|
14
|
+
- Use `t.TempDir()` for filesystem tests; never rely on a real home directory.
|
|
15
|
+
- Keep integration tests skippable with `testing.Short()` when they run external commands or slow flows.
|
|
16
|
+
- For Bubbletea, test `Model.Update()` directly for state changes; use `teatest` only for interactive flows.
|
|
17
|
+
- Golden files must be deterministic; update only through the repo's `-update` path and rerun tests without `-update`.
|
|
18
|
+
- Use small mocks/interfaces around system or command execution boundaries.
|
|
19
|
+
|
|
20
|
+
## Decision Gates
|
|
21
|
+
|
|
22
|
+
| Target | Test pattern |
|
|
23
|
+
|---|---|
|
|
24
|
+
| Pure function or parser | Table-driven unit test. |
|
|
25
|
+
| Error behavior | Explicit success and failure cases. |
|
|
26
|
+
| File operations | `t.TempDir()` plus focused assertions. |
|
|
27
|
+
| TUI state transition | Direct `Model.Update()` call with `tea.Msg`. |
|
|
28
|
+
| Full TUI interaction | `teatest.NewTestModel()`. |
|
|
29
|
+
| Rendered output | Golden file test. |
|
|
30
|
+
| Real external command | Integration test; skip in `-short`. |
|
|
31
|
+
|
|
32
|
+
## Execution Steps
|
|
33
|
+
|
|
34
|
+
1. Identify behavior under test and the smallest public boundary that proves it.
|
|
35
|
+
2. Choose the test pattern from the decision gate.
|
|
36
|
+
3. Name cases by scenario, not input mechanics.
|
|
37
|
+
4. Assert outputs, errors, state, and side effects explicitly.
|
|
38
|
+
5. Run the narrow package test first, then the relevant broader suite.
|
|
39
|
+
6. For golden updates: run with `-update`, inspect diff, then rerun without `-update`.
|
|
40
|
+
|
|
41
|
+
## Output Contract
|
|
42
|
+
|
|
43
|
+
Report test files changed, scenarios covered, commands executed, golden files updated, and any skipped integration scope.
|
|
44
|
+
|
|
45
|
+
## References
|
|
46
|
+
|
|
47
|
+
- [references/examples.md](references/examples.md) — compact table-driven, Bubbletea, teatest, golden, and command examples.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Go Testing Examples
|
|
2
|
+
|
|
3
|
+
## Table-Driven Test
|
|
4
|
+
|
|
5
|
+
```go
|
|
6
|
+
func TestProcessInput(t *testing.T) {
|
|
7
|
+
tests := []struct {
|
|
8
|
+
name string
|
|
9
|
+
input string
|
|
10
|
+
want string
|
|
11
|
+
wantErr bool
|
|
12
|
+
}{
|
|
13
|
+
{name: "valid input", input: "hello", want: "HELLO"},
|
|
14
|
+
{name: "empty input", input: "", wantErr: true},
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
for _, tt := range tests {
|
|
18
|
+
t.Run(tt.name, func(t *testing.T) {
|
|
19
|
+
got, err := ProcessInput(tt.input)
|
|
20
|
+
if (err != nil) != tt.wantErr {
|
|
21
|
+
t.Fatalf("err = %v, wantErr %v", err, tt.wantErr)
|
|
22
|
+
}
|
|
23
|
+
if got != tt.want {
|
|
24
|
+
t.Fatalf("got %q, want %q", got, tt.want)
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Bubbletea State Transition
|
|
32
|
+
|
|
33
|
+
```go
|
|
34
|
+
func TestModelUpdateEnter(t *testing.T) {
|
|
35
|
+
m := NewModel()
|
|
36
|
+
next, _ := m.Update(tea.KeyMsg{Type: tea.KeyEnter})
|
|
37
|
+
got := next.(Model)
|
|
38
|
+
if got.Screen != ScreenMainMenu {
|
|
39
|
+
t.Fatalf("screen = %v, want %v", got.Screen, ScreenMainMenu)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Teatest Flow
|
|
45
|
+
|
|
46
|
+
```go
|
|
47
|
+
func TestInteractiveFlow(t *testing.T) {
|
|
48
|
+
tm := teatest.NewTestModel(t, NewModel())
|
|
49
|
+
tm.Send(tea.KeyMsg{Type: tea.KeyEnter})
|
|
50
|
+
tm.WaitFinished(t, teatest.WithDuration(time.Second))
|
|
51
|
+
final := tm.FinalModel(t).(Model)
|
|
52
|
+
if final.Screen != ExpectedScreen {
|
|
53
|
+
t.Fatalf("screen = %v, want %v", final.Screen, ExpectedScreen)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Golden File Pattern
|
|
59
|
+
|
|
60
|
+
```go
|
|
61
|
+
var update = flag.Bool("update", false, "update golden files")
|
|
62
|
+
|
|
63
|
+
func assertGolden(t *testing.T, path string, got string) {
|
|
64
|
+
t.Helper()
|
|
65
|
+
if *update {
|
|
66
|
+
if err := os.WriteFile(path, []byte(got), 0o644); err != nil {
|
|
67
|
+
t.Fatal(err)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
want, err := os.ReadFile(path)
|
|
71
|
+
if err != nil {
|
|
72
|
+
t.Fatal(err)
|
|
73
|
+
}
|
|
74
|
+
if got != string(want) {
|
|
75
|
+
t.Fatalf("golden mismatch for %s", path)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Commands
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
go test ./...
|
|
84
|
+
go test -v ./internal/tui/...
|
|
85
|
+
go test -run TestNavigation ./internal/tui
|
|
86
|
+
go test -cover ./...
|
|
87
|
+
go test ./internal/components -update
|
|
88
|
+
go test -short ./...
|
|
89
|
+
```
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: issue-creation
|
|
3
|
+
description: Create issues with issue-first checks. Trigger: creating GitHub issues, bug reports, or feature requests.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## When to Use
|
|
7
|
+
|
|
8
|
+
Use this skill when:
|
|
9
|
+
- Creating a GitHub issue (bug report or feature request)
|
|
10
|
+
- Helping a contributor file an issue
|
|
11
|
+
- Triaging or approving issues as a maintainer
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Critical Rules
|
|
16
|
+
|
|
17
|
+
1. **Blank issues are disabled** — MUST use a template (bug report or feature request)
|
|
18
|
+
2. **Every issue gets `status:needs-review` automatically** on creation
|
|
19
|
+
3. **A maintainer MUST add `status:approved`** before any PR can be opened
|
|
20
|
+
4. **Questions go to your project's own Discussions tab (or equivalent support channel)**, not issues — don't point contributors at a foreign repo's discussions
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Workflow
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
1. Search existing issues for duplicates
|
|
28
|
+
2. Choose the correct template (Bug Report or Feature Request)
|
|
29
|
+
3. Fill in ALL required fields
|
|
30
|
+
4. Check pre-flight checkboxes
|
|
31
|
+
5. Submit → issue gets status:needs-review automatically
|
|
32
|
+
6. Wait for maintainer to add status:approved
|
|
33
|
+
7. Only then open a PR linking this issue
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Issue Templates
|
|
39
|
+
|
|
40
|
+
### Bug Report
|
|
41
|
+
|
|
42
|
+
Template: `.github/ISSUE_TEMPLATE/bug_report.yml`
|
|
43
|
+
Auto-labels: `bug`, `status:needs-review`
|
|
44
|
+
|
|
45
|
+
#### Required Fields
|
|
46
|
+
|
|
47
|
+
| Field | Description |
|
|
48
|
+
|-------|-------------|
|
|
49
|
+
| **Pre-flight Checks** | Checkboxes: no duplicate + understands approval workflow |
|
|
50
|
+
| **Bug Description** | Clear description of the bug |
|
|
51
|
+
| **Steps to Reproduce** | Numbered steps to reproduce |
|
|
52
|
+
| **Expected Behavior** | What should have happened |
|
|
53
|
+
| **Actual Behavior** | What happened instead (include errors/logs) |
|
|
54
|
+
| **Operating System** | Dropdown: macOS, Linux variants, Windows, WSL |
|
|
55
|
+
| **Agent / Client** | Dropdown: Claude Code, OpenCode, Gemini CLI, Cursor, Windsurf, Codex, Other |
|
|
56
|
+
| **Shell** | Dropdown: bash, zsh, fish, Other |
|
|
57
|
+
|
|
58
|
+
#### Optional Fields
|
|
59
|
+
|
|
60
|
+
| Field | Description |
|
|
61
|
+
|-------|-------------|
|
|
62
|
+
| **Relevant Logs** | Log output (auto-formatted as code block) |
|
|
63
|
+
| **Additional Context** | Screenshots, workarounds, extra info |
|
|
64
|
+
|
|
65
|
+
#### Example — Bug Report via CLI
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
gh issue create --template "bug_report.yml" \
|
|
69
|
+
--title "fix(scripts): setup.sh fails on zsh with glob error" \
|
|
70
|
+
--body "
|
|
71
|
+
### Pre-flight Checks
|
|
72
|
+
- [x] I have searched existing issues and this is not a duplicate
|
|
73
|
+
- [x] I understand this issue needs status:approved before a PR can be opened
|
|
74
|
+
|
|
75
|
+
### Bug Description
|
|
76
|
+
Running setup.sh on zsh throws a glob error when no matching files exist.
|
|
77
|
+
|
|
78
|
+
### Steps to Reproduce
|
|
79
|
+
1. Clone the repo
|
|
80
|
+
2. Run \`./scripts/setup.sh\` in zsh
|
|
81
|
+
3. See error: \`zsh: no matches found: skills/*\`
|
|
82
|
+
|
|
83
|
+
### Expected Behavior
|
|
84
|
+
The script should handle missing glob matches gracefully.
|
|
85
|
+
|
|
86
|
+
### Actual Behavior
|
|
87
|
+
Script crashes with glob error.
|
|
88
|
+
|
|
89
|
+
### Operating System
|
|
90
|
+
macOS
|
|
91
|
+
|
|
92
|
+
### Agent / Client
|
|
93
|
+
Claude Code
|
|
94
|
+
|
|
95
|
+
### Shell
|
|
96
|
+
zsh
|
|
97
|
+
|
|
98
|
+
### Relevant Logs
|
|
99
|
+
\`\`\`
|
|
100
|
+
zsh: no matches found: skills/*
|
|
101
|
+
\`\`\`
|
|
102
|
+
"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
### Feature Request
|
|
108
|
+
|
|
109
|
+
Template: `.github/ISSUE_TEMPLATE/feature_request.yml`
|
|
110
|
+
Auto-labels: `enhancement`, `status:needs-review`
|
|
111
|
+
|
|
112
|
+
#### Required Fields
|
|
113
|
+
|
|
114
|
+
| Field | Description |
|
|
115
|
+
|-------|-------------|
|
|
116
|
+
| **Pre-flight Checks** | Checkboxes: no duplicate + understands approval workflow |
|
|
117
|
+
| **Problem Description** | The pain point this feature solves |
|
|
118
|
+
| **Proposed Solution** | How it should work from the user's perspective |
|
|
119
|
+
| **Affected Area** | Dropdown: Scripts, Skills, Examples, Documentation, CI/Workflows, Other |
|
|
120
|
+
|
|
121
|
+
#### Optional Fields
|
|
122
|
+
|
|
123
|
+
| Field | Description |
|
|
124
|
+
|-------|-------------|
|
|
125
|
+
| **Alternatives Considered** | Other approaches or workarounds |
|
|
126
|
+
| **Additional Context** | Mockups, examples, references |
|
|
127
|
+
|
|
128
|
+
#### Example — Feature Request via CLI
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
gh issue create --template "feature_request.yml" \
|
|
132
|
+
--title "feat(scripts): add Codex support to setup.sh" \
|
|
133
|
+
--body "
|
|
134
|
+
### Pre-flight Checks
|
|
135
|
+
- [x] I have searched existing issues and this is not a duplicate
|
|
136
|
+
- [x] I understand this issue needs status:approved before a PR can be opened
|
|
137
|
+
|
|
138
|
+
### Problem Description
|
|
139
|
+
The setup script only configures Claude Code, Gemini CLI, and OpenCode. Codex users have to manually copy skills.
|
|
140
|
+
|
|
141
|
+
### Proposed Solution
|
|
142
|
+
Add a Codex option to setup.sh that links skills to the .codex/ directory.
|
|
143
|
+
|
|
144
|
+
Example:
|
|
145
|
+
\`\`\`bash
|
|
146
|
+
./scripts/setup.sh --agent codex
|
|
147
|
+
\`\`\`
|
|
148
|
+
|
|
149
|
+
### Affected Area
|
|
150
|
+
Scripts (setup, installation)
|
|
151
|
+
|
|
152
|
+
### Alternatives Considered
|
|
153
|
+
Manually symlinking, but that defeats the purpose of the setup script.
|
|
154
|
+
"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Label System
|
|
160
|
+
|
|
161
|
+
### Applied Automatically on Issue Creation
|
|
162
|
+
|
|
163
|
+
| Template | Labels added |
|
|
164
|
+
|----------|-------------|
|
|
165
|
+
| Bug Report | `bug`, `status:needs-review` |
|
|
166
|
+
| Feature Request | `enhancement`, `status:needs-review` |
|
|
167
|
+
|
|
168
|
+
### Applied by Maintainers
|
|
169
|
+
|
|
170
|
+
| Label | When to apply |
|
|
171
|
+
|-------|--------------|
|
|
172
|
+
| `status:approved` | Issue accepted for implementation — PRs can now be opened |
|
|
173
|
+
| `priority:high` | Critical bug or urgent feature |
|
|
174
|
+
| `priority:medium` | Important but not blocking |
|
|
175
|
+
| `priority:low` | Nice to have |
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Maintainer Approval Workflow
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
1. New issue arrives with status:needs-review
|
|
183
|
+
2. Review the issue — is it valid, clear, and in scope?
|
|
184
|
+
3. If YES → add status:approved label
|
|
185
|
+
4. If NO → comment with reason, close if needed
|
|
186
|
+
5. Contributor can now open a PR linking this issue
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Decision Tree
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
Is it a bug? → Use Bug Report template
|
|
195
|
+
Is it a new feature/improvement? → Use Feature Request template
|
|
196
|
+
Is it a question? → Use your project's Discussions (or equivalent), NOT issues
|
|
197
|
+
Is it a duplicate? → Link to existing issue, close
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Commands
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# Search existing issues before creating
|
|
206
|
+
gh issue list --search "keyword"
|
|
207
|
+
|
|
208
|
+
# Create bug report
|
|
209
|
+
gh issue create --template "bug_report.yml" --title "fix(scope): description"
|
|
210
|
+
|
|
211
|
+
# Create feature request
|
|
212
|
+
gh issue create --template "feature_request.yml" --title "feat(scope): description"
|
|
213
|
+
|
|
214
|
+
# Maintainer: approve an issue
|
|
215
|
+
gh issue edit <number> --add-label "status:approved"
|
|
216
|
+
|
|
217
|
+
# Maintainer: add priority
|
|
218
|
+
gh issue edit <number> --add-label "priority:high"
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
_Adapted from a skill originally authored by gentleman-programming._
|