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
43 changes: 43 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Bug report
description: Report a reproducible problem in the browser library, Bridge, or share service.
title: "bug: "
labels: [bug]
body:
- type: markdown
attributes:
value: |
Do not attach Bridge tokens, private HTML artifacts, browser-library exports, or machine addresses.
- type: textarea
id: observed
attributes:
label: What happened?
description: Include the visible result and any non-sensitive error message.
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: Minimal reproduction
description: List the smallest safe steps that reproduce the issue.
placeholder: |
1. Start Helm with ...
2. Open ...
3. Observe ...
validations:
required: true
- type: input
id: version
attributes:
label: Helm commit or version
placeholder: main / commit SHA
- type: dropdown
id: area
attributes:
label: Area
options:
- Browser library
- HDOC document contract
- Agent Bridge
- Intranet sharing
- Backup or folder sync
- Documentation
24 changes: 24 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Feature request
description: Propose a user problem Helm should solve.
title: "feature: "
labels: [enhancement]
body:
- type: textarea
id: problem
attributes:
label: User problem
description: Describe the recurring outcome that is currently hard, not only a proposed UI control.
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposed outcome
description: Explain the smallest change that would make the problem easier.
validations:
required: true
- type: textarea
id: boundaries
attributes:
label: Trust and durability impact
description: Say whether the idea could affect original-file immutability, local-first behavior, explicit owner control, or portability.
13 changes: 13 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Outcome

What does this change make possible for a Helm user or contributor?

## Invariant preserved

Which durability, security, or ownership boundary remains true?

## Verification

- [ ] `python3 -m unittest discover -s tests -p 'test_*.py'`
- [ ] Browser smoke page checked when HTML behavior changed
- [ ] No tokens, private artifacts, machine addresses, or generated reports included
21 changes: 21 additions & 0 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Verify

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Run contract and service tests
run: python -m unittest discover -s tests -p 'test_*.py'
34 changes: 34 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Contributing to Helm

Thank you for improving Helm. The project is small by design, so a focused change with a clear contract is more valuable than a broad refactor.

## Before you start

1. Read [`README.md`](README.md) and [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).
2. For retained HTML or agent workflows, read [`AGENTS.md`](AGENTS.md), [`AI-GUIDE.md`](AI-GUIDE.md), and the full [`docs/HTML-DOCUMENT-SPEC.md`](docs/HTML-DOCUMENT-SPEC.md).
3. Keep the original HTML immutable. Catalog metadata is an overlay; it is never a silent source-file rewrite.

## Local verification

```bash
python3 -m unittest discover -s tests -p 'test_*.py'
python3 helm_share_server.py --host 127.0.0.1 --port 4173
```

Open the local app and, when a change affects HTML validity or repair behavior, visit `/tests/contract-smoke.html` and `/tests/repair-smoke.html`. Both should show `passed`.

## Pull-request expectations

- Explain the user-visible outcome and the preserved invariant.
- Keep unrelated formatting and generated artifacts out of the change.
- Add or update a focused regression test for behavioral changes.
- Do not commit Bridge tokens, browser IndexedDB data, private artifacts, machine addresses, or generated local reports.
- Do not add remote scripts, runtime CDNs, or executable HTML to a retained artifact without a documented and reviewed reason.

## Design bar

Helm is a calm, evidence-forward research workbench, not a generic file manager or marketing page. Visuals must clarify a real comparison, flow, boundary, or uncertainty; they must not be decoration. See [`docs/REPORT-DESIGN-STANDARD.md`](docs/REPORT-DESIGN-STANDARD.md).

## Reporting a security issue

Do not include credentials or private artifacts in a public issue. For a vulnerability that could expose a local library, Bridge token, or shared document, use GitHub's private vulnerability-reporting channel when it is available; otherwise contact the repository owner privately before publishing technical details.
88 changes: 75 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,105 @@
# Helm

