ソース情報
- リポジトリ
- trycompai/comp
- ソースの最終更新活動
- 2026年4月27日 13:56
- 検出された SKILL.md の言語
- 英語
- スター
- 1,870
- フォーク
- 383
インストール方法
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
ソースファイルを確認
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
メニュー
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
SOC 職業分類に基づく
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/trycompai/comp --skill formsコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
SKILL.md を表示中
Run all audit checks (RBAC, hooks, design system, tests) and verify build
Check code for the most common, high-risk security vulnerabilities (broken access control, tenant isolation, injection, secrets, SSRF, auth/session, unsafe file handling, mass assignment) before it ships. Use after editing any API controller, guard, or auth code (apps/api/src/auth/**), a Prisma schema/query, a file-upload/webhook handler, or before committing/pushing security-sensitive changes.
How to reuse ANY integration check's results in a feature via the universal CheckResultsService (apps/api integration-platform). Use whenever a feature needs data produced by an integration check — "show 2FA status on People", "surface AWS S3 findings in X", "reuse a check's results", "per-user/per-resource results from a connected integration", "which integrations feed task T". Read this BEFORE writing your own IntegrationCheckResult / CheckRunRepository query — don't hand-roll it.
| name | forms |
| description | Use when building forms - covers React Hook Form, Zod validation, and form patterns |
Source Cursor rule: .cursor/rules/forms.mdc.
Original Cursor alwaysApply: false.
All forms MUST use React Hook Form with Zod validation.
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { Button, Input } from '@trycompai/design-system';
// 1. Define schema
const formSchema = z.object({
email: z.string().email('Invalid email'),
password: z.string().min(8, 'Min 8 characters'),
});
// 2. Infer type
type FormData = z.infer<typeof formSchema>;
// 3. Use in component
function MyForm() {
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<FormData>({
resolver: zodResolver(formSchema),
});
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Input {...register('email')} />
{errors.email && <p>{errors.email.message}</p>}
<Button type="submit" loading={isSubmitting}>
Submit
</Button>
</form>
);
}
const profileSchema = z.object({
// Strings
name: z.string().min(1, 'Required'),
email: z.string().email(),
website: z.string().url().optional(),
// Numbers (coerce for inputs)
age: z.coerce.number().int().min(0),
price: z.coerce.number().positive(),
// Arrays
tags: z.array(z.string()).min(1),
// Enums
status: z.enum(['active', 'inactive']),
});
// Cross-field validation
const passwordSchema = z.object({
password: z.string().min(8),
confirmPassword: z.string(),
}).refine(d => d.password === d.confirmPassword, {
message: ,
: [],
});
import { Controller } from 'react-hook-form';
import { Select, SelectContent, SelectItem, SelectTrigger } from '@trycompai/design-system';
<Controller
name="status"
control={control}
render={({ field }) => (
<Select onValueChange={field.onChange} value={field.value}>
<SelectTrigger>{field.value || 'Select...'}</SelectTrigger>
<SelectContent>
<SelectItem value="active">Active</SelectItem>
<SelectItem value="inactive">Inactive</SelectItem>
</SelectContent>
</Select>
)}
/>
const {
register,
handleSubmit,
control,
watch, // Watch field values
setValue, // Set field programmatically
reset, // Reset form
setError, // Set error manually
formState: {
errors, // Field errors
isSubmitting, // Submitting
isValid, // All valid
isDirty, // Modified
},
} = useForm<FormData>({
resolver: zodResolver(schema),
mode: 'onChange', // Validate on change
});
const onSubmit = async (data: FormData) => {
try {
await submitToApi(data);
} catch (error) {
// Field-specific error
setError('email', { message: 'Email taken' });
// Or root error
setError('root', { message: 'Something went wrong' });
}
};
// Display root error
{errors.root && <p>{errors.root.message}</p>}
import { useFieldArray } from 'react-hook-form';
const { fields, append, remove } = useFieldArray({
control,
name: 'items',
});
{fields.map((field, index) => (
<div key={field.id}>
<Input {...register(`items.${index}.name`)} />
<Button type="button" onClick={() => remove(index)}>Remove</Button>
</div>
))}
<Button type="button" onClick={() => append({ name: '' })}>Add</Button>
// ❌ useState for form fields
const [email, setEmail] = useState('');
// ❌ Manual validation
if (email.length < 5) setError('Too short');
// ❌ Missing button type (defaults to submit)
<Button onClick={handleCancel}>Cancel</Button>
// ✅ Correct
const { register } = useForm();
const schema = z.object({ email: z.string().min(5) });
<Button type="button" onClick={handleCancel}>Cancel</Button>