diff --git a/.agents/project.md b/.agents/project.md new file mode 100644 index 00000000..8d7d863b --- /dev/null +++ b/.agents/project.md @@ -0,0 +1,141 @@ +# Project + +This document gives agents and contributors the Chords project overview, module +map, architecture notes, documentation ownership, and CI notes. For agent +operating policy, read [`AGENTS.md`](../AGENTS.md). + +## Overview + +**Chords** is a suite of open-source Kotlin/JVM libraries for desktop UI +development with the Compose Multiplatform toolkit. The libraries introduce a +class-based component model on top of Compose, domain-specific input components +that operate on Protobuf messages, and server connectivity based on the Spine +Event Engine framework. The libraries are currently at an experimental stage. + +The main concerns are: + +- A class-based UI component model and application shell on top of Compose + (`core`). +- Input components, message forms, and validation for Protobuf-based domain + models (`proto`). +- Supplementary Protobuf messages and Kotlin extensions (`proto-values`). +- Server connectivity, command posting, and entity subscriptions via Spine + Event Engine (`client`). +- Code generation that enriches Protobuf message APIs with `MessageField`, + `MessageOneof`, and `MessageDef` implementations (`codegen/*`). + +Artifacts are published as `io.spine.chords:spine-chords-` to the Spine +snapshots repository (`https://europe-maven.pkg.dev/spine-event-engine/snapshots`) +and GitHub Packages. + +## Project Map + +- `settings.gradle.kts`: root Gradle module registry (`core`, `runtime`, + `proto-values`, `proto`, `client`, `codegen-tests`). +- `build.gradle.kts`: root Gradle configuration for group/version, the Chords + codegen Gradle plugin wiring, publishing, license reports, and Jacoco. +- `version.gradle.kts`: the single `chordsVersion` for all Chords libraries; + must be incremented in every PR. +- `buildSrc/`: dependency coordinates, repository helpers, and shared Gradle + convention plugins for the root project. +- `quality/detekt-config.yml`: Detekt rules for the repository. +- `config/`: Git submodule shared across Spine repositories with build scripts + and CI helpers; owned by `SpineEventEngine/config`, do not edit here. +- `core/`: application shell, class-based `Component` model, input component + base classes, layouts, and primitive UI components. +- `proto/`: Protobuf-aware UI components — `MessageForm`, field editors, oneof + support, and validation display for Protobuf domain models. +- `proto-values/`: supplementary Protobuf message declarations (e.g., money + types) with Kotlin extensions; uses Chords code generation. +- `client/`: server connectivity components — application shell client + extensions, command posting, entity subscriptions, and entity-backed + components such as `EntityChooser`. +- `codegen/runtime/` (Gradle path `:runtime`): the runtime library required by + `proto` and `client` to use generated `MessageField`/`MessageOneof`/ + `MessageDef` implementations. +- `codegen/tests/` (Gradle path `:codegen-tests`): tests that check the + correctness of code generation; uses Chords code generation. +- `codegen/plugins/`: **separate Gradle project** with ProtoData plugins that + generate Kotlin extensions for Protobuf messages. Requires JDK 17, + Gradle 9.4.x, and Kotlin 2.3.20, unlike the root project (JDK 11, + Gradle 6.9.4, Kotlin 1.8.20). Applied to consuming projects through the + [Chords Gradle plugin](https://github.com/SpineEventEngine/Chords-Gradle-plugin). +- `pom.xml`, `dependencies.md`: generated dependency/license reports; must be + regenerated (not hand-edited) when the version or dependencies change. +- `.github/workflows/`: CI for Ubuntu/Windows builds, license-report and + version-increment guards, Gradle wrapper validation, and publishing. + +Gradle group: `io.spine.chords`. Artifact prefix: `spine-chords-`. Preserve +package roots such as `io.spine.chords` and `io.spine.money` where already +present. + +## Architecture Notes + +The `core` module defines the class-based component model. Components extend +`io.spine.chords.core.Component` (or `InputComponent` for value-editing +components), render in `content()`, and perform pre-composition state updates +in `beforeComposeContent()`. Components are configured declaratively with +`Props`-style configuration lambdas and are instantiated per usage site via +companion-object `invoke` operators. State that must trigger recomposition is +held in `mutableStateOf`-backed properties. + +The `proto` module builds `MessageForm` and related editors on top of `core`, +using generated `MessageField`/`MessageOneof`/`MessageDef` metadata from the +codegen runtime to bind form fields to Protobuf message fields with validation. + +The `client` module connects components to a Spine Event Engine server through +the application shell's `app.client` API (reading, observing, and posting +commands). Components such as `EntityChooser` read and observe entity states. + +Code generation flow: the `codegen/plugins` project builds ProtoData plugins; +the root build's `publishCodegenPluginsToMavenLocal` task publishes them to +Maven local; the `io.spine.chords` Gradle plugin then applies them to the +modules listed in `modulesWithChordsCodegen` (`proto-values`, `codegen-tests`) +inside a generated codegen workspace. This chain is wired automatically into +the root build; touching it usually means `build.gradle.kts` or +`buildSrc` work. + +The versions of the toolchain are intentionally conservative to match consumer +projects (Spine 1.9.x ecosystem). Do not casually bump Kotlin, Compose, Gradle, +or Spine versions; such upgrades are dedicated tasks with wide impact. + +## Documentation Ownership + +- `README.md`: project entry point — library list, supported environment, + consumption instructions, and development setup. +- `AGENTS.md`: repository operating policy for agents. +- `.agents/project.md`: project map, architecture notes, documentation + ownership, and CI notes. +- `core/README.md`: application shell, component model, and core components. +- `proto/README.md`: Protobuf-aware components and message forms. +- `proto-values/README.md`: supplementary Protobuf messages and extensions. +- `client/README.md`: server connectivity facilities. +- `codegen/runtime/README.md`: codegen runtime ownership. +- `codegen/plugins/README.md`: ProtoData plugin project — requirements, + workspace resources, and module layout. +- `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`: standard contribution policy. + +Keep usage instructions in the nearest library README. Keep architecture, +module ownership, and CI notes in this file. Keep agent policy in `AGENTS.md`. +API-level documentation belongs in KDoc on the public declarations. + +## CI + +This repository is configured with these GitHub workflows: + +- `Build under Ubuntu` (`.github/workflows/build-on-ubuntu.yml`): runs on every + push, sets up JDK 11, and runs `./gradlew build --stacktrace`. +- `Build under Windows` (`.github/workflows/build-on-windows.yml`): runs on + pull requests and builds with `gradlew.bat build --stacktrace --no-daemon`. +- `Ensure license reports updated` (`.github/workflows/ensure-reports-updated.yml`): + runs on pull requests and fails when `dependencies.md` / `pom.xml` (or + `version.gradle.kts`) were not updated in the changeset. +- `Check version increment` (`.github/workflows/increment-guard.yml`): runs + `./gradlew checkVersionIncrement` to enforce that `chordsVersion` grows. +- `Validate Gradle Wrapper` (`.github/workflows/gradle-wrapper-validation.yml`): + validates wrapper JAR integrity. +- `Publish` (`.github/workflows/publish.yml`): runs on pushes to `master`, + decrypts publishing credentials from `.github/keys/*.gpg`, and publishes + artifacts to the configured Maven repositories. + +Publishing credentials and their rotation are human-owned. diff --git a/.agents/skills/README.md b/.agents/skills/README.md new file mode 100644 index 00000000..7d8645bd --- /dev/null +++ b/.agents/skills/README.md @@ -0,0 +1,51 @@ +# Skills + +This index is a quick orientation aid. Each skill's frontmatter remains the +routing source of truth. + +- `engineer`: routing skill for mixed or unclear implementation work. +- `component-engineer`: class-based Compose UI components across `core`, + `proto`, and `client` — the component model, input components, message + forms, and server-connected components. +- `codegen-engineer`: ProtoData codegen plugins, the codegen runtime, + generated `MessageField`/`MessageOneof`/`MessageDef` contracts, and + Protobuf declarations in `proto-values`. +- `build-engineer`: root and `codegen/plugins` Gradle builds, `buildSrc` + dependency coordinates, publishing wiring, version policy, and generated + report regeneration. +- `security-reviewer`: publishing credentials, GitHub Actions secrets, + dependency provenance, agent prompt/configuration safety, and accidental + secret exposure review. +- `ci-engineer`: GitHub Actions workflow authoring and review for build, + guard, validation, and publishing pipelines. +- `code-reviewer`: implementation review for component, codegen, and build + changes. +- `tester`: test authoring and verification strategy for all modules, + including codegen correctness tests. +- `docs-writer`: documentation authoring, editing, restructuring, and claim + checks. +- `docs-reviewer`: documentation review for prose, examples, and comments. + +## Skill Directory Layout + +Each skill lives in its own directory: + +``` +.agents/skills// + SKILL.md — frontmatter (name, description) + policy body + agents/openai.yaml — UI metadata for the OpenAI-based agent interface +``` + +`openai.yaml` fields: +- `display_name`: label shown in the UI +- `short_description`: hint shown in the UI +- `default_prompt`: starter prompt shown by the interface when the skill is invoked + +The `name` in `SKILL.md` frontmatter must match the directory name. + +## Invocation + +Skills are invoked via `$` in supported agent interfaces (for +example, `$component-engineer`). Supported runtimes read the corresponding +`SKILL.md` as the skill's durable instructions; `openai.yaml` carries only UI +metadata, not policy. diff --git a/.agents/skills/build-engineer/SKILL.md b/.agents/skills/build-engineer/SKILL.md new file mode 100644 index 00000000..bfbb288a --- /dev/null +++ b/.agents/skills/build-engineer/SKILL.md @@ -0,0 +1,79 @@ +--- +name: build-engineer +description: > + Chords build and release-engineering policy. Use for root and codegen/plugins + Gradle build logic, buildSrc dependency coordinates, publishing wiring, + version increments, generated `pom.xml`/`dependencies.md` reports, and the + config submodule relationship. +--- + +# Build Engineering + +## When to Use + +Use this skill for build, dependency, and release-plumbing work: + +- Root `build.gradle.kts`, `settings.gradle.kts`, `version.gradle.kts`, and + `gradle.properties`. +- `buildSrc/` dependency coordinates, repository helpers, and convention + plugins (`jvm-module`, publishing, reports). +- The `codegen/plugins` Gradle project's own build logic and its + `codegen-workspace` resource packaging. +- Publishing configuration: `spinePublishing`, artifact prefix, destination + repositories, and the `publishCodegenPlugins*` tasks. +- Version policy and the generated `pom.xml` / `dependencies.md` reports. +- Detekt configuration under `quality/`. + +For workflow YAML under `.github/workflows`, use +`.agents/skills/ci-engineer/SKILL.md`. + +## Policy + +- Two toolchains coexist: the root project uses JDK 11 / Gradle 6.9.4 / + Kotlin 1.8.20; `codegen/plugins` uses JDK 17 / Gradle 9.4.x / Kotlin 2.3.20. + Keep build logic compatible with the owning toolchain. +- Dependency coordinates belong in + `buildSrc/src/main/kotlin/io/spine/internal/dependency/`, one object per + library, following the existing pattern. Do not inline version strings into + module build files. +- Do not auto-update external dependencies or toolchain versions outside + dedicated upgrade tasks; the pins match the Spine 1.9.x consumer ecosystem. +- Every PR increments `chordsVersion` in `version.gradle.kts` + (`2.0.0-SNAPSHOT.`); CI enforces this with `checkVersionIncrement`. +- `pom.xml` and `dependencies.md` are generated by the build (PomGenerator and + LicenseReporter); regenerate them via `./gradlew build` rather than editing, + and include the regenerated files in version-bump changesets. +- The `config/` submodule is owned by `SpineEventEngine/config`; do not edit + its contents here. If shared build logic must change, describe the upstream + change instead. +- Do not run `publish` or `publishCodegenPlugins` against remote repositories; + publishing is CI-owned (pushes to `master`). Local verification uses + `publishToMavenLocal`. +- Preserve the codegen wiring contract: `modulesWithChordsCodegen` lists the + modules that get the `io.spine.chords` Gradle plugin, and + `createCodegenWorkspace` depends on `publishCodegenPluginsToMavenLocal`. +- Keep the Gradle plugin version (`io.spine.chords` in `build.gradle.kts` and + `Spine.kt` in `buildSrc`) consistent in both places when bumping it. + +## Verification + +Root build (repository root, JDK 11): + +```bash +./gradlew clean build +./gradlew publishToMavenLocal +./gradlew checkVersionIncrement +``` + +Codegen plugins build (from `codegen/plugins/`, JDK 17): + +```bash +./gradlew build +./gradlew publishToMavenLocal +``` + +Run the `publishToMavenLocal` variant when plugin publication is part of the +change, so root modules consume the rebuilt plugins. + +After version or dependency changes, confirm `pom.xml` and `dependencies.md` +were regenerated and reflect the new version. diff --git a/.agents/skills/build-engineer/agents/openai.yaml b/.agents/skills/build-engineer/agents/openai.yaml new file mode 100644 index 00000000..3462c4cb --- /dev/null +++ b/.agents/skills/build-engineer/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Build Engineer" + short_description: "Implement Chords Gradle, publishing, or version changes" + default_prompt: > + Use $build-engineer after reading AGENTS.md, README.md, and + .agents/project.md to implement a scoped Chords build or + release-plumbing change. diff --git a/.agents/skills/ci-engineer/SKILL.md b/.agents/skills/ci-engineer/SKILL.md new file mode 100644 index 00000000..e4178680 --- /dev/null +++ b/.agents/skills/ci-engineer/SKILL.md @@ -0,0 +1,66 @@ +--- +name: ci-engineer +description: > + Chords CI/CD workflow guidance. Use for authoring or reviewing GitHub Actions + workflows under `.github/workflows`: Ubuntu/Windows builds, license-report + and version-increment guards, Gradle wrapper validation, and artifact + publishing. +--- + +# CI Engineering + +Use this skill for GitHub Actions workflow work under `.github/workflows/`. +Publishing to Maven repositories happens automatically on `master`, but changes +to the publishing pipeline and its credentials remain human-reviewed; this +skill authors and reviews workflow definitions, it does not trigger them. + +## Scope + +- `.github/workflows/build-on-ubuntu.yml`: JDK 11 build on every push. +- `.github/workflows/build-on-windows.yml`: Windows build on pull requests. +- `.github/workflows/ensure-reports-updated.yml`: guard that `dependencies.md` + / `pom.xml` (or `version.gradle.kts`) changed in the PR, via + `config/scripts/ensure-reports-updated.sh`. +- `.github/workflows/increment-guard.yml`: the `checkVersionIncrement` guard. +- `.github/workflows/gradle-wrapper-validation.yml`: wrapper JAR integrity. +- `.github/workflows/publish.yml`: publishing from `master`, including GPG + decryption of credentials from `.github/keys/`. +- Workflow triggers, branch filters, job/step wiring, JDK setup, caching, + working directories, and secret references by name. + +For secret handling and supply-chain safety, also use +`.agents/skills/security-reviewer/SKILL.md`. For the Gradle tasks the +workflows invoke, use `.agents/skills/build-engineer/SKILL.md`. + +## Rules + +- Do not weaken the guards that gate merges: the version-increment check, the + license-report check, wrapper validation, and the build steps. +- Preserve existing triggers, branch filters, JDK versions, and working + directories unless the task explicitly asks to change them. Note that the + repository checkout must initialize the `config` submodule where scripts + from it are used. +- Reference secrets by name through `secrets.*`. Never inline secret values, + tokens, or credentials into a workflow. +- Do not add steps that publish artifacts or rotate credentials as routine + changes. Describe the required human action instead. +- Keep in mind the two-toolchain layout: root builds need JDK 11; any step + building `codegen/plugins` directly needs JDK 17 and runs from + `codegen/plugins/`. + +## Verification + +Workflows run in GitHub Actions, not locally. Verify changes by static review: + +- Confirm referenced Gradle tasks, module paths, scripts, and working + directories exist and match the owning `build.gradle.kts`, `config/scripts`, + and README files. +- Confirm secret names, environment variables, branch filters, and job + dependencies match the intended trigger and the rest of the pipeline. +- Confirm that jobs using scripts from the `config/` submodule configure + `actions/checkout` with submodule initialization. +- Validate YAML structure and the versions of referenced actions. + +State clearly in the final response that full validation happens in CI. + +Follow the git-history and safety policy in `AGENTS.md`. diff --git a/.agents/skills/ci-engineer/agents/openai.yaml b/.agents/skills/ci-engineer/agents/openai.yaml new file mode 100644 index 00000000..aa2e3ea5 --- /dev/null +++ b/.agents/skills/ci-engineer/agents/openai.yaml @@ -0,0 +1,6 @@ +interface: + display_name: "CI Engineer" + short_description: "Author or review Chords GitHub Actions workflows" + default_prompt: > + Use $ci-engineer after reading AGENTS.md and .agents/project.md to author + or review a scoped change to the GitHub Actions workflows of Chords. diff --git a/.agents/skills/code-reviewer/SKILL.md b/.agents/skills/code-reviewer/SKILL.md new file mode 100644 index 00000000..c2eef509 --- /dev/null +++ b/.agents/skills/code-reviewer/SKILL.md @@ -0,0 +1,91 @@ +--- +name: code-reviewer +description: > + Reviews Chords implementation changes for correctness, regressions, public + API breaks, missing tests, and cross-module contract breaks. Use to review + component, codegen, or build diffs. Read-only unless explicitly asked to run + checks. +--- + +# Code Review + +You are the implementation reviewer for Chords. Focus on correctness and +contract risk in changed code. Include any security risks you find in the +review output. Do not duplicate `docs-reviewer` for documentation prose or +`tester` for test design; hand those findings off instead. + +## Review Procedure + +1. **Scope the diff.** Review changed source files and their direct callers or + contracts. Do not review the full repository unless asked. +2. **Read each affected file fully.** Component lifecycle, recomposition + behavior, and contract impact require context beyond the diff hunk. +3. **Trace the owning flow.** For component changes, follow the + `Component`/`InputComponent` lifecycle (`beforeComposeContent`, `content`, + `Props` configuration) and the state properties involved. For codegen + changes, follow the generator, the runtime contract, and `codegen/tests` + together. +4. **Verify claims against source.** Confirm Gradle task names, module paths, + generated API shapes, and toolchain constraints against the relevant build + file, README, or workflow. + +## Review Focus + +- Correctness bugs and behavioral regressions in changed logic, including + Compose-specific issues: state not backed by `mutableStateOf`, reads outside + composition scope, or side effects in `@ReadOnlyComposable` code. +- Public API breaks: changed signatures, visibility, or semantics of `public` + and `protected` declarations in published modules — external projects and + component subclasses consume them. Kotlin explicit API mode applies. +- Cross-module contract breaks: `core`/`proto`/`client` layering, the + generated `MessageField`/`MessageOneof`/`MessageDef` contract between + `codegen/plugins` and `codegen/runtime`, and Protobuf compatibility in + `proto-values`. +- Toolchain violations: language or library features newer than Kotlin 1.8.20 + / Compose 1.5.12 in root modules (or mixing the `codegen/plugins` toolchain + into root code). +- Missing or weak tests for changed logic, extensions, or codegen behavior. +- Version-policy misses: `chordsVersion` not incremented, or `pom.xml` / + `dependencies.md` not regenerated when required. +- Module-ownership violations, leaked state, unjustified reflection, and + hidden background work. + +## Handoffs + +- Include credential, secret, workflow-security, or agent prompt/configuration + security findings in the review output. Also use + `.agents/skills/security-reviewer/SKILL.md` when the task needs deeper + security-specific analysis. +- Documentation and comment findings go to + `.agents/skills/docs-reviewer/SKILL.md`. +- Test design or coverage authoring goes to `.agents/skills/tester/SKILL.md`. + +## Skip + +Skip routine review of generated or vendored files: + +- `gradlew`, `gradlew.bat`, `gradle/wrapper/**` (root and `codegen/plugins`) +- generated `pom.xml` and `dependencies.md` reports +- generated Protobuf/codegen outputs (`generated/`, `_out/`) +- the `config/` submodule +- IDE metadata such as `.idea/**` + +Do not skip `buildSrc/**` or `codegen/plugins/buildSrc/**`; they own dependency +and Gradle configuration for Chords. + +## Output Format + +Return three sections, in this order: + +- **Must fix** - correctness bugs, contract breaks, or regressions that cause + incorrect behavior, a test failure, or a broken build. +- **Should fix** - missing tests, public API risks, module-ownership + violations, or changes that are technically correct but likely to mislead or + regress. +- **Nits** - style, naming, minor structure, or handoff notes for another skill. + +For each finding, cite the file and line, quote the relevant text, explain the +impact, and show the recommended fix. If a section is empty, write `None.` + +End with a one-line verdict: `APPROVE`, `APPROVE WITH CHANGES`, or +`REQUEST CHANGES`. diff --git a/.agents/skills/code-reviewer/agents/openai.yaml b/.agents/skills/code-reviewer/agents/openai.yaml new file mode 100644 index 00000000..4b775ac4 --- /dev/null +++ b/.agents/skills/code-reviewer/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Code Reviewer" + short_description: "Review Chords component, codegen, or build changes" + default_prompt: > + Use $code-reviewer after reading AGENTS.md, README.md, .agents/project.md, + and the nearest README for the area being changed to review a scoped + Chords implementation change. diff --git a/.agents/skills/codegen-engineer/SKILL.md b/.agents/skills/codegen-engineer/SKILL.md new file mode 100644 index 00000000..0d0269a6 --- /dev/null +++ b/.agents/skills/codegen-engineer/SKILL.md @@ -0,0 +1,73 @@ +--- +name: codegen-engineer +description: > + Chords code generation policy. Use for the ProtoData codegen plugins project, + the codegen runtime library, generated MessageField/MessageOneof/MessageDef + contracts, codegen correctness tests, and Protobuf declarations with Kotlin + extensions in proto-values. +--- + +# Codegen Engineering + +## When to Use + +Use this skill for code generation and Protobuf model work: + +- ProtoData plugins under `codegen/plugins/` (a separate Gradle project). +- The codegen runtime under `codegen/runtime/` (Gradle path `:runtime`): + `MessageField`, `MessageOneof`, `MessageDef`, and related runtime types. +- Codegen correctness tests under `codegen/tests/` (Gradle path + `:codegen-tests`). +- Protobuf declarations and Kotlin extensions in `proto-values`. +- The codegen wiring in the root build (`modulesWithChordsCodegen`, + `publishCodegenPluginsToMavenLocal`, the `io.spine.chords` Gradle plugin + configuration). + +For components that merely consume generated metadata, prefer +`.agents/skills/component-engineer/SKILL.md`. For build-only concerns, use +`.agents/skills/build-engineer/SKILL.md`. + +## Policy + +- `codegen/plugins` targets JDK 17, Gradle 9.4.x, and Kotlin 2.3.20; the rest + of the repository targets JDK 11, Gradle 6.9.4, and Kotlin 1.8.20. Never mix + the two toolchains in one command or assume APIs from one are available in + the other. +- The generated-code contract is consumed by `proto` and `client` and by + external projects: changes to `MessageField`/`MessageOneof`/`MessageDef` + shapes are public API changes on both the generator and runtime sides and + must stay in sync. +- For Protobuf schema changes in `proto-values`: never delete or renumber + existing fields, reserve retired field numbers and names, and keep package + names consistent with the existing `spine/chords/proto/value/**` structure + under `proto-values/src/main/proto/`. +- Keep `codegen/plugins/src/main/resources/codegen-workspace` resources + consistent with the build logic that copies `buildSrc` and wrapper files + into them; that workspace is what the Chords Gradle plugin unpacks in + consumer projects. +- Do not manually edit generated outputs (`generated/`, `_out/`); change the + generator and regenerate instead. +- Cover generator behavior changes with tests in `codegen/tests`, which + exercise generation end-to-end against test Protobuf definitions. + +## Verification + +Codegen plugin changes (from `codegen/plugins/`, JDK 17): + +```bash +./gradlew build +./gradlew publishToMavenLocal +``` + +Runtime and end-to-end verification (from the repository root, JDK 11): + +```bash +./gradlew :runtime:test +./gradlew :codegen-tests:test +./gradlew :proto-values:test +./gradlew clean build +``` + +The root build republishes codegen plugins to Maven local automatically before +generating; a stale local plugin usually means the `codegen/plugins` build was +not rerun. diff --git a/.agents/skills/codegen-engineer/agents/openai.yaml b/.agents/skills/codegen-engineer/agents/openai.yaml new file mode 100644 index 00000000..6e44448f --- /dev/null +++ b/.agents/skills/codegen-engineer/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Codegen Engineer" + short_description: "Implement Chords code generation or Protobuf model changes" + default_prompt: > + Use $codegen-engineer after reading AGENTS.md, README.md, + .agents/project.md, and codegen/plugins/README.md to implement a scoped + Chords code generation change. diff --git a/.agents/skills/component-engineer/SKILL.md b/.agents/skills/component-engineer/SKILL.md new file mode 100644 index 00000000..395b8ad8 --- /dev/null +++ b/.agents/skills/component-engineer/SKILL.md @@ -0,0 +1,83 @@ +--- +name: component-engineer +description: > + Chords UI component implementation policy. Use for the class-based component + model, application shell, input components, layouts, message forms, + validation display, dropdown/table/entity components, and server-connected + components across the core, proto, and client modules. +--- + +# Component Engineering + +## When to Use + +Use this skill for UI component and component-infrastructure work: + +- The `Component`/`InputComponent` class hierarchy, component lifecycle, and + `Props`-style configuration in `core`. +- The application shell (`appshell`), views, and navigation support in `core`. +- Basic components: dropdowns, selectors, layouts, dialogs, tables, and + wizards in `core`. +- Protobuf-aware components in `proto`: `MessageForm`, field editors, oneof + support, and validation message display. +- Server-connected components in `client`: command posting, entity + subscriptions, and entity-backed components such as `EntityChooser`. + +For generated `MessageField`/`MessageOneof`/`MessageDef` contracts or Protobuf +declarations, prefer `.agents/skills/codegen-engineer/SKILL.md`. For Gradle +build logic, use `.agents/skills/build-engineer/SKILL.md`. + +## Policy + +- Follow the class-based component pattern: rendering in `content()`, + pre-composition state updates in `beforeComposeContent()`, configuration via + companion-object `invoke` operators with `Props`-style lambdas. +- Name composable functions and composable-emitting methods in `PascalCase`. +- Hold state that must trigger recomposition in `mutableStateOf`-backed + properties (`by mutableStateOf(...)` with `getValue`/`setValue` imports). +- Respect module layering: `core` must not depend on `proto` or `client`; + `proto` must not depend on `client`. Put behavior in the lowest module that + owns it. +- All libraries use Kotlin explicit API mode: public declarations need + explicit `public` modifiers and public API needs KDoc. +- Avoid breaking public API: signatures, property names, and visibility of + published declarations are contracts for external consumers. Prefer additive + changes; when a member is `protected`, it is part of the API for component + subclasses. +- Target the pinned toolchain: Kotlin 1.8.20 and Compose Multiplatform 1.5.12. + Do not use newer language features or Compose APIs. Some Compose APIs in use + are experimental (`@OptIn(ExperimentalComposeUiApi::class)`); keep such + opt-ins localized and documented. +- Match existing KDoc style: `@param` tags for type parameters and + constructor-like parameters, backticked identifiers, and wrapped lines + within 100 characters. +- When changing a public component, check the KDoc examples of the changed + class and its neighbors: examples are not compiled or covered by tests and + go stale silently. +- Keep the copyright header year current in modified files. + +## Hotspots + +- Component lifecycle: trace `Component`, `InputComponent`, and the concrete + component's `beforeComposeContent`/`content` overrides together when + changing state or recomposition behavior. +- Message forms: trace `MessageForm`, field/oneof registration, validation + state, and the codegen runtime metadata (`MessageField`, `MessageOneof`) + together. +- Entity components: trace `app.client` read/observe calls, entity-to-ID + mapping, and selection state together (e.g., `EntityChooser`, + `DropdownSelector`). + +## Verification + +Run the narrowest relevant command first (repository root, JDK 11): + +```bash +./gradlew ::test +./gradlew ::check +./gradlew clean build +``` + +UI rendering and interaction cannot be covered by automated tests here. For +visual or interactive changes, verify compilation and existing tests, then +state clearly in the final response what manual verification remains. diff --git a/.agents/skills/component-engineer/agents/openai.yaml b/.agents/skills/component-engineer/agents/openai.yaml new file mode 100644 index 00000000..b37eb447 --- /dev/null +++ b/.agents/skills/component-engineer/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Component Engineer" + short_description: "Implement Chords UI component changes" + default_prompt: > + Use $component-engineer after reading AGENTS.md, README.md, + .agents/project.md, and the nearest README for the area being changed to + implement a scoped Chords component change. diff --git a/.agents/skills/docs-reviewer/SKILL.md b/.agents/skills/docs-reviewer/SKILL.md new file mode 100644 index 00000000..d6163a8e --- /dev/null +++ b/.agents/skills/docs-reviewer/SKILL.md @@ -0,0 +1,105 @@ +--- +name: docs-reviewer +description: > + Reviews Chords documentation changes: KDoc comments, README.md files, + .agents/project.md, AGENTS.md, skills, command examples, and architecture + or module maps. Read-only unless explicitly asked to run checks. +--- + +# Review Documentation + +You are the documentation reviewer for Chords. Focus strictly on documentation +quality: comments, Markdown, examples, and repository guidance. Do not +duplicate `docs-writer` for authoring strategy, the engineering skills for +implementation correctness, or `tester` for test design. + +## Review Procedure + +1. **Scope the diff.** Review changed documentation files and changed comments + inside source files. Do not review the full repository unless asked. +2. **Read each affected file fully.** Prose quality, heading hierarchy, + command accuracy, and identifier references require context beyond the diff + hunk. +3. **Verify claims against source.** When documentation mentions Gradle tasks, + module names, versions, toolchain requirements, or runtime behavior, + confirm it against the relevant code, build file, README, or workflow. +4. **Stay in scope.** If you spot a code or test issue, mention it briefly as + a handoff item for the relevant engineering or testing skill instead of + expanding the docs review. + +## Checks + +### A. Source Comments + +- **KDoc covers the public contract.** Explicit API mode makes public + declarations contracts; missing or stale KDoc on changed public API is a + finding. +- **Comments describe behavior or rationale.** Avoid prose that only restates + parameters, return values, or obvious assignments. +- **Mention important effects.** Document recomposition triggers, server + calls, generated-code dependencies, experimental API opt-ins, and + non-obvious constraints. +- **Inline comments are rare.** They should explain why a constraint exists, + not narrate what the next line does. +- **Paths and identifiers are exact.** Render file paths, package paths, + module names, class/function names, and identifiers as code, matching the + local backtick idiom. + +### B. Markdown Docs + +- **Heading hierarchy is valid.** Use one top-level `#`; do not skip levels. +- **Commands are fenced.** Use fenced code blocks for shell commands and file + examples. Avoid indented command blocks. +- **Examples are current.** Verify documented Gradle tasks, module names, + versions, and toolchain requirements against build files or owning docs. + Watch for the JDK 11 vs JDK 17 and root vs `codegen/plugins` distinctions. +- **Links resolve.** Check local relative links and referenced paths. External + inline links are acceptable when the surrounding file already uses them. +- **Terminology is consistent.** Use one term for the same concept within a + change set: Chords, Compose Multiplatform, Spine Event Engine, Protobuf, + ProtoData, codegen plugins, codegen runtime, application shell. +- **No orphans.** A paragraph, list item, or table cell must not end with a + final line containing only one word. Flag it and propose a reflow or + rewrite. +- **Project docs keep their ownership.** `README.md` is the project entry + point, library READMEs own usage instructions, `.agents/project.md` owns the + project map and CI notes, skills own task-specific policy, and `AGENTS.md` + owns agent operating policy. KDoc owns API-level documentation. + +### C. Skills And Agent Docs + +- **Skill frontmatter is compact and trigger-focused.** `name` is hyphen-case + and matches the directory. `description` explains when to use the skill. +- **Skill body follows the pattern.** Prefer role intro, use cases, fast path + or workflow, checks/policy sections, repo notes, verification, and output + format. +- **Avoid duplicated policy.** Keep implementation policy in area-specific + engineering skills, test policy in `tester`, documentation authoring policy + in `docs-writer`, documentation review policy in `docs-reviewer`, project + description in `.agents/project.md`, and global operating policy in + `AGENTS.md`. +- **`openai.yaml` stays UI metadata.** `display_name`, `short_description`, + and `default_prompt` describe the skill for the interface and must not carry + durable policy; their routing hints should match the skill's frontmatter and + the index in `.agents/skills/README.md`. +- **No task-plan references.** Skills should point at durable files and source + paths, not temporary task plans. + +## Output Format + +Return three sections, in this order: + +- **Must fix** - broken links, documented commands or syntax that are false, + missing important comments for non-obvious behavior, or Markdown structure + that prevents correct rendering. +- **Should fix** - unclear comments, duplicated policy, stale module maps, + inconsistent terminology, orphaned one-word final lines, overbroad inline + comments, or examples that are technically right but likely to mislead. +- **Nits** - wording, wrapping, minor style, or handoff notes for the relevant + engineering or testing skill. + +For each finding, cite the file and line, quote the relevant text, explain the +impact, and show the recommended rewrite. If a section is empty, write `None.` + +End with a one-line verdict: `APPROVE`, `APPROVE WITH CHANGES`, or +`REQUEST CHANGES`. diff --git a/.agents/skills/docs-reviewer/agents/openai.yaml b/.agents/skills/docs-reviewer/agents/openai.yaml new file mode 100644 index 00000000..e3ed17f5 --- /dev/null +++ b/.agents/skills/docs-reviewer/agents/openai.yaml @@ -0,0 +1,6 @@ +interface: + display_name: "Docs Reviewer" + short_description: "Review Chords documentation and comments" + default_prompt: > + Use $docs-reviewer after reading AGENTS.md, README.md, and + .agents/project.md to review a scoped Chords documentation change. diff --git a/.agents/skills/docs-writer/SKILL.md b/.agents/skills/docs-writer/SKILL.md new file mode 100644 index 00000000..8ab314ec --- /dev/null +++ b/.agents/skills/docs-writer/SKILL.md @@ -0,0 +1,101 @@ +--- +name: docs-writer +description: > + Writes, edits, and restructures Chords documentation. Use when asked to + create or update README.md files, .agents/project.md, AGENTS.md, skills, + KDoc comments, or inline explanatory comments. Verifies claims against + current code, tests, workflows, and build files. +--- + +# Documentation Writing + +## Decide the Target and Audience + +- Identify the target reader: library consumer, component subclass author, + contributor, maintainer, or agent. +- Identify the task type: new doc, update, restructure, or documentation audit. +- Identify the acceptance criteria: what is correct when the reader is done? +- Build a short plan before editing. Ask all clarification questions needed to + close uncovered spots in the plan when the audience, scope, ownership, or + expected output file is unclear. + +## Choose Where The Content Should Live + +Prefer updating an existing document over creating a new one. Use +`.agents/project.md` as the source of truth for documentation ownership and +the project map. API-level documentation belongs in KDoc on the public +declarations, not in READMEs. + +Do not link temporary artifacts, such as audit reports or task plans, from +durable documentation like `.agents/project.md` unless they become maintained +documents. + +## Verify Against Project Flows + +Use `.agents/project.md` to find the owning document or module, then verify +claims against the nearest README, build file, workflow, or source file. + +## Follow Local Documentation Conventions + +- Use fenced code blocks for commands, Kotlin, Protobuf, YAML, and shell + examples. +- Render file paths, package paths, Gradle tasks, module names, class and + function names, and command names as code. +- Keep headings hierarchical: one top-level `#`, then ordered levels. +- Use local relative links for repository files. +- Keep examples small enough to verify and copy; component examples follow + the class-based pattern shown in existing KDoc (e.g., the `Table` and + `EntityChooser` class docs). +- Use consistent terminology: Chords, Compose Multiplatform, Spine Event + Engine, Protobuf, ProtoData, codegen plugins, codegen runtime, application + shell, class-based components. +- Do not leave orphans: avoid wrapping any paragraph, list item, or table cell + so that a single word is left on its own final line. +- Do not duplicate long explanations between README files, `AGENTS.md`, and + skills; link to the owning document instead. +- Keep lines within 100 characters, matching the code style limit. + +## Comment Guidance + +- Document public APIs: explicit API mode makes every public declaration a + contract, and KDoc is expected on public classes, functions, and properties. +- Follow the local KDoc idiom: a one-sentence summary paragraph, detail + paragraphs, `@param` tags for type and value parameters, and backticked + identifiers. +- Use comments to explain why a constraint exists, not what the next line + does. +- Mention important effects: recomposition triggers, server calls, + generated-code dependencies, experimental Compose API usage, and returned + errors. +- Do not add comments that restate names, parameters, or obvious operations. + +## Make Docs Actionable + +- Prefer executable steps, expected outcomes, and concrete examples. +- Include easy-to-miss prerequisites: working directory (root vs + `codegen/plugins`), JDK version (11 vs 17), the `config` submodule + initialization, and Maven-local publication of codegen plugins. +- When documenting failure behavior, include the concrete reason and where the + user should look. +- When documenting architecture, describe ownership boundaries and the normal + flow rather than every helper function. + +## Validate Changes + +- Verify every referenced path exists. +- Verify Gradle tasks, module names, versions, and defaults against build + files or README ownership. +- Verify Markdown examples and local links. +- Run focused commands only when documentation changes depend on behavior that + should be proven by build/test output. + +## Output Format (for interactive sessions) + +When writing documentation: + +1. State the target audience and file location. +2. Summarize the documentation changed. +3. List source files, workflows, or docs used to verify claims. +4. Report validation commands run and any remaining unverified claims. + +Follow the git-history policy in `AGENTS.md`. diff --git a/.agents/skills/docs-writer/agents/openai.yaml b/.agents/skills/docs-writer/agents/openai.yaml new file mode 100644 index 00000000..231667ef --- /dev/null +++ b/.agents/skills/docs-writer/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Docs Writer" + short_description: "Write or update Chords documentation" + default_prompt: > + Use $docs-writer after reading AGENTS.md, README.md, and + .agents/project.md to write or update Chords documentation with claims + verified against the code. diff --git a/.agents/skills/engineer/SKILL.md b/.agents/skills/engineer/SKILL.md new file mode 100644 index 00000000..52007e2f --- /dev/null +++ b/.agents/skills/engineer/SKILL.md @@ -0,0 +1,42 @@ +--- +name: engineer +description: > + Routes Chords implementation work to the area-specific engineering skill. Use + for mixed component/codegen/build changes or when the owning area is unclear; + otherwise prefer the narrowest specialist skill directly. +--- + +# Engineering Router + +Use the narrowest implementation skill that fits the task: + +- `.agents/skills/component-engineer/SKILL.md` for class-based Compose UI + components in `core`, `proto`, and `client`: the component model, + application shell, input components, message forms, validation display, and + server-connected components. +- `.agents/skills/codegen-engineer/SKILL.md` for the `codegen/plugins` + ProtoData project, the codegen runtime (`codegen/runtime`), codegen + correctness tests (`codegen/tests`), generated + `MessageField`/`MessageOneof`/`MessageDef` contracts, and Protobuf + declarations in `proto-values`. +- `.agents/skills/build-engineer/SKILL.md` for root and `codegen/plugins` + Gradle build logic, `buildSrc` dependency coordinates, publishing wiring, + version policy, generated `pom.xml`/`dependencies.md` reports, and the + `config` submodule relationship. +- `.agents/skills/ci-engineer/SKILL.md` for GitHub Actions workflows under + `.github/workflows`: Ubuntu/Windows builds, license-report and + version-increment guards, wrapper validation, and publishing. +- `.agents/skills/security-reviewer/SKILL.md` for publishing credentials, + workflow secrets, dependency provenance, agent prompt/configuration safety + under `.agents/**`, and secret-exposure review. + +For changes that cross areas, read each area-specific skill and keep +verification commands separate (the root project and `codegen/plugins` use +different JDKs and Gradle versions). + +For documentation changes alongside implementation, also use +`.agents/skills/docs-writer/SKILL.md`. For verification work, use +`.agents/skills/tester/SKILL.md`. To review an implementation diff for +correctness and regressions, use `.agents/skills/code-reviewer/SKILL.md`. + +Follow the git-history and safety policy in `AGENTS.md`. diff --git a/.agents/skills/engineer/agents/openai.yaml b/.agents/skills/engineer/agents/openai.yaml new file mode 100644 index 00000000..c86e1771 --- /dev/null +++ b/.agents/skills/engineer/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Engineer" + short_description: "Route mixed or unclear Chords implementation work" + default_prompt: > + Use $engineer after reading AGENTS.md, README.md, and .agents/project.md + to route a Chords implementation task to the narrowest area-specific + skill. diff --git a/.agents/skills/security-reviewer/SKILL.md b/.agents/skills/security-reviewer/SKILL.md new file mode 100644 index 00000000..fdb13faa --- /dev/null +++ b/.agents/skills/security-reviewer/SKILL.md @@ -0,0 +1,65 @@ +--- +name: security-reviewer +description: > + Chords security review guidance. Use for publishing-credential handling, + GitHub Actions secrets, GPG-encrypted key files, dependency provenance, + Gradle wrapper integrity, agent prompt/configuration safety under + `.agents/**`, and accidental secret exposure in this public repository. +--- + +# Security Reviewer + +Use this skill for security-focused review or implementation guidance. Chords +is a public open-source repository with no runtime backend of its own, so the +main risk surface is the supply chain — publishing credentials, CI workflows, +and dependencies — plus the agent configuration itself under `.agents/**`. + +## Scope + +- Publishing credentials: the GPG-encrypted key files under `.github/keys/`, + the decryption scripts under `config/scripts/`, and their use in + `.github/workflows/publish.yml`. +- GitHub Actions secrets and workflows that build, validate, or publish + artifacts. +- Dependency provenance: coordinates and repositories declared in `buildSrc` + and `codegen/plugins/buildSrc`; Gradle wrapper integrity (the + `gradle-wrapper-validation` workflow). +- Accidental commits of credentials, tokens, private keys, or TeamDev-internal + data into this public repository. +- Agent configuration files (`.agents/**`, `openai.yaml`, `AGENTS.md`): flag + prompt-injection risks in `default_prompt` fields and skill instructions + that could cause an agent to exfiltrate secrets or bypass safety rules. + +## Rules + +- Treat credential leakage as high severity: this repository is public, and + anything committed is published. +- Do not print secret values, tokens, private keys, or decrypted credential + payloads. +- Do not suggest storing secrets in source-controlled files; encrypted `.gpg` + blobs under `.github/keys/` are the existing sanctioned mechanism, and + changes to them are human-owned. +- Reference workflow secrets by name through `secrets.*`; never inline values. +- Do not run commands that publish artifacts, rotate credentials, or change + GitHub secrets. +- Watch for dependency-confusion risk: new repositories or dependency + coordinates must match the trusted Spine/TeamDev sources already configured + in `buildSrc`. + +## Review Focus + +- Workflow changes that widen `on:` triggers, expose secrets to + pull-request-controlled contexts, or add untrusted third-party actions. +- New or changed Maven repositories and dependency coordinates. +- Scripts that decrypt, copy, or upload credential material. +- Content that should not be public: internal hostnames, e-mail addresses of + individuals, or internal project data in code, tests, or docs. +- Prompt-injection risks in `.agents/**`: overbroad `default_prompt` fields, + skill instructions that could bypass the policy in `AGENTS.md`, and + instructions that could cause an agent to exfiltrate secrets. + +## Output Format + +For reviews, lead with findings ordered by severity and include file/line +references. If no issues are found, state that clearly and mention any residual +risk or unverified external configuration. diff --git a/.agents/skills/security-reviewer/agents/openai.yaml b/.agents/skills/security-reviewer/agents/openai.yaml new file mode 100644 index 00000000..de68cb46 --- /dev/null +++ b/.agents/skills/security-reviewer/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Security Reviewer" + short_description: "Review Chords credential, supply-chain, and agent-config safety" + default_prompt: > + Use $security-reviewer after reading AGENTS.md and .agents/project.md to + review credential handling, workflow secrets, dependency provenance, or + agent prompt/configuration safety in a scoped Chords change. diff --git a/.agents/skills/tester/SKILL.md b/.agents/skills/tester/SKILL.md new file mode 100644 index 00000000..5289b693 --- /dev/null +++ b/.agents/skills/tester/SKILL.md @@ -0,0 +1,53 @@ +--- +name: tester +description: > + Chords test and verification policy. Use for test authoring and verification + strategy across core, proto, proto-values, client, the codegen runtime, and + codegen correctness tests, including Gradle verification commands. +--- + +# Testing + +## Core Policy + +- Follow existing local style. Tests are named `*Spec.kt` and use JUnit + Jupiter with Truth, AssertK, or Kotest matchers depending on the owning + module; check neighboring tests before introducing a new dependency. +- Put focused regression tests in the module that owns the behavior, under + `src/test/kotlin` mirroring the production package. +- Keep fixtures small and near the tests (`Given.kt`-style files), named after + the behavior they represent. +- Prefer public APIs, generated messages, and observable component state over + private implementation details. +- Cover both success and failure paths for validation, value parsing, + extensions, and codegen output shape. +- UI rendering and interaction are not covered by automated tests in this + repository. Do not force UI snapshot tooling in; verify what is testable + (logic, extensions, codegen) and report the manual-verification remainder + explicitly. +- Codegen behavior is verified end-to-end in `codegen/tests` + (`:codegen-tests`), which runs generation against test Protobuf definitions + and asserts on the generated API; add coverage there for generator changes. +- Do not skip codegen-related Gradle tasks when generator behavior, Protobuf + schemas, or generated API contracts are part of the change: rebuild + `codegen/plugins` and run `:codegen-tests:test` so assertions run against + freshly generated code, not outputs left over from a previous build. +- Avoid tests that depend on a real Spine server, network resources, or local + absolute paths. + +## Verification + +Run the smallest useful command while iterating (repository root, JDK 11): + +```bash +./gradlew ::test +./gradlew ::test --tests "io.spine.chords.proto.money.MoneyFieldSpec" +./gradlew :codegen-tests:test +./gradlew clean build +``` + +Module Gradle paths: `core`, `proto`, `proto-values`, `client`, `runtime`, +`codegen-tests`. The `codegen/plugins` project verifies separately from +`codegen/plugins/` with JDK 17 (`./gradlew build`). + +Follow the git-history and safety policy in `AGENTS.md`. diff --git a/.agents/skills/tester/agents/openai.yaml b/.agents/skills/tester/agents/openai.yaml new file mode 100644 index 00000000..e45c9b75 --- /dev/null +++ b/.agents/skills/tester/agents/openai.yaml @@ -0,0 +1,6 @@ +interface: + display_name: "Tester" + short_description: "Author or verify Chords tests" + default_prompt: > + Use $tester after reading AGENTS.md, README.md, and .agents/project.md to + author tests or run verification for a scoped Chords change. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..2b1a594b --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,171 @@ +# Welcome, Agents + +## Orientation + +This repository is **Chords**, a suite of open-source libraries by TeamDev for +desktop UI development with the Compose Multiplatform toolkit, built around the +Spine Event Engine ecosystem. + +For substantive implementation, review, or documentation work, start by reading: + +- `README.md` for the library overview, supported environment, development + setup, and build commands. +- `.agents/project.md` for the project overview, module map, architecture + notes, documentation ownership, and CI notes. +- The README closest to the area you are changing, especially: + - `core/README.md` for the application shell, class-based components, and + basic UI components. + - `proto/README.md` for Protobuf-aware UI components and message forms. + - `proto-values/README.md` for supplementary Protobuf messages and Kotlin + extensions. + - `client/README.md` for server connectivity via Spine Event Engine. + - `codegen/runtime/README.md` and `codegen/plugins/README.md` for the code + generation runtime and ProtoData plugins. + +Local task-specific skills live under `.agents/skills/`. Use them when their +frontmatter matches the task. + +## Commit and History Safety + +Do not commit, push, tag, rebase, merge, cherry-pick, or otherwise write to Git +history unless the user's current prompt explicitly asks for it. + +Authorization does not carry over between turns or sessions. When in doubt, +leave changes unstaged, show the diff or summarize it, and let the user decide. + +When moving or renaming tracked files, use `git mv` so file history is preserved. + +## Safety Rules + +- This is a public open-source repository (Apache 2.0). Do not add secrets, + credentials, tokens, private keys, or TeamDev-internal data to it. +- Do not modify files under the `config/` Git submodule; it is owned by the + [SpineEventEngine/config](https://github.com/SpineEventEngine/config) + repository, and changes belong upstream. +- Do not publish artifacts or trigger publishing tasks (`publish`, + `publishCodegenPlugins`) unless the user's current prompt explicitly asks for + it. Publishing is normally performed by CI on pushes to `master`. +- Do not edit the encrypted key files under `.github/keys/` or the decryption + scripts' credential wiring. +- Do not auto-update external dependencies outside dedicated update tasks. The + toolchain versions are deliberately pinned (see Development Conventions) and + upgrading them is a project-level decision. +- Do not add analytics, telemetry, or tracking code. +- Avoid reflection, unsafe code, broad global state, and hidden background work + unless explicitly justified by the task (reflection is already used + deliberately in a few places, such as resolving component type parameters). +- Preserve existing package structure, module boundaries, naming conventions, + and Gradle patterns. +- Do not manually edit generated sources or build outputs: `generated/` + folders, codegen workspace outputs (`_out/`), Gradle wrapper files, or the + generated `pom.xml` / `dependencies.md` reports (regenerate them with Gradle + instead). +- Public API changes require care: all libraries are consumed by external + projects, and Kotlin explicit API mode is enabled. Avoid breaking existing + public signatures; prefer additive changes. + +## Versioning and Reports + +Every PR must increment `chordsVersion` in `version.gradle.kts` (enforced by +the `Check version increment` workflow). The version scheme is +`2.0.0-SNAPSHOT.` where `` grows monotonically. + +The `pom.xml` and `dependencies.md` files at the repository root are generated +reports that must stay in sync with the changeset (enforced by the +`Ensure license reports updated` workflow). They are regenerated as part of +`./gradlew build`. When your change affects the version or dependencies, make +sure regenerated reports are part of the changeset. + +Source files carry a copyright header; when modifying a file, keep the header +year current (files touched in a given year carry that year). + +## Verification and Quality + +Never mark a non-trivial change done without verification. Choose the smallest +command that proves the touched behavior, then broaden when shared behavior or +contracts are affected. + +Useful root commands (run from the repository root, JDK 11): + +```bash +./gradlew ::test +./gradlew ::test --tests "io.spine.chords.proto.money.MoneyFieldSpec" +./gradlew ::check +./gradlew detekt +./gradlew clean build +./gradlew publishToMavenLocal +``` + +Module names for Gradle paths: `core`, `proto`, `proto-values`, `client`, +`runtime` (located at `codegen/runtime`), and `codegen-tests` (located at +`codegen/tests`). + +The `codegen/plugins` directory is a **separate Gradle project** requiring +JDK 17 and Gradle 9.4.x; run its commands from `codegen/plugins/`: + +```bash +./gradlew build +./gradlew publishToMavenLocal +``` + +Modules that use Chords code generation (`proto-values`, `codegen-tests`) +automatically depend on `publishCodegenPluginsToMavenLocal`, which builds and +publishes the codegen plugins locally before they are applied. + +Chords libraries are UI libraries; automated tests cannot cover rendering +behavior. For visual/interactive component changes, state clearly in the final +response that behavior was verified by compilation and tests only, and describe +what manual verification remains. + +If verification cannot be run, state the reason clearly in the final response. + +## Development Conventions + +- Use JDK 11 for the root project and JDK 17 for `codegen/plugins`. +- The supported environment is deliberately conservative: Kotlin 1.8.20, + Compose Multiplatform 1.5.12, Spine Event Engine 1.9.0, Gradle 6.9.4 for the + root project. Do not assume newer language or library features are available. +- Kotlin explicit API mode is enabled: public declarations require explicit + `public` modifiers and public API should have KDoc. +- Configure IntelliJ IDEA Detekt with `quality/detekt-config.yml`. +- Keep lines within 100 characters (Detekt `MaxLineLength`). +- UI components follow the class-based component pattern from `core` (see + `io.spine.chords.core.Component` and its inheritors): composition happens in + `content()`, pre-composition updates in `beforeComposeContent()`, and + instance configuration via the `Props`-style lambdas. Composable functions + and composable-emitting methods are named in `PascalCase`. +- Tests are named `*Spec.kt`, use JUnit Jupiter with Truth/AssertK/Kotest + matchers depending on the owning module, and keep fixtures in `Given.kt`-style + files near the test. +- Dependency coordinates live in `buildSrc/src/main/kotlin/io/spine/internal/dependency/`; + add or change them there, following the existing object-per-library pattern. +- Get the `config` submodule content with + `git submodule update --init --recursive` before building. + +## Code Review + +For reviews, lead with findings ordered by severity and include file/line +references. Focus on bugs, regressions, public API breaks, missing tests, and +convention violations. + +Skip routine review of generated or vendored files, including: + +- `gradlew`, `gradlew.bat`, `gradle/wrapper/**` (root and `codegen/plugins`) +- generated `pom.xml` and `dependencies.md` reports +- generated Protobuf/codegen outputs +- the `config/` submodule +- IDE metadata such as `.idea/**` + +Do not skip `buildSrc/**` or `codegen/plugins/buildSrc/**`: they own dependency +and Gradle configuration for Chords. + +## Planning and Questions + +Start each task by forming an agent-owned plan before editing or running +non-trivial commands. While composing that plan, identify missing requirements, +risks, affected areas, and verification needs. + +Ask all clarification questions needed to close uncovered spots in the plan. +Group related questions together when they are blocking the same decision. +Prefer a reasonable assumption only when the answer would not materially change +the plan, implementation, safety posture, or verification path. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..9749b7db --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,8 @@ +# CLAUDE.md + +See [`AGENTS.md`](AGENTS.md) for the full repository operating policy: safety +rules, Git history policy, verification commands, development conventions, and +code review guidance. + +See [`.agents/skills/README.md`](.agents/skills/README.md) for the local skill +index and routing overview. diff --git a/dependencies.md b/dependencies.md index 50ccc15c..4e4527bf 100644 --- a/dependencies.md +++ b/dependencies.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine.chords:spine-chords-client:2.0.0-SNAPSHOT.87` +# Dependencies of `io.spine.chords:spine-chords-client:2.0.0-SNAPSHOT.88` ## Runtime 1. **Group** : cafe.adriel.voyager. **Name** : voyager-core. **Version** : 1.0.1.**No license information found** @@ -1104,12 +1104,12 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Jul 14 18:38:48 EEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Jul 14 20:02:53 EEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.chords:spine-chords-codegen-tests:2.0.0-SNAPSHOT.87` +# Dependencies of `io.spine.chords:spine-chords-codegen-tests:2.0.0-SNAPSHOT.88` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -1899,12 +1899,12 @@ This report was generated on **Tue Jul 14 18:38:48 EEST 2026** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Jul 14 18:38:49 EEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Jul 14 20:02:54 EEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.chords:spine-chords-core:2.0.0-SNAPSHOT.87` +# Dependencies of `io.spine.chords:spine-chords-core:2.0.0-SNAPSHOT.88` ## Runtime 1. **Group** : cafe.adriel.voyager. **Name** : voyager-core. **Version** : 1.0.1. @@ -2938,12 +2938,12 @@ This report was generated on **Tue Jul 14 18:38:49 EEST 2026** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Jul 14 18:38:51 EEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Jul 14 20:02:55 EEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.chords:spine-chords-proto:2.0.0-SNAPSHOT.87` +# Dependencies of `io.spine.chords:spine-chords-proto:2.0.0-SNAPSHOT.88` ## Runtime 1. **Group** : cafe.adriel.voyager. **Name** : voyager-core. **Version** : 1.0.1.**No license information found** @@ -3976,12 +3976,12 @@ This report was generated on **Tue Jul 14 18:38:51 EEST 2026** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Jul 14 18:38:52 EEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Jul 14 20:02:56 EEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.chords:spine-chords-proto-values:2.0.0-SNAPSHOT.87` +# Dependencies of `io.spine.chords:spine-chords-proto-values:2.0.0-SNAPSHOT.88` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -4775,12 +4775,12 @@ This report was generated on **Tue Jul 14 18:38:52 EEST 2026** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Jul 14 18:38:53 EEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). +This report was generated on **Tue Jul 14 20:02:57 EEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.chords:spine-chords-runtime:2.0.0-SNAPSHOT.87` +# Dependencies of `io.spine.chords:spine-chords-runtime:2.0.0-SNAPSHOT.88` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -5544,4 +5544,4 @@ This report was generated on **Tue Jul 14 18:38:53 EEST 2026** using [Gradle-Lic The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Tue Jul 14 18:38:54 EEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file +This report was generated on **Tue Jul 14 20:02:57 EEST 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/pom.xml b/pom.xml index 44c2f025..9e6a9c17 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ all modules and does not describe the project structure per-subproject. --> io.spine.chords Chords -2.0.0-SNAPSHOT.87 +2.0.0-SNAPSHOT.88 2015 diff --git a/version.gradle.kts b/version.gradle.kts index 8b8ae5aa..18bbc932 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -27,4 +27,4 @@ /** * The version of all Chords libraries. */ -val chordsVersion: String by extra("2.0.0-SNAPSHOT.87") +val chordsVersion: String by extra("2.0.0-SNAPSHOT.88")