Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 0 additions & 12 deletions .eslintrc.base.json

This file was deleted.

8 changes: 2 additions & 6 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
#!/usr/bin/env bash
# Committed pre-push hook. Runs the fast lint gate (`make fmt clippy`) before
# any push so formatting/clippy failures are caught locally instead of on CI.
# Tests are deliberately excluded — they are too slow for a push gate; run
# `make check` or `scripts/cicdprep.sh` before opening a PR.
#
# Committed pre-push hook. Runs the fast lint gate (`make fmt clippy`) before any push so formatting/clippy failures are caught locally
# Enable once per clone: make install-hooks (sets core.hooksPath=.githooks)
# Bypass in an emergency: git push --no-verify
set -euo pipefail
Expand All @@ -15,7 +11,7 @@ cd "$repo_root"
echo "pre-push: running lint checks (fmt + clippy)…"
if ! make fmt clippy; then
echo
echo "pre-push: lint checks failed push aborted." >&2
echo "pre-push: lint checks failed - push aborted." >&2
echo "Fix the issues above, or bypass with 'git push --no-verify' (not recommended)." >&2
exit 1
fi
3 changes: 0 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,3 @@ updates:
- dependency-name: "actions/*"
cooldown:
default-days: 7
semver-major-days: 30
semver-minor-days: 14
semver-patch-days: 3
2 changes: 0 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ jobs:
restore-keys: ${{ runner.os }}-cargo-

# The frontend is typed against these; generate before anything compiles.
# bindings/ is committed — the script regenerates and fails on any
# checksum difference vs the checkout (modified or newly exported types).
- name: Generate TypeScript bindings and verify they are committed
run: |
scripts/check-bindings-fresh.sh || {
Expand Down
243 changes: 243 additions & 0 deletions .oxlintrc.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": [
"eslint",
"typescript",
"unicorn",
"oxc",
"react",
"react-perf",
"jsx-a11y",
"promise"
],
"categories": {
"correctness": "error",
"suspicious": "error",
"perf": "error",
"pedantic": "off",
"style": "off",
"restriction": "off",
"nursery": "off"
},

"options": { "typeAware": true },

"env": { "es2022": true },

"settings": {
"react": { "version": "19.0" }
},

"ignorePatterns": [
"**/node_modules/**",
"**/dist/**",
"**/out/**",
"**/*.d.ts",
"webcomponents/src/generated/**",
"vscode-extension/src/generated/**",
"vscode-extension/shared/**",
"vscode-extension/.vscode-test/**",
"**/.claude/**",
"target/**",
"docs/_site/**",
"docs/assets/js/**",
"agnt-plugin/**",
"coder-module/**",
"bindings/**",
"shared/**",
"scripts/**",
"zed-extension/**",
"opr8r/**"
],

