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
36 changes: 35 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.0.11] - 2026-07-26

### Added

- Notes now include a focused Markdown toolbar for headings, bold, italic,
lists, code, and links, plus Write and Preview modes that render the current
unsaved draft.
- Configured Photon workspaces now show a private **Texts** tab only in the
Captain's personal `#main`. It lists every Skipper conversation, preserves
each thread, and lets the Captain select, resume, and continue it on desktop.

### Changed

- Notes use a cleaner searchable sidebar, friendly titles without a visible
`.md` suffix, and a more spacious editor layout.
- Photon is now channel-agnostic: the configured Captain phone always texts
Skipper, one conversation remains current until `/new`, and legacy mapped
conversations move to the Captain's private Texts inbox during migration.
Desktop continuations share the same context without echoing to iMessage;
returning to the phone continues the conversation selected on desktop.
- GitHub Releases now require the complete numbered acceptance ledger from a
multi-item request, plus artifact and verification evidence. Generated
commit summaries can no longer replace the user-facing change list.
- The retained Apple Silicon release host now owns the complete macOS path:
clean build, signing, notarization, public-download installation, launch,
smoke verification, and Application Support preservation.

### Fixed

- New notes accept titles with or without `.md`, add the suffix when omitted,
and reject another extension with a corrected `.md` suggestion.
- Theme, reconnect, and service-worker update refreshes no longer discard or
replace the active Notes editor. The exact editor node, unsaved draft, focus,
selection, and preview state survive shell rebuilds.
- Long channel descriptions remain single-line and truncated at narrower
desktop widths instead of expanding the top bar into a one-character column.
- Newly provisioned residents prefer an unused character/color avatar
combination, eliminating stochastic duplicate identities in small fleets.
- Photon content is excluded from channel Chat, channel/global Threads, Board,
and unread counts, and the obsolete resident Photon tools and mapping UI are
removed.

## [0.0.10] - 2026-07-25

### Fixed
Expand Down Expand Up @@ -301,7 +334,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
notarization, stapled tickets, Gatekeeper verification, persistent
Application Support, and isolated Apple container machines.

[Unreleased]: https://github.com/gitcommit90/1Helm/compare/v0.0.10...HEAD
[Unreleased]: https://github.com/gitcommit90/1Helm/compare/v0.0.11...HEAD
[0.0.11]: https://github.com/gitcommit90/1Helm/releases/tag/v0.0.11
[0.0.10]: https://github.com/gitcommit90/1Helm/releases/tag/v0.0.10
[0.0.9]: https://github.com/gitcommit90/1Helm/releases/tag/v0.0.9
[0.0.8]: https://github.com/gitcommit90/1Helm/releases/tag/v0.0.8
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,10 @@ keys per member.

Connections are host-owned brokers, not secrets copied into every resident's
shell. Gmail exposes scoped account listing, search, read, and draft creation;
sending remains disabled by default. Photon maps allowlisted inbound iMessage
threads to a resident and permits narrow replies in an already-authorized
conversation. Provider, Gmail, and Photon credentials stay on the host.
sending remains disabled by default. Photon gives the Captain one direct line
to Skipper: every text stays in a private Texts thread until `/new`, and that
same context can continue on desktop without echoing desktop-only turns back to
iMessage. Provider, Gmail, and Photon credentials stay on the host.

New connection types have to earn their place with least-privilege scoping,
secret isolation, reconnect and recovery, deduplication, deterministic tests,
Expand Down Expand Up @@ -256,7 +257,7 @@ A fresh data directory opens first-run setup. The source runtime defaults to
| `PORT` | `8123` | HTTP/WebSocket control-plane port. |
| `CTRL_DATA_DIR` | `./data` | Databases, routing state, uploads, and narrow workspace mirrors. |
| `HELM_CHANNEL_COMPUTER_BACKEND` | `apple` on macOS, `lxc` on Linux, `wsl` on Windows | Host isolation backend; `native` and `mock` are explicit development/test overrides. |
| `HELM_CHANNEL_MACHINE_IMAGE` | `local/1helm-channel-machine:0.0.10` | Versioned channel-machine image contract. |
| `HELM_CHANNEL_MACHINE_IMAGE` | `local/1helm-channel-machine:0.0.11` | Versioned channel-machine image contract. |

### Agent-first JSON CLI

