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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# GitHub Copilot Instructions — Innamark

Primary audience: GitHub Copilot. Other agents should follow `AGENTS.md` and the closest
subproject `AGENTS.md`; reading this file is optional and only adds Copilot-tuned completion hints.

**Read `AGENTS.md` first** for the shared rules (monorepo layout, tooling baseline, invariants,
working rules, style baseline, AI-assistance marker, secrets/network policy, PR sizing). Then read
the closest subproject `AGENTS.md`. This file only adds Copilot-specific behavior on top.

## 0. Scope and role
- Act as a senior engineer supporting repository users (developers, architects, and maintainers).
- Be direct and implementation-focused.
- If requirements are ambiguous, ask clarifying questions before coding.
- If uncertain, say "I'm not sure" instead of guessing.
- Prefer a focused change with a clarifying question over a large speculative refactor

## 1. Operational boundaries
- Never commit, push, merge, deploy, publish, or modify repository settings unless explicitly asked.
- Do not install dependencies, delete files, or change public APIs without proposing first.
- Keep changes scoped; avoid unrelated refactors.
- Do not read or print secrets, tokens, or local `.env` files.

## 2. Where to look first (Copilot completion hints)
Concrete file paths that improve completion quality:
- `watermarker/src/commonMain/kotlin/watermarkers/text/PlainTextWatermarker.kt`
- `watermarker/src/commonMain/kotlin/types/watermarks/`
- `watermarker/src/commonMain/kotlin/types/responses/` (`Status`, `Result<T>`)
- `cli/src/main/kotlin/Main.kt`
- `webinterface/src/jsMain/kotlin/`
- `docs/docs/03-usage/` and `docs/docs/04-development/`

## 3. Copilot-specific reminders
- When generating or significantly modifying a Kotlin file, add the AI-assistance marker exactly
as defined in the root `AGENTS.md` (top-level `//` line after the license header, before
`package`). Do not place it inside KDoc.
- Mirror the matching workflow in `.github/workflows/` for touched paths when validating changes
locally (`test_watermarker.yml`, `test_cli.yml`, `test_webinterface.yml`, `test_docusaurus.yml`).
- For algorithm constraints, deprecated APIs (`ZipFileWatermarker`), preferred builders
(`InnamarkTagBuilder`), and per-subproject test/build commands: defer to `AGENTS.md` and the
subproject `AGENTS.md` rather than restating them here.

## 4. Documentation and PR rules (Copilot)
- Update docs when user-facing behavior changes (numbered kebab-case files; add sequentially).
- PR titles: conventional commits with component scope (full format in `CONTRIBUTING.md`).

## 5. Maintainer note — keeping this file effective
Internal guidance for whoever edits this file (not runtime rules for Copilot):
- Keep it short, structured, and imperative.
- Prefer concrete project facts and runnable commands over generic advice.
- Avoid duplicating content from `AGENTS.md`; link or defer instead.
- Add examples only when they clarify a non-obvious rule.
102 changes: 102 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# AGENTS.md

Repository-wide guidance for all coding agents in this monorepo.

## Read order and precedence
- Start here for global rules.
- Then read the closest subproject file (nearest file wins):
- `watermarker/AGENTS.md`
- `cli/AGENTS.md`
- `webinterface/AGENTS.md`
- `docs/AGENTS.md`
- For GitHub Copilot-specific behavior, also read `.github/copilot-instructions.md`.

## Monorepo layout
- This repository has **independent builds** per subproject; there is no root Gradle build.
- Subprojects:
- `watermarker/`: Kotlin Multiplatform core library (JVM + JS)
- `cli/`: Kotlin/JVM CLI app consuming `watermarker-jvm`
- `webinterface/`: Kotlin/JS KVision UI consuming `watermarker`
- `docs/`: Docusaurus 3 documentation site
- `cli/` and `webinterface/` consume the **locally published** `watermarker` artifact. When touching
library code, publish first from `watermarker/`:

```bash
cd watermarker && ./gradlew publishToMavenLocal
```

## Tooling baseline
- Kotlin subprojects (`watermarker/`, `cli/`, `webinterface/`): JDK 21, Gradle wrapper from the
subproject folder.
- `docs/`: Node 18 with yarn.
- Always run commands from the relevant subproject directory.

