---
title: "skill by agenticluke · skilld"
canonical_url: "https://skilld.dev/gh/agenticluke/tinystruct-builder-plus"
meta:
  description: "Use this skill to build or fix tinystruct app modules and small services. Covers routes, Context, Builder JSON, settings, tests, and actions that work in… From agenticluke/tinystruct-builder-plus."
  "og:description": "Use this skill to build or fix tinystruct app modules and small services. Covers routes, Context, Builder JSON, settings, tests, and actions that work in… From agenticluke/tinystruct-builder-plus."
  "og:title": "skill by agenticluke"
  "twitter:description": "Use this skill to build or fix tinystruct app modules and small services. Covers routes, Context, Builder JSON, settings, tests, and actions that work in… From agenticluke/tinystruct-builder-plus."
  "twitter:title": "skill by agenticluke"
---

`

[All skills](https://skilld.dev/skills)

[![agenticluke avatar](https://skilld.dev/_img/avatar?url=https%3A%2F%2Fgithub.com%2Fagenticluke.png%3Fsize%3D96)](https://skilld.dev/gh/agenticluke)

# **/skill**

[@c43daec](https://github.com/agenticluke/tinystruct-builder-plus/commit/c43daec8cc125ab2d91ee3f1a7116a9cc6f2e964 "Your agent reads SKILL.md at commit c43daec")

by [agenticluke](https://skilld.dev/gh/agenticluke)· [agenticluke](https://skilld.dev/gh/agenticluke)/ [tinystruct-builder-plus](https://skilld.dev/gh/agenticluke/tinystruct-builder-plus)

Use this skill to build or fix tinystruct app modules and small services. Covers routes, Context, Builder JSON, settings, tests, and actions that work in both CLI and HTTP modes.

- 1 file
- 8 KB
- Updated last week
- [GitHub](https://github.com/agenticluke/tinystruct-builder-plus/blob/main/skill/SKILL.md "View SKILL.md on GitHub")

## SKILL.md

8 KB

**≈46** tokens always: the name and description. **≈2k** when used: this file.

## tinystruct Development Patterns

### Credit

This skill comes from ECC. Credit ECC in any copy or changed version.

### Use This Skill When

Use this skill when you:

- Create a module that extends `AbstractApplication`.
- Add a CLI or HTTP action with `@Action`.
- Read request data from `Context`.
- Return JSON data with `Builder`.
- Change `application.properties`.
- Create or rebuild `bin/dispatcher`.
- Fix route clashes or CLI argument errors.

### Main Rules

1. Extend `AbstractApplication`.
2. Put `@Action` only on `public` methods.
3. Use one action pattern for both CLI and HTTP when they do the same job.
4. Set the HTTP mode when an action must use a set method, such as POST.
5. Use `Builder` for JSON data.
6. Use `Context` only for data tied to the current request.
7. Turn off views for an API-only app.
8. Use `bin/dispatcher` as the main CLI entry point.
9. Let tinystruct find actions. Do not add them to `ActionRegistry` by hand.
10. Test both valid and bad input.

### Build Steps

#### 1. Create the app

```
public class MyService extends AbstractApplication {
    @Override
    public void init() {
        setTemplateRequired(false);
    }

    @Override
    public String version() {
        return "1.0.0";
    }
}
```

Call `setTemplateRequired(false)` when the app returns data and has no `.view` files.

#### 2. Add a simple action

```
@Action("greet")
public String greet() {
    return "Hello from tinystruct!";
}
```

Run it from the CLI:

```
bin/dispatcher greet
```

The same action can be used as an HTTP route when the app runs as a web service.

#### 3. Add route values

Each regex capture group must match one method argument. Keep the same order.

```
@Action("api/user/(\\d+)")
public String getUser(int userId) {
    return "User ID: " + userId;
}
```

Examples:

```
HTTP: /api/user/123
CLI:  bin/dispatcher api/user/123
```

Use a narrow pattern. For an ID, prefer `(\\d+)` over `(.*)`.

#### 4. Set the HTTP method

Use an HTTP mode when a route must accept only one method.

```
@Action(value = "login", mode = Mode.HTTP_POST)
public boolean login() {
    return true;
}
```

Do not put secret data in a URL. Read passwords and tokens from the request body or request context.

#### 5. Return JSON data

Use tinystruct's `Builder`. Do not add Gson or Jackson just for basic JSON.

```
@Action("api/data")
public Builder getData() throws ApplicationException {
    Builder result = new Builder();
    result.put("status", "success");

    Builder user = new Builder();
    user.put("id", 1);
    user.put("name", "James");

    result.put("data", user);
    return result;
}
```

Keep one clear shape for both success and error data. Do not return a `Builder` on success and a plain string on failure.

#### 6. Use request context with care

Use `Context` for request values, session values, and other request state.

- Check that a value exists before using it.
- Check its type before casting it.
- Do not store request state in static fields.
- Do not reuse one request's data in another request.
- Handle missing or bad values with a clear error result.

See [System and Usage](https://skilld.dev/gh/agenticluke/tinystruct-builder-plus/skill/-/references/system-usage.md) for the exact `Context` calls.

#### 7. Set app options

Put settings in:

```
src/main/resources/application.properties
```

Use the exact property names listed in [Architecture and Settings](https://skilld.dev/gh/agenticluke/tinystruct-builder-plus/skill/-/references/architecture.md).

Do not commit passwords, keys, or tokens. Read them from the safe setting source used by the project.

#### 8. Create the dispatcher

Use `ApplicationManager.init()` when the project needs a new or rebuilt `bin/dispatcher`.

Before replacing an existing script:

- Check whether it has local changes.
- Keep its run rights.
- Run one known action after it is built.

Do not add a separate `main(String[] args)` to each module.

### Full Usage Example

This service supports one route in both CLI and HTTP modes.

```
public class UserService extends AbstractApplication {
    @Override
    public void init() {
        setTemplateRequired(false);
    }