[![Verify](https://github.com/waple0820/html-displayer/actions/workflows/verify.yml/badge.svg)](https://github.com/waple0820/html-displayer/actions/workflows/verify.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-1f6feb.svg)](LICENSE)

<p align="center">
<img src="assets/helm-mark.png" width="96" height="96" alt="Helm logo" />
</p>

**A local-first artifact repository for work produced by AI agents.**
<p align="center"><strong>A local-first artifact repository for work produced by AI agents.</strong></p>

Helm turns finished HTML reports, briefs, dashboards, and research into durable project artifacts: searchable, inspectable, reviewable, and shareable without surrendering the original file.
Helm keeps finished HTML reports, briefs, dashboards, and research as durable project artifacts. It preserves the original file, makes its contract inspectable, and gives people—not agents—the final say over what enters a personal library or gets shared.

![Helm library showing project navigation, agent-authored reports, document inspection, and intranet sharing](assets/helm-library.jpg)

## Start Helm
## Why Helm

- **Originals remain evidence.** Helm indexes, exports, backs up, and shares the exact HTML bytes; it never silently rewrites the source artifact.
- **Agents have a contract.** `HDOC/1.0`, report templates, and the checked-in agent guide make artifacts portable across projects and agents.
- **The owner keeps control.** Agent output arrives in a reviewable inbox. Browser storage, imports, and intranet publication remain deliberate human actions.

## Start in one minute

```bash
git clone <this-repository>
git clone https://github.com/waple0820/html-displayer.git
cd html-displayer

# Serve the library and its read-only share links.
# Browser library + optional read-only intranet sharing service.
python3 helm_share_server.py --host 127.0.0.1 --port 4173
```

Open [http://127.0.0.1:4173](http://127.0.0.1:4173). On the same machine, prepare the local Agent inbox once:
Open [http://127.0.0.1:4173](http://127.0.0.1:4173). The library is stored in that browser's IndexedDB; no account, cloud sync, build step, or external font is required.

## How an artifact moves

```text
Agent / project
└─ complete HDOC/1.0 HTML
└─ Helm Bridge inbox ── owner review ──> browser library (IndexedDB)
│ │
└─ exact original bytes ├─ HARC backup / explicit folder sync
└─ explicit immutable intranet share
```

The important boundary is deliberate: submitting to the Bridge is a handoff, not permission to modify the browser library.

## Hand an artifact to Helm

For the machine that owns the library, bootstrap the loopback Bridge once:

```bash
scripts/helm-agent-bootstrap --agent-name codex
```

## Agent quick path
From the project that produced a final report, brief, reference note, or dashboard:

`AGENTS.md` is the entry point. A compatible agent entering this repository should read it automatically; otherwise tell the agent:
```bash
/path/to/html-displayer/scripts/helm-submit output.html --source "your-agent-name"
```

> Read `AGENTS.md` and follow the Helm artifact handoff instructions. Produce one final, self-contained `HDOC/1.0` HTML artifact, validate it locally, and submit it exactly once.
The final artifact appears in **Agent inbox** for review and explicit import. Read [`AGENTS.md`](AGENTS.md) first when authoring with an agent; [`AI-GUIDE.md`](AI-GUIDE.md) contains the concise generation entry point.

From the project that produced the report, the final handoff is:
## Repository guide

| Path | Purpose |
| --- | --- |
| [`index.html`](index.html), [`app.js`](app.js), [`styles.css`](styles.css) | Static browser library, local catalog, safe reader, and interface. |
| [`validator.js`](validator.js) | Browser-side `HDOC/1.0` inspection and portability warnings. |
| [`helm_bridge.py`](helm_bridge.py) | Loopback-only agent ingress and immutable inbox records. |
| [`helm_share_server.py`](helm_share_server.py) | Static app plus owner-only publication of immutable read-only share links. |
| [`docs/`](docs/) | Format contract, architecture, report design, storage, Bridge, and sharing references. |
| [`templates/`](templates/) | Complete standalone report starters with visual evidence patterns. |
| [`scripts/`](scripts/) | Clone bootstrap and final agent handoff commands. |
| [`tests/`](tests/) | Contract, Bridge, share-store, and template regression checks. |

Read [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the data boundaries and [`docs/HTML-DOCUMENT-SPEC.md`](docs/HTML-DOCUMENT-SPEC.md) for the interoperable artifact contract.

## Develop and verify

Helm has no package-install step. Run the same checks used by CI:

```bash
/path/to/html-displayer/scripts/helm-submit output.html --source "your-agent-name"
python3 -m unittest discover -s tests -p 'test_*.py'
python3 helm_share_server.py --host 127.0.0.1 --port 4173
```

Helm derives the project identity from that working directory. The artifact then appears in **Agent inbox** for explicit review and import; the agent never receives direct access to the owner's browser library.
The browser smoke pages are available at [`/tests/contract-smoke.html`](tests/contract-smoke.html) and [`/tests/repair-smoke.html`](tests/repair-smoke.html) while the local server is running. Both should show `passed`.

## Scope and boundaries

Helm is intentionally a single-person, local-first archive. It does not provide cloud sync, multi-user collaboration, a WYSIWYG editor, background filesystem watching, RAG chat, OCR, or a mobile app. Those belong only after the original-file, recovery, and handoff contracts prove durable.

## Documentation

- [`AGENTS.md`](AGENTS.md) — instructions for coding agents entering the repository.
- [`AI-GUIDE.md`](AI-GUIDE.md) — concise HTML generation and handoff guide.
- [`docs/HTML-DOCUMENT-SPEC.md`](docs/HTML-DOCUMENT-SPEC.md) — `HDOC/1.0` interchange contract.
- [`docs/REPORT-DESIGN-STANDARD.md`](docs/REPORT-DESIGN-STANDARD.md) — answer-first report and visual-evidence standard.
- [`docs/AGENT-BRIDGE.md`](docs/AGENT-BRIDGE.md) — Bridge API, security model, and conflict semantics.
- [`docs/LOCAL-ARCHIVE-LAYOUT.md`](docs/LOCAL-ARCHIVE-LAYOUT.md) — portable `HARC/1.0` archive format.
- [`docs/INTRANET-SHARING.md`](docs/INTRANET-SHARING.md) — owner-controlled immutable sharing model.

## Contributing and security

For the contract and ready-to-use report patterns, see [`AI-GUIDE.md`](AI-GUIDE.md) and [`templates/`](templates/).
Contributions are welcome. Please read [`CONTRIBUTING.md`](CONTRIBUTING.md), preserve the immutable-original and no-secret boundaries, and run the verification command before opening a pull request. Helm is released under the [MIT License](LICENSE).
51 changes: 51 additions & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Helm architecture

Helm is deliberately split into small, inspectable planes. A document can remain useful even when any optional plane is not running.

## System map

```text
final standalone HDOC/1.0 HTML
agent/project ── POST ──> Loopback Bridge ── review ──> Browser library
original bytes IndexedDB
│ │
└── immutable inbox ├── HARC export
├── explicit folder sync
└── owner-selected share
read-only intranet HTML
```

## Four planes

| Plane | Primary code | Responsibility | Trust boundary |
| --- | --- | --- | --- |
| Browser library | `index.html`, `app.js`, `validator.js`, `archive-backup.js`, `folder-sync.js`, `repair.js` | Catalog, safe reading, search, metadata overlays, recovery, and explicit import. | The browser owns the personal library. |
| Artifact contract | `docs/HTML-DOCUMENT-SPEC.md`, `AI-GUIDE.md`, `templates/` | Portable `HDOC/1.0` HTML with evidence, provenance, and visual reading structure. | Artifact authors must not rely on Helm to make a document intelligible. |
| Agent handoff | `helm_bridge.py`, `scripts/helm-agent-bootstrap`, `scripts/helm-submit` | Authenticated loopback ingress; exact-byte inbox storage; idempotency and revision semantics. | Agents can submit, never import into browser storage. |
| Intranet sharing | `helm_share_server.py`, `docs/INTRANET-SHARING.md` | Explicit, immutable, read-only publication of one validated artifact. | Visitors can read a selected shared file, never enumerate or alter the library. |

## Data invariants

1. **Original HTML is immutable.** A browser catalog overlay may improve title, project, tag, or source metadata without rewriting the stored file.
2. **Identity is stable.** The manifest ID identifies the artifact; changed bytes are a revision or a genuinely new artifact, never an overwrite.
3. **The document is portable.** A finished artifact is a standalone `HDOC/1.0` file with a semantic root, embedded essential CSS, manifest, and provenance.
4. **Import is owner-controlled.** The Bridge and an intranet share server cannot mutate IndexedDB.
5. **Publication is explicit.** Sharing produces a content-addressed read-only copy outside the browser library and outside the Git checkout.

## Repository layout

The root remains intentionally small because the product is a static browser application plus Python standard-library services. Browser modules stay adjacent to the entry page; reusable standards and operational contracts live under `docs/`; user-facing starters live under `templates/`; and behavior is covered by `tests/`.

Do not introduce a framework build pipeline, server database, or cloud dependency merely to reorganize files. A new dependency needs to preserve Helm's local-first and durable-original guarantees.

## Reading order for contributors

1. [`README.md`](../README.md) — product promise and local start.
2. [`HTML-DOCUMENT-SPEC.md`](HTML-DOCUMENT-SPEC.md) — artifact interchange contract.
3. [`AGENT-BRIDGE.md`](AGENT-BRIDGE.md) or [`INTRANET-SHARING.md`](INTRANET-SHARING.md) — the relevant server boundary.
4. `app.js` or the corresponding Python service — implementation.
5. The matching test in `tests/` — observable behavior and regression guard.
33 changes: 33 additions & 0 deletions tests/test_templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import sys
import unittest
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

from helm_bridge import validate_hdoc


ROOT = Path(__file__).resolve().parents[1]
TEMPLATES = (
"research-dossier.html",
"decision-brief.html",
"reference-note.html",
"agent-handoff.html",
)


class TemplateContractTests(unittest.TestCase):
def test_shipped_templates_are_valid_hdoc_documents(self):
for name in TEMPLATES:
with self.subTest(template=name):
html = (ROOT / "templates" / name).read_text(encoding="utf-8")
manifest, _ = validate_hdoc(html)
self.assertEqual(manifest["schema_version"], "HDOC/1.0")
self.assertTrue(manifest["id"])
self.assertTrue(manifest["project"]["id"])
self.assertIn("<main data-document-root>", html)
self.assertEqual(html.lower().count("<h1"), 1)


if __name__ == "__main__":
unittest.main()
Loading