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
2 changes: 1 addition & 1 deletion .claude/agents/test-investigator.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ model: sonnet

You run Mill's checks and report what actually failed — nothing else.

Suites and how to run them (from the repo root, /Users/ali/code/mill):
Suites and how to run them (from the repo root):
- Go: `go test -tags server -count=1 -timeout 600s ./internal/... .`
- Frontend static: `cd frontend && npx tsc --noEmit && npm run lint && npm run boundaries`
- E2e (server build required first):
Expand Down
19 changes: 19 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
name: Bug report
about: Report something that isn't working
title: ''
labels: bug
assignees: ''
---

**What happened?**

**What did you expect to happen instead?**

**macOS version:**

**Build-identity badge value** (top-left of Mill's window — one of
`DEV · live`, `INSTALLED · <commit>`, `SERVER · <commit>`, or a red
`STALE BUILD` warning):

**Steps to reproduce (if known):**
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
with:
# goal 0028: a copyleft dependency can't enter via PR unnoticed -- Apache-2.0 (Mill's own LICENSE) is incompatible with GPL/AGPL's copyleft terms.
deny-licenses: GPL-2.0-only, GPL-2.0-or-later, GPL-3.0-only, GPL-3.0-or-later, AGPL-3.0-only, AGPL-3.0-or-later

# The future single required check (goal 0024/ADR-0034): decouples the
# branch ruleset from job-name churn -- the ruleset names only
Expand Down
53 changes: 53 additions & 0 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Scorecard analysis workflow

# Official ossf/scorecard template (goal 0028), adapted only for this
# repo's SHA-pinning style (matches ci.yml/release.yml's pinned
# actions/checkout and actions/upload-artifact versions, rather than the
# template's own independently-pinned SHAs, which happened to already
# match here). publish_results: true opts into the public score at
# https://scorecard.dev, which is what makes the README badge live.
on:
push:
# Only the default branch is supported by Scorecard's own docs.
branches:
- main
schedule:
# Weekly, Saturdays -- matches the upstream template's cadence.
- cron: '30 1 * * 6'

permissions: read-all

jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
permissions:
# Needed for Code scanning upload.
security-events: write
# Needed for GitHub OIDC token, required by publish_results: true.
id-token: write

steps:
- name: 'Checkout code'
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: 'Run analysis'
uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
with:
results_file: results.sarif
results_format: sarif
publish_results: true

- name: 'Upload artifact'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: SARIF file
path: results.sarif
retention-days: 5

- name: 'Upload to code-scanning'
uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
with:
sarif_file: results.sarif
28 changes: 28 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ linters:
enable:
- unused
- staticcheck
# goal 0028, first strengthening pass (security + HTTP-client hygiene
# matching what the code actually does -- procexec/httpconnector/
# openapispec are the real attack-surface packages). Second pass
# (gocritic/prealloc/contextcheck/sqlclosecheck) is deliberately not
# part of this goal -- tracked as future work in goal 0028's file.
- gosec
- bodyclose
- noctx
- revive
- unparam
exclusions:
paths:
- frontend
Expand All @@ -13,6 +23,24 @@ linters:
- builtin$
- examples$

settings:
revive:
rules:
# This repo has never doc-commented every exported symbol --
# confirmed by the first real run of this rule, which flagged
# ~40 pre-existing exported consts/types/funcs across files that
# already had real, deliberate doc comments on the pieces that
# matter (packages, non-obvious functions) and none on
# self-explanatory ones (e.g. `StatusLocked Status = "LOCKED"`).
# Enforcing full Java/godoc-style coverage retroactively is
# ceremony that fights the established house style, not a real
# finding -- goal 0028's own explicit "tune revive if its
# defaults fight house style" guidance (e.g. package-comments).
- name: exported
disabled: true
- name: package-comments
disabled: true

formatters:
exclusions:
paths:
Expand Down
7 changes: 6 additions & 1 deletion .ls-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@
# layout decisions, never accidents.
ls:
.go: regex:(main|singleinstance_(production|dev))
.*: regex:(README|CLAUDE|Taskfile|lefthook|go|\.golangci|\.ls-lint)
# SECURITY/CONTRIBUTING added goal 0028 (public-repo hygiene): both are
# standard GitHub community-profile root files, same allowlist family as
# README below (checked, not new -- CODE_OF_CONDUCT deliberately stays
# OUT per goal 0028's skip list until a second contributor exists, so
# it's not pre-added here).
.*: regex:(README|SECURITY|CONTRIBUTING|CLAUDE|Taskfile|lefthook|go|\.golangci|\.ls-lint)

ignore:
- build
Expand Down
41 changes: 41 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Contributing to Mill

Mill is solo-maintained. Contributions are welcome, but the process is
kept deliberately light — there's no separate contributor doc to
maintain in parallel with reality.

