Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9a70a04
style: redesign typed peripheral docs with modern indigo theme
SirEdvin Jul 16, 2026
d24948e
Merge pull request #15 from SirEdvin/feat/modern-docs-theme
SirEdvin Jul 16, 2026
ee39ad4
docs: add player-focused peripheral pages
SirEdvin Jul 16, 2026
7300a06
docs: generate peripheral method reference
SirEdvin Jul 16, 2026
fb9773e
Merge remote-tracking branch 'origin/1.20' into docs/peripheral-pages
SirEdvin Jul 16, 2026
f1d0de9
Merge pull request #16 from SirEdvin/docs/peripheral-pages
SirEdvin Jul 16, 2026
31af87b
docs: add material theme selection
SirEdvin Jul 16, 2026
28caaad
Merge pull request #17 from SirEdvin/docs/material-theme-switch
SirEdvin Jul 16, 2026
c3e31eb
docs: replace TypeDoc with MkDocs
SirEdvin Jul 16, 2026
5c91e8d
Merge pull request #18 from SirEdvin/docs/mkdocs-peripheral-reference
SirEdvin Jul 16, 2026
fc7a57a
docs: render isometric peripheral blocks
SirEdvin Jul 22, 2026
4344f0f
Merge pull request #20 from SirEdvin/docs/isometric-block-renders
SirEdvin Jul 22, 2026
d03c6a1
docs: expand repository guidance
SirEdvin Jul 22, 2026
984ce79
Merge pull request #21 from SirEdvin/docs/adapt-agents-guidance
SirEdvin Jul 22, 2026
cbcf671
docs: fix block images and method headings
SirEdvin Jul 22, 2026
b8ad4d8
Merge pull request #22 from SirEdvin/docs/fix-block-images-and-method…
SirEdvin Jul 22, 2026
4903e5f
docs: render pixel-accurate block previews
SirEdvin Jul 22, 2026
37a087d
Add venv
SirEdvin Jul 27, 2026
dc5b6e3
Merge pull request #23 from SirEdvin/docs/fix-isometric-renders-and-m…
SirEdvin Jul 27, 2026
6093a1a
Merge branch '1.20' into 1.21
SirEdvin Jul 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions .github/scripts/docs-site.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,21 @@ import { spawnSync } from "node:child_process";
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
import { fileURLToPath } from "node:url";

