Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
87b0add
fix: include bun.lock in release commit changedFiles
rhuanbarreto Mar 18, 2026
4986f7e
fix: show platform-appropriate shell syntax in TLS error hint
rhuanbarreto Mar 18, 2026
1c7797d
feat: add ARCH-009 ADR for centralized platform detection
rhuanbarreto Mar 18, 2026
2736a0b
fix: show all Windows shell variants in TLS error hint
rhuanbarreto Mar 18, 2026
60db9ec
feat: interactive signup flow in login command
rhuanbarreto Mar 18, 2026
cb45189
feat: prefill email from GitHub in signup flow
rhuanbarreto Mar 18, 2026
781f141
feat: use signup token directly and ask for editor preference
rhuanbarreto Mar 18, 2026
1ed7f0a
feat: add all editor options to signup flow
rhuanbarreto Mar 18, 2026
30bb503
fix: show context-aware hint after login
rhuanbarreto Mar 18, 2026
feb8012
docs: update login documentation for interactive signup and TLS handling
rhuanbarreto Mar 18, 2026
4ac680c
feat: offer inline login and signup during archgate init
rhuanbarreto Mar 18, 2026
6fb70a3
refactor: extract shared login+signup flow into login-flow.ts
rhuanbarreto Mar 18, 2026
cc54921
docs: remove change-announcement language from login documentation
rhuanbarreto Mar 18, 2026
819d370
docs: replace plugins.archgate.dev signup links with archgate login
rhuanbarreto Mar 18, 2026
2d687da
docs: add VS Code and Copilot CLI guides to index pages
rhuanbarreto Mar 18, 2026
4a618b8
feat: add GEN-002 rule to catch locale-prefixed links in i18n pages
rhuanbarreto Mar 18, 2026
25b9cd3
docs: regenerate llms-full.txt
rhuanbarreto Mar 18, 2026
b75f99a
ci: check llms-full.txt is up to date with docs
rhuanbarreto Mar 18, 2026
c95c535
ci: auto-regenerate llms-full.txt when docs change
rhuanbarreto Mar 18, 2026
3e1f298
ci: restore llms-full.txt freshness check in validation
rhuanbarreto Mar 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions .archgate/adrs/ARCH-009-platform-detection-helper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
id: ARCH-009
title: Centralized Platform Detection
domain: architecture
rules: true
files:
- "src/**/*.ts"
---

## Context

The Archgate CLI runs on macOS, Linux, and Windows (including WSL). Platform-specific behavior appears throughout the codebase: shell syntax in user-facing messages, path separators, subprocess resolution, and feature availability checks.

The `src/helpers/platform.ts` module already provides a centralized, cached API for platform detection (`isWindows()`, `isMacOS()`, `isLinux()`, `isWSL()`, `getPlatformInfo()`). It also exposes a `_resetPlatformCache()` function that allows tests to simulate different platforms without mocking `process.platform` directly.

The problem is that nothing prevents code from bypassing this module and reading `process.platform` directly. Direct reads:

- **Scatter platform logic** — Platform checks end up duplicated across modules with inconsistent patterns (`process.platform === "win32"` vs `process.platform !== "linux"`).
- **Cannot be tested** — `process.platform` is read-only in Bun. Code that reads it directly cannot be tested under a different platform without modifying global state. The platform helper's `_resetPlatformCache()` makes cross-platform testing straightforward.
- **Miss WSL** — `process.platform` returns `"linux"` inside WSL. Code that checks for `"win32"` to decide Windows-specific behavior will miss WSL scenarios where Windows paths or tools are relevant. The platform helper accounts for WSL.

## Decision

All platform detection in `src/` MUST go through `src/helpers/platform.ts`. Direct access to `process.platform` outside of `platform.ts` is **forbidden**.

This covers:

- OS-conditional logic (Windows vs macOS vs Linux)
- WSL detection
- Platform-specific user-facing messages (shell syntax, paths)
- Feature availability checks that depend on the OS

This does NOT cover:

- Test files (`tests/**/*.ts`) — tests may inspect `process.platform` for conditional assertions
- Build scripts and configuration files outside `src/`

## Do's and Don'ts

### Do

- **DO** import from `src/helpers/platform.ts` for any platform check: `isWindows()`, `isMacOS()`, `isLinux()`, `isWSL()`, `getPlatformInfo()`
- **DO** use `_resetPlatformCache()` in tests to simulate different platforms
- **DO** consider WSL when implementing Windows-specific behavior — `isWSL()` returns true when running Linux inside WSL, where Windows tools may still be relevant

### Don't

- **DON'T** read `process.platform` directly in source files — use the platform helper instead
- **DON'T** duplicate platform detection logic that already exists in `platform.ts`
- **DON'T** assume `"linux"` means a native Linux environment — it could be WSL

## Consequences

### Positive