    @Override
    public String version() {
        return "1.0.0";
    }

    @Action("api/user/(\\d+)")
    public Builder getUser(int userId) throws ApplicationException {
        Builder result = new Builder();
        result.put("status", "success");

        Builder user = new Builder();
        user.put("id", userId);
        user.put("name", "James");

        result.put("data", user);
        return result;
    }
}
```

Run it:

```
bin/dispatcher api/user/123
```

Test these cases:

```
api/user/123     should match
api/user/0       should match if zero is allowed
api/user/abc     should not match
api/user/        should not match
```

Also call the HTTP route and check that it returns the same data shape.

### Edge Cases

#### Route clashes

Two actions may match the same path.

- Search all `@Action` values.
- Make each pattern as narrow as possible.
- Check fixed routes before adding broad regex routes.
- Test the path in both CLI and HTTP modes.

#### Route value errors

A route may match text that the method cannot read.

- Match digits for an `int`.
- Keep capture groups and method arguments in the same order.
- Do not add a capture group unless the method accepts it.
- Test very large numbers and missing values.

#### Wrong HTTP method

A route may exist but reject the request method.

- Check the action's `mode`.
- Use `Mode.HTTP_POST` for POST-only work.
- Do not let a state-changing action run through GET unless the app calls for it.

#### Missing views

If an API-only app throws `FileNotFoundException` for a `.view` file, call:

```
setTemplateRequired(false);
```

Do this in `init()`.

#### Bad or missing settings

- Give clear errors for required settings.
- Do not hide a missing setting with an unsafe default.
- Keep local and test settings apart when the project supports it.
- Do not print secret values in logs or errors.

#### JSON values

- Pick one rule for missing values, such as `null` or no field.
- Keep number, text, and boolean types stable.
- Use nested `Builder` values for nested objects.
- Check [Data Handling](https://skilld.dev/gh/agenticluke/tinystruct-builder-plus/skill/-/references/data-handling.md) before adding lists or custom types.

### Tests

Use JUnit 5.

Test that:

- The app starts.
- Each action is in `ActionRegistry`.
- Valid paths reach the right action.
- Bad paths do not match.
- Capture groups map to the right argument types.
- HTTP method limits work.
- CLI and HTTP calls give the same result shape.
- API-only apps do not look for view files.
- Missing context and settings fail in a clear way.

Do not rely only on direct method tests. A direct call will not catch a bad `@Action` pattern.

### Common Problems

| Problem | Fix |
| --- | --- |
| Gson or Jackson was added for basic JSON | Use `org.tinystruct.data.component.Builder`. |
| A `.view` file is missing | Call `setTemplateRequired(false)` in `init()`. |
| An action is not found | Make the method `public` and check its `@Action` value. |
| A route value cannot become an `int` | Use a digit-only capture group and test its range. |
| Two actions match one path | Make the patterns more exact. |
| CLI and HTTP give different results | Put shared work in one method and keep input rules the same. |
| Each module has its own `main` method | Use `bin/dispatcher`. |
| Code adds actions to `ActionRegistry` by hand | Use `@Action` and automatic discovery. |
| Request data is stored in a static field | Keep it in `Context` or a local value. |

### Reference Files

Read only the file needed for the task:

- [Architecture and Settings](https://skilld.dev/gh/agenticluke/tinystruct-builder-plus/skill/-/references/architecture.md): app base classes, packages, and properties.
- [Routing and @Action](https://skilld.dev/gh/agenticluke/tinystruct-builder-plus/skill/-/references/routing.md): route patterns, modes, and arguments.
- [Data Handling](https://skilld.dev/gh/agenticluke/tinystruct-builder-plus/skill/-/references/data-handling.md): `Builder`, nested data, and JSON values.
- [System and Usage](https://skilld.dev/gh/agenticluke/tinystruct-builder-plus/skill/-/references/system-usage.md): `Context`, sessions, events, and CLI use.
- [Testing](https://skilld.dev/gh/agenticluke/tinystruct-builder-plus/skill/-/references/testing.md): JUnit 5 and `ActionRegistry` tests.

Source: [SKILL.md on GitHub](https://github.com/agenticluke/tinystruct-builder-plus/blob/main/skill/SKILL.md)

## Third-party checks

No third-party reports yet.

## Provenance

[Signed by skilld at c43daec.](https://github.com/agenticluke/tinystruct-builder-plus/commit/c43daec8cc125ab2d91ee3f1a7116a9cc6f2e964 "c43daec8cc125ab2d91ee3f1a7116a9cc6f2e964") This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last week.

Activeupdated last week

## Capability

<dl>

<dt>origin</dt>
<dd>ECC</dd>

</dl>

## README badge

![README badge for agenticluke/tinystruct-builder-plus](https://skilld.dev/b/agenticluke/tinystruct-builder-plus?theme=light&label=0)

## Related skills

-
-
-
-
-
-