"rules": {
"eslint/no-unused-vars": ["error", {
"args": "after-used",
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_",
"ignoreRestSiblings": true
}],
"eslint/no-void": ["error", { "allowAsStatement": true }],
"typescript/no-explicit-any": "error",
"eslint/curly": ["error", "all"],
"eslint/eqeqeq": ["error", "always", { "null": "ignore" }],
"typescript/explicit-function-return-type": "off",
"typescript/explicit-module-boundary-types": "off",
// Was webview-ui-only under eslint; no reason for that scoping.
"typescript/consistent-type-assertions": ["error", {
"assertionStyle": "as",
"objectLiteralTypeAssertions": "never"
}],

// ---- Disabled: these fire on deliberate repo-wide conventions ----
// React 19 automatic runtime ("jsx": "react-jsx").
"react/react-in-jsx-scope": "off",
// Collides with the ^_ unused-arg convention above.
"eslint/no-underscore-dangle": "off",
// Sequential awaits are deliberate in vscode-extension orchestration.
"eslint/no-await-in-loop": "off",
// Fires on every `(await res.json()) as T`; recommended or strict either.
"typescript/no-unsafe-type-assertion": "off",
"react/rules-of-hooks": "error",
"react/jsx-no-target-blank": "error",
"react/jsx-no-useless-fragment": "error",
"jsx-a11y/anchor-ambiguous-text": "error",
"typescript/ban-ts-comment": "error",
"typescript/adjacent-overload-signatures": "error",
"typescript/consistent-type-exports": "error",
"typescript/no-empty-object-type": "error",
"typescript/no-unsafe-function-type": "error",
"typescript/prefer-enum-initializers": "error",
"typescript/prefer-literal-enum-member": "error",
"typescript/prefer-optional-chain": "error",
"eslint/prefer-const": ["error", { "destructuring": "all" }],
"eslint/no-else-return": ["error", { "allowElseIf": false }],
"eslint/one-var": ["error", "never"],
"eslint/no-use-before-define": ["error", {
"functions": false,
"classes": false,
"variables": false
}],
"eslint/no-array-constructor": "error",
"eslint/no-case-declarations": "error",
"eslint/no-constructor-return": "error",
"eslint/no-inner-declarations": "error",
"eslint/no-prototype-builtins": "error",
"eslint/no-self-compare": "error",
"eslint/no-label-var": "error",
"eslint/no-labels": "error",
"eslint/no-extra-label": "error",
"eslint/no-lone-blocks": "error",
"eslint/no-proto": "error",
"eslint/no-regex-spaces": "error",
"eslint/no-script-url": "error",
"eslint/no-sequences": "error",
"eslint/default-case-last": "error",
"eslint/radix": "error",
"eslint/prefer-arrow-callback": "error",
"eslint/prefer-exponentiation-operator": "error",
"eslint/prefer-numeric-literals": "error",
"eslint/prefer-regex-literals": "error",
"eslint/prefer-rest-params": "error",
"oxc/no-const-enum": "error",
"unicorn/new-for-builtins": "error",
"unicorn/no-document-cookie": "error",
"unicorn/no-instanceof-array": "error",
"unicorn/no-useless-switch-case": "error",
"unicorn/prefer-array-index-of": "error",
"unicorn/prefer-date-now": "error",
"unicorn/prefer-node-protocol": "error",
"unicorn/prefer-number-properties": ["error", { "checkInfinity": true }],
"unicorn/require-post-message-target-origin": "off",
"eslint/no-console": "error",
"eslint/no-fallthrough": "error",
"eslint/no-redeclare": "error",
"eslint/prefer-template": "error",
"react/jsx-curly-brace-presence": "error",
"react/no-danger": "error",
"typescript/consistent-type-imports": "error",
"typescript/no-empty-interface": "error",
"typescript/no-inferrable-types": "error",
"typescript/no-invalid-void-type": "error",
"typescript/prefer-function-type": "error",

// ---- type-aware (tsgolint); these are pedantic so must be listed ----
"typescript/no-misused-promises": ["error", {
"checksVoidReturn": { "attributes": false }
}],
"typescript/only-throw-error": "error",
"typescript/require-await": "error",
"typescript/prefer-promise-reject-errors": "error",
"typescript/restrict-plus-operands": "error",
"typescript/return-await": ["error", "in-try-catch"],
"typescript/switch-exhaustiveness-check": ["error", {
"allowDefaultCaseForExhaustiveSwitch": true,
"considerDefaultExhaustiveForUnions": true
}],
"typescript/prefer-nullish-coalescing": ["error", {
"ignoreTernaryTests": true,
"ignorePrimitives": { "string": true }
}],
"typescript/no-deprecated": "warn",

// ---- type-aware deferred (noisy or structurally wrong here) ----
// bindings/ types are ts-rs-generated and assert more than the wire
// guarantees, so defensive runtime checks look "unnecessary".
"typescript/no-unnecessary-condition": "off",
"typescript/strict-boolean-expressions": "off",
"typescript/no-confusing-void-expression": "off",
"typescript/promise-function-async": "off",
"typescript/prefer-readonly-parameter-types": "off",
"typescript/strict-void-return": "off",

// no-unsafe-* is error only in vscode-extension/src (eslint parity there).
"typescript/no-unsafe-argument": "off",
"typescript/no-unsafe-assignment": "off",
"typescript/no-unsafe-call": "off",
"typescript/no-unsafe-member-access": "off",
"typescript/no-unsafe-return": "off",

// ---- react-perf: new class of finding, land as warn ----
"react-perf/jsx-no-new-object-as-prop": "warn",
"react-perf/jsx-no-new-array-as-prop": "warn",
"react-perf/jsx-no-new-function-as-prop": "warn",
"react-perf/jsx-no-jsx-as-prop": "warn"
},