## Process

- **Read `CLAUDE.md` first.** It's the actual working process for this
repo (Research → Plan → Implement, coding conventions in
`.claude/rules/`), not an AI-only artifact — it applies whether you're
a human or an agent making the change.
- **Open an issue before a large PR.** Small fixes (typos, an obvious
bug with an obvious fix) can go straight to a PR. Anything that adds a
capability, changes a schema, or touches more than a couple of files
should start as an issue so the approach can be agreed before the work
is done — `docs/SPEC.md` is the source of truth for what Mill is and
why, and a PR that conflicts with it needs to resolve that first.
- **Run the local checks before opening a PR.** `task setup:hooks`
installs Lefthook's pre-commit hooks, which mirror what CI runs
(lint, vet, build, the file-length and root-layout checks). A PR
that fails CI's `ci-gate` required check won't merge.
- **Tests are part of the change, not a follow-up.** See
`.claude/rules/testing.md` for what layer a given bug or feature's
proof belongs at.

## Getting set up

See the [README](README.md#install) for the clone-and-run steps.

## Reporting a bug

Use the bug report issue template. It's short by design: what happened,
what you expected, your macOS version, and the build-identity badge
value shown in Mill's own UI (`DEV · live` / `INSTALLED · <commit>` /
`SERVER · <commit>`) — that one field tells us exactly which build you
were running.

## Reporting a security issue

Don't open a public issue — see [SECURITY.md](SECURITY.md).
122 changes: 63 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,65 @@
# Welcome to Your New Wails3 Project!
# Mill