export const REQUIRED_DOC_FILES = [
export const COMMON_DOC_FILES = [
"projects/typed-peripheral-digitalitems/build.gradle.kts",
"projects/typed-peripheral-digitalitems/package.json",
"projects/typed-peripheral-digitalitems/package-lock.json",
"projects/typed-peripheral-digitalitems/typedoc.json",
"projects/typed-peripheral-digitalitems/tsconfig.docs.json",
"projects/typed-peripheral-digitalitems/shared.ts",
"projects/typed-peripheral-digitalitems/digitizer.ts",
"projects/typed-peripheral-digitalitems/advanced_digitizer.ts",
"projects/typed-peripheral-digitalitems/documentation/index.md",
"projects/typed-peripheral-digitalitems/documentation/theme/plugin.mjs",
"projects/typed-peripheral-digitalitems/documentation/theme/digitalitems.css",
"projects/typed-peripheral-digitalitems/documentation/theme/digitalitems.js",
];
const DOC_GENERATORS = [
["projects/typed-peripheral-digitalitems/typedoc.json", "projects/typed-peripheral-digitalitems/documentation/theme/plugin.mjs"],
["projects/typed-peripheral-digitalitems/mkdocs.yml", "projects/typed-peripheral-digitalitems/requirements-docs.txt", "projects/typed-peripheral-digitalitems/documentation/generate-docs.mjs"],
];

const BRANCHES = ["1.20", "1.21"];
const TAG_RE = /^v\d+(?:\.\d+)+(?:-[0-9A-Za-z]+(?:[.-][0-9A-Za-z]+)*)?$/;
Expand Down Expand Up @@ -119,9 +120,10 @@ function show(repository, ref, path) {
}

function refHasDocs(repository, ref) {
return REQUIRED_DOC_FILES.every((path) =>
git(repository, ["cat-file", "-e", `${ref}:${path}`], true).status === 0
) && /\bgenerateDocs\b/.test(show(repository, ref, REQUIRED_DOC_FILES[0]));
const has = (path) => git(repository, ["cat-file", "-e", `${ref}:${path}`], true).status === 0;
return COMMON_DOC_FILES.every(has)
&& DOC_GENERATORS.some((files) => files.every(has))
&& /\bgenerateDocs\b/.test(show(repository, ref, COMMON_DOC_FILES[0]));
}

function metadata(repository, ref) {
Expand Down Expand Up @@ -265,7 +267,10 @@ function localTarget(root, html, rawLink) {
fail(`Malformed local link in ${html}: ${rawLink}`);
}
if (pathname.includes("\\") || pathname.includes("\0")) fail(`Unsafe local link in ${html}: ${rawLink}`);
const target = pathname.startsWith("/") ? resolve(root, `.${pathname}`) : resolve(dirname(html), pathname);
const versionedPath = pathname.match(/^\/.*?\/((?:branch|tag)\/.*)$/)?.[1];
const target = pathname.startsWith("/")
? resolve(root, versionedPath ?? `.${pathname}`)
: resolve(dirname(html), pathname);
if (!within(root, target)) fail(`Local link escapes site in ${html}: ${rawLink}`);
return target;
}
Expand All @@ -290,9 +295,6 @@ export async function validateSite(site) {
for (const entry of plan) {
const versionRoot = resolve(root, entry.path);
await regularFile(resolve(versionRoot, "index.html"), `${entry.path} index.html`);
for (const asset of ["search.js", "navigation.js", "custom.css", "custom.js"]) {
await regularFile(resolve(versionRoot, "assets", asset), `${entry.path} ${asset}`);
}
}
const canonicalRoot = await realpath(root);
for (const html of await htmlFiles(root)) {
Expand Down
19 changes: 14 additions & 5 deletions .github/scripts/docs-site.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ function entry(kind, name, sha = SHA_A) {
};
}

async function fragment(root, path, html = '<a href="assets/main.js">asset</a>') {
async function fragment(root, path, html = '<link rel="stylesheet" href="assets/main.css"><script src="assets/main.js"></script>') {
const directory = join(root, path);
await mkdir(join(directory, "assets"), { recursive: true });
await writeFile(join(directory, "index.html"), html);
for (const asset of ["main.js", "search.js", "navigation.js", "custom.css", "custom.js"]) {
for (const asset of ["main.js", "main.css"]) {
await writeFile(join(directory, "assets", asset), "// docs\n");
}
}
Expand Down Expand Up @@ -107,14 +107,23 @@ test("validate rejects links escaping the site", async () => {
await assert.rejects(validateSite(output), /escapes site/);
});

test("validate rejects missing TypeDoc assets", async () => {
test("validate resolves hosted version paths below the Pages project prefix", async () => {
const root = await mkdtemp(join(tmpdir(), "docs-site-prefix-"));
const input = join(root, "input");
const output = join(root, "output");
await fragment(input, "branch/1.20", '<script src="/DigitalItems/branch/1.20/assets/main.js"></script>');
await assembleSite({ input, output, plan: [entry("branch", "1.20")] });
await validateSite(output);
});

test("validate rejects a missing linked asset", async () => {
const root = await mkdtemp(join(tmpdir(), "docs-site-assets-"));
const input = join(root, "input");
const output = join(root, "output");
await fragment(input, "branch/1.20");
await assembleSite({ input, output, plan: [entry("branch", "1.20")] });
await unlink(join(output, "branch", "1.20", "assets", "search.js"));
await assert.rejects(validateSite(output), /Missing branch\/1.20 search.js/);
await unlink(join(output, "branch", "1.20", "assets", "main.css"));
await assert.rejects(validateSite(output), /Broken local link.*assets\/main.css/);
});

test("assemble rejects a symlinked output ancestor", async () => {
Expand Down
12 changes: 11 additions & 1 deletion .github/workflows/docs-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ jobs:
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: projects/typed-peripheral-digitalitems/requirements-docs.txt

- name: Install documentation dependencies
run: timeout --foreground 120s python -m pip install -r projects/typed-peripheral-digitalitems/requirements-docs.txt

- name: Build package and documentation
run: timeout --foreground 600s ./gradlew :typed-peripheral-digitalitems:compileTypeScript :typed-peripheral-digitalitems:generateDocs --no-daemon

Expand All @@ -55,7 +65,7 @@ jobs:
run: |
set -euo pipefail
NODE="$PWD/.gradle/nodejs/node-v22.14.0-linux-x64/bin/node"
timeout --foreground 60s "$NODE" --test .github/scripts/docs-site.test.mjs
timeout --foreground 60s "$NODE" --test .github/scripts/docs-site.test.mjs projects/typed-peripheral-digitalitems/documentation/generate-docs.test.mjs
mkdir -p build/docs-fragments/branch/1.21
cp -a projects/typed-peripheral-digitalitems/docs/. build/docs-fragments/branch/1.21/
timeout --foreground 60s "$NODE" .github/scripts/docs-site.mjs assemble --input build/docs-fragments --output build/docs-site --plan-json "$DOCS_PLAN"
Expand Down
11 changes: 11 additions & 0 deletions .github/workflows/docs-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ jobs:
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install MkDocs for migrated refs
run: |
if [[ -f projects/typed-peripheral-digitalitems/requirements-docs.txt ]]; then
timeout --foreground 120s python -m pip install -r projects/typed-peripheral-digitalitems/requirements-docs.txt
fi

- name: Generate documentation with ref-owned task
env:
DOCS_PATH: ${{ matrix.path }}
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ run/
.env
UnlimitedPeripheralWorks-*
.kotlin

.venv
70 changes: 63 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,73 @@
# Repository Guidelines
# Digital Items

## Overview

Digital Items is a Minecraft 1.20.1 mod that adds digital item storage peripherals for CC:Tweaked. It supports both Fabric and Forge from a shared core module.

## Tech Stack

- Runtime: Minecraft 1.20.1 / Java 17
- Languages: Kotlin 2.0, Java, TypeScript, and Lua
- Loaders: Fabric Loader 0.15 and Forge 47
- Computer mod: CC:Tweaked 1.113
- Testing: Testiarium GameTests and TypeScript-to-Lua fixtures
- Build system: Gradle Wrapper

## Key Commands

Log handling is important. Always use an explicit timeout and silently save complete output.

- Build: `mkdir -p build; LOG="build/gradle-$(date +%Y%m%d-%H%M%S).log"; timeout --foreground 10m ./gradlew build --no-daemon >"$LOG" 2>&1`
- GameTests: `mkdir -p build; LOG="build/gametests-$(date +%Y%m%d-%H%M%S).log"; timeout --foreground 20m xvfb-run -a ./gradlew gameTest --no-daemon -PminimalTestEnvironment >"$LOG" 2>&1`
- TypeScript fixtures: `mkdir -p build; LOG="build/typescript-tests-$(date +%Y%m%d-%H%M%S).log"; timeout --foreground 5m ./gradlew :typescript-tests:compileTestLua --no-daemon >"$LOG" 2>&1`

Increase timeouts only when required. Stop development clients and servers after collecting results. Report the command, exit code, duration, log path, and relevant errors; inspect only the relevant failure window.

## Project Structure

DigitalItems is a Gradle multi-project repository. Subprojects live under `projects/`:
```text
projects/
core/ # Shared implementation, resources, and GameTests
fabric/ # Fabric integration and test mod
forge/ # Forge integration and test mod
typed-peripheral-digitalitems/ # Publishable TypeScriptToLua peripheral API
typescript-tests/ # TypeScript sources compiled to ComputerCraft Lua fixtures
gradle/ # Version catalog and Gradle configuration
```

- `core`: loader-independent Minecraft mod code and shared test-mod sources.
- `forge`: Forge implementation, generated resources, and Forge GameTests.
- `fabric`: Fabric implementation, generated resources, and Fabric GameTests.
- `typed-peripheral-digitalitems`: publishable TypeScriptToLua peripheral API package.
- `typescript-tests`: TypeScript GameTest programs compiled to Lua and included in the shared test mod.
Production code lives in `src/main/`. Shared GameTests and fixtures live in `projects/core/src/testMod/`; loader test-mod entry points and metadata live in each loader's `src/testMod/`.

The TypeScript tests consume `typed-peripheral-digitalitems` through a local npm file dependency. Gradle compiles the package before installing the test project's npm dependencies.

## Contribution Workflow

Every new task must be implemented on a dedicated branch and submitted as a GitHub pull request. Do not commit task changes directly to the base branch.

## Conventions

- Keep loader-independent behavior in `projects/core/`.
- Keep loader API usage in the corresponding `fabric` or `forge` module.
- Follow the official Kotlin code style configured in `gradle.properties`.
- Reuse existing project patterns before adding helpers, abstractions, or dependencies.
- Comments explain why, not what.

## DO NOT MODIFY

- Never edit generated build output; change its source and rerun the relevant Gradle task.
- Never commit `build/`, development run directories, logs, EULA files, or `node_modules/`.
- Do not modify unrelated user changes in a dirty worktree.

## Testing Approach

- Run `:typescript-tests:compileTestLua` after changing TypeScript fixtures or the typed peripheral package.
- Run the root `gameTest` task for both Fabric and Forge GameTests, using `xvfb-run` for graphics-dependent Minecraft startup.
- Run the timed multi-loader build before marking code changes complete.
- Fix failing tests rather than skipping them.

## Code Style

- Prefer the smallest correct change.
- Do not add speculative abstractions or dependencies.
- Keep shared and loader-specific responsibilities separated.
- Preserve validation, error handling, and dedicated-server safety.
- If requirements are unclear, ask instead of assuming.
1 change: 1 addition & 0 deletions projects/typed-peripheral-digitalitems/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
*.d.ts
node_modules/
docs/
.mkdocs-build/
6 changes: 4 additions & 2 deletions projects/typed-peripheral-digitalitems/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ val generateDocs by tasks.registering(NpmTask::class) {
"package.json",
"package-lock.json",
"tsconfig.json",
"tsconfig.docs.json",
"typedoc.json",
"mkdocs.yml",
"requirements-docs.txt",
"*.ts",
"documentation/**/*.md",
"documentation/**/*.mjs",
"documentation/theme/**",
)
exclude("node_modules/**", "*.d.ts")
Expand All @@ -71,6 +72,7 @@ tasks.assemble {

tasks.clean {
delete(file("docs"))
delete(file(".mkdocs-build"))
delete(fileTree(projectDir) {
include("*.d.ts", "*.lua")
})
Expand Down
Loading
Loading