"overrides": [
{
"files": ["ui/src/**/*.ts", "ui/src/**/*.tsx"],
"env": { "browser": true, "es2022": true }
},
{
"files": ["webcomponents/src/**/*.ts", "webcomponents/src/**/*.tsx"],
"env": { "browser": true, "es2022": true }
},
{
"files": ["webcomponents/src/**/*.test.ts", "webcomponents/src/**/*.test.tsx"],
"globals": { "Bun": "readonly" },
"rules": { "eslint/no-console": "off" }
},
{
"files": ["vscode-extension/src/**/*.ts"],
"env": { "node": true, "es2022": true },
"rules": {
// Parity with the recommendedTypeChecked config this replaces
"typescript/no-unsafe-argument": "error",
"typescript/no-unsafe-assignment": "error",
"typescript/no-unsafe-call": "error",
"typescript/no-unsafe-member-access": "error",
"typescript/no-unsafe-return": "error",
"typescript/no-require-imports": "error",
"typescript/no-namespace": "error"
}
},
{
"files": ["vscode-extension/test/**/*.ts"],
"env": { "node": true, "mocha": true, "es2022": true },
"rules": {
"eslint/no-console": "off",
"unicorn/consistent-function-scoping": "off",
"typescript/unbound-method": "off",
"typescript/no-misused-promises": "off"
}
},
{
"files": [
"webcomponents/scripts/**",
"vscode-extension/scripts/**",
"vscode-extension/src/webhook-server.ts",
"vscode-extension/src/walkthrough.ts"
],
"rules": { "eslint/no-console": "off" }
},
{
"files": [
"vscode-extension/webview-ui/**/*.ts",
"vscode-extension/webview-ui/**/*.tsx"
],
"env": { "browser": true, "es2022": true }
}
]
}
25 changes: 14 additions & 11 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@

## Code Style
Aim for functional software development with a focus on stateless, single responsibility focus.
ABSOLUTELY NO UNNECESSARY CODE COMMENTS WITHIN FUNCTIONS OR CONFIGURATION.
Minimize use of comments entirely; they should be terse and used judiciously, ideally one line tops.
Data types come from rust; typescript and docs binds are generated from low-level rust types annotated with comments that embed as descriptions into configuration and reference files.
Favor falsey defaults ; lets aim not to enforce `default=true` or some other javascript-truthy default value.

### Comments

Code comments are terse, short and punctual. Comments should not refer to implementation or current wip status.

## Plans & Specs Location

Write superpowers plans to `superpowers/plans/` and design specs to `superpowers/specs/` (repo root, not hosted).
Expand Down Expand Up @@ -59,6 +62,11 @@ make install-hooks # sets core.hooksPath=.githooks

If any of these fail, fix the issues before proceeding. Do NOT use `#[allow(...)]` attributes to silence warnings unless there's a documented reason (e.g., code used only in tests).

#### Strict Linting

Linting is strictly enforced; the rules are tighter than other software. Linting warnings are errors; address them as part of design.
Always running lint step when finished working in a directory. Fix all found linting problems before declaring work done.