## Global invariants
- Innamark uses whitespace replacement (base-4 alphabet: `\u2008`, `\u2009`, `\u202F`, `\u205F`).
- Separator is `\u2004` (`DefaultTranscoding.SEPARATOR_CHAR`).
- Capacity is based on **regular-space count**, not total text length.
- Watermark repetition across the cover is intentional for robustness; do not remove it.
- Prefer `InnamarkTagBuilder` for new watermark creation paths.
- `ZipFileWatermarker` is deprecated; do not extend it.

## Working rules
- Run commands from the relevant subproject directory.
- Keep diffs focused; avoid drive-by reformatting.
- Keep Fraunhofer license headers intact in source files (see `CONTRIBUTING.md` → License Header
for the exact block).
- Add tests for behavioral changes and keep docs in `docs/` in sync for user-facing changes.
- Do not commit, push, merge, release, or deploy unless explicitly requested by the user.
- Do not install dependencies, fetch from the network, delete files, or change public APIs without
proposing the change first.
- Do not read or print secrets, tokens, or local `.env` files; if such content is encountered,
stop and ask before continuing.
- Soft recommendation: keep individual change sets under ~1000 LOC (see `CONTRIBUTING.md` for the
full PR sizing guidance).

## Testing policy
- `watermarker/` is the only subproject with a mature automated test suite and should remain fully
tested.
- For `watermarker/`, behavioral changes should come with tests unless there is a strong reason not to.
- `cli/` and `webinterface/` testing is optional today, not mandatory; add tests when practical,
but do not block small focused changes solely on missing new tests there.
- File-based behaviors should reuse existing fixtures from the `samples/` folder where possible
instead of inventing new ad-hoc samples.

## Style and quality baseline
- Kotlin style: 4 spaces, hard wrap at 100 chars, KDoc for public APIs.
- Follow Kotlin KDoc syntax: `https://kotlinlang.org/docs/kotlin-doc.html`.
- Every class/interface/object should have valid KDoc.
- Methods/functions with substantial logic should have valid KDoc when it improves generated docs
and maintainability.
- Inline comments should stay light; prefer short one-sentence comments only for long or difficult
code blocks.
- Tests do not need extra explanatory comments unless a case is genuinely non-obvious.
- Watermarker library: value-based error handling (`Status`/`Result<T>`), avoid exceptions in core.
- Every Kotlin file should keep the Fraunhofer license header and a copyright year range from the
original creation year to the latest modification year. On any change to a file, bump the end of
the range to the current year.
- If an AI assistant makes a non-trivial logic change to a Kotlin file (i.e. anything beyond pure
formatting, renames, or comment-only edits), add the AI-assistance marker:

```kotlin
// This file was developed with AI assistance.
```

Place it as a single top-level line directly after the license header block and
before the `package` statement. This keeps the marker file-level, greppable, and out of
generated KDoc.
- PR titles should follow conventional commits with component scope (e.g. `fix(cli): ...`); see
`CONTRIBUTING.md` for the full format.

## Related instructions
- Copilot-focused instructions: `.github/copilot-instructions.md`
- Contribution details: `CONTRIBUTING.md`

## Maintainer note — keeping this file effective
Internal guidance for whoever edits this file (not runtime rules for agents):
- Keep it short, structured, and imperative.
- Prefer concrete project facts and runnable commands over generic advice.
- Avoid duplicating content from `CONTRIBUTING.md` or subproject `AGENTS.md`; link or defer instead.
- Add examples only when they clarify a non-obvious rule.
- When changing rules here, check whether `.github/copilot-instructions.md` and the subproject
`AGENTS.md` files still align.
34 changes: 34 additions & 0 deletions cli/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# AGENTS.md (cli)

This file applies to `cli/`. Also read the repository-level `../AGENTS.md` for global rules.

## Scope
- Thin Kotlin/JVM CLI wrapper over `watermarker-jvm`.
- Main entry point: `src/main/kotlin/Main.kt`.

## Dependency and build flow
- `cli/` depends on local Maven publication from `watermarker/`.
- Always run this first when library changes are involved:
- `cd ../watermarker && ./gradlew publishToMavenLocal`
- If dependency resolution fails for `watermarker-jvm`, publish local artifacts and retry.

## Dev environment and commands
- Use JDK 21 and the local wrapper from this folder.
- Commands:
- `./gradlew ktlintCheck` (mandatory before finishing changes)
- `./gradlew test`
- `./gradlew shadowJar` — produces `build/libs/cli-<version>-all.jar`
- `./gradlew run --args="--help"`
- Before finishing CLI changes, at minimum run `./gradlew ktlintCheck` and `./gradlew test`.

