stealthos-cli 0.1.0-alpha.2 → 0.1.0-alpha.4
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/ai/CONTRACT.md +110 -0
- package/ai/INDEX.md +203 -0
- package/ai/README.md +434 -0
- package/ai/ROUTER.md +288 -0
- package/ai/agents/README.md +103 -0
- package/ai/agents/architect.md +59 -0
- package/ai/agents/backend-engineer.md +62 -0
- package/ai/agents/founder.md +45 -0
- package/ai/agents/frontend-engineer.md +61 -0
- package/ai/agents/product-manager.md +56 -0
- package/ai/agents/qa-engineer.md +53 -0
- package/ai/agents/researcher.md +74 -0
- package/ai/agents/reviewer.md +73 -0
- package/ai/agents/security-engineer.md +59 -0
- package/ai/agents/sre-engineer.md +70 -0
- package/ai/agents/tech-lead.md +70 -0
- package/ai/architecture/README.md +35 -0
- package/ai/architecture/components.md +24 -0
- package/ai/architecture/containers.md +30 -0
- package/ai/architecture/event-flows.md +36 -0
- package/ai/architecture/sequence-diagrams.md +38 -0
- package/ai/architecture/system-context.md +46 -0
- package/ai/architecture/threat-modeling.md +40 -0
- package/ai/blueprints/README.md +67 -0
- package/ai/blueprints/_schema.json +40 -0
- package/ai/blueprints/ai-platform.json +28 -0
- package/ai/blueprints/crm.json +22 -0
- package/ai/blueprints/game.json +25 -0
- package/ai/blueprints/mobile.json +24 -0
- package/ai/blueprints/realtime.json +22 -0
- package/ai/blueprints/saas.json +25 -0
- package/ai/blueprints/telemetry.json +30 -0
- package/ai/blueprints/web.json +23 -0
- package/ai/bootstrap/discovery-questions.md +117 -0
- package/ai/bootstrap/dispatcher.md +85 -0
- package/ai/bootstrap/existing-project.md +191 -0
- package/ai/bootstrap/new-project.md +127 -0
- package/ai/bootstrap/tech-mapping.md +164 -0
- package/ai/clients/README.md +114 -0
- package/ai/clients/antigravity.md +125 -0
- package/ai/clients/claude-code.md +65 -0
- package/ai/clients/cline.md +69 -0
- package/ai/clients/codex-aider-cli.md +82 -0
- package/ai/clients/continue.md +67 -0
- package/ai/clients/copilot.md +49 -0
- package/ai/clients/cursor.md +81 -0
- package/ai/clients/snippets/mcp-absolute-paths.json +9 -0
- package/ai/clients/snippets/mcp-http.json +7 -0
- package/ai/clients/snippets/mcp-stdio.json +9 -0
- package/ai/clients/trae.md +69 -0
- package/ai/clients/windsurf.md +71 -0
- package/ai/core/pipeline/execution-engine.md +157 -0
- package/ai/engineering/README.md +32 -0
- package/ai/engineering/observability/incident-response.md +82 -0
- package/ai/evals/protocol-tests.md +150 -0
- package/ai/evolution/agent-evolution.md +161 -0
- package/ai/evolution/improvements.md +91 -0
- package/ai/evolution/learnings.md +49 -0
- package/ai/evolution/patterns-discovered.md +48 -0
- package/ai/execution/README.md +33 -0
- package/ai/execution/backlog.md +27 -0
- package/ai/execution/milestones.md +26 -0
- package/ai/execution/roadmap.md +30 -0
- package/ai/execution/sprint.md +42 -0
- package/ai/governance/README.md +34 -0
- package/ai/governance/architecture-principles.md +99 -0
- package/ai/governance/definition-of-done.md +88 -0
- package/ai/governance/definition-of-ready.md +69 -0
- package/ai/governance/engineering-principles.md +70 -0
- package/ai/governance/quality-gates.md +85 -0
- package/ai/governance/security-policies.md +84 -0
- package/ai/hooks/enforce-audit.ps1 +41 -0
- package/ai/hooks/enforce-audit.sh +39 -0
- package/ai/hooks/guard-edit.ps1 +182 -0
- package/ai/hooks/guard-edit.sh +161 -0
- package/ai/hooks/inject-os-reminder.ps1 +40 -0
- package/ai/hooks/inject-os-reminder.sh +16 -0
- package/ai/manifest.json +238 -0
- package/ai/memory/_detected-stack.json +33 -0
- package/ai/memory/_summary.md +49 -0
- package/ai/memory/archive/.gitkeep +3 -0
- package/ai/memory/completed-tasks.md +156 -0
- package/ai/memory/decisions.md +257 -0
- package/ai/memory/errors-and-solutions.md +41 -0
- package/ai/memory/known-issues.md +40 -0
- package/ai/memory/pending-tasks.md +37 -0
- package/ai/memory/project-context.md +67 -0
- package/ai/operating-system/architecture.md +54 -0
- package/ai/operating-system/coding-standards.md +84 -0
- package/ai/operating-system/folder-structure.md +126 -0
- package/ai/operating-system/performance-rules.md +86 -0
- package/ai/operating-system/quality-control.md +81 -0
- package/ai/operating-system/security-rules.md +91 -0
- package/ai/operating-system/workflow.md +86 -0
- package/ai/product/README.md +24 -0
- package/ai/product/business-rules.md +26 -0
- package/ai/product/personas.md +29 -0
- package/ai/product/user-journeys.md +30 -0
- package/ai/product/vision.md +35 -0
- package/ai/rules/behavior.md +45 -0
- package/ai/rules/do.md +47 -0
- package/ai/rules/dont.md +46 -0
- package/ai/rules/execution-flow.md +125 -0
- package/ai/rules/structural-constraints.md +59 -0
- package/ai/rules/structure-canon.md +116 -0
- package/ai/runtime.md +179 -0
- package/ai/scripts/detect-stack.ps1 +166 -0
- package/ai/scripts/detect-stack.sh +172 -0
- package/ai/scripts/init-ai-os.ps1 +170 -0
- package/ai/scripts/init-ai-os.sh +99 -0
- package/ai/scripts/lint-os.ps1 +99 -0
- package/ai/scripts/lint-os.sh +85 -0
- package/ai/scripts/start-os.ps1 +151 -0
- package/ai/scripts/start-os.sh +141 -0
- package/ai/server/README.md +105 -0
- package/ai/server/aios-server.mjs +2134 -0
- package/ai/server/package-lock.json +802 -0
- package/ai/server/package.json +31 -0
- package/ai/server/src/analyzer/graph-builder.ts +92 -0
- package/ai/server/src/analyzer/index.ts +191 -0
- package/ai/server/src/analyzer/module-mapper.ts +171 -0
- package/ai/server/src/analyzer/smell-detector.ts +54 -0
- package/ai/server/src/analyzer/stack-detector.ts +70 -0
- package/ai/server/src/index.ts +16 -0
- package/ai/server/src/packager/context-builder.ts +217 -0
- package/ai/server/src/packager/index.ts +3 -0
- package/ai/server/src/packager/memory-injector.ts +128 -0
- package/ai/server/src/packager/module-summarizer.ts +60 -0
- package/ai/server/src/packager/token-estimator.ts +26 -0
- package/ai/server/src/snapshot/index.ts +3 -0
- package/ai/server/src/snapshot/snapshot-creator.ts +206 -0
- package/ai/server/src/snapshot/snapshot-diff.ts +86 -0
- package/ai/server/src/snapshot/snapshot-restore.ts +14 -0
- package/ai/server/src/types.ts +94 -0
- package/ai/server/tsconfig.json +26 -0
- package/ai/skills/architecture-design.md +82 -0
- package/ai/skills/backend-engineering.md +57 -0
- package/ai/skills/database-design.md +76 -0
- package/ai/skills/frontend-engineering.md +63 -0
- package/ai/skills/performance.md +73 -0
- package/ai/skills/scalability.md +84 -0
- package/ai/skills/security.md +71 -0
- package/ai/skills/testing.md +77 -0
- package/ai/specs/ADR/ADR-0002-typescript-runtime.md +103 -0
- package/ai/specs/ADR/ADR-0004-runtime-orchestrator.md +94 -0
- package/ai/specs/ADR/ADR-0005-workflow-engine.md +105 -0
- package/ai/specs/ADR/ADR-0006-runtime-state.md +104 -0
- package/ai/specs/ADR/ADR-0007-state-compiler-drift-context-layers-artifact-index.md +82 -0
- package/ai/specs/ADR/ADR-0008-intent-runtime-discovery-branching.md +93 -0
- package/ai/specs/ADR/ADR-0009-confidence-system-maturity-tracking.md +113 -0
- package/ai/specs/ADR/ADR-0010-structural-architecture-standards.md +121 -0
- package/ai/specs/ADR/ADR-0011-mcp-prompts.md +86 -0
- package/ai/specs/ADR/ADR-0012-stealthos-hybrid-architecture.md +174 -0
- package/ai/specs/ADR/_TEMPLATE.md +60 -0
- package/ai/specs/BRD/_TEMPLATE.md +50 -0
- package/ai/specs/PRD/_TEMPLATE.md +72 -0
- package/ai/specs/README.md +43 -0
- package/ai/specs/RFC/RFC-0001-runtime-orchestrator.md +149 -0
- package/ai/specs/RFC/RFC-0002-runtime-orchestrator-extended.md +134 -0
- package/ai/specs/RFC/_TEMPLATE.md +61 -0
- package/ai/specs/RUNBOOKS/_TEMPLATE.md +68 -0
- package/ai/specs/SDD/_TEMPLATE.md +104 -0
- package/ai/specs/TASKS/_TEMPLATE.md +52 -0
- package/ai/tools/debugging.md +64 -0
- package/ai/tools/dependency-analysis.md +46 -0
- package/ai/tools/internet-research.md +42 -0
- package/ai/tools/mcp-discovery.md +44 -0
- package/ai/workflows/_schema.json +81 -0
- package/ai/workflows/init.json +148 -0
- package/ai/workflows/sync.json +71 -0
- package/ai/workflows/work.json +91 -0
- package/bin.cjs +7 -0
- package/package.json +9 -3
- package/scripts/bundle-ai.mjs +58 -0
- package/src/cli.mjs +1 -1
- package/src/commands/install.mjs +35 -11
- package/src/lib/resolve-source.mjs +27 -10
- package/stealthos +0 -2
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import type { ProjectState, SnapshotDiff, SnapshotManifest } from "../types.js";
|
|
5
|
+
|
|
6
|
+
export async function listSnapshots(
|
|
7
|
+
projectRoot: string,
|
|
8
|
+
): Promise<SnapshotManifest[]> {
|
|
9
|
+
const dir = join(projectRoot, ".ai", "snapshots");
|
|
10
|
+
if (!existsSync(dir)) return [];
|
|
11
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
12
|
+
const out: SnapshotManifest[] = [];
|
|
13
|
+
for (const e of entries) {
|
|
14
|
+
if (!e.isDirectory()) continue;
|
|
15
|
+
const manifestPath = join(dir, e.name, "manifest.json");
|
|
16
|
+
if (!existsSync(manifestPath)) continue;
|
|
17
|
+
try {
|
|
18
|
+
const txt = await readFile(manifestPath, "utf8");
|
|
19
|
+
out.push(JSON.parse(txt) as SnapshotManifest);
|
|
20
|
+
} catch {
|
|
21
|
+
// ignore malformed
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return out.sort((a, b) => (a.created_at < b.created_at ? 1 : -1));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function diffSnapshots(
|
|
28
|
+
projectRoot: string,
|
|
29
|
+
idA: string,
|
|
30
|
+
idB: string,
|
|
31
|
+
): Promise<SnapshotDiff> {
|
|
32
|
+
const dir = join(projectRoot, ".ai", "snapshots");
|
|
33
|
+
const a = await loadManifest(dir, idA);
|
|
34
|
+
const b = await loadManifest(dir, idB);
|
|
35
|
+
const stateA = await loadState(dir, idA);
|
|
36
|
+
const stateB = await loadState(dir, idB);
|
|
37
|
+
|
|
38
|
+
const filesA = new Set(Object.keys(a.file_hashes));
|
|
39
|
+
const filesB = new Set(Object.keys(b.file_hashes));
|
|
40
|
+
const files_added: string[] = [];
|
|
41
|
+
const files_removed: string[] = [];
|
|
42
|
+
const files_changed: string[] = [];
|
|
43
|
+
for (const f of filesB) {
|
|
44
|
+
if (!filesA.has(f)) files_added.push(f);
|
|
45
|
+
else if (a.file_hashes[f] !== b.file_hashes[f]) files_changed.push(f);
|
|
46
|
+
}
|
|
47
|
+
for (const f of filesA) {
|
|
48
|
+
if (!filesB.has(f)) files_removed.push(f);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const modulesA = new Set(stateA?.modules.map((m) => m.id) ?? []);
|
|
52
|
+
const modulesB = new Set(stateB?.modules.map((m) => m.id) ?? []);
|
|
53
|
+
const modules_added: string[] = [];
|
|
54
|
+
const modules_removed: string[] = [];
|
|
55
|
+
for (const m of modulesB) if (!modulesA.has(m)) modules_added.push(m);
|
|
56
|
+
for (const m of modulesA) if (!modulesB.has(m)) modules_removed.push(m);
|
|
57
|
+
|
|
58
|
+
const smells_delta =
|
|
59
|
+
(stateB?.smells.length ?? 0) - (stateA?.smells.length ?? 0);
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
a: idA,
|
|
63
|
+
b: idB,
|
|
64
|
+
files_added,
|
|
65
|
+
files_removed,
|
|
66
|
+
files_changed,
|
|
67
|
+
modules_added,
|
|
68
|
+
modules_removed,
|
|
69
|
+
decisions_added: 0,
|
|
70
|
+
smells_delta,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function loadManifest(snapDir: string, id: string): Promise<SnapshotManifest> {
|
|
75
|
+
const txt = await readFile(join(snapDir, id, "manifest.json"), "utf8");
|
|
76
|
+
return JSON.parse(txt) as SnapshotManifest;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function loadState(snapDir: string, id: string): Promise<ProjectState | null> {
|
|
80
|
+
try {
|
|
81
|
+
const txt = await readFile(join(snapDir, id, "state.json"), "utf8");
|
|
82
|
+
return JSON.parse(txt) as ProjectState;
|
|
83
|
+
} catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface RestoreOptions {
|
|
2
|
+
id: string;
|
|
3
|
+
dryRun?: boolean;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export async function restoreSnapshot(
|
|
7
|
+
_projectRoot: string,
|
|
8
|
+
_options: RestoreOptions,
|
|
9
|
+
): Promise<never> {
|
|
10
|
+
throw new Error(
|
|
11
|
+
"restore not implemented in v0.1 — snapshots are read-only in this version. " +
|
|
12
|
+
"Use snapshotList/snapshotDiff for inspection. Restore is on the v0.2 roadmap.",
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
export interface ProjectState {
|
|
2
|
+
version: string;
|
|
3
|
+
generated_at: string;
|
|
4
|
+
project_root: string;
|
|
5
|
+
stack: StackInfo;
|
|
6
|
+
modules: ModuleInfo[];
|
|
7
|
+
graph: DependencyGraph;
|
|
8
|
+
smells: Smell[];
|
|
9
|
+
stats: ProjectStats;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface StackInfo {
|
|
13
|
+
languages: string[];
|
|
14
|
+
frameworks: string[];
|
|
15
|
+
package_manager?: string;
|
|
16
|
+
databases?: string[];
|
|
17
|
+
test_frameworks?: string[];
|
|
18
|
+
linters?: string[];
|
|
19
|
+
ci_cd?: string[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ModuleInfo {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
path: string;
|
|
26
|
+
kind: "file" | "directory";
|
|
27
|
+
language: string;
|
|
28
|
+
size_lines: number;
|
|
29
|
+
imports: string[];
|
|
30
|
+
exports: string[];
|
|
31
|
+
responsibilities?: string[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface DependencyGraph {
|
|
35
|
+
nodes: string[];
|
|
36
|
+
edges: Array<{ from: string; to: string }>;
|
|
37
|
+
cycles: string[][];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface Smell {
|
|
41
|
+
kind:
|
|
42
|
+
| "circular_dependency"
|
|
43
|
+
| "large_file"
|
|
44
|
+
| "large_function"
|
|
45
|
+
| "dead_code"
|
|
46
|
+
| "todo_comment"
|
|
47
|
+
| "fixme_comment";
|
|
48
|
+
severity: "low" | "medium" | "high";
|
|
49
|
+
location: { file: string; line?: number };
|
|
50
|
+
message: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface ProjectStats {
|
|
54
|
+
total_files: number;
|
|
55
|
+
total_lines: number;
|
|
56
|
+
files_by_language: Record<string, number>;
|
|
57
|
+
largest_files: Array<{ path: string; lines: number }>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface ContextPackage {
|
|
61
|
+
intent: string;
|
|
62
|
+
generated_at: string;
|
|
63
|
+
estimated_tokens: number;
|
|
64
|
+
source_state_hash: string;
|
|
65
|
+
modules_included: string[];
|
|
66
|
+
markdown: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface SnapshotManifest {
|
|
70
|
+
id: string;
|
|
71
|
+
label: string;
|
|
72
|
+
created_at: string;
|
|
73
|
+
project_root: string;
|
|
74
|
+
state_file: string;
|
|
75
|
+
summary_file: string;
|
|
76
|
+
file_hashes: Record<string, string>;
|
|
77
|
+
stats: {
|
|
78
|
+
total_files_hashed: number;
|
|
79
|
+
modules: number;
|
|
80
|
+
smells: number;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface SnapshotDiff {
|
|
85
|
+
a: string;
|
|
86
|
+
b: string;
|
|
87
|
+
files_added: string[];
|
|
88
|
+
files_removed: string[];
|
|
89
|
+
files_changed: string[];
|
|
90
|
+
modules_added: string[];
|
|
91
|
+
modules_removed: string[];
|
|
92
|
+
decisions_added: number;
|
|
93
|
+
smells_delta: number;
|
|
94
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"noImplicitAny": true,
|
|
11
|
+
"strictNullChecks": true,
|
|
12
|
+
"noUnusedLocals": true,
|
|
13
|
+
"noUnusedParameters": true,
|
|
14
|
+
"esModuleInterop": true,
|
|
15
|
+
"allowSyntheticDefaultImports": true,
|
|
16
|
+
"forceConsistentCasingInFileNames": true,
|
|
17
|
+
"skipLibCheck": true,
|
|
18
|
+
"resolveJsonModule": true,
|
|
19
|
+
"declaration": false,
|
|
20
|
+
"sourceMap": false,
|
|
21
|
+
"isolatedModules": true,
|
|
22
|
+
"verbatimModuleSyntax": false
|
|
23
|
+
},
|
|
24
|
+
"include": ["src/**/*.ts"],
|
|
25
|
+
"exclude": ["node_modules", "dist"]
|
|
26
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
updated: 2026-05-14
|
|
4
|
+
tier: conditional
|
|
5
|
+
tokens: ~600
|
|
6
|
+
load: architecture, design_decision
|
|
7
|
+
triggers: arquitetura, architecture, design, padrão, microserviço, monorepo
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Skill: Architecture Design
|
|
11
|
+
|
|
12
|
+
## Princípios
|
|
13
|
+
|
|
14
|
+
- **YAGNI até dor real.** Não desenhe para escala que não existe.
|
|
15
|
+
- **Conway's Law.** A arquitetura tende a refletir a estrutura do time.
|
|
16
|
+
- **Reversibilidade.** Decisões caras devem ser tomadas tarde; baratas, cedo.
|
|
17
|
+
- **Trade-offs explícitos.** Toda decisão tem um custo — registrar qual.
|
|
18
|
+
|
|
19
|
+
## Quando reformular arquitetura
|
|
20
|
+
|
|
21
|
+
- A regra atual exige >3 hops para entender um fluxo simples.
|
|
22
|
+
- Mudanças simples exigem alterar >5 arquivos não relacionados.
|
|
23
|
+
- Acoplamento bloqueia testes em isolamento.
|
|
24
|
+
- Performance degradou e não há caminho claro de otimização.
|
|
25
|
+
|
|
26
|
+
## Camadas Recomendadas
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Presentation (UI / API handlers)
|
|
30
|
+
↓
|
|
31
|
+
Application (casos de uso, orquestração)
|
|
32
|
+
↓
|
|
33
|
+
Domain (entidades, regras de negócio puras)
|
|
34
|
+
↓
|
|
35
|
+
Infrastructure (DB, HTTP clients, filas)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- Dependências apontam para dentro (Clean Architecture / Hexagonal).
|
|
39
|
+
- Domain não conhece infrastructure.
|
|
40
|
+
|
|
41
|
+
## Decomposição
|
|
42
|
+
|
|
43
|
+
| Sintoma | Resposta |
|
|
44
|
+
|---|---|
|
|
45
|
+
| Módulo > 1000 linhas | Quebrar por responsabilidade |
|
|
46
|
+
| Duas equipes editando o mesmo arquivo | Quebrar por ownership |
|
|
47
|
+
| Tempo de build inaceitável | Quebrar em pacotes/módulos |
|
|
48
|
+
| Deploy acoplado entre features independentes | Considerar microserviço |
|
|
49
|
+
|
|
50
|
+
## Microserviços — usar quando
|
|
51
|
+
|
|
52
|
+
- Times independentes precisam liberar em cadências diferentes.
|
|
53
|
+
- Escala MUITO diferente entre componentes.
|
|
54
|
+
- Tolerância a falha precisa ser isolada.
|
|
55
|
+
|
|
56
|
+
## Microserviços — NÃO usar quando
|
|
57
|
+
|
|
58
|
+
- Time único, projeto novo.
|
|
59
|
+
- Transações atravessam serviços frequentemente.
|
|
60
|
+
- Latência inter-serviço é crítica.
|
|
61
|
+
|
|
62
|
+
## ADR (Architecture Decision Record)
|
|
63
|
+
|
|
64
|
+
Toda decisão arquitetural vai para `memory/decisions.md` no formato:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
## ADR-NNN — Título
|
|
68
|
+
Data: AAAA-MM-DD
|
|
69
|
+
Status: Proposto | Aceito | Substituído por ADR-NNN
|
|
70
|
+
|
|
71
|
+
### Contexto
|
|
72
|
+
O que motivou a decisão.
|
|
73
|
+
|
|
74
|
+
### Decisão
|
|
75
|
+
O que foi decidido.
|
|
76
|
+
|
|
77
|
+
### Consequências
|
|
78
|
+
Trade-offs aceitos.
|
|
79
|
+
|
|
80
|
+
### Alternativas consideradas
|
|
81
|
+
Por que NÃO foram escolhidas.
|
|
82
|
+
```
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
updated: 2026-05-14
|
|
4
|
+
tier: conditional
|
|
5
|
+
tokens: ~600
|
|
6
|
+
load: backend, api
|
|
7
|
+
triggers: endpoint, api, rest, graphql, controller, route, middleware
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Skill: Backend Engineering
|
|
11
|
+
|
|
12
|
+
## Princípios
|
|
13
|
+
|
|
14
|
+
- **Boundaries explícitos.** Entrada validada, saída tipada, erros mapeados.
|
|
15
|
+
- **Idempotência por padrão** em endpoints de escrita quando possível (chaves de idempotência).
|
|
16
|
+
- **Stateless services** > estado em memória. Estado vai para DB/cache/fila.
|
|
17
|
+
- **Falha rápida.** Validar input na borda, não em camadas profundas.
|
|
18
|
+
|
|
19
|
+
## API Design
|
|
20
|
+
|
|
21
|
+
- REST: substantivos + verbos HTTP. `POST /orders`, não `POST /createOrder`.
|
|
22
|
+
- Status codes corretos: 2xx sucesso, 4xx erro do cliente, 5xx erro do servidor.
|
|
23
|
+
- Versionamento explícito (`/v1/`, header, ou query) desde o dia 1.
|
|
24
|
+
- Paginação padronizada (`?limit=&cursor=`), nunca offset puro em datasets grandes.
|
|
25
|
+
- Erros estruturados: `{ "error": { "code": "...", "message": "...", "details": {...} } }`.
|
|
26
|
+
|
|
27
|
+
## Validação
|
|
28
|
+
|
|
29
|
+
- Schema na borda (Zod, Pydantic, JSON Schema).
|
|
30
|
+
- Reject unknown fields por padrão.
|
|
31
|
+
- Limites: tamanho de payload, profundidade de objetos, tamanho de strings.
|
|
32
|
+
|
|
33
|
+
## Persistência
|
|
34
|
+
|
|
35
|
+
- Transações para operações multi-step.
|
|
36
|
+
- Migrations versionadas, reversíveis quando possível.
|
|
37
|
+
- Não fazer queries em loop (N+1). Usar join/batch.
|
|
38
|
+
- Índices baseados em queries reais, não em palpite.
|
|
39
|
+
|
|
40
|
+
## Concorrência
|
|
41
|
+
|
|
42
|
+
- Locks otimistas (versionamento de linha) > pessimistas.
|
|
43
|
+
- Filas para trabalho async; nunca processar pesado dentro do request HTTP.
|
|
44
|
+
- Retry com backoff exponencial + jitter.
|
|
45
|
+
|
|
46
|
+
## Observabilidade
|
|
47
|
+
|
|
48
|
+
- Logs estruturados (JSON) com `request_id`, `user_id`, `trace_id`.
|
|
49
|
+
- Métricas: latência (p50/p95/p99), taxa de erro, throughput.
|
|
50
|
+
- Health checks: `/healthz` (vivo) e `/readyz` (pronto para tráfego).
|
|
51
|
+
|
|
52
|
+
## Erros comuns a evitar
|
|
53
|
+
|
|
54
|
+
- Vazar stack trace para o cliente.
|
|
55
|
+
- Esconder erros internos atrás de 200 OK.
|
|
56
|
+
- Tornar endpoints "convenientes" misturando 5 ações em um.
|
|
57
|
+
- Acoplar lógica de negócio à camada HTTP.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
updated: 2026-05-14
|
|
4
|
+
tier: conditional
|
|
5
|
+
tokens: ~600
|
|
6
|
+
load: database
|
|
7
|
+
triggers: db, database, banco, sql, query, migration, schema, índice, postgres, mysql, mongo
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Skill: Database Design
|
|
11
|
+
|
|
12
|
+
## Princípios
|
|
13
|
+
|
|
14
|
+
- **Modelar o domínio, não a UI.** A tela muda, o modelo deveria mudar menos.
|
|
15
|
+
- **Normalizar primeiro, desnormalizar com motivo.** 3NF como ponto de partida.
|
|
16
|
+
- **Constraints no banco**, não só na aplicação. NOT NULL, FK, UNIQUE, CHECK.
|
|
17
|
+
- **Migrations são código de produção.** Versionadas, revisadas, reversíveis.
|
|
18
|
+
|
|
19
|
+
## Escolha de DB
|
|
20
|
+
|
|
21
|
+
| Caso | Escolha típica |
|
|
22
|
+
|---|---|
|
|
23
|
+
| OLTP relacional, transações | PostgreSQL / MySQL |
|
|
24
|
+
| Documentos flexíveis | MongoDB (com cuidado) ou JSONB no Postgres |
|
|
25
|
+
| Cache / sessões | Redis |
|
|
26
|
+
| Full-text search | Elasticsearch / Meilisearch / Postgres FTS |
|
|
27
|
+
| Time-series | TimescaleDB / InfluxDB |
|
|
28
|
+
| Grafos | Neo4j (raro; geralmente Postgres com recursivo basta) |
|
|
29
|
+
|
|
30
|
+
## Schema
|
|
31
|
+
|
|
32
|
+
- IDs: UUID v7 ou ULID (ordenáveis) > UUID v4 > auto-increment.
|
|
33
|
+
- Timestamps: `created_at`, `updated_at` em UTC, sempre.
|
|
34
|
+
- Soft delete: `deleted_at` nullable; nunca remover linhas com histórico relevante.
|
|
35
|
+
- Enums em coluna com CHECK ou tabela de lookup; não string livre.
|
|
36
|
+
|
|
37
|
+
## Índices
|
|
38
|
+
|
|
39
|
+
- Em colunas usadas em `WHERE`, `JOIN`, `ORDER BY`.
|
|
40
|
+
- Composto na ordem de seletividade.
|
|
41
|
+
- Não indexar tudo — índice tem custo de escrita.
|
|
42
|
+
- Verificar uso real com `EXPLAIN ANALYZE` antes de criar.
|
|
43
|
+
|
|
44
|
+
## Migrations
|
|
45
|
+
|
|
46
|
+
- Uma migration = uma mudança lógica.
|
|
47
|
+
- Reversível quando possível (`up` + `down`).
|
|
48
|
+
- Adicionar coluna NOT NULL: 1) adicionar nullable + default 2) backfill 3) ALTER para NOT NULL.
|
|
49
|
+
- Lock-aware em tabelas grandes (PostgreSQL: `CREATE INDEX CONCURRENTLY`).
|
|
50
|
+
|
|
51
|
+
## Queries
|
|
52
|
+
|
|
53
|
+
- Parametrizadas SEMPRE (prevenção de SQL injection).
|
|
54
|
+
- Evitar `SELECT *` em produção — listar colunas.
|
|
55
|
+
- LIMIT obrigatório em queries que retornam lista.
|
|
56
|
+
- Detectar N+1 (logging de queries em dev; ORMs têm flag).
|
|
57
|
+
|
|
58
|
+
## Transações
|
|
59
|
+
|
|
60
|
+
- Tão curtas quanto possível.
|
|
61
|
+
- Não fazer I/O externo dentro de transação.
|
|
62
|
+
- Isolation level explícito quando importa (READ COMMITTED é default usual).
|
|
63
|
+
- Deadlock → ordenar acessos a recursos consistentemente.
|
|
64
|
+
|
|
65
|
+
## Backup e recovery
|
|
66
|
+
|
|
67
|
+
- Backup automatizado, retenção definida.
|
|
68
|
+
- TESTAR restore periodicamente — backup não testado é teoria.
|
|
69
|
+
- PITR (point-in-time recovery) em produção.
|
|
70
|
+
|
|
71
|
+
## Anti-padrões
|
|
72
|
+
|
|
73
|
+
- EAV (entity-attribute-value) genérico "para flexibilidade".
|
|
74
|
+
- Strings concatenadas para queries dinâmicas.
|
|
75
|
+
- `OFFSET N` em paginação de tabela grande (usar cursor).
|
|
76
|
+
- Múltiplas booleans para estados mutuamente exclusivos (usar enum).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
updated: 2026-05-14
|
|
4
|
+
tier: conditional
|
|
5
|
+
tokens: ~600
|
|
6
|
+
load: frontend, ui
|
|
7
|
+
triggers: ui, ux, component, react, vue, svelte, form, css, a11y
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Skill: Frontend Engineering
|
|
11
|
+
|
|
12
|
+
## Princípios
|
|
13
|
+
|
|
14
|
+
- **Componentes pequenos, com responsabilidade única.**
|
|
15
|
+
- **Estado o mais próximo possível de onde é usado.** Subir apenas quando compartilhado.
|
|
16
|
+
- **Acessibilidade não é opcional.** Roles, labels, contraste, navegação por teclado.
|
|
17
|
+
- **Performance percebida > performance bruta.** Skeleton, optimistic UI, lazy load.
|
|
18
|
+
|
|
19
|
+
## Estrutura
|
|
20
|
+
|
|
21
|
+
- Separar **UI puro** (apresentação) de **container** (estado/fetch).
|
|
22
|
+
- Hooks customizados para lógica reutilizável.
|
|
23
|
+
- Tipos em todo lugar (TS estrito; `any` é code smell).
|
|
24
|
+
|
|
25
|
+
## Estado
|
|
26
|
+
|
|
27
|
+
| Tipo | Onde mora |
|
|
28
|
+
|---|---|
|
|
29
|
+
| UI local (input, toggle) | `useState` no componente |
|
|
30
|
+
| Compartilhado entre poucos | Context ou prop drilling raso |
|
|
31
|
+
| Global cliente | Zustand, Jotai, Redux (escolher um) |
|
|
32
|
+
| Servidor / cache | React Query, SWR, Apollo |
|
|
33
|
+
| URL | Query params, route state |
|
|
34
|
+
|
|
35
|
+
## Renderização
|
|
36
|
+
|
|
37
|
+
- Evitar re-render desnecessário: memoização SÓ depois de medir, não preventivamente.
|
|
38
|
+
- Lista grande → virtualização (react-window, tanstack-virtual).
|
|
39
|
+
- Imagens → `srcset`, formatos modernos (WebP/AVIF), lazy loading.
|
|
40
|
+
|
|
41
|
+
## Forms
|
|
42
|
+
|
|
43
|
+
- Validação client-side imediata + server-side autoritativa.
|
|
44
|
+
- Estado controlado para forms complexos; uncontrolled para forms triviais.
|
|
45
|
+
- Disable do submit enquanto pending. Loading state visível.
|
|
46
|
+
|
|
47
|
+
## Estilo
|
|
48
|
+
|
|
49
|
+
- Token-based (cores, espaçamentos, tipografia) — nunca valor cru.
|
|
50
|
+
- Mobile-first.
|
|
51
|
+
- Dark mode considerado desde o design, não retrofit.
|
|
52
|
+
|
|
53
|
+
## Erros e Loading
|
|
54
|
+
|
|
55
|
+
- Toda chamada async tem 3 estados visuais: idle, loading, error.
|
|
56
|
+
- Mensagens de erro acionáveis ("Conexão falhou. Tentar novamente"), não genéricas ("Algo deu errado").
|
|
57
|
+
|
|
58
|
+
## Anti-padrões
|
|
59
|
+
|
|
60
|
+
- `useEffect` para sincronizar com estado externo quando `useMemo`/derivação resolveria.
|
|
61
|
+
- Re-fetch a cada navegação quando cache resolveria.
|
|
62
|
+
- DOM imperativo dentro de React (`document.querySelector`).
|
|
63
|
+
- CSS global que vaza em tudo.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
updated: 2026-05-14
|
|
4
|
+
tier: conditional
|
|
5
|
+
tokens: ~500
|
|
6
|
+
load: performance
|
|
7
|
+
triggers: lento, slow, performance, latência, p95, p99, gargalo, otimizar
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Skill: Performance
|
|
11
|
+
|
|
12
|
+
## Princípio
|
|
13
|
+
|
|
14
|
+
> Medir > supor. Otimizar > especular. Profiling > opinião.
|
|
15
|
+
|
|
16
|
+
## Ordem de Investigação
|
|
17
|
+
|
|
18
|
+
1. **Reproduzir** o problema com workload realista.
|
|
19
|
+
2. **Medir** com profiler (não estimar).
|
|
20
|
+
3. **Identificar** o hot path (geralmente <5% do código consome >90% do tempo).
|
|
21
|
+
4. **Atacar** a maior contribuição primeiro.
|
|
22
|
+
5. **Validar** com novo profile.
|
|
23
|
+
|
|
24
|
+
## Métricas-alvo (referência)
|
|
25
|
+
|
|
26
|
+
| Camada | Métrica | Alvo razoável |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| HTTP API | p99 latency | < 300ms |
|
|
29
|
+
| Frontend | LCP | < 2.5s |
|
|
30
|
+
| Frontend | INP | < 200ms |
|
|
31
|
+
| DB query | p99 | < 100ms |
|
|
32
|
+
| Background job | throughput | depende do volume |
|
|
33
|
+
|
|
34
|
+
## Padrões de otimização (em ordem de impacto)
|
|
35
|
+
|
|
36
|
+
### Algoritmo
|
|
37
|
+
- O(n²) → O(n log n) ou O(n) com hash.
|
|
38
|
+
- Eliminar trabalho redundante (memoize, cache).
|
|
39
|
+
|
|
40
|
+
### I/O
|
|
41
|
+
- Batch (N requests → 1).
|
|
42
|
+
- Paralelizar requests independentes.
|
|
43
|
+
- Streaming em vez de carregar tudo.
|
|
44
|
+
|
|
45
|
+
### Banco
|
|
46
|
+
- Índice em coluna usada em WHERE/ORDER BY.
|
|
47
|
+
- Evitar N+1 (JOIN ou batch fetch).
|
|
48
|
+
- Paginar resultados grandes.
|
|
49
|
+
- Read replicas para leitura pesada.
|
|
50
|
+
|
|
51
|
+
### Cache
|
|
52
|
+
- Cache na camada mais próxima do consumo.
|
|
53
|
+
- TTL adequado ao churn dos dados.
|
|
54
|
+
- Invalidação explícita > TTL ingênuo.
|
|
55
|
+
|
|
56
|
+
### Concorrência
|
|
57
|
+
- Async para I/O-bound.
|
|
58
|
+
- Pool de workers para CPU-bound.
|
|
59
|
+
- Backpressure para evitar buffer overflow.
|
|
60
|
+
|
|
61
|
+
## Anti-padrões
|
|
62
|
+
|
|
63
|
+
- "Otimização preventiva" sem profile.
|
|
64
|
+
- Cache em tudo (cache miss + invalidação fica pior que sem cache).
|
|
65
|
+
- Paralelizar antes de garantir thread-safety.
|
|
66
|
+
- Trocar lib por outra "mais rápida" sem medir o ganho real.
|
|
67
|
+
|
|
68
|
+
## Registro
|
|
69
|
+
|
|
70
|
+
Toda otimização não-trivial vai para `memory/decisions.md` com:
|
|
71
|
+
- Métrica antes / depois
|
|
72
|
+
- Como foi medida
|
|
73
|
+
- Custo (complexidade, manutenção)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.0.0
|
|
3
|
+
updated: 2026-05-14
|
|
4
|
+
tier: conditional
|
|
5
|
+
tokens: ~550
|
|
6
|
+
load: scaling
|
|
7
|
+
triggers: escalar, scale, scaling, tráfego, sharding, replicação, fila, queue
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Skill: Scalability
|
|
11
|
+
|
|
12
|
+
## Princípio
|
|
13
|
+
|
|
14
|
+
> Escala que não existe é problema imaginário. Mas decisões erradas cedo são caras de desfazer.
|
|
15
|
+
|
|
16
|
+
## Eixos de Escala
|
|
17
|
+
|
|
18
|
+
1. **Vertical** (mais CPU/RAM): rápido, finito, simples.
|
|
19
|
+
2. **Horizontal** (mais máquinas): exige stateless, harder, ilimitado em teoria.
|
|
20
|
+
3. **Funcional** (split por serviço/domínio): exige boundaries claros.
|
|
21
|
+
4. **Dados** (sharding/partitioning): último recurso para datasets gigantes.
|
|
22
|
+
|
|
23
|
+
Ordem recomendada: vertical → horizontal → funcional → dados.
|
|
24
|
+
|
|
25
|
+
## Stateless
|
|
26
|
+
|
|
27
|
+
- Estado fora do processo (Redis, DB, S3).
|
|
28
|
+
- Sessões via cookie assinado ou store externa, não memória do worker.
|
|
29
|
+
- Workers descartáveis a qualquer momento.
|
|
30
|
+
|
|
31
|
+
## Caching em Camadas
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Browser cache
|
|
35
|
+
↓
|
|
36
|
+
CDN (estáticos + edge cache)
|
|
37
|
+
↓
|
|
38
|
+
Reverse proxy cache (Varnish, Nginx)
|
|
39
|
+
↓
|
|
40
|
+
Application cache (Redis)
|
|
41
|
+
↓
|
|
42
|
+
DB query cache
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Cada camada absorve uma classe de carga. Comece pela mais barata (CDN) antes da mais cara (DB cache).
|
|
46
|
+
|
|
47
|
+
## Async + Filas
|
|
48
|
+
|
|
49
|
+
- Trabalho que não precisa ser síncrono → fila (SQS, RabbitMQ, Redis Streams).
|
|
50
|
+
- Worker pool processa em background.
|
|
51
|
+
- Webhook recebido → ack rápido + enfileira; nunca processar dentro do request.
|
|
52
|
+
|
|
53
|
+
## Read vs Write
|
|
54
|
+
|
|
55
|
+
- Leitura escala mais barato que escrita.
|
|
56
|
+
- Read replicas para leitura pesada.
|
|
57
|
+
- CQRS quando read e write têm modelos muito diferentes.
|
|
58
|
+
- Write: batch, async, particionar.
|
|
59
|
+
|
|
60
|
+
## Particionamento
|
|
61
|
+
|
|
62
|
+
- Por chave natural (user_id, tenant_id, region).
|
|
63
|
+
- Hot partition é o pior cenário — distribuição uniforme importa.
|
|
64
|
+
- Reparticionamento é doloroso → escolher chave com folga.
|
|
65
|
+
|
|
66
|
+
## Limites e Backpressure
|
|
67
|
+
|
|
68
|
+
- Rate limit por API key / IP / user.
|
|
69
|
+
- Circuit breaker em chamadas a serviços externos.
|
|
70
|
+
- Bulkhead: pools separados para cargas diferentes.
|
|
71
|
+
- Timeout em TODA chamada de rede.
|
|
72
|
+
|
|
73
|
+
## Observabilidade em Escala
|
|
74
|
+
|
|
75
|
+
- Sampling de traces (não trace 100% em alto throughput).
|
|
76
|
+
- Métricas agregadas + traces para amostras suspeitas.
|
|
77
|
+
- Alertas em sintomas (latência, erro) > em causas (CPU alto pode ser ok).
|
|
78
|
+
|
|
79
|
+
## Anti-padrões
|
|
80
|
+
|
|
81
|
+
- Microserviços antes de hitting limites do monolito.
|
|
82
|
+
- Sharding de DB antes de explorar índices/queries.
|
|
83
|
+
- Otimizar para 1000x do tráfego atual.
|
|
84
|
+
- Kafka + Kubernetes + 12 ferramentas para 100 usuários.
|