agentsclimarketplace

Code formatter

Skill Lukk17/agent-standards/.agents/skills/code-formatter

Universal source-code formatting patterns the project owner expects, opinionated about visual hierarchy and reading flow rather than line length. Triggers on any new code, code review, or refactor across Dart, Java, Python, Kotlin, TypeScript, and Go. Apply these whenever you write or modify a function body so the next reader can locate control-flow exits and async phase transitions in one scan. Intentionally diverges from default auto-formatters (gofmt, dart format, black, google-java-format) in specific places; see each rule.From its SKILL.md

Install
npx -y skills add Lukk17/agent-standards --skill code-formatter

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

12.1 KB, ~2.9k tokens by cl100k_base, as published. Nobody here has run it

Code Formatter

The canonical engineering-principles hub is the coding-standards skill (SOLID, DRY, KISS, YAGNI, FIRST, naming, error handling, architecture, feature flags). This skill covers only visual formatting and reading flow; defer to the hub for the cross-cutting rules and to coding-standards for comment policy (near zero, explain why not what).


When to activate

  • Writing new source files in any language listed in the description.
  • Editing existing files: apply these rules when the file is already in this style; don't silently auto-format an unrelated file.
  • Reviewing a PR or a teammate's branch and flagging readability issues.

These rules are about visual hierarchy: how a reader's eyes find the landmarks of a function, not about line length or column alignment. Default tooling tends to optimise for line length and consistency; this skill optimises for "the next person reading this can locate the control-flow exits and async phase transitions in one scan."


Rules

Brace every inline if (x) return y; / if (x) throw z;

A control-flow exit should never share a line with its condition. The reader's eye should land on a return or throw as a line, not as the tail of an if. Multi-line, braced, body indented.

Java (wrong)

if (rows.isEmpty()) return null;

Java (right)

if (rows.isEmpty()) {
    return null;
}

Python (wrong)

if not rows: return None

Python (right)

if not rows:
    return None

Dart (wrong)

if (rows.isEmpty) return null;

Dart (right)

if (rows.isEmpty) {
  return null;
}

Empty lines around try / catch / finally

A try block is a control-flow landmark: it tells the reader "things can go wrong here." Give it room to breathe before and after so the eye treats it as a phase, not buried text. Same for each catch / finally clause's body.

Java

var logger = LoggerFactory.getLogger(getClass());

try {
    service.backup();

    logger.info("backup complete");
} catch (BackupException e) {
    logger.error("backup failed", e);
}

Python

logger = logging.getLogger(__name__)

try:
    service.backup()

    logger.info("backup complete")
except BackupError as e:
    logger.error("backup failed: %s", e)

Dart

final messenger = ScaffoldMessenger.of(context);

try {
  await service.backup();

  if (!mounted) {
    return;
  }

  messenger.showSnackBar(const SnackBar(content: Text('Backup created.')));
} on BackupException catch (e) {
  if (!mounted) {
    return;
  }

  messenger.showSnackBar(SnackBar(content: Text('Backup failed: $e')));
}

Empty line above significant standalone await / async I/O

When an async call marks a phase transition in a function (setup, then I/O, then cleanup), give it a blank line above. The reader's eye should register "now we hand off to the network/disk" as a distinct beat. This applies to standalone awaits, not awaits embedded in an assignment expression.

Java

state = state.toBuilder().running(true).build();

CompletableFuture<Void> shown = gateway.show(1001, "Rest over", "Time to lift");

logger.info("alarm fired");

Python

state.running = True

await gateway.show(id=1001, title="Rest over", body="Time to lift")

logger.info("alarm fired")

Dart

state = state.copyWith(running: true);

await _gateway.show(id: 1001, title: 'Rest over', body: 'Time to lift');

logFine('alarm fired', name: _tag);

Empty line above return when it ends a multi-statement block

When a function does several things and then returns, the return gets a blank line above so it reads as "and now hand back the result" rather than blending into the last statement. Doesn't apply to single-statement bodies, arrow functions, or one-line defs; the blank-line rules apply to blocks.

Java

public Optional<WorkLog> findFor(Exercise e, LocalDate date) {
    var list = dao.getForDate(date);

    for (var w : list) {
        if (w.exercise().name().equals(e.name())) {
            dao.merge(w);

            return Optional.of(w);
        }
    }

    return Optional.empty();
}

Python

async def add_work_log(exercise: Exercise, date: date) -> None:
    existing = await dao.get_for_date(date)

    for w in existing:
        if w.exercise.name == exercise.name:
            await dao.merge(w)

            return

    await dao.insert(WorkLog.create(exercise=exercise, on=date))

Dart

Future<void> _addWorkLog(Exercise e, DateTime date) async {
  final list = await _dao.getForDate(date);

  for (final w in list) {
    if (w.exercise.name == e.name) {
      await _dao.merge(w);

      return;
    }
  }

  await _dao.insert(WorkLog.create(exercise: e, on: date));
}

Blank line below return inside a try that has catch / finally

When a try block ends with return X; and is followed by a catch or finally clause, leave a blank line between the return and the closing } of the try. The blank line marks the hand-off from the happy-path body to the failure / cleanup clauses, so the reader's eye can see the seam.

Java (wrong)

try {
    String xml = xmlGenerationService.generateXml(documents);

    log.info("audit xml.generation success documentType={} bytes={}",
            documentType, subject, xml.length());

    return xml;
} catch (XmlMappingException ex) {
    ...
} finally {
    ...
}

Java (right)