## Implementation conventions
- Keep CLI behavior thin and delegate watermarking logic to `watermarker-jvm`.
- Avoid duplicating core algorithm logic in CLI.
- Follow existing option/argument style in `Main.kt` and keep UX consistent.

## Testing and quality
- CLI testing is optional today, not mandatory.
- Add or adjust tests for changed CLI behavior when practical, especially for larger behavior changes.
- At minimum, validate the affected CLI flow manually or with the existing Gradle test/run commands.
- Keep diffs focused and avoid unrelated formatting churn.
- If user-facing CLI behavior changes, update docs under `docs/docs/03-usage/11-cli/`.
35 changes: 35 additions & 0 deletions docs/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# AGENTS.md (docs)

This file applies to `docs/`. Also read the repository-level `../AGENTS.md` for global rules.

## Scope
- Docusaurus 3 documentation site for all Innamark subprojects.
- This is not a Gradle project.

## Dev environment and commands
- Use Node 18 and yarn.
- Run from `docs/`:
- `yarn install --frozen-lockfile`
- `yarn start`
- `yarn build`
- Matching CI workflows: `.github/workflows/test_docusaurus.yml`,
`.github/workflows/deploy_docusaurus.yml`.

## Content structure rules
- Keep numbered, kebab-case paths and filenames.
- Relevant roots:
- `docs/docs/03-usage/`
- `docs/docs/04-development/`
- Add new docs with the next sequential number; do not renumber existing files unless required.

## Update policy
- Any user-facing behavior change in `watermarker/`, `cli/`, or `webinterface/` should be reflected here.
- Keep examples and command snippets consistent with current build/test workflows.

## Assets and licensing
- New non-source assets (images and other binary files) require a sibling `<name>.license` file
per REUSE (e.g. `my-figure.jpg.license` for `my-figure.jpg`).

## Quality
- Prefer small, focused docs diffs.
- Keep terminology aligned with the implementation and the watermarking algorithm.
80 changes: 80 additions & 0 deletions watermarker/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# AGENTS.md (watermarker)

This file applies to `watermarker/`. Also read the repository-level `../AGENTS.md` for global rules.

## Scope
- Core Kotlin Multiplatform watermarking library (`commonMain`, `jvmMain`, `jsMain`).
- This is the canonical implementation used by both `cli/` and `webinterface/`.

## Dev environment and commands
- Use JDK 21 and the local wrapper from this folder.
- Main commands:
- `./gradlew ktlintCheck`
- `./gradlew allTests`
- `./gradlew build` — canonical pre-finish check (runs `ktlintCheck` + tests).
- `./gradlew publishToMavenLocal`
- If downstream projects are touched (`cli/`, `webinterface/`), publish locally first.

## Architecture map
- Core text algorithm:
- `src/commonMain/kotlin/watermarkers/text/PlainTextWatermarker.kt`
- `src/commonMain/kotlin/watermarkers/text/TextWatermarker.kt`
- Watermark/tag types:
- `src/commonMain/kotlin/types/watermarks/`
- Value-based responses:
- `src/commonMain/kotlin/types/responses/`
- JVM file integrations:
- `src/jvmMain/kotlin/watermarkers/file/`
- `src/jvmMain/kotlin/utils/FileHandling.kt`
- Platform-specific utils:
- JVM: `src/jvmMain/kotlin/utils/`
- JS: `src/jsMain/kotlin/utils/`

## Core algorithm constraints (do not break)
- `PlainTextWatermarker` must reject covers that already contain alphabet chars or separator char
(alphabet: `\u2008`, `\u2009`, `\u202F`, `\u205F`; separator: `\u2004`).
- Capacity is driven by regular spaces only.
- Repeated embedding with separator delimiters is intentional robustness behavior.
- Keep JVM/JS/common behavior aligned so generated watermarks are interoperable.

## Implementation conventions
- Use `InnamarkTagBuilder` by default for new watermark creation flows.
- Use value-based error handling in library code (`Status`, `Result<T>`, `appendStatus`, `prependStatus`).
- For new custom events, subclass `Event.Warning` or `Event.Error`, set `source`, and implement `getMessage()`.
- Do not throw exceptions in core library paths unless there is an existing established exception boundary.