[![CI](https://github.com/alicoding/mill/actions/workflows/ci.yml/badge.svg)](https://github.com/alicoding/mill/actions/workflows/ci.yml)

Congratulations on generating your Wails3 application! This README will guide you through the next steps to get your project up and running.

## Getting Started

1. Navigate to your project directory in the terminal.

2. To run your application in development mode, use the following command:

```
wails3 dev
```

This will start your application and enable hot-reloading for both frontend and backend changes.

3. To build your application for production, use:

```
wails3 build
```

This will create a production-ready executable in the `build` directory.

## Exploring Wails3 Features

Now that you have your project set up, it's time to explore the features that Wails3 offers:

1. **Check out the examples**: The best way to learn is by example. Visit the `examples` directory in the `v3/examples` directory to see various sample applications.

2. **Run an example**: To run any of the examples, navigate to the example's directory and use:

```
go run .
```

Note: Some examples may be under development during the alpha phase.

3. **Explore the documentation**: Visit the [Wails3 documentation](https://v3.wails.io/) for in-depth guides and API references.

4. **Join the community**: Have questions or want to share your progress? Join the [Wails Discord](https://discord.gg/JDdSxwjhGf) or visit the [Wails discussions on GitHub](https://github.com/wailsapp/wails/discussions).

## Project Structure

Take a moment to familiarize yourself with your project structure:

- `frontend/`: Contains your frontend code (HTML, CSS, JavaScript/TypeScript)
- `main.go`: The entry point of your Go backend
- `app.go`: Define your application structure and methods here
- `wails.json`: Configuration file for your Wails project

## Next Steps

1. Modify the frontend in the `frontend/` directory to create your desired UI.
2. Add backend functionality in `main.go`.
3. Use `wails3 dev` to see your changes in real-time.
4. When ready, build your application with `wails3 build`.

Happy coding with Wails3! If you encounter any issues or have questions, don't hesitate to consult the documentation or reach out to the Wails community.
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/alicoding/mill/badge)](https://scorecard.dev/viewer/?uri=github.com/alicoding/mill)

Mill is a guardrailed, agentic-workflow desktop app: it lets an AI agent (or
a human) compose and run automations — capturing data, processing it,
applying an action — while keeping every step reviewable and reversible.
The core idea is *what-you-see-is-what-I-see*: an AI acting on a system it
can't verify has to guess at the real state (what's actually on the
clipboard, what a command will really do, what a setting is really set to),
and that gap between the guess and reality is exactly where hallucination
and silent failure live. Mill closes that gap by giving both the human and
the AI the same verified, structured view of state — and a guardrail that
previews an action before it happens, instead of trusting a text
description of it. Mill isn't a novel category: it composes existing
primitives (a workflow authoring layer with guardrails) the way a generic
credential manager or a generic workflow-automation tool would, applied to
agent-guarded local actions instead.

## Status

Mill is under active development, pre-1.0. Several UX surfaces are
explicitly prototype-quality (tracked as such in `docs/SPEC.md`) while the
underlying capability is real and exercised end-to-end. Expect rough edges
in presentation before you expect them in behavior — and expect both to
keep changing release to release.

## Install

Mill ships as a single Go binary with the frontend compiled in (no
separate CLI/backend, no hosted-service dependency) — `git clone` plus a
local build is the whole install story. You'll need Go 1.25+, Node 22+,
the [Task](https://taskfile.dev) CLI, and the Wails3 CLI first:

```sh
brew install go node go-task lefthook golangci-lint
go install github.com/loeffel-io/ls-lint/v2/cmd/ls_lint@v2.3.1
go install github.com/wailsapp/wails/v3/cmd/wails3@v3.0.0-beta.4
# make sure $(go env GOPATH)/bin (usually ~/go/bin) is on your PATH

git clone https://github.com/alicoding/mill.git
cd mill
task setup:hooks # installs Lefthook's pre-commit hooks (mirrors CI)

# Run it
task dev # starts Mill with hot reload — leave it running
```

`task dev` is the way to iterate: frontend edits hot-reload instantly, and
only a Go change triggers a restart. See `CLAUDE.md` for the full set of
build/dev commands (`task install:app`, `task build`, `task package`, ...).

## Documentation

- [`docs/SPEC.md`](docs/SPEC.md) — the living architecture and positioning
doc (also rendered inside the app itself). Source of truth for what
Mill is, what's decided (`LOCKED`), and what's still open (`OPEN`).
- [`CONTRIBUTING.md`](CONTRIBUTING.md) — how to propose a change.
- [`SECURITY.md`](SECURITY.md) — how to report a vulnerability and what's
in scope.

## License

[Apache-2.0](LICENSE).
46 changes: 46 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Security Policy

## Reporting a vulnerability

Please report security vulnerabilities through GitHub's private
vulnerability reporting, not a public issue:

**[Report a vulnerability](https://github.com/alicoding/mill/security/advisories/new)**
(Security tab → "Report a vulnerability")

This opens a private advisory visible only to you and the maintainer, so
the issue isn't publicly disclosed before a fix ships. Please include
enough detail to reproduce it (steps, affected version/commit, expected
vs. actual behavior).

## Scope

Mill is a desktop app that executes guardrailed local commands and
integrations on the user's behalf. Things that are in scope for a security
report:

- A workflow, trigger, or MCP tool call bypassing the guardrail preview/
approval step and taking an action without the user seeing it first.
- Secrets (connector credentials, API keys) stored anywhere other than the
OS keychain, or leaking into logs, exported workflows, or the frontend.
- The MCP listener: Mill exposes a local, unauthenticated MCP server bound
to `127.0.0.1` (loopback-only, by design — it never binds a non-loopback
interface and is not reachable off the local machine). A report that it
*is* reachable off-machine, or that a loopback process without the
user's intent can drive it, is in scope. A report that "it has no auth"
on its own is expected/by-design for a loopback listener and not itself
a vulnerability, unless it demonstrates cross-boundary reachability.
- Arbitrary command/code execution reachable without going through the
guardrail (i.e. a path that runs something the user never previewed or
approved).

Out of scope: vulnerabilities requiring an already-compromised machine,
social engineering, or issues in third-party dependencies without a
demonstrated Mill-specific exploit path (report those upstream; Mill still
wants to know if it makes a dependency's issue reachable in a novel way).

## Supported versions

Mill is pre-1.0. There are no released version branches yet — the only
supported line is the latest commit on `main`. Fixes land there; there is
no backport policy until a 1.0 release establishes one.
13 changes: 13 additions & 0 deletions docs/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,19 @@ and are still current** (not Runbook-specific, so they outlived it):
(server, since the client can't be trusted), and the zod schema at
save time — a canvas can represent shapes the domain can't execute,
unlike the old linear-list form. `UX: PROTOTYPE`.
- **`elkjs` license verdict (goal 0028, recorded — not previously
resolved despite being flagged above): EPL-2.0, the license of the
two `elkjs` offers under its dual license, is the one Mill takes.**
`LOCKED`. EPL-2.0 is copyleft on modifications to the covered work
itself, not on separate works that merely link/import it — and Mill
never modifies `elkjs`'s source, only imports the unmodified npm
package. It's also loaded via a dynamic `import()` into its own
separate bundle chunk (not statically bundled into Mill's Apache-2.0
code), which is the clean case even under EPL-2.0's own stricter
"larger work" language: an unmodified dependency, distributed as its
own separate file, invoked at runtime rather than compiled together.
No Apache-2.0/EPL-2.0 conflict on this shape. No tooling change
follows from this — it's a recorded verdict, not a new check.
- **A workflow opens into the canvas via "New workflow" or by editing an
existing one, each in its own tab — `CompositionView.tsx`'s tab bar,
built on `@primer/react/experimental`'s headless `Tabs` state/ARIA
Expand Down
Loading
Loading