try {
    String xml = xmlGenerationService.generateXml(documents);

    log.info("audit xml.generation success documentType={} bytes={}",
            documentType, subject, xml.length());

    return xml;

} catch (XmlMappingException ex) {
    ...
} finally {
    ...
}

The same rule applies to a throw that ends a try body when a catch / finally follows it.

Empty line above operation-terminating calls

Calls that end a phase get a blank line above. The eye should see "the act" separated from the local-var arithmetic that prepared for it. Examples of operation-terminators in each language:

  • Java: dialog.dismiss(), httpClient.send(...), logger.info("phase done", ...), eventBus.publish(...)
  • Python: dialog.dismiss(), requests.post(...), logger.info("phase done"), sys.exit(0)
  • Dart / Flutter: Navigator.pop(context), messenger.showSnackBar(...), state = state.copyWith(...), _ticker?.cancel(), logFine('phase done')

Java

var normalized = startOfDay(day);
state.setSelectedDate(normalized);
logger.info("Chosen date: {}", normalized);

dialog.dismiss();

Python

normalized = start_of_day(day)
state.selected_date = normalized
logger.info("Chosen date: %s", normalized)

dialog.dismiss()

Dart

final normalized = _startOfDay(day);
ref.read(selectedDateProvider.notifier).state = normalized;
logFine('Chosen date: $normalized', name: _tag);

Navigator.of(context).pop();

Comments above the line they describe, never trailing

Trailing comments get truncated by long lines and force horizontal scrolling. A comment is a sentence about the next thing the reader is about to see; write it on its own line, above.

Java (wrong)

var delay = computeBackoff(retryCount); // exponential, max 30s

Java (right)

// Exponential backoff, capped at 30s to avoid hammering the server.
var delay = computeBackoff(retryCount);

Python (wrong)

delay = compute_backoff(retry_count)  # exponential, max 30s

Python (right)

# Exponential backoff, capped at 30s to avoid hammering the server.
delay = compute_backoff(retry_count)

Dart (wrong)

final delay = computeBackoff(retryCount); // exponential, max 30s

Dart (right)

// Exponential backoff, capped at 30s to avoid hammering the server.
final delay = computeBackoff(retryCount);

Exception: throwaway tag comments tied to an issue tracker (e.g. // TODO(ABC-123): drop after Q3) sometimes trail by team convention. Even then, prefer the comment above when there's room.

One concept per blank-line-separated paragraph

Inside a function body, related lines stick together with no blank between them; a topic transition gets one blank. Two blank lines anywhere inside a function body is a smell; extract a method.

Java

public void save() {
    var navigator = activity.getNavigator();
    var selectedDate = repository.getSelectedDate();

    var updated = original.toBuilder()
        .name(nameField.getText())
        .bodyParts(form.getPrimary())
        .build();
    dao.replace(updated);

    if (isDestroyed()) {
        return;
    }

    eventBus.publish(new ExercisesInvalidated());

    navigator.pop();
}

Python

async def save() -> None:
    navigator = activity.navigator
    selected_date = repository.selected_date

    updated = replace(
        original,
        name=name_field.text,
        body_parts=form.primary,
    )
    await dao.replace(updated)

    if is_destroyed():
        return

    event_bus.publish(ExercisesInvalidated())

    navigator.pop()

Dart

Future<void> save() async {
  final navigator = Navigator.of(context);
  final selectedDate = ref.read(selectedDateProvider);

  final updated = widget.exercise!.copyWith(
    name: _nameController.text,
    bodyParts: form.primary,
  );
  await _dao.replace(updated);

  if (!mounted) {
    return;
  }

  ref.invalidate(exercisesProvider);

  navigator.pop();
}

Each paragraph reads as a phase: capture context, build and persist, mounted-guard, invalidate dependents, exit.

Method chains: line-break before each .

Fluent / functional pipelines (filter, map, reduce, take, toList, collect) read top-down, one transformation per line. Easier to diff, easier to insert or remove a step.

Java

var activeNames = exercises.stream()
    .filter(Exercise::isActive)
    .map(Exercise::name)
    .toList();

Python

Python's idiomatic equivalent is a comprehension; reach for that first. When you do chain (e.g. with a pipe helper or pandas), keep one step per line:

active_names = [e.name for e in exercises if e.is_active]

active_names = (pipe(exercises)
    .filter(lambda e: e.is_active)
    .map(lambda e: e.name)
    .to_list()
)

Dart

final activeNames = exercises
    .where((e) => e.isActive)
    .map((e) => e.name)
    .toList();

The prefer chains over loops part is a coding-standards rule, not a formatter one. The formatter point here is: when you do chain, one step per line.

Single-expression bodies stay on one line

The blank-line rules apply to blocks, not arrow functions or one-line defs. Don't expand a pure transformation into a multi-line body just to satisfy a "blank line above return" rule that doesn't apply.

Java

Function<Integer, Integer> doubled = x -> x * 2;
record Exercise(String id, String name) {
    boolean isActive() { return !name.isBlank(); }
}

Python

def doubled(x: int) -> int:
    return x * 2

sorted(items, key=lambda i: i.priority)

Dart

int doubled(int x) => x * 2;
DateTime startOfDay(DateTime d) => DateTime(d.year, d.month, d.day);

What this skill does not cover

  • Naming conventions, class-member ordering, import ordering: those vary per language. See language-specific style guides (PEP 8, Google Java Style, Effective Dart) and the coding-standards skill.
  • Line length caps: kept readable by extracting locals rather than wrapping. Each project sets its own column budget.
  • Trailing commas, brace placement, indent width: handled by the default formatter for each language; this skill doesn't override those.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,835. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.