## File type support (JVM only)
- For new watermarkable file types:
1. Implement `WatermarkableFile`.
2. Implement matching `FileWatermarker`.
3. Register extension in `SupportedFileType` in `src/jvmMain/kotlin/utils/FileHandling.kt`.
- Do not extend deprecated `ZipFileWatermarker`.

## Testing expectations
- `watermarker/` should always aim to be fully tested; this is the best-covered subproject in the repo.
- Before finishing watermarker changes, run from this folder:
- `./gradlew build` (canonical; runs `ktlintCheck` + all tests)
- or, for faster inner-loop iteration: `./gradlew ktlintCheck` plus `./gradlew jvmTest` /
`./gradlew jsTest` / `./gradlew allTests`
- Add/update tests in the correct target and level:
- `commonTest`, `jvmTest`, `jsTest`
- unit/integration where appropriate
- Current JVM test layout mirrors production packages and then splits into `unitTest/` and
`integrationTest/` directories, for example:
- `src/jvmTest/kotlin/types/files/unitTest/`
- `src/jvmTest/kotlin/types/files/integrationTest/`
- `src/jvmTest/kotlin/watermarkers/file/unitTest/`
- `src/jvmTest/kotlin/watermarkers/file/integrationTest/`
- Follow existing class naming patterns:
- shared/general tests often use `*Test`
- JVM-specific tests often use `*TestJvm`
- integration tests use `*IntegrationTest` or `*IntegrationTestJvm`
- Follow existing test function naming style: lowercase names with underscores that describe
operation, condition, and expected result, for example `addWatermark_valid_success`,
`fromFile_invalidPath_error`, or `decode_encode_inversion`.
- Keep the current `Arrange` / `Act` / `Assert` structure used in existing tests.
- Use `src/jvmTest/resources/` for stable JVM test fixtures and reuse representative files from
`samples/` for file-based scenarios when they already match the intended behavior.
- The `samples/` directory contains important text and zip examples for file-oriented watermarking
cases; prefer reusing those scenarios over inventing new binary fixtures.
- Do not regenerate or modify existing binary fixtures unintentionally.
45 changes: 45 additions & 0 deletions webinterface/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# AGENTS.md (webinterface)

This file applies to `webinterface/`. Also read the repository-level `../AGENTS.md` for global rules.

## Scope
- Kotlin/JS KVision frontend consuming multiplatform `watermarker` artifacts.
- Main UI code lives in `src/jsMain/kotlin/`.

## Dependency and build flow
- `webinterface/` depends on local `watermarker` publication.
- Precondition when library changes are involved:
- `cd ../watermarker && ./gradlew publishToMavenLocal`

## Dev environment and commands
- Use JDK 21 and the local wrapper from this folder.
- Run from `webinterface/`:
- `./gradlew ktlintCheck` (mandatory before finishing changes)
- `./gradlew test`
- `./gradlew -t run`
- `./gradlew clean zip`
- Docker path validated in CI:
- `docker build -t innamark-webinterface -f webinterface/Dockerfile .`
- Newcomer fast-start from repo root:
- `docker compose up` using `../docker-compose.yml` (builds and serves the webinterface path).
- Before finishing changes, at minimum run `./gradlew ktlintCheck` and `./gradlew test`.

## UI behavior constraints
- Keep the two active text tabs functionally correct:
- Embed tab lets users check if a watermark fits the cover text, choose `InnamarkTag`
configurations (for example CRC32, SHA3, compression/size), and embed the watermark into
the cover text.
- Extract tab lets users extract watermark content from an existing watermarked cover text.
- Preserve capacity logic based on `PlainTextWatermarker.getMinimumInsertPositions(...)`.
- Keep the tab-specific UX with separate text input/textarea fields for embed and extract flows.
- Keep behavior aligned with library constraints (space-based capacity, alphabet/separator handling).

## Versioning caution
- Do not casually change pinned Kotlin/KVision versions in `gradle.properties`.
- KVision is version-sensitive to Kotlin; upgrades should be explicit and validated.

## Testing and docs
- Webinterface testing is optional today, not mandatory.
- Add or update JS tests for behavior changes when practical, especially for non-trivial UI logic.
- At minimum, validate changed flows in the dev server or docker-based fast-start path when feasible.
- If user-facing UI behavior changes, update docs under `docs/docs/03-usage/12-webinterface/`.
Loading