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,210 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zod-4
|
|
3
|
+
description: Zod 4 schema validation patterns. Trigger: When using Zod for validation - breaking changes from v3.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Breaking Changes from Zod 3
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
// ❌ Zod 3 (OLD)
|
|
10
|
+
z.string().email()
|
|
11
|
+
z.string().uuid()
|
|
12
|
+
z.string().url()
|
|
13
|
+
z.string().nonempty()
|
|
14
|
+
z.object({ name: z.string() }).required_error("Required")
|
|
15
|
+
|
|
16
|
+
// ✅ Zod 4 (NEW)
|
|
17
|
+
z.email()
|
|
18
|
+
z.uuid()
|
|
19
|
+
z.url()
|
|
20
|
+
z.string().min(1)
|
|
21
|
+
z.object({ name: z.string() }, { error: "Required" })
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Basic Schemas
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { z } from "zod";
|
|
28
|
+
|
|
29
|
+
// Primitives
|
|
30
|
+
const stringSchema = z.string();
|
|
31
|
+
const numberSchema = z.number();
|
|
32
|
+
const booleanSchema = z.boolean();
|
|
33
|
+
const dateSchema = z.date();
|
|
34
|
+
|
|
35
|
+
// Top-level validators (Zod 4)
|
|
36
|
+
const emailSchema = z.email();
|
|
37
|
+
const uuidSchema = z.uuid();
|
|
38
|
+
const urlSchema = z.url();
|
|
39
|
+
|
|
40
|
+
// With constraints
|
|
41
|
+
const nameSchema = z.string().min(1).max(100);
|
|
42
|
+
const ageSchema = z.number().int().positive().max(150);
|
|
43
|
+
const priceSchema = z.number().min(0).multipleOf(0.01);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Object Schemas
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
const userSchema = z.object({
|
|
50
|
+
id: z.uuid(),
|
|
51
|
+
email: z.email({ error: "Invalid email address" }),
|
|
52
|
+
name: z.string().min(1, { error: "Name is required" }),
|
|
53
|
+
age: z.number().int().positive().optional(),
|
|
54
|
+
role: z.enum(["admin", "user", "guest"]),
|
|
55
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
type User = z.infer<typeof userSchema>;
|
|
59
|
+
|
|
60
|
+
// Parsing
|
|
61
|
+
const user = userSchema.parse(data); // Throws on error
|
|
62
|
+
const result = userSchema.safeParse(data); // Returns { success, data/error }
|
|
63
|
+
|
|
64
|
+
if (result.success) {
|
|
65
|
+
console.log(result.data);
|
|
66
|
+
} else {
|
|
67
|
+
console.log(result.error.issues);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Arrays and Records
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// Arrays
|
|
75
|
+
const tagsSchema = z.array(z.string()).min(1).max(10);
|
|
76
|
+
const numbersSchema = z.array(z.number()).nonempty();
|
|
77
|
+
|
|
78
|
+
// Records (objects with dynamic keys)
|
|
79
|
+
const scoresSchema = z.record(z.string(), z.number());
|
|
80
|
+
// { [key: string]: number }
|
|
81
|
+
|
|
82
|
+
// Tuples
|
|
83
|
+
const coordinatesSchema = z.tuple([z.number(), z.number()]);
|
|
84
|
+
// [number, number]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Unions and Discriminated Unions
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
// Simple union
|
|
91
|
+
const stringOrNumber = z.union([z.string(), z.number()]);
|
|
92
|
+
|
|
93
|
+
// Discriminated union (more efficient)
|
|
94
|
+
const resultSchema = z.discriminatedUnion("status", [
|
|
95
|
+
z.object({ status: z.literal("success"), data: z.unknown() }),
|
|
96
|
+
z.object({ status: z.literal("error"), error: z.string() }),
|
|
97
|
+
]);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Transformations
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// Transform during parsing
|
|
104
|
+
const lowercaseEmail = z.email().transform(email => email.toLowerCase());
|
|
105
|
+
|
|
106
|
+
// Coercion (convert types)
|
|
107
|
+
const numberFromString = z.coerce.number(); // "42" → 42
|
|
108
|
+
const dateFromString = z.coerce.date(); // "2024-01-01" → Date
|
|
109
|
+
|
|
110
|
+
// Preprocessing
|
|
111
|
+
const trimmedString = z.preprocess(
|
|
112
|
+
val => typeof val === "string" ? val.trim() : val,
|
|
113
|
+
z.string()
|
|
114
|
+
);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Refinements
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
const passwordSchema = z.string()
|
|
121
|
+
.min(8)
|
|
122
|
+
.refine(val => /[A-Z]/.test(val), {
|
|
123
|
+
message: "Must contain uppercase letter",
|
|
124
|
+
})
|
|
125
|
+
.refine(val => /[0-9]/.test(val), {
|
|
126
|
+
message: "Must contain number",
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// With superRefine for multiple errors
|
|
130
|
+
const formSchema = z.object({
|
|
131
|
+
password: z.string(),
|
|
132
|
+
confirmPassword: z.string(),
|
|
133
|
+
}).superRefine((data, ctx) => {
|
|
134
|
+
if (data.password !== data.confirmPassword) {
|
|
135
|
+
ctx.addIssue({
|
|
136
|
+
code: z.ZodIssueCode.custom,
|
|
137
|
+
message: "Passwords don't match",
|
|
138
|
+
path: ["confirmPassword"],
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Optional and Nullable
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
// Optional (T | undefined)
|
|
148
|
+
z.string().optional()
|
|
149
|
+
|
|
150
|
+
// Nullable (T | null)
|
|
151
|
+
z.string().nullable()
|
|
152
|
+
|
|
153
|
+
// Both (T | null | undefined)
|
|
154
|
+
z.string().nullish()
|
|
155
|
+
|
|
156
|
+
// Default values
|
|
157
|
+
z.string().default("unknown")
|
|
158
|
+
z.number().default(() => Math.random())
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Error Handling
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// Zod 4: Use 'error' param instead of 'message'
|
|
165
|
+
const schema = z.object({
|
|
166
|
+
name: z.string({ error: "Name must be a string" }),
|
|
167
|
+
email: z.email({ error: "Invalid email format" }),
|
|
168
|
+
age: z.number().min(18, { error: "Must be 18 or older" }),
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Custom error map
|
|
172
|
+
const customSchema = z.string({
|
|
173
|
+
error: (issue) => {
|
|
174
|
+
if (issue.code === "too_small") {
|
|
175
|
+
return "String is too short";
|
|
176
|
+
}
|
|
177
|
+
return "Invalid string";
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## React Hook Form Integration
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
import { useForm } from "react-hook-form";
|
|
186
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
187
|
+
|
|
188
|
+
const schema = z.object({
|
|
189
|
+
email: z.email(),
|
|
190
|
+
password: z.string().min(8),
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
type FormData = z.infer<typeof schema>;
|
|
194
|
+
|
|
195
|
+
function Form() {
|
|
196
|
+
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
|
|
197
|
+
resolver: zodResolver(schema),
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
return (
|
|
201
|
+
<form onSubmit={handleSubmit(onSubmit)}>
|
|
202
|
+
<input {...register("email")} />
|
|
203
|
+
{errors.email && <span>{errors.email.message}</span>}
|
|
204
|
+
</form>
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Keywords
|
|
210
|
+
zod, validation, schema, typescript, forms, parsing
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zustand-5
|
|
3
|
+
description: Zustand 5 state management patterns. Trigger: When managing React state with Zustand.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Basic Store
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
import { create } from "zustand";
|
|
10
|
+
|
|
11
|
+
interface CounterStore {
|
|
12
|
+
count: number;
|
|
13
|
+
increment: () => void;
|
|
14
|
+
decrement: () => void;
|
|
15
|
+
reset: () => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const useCounterStore = create<CounterStore>((set) => ({
|
|
19
|
+
count: 0,
|
|
20
|
+
increment: () => set((state) => ({ count: state.count + 1 })),
|
|
21
|
+
decrement: () => set((state) => ({ count: state.count - 1 })),
|
|
22
|
+
reset: () => set({ count: 0 }),
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
// Usage
|
|
26
|
+
function Counter() {
|
|
27
|
+
const { count, increment, decrement } = useCounterStore();
|
|
28
|
+
return (
|
|
29
|
+
<div>
|
|
30
|
+
<span>{count}</span>
|
|
31
|
+
<button onClick={increment}>+</button>
|
|
32
|
+
<button onClick={decrement}>-</button>
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Persist Middleware
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { create } from "zustand";
|
|
42
|
+
import { persist } from "zustand/middleware";
|
|
43
|
+
|
|
44
|
+
interface SettingsStore {
|
|
45
|
+
theme: "light" | "dark";
|
|
46
|
+
language: string;
|
|
47
|
+
setTheme: (theme: "light" | "dark") => void;
|
|
48
|
+
setLanguage: (language: string) => void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const useSettingsStore = create<SettingsStore>()(
|
|
52
|
+
persist(
|
|
53
|
+
(set) => ({
|
|
54
|
+
theme: "light",
|
|
55
|
+
language: "en",
|
|
56
|
+
setTheme: (theme) => set({ theme }),
|
|
57
|
+
setLanguage: (language) => set({ language }),
|
|
58
|
+
}),
|
|
59
|
+
{
|
|
60
|
+
name: "settings-storage", // localStorage key
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Selectors (Zustand 5)
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// ✅ Select specific fields to prevent unnecessary re-renders
|
|
70
|
+
function UserName() {
|
|
71
|
+
const name = useUserStore((state) => state.name);
|
|
72
|
+
return <span>{name}</span>;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ✅ For multiple fields, use useShallow
|
|
76
|
+
import { useShallow } from "zustand/react/shallow";
|
|
77
|
+
|
|
78
|
+
function UserInfo() {
|
|
79
|
+
const { name, email } = useUserStore(
|
|
80
|
+
useShallow((state) => ({ name: state.name, email: state.email }))
|
|
81
|
+
);
|
|
82
|
+
return <div>{name} - {email}</div>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ❌ AVOID: Selecting entire store (causes re-render on any change)
|
|
86
|
+
const store = useUserStore(); // Re-renders on ANY state change
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Async Actions
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
interface UserStore {
|
|
93
|
+
user: User | null;
|
|
94
|
+
loading: boolean;
|
|
95
|
+
error: string | null;
|
|
96
|
+
fetchUser: (id: string) => Promise<void>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const useUserStore = create<UserStore>((set) => ({
|
|
100
|
+
user: null,
|
|
101
|
+
loading: false,
|
|
102
|
+
error: null,
|
|
103
|
+
|
|
104
|
+
fetchUser: async (id) => {
|
|
105
|
+
set({ loading: true, error: null });
|
|
106
|
+
try {
|
|
107
|
+
const response = await fetch(`/api/users/${id}`);
|
|
108
|
+
const user = await response.json();
|
|
109
|
+
set({ user, loading: false });
|
|
110
|
+
} catch (error) {
|
|
111
|
+
set({ error: "Failed to fetch user", loading: false });
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
}));
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Slices Pattern
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// userSlice.ts
|
|
121
|
+
interface UserSlice {
|
|
122
|
+
user: User | null;
|
|
123
|
+
setUser: (user: User) => void;
|
|
124
|
+
clearUser: () => void;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const createUserSlice = (set): UserSlice => ({
|
|
128
|
+
user: null,
|
|
129
|
+
setUser: (user) => set({ user }),
|
|
130
|
+
clearUser: () => set({ user: null }),
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// cartSlice.ts
|
|
134
|
+
interface CartSlice {
|
|
135
|
+
items: CartItem[];
|
|
136
|
+
addItem: (item: CartItem) => void;
|
|
137
|
+
removeItem: (id: string) => void;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const createCartSlice = (set): CartSlice => ({
|
|
141
|
+
items: [],
|
|
142
|
+
addItem: (item) => set((state) => ({ items: [...state.items, item] })),
|
|
143
|
+
removeItem: (id) => set((state) => ({
|
|
144
|
+
items: state.items.filter(i => i.id !== id)
|
|
145
|
+
})),
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// store.ts
|
|
149
|
+
type Store = UserSlice & CartSlice;
|
|
150
|
+
|
|
151
|
+
const useStore = create<Store>()((...args) => ({
|
|
152
|
+
...createUserSlice(...args),
|
|
153
|
+
...createCartSlice(...args),
|
|
154
|
+
}));
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Immer Middleware
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import { create } from "zustand";
|
|
161
|
+
import { immer } from "zustand/middleware/immer";
|
|
162
|
+
|
|
163
|
+
interface TodoStore {
|
|
164
|
+
todos: Todo[];
|
|
165
|
+
addTodo: (text: string) => void;
|
|
166
|
+
toggleTodo: (id: string) => void;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const useTodoStore = create<TodoStore>()(
|
|
170
|
+
immer((set) => ({
|
|
171
|
+
todos: [],
|
|
172
|
+
|
|
173
|
+
addTodo: (text) => set((state) => {
|
|
174
|
+
// Mutate directly with Immer!
|
|
175
|
+
state.todos.push({ id: crypto.randomUUID(), text, done: false });
|
|
176
|
+
}),
|
|
177
|
+
|
|
178
|
+
toggleTodo: (id) => set((state) => {
|
|
179
|
+
const todo = state.todos.find(t => t.id === id);
|
|
180
|
+
if (todo) todo.done = !todo.done;
|
|
181
|
+
}),
|
|
182
|
+
}))
|
|
183
|
+
);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## DevTools
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { create } from "zustand";
|
|
190
|
+
import { devtools } from "zustand/middleware";
|
|
191
|
+
|
|
192
|
+
const useStore = create<Store>()(
|
|
193
|
+
devtools(
|
|
194
|
+
(set) => ({
|
|
195
|
+
// store definition
|
|
196
|
+
}),
|
|
197
|
+
{ name: "MyStore" } // Name in Redux DevTools
|
|
198
|
+
)
|
|
199
|
+
);
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Outside React
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
// Access store outside components
|
|
206
|
+
const { count, increment } = useCounterStore.getState();
|
|
207
|
+
increment();
|
|
208
|
+
|
|
209
|
+
// Subscribe to changes
|
|
210
|
+
const unsubscribe = useCounterStore.subscribe(
|
|
211
|
+
(state) => console.log("Count changed:", state.count)
|
|
212
|
+
);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Keywords
|
|
216
|
+
zustand, state management, react, store, persist, middleware
|
package/bin/argos.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Thin, committed entrypoint for the `argos` binary.
|
|
3
|
+
// dist/index.js is ESM and runs the CLI as a side effect of being imported
|
|
4
|
+
// (it calls citty's runMain() at module-eval time), so importing it here
|
|
5
|
+
// is enough to actually execute the CLI — no exported function to call.
|
|
6
|
+
await import("../dist/index.js");
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { FileStatus } from "../lib/managed-files.js";
|
|
2
|
+
/** Written when no lint/typecheck/test script exists to build a real gate from. */
|
|
3
|
+
export declare const NO_GATE_PLACEHOLDER = "echo 'argos: no lint/typecheck/test scripts detected \u2014 set qualityGate.fast manually'";
|
|
4
|
+
export interface AdoptRow {
|
|
5
|
+
field: string;
|
|
6
|
+
value: string;
|
|
7
|
+
source: "imported" | "preserved" | "detected" | "default" | "info" | "warning" | "error";
|
|
8
|
+
}
|
|
9
|
+
export interface AdoptOptions {
|
|
10
|
+
cwd: string;
|
|
11
|
+
refresh?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface AdoptReport {
|
|
14
|
+
rows: AdoptRow[];
|
|
15
|
+
configPath?: string;
|
|
16
|
+
fichaStatus?: FileStatus;
|
|
17
|
+
backupPath?: string;
|
|
18
|
+
exitCode: 0 | 1;
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Core, testable implementation of `argos adopt [--refresh]`: writes
|
|
23
|
+
* `argos.config.json` (detecting stack/quality-gate/identity, importing
|
|
24
|
+
* `navori.config.json` when present) and injects the `ficha` managed block
|
|
25
|
+
* into `./CLAUDE.md`. Pure function of the filesystem — no process.exit.
|
|
26
|
+
*/
|
|
27
|
+
export declare function runAdopt(options: AdoptOptions): AdoptReport;
|
|
28
|
+
export declare const adoptCommand: import("citty").CommandDef<{
|
|
29
|
+
readonly refresh: {
|
|
30
|
+
readonly type: "boolean";
|
|
31
|
+
readonly default: false;
|
|
32
|
+
readonly description: "Regenera argos.config.json y la ficha aunque ya existan.";
|
|
33
|
+
};
|
|
34
|
+
}>;
|
|
35
|
+
//# sourceMappingURL=adopt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopt.d.ts","sourceRoot":"","sources":["../../src/commands/adopt.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAK1D,mFAAmF;AACnF,eAAO,MAAM,mBAAmB,+FACyD,CAAC;AAE1F,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;CAC1F;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW,CAyO3D;AAED,eAAO,MAAM,YAAY;;;;;;EAgCvB,CAAC"}
|