Expand Down
7 changes: 4 additions & 3 deletions docs/RELIABILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ ownership, recovery, and tests rather than depend on a prompt alone.
- Delivery state records pending, attempting, delivered, failed, or uncertain.
A restart may resume a never-attempted reply. An interrupted attempt is
surfaced as uncertain and is not blindly replayed into a duplicate.
- An external message received through Photon defaults to the Captain's
`#main`/Skipper mapping, invokes the mapped partner, and returns the final
response to the originating authorized conversation.
- An external message received through Photon is private Captain ↔ Skipper
state. It appears only in `#main` Texts, returns the final response to the
originating phone conversation, and continues until the Captain sends
`/new`; desktop continuations share context without producing iMessage echo.
- Timers, recurring workflows, long-running follow-ups, and connector replies
are durable obligations. Sleep, restart, or a closed renderer must not erase
them.
Expand Down
19 changes: 10 additions & 9 deletions docs/USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,15 +248,16 @@ running on that host.
## Photon / iMessage

Connections guides Photon device authorization, project setup, secret rotation,
phone registration, sidecar health, and conversation mapping. The first mapping
defaults to the Captain's `#main` and Skipper.

An allowlisted inbound text creates a real 1Helm thread, invokes the mapped
agent, retains its reply in 1Helm, and sends that final reply to the exact inbound
conversation once. If the agent explicitly uses `photon_send`, the automatic
return suppresses its duplicate. New unrelated outbound destinations remain
blocked unless explicitly granted. Rich attachment fidelity is not yet part of
the verified contract.
phone registration, and sidecar health. There are no channel mappings: the
Captain's configured phone always talks directly to Skipper.

The first inbound text creates a private conversation in `#main`'s **Texts**
tab. Phone messages and Skipper's iMessage replies are retained there, and the
conversation keeps one context across connector restarts and Photon space-ID
changes until the Captain sends `/new`. The Captain can continue the same
thread inside 1Helm and return to the phone later; desktop-only turns stay in
1Helm rather than being replayed as iMessages. Rich attachment fidelity is not
yet part of the verified contract.

## Workflows, follow-ups, and computer care

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "1helm",
"productName": "1Helm",
"version": "0.0.10",
"version": "0.0.11",
"private": true,
"type": "module",
"license": "AGPL-3.0-only",
Expand Down
4 changes: 2 additions & 2 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@
document.querySelectorAll('meta[name="theme-color"]').forEach(function (m) { m.setAttribute("content", color); });
})();
</script>
<link rel="stylesheet" href="/app.css?v=e7e858bbd30c" />
<link rel="stylesheet" href="/app.css?v=a96cb46611b7" />
<link rel="stylesheet" href="/bundle.css" />
</head>
<body class="h-screen w-screen overflow-hidden antialiased">
<div id="app" class="h-full w-full"></div>
<script type="module" src="/bundle.js?v=de7765eea23f"></script>
<script type="module" src="/bundle.js?v=f02f841b8e70"></script>
</body>
</html>
3 changes: 2 additions & 1 deletion src/client/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type AgentQuestions = {
answers?: Array<{ question_id: string; question: string; values: string[]; custom: string }> | null;
answered?: number | null;
};
export type Message = { id: number; channel_id: number; parent_id: number | null; body: string; created: number; reply_count: number; last_reply: number | null; author: Author; attachments: Attachment[]; progress?: AgentProgress[]; questions?: AgentQuestions | null };
export type Message = { id: number; channel_id: number; parent_id: number | null; body: string; created: number; reply_count: number; last_reply: number | null; author: Author; attachments: Attachment[]; progress?: AgentProgress[]; questions?: AgentQuestions | null; photon_conversation_id?: number | null; transport?: "inbound" | "outbound" | "app" };
export type ModelPolicy = { provider_id: number | null; provider_name: string | null; provider_kind: string | null; model: string; overridden: boolean; editable: boolean };
export type ResidentAgent = {
id: number; bot_id: number; kind: "channel" | "skipper"; name: string; display_name: string;
Expand Down Expand Up @@ -57,6 +57,7 @@ export type ThreadState = {
followup?: ThreadFollowup | null;
};
export type GlobalThread = ThreadState & { channel_name: string; channel_slug: string; unread: boolean };
export type TextConversation = { id: number; sender: string; root_message_id: number; thread_id: number; active: number; started: number; updated: number; closed?: number | null; title: string; summary: string; status: string; last_body?: string; message_count?: number; messages?: Message[] };
export type ChannelFile = { path: string; name: string; size: number; modified: number; kind: "file" | "directory" };
export type MemoryItem = { id: number; channel_id: number; thread_id: number | null; root_message_id?: number | null; kind: "summary" | "decision" | "fact" | "preference" | "artifact_ref"; content: string; author_type: string; scope: string; status: "current" | "superseded"; created: number };
export type ActivityItem = {
Expand Down
Loading
Loading