Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
git clone --depth 1 https://github.com/JrPribs/SmarterStarterWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/rules/jrpribs/smarterstarter/600-angular-ngrx-signal-store)<a href="https://agentmods.dev/rules/jrpribs/smarterstarter/600-angular-ngrx-signal-store"><img src="https://agentmods.dev/badge/rules/jrpribs/smarterstarter/600-angular-ngrx-signal-store/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/rules/jrpribs/smarterstarter/600-angular-ngrx-signal-store"><img src="https://agentmods.dev/badge/rules/jrpribs/smarterstarter/600-angular-ngrx-signal-store.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00000 | $0.03892 |
| Opus 5 | $0.00000 | $0.01946 |
| Sonnet 5 | $0.00000 | $0.00778 |
| Haiku 4.5 | $0.00000 | $0.00389 |
Grade A, and why
600-angular-ngrx-signal-store scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 9d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 608 lines — stays where its author put it; the contents beside it link to each section on GitHub.
NGRx Signal Store Best Practices
- Creating Signal Stores: Use the createStore function from @ngrx/signals to create a signal store as part of the global state layer.
import { createStore, withState, withComputed, withMethods, patchState } from '@ngrx/signals';
import { rxMethod } from '@ngrx/signals/rxjs-interop';
import { pipe, switchMap, map, catchError } from 'rxjs';
import { inject } from '@angular/core';
import { tapResponse } from '@ngrx/operators';
export interface TodosState {
todos: Todo[];
status: 'idle' | 'loading' | 'error';
error: string | null;
}
export const initialState: TodosState = {
todos: [],
status: 'idle',
error: null
};
export const TodosStore = createStore(
{ providedIn: 'root' },
withState(initialState),
withComputed(({ todos }) => ({
completedTodos: computed(() => todos().filter(todo => todo.completed)),
incompleteTodos: computed(() => todos().filter(todo => !todo.completed)),
todoCount: computed(() => todos().length)
})),
withMethods((store, todosService = inject(TodosService)) => ({
loadTodos: rxMethod(
pipe(
switchMap(() => {
patchState(store, { status: 'loading', error: null });
return todosService.getTodos().pipe(
tapResponse(
(todos) => patchState(store, { todos, status: 'idle' }),
(error) => patchState(store, {
status: 'error',
error: error instanceof Error ? error.message : 'Unknown error'
})
)
);
})
)
),
addTodo: (title: string) => {
const newTodo: Todo = {
id: Date.now().toString(),
title,
completed: false
};
patchState(store, ({ todos }) => ({
todos: [...todos, newTodo]
}));
},
removeTodo: (id: string) => {
patchState(store, ({ todos }) => ({
todos: todos.filter(todo => todo.id !== id)
}));
},
toggleTodo: (id: string) => {
patchState(store, ({ todos }) => ({
todos: todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
)
}));
}
}))
);
- Store Methods Are Not Services: Methods in the store should focus on state updates only, not business logic.
// ❌ AVOID: Business logic in store methods
export const BadUserStore = createStore(
{ providedIn: 'root' },
withState<UserState>(initialUserState),
withMethods((store) => ({
updateUser: (userData: UserUpdateDto) => {
// Business validation doesn't belong in the store
if (!userData.name || userData.name.length < 3) {
throw new Error('Name must be at least 3 characters');
}
// Business transformations should be in services
const formattedUser = {
...userData,
name: userData.name.trim(),
updatedAt: new Date().toISOString()
};
// The state update itself is appropriate
patchState(store, { user: formattedUser });
}
}))
);
// ✅ GOOD: Store methods focused on state updates
export const GoodUserStore = createStore(
{ providedIn: 'root' },
withState<UserState>(initialUserState),
withMethods((store) => ({
// Store methods should be simple state operations
updateUser: (user: User) => {
patchState(store, { user });
},
setLoading: (loading: boolean) => {
patchState(store, { loading });
},
setError: (error: string | null) => {
patchState(store, { error });
}
}))
);
// Services handle business logic before updating store
@Injectable({ providedIn: 'root' })
export class UserService {
constructor(private userStore: typeof GoodUserStore) {}
updateUser(userData: UserUpdateDto): Observable<User> {
// Business validation
if (!userData.name || userData.name.length < 3) {
return throwError(() => new Error('Name must be at least 3 characters'));
}
// Business transformation
const updatedUser = {
...userData,
name: userData.name.trim(),
updatedAt: new Date().toISOString()
};
// Update loading state
this.userStore.setLoading(true);
// API call
return this.http.put<User>(`/api/users/${userData.id}`, updatedUser).pipe(
tap(user => {
// State update happens after business logic
this.userStore.updateUser(user);
this.userStore.setLoading(false);
}),
catchError(error => {
this.userStore.setError(error.message);
this.userStore.setLoading(false);
return throwError(() => error);
})
);
}
}
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 9d ago First seen · 608 lines · 0 tokens per session scan A acb09e64adb7
600-angular-ngrx-signal-store is a cursor rule published in the GitHub repository JrPribs/SmarterStarter (2 stars, last pushed 1y ago), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 3,892 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other cursor rules, from other repositories
pages
Source: docs/agents/pages.md Regenerate: npm run agents:sync -w packages/openbridge-webcomponents -->.
shadcn-tailwind-guide
A guide to building new components with shadcn/ui and Tailwind CSS, a utility-based system for styling interfaces.
css-render-blocking-diagnosis
Cursor rule "css-render-blocking-diagnosis" from adobecom/da-express-milo, covering css render-blocking diagnosis & resolution, critical learning from 98 pagespeed achievement, primary diagnostic protocol, step 1: css blocking symptom recognition and step 2: css loading sequence audit.
frontend-architecture
Vite + React SPA architecture - directory layout, providers, bundle splitting. Tailwind styling in tailwind.mdc.
web-pages-e2e-test-maintenance
Keep web pages end-to-end coverage current.
tanstack-react-router_routing
TanStack Router: Routing.