- **Single source of truth** — All platform detection flows through one module with consistent caching and WSL awareness.
- **Testable** — Cross-platform behavior can be tested on any OS via `_resetPlatformCache()`.
- **WSL-safe** — The helper correctly distinguishes native Linux from WSL, preventing subtle bugs.

### Negative

- **Import overhead** — Modules that need a one-off platform check must import from `platform.ts` instead of reading `process.platform` directly.

## Compliance and Enforcement

### Automated Enforcement

- **Archgate rule** `ARCH-009/no-direct-process-platform`: Scans all TypeScript source files (excluding `platform.ts` itself and tests) for direct `process.platform` access. Severity: `error`.

### Manual Enforcement

Code reviewers MUST verify:

1. No `process.platform` reads appear outside `src/helpers/platform.ts`
2. Platform-conditional logic uses the helper functions, not inline checks
3. WSL is considered when the behavior differs between Linux and Windows

## References

- [ARCH-007 — Cross-Platform Subprocess Execution](./ARCH-007-cross-platform-subprocess-execution.md) — Related cross-platform concern for subprocess APIs
- `src/helpers/platform.ts` — The canonical platform detection module
31 changes: 31 additions & 0 deletions .archgate/adrs/ARCH-009-platform-detection-helper.rules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { defineRules } from "../../src/formats/rules";

export default defineRules({
"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")
);

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(), isLinux(), or getPlatformInfo() from src/helpers/platform.ts instead.",
file: m.file,
line: m.line,
fix: 'Import { isWindows } from "../helpers/platform" (or the appropriate helper) and use it instead of process.platform',
});
}
}
},
},
});
35 changes: 35 additions & 0 deletions .archgate/adrs/GEN-002-docs-i18n.rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,42 @@ const LOCALES = ["pt-br"];

const CONTENT_ROOT = "docs/src/content/docs";

/** Patterns that match locale-prefixed internal links in MDX files. */
const LOCALE_LINK_PATTERNS = LOCALES.map(
(locale) => new RegExp(`(?:href="|\\]\\()/${locale}/`, "g")
);

export default defineRules({
"no-locale-prefix-in-links": {
description:
"Locale pages must not use locale-prefixed internal links — Starlight resolves them automatically",
severity: "error",
async check(ctx) {
/* oxlint-disable no-await-in-loop -- sequential per-locale is fine for a small list */
for (const locale of LOCALES) {
const localePrefix = `${CONTENT_ROOT}/${locale}/`;
const localeFiles = (await ctx.glob(`${localePrefix}**/*.mdx`)).filter(
(f) => f.startsWith(localePrefix)
);
const pattern = LOCALE_LINK_PATTERNS[LOCALES.indexOf(locale)];

const matches = await Promise.all(
localeFiles.map((file) => ctx.grep(file, pattern))
);
for (const fileMatches of matches) {
for (const m of fileMatches) {
ctx.report.violation({
message: `Internal link contains locale prefix "/${locale}/". Remove the prefix — Starlight resolves locale routes automatically.`,
file: m.file,
line: m.line,
fix: `Replace "/${locale}/..." with "/..." in the link`,
});
}
}
}
/* oxlint-enable no-await-in-loop */
},
},
"i18n-page-parity": {
description:
"Every root MDX file must have a corresponding translation in each locale, and vice versa",
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/code-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ jobs:
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: echo "$PR_TITLE" | bun run commitlint
- name: Check llms-full.txt is up to date
run: |
bun run docs/scripts/generate-llms-full.ts
git diff --exit-code docs/public/llms-full.txt || {
echo "::error::docs/public/llms-full.txt is out of date. Run 'bun run docs/scripts/generate-llms-full.ts' and commit the result."
exit 1
}
- name: Validate
id: validate
run: bun run validate
Expand Down
47 changes: 47 additions & 0 deletions .github/workflows/update-llms.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Update llms-full.txt
on:
pull_request:
branches:
- main
paths:
- "docs/src/content/docs/**"
- "docs/scripts/generate-llms-full.ts"
- ".github/workflows/update-llms.yaml"
permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
update-llms:
name: Update llms-full.txt
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Generate token
id: generate_token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.GH_APP_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- uses: actions/checkout@v4
with:
token: ${{ steps.generate_token.outputs.token }}
fetch-depth: 1
ref: ${{ github.head_ref }}
- uses: moonrepo/setup-toolchain@v0
with:
auto-install: true
cache: true
cache-base: main
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Regenerate llms-full.txt
run: bun run docs/scripts/generate-llms-full.ts
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v6
with:
commit_message: "docs: regenerate llms-full.txt"
file_pattern: docs/public/llms-full.txt
1 change: 1 addition & 0 deletions .simple-release.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class ArchgateProject extends NpmProject {
if (changed) {
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
execSync("bun install", { stdio: "inherit" });
this.changedFiles.push("bun.lock");
}
}

Expand Down
Loading
Loading