From f09d8d60f1e1fa69b51bedfdb9897d1bab2af254 Mon Sep 17 00:00:00 2001 From: Rhuan Barreto Date: Thu, 28 May 2026 20:16:38 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20add=20full=20Norwegian=20Bokm=C3=A5l=20?= =?UTF-8?q?(nb)=20locale=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Norwegian Bokmål as a third locale alongside English and pt-BR, covering all 56 documentation pages with translated content. Infrastructure changes: - Register nb locale in astro.config.mjs with sidebar group translations - Refactor HeadSEO.astro hreflang logic from hardcoded en/pt-BR to config-driven multi-locale array - Update generate-llms-full.ts to exclude nb/ from English-only output - Add og:locale:alternate for nb_NO and update JSON-LD inLanguage Governance updates: - Add "nb" to LOCALES in GEN-002-docs-i18n.rules.ts - Update GEN-002 ADR with Norwegian locale entry and Bokmål-specific translation guidelines Content: 56 new .mdx files under docs/src/content/docs/nb/ mirroring the full English site structure (getting-started, concepts, guides, reference, examples, studies). Signed-off-by: Rhuan Barreto --- .archgate/adrs/GEN-002-docs-i18n.md | 10 +- .archgate/adrs/GEN-002-docs-i18n.rules.ts | 2 +- docs/astro.config.mjs | 20 +- docs/scripts/generate-llms-full.ts | 8 +- docs/src/components/HeadSEO.astro | 25 +- docs/src/content/docs/nb/concepts/adrs.mdx | 183 ++++++++++ docs/src/content/docs/nb/concepts/domains.mdx | 133 +++++++ docs/src/content/docs/nb/concepts/rules.mdx | 170 +++++++++ .../nb/examples/clean-architecture-layers.mdx | 128 +++++++ .../docs/nb/examples/common-rule-patterns.mdx | 60 ++++ .../docs/nb/examples/component-pairing.mdx | 82 +++++ .../nb/examples/database-audit-fields.mdx | 117 +++++++ .../docs/nb/examples/kebab-case-filenames.mdx | 82 +++++ .../nb/examples/license-compatibility.mdx | 135 ++++++++ .../docs/nb/examples/max-file-length.mdx | 67 ++++ .../docs/nb/examples/monorepo-task-runner.mdx | 111 ++++++ .../docs/nb/examples/no-banned-api.mdx | 110 ++++++ .../docs/nb/examples/no-banned-imports.mdx | 83 +++++ .../docs/nb/examples/no-barrel-files.mdx | 106 ++++++ .../docs/nb/examples/no-emoji-in-output.mdx | 99 ++++++ .../docs/nb/examples/no-todo-comments.mdx | 61 ++++ .../docs/nb/examples/no-unapproved-deps.mdx | 77 +++++ .../docs/nb/examples/openapi-routes.mdx | 108 ++++++ .../examples/page-component-constraints.mdx | 117 +++++++ .../nb/examples/required-export-pattern.mdx | 82 +++++ .../docs/nb/examples/spdx-license-headers.mdx | 99 ++++++ .../docs/nb/examples/test-file-coverage.mdx | 82 +++++ .../docs/nb/examples/version-catalog.mdx | 143 ++++++++ .../docs/nb/examples/wrapper-enforcement.mdx | 79 +++++ .../docs/nb/getting-started/installation.mdx | 161 +++++++++ .../docs/nb/getting-started/quick-start.mdx | 146 ++++++++ .../content/docs/nb/guides/ci-integration.mdx | 291 ++++++++++++++++ .../docs/nb/guides/claude-code-plugin.mdx | 153 ++++++++ .../docs/nb/guides/copilot-cli-plugin.mdx | 129 +++++++ .../docs/nb/guides/cursor-integration.mdx | 161 +++++++++ .../content/docs/nb/guides/importing-adrs.mdx | 131 +++++++ .../docs/nb/guides/opencode-integration.mdx | 138 ++++++++ .../docs/nb/guides/pre-commit-hooks.mdx | 92 +++++ docs/src/content/docs/nb/guides/security.mdx | 144 ++++++++ .../content/docs/nb/guides/vscode-plugin.mdx | 167 +++++++++ .../content/docs/nb/guides/writing-adrs.mdx | 327 ++++++++++++++++++ .../content/docs/nb/guides/writing-rules.mdx | 308 +++++++++++++++++ docs/src/content/docs/nb/index.mdx | 128 +++++++ .../content/docs/nb/reference/adr-schema.mdx | 309 +++++++++++++++++ .../src/content/docs/nb/reference/cli/adr.mdx | 321 +++++++++++++++++ .../content/docs/nb/reference/cli/check.mdx | 175 ++++++++++ .../content/docs/nb/reference/cli/clean.mdx | 22 ++ .../content/docs/nb/reference/cli/doctor.mdx | 62 ++++ .../content/docs/nb/reference/cli/index.mdx | 33 ++ .../content/docs/nb/reference/cli/init.mdx | 61 ++++ .../content/docs/nb/reference/cli/login.mdx | 124 +++++++ .../content/docs/nb/reference/cli/plugin.mdx | 85 +++++ .../docs/nb/reference/cli/review-context.mdx | 25 ++ .../docs/nb/reference/cli/session-context.mdx | 99 ++++++ .../docs/nb/reference/cli/telemetry.mdx | 74 ++++ .../content/docs/nb/reference/cli/upgrade.mdx | 72 ++++ .../docs/nb/reference/configuration.mdx | 112 ++++++ .../docs/nb/reference/privacy-policy.mdx | 62 ++++ .../content/docs/nb/reference/rule-api.mdx | 310 +++++++++++++++++ .../content/docs/nb/reference/telemetry.mdx | 148 ++++++++ ...sentry-pr-review-friction-and-adr-pack.mdx | 25 ++ 61 files changed, 7160 insertions(+), 14 deletions(-) create mode 100644 docs/src/content/docs/nb/concepts/adrs.mdx create mode 100644 docs/src/content/docs/nb/concepts/domains.mdx create mode 100644 docs/src/content/docs/nb/concepts/rules.mdx create mode 100644 docs/src/content/docs/nb/examples/clean-architecture-layers.mdx create mode 100644 docs/src/content/docs/nb/examples/common-rule-patterns.mdx create mode 100644 docs/src/content/docs/nb/examples/component-pairing.mdx create mode 100644 docs/src/content/docs/nb/examples/database-audit-fields.mdx create mode 100644 docs/src/content/docs/nb/examples/kebab-case-filenames.mdx create mode 100644 docs/src/content/docs/nb/examples/license-compatibility.mdx create mode 100644 docs/src/content/docs/nb/examples/max-file-length.mdx create mode 100644 docs/src/content/docs/nb/examples/monorepo-task-runner.mdx create mode 100644 docs/src/content/docs/nb/examples/no-banned-api.mdx create mode 100644 docs/src/content/docs/nb/examples/no-banned-imports.mdx create mode 100644 docs/src/content/docs/nb/examples/no-barrel-files.mdx create mode 100644 docs/src/content/docs/nb/examples/no-emoji-in-output.mdx create mode 100644 docs/src/content/docs/nb/examples/no-todo-comments.mdx create mode 100644 docs/src/content/docs/nb/examples/no-unapproved-deps.mdx create mode 100644 docs/src/content/docs/nb/examples/openapi-routes.mdx create mode 100644 docs/src/content/docs/nb/examples/page-component-constraints.mdx create mode 100644 docs/src/content/docs/nb/examples/required-export-pattern.mdx create mode 100644 docs/src/content/docs/nb/examples/spdx-license-headers.mdx create mode 100644 docs/src/content/docs/nb/examples/test-file-coverage.mdx create mode 100644 docs/src/content/docs/nb/examples/version-catalog.mdx create mode 100644 docs/src/content/docs/nb/examples/wrapper-enforcement.mdx create mode 100644 docs/src/content/docs/nb/getting-started/installation.mdx create mode 100644 docs/src/content/docs/nb/getting-started/quick-start.mdx create mode 100644 docs/src/content/docs/nb/guides/ci-integration.mdx create mode 100644 docs/src/content/docs/nb/guides/claude-code-plugin.mdx create mode 100644 docs/src/content/docs/nb/guides/copilot-cli-plugin.mdx create mode 100644 docs/src/content/docs/nb/guides/cursor-integration.mdx create mode 100644 docs/src/content/docs/nb/guides/importing-adrs.mdx create mode 100644 docs/src/content/docs/nb/guides/opencode-integration.mdx create mode 100644 docs/src/content/docs/nb/guides/pre-commit-hooks.mdx create mode 100644 docs/src/content/docs/nb/guides/security.mdx create mode 100644 docs/src/content/docs/nb/guides/vscode-plugin.mdx create mode 100644 docs/src/content/docs/nb/guides/writing-adrs.mdx create mode 100644 docs/src/content/docs/nb/guides/writing-rules.mdx create mode 100644 docs/src/content/docs/nb/index.mdx create mode 100644 docs/src/content/docs/nb/reference/adr-schema.mdx create mode 100644 docs/src/content/docs/nb/reference/cli/adr.mdx create mode 100644 docs/src/content/docs/nb/reference/cli/check.mdx create mode 100644 docs/src/content/docs/nb/reference/cli/clean.mdx create mode 100644 docs/src/content/docs/nb/reference/cli/doctor.mdx create mode 100644 docs/src/content/docs/nb/reference/cli/index.mdx create mode 100644 docs/src/content/docs/nb/reference/cli/init.mdx create mode 100644 docs/src/content/docs/nb/reference/cli/login.mdx create mode 100644 docs/src/content/docs/nb/reference/cli/plugin.mdx create mode 100644 docs/src/content/docs/nb/reference/cli/review-context.mdx create mode 100644 docs/src/content/docs/nb/reference/cli/session-context.mdx create mode 100644 docs/src/content/docs/nb/reference/cli/telemetry.mdx create mode 100644 docs/src/content/docs/nb/reference/cli/upgrade.mdx create mode 100644 docs/src/content/docs/nb/reference/configuration.mdx create mode 100644 docs/src/content/docs/nb/reference/privacy-policy.mdx create mode 100644 docs/src/content/docs/nb/reference/rule-api.mdx create mode 100644 docs/src/content/docs/nb/reference/telemetry.mdx create mode 100644 docs/src/content/docs/nb/studies/sentry-pr-review-friction-and-adr-pack.mdx diff --git a/.archgate/adrs/GEN-002-docs-i18n.md b/.archgate/adrs/GEN-002-docs-i18n.md index 62dd6ba6..cf61309c 100644 --- a/.archgate/adrs/GEN-002-docs-i18n.md +++ b/.archgate/adrs/GEN-002-docs-i18n.md @@ -14,7 +14,7 @@ Archgate targets a global developer audience, but the documentation site ([GEN-0 2. **Community growth is limited** -- Open-source adoption in non-English markets depends on accessible documentation 3. **Translation efforts lack governance** -- Without structure, translations drift from the source language, pages get added without corresponding translations, and stale translations mislead users -Brazilian Portuguese is the first translation target. The Starlight documentation framework already provides built-in i18n support with locale-based routing, automatic language switching, and fallback behavior. +Brazilian Portuguese and Norwegian Bokmål are translation targets. The Starlight documentation framework already provides built-in i18n support with locale-based routing, automatic language switching, and fallback behavior. **Alternatives considered:** @@ -56,6 +56,7 @@ The sidebar in `docs/astro.config.mjs` does NOT need per-locale duplication. Sta | ---------- | ------------------ | ---------- | ---------- | | `root` | English | `en` | _(none)_ | | `pt-br` | Portugues (Brasil) | `pt-BR` | `/pt-br/` | +| `nb` | Norsk (Bokmål) | `nb` | `/nb/` | ## Do's and Don'ts @@ -71,6 +72,7 @@ The sidebar in `docs/astro.config.mjs` does NOT need per-locale duplication. Sta - **DO** preserve Starlight component import statements identically in translated files - **DO** update translations in the same PR that modifies the English source content - **DO** use correct diacritical marks (accents) in Portuguese translations -- ã, ç, é, í, ó, ú, â, ê, ô, à are mandatory. Never write unaccented Portuguese (e.g., `não` not `nao`, `código` not `codigo`, `você` not `voce`, `segurança` not `seguranca`, `funções` not `funcoes`) +- **DO** use Norwegian Bokmål (not Nynorsk) for Norwegian translations, with the informal "du" form and correct Norwegian characters (æ, ø, å) - **DO** update the `LOCALES` constant in the companion rules file when adding a new language ### Don't @@ -88,7 +90,7 @@ The sidebar in `docs/astro.config.mjs` does NOT need per-locale duplication. Sta ### Positive -- **Broader international audience** -- Brazilian Portuguese speakers can read documentation in their language, lowering the barrier to adoption +- **Broader international audience** -- Brazilian Portuguese and Norwegian speakers can read documentation in their language, lowering the barrier to adoption - **Zero breaking changes** -- The root locale pattern preserves all existing English URLs; no redirects or link updates needed - **Automatic language switching** -- Starlight renders a language switcher in the navigation with no custom code - **Automated parity enforcement** -- The companion rule catches missing translations and orphan files before they reach production @@ -96,9 +98,9 @@ The sidebar in `docs/astro.config.mjs` does NOT need per-locale duplication. Sta ### Negative -- **Doubled content maintenance** -- Every content PR must update both English and Portuguese files, increasing review scope +- **Multiplied content maintenance** -- Every content PR must update English, Portuguese, and Norwegian files, increasing review scope - **Translation quality depends on reviewers** -- The automated rule only checks file existence, not translation accuracy or completeness -- **Contributor friction** -- Contributors who only speak English must still account for the Portuguese translation (even if they only add a placeholder file) +- **Contributor friction** -- Contributors who only speak English must still account for all locale translations (even if they only add a placeholder file) ### Risks diff --git a/.archgate/adrs/GEN-002-docs-i18n.rules.ts b/.archgate/adrs/GEN-002-docs-i18n.rules.ts index 21bf18e8..5d59d0c8 100644 --- a/.archgate/adrs/GEN-002-docs-i18n.rules.ts +++ b/.archgate/adrs/GEN-002-docs-i18n.rules.ts @@ -5,7 +5,7 @@ * When adding a new language, add its directory name here AND in * docs/astro.config.mjs under the `locales` key. */ -const LOCALES = ["pt-br"]; +const LOCALES = ["pt-br", "nb"]; const CONTENT_ROOT = "docs/src/content/docs"; diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index ffb53847..ed7bb9d0 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -10,6 +10,7 @@ export default defineConfig({ locales: { root: { label: "English", lang: "en" }, "pt-br": { label: "Português (Brasil)", lang: "pt-BR" }, + nb: { label: "Norsk (Bokmål)", lang: "nb" }, }, description: "Enforce Architecture Decision Records as executable rules — for both humans and AI agents.", @@ -112,6 +113,10 @@ export default defineConfig({ tag: "meta", attrs: { property: "og:locale:alternate", content: "pt_BR" }, }, + { + tag: "meta", + attrs: { property: "og:locale:alternate", content: "nb_NO" }, + }, { tag: "meta", attrs: { @@ -163,7 +168,7 @@ export default defineConfig({ url: "https://cli.archgate.dev", description: "Documentation for Archgate — enforce Architecture Decision Records as executable TypeScript rules for automated code governance.", - inLanguage: ["en", "pt-BR"], + inLanguage: ["en", "pt-BR", "nb"], }), }, // ── JSON-LD: SoftwareApplication ────────────────────────── @@ -195,6 +200,7 @@ export default defineConfig({ sidebar: [ { label: "Getting Started", + translations: { "pt-BR": "Primeiros Passos", nb: "Kom i gang" }, items: [ { label: "Installation", slug: "getting-started/installation" }, { label: "Quick Start", slug: "getting-started/quick-start" }, @@ -202,6 +208,10 @@ export default defineConfig({ }, { label: "Core Concepts", + translations: { + "pt-BR": "Conceitos Fundamentais", + nb: "Grunnleggende konsepter", + }, items: [ { label: "Architecture Decision Records", slug: "concepts/adrs" }, { label: "Rules", slug: "concepts/rules" }, @@ -210,6 +220,7 @@ export default defineConfig({ }, { label: "Guides", + translations: { "pt-BR": "Guias", nb: "Guider" }, items: [ { label: "Writing ADRs", slug: "guides/writing-adrs" }, { label: "Writing Rules", slug: "guides/writing-rules" }, @@ -229,9 +240,14 @@ export default defineConfig({ }, { label: "Reference", + translations: { "pt-BR": "Referência", nb: "Referanse" }, items: [ { label: "CLI Commands", + translations: { + "pt-BR": "Comandos da CLI", + nb: "CLI-kommandoer", + }, items: [ { label: "Overview", slug: "reference/cli" }, { label: "archgate login", slug: "reference/cli/login" }, @@ -261,11 +277,13 @@ export default defineConfig({ }, { label: "Examples", + translations: { "pt-BR": "Exemplos", nb: "Eksempler" }, collapsed: true, items: [{ autogenerate: { directory: "examples", collapsed: true } }], }, { label: "Studies", + translations: { "pt-BR": "Estudos", nb: "Studier" }, collapsed: true, items: [{ autogenerate: { directory: "studies", collapsed: true } }], }, diff --git a/docs/scripts/generate-llms-full.ts b/docs/scripts/generate-llms-full.ts index 82f36ea1..86d3450a 100644 --- a/docs/scripts/generate-llms-full.ts +++ b/docs/scripts/generate-llms-full.ts @@ -8,7 +8,7 @@ * bun run docs/scripts/generate-llms-full.ts */ import { readFileSync, writeFileSync, readdirSync, statSync } from "node:fs"; -import { join, relative } from "node:path"; +import { join, relative, sep } from "node:path"; const docsDir = join(import.meta.dirname, "..", "src", "content", "docs"); const outputPath = join(import.meta.dirname, "..", "public", "llms-full.txt"); @@ -110,8 +110,10 @@ for (const section of sections) { continue; // section directory may not exist } - // Skip pt-br files — English only - const enFiles = files.filter((f) => !f.includes("pt-br")); + // Skip translated locale files — English only + const enFiles = files.filter( + (f) => !f.includes(`${sep}pt-br${sep}`) && !f.includes(`${sep}nb${sep}`) + ); if (enFiles.length === 0) continue; for (const file of enFiles) { diff --git a/docs/src/components/HeadSEO.astro b/docs/src/components/HeadSEO.astro index 860a32d0..6a15f884 100644 --- a/docs/src/components/HeadSEO.astro +++ b/docs/src/components/HeadSEO.astro @@ -24,12 +24,27 @@ const description = hasRoute ? route.entry.data.description : undefined; const template = hasRoute ? route.entry.data.template : undefined; // ── hreflang alternate links ───────────────────────────────────── -// Map between English and pt-BR pages for search engine language targeting. -const isPtBr = pathname.startsWith("/pt-br/"); -const enPath = isPtBr ? pathname.replace(/^\/pt-br\//u, "/") : pathname; -const ptBrPath = isPtBr ? pathname : `/pt-br${pathname}`; +// Map between all locale variants for search engine language targeting. +const LOCALE_PREFIXES = ["pt-br", "nb"] as const; +const LOCALE_HREFLANG: Record = { + "pt-br": "pt-BR", + nb: "nb", +}; + +// Strip any locale prefix to get the base English path. +let enPath = pathname; +for (const prefix of LOCALE_PREFIXES) { + if (pathname.startsWith(`/${prefix}/`)) { + enPath = pathname.replace(new RegExp(`^/${prefix}/`, "u"), "/"); + break; + } +} + const enUrl = `${siteUrl}${enPath}`; -const ptBrUrl = `${siteUrl}${ptBrPath}`; +const localeAlternates = LOCALE_PREFIXES.map((prefix) => ({ + hreflang: LOCALE_HREFLANG[prefix], + href: `${siteUrl}/${prefix}${enPath}`, +})); /** * Convert a URL path segment into a human-readable breadcrumb label. diff --git a/docs/src/content/docs/nb/concepts/adrs.mdx b/docs/src/content/docs/nb/concepts/adrs.mdx new file mode 100644 index 00000000..47848e52 --- /dev/null +++ b/docs/src/content/docs/nb/concepts/adrs.mdx @@ -0,0 +1,183 @@ +--- +title: Architecture Decision Records +description: Lær hvordan Architecture Decision Records (ADR-er) fungerer i Archgate som både lesbar dokumentasjon og maskinelt kjørbare samsvarregler. +--- + +En Architecture Decision Record (ADR) er et kort dokument som fanger opp en enkelt arkitekturbeslutning sammen med dens kontekst og konsekvenser. ADR-er svarer på spørsmålet: _hvorfor_ ble denne beslutningen tatt, og _hva_ er avveiningene? + +Archgate bygger videre på ADR-konseptet ved å gi hver beslutning to uttrykk: et **dokument** som mennesker og AI-agenter leser, og en valgfri **regelfil** som maskiner kjører. + +## To uttrykk for en ADR + +### ADR som dokument + +Dokumentet er en Markdown-fil med YAML frontmatter lagret i `.archgate/adrs/`. Det beskriver beslutningen i vanlig språk: hvilket problem det løser, hvilke alternativer som ble vurdert, hva teamet besluttet, og hvilke konsekvenser som følger. + +Både mennesker og AI-agenter bruker dette dokumentet. Når en AI-kodeagent skal skrive kode, leser den de relevante ADR-ene for å forstå begrensningene før den genererer noe. + +:::tip[Automatiser dette med editorplugins] +Med [Claude Code](/guides/claude-code-plugin/)- eller [Cursor](/guides/cursor-integration/)-pluginen leser AI-agenten din de gjeldende ADR-ene automatisk før hver kodeoppgave -- ingen manuell kopiering og liming inn i ledetekster. [Registrer deg for beta-tilgang](https://plugins.archgate.dev). +::: + +### ADR som regler + +Regelfilen er en tilhørende `.rules.ts`-fil som eksporterer et vanlig objekt typet med `satisfies RuleSet`. Når du kjører `archgate check`, laster CLI-en inn hver ADR som har `rules: true` i frontmatteren, kjører den tilhørende regelfilen mot kodebasen din og rapporterer eventuelle brudd med filstier og linjenumre. + +Ikke alle ADR-er trenger regler. Noen beslutninger håndheves best kun gjennom kodegjennomgang. Sett `rules: false` når ingen automatisert sjekk er praktisk. + +## Navnekonvensjon for filer + +ADR-filer følger en streng navnekonvensjon som koder domeneprefiks, sekvensnummer og en lesbar slug: + +``` +{PREFIX}-{NNN}-{slug}.md # The document +{PREFIX}-{NNN}-{slug}.rules.ts # The companion rules file (optional) +``` + +For eksempel vil en ADR i arkitekturdomenet om kommandostruktur gi: + +``` +ARCH-001-command-structure.md +ARCH-001-command-structure.rules.ts +``` + +Prefikset kommer fra ADR-ens domene (se [Domener](/concepts/domains/)). Sekvensnummeret er nullpolstret til tre sifre og auto-inkrementert av `archgate adr create`. + +## YAML Frontmatter + +Hvert ADR-dokument starter med en YAML frontmatter-blokk mellom `---`-skilletegn. Frontmatteren er de maskinlesbare metadataene som Archgate bruker til å laste, filtrere og avgrense regler. + +| Felt | Type | Påkrevd | Beskrivelse | +| ------------------ | ------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | string | Ja | Unik identifikator som `ARCH-001` eller `BE-003` | +| `title` | string | Ja | Lesbar tittel for beslutningen | +| `domain` | string | Ja | Registrert domenenavn. Innebygde: `backend`, `frontend`, `data`, `architecture`, `general`. [Egendefinerte domener](/concepts/domains/#custom-domains) kan legges til via `archgate adr domain add`. | +| `rules` | boolean | Ja | Om denne ADR-en har en tilhørende `.rules.ts`-fil | +| `files` | string array | Nei | Glob-mønstre som avgrenser hvilke filer reglene sjekker | +| `respectGitignore` | boolean | Nei | Om filer i `.gitignore` skal filtreres bort. Standard er `true`. | + +Feltet `files` er valgfritt. Når det er tilstede, begrenser det regelkjøring til kun filene som matcher de angitte globbene. Når det er fraværende, kjøres regler mot alle prosjektfiler. For eksempel begrenser `files: ["src/commands/**/*.ts"]` sjekker til kun kommandofiler. + +Feltet `respectGitignore` er også valgfritt. Som standard ekskluderes filer oppført i `.gitignore` fra alle filsøkeoperasjoner (`ctx.scopedFiles`, `ctx.glob()`, `ctx.grepFiles()`). Sett `respectGitignore: false` for å inkludere git-ignorerte filer -- nyttig for regler som trenger å inspisere byggeresultater eller genererte filer. + +## ADR-seksjonene + +Etter frontmatteren følger ADR-kroppen en standardisert seksjonsstruktur: + +### Context + +Beskriver problemet eller situasjonen som utløste beslutningen. Inkluder alternativer som ble vurdert og hvorfor de ble forkastet. + +### Decision + +Fastslår selve beslutningen og dens viktigste begrensninger. Dette er seksjonen AI-agenter legger mest merke til når de bestemmer hvordan de skal skrive kode. + +### Do's and Don'ts + +Konkret, handlingsrettet veiledning delt i to underseksjoner. Fungerer som en hurtigreferanse-sjekkliste for utviklere og AI-agenter. + +### Consequences + +Delt i tre underseksjoner: + +- **Positive** -- fordeler beslutningen gir +- **Negative** -- avveininger som aksepteres +- **Risks** -- ting som kan gå galt og hvordan de kan begrenses + +### Compliance and Enforcement + +Beskriver hvordan beslutningen håndheves, både gjennom automatiserte regler (med regel-ID-er og alvorlighetsgrader) og manuelle gjennomgangssjekklister. + +### References + +Lenker til relaterte ADR-er, ekstern dokumentasjon eller designdokumenter. + +## Komplett eksempel + +Nedenfor er en fullstendig ADR med frontmatter og alle seksjoner fylt ut. + +```markdown +--- +id: BE-001 +title: API Response Envelope +domain: backend +rules: true +files: ["src/api/**/*.ts"] +--- + +## Context + +The API returns data in inconsistent shapes across endpoints. Some endpoints +wrap responses in `{ data, error }`, others return raw arrays, and error +responses vary between plain strings and structured objects. + +**Alternatives considered:** + +- **No envelope** -- Return raw data and rely on HTTP status codes alone. + Simple, but clients cannot distinguish between "the endpoint returned an + empty array" and "the endpoint errored." +- **GraphQL-style errors array** -- Use `{ data, errors: [] }`. Flexible + but adds complexity for simple REST endpoints. + +The chosen envelope balances consistency with simplicity. + +## Decision + +All API endpoints MUST return responses in a standard envelope: + +- Success: `{ data: T }` +- Error: `{ error: { code: string, message: string } }` + +HTTP status codes remain the primary success/failure signal. The envelope +provides a predictable structure for clients to parse. + +## Do's and Don'ts + +### Do + +- Wrap all API responses in the `{ data }` or `{ error }` envelope +- Use specific error codes (e.g., `VALIDATION_FAILED`, `NOT_FOUND`) +- Include the HTTP status code that matches the error semantics + +### Don't + +- Don't return raw arrays or primitives from API endpoints +- Don't nest envelopes (no `{ data: { data: ... } }`) +- Don't put stack traces in the error message field + +## Consequences + +### Positive + +- Clients can parse every response with the same logic +- Error responses always have a machine-readable code for programmatic handling + +### Negative + +- Adds a small amount of boilerplate to every endpoint handler +- Slightly larger payloads due to the wrapper object + +### Risks + +- Developers may forget the envelope on new endpoints. Mitigated by + the automated rule that scans for non-conforming return statements. + +## Compliance and Enforcement + +### Automated Enforcement + +- **Archgate rule** BE-001/response-envelope: Scans API handler files for + return statements and verifies they use the envelope helper. Severity: error. + +### Manual Enforcement + +Code reviewers MUST verify: + +1. New API endpoints use the response envelope +2. Error responses include a specific error code, not a generic message + +## References + +- [Microsoft REST API Guidelines](https://github.com/microsoft/api-guidelines) +- [ARCH-002 -- Error Handling](./ARCH-002-error-handling.md) +``` diff --git a/docs/src/content/docs/nb/concepts/domains.mdx b/docs/src/content/docs/nb/concepts/domains.mdx new file mode 100644 index 00000000..f7da5113 --- /dev/null +++ b/docs/src/content/docs/nb/concepts/domains.mdx @@ -0,0 +1,133 @@ +--- +title: Domener +description: Organiser Architecture Decision Records etter domene i Archgate. Grupper ADR-er etter arkitektur, testing, sikkerhet eller enhver egendefinert kategori for målrettet styring. +--- + +Domener er kategorier som grupperer relaterte ADR-er. Hver ADR tilhører nøyaktig ett domene, og domenet bestemmer prefikset som brukes i ADR-ens identifikator. + +## Innebygde domener + +Archgate leveres med fem innebygde domener. Hvert har et kort prefiks som vises i starten av hver ADR-ID i det domenet. + +| Domene | Prefiks | Brukes til | +| -------------- | ------- | ----------------------------------------------------- | +| `backend` | `BE` | Server-side-logikk, API-er, databaser, tjenester | +| `frontend` | `FE` | UI-komponenter, klient-side-logikk, stilmønstre | +| `data` | `DATA` | Datamodeller, skjemaer, pipelines, lagringsstrategier | +| `architecture` | `ARCH` | Tverrgående arkitekturbeslutninger | +| `general` | `GEN` | Generelle prosjektkonvensjoner og arbeidsflyter | + +For eksempel vil den tredje backend-ADR-en ha ID-en `BE-003`, og den første frontend-ADR-en vil være `FE-001`. + +## Hvordan domener brukes + +### ADR-identifikasjon + +Domeneprefikset er bakt inn i hvert ADR-s `id`-felt. Når du kjører `archgate adr create` og velger et domene, bestemmer CLI-en automatisk neste tilgjengelige sekvensnummer for det domenets prefiks. Et arkitekturdomene med to eksisterende ADR-er (`ARCH-001`, `ARCH-002`) vil tildele `ARCH-003` til den neste. + +Filnavnet speiler ID-en: + +``` +ARCH-003-dependency-policy.md +ARCH-003-dependency-policy.rules.ts +``` + +### Filtrering + +Kommandoen `archgate adr list` støtter flagget `--domain` for å vise kun ADR-er fra et bestemt domene: + +```bash +archgate adr list --domain backend +archgate adr list --domain architecture +``` + +Dette er nyttig i store prosjekter der mange ADR-er spenner over flere ansvarsområder. Filtrering etter domene lar deg fokusere på beslutningene som er relevante for ditt nåværende arbeid. + +### AI-agentkontekst + +Kommandoen `archgate review-context` grupperer endrede filer etter domene når den gir kontekst til AI-agenter. Når en agent skal skrive kode, mottar den bare ADR-briefingene som er relevante for domenene endringene berører, i stedet for det fullstendige settet av alle ADR-er. Denne avgrensningen reduserer støy og hjelper agenter å fokusere på begrensningene som faktisk gjelder. + +### Avgrenset validering + +Selv om domener i seg selv ikke begrenser hvilke filer en regel kan sjekke (det er jobben til `files`-globen i ADR frontmatteren), gir domener en logisk gruppering som hjelper team å organisere styringen sin. Et backend-team kan gjennomgå alle `BE-*`-ADR-er for å forstå sine begrensninger, mens frontend-teamet fokuserer på `FE-*`. + +## Når du bør bruke hvilket domene + +### backend + +Bruk for beslutninger om server-side-kode: API-designmønstre, databasetilgangskonvensjoner, autentiseringsflyter, tjeneste-til-tjeneste-kommunikasjon, køhåndtering og mønster for bakgrunnsjobber. + +**Eksempel-ADR-er:** API-responskonvoluttformat, databasemigreringsstrategi, feilkodetaksonomi. + +### frontend + +Bruk for beslutninger om klient-side-kode: komponentstruktur, tilstandshåndteringsmønstre, stilingsmetoder, tilgjengelighetskrav og valg av byggeverktøy. + +**Eksempel-ADR-er:** Komponentfilstruktur, CSS-metodikk, skjemavalideringsmønster. + +### data + +Bruk for beslutninger om data: skjemadesign, datapipeline-konvensjoner, valg av lagringsmotor, serialiseringsformater og datavalideringsstrategier. + +**Eksempel-ADR-er:** Hendelseskjemaversionering, databasenavnekonvensjoner, retningslinjer for dataoppbevaring. + +### architecture + +Bruk for tverrgående beslutninger som spenner over flere domener eller påvirker prosjektets overordnede struktur. Dette er beslutninger som backend-, frontend- og datateam alle må følge. + +**Eksempel-ADR-er:** Kommandostruktur, feilhåndteringskonvensjoner, avhengighetsforvaltningspolicy, testestandarder. + +### general + +Bruk for prosjektomfattende konvensjoner som ikke passer godt inn i et teknisk domene: kodegjennomgangsprosesser, formater for commit-meldinger, dokumentasjonsstandarder og onboarding-praksis. + +**Eksempel-ADR-er:** Commit-meldingsformat, PR-beskrivelsemal, dokumentasjonskrav. + +## Velge riktig domene + +Når du bestemmer hvilket domene en ADR tilhører, tenk på hvem som må følge den: + +- Hvis bare backend-utviklere trenger å følge den, bruk `backend`. +- Hvis bare frontend-utviklere trenger å følge den, bruk `frontend`. +- Hvis den gjelder spesifikt datamodellering eller pipelines, bruk `data`. +- Hvis den gjelder på tvers av flere tekniske domener, bruk `architecture`. +- Hvis det er en prosess eller konvensjon snarere enn en teknisk beslutning, bruk `general`. + +Når du er i tvil mellom `architecture` og et spesifikt domene, foretrekk det mer spesifikke domenet. Reserver `architecture` for beslutninger som genuint krysser grenser. + +## Egendefinerte domener + +Når de fem innebygde domenene virkelig ikke passer for en kategori av beslutninger -- for eksempel `security`, `ml-ops` eller `compliance` -- kan du registrere et egendefinert domene via CLI-en: + +```bash +# Se hva som for øyeblikket er gjenkjent i dette prosjektet +archgate adr domain list + +# Registrer et nytt domene med ID-prefiks +archgate adr domain add security SEC + +# Fjern et egendefinert domene (innebygde kan ikke fjernes) +archgate adr domain remove security +``` + +Egendefinerte domene-til-prefiks-tilordninger lagres i [`.archgate/config.json`](/reference/configuration/) og slås sammen med de innebygde ved lesing. Et registrert egendefinert domene oppfører seg nøyaktig som et innebygd: `archgate adr create --domain security` genererer automatisk ID-er som `SEC-001`, og `archgate adr list --domain security` filtrerer til disse ADR-ene. + +### Navneregler + +- **Navn** -- kebab-case med små bokstaver, 2--32 tegn (f.eks. `security`, `ml-ops`, `compliance`). +- **Prefiks** -- store bokstaver, sifre eller understreker, 2--10 tegn (f.eks. `SEC`, `MLOPS`, `COMP`). +- Egendefinerte navn og prefikser kan ikke kollidere med innebygde eller andre egendefinerte oppføringer. + +### Når du bør foretrekke et innebygd + +De fem innebygde domenene er bevisst opinionerte. Før du registrerer et egendefinert domene, sjekk om beslutningen kan plasseres under et eksisterende: + +- En beslutning om autentiseringsmellomvare passer vanligvis under `backend`, selv om motivasjonen er sikkerhet. +- En beslutning om skjemaversionering passer vanligvis under `data`, selv om motivasjonen er samsvar. +- En beslutning som spenner over flere tekniske områder passer vanligvis under `architecture`. + +Bruk et egendefinert domene bare når ingen av de innebygde passer -- for eksempel når du har et dedikert team eller et samsvarregime som trenger sin egen styringsflate. + +### Veiledning for AI-agenter + +Når du bruker Archgate-editorpluginen til å opprette ADR-er, er agentene instruert til å foretrekke de innebygde domenene og spørre før de introduserer et egendefinert. De viser den samlede listen via `archgate adr domain list` og registrerer bare et nytt domene etter å ha bekreftet med deg at ingen innebygde passer. diff --git a/docs/src/content/docs/nb/concepts/rules.mdx b/docs/src/content/docs/nb/concepts/rules.mdx new file mode 100644 index 00000000..1234e575 --- /dev/null +++ b/docs/src/content/docs/nb/concepts/rules.mdx @@ -0,0 +1,170 @@ +--- +title: Regler +description: Forstå Archgates TypeScript-regelsystem som gjør Architecture Decision Records om til automatiserte samsvarssjekker med bruddrapportering på filnivå. +--- + +Regler er den kjørbare siden av en ADR. De bor i tilhørende `.rules.ts`-filer ved siden av ADR-dokumentet og eksporterer et vanlig objekt typet med `satisfies RuleSet`. Når du kjører `archgate check`, laster CLI-en inn hver ADR som har `rules: true`, importerer den tilhørende regelfilen og kjører hver sjekk mot kodebasen din. + +## Definere regler + +En regelfil er en TypeScript-modul som standard-eksporterer et vanlig objekt i samsvar med `RuleSet`-typen. Typen leveres av den lokale shimen som auto-genereres av `archgate init` (ingen npm-installasjon nødvendig): + +```typescript +/// + +export default { + rules: { + "rule-key": { + description: "What this rule checks", + severity: "error", + async check(ctx) { + // Inspect files and report violations + }, + }, + }, +} satisfies RuleSet; +``` + +Hver nøkkel i `rules`-objektet blir regel-ID-en. Den fullstendige regelidentifikatoren som vises i sjekk-utdata kombinerer ADR-ID-en og regelnøkkelen, for eksempel `ARCH-004/no-barrel-files`. + +## Regelstruktur + +Hver regel har tre deler: + +| Egenskap | Type | Påkrevd | Beskrivelse | +| ------------- | -------- | ------- | ------------------------------------------------ | +| `description` | string | Ja | Et kort sammendrag av hva regelen sjekker | +| `severity` | string | Nei | `"error"` (standard), `"warning"` eller `"info"` | +| `check` | function | Ja | Asynkron funksjon som mottar en `RuleContext` | + +### Alvorlighetsgrader + +Alvorlighetsgraden bestemmer hva som skjer når en regel finner et problem: + +| Alvorlighetsgrad | Exit Code | Effekt | +| ---------------- | --------- | ------------------------------------- | +| `error` | 1 | Bruddet rapporteres og sjekken feiler | +| `warning` | 0 | Advarselen logges, men sjekken består | +| `info` | 0 | Informasjonsmelding, sjekken består | + +Når `archgate check` kjøres, betyr exit code 1 at minst ett brudd med alvorlighetsgrad `error` ble funnet. Exit code 0 betyr ingen feil (advarsler og informasjonsmeldinger logges, men blokkerer ikke). + +## RuleContext + +`check`-funksjonen mottar et `RuleContext`-objekt som gir alt en regel trenger for å inspisere kodebasen og rapportere funn. + +### Prosjektinformasjon + +| Egenskap | Type | Beskrivelse | +| ------------------ | ---------- | -------------------------------------------------------------------------------------------- | +| `ctx.projectRoot` | `string` | Absolutt sti til prosjektets rotmappe | +| `ctx.scopedFiles` | `string[]` | Filer som matcher ADR-ens `files`-glober, eller alle prosjektfiler hvis ingen glober er satt | +| `ctx.changedFiles` | `string[]` | Filer endret i git (auto-oppdaget fra branch-diff, eller fra `--staged`/`--base`) | + +### Filoperasjoner + +| Metode | Returtype | Beskrivelse | +| -------------------- | ------------------- | -------------------------------------- | +| `ctx.glob(pattern)` | `Promise` | Finn filer som matcher et glob-mønster | +| `ctx.readFile(path)` | `Promise` | Les en fils innhold som streng | +| `ctx.readJSON(path)` | `Promise` | Les og parse en JSON-fil | + +### Søkeoperasjoner + +| Metode | Returtype | Beskrivelse | +| ---------------------------------- | ---------------------- | ----------------------------------------------- | +| `ctx.grep(file, pattern)` | `Promise` | Søk i en enkelt fil med et regex-mønster | +| `ctx.grepFiles(pattern, fileGlob)` | `Promise` | Søk på tvers av flere filer som matcher en glob | + +Både `grep` og `grepFiles` returnerer et array av `GrepMatch`-objekter: + +```typescript +interface GrepMatch { + file: string; // Relative path from project root + line: number; // 1-based line number + column: number; // 1-based column number + content: string; // The full line content +} +``` + +### Rapportering + +`ctx.report`-objektet gir tre metoder for å rapportere funn: + +```typescript +ctx.report.violation({ message, file?, line?, fix? }); +ctx.report.warning({ message, file?, line?, fix? }); +ctx.report.info({ message, file?, line?, fix? }); +``` + +Hver metode aksepterer et objekt med: + +| Egenskap | Type | Påkrevd | Beskrivelse | +| --------- | ------ | ------- | ---------------------------------- | +| `message` | string | Ja | Hva problemet er | +| `file` | string | Nei | Relativ sti til den aktuelle filen | +| `line` | number | Nei | Linjenummer der problemet oppstår | +| `fix` | string | Nei | Foreslått rettelse for bruddet | + +Bruk `ctx.report.violation()` for problemer som skal blokkere sammenslåinger. Bruk `ctx.report.warning()` for problemer som er verdt å flagge, men som ikke blokkerer. Bruk `ctx.report.info()` for rent informativ utdata. + +## Tidsavbrudd for regler + +Hver regel har en kjøretidsgrense på 30 sekunder. Hvis en regels `check`-funksjon ikke fullføres innen 30 sekunder, termineres den og rapporteres som feil. Dette forhindrer at regler som løper løpsk blokkerer pipelinen på ubestemt tid. + +## Komplett eksempel + +Her er en komplett regelfil som sjekker for et forbudt importmønster. Den håndhever at ingen kildefil importerer direkte fra `node:fs` (prosjektet krever bruk av en wrapper). + +```typescript +/// + +export default { + rules: { + "no-direct-fs-import": { + description: + "Source files must not import directly from node:fs; use the fs wrapper", + severity: "error", + async check(ctx) { + const sourceFiles = ctx.scopedFiles.filter( + (f) => f.endsWith(".ts") && !f.endsWith(".test.ts") + ); + + for (const file of sourceFiles) { + const matches = await ctx.grep(file, /from ["']node:fs["']/); + + for (const match of matches) { + ctx.report.violation({ + message: `Direct import from "node:fs" is not allowed. Use the fs wrapper from "src/helpers/fs" instead.`, + file: match.file, + line: match.line, + fix: 'Replace the import with: import { readFile, writeFile } from "../helpers/fs"', + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +Når denne regelen kjøres mot en fil som inneholder `import { readFileSync } from "node:fs"`, ser utdataen slik ut: + +``` +ARCH-007/no-direct-fs-import ERROR + src/services/config.ts:3 — Direct import from "node:fs" is not allowed. Use the fs wrapper from "src/helpers/fs" instead. + Fix: Replace the import with: import { readFile, writeFile } from "../helpers/fs" +``` + +## Kjøremodell + +Regler kjøres med følgende garantier: + +- **Parallelt mellom ADR-er** -- Regler fra forskjellige ADR-er kjøres samtidig for raskere kjøring. +- **Sekvensielt innenfor en ADR** -- Regler som tilhører samme ADR kjøres etter hverandre, slik at tidligere regler kan etablere kontekst for senere. +- **Avgrensede filer er forhåndsløst** -- `ctx.scopedFiles`-arrayet er fylt ut før `check`-funksjonen din kalles, basert på ADR-ens `files`-glober. +- **Endrede filer auto-oppdaget** -- `ctx.changedFiles` fylles automatisk med branch-diffen mot base-branchen (f.eks. `main`). Bruk `--staged` for pre-commit hooks (kun staged-filer) eller `--base ` for en eksplisitt base. Dette gjør at kryss-fil-avhengighetsregler fungerer lokalt, ikke bare i CI. + +:::tip[Kjør sjekker automatisk med editorplugins] +Editorpluginene for [Claude Code](/guides/claude-code-plugin/) og [Cursor](/guides/cursor-integration/) kjører `archgate check` automatisk etter hver kodeendring. Agenten leser de gjeldende ADR-ene, skriver samsvarende kode og validerer -- ingen manuelle sjekkkommandoer nødvendig. [Registrer deg for beta-tilgang](https://plugins.archgate.dev). +::: diff --git a/docs/src/content/docs/nb/examples/clean-architecture-layers.mdx b/docs/src/content/docs/nb/examples/clean-architecture-layers.mdx new file mode 100644 index 00000000..b3e3d7d6 --- /dev/null +++ b/docs/src/content/docs/nb/examples/clean-architecture-layers.mdx @@ -0,0 +1,128 @@ +--- +title: clean-architecture-layers +description: Krev avhengighetsretning i ren arkitektur ved å forhindre at indre lag refererer til ytre lag. +--- + +Krev avhengighetsretning i ren arkitektur -- indre lag må ikke referere til ytre lag. + +## Regeldetaljer + +Ren arkitektur krever at avhengigheter peker innover: API -> Application -> Domain. Domain-laget må ha null eksterne avhengigheter, Application-laget må ikke referere til Infrastructure direkte, og ingen lavere lag skal referere til API-prosjektet. Denne regelen sjekker `using`-direktiver (C#) eller `import`-setninger for å håndheve disse grensene. + +Det samme monsteret gjelder for enhver lagdelt arkitektur i ethvert språk -- tilpass importmonstrene og lagstiene deretter. + +## Eksempler på **feil** kode + +```csharp title="Domain/Entities/User.cs" +using Microsoft.EntityFrameworkCore; // ✗ Domain → Infrastructure +using StavangerChallenge.Infrastructure; // ✗ Domain → Infrastructure +``` + +```csharp title="Application/Services/UserService.cs" +using StavangerChallenge.Infrastructure; // ✗ Application → Infrastructure +using StavangerChallenge.API; // ✗ Application → API +``` + +## Eksempler på **riktig** kode + +```csharp title="Domain/Entities/User.cs" +namespace StavangerChallenge.Domain.Entities; +// No external dependencies — pure domain logic +``` + +```csharp title="Application/Services/UserService.cs" +using StavangerChallenge.Domain.Entities; // ✓ Application → Domain +// Uses IRepository interface, not Infrastructure directly +``` + +## Regelimplementasjon + +```typescript +/// + +export default { + rules: { + "no-infrastructure-in-domain": { + description: + "Domain layer must not reference Infrastructure or ORM packages", + async check(ctx) { + const domainFiles = await ctx.glob("backend/src/**/Domain/**/*.cs"); + for (const file of domainFiles) { + const matches = await ctx.grep( + file, + /using\s+(Microsoft\.EntityFrameworkCore|MyApp\.Infrastructure)/ + ); + for (const match of matches) { + ctx.report.violation({ + message: `Domain must not reference Infrastructure: "${match.content.trim()}"`, + file: match.file, + line: match.line, + fix: "Remove this using directive. Domain entities should have zero external dependencies.", + }); + } + } + }, + }, + "no-infrastructure-in-application": { + description: + "Application layer must not reference Infrastructure directly", + async check(ctx) { + const appFiles = await ctx.glob("backend/src/**/Application/**/*.cs"); + for (const file of appFiles) { + const matches = await ctx.grep(file, /using\s+MyApp\.Infrastructure/); + for (const match of matches) { + ctx.report.violation({ + message: `Application must not reference Infrastructure: "${match.content.trim()}"`, + file: match.file, + line: match.line, + fix: "Define an interface in Application and implement it in Infrastructure.", + }); + } + } + }, + }, + "no-upward-api-references": { + description: "No layer should reference the API project", + async check(ctx) { + const lowerLayerPatterns = [ + "backend/src/**/Domain/**/*.cs", + "backend/src/**/Application/**/*.cs", + "backend/src/**/Infrastructure/**/*.cs", + ]; + for (const pattern of lowerLayerPatterns) { + const files = await ctx.glob(pattern); + for (const file of files) { + const matches = await ctx.grep(file, /using\s+MyApp\.API/); + for (const match of matches) { + ctx.report.violation({ + message: `Lower layers must not reference the API project: "${match.content.trim()}"`, + file: match.file, + line: match.line, + fix: "Dependencies flow inward: API → Application → Domain.", + }); + } + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +For TypeScript-prosjekter, tilpass monstrene: + +```typescript +// Check that domain/ does not import from infrastructure/ +/import\s+.*from\s+["'].*\/infrastructure\// + +// Check that no layer imports from api/ +/import\s+.*from\s+["'].*\/api\// +``` + +## Når bør du bruke den + +Når prosjektet ditt folger ren arkitektur, heksagonal arkitektur, eller en annen lagdelt arkitektur der avhengighetsretning må håndheves. + +## Når bør du ikke bruke den + +Når prosjektet ditt ikke bruker en lagdelt arkitektur, eller når lagene ikke er organisert i separate mapper. diff --git a/docs/src/content/docs/nb/examples/common-rule-patterns.mdx b/docs/src/content/docs/nb/examples/common-rule-patterns.mdx new file mode 100644 index 00000000..e21007d3 --- /dev/null +++ b/docs/src/content/docs/nb/examples/common-rule-patterns.mdx @@ -0,0 +1,60 @@ +--- +title: Vanlige regelmonstre +description: "Bruksklare Archgate-regelmonstre for vanlige styringsbehov: avhengighetsstyring, importrestriksjoner, filstruktur, kodekvalitet, databaseskjema og arkitekturgrenser." +sidebar: + order: 0 +--- + +Bla gjennom komplette, kopierbare regeleksempler organisert etter kategori. Hver regelside folger et konsistent format: hva regelen sjekker, eksempler pa feil og riktig kode, den fullstendige `.rules.ts`-implementasjonen, og veiledning om nar du bor bruke den. + +## Avhengigheter og pakkestyring + +| Regel | Beskrivelse | +| ------------------------------------------------------- | ---------------------------------------------------------------------------- | +| [no-unapproved-deps](/examples/no-unapproved-deps/) | Begrens produksjonsavhengigheter til en godkjent liste | +| [version-catalog](/examples/version-catalog/) | Krev sentralisert versjonsstyring i monorepositories med `catalog:`-notasjon | +| [monorepo-task-runner](/examples/monorepo-task-runner/) | Forby `package.json`-skript og krev task runner-konfigurasjon i alle pakker | + +## Import- og API-restriksjoner + +| Regel | Beskrivelse | +| ----------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| [no-banned-imports](/examples/no-banned-imports/) | Forhindre bruk av forbudte biblioteker med en datadrevet monsterliste | +| [no-banned-api](/examples/no-banned-api/) | Forby spesifikke kjoretidens API-er som forårsaker plattform- eller stabilitetsproblemer | +| [wrapper-enforcement](/examples/wrapper-enforcement/) | Krev bruk av en prosjektwrapper i stedet for en rå plattform-API | + +## Filstruktur og organisering + +| Regel | Beskrivelse | +| ------------------------------------------------------- | ------------------------------------------------------------------ | +| [kebab-case-filenames](/examples/kebab-case-filenames/) | Krev konsistente filnavnkonvensjoner med regex-validering | +| [no-barrel-files](/examples/no-barrel-files/) | Oppdag og forby barrel-filer (re-eksport-bare `index.ts`) | +| [test-file-coverage](/examples/test-file-coverage/) | Kontroller at hver kildefil har en tilhorende testfil | +| [component-pairing](/examples/component-pairing/) | Krev Connected/presentational-komponentpar med mulighet for unntak | + +## Kodekvalitet og output + +| Regel | Beskrivelse | +| ------------------------------------------------------------------- | -------------------------------------------------------------------- | +| [no-todo-comments](/examples/no-todo-comments/) | Flagg TODO-, FIXME-, HACK- og XXX-kommentarer for sammenslåing | +| [no-emoji-in-output](/examples/no-emoji-in-output/) | Forby emoji og rå ANSI-koder i CLI-outputstrenger | +| [max-file-length](/examples/max-file-length/) | Advar nar kildefiler overskrider en konfigurerbar linjeantallsgrense | +| [page-component-constraints](/examples/page-component-constraints/) | Krev storrelesgrenser og forby data-henting-hooks i sidekomponenter | + +## Databaseskjema + +| Regel | Beskrivelse | +| --------------------------------------------------------- | --------------------------------------------------------------------------- | +| [database-audit-fields](/examples/database-audit-fields/) | Sorg for at alle tabeller inkluderer `created_at`- og `updated_at`-kolonner | + +## Arkitekturgrenser + +| Regel | Beskrivelse | +| ----------------------------------------------------------------- | ------------------------------------------------------------ | +| [required-export-pattern](/examples/required-export-pattern/) | Kontroller at filer eksporterer en pakrevd funksjonssignatur | +| [openapi-routes](/examples/openapi-routes/) | Sorg for at backend-ruter bruker OpenAPI-typede definisjoner | +| [clean-architecture-layers](/examples/clean-architecture-layers/) | Krev avhengighetsretning i lagdelte arkitekturer | + +:::tip[La AI-agenter skrive regler for deg] +Editorutvidelsene for [Claude Code](/guides/claude-code-plugin/) og [Cursor](/guides/cursor-integration/) inkluderer en Quality Manager-ferdighet som identifiserer gjentakende monstre i kodebasen din og foreslar nye regler for å handtere dem. [Registrer deg for betatilgang](https://plugins.archgate.dev). +::: diff --git a/docs/src/content/docs/nb/examples/component-pairing.mdx b/docs/src/content/docs/nb/examples/component-pairing.mdx new file mode 100644 index 00000000..7c111791 --- /dev/null +++ b/docs/src/content/docs/nb/examples/component-pairing.mdx @@ -0,0 +1,82 @@ +--- +title: component-pairing +description: Krev at tilstandsfulle Connected-komponenter har en tilhørende presentasjonskomponentfil, med mulighet for unntak. +--- + +Krev at tilstandsfulle "Connected"-komponenter har en tilhørende presentasjonskomponentfil. + +## Regeldetaljer + +Container/presentational-monsteret skiller datahentende (Connected) komponenter fra rene UI- (presentasjons-) komponenter. Denne regelen sjekker at hver `*Connected.tsx`-fil har en matchende `*.tsx` presentasjonsmotstykke. Den stotter et unntak-direktiv (`// @no-presentational: `) for tilfeller der en Connected-komponent ikke trenger et presentasjonspar. + +## Eksempler på **feil** kode + +``` +src/components/ + UserListConnected.tsx ← no UserList.tsx ✗ +``` + +## Eksempler på **riktig** kode + +``` +src/components/ + UserListConnected.tsx ← fetches data, passes to UserList + UserList.tsx ← pure presentational component +``` + +Eller, med unntak: + +```typescript title="src/components/RedirectConnected.tsx" +// @no-presentational: this component only redirects, no UI to render +import { useNavigate } from "react-router"; +// ... +``` + +## Regelimplementasjon + +```typescript +/// + +export default { + rules: { + "connected-wrapper-existence": { + description: + "Connected wrappers must have a corresponding presentational component file", + async check(ctx) { + const connectedFiles = await ctx.glob( + "packages/frontend/src/components/**/*Connected.tsx" + ); + + for (const file of connectedFiles) { + if (file.includes(".stories.") || file.includes(".test.")) continue; + + const content = await ctx.readFile(file); + + // Support opt-out directive + if (/^\/\/\s*@no-presentational:/.test(content.trimStart())) continue; + + const presentationalFile = file.replace(/Connected\.tsx$/, ".tsx"); + + try { + await ctx.readFile(presentationalFile); + } catch { + ctx.report.violation({ + message: `Connected wrapper has no corresponding presentational component (expected ${presentationalFile}). Add "// @no-presentational: " to opt out.`, + file, + fix: `Create ${presentationalFile} as the presentational counterpart`, + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når bør du bruke den + +Når frontend-arkitekturen din folger container/presentational-monsteret og du vil håndheve at datahentingslogikk alltid er adskilt fra UI-rendering. + +## Når bør du ikke bruke den + +Når prosjektet ditt bruker en annen komponentarkitektur (f.eks. kun hooks, eller serverkomponenter), eller når monsteret brukes selektivt i stedet for universelt. diff --git a/docs/src/content/docs/nb/examples/database-audit-fields.mdx b/docs/src/content/docs/nb/examples/database-audit-fields.mdx new file mode 100644 index 00000000..a808e39b --- /dev/null +++ b/docs/src/content/docs/nb/examples/database-audit-fields.mdx @@ -0,0 +1,117 @@ +--- +title: database-audit-fields +description: Sørg for at alle databasetabeller inkluderer påkrevde revisjonskolonner som created_at og updated_at for sporbarhet. +--- + +Sorg for at alle databasetabeller inkluderer påkrevde revisjonskolonner. + +## Regeldetaljer + +Revisjonsfelt (`created_at`, `updated_at`) er essensielle for feilsoking, datastyring og synkroniseringsprotokoller. Denne regelen analyserer skjemafiler for å finne tabelldefinisjoner, henter ut hver tabells kolonneblokk ved hjelp av klammeparentesdybde-sporing, og sjekker om påkrevde kolonner er til stede. Den fungerer med enhver ORM som definerer tabeller som funksjonsanrop med objektargumenter (Drizzle, Prisma schema-in-code, osv.). + +## Eksempler på **feil** kode + +```typescript title="packages/db/src/schema.ts" +export const users = sqliteTable("users", { + id: text("id").primaryKey(), + name: text("name").notNull(), + email: text("email").notNull(), + // Missing created_at and updated_at +}); +``` + +## Eksempler på **riktig** kode + +```typescript title="packages/db/src/schema.ts" +export const users = sqliteTable("users", { + id: text("id").primaryKey(), + name: text("name").notNull(), + email: text("email").notNull(), + created_at: text("created_at") + .notNull() + .$defaultFn(() => new Date().toISOString()), + updated_at: text("updated_at") + .notNull() + .$defaultFn(() => new Date().toISOString()), +}); +``` + +## Regelimplementasjon + +```typescript +/// + +export default { + rules: { + "audit-fields": { + description: + "All database tables must have created_at and updated_at columns", + async check(ctx) { + const schemaFiles = await ctx.glob("packages/**/src/schema.ts"); + const TABLE_PATTERN = /sqliteTable\s*\(\s*["']([^"']+)["']/g; + + for (const file of schemaFiles) { + const content = await ctx.readFile(file); + let match; + + while ((match = TABLE_PATTERN.exec(content)) !== null) { + const tableName = match[1]; + const tableStart = match.index; + + // Extract the table's column block using brace-depth tracking + const afterMatch = content.slice(tableStart); + const firstBrace = afterMatch.indexOf("{"); + if (firstBrace === -1) continue; + + let depth = 0; + let tableEnd = tableStart + firstBrace; + for (let i = firstBrace; i < afterMatch.length; i++) { + if (afterMatch[i] === "{") depth++; + else if (afterMatch[i] === "}") { + depth--; + if (depth === 0) { + tableEnd = tableStart + i; + break; + } + } + } + + const tableBlock = content.slice(tableStart, tableEnd + 1); + + if (!tableBlock.includes('"created_at"')) { + ctx.report.violation({ + message: `Table "${tableName}" is missing "created_at" column`, + file, + fix: 'Add created_at: text("created_at").notNull().$defaultFn(() => new Date().toISOString())', + }); + } + if (!tableBlock.includes('"updated_at"')) { + ctx.report.violation({ + message: `Table "${tableName}" is missing "updated_at" column`, + file, + fix: 'Add updated_at: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())', + }); + } + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når bør du bruke den + +Når datamodellen din krever konsistente revisjonsfelt for sporbarhet, feilsoking eller samsvar. Tilpass `TABLE_PATTERN`-regex og kolonnenavn for din ORM: + +```typescript +// For Drizzle with PostgreSQL +const TABLE_PATTERN = /pgTable\s*\(\s*["']([^"']+)["']/g; + +// For Prisma-style definitions +const TABLE_PATTERN = /model\s+(\w+)\s*\{/g; +``` + +## Når bør du ikke bruke den + +Når noen tabeller med vilje utelater revisjonsfelt (f.eks. kobletabeller, materialiserte visninger), eller når revisjonsfelt legges til automatisk på databasenivå via triggere. diff --git a/docs/src/content/docs/nb/examples/kebab-case-filenames.mdx b/docs/src/content/docs/nb/examples/kebab-case-filenames.mdx new file mode 100644 index 00000000..aa875a02 --- /dev/null +++ b/docs/src/content/docs/nb/examples/kebab-case-filenames.mdx @@ -0,0 +1,82 @@ +--- +title: kebab-case-filenames +description: Krev konsistente filnavnkonvensjoner på tvers av kildemapper ved hjelp av regex-validering. +--- + +Krev konsistente filnavnkonvensjoner på tvers av kildemapper. + +## Regeldetaljer + +Inkonsistente filnavn (blanding av `camelCase`, `PascalCase`, `snake_case` og `kebab-case`) gjor filer vanskeligere å finne og forårsaker problemer med store/små bokstaver på tvers av operativsystemer. Denne regelen validerer hvert filnavn innenfor omfanget mot et regex-monster og foreslar rettelser. + +## Eksempler på **feil** kode + +``` +src/ + helpers/ + pathUtils.ts ← camelCase + Git_Helper.ts ← PascalCase + snake_case + ADRWriter.ts ← PascalCase +``` + +## Eksempler på **riktig** kode + +``` +src/ + helpers/ + path-utils.ts + git-helper.ts + adr-writer.ts +``` + +## Regelimplementasjon + +```typescript +/// +import { basename } from "node:path"; + +const KEBAB_CASE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*\.(ts|tsx|js|jsx)$/; + +export default { + rules: { + "kebab-case-filenames": { + description: "Source files must use kebab-case naming", + async check(ctx) { + for (const file of ctx.scopedFiles) { + const name = basename(file); + + // Skip test files and type declaration files + if (name.endsWith(".test.ts") || name.endsWith(".d.ts")) continue; + + if (!KEBAB_CASE.test(name)) { + ctx.report.violation({ + message: `File "${name}" does not follow kebab-case naming convention`, + file, + fix: `Rename to ${name.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()}`, + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når bør du bruke den + +Når teamet ditt har standardisert en navnekonvensjon og onsker å håndheve den automatisk. Tilpass regex for din konvensjon: + +```typescript +// PascalCase (React components) +const PASCAL_CASE = /^[A-Z][a-zA-Z0-9]*\.(ts|tsx)$/; + +// camelCase +const CAMEL_CASE = /^[a-z][a-zA-Z0-9]*\.(ts|tsx|js|jsx)$/; + +// snake_case (Python-style) +const SNAKE_CASE = /^[a-z][a-z0-9]*(_[a-z0-9]+)*\.(ts|tsx|js|jsx)$/; +``` + +## Når bør du ikke bruke den + +Når prosjektet ditt med vilje blander navnekonvensjoner (f.eks. PascalCase for React-komponenter og kebab-case for hjelpefunksjoner), eller når du migrerer en gammel kodebase der masseomdobing ikke er gjennomforbart. diff --git a/docs/src/content/docs/nb/examples/license-compatibility.mdx b/docs/src/content/docs/nb/examples/license-compatibility.mdx new file mode 100644 index 00000000..186f0865 --- /dev/null +++ b/docs/src/content/docs/nb/examples/license-compatibility.mdx @@ -0,0 +1,135 @@ +--- +title: license-compatibility +description: Verifiser at alle avhengigheter bruker lisenser som er kompatible med prosjektets lisens for å forhindre copyleft-kontaminering. +--- + +Forhindre copyleft- eller inkompatible lisenser fra å komme inn i avhengighetstreet ditt. + +## Regeldetaljer + +Når du kompilerer eller bundler avhengigheter inn i applikasjonen din, gjelder lisensvilkårene deres for det kombinerte verket. En enkelt GPL-avhengighet i et permissivt (MIT/Apache-2.0) prosjekt kan tvinge hele prosjektet til å ta i bruk copyleft-vilkår. Denne regelen sjekker alle direkte avhengigheter mot en tillatt-liste med permissive lisenser. + +## Eksempler på **feil** kode + +```json title="package.json" +{ + "dependencies": { "zod": "^3.23.0" }, + "devDependencies": { "readline-sync": "^1.4.10" } +} +``` + +Hvis `readline-sync` bruker GPL-3.0, utloses et brudd selv som devDependency. + +## Eksempler på **riktig** kode + +```json title="package.json" +{ + "dependencies": { "zod": "^3.23.0" }, + "devDependencies": { "fast-check": "^4.7.0" } +} +``` + +Både `zod` (MIT) og `fast-check` (MIT) er på den permissive tillatt-listen. + +## Regelimplementasjon + +```typescript +/// + +const ALLOWED_LICENSES = new Set([ + "MIT", + "Apache-2.0", + "ISC", + "BSD-2-Clause", + "BSD-3-Clause", + "0BSD", + "CC0-1.0", + "Unlicense", + "BlueOak-1.0.0", +]); + +function isAllowed(license: string | undefined): boolean { + if (!license) return false; + if (ALLOWED_LICENSES.has(license)) return true; + + // Handle SPDX OR expressions — at least one option must be allowed + const normalized = license.trim().replace(/^\(/u, "").replace(/\)$/u, ""); + if (ALLOWED_LICENSES.has(normalized)) return true; + + if (normalized.includes(" OR ")) { + return normalized.split(" OR ").some((l) => ALLOWED_LICENSES.has(l.trim())); + } + + return false; +} + +/** + * Extract package name from a node_modules path. + * Handles both regular and scoped (@scope/name) packages. + */ +function extractPackageName(path: string): string { + const parts = path.replaceAll("\\", "/").split("/"); + const nmIdx = parts.lastIndexOf("node_modules"); + if (nmIdx === -1) return path; + const afterNm = parts.slice(nmIdx + 1); + if (afterNm[0]?.startsWith("@") && afterNm.length >= 2) { + return `${afterNm[0]}/${afterNm[1]}`; + } + return afterNm[0] ?? path; +} + +export default { + rules: { + "no-copyleft-deps": { + description: + "All dependencies (including transitive) must use permissive licenses", + async check(ctx) { + // Scan ALL packages in node_modules — direct AND transitive. + // Brace expansion covers both regular and scoped packages. + const pkgFiles = await ctx.glob("node_modules/{*,@*/*}/package.json"); + + const depResults = await Promise.all( + pkgFiles.map(async (pkgPath) => { + try { + const depPkg = (await ctx.readJSON(pkgPath)) as { + license?: string; + }; + return { + dep: extractPackageName(pkgPath), + license: depPkg.license, + }; + } catch { + return null; + } + }) + ); + + for (const result of depResults) { + if (result === null) continue; + if (!isAllowed(result.license)) { + ctx.report.violation({ + message: `Dependency "${result.dep}" has disallowed license: "${result.license ?? "(none)"}".`, + file: "package.json", + fix: `Remove "${result.dep}" or find an alternative with a permissive license.`, + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Tilpasning + +- **Endre tillatt-listen**: Legg til eller fjern lisensidentifikatorer basert på prosjektets lisens. GPL-prosjekter kan tillate GPL-avhengigheter; Apache-2.0-prosjekter bor blokkere dem. +- **Sjekk kun produksjonsavhengigheter**: Fjern `devDependencies` fra `allDeps` hvis du bare bryr deg om bundlet/levert kode. +- **Skann transitive avhengigheter**: Bruk `ctx.glob("node_modules/{*,@*/*}/package.json")` for å skanne alle installerte pakker (inkludert scoped) rekursivt, ikke bare direkte avhengigheter. + +## Når bør du bruke den + +Når prosjektet ditt bruker en permissiv lisens (MIT, Apache-2.0, ISC, BSD) og du vil forhindre copyleft-kontaminering, spesielt i kompilerte/bundlede distribusjoner. + +## Når bør du ikke bruke den + +I GPL-lisensierte prosjekter (der copyleft-avhengigheter er kompatible), eller når du har et dedikert lisensskanningsverktoy (FOSSA, Snyk) som allerede beskytter CI-pipelinen din. diff --git a/docs/src/content/docs/nb/examples/max-file-length.mdx b/docs/src/content/docs/nb/examples/max-file-length.mdx new file mode 100644 index 00000000..41c0c450 --- /dev/null +++ b/docs/src/content/docs/nb/examples/max-file-length.mdx @@ -0,0 +1,67 @@ +--- +title: max-file-length +description: Advar når kildefiler overskrider en konfigurerbar linjeantallsgrense for å oppmuntre til modulær kode. +--- + +Advar når kildefiler overskrider en linjeantallsgrense. + +## Regeldetaljer + +Store filer er vanskeligere å navigere, gjennomgå og teste. Denne regelen teller linjer i hver fil innenfor omfanget og rapporterer en advarsel når antallet overskrider et konfigurerbart maksimum. Bruk av `warning`-alvorlighetsgrad holder CI gronn samtidig som filer som bor refaktoreres blir synliggjort. + +## Eksempler på **feil** kode + +En fil med 450 linjer når grensen er 300: + +``` +src/engine/runner.ts (450 lines) +``` + +## Eksempler på **riktig** kode + +Den samme logikken delt opp i fokuserte moduler: + +``` +src/engine/runner.ts (120 lines) +src/engine/loader.ts (95 lines) +src/engine/reporter.ts (85 lines) +``` + +## Regelimplementasjon + +```typescript +/// + +const MAX_LINES = 300; + +export default { + rules: { + "max-file-length": { + description: `Source files should not exceed ${MAX_LINES} lines`, + severity: "warning", + async check(ctx) { + const checks = ctx.scopedFiles.map(async (file) => { + const content = await ctx.readFile(file); + const lineCount = content.split("\n").length; + if (lineCount > MAX_LINES) { + ctx.report.warning({ + message: `File has ${lineCount} lines (max: ${MAX_LINES}). Consider splitting it.`, + file, + fix: "Extract related functions into separate modules", + }); + } + }); + await Promise.all(checks); + }, + }, + }, +} satisfies RuleSet; +``` + +## Når bør du bruke den + +Når du onsker en myk grense mot at filer vokser for store. Juster `MAX_LINES` etter teamets preferanse (200-500 er vanlig). + +## Når bør du ikke bruke den + +Når noen filer med rette er store (generert kode, testsuiter med mange tilfeller), eller når du foretrekker andre kompleksitetsmetrikker som syklomatisk kompleksitet. diff --git a/docs/src/content/docs/nb/examples/monorepo-task-runner.mdx b/docs/src/content/docs/nb/examples/monorepo-task-runner.mdx new file mode 100644 index 00000000..ff8b14b6 --- /dev/null +++ b/docs/src/content/docs/nb/examples/monorepo-task-runner.mdx @@ -0,0 +1,111 @@ +--- +title: monorepo-task-runner +description: Krev at alle pakker bruker en sentralisert task runner i stedet for package.json-skript for konsistent byggeorkestrering. +--- + +Krev at alle pakker bruker en sentralisert task runner i stedet for `package.json`-skript. + +## Regeldetaljer + +I et monorepo er `package.json`-skript lokale for hver pakke og kan ikke uttrykke avhengigheter mellom pakker, caching eller orkestrering. Denne regelen krever at alle pakker bruker en sentralisert task runner (f.eks. Moon, Turborepo, Nx) ved å forby `scripts` i `package.json` og kreve en task runner-konfigurasjonsfil (`moon.yml`, `turbo.json`, osv.) i hver pakke. + +## Eksempler på **feil** kode + +```json title="packages/api/package.json" +{ + "name": "@myorg/api", + "scripts": { "build": "tsc", "test": "vitest", "lint": "eslint ." } +} +``` + +## Eksempler på **riktig** kode + +```json title="packages/api/package.json" +{ "name": "@myorg/api" } +``` + +```yaml title="packages/api/moon.yml" +tasks: + build: + command: tsc + inputs: + - src/**/* + test: + command: vitest + deps: + - ~:build + lint: + command: eslint . +``` + +## Regelimplementasjon + +```typescript +/// + +export default { + rules: { + "no-package-scripts": { + description: + "package.json must not have scripts — use the task runner instead", + async check(ctx) { + const packageJsonFiles = [ + ...(await ctx.glob("packages/*/package.json")), + ...(await ctx.glob("packages/*/*/package.json")), + ]; + + for (const file of packageJsonFiles) { + const pkg = (await ctx.readJSON(file)) as { + scripts?: Record; + }; + if (pkg.scripts && Object.keys(pkg.scripts).length > 0) { + ctx.report.violation({ + message: `${file}: has "scripts" field — use task runner config instead`, + file, + fix: 'Move scripts to the task runner config and remove "scripts" from package.json', + }); + } + } + }, + }, + "task-runner-config": { + description: "All packages must have a task runner configuration file", + async check(ctx) { + const packageJsonFiles = [ + ...(await ctx.glob("packages/*/package.json")), + ...(await ctx.glob("packages/*/*/package.json")), + ]; + + for (const file of packageJsonFiles) { + const configPath = file.replace("/package.json", "/moon.yml"); + try { + await ctx.readFile(configPath); + } catch { + ctx.report.violation({ + message: `Missing task runner config: ${configPath}`, + file: configPath, + fix: "Create a moon.yml file with appropriate task definitions for this package", + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når bør du bruke den + +I monorepositories som bruker en sentralisert task runner for byggeorkestrering. Tilpass konfigurasjonsfil-sjekken for din task runner: + +```typescript +// Turborepo +const configPath = file.replace("/package.json", "/turbo.json"); + +// Nx +const configPath = file.replace("/package.json", "/project.json"); +``` + +## Når bør du ikke bruke den + +I enkeltpakke-repositorier, eller i monorepositories der task runner-en er konfigurert sentralt (f.eks. en enkelt `turbo.json` i roten) i stedet for per pakke. diff --git a/docs/src/content/docs/nb/examples/no-banned-api.mdx b/docs/src/content/docs/nb/examples/no-banned-api.mdx new file mode 100644 index 00000000..8ab965f1 --- /dev/null +++ b/docs/src/content/docs/nb/examples/no-banned-api.mdx @@ -0,0 +1,110 @@ +--- +title: no-banned-api +description: Forby spesifikke kjøretids-API-er som forårsaker plattform- eller stabilitetsproblemer, og krev sikre alternativer. +--- + +Forby spesifikke kjøretids-API-er som forårsaker plattform- eller stabilitetsproblemer. + +## Regeldetaljer + +Noen API-er fungerer korrekt på en plattform, men feiler på en annen. For eksempel henger Buns shell-API (`Bun.$`) på Windows på grunn av pipe-deadlocks. Denne regelen oppdager flere varianter av en forbudt API -- det direkte kallet, importen og destrukturert bruk -- og sikrer at ingen form slipper gjennom. + +Dette monsteret kan generaliseres til enhver API du vil forby mens du tillater et sikkert alternativ. + +## Eksempler på **feil** kode + +```typescript title="src/helpers/git.ts" +// Direct usage +const result = await Bun.$`git status`; + +// Import +import { $ } from "bun"; + +// Destructured usage +const output = await $`ls -la`; +``` + +## Eksempler på **riktig** kode + +```typescript title="src/helpers/git.ts" +const proc = Bun.spawn(["git", "status"], { stdout: "pipe", stderr: "pipe" }); +const output = await new Response(proc.stdout).text(); +``` + +## Regelimplementasjon + +```typescript +/// + +export default { + rules: { + "no-bun-shell": { + description: + "Subprocess execution must use Bun.spawn, not Bun.$ (shell hangs on Windows)", + async check(ctx) { + const files = ctx.scopedFiles.filter( + (f) => !f.includes("tests/") && !f.includes(".archgate/") + ); + + // Variant 1: Bun.$` template literal + const bunShellMatches = await Promise.all( + files.map((file) => ctx.grep(file, /Bun\.\$`/)) + ); + for (const fileMatches of bunShellMatches) { + for (const m of fileMatches) { + ctx.report.violation({ + message: + "Do not use Bun.$ template literals — they hang on Windows. Use Bun.spawn instead.", + file: m.file, + line: m.line, + fix: "Replace Bun.$`cmd args` with Bun.spawn(['cmd', 'args'], { stdout: 'pipe', stderr: 'pipe' })", + }); + } + } + + // Variant 2: import { $ } from "bun" + const dollarImportMatches = await Promise.all( + files.map((file) => + ctx.grep(file, /import\s*\{[^}]*\$[^}]*\}\s*from\s*["']bun["']/) + ) + ); + for (const fileMatches of dollarImportMatches) { + for (const m of fileMatches) { + ctx.report.violation({ + message: + 'Do not import $ from "bun" — the shell API hangs on Windows. Use Bun.spawn instead.', + file: m.file, + line: m.line, + fix: "Remove the $ import and replace shell calls with Bun.spawn", + }); + } + } + + // Variant 3: await $` (destructured) + const destructuredMatches = await Promise.all( + files.map((file) => ctx.grep(file, /await\s+\$`/)) + ); + for (const fileMatches of destructuredMatches) { + for (const m of fileMatches) { + ctx.report.violation({ + message: + "Do not use $` template literals — they hang on Windows. Use Bun.spawn instead.", + file: m.file, + line: m.line, + fix: "Replace $`cmd args` with Bun.spawn(['cmd', 'args'], { stdout: 'pipe', stderr: 'pipe' })", + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når bør du bruke den + +Når prosjektet ditt må kjore på flere plattformer og en spesifikk API er kjent for å feile på en av dem. Også nyttig for å forby utdaterte API-er med kjente stabilitetsproblemer. + +## Når bør du ikke bruke den + +Når prosjektet ditt retter seg mot en enkelt plattform og den forbudte API-en fungerer pålitelig der. diff --git a/docs/src/content/docs/nb/examples/no-banned-imports.mdx b/docs/src/content/docs/nb/examples/no-banned-imports.mdx new file mode 100644 index 00000000..4618f85c --- /dev/null +++ b/docs/src/content/docs/nb/examples/no-banned-imports.mdx @@ -0,0 +1,83 @@ +--- +title: no-banned-imports +description: Forhindre bruk av forbudte biblioteker og krev anbefalte alternativer ved hjelp av en datadrevet mønsterliste. +--- + +Forhindre bruk av forbudte biblioteker og krev anbefalte alternativer. + +## Regeldetaljer + +Team forbyr ofte tunge eller utdaterte biblioteker til fordel for lettere eller native alternativer. Denne regelen bruker en datadrevet konfigurasjon -- en array med objekter som spesifiserer regex-monsteret, biblioteknavnet og det anbefalte alternativet. Å legge til et nytt forbud er en endring på en linje. + +## Eksempler på **feil** kode + +```typescript title="src/utils/date.ts" +import { format } from "moment"; +``` + +```typescript title="src/api/client.ts" +import axios from "axios"; +``` + +## Eksempler på **riktig** kode + +```typescript title="src/utils/date.ts" +import { format } from "date-fns"; +``` + +```typescript title="src/api/client.ts" +const response = await fetch("/api/data"); +``` + +## Regelimplementasjon + +```typescript +/// + +const BANNED_IMPORTS = [ + { + pattern: /from\s+['"]lodash['"]/, + name: "lodash", + alternative: "native array methods", + }, + { + pattern: /from\s+['"]moment['"]/, + name: "moment", + alternative: "Temporal API or date-fns", + }, + { + pattern: /from\s+['"]axios['"]/, + name: "axios", + alternative: "native fetch()", + }, +]; + +export default { + rules: { + "no-banned-imports": { + description: "Prevent usage of banned libraries", + async check(ctx) { + for (const banned of BANNED_IMPORTS) { + const matches = await ctx.grepFiles(banned.pattern, "src/**/*.ts"); + for (const match of matches) { + ctx.report.violation({ + message: `Banned import: "${banned.name}" is not allowed. Use ${banned.alternative} instead.`, + file: match.file, + line: match.line, + fix: `Replace ${banned.name} with ${banned.alternative}`, + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når bør du bruke den + +Når teamet ditt har standardisert på bestemte biblioteker og vil forhindre avvik mot alternativer. Vanlige forbud inkluderer lodash (native metoder), moment (date-fns eller Temporal) og axios (native fetch). + +## Når bør du ikke bruke den + +Når prosjektet ditt ikke har preferanser mellom biblioteker, eller når det forbudte biblioteket fremdeles er under aktiv migrering og noe bruk forventes midlertidig. diff --git a/docs/src/content/docs/nb/examples/no-barrel-files.mdx b/docs/src/content/docs/nb/examples/no-barrel-files.mdx new file mode 100644 index 00000000..e7f2bf45 --- /dev/null +++ b/docs/src/content/docs/nb/examples/no-barrel-files.mdx @@ -0,0 +1,106 @@ +--- +title: no-barrel-files +description: Oppdag og forby barrel-filer (index.ts med kun re-eksporter) for å kreve direkte importer og forbedre tree-shaking. +--- + +Oppdag og forby barrel-filer -- `index.ts`-filer som kun inneholder re-eksporter og ingen logikk. + +## Regeldetaljer + +Barrel-filer (re-eksport-bare `index.ts`) tilslorer hvor koden faktisk befinner seg, forringer tree-shaking, skaper risiko for sirkulære avhengigheter og gjor IDE-navigasjon tregere. Denne regelen bruker en tilpasset analysefunksjon for å avgjore om en `index.ts`-fil er en ren re-eksport-barrel ved å inspisere hver ikke-kommentar-, ikke-tom linje. + +## Eksempler på **feil** kode + +```typescript title="src/helpers/index.ts" +export { logInfo, logError } from "./log"; +export { resolvePaths } from "./paths"; +export type { PathConfig } from "./paths"; +``` + +En fil som kun re-eksporterer symboler fra andre moduler er en barrel-fil. + +## Eksempler på **riktig** kode + +```typescript title="src/helpers/index.ts" +export { logInfo, logError } from "./log"; +export { resolvePaths } from "./paths"; + +// This file has its own logic, so it is not a barrel +export function getHelperVersion(): string { + return "1.0.0"; +} +``` + +Eller enda bedre -- slett `index.ts` helt og importer direkte: + +```typescript +import { logInfo } from "./helpers/log"; +import { resolvePaths } from "./helpers/paths"; +``` + +## Regelimplementasjon + +```typescript +/// + +function isBarrelFile(content: string): boolean { + const lines = content + .split("\n") + .map((l) => l.trim()) + .filter( + (l) => + l !== "" && + !l.startsWith("//") && + !l.startsWith("/*") && + !l.startsWith("*") + ); + + if (lines.length === 0) return false; + + return lines.every( + (line) => + line.startsWith("export ") || + line.startsWith("export{") || + line.startsWith("import ") || + line.startsWith("} from") || + line.startsWith("type ") || + /^[A-Za-z_$,\s]+$/.test(line) || + line === "}" || + line === "};" + ); +} + +export default { + rules: { + "no-barrel-files": { + description: "index.ts files must not be pure re-export barrels", + async check(ctx) { + const indexFiles = ctx.scopedFiles.filter((f) => + f.endsWith("/index.ts") + ); + + const checks = indexFiles.map(async (file) => { + const content = await ctx.readFile(file); + if (isBarrelFile(content)) { + ctx.report.violation({ + message: `Barrel file detected: ${file} contains only re-exports and no logic.`, + file, + fix: "Delete this barrel file and update imports to point directly to the source module", + }); + } + }); + + await Promise.all(checks); + }, + }, + }, +} satisfies RuleSet; +``` + +## Når bør du bruke den + +Når du vil kreve direkte importer og unngå omveien som barrel-filer introduserer. Spesielt verdifullt i store kodebaser der barrel-filer forårsaker treg IDE-ytelse og gjor avhengighetsgrafer vanskeligere å forstå. + +## Når bør du ikke bruke den + +Når prosjektet ditt med vilje bruker barrel-filer som en offentlig API-grense (f.eks. et bibliotek som eksporterer en kuratert API fra `index.ts`). diff --git a/docs/src/content/docs/nb/examples/no-emoji-in-output.mdx b/docs/src/content/docs/nb/examples/no-emoji-in-output.mdx new file mode 100644 index 00000000..afacf4e9 --- /dev/null +++ b/docs/src/content/docs/nb/examples/no-emoji-in-output.mdx @@ -0,0 +1,99 @@ +--- +title: no-emoji-in-output +description: Forby emoji-tegn i CLI-utdata for konsistent visning på tvers av terminaler og tilgjengelighetsverktøy. +--- + +Forby emoji-tegn i CLI-utdata. + +## Regeldetaljer + +Emoji vises inkonsekvent på tvers av terminaler, bryter justering i monospace-utdata, og skaper problemer med skjermlesere og CI-loggparsere. Denne regelen bruker Unicode-område-regex for å oppdage emoji-tegn og en sekundær sjekk for å sikre at de forekommer inne i streng-literaler (ikke kommentarer eller variabelnavn). + +Regelen sjekker også for rå ANSI-escape-koder, og håndhever bruk av `styleText()` fra `node:util` for terminalformatering. + +## Eksempler på **feil** kode + +```typescript title="src/commands/check.ts" +console.log("✅ All checks passed!"); +console.log("❌ Validation failed"); +console.log("\x1b[32mSuccess\x1b[0m"); // raw ANSI +``` + +## Eksempler på **riktig** kode + +```typescript title="src/commands/check.ts" +import { styleText } from "node:util"; + +console.log("All checks passed"); +console.log("Validation failed"); +console.log(styleText("green", "Success")); +``` + +## Regelimplementasjon + +```typescript +/// + +const EMOJI_PATTERN = + /[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F900}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/u; +const EMOJI_IN_STRING = + /["'`].*[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F900}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}].*["'`]/u; + +export default { + rules: { + "no-emoji-in-output": { + description: "CLI output must not contain emoji characters", + async check(ctx) { + const files = ctx.scopedFiles.filter( + (f) => !f.includes("tests/") && !f.includes(".archgate/") + ); + const matches = await Promise.all( + files.map((file) => ctx.grep(file, EMOJI_PATTERN)) + ); + for (const fileMatches of matches) { + for (const m of fileMatches) { + if (EMOJI_IN_STRING.test(m.content)) { + ctx.report.violation({ + message: "Do not use emoji in CLI output strings", + file: m.file, + line: m.line, + fix: "Remove emoji from output strings", + }); + } + } + } + }, + }, + "use-style-text": { + description: "Use styleText from node:util instead of raw ANSI codes", + async check(ctx) { + const files = ctx.scopedFiles.filter( + (f) => !f.includes("tests/") && !f.includes(".archgate/") + ); + const matches = await Promise.all( + files.map((file) => ctx.grep(file, /\\u001b\[|\\x1b\[|\\033\[/)) + ); + for (const fileMatches of matches) { + for (const m of fileMatches) { + ctx.report.violation({ + message: + "Use styleText() from node:util instead of raw ANSI escape codes", + file: m.file, + line: m.line, + fix: "Import { styleText } from 'node:util' and use styleText(style, text)", + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når du bør bruke den + +I CLI-verktøy der konsistent utdata på tvers av terminaler er viktig, eller når tilgjengelighet har prioritet. + +## Når du ikke bør bruke den + +I webapplikasjoner eller verktøy der emoji er en del av det forventede brukergrensesnittet, eller når utdataene alltid konsumeres av mennesker i moderne terminaler. diff --git a/docs/src/content/docs/nb/examples/no-todo-comments.mdx b/docs/src/content/docs/nb/examples/no-todo-comments.mdx new file mode 100644 index 00000000..920e767a --- /dev/null +++ b/docs/src/content/docs/nb/examples/no-todo-comments.mdx @@ -0,0 +1,61 @@ +--- +title: no-todo-comments +description: Flagg TODO-, FIXME-, HACK- og XXX-kommentarer for å sikre at de løses før sammenslåing. +--- + +Flagg `TODO`-, `FIXME`-, `HACK`- og `XXX`-kommentarer slik at de løses før sammenslåing. + +## Regeldetaljer + +TODO-kommentarer er nyttige under utvikling, men bør ikke hope seg opp i hovedgrenen. Denne regelen bruker `ctx.grepFiles` for å skanne alle kildefiler etter vanlige oppgavemarkerings-kommentarer. Den bruker `warning`-alvorlighetsgrad slik at den ikke blokkerer CI, men gjør kommentarene synlige i hver sjekk. + +## Eksempler på **feil** kode + +```typescript title="src/helpers/git.ts" +// TODO: handle merge conflicts +// FIXME: this breaks on Windows +// HACK: workaround for upstream bug +// XXX: revisit this logic +``` + +## Eksempler på **riktig** kode + +```typescript title="src/helpers/git.ts" +// Proper implementation with no deferred work +``` + +## Regelimplementasjon + +```typescript +/// + +export default { + rules: { + "no-todo-comments": { + description: "TODO and FIXME comments should be resolved before merging", + severity: "warning", + async check(ctx) { + const matches = await ctx.grepFiles( + /\/\/\s*(TODO|FIXME|HACK|XXX):/i, + "src/**/*.ts" + ); + for (const match of matches) { + ctx.report.warning({ + message: `${match.content.trim()} — resolve before merging`, + file: match.file, + line: match.line, + }); + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når du bør bruke den + +Når du ønsker innsikt i utsatt arbeid og vil forhindre at TODO-kommentarer hoper seg opp over tid. Endre alvorlighetsgrad til `"error"` og bruk `ctx.report.violation()` for å gjøre den til en hard blokkering. + +## Når du ikke bør bruke den + +Når TODO-kommentarer er tilsiktet dokumentasjon (f.eks. sporet av et eget verktøy som oppretter saker fra TODO-kommentarer). diff --git a/docs/src/content/docs/nb/examples/no-unapproved-deps.mdx b/docs/src/content/docs/nb/examples/no-unapproved-deps.mdx new file mode 100644 index 00000000..a2b05e80 --- /dev/null +++ b/docs/src/content/docs/nb/examples/no-unapproved-deps.mdx @@ -0,0 +1,77 @@ +--- +title: no-unapproved-deps +description: Begrens produksjonsavhengigheter til en godkjent tillatelsesliste for å kontrollere forsyningskjederisiko og avhengighetsoppblåsing. +--- + +Begrens produksjonsavhengigheter til en godkjent tillatelsesliste. + +## Regeldetaljer + +Store avhengighetstrær øker forsyningskjederisiko og blåser opp pakkestørrelser. Denne regelen leser `package.json` og rapporterer enhver produksjonsavhengighet som ikke står på en eksplisitt tillatelsesliste. Utviklingsavhengigheter sjekkes ikke. + +## Eksempler på **feil** kode + +```json title="package.json" +{ "dependencies": { "zod": "^3.23.0", "chalk": "^5.3.0" } } +``` + +Hvis bare `zod` står på den godkjente listen, utløser `chalk` et brudd. + +## Eksempler på **riktig** kode + +```json title="package.json" +{ + "dependencies": { "zod": "^3.23.0" }, + "devDependencies": { "chalk": "^5.3.0" } +} +``` + +Alle produksjonsavhengigheter står på den godkjente listen. Biblioteker som bare trengs ved byggetidspunkt ligger i `devDependencies`. + +## Regelimplementasjon + +```typescript +/// + +const APPROVED_DEPS = [ + "@commander-js/extra-typings", + "inquirer", + "@modelcontextprotocol/sdk", + "zod", +]; + +export default { + rules: { + "no-unapproved-deps": { + description: "Production dependencies must be on the approved list", + async check(ctx) { + let pkg: { dependencies?: Record }; + try { + pkg = (await ctx.readJSON("package.json")) as typeof pkg; + } catch { + return; // No package.json — nothing to check + } + + const deps = Object.keys(pkg.dependencies ?? {}); + for (const dep of deps) { + if (!APPROVED_DEPS.includes(dep)) { + ctx.report.violation({ + message: `Unapproved production dependency: "${dep}". Approved: ${APPROVED_DEPS.join(", ")}`, + file: "package.json", + fix: `Either add "${dep}" to the approved list in the ADR or move it to devDependencies`, + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når du bør bruke den + +Når teamet ditt har en eksplisitt policy for avhengighetsstyring og ønsker å forhindre at ikke-godkjente pakker havner i produksjonspakken. + +## Når du ikke bør bruke den + +I prosjekter i tidlig fase der avhengighetslisten fortsatt utvikles raskt, eller når avhengighetsstyring håndteres av et eget verktøy som Socket eller Snyk. diff --git a/docs/src/content/docs/nb/examples/openapi-routes.mdx b/docs/src/content/docs/nb/examples/openapi-routes.mdx new file mode 100644 index 00000000..66cfd222 --- /dev/null +++ b/docs/src/content/docs/nb/examples/openapi-routes.mdx @@ -0,0 +1,108 @@ +--- +title: openapi-routes +description: Sørg for at alle backend-rutefiler bruker OpenAPI-typede rutedefinisjoner i stedet for rå HTTP-metodebehandlere. +--- + +Sørg for at alle backend-rutefiler bruker OpenAPI-typede rutedefinisjoner. + +## Regeldetaljer + +Når et backend-rammeverk støtter OpenAPI-integrasjon (f.eks. `@hono/zod-openapi`), omgår rå HTTP-metodebehandlere (`.get()`, `.post()`) skjemavalidering og dokumentasjonsgenerering. Denne regelen sjekker at rutefiler importerer OpenAPI-integrasjonen og bruker `.openapi()` i stedet for rå metoder. + +## Eksempler på **feil** kode + +```typescript title="packages/backend/src/routes/users.ts" +import { Hono } from "hono"; + +const app = new Hono(); + +app.get("/users", async (c) => { + // No OpenAPI schema, no auto-generated docs + return c.json(await getUsers()); +}); +``` + +## Eksempler på **riktig** kode + +```typescript title="packages/backend/src/routes/users.ts" +import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi"; + +const route = createRoute({ + method: "get", + path: "/users", + responses: { + 200: { + content: { "application/json": { schema: UserListSchema } }, + description: "List of users", + }, + }, +}); + +app.openapi(route, async (c) => { + return c.json(await getUsers()); +}); +``` + +## Regelimplementasjon + +```typescript +/// + +export default { + rules: { + "openapi-route-completeness": { + description: + "All backend routes must use @hono/zod-openapi, not raw HTTP methods", + async check(ctx) { + const routeFiles = await ctx.glob("packages/backend/src/routes/*.ts"); + + for (const file of routeFiles) { + if (file.includes(".test.") || file.includes(".spec.")) continue; + + const content = await ctx.readFile(file); + + const importsOpenApi = /from\s+["']@hono\/zod-openapi["']/.test( + content + ); + const hasRawMethods = /\.(?:get|post|put|delete|patch)\s*\(/.test( + content + ); + const hasOpenApiCalls = /\.openapi\s*\(/.test(content); + + if (!importsOpenApi && hasRawMethods) { + ctx.report.violation({ + message: `Route file uses raw HTTP methods without importing @hono/zod-openapi`, + file, + fix: "Import from @hono/zod-openapi and use .openapi() instead of raw .get()/.post()", + }); + } + + if (importsOpenApi && hasRawMethods && !hasOpenApiCalls) { + ctx.report.violation({ + message: `Route file imports @hono/zod-openapi but uses raw HTTP methods instead of .openapi()`, + file, + fix: "Replace raw .get()/.post() calls with .openapi() route definitions", + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når du bør bruke den + +Når backend-rammeverket ditt støtter OpenAPI-integrasjon og du vil sikre at alle ruter er dokumentert og skjemavalidert. Tilpass importmønsteret og metodedeteksjonen for ditt rammeverk: + +```typescript +// For Express with express-openapi-validator +/from\s+["']express-openapi-validator["']/ + +// For Fastify with @fastify/swagger +/from\s+["']@fastify\/swagger["']/ +``` + +## Når du ikke bør bruke den + +Når ikke alle ruter krever OpenAPI-dokumentasjon (f.eks. interne helsesjekker, metrikk-endepunkter), eller når OpenAPI-spesifikasjoner vedlikeholdes separat fra rutekoden. diff --git a/docs/src/content/docs/nb/examples/page-component-constraints.mdx b/docs/src/content/docs/nb/examples/page-component-constraints.mdx new file mode 100644 index 00000000..04062a6c --- /dev/null +++ b/docs/src/content/docs/nb/examples/page-component-constraints.mdx @@ -0,0 +1,117 @@ +--- +title: page-component-constraints +description: Håndhev at sidekomponenter er tynne layout-innpakninger ved å begrense størrelsen og forby datahentings-hooks. +--- + +Håndhev at sidekomponenter er tynne layout-innpakninger -- små i størrelse og fri for datahentingslogikk. + +## Regeldetaljer + +I frontend-arkitekturer som skiller ruting fra logikk, bør sidekomponenter bare sette sammen layout og delegere datahenting til Connected-komponenter. Denne regelen håndhever to begrensninger i en enkelt regelfil: + +1. **Størrelsesgrense** -- Sidekomponenter må holde seg under et konfigurerbart linjetall (standard: 75 linjer). +2. **Ingen data-hooks** -- Sidekomponenter må ikke bruke `useState`, `useQuery`, `useMutation` eller andre datahentings-hooks direkte. + +## Eksempler på **feil** kode + +```tsx title="src/pages/DashboardPage.tsx" +import { useQuery } from "@tanstack/react-query"; +import { useState } from "react"; + +export default function DashboardPage() { + const [filter, setFilter] = useState(""); // ✗ state hook + const { data } = useQuery({ queryKey: ["dashboard"] }); // ✗ data hook + // ... 120 lines of layout + logic +} +``` + +## Eksempler på **riktig** kode + +```tsx title="src/pages/DashboardPage.tsx" +import { DashboardConnected } from "../components/DashboardConnected"; +import { Sidebar } from "../components/Sidebar"; + +export default function DashboardPage() { + return ( +
+ + +
+ ); +} +``` + +## Regelimplementasjon + +```typescript +/// + +const PAGE_MAX_LINES = 75; + +export default { + rules: { + "page-max-lines": { + description: `Page components must be under ${PAGE_MAX_LINES} lines`, + async check(ctx) { + const pageFiles = await ctx.glob("src/pages/*Page.tsx"); + + for (const file of pageFiles) { + if (file.includes(".test.")) continue; + + const content = await ctx.readFile(file); + const lineCount = content.split("\n").length; + + if (lineCount > PAGE_MAX_LINES) { + ctx.report.violation({ + message: `Page component has ${lineCount} lines (max ${PAGE_MAX_LINES}). Extract logic to Connected components.`, + file, + fix: "Move data-fetching and business logic to Connected components", + }); + } + } + }, + }, + "page-no-data-hooks": { + description: "Page components must not use data-fetching or state hooks", + async check(ctx) { + const pageFiles = await ctx.glob("src/pages/*Page.tsx"); + + const FORBIDDEN_HOOKS = + /\b(useState|useForm|useQuery|useMutation|useSuspenseQuery|useInfiniteQuery)\s*[<(]/g; + + const ALLOWED_HOOKS = new Set([ + "useParams", + "useNavigate", + "useRouter", + "useMatch", + "useLocation", + "useSearch", + ]); + + for (const file of pageFiles) { + if (file.includes(".test.")) continue; + + const content = await ctx.readFile(file); + + let match; + while ((match = FORBIDDEN_HOOKS.exec(content)) !== null) { + ctx.report.violation({ + message: `Page component uses "${match[1]}" hook. Extract to a Connected component.`, + file, + fix: `Move the "${match[1]}" hook to a Connected component`, + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når du bør bruke den + +Når frontend-arkitekturen din følger page/container/presentational-mønsteret og du vil håndheve at sider forblir tynne rutingsendepunkter. Juster `PAGE_MAX_LINES` og hook-listene for ditt rammeverk. + +## Når du ikke bør bruke den + +Når sider forventes å inneholde logikk (f.eks. i Next.js server-komponenter der datahenting i siden er idiomatisk), eller når prosjektet ditt ikke følger dette arkitekturmønsteret. diff --git a/docs/src/content/docs/nb/examples/required-export-pattern.mdx b/docs/src/content/docs/nb/examples/required-export-pattern.mdx new file mode 100644 index 00000000..c807c6e2 --- /dev/null +++ b/docs/src/content/docs/nb/examples/required-export-pattern.mdx @@ -0,0 +1,82 @@ +--- +title: required-export-pattern +description: Verifiser at filer i en spesifikk mappe eksporterer en påkrevd funksjonssignatur for å håndheve konsistent modulstruktur. +--- + +Verifiser at filer i en spesifikk mappe eksporterer en påkrevd funksjonssignatur. + +## Regeldetaljer + +Konvensjonsbaserte arkitekturer (CLI-kommandofiler, rutebehandlere, pluginmoduler) krever ofte at hver fil eksporterer en funksjon med et spesifikt navnemønster. Denne regelen skanner omfangsfiler etter en påkrevd eksport og rapporterer enhver fil som ikke samsvarer. Den bruker `Promise.all()` for å sjekke filer parallelt for ytelse. + +## Eksempler på **feil** kode + +```typescript title="src/commands/deploy.ts" +// Missing the required register*Command export +export function deploy() { + // ... +} +``` + +## Eksempler på **riktig** kode + +```typescript title="src/commands/deploy.ts" +import type { Command } from "commander"; + +export function registerDeployCommand(program: Command) { + program + .command("deploy") + .description("Deploy the application") + .action(() => { + // ... + }); +} +``` + +## Regelimplementasjon + +```typescript +/// + +export default { + rules: { + "register-function-export": { + description: "Command files must export a register*Command function", + async check(ctx) { + const files = ctx.scopedFiles.filter((f) => !f.endsWith("index.ts")); + const checks = files.map(async (file) => { + const content = await ctx.readFile(file); + if (!/export\s+function\s+register\w+Command/.test(content)) { + ctx.report.violation({ + message: "Command file must export a register*Command function", + file, + }); + } + }); + await Promise.all(checks); + }, + }, + }, +} satisfies RuleSet; +``` + +Tilpass mønsteret for andre konvensjoner: + +```typescript +// Express/Hono route handlers +/export\s+default\s+.*Router/ + +// React page components +/export\s+default\s+function\s+\w+Page/ + +// Plugin modules +/export\s+const\s+plugin\s*[:=]/ +``` + +## Når du bør bruke den + +Når arkitekturen din krever et spesifikt eksportmønster fra filer i en mappe. Kombiner denne med ADR-ens `files`-frontmatter-felt for å avgrense den til riktig mappe. + +## Når du ikke bør bruke den + +Når mappen inneholder blandede filtyper som ikke alle trenger å følge det samme eksportmønsteret. diff --git a/docs/src/content/docs/nb/examples/spdx-license-headers.mdx b/docs/src/content/docs/nb/examples/spdx-license-headers.mdx new file mode 100644 index 00000000..9d5f2262 --- /dev/null +++ b/docs/src/content/docs/nb/examples/spdx-license-headers.mdx @@ -0,0 +1,99 @@ +--- +title: spdx-license-headers +description: Håndhev SPDX-License-Identifier-hoder i alle kildefiler for lisensklarhet per fil og kompatibilitet med samsvarsskannere. +--- + +Sørg for at hver kildefil deklarerer lisensen sin med en maskinlesbar SPDX-identifikator. + +## Regeldetaljer + +Åpen kildekode-prosjekter drar nytte av lisensdeklarasjoner per fil -- de overlever filutpakking, bunting og kopier-og-lim-scenarier der rot-LICENSE-filen ikke er til stede. Denne regelen verifiserer at hver TypeScript-kildefil starter med standard SPDX-hodekommentar. + +## Eksempler på **feil** kode + +```typescript title="src/helpers/utils.ts" +import { join } from "node:path"; + +export function resolvePath(base: string, rel: string): string { + return join(base, rel); +} +``` + +Filen mangler SPDX-lisensidentifikator-hodet. + +## Eksempler på **riktig** kode + +```typescript title="src/helpers/utils.ts" +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2026 Archgate +import { join } from "node:path"; + +export function resolvePath(base: string, rel: string): string { + return join(base, rel); +} +``` + +For filer med en shebang: + +```typescript title="src/cli.ts" +#!/usr/bin/env bun +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2026 Archgate +import { Command } from "commander"; +``` + +## Regelimplementasjon + +```typescript +/// + +export default { + rules: { + "spdx-header-present": { + description: + "All TypeScript source files must have an SPDX-License-Identifier header", + async check(ctx) { + const results = await Promise.all( + ctx.scopedFiles.map(async (file) => { + const content = await ctx.readFile(file); + return { file, content }; + }) + ); + + for (const { file, content } of results) { + if (content === null) continue; + + // Check first 5 lines for the SPDX identifier (allows for shebang) + const lines = content.split("\n").slice(0, 5); + const hasSpdx = lines.some((line) => + line.includes("SPDX-License-Identifier: Apache-2.0") + ); + + if (!hasSpdx) { + ctx.report.violation({ + message: "Missing SPDX-License-Identifier header.", + file, + line: 1, + fix: 'Add "// SPDX-License-Identifier: Apache-2.0" as the first line of the file', + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Tilpasning + +- **Endre lisensen**: Erstatt `Apache-2.0` med prosjektets SPDX-identifikator (f.eks. `MIT`, `BSD-3-Clause`) +- **Endre omfanget**: Juster `files`-glob-en i ADR-frontmatteren for å samsvare med kildekatalogene dine +- **Legg til opphavsrettssjekk**: Utvid regelen til også å verifisere opphavsrettslinje-formatet + +## Når du bør bruke den + +Når prosjektet ditt er åpen kildekode og du ønsker entydige lisensdeklarasjoner per fil som gjenkjennes av samsvarsskannere (FOSSA, Snyk, Black Duck, npm license-checker). + +## Når du ikke bør bruke den + +I proprietære/lukkede prosjekter der alle filer implisitt er "alle rettigheter forbeholdt", eller når organisasjonen din bruker en annen lisensdeklarasjonsmekanisme som REUSE 3.0 `.dep5`-filer. diff --git a/docs/src/content/docs/nb/examples/test-file-coverage.mdx b/docs/src/content/docs/nb/examples/test-file-coverage.mdx new file mode 100644 index 00000000..dc41158d --- /dev/null +++ b/docs/src/content/docs/nb/examples/test-file-coverage.mdx @@ -0,0 +1,82 @@ +--- +title: test-file-coverage +description: Verifiser at hver kildefil har en tilhørende testfil for å forhindre at utestet kode blir sammenslått. +--- + +Verifiser at hver kildefil har en tilhørende testfil. + +## Regeldetaljer + +Utestet kode er en risiko. Denne regelen håndhever en strukturell konvensjon: for hver fil i `src/` må en matchende `.test.ts`-fil finnes i `tests/`. Den bruker `ctx.glob` for å oppdage eksisterende testfiler, bygger et oppslagssett for rask matching, og rapporterer enhver kildefil uten en motpart. + +## Eksempler på **feil** kode + +``` +src/ + helpers/ + log.ts ← has a test ✓ + paths.ts ← no test file ✗ +tests/ + helpers/ + log.test.ts +``` + +## Eksempler på **riktig** kode + +``` +src/ + helpers/ + log.ts + paths.ts +tests/ + helpers/ + log.test.ts + paths.test.ts +``` + +## Regelimplementasjon + +```typescript +/// +import { relative } from "node:path"; + +export default { + rules: { + "test-file-exists": { + description: "Every source file should have a corresponding test file", + severity: "warning", + async check(ctx) { + for (const file of ctx.scopedFiles) { + const rel = relative(ctx.projectRoot, file); + const testPath = rel + .replace(/^src\//, "tests/") + .replace(/\.ts$/, ".test.ts"); + const testFiles = await ctx.glob(testPath); + if (testFiles.length === 0) { + ctx.report.warning({ + message: `No test file found at ${testPath}`, + file, + fix: `Create a test file at ${testPath}`, + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +For å tilpasse til prosjekter som plasserer tester ved siden av kildefilene: + +```typescript +const testPath = rel.replace(/\.ts$/, ".test.ts"); +// src/helpers/log.ts → src/helpers/log.test.ts +``` + +## Når du bør bruke den + +Når teamet ditt følger en konvensjon om at hver kildemodul må ha en tilhørende testfil, og du ønsker å fange opp manglende tester under kodegjennomgang. + +## Når du ikke bør bruke den + +Når testdekning spores på andre måter (f.eks. dekningsgrenser i CI), eller når noen kildefiler genuint ikke trenger tester (kun-type-filer, konstanter). diff --git a/docs/src/content/docs/nb/examples/version-catalog.mdx b/docs/src/content/docs/nb/examples/version-catalog.mdx new file mode 100644 index 00000000..154edfdb --- /dev/null +++ b/docs/src/content/docs/nb/examples/version-catalog.mdx @@ -0,0 +1,143 @@ +--- +title: version-catalog +description: Håndhev sentralisert versjonsadministrasjon i monorepoer ved å kreve catalog- eller workspace-notasjon for alle avhengigheter. +--- + +Håndhev sentralisert versjonsadministrasjon i monorepoer ved å kreve `catalog:`- eller `workspace:`-notasjon for alle avhengigheter. + +## Regeldetaljer + +I monorepoer med mange pakker fører duplisering av versjonsstrenger på tvers av `package.json`-filer til versjonsforskyvning og oppgraderingssmerter. Denne regelen sikrer at hver avhengighetsreferanse bruker `catalog:` (hentet fra en sentral katalog i rot-`package.json`) eller `workspace:` (for interne pakker), aldri en rå semver-streng. + +Regelen har to sjekker: `catalog-usage` verifiserer at alle avhengigheter bruker riktig notasjon, og `catalog-completeness` verifiserer at hver `catalog:`-referanse peker til en faktisk oppføring i rotkatalogen. + +## Eksempler på **feil** kode + +```json title="packages/api/package.json" +{ "dependencies": { "zod": "^3.23.0", "hono": "^4.0.0" } } +``` + +Rå semver-strenger omgår den sentrale katalogen og vil divergere på tvers av pakker. + +## Eksempler på **riktig** kode + +```json title="packages/api/package.json" +{ + "dependencies": { + "zod": "catalog:", + "hono": "catalog:", + "@myorg/shared": "workspace:*" + } +} +``` + +```json title="package.json (root)" +{ "catalog": { "zod": "^3.23.0", "hono": "^4.0.0" } } +``` + +Alle versjoner administreres sentralt. Oppgradering av `zod` krever bare endring av rotkatalogen. + +## Regelimplementasjon + +```typescript +/// + +export default { + rules: { + "catalog-usage": { + description: + 'All workspace dependencies must use "catalog:" or "workspace:" notation', + async check(ctx) { + const packageJsonFiles = [ + ...(await ctx.glob("packages/*/package.json")), + ...(await ctx.glob("packages/*/*/package.json")), + ]; + + for (const file of packageJsonFiles) { + const pkg = (await ctx.readJSON(file)) as Record; + for (const depType of [ + "dependencies", + "devDependencies", + "peerDependencies", + ]) { + const deps = pkg[depType] as Record | undefined; + if (!deps) continue; + + for (const [name, version] of Object.entries(deps)) { + if ( + typeof version === "string" && + !version.startsWith("catalog:") && + !version.startsWith("workspace:") + ) { + ctx.report.violation({ + message: `${file}: ${depType}.${name} uses "${version}" instead of "catalog:" or "workspace:"`, + file, + fix: `Change to "catalog:" and ensure the package is listed in root package.json catalog`, + }); + } + } + } + } + }, + }, + "catalog-completeness": { + description: + "All catalog: references must resolve to entries in root package.json catalog", + async check(ctx) { + const rootPkg = (await ctx.readJSON("package.json")) as Record< + string, + unknown + >; + const catalog = (rootPkg.catalog ?? {}) as Record; + const catalogKeys = new Set(Object.keys(catalog)); + + const packageJsonFiles = [ + ...(await ctx.glob("packages/*/package.json")), + ...(await ctx.glob("packages/*/*/package.json")), + ]; + + for (const file of packageJsonFiles) { + const pkg = (await ctx.readJSON(file)) as Record; + for (const depType of [ + "dependencies", + "devDependencies", + "peerDependencies", + ]) { + const deps = pkg[depType] as Record | undefined; + if (!deps) continue; + + for (const [name, version] of Object.entries(deps)) { + if ( + typeof version !== "string" || + !version.startsWith("catalog:") + ) + continue; + + const catalogRef = + version === "catalog:" + ? name + : version.slice("catalog:".length); + + if (!catalogKeys.has(catalogRef)) { + ctx.report.violation({ + message: `${file}: ${depType}.${name} references catalog:${catalogRef} but it is not in root catalog`, + file, + fix: `Add "${catalogRef}" to the catalog section in the root package.json`, + }); + } + } + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når du bør bruke den + +I monorepoer der flere pakker deler avhengigheter og du ønsker en enkelt sannhetskilde for versjoner (f.eks. Bun workspaces med katalogstøtte, eller lignende oppsett). + +## Når du ikke bør bruke den + +I enkeltpakke-repositorier eller monorepoer som bruker en annen versjonsstyringstrategi som Renovates gruppeoppdateringer. diff --git a/docs/src/content/docs/nb/examples/wrapper-enforcement.mdx b/docs/src/content/docs/nb/examples/wrapper-enforcement.mdx new file mode 100644 index 00000000..2e1f94d9 --- /dev/null +++ b/docs/src/content/docs/nb/examples/wrapper-enforcement.mdx @@ -0,0 +1,79 @@ +--- +title: wrapper-enforcement +description: Håndhev bruk av en prosjektinnpakning eller hjelper i stedet for et rått plattform-API, med automatisk ekskludering av innpakningsfilen selv. +--- + +Håndhev bruk av en prosjektinnpakning i stedet for et rått plattform-API. + +## Regeldetaljer + +Når et prosjekt tilbyr en hjelper som normaliserer et lavnivå-API (f.eks. en `platform.ts`-hjelper som innpakker `process.platform`), bør direkte bruk av det rå API-et forbys overalt unntatt i innpakningen selv. Denne regelen skanner omfangsfiler etter det rå API-kallet og ekskluderer automatisk hjelpefilen og ikke-produksjonskode. + +## Eksempler på **feil** kode + +```typescript title="src/commands/build.ts" +if (process.platform === "win32") { + // Windows-specific logic +} +``` + +## Eksempler på **riktig** kode + +```typescript title="src/commands/build.ts" +import { isWindows } from "../helpers/platform"; + +if (isWindows()) { + // Windows-specific logic +} +``` + +## Regelimplementasjon + +```typescript +/// + +export default { + rules: { + "no-direct-process-platform": { + description: + "Platform detection must use src/helpers/platform.ts, not process.platform directly", + async check(ctx) { + const files = ctx.scopedFiles.filter( + (f) => + !f.includes("tests/") && + !f.includes(".archgate/") && + !f.endsWith("src/helpers/platform.ts") // Exclude the wrapper itself + ); + + const matches = await Promise.all( + files.map((file) => ctx.grep(file, /process\.platform/)) + ); + for (const fileMatches of matches) { + for (const m of fileMatches) { + ctx.report.violation({ + message: + "Do not access process.platform directly — use isWindows(), isMacOS(), or isLinux() from src/helpers/platform.ts instead.", + file: m.file, + line: m.line, + fix: 'Import { isWindows } from "../helpers/platform" and use it instead of process.platform', + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +## Når du bør bruke den + +Når prosjektet ditt har en innpakning eller hjelpemodul som normaliserer et rått API og du vil forhindre direkte tilgang til det underliggende API-et. Vanlige eksempler: + +- `platform.ts` som innpakker `process.platform` +- `logger.ts` som innpakker `console.log` / `console.error` +- `fs.ts` som innpakker `node:fs` med prosjektspesifikke standardverdier +- `env.ts` som innpakker `process.env` med typede aksessorer + +## Når du ikke bør bruke den + +Når det rå API-et er enkelt nok til at en innpakning ikke tilfører verdi, eller når innpakningen ennå ikke er tatt i bruk på tvers av kodebasen (vurder å bruke `warning`-alvorlighetsgrad under migrering). diff --git a/docs/src/content/docs/nb/getting-started/installation.mdx b/docs/src/content/docs/nb/getting-started/installation.mdx new file mode 100644 index 00000000..c4871b7a --- /dev/null +++ b/docs/src/content/docs/nb/getting-started/installation.mdx @@ -0,0 +1,161 @@ +--- +title: Installasjon +description: Installer Archgate CLI på macOS, Linux eller Windows via en enlinje-installatør, npm eller frittstående binærfil. Begynn å håndheve ADR-er som kjørbare koderegler på minutter. +--- + +## Frittstående installasjon (anbefalt) + +Den raskeste måten å installere Archgate på -- ingen Node.js eller pakkebehandler nødvendig: + +```bash +# macOS / Linux +curl -fsSL https://cli.archgate.dev/install-unix | sh + +# Windows (PowerShell) +irm https://cli.archgate.dev/install-windows | iex + +# Windows (Git Bash / MSYS2) +curl -fsSL https://cli.archgate.dev/install-unix | sh +``` + +Dette laster ned en forhåndskompilert binærfil for din plattform og installerer den til `~/.archgate/bin/`. Installatøren oppdager shell-profilene dine og tilbyr å legge mappen til PATH. + +På Windows oppdager PowerShell-installatøren også Git Bash shell-profiler (`.bashrc`, `.bash_profile`, `.profile`) og tilbyr å konfigurere PATH der også. + +Du kan tilpasse installasjonen med miljøvariabler: + +| Variabel | Beskrivelse | Standard | +| ---------------------- | ----------------------------------------------- | ----------------- | +| `ARCHGATE_VERSION` | Installer en bestemt versjon (f.eks. `v0.11.2`) | Siste versjon | +| `ARCHGATE_INSTALL_DIR` | Egendefinert installasjonsmappe | `~/.archgate/bin` | + +Du kan også laste ned binærfiler direkte fra [GitHub Releases](https://github.com/archgate/cli/releases). + +## Installer via npm + +Installer Archgate globalt med din foretrukne Node.js-pakkebehandler: + +```bash +# npm +npm install -g archgate + +# Bun +bun install -g archgate + +# Yarn +yarn global add archgate + +# pnpm +pnpm add -g archgate +``` + +Dette installerer en lettvekts-wrapper som delegerer til en plattformspesifikk binærfil. CLI-en er en frittstående binærfil kompilert med Bun -- Node.js trengs bare for npm/yarn/pnpm-wrapperen. + +## Installer som utviklingsavhengighet + +Du kan også legge til Archgate som en utviklingsavhengighet i prosjektet ditt og kjøre den gjennom pakkebehandlerens script runner. Dette er nyttig for å låse en bestemt versjon per prosjekt eller kjøre sjekker i CI uten global installasjon. + +```bash +# npm +npm install -D archgate + +# Bun +bun add -d archgate + +# Yarn +yarn add -D archgate + +# pnpm +pnpm add -D archgate +``` + +Deretter kjører du Archgate via pakkebehandleren din: + +```bash +# npm / Yarn / pnpm +npx archgate check + +# Bun +bun run archgate check +``` + +Eller legg til et script i `package.json`: + +```json +{ "scripts": { "check:adrs": "archgate check" } } +``` + +```bash +# Works with any package manager +npm run check:adrs +bun run check:adrs +yarn check:adrs +pnpm check:adrs +``` + +## Plattformstøtte + +Archgate leverer forhåndskompilerte binærfiler for følgende plattformer: + +| Plattform | Arkitektur | Artefakt | +| --------- | ---------- | ----------------------- | +| macOS | arm64 | `archgate-darwin-arm64` | +| Linux | x86_64 | `archgate-linux-x64` | +| Windows | x86_64 | `archgate-win32-x64` | + +Riktig binærfil lastes ned automatisk fra GitHub Releases ved første kjøring og hurtiglagres i `~/.archgate/bin/`. + +## Verifiser installasjonen + +```bash +archgate --version +``` + +Du bør se den installerte versjonen skrevet ut til stdout. + +## Installer via proto + +Hvis du bruker [proto](https://moonrepo.dev/proto) (moonrepos verktøykjedebehandler), kan du installere Archgate direkte som en proto-plugin -- ingen Node.js eller npm nødvendig. + +Legg til pluginen i `.prototools`: + +```toml +[plugins.tools] +archgate = "github://archgate/proto-plugin" +``` + +Deretter installerer og bruker du den som et hvilket som helst annet proto-verktøy: + +```bash +proto install archgate +archgate check +``` + +Proto administrerer binærfilen for deg, inkludert versjonslåsing og automatisk installasjon. For å låse en bestemt versjon, legg den til i roten av `.prototools`: + +```toml +archgate = "0.15.0" + +[plugins.tools] +archgate = "github://archgate/proto-plugin" +``` + +Du kan også liste tilgjengelige versjoner og administrere installasjoner med proto-kommandoer: + +```bash +proto list-remote archgate # liste tilgjengelige versjoner +proto install archgate 0.15.0 # installere en bestemt versjon +proto pin archgate 0.15.0 # låse versjon i .prototools +``` + +:::note[Bruker du npm globals med proto?] +Hvis du foretrekker `npm install -g archgate` i stedet for proto-pluginen, må du konfigurere proto til å eksponere globale npm-binærfiler. Legg til `shared-globals-dir = true` under `[tools.npm]` i `~/.proto/config.toml`, og legg deretter til `$HOME/.proto/tools/node/globals/bin` i shell-PATHen din. +::: + +## Neste steg + +Etter installasjonen, kjør `archgate init` i prosjektet ditt for å sette opp styring. Se guiden [Hurtigstart](/getting-started/quick-start/) for en gjennomgang. + +:::tip[Editorplugins (beta)] +Vil du at AI-agenten din skal lese ADR-er før den koder og validere etterpå? Editorpluginene for [Claude Code](/guides/claude-code-plugin/) og [Cursor](/guides/cursor-integration/) legger til en komplett styringsarbeidsflyt på toppen av CLI-en. Kjør `archgate login` for å registrere deg og komme i gang. +::: diff --git a/docs/src/content/docs/nb/getting-started/quick-start.mdx b/docs/src/content/docs/nb/getting-started/quick-start.mdx new file mode 100644 index 00000000..c6e35bc9 --- /dev/null +++ b/docs/src/content/docs/nb/getting-started/quick-start.mdx @@ -0,0 +1,146 @@ +--- +title: Hurtigstart +description: Kom i gang med Archgate på under 5 minutter. Initialiser et prosjekt, opprett din første ADR, skriv samsvarregler, og kjør automatiserte arkitektursjekker. +--- + +## 1. Installer Archgate + +Hvis du ikke har installert CLI-en ennå: + +```bash +# Standalone (no Node.js required) +curl -fsSL https://cli.archgate.dev/install-unix | sh + +# Or via npm +npm install -g archgate +``` + +Se [Installasjon](/getting-started/installation/)-siden for alle alternativer, inkludert Windows og egendefinerte installasjonsmapper. + +## 2. Initialiser prosjektet ditt + +Naviger til prosjektroten din og kjør `init`-kommandoen: + +```bash +cd my-project +archgate init +``` + +Dette oppretter `.archgate/`-mappen med følgende struktur: + +``` +.archgate/ + adrs/ + ARCH-001-example.md # Example ADR + ARCH-001-example.rules.ts # Example rules file + lint/ + archgate.config.ts # Archgate configuration +``` + +De genererte filene gir deg et fungerende eksempel å bygge videre på. + +## 3. Rediger eksempel-ADR-en + +Åpne `.archgate/adrs/ARCH-001-example.md`. Hver ADR starter med YAML frontmatter som definerer identiteten: + +```yaml +--- +id: ARCH-001 +title: Example Decision +domain: architecture +rules: true +files: ["src/**/*.ts"] +--- +``` + +- **id** -- Unik identifikator. Konvensjonen er `ARCH-NNN`, men enhver streng fungerer. +- **title** -- Lesbart navn for beslutningen. +- **domain** -- Grupperer relaterte ADR-er (`architecture`, `backend`, `frontend`, `data` eller `general`). +- **rules** -- Sett til `true` hvis denne ADR-en har en tilhørende `.rules.ts`-fil med automatiserte sjekker. +- **files** -- Valgfrie glob-mønstre som begrenser hvilke filer reglene gjelder for. + +Under frontmatter skriver du beslutningen i markdown. Archgate pålegger ikke en bestemt seksjonsstruktur, men de anbefalte seksjonene er: Context, Decision, Do's and Don'ts, Consequences, Compliance og References. + +## 4. Legg til en tilhørende regelfil + +Opprett en `.rules.ts`-fil ved siden av ADR-en med samme navneprefiks. Regler skrives i TypeScript med `RuleSet`-typen: + +```typescript +/// + +export default { + rules: { + "no-console-error": { + description: "Use logError() instead of console.error()", + async check(ctx) { + for (const file of ctx.scopedFiles) { + const matches = await ctx.grep(file, /console\.error\(/); + for (const match of matches) { + ctx.report.violation({ + message: "Use logError() instead of console.error()", + file: match.file, + line: match.line, + fix: "Import logError from your helpers and use it instead", + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +Hver regel har en unik nøkkel, en beskrivelse og en asynkron `check`-funksjon. Inne i `check` har du tilgang til: + +- **`ctx.scopedFiles`** -- Filer som matcher ADR-ens `files` glob-mønstre. +- **`ctx.grep(file, pattern)`** -- Søk i en fil etter regex-treff, returnerer filstier og linjenumre. +- **`ctx.report.violation()`** -- Rapporter et brudd med melding, filsti, linjenummer og valgfritt rettingsforslag. + +## 5. Kjør sjekker + +Kjør samsvarssjekken mot kodebasen din: + +```bash +archgate check +``` + +Archgate laster inn hver ADR med `rules: true`, kjører den tilhørende regelfilen og skriver ut resultatene. Avslutningskoden forteller deg utfallet: + +| Avslutningskode | Betydning | +| --------------- | --------------------------------------------------- | +| 0 | Alle regler bestått. Ingen brudd funnet. | +| 1 | Ett eller flere brudd oppdaget. | +| 2 | Intern feil (f.eks. feilformatert ADR eller regel). | + +For å sjekke bare staged-filer (nyttig i pre-commit hooks eller CI): + +```bash +archgate check --staged +``` + +## Hva nå? + +Nå som du har et fungerende oppsett, kan du dykke dypere: + +**Forstå konseptene:** + +- [ADR-er](/concepts/adrs/) -- Hva Architecture Decision Records er og hvordan Archgate bruker dem. +- [Regler](/concepts/rules/) -- Hvordan tilhørende `.rules.ts`-filer gjør beslutninger om til automatiserte sjekker. +- [Domener](/concepts/domains/) -- Hvordan domener grupperer relaterte ADR-er og begrenser filtilordning. + +**Skriv dine egne:** + +- [Skrive ADR-er](/guides/writing-adrs/) -- Lær det fullstendige ADR-formatet og beste praksis for å skrive effektive beslutninger. +- [Skrive regler](/guides/writing-rules/) -- Utforsk regel-API-et, avanserte mønstre og hvordan du tester reglene dine. +- [Vanlige regelmønstre](/examples/common-rule-patterns/) -- Mønstre du kan kopiere og lime inn for avhengighetssjekker, navnekonvensjoner og mer. + +**Integrer i arbeidsflyten din:** + +- [CI-integrasjon](/guides/ci-integration/) -- Koble `archgate check` til GitHub Actions, GitLab CI eller en hvilken som helst pipeline. +- [Pre-commit Hooks](/guides/pre-commit-hooks/) -- Kjør sjekker lokalt før hver commit. +- [Claude Code-plugin](/guides/claude-code-plugin/) -- Gi AI-agenter en komplett styringsarbeidsflyt med rollebaserte ferdigheter. +- [Cursor-integrasjon](/guides/cursor-integration/) -- Bruk Archgate med Cursor IDE for AI-assistert utvikling. + +:::tip[Editorplugins (beta)] +Vil du ha AI-agenter som automatisk leser ADR-ene dine før de koder? Kjør `archgate login` for å registrere deg og autentisere, deretter kjør `archgate init --install-plugin` for å sette opp pluginen. +::: diff --git a/docs/src/content/docs/nb/guides/ci-integration.mdx b/docs/src/content/docs/nb/guides/ci-integration.mdx new file mode 100644 index 00000000..9f925dbb --- /dev/null +++ b/docs/src/content/docs/nb/guides/ci-integration.mdx @@ -0,0 +1,291 @@ +--- +title: CI-integrasjon +description: Integrer Archgate-samsvarsjekker i GitHub Actions, GitLab CI eller hvilken som helst CI/CD-pipeline. Blokker sammenslåinger når arkitekturregler brytes. +--- + +Archgate-sjekker passer inn i ethvert CI-system som respekterer exit-koder. Legg til ett enkelt steg i pipelinen din, så blokkeres sammenslåinger automatisk ved brudd. + +## GitHub Actions + +Den raskeste måten å legge til Archgate i GitHub Actions er med den offisielle [`archgate/check-action`](https://github.com/archgate/check-action). Den installerer CLI-et, kjører `archgate check --ci` og viser brudd som innebygde merknader på pull requestens "Files changed"-fane: + +```yaml +name: Archgate +on: + pull_request: + push: + branches: [main] + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: archgate/check-action@v1 +``` + +Det er alt -- ingen Node.js-oppsett, ingen installasjonssteg. Hvis en regel rapporterer et brudd med `error`-alvorlighetsgrad, feiler jobben med exit-kode 1. + +### Fest en versjon + +```yaml +- uses: archgate/check-action@v1 + with: + version: v0.15.0 +``` + +### Kun oppsett-action + +Hvis du trenger å kjøre Archgate-kommandoer utover `check` (f.eks. `archgate adr list --json`), bruk [`archgate/setup-action`](https://github.com/archgate/setup-action) for å installere CLI-et og legge det til PATH, og kjør deretter de kommandoene du trenger: + +```yaml +steps: + - uses: actions/checkout@v4 + - uses: archgate/setup-action@v1 + - run: archgate check --ci + - run: archgate adr list --json +``` + +### Kryssplattform-arbeidsflyt + +Begge actionene støtter Ubuntu, macOS og Windows-runnere: + +```yaml +jobs: + check: + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: archgate/check-action@v1 +``` + +### Manuelt oppsett + +Hvis du foretrekker å ikke bruke de offisielle actionene, kan du installere Archgate manuelt: + +```yaml +steps: + - uses: actions/checkout@v4 + - run: npm install -g archgate + - run: archgate check +``` + +## GitHub Actions-merknader + +Bruk `--ci` for å skrive brudd som GitHub Actions-arbeidsflytmerknader. Disse vises innebygd på pull requestens "Files changed"-fane og peker direkte til den problematiske filen og linjen. + +```yaml +- run: archgate check --ci +``` + +Flagget `--ci` produserer `::error`- og `::warning`-merknader i formatet GitHub Actions forventer. Hver merknad inkluderer ADR-ID, regel-ID, filsti og linjenummer. + +:::note[Merknad] +`archgate/check-action` sender `--ci` automatisk -- du trenger bare dette flagget når du kjører `archgate check` manuelt. +::: + +## Maskinlesbar utdata + +Bruk `--json` for strukturert utdata som andre verktøy kan parse: + +```yaml +- run: archgate check --json > results.json +``` + +JSON-utdataen inkluderer: + +```json +{ + "pass": false, + "total": 6, + "passed": 5, + "failed": 1, + "warnings": 0, + "errors": 1, + "infos": 0, + "ruleErrors": 0, + "truncated": false, + "results": [ + { + "adrId": "ARCH-006", + "ruleId": "no-unapproved-deps", + "description": "Production dependencies must be on the approved list", + "status": "fail", + "totalViolations": 1, + "shownViolations": 1, + "violations": [ + { + "message": "Unapproved production dependency: \"chalk\"", + "file": "package.json", + "severity": "error" + } + ], + "durationMs": 18 + } + ], + "durationMs": 142 +} +``` + +## Exit-koder + +| Kode | Betydning | CI-oppførsel | +| ---- | --------------- | ------------- | +| 0 | Alle sjekker ok | Jobben lykkes | +| 1 | Brudd funnet | Jobben feiler | +| 2 | Intern feil | Jobben feiler | + +Advarsler (alvorlighetsgrad `warning`) logges, men påvirker ikke exit-koden. Bare brudd med `error`-alvorlighetsgrad forårsaker exit-kode 1. + +## Avgrense omfanget + +### Sjekk filer endret i PR-en + +Bruk `--base` for å sammenligne mot PR-ens grunngren. Dette gir regler for avhengigheter mellom filer det fulle bildet av hva som er endret: + +```yaml +- run: archgate check --base origin/${{ github.base_ref }} +``` + +Uten `--base` auto-detekteres grunngrenen fra `origin/HEAD`. Den eksplisitte formen anbefales i CI for deterministisk oppførsel. + +### Sjekk bare stagede filer + +Bruk `--staged` for å begrense sjekkingen til git-stagede filer. Dette er nyttig i pre-commit-hooks eller når du bare vil validere det som er i ferd med å bli committet: + +```yaml +- run: archgate check --staged +``` + +### Sjekk en spesifikk ADR + +Bruk `--adr ` for å kjøre regler fra en enkelt ADR: + +```yaml +- run: archgate check --adr ARCH-006 +``` + +Dette er nyttig når en PR bare berører filer styrt av en ADR og du vil ha raskere tilbakemelding. + +## Legge til i en eksisterende pipeline + +Hvis du allerede har en CI-konfigurasjon, legg til Archgate som et enkelt steg etter checkout: + +```yaml +# Existing pipeline +steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "22" + - run: npm ci + - run: npm test + + # Add Archgate check + - run: npm install -g archgate + - run: archgate check --ci +``` + +Ingen ekstra avhengigheter eller konfigurasjonsfiler er nødvendige utover `.archgate/`-katalogen som allerede er i repositoriet ditt. + +## Hurtigbufre installasjonen + +Hurtigbufre `~/.archgate`-katalogen for å fremskynde gjentatte installasjoner: + +```yaml +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Cache Archgate + uses: actions/cache@v4 + with: + path: ~/.archgate + key: archgate-${{ runner.os }} + + - run: npm install -g archgate + - run: archgate check --ci +``` + +## GitLab CI + +```yaml +adr-compliance: + image: node:22 + script: + - npm install -g archgate + - archgate check +``` + +## Frittstående installasjon (uten Node.js) + +Hvis CI-miljøet ditt ikke har Node.js, bruk den frittstående installasjonsskriptet for å laste ned en forhåndsbygd binærfil direkte fra GitHub Releases: + +```yaml +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: curl -fsSL https://cli.archgate.dev/install-unix | sh + - run: ~/.archgate/bin/archgate check --ci +``` + +Dette fungerer i ethvert miljø med `curl` og `tar` -- ingen kjøretidsavhengigheter nødvendig. Du kan feste en versjon med miljøvariabelen `ARCHGATE_VERSION`: + +```yaml +- run: curl -fsSL https://raw.githubusercontent.com/archgate/cli/main/install.sh | ARCHGATE_VERSION=v0.11.2 sh +``` + +## Bun-basert CI + +Hvis CI-et ditt allerede bruker Bun, installer Archgate med `bun` i stedet for `npm`: + +```yaml +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + - run: bun install -g archgate + - run: archgate check --ci +``` + +## Andre CI-systemer + +Archgate fungerer med ethvert CI-system som kan kjøre shell-kommandoer. Mønsteret er alltid det samme: + +1. Installer: `npm install -g archgate`, `bun install -g archgate`, eller bruk den [frittstående installasjonsskriptet](/getting-started/installation/#install-standalone-recommended) +2. Kjør: `archgate check` +3. Sjekk exit-koden (0 = bestått, 1 = brudd, 2 = feil) + +For systemer som støtter merknader (Azure DevOps, Buildkite osv.), bruk `--json` for å parse utdataen og sende merknader i formatet CI-et ditt forventer. + +## Pre-commit-hooks + +Du kan også kjøre Archgate som en lokal pre-commit-hook. Legg dette til `.git/hooks/pre-commit` (eller bruk en hook-administrator som Husky eller Lefthook): + +```bash +#!/bin/sh +archgate check --staged +``` + +Flagget `--staged` sikrer at bare filer som er i ferd med å bli committet sjekkes, noe som holder hooken rask. + +## Detaljert utdata + +Bruk `--verbose` for å se beståtte regler og tidsinformasjon sammen med feil. Dette er nyttig for feilsøking av trege sjekker eller for å bekrefte at regler kjører som forventet: + +```yaml +- run: archgate check --verbose +``` + +:::tip[Legg til AI-styring i arbeidsflyten din] +CI fanger brudd ved sammenslåing. Redaktørplugins fanger dem under koding. Med [Claude Code](/guides/claude-code-plugin/)- eller [Cursor](/guides/cursor-integration/)-pluginen leser AI-agenten din ADR-er før den skriver kode og validerer samsvar før du i det hele tatt committer. [Meld deg på beta-tilgang](https://plugins.archgate.dev). +::: diff --git a/docs/src/content/docs/nb/guides/claude-code-plugin.mdx b/docs/src/content/docs/nb/guides/claude-code-plugin.mdx new file mode 100644 index 00000000..fee3f4e4 --- /dev/null +++ b/docs/src/content/docs/nb/guides/claude-code-plugin.mdx @@ -0,0 +1,153 @@ +--- +title: Claude Code-plugin +description: Sett opp Archgate-pluginen for Claude Code. Gi AI-agenter en styringsarbeidsflyt som leser ADR-er, validerer kode og fanger opp arkitekturmønstre. +--- + +Archgate Claude Code-pluginen gir AI-agenter som jobber i [Claude Code](https://claude.ai/code) en strukturert styringsarbeidsflyt. I stedet for å stole på prompt-instruksjoner som glir over tid, leser agenter ADR-ene dine direkte via Archgate CLI-kommandoer og validerer sin egen kode mot reglene dine. + +## Hva pluginen tilbyr + +Pluginen legger til en agent og rollebaserte ferdigheter i Claude Code. Agenten orkestrerer styringsarbeidsflyten, og aktiverer ferdigheter etter behov -- les beslutninger før koding, valider etterpå, og fang opp nye mønstre for teamet. + +### Agent + +| Agent | Formål | +| -------------------- | ------------------------------------------------------------------------- | +| `archgate:developer` | Generell utviklingsagent som leser ADR-er før koding og validerer etterpå | + +`archgate:developer`-agenten er satt som standardagent via `.claude/settings.local.json`. Den orkestrerer ferdighetene nedenfor automatisk som en del av arbeidsflyten sin. + +### Ferdigheter + +| Ferdighet | Formål | +| -------------------------- | --------------------------------------------------------------------------------------- | +| `archgate:architect` | Validerer kodeendringer mot alle prosjektets ADR-er for strukturelt samsvar | +| `archgate:quality-manager` | Gjennomgår regeldekning og foreslår nye ADR-er når mønstre dukker opp | +| `archgate:adr-author` | Oppretter og redigerer ADR-er i henhold til prosjektets konvensjoner | +| `archgate:onboard` | Engangsoppsett: utforsker kodebasen, intervjuer utvikleren, oppretter innledende ADR-er | + +## Installasjon + +:::note[Beta-tilgang kreves] +Claude Code-pluginen er for tiden i beta. Kjør `archgate login` for å registrere deg og autentisere. +::: + +### 1. Logg inn med GitHub + +Autentiser med GitHub-kontoen din for å få et plugin-token: + +```bash +archgate login +``` + +Dette starter en GitHub Device Flow. CLI-et viser en engangskode og URL -- åpne URL-en i nettleseren din, skriv inn koden og autoriser. Når det er ferdig, lagres legitimasjonen sikkert i operativsystemets legitimasjonsbehandler via `git credential approve`. + +### 2. Initialiser prosjektet ditt med pluginen + +Kjør `archgate init` i prosjektet ditt. Hvis du allerede er logget inn, installeres pluginen automatisk: + +```bash +archgate init +``` + +For å eksplisitt be om plugininstallasjon: + +```bash +archgate init --install-plugin +``` + +Dette oppretter `.claude/settings.local.json` med `archgate:developer`-agenten og ferdighetstillatelser forhåndskonfigurert. + +Hvis `claude`-CLI-et er på PATH, installeres pluginen automatisk via: + +1. `claude plugin marketplace add` (registrerer Archgate-markedsplassen) +2. `claude plugin install archgate@archgate` (installerer pluginen) + +Hvis `claude`-CLI-et ikke finnes, skriver kommandoen ut de manuelle kommandoene du må kjøre. + +### Installere pluginen på et eksisterende prosjekt + +Hvis prosjektet ditt allerede er initialisert, kan du installere eller reinstallere pluginen uten å kjøre `archgate init` på nytt: + +```bash +archgate plugin install +``` + +For å få den autentiserte repository-URL-en for manuell konfigurasjon: + +```bash +archgate plugin url +``` + +## Innledende oppsett med onboard + +Etter installasjon, kjør `archgate:onboard`-ferdigheten i prosjektet ditt en gang. Denne ferdigheten: + +1. Utforsker kodebasens struktur (kataloger, nøkkelfiler, pakkekonfigurasjon) +2. Intervjuer deg om teamets konvensjoner, begrensninger og arkitekturbeslutninger +3. Oppretter et innledende sett med ADR-er basert på svarene dine +4. Setter opp `.archgate/`-katalogen med de første reglene dine + +Onboard-ferdigheten er laget for å kjøres en gang per prosjekt. Etter onboarding håndterer de andre ferdighetene daglig utvikling. + +## Slik fungerer det i praksis + +Pluginen følger en strukturert arbeidsflyt for hver kodeoppgave: + +### 1. Les gjeldende ADR-er + +Når utvikleren gir en kodeoppgave, kjører agenten `archgate review-context` for å lese alle ADR-er som gjelder for filene som endres. Dette gir en komprimert briefing med **Decision**- og **Do's and Don'ts**-seksjonene fra hver relevante ADR. + +Agenten skriver ikke kode før den har lest de gjeldende ADR-ene. Dette håndheves av `archgate:developer`-ferdigheten. + +### 2. Skriv kode i henhold til ADR-begrensninger + +Agenten skriver kode som er i samsvar med begrensningene fra ADR-ene. Do's and Don'ts-seksjonene fungerer som konkrete retningslinjer -- agenten refererer til dem mens den koder. + +### 3. Valider endringer + +Etter at koden er skrevet, kjører agenten `archgate check` for å kjøre automatiserte regler mot endringene. Eventuelle brudd fikses før den går videre. + +### 4. Arkitektgjennomgang + +Agenten aktiverer `archgate:architect` for å validere strukturelt ADR-samsvar utover det automatiserte regler fanger opp. Arkitektferdigheten gjennomgår den fulle konteksten av endringene mot alle gjeldende ADR-er. + +### 5. Fange opp lærdommer + +Agenten aktiverer `archgate:quality-manager` for å gjennomgå arbeidet og identifisere mønstre som er verdt å fange opp. Quality manager kan foreslå nye ADR-er eller oppdateringer til eksisterende når gjentakende konvensjoner dukker opp. + +## ADR-drevet avvisning + +Når agenten møter en oppgave som ville kreve brudd på en ADR, avviser den og forklarer hvilken ADR som ville blitt brutt. Den foreslår deretter hvordan man kan oppnå det samme målet mens man holder seg i samsvar. + +For eksempel, hvis en utvikler ber agenten om å legge til `chalk` som en avhengighet i et prosjekt styrt av ARCH-006 (avhengighetspolicy), vil agenten: + +1. Avvise, med referanse til ARCH-006 og den godkjente avhengighetslisten +2. Foreslå å bruke `styleText()` fra `node:util` i stedet +3. Tilby å implementere oppgaven med det samsvarende alternativet + +Denne oppførselen er konsistent uavhengig av hvordan utvikleren formulerer forespørselen. ADR-er behandles som obligatoriske begrensninger, ikke forslag. + +## Slik får pluginen tilgang til ADR-er + +Pluginen bruker Archgate CLI-kommandoer direkte for å lese ADR-er og kjøre samsvarsjekker. Nøkkelkommandoene er: + +- **`archgate review-context`** -- komprimerte briefinger av alle ADR-er som gjelder for endrede filer, gruppert etter domene +- **`archgate check --staged`** -- automatisert regelsjekking med bruddrapportering +- **`archgate adr show `** -- full tekst av en spesifikk ADR +- **`archgate adr list`** -- oversikt over alle ADR-er i prosjektet med metadata +- **`archgate session-context claude-code`** -- les sesjonsutskrifter for kontekstgjenoppretting + +Alle kommandoer kjøres lokalt og leser direkte fra `.archgate/adrs/`-katalogen din. Ingen data forlater maskinen din. + +## Når du skal bruke hvilken agent eller ferdighet + +| Scenario | Agent eller ferdighet | +| ------------------------------------------------- | -------------------------- | +| Starte et nytt prosjekt med Archgate | `archgate:onboard` | +| Daglige kodeoppgaver | `archgate:developer` | +| Gjennomgå en PR for ADR-samsvar | `archgate:architect` | +| Oppdage et gjentakende mønster verdt å kodifisere | `archgate:quality-manager` | +| Opprette eller redigere en ADR | `archgate:adr-author` | + +`archgate:developer`-agenten orkestrerer ferdighetene automatisk -- den aktiverer `archgate:architect` og `archgate:quality-manager` som en del av arbeidsflyten sin. Mesteparten av tiden trenger du bare å samhandle med developer-agenten direkte. diff --git a/docs/src/content/docs/nb/guides/copilot-cli-plugin.mdx b/docs/src/content/docs/nb/guides/copilot-cli-plugin.mdx new file mode 100644 index 00000000..a9aaad19 --- /dev/null +++ b/docs/src/content/docs/nb/guides/copilot-cli-plugin.mdx @@ -0,0 +1,129 @@ +--- +title: Copilot CLI-plugin +description: Sett opp Archgate-pluginet for GitHub Copilot CLI. Legg til arkitekturstyring i Copilot med automatisert ADR-samsvar og regelhaandheving. +--- + +Archgate Copilot CLI-pluginet gir AI-agenter som jobber i [GitHub Copilot CLI](https://github.com/features/copilot) en strukturert styringsarbeidsflyt. Agenter leser ADR-ene dine for de skriver kode, validerer etterpaa, og fanger opp nye monstre for teamet -- den samme arbeidsflyten som er tilgjengelig i [Claude Code-pluginet](/guides/claude-code-plugin/). + +## Hvordan det fungerer + +Copilot CLI stotter plugin-installasjon fra git-repositorier ved hjelp av `copilot plugin install`. Archgate-pluginet serveres fra et git-repositorium paa `plugins.archgate.dev/archgate.git`, som Copilot CLI gjenkjenner direkte -- det samme `.claude-plugin/plugin.json`-manifestformatet fungerer for baade Claude Code og Copilot CLI. + +## Installasjon + +:::note[Betatilgang kreves] +Copilot CLI-pluginet er for oyeblikket i beta. Kjor `archgate login` for aa registrere deg og autentisere for du folger trinnene nedenfor. +::: + +### 1. Logg inn med GitHub + +Autentiser med GitHub-kontoen din for aa faa et plugin-token: + +```bash +archgate login +``` + +Dette starter en GitHub Device Flow. CLI-en viser en engangskode og URL -- aapne URL-en i nettleseren din, skriv inn koden, og autoriser. Naar det er fullfort, lagres legitimasjonen sikkert i operativsystemets legitimasjonsbehandler via `git credential approve`. + +### 2. Initialiser prosjektet ditt med pluginet + +Kjor `archgate init` med `--editor copilot`-flagget: + +```bash +archgate init --editor copilot +``` + +Hvis du allerede er logget inn og `copilot`-CLI-en er paa PATH, installeres pluginet automatisk via: + +```bash +copilot plugin install https://:@plugins.archgate.dev/archgate.git +``` + +Hvis `copilot`-CLI-en ikke finnes, skriver kommandoen ut den manuelle kommandoen du maa kjore. + +For aa eksplisitt be om plugin-installasjon: + +```bash +archgate init --editor copilot --install-plugin +``` + +For aa installere eller reinstallere pluginet paa et allerede initialisert prosjekt: + +```bash +archgate plugin install --editor copilot +``` + +### Genererte filer + +Kommandoen oppretter `.github/copilot/`-mappen for plugin-konfigurasjon. Plugin-installasjon haandteres separat via `copilot plugin install`-kommandoen. + +### Manuell installasjon + +Hvis `copilot`-CLI-en ikke finnes under `archgate init`, kan du installere pluginet manuelt: + +```bash +copilot plugin install https://:@plugins.archgate.dev/archgate.git +``` + +Du kan finne den autentiserte URL-en din ved aa kjore `archgate plugin url copilot`. + +## Hva pluginet tilbyr + +Pluginet legger til en agent og rollebaserte ferdigheter i Copilot CLI. Agenten orkestrerer styringsarbeidsflyten og aktiverer ferdigheter etter behov. + +### Agent + +| Agent | Formaal | +| -------------------- | -------------------------------------------------------------------------- | +| `archgate:developer` | Generell utviklingsagent som leser ADR-er for koding og validerer etterpaa | + +`archgate:developer`-agenten er satt som standardagent via plugin-innstillingene. Den orkestrerer ferdighetene nedenfor automatisk som en del av arbeidsflyten. + +### Ferdigheter + +| Ferdighet | Formaal | +| -------------------------- | --------------------------------------------------------------------------------------- | +| `archgate:architect` | Validerer kodeendringer mot alle prosjektets ADR-er for strukturell samsvar | +| `archgate:quality-manager` | Gjennomgaar regeldekning og foreslar nye ADR-er naar monstre dukker opp | +| `archgate:adr-author` | Oppretter og redigerer ADR-er i henhold til prosjektets konvensjoner | +| `archgate:onboard` | Engangsoppsett: utforsker kodebasen, intervjuer utvikleren, oppretter innledende ADR-er | + +## Forste oppsett med onboard + +Etter installasjon, kjor `archgate:onboard`-ferdigheten i prosjektet ditt en gang. Denne ferdigheten: + +1. Utforsker kodebasestrukturen din (mapper, nokkelfiler, pakkekonfigurasjon) +2. Intervjuer deg om teamets konvensjoner, begrensninger og arkitekturbeslutninger +3. Oppretter et innledende sett med ADR-er basert paa svarene dine +4. Setter opp `.archgate/`-mappen med de forste reglene dine + +Onboard-ferdigheten er designet for aa kjores en gang per prosjekt. Etter onboarding handterer de andre ferdighetene daglig utvikling. + +## Hvordan det fungerer i praksis + +Pluginet folger en strukturert arbeidsflyt for hver kodeoppgave: + +### 1. Les gjeldende ADR-er + +Naar utvikleren gir en kodeoppgave, kjorer agenten `archgate review-context` for aa lese alle ADR-er som gjelder for filene som endres. Dette gir en komprimert briefing med **Decision**- og **Do's and Don'ts**-seksjonene fra hver relevante ADR. + +### 2. Skriv kode i henhold til ADR-begrensninger + +Agenten skriver kode som samsvarer med begrensningene fra ADR-ene. Do's and Don'ts-seksjonene fungerer som konkrete retningslinjer. + +### 3. Valider endringer + +Etter aa ha skrevet kode, kjorer agenten `archgate check` for aa utfore automatiserte regler mot endringene. Eventuelle brudd utbedres for man gaar videre. + +### 4. Arkitektgjennomgang + +Agenten aktiverer `archgate:architect` for aa validere strukturelt ADR-samsvar utover det automatiserte regler fanger opp. + +### 5. Fang opp laeringer + +Agenten aktiverer `archgate:quality-manager` for aa gjennomgaa arbeidet og identifisere monstre som er verdt aa fange opp som nye ADR-er. + +## Tips + +- **Kjor onboard en gang per prosjekt** for aa generere de innledende ADR-ene fra den faktiske kodebasen din. +- **Hold ADR-regelfiler oppdatert** -- agenten haandterer det reglene sjekker for. diff --git a/docs/src/content/docs/nb/guides/cursor-integration.mdx b/docs/src/content/docs/nb/guides/cursor-integration.mdx new file mode 100644 index 00000000..22166f40 --- /dev/null +++ b/docs/src/content/docs/nb/guides/cursor-integration.mdx @@ -0,0 +1,161 @@ +--- +title: Cursor-integrasjon +description: Integrer Archgate med Cursor IDE for AI-assistert utvikling med arkitekturstyring. Konfigurer agentregler og ferdigheter for ADR-samsvar. +--- + +Archgate integreres med [Cursor](https://cursor.com) for aa gi AI-agenter en strukturert styringsarbeidsflyt. Agenten leser ADR-ene dine for den skriver kode, validerer etterpaa, og fanger opp nye monstre for teamet -- den samme arbeidsflyten som er tilgjengelig i [Claude Code-pluginet](/guides/claude-code-plugin/). + +## Oppsett + +Kjor `archgate init` med `--editor cursor`-flagget for aa konfigurere Cursor-integrasjon i prosjektet ditt: + +```bash +archgate init --editor cursor +``` + +### Med plugin (beta) + +:::note[Betatilgang kreves] +Cursor-pluginet er for oyeblikket i beta. Kjor `archgate login` for aa registrere deg og autentisere. +::: + +Hvis du har logget inn via `archgate login`, installerer init-kommandoen ogsaa Archgate-pluginet for Cursor. Pluginet tilbyr ferdigbygde agentregler og ferdigheter som gir Cursor sin AI-agent en komplett styringsarbeidsflyt. + +Pluginet distribueres paa to maater: + +1. **Cursor Team Marketplace** -- Pluginet publiseres til et git-basert team-markedsplass-repositorium. Etter installasjon oppdager Cursor det fra team-markedsplassens URL som skrives ut av CLI-en. +2. **VS Code Extension (VSIX)** -- En `.vsix`-utvidelse installeres i Cursor via `cursor --install-extension`-kommandoen. + +For aa eksplisitt installere pluginet: + +```bash +archgate login # engangsoppsett +archgate init --editor cursor --install-plugin +``` + +Kommandoen `archgate plugin install --editor cursor` installerer VS Code-utvidelsen via `cursor`-CLI-en hvis tilgjengelig og skriver ut team-markedsplassens URL; ellers skrives manuelle instruksjoner ut. + +For aa installere eller reinstallere pluginet paa et allerede initialisert prosjekt: + +```bash +archgate plugin install --editor cursor +``` + +### Uten plugin (gratis) + +Uten pluginet konfigurerer `archgate init --editor cursor` fortsatt en grunnleggende styringsregel. AI-agenten kan konsultere ADR-er og kjore sjekker via CLI-kommandoer, men faar ikke de rollebaserte ferdighetene beskrevet nedenfor. + +### Genererte filer + +| Fil | Formaal | +| --------------------------------------- | ---------------------------------------------------------------------- | +| `.cursor/rules/archgate-governance.mdc` | Alltid-paa Cursor-regel som instruerer agenten om aa konsultere ADR-er | + +## Hva pluginet tilbyr + +Pluginet legger til en agent og rollebaserte ferdigheter i Cursor. Cursors plugin-system haandterer navnerom, saa ferdigheter bruker sine direkte navn uten prefiks. + +### Agent + +| Navn | Formaal | +| ----------- | -------------------------------------------------------------------------- | +| `developer` | Generell utviklingsagent som leser ADR-er for koding og validerer etterpaa | + +`developer`-agenten orkestrerer ferdighetene nedenfor automatisk som en del av arbeidsflyten. + +### Ferdigheter + +| Navn | Formaal | +| ----------------- | --------------------------------------------------------------------------------------- | +| `architect` | Validerer kodeendringer mot alle prosjektets ADR-er for strukturell samsvar | +| `quality-manager` | Gjennomgaar regeldekning og foreslar nye ADR-er naar monstre dukker opp | +| `adr-author` | Oppretter og redigerer ADR-er i henhold til prosjektets konvensjoner | +| `onboard` | Engangsoppsett: utforsker kodebasen, intervjuer utvikleren, oppretter innledende ADR-er | +| `cli-reference` | Intern referanse for AI-agenter med den komplette Archgate CLI-kommandoguiden | + +Disse er den samme agenten og ferdighetene som er tilgjengelige i Claude Code-pluginet (`archgate:developer`, `archgate:architect`, osv.), tilpasset Cursors plugin-system. + +## Forste oppsett med onboard + +Etter aa ha installert pluginet, kjor `onboard`-ferdigheten i prosjektet ditt en gang. Denne ferdigheten: + +1. Utforsker kodebasestrukturen din (mapper, nokkelfiler, pakkekonfigurasjon) +2. Intervjuer deg om teamets konvensjoner, begrensninger og arkitekturbeslutninger +3. Oppretter et innledende sett med ADR-er basert paa svarene dine +4. Setter opp `.archgate/`-mappen med de forste reglene dine + +Onboard-ferdigheten er designet for aa kjores en gang per prosjekt. Etter onboarding haandterer de andre ferdighetene daglig utvikling. + +## Hvordan det fungerer i praksis + +### Med pluginet + +`developer`-agenten folger en strukturert arbeidsflyt for hver kodeoppgave: + +1. **Les gjeldende ADR-er** -- Agenten kjorer `archgate review-context` for aa se hvilke ADR-er som gjelder for filene som endres. Den skriver ikke kode for den har lest de gjeldende ADR-ene. + +2. **Skriv kode i henhold til ADR-begrensninger** -- Agenten implementerer endringer i henhold til Do's and Don'ts fra de gjeldende ADR-ene. + +3. **Kjor samsvarssjekker** -- Agenten kjorer `archgate check --staged` for aa utfore automatiserte regler. Eventuelle brudd utbedres for man gaar videre. + +4. **Arkitektgjennomgang** -- Agenten aktiverer `architect`-ferdigheten for aa validere strukturelt ADR-samsvar utover det automatiserte regler fanger opp. + +5. **Fang opp laeringer** -- Agenten aktiverer `quality-manager`-ferdigheten for aa gjennomgaa arbeidet og identifisere monstre som er verdt aa fange opp som nye ADR-er eller oppdateringer til eksisterende. + +### Uten pluginet + +Agenten bruker styringsregelen og CLI-kommandoer for aa folge fire manuelle trinn: + +1. **Gjennomgaa kontekst** -- Kjor `archgate review-context` for aa se hvilke ADR-er som gjelder for filene som endres. + +2. **Les individuelle ADR-er** -- For full kontekst om en spesifikk beslutning, kjor `archgate adr show ` (for eksempel `archgate adr show ARCH-001`). + +3. **Skriv kode** -- Implementer endringer i henhold til begrensningene fra de gjeldende ADR-ene. + +4. **Kjor samsvarssjekker** -- Kjor `archgate check --staged` for aa validere at koden samsvarer med alle ADR-regler. + +## ADR-drevet avvisning + +Naar agenten moter en oppgave som ville kreve brudd paa en ADR, avviser den og forklarer hvilken ADR som ville bli brutt. Den foreslar deretter hvordan man kan oppnaa det samme maalet uten aa bryte reglene. + +Hvis for eksempel en utvikler ber agenten om aa legge til `chalk` som en avhengighet i et prosjekt styrt av en ADR for avhengighetspolicy, vil agenten: + +1. Avvise, med henvisning til ADR-en og den godkjente avhengighetslisten +2. Foresla det godkjente alternativet i stedet +3. Tilby aa implementere oppgaven med den samsvarende tilnaermingen + +Denne oppforselen er konsistent uavhengig av hvordan utvikleren formulerer forsporselen. ADR-er behandles som obligatoriske begrensninger, ikke forslag. + +## Naar du skal bruke hver agent eller ferdighet + +| Scenario | Ferdighet | +| -------------------------------------------------- | ----------------- | +| Starte et nytt prosjekt med Archgate | `onboard` | +| Daglige kodeoppgaver | `developer` | +| Gjennomgaa en PR for ADR-samsvar | `architect` | +| Oppdage et gjentagende monster verdt aa kodifisere | `quality-manager` | +| Opprette eller redigere en ADR | `adr-author` | + +`developer`-agenten orkestrerer ferdighetene automatisk -- den aktiverer `architect` og `quality-manager` som en del av arbeidsflyten. Mesteparten av tiden trenger du bare aa bruke `developer` direkte. + +## Styringsregel + +Styringsregelen i `.cursor/rules/archgate-governance.mdc` bruker `alwaysApply: true`, noe som betyr at Cursor-agenten alltid har styringstilgang tilgjengelig uten manuell aktivering. Den instruerer agenten om aa kjore `archgate review-context` for koding og `archgate check --staged` etterpaa. + +## Tilgang til sesjonsutskrifter + +Kommandoen `archgate session-context cursor` leser Cursor-agentens sesjonsutskrifter fra disk. Dette lar ferdigheter faa tilgang til historikken til den gjeldende samtalen, noe som er nyttig for aa gjenopprette kontekst som kan ha blitt komprimert eller avkortet. + +Kommandoen aksepterer to valgfrie flagg: + +- `--max-entries ` -- Maksimalt antall oppforinger aa returnere (standard: 200, nyeste oppforinger). +- `--session-id ` -- En spesifikk sesjons-UUID aa lese. Hvis utelatt, brukes den nyeste sesjonen. + +## Tips for effektiv bruk + +- **Bruk `developer`-ferdigheten for kodeoppgaver.** Den orkestrerer hele les-valider-fang-opp-arbeidsflyten automatisk. +- **Kjor `onboard` en gang per prosjekt.** Den setter opp de innledende ADR-ene basert paa den faktiske kodebasen og konvensjonene dine. +- **Bruk `architect` for PR-gjennomganger.** Den validerer strukturelt samsvar utover det automatiserte regler fanger opp. +- **Bruk `quality-manager` etter aa ha lost vanskelige problemer.** Den fanger opp laeringer slik at de samme feilene ikke gjentas. +- **Commit `.cursor/`-mappen.** Dette sikrer at alle teammedlemmer faar den samme styringskonfigurasjonen naar de kloner repositoriet. +- **Hold ADR-regelfiler oppdatert.** Agenten haandterer det reglene sjekker for -- hvis en regel mangler, vil bruddet ikke bli fanget opp. diff --git a/docs/src/content/docs/nb/guides/importing-adrs.mdx b/docs/src/content/docs/nb/guides/importing-adrs.mdx new file mode 100644 index 00000000..8adeaeb6 --- /dev/null +++ b/docs/src/content/docs/nb/guides/importing-adrs.mdx @@ -0,0 +1,131 @@ +--- +title: Importere ADR-er +description: Importer kuraterte Architecture Decision Records fra Archgate-registeret eller et hvilket som helst git-repositorium. Start med utprovde konvensjoner i stedet for en blank side. +--- + +import { Tabs, TabItem } from "@astrojs/starlight/components"; + +## Hva er ADR-pakker? + +En **ADR-pakke** er en kuratert samling av Architecture Decision Records buntet sammen under et felles tema. Hver pakke inkluderer: + +- En `archgate-pack.yaml`-manifestfil med metadata (navn, versjon, vedlikeholdere, tagger) +- En eller flere ADR-markdownfiler i en `adrs/`-katalog +- Valgfrie tilhorende `.rules.ts`-filer som haandhever hver beslutning automatisk + +Pakker lar deg starte et prosjekt med utprovde arkitekturkonvensjoner i stedet for aa skrive alt fra bunnen av. + +## Importere fra registeret + +[Archgate awesome-adrs-registeret](https://github.com/archgate/awesome-adrs) er vert for fellesskapsvedlikeholdte pakker. Importer en med: + +```bash +archgate adr import packs/typescript-strict +``` + +Dette kloner registeret, kopierer ADR-ene til `.archgate/adrs/`-katalogen din, og tilordner ID-er paa nytt for aa passe prosjektets nummereringsskjema. + +### Laase til en versjon + +Legg til `@` for aa laase til en spesifikk git-tag eller gren: + +```bash +archgate adr import packs/typescript-strict@0.3.0 +``` + +## Plukke ut individuelle ADR-er + +Du trenger ikke importere en hel pakke. Pek til en spesifikk ADR-fil inni en pakke: + +```bash +archgate adr import packs/security/adrs/SEC-001-no-secrets-in-code +``` + +Bare den ene ADR-en (og dens tilhorende regelfil, hvis den finnes) vil bli importert. + +## Importere fra tredjepartsrepositorier + +Ethvert GitHub-repositorium med ADR-filer fungerer som kilde. Bruk syntaksen med tre segmenter `org/repo/sti`: + +```bash +archgate adr import acme/company-adrs/packs/api-standards +``` + +Dette kloner `https://github.com/acme/company-adrs.git` og importerer fra den angitte underkatalogen. + +## Importere fra en hvilken som helst git-URL + +For ikke-GitHub-repositorier eller naar du trenger full kontroll, send en fullstendig URL: + +```bash +archgate adr import https://github.com/org/repo/tree/main/packs/my-pack +``` + +CLI-en parser GitHub `/tree//`-formatet automatisk. For andre verter kan du sende enhver git-klonbar URL: + +```bash +archgate adr import https://gitlab.com/team/repo.git +``` + +## Forhaandsvis med `--dry-run` + +Se hva som ville blitt importert uten aa skrive noe: + +```bash +archgate adr import packs/typescript-strict --dry-run +``` + +Utskriften viser de opprinnelige ID-ene, nytilordnede ID-er og titler i en tabell. + +## Liste importerte ADR-er med `--list` + +Sjekk hva som har blitt importert tidligere: + +```bash +archgate adr import --list +``` + +Dette leser `.archgate/imports.json` og viser hver kilde, versjon og ADR-ID-ene den produserte. + +## Hvordan ID-nytilordning fungerer + +Naar du importerer ADR-er, blir de opprinnelige ID-ene **nytilordnet** for aa matche prosjektets domeneprefikser. Hver ADRs `domain`-felt bestemmer hvilket prefiks den faar -- for eksempel blir en ADR med `domain: frontend` til `FE-XXX`, mens en med `domain: backend` blir `BE-XXX`. Hvert domene har sin egen teller, saa import av en pakke med blandede domener produserer korrekt prefiksede ID-er uten kollisjoner. + +For eksempel, naar du importerer en pakke med tre frontend-ADR-er og to backend-ADR-er inn i et prosjekt som allerede har `FE-001` og `BE-001`, produseres: + +- `FE-002`, `FE-003`, `FE-004` (frontend) +- `BE-002`, `BE-003` (backend) + +Nytilordningen sikrer: + +1. Ingen ID-kollisjoner med eksisterende ADR-er +2. Hvert domene opprettholder sin egen nummereringssekvens +3. Importerte regelfiler fungerer umiddelbart uten manuelle endringer + +## imports.json-manifestet + +Hver import registreres i `.archgate/imports.json`: + +```json +{ + "imports": [ + { + "source": "packs/typescript-strict", + "version": "0.3.0", + "importedAt": "2026-05-10T14:32:00.000Z", + "adrIds": ["ARCH-006", "ARCH-007", "ARCH-008"] + } + ] +} +``` + +Dette manifestet lar deg spore opprinnelse -- hvor hver importerte ADR kom fra og naar. Commit det til versjonskontroll sammen med ADR-ene dine. + +## Referanse for kommandoalternativer + +| Alternativ | Beskrivelse | +| ----------- | ------------------------------------------- | +| `--yes` | Hopp over bekreftelsesdialogen | +| `--json` | Skriv ut resultater som JSON | +| `--dry-run` | Forhaandsvis endringer uten aa skrive filer | +| `--list` | List tidligere importerte ADR-er | diff --git a/docs/src/content/docs/nb/guides/opencode-integration.mdx b/docs/src/content/docs/nb/guides/opencode-integration.mdx new file mode 100644 index 00000000..08412e13 --- /dev/null +++ b/docs/src/content/docs/nb/guides/opencode-integration.mdx @@ -0,0 +1,138 @@ +--- +title: opencode-integrasjon +description: Integrer Archgate med opencode for AI-assistert utvikling med arkitekturstyring. Konfigurer agenter og underagenter for ADR-samsvar. +--- + +Archgate integreres med [opencode](https://opencode.ai) for aa gi AI-agenter en strukturert styringsarbeidsflyt. Agenten leser ADR-ene dine for den skriver kode, validerer etterpaa, og fanger opp nye monstre for teamet -- den samme arbeidsflyten som er tilgjengelig i [Claude Code-pluginet](/guides/claude-code-plugin/). + +## Oppsett + +Kjor `archgate init` med `--editor opencode`-flagget for aa konfigurere opencode-integrasjon i prosjektet ditt: + +```bash +archgate init --editor opencode +``` + +:::note[Betatilgang kreves] +opencode-agentpakken er for oyeblikket i beta. Kjor `archgate login` for aa registrere deg og autentisere. +::: + +I motsetning til Claude Code- eller Cursor-integrasjonene skrives opencode-agentene **ikke til prosjekttreet ditt**. De installeres i stedet paa brukernivaa -- saa de bor paa maskinen din, ikke i repositoriet ditt, og er tilgjengelige paa tvers av alle prosjekter du aapner med opencode. + +opencode bruker XDG Base Directory-konvensjonen paa alle plattformer (via `xdg-basedir`-pakken), saa installasjonsplasseringen resolves til `$XDG_CONFIG_HOME/opencode/agents/` naar den variabelen er satt, og faller tilbake til `$HOME/.config/opencode/agents/` ellers. Det betyr at Windows-installasjoner havner under `C:\Users\\.config\opencode\agents\`, ikke under `%APPDATA%`: + +| Plattform | Installasjonsplassering | +| ------------- | ------------------------------------------------ | +| Linux / macOS | `~/.config/opencode/agents/` | +| Windows | `C:\Users\\.config\opencode\agents\` | + +### Autentisert installasjon + +:::caution[opencode maa vaere installert forst] +Installasjonstrinnet kjorer bare naar `opencode`-CLI-en er paa PATH. Archgate maa bekrefte at opencode er tilstede for den skriver filer til brukernivaaets konfigurasjonskatalog -- ellers ville agentene ligge paa en plassering ingenting leser. Installer opencode fra [opencode.ai](https://opencode.ai/docs/) forst, og kjor deretter `archgate init --editor opencode` eller `archgate plugin install --editor opencode` paa nytt. +::: + +Hvis du har logget inn via `archgate login` **og** `opencode` er paa PATH, laster init-kommandoen ned og installerer Archgate-agentpakken for opencode. Pakken tilbyr en ferdigbygd primaer agent og fire underagenter som gir opencode sin AI en komplett styringsarbeidsflyt. + +For aa eksplisitt installere agentene: + +```bash +archgate login # engangsoppsett +archgate init --editor opencode --install-plugin +``` + +For aa installere eller reinstallere paa et allerede initialisert prosjekt: + +```bash +archgate plugin install --editor opencode +``` + +Installasjonstrinnet laster ned en autentisert tarball fra Archgate plugins-tjenesten og pakker ut de fem `archgate-*.md`-agentfilene i opencode brukernivaa-katalogen. + +### Genererte filer (brukernivaa) + +| Fil | Formaal | +| ----------------------------------------------- | ----------------------------------------------------------------------- | +| `/archgate-developer.md` | Primaer agent (velges med Tab) som kjorer den fulle ADR-arbeidsflyten | +| `/archgate-architect.md` | Underagent som validerer kodeendringer mot alle prosjektets ADR-er | +| `/archgate-quality-manager.md` | Underagent som fanger opp laeringer og foreslar nye ADR-er | +| `/archgate-adr-author.md` | Underagent som oppretter og redigerer ADR-er i henhold til konvensjoner | +| `/archgate-cli-reference.md` | Intern referanseunderagent med Archgate CLI-kommandoguiden (skjult) | + +`.archgate/adrs/` og `.archgate/lint/` opprettes fortsatt i prosjektet som vanlig -- bare de opencode-spesifikke agentfilene bor utenfor prosjekttreet. + +## Hva pakken tilbyr + +`archgate-`-prefikset unngaar kollisjoner med brukeropprettede opencode-agenter i samme katalog. Underagenter aktiveres via opencodes `@-mention`-syntaks. + +### Primaer agent + +| Navn | Formaal | +| -------------------- | -------------------------------------------------------------------------- | +| `archgate-developer` | Generell utviklingsagent som leser ADR-er for koding og validerer etterpaa | + +`archgate-developer`-agenten orkestrerer underagentene nedenfor automatisk som en del av arbeidsflyten. + +### Underagenter + +| Navn | Formaal | +| -------------------------- | ----------------------------------------------------------------------------- | +| `archgate-architect` | Validerer kodeendringer mot alle prosjektets ADR-er for strukturell samsvar | +| `archgate-quality-manager` | Gjennomgaar regeldekning og foreslar nye ADR-er naar monstre dukker opp | +| `archgate-adr-author` | Oppretter og redigerer ADR-er i henhold til prosjektets konvensjoner | +| `archgate-cli-reference` | Intern referanse for AI-agenter med den komplette Archgate CLI-kommandoguiden | + +Disse er de samme rollene som er tilgjengelige i Claude Code-pluginet, tilpasset opencodes opprinnelige primaer-/underagentmodell. + +## Hvordan det fungerer i praksis + +Velg `archgate-developer` som din primaere agent (bruk Tab-tasten i opencode) naar du starter en kodeoppgave. Agenten folger en strukturert arbeidsflyt for hver endring: + +1. **Les gjeldende ADR-er** -- Agenten kjorer `archgate review-context` for aa se hvilke ADR-er som gjelder for filene som endres. Den skriver ikke kode for den har lest de gjeldende ADR-ene. + +2. **Skriv kode i henhold til ADR-begrensninger** -- Agenten implementerer endringer i henhold til Do's and Don'ts fra de gjeldende ADR-ene. + +3. **Kjor samsvarssjekker** -- Agenten kjorer `archgate check` for aa utfore automatiserte regler. Eventuelle brudd utbedres for man gaar videre. + +4. **Arkitektgjennomgang** -- Agenten nevner `@archgate-architect` for aa validere strukturelt ADR-samsvar utover det automatiserte regler fanger opp. + +5. **Fang opp laeringer** -- Agenten nevner `@archgate-quality-manager` for aa gjennomgaa arbeidet og identifisere monstre som er verdt aa fange opp som nye ADR-er eller oppdateringer til eksisterende. + +## ADR-drevet avvisning + +Naar `archgate-developer` moter en oppgave som ville kreve brudd paa en ADR, avviser den og forklarer hvilken ADR som ville bli brutt. Den foreslar deretter hvordan man kan oppnaa det samme maalet uten aa bryte reglene. + +Hvis for eksempel en utvikler ber agenten om aa legge til `chalk` som en avhengighet i et prosjekt styrt av en ADR for avhengighetspolicy, vil agenten: + +1. Avvise, med henvisning til ADR-en og den godkjente avhengighetslisten +2. Foresla det godkjente alternativet i stedet +3. Tilby aa implementere oppgaven med den samsvarende tilnaermingen + +Denne oppforselen er konsistent uavhengig av hvordan utvikleren formulerer forsporselen. ADR-er behandles som obligatoriske begrensninger, ikke forslag. + +## Naar du skal bruke hver agent eller underagent + +| Scenario | Agent / Underagent | +| -------------------------------------------------- | ------------------------------ | +| Daglige kodeoppgaver | `archgate-developer` (primaer) | +| Gjennomgaa en endring for ADR-samsvar | `@archgate-architect` | +| Oppdage et gjentagende monster verdt aa kodifisere | `@archgate-quality-manager` | +| Opprette eller redigere en ADR | `@archgate-adr-author` | + +`archgate-developer`-agenten orkestrerer underagentene automatisk -- den nevner `@archgate-architect` og `@archgate-quality-manager` som en del av arbeidsflyten. Mesteparten av tiden trenger du bare aa velge `archgate-developer` og la den kjore. + +## Brukernivaa vs. prosjektnivaa + +opencode-pakken bor i opencode-katalogen paa brukernivaa i stedet for i `.opencode/` inne i prosjektet ditt. Konsekvenser: + +- **En installasjon per maskin.** `archgate plugin install --editor opencode` installerer pakken globalt. Alle prosjekter du aapner med opencode ser de samme `archgate-*`-agentene. +- **Repositoriet ditt forblir rent.** Ingen `.opencode/`-mappe opprettes noensinne av `archgate init`. Teammedlemmer som onsker agentene kjorer sin egen `archgate plugin install --editor opencode`. +- **Oppgraderinger er globale.** Aa kjore `archgate plugin install --editor opencode` paa nytt overskriver de eksisterende filene med den nyeste pakken. + +## Tips for effektiv bruk + +- **Velg `archgate-developer` ved starten av kodeokter.** Den orkestrerer hele les-valider-fang-opp-arbeidsflyten automatisk. +- **Bruk `@archgate-architect` for gjennomganger.** Den validerer strukturelt samsvar utover det automatiserte regler fanger opp. +- **Bruk `@archgate-quality-manager` etter aa ha lost vanskelige problemer.** Den fanger opp laeringer slik at de samme feilene ikke gjentas. +- **Hold ADR-regelfiler oppdatert.** Agenten haandterer det reglene sjekker for -- hvis en regel mangler, vil bruddet ikke bli fanget opp. +- **Kjor `archgate plugin install --editor opencode` paa nytt for aa oppgradere.** Tjenesten returnerer den nyeste agentpakken ved hver autentisert nedlasting. diff --git a/docs/src/content/docs/nb/guides/pre-commit-hooks.mdx b/docs/src/content/docs/nb/guides/pre-commit-hooks.mdx new file mode 100644 index 00000000..220140b9 --- /dev/null +++ b/docs/src/content/docs/nb/guides/pre-commit-hooks.mdx @@ -0,0 +1,92 @@ +--- +title: Pre-commit-hooks +description: Sett opp Archgate pre-commit-hooks for aa automatisk sjekke ADR-samsvar for hver commit. Fang opp arkitekturbrudd for de naar CI. +--- + +## Oversikt + +Kommandoen `archgate check --staged` sjekker bare git-stagede filer mot ADR-reglene dine. Fordi den hopper over ustagede og usporede filer, kjorer den raskt nok til aa brukes som en pre-commit-hook uten aa bremse arbeidsflyten din. + +Naar en sjekk feiler, blokkeres committen. Brudd skrives ut til stderr med filstier og linjenumre slik at du kan finne og fikse dem umiddelbart. + +## Lefthook + +[Lefthook](https://github.com/evilmartians/lefthook) er en rask, kryssplattform git-hooks-behandler. Legg til folgende i `lefthook.yml`: + +```yaml +# lefthook.yml +pre-commit: + commands: + adr-check: + run: archgate check --staged +``` + +Installer hooken med: + +```bash +lefthook install +``` + +## Husky + +[Husky](https://typicode.github.io/husky/) er et populaert git-hooks-verktoy for Node.js-prosjekter. Legg til sjekken i pre-commit-hooken din: + +```bash +# .husky/pre-commit +archgate check --staged +``` + +Sorge for at hook-filen er kjoerbar: + +```bash +chmod +x .husky/pre-commit +``` + +## Hva skjer naar sjekker feiler + +Naar `archgate check --staged` finner brudd, avslutter den med kode 1. Dette blokkerer committen. Utskriften inkluderer: + +- ADR-ID-en og regelnavnet som ble brutt +- Filstien der bruddet ble funnet +- Linjenummeret (naar tilgjengelig) +- En beskrivelse av hva regelen forventer + +Fiks bruddene, stage filene paa nytt med `git add`, og commit igjen. + +## Ytelse + +`--staged`-flagget begrenser sjekker til bare filene i git-stageomraadet. Dette betyr: + +- Et prosjekt med hundrevis av kildefiler, men bare tre stagede filer, vil bare sjekke de tre filene. +- Regler som ikke matcher noen stagede filer, hoppes helt over. +- Typiske pre-commit-sjekker fullores paa under et sekund. + +Uten `--staged` skanner `archgate check` alle filer som matcher hver ADRs `files`-globmonster, noe som er nyttig for CI, men tregere for interaktiv bruk. + +## Nyttige flagg + +| Flagg | Formaal | +| ------------ | ---------------------------------------------------------------------------------------------------------------------------- | +| `--staged` | Sjekk bare git-stagede filer (paakrevd for pre-commit) | +| `--verbose` | Vis bestaatte regler og tidsinformasjon -- nyttig for aa feilsoke hvorfor en sjekk er treg eller hvilke regler som evalueres | +| `--json` | Skriv ut resultater som JSON -- nyttig for aa pipe til andre verktoy eller egendefinerte rapporteringsskript | +| `--adr ` | Sjekk bare regler fra en spesifikk ADR -- nyttig for aa isolere en enkelt regel under feilsoking | +| `--ci` | Skriv ut GitHub Actions-annotasjoner -- bruk dette i CI-arbeidsflyter i stedet for pre-commit-hooks | + +## Kombinere med andre hooks + +Pre-commit-hooks kan kjore flere kommandoer. For eksempel med Lefthook: + +```yaml +# lefthook.yml +pre-commit: + commands: + lint: + run: npm run lint + typecheck: + run: npm run typecheck + adr-check: + run: archgate check --staged +``` + +Hver kommando kjorer uavhengig. Hvis en kommando avslutter med en kode som ikke er null, blokkeres committen. diff --git a/docs/src/content/docs/nb/guides/security.mdx b/docs/src/content/docs/nb/guides/security.mdx new file mode 100644 index 00000000..9d882a40 --- /dev/null +++ b/docs/src/content/docs/nb/guides/security.mdx @@ -0,0 +1,144 @@ +--- +title: Sikkerhet +description: Forstaa Archgate CLIs tillitsmodell, hvordan regler kjores, og beste praksis for aa kjore sjekker trygt i CI/CD og lokal utvikling. +--- + +Archgate kjorer TypeScript-regler fra `.rules.ts`-filer i repositoriet ditt. Denne siden forklarer tillitsmodellen, hva regler kan og ikke kan gjore, og hvordan du kjorer sjekker trygt. + +## Tillitsmodell + +**`.rules.ts`-filer er kjoerbar kode.** Naar du kjorer `archgate check`, importerer CLI-en dynamisk hver `.rules.ts`-folgestykke-fil og kjorer `check`-funksjonene. Dette tilsvarer aa kjore `bun .archgate/adrs/*.rules.ts` -- koden har de samme mulighetene som ethvert annet skript paa maskinen din. + +Dette betyr: + +- Kjor bare `archgate check` paa repositorier du stoler paa. +- Gjennomgaa `.rules.ts`-filer med samme grundighet som all annen kildekode i prosjektet. +- I open source-prosjekter, behandle `.rules.ts`-endringer i pull requests som sikkerhetssensitive. + +### Hva regler kan faa tilgang til + +Regler mottar et `RuleContext`-objekt med sandkassede filoperasjoner. Alle `RuleContext`-metoder (`readFile`, `readJSON`, `grep`, `grepFiles`, `glob`) er begrenset til prosjektets rotkatalog -- stitraversering via `../`, absolutte stier og symbolske lenker er blokkert og kaster en feil. + +I tillegg til kjoringsmiljoets sandkasse kjorer Archgate en **statisk analysesikkerhetsskanner** paa hver `.rules.ts`-fil for den kjores. Skanneren parser regelens AST og blokkerer filer som inneholder farlige monstre: + +| Monster | Blokkert | +| ------------------------------------------------------------------- | -------- | +| Import av `node:fs`, `child_process`, `net`, `http`, `vm`, osv. | Ja | +| `Bun.spawn()`, `Bun.write()`, `Bun.file()`, `Bun.$` | Ja | +| `fetch()` | Ja | +| `eval()`, `new Function()` | Ja | +| Beregnet egenskapstilgang (`Bun[variable]`, `globalThis[variable]`) | Ja | +| Dynamisk `import()` med ikke-literal argument | Ja | +| Tilordning til `globalThis` eller `process.env` | Ja | + +Hvis et forbudt monster finnes, blir regelfilen **ikke importert eller kjoert**, og `archgate check` avslutter med en feil. + +**Trygge moduler som er tillatt:** `node:path`, `node:url`, `node:util`, `node:crypto` -- dette er verktoymoduler uten filsystem-, nettverks- eller prosess-I/O-funksjonalitet. + +Skanneren hever terskelen fra "trivielt aa utnytte" til "krever bevisst obfuskering som ser mistenkelig ut i kodegjennomgang." Veloppforte regler bruker bare `RuleContext`-metodene (`ctx.readFile`, `ctx.grep`, `ctx.glob`, osv.) og `ctx.report` for utskrift. + +### Hva regler ikke kan gjore + +- **Skrive filer** -- `RuleContext`-API-et er skrivebeskyttet. Regler rapporterer brudd, men kan ikke endre kodebasen. +- **Unnslippe 30-sekunders tidsgrensen** -- hver regel termineres etter 30 sekunder veggtid. +- **Paavirke andre regler** -- regler fra forskjellige ADR-er kjorer parallelt, men deler ingen mutbar tilstand gjennom kontekst-API-et. +- **Bruke farlige API-er** -- sikkerhetsskanneren blokkerer import av systemmoduler (`fs`, `child_process`, `net`, osv.), Bun-API-er (`Bun.spawn`, `Bun.file`), nettverkstilgang (`fetch`) og kodegenerering (`eval`, `new Function`). Regelfiler som inneholder disse monstrene avvises for kjoring. + +## Beste praksis for CI/CD + +Aa kjore `archgate check` i CI er trygt naar du kontrollerer repositoriets innhold. Ekstra forsiktighet er nodvendig for pull requests fra eksterne bidragsytere. + +### Paalitelige grener + +For pushes til `main` eller andre beskyttede grener kjorer `archgate check` kode som allerede er gjennomgaatt og merget. Dette er trygt: + +```yaml +on: + push: + branches: [main] + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: archgate/check-action@v1 +``` + +### Pull requests fra forks + +Naar en pull request kommer fra en fork, kan `.rules.ts`-filene i PR-en inneholde vilkaarlig kode. Dette er den samme risikoen som aa kjore et hvilket som helst ikke-paalitelig CI-skript. + +**Alternativ 1: Krev godkjenning for kjoring.** Bruk GitHubs miljoebeskyttelsesregler eller `pull_request_target` med manuell godkjenning for aa gate CI paa gjennomgang: + +```yaml +on: + pull_request_target: + +jobs: + check: + runs-on: ubuntu-latest + environment: pr-check # Krever manuell godkjenning + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + - uses: archgate/check-action@v1 +``` + +**Alternativ 2: Kjor bare sjekker paa paalitelige filer.** Bruk en separat arbeidsflyt som sjekker ut basisgrenens `.rules.ts`-filer og kjorer dem mot PR-ens kildefiler. Dette sikrer at bare gjennomgaatte regler kjores. + +**Alternativ 3: Hopp over sjekker paa fork-PR-er.** Hvis reglene dine hovedsakelig er for intern styring, hopp over automatiserte sjekker paa fork-PR-er og kjor dem manuelt etter gjennomgang: + +```yaml +on: + pull_request: + +jobs: + check: + if: github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: archgate/check-action@v1 +``` + +### Minst-privilegium-kjorere + +Kjor `archgate check` paa kjorere med minimale tilganger. Jobben trenger bare lesetilgang til repositoriet -- ingen hemmeligheter, distribusjonsnokler eller skrivetilganger er nodvendig: + +```yaml +jobs: + check: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - uses: archgate/check-action@v1 +``` + +## Lokal utvikling + +### Gjennomgaa regler i nye repositorier + +Naar du kloner eller forker et repositorium som bruker Archgate, blokkerer sikkerhetsskanneren automatisk farlige monstre i `.rules.ts`-filer. Du bor likevel gjennomgaa regelfiler for du kjorer `archgate check` for forste gang: + +- Skanneren fanger eksplisitt bruk av forbudte API-er, men sofistikert obfuskering (f.eks. `Reflect.get(Bun, "spawn")`) kan omgaa den +- Toppnivaa-kode som kjorer ved import (for `check`-funksjonen kalles) kjores fortsatt hvis den bestaar skanneren +- Veloppforte regler bruker bare `RuleContext`-metodene (`ctx.readFile`, `ctx.grep`, `ctx.glob`, osv.) og `ctx.report` for utskrift + +### Legitimasjon + +Kommandoen `archgate login` lagrer autentiseringstokenet ditt i operativsystemets legitimasjonsbehandler (macOS Keychain, Windows Credential Manager eller Linux libsecret) via `git credential approve`. Ingen legitimasjon skrives til disk som klartekstfiler. Tokenet brukes for plugin-installasjon og sendes aldri til tredjeparter utover Archgate plugins-tjenesten. + +- Del ikke tokenet i CI-logger. Plugin-installasjonskommandoer sender legitimasjon via autentiserte URL-er til git, som kan dukke opp i prosesslister. Unngaa aa kjore `archgate plugin install` med detaljert logging i delte CI-miljoer. +- For aa tilbakekalle tilgang, kjor `archgate login logout`. + +### Selvoppdateringsintegritet + +Naar du kjorer `archgate upgrade`, laster CLI-en ned utgivelsesbinaeeren fra GitHub Releases og verifiserer SHA256-sjekksummen for den pakkes ut. Hvis sjekksummen ikke stemmer, avbrytes oppgraderingen. Dette beskytter mot manipulerte nedlastinger paa grunn av nettverksavlytting eller kompromitterte speil. + +## Rapportere saaerbarheter + +Hvis du oppdager et sikkerhetsproblem i Archgate, vennligst rapporter det ansvarlig ved aa aapne en [GitHub-sak](https://github.com/archgate/cli/issues) eller kontakte vedlikeholderne direkte. Ikke inkluder utnyttelseskode i offentlige saker. diff --git a/docs/src/content/docs/nb/guides/vscode-plugin.mdx b/docs/src/content/docs/nb/guides/vscode-plugin.mdx new file mode 100644 index 00000000..1f0b9f65 --- /dev/null +++ b/docs/src/content/docs/nb/guides/vscode-plugin.mdx @@ -0,0 +1,167 @@ +--- +title: VS Code-plugin +description: Installer Archgate VS Code-utvidelsen for AI-assistert utvikling med arkitekturstyring. Sanntids ADR-samsvarskontroll i editoren din. +--- + +Archgate VS Code-pluginet gir AI-agenter som jobber i [VS Code](https://code.visualstudio.com/) en strukturert styringsarbeidsflyt. Agenter leser ADR-ene dine for de skriver kode, validerer etterpaa, og fanger opp nye monstre for teamet -- den samme arbeidsflyten som er tilgjengelig i [Claude Code-pluginet](/guides/claude-code-plugin/). + +## Hvordan det fungerer + +VS Code stotter **agent-plugins** installert fra git-baserte markedsplasser. Archgate-pluginet serveres fra et git-repositorium paa `plugins.archgate.dev/archgate/vscode.git`. Naar du legger til denne markedsplassen i VS Code-brukerinnstillingene dine, oppdager og installerer VS Code pluginet automatisk. + +Pluginet serveres i VS Code Copilots opprinnelige `.github/plugin/`-manifestformat, adskilt fra Claude Code `.claude-plugin/`-formatet. + +## Installasjon + +:::caution[Krav til VS Code-versjon] +Agent-plugins krever **VS Code 1.110 (februar 2026-utgivelsen) eller nyere**. Tidligere versjoner stotter ikke git-baserte agent-plugin-markedsplasser. Sjekk versjonen din med `code --version`. +::: + +:::note[Betatilgang kreves] +VS Code-pluginet er for oyeblikket i beta. Kjor `archgate login` for aa registrere deg og autentisere for du folger trinnene nedenfor. +::: + +### 1. Logg inn med GitHub + +Autentiser med GitHub-kontoen din for aa faa et plugin-token: + +```bash +archgate login +``` + +Dette starter en GitHub Device Flow. CLI-en viser en engangskode og URL -- aapne URL-en i nettleseren din, skriv inn koden, og autoriser. Naar det er fullfort, lagres legitimasjonen sikkert i operativsystemets legitimasjonsbehandler via `git credential approve`. + +### 2. Initialiser prosjektet ditt med pluginet + +Kjor `archgate init` med `--editor vscode`-flagget: + +```bash +archgate init --editor vscode +``` + +Hvis du allerede er logget inn, vil denne kommandoen: + +1. Opprette `.archgate/`-styringsmappen (ADR-er, lint-regler) +2. Legge til den autentiserte markedsplassens URL i VS Code-**brukerinnstillingene** dine +3. Laste ned og installere Archgate VS Code-utvidelsen (`.vsix`) hvis `code`-CLI-en er tilgjengelig + +Innstillingen `chat.plugins.marketplaces` er applikasjonsscopet i VS Code, saa den kan ikke settes per arbeidsomraade. CLI-en skriver den automatisk til `settings.json` paa brukernivaa: + +| Plattform | Sti til brukerinnstillinger | +| --------- | ------------------------------------------------------- | +| Windows | `%APPDATA%\Code\User\settings.json` | +| macOS | `~/Library/Application Support/Code/User/settings.json` | +| Linux | `~/.config/Code/User/settings.json` | + +For aa eksplisitt be om plugin-installasjon: + +```bash +archgate init --editor vscode --install-plugin +``` + +For aa installere eller reinstallere pluginet paa et allerede initialisert prosjekt: + +```bash +archgate plugin install --editor vscode +``` + +### Genererte filer + +Kommandoen oppretter eller oppdaterer folgende: + +| Fil | Omfang | Formaal | +| ---------------------- | ----------- | ------------------------------------------------------- | +| Bruker `settings.json` | Bruker | `chat.plugins.marketplaces` med den autentiserte URL-en | +| Archgate-utvidelse | Applikasjon | VS Code-utvidelse installert via `.vsix` | + +Brukerinnstillingsfilen flettes additivt -- eksisterende innstillinger overskrives aldri. VS Codes innebygde standardmarkedsplasser (`github/copilot-plugins`, `github/awesome-copilot`) bevares naar nokkelen settes for forste gang. + +VS Code-utvidelsen lastes ned fra Archgate plugins-tjenesten og installeres via `code --install-extension`. Hvis `code`-CLI-en ikke er tilgjengelig, skrives instruksjoner for manuell installasjon ut. + +Markedsplassinnstillingen paa brukernivaa (lagt til i `settings.json`): + +```json +{ + "chat.plugins.marketplaces": [ + "https://:@plugins.archgate.dev/archgate/vscode.git" + ] +} +``` + +### Manuelt oppsett + +Hvis du foretrekker at CLI-en ikke endrer brukerinnstillingene dine, kan du sette opp ting manuelt: + +**Markedsplassens URL:** Aapne VS Codes brukerinnstillinger-JSON (`Ctrl+Shift+P` -> "Preferences: Open User Settings (JSON)") og legg til `chat.plugins.marketplaces`-oppforingen vist ovenfor. Du kan finne den autentiserte URL-en din ved aa kjore `archgate plugin url vscode`. + +**Utvidelse:** Last ned og installer `.vsix`-filen direkte: + +```bash +curl -H "Authorization: Bearer " https://plugins.archgate.dev/api/vscode -o archgate.vsix +code --install-extension archgate.vsix +rm archgate.vsix +``` + +Erstatt `` med archgate-tokenet ditt (hent det via `archgate plugin url vscode`). + +## Hva pluginet tilbyr + +Pluginet legger til en agent og rollebaserte ferdigheter i VS Codes AI. Agenten orkestrerer styringsarbeidsflyten og aktiverer ferdigheter etter behov. + +### Agent + +| Agent | Formaal | +| -------------------- | -------------------------------------------------------------------------- | +| `archgate:developer` | Generell utviklingsagent som leser ADR-er for koding og validerer etterpaa | + +`archgate:developer`-agenten er satt som standardagent via plugin-innstillingene. Den orkestrerer ferdighetene nedenfor automatisk som en del av arbeidsflyten. + +### Ferdigheter + +| Ferdighet | Formaal | +| -------------------------- | --------------------------------------------------------------------------------------- | +| `archgate:architect` | Validerer kodeendringer mot alle prosjektets ADR-er for strukturell samsvar | +| `archgate:quality-manager` | Gjennomgaar regeldekning og foreslar nye ADR-er naar monstre dukker opp | +| `archgate:adr-author` | Oppretter og redigerer ADR-er i henhold til prosjektets konvensjoner | +| `archgate:onboard` | Engangsoppsett: utforsker kodebasen, intervjuer utvikleren, oppretter innledende ADR-er | + +## Forste oppsett med onboard + +Etter installasjon, kjor `archgate:onboard`-ferdigheten i prosjektet ditt en gang. Denne ferdigheten: + +1. Utforsker kodebasestrukturen din (mapper, nokkelfiler, pakkekonfigurasjon) +2. Intervjuer deg om teamets konvensjoner, begrensninger og arkitekturbeslutninger +3. Oppretter et innledende sett med ADR-er basert paa svarene dine +4. Setter opp `.archgate/`-mappen med de forste reglene dine + +Onboard-ferdigheten er designet for aa kjores en gang per prosjekt. Etter onboarding handterer de andre ferdighetene daglig utvikling. + +## Hvordan det fungerer i praksis + +Pluginet folger en strukturert arbeidsflyt for hver kodeoppgave: + +### 1. Les gjeldende ADR-er + +Naar utvikleren gir en kodeoppgave, kjorer agenten `archgate review-context` for aa lese alle ADR-er som gjelder for filene som endres. Dette gir en komprimert briefing med **Decision**- og **Do's and Don'ts**-seksjonene fra hver relevante ADR. + +### 2. Skriv kode i henhold til ADR-begrensninger + +Agenten skriver kode som samsvarer med begrensningene fra ADR-ene. Do's and Don'ts-seksjonene fungerer som konkrete retningslinjer. + +### 3. Valider endringer + +Etter aa ha skrevet kode, kjorer agenten `archgate check` for aa utfore automatiserte regler mot endringene. Eventuelle brudd utbedres for man gaar videre. + +### 4. Arkitektgjennomgang + +Agenten aktiverer `archgate:architect` for aa validere strukturelt ADR-samsvar utover det automatiserte regler fanger opp. + +### 5. Fang opp laeringer + +Agenten aktiverer `archgate:quality-manager` for aa gjennomgaa arbeidet og identifisere monstre som er verdt aa fange opp som nye ADR-er. + +## Tips + +- **Hver utvikler kjorer `archgate init --editor vscode`** etter `archgate login` for aa konfigurere markedsplassens URL paa brukernivaa. +- **Kjor onboard en gang per prosjekt** for aa generere de innledende ADR-ene fra den faktiske kodebasen din. +- **Hold ADR-regelfiler oppdatert** -- agenten haandterer det reglene sjekker for. diff --git a/docs/src/content/docs/nb/guides/writing-adrs.mdx b/docs/src/content/docs/nb/guides/writing-adrs.mdx new file mode 100644 index 00000000..e6f74e09 --- /dev/null +++ b/docs/src/content/docs/nb/guides/writing-adrs.mdx @@ -0,0 +1,327 @@ +--- +title: Skrive ADR-er +description: Komplett guide til å skrive effektive Architecture Decision Records i Archgate. Lær YAML frontmatter-skjemaet, markdown-strukturen og beste praksis. +--- + +## Opprette en ADR + +Bruk `archgate adr create` for å generere en ny ADR med standardmalen. Kommandoen støtter både interaktiv og ikke-interaktiv modus. + +### Interaktiv modus + +Kjør kommandoen uten argumenter for å få veiledende spørsmål: + +```bash +archgate adr create +``` + +Du blir bedt om å oppgi: + +1. **Domene** -- et av de innebygde `backend`, `frontend`, `data`, `architecture` eller `general`, pluss eventuelle [egendefinerte domener](/concepts/domains/#custom-domains) prosjektet har registrert via `archgate adr domain add` +2. **Tittel** -- et kort, beskrivende navn for beslutningen +3. **Filmønstre** -- valgfrie kommaseparerte glob-mønstre som avgrenser regelsjekking (f.eks. `src/commands/**/*.ts`) + +CLI-et tildeler en sekvensiell ID basert på domeneprefikset (`ARCH-001`, `FE-002`, `BE-003` osv.) og skriver filen til `.archgate/adrs/`. + +### Ikke-interaktiv modus + +Bruk `--title` og `--domain` for å hoppe over spørsmålene: + +```bash +archgate adr create --title "API Response Format" --domain backend --files "src/api/**/*.ts" +``` + +Tilgjengelige flagg: + +| Flagg | Beskrivelse | +| ----------------- | ----------------------------------------------------------------------------- | +| `--title ` | ADR-tittel (påkrevd i ikke-interaktiv modus) | +| `--domain <name>` | Domenenavn (innebygd eller [egendefinert](/concepts/domains/#custom-domains)) | +| `--files <globs>` | Kommaseparerte filmønstre for regelavgrensning | +| `--rules` | Setter `rules: true` i frontmatter | +| `--body <md>` | Fullstendig ADR-innhold i markdown (hopper over malen) | +| `--json` | Skriv resultatet som JSON | + +## Den genererte malen + +Når du oppretter en ADR uten `--body`, genererer CLI-et en mal med alle standardseksjoner: + +```markdown +--- +id: BE-001 +title: API Response Format +domain: backend +rules: false +files: ["src/api/**/*.ts"] +--- + +# API Response Format + +## Context + +Describe the context and problem statement. + +## Decision + +Describe the decision that was made. + +## Do's and Don'ts + +### Do + +- + +### Don't + +- + +## Consequences + +### Positive + +- + +### Negative + +- + +### Risks + +- + +## Compliance and Enforcement + +Describe how this decision will be enforced. + +## References + +- +``` + +## Veiledning seksjon for seksjon + +### Context + +Forklar hvorfor denne beslutningen var nødvendig. Hvilket problem utløste den? Hvilke alternativer ble vurdert, og hvorfor ble de forkastet? + +Gode Context-seksjoner inkluderer: + +- Problemet eller smertepunktet som utløste beslutningen +- Alternativer som ble evaluert, med kort avveining +- Eventuelle begrensninger som innsnevret valgene (teamstørrelse, kjøretid, kompatibilitet) + +```markdown +## Context + +The CLI needs a consistent pattern for defining and registering commands. As the +command surface grows (init, check, adr, login, upgrade, clean), the registration +mechanism must scale without introducing hidden coupling or making the dependency +graph opaque. + +**Alternatives considered:** + +- **Auto-discovery via `executableDir()`** -- Commander.js supports automatic + command discovery by scanning a directory. This hides the dependency graph and + makes dead command detection impossible. +- **Single-file command map** -- Simple but creates a monolithic file that grows + with every command. +``` + +### Decision + +Beskriv hva som ble besluttet. Vær spesifikk og konkret -- denne seksjonen skal ikke etterlate noen tvil om hva utviklere må gjøre. + +Inkluder nummererte begrensninger når beslutningen har flere fasetter: + +```markdown +## Decision + +Commands live in src/commands/ and export a register\*Command(program) function. +The main entry point (src/cli.ts) explicitly imports and calls each register +function. + +**Key constraints:** + +1. **One command per file** -- Each .ts file defines exactly one command +2. **Explicit registration** -- Every command must be manually imported in src/cli.ts +3. **Thin commands** -- Command files handle I/O only; no business logic +``` + +### Do's and Don'ts + +Dette er seksjonen utviklere og AI-agenter refererer til oftest. Skriv konkrete eksempler på korrekte og ukorrekte mønstre. Bruk ekte kode når det er mulig. + +```markdown +## Do's and Don'ts + +### Do + +- Export a register\*Command function from each command module +- Keep commands thin: parse args, call helpers/engine, format output +- Use src/commands/<name>.ts for top-level commands + +### Don't + +- Don't put business logic in command files -- move it to src/engine/ or src/helpers/ +- Don't use executableDir() for command discovery +- Don't call .parse() in command files -- the entry point handles parsing +``` + +### Consequences + +Del konsekvensene inn i tre kategorier: + +- **Positive** -- fordeler teamet oppnår med denne beslutningen +- **Negative** -- avveininger teamet aksepterer (enhver beslutning har dem) +- **Risks** -- hva som kan gå galt, og hvordan du planlegger å redusere risikoen + +```markdown +## Consequences + +### Positive + +- In-process execution enables testing without spawning subprocesses +- Explicit imports make all commands visible at a glance in src/cli.ts + +### Negative + +- Manual import bookkeeping -- each new command requires adding an import + +### Risks + +- Stale imports when commands are removed. Mitigation: TypeScript catches + missing modules at compile time. +``` + +### Compliance and Enforcement + +Beskriv hvordan denne beslutningen håndheves. Det finnes to håndhevingsmekanismer: + +1. **Automatiserte regler** -- tilhørende `.rules.ts`-filer som kjøres under `archgate check` +2. **Manuell håndhevelse** -- hva kodegjennomgåere bør verifisere + +```markdown +## Compliance and Enforcement + +### Automated Enforcement + +- **Archgate rule** ARCH-001/register-function-export: Scans all command files + and verifies each exports a register\*Command function. Severity: error. + +### Manual Enforcement + +Code reviewers MUST verify: + +1. New commands are imported and registered in src/cli.ts +2. Command files delegate to engine/helpers for business logic +``` + +### References + +Lenke til relaterte ADR-er, ekstern dokumentasjon eller relevante diskusjoner: + +```markdown +## References + +- [Commander.js documentation](https://github.com/tj/commander.js) +- [ARCH-004 -- No Barrel Files](./ARCH-004-no-barrel-files.md) +- [ARCH-002 -- Error Handling](./ARCH-002-error-handling.md) +``` + +## Avgrense regler med `files` + +Feltet `files` i frontmatter er en matrise med glob-mønstre. Når det er satt, sender `archgate check` bare matchende filer til regelens `ctx.scopedFiles`. Dette holder reglene fokusert på koden de styrer. + +```yaml +--- +id: ARCH-001 +title: Command Structure +domain: architecture +rules: true +files: ["src/commands/**/*.ts"] +--- +``` + +Hvis `files` utelates, inkluderer `ctx.scopedFiles` alle prosjektfiler. Dette er passende for prosjektomfattende regler som avhengighetspolicyer. + +Som standard blir filer oppført i `.gitignore` (f.eks. `node_modules/`, `dist/`) automatisk ekskludert fra `ctx.scopedFiles`, `ctx.glob()` og `ctx.grepFiles()`. For å inkludere gitignorerte filer, sett `respectGitignore: false`: + +```yaml +--- +id: BUILD-001 +title: Build Output Structure +domain: architecture +rules: true +respectGitignore: false +files: ["dist/**/*.js"] +--- +``` + +:::tip[Hold filomfanget smalt] +CLI-et advarer når en ADRs `files`-mønstre treffer mer enn 1 000 filer eller glob-skanningen tar over 2 sekunder. Brede mønstre som `**/*.ts` kan gi trege sjekker i store prosjekter. Foretrekk å målrette spesifikke kataloger (f.eks. `src/commands/**/*.ts`) fremfor prosjektomfattende glob-mønstre. +::: + +Vanlige mønstre: + +| Mønster | Treffer | +| ---------------------- | -------------------------------- | +| `src/commands/**/*.ts` | Alle TypeScript-filer i commands | +| `src/**/*.ts` | Alle TypeScript-kildefiler | +| `package.json` | Bare rot-package.json | +| `src/api/**/*.ts` | API-lagfiler | +| `tests/**/*.test.ts` | Testfiler | + +## Når du skal sette `rules: true` vs `rules: false` + +Sett `rules: true` når du har en tilhørende `.rules.ts`-fil med automatiserte sjekker. Filen må ha samme navn som ADR-markdown-filen, men med `.rules.ts`-endelse: + +``` +.archgate/adrs/ + ARCH-001-command-structure.md # rules: true + ARCH-001-command-structure.rules.ts # tilhørende regelfil + ARCH-002-error-handling.md # rules: true + ARCH-002-error-handling.rules.ts # tilhørende regelfil + GEN-001-code-review-process.md # rules: false (ingen automatiserte sjekker) +``` + +Sett `rules: false` for beslutninger som bare håndheves gjennom kodegjennomgang -- prosessbeslutninger, teamavtaler eller retningslinjer som er vanskelige å sjekke programmatisk. + +## Oppdatere ADR-er + +Bruk `archgate adr update` for å endre en eksisterende ADR: + +```bash +archgate adr update --id ARCH-001 --body "## Context\n\nUpdated context..." --title "New Title" +``` + +Flaggene `--id` og `--body` er påkrevd. Alle andre frontmatter-felt (`--title`, `--domain`, `--files`, `--rules`) er valgfrie og beholder eksisterende verdier når de utelates. + +| Flagg | Beskrivelse | +| ----------------- | --------------------------------------------------- | +| `--id <id>` | ADR-ID som skal oppdateres (påkrevd) | +| `--body <md>` | Fullstendig erstatningsinnhold i markdown (påkrevd) | +| `--title <title>` | Ny tittel (beholder eksisterende hvis utelatt) | +| `--domain <name>` | Nytt domene (beholder eksisterende hvis utelatt) | +| `--files <globs>` | Nye filmønstre (beholder eksisterende hvis utelatt) | +| `--rules` | Setter `rules: true` | +| `--json` | Skriv resultatet som JSON | + +## Tips for effektive ADR-er + +1. **Hold hver ADR fokusert på en enkelt beslutning.** Hvis du oppdager at du skriver om to urelaterte emner, del dem opp i separate ADR-er. + +2. **Vær spesifikk i Do's and Don'ts.** Vage retningslinjer som "skriv ren kode" er ikke handlingsbare. Vis konkrete kodemønstre. + +3. **Inkluder ekte kodeeksempler.** Do's and Don'ts-seksjonen er der utviklere og AI-agenter ser først. Annoterte kodeeksempler gjør beslutningen utvetydig. + +4. **Dokumenter alternativer du forkastet.** Fremtidige bidragsytere vil spørre "hvorfor brukte vi ikke X?" Context-seksjonen bør svare på det spørsmålet. + +5. **Beskriv avveininger ærlig.** Enhver beslutning har negative konsekvenser. Å dokumentere dem bygger tillit og hjelper teamet med å forstå hva som ble ofret. + +6. **Skriv regler for beslutninger som kan sjekkes automatisk.** Hvis en regel kan fange et brudd før kodegjennomgang, sett `rules: true` og skriv en tilhørende `.rules.ts`-fil. Se guiden [Skrive regler](/guides/writing-rules/). + +7. **Bruk domeneprefikser for å organisere.** Domenefeltet bestemmer ID-prefikset og hjelper med å filtrere ADR-er etter område. Foretrekk de fem innebygde (`backend`, `frontend`, `data`, `architecture`, `general`); registrer et [egendefinert domene](/concepts/domains/#custom-domains) bare når ingen av dem passer godt. + +:::tip[La AI-agenter skrive ADR-er for deg] +Redaktørpluginene for [Claude Code](/guides/claude-code-plugin/) og [Cursor](/guides/cursor-integration/) inkluderer en ADR Author-ferdighet som oppretter og oppdaterer ADR-er i henhold til prosjektets konvensjoner. Quality Manager-ferdigheten foreslår også nye ADR-er når den oppdager gjentakende mønstre. [Meld deg på beta-tilgang](https://plugins.archgate.dev). +::: diff --git a/docs/src/content/docs/nb/guides/writing-rules.mdx b/docs/src/content/docs/nb/guides/writing-rules.mdx new file mode 100644 index 00000000..72fc3a61 --- /dev/null +++ b/docs/src/content/docs/nb/guides/writing-rules.mdx @@ -0,0 +1,308 @@ +--- +title: Skrive regler +description: Skriv TypeScript-regler som automatisk håndhever Architecture Decision Records. Lær Archgate-regel-API-et med satisfies RuleSet, filmønstermatching og bruddrapportering. +--- + +Regler er TypeScript-funksjoner som sjekker kodebasen din for ADR-samsvar. De ligger i tilhørende `.rules.ts`-filer ved siden av ADR-markdown-filer og kjøres når du utfører `archgate check`. + +``` +.archgate/adrs/ + ARCH-001-command-structure.md # Beslutningen + ARCH-001-command-structure.rules.ts # De automatiserte sjekkene +``` + +## Grunnleggende oppsett + +Hver regelfil eksporterer et standard-objekt typet med `satisfies RuleSet`. Hver nøkkel i `rules`-objektet blir en regel-ID, og hver regel har en `description` og en asynkron `check`-funksjon som mottar et kontekstobjekt. + +```typescript +/// <reference path="../rules.d.ts" /> + +export default { + rules: { + "my-rule-id": { + description: "What this rule checks", + async check(ctx) { + // Your check logic here + }, + }, + }, +} satisfies RuleSet; +``` + +:::note[Merknad] +Direktivet `/// <reference path>` kan komme i konflikt med regelen `@typescript-eslint/triple-slash-reference` i ESLint eller oxlint. Hvis prosjektet ditt bruker denne regelen, deaktiver den for `.archgate/adrs/`-filer. + +For **ESLint** (flat config): + +```js +{ + files: [".archgate/adrs/*.rules.ts"], + rules: { "@typescript-eslint/triple-slash-reference": "off" }, +} +``` + +For **oxlint** (`.oxlintrc.json`): + +```json +{ + "overrides": [ + { + "files": [".archgate/adrs/*.rules.ts"], + "rules": { "typescript/triple-slash-reference": "off" } + } + ] +} +``` + +::: + +En enkelt regelfil kan definere flere regler: + +```typescript +/// <reference path="../rules.d.ts" /> + +export default { + rules: { + "first-rule": { + description: "Checks one thing", + async check(ctx) { + // ... + }, + }, + "second-rule": { + description: "Checks another thing", + async check(ctx) { + // ... + }, + }, + }, +} satisfies RuleSet; +``` + +## Context API-et + +`ctx`-objektet som sendes til hver `check`-funksjon gir muligheter for fillesing, søk og rapportering. Her er en detaljert referanse med eksempler. + +### ctx.scopedFiles + +En matrise med filstier som matcher ADR-ens `files`-glob fra frontmatter. Hvis ADR-en ikke har noe `files`-felt, inkluderer dette alle prosjektfiler. + +```typescript +for (const file of ctx.scopedFiles) { + const content = await ctx.readFile(file); + // Check content... +} +``` + +Bruk `ctx.scopedFiles` når regelen din bare skal gjelde filer ADR-en styrer. For eksempel vil en kommandostrukturregel avgrenset til `src/commands/**/*.ts` bare motta kommandofiler. + +### ctx.changedFiles + +En matrise med filstier som skiller seg fra grunngrenen. Auto-detektert som standard, eller fylt fra `--staged` / `--base <ref>`. Nyttig for inkrementell sjekking og regler for avhengigheter mellom filer. + +```typescript +// Incremental checking -- only validate changed files +const filesToCheck = ctx.scopedFiles.filter((f) => + ctx.changedFiles.includes(f) +); + +// Cross-file dependency -- if file A changed, file B must also change +if (ctx.changedFiles.includes("config/database.yml")) { + if (!ctx.changedFiles.includes("deploy/manifest.yml")) { + ctx.report.violation({ + message: "config changed but manifest was not bumped", + file: "config/database.yml", + }); + } +} +``` + +### ctx.readFile(path) + +Les innholdet i en fil som en streng. Stien er relativ til prosjektroten. + +```typescript +const content = await ctx.readFile("src/cli.ts"); +``` + +### ctx.readJSON(path) + +Les og parse en JSON-fil. Returnerer `unknown` -- cast den til forventet form. + +```typescript +const pkg = (await ctx.readJSON("package.json")) as { + dependencies?: Record<string, string>; +}; +``` + +### ctx.grep(file, pattern) + +Søk i en enkelt fil med et regulært uttrykk. Returnerer en matrise med `GrepMatch`-objekter, hver med egenskapene `file`, `line`, `column` og `content`. + +```typescript +const matches = await ctx.grep(file, /console\.error\(/); +for (const match of matches) { + ctx.report.violation({ + message: "Use logError() instead of console.error()", + file: match.file, + line: match.line, + }); +} +``` + +### ctx.grepFiles(pattern, fileGlob) + +Søk på tvers av flere filer som matcher et glob-mønster. Returnerer en flat matrise med `GrepMatch`-objekter fra alle matchende filer. Filer ignorert av `.gitignore` ekskluderes som standard. Sett `respectGitignore: false` i ADR-frontmatter for å inkludere dem. + +```typescript +const matches = await ctx.grepFiles(/TODO:/, "src/**/*.ts"); +for (const match of matches) { + ctx.report.warning({ + message: "TODO comment found", + file: match.file, + line: match.line, + }); +} +``` + +### ctx.glob(pattern) + +Finn filer etter glob-mønster. Returnerer en matrise med filstier relative til prosjektroten. Filer ignorert av `.gitignore` ekskluderes som standard. Sett `respectGitignore: false` i ADR-frontmatter for å inkludere dem. + +```typescript +const testFiles = await ctx.glob("tests/**/*.test.ts"); +``` + +### ctx.report + +Rapporteringsgrensesnittet med tre alvorlighetsgradsmetoder: + +- `ctx.report.violation(detail)` -- feil-alvorlighetsgrad (exit-kode 1, blokkerer CI) +- `ctx.report.warning(detail)` -- advarsel-alvorlighetsgrad (logges, men blokkerer ikke) +- `ctx.report.info(detail)` -- informasjon (logges for synlighet) + +Hver metode aksepterer et objekt med: + +| Felt | Type | Påkrevd | Beskrivelse | +| --------- | -------- | ------- | ---------------------------------------- | +| `message` | `string` | Ja | Hva bruddet er | +| `file` | `string` | Nei | Sti til den problematiske filen | +| `line` | `number` | Nei | Linjenummer for bruddet | +| `fix` | `string` | Nei | Foreslått løsning (vises til utvikleren) | + +```typescript +ctx.report.violation({ + message: "Command file must export a register*Command function", + file: "src/commands/check.ts", + line: 5, + fix: "Add: export function registerCheckCommand(program: Command) { ... }", +}); +``` + +### ctx.projectRoot + +Den absolutte stien til prosjektets rotkatalog. Nyttig når du trenger å konstruere absolutte stier. + +## Alvorlighetsgrader + +Hver regel kan sette en standard alvorlighetsgrad i konfigurasjonen sin. Alvorlighetsgraden bestemmer hvordan brudd behandles: + +| Alvorlighetsgrad | Exit-kode | Oppførsel | +| ---------------- | --------- | --------------------------------- | +| `error` | 1 | Blokkerer CI, må fikses | +| `warning` | 0 | Logges, men blokkerer ikke | +| `info` | 0 | Informasjon, logges for synlighet | + +Sett alvorlighetsgraden i regeldefinisjonen: + +```typescript +export default { + rules: { + "my-rule": { + description: "...", + severity: "warning", + async check(ctx) { + // Violations from this rule are warnings, not errors + ctx.report.violation({ message: "..." }); + }, + }, + }, +} satisfies RuleSet; +``` + +Hvis `severity` utelates, er standardverdien `error`. + +Du kan også rapportere med ulike alvorlighetsgrader innenfor samme regel ved å bruke `ctx.report.violation()`, `ctx.report.warning()` og `ctx.report.info()` direkte. + +## Tidsgrense for regler + +Hver regel har en kjøringstidsgrense på 30 sekunder. Hvis en regel overskrider denne grensen, behandles den som en feil. Dette forhindrer at uendelige sjekker blokkerer pipelinen. + +Hold reglene raske ved å: + +- Bruke `ctx.grepFiles()` i stedet for å lese hver fil manuelt +- Bruke `Promise.all()` for å sjekke filer parallelt +- Avgrense regler med `files`-feltet i frontmatter for å begrense antall filer som behandles + +## `fix`-feltet + +`fix`-feltet er en valgfri streng som vises til utvikleren sammen med bruddmeldingen. Den beskriver hvilken handling som må utføres for å løse problemet. Fikser brukes ikke automatisk -- de er veiledning. + +```typescript +ctx.report.violation({ + message: `Unapproved dependency: "chalk"`, + file: "package.json", + fix: "Use styleText() from node:util instead of chalk", +}); +``` + +Når den vises, kommer fiksen under bruddmeldingen: + +``` +ARCH-006/no-unapproved-deps + package.json + Unapproved dependency: "chalk" + Fix: Use styleText() from node:util instead of chalk +``` + +## Tips for å skrive regler + +1. **Bruk `Promise.all()` for parallelle filsjekker.** Når du sjekker flere filer uavhengig, prosesser dem parallelt i stedet for sekvensielt. + + ```typescript + // Good: parallel + const checks = files.map(async (file) => { + const content = await ctx.readFile(file); + // ... + }); + await Promise.all(checks); + + // Avoid: sequential + for (const file of files) { + const content = await ctx.readFile(file); + // ... + } + ``` + +2. **Bruk `ctx.changedFiles` for inkrementell sjekking.** `ctx.changedFiles` fylles automatisk med grenforskjellen (eller stagede filer med `--staged`). Filtrer `ctx.scopedFiles` mot den for å bare sjekke det som er endret, eller bruk den direkte for regler om avhengigheter mellom filer. + +3. **Hold reglene fokusert på ett anliggende.** En regel som sjekker både navnekonvensjoner og importmønstre bør deles i to regler med separate ID-er. + +4. **Bruk `ctx.grepFiles()` fremfor manuell iterering.** Når du søker etter et mønster på tvers av mange filer, er `ctx.grepFiles()` mer effektivt enn å lese hver fil og kjøre et regulært uttrykk. + +5. **Gi handlingsbare `fix`-meldinger.** En fiks som "Ikke gjør dette" er ikke nyttig. Fortell utvikleren nøyaktig hva som skal gjøres i stedet. + +6. **Filtrer bort ikke-relevante filer tidlig.** Hvis regelen din bare gjelder for bestemte filer innenfor omfanget, filtrer `ctx.scopedFiles` før prosessering: + + ```typescript + const commandFiles = ctx.scopedFiles.filter((f) => !f.endsWith("index.ts")); + ``` + +7. **Håndter manglende filer elegant.** Hvis regelen din leser en spesifikk fil som `package.json`, pakk lesingen i en try/catch og returner tidlig hvis filen ikke eksisterer. + +## Neste steg + +- [Vanlige regelmønstre](/examples/common-rule-patterns/) -- Kopier-og-lim-inn-mønstre organisert etter kategori: avhengighetshåndtering, importrestriksjoner, filstruktur, kodekvalitet, databaseskjema og arkitekturgrenser. +- [Regel-API-referanse](/reference/rule-api/) -- Fullstendig referanse for alle regel-API-typer og -funksjoner. +- [CI-integrasjon](/guides/ci-integration/) -- Koble `archgate check` til pipelinen din for å håndheve regler på hver PR. diff --git a/docs/src/content/docs/nb/index.mdx b/docs/src/content/docs/nb/index.mdx new file mode 100644 index 00000000..a4ca1f18 --- /dev/null +++ b/docs/src/content/docs/nb/index.mdx @@ -0,0 +1,128 @@ +--- +title: Archgate +description: Archgate CLI håndhever Architecture Decision Records (ADR-er) som kjørbare TypeScript-regler. Automatiser kodestyring for mennesker og AI-agenter. +template: splash +hero: + tagline: Skriv en ADR én gang. Håndhev den overalt. Gi den til AI-agenter automatisk. + actions: + - text: Kom i gang + link: /getting-started/installation/ + icon: right-arrow + variant: primary + - text: Se på GitHub + link: https://github.com/archgate/cli + icon: external + variant: minimal +--- + +import { Card, CardGrid, LinkCard } from "@astrojs/starlight/components"; +import CodeShowcase from "../../../components/CodeShowcase.astro"; + +## Hvordan det fungerer + +Archgate har to lag som fungerer sammen: + +1. **ADR-er som dokumenter** — Markdown-filer med YAML-frontmatter som beskriver arkitekturbeslutninger i klartekst. Mennesker leser dem. AI-agenter leser dem. Alle holder seg samkjørte. + +2. **ADR-er som regler** — Tilhørende `.rules.ts`-filer med automatiserte kontroller skrevet i TypeScript. De kjøres mot kodebasen din og rapporterer brudd med filstier og linjenumre. + +<CodeShowcase + heading="ADR-er som håndhever seg selv" + subtext="Skriv en beslutning i Markdown. Legg til regler i TypeScript. CLI-en sjekker samsvar automatisk." +/> + +Når du kjører `archgate check`, laster CLI-en inn hver ADR som har `rules: true` i frontmatter, kjører den tilhørende regelfilen og rapporterer eventuelle brudd. Utgangskode 0 betyr at koden din er i samsvar. Utgangskode 1 betyr at den ikke er det. + +## Hovedfunksjoner + +<CardGrid> + <Card title="Kjørbare regler" icon="seti:typescript"> + Skriv regler i TypeScript. Archgate kjører dem mot kodebasen din og + rapporterer brudd med filstier og linjenumre. Reglene ligger ved siden av + beslutningene de håndhever. + </Card> + <Card title="CI-integrasjon" icon="seti:pipeline"> + Koble `archgate check` inn i pipelinen din. Utgangskode 1 blokkerer merges + når regler brytes. Fungerer med GitHub Actions, GitLab CI eller ethvert + CI-system som respekterer utgangskoder. + </Card> + <Card title="AI-bevisst styring" icon="star"> + Editorplugins gir AI-agenter direkte tilgang til ADR-ene dine via + CLI-kommandoer. De leser beslutninger før de skriver kode, og validerer + etterpå. Ingen kopiering og liming av regler i ledetekster. + </Card> + <Card title="Selvstyre" icon="approve-check-circle"> + Archgate styrer sin egen utvikling. Det samme verktøyet som sjekker koden + din, sjekker vår. Våre egne ADR-er håndhever kommandostruktur, + feilhåndtering, utdataformatering, testing og mer — [se dem på + GitHub](https://github.com/archgate/cli/tree/main/.archgate/adrs). + </Card> +</CardGrid> + +## Editorplugins + +Archgate CLI fungerer frittstående, men **editorplugins** låser opp en fullstendig AI-styringsarbeidsflyt. Plugins gir AI-agenter rollebaserte ferdigheter slik at de leser ADR-ene dine før de koder, validerer etterpå og fanger opp nye mønstre for teamet ditt — automatisk. + +<CardGrid> + <Card title="Claude Code" icon="star"> + Claude Code-pluginen legger til fem ferdigheter: developer, architect, + quality-manager, adr-author og onboard. Agenter følger en strukturert + les-valider-fang-løkke for hver oppgave. + </Card> + <Card title="Cursor" icon="pencil"> + Cursor-pluginen tilbyr ferdigbygde agentregler og ferdigheter som gir + Cursors AI-agent den samme styringsarbeidsflyten som Claude Code. + </Card> +</CardGrid> + +:::tip[Beta-tilgang] +Editorplugins er for øyeblikket i beta. Kjør `archgate login` for å registrere deg og autentisere, deretter `archgate init --install-plugin` for å sette opp pluginen. +::: + +<CardGrid> + <LinkCard + title="Claude Code plugin-guide" + href="/guides/claude-code-plugin/" + description="Fullstendig oppsett- og bruksguide for Claude Code-pluginen." + /> + <LinkCard + title="VS Code plugin-guide" + href="/guides/vscode-plugin/" + description="Sett opp Archgate med VS Code." + /> + <LinkCard + title="Copilot CLI plugin-guide" + href="/guides/copilot-cli-plugin/" + description="Sett opp Archgate med GitHub Copilot CLI." + /> + <LinkCard + title="Cursor integrasjonsguide" + href="/guides/cursor-integration/" + description="Sett opp Archgate med Cursor IDE." + /> +</CardGrid> + +## Lær mer + +<CardGrid> + <LinkCard + title="Hva er ADR-er?" + href="/concepts/adrs/" + description="Forstå Architecture Decision Records og hvordan Archgate bruker dem." + /> + <LinkCard + title="Skrive regler" + href="/guides/writing-rules/" + description="Skriv TypeScript-regler som håndhever beslutningene dine automatisk." + /> + <LinkCard + title="CI-integrasjon" + href="/guides/ci-integration/" + description="Blokker merges når regler brytes i GitHub Actions, GitLab CI eller en hvilken som helst pipeline." + /> + <LinkCard + title="CLI-kommandoer" + href="/reference/cli-commands/" + description="Komplett referanse for alle Archgate CLI-kommandoer og -alternativer." + /> +</CardGrid> diff --git a/docs/src/content/docs/nb/reference/adr-schema.mdx b/docs/src/content/docs/nb/reference/adr-schema.mdx new file mode 100644 index 00000000..6e0892d2 --- /dev/null +++ b/docs/src/content/docs/nb/reference/adr-schema.mdx @@ -0,0 +1,309 @@ +--- +title: ADR-skjema +description: Komplett YAML frontmatter-skjema og Markdown-strukturreferanse for Archgate Architecture Decision Records. Alle felt og valideringsregler forklart. +--- + +Hver Archgate ADR er en Markdown-fil lagret i `.archgate/adrs/` med YAML frontmatter som definerer beslutningens identitet og omfang. Denne siden dokumenterer frontmatter-skjemaet, Markdown-seksjonsstrukturen og valideringsatferd. + +## Frontmatter-skjema + +YAML frontmatter-blokken ligger mellom `---`-skilletegn overst i filen. + +```yaml +--- +id: ARCH-001 +title: Command Structure +domain: architecture +rules: true +files: ["src/commands/**/*.ts"] +--- +``` + +### Felt + +| Felt | Type | Pakrevd | Beskrivelse | +| ------------------ | ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | `string` | Ja | Unik identifikator. Ma vaere ikke-tom. Konvensjon: `PREFIX-NNN` (f.eks. `ARCH-001`). | +| `title` | `string` | Ja | Lesbar tittel pa beslutningen. Ma vaere ikke-tom. | +| `domain` | `string` | Ja | Et registrert domenenavn i kebab-case med sma bokstaver. Innebygde: `backend`, `frontend`, `data`, `architecture`, `general`. Egendefinerte domener registreres via [`archgate adr domain add`](/reference/cli/adr/#archgate-adr-domain). | +| `rules` | `boolean` | Ja | Om denne ADR-en har en tilhorende `.rules.ts`-fil med automatiserte kontroller. | +| `files` | `string[]` | Nei | Globmonstre som avgrenser hvilke filer reglene gjelder for. | +| `respectGitignore` | `boolean` | Nei | Om `.gitignore`-filer skal filtreres bort. Standard er `true`. | + +### id + +ADR-identifikatoren. Etter konvensjon brukes domeneprefikset etterfulgt av et null-utfylt sekvensnummer (f.eks. `ARCH-001`, `BE-003`). Kommandoen `archgate adr create` genererer ID-er automatisk. + +Enhver ikke-tom streng er gyldig, men a folge prefikskonvensjonen holder ADR-ene organisert og sorterbare. + +### title + +Et kort, beskrivende navn for den arkitektoniske beslutningen. Vises i `archgate adr list`-utdata og brukes som overskrift nar AI-agenter refererer til ADR-en. + +### domain + +Grupperer relaterte ADR-er sammen. Domenet bestemmer ogsa ID-prefikset som brukes av `archgate adr create`. + +Prosjekter kan utvide det innebygde settet med egendefinerte domener via [`archgate adr domain add`](/reference/cli/adr/#archgate-adr-domain). Egendefinerte domene-til-prefiks-tilordninger lagres i `.archgate/config.json` og slAs sammen med de innebygde ved lesing. + +### rules + +Sett til `true` nar denne ADR-en har en tilhorende `.rules.ts`-fil. Nar `archgate check` kjorer, hopper den over ADR-er der `rules` er `false`. + +### files + +En valgfri matrise med globmonstre som avgrenser regelens fildekning. Nar den er til stede, inneholder `ctx.scopedFiles` i regelfilen kun filer som matcher disse monstrene. Nar den er fravarende, er alle prosjektfiler i omfang. + +```yaml +files: ["src/commands/**/*.ts"] +``` + +Flere monstre kan spesifiseres: + +```yaml +files: ["src/api/**/*.ts", "src/middleware/**/*.ts"] +``` + +### respectGitignore + +Styrer om `.gitignore`-filer ekskluderes fra `ctx.scopedFiles`, `ctx.glob()` og `ctx.grepFiles()`. Standard er `true` nar feltet utelates -- gitignorerte filer (f.eks. `node_modules/`, `dist/`) filtreres automatisk bort. + +Sett til `false` nar en regel med vilje trenger a inspisere ignorerte filer, for eksempel for a sjekke strukturen pa byggeutdata: + +```yaml +respectGitignore: false +files: ["dist/**/*.js"] +``` + +Nar `respectGitignore` er `false`, inkluderes alle filer som matcher `files`-globene uavhengig av `.gitignore`-regler. Nar man ikke er inne i et git-repository, har dette feltet ingen effekt -- alle matchede filer inkluderes. + +--- + +## Domeneprefikser + +Hvert domene tilordnes et prefiks som brukes i ADR-ID-konvensjonen. + +### Innebygde domener + +| Domene | Prefiks | Eksempel-ID | +| -------------- | ------- | ----------- | +| `backend` | `BE` | `BE-001` | +| `frontend` | `FE` | `FE-001` | +| `data` | `DATA` | `DATA-001` | +| `architecture` | `ARCH` | `ARCH-001` | +| `general` | `GEN` | `GEN-001` | + +Kommandoen `archgate adr create` bruker denne tilordningen til a autogenerere ID-er. + +### Egendefinerte domener + +Prosjekter kan registrere ytterligere domene-til-prefiks-tilordninger via [`archgate adr domain add`](/reference/cli/adr/#archgate-adr-domain). Nar de er registrert, oppforer egendefinerte domener seg som innebygde: `archgate adr create --domain <name>` autogenererer ID-er med det tilhorende prefikset, og ADR-er med egendefinerte domener parses uten problemer. + +Se [konseptsiden for domener](/concepts/domains/) for veiledning om nar du bor introdusere et egendefinert domene. + +--- + +## Konvensjon for filnavn + +ADR-filer folger en navnekonvensjon som koder inn ID-en og en lesbar slug: + +``` +{ID}-{slug}.md # Dokumentet +{ID}-{slug}.rules.ts # Den tilhorende regelfilen (valgfri) +``` + +For eksempel: + +``` +ARCH-001-command-structure.md +ARCH-001-command-structure.rules.ts +``` + +Slugen er en kebab-case-versjon av tittelen, autogenerert av `archgate adr create`. + +--- + +## Markdown-seksjoner + +Etter frontmatter folger ADR-kroppen en standard seksjonsstruktur. Selv om Archgate ikke pahvinger spesifikke seksjoner, anbefales folgende struktur for konsistens. + +### Context + +Beskriver problemet eller situasjonen som utloste beslutningen. Inkluder alternativer som ble vurdert og hvorfor de ble forkastet. + +```markdown +## Context + +The CLI returns errors in inconsistent formats. Some commands print raw +stack traces, others print nothing, and a few use `console.error()` with +custom formatting. + +**Alternatives considered:** + +- **No standard** -- Let each command handle errors its own way. Simple + but leads to an inconsistent user experience. +- **Try/catch wrapper** -- A global try/catch at the CLI entry point. + Loses context about which command failed. +``` + +### Decision + +Angir selve beslutningen og dens viktigste begrensninger. Dette er den primaere seksjonen AI-agenter leser for de skriver kode. + +```markdown +## Decision + +All commands MUST use `logError()` from `src/helpers/log.ts` for error +output. Commands MUST NOT call `console.error()` directly. +``` + +### Do's and Don'ts + +Konkret, handlingsrettet veiledning delt i to underseksjoner. Disse fungerer som en hurtigreferanse-sjekkliste for utviklere og AI-agenter. + +```markdown +## Do's and Don'ts + +### Do + +- Use `logError(message, detail?)` for all error output +- Include a suggested fix in the detail parameter when possible +- Exit with code 1 for user errors, code 2 for internal errors + +### Don't + +- Don't call `console.error()` directly in command files +- Don't print stack traces to users +- Don't exit without printing an error message first +``` + +### Consequences + +Delt i tre underseksjoner som dokumenterer avveininger. + +```markdown +## Consequences + +### Positive + +- Consistent error formatting across all commands +- Machine-parseable error output when combined with `--json` + +### Negative + +- Requires importing `logError` in every command file +- Cannot use built-in error formatting from libraries + +### Risks + +- New contributors may use `console.error()` by habit. Mitigated by the + automated rule that scans for direct `console.error()` calls. +``` + +### Compliance and Enforcement + +Beskriver hvordan beslutningen handheves gjennom automatiserte regler og manuell gjennomgang. + +```markdown +## Compliance and Enforcement + +### Automated Enforcement + +- **Archgate rule** ARCH-002/no-console-error: Scans command files for + `console.error()` calls. Severity: error. + +### Manual Enforcement + +Code reviewers MUST verify: + +1. Error messages are actionable and include context +2. Exit codes match the error type (1 for user, 2 for internal) +``` + +### References + +Lenker til relaterte ADR-er, ekstern dokumentasjon eller designdokumenter. + +```markdown +## References + +- [ARCH-001 -- Command Structure](./ARCH-001-command-structure.md) +- [Node.js process.exit documentation](https://nodejs.org/api/process.html#processexitcode) +``` + +--- + +## Tilhorende regelfil + +Nar `rules: true`, leter Archgate etter en tilhorende fil med samme navn men `.rules.ts`-endelse. + +``` +ARCH-002-error-handling.md # rules: true i frontmatter +ARCH-002-error-handling.rules.ts # tilhorende regelfil +``` + +Regelfilen ma eksportere et standard `RuleSet` ved hjelp av et vanlig objekt med `satisfies RuleSet`: + +```typescript +/// <reference path="../rules.d.ts" /> + +export default { + rules: { + "no-console-error": { + description: "Use logError() instead of console.error()", + async check(ctx) { + for (const file of ctx.scopedFiles) { + const matches = await ctx.grep(file, /console\.error\(/); + for (const match of matches) { + ctx.report.violation({ + message: "Use logError() instead of console.error()", + file: match.file, + line: match.line, + fix: "Import logError from src/helpers/log and use it instead", + }); + } + } + }, + }, + }, +} satisfies RuleSet; +``` + +Se [Rule API](/reference/rule-api/) for den komplette TypeScript API-referansen. + +--- + +## Validering + +YAML frontmatter valideres ved parsetidspunkt ved hjelp av et Zod-skjema. Ugyldig frontmatter forarsakar en parsefeil med en beskrivende melding. + +### Pakrevde felt + +Hvis et pakrevd felt mangler, feiler ADR-parsingen: + +``` +Invalid ADR frontmatter in ARCH-001-example.md: + - domain: Required +``` + +### Ugyldig domeneformat + +Hvis `domain` ikke er en gyldig kebab-case-identifikator (f.eks. har store bokstaver eller mellomrom): + +``` +Invalid ADR frontmatter in ARCH-001-example.md: + - domain: domain must be lowercase kebab-case (e.g. 'backend', 'ml-ops') +``` + +Merk: parseren aksepterer ethvert navn som matcher kebab-case-monsteret. Om et spesifikt navn er "kjent" for prosjektet -- og dermed har et prefiks som `archgate adr create` kan bruke -- avhenger av det innebygde settet pluss eventuelle egendefinerte domener registrert via [`archgate adr domain add`](/reference/cli/adr/#archgate-adr-domain). A opprette en ADR med et uregistrert domenenavn feiler med en "Unknown ADR domain"-feil som foreslar a kjore `archgate adr domain add`. + +### Typefeil + +Hvis `rules` er en streng i stedet for en boolean: + +``` +Invalid ADR frontmatter in ARCH-001-example.md: + - rules: Expected boolean, received string +``` + +ADR-er som feiler validering, hoppes over av `archgate check` og rapporteres som feil. diff --git a/docs/src/content/docs/nb/reference/cli/adr.mdx b/docs/src/content/docs/nb/reference/cli/adr.mdx new file mode 100644 index 00000000..4ef3aa04 --- /dev/null +++ b/docs/src/content/docs/nb/reference/cli/adr.mdx @@ -0,0 +1,321 @@ +--- +title: archgate adr +description: "Opprett, list, vis og oppdater Architecture Decision Records." +--- + +## archgate adr create + +Opprett en ny ADR interaktivt eller via flagg. + +```bash +archgate adr create [options] +``` + +Når kommandoen kjøres uten `--title` og `--domain`, spør den interaktivt om domene, tittel og valgfrie filmønstre. Når både `--title` og `--domain` er oppgitt, kjører den ikke-interaktivt. + +ADR-ID-en genereres automatisk med domeneprefikset og neste tilgjengelige sekvensnummer (f.eks. `ARCH-002`, `BE-001`). + +### Valg + +| Valg | Beskrivelse | +| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--title <title>` | ADR-tittel (hopp over interaktiv prompt) | +| `--domain <domain>` | ADR-domene. Innebygde: `backend`, `frontend`, `data`, `architecture`, `general`. Egendefinerte domener må først registreres via [`archgate adr domain add`](#archgate-adr-domain). | +| `--files <patterns>` | Filmønstre, kommaseparert | +| `--body <markdown>` | Fullstendig ADR-brødtekst i markdown (hopp over mal) | +| `--rules` | Sett `rules: true` i frontmatter | +| `--json` | Utdata som JSON | + +### Eksempler + +Interaktiv modus: + +```bash +archgate adr create +``` + +Ikke-interaktiv modus: + +```bash +archgate adr create \ + --title "API Response Envelope" \ + --domain backend \ + --files "src/api/**/*.ts" \ + --rules +``` + +--- + +## archgate adr list + +List alle ADR-er i prosjektet. + +```bash +archgate adr list [options] +``` + +### Valg + +| Valg | Beskrivelse | +| ------------------- | -------------------- | +| `--json` | Utdata som JSON | +| `--domain <domain>` | Filtrer etter domene | + +### Eksempler + +List alle ADR-er i tabellformat: + +```bash +archgate adr list +``` + +``` +ID Domain Rules Title +──────────────────────────────────────────────────────── +ARCH-001 architecture true Command Structure +ARCH-002 architecture true Error Handling +BE-001 backend true API Response Envelope +``` + +List ADR-er som JSON: + +```bash +archgate adr list --json +``` + +Filtrer etter domene: + +```bash +archgate adr list --domain backend +``` + +--- + +## archgate adr show + +Skriv ut en bestemt ADR etter ID. + +```bash +archgate adr show <id> +``` + +Skriver ut hele ADR-innholdet (frontmatter og brødtekst) til stdout. + +### Argumenter + +| Argument | Beskrivelse | +| -------- | ------------------------------------ | +| `<id>` | ADR-ID (f.eks. `ARCH-001`, `BE-003`) | + +### Eksempel + +```bash +archgate adr show ARCH-001 +``` + +--- + +## archgate adr update + +Oppdater en eksisterende ADR etter ID. + +```bash +archgate adr update --id <id> --body <markdown> [options] +``` + +Erstatter ADR-brødteksten med den oppgitte markdownen. Frontmatter-felter (`--title`, `--domain`, `--files`, `--rules`) oppdateres bare når de eksplisitt sendes med; ellers beholdes eksisterende verdier. + +### Valg + +| Valg | Påkrevd | Beskrivelse | +| -------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--id <id>` | Ja | ADR-ID å oppdatere (f.eks. `ARCH-001`) | +| `--body <markdown>` | Ja | Fullstendig erstatnings-ADR-brødtekst i markdown | +| `--title <title>` | Nei | Ny ADR-tittel (beholder eksisterende hvis utelatt) | +| `--domain <domain>` | Nei | Nytt domene. Innebygde: `backend`, `frontend`, `data`, `architecture`, `general`. Egendefinerte domener må først registreres via [`archgate adr domain add`](#archgate-adr-domain). | +| `--files <patterns>` | Nei | Nye filmønstre, kommaseparert (beholder eksisterende hvis utelatt) | +| `--rules` | Nei | Sett `rules: true` i frontmatter | +| `--json` | Nei | Utdata som JSON | + +### Eksempel + +```bash +archgate adr update \ + --id ARCH-001 \ + --title "Updated Command Structure" \ + --body "## Context\n\nUpdated context..." +``` + +--- + +## archgate adr domain + +Administrer egendefinerte ADR-domener. Egendefinerte domener er navn-til-ID-prefiks-tilordninger som lagres i `.archgate/config.json` og slås sammen med de fem innebygde (`backend`, `frontend`, `data`, `architecture`, `general`) ved lesing. + +Bruk denne kommandoen når en beslutning ikke passer inn under noe innebygd domene. Før du registrerer et nytt, sjekk om beslutningen kan legges under et eksisterende domene -- innebygde er standarden, og et egendefinert domene bør bare introduseres når ingen innebygde passer. + +```bash +archgate adr domain <subcommand> [options] +``` + +### Underkommandoer + +| Underkommando | Beskrivelse | +| ----------------------------------------- | --------------------------------------------------------------------------- | +| `archgate adr domain list` | Vis alle sammenslåtte (innebygde + egendefinerte) domener og prefikser | +| `archgate adr domain add <name> <prefix>` | Registrer et egendefinert domene | +| `archgate adr domain remove <name>` | Fjern registreringen av et egendefinert domene (innebygde kan ikke fjernes) | + +### Navneregler + +- `<name>` -- kebab-case med små bokstaver, 2-32 tegn (f.eks. `security`, `ml-ops`) +- `<prefix>` -- store bokstaver, sifre eller understrek, 2-10 tegn (f.eks. `SEC`, `MLOPS`) +- Egendefinerte navn og prefikser kan ikke kollidere med innebygde eller med andre egendefinerte oppføringer. + +### Valg + +| Valg | Gjelder for | Beskrivelse | +| -------- | -------------------- | --------------- | +| `--json` | alle underkommandoer | Utdata som JSON | + +### Eksempler + +List innebygde og egendefinerte domener: + +```bash +archgate adr domain list +``` + +``` +Domain Prefix Source +──────────────────────────────── +architecture ARCH default +backend BE default +data DATA default +frontend FE default +general GEN default +security SEC custom +``` + +Registrer et egendefinert domene: + +```bash +archgate adr domain add security SEC +``` + +Fjern et egendefinert domene: + +```bash +archgate adr domain remove security +``` + +--- + +## archgate adr import + +Importer ADR-er fra registeret eller et git-repository. + +```bash +archgate adr import <source...> [options] +``` + +Kommandoen kloner kilden, leser ADR-filer, omtilordner ID-er for å passe inn i det lokale prosjektets sekvens, og skriver dem til `.archgate/adrs/`. Den sporer importer i `.archgate/imports.json` slik at de senere kan sjekkes for oppstrømsoppdateringer via [`archgate adr sync`](#archgate-adr-sync). + +### Argumenter + +| Argument | Beskrivelse | +| ------------- | -------------------------------------------------- | +| `<source...>` | Registersti(er), `org/repo/path` eller git-URL(er) | + +### Valg + +| Valg | Beskrivelse | +| ----------- | ----------------------------------- | +| `--yes` | Hopp over bekreftelsesprompt | +| `--json` | Utdata som JSON | +| `--dry-run` | Forhåndsvis endringer uten å skrive | +| `--list` | List tidligere importerte ADR-er | + +### Eksempler + +Importer fra registeret: + +```bash +archgate adr import archgate/packs/typescript +``` + +Importer fra et git-repository: + +```bash +archgate adr import https://github.com/acme/adr-packs.git +``` + +Forhåndsvis hva som ville bli importert uten å skrive noen filer: + +```bash +archgate adr import archgate/packs/typescript --dry-run +``` + +Importer ikke-interaktivt (hopp over bekreftelse): + +```bash +archgate adr import archgate/packs/typescript --yes +``` + +List tidligere importerte ADR-er: + +```bash +archgate adr import --list +``` + +--- + +## archgate adr sync + +Sjekk for oppstrømsoppdateringer av importerte ADR-er. + +```bash +archgate adr sync [source...] [options] +``` + +Kommandoen sammenligner lokale importerte ADR-er mot oppstrømskilden og viser hvilke seksjoner som er endret. I interaktiv modus spør den for hver endret ADR med tre valg: behold lokal, ta oppstrøms eller hopp over. + +### Argumenter + +| Argument | Beskrivelse | +| ------------- | ------------------------------------------------------------ | +| `[source...]` | Valgfritt kildefilter -- synkroniser bare matchende importer | + +### Valg + +| Valg | Beskrivelse | +| --------- | -------------------------------------------------------------- | +| `--check` | Avslutt med kode 1 hvis oppstrøms har oppdateringer (CI-modus) | +| `--yes` | Hopp over bekreftelsespromter | +| `--json` | Utdata som JSON | + +### Eksempler + +Sjekk alle importerte ADR-er for oppstrømsoppdateringer: + +```bash +archgate adr sync +``` + +Sjekk kun importer fra en bestemt kilde: + +```bash +archgate adr sync archgate/packs/typescript +``` + +CI-modus -- feil bygget hvis noen importert ADR er utdatert: + +```bash +archgate adr sync --check +``` + +Godta alle oppstrømsoppdateringer ikke-interaktivt: + +```bash +archgate adr sync --yes +``` diff --git a/docs/src/content/docs/nb/reference/cli/check.mdx b/docs/src/content/docs/nb/reference/cli/check.mdx new file mode 100644 index 00000000..cddbabf9 --- /dev/null +++ b/docs/src/content/docs/nb/reference/cli/check.mdx @@ -0,0 +1,175 @@ +--- +title: archgate check +description: "Kjør alle automatiserte ADR-samsvarskontroller mot kodebasen." +--- + +Kjør alle automatiserte ADR-samsvarskontroller mot kodebasen. + +```bash +archgate check [options] [files...] +``` + +Laster inn hver ADR med `rules: true` i frontmatteren, kjører den tilhørende `.rules.ts`-filen og rapporterer brudd med filstier og linjenumre. Når filstier oppgis som posisjonsargumenter, kjøres bare ADR-er der `files`-mønstrene matcher disse filene. + +## Valg + +| Valg | Beskrivelse | +| -------------- | ---------------------------------------------------------------------------- | +| `--staged` | Sjekk kun git-stagede filer (nyttig for pre-commit-hooks) | +| `--base [ref]` | Sammenlign endrede filer mot en basisreferanse (autodetekteres hvis utelatt) | +| `--json` | Maskinlesbar JSON-utdata | +| `--ci` | GitHub Actions-annotasjonsformat | +| `--adr <id>` | Sjekk kun regler fra en bestemt ADR | +| `--verbose` | Vis beståtte regler og tidsinformasjon | + +## Argumenter + +| Argument | Beskrivelse | +| ------------ | ------------------------------------------------------------------------------------------------------------------------- | +| `[files...]` | Valgfrie filstier for å begrense kontrollene. Bare ADR-er der `files`-mønstrene matcher vil kjøres. Støtter stdin-piping. | + +## Avslutningskoder + +| Kode | Betydning | +| ---- | -------------------------------------------------------------------------------- | +| 0 | Alle regler bestått. Ingen brudd funnet. | +| 1 | Ett eller flere brudd oppdaget. | +| 2 | Feil ved regelkjøring (f.eks. feilformatert regel, sikkerhetsskannerblokkering). | + +## Eksempler + +Sjekk hele prosjektet: + +```bash +archgate check +``` + +Sjekk kun stagede filer før commit: + +```bash +archgate check --staged +``` + +Sjekk alle filer endret på gjeldende gren vs `main`: + +```bash +archgate check --base main +``` + +Sjekk en enkelt ADR: + +```bash +archgate check --adr ARCH-001 +``` + +Sjekk bestemte filer (bare matchende ADR-er kjøres): + +```bash +archgate check src/foo.ts src/bar.ts +``` + +Pipe fra git (sjekk kun endrede filer): + +```bash +git diff --name-only | archgate check --json +``` + +Hent JSON-utdata for CI-integrasjon: + +```bash +archgate check --json +``` + +Hent GitHub Actions-annotasjoner: + +```bash +archgate check --ci +``` + +## Deteksjon av endrede filer + +Som standard autodetekterer `archgate check` hovedgrenen og fyller `ctx.changedFiles` med grendifferansen (`git diff <base>...HEAD`). Dette gjør at regler for avhengigheter på tvers av filer fungerer lokalt -- ikke bare i CI. + +Basisreferansen løses i denne prioritetsrekkefølgen: + +| Prioritet | Kilde | `changedFiles` fylles med | +| --------- | ------------------------------------ | -------------------------------- | +| 1 | `--staged` | Kun git-stagingområdet | +| 2 | `--base <ref>` | `git diff <ref>...HEAD` | +| 3 | `.archgate/config.json` `baseBranch` | `git diff <resolved-ref>...HEAD` | +| 4 | Git-autodeteksjon | `git diff <detected-ref>...HEAD` | +| 5 | Deteksjon mislykkes | Tom (fullskanmodus) | + +Autodeteksjon prøver `origin/HEAD`, deretter `origin/main`, `origin/master`, lokal `main` og lokal `master`. For å sette en prosjektstandard, legg til `baseBranch` i `.archgate/config.json`: + +```json +{ "baseBranch": "main" } +``` + +## Diagnostikk + +Under kjøring sender `archgate check` advarsler for vanlige feilkonfigurasjoner som kan forårsake trege eller uventede resultater: + +| Advarsel | Tilstand | Anbefaling | +| -------------------------------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| **Bredt filomfang** | En ADRs `files`-mønstre løser til mer enn 1000 filer eller glob-skanningen tar over 2 sekunder | Begrens `files`-mønstrene i ADR-frontmatteren til å kun omfatte relevante kildekatalogene | +| **Uscopet gitignore-fravalg** | `respectGitignore: false` er satt uten et `files`-omfang | Legg til `files`-mønstre for å unngå skanning av alle filer inkludert `node_modules/`, `.git/` osv. | +| **Alle filer ekskludert av gitignore** | Eksplisitte `files`-mønstre matcher filer, men alle treff er ekskludert av `.gitignore` | Sett `respectGitignore: false` i ADR-frontmatteren for å inkludere gitignorerte filer | + +Disse advarslene vises i standardutdataene og påvirker ikke avslutningskoden. De vises også i JSON-utdata når `--json` brukes (som brudd med `"severity": "warning"`). + +## JSON-utdataformat + +Når `--json` brukes, er utdataene et enkelt JSON-objekt: + +```json +{ + "pass": false, + "total": 4, + "passed": 3, + "failed": 1, + "warnings": 0, + "errors": 1, + "infos": 0, + "ruleErrors": 0, + "truncated": false, + "results": [ + { + "adrId": "ARCH-001", + "ruleId": "register-function-export", + "description": "Command file must export a register*Command function", + "status": "fail", + "totalViolations": 1, + "shownViolations": 1, + "violations": [ + { + "message": "Command file must export a register*Command function", + "file": "src/commands/broken.ts", + "line": 1, + "endLine": 1, + "endColumn": 42, + "severity": "error" + } + ], + "durationMs": 12 + } + ], + "durationMs": 42 +} +``` + +### Bruddfelter + +| Felt | Type | Beskrivelse | +| ----------- | ------- | ----------------------------------------------------- | +| `message` | string | Hva bruddet er | +| `file` | string? | Relativ filsti | +| `line` | number? | Startlinje (1-basert) | +| `endLine` | number? | Sluttlinje (1-basert) -- for presis editor-utheving | +| `endColumn` | number? | Sluttkolonne (0-basert) -- for presis editor-utheving | +| `fix` | string? | Foreslått fiks (kun veiledning) | +| `severity` | string | `"error"`, `"warning"` eller `"info"` | + +### Blokkerte regelfiler + +Når en regelfil blokkeres av sikkerhetsskanneren (f.eks. bruker `Bun.spawn()`) eller en tilhørende `.rules.ts`-fil mangler, vises resultatet i JSON-utdataene med `status: "error"` og `ruleId: "security-scan"`. Brudd inkluderer den eksakte filen og linjen til den blokkerte koden (eller `rules: true`-linjen i ADR-en for manglende tilhørende filer). diff --git a/docs/src/content/docs/nb/reference/cli/clean.mdx b/docs/src/content/docs/nb/reference/cli/clean.mdx new file mode 100644 index 00000000..8b1e002b --- /dev/null +++ b/docs/src/content/docs/nb/reference/cli/clean.mdx @@ -0,0 +1,22 @@ +--- +title: archgate clean +description: "Fjern CLI-hurtigbufferkatalogen." +--- + +Fjern CLI-hurtigbufferkatalogen. + +```bash +archgate clean +``` + +Fjerner `~/.archgate/`, som lagrer hurtigbufrede data som tidsstempler for oppdateringssjekker. Trygt å kjøre når som helst -- katalogen gjenskapes automatisk ved behov. + +## Eksempel + +```bash +archgate clean +``` + +``` +/home/user/.archgate cleaned up +``` diff --git a/docs/src/content/docs/nb/reference/cli/doctor.mdx b/docs/src/content/docs/nb/reference/cli/doctor.mdx new file mode 100644 index 00000000..e32ec0ff --- /dev/null +++ b/docs/src/content/docs/nb/reference/cli/doctor.mdx @@ -0,0 +1,62 @@ +--- +title: archgate doctor +description: "Sjekk systemmiljoet, installasjonsmetoden og editor-integrasjoner." +--- + +Sjekk systemmiljoet, installasjonsmetoden og editor-integrasjoner. Nyttig for å diagnostisere konfigurasjonsproblemer og dele feilsokingskontekst i feilrapporter. + +```bash +archgate doctor [options] +``` + +## Valg + +| Valg | Beskrivelse | +| -------- | ------------------- | +| `--json` | Maskinlesbar utdata | + +## Utdataseksjoner + +- **System** -- OS, arkitektur, WSL-deteksjon, Bun- og Node-versjoner +- **Archgate** -- CLI-versjon, installasjonsmetode (binary, proto, local, global-pm), konfigurasjonskatalog, telemetri- og innloggingsstatus +- **Project** -- Om et `.archgate/`-prosjekt finnes, antall ADR-er, domener +- **Editor CLIs** -- Om `claude`, `cursor`, `code` (VS Code), `copilot` og `git` er tilgjengelige på PATH +- **Project Integrations** -- Om editor-spesifikke plugin-filer finnes i det gjeldende prosjektet (`.claude/settings.local.json`, `.cursor/rules/archgate-governance.mdc`, `.vscode/settings.json`, `.github/copilot/instructions.md`) + +## Eksempel + +```bash +archgate doctor +``` + +``` +System + OS: win32/x64 + Bun: 1.3.11 + Node: v24.3.0 + +Archgate + Version: 0.25.1 + Install: binary + Exec path: /home/user/.archgate/bin/archgate + Config dir: /home/user/.archgate OK + Telemetry: enabled + Logged in: yes + +Project + ADRs: 5 (3 with rules) + Domains: ARCH, GEN + +Editor CLIs + claude: OK + cursor: MISSING + code (vscode):OK + copilot: MISSING + git: OK + +Project Integrations + Claude: OK (.claude/settings.local.json) + Cursor: MISSING (.cursor/rules/archgate-governance.mdc) + VS Code: OK (.vscode/settings.json) + Copilot: MISSING (.github/copilot/instructions.md) +``` diff --git a/docs/src/content/docs/nb/reference/cli/index.mdx b/docs/src/content/docs/nb/reference/cli/index.mdx new file mode 100644 index 00000000..efd958ef --- /dev/null +++ b/docs/src/content/docs/nb/reference/cli/index.mdx @@ -0,0 +1,33 @@ +--- +title: CLI-kommandoer +description: "Komplett referanse for alle Archgate CLI-kommandoer: init, check, adr, login, plugin, review-context, session-context, upgrade, doctor, clean og telemetry." +--- + +## Globale valg + +Disse valgene er tilgjengelige for alle kommandoer: + +| Valg | Beskrivelse | +| ----------------- | --------------------------- | +| `--version`, `-V` | Skriv ut Archgate-versjonen | +| `--help`, `-h` | Vis hjelp for en kommando | + +```bash +archgate --version +archgate check --help +``` + +## Kommandoer + +| Kommando | Beskrivelse | +| ------------------------------------------------ | --------------------------------------------------------------- | +| [`archgate login`](./login/) | Autentiser med GitHub | +| [`archgate init`](./init/) | Initialiser Archgate-styring | +| [`archgate plugin`](./plugin/) | Administrer editor-plugins | +| [`archgate check`](./check/) | Kjor ADR-samsvarskontroller | +| [`archgate adr`](./adr/) | Opprett, list, vis og oppdater ADR-er | +| [`archgate review-context`](./review-context/) | Forhåndsberegn gjennomgangskontekst for CI/editor-integrasjoner | +| [`archgate session-context`](./session-context/) | Les AI-editor-sesjonslogger | +| [`archgate upgrade`](./upgrade/) | Oppgrader Archgate til nyeste versjon | +| [`archgate doctor`](./doctor/) | Sjekk systemmiljo og editor-integrasjoner | +| [`archgate clean`](./clean/) | Fjern CLI-hurtigbufferkatalogen | diff --git a/docs/src/content/docs/nb/reference/cli/init.mdx b/docs/src/content/docs/nb/reference/cli/init.mdx new file mode 100644 index 00000000..c6b19ff5 --- /dev/null +++ b/docs/src/content/docs/nb/reference/cli/init.mdx @@ -0,0 +1,61 @@ +--- +title: archgate init +description: "Initialiser Archgate-styring i det gjeldende prosjektet." +--- + +Initialiser Archgate-styring i det gjeldende prosjektet. + +```bash +archgate init [options] +``` + +Oppretter `.archgate/`-katalogen med en eksempel-ADR, tilhørende regelfil og linter-konfigurasjon. Kan valgfritt konfigurere editor-integrasjon for AI-agentarbeidsflyter og installere Archgate editor-pluginen. + +## Valg + +| Valg | Standard | Beskrivelse | +| ------------------- | -------- | -------------------------------------------------------------------------------------- | +| `--editor <editor>` | `claude` | Editor-integrasjon å konfigurere (`claude`, `cursor`, `vscode`, `copilot`, `opencode`) | +| `--install-plugin` | auto | Installer Archgate editor-pluginen (krever tidligere `archgate login`) | + +Når `--install-plugin` sendes med, installerer CLI-en Archgate-pluginen for den valgte editoren. Hvis flagget utelates, autodetekterer CLI-en: den installerer pluginen når gyldig legitimasjon finnes (fra en tidligere `archgate login`) og hopper over ellers. + +## Installasjonsoppførsel for plugins + +**Claude Code:** Hvis `claude`-CLI-en er på din PATH, installeres pluginen automatisk via `claude plugin marketplace add` og `claude plugin install`. Hvis `claude`-CLI-en ikke finnes, skriver kommandoen ut de manuelle installasjonskommandoene i stedet. + +**Cursor:** Hvis `cursor`-CLI-en er på din PATH, installeres VS Code-utvidelsen automatisk via `cursor --install-extension`. Team-markedsplassen-URL-en skrives ut for manuell plugin-oppdagelse. + +**opencode:** Krever at `opencode`-CLI-en er på din PATH -- hvis den ikke er det, hoppes installasjonen over og en melding ber deg installere opencode først. Når den er til stede, laster CLI-en ned en autentisert tarball med agentfiler fra Archgate plugins-tjenesten og pakker den ut i opencode-agentkatalogen for brukerskoopet (`$XDG_CONFIG_HOME/opencode/agents/`, faller tilbake til `$HOME/.config/opencode/agents/` på alle plattformer inkludert Windows -- opencode bruker XDG-stier via `xdg-basedir` og leser ikke `%APPDATA%`). Ingen filer skrives til prosjekttreet. Se [opencode-integrasjonsguiden](/guides/opencode-integration/) for detaljer. + +## Utdata + +``` +Initialized Archgate governance in /path/to/project + adrs/ - architecture decision records + lint/ - linter-specific rules + .claude/ - Claude Code settings configured + +Archgate plugin installed for Claude Code. +``` + +Når `--editor cursor` brukes, viser utdataene `.cursor/` i stedet for `.claude/`. + +## Deteksjon av hovedgren + +Når kommandoen kjøres i et git-repositorium, autodetekterer `archgate init` hovedgrenen og lagrer den i `.archgate/config.json` som `baseBranch`-feltet. Dette lar `archgate check` hoppe over grendeteksjon ved hver kjøring, noe som sparer 1-4 git-subprosessanrop. + +Deteksjonen prøver `origin/HEAD`, `origin/main`, `origin/master`, lokal `main` og lokal `master` (første treff vinner). Hvis ingen finnes (f.eks. ikke et git-repo), skrives ingen `baseBranch`. + +Å kjøre `archgate init` på nytt overskriver **ikke** en manuelt konfigurert `baseBranch`. Se [Konfigurasjon -- `baseBranch`](/reference/configuration/#basebranch) for detaljer. + +## Generert struktur + +``` +.archgate/ + adrs/ + ARCH-001-example.md # Example ADR + ARCH-001-example.rules.ts # Example rules file + lint/ + archgate.config.ts # Archgate configuration +``` diff --git a/docs/src/content/docs/nb/reference/cli/login.mdx b/docs/src/content/docs/nb/reference/cli/login.mdx new file mode 100644 index 00000000..0e39a91e --- /dev/null +++ b/docs/src/content/docs/nb/reference/cli/login.mdx @@ -0,0 +1,124 @@ +--- +title: archgate login +description: "Autentiser med GitHub for å få tilgang til Archgate editor-plugins." +--- + +Autentiser med GitHub for å få tilgang til Archgate editor-plugins. Hvis du ikke er registrert ennå, håndterer CLI-en registrering automatisk -- den ber om e-postadressen din, foretrukket editor (Claude Code, VS Code, Copilot CLI eller Cursor) og bruksområde, og registrerer deg før innloggingen fullføres. + +```bash +archgate login +``` + +Starter en GitHub Device Flow (OAuth). CLI-en viser en engangskode og en URL. Åpne URL-en i nettleseren din, skriv inn koden og autoriser Archgate GitHub OAuth-appen. Når autorisasjonen er fullført, veksler CLI-en GitHub-identiteten din mot et Archgate plugin-token og lagrer det sikkert i operativsystemets legitimasjonsbehandler (macOS Keychain, Windows Credential Manager eller Linux libsecret) via `git credential approve`. Ingen legitimasjon skrives til disk som klartekstfiler. + +Hvis GitHub-kontoen din ikke er registrert ennå, ber CLI-en om e-postadressen din, foretrukket editor og bruksområde, og registrerer deg automatisk. + +Legitimasjon kreves for å installere editor-plugins via `archgate init --install-plugin`. Selve CLI-en (check, init osv.) fungerer uten innlogging. + +:::tip[Plugin-beta] +Editor-plugins er for tiden i beta. Kjør `archgate login` for å registrere deg og autentisere. +::: + +## Underkommandoer + +| Underkommando | Beskrivelse | +| ------------------------ | ------------------------------------------------ | +| `archgate login` | Autentiser (hopper over hvis allerede innlogget) | +| `archgate login status` | Vis gjeldende autentiseringsstatus | +| `archgate login logout` | Fjern lagret legitimasjon | +| `archgate login refresh` | Autentiser på nytt og hent et nytt token | + +## Eksempler + +Logg inn for første gang: + +```bash +archgate login +``` + +``` +Authenticating with GitHub... + +Open https://github.com/login/device in your browser +and enter the code: ABCD-1234 + +Waiting for authorization... +GitHub user: yourname + +Your GitHub account yourname is not yet registered. +Let's sign you up now. + +Email: you@example.com +Editor: Claude Code +Use case: Enforcing ADRs in our monorepo + +Submitting signup request... +Claiming archgate plugin token... + +Authenticated as yourname. Plugin access is now available. +Run `archgate init` to set up a project with the archgate plugin. +``` + +Hvis prosjektet allerede har `.archgate/adrs/`, lyder den siste linjen: + +``` +Run `archgate check` to validate your project against its ADRs. +``` + +## Feilsøking + +### TLS/bedriftsproxy-feil + +Hvis `archgate login` feiler med en TLS-sertifikatfeil (vanlig bak bedriftsproxyer), pek kjøretidsmiljøet mot organisasjonens CA-sertifikatpakke ved å bruke miljøvariabelen `NODE_EXTRA_CA_CERTS`. + +På macOS/Linux: + +```bash +export NODE_EXTRA_CA_CERTS=/path/to/your-corporate-ca.pem +archgate login +``` + +På Windows (PowerShell): + +```powershell +$env:NODE_EXTRA_CA_CERTS = "C:\path\to\your-corporate-ca.pem" +archgate login +``` + +På Windows (cmd): + +```cmd +set NODE_EXTRA_CA_CERTS=C:\path\to\your-corporate-ca.pem +archgate login +``` + +På Windows (Git Bash): + +```bash +export NODE_EXTRA_CA_CERTS=/c/path/to/your-corporate-ca.pem +archgate login +``` + +Spør IT-avdelingen din om riktig sertifikatsti hvis du er usikker. + +Sjekk innloggingsstatus: + +```bash +archgate login status +``` + +``` +Logged in as yourname (since 2026-02-28) +``` + +Logg ut: + +```bash +archgate login logout +``` + +Autentiser på nytt: + +```bash +archgate login refresh +``` diff --git a/docs/src/content/docs/nb/reference/cli/plugin.mdx b/docs/src/content/docs/nb/reference/cli/plugin.mdx new file mode 100644 index 00000000..4d49732f --- /dev/null +++ b/docs/src/content/docs/nb/reference/cli/plugin.mdx @@ -0,0 +1,85 @@ +--- +title: archgate plugin +description: "Administrer Archgate editor-plugins uavhengig av archgate init." +--- + +Administrer Archgate editor-plugins uavhengig av `archgate init`. + +```bash +archgate plugin <subcommand> [options] +``` + +Bruk `archgate plugin` til å installere plugins eller hente den autentiserte repository-URL-en for prosjekter som allerede er initialisert. + +## Underkommandoer + +### archgate plugin url + +Skriv ut plugin-repository-URL-en for manuell verktøykonfigurasjon. + +```bash +archgate plugin url [options] +``` + +| Valg | Standard | Beskrivelse | +| ------------------- | -------- | --------------------------------------------------------------- | +| `--editor <editor>` | `claude` | Måleditor (`claude`, `cursor`, `vscode`, `copilot`, `opencode`) | + +URL-en kan brukes til å konfigurere editorverktøy manuelt. Legitimasjon leveres automatisk av git-legitimasjonsbehandleren din (lagret under `archgate login`). For eksempel, for å legge til Archgate-markedsplassen i Claude Code: + +```bash +claude plugin marketplace add "$(archgate plugin url)" +claude plugin install archgate@archgate +``` + +For VS Code peker URL-en til et separat plugin-repository: + +```bash +archgate plugin url --editor vscode +``` + +### archgate plugin install + +Installer Archgate-pluginen for den angitte editoren i et allerede initialisert prosjekt. + +```bash +archgate plugin install [options] +``` + +| Valg | Standard | Beskrivelse | +| ------------------- | -------- | --------------------------------------------------------------- | +| `--editor <editor>` | `claude` | Måleditor (`claude`, `cursor`, `vscode`, `copilot`, `opencode`) | + +Installasjonsoppførselen varierer etter editor: + +- **Claude Code:** Autoinstallerer via `claude`-CLI-en hvis tilgjengelig; skriver ut manuelle kommandoer ellers. +- **Copilot CLI:** Autoinstallerer via `copilot`-CLI-en hvis tilgjengelig; skriver ut manuelle kommandoer ellers. +- **Cursor:** Skriver ut [Team Private Plugin Marketplace](https://cursor.com/docs/plugins#team-marketplaces)-URL-en med instruksjoner for å legge den til i Cursor-innstillingene. Cursor støtter ikke VSIX-installasjon fra CLI-en. +- **VS Code:** Installerer VS Code-utvidelsen (`.vsix`) via `code`-CLI-en hvis tilgjengelig; skriver ut manuelle instruksjoner ellers. +- **opencode:** Krever at `opencode`-CLI-en er på PATH -- hopper over installasjonen med en tydelig melding ellers. Når den er til stede, laster den ned en autentisert tarball med agentfiler og pakker den ut i opencode-agentkatalogen for brukerskoopet. `archgate plugin url --editor opencode` skriver ut "N/A" -- opencode har ingen markedsplassURL. Se [opencode-integrasjonsguiden](/guides/opencode-integration/) for detaljer. + +## Eksempler + +Hent plugin-URL-en for manuell konfigurasjon: + +```bash +archgate plugin url +``` + +Installer pluginen for Claude Code: + +```bash +archgate plugin install +``` + +Installer pluginen for Cursor: + +```bash +archgate plugin install --editor cursor +``` + +Installer agentpakken for opencode: + +```bash +archgate plugin install --editor opencode +``` diff --git a/docs/src/content/docs/nb/reference/cli/review-context.mdx b/docs/src/content/docs/nb/reference/cli/review-context.mdx new file mode 100644 index 00000000..4e550a97 --- /dev/null +++ b/docs/src/content/docs/nb/reference/cli/review-context.mdx @@ -0,0 +1,25 @@ +--- +title: archgate review-context +description: "Forhåndsberegn gjennomgangskontekst med ADR-briefinger for endrede filer." +--- + +Forhåndsberegn gjennomgangskontekst med ADR-briefinger for endrede filer. Designet for CI og editor-plugin-integrasjoner som trenger en oppsummering av hvilke ADR-er som gjelder for filene som endres. + +```bash +archgate review-context [options] +``` + +## Valg + +| Valg | Beskrivelse | +| ------------------- | ---------------------------------------------------------------------------- | +| `--staged` | Inkluder kun git-stagede filer | +| `--base [ref]` | Sammenlign endrede filer mot en basisreferanse (autodetekteres hvis utelatt) | +| `--run-checks` | Inkluder resultater fra ADR-samsvarskontroller | +| `--domain <domain>` | Filtrer til et enkelt domene | + +## Eksempel + +```bash +archgate review-context --staged +``` diff --git a/docs/src/content/docs/nb/reference/cli/session-context.mdx b/docs/src/content/docs/nb/reference/cli/session-context.mdx new file mode 100644 index 00000000..95e9b72d --- /dev/null +++ b/docs/src/content/docs/nb/reference/cli/session-context.mdx @@ -0,0 +1,99 @@ +--- +title: archgate session-context +description: "Les AI-editor-sesjonslogger for prosjektet." +--- + +Les AI-editor-sesjonslogger for prosjektet. Nyttig for å revidere hva en AI-agent gjorde under en kodeøkt. + +```bash +archgate session-context <subcommand> [options] +``` + +## Underkommandoer + +### archgate session-context claude-code + +Les Claude Code-sesjonsloggen for prosjektet. + +```bash +archgate session-context claude-code [options] +``` + +| Valg | Beskrivelse | +| ------------------- | ------------------------------------------------------------------- | +| `--max-entries <n>` | Maksimalt antall oppføringer å returnere (standard: 200) | +| `--skip <n>` | Hopp over de N nyeste sesjonene (nyttig ved kjøring som underagent) | + +### archgate session-context copilot + +Les Copilot CLI-sesjonsloggen for prosjektet. Sesjoner matches etter arbeidsområdets `cwd`-felt. + +```bash +archgate session-context copilot [options] +``` + +| Valg | Beskrivelse | +| ------------------- | ------------------------------------------------------------------- | +| `--max-entries <n>` | Maksimalt antall oppføringer å returnere (standard: 200) | +| `--skip <n>` | Hopp over de N nyeste sesjonene (nyttig ved kjøring som underagent) | +| `--session-id <id>` | Spesifikk sesjons-UUID å lese | + +### archgate session-context cursor + +Les Cursor-agentsesjonsloggen for prosjektet. + +```bash +archgate session-context cursor [options] +``` + +| Valg | Beskrivelse | +| ------------------- | ------------------------------------------------------------------- | +| `--max-entries <n>` | Maksimalt antall oppføringer å returnere (standard: 200) | +| `--skip <n>` | Hopp over de N nyeste sesjonene (nyttig ved kjøring som underagent) | +| `--session-id <id>` | Spesifikk sesjons-UUID å lese | + +### archgate session-context opencode + +Les opencode-sesjonsloggen for prosjektet. Sesjoner matches etter prosjektets `path`-felt i sesjonsmetadataene. + +```bash +archgate session-context opencode [options] +``` + +| Valg | Beskrivelse | +| ------------------- | ------------------------------------------------------------------- | +| `--max-entries <n>` | Maksimalt antall oppføringer å returnere (standard: 200) | +| `--skip <n>` | Hopp over de N nyeste sesjonene (nyttig ved kjøring som underagent) | +| `--session-id <id>` | Spesifikk sesjons-ID å lese | + +## Eksempler + +Les den nyeste Claude Code-sesjonen: + +```bash +archgate session-context claude-code +``` + +Les en bestemt Cursor-sesjon: + +```bash +archgate session-context cursor --session-id abc123 +``` + +Les den nyeste Copilot CLI-sesjonen: + +```bash +archgate session-context copilot +``` + +Les den nyeste opencode-sesjonen: + +```bash +archgate session-context opencode +``` + +Les foreldresesjonen (hopp over underagentens egen sesjon): + +```bash +archgate session-context claude-code --skip 1 +``` diff --git a/docs/src/content/docs/nb/reference/cli/telemetry.mdx b/docs/src/content/docs/nb/reference/cli/telemetry.mdx new file mode 100644 index 00000000..24ddf0ec --- /dev/null +++ b/docs/src/content/docs/nb/reference/cli/telemetry.mdx @@ -0,0 +1,74 @@ +--- +title: archgate telemetry +description: "Administrer anonym bruksdatainnsamling for Archgate CLI." +--- + +Administrer anonym bruksdatainnsamling for Archgate CLI. Telemetri er opt-out: aktivert som standard, samler aldri inn personlig identifiserbar informasjon, og anonymiserer klient-IP-en serversiden. + +```bash +archgate telemetry <subcommand> +``` + +Se [CLI-telemetri](/reference/telemetry/) for den fullstendige personvernpolicyen, listen over hendelser som sendes, og hvordan telemetri samhandler med `ARCHGATE_TELEMETRY=0` og CI-miljoer. + +## Underkommandoer + +| Underkommando | Beskrivelse | +| ---------------------------- | --------------------------------------------------- | +| `archgate telemetry status` | Vis om telemetri er aktivert for denne CLI-brukeren | +| `archgate telemetry enable` | Aktiver anonym bruksdatainnsamling | +| `archgate telemetry disable` | Deaktiver anonym bruksdatainnsamling | + +Alle tre underkommandoene leser og skriver `~/.archgate/config.json`, som lagrer opt-in-tilstanden og den anonyme installasjons-ID-en brukt som telemetriets `distinct_id`. + +## Eksempler + +Sjekk gjeldende tilstand: + +```bash +archgate telemetry status +``` + +``` +Telemetry is enabled. +Anonymous usage data helps improve Archgate. No personal information is collected. + +To disable: `archgate telemetry disable` or set ARCHGATE_TELEMETRY=0 +Learn more: https://cli.archgate.dev/reference/telemetry +``` + +Deaktiver telemetri: + +```bash +archgate telemetry disable +``` + +``` +Telemetry disabled. No usage data will be collected. +``` + +Aktiver telemetri på nytt: + +```bash +archgate telemetry enable +``` + +``` +Telemetry enabled. Thank you for helping improve Archgate. +``` + +## Overstyring via miljovariabel + +Å sette `ARCHGATE_TELEMETRY=0` (eller `false`, `no`, `off`, uavhengig av store/små bokstaver) deaktiverer telemetri for en enkelt kjøring uavhengig av den lagrede tilstanden. Bruk dette i CI eller delte miljoer der du ønsker fravalg uten å endre brukerens konfigurasjon: + +```bash +ARCHGATE_TELEMETRY=0 archgate check +``` + +`archgate telemetry status` detekterer overstyringen og rapporterer: + +``` +Telemetry is disabled (ARCHGATE_TELEMETRY environment variable). +``` + +Når overstyringen er aktiv og du kjører `archgate telemetry enable`, lagres opt-in, men det skrives ut en merknad om at miljovariabelen fortsetter å deaktivere telemetri til den fjernes. diff --git a/docs/src/content/docs/nb/reference/cli/upgrade.mdx b/docs/src/content/docs/nb/reference/cli/upgrade.mdx new file mode 100644 index 00000000..4be5b140 --- /dev/null +++ b/docs/src/content/docs/nb/reference/cli/upgrade.mdx @@ -0,0 +1,72 @@ +--- +title: archgate upgrade +description: "Oppgrader Archgate til nyeste versjon." +--- + +Oppgrader Archgate til nyeste versjon. + +```bash +archgate upgrade +``` + +Sjekker GitHub Releases for den siste publiserte versjonen. Hvis en nyere versjon er tilgjengelig, autodetekterer kommandoen hvordan Archgate ble installert og kjører den passende oppgraderingsstrategien. Hvis allerede oppdatert, skrives en melding og kommandoen avsluttes. + +## Valg + +| Valg | Beskrivelse | +| ----------- | ----------------------------------------------- | +| `--plugins` | Oppdater også editor-plugins etter oppgradering | + +## Deteksjon av installasjonsmetode + +Oppgraderingskommandoen inspiserer den kjørende binærfilens sti for å bestemme installasjonsmetoden, og delegerer deretter til den matchende strategien: + +| Installasjonsmetode | Deteksjon | Oppgraderingshandling | +| ------------------------------------------ | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Binærinstallasjon** (`~/.archgate/bin/`) | Binærfilen ligger i `~/.archgate/bin/` | Laster ned den nyeste binærfilen fra GitHub Releases og erstatter den eksisterende | +| **Proto** | Binærfilen ligger i `~/.proto/tools/archgate/` | Kjører `proto install archgate latest --pin` | +| **Lokal dev-avhengighet** | Binærfilen ligger i `node_modules/` | Detekterer pakkebehandleren fra nærmeste lockfile (bun, pnpm, yarn eller npm) og kjører riktig add-kommando (f.eks. `bun add -d archgate@latest`) | +| **Global pakkebehandler** | Binærfilen ligger i en global bin-katalog | Detekterer hvilken pakkebehandler som eier den globale bin-katalogen og kjører dens oppgraderingskommando (f.eks. `npm install -g archgate@latest`) | + +Hvis ingen spesifikk metode detekteres, faller kommandoen tilbake til `npm install -g archgate@latest`. + +## Plugin-oppdateringer + +Etter en vellykket oppgradering tilbyr CLI-en å oppdatere editor-pluginene dine. I en interaktiv terminal får du en bekreftelsesprompt: + +``` +Archgate upgraded to 0.35.0 successfully. +? Would you like to update your editor plugins too? (Y/n) +``` + +CLI-en autodetekterer installerte editorer (Claude Code, Cursor, VS Code, Copilot CLI, opencode) og kjører plugin-installasjonen for hver valgte editor. Feil ved plugin-oppdatering rapporteres, men påvirker ikke avslutningskoden -- selve CLI-oppgraderingen er allerede fullført. + +Bruk `--plugins` for å hoppe over prompten og oppdatere alle detekterte editorer automatisk: + +```bash +archgate upgrade --plugins +``` + +:::note +Plugin-oppdateringer krever autentisering. Hvis du ikke er innlogget, skriver CLI-en ut en påminnelse om å kjøre `archgate login` først. +::: + +## Eksempler + +Oppgrader CLI-en: + +```bash +archgate upgrade +``` + +``` +Checking for latest Archgate release... +Upgrading 0.34.0 -> 0.35.0... +Archgate upgraded to 0.35.0 successfully. +``` + +Oppgrader og oppdater alle editor-plugins i ett trinn: + +```bash +archgate upgrade --plugins +``` diff --git a/docs/src/content/docs/nb/reference/configuration.mdx b/docs/src/content/docs/nb/reference/configuration.mdx new file mode 100644 index 00000000..98fc18df --- /dev/null +++ b/docs/src/content/docs/nb/reference/configuration.mdx @@ -0,0 +1,112 @@ +--- +title: Konfigurasjon +description: Referanse for prosjektkonfigurasjonsfilen .archgate/config.json. Konfigurer egendefinerte ADR-kataloger, domenetilordninger og innstillinger pa prosjektniva. +--- + +Filen `.archgate/config.json` lagrer konfigurasjon pa prosjektniva som committes til versjonskontroll og deles pa tvers av teamet. + +Denne filen opprettes automatisk av `archgate init` (for a lagre den autodetekterte basisgrenen og eventuelle egendefinerte domener) eller nar du legger til konfigurasjon manuelt. Den ligger inne i `.archgate/`-katalogen i prosjektroten din. + +## Skjema + +```json +{ + "domains": { "security": "SEC", "compliance": "COMP" }, + "paths": { "adrs": "docs/adrs", "rules": "docs/adrs" }, + "baseBranch": "main" +} +``` + +### `domains` + +Egendefinerte domene-til-prefiks-tilordninger. Se [Egendefinerte domener](/concepts/domains/#custom-domains) for detaljer. + +| Nokkel | Type | Beskrivelse | +| ------ | -------- | --------------------------------------------------------------------------------------------------------- | +| _navn_ | `string` | Domenenavn (kebab-case med sma bokstaver, 2-32 tegn) tilordnes et ID-prefiks (store bokstaver, 2-10 tegn) | + +Disse slas sammen med de innebygde domenene (`backend`, `frontend`, `data`, `architecture`, `general`) ved lesing. Egendefinerte oppforinger kan ikke overstyre innebygde navn eller prefikser. + +### `baseBranch` + +Basisgren for endringsdeteksjon i `archgate check`. Nar dette er satt, hopper `archgate check` over autodeksjonsprobing og bruker denne verdien direkte for populering av `ctx.changedFiles` via `git diff <baseBranch>...HEAD`. + +| Type | Standard | Beskrivelse | +| -------- | ---------------- | ------------------------------------------------------------ | +| `string` | _(autodetekter)_ | Grennavn eller fjernreferanse (f.eks. `main`, `origin/main`) | + +Dette feltet **fylles automatisk** av `archgate init` nar et git-repository detekteres. Autodeteksjonen provar `origin/HEAD`, `origin/main`, `origin/master`, lokal `main` og lokal `master` (forste treff vinner). A kjore `archgate init` pa nytt overskriver ikke en manuelt konfigurert verdi. + +Du kan ogsa sette den manuelt: + +```json +{ "baseBranch": "main" } +``` + +Se [`archgate check` -- Deteksjon av endrede filer](/reference/cli/check/#changed-files-detection) for den fullstendige prioritetsrekkfolgen. + +### `paths` + +Overstyr standardkataloger for ADR-er og regler. + +| Felt | Type | Standard | Beskrivelse | +| ------- | -------- | ---------------- | ------------------------------------- | +| `adrs` | `string` | `.archgate/adrs` | Relativ sti til ADR-katalogen | +| `rules` | `string` | `.archgate/lint` | Relativ sti til regel-/lint-katalogen | + +Begge feltene er valgfrie. Nar de utelates, brukes standardkatalogene `.archgate/adrs/` og `.archgate/lint/`. + +#### Stivalidering + +- Stier **ma vaere relative** til prosjektroten -- absolutte stier (f.eks. `/docs/adrs`, `C:\docs\adrs`) avvises. +- Stier **ma ikke inneholde `..`-segmenter** -- traversering over prosjektroten er ikke tillatt (f.eks. `../other-repo/adrs` avvises). +- Stier bruker skrastrek (`/`) som skilletegn, i trad med standard globkonvensjoner. + +## Egendefinert ADR-katalog + +Som standard ligger ADR-er i `.archgate/adrs/`. For a lagre dem i en annen katalog (f.eks. `docs/adrs/`), legg til en `paths`-seksjon i `.archgate/config.json`: + +```json +{ "paths": { "adrs": "docs/adrs" } } +``` + +Etter at konfigurasjonen er lagt til: + +1. Opprett malkatalogen (f.eks. `mkdir -p docs/adrs`) +2. Flytt eksisterende ADR-filer og deres tilhorende `.rules.ts`-filer fra `.archgate/adrs/` til den nye katalogen +3. Kjor `archgate check` for a verifisere at reglene fortsatt lastes riktig + +Alle CLI-kommandoer (`archgate adr list`, `archgate adr create`, `archgate check`, `archgate review-context`) leser automatisk den konfigurerte katalogen. + +:::caution +`.archgate/`-katalogen ma fortsatt eksistere -- den er prosjektmarkoren som CLI-en bruker for a finne prosjektroten din. Ikke slett den etter at du har konfigurert egendefinerte stier. +::: + +### Eksempel: dokumentasjonsmappe i monorepo + +Et vanlig monster er a plassere ADR-er sammen med annen dokumentasjon: + +``` +my-project/ + .archgate/ + config.json # { "paths": { "adrs": "docs/adrs" } } + lint/ + rules.d.ts + docs/ + adrs/ + ARCH-001-api-design.md + ARCH-001-api-design.rules.ts + BE-001-database-access.md + BE-001-database-access.rules.ts + rules.d.ts # autogenerert av archgate check + guides/ + ... + src/ + ... +``` + +## Merknader + +- `paths`-konfigurasjonen er en **teamomfattende innstilling** -- den committes til versjonskontroll og gjelder for alle teammedlemmer. Det finnes ingen brukerniva-overstyring for ADR-stier. +- Endring av konfigurasjonen krever manuell redigering av `.archgate/config.json` etter at `archgate init` er kjort. +- Typedefinisjonfilen `rules.d.ts` skrives automatisk til bade `.archgate/` og foreldrekatalogen til den konfigurerte ADR-katalogen, slik at tilhorende `.rules.ts`-filer loser `/// <reference path="../rules.d.ts" />`-direktivet riktig. diff --git a/docs/src/content/docs/nb/reference/privacy-policy.mdx b/docs/src/content/docs/nb/reference/privacy-policy.mdx new file mode 100644 index 00000000..198c7f92 --- /dev/null +++ b/docs/src/content/docs/nb/reference/privacy-policy.mdx @@ -0,0 +1,62 @@ +--- +title: Personvernerklaering +description: Hvordan Archgate behandler dataene dine, hva vi samler inn, og rettighetene dine. +--- + +For den fullstendige Archgate-personvernerklaering, besok: + +**[archgate.dev/privacy-policy](https://archgate.dev/privacy-policy)** + +Seksjonene nedenfor oppsummerer de mest relevante punktene for CLI-brukere. Den kanoniske erklaering pa nettstedet er den juridisk bindende versjonen. + +**Behandlingsansvarlig:** Dasolve AS (Org.nr 936 035 019), Lillogata 5P, 0484 Oslo, Norge. Kontakt: [privacy@archgate.dev](mailto:privacy@archgate.dev). + +## Sammendrag for CLI-brukere + +### Hva CLI-en samler inn + +Archgate samler inn **anonym bruksanalyse** (via PostHog) og **krasjrapporter** (via Sentry) for a forbedre verktøyet. Ingen personopplysninger, kildekode, filinnhold eller AI-prompter samles noensinne inn av selve CLI-en. Se [Telemetri](/reference/telemetry/)-siden for en detaljert gjennomgang av hvert datapunkt. + +**Rettslig grunnlag:** Berettiget interesse under GDPR artikkel 6(1)(f). Se var [Vurdering av berettigede interesser](https://archgate.dev/legitimate-interest-assessment). + +### Datalagring og oppbevaringstid + +| Tjeneste | Data | Region | Oppbevaringstid | +| ------------- | ------------------------- | -------------- | ------------------------- | +| PostHog Cloud | Anonym bruksanalyse | EU (Frankfurt) | 1 ar | +| Sentry Cloud | Krasjrapporter | EU (Frankfurt) | 90 dager | +| Turso | Plugins Service-kontodata | EU | Til sletting etterspørres | + +Data overføres via reverseproksier pa `n.archgate.dev` (analyse) og `s.archgate.dev` (feil) -- transparente videresendere driftet av Dasolve AS pa Cloudflare, uten logging eller lagring. + +### Archgate Plugins Service + +Nar du registrerer deg via `archgate login`, samler **Plugins Service** (`plugins.archgate.dev`) inn personopplysninger: din **e-postadresse**, **GitHub-brukernavn**, **editorvalg** og en **beskrivelse av bruksomrade**. Disse dataene brukes til a opprette kontoen din og sende en velkomst-e-post. Autentiseringstokener lagres som SHA-256-hasher pa serverne vare; pa din maskin oppbevares legitimasjonen i operativsystemets legitimasjonsbehandler (aldri som ren tekstfiler). + +Ved a opprette en konto godtar du [tjenestevilkarene](https://archgate.dev/terms-of-service). Se den [fullstendige personvernerklaering](https://archgate.dev/privacy-policy) for komplette detaljer. + +### Slik reserverer du deg + +```bash +# Miljøvariabel (umiddelbar, per sesjon eller i shellprofil) +export ARCHGATE_TELEMETRY=0 + +# Eller permanent via CLI-en +archgate telemetry disable +``` + +Merk: telemetrireservasjon deaktiverer CLI-analyse og krasjrapportering. Det pavirker ikke Plugins Service-kontodataene, som kreves for plugintilgang. For a slette kontodataene dine, kontakt [privacy@archgate.dev](mailto:privacy@archgate.dev). + +### Dine rettigheter + +- **Innsyn:** Be om en kopi av dataene dine -- send e-post til [privacy@archgate.dev](mailto:privacy@archgate.dev) med din installasjons-ID (fra `~/.archgate/config.json` eller `archgate telemetry status`). +- **Sletting:** Be om sletting av historiske data -- send e-post med din installasjons-ID. Gjennomføres innen 30 dager. +- **Protest:** Deaktiver telemetri nar som helst via `archgate telemetry disable`. +- **Dataportabilitet:** Be om dataeksport i JSON- eller CSV-format. +- **Klage:** Kontakt Datatilsynet ([Datatilsynet](https://www.datatilsynet.no)). + +### Hva dokumentasjonssiden samler inn + +Denne dokumentasjonssiden (`cli.archgate.dev`) bruker [Cloudflare Web Analytics](https://www.cloudflare.com/web-analytics/), en personvernvennlig analysetjeneste. Cloudflare Web Analytics bruker ikke informasjonskapsler, sporer ikke individuelle besøkende og samler ikke inn personopplysninger. Tjenesten gir kun aggregerte sidevisnings- og ytelsesmålinger. + +PostHog brukes ogsa pa dette nettstedet med **informasjonskapselløs sporing kun i minnet** (`persistence: "memory"`). Ingen informasjonskapsler settes, ingen localStorage skrives, og ingen data vedvarer mellom sidelastinger. diff --git a/docs/src/content/docs/nb/reference/rule-api.mdx b/docs/src/content/docs/nb/reference/rule-api.mdx new file mode 100644 index 00000000..5ff88ace --- /dev/null +++ b/docs/src/content/docs/nb/reference/rule-api.mdx @@ -0,0 +1,310 @@ +--- +title: Rule API +description: TypeScript API-referanse for skriving av Archgate-regler. Lær RuleSet med satisfies, RuleContext, rapportering av brudd, filmatchning og AST-baserte samsvarskontroller. +--- + +Archgate-regler er TypeScript-filer som eksporterer et vanlig objekt typet med `satisfies RuleSet`. Hver regel mottar en `RuleContext` med verktoy for a soke i filer, lese innhold og rapportere brudd. + +## RuleSet + +```typescript +/// <reference path="../rules.d.ts" /> + +export default { + rules: { + "my-rule-id": { + description: "Human-readable description of what this rule checks", + severity: "error", // optional, defaults to "error" + async check(ctx) { + // Rule logic here + }, + }, + }, +} satisfies RuleSet; +``` + +En regelfil eksporterer som standard et vanlig objekt med en `rules`-post indeksert etter regel-ID. Noklene blir regel-ID-ene som vises i sjekkutdata og bruddrapporter. Annotasjonen `satisfies RuleSet` gir typekontroll uten a pakke inn i et funksjonskall. + +```typescript +type RuleSet = { rules: Record<string, RuleConfig> }; +``` + +--- + +## RuleConfig + +Hver regel i posten ma samsvare med `RuleConfig`-grensesnittet. + +```typescript +interface RuleConfig { + description: string; + severity?: Severity; + check: (ctx: RuleContext) => Promise<void>; +} +``` + +| Felt | Type | Pakrevd | Beskrivelse | +| ------------- | ------------------------------------- | ------- | ---------------------------------------------------------- | +| `description` | `string` | Ja | Lesbar beskrivelse som vises i sjekkutdata | +| `severity` | `Severity` | Nei | Standard alvorlighetsgrad for brudd. Standard er `"error"` | +| `check` | `(ctx: RuleContext) => Promise<void>` | Ja | Asynkron funksjon som inneholder regellogikken | + +--- + +## RuleContext + +`check`-funksjonen mottar et `RuleContext`-objekt med prosjekttilstand og hjelpemetoder. + +```typescript +interface RuleContext { + projectRoot: string; + scopedFiles: string[]; + changedFiles: string[]; + glob(pattern: string): Promise<string[]>; + grep(file: string, pattern: RegExp): Promise<GrepMatch[]>; + grepFiles(pattern: RegExp, fileGlob: string): Promise<GrepMatch[]>; + readFile(path: string): Promise<string>; + readJSON(path: string): Promise<unknown>; + report: RuleReport; +} +``` + +### Egenskaper + +#### projectRoot + +```typescript +projectRoot: string; +``` + +Absolutt sti til prosjektets rotkatalog (der `.archgate/` ligger). + +#### scopedFiles + +```typescript +scopedFiles: string[]; +``` + +Filer som matcher ADR-ens `files`-globmonstre fra frontmatter. Hvis ADR-en ikke har et `files`-felt, inneholder denne alle prosjektfiler. Bruk denne som den primaere fillisten for regelkontrollene dine. + +#### changedFiles + +```typescript +changedFiles: string[]; +``` + +Filer som har blitt endret ifolge git. Som standard fylles denne automatisk med branch-diffen mot den detekterte basisgrenen (f.eks. `origin/main`). Nar `--staged` brukes, inneholder den kun stagede filer. Nar `--base <ref>` brukes, inneholder den alle filer som er endret siden den referansen. Tom nar basisdeteksjon feiler eller ingen endringer finnes. Bruk denne til a bygge regler for avhengigheter mellom filer (f.eks. "hvis fil A endret seg, ma fil B ogsa endres"). + +#### report + +```typescript +report: RuleReport; +``` + +Rapporteringsgrensesnittet for a registrere brudd, advarsler og informasjonsmeldinger. Se [RuleReport](#rulereport) nedenfor. + +### Metoder + +#### glob + +```typescript +glob(pattern: string): Promise<string[]>; +``` + +Finn filer som matcher et globmonster relativt til prosjektroten. Returnerer en matrise med filstier. Filer som ignoreres av `.gitignore` er ekskludert som standard. Sett `respectGitignore: false` i ADR-ens frontmatter for a inkludere dem. + +```typescript +const testFiles = await ctx.glob("tests/**/*.test.ts"); +``` + +#### grep + +```typescript +grep(file: string, pattern: RegExp): Promise<GrepMatch[]>; +``` + +Sok i en enkelt fil etter linjer som matcher et regulaert uttrykk. Returnerer en matrise med `GrepMatch`-objekter med filsti, linjenummer, kolonne og matchet innhold. + +```typescript +const matches = await ctx.grep(file, /console\.error\(/); +``` + +#### grepFiles + +```typescript +grepFiles(pattern: RegExp, fileGlob: string): Promise<GrepMatch[]>; +``` + +Sok i flere filer som matcher et globmonster etter linjer som matcher et regulaert uttrykk. Kombinerer `glob` og `grep` i ett enkelt kall. Filer som ignoreres av `.gitignore` er ekskludert som standard. Sett `respectGitignore: false` i ADR-ens frontmatter for a inkludere dem. + +```typescript +const matches = await ctx.grepFiles(/TODO:/i, "src/**/*.ts"); +``` + +#### readFile + +```typescript +readFile(path: string): Promise<string>; +``` + +Les innholdet i en fil som en streng. Stien er relativ til prosjektroten. + +```typescript +const content = await ctx.readFile("src/config.ts"); +``` + +#### readJSON + +```typescript +readJSON(path: string): Promise<unknown>; +``` + +Les og parse en JSON-fil. Stien er relativ til prosjektroten. Returnerer den parsede verdien som `unknown` -- cast til forventet type i regelen din. + +```typescript +const pkg = (await ctx.readJSON("package.json")) as { + dependencies?: Record<string, string>; +}; +``` + +--- + +## RuleReport + +Rapporteringsgrensesnittet for a registrere sjekkresultater. Hver metode aksepterer et detalobjekt som beskriver problemet. + +```typescript +interface RuleReport { + violation(detail: ReportDetail): void; + warning(detail: ReportDetail): void; + info(detail: ReportDetail): void; +} +``` + +#### violation + +```typescript +report.violation(detail: ReportDetail): void; +``` + +Rapporter et regelbrudd. Brudd far sjekken til a feile med avslutningskode 1. Bruk for harde begrensninger som ikke skal merges. + +#### warning + +```typescript +report.warning(detail: ReportDetail): void; +``` + +Rapporter en advarsel. Advarsler vises i sjekkutdata, men far ikke sjekken til a feile. Bruk for ikke-blokkerende veiledning. + +#### info + +```typescript +report.info(detail: ReportDetail): void; +``` + +Rapporter en informasjonsmelding. Pavirker ikke avslutningskoden for sjekken. Bruk for forslag eller notater. + +### ReportDetail + +Detalobjektet som sendes til `violation`, `warning` og `info`. + +```typescript +interface ReportDetail { + message: string; + file?: string; + line?: number; + endLine?: number; + endColumn?: number; + fix?: string; +} +``` + +| Felt | Type | Pakrevd | Beskrivelse | +| ----------- | -------- | ------- | -------------------------------------------------------------------------- | +| `message` | `string` | Ja | Lesbar beskrivelse av problemet | +| `file` | `string` | Nei | Filsti der problemet ble funnet | +| `line` | `number` | Nei | Startlinjenummer (1-basert) | +| `endLine` | `number` | Nei | Sluttlinjenummer (1-basert) -- for presis uthevning av omrade i editoren | +| `endColumn` | `number` | Nei | Sluttkolonnenummer (0-basert) -- for presis uthevning av omrade i editoren | +| `fix` | `string` | Nei | Foreslatt rettelse eller utbedringstiltak | + +Nar `endLine` og `endColumn` er oppgitt, kan editorer (VS Code, Cursor) utheve det noyaktige uttrykket som bryter regelen, i stedet for hele linjen. Hvis de utelates, utheves hele linjen ved `line`. + +--- + +## GrepMatch + +Returnert av `ctx.grep()` og `ctx.grepFiles()`. + +```typescript +interface GrepMatch { + file: string; + line: number; + column: number; + content: string; +} +``` + +| Felt | Type | Beskrivelse | +| --------- | -------- | ------------------------------------ | +| `file` | `string` | Absolutt sti til den matchede filen | +| `line` | `number` | Linjenummer for treffet (1-basert) | +| `column` | `number` | Kolonnenummer for treffet (1-basert) | +| `content` | `string` | Fullt innhold av den matchede linjen | + +--- + +## Severity + +```typescript +type Severity = "error" | "warning" | "info"; +``` + +| Verdi | Pavirkning pa avslutningskode | Beskrivelse | +| ----------- | ----------------------------- | ------------------------------------------ | +| `"error"` | Forarsakar avslutningskode 1 | Hard begrensning, blokkerer sammenslainger | +| `"warning"` | Ingen pavirkning | Ikke-blokkerende veiledning | +| `"info"` | Ingen pavirkning | Informasjon, kun forslag | + +--- + +## ViolationDetail + +Den interne representasjonen av et rapportert problem, brukt i sjekkutdata og JSON-resultater. + +```typescript +interface ViolationDetail { + ruleId: string; + adrId: string; + message: string; + file?: string; + line?: number; + endLine?: number; + endColumn?: number; + fix?: string; + severity: Severity; +} +``` + +| Felt | Type | Beskrivelse | +| ----------- | ---------- | ---------------------------------------------------------- | +| `ruleId` | `string` | Regel-ID fra `rules`-objektnokelen | +| `adrId` | `string` | ADR-ID fra frontmatter | +| `message` | `string` | Lesbar beskrivelse | +| `file` | `string?` | Filsti der problemet ble funnet | +| `line` | `number?` | Startlinjenummer (1-basert) | +| `endLine` | `number?` | Sluttlinje (1-basert) -- for presis uthevning i editoren | +| `endColumn` | `number?` | Sluttkolonne (0-basert) -- for presis uthevning i editoren | +| `fix` | `string?` | Foreslatt rettelse | +| `severity` | `Severity` | Effektiv alvorlighetsgrad for dette bruddet | + +--- + +## RuleSet + +Typen brukt med `satisfies` for a typekontrollere regelobjektet ditt. Eksporter et vanlig objekt som samsvarer med denne formen. + +```typescript +type RuleSet = { rules: Record<string, RuleConfig> }; +``` diff --git a/docs/src/content/docs/nb/reference/telemetry.mdx b/docs/src/content/docs/nb/reference/telemetry.mdx new file mode 100644 index 00000000..55c0d198 --- /dev/null +++ b/docs/src/content/docs/nb/reference/telemetry.mdx @@ -0,0 +1,148 @@ +--- +title: Telemetri +description: Hvilke anonyme bruksdata Archgate samler inn, hvordan du kan reservere deg, og vare personvernforpliktelser. +--- + +Archgate samler inn **anonyme bruksdata** for a hjelpe oss med a forsta hvordan CLI-en brukes, prioritere funksjoner og fikse krasjer. Denne siden forklarer noyaktig hva som samles inn, hva som ikke samles inn, og hvordan du kan reservere deg. + +## Hva vi samler inn + +### Bruksanalyse (PostHog) + +Nar du kjorer en Archgate-kommando, registrerer vi: + +- **Kommandonavn** og **hvilke flagg som ble brukt** (f.eks. `check --json` -- kun flaggtilstedevaerelse, aldri flaggverdier) +- **Avslutningskode** (0, 1, 2 eller 130) og **kjoretid** (millisekunder), pluss en kort **utfallstagg** (`success`, `user_error`, `internal_error`, `cancelled`) +- **Miljo**: OS, arkitektur, Bun-versjon, Archgate-versjon, CI-deteksjon (inkludert leverandor: GitHub Actions / GitLab CI / CircleCI / osv.), TTY-deteksjon, WSL-deteksjon, shell (bash, zsh, pwsh...) og locale +- **Installasjonskontekst**: hvordan CLI-en ble installert (binaerfil, proto, lokal dev-avhengighet eller global pakkebehandler) +- **Prosjektkontekst**: om et Archgate-prosjekt finnes i gjeldende katalog, hvor mange ADR-er det har, hvor mange som har automatiserte regler, og hvor mange distinkte ADR-domener som brukes +- **Repokontekst** (ikke-identifiserende): om gjeldende katalog er et git-repository, vertsboksen (`github` / `gitlab` / `bitbucket` / `azure-devops` / `other`), en **hashet `repo_id`** (SHA-256 av den normaliserte fjern-URL-en, avkortet til 16 heksadesimale tegn -- ikke reverserbar), og standard grennavn +- **Grov lokasjon**: land og region (resolveres pa serversiden fra IP-adressen din, deretter forkastes IP-en -- se [IP-anonymisering](#ip-anonymisering)) +- **Anonym installasjons-ID**: en tilfeldig UUID generert ved forste kjoring -- ikke avledet fra personopplysninger + +I tillegg til de generelle livssyklushendelsene for kommandoer (`command_executed` / `command_completed`), sender spesifikke kommandoer berikede utfallshendelser: + +- **`check`**: aggregerte regeltellinger (totalt, bestaatt, feilet, advarsler, feil), brukt utdataformat, om filtre ble brukt, skannede filer, lastetid, sjekktid -- ingen filstier eller bruddinnhold +- **`init`**: editorvalg, om pluginen ble installert, om prosjektet allerede eksisterte. En separat engangshendelse `project_initialized` sendes med repovertsboksen, `repo_is_git` og et `repo_public`-flagg. For repoer bekreftet som offentlige pa GitHub / GitLab / Bitbucket, inneholder denne hendelsen ogsa fjern-URL, eier og reponavn -- se [Repoidentitet](#repoidentitet). Private og selvhostede repoer far aldri identitet delt. +- **`upgrade`**: versjonsovergang (fra -> til), installasjonsmetode, suksess/feil og en valgfri feilarsak +- **`login`**: underkommando brukt (login, logout, refresh, status), suksess/feil og en feilboks (`network`, `tls`, `denied`, `other`) nar det feiler +- **`telemetry_preference_changed`**: utloses en gang nar du aktiverer eller deaktiverer telemetri, slik at vi kan forsta reservasjonsrater + +## Repoidentitet + +Archgate sender en **hashet** `repo_id` med hver hendelse slik at vi kan telle distinkte repositorier som bruker CLI-en uten a laere navnene deres. Den ra fjern-URL-en, eieren og reponavnet er **ikke** inkludert i den generelle hendelsesstrommen. + +Ved `archgate init` sendes en engangshendelse `project_initialized`. Hvis -- og bare hvis -- repositoriet er bekreftet **offentlig** pa GitHub, GitLab, Bitbucket eller Azure DevOps (via en uautentisert API-probing mot verten), inneholder den hendelsen i tillegg `remote_url`, `repo_owner` og `repo_name`. Dette lar oss se hvilke offentlige repositorier som tar i bruk Archgate uten a noensinne eksponere private. + +**Hva som aldri deles:** + +- Private repositorier (API-probing returnerer 404, 401 eller `private: true`) +- Selvhostede Git-verter (probingen hopper over disse helt) +- Repositorier der probingen far tidsavbrudd, ratebegrensning eller pa annen mate ikke klarer a returnere et definitivt offentlig svar + +**Vil du ikke ha hendelsen i det hele tatt?** Deaktiver telemetri helt -- hele `project_initialized`-hendelsen undertrykkes da sammen med alt annet: + +```bash +# Per shell / per kjoring +export ARCHGATE_TELEMETRY=0 + +# Eller permanent +archgate telemetry disable +``` + +Se [Slik reserverer du deg](#slik-reserverer-du-deg) nedenfor for fullstendige detaljer. + +### Feilsporing (Sentry) + +Nar CLI-en krasjer (avslutningskode 2), sender vi: + +- **Feiltype, melding og stacktrace** (filstier strippes til relative stier som `src/cli.ts`) +- **Kjoretidskontekst**: OS, arkitektur, Bun-versjon, Archgate-versjon +- **Anonym installasjons-ID** (samme tilfeldige UUID som analyse) + +## Hva vi IKKE samler inn + +- **Ingen personopplysninger**: ingen brukernavn, e-postadresser eller IP-adresser. GitHub / GitLab / Bitbucket eier-/reponavn sendes kun pa engangshendelsen `project_initialized` for repositorier som er bekreftet offentlige av verten sin -- se [Repoidentitet](#repoidentitet). Private og selvhostede repoer far aldri identitet delt. +- **Intet filinnhold**: ingen ADR-innhold, kildekode eller filstier +- **Ingen prompt- eller AI-kontekst**: ingenting fra agentinteraksjoner, prompter eller AI-generert innhold +- **Ingen flaggverdier**: vi registrerer at `--json` ble brukt, ikke hva JSON-utdataene inneholdt +- **Ingen nettverksaktivitet**: ingen URL-er, API-nokler eller tokener + +## IP-anonymisering + +Archgate bruker PostHogs innebygde IP-anonymisering: + +1. CLI-en din sender en hendelse til PostHog med `$ip: null` +2. PostHog resolver IP-adressen din til et **land og en region** (f.eks. "US", "California") pa serversiden +3. IP-adressen **forkastes** deretter -- den lagres aldri i PostHog + +For Sentry feilsporing har prosjektet **"Prevent Storing of IP Addresses"** aktivert, slik at IP-adresser fjernes for lagring. + +## Slik reserverer du deg + +Du kan deaktivere all telemetri (bade analyse og feilsporing) pa to mater: + +### Miljovariabel + +```bash +export ARCHGATE_TELEMETRY=0 +``` + +Aksepterte verdier: `0`, `false`, `no`, `off` (uavhengig av store/sma bokstaver). + +Legg dette til i shellprofilen din (`.bashrc`, `.zshrc`, osv.) for a deaktivere permanent. + +### CLI-kommando + +```bash +archgate telemetry disable +``` + +For a reaktivere: + +```bash +archgate telemetry enable +``` + +For a sjekke gjeldende status: + +```bash +archgate telemetry status +``` + +Miljovariabelen har forrang over CLI-innstillingen. Hvis `ARCHGATE_TELEMETRY=0` er satt, er telemetri deaktivert uavhengig av CLI-konfigurasjonen. + +## Rettslig grunnlag + +Archgate CLI-telemetri opererer pa **reservasjonsbasis** under GDPR artikkel 6(1)(f) og LGPD artikkel 7, IX c/c artikkel 10 -- behandlingsansvarliges berettigede interesser. Vi har publisert en formell [Vurdering av berettigede interesser](https://archgate.dev/legitimate-interest-assessment) som dokumenterer hvorfor dette er forholdsmessig og lovlig. + +Oppsummert: dataene er anonyme (tilfeldig UUID, ingen personopplysninger), pavirkningen pa brukere er minimal, robuste sikkerhetstiltak er pa plass (IP-anonymisering, EU-lagring, begrenset oppbevaringstid, transparens), og brukere beholder full kontroll via en enkel, permanent reservasjonsmulighet. + +## Hvor data lagres + +| Tjeneste | Data | Region | Oppbevaringstid | +| ------------- | -------------------------------------- | -------------- | ------------------ | +| PostHog Cloud | Anonym bruksanalyse | EU (Frankfurt) | 1 ar | +| Sentry Cloud | Krasjrapporter | EU (Frankfurt) | 90 dager | +| Lokal konfig | Telemetripreferanse + installasjons-ID | Din maskin | Til du sletter den | + +Analysehendelser rutes gjennom `n.archgate.dev` og feilrapporter gjennom `s.archgate.dev`. Disse er transparente reverseproksier driftet av Dasolve AS pa Cloudflare-infrastruktur -- de videresender foresporsler uten a logge, lagre eller inspisere nyttelast. + +## Dine rettigheter + +- **Rett til innsyn**: Be om en kopi av alle data knyttet til din installasjons-ID. Send e-post til [privacy@archgate.dev](mailto:privacy@archgate.dev) med din installasjons-ID (finnes via `archgate telemetry status` eller i `~/.archgate/config.json`). Svar innen 30 dager. +- **Rett til sletting**: Be om sletting av historiske analyse- og krasjdata. A deaktivere telemetri stopper fremtidig innsamling, men sletter ikke tidligere hendelser. Send e-post til [privacy@archgate.dev](mailto:privacy@archgate.dev) med din installasjons-ID for sletting. +- **Rett til a protestere**: Deaktiver telemetri nar som helst via `archgate telemetry disable` eller `ARCHGATE_TELEMETRY=0`. +- **Rett til a klage**: Kontakt Datatilsynet ([Datatilsynet](https://www.datatilsynet.no)) eller, for brasilianske brukere, ANPD ([www.gov.br/anpd](https://www.gov.br/anpd)). + +**Behandlingsansvarlig:** Dasolve AS (Org.nr 936 035 019), Lillogata 5P, 0484 Oslo, Norge. Kontakt: [privacy@archgate.dev](mailto:privacy@archgate.dev). + +**Brasilianske brukere (LGPD):** For LGPD-spesifikke rettigheter (art. 18), detaljer om internasjonal overforing (art. 33) og ANPD-kontaktinformasjon, se [personvernerklaering pa portugisisk](https://archgate.dev/pt-br/privacy-policy). + +## Apen kildekode + +Telemetriimplementasjonen er fullstendig apen kildekode. Du kan inspisere noyaktig hvilke data som samles inn ved a lese: + +- [`src/helpers/telemetry.ts`](https://github.com/archgate/cli/blob/main/src/helpers/telemetry.ts) -- PostHog-hendelsessporing +- [`src/helpers/sentry.ts`](https://github.com/archgate/cli/blob/main/src/helpers/sentry.ts) -- Sentry-feilfangst +- [`src/helpers/telemetry-config.ts`](https://github.com/archgate/cli/blob/main/src/helpers/telemetry-config.ts) -- Konfigurasjon og reservasjonslogikk diff --git a/docs/src/content/docs/nb/studies/sentry-pr-review-friction-and-adr-pack.mdx b/docs/src/content/docs/nb/studies/sentry-pr-review-friction-and-adr-pack.mdx new file mode 100644 index 00000000..88ee1c9c --- /dev/null +++ b/docs/src/content/docs/nb/studies/sentry-pr-review-friction-and-adr-pack.mdx @@ -0,0 +1,25 @@ +--- +title: "Studie: Sentry PR-friksjon og ADR-standardisering" +description: "En 90-dagers pull request-studie av getsentry/sentry som viser hvor gjennomgangs-friksjon samler seg og hvilke ADR-er/regler som kan redusere gjentatte diskusjoner." +--- + +Denne studien måler hvor kodegjennomgangsfriksjon konsentrerer seg i [`getsentry/sentry`](https://github.com/getsentry/sentry) og identifiserer hvilke ADR-er som kan redusere gjentatte diskusjonssykluser. + +Målet er ikke å fjerne menneskelig gjennomgang. Målet er å flytte gjentatte, forutsigbare gjennomgangsdebatter inn i eksplisitte beslutninger og maskinsjekbar policy. + +## Høydepunkter + +På tvers av **500 sammenslåtte PR-er**, **500 lukket-uten-sammenslåing PR-er** og **251 åpne PR-er** over et 90-dagers vindu: + +- **PR-størrelse er den sterkeste friksjonsindikator** -- store PR-er havner i den høye friksjonskvartilen **57 %** av gangene mot **10 %** for små PR-er. +- **Median tid-til-sammenslåing er ca. 5 timer**, men P90 når **ca. 71 timer** (en 14x-multiplikator). +- **Gjentatte diskusjonstemaer** samler seg rundt API-semantikk, typesikkerhet, testbevis, UX-flytutvarianter og omfangssplitting. +- **5 foreslåtte ADR-er** adresserer de største friksjonskildene, med tilhørende regler og en faseinndelt utrullingsplan. + +## Les den fullstendige studien + +Den komplette studien -- metodikk, grunnlinjemetrikker, friksjonskart, temaanalyse og ADR-forslag -- er publisert på: + +**[studies.archgate.dev/studies/sentry-pr-review-friction](https://studies.archgate.dev/studies/sentry-pr-review-friction/)** + +Kildekode og dataartefakter finnes i [`archgate/studies`](https://github.com/archgate/studies/tree/main/studies/sentry-pr-review-friction).