### Subproject Validation

When changes touch subprojects, those must also pass validation:
Expand Down Expand Up @@ -124,7 +132,7 @@ Full command list: `docs/cli/` (auto-generated).

## Architecture

Grouped map of `src/` (not exhaustive `ls src/` for the full list):
Grouped map of `src/` (not exhaustive - `ls src/` for the full list):

```
src/
Expand Down Expand Up @@ -167,15 +175,15 @@ Execution mode is declared per issue type (`mode` in the issuetype schema):
- **Paired** (e.g. SPIKE, INV): require human interaction, track "awaiting input"

### Parallelism Rules
- Effective max agents = max(1, min(`agents.max_parallel`, cpu_cores `agents.cores_reserved`))
- Effective max agents = max(1, min(`agents.max_parallel`, cpu_cores - `agents.cores_reserved`))
- Same repo is sequential unless `git.use_worktrees = true`, which allows up to
`agents.max_agents_per_repo` agents in per-ticket worktrees
- Paired agents run one at a time per operator attention

## State Management

Persistent state lives under `paths.state` (default `.tickets/operator/`);
`state.json` holds queue/agent state schema documented at `/schemas/state/`.
`state.json` holds queue/agent state - schema documented at `/schemas/state/`.
Per-ticket worktrees default to `~/.operator/worktrees`.

## Ticket Workflow
Expand Down Expand Up @@ -300,10 +308,5 @@ When adding or changing UI: change a brand color in `tokens.css` (web surfaces
follow automatically); reference semantic tokens in new web CSS; map a role to
ANSI in the TUI; and leave the webview deferring to the editor theme.

**Icons.** Every SVG icon follows the Operator icon standard - a single
monochrome `<path>` on a 24×24 canvas with no `fill`/`stroke`/`width`/`height`,
so it tints from `currentColor` and sizes to its container on all four
surfaces. Governed directories: `icons/`, `docs/assets/icons/`,
`ui/public/icons/`, and each collection's `icon.svg`. Enforced by
`cargo test --test svg_icon_standard`; the rules and rationale are in
`docs/design-system/`.
**Icons.** Every SVG icon follows the Operator icon standard - a single monochrome `<path>` on a 24×24 canvas with no `fill`/`stroke`/`width`/`height`, so it tints from `currentColor` and sizes to its container on all four surfaces. Governed directories: `icons/`, `docs/assets/icons/`, `ui/public/icons/`, and each collection's `icon.svg`.
Enforced by `cargo test --test svg_icon_standard`; the rules and rationale are in `docs/design-system/`.
20 changes: 19 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,22 @@ flate2 = "1"
unsafe_code = "deny"

[lints.clippy]
all = { level = "warn", priority = -2 }
pedantic = { level = "warn", priority = -1 }

# Nursery lints for cohesion
cognitive_complexity = "warn"
redundant_clone = "warn"
redundant_clone = "deny"

# Clone and borrow discipline
clone_on_copy = "deny"
unnecessary_to_owned = "deny"
borrowed_box = "deny"
explicit_auto_deref = "deny"
borrow_deref_ref = "deny"
deref_addrof = "deny"
needless_borrow = "deny"
clone_on_ref_ptr = "warn"

# Allow noisy pedantic lints that don't add value here
module_name_repetitions = "allow"
Expand Down Expand Up @@ -181,6 +192,13 @@ needless_for_each = "allow"
needless_continue = "allow"
# Wildcard matches are intentional for future-proofing
match_wildcard_for_single_variants = "allow"
# Legacy style cleanup is outside ownership lint enforcement
redundant_else = "allow"
needless_raw_string_hashes = "allow"
doc_markdown = "allow"
uninlined_format_args = "allow"
single_match_else = "allow"
nonminimal_bool = "allow"

# Platform-specific notifications
[target.'cfg(target_os = "macos")'.dependencies]
Expand Down
